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