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