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