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