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