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