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