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