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