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