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