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