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