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