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