1 //===--- PPC.cpp - Implement PPC target feature support -------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements PPC TargetInfo objects.
11 //===----------------------------------------------------------------------===//
14 #include "clang/Basic/Diagnostic.h"
15 #include "clang/Basic/MacroBuilder.h"
16 #include "clang/Basic/TargetBuiltins.h"
18 using namespace clang;
19 using namespace clang::targets;
21 const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
22 #define BUILTIN(ID, TYPE, ATTRS) \
23 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
24 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
25 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
26 #include "clang/Basic/BuiltinsPPC.def"
29 /// handleTargetFeatures - Perform initialization based on the user
30 /// configured set of features.
31 bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
32 DiagnosticsEngine &Diags) {
34 for (const auto &Feature : Features) {
35 if (Feature == "+altivec") {
37 } else if (Feature == "+vsx") {
39 } else if (Feature == "+bpermd") {
41 } else if (Feature == "+extdiv") {
43 } else if (Feature == "+power8-vector") {
45 } else if (Feature == "+crypto") {
47 } else if (Feature == "+direct-move") {
49 } else if (Feature == "+qpx") {
51 } else if (Feature == "+htm") {
53 } else if (Feature == "+float128") {
55 } else if (Feature == "+power9-vector") {
57 } else if (Feature == "+power10-vector") {
59 } else if (Feature == "+pcrelative-memops") {
60 HasPCRelativeMemops = true;
61 } else if (Feature == "+spe") {
63 LongDoubleWidth = LongDoubleAlign = 64;
64 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
65 } else if (Feature == "-hard-float") {
68 // TODO: Finish this list and add an assert that we've handled them
75 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
76 /// #defines that are not tied to a specific subtarget.
77 void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
78 MacroBuilder &Builder) const {
79 // Target identification.
80 Builder.defineMacro("__ppc__");
81 Builder.defineMacro("__PPC__");
82 Builder.defineMacro("_ARCH_PPC");
83 Builder.defineMacro("__powerpc__");
84 Builder.defineMacro("__POWERPC__");
85 if (PointerWidth == 64) {
86 Builder.defineMacro("_ARCH_PPC64");
87 Builder.defineMacro("__powerpc64__");
88 Builder.defineMacro("__ppc64__");
89 Builder.defineMacro("__PPC64__");
93 if (getTriple().getArch() == llvm::Triple::ppc64le) {
94 Builder.defineMacro("_LITTLE_ENDIAN");
96 if (!getTriple().isOSNetBSD() &&
97 !getTriple().isOSOpenBSD())
98 Builder.defineMacro("_BIG_ENDIAN");
102 if (ABI == "elfv1" || ABI == "elfv1-qpx")
103 Builder.defineMacro("_CALL_ELF", "1");
105 Builder.defineMacro("_CALL_ELF", "2");
107 // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but
108 // our support post-dates this and it should work on all 64-bit ppc linux
109 // platforms. It is guaranteed to work on all elfv2 platforms.
110 if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64)
111 Builder.defineMacro("_CALL_LINUX", "1");
113 // Subtarget options.
114 if (!getTriple().isOSAIX()){
115 Builder.defineMacro("__NATURAL_ALIGNMENT__");
117 Builder.defineMacro("__REGISTER_PREFIX__", "");
119 // FIXME: Should be controlled by command line option.
120 if (LongDoubleWidth == 128) {
121 Builder.defineMacro("__LONG_DOUBLE_128__");
122 Builder.defineMacro("__LONGDOUBLE128");
125 // Define this for elfv2 (64-bit only) or 64-bit darwin.
126 if (ABI == "elfv2" ||
127 (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64))
128 Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");
130 if (ArchDefs & ArchDefineName)
131 Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
132 if (ArchDefs & ArchDefinePpcgr)
133 Builder.defineMacro("_ARCH_PPCGR");
134 if (ArchDefs & ArchDefinePpcsq)
135 Builder.defineMacro("_ARCH_PPCSQ");
136 if (ArchDefs & ArchDefine440)
137 Builder.defineMacro("_ARCH_440");
138 if (ArchDefs & ArchDefine603)
139 Builder.defineMacro("_ARCH_603");
140 if (ArchDefs & ArchDefine604)
141 Builder.defineMacro("_ARCH_604");
142 if (ArchDefs & ArchDefinePwr4)
143 Builder.defineMacro("_ARCH_PWR4");
144 if (ArchDefs & ArchDefinePwr5)
145 Builder.defineMacro("_ARCH_PWR5");
146 if (ArchDefs & ArchDefinePwr5x)
147 Builder.defineMacro("_ARCH_PWR5X");
148 if (ArchDefs & ArchDefinePwr6)
149 Builder.defineMacro("_ARCH_PWR6");
150 if (ArchDefs & ArchDefinePwr6x)
151 Builder.defineMacro("_ARCH_PWR6X");
152 if (ArchDefs & ArchDefinePwr7)
153 Builder.defineMacro("_ARCH_PWR7");
154 if (ArchDefs & ArchDefinePwr8)
155 Builder.defineMacro("_ARCH_PWR8");
156 if (ArchDefs & ArchDefinePwr9)
157 Builder.defineMacro("_ARCH_PWR9");
158 if (ArchDefs & ArchDefinePwr10)
159 Builder.defineMacro("_ARCH_PWR10");
160 if (ArchDefs & ArchDefineA2)
161 Builder.defineMacro("_ARCH_A2");
162 if (ArchDefs & ArchDefineA2q) {
163 Builder.defineMacro("_ARCH_A2Q");
164 Builder.defineMacro("_ARCH_QP");
166 if (ArchDefs & ArchDefineE500)
167 Builder.defineMacro("__NO_LWSYNC__");
168 if (ArchDefs & ArchDefineFuture)
169 Builder.defineMacro("_ARCH_PWR_FUTURE");
171 if (getTriple().getVendor() == llvm::Triple::BGQ) {
172 Builder.defineMacro("__bg__");
173 Builder.defineMacro("__THW_BLUEGENE__");
174 Builder.defineMacro("__bgq__");
175 Builder.defineMacro("__TOS_BGQ__");
179 Builder.defineMacro("__VEC__", "10206");
180 Builder.defineMacro("__ALTIVEC__");
183 Builder.defineMacro("__SPE__");
184 Builder.defineMacro("__NO_FPRS__");
187 Builder.defineMacro("__VSX__");
189 Builder.defineMacro("__POWER8_VECTOR__");
191 Builder.defineMacro("__CRYPTO__");
193 Builder.defineMacro("__HTM__");
195 Builder.defineMacro("__FLOAT128__");
197 Builder.defineMacro("__POWER9_VECTOR__");
199 Builder.defineMacro("__POWER10_VECTOR__");
201 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
202 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
203 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
204 if (PointerWidth == 64)
205 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
207 // We have support for the bswap intrinsics so we can define this.
208 Builder.defineMacro("__HAVE_BSWAP__", "1");
210 // FIXME: The following are not yet generated here by Clang, but are
214 // __RECIP_PRECISION__
228 // Handle explicit options being passed to the compiler here: if we've
229 // explicitly turned off vsx and turned on any of:
235 // then go ahead and error since the customer has expressed an incompatible
237 static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
238 const std::vector<std::string> &FeaturesVec) {
240 // vsx was not explicitly turned off.
241 if (llvm::find(FeaturesVec, "-vsx") == FeaturesVec.end())
244 auto FindVSXSubfeature = [&](StringRef Feature, StringRef Option) {
245 if (llvm::find(FeaturesVec, Feature) != FeaturesVec.end()) {
246 Diags.Report(diag::err_opt_not_valid_with_opt) << Option << "-mno-vsx";
252 bool Found = FindVSXSubfeature("+power8-vector", "-mpower8-vector");
253 Found |= FindVSXSubfeature("+direct-move", "-mdirect-move");
254 Found |= FindVSXSubfeature("+float128", "-mfloat128");
255 Found |= FindVSXSubfeature("+power9-vector", "-mpower9-vector");
256 Found |= FindVSXSubfeature("+power10-vector", "-mpower10-vector");
258 // Return false if any vsx subfeatures was found.
262 bool PPCTargetInfo::initFeatureMap(
263 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
264 const std::vector<std::string> &FeaturesVec) const {
265 Features["altivec"] = llvm::StringSwitch<bool>(CPU)
277 .Case("ppc64le", true)
280 Features["qpx"] = (CPU == "a2q");
281 Features["power9-vector"] = (CPU == "pwr9");
282 Features["crypto"] = llvm::StringSwitch<bool>(CPU)
283 .Case("ppc64le", true)
287 Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)
288 .Case("ppc64le", true)
292 Features["bpermd"] = llvm::StringSwitch<bool>(CPU)
293 .Case("ppc64le", true)
298 Features["extdiv"] = llvm::StringSwitch<bool>(CPU)
299 .Case("ppc64le", true)
304 Features["direct-move"] = llvm::StringSwitch<bool>(CPU)
305 .Case("ppc64le", true)
309 Features["vsx"] = llvm::StringSwitch<bool>(CPU)
310 .Case("ppc64le", true)
315 Features["htm"] = llvm::StringSwitch<bool>(CPU)
316 .Case("ppc64le", true)
321 Features["spe"] = llvm::StringSwitch<bool>(CPU)
326 // Power10 includes all the same features as Power9 plus any features specific
327 // to the Power10 core.
328 if (CPU == "pwr10" || CPU == "power10") {
329 initFeatureMap(Features, Diags, "pwr9", FeaturesVec);
330 addP10SpecificFeatures(Features);
333 // Future CPU should include all of the features of Power 10 as well as any
334 // additional features (yet to be determined) specific to it.
335 if (CPU == "future") {
336 initFeatureMap(Features, Diags, "pwr10", FeaturesVec);
337 addFutureSpecificFeatures(Features);
340 if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
343 if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) &&
344 llvm::find(FeaturesVec, "+float128") != FeaturesVec.end()) {
345 // We have __float128 on PPC but not power 9 and above.
346 Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU;
350 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
353 // Add any Power10 specific features.
354 void PPCTargetInfo::addP10SpecificFeatures(
355 llvm::StringMap<bool> &Features) const {
356 Features["htm"] = false; // HTM was removed for P10.
357 Features["power10-vector"] = true;
358 Features["pcrelative-memops"] = true;
362 // Add features specific to the "Future" CPU.
363 void PPCTargetInfo::addFutureSpecificFeatures(
364 llvm::StringMap<bool> &Features) const {
368 bool PPCTargetInfo::hasFeature(StringRef Feature) const {
369 return llvm::StringSwitch<bool>(Feature)
370 .Case("powerpc", true)
371 .Case("altivec", HasAltivec)
373 .Case("power8-vector", HasP8Vector)
374 .Case("crypto", HasP8Crypto)
375 .Case("direct-move", HasDirectMove)
378 .Case("bpermd", HasBPERMD)
379 .Case("extdiv", HasExtDiv)
380 .Case("float128", HasFloat128)
381 .Case("power9-vector", HasP9Vector)
382 .Case("power10-vector", HasP10Vector)
383 .Case("pcrelative-memops", HasPCRelativeMemops)
388 void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
389 StringRef Name, bool Enabled) const {
391 // If we're enabling any of the vsx based features then enable vsx and
392 // altivec. We'll diagnose any problems later.
393 bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)
395 .Case("direct-move", true)
396 .Case("power8-vector", true)
397 .Case("power9-vector", true)
398 .Case("power10-vector", true)
399 .Case("float128", true)
402 Features["vsx"] = Features["altivec"] = true;
403 if (Name == "power9-vector")
404 Features["power8-vector"] = true;
405 else if (Name == "power10-vector")
406 Features["power8-vector"] = Features["power9-vector"] = true;
408 Features["pcrelative-memops"] = true;
410 Features[Name] = true;
412 // If we're disabling altivec or vsx go ahead and disable all of the vsx
414 if ((Name == "altivec") || (Name == "vsx"))
415 Features["vsx"] = Features["direct-move"] = Features["power8-vector"] =
416 Features["float128"] = Features["power9-vector"] =
417 Features["power10-vector"] = false;
418 if (Name == "power8-vector")
419 Features["power9-vector"] = Features["power10-vector"] = false;
420 else if (Name == "power9-vector")
421 Features["power10-vector"] = false;
423 Features["pcrelative-memops"] = false;
425 Features[Name] = false;
429 const char *const PPCTargetInfo::GCCRegNames[] = {
430 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
431 "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
432 "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
433 "r27", "r28", "r29", "r30", "r31", "f0", "f1", "f2", "f3",
434 "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12",
435 "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
436 "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30",
437 "f31", "mq", "lr", "ctr", "ap", "cr0", "cr1", "cr2", "cr3",
438 "cr4", "cr5", "cr6", "cr7", "xer", "v0", "v1", "v2", "v3",
439 "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12",
440 "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
441 "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30",
442 "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp"
445 ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {
446 return llvm::makeArrayRef(GCCRegNames);
449 const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
450 // While some of these aliases do map to different registers
451 // they still share the same register name.
452 {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"},
453 {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"},
454 {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"},
455 {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"},
456 {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"},
457 {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"},
458 {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"},
459 {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"},
460 {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"},
461 {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"},
462 {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"},
463 {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"},
464 {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"},
465 {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"},
466 {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"},
467 {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"},
471 ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
472 return llvm::makeArrayRef(GCCRegAliases);
475 // PPC ELFABIv2 DWARF Definitoin "Table 2.26. Mappings of Common Registers".
476 // vs0 ~ vs31 is mapping to 32 - 63,
477 // vs32 ~ vs63 is mapping to 77 - 108.
478 const TargetInfo::AddlRegName GCCAddlRegNames[] = {
479 // Table of additional register names to use in user input.
480 {{"vs0"}, 32}, {{"vs1"}, 33}, {{"vs2"}, 34}, {{"vs3"}, 35},
481 {{"vs4"}, 36}, {{"vs5"}, 37}, {{"vs6"}, 38}, {{"vs7"}, 39},
482 {{"vs8"}, 40}, {{"vs9"}, 41}, {{"vs10"}, 42}, {{"vs11"}, 43},
483 {{"vs12"}, 44}, {{"vs13"}, 45}, {{"vs14"}, 46}, {{"vs15"}, 47},
484 {{"vs16"}, 48}, {{"vs17"}, 49}, {{"vs18"}, 50}, {{"vs19"}, 51},
485 {{"vs20"}, 52}, {{"vs21"}, 53}, {{"vs22"}, 54}, {{"vs23"}, 55},
486 {{"vs24"}, 56}, {{"vs25"}, 57}, {{"vs26"}, 58}, {{"vs27"}, 59},
487 {{"vs28"}, 60}, {{"vs29"}, 61}, {{"vs30"}, 62}, {{"vs31"}, 63},
488 {{"vs32"}, 77}, {{"vs33"}, 78}, {{"vs34"}, 79}, {{"vs35"}, 80},
489 {{"vs36"}, 81}, {{"vs37"}, 82}, {{"vs38"}, 83}, {{"vs39"}, 84},
490 {{"vs40"}, 85}, {{"vs41"}, 86}, {{"vs42"}, 87}, {{"vs43"}, 88},
491 {{"vs44"}, 89}, {{"vs45"}, 90}, {{"vs46"}, 91}, {{"vs47"}, 92},
492 {{"vs48"}, 93}, {{"vs49"}, 94}, {{"vs50"}, 95}, {{"vs51"}, 96},
493 {{"vs52"}, 97}, {{"vs53"}, 98}, {{"vs54"}, 99}, {{"vs55"}, 100},
494 {{"vs56"}, 101}, {{"vs57"}, 102}, {{"vs58"}, 103}, {{"vs59"}, 104},
495 {{"vs60"}, 105}, {{"vs61"}, 106}, {{"vs62"}, 107}, {{"vs63"}, 108},
498 ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const {
500 return llvm::makeArrayRef(GCCAddlRegNames);
502 return TargetInfo::getGCCAddlRegNames();
505 static constexpr llvm::StringLiteral ValidCPUNames[] = {
506 {"generic"}, {"440"}, {"450"}, {"601"}, {"602"},
507 {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"},
508 {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"},
509 {"7450"}, {"g4+"}, {"750"}, {"8548"}, {"970"},
510 {"g5"}, {"a2"}, {"a2q"}, {"e500"}, {"e500mc"},
511 {"e5500"}, {"power3"}, {"pwr3"}, {"power4"}, {"pwr4"},
512 {"power5"}, {"pwr5"}, {"power5x"}, {"pwr5x"}, {"power6"},
513 {"pwr6"}, {"power6x"}, {"pwr6x"}, {"power7"}, {"pwr7"},
514 {"power8"}, {"pwr8"}, {"power9"}, {"pwr9"}, {"power10"},
515 {"pwr10"}, {"powerpc"}, {"ppc"}, {"powerpc64"}, {"ppc64"},
516 {"powerpc64le"}, {"ppc64le"}, {"future"}};
518 bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
519 return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
522 void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
523 Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
526 void PPCTargetInfo::adjust(LangOptions &Opts) {
529 TargetInfo::adjust(Opts);
530 if (LongDoubleFormat != &llvm::APFloat::IEEEdouble())
531 LongDoubleFormat = Opts.PPCIEEELongDouble
532 ? &llvm::APFloat::IEEEquad()
533 : &llvm::APFloat::PPCDoubleDouble();
536 ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
537 return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin -
538 Builtin::FirstTSBuiltin);