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