xref: /freebsd/contrib/llvm-project/llvm/lib/TargetParser/PPCTargetParser.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===---- PPCTargetParser.cpp - Parser for target features ------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements a target parser to recognise hardware features
10 // for PPC CPUs.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/TargetParser/PPCTargetParser.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/TargetParser/Host.h"
17 
18 #define GET_SUBTARGETFEATURES_ENUM
19 #define GET_SUBTARGETFEATURES_KV
20 #include "llvm/TargetParser/PPCGenTargetFeatures.inc"
21 
22 namespace llvm {
23 namespace PPC {
24 
25 struct CPUInfo {
26   StringLiteral Name;
27   // FIXME: add the features field for this CPU.
28 };
29 
30 constexpr CPUInfo PPCCPUInfo[] = {
31 #define PPC_CPU(Name, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD,       \
32                 AIXID)                                                         \
33   {Name},
34 #include "llvm/TargetParser/PPCTargetParser.def"
35 };
36 
getCPUInfoByName(StringRef CPU)37 static const CPUInfo *getCPUInfoByName(StringRef CPU) {
38   for (auto &C : PPCCPUInfo)
39     if (C.Name == CPU)
40       return &C;
41   return nullptr;
42 }
43 
normalizeCPUName(StringRef CPUName)44 StringRef normalizeCPUName(StringRef CPUName) {
45   // Clang/LLVM does not actually support code generation
46   // for the 405 CPU. However, there are uses of this CPU ID
47   // in projects that previously used GCC and rely on Clang
48   // accepting it. Clang has always ignored it and passed the
49   // generic CPU ID to the back end.
50   return StringSwitch<StringRef>(CPUName)
51       .Cases("common", "405", "generic")
52       .Cases("ppc440", "440fp", "440")
53       .Cases("630", "power3", "pwr3")
54       .Case("G3", "g3")
55       .Case("G4", "g4")
56       .Case("G4+", "g4+")
57       .Case("8548", "e500")
58       .Case("ppc970", "970")
59       .Case("G5", "g5")
60       .Case("ppca2", "a2")
61       .Case("power4", "pwr4")
62       .Case("power5", "pwr5")
63       .Case("power5x", "pwr5x")
64       .Case("power5+", "pwr5+")
65       .Case("power6", "pwr6")
66       .Case("power6x", "pwr6x")
67       .Case("power7", "pwr7")
68       .Case("power8", "pwr8")
69       .Case("power9", "pwr9")
70       .Case("power10", "pwr10")
71       .Case("power11", "pwr11")
72       .Cases("powerpc", "powerpc32", "ppc")
73       .Case("powerpc64", "ppc64")
74       .Case("powerpc64le", "ppc64le")
75       .Default(CPUName);
76 }
77 
fillValidCPUList(SmallVectorImpl<StringRef> & Values)78 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) {
79   for (const auto &C : PPCCPUInfo)
80     Values.emplace_back(C.Name);
81 }
82 
fillValidTuneCPUList(SmallVectorImpl<StringRef> & Values)83 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) {
84   for (const auto &C : PPCCPUInfo)
85     Values.emplace_back(C.Name);
86 }
87 
isValidCPU(StringRef CPU)88 bool isValidCPU(StringRef CPU) {
89   const CPUInfo *Info = getCPUInfoByName(CPU);
90   if (!Info)
91     return false;
92   return true;
93 }
94 
getNormalizedPPCTargetCPU(const Triple & T,StringRef CPUName)95 StringRef getNormalizedPPCTargetCPU(const Triple &T, StringRef CPUName) {
96   if (!CPUName.empty()) {
97     if (CPUName == "native") {
98       StringRef CPU = sys::getHostCPUName();
99       if (!CPU.empty() && CPU != "generic")
100         return CPU;
101     }
102 
103     StringRef CPU = normalizeCPUName(CPUName);
104     if (CPU != "generic" && CPU != "native")
105       return CPU;
106   }
107 
108   // LLVM may default to generating code for the native CPU, but, like gcc, we
109   // default to a more generic option for each architecture. (except on AIX)
110   if (T.isOSAIX())
111     return "pwr7";
112   else if (T.getArch() == Triple::ppc64le)
113     return "ppc64le";
114   else if (T.getArch() == Triple::ppc64)
115     return "ppc64";
116 
117   return "ppc";
118 }
119 
getNormalizedPPCTuneCPU(const Triple & T,StringRef CPUName)120 StringRef getNormalizedPPCTuneCPU(const Triple &T, StringRef CPUName) {
121   return getNormalizedPPCTargetCPU(T, CPUName);
122 }
123 
getPPCDefaultTargetFeatures(const Triple & T,StringRef CPU)124 std::optional<StringMap<bool>> getPPCDefaultTargetFeatures(const Triple &T,
125                                                            StringRef CPU) {
126   std::optional<StringMap<bool>> FeaturesOpt =
127       getCPUDefaultTargetFeatures(CPU, BasicPPCSubTypeKV, BasicPPCFeatureKV);
128 
129   if (!FeaturesOpt.has_value())
130     return std::nullopt;
131 
132   StringMap<bool> Features = FeaturesOpt.value();
133   // FIXME: We need to check for the processor model 8548, since the backend
134   // does not support this processor. When this processor model is implemented
135   // within the backend, the following code can be removed.
136   if (CPU == "8548")
137     Features["spe"] = true;
138 
139   // The target feature `quadword-atomics` is only supported for 64-bit
140   // POWER8 and above.
141   if (Features.find("quadword-atomics") != Features.end() && !T.isArch64Bit())
142     Features["quadword-atomics"] = false;
143   return Features;
144 }
145 } // namespace PPC
146 } // namespace llvm
147