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