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