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