1 //===--- PPC.cpp - Implement PPC target feature support -------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements PPC TargetInfo objects.
12 //===----------------------------------------------------------------------===//
15 #include "clang/Basic/Diagnostic.h"
16 #include "clang/Basic/MacroBuilder.h"
17 #include "clang/Basic/TargetBuiltins.h"
18 #include "llvm/ADT/StringSwitch.h"
20 using namespace clang;
21 using namespace clang::targets;
23 const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
24 #define BUILTIN(ID, TYPE, ATTRS) \
25 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
26 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
27 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
28 #include "clang/Basic/BuiltinsPPC.def"
31 /// handleTargetFeatures - Perform initialization based on the user
32 /// configured set of features.
33 bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
34 DiagnosticsEngine &Diags) {
35 for (const auto &Feature : Features) {
36 if (Feature == "+altivec") {
38 } else if (Feature == "+vsx") {
40 } else if (Feature == "+bpermd") {
42 } else if (Feature == "+extdiv") {
44 } else if (Feature == "+power8-vector") {
46 } else if (Feature == "+crypto") {
48 } else if (Feature == "+direct-move") {
50 } else if (Feature == "+qpx") {
52 } else if (Feature == "+htm") {
54 } else if (Feature == "+float128") {
56 } else if (Feature == "+power9-vector") {
59 // TODO: Finish this list and add an assert that we've handled them
66 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
67 /// #defines that are not tied to a specific subtarget.
68 void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
69 MacroBuilder &Builder) const {
70 // Target identification.
71 Builder.defineMacro("__ppc__");
72 Builder.defineMacro("__PPC__");
73 Builder.defineMacro("_ARCH_PPC");
74 Builder.defineMacro("__powerpc__");
75 Builder.defineMacro("__POWERPC__");
76 if (PointerWidth == 64) {
77 Builder.defineMacro("_ARCH_PPC64");
78 Builder.defineMacro("__powerpc64__");
79 Builder.defineMacro("__ppc64__");
80 Builder.defineMacro("__PPC64__");
84 if (getTriple().getArch() == llvm::Triple::ppc64le) {
85 Builder.defineMacro("_LITTLE_ENDIAN");
87 if (getTriple().getOS() != llvm::Triple::NetBSD &&
88 getTriple().getOS() != llvm::Triple::OpenBSD)
89 Builder.defineMacro("_BIG_ENDIAN");
93 if (ABI == "elfv1" || ABI == "elfv1-qpx")
94 Builder.defineMacro("_CALL_ELF", "1");
96 Builder.defineMacro("_CALL_ELF", "2");
98 // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but
99 // our suppport post-dates this and it should work on all 64-bit ppc linux
100 // platforms. It is guaranteed to work on all elfv2 platforms.
101 if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64)
102 Builder.defineMacro("_CALL_LINUX", "1");
104 // Subtarget options.
105 Builder.defineMacro("__NATURAL_ALIGNMENT__");
106 Builder.defineMacro("__REGISTER_PREFIX__", "");
108 // FIXME: Should be controlled by command line option.
109 if (LongDoubleWidth == 128) {
110 Builder.defineMacro("__LONG_DOUBLE_128__");
111 Builder.defineMacro("__LONGDOUBLE128");
114 // Define this for elfv2 (64-bit only) or 64-bit darwin.
115 if (ABI == "elfv2" ||
116 (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64))
117 Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");
119 // CPU identification.
120 ArchDefineTypes defs =
121 (ArchDefineTypes)llvm::StringSwitch<int>(CPU)
122 .Case("440", ArchDefineName)
123 .Case("450", ArchDefineName | ArchDefine440)
124 .Case("601", ArchDefineName)
125 .Case("602", ArchDefineName | ArchDefinePpcgr)
126 .Case("603", ArchDefineName | ArchDefinePpcgr)
127 .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
128 .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
129 .Case("604", ArchDefineName | ArchDefinePpcgr)
130 .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr)
131 .Case("620", ArchDefineName | ArchDefinePpcgr)
132 .Case("630", ArchDefineName | ArchDefinePpcgr)
133 .Case("7400", ArchDefineName | ArchDefinePpcgr)
134 .Case("7450", ArchDefineName | ArchDefinePpcgr)
135 .Case("750", ArchDefineName | ArchDefinePpcgr)
136 .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr |
138 .Case("a2", ArchDefineA2)
139 .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q)
140 .Case("pwr3", ArchDefinePpcgr)
141 .Case("pwr4", ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq)
142 .Case("pwr5", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr |
144 .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4 |
145 ArchDefinePpcgr | ArchDefinePpcsq)
146 .Case("pwr6", ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5 |
147 ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
148 .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x |
149 ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
151 .Case("pwr7", ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6 |
152 ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 |
153 ArchDefinePpcgr | ArchDefinePpcsq)
154 .Case("pwr8", ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x |
155 ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 |
156 ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
157 .Case("pwr9", ArchDefineName | ArchDefinePwr8 | ArchDefinePwr7 |
158 ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x |
159 ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
161 .Case("power3", ArchDefinePpcgr)
162 .Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
163 .Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
165 .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 |
166 ArchDefinePpcgr | ArchDefinePpcsq)
167 .Case("power6", ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 |
168 ArchDefinePwr4 | ArchDefinePpcgr |
170 .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x |
171 ArchDefinePwr5 | ArchDefinePwr4 |
172 ArchDefinePpcgr | ArchDefinePpcsq)
173 .Case("power7", ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 |
174 ArchDefinePwr5x | ArchDefinePwr5 |
175 ArchDefinePwr4 | ArchDefinePpcgr |
177 .Case("power8", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x |
178 ArchDefinePwr6 | ArchDefinePwr5x |
179 ArchDefinePwr5 | ArchDefinePwr4 |
180 ArchDefinePpcgr | ArchDefinePpcsq)
181 .Case("power9", ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 |
182 ArchDefinePwr6x | ArchDefinePwr6 |
183 ArchDefinePwr5x | ArchDefinePwr5 |
184 ArchDefinePwr4 | ArchDefinePpcgr |
186 // powerpc64le automatically defaults to at least power8.
187 .Case("ppc64le", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x |
188 ArchDefinePwr6 | ArchDefinePwr5x |
189 ArchDefinePwr5 | ArchDefinePwr4 |
190 ArchDefinePpcgr | ArchDefinePpcsq)
191 .Default(ArchDefineNone);
193 if (defs & ArchDefineName)
194 Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
195 if (defs & ArchDefinePpcgr)
196 Builder.defineMacro("_ARCH_PPCGR");
197 if (defs & ArchDefinePpcsq)
198 Builder.defineMacro("_ARCH_PPCSQ");
199 if (defs & ArchDefine440)
200 Builder.defineMacro("_ARCH_440");
201 if (defs & ArchDefine603)
202 Builder.defineMacro("_ARCH_603");
203 if (defs & ArchDefine604)
204 Builder.defineMacro("_ARCH_604");
205 if (defs & ArchDefinePwr4)
206 Builder.defineMacro("_ARCH_PWR4");
207 if (defs & ArchDefinePwr5)
208 Builder.defineMacro("_ARCH_PWR5");
209 if (defs & ArchDefinePwr5x)
210 Builder.defineMacro("_ARCH_PWR5X");
211 if (defs & ArchDefinePwr6)
212 Builder.defineMacro("_ARCH_PWR6");
213 if (defs & ArchDefinePwr6x)
214 Builder.defineMacro("_ARCH_PWR6X");
215 if (defs & ArchDefinePwr7)
216 Builder.defineMacro("_ARCH_PWR7");
217 if (defs & ArchDefinePwr8)
218 Builder.defineMacro("_ARCH_PWR8");
219 if (defs & ArchDefinePwr9)
220 Builder.defineMacro("_ARCH_PWR9");
221 if (defs & ArchDefineA2)
222 Builder.defineMacro("_ARCH_A2");
223 if (defs & ArchDefineA2q) {
224 Builder.defineMacro("_ARCH_A2Q");
225 Builder.defineMacro("_ARCH_QP");
228 if (getTriple().getVendor() == llvm::Triple::BGQ) {
229 Builder.defineMacro("__bg__");
230 Builder.defineMacro("__THW_BLUEGENE__");
231 Builder.defineMacro("__bgq__");
232 Builder.defineMacro("__TOS_BGQ__");
236 Builder.defineMacro("__VEC__", "10206");
237 Builder.defineMacro("__ALTIVEC__");
240 Builder.defineMacro("__VSX__");
242 Builder.defineMacro("__POWER8_VECTOR__");
244 Builder.defineMacro("__CRYPTO__");
246 Builder.defineMacro("__HTM__");
248 Builder.defineMacro("__FLOAT128__");
250 Builder.defineMacro("__POWER9_VECTOR__");
252 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
253 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
254 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
255 if (PointerWidth == 64)
256 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
258 // We have support for the bswap intrinsics so we can define this.
259 Builder.defineMacro("__HAVE_BSWAP__", "1");
261 // FIXME: The following are not yet generated here by Clang, but are
265 // __RECIP_PRECISION__
280 // Handle explicit options being passed to the compiler here: if we've
281 // explicitly turned off vsx and turned on any of:
286 // then go ahead and error since the customer has expressed an incompatible
288 static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
289 const std::vector<std::string> &FeaturesVec) {
291 if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "-vsx") !=
293 if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power8-vector") !=
295 Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower8-vector"
300 if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+direct-move") !=
302 Diags.Report(diag::err_opt_not_valid_with_opt) << "-mdirect-move"
307 if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") !=
309 Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128"
314 if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power9-vector") !=
316 Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower9-vector"
325 bool PPCTargetInfo::initFeatureMap(
326 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
327 const std::vector<std::string> &FeaturesVec) const {
328 Features["altivec"] = llvm::StringSwitch<bool>(CPU)
340 .Case("ppc64le", true)
343 Features["qpx"] = (CPU == "a2q");
344 Features["power9-vector"] = (CPU == "pwr9");
345 Features["crypto"] = llvm::StringSwitch<bool>(CPU)
346 .Case("ppc64le", true)
350 Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)
351 .Case("ppc64le", true)
355 Features["bpermd"] = llvm::StringSwitch<bool>(CPU)
356 .Case("ppc64le", true)
361 Features["extdiv"] = llvm::StringSwitch<bool>(CPU)
362 .Case("ppc64le", true)
367 Features["direct-move"] = llvm::StringSwitch<bool>(CPU)
368 .Case("ppc64le", true)
372 Features["vsx"] = llvm::StringSwitch<bool>(CPU)
373 .Case("ppc64le", true)
378 Features["htm"] = llvm::StringSwitch<bool>(CPU)
379 .Case("ppc64le", true)
384 if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
387 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
390 bool PPCTargetInfo::hasFeature(StringRef Feature) const {
391 return llvm::StringSwitch<bool>(Feature)
392 .Case("powerpc", true)
393 .Case("altivec", HasAltivec)
395 .Case("power8-vector", HasP8Vector)
396 .Case("crypto", HasP8Crypto)
397 .Case("direct-move", HasDirectMove)
400 .Case("bpermd", HasBPERMD)
401 .Case("extdiv", HasExtDiv)
402 .Case("float128", HasFloat128)
403 .Case("power9-vector", HasP9Vector)
407 void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
408 StringRef Name, bool Enabled) const {
410 // If we're enabling any of the vsx based features then enable vsx and
411 // altivec. We'll diagnose any problems later.
412 bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)
414 .Case("direct-move", true)
415 .Case("power8-vector", true)
416 .Case("power9-vector", true)
417 .Case("float128", true)
420 Features["vsx"] = Features["altivec"] = true;
421 if (Name == "power9-vector")
422 Features["power8-vector"] = true;
423 Features[Name] = true;
425 // If we're disabling altivec or vsx go ahead and disable all of the vsx
427 if ((Name == "altivec") || (Name == "vsx"))
428 Features["vsx"] = Features["direct-move"] = Features["power8-vector"] =
429 Features["float128"] = Features["power9-vector"] = false;
430 if (Name == "power8-vector")
431 Features["power9-vector"] = false;
432 Features[Name] = false;
436 const char *const PPCTargetInfo::GCCRegNames[] = {
437 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
438 "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
439 "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
440 "r27", "r28", "r29", "r30", "r31", "f0", "f1", "f2", "f3",
441 "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12",
442 "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
443 "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30",
444 "f31", "mq", "lr", "ctr", "ap", "cr0", "cr1", "cr2", "cr3",
445 "cr4", "cr5", "cr6", "cr7", "xer", "v0", "v1", "v2", "v3",
446 "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12",
447 "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
448 "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30",
449 "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp"
452 ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {
453 return llvm::makeArrayRef(GCCRegNames);
456 const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
457 // While some of these aliases do map to different registers
458 // they still share the same register name.
459 {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"},
460 {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"},
461 {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"},
462 {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"},
463 {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"},
464 {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"},
465 {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"},
466 {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"},
467 {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"},
468 {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"},
469 {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"},
470 {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"},
471 {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"},
472 {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"},
473 {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"},
474 {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"},
478 ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
479 return llvm::makeArrayRef(GCCRegAliases);
482 bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
483 return llvm::StringSwitch<bool>(Name)
484 .Case("generic", true)
506 .Case("e500mc", true)
508 .Case("power3", true)
510 .Case("power4", true)
512 .Case("power5", true)
514 .Case("power5x", true)
516 .Case("power6", true)
518 .Case("power6x", true)
520 .Case("power7", true)
522 .Case("power8", true)
524 .Case("power9", true)
526 .Case("powerpc", true)
528 .Case("powerpc64", true)
530 .Case("powerpc64le", true)
531 .Case("ppc64le", true)
535 void PPCTargetInfo::adjust(LangOptions &Opts) {
538 TargetInfo::adjust(Opts);
541 ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
542 return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin -
543 Builtin::FirstTSBuiltin);