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