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