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