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