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