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