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