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