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