xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp (revision 6ba2210ee039f2f12878c217bcf058e9c8b26b29)
1 //===--- PPC.cpp - Implement PPC target feature support -------------------===//
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 PPC TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "PPC.h"
14 #include "clang/Basic/Diagnostic.h"
15 #include "clang/Basic/MacroBuilder.h"
16 #include "clang/Basic/TargetBuiltins.h"
17 
18 using namespace clang;
19 using namespace clang::targets;
20 
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"
27 };
28 
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) {
33   FloatABI = HardFloat;
34   for (const auto &Feature : Features) {
35     if (Feature == "+altivec") {
36       HasAltivec = true;
37     } else if (Feature == "+vsx") {
38       HasVSX = true;
39     } else if (Feature == "+bpermd") {
40       HasBPERMD = true;
41     } else if (Feature == "+extdiv") {
42       HasExtDiv = true;
43     } else if (Feature == "+power8-vector") {
44       HasP8Vector = true;
45     } else if (Feature == "+crypto") {
46       HasP8Crypto = true;
47     } else if (Feature == "+direct-move") {
48       HasDirectMove = true;
49     } else if (Feature == "+htm") {
50       HasHTM = true;
51     } else if (Feature == "+float128") {
52       HasFloat128 = true;
53     } else if (Feature == "+power9-vector") {
54       HasP9Vector = true;
55     } else if (Feature == "+power10-vector") {
56       HasP10Vector = true;
57     } else if (Feature == "+pcrelative-memops") {
58       HasPCRelativeMemops = true;
59     } else if (Feature == "+spe" || Feature == "+efpu2") {
60       HasStrictFP = false;
61       HasSPE = true;
62       LongDoubleWidth = LongDoubleAlign = 64;
63       LongDoubleFormat = &llvm::APFloat::IEEEdouble();
64     } else if (Feature == "-hard-float") {
65       FloatABI = SoftFloat;
66     } else if (Feature == "+paired-vector-memops") {
67       PairedVectorMemops = true;
68     } else if (Feature == "+mma") {
69       HasMMA = true;
70     }
71     // TODO: Finish this list and add an assert that we've handled them
72     // all.
73   }
74 
75   return true;
76 }
77 
78 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
79 /// #defines that are not tied to a specific subtarget.
80 void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
81                                      MacroBuilder &Builder) const {
82   // Target identification.
83   Builder.defineMacro("__ppc__");
84   Builder.defineMacro("__PPC__");
85   Builder.defineMacro("_ARCH_PPC");
86   Builder.defineMacro("__powerpc__");
87   Builder.defineMacro("__POWERPC__");
88   if (PointerWidth == 64) {
89     Builder.defineMacro("_ARCH_PPC64");
90     Builder.defineMacro("__powerpc64__");
91     Builder.defineMacro("__ppc64__");
92     Builder.defineMacro("__PPC64__");
93   }
94 
95   // Target properties.
96   if (getTriple().getArch() == llvm::Triple::ppc64le ||
97       getTriple().getArch() == llvm::Triple::ppcle) {
98     Builder.defineMacro("_LITTLE_ENDIAN");
99   } else {
100     if (!getTriple().isOSNetBSD() &&
101         !getTriple().isOSOpenBSD())
102       Builder.defineMacro("_BIG_ENDIAN");
103   }
104 
105   // ABI options.
106   if (ABI == "elfv1")
107     Builder.defineMacro("_CALL_ELF", "1");
108   if (ABI == "elfv2")
109     Builder.defineMacro("_CALL_ELF", "2");
110 
111   // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but
112   // our support post-dates this and it should work on all 64-bit ppc linux
113   // platforms. It is guaranteed to work on all elfv2 platforms.
114   if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64)
115     Builder.defineMacro("_CALL_LINUX", "1");
116 
117   // Subtarget options.
118   if (!getTriple().isOSAIX()){
119     Builder.defineMacro("__NATURAL_ALIGNMENT__");
120   }
121   Builder.defineMacro("__REGISTER_PREFIX__", "");
122 
123   // FIXME: Should be controlled by command line option.
124   if (LongDoubleWidth == 128) {
125     Builder.defineMacro("__LONG_DOUBLE_128__");
126     Builder.defineMacro("__LONGDOUBLE128");
127     if (Opts.PPCIEEELongDouble)
128       Builder.defineMacro("__LONG_DOUBLE_IEEE128__");
129     else
130       Builder.defineMacro("__LONG_DOUBLE_IBM128__");
131   }
132 
133   // Define this for elfv2 (64-bit only) or 64-bit darwin.
134   if (ABI == "elfv2" ||
135       (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64))
136     Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");
137 
138   if (ArchDefs & ArchDefineName)
139     Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
140   if (ArchDefs & ArchDefinePpcgr)
141     Builder.defineMacro("_ARCH_PPCGR");
142   if (ArchDefs & ArchDefinePpcsq)
143     Builder.defineMacro("_ARCH_PPCSQ");
144   if (ArchDefs & ArchDefine440)
145     Builder.defineMacro("_ARCH_440");
146   if (ArchDefs & ArchDefine603)
147     Builder.defineMacro("_ARCH_603");
148   if (ArchDefs & ArchDefine604)
149     Builder.defineMacro("_ARCH_604");
150   if (ArchDefs & ArchDefinePwr4)
151     Builder.defineMacro("_ARCH_PWR4");
152   if (ArchDefs & ArchDefinePwr5)
153     Builder.defineMacro("_ARCH_PWR5");
154   if (ArchDefs & ArchDefinePwr5x)
155     Builder.defineMacro("_ARCH_PWR5X");
156   if (ArchDefs & ArchDefinePwr6)
157     Builder.defineMacro("_ARCH_PWR6");
158   if (ArchDefs & ArchDefinePwr6x)
159     Builder.defineMacro("_ARCH_PWR6X");
160   if (ArchDefs & ArchDefinePwr7)
161     Builder.defineMacro("_ARCH_PWR7");
162   if (ArchDefs & ArchDefinePwr8)
163     Builder.defineMacro("_ARCH_PWR8");
164   if (ArchDefs & ArchDefinePwr9)
165     Builder.defineMacro("_ARCH_PWR9");
166   if (ArchDefs & ArchDefinePwr10)
167     Builder.defineMacro("_ARCH_PWR10");
168   if (ArchDefs & ArchDefineA2)
169     Builder.defineMacro("_ARCH_A2");
170   if (ArchDefs & ArchDefineE500)
171     Builder.defineMacro("__NO_LWSYNC__");
172   if (ArchDefs & ArchDefineFuture)
173     Builder.defineMacro("_ARCH_PWR_FUTURE");
174 
175   if (HasAltivec) {
176     Builder.defineMacro("__VEC__", "10206");
177     Builder.defineMacro("__ALTIVEC__");
178   }
179   if (HasSPE) {
180     Builder.defineMacro("__SPE__");
181     Builder.defineMacro("__NO_FPRS__");
182   }
183   if (HasVSX)
184     Builder.defineMacro("__VSX__");
185   if (HasP8Vector)
186     Builder.defineMacro("__POWER8_VECTOR__");
187   if (HasP8Crypto)
188     Builder.defineMacro("__CRYPTO__");
189   if (HasHTM)
190     Builder.defineMacro("__HTM__");
191   if (HasFloat128)
192     Builder.defineMacro("__FLOAT128__");
193   if (HasP9Vector)
194     Builder.defineMacro("__POWER9_VECTOR__");
195   if (HasMMA)
196     Builder.defineMacro("__MMA__");
197   if (HasP10Vector)
198     Builder.defineMacro("__POWER10_VECTOR__");
199 
200   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
201   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
202   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
203   if (PointerWidth == 64)
204     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
205 
206   // We have support for the bswap intrinsics so we can define this.
207   Builder.defineMacro("__HAVE_BSWAP__", "1");
208 
209   // FIXME: The following are not yet generated here by Clang, but are
210   //        generated by GCC:
211   //
212   //   _SOFT_FLOAT_
213   //   __RECIP_PRECISION__
214   //   __APPLE_ALTIVEC__
215   //   __RECIP__
216   //   __RECIPF__
217   //   __RSQRTE__
218   //   __RSQRTEF__
219   //   _SOFT_DOUBLE_
220   //   __NO_LWSYNC__
221   //   __CMODEL_MEDIUM__
222   //   __CMODEL_LARGE__
223   //   _CALL_SYSV
224   //   _CALL_DARWIN
225 }
226 
227 // Handle explicit options being passed to the compiler here: if we've
228 // explicitly turned off vsx and turned on any of:
229 // - power8-vector
230 // - direct-move
231 // - float128
232 // - power9-vector
233 // - paired-vector-memops
234 // - mma
235 // - power10-vector
236 // then go ahead and error since the customer has expressed an incompatible
237 // set of options.
238 static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
239                                  const std::vector<std::string> &FeaturesVec) {
240 
241   // vsx was not explicitly turned off.
242   if (llvm::find(FeaturesVec, "-vsx") == FeaturesVec.end())
243     return true;
244 
245   auto FindVSXSubfeature = [&](StringRef Feature, StringRef Option) {
246     if (llvm::find(FeaturesVec, Feature) != FeaturesVec.end()) {
247       Diags.Report(diag::err_opt_not_valid_with_opt) << Option << "-mno-vsx";
248       return true;
249     }
250     return false;
251   };
252 
253   bool Found = FindVSXSubfeature("+power8-vector", "-mpower8-vector");
254   Found |= FindVSXSubfeature("+direct-move", "-mdirect-move");
255   Found |= FindVSXSubfeature("+float128", "-mfloat128");
256   Found |= FindVSXSubfeature("+power9-vector", "-mpower9-vector");
257   Found |= FindVSXSubfeature("+paired-vector-memops", "-mpaired-vector-memops");
258   Found |= FindVSXSubfeature("+mma", "-mmma");
259   Found |= FindVSXSubfeature("+power10-vector", "-mpower10-vector");
260 
261   // Return false if any vsx subfeatures was found.
262   return !Found;
263 }
264 
265 bool PPCTargetInfo::initFeatureMap(
266     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
267     const std::vector<std::string> &FeaturesVec) const {
268   Features["altivec"] = llvm::StringSwitch<bool>(CPU)
269                             .Case("7400", true)
270                             .Case("g4", true)
271                             .Case("7450", true)
272                             .Case("g4+", true)
273                             .Case("970", true)
274                             .Case("g5", true)
275                             .Case("pwr6", true)
276                             .Case("pwr7", true)
277                             .Case("pwr8", true)
278                             .Case("pwr9", true)
279                             .Case("ppc64", true)
280                             .Case("ppc64le", true)
281                             .Default(false);
282 
283   Features["power9-vector"] = (CPU == "pwr9");
284   Features["crypto"] = llvm::StringSwitch<bool>(CPU)
285                            .Case("ppc64le", true)
286                            .Case("pwr9", true)
287                            .Case("pwr8", true)
288                            .Default(false);
289   Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)
290                                   .Case("ppc64le", true)
291                                   .Case("pwr9", true)
292                                   .Case("pwr8", true)
293                                   .Default(false);
294   Features["bpermd"] = llvm::StringSwitch<bool>(CPU)
295                            .Case("ppc64le", true)
296                            .Case("pwr9", true)
297                            .Case("pwr8", true)
298                            .Case("pwr7", true)
299                            .Default(false);
300   Features["extdiv"] = llvm::StringSwitch<bool>(CPU)
301                            .Case("ppc64le", true)
302                            .Case("pwr9", true)
303                            .Case("pwr8", true)
304                            .Case("pwr7", true)
305                            .Default(false);
306   Features["direct-move"] = llvm::StringSwitch<bool>(CPU)
307                                 .Case("ppc64le", true)
308                                 .Case("pwr9", true)
309                                 .Case("pwr8", true)
310                                 .Default(false);
311   Features["vsx"] = llvm::StringSwitch<bool>(CPU)
312                         .Case("ppc64le", true)
313                         .Case("pwr9", true)
314                         .Case("pwr8", true)
315                         .Case("pwr7", true)
316                         .Default(false);
317   Features["htm"] = llvm::StringSwitch<bool>(CPU)
318                         .Case("ppc64le", true)
319                         .Case("pwr9", true)
320                         .Case("pwr8", true)
321                         .Default(false);
322 
323   Features["spe"] = llvm::StringSwitch<bool>(CPU)
324                         .Case("8548", true)
325                         .Case("e500", true)
326                         .Default(false);
327 
328   // Power10 includes all the same features as Power9 plus any features specific
329   // to the Power10 core.
330   if (CPU == "pwr10" || CPU == "power10") {
331     initFeatureMap(Features, Diags, "pwr9", FeaturesVec);
332     addP10SpecificFeatures(Features);
333   }
334 
335   // Future CPU should include all of the features of Power 10 as well as any
336   // additional features (yet to be determined) specific to it.
337   if (CPU == "future") {
338     initFeatureMap(Features, Diags, "pwr10", FeaturesVec);
339     addFutureSpecificFeatures(Features);
340   }
341 
342   if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
343     return false;
344 
345   if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) &&
346       llvm::find(FeaturesVec, "+float128") != FeaturesVec.end()) {
347     // We have __float128 on PPC but not power 9 and above.
348     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU;
349     return false;
350   }
351 
352   if (!(ArchDefs & ArchDefinePwr10) &&
353       llvm::find(FeaturesVec, "+mma") != FeaturesVec.end()) {
354     // We have MMA on PPC but not power 10 and above.
355     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU;
356     return false;
357   }
358 
359   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
360 }
361 
362 // Add any Power10 specific features.
363 void PPCTargetInfo::addP10SpecificFeatures(
364     llvm::StringMap<bool> &Features) const {
365   Features["htm"] = false; // HTM was removed for P10.
366   Features["paired-vector-memops"] = true;
367   Features["mma"] = true;
368   Features["power10-vector"] = true;
369   Features["pcrelative-memops"] = true;
370   return;
371 }
372 
373 // Add features specific to the "Future" CPU.
374 void PPCTargetInfo::addFutureSpecificFeatures(
375     llvm::StringMap<bool> &Features) const {
376   return;
377 }
378 
379 bool PPCTargetInfo::hasFeature(StringRef Feature) const {
380   return llvm::StringSwitch<bool>(Feature)
381       .Case("powerpc", true)
382       .Case("altivec", HasAltivec)
383       .Case("vsx", HasVSX)
384       .Case("power8-vector", HasP8Vector)
385       .Case("crypto", HasP8Crypto)
386       .Case("direct-move", HasDirectMove)
387       .Case("htm", HasHTM)
388       .Case("bpermd", HasBPERMD)
389       .Case("extdiv", HasExtDiv)
390       .Case("float128", HasFloat128)
391       .Case("power9-vector", HasP9Vector)
392       .Case("paired-vector-memops", PairedVectorMemops)
393       .Case("power10-vector", HasP10Vector)
394       .Case("pcrelative-memops", HasPCRelativeMemops)
395       .Case("spe", HasSPE)
396       .Case("mma", HasMMA)
397       .Default(false);
398 }
399 
400 void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
401                                       StringRef Name, bool Enabled) const {
402   if (Enabled) {
403     if (Name == "efpu2")
404       Features["spe"] = true;
405     // If we're enabling any of the vsx based features then enable vsx and
406     // altivec. We'll diagnose any problems later.
407     bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)
408                              .Case("vsx", true)
409                              .Case("direct-move", true)
410                              .Case("power8-vector", true)
411                              .Case("power9-vector", true)
412                              .Case("paired-vector-memops", true)
413                              .Case("power10-vector", true)
414                              .Case("float128", true)
415                              .Case("mma", true)
416                              .Default(false);
417     if (FeatureHasVSX)
418       Features["vsx"] = Features["altivec"] = true;
419     if (Name == "power9-vector")
420       Features["power8-vector"] = true;
421     else if (Name == "power10-vector")
422       Features["power8-vector"] = Features["power9-vector"] = true;
423     if (Name == "pcrel")
424       Features["pcrelative-memops"] = true;
425     else
426       Features[Name] = true;
427   } else {
428     if (Name == "spe")
429       Features["efpu2"] = false;
430     // If we're disabling altivec or vsx go ahead and disable all of the vsx
431     // features.
432     if ((Name == "altivec") || (Name == "vsx"))
433       Features["vsx"] = Features["direct-move"] = Features["power8-vector"] =
434           Features["float128"] = Features["power9-vector"] =
435               Features["paired-vector-memops"] = Features["mma"] =
436                   Features["power10-vector"] = false;
437     if (Name == "power8-vector")
438       Features["power9-vector"] = Features["paired-vector-memops"] =
439           Features["mma"] = Features["power10-vector"] = false;
440     else if (Name == "power9-vector")
441       Features["paired-vector-memops"] = Features["mma"] =
442           Features["power10-vector"] = false;
443     if (Name == "pcrel")
444       Features["pcrelative-memops"] = false;
445     else
446       Features[Name] = false;
447   }
448 }
449 
450 const char *const PPCTargetInfo::GCCRegNames[] = {
451     "r0",  "r1",     "r2",   "r3",      "r4",      "r5",  "r6",  "r7",  "r8",
452     "r9",  "r10",    "r11",  "r12",     "r13",     "r14", "r15", "r16", "r17",
453     "r18", "r19",    "r20",  "r21",     "r22",     "r23", "r24", "r25", "r26",
454     "r27", "r28",    "r29",  "r30",     "r31",     "f0",  "f1",  "f2",  "f3",
455     "f4",  "f5",     "f6",   "f7",      "f8",      "f9",  "f10", "f11", "f12",
456     "f13", "f14",    "f15",  "f16",     "f17",     "f18", "f19", "f20", "f21",
457     "f22", "f23",    "f24",  "f25",     "f26",     "f27", "f28", "f29", "f30",
458     "f31", "mq",     "lr",   "ctr",     "ap",      "cr0", "cr1", "cr2", "cr3",
459     "cr4", "cr5",    "cr6",  "cr7",     "xer",     "v0",  "v1",  "v2",  "v3",
460     "v4",  "v5",     "v6",   "v7",      "v8",      "v9",  "v10", "v11", "v12",
461     "v13", "v14",    "v15",  "v16",     "v17",     "v18", "v19", "v20", "v21",
462     "v22", "v23",    "v24",  "v25",     "v26",     "v27", "v28", "v29", "v30",
463     "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp"
464 };
465 
466 ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {
467   return llvm::makeArrayRef(GCCRegNames);
468 }
469 
470 const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
471     // While some of these aliases do map to different registers
472     // they still share the same register name.
473     {{"0"}, "r0"},     {{"1"}, "r1"},     {{"2"}, "r2"},     {{"3"}, "r3"},
474     {{"4"}, "r4"},     {{"5"}, "r5"},     {{"6"}, "r6"},     {{"7"}, "r7"},
475     {{"8"}, "r8"},     {{"9"}, "r9"},     {{"10"}, "r10"},   {{"11"}, "r11"},
476     {{"12"}, "r12"},   {{"13"}, "r13"},   {{"14"}, "r14"},   {{"15"}, "r15"},
477     {{"16"}, "r16"},   {{"17"}, "r17"},   {{"18"}, "r18"},   {{"19"}, "r19"},
478     {{"20"}, "r20"},   {{"21"}, "r21"},   {{"22"}, "r22"},   {{"23"}, "r23"},
479     {{"24"}, "r24"},   {{"25"}, "r25"},   {{"26"}, "r26"},   {{"27"}, "r27"},
480     {{"28"}, "r28"},   {{"29"}, "r29"},   {{"30"}, "r30"},   {{"31"}, "r31"},
481     {{"fr0"}, "f0"},   {{"fr1"}, "f1"},   {{"fr2"}, "f2"},   {{"fr3"}, "f3"},
482     {{"fr4"}, "f4"},   {{"fr5"}, "f5"},   {{"fr6"}, "f6"},   {{"fr7"}, "f7"},
483     {{"fr8"}, "f8"},   {{"fr9"}, "f9"},   {{"fr10"}, "f10"}, {{"fr11"}, "f11"},
484     {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"},
485     {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"},
486     {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"},
487     {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"},
488     {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"},
489     {{"cc"}, "cr0"},
490 };
491 
492 ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
493   return llvm::makeArrayRef(GCCRegAliases);
494 }
495 
496 // PPC ELFABIv2 DWARF Definitoin "Table 2.26. Mappings of Common Registers".
497 // vs0 ~ vs31 is mapping to 32 - 63,
498 // vs32 ~ vs63 is mapping to 77 - 108.
499 const TargetInfo::AddlRegName GCCAddlRegNames[] = {
500     // Table of additional register names to use in user input.
501     {{"vs0"}, 32},   {{"vs1"}, 33},   {{"vs2"}, 34},   {{"vs3"}, 35},
502     {{"vs4"}, 36},   {{"vs5"}, 37},   {{"vs6"}, 38},   {{"vs7"}, 39},
503     {{"vs8"}, 40},   {{"vs9"}, 41},   {{"vs10"}, 42},  {{"vs11"}, 43},
504     {{"vs12"}, 44},  {{"vs13"}, 45},  {{"vs14"}, 46},  {{"vs15"}, 47},
505     {{"vs16"}, 48},  {{"vs17"}, 49},  {{"vs18"}, 50},  {{"vs19"}, 51},
506     {{"vs20"}, 52},  {{"vs21"}, 53},  {{"vs22"}, 54},  {{"vs23"}, 55},
507     {{"vs24"}, 56},  {{"vs25"}, 57},  {{"vs26"}, 58},  {{"vs27"}, 59},
508     {{"vs28"}, 60},  {{"vs29"}, 61},  {{"vs30"}, 62},  {{"vs31"}, 63},
509     {{"vs32"}, 77},  {{"vs33"}, 78},  {{"vs34"}, 79},  {{"vs35"}, 80},
510     {{"vs36"}, 81},  {{"vs37"}, 82},  {{"vs38"}, 83},  {{"vs39"}, 84},
511     {{"vs40"}, 85},  {{"vs41"}, 86},  {{"vs42"}, 87},  {{"vs43"}, 88},
512     {{"vs44"}, 89},  {{"vs45"}, 90},  {{"vs46"}, 91},  {{"vs47"}, 92},
513     {{"vs48"}, 93},  {{"vs49"}, 94},  {{"vs50"}, 95},  {{"vs51"}, 96},
514     {{"vs52"}, 97},  {{"vs53"}, 98},  {{"vs54"}, 99},  {{"vs55"}, 100},
515     {{"vs56"}, 101}, {{"vs57"}, 102}, {{"vs58"}, 103}, {{"vs59"}, 104},
516     {{"vs60"}, 105}, {{"vs61"}, 106}, {{"vs62"}, 107}, {{"vs63"}, 108},
517 };
518 
519 ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const {
520   if (ABI == "elfv2")
521     return llvm::makeArrayRef(GCCAddlRegNames);
522   else
523     return TargetInfo::getGCCAddlRegNames();
524 }
525 
526 static constexpr llvm::StringLiteral ValidCPUNames[] = {
527     {"generic"}, {"440"},     {"450"},       {"601"},     {"602"},
528     {"603"},     {"603e"},    {"603ev"},     {"604"},     {"604e"},
529     {"620"},     {"630"},     {"g3"},        {"7400"},    {"g4"},
530     {"7450"},    {"g4+"},     {"750"},       {"8548"},    {"970"},
531     {"g5"},      {"a2"},      {"e500"},      {"e500mc"},  {"e5500"},
532     {"power3"},  {"pwr3"},    {"power4"},    {"pwr4"},    {"power5"},
533     {"pwr5"},    {"power5x"}, {"pwr5x"},     {"power6"},  {"pwr6"},
534     {"power6x"}, {"pwr6x"},   {"power7"},    {"pwr7"},    {"power8"},
535     {"pwr8"},    {"power9"},  {"pwr9"},      {"power10"}, {"pwr10"},
536     {"powerpc"}, {"ppc"},     {"powerpc64"}, {"ppc64"},   {"powerpc64le"},
537     {"ppc64le"}, {"future"}};
538 
539 bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
540   return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
541 }
542 
543 void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
544   Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
545 }
546 
547 void PPCTargetInfo::adjust(LangOptions &Opts) {
548   if (HasAltivec)
549     Opts.AltiVec = 1;
550   TargetInfo::adjust(Opts);
551   if (LongDoubleFormat != &llvm::APFloat::IEEEdouble())
552     LongDoubleFormat = Opts.PPCIEEELongDouble
553                            ? &llvm::APFloat::IEEEquad()
554                            : &llvm::APFloat::PPCDoubleDouble();
555 }
556 
557 ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
558   return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin -
559                                              Builtin::FirstTSBuiltin);
560 }
561