xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
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 #include "llvm/TargetParser/PPCTargetParser.h"
18 #include <optional>
19 
20 using namespace clang;
21 using namespace clang::targets;
22 
23 static constexpr int NumBuiltins =
24     clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin;
25 
26 static constexpr llvm::StringTable BuiltinStrings =
27     CLANG_BUILTIN_STR_TABLE_START
28 #define BUILTIN CLANG_BUILTIN_STR_TABLE
29 #define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
30 #include "clang/Basic/BuiltinsPPC.def"
31     ;
32 
33 static constexpr auto BuiltinInfos = Builtin::MakeInfos<NumBuiltins>({
34 #define BUILTIN CLANG_BUILTIN_ENTRY
35 #define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
36 #define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
37 #include "clang/Basic/BuiltinsPPC.def"
38 });
39 
40 /// handleTargetFeatures - Perform initialization based on the user
41 /// configured set of features.
42 bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
43                                          DiagnosticsEngine &Diags) {
44   FloatABI = HardFloat;
45   for (const auto &Feature : Features) {
46     if (Feature == "+altivec") {
47       HasAltivec = true;
48     } else if (Feature == "+vsx") {
49       HasVSX = true;
50     } else if (Feature == "+power8-vector") {
51       HasP8Vector = true;
52     } else if (Feature == "+crypto") {
53       HasP8Crypto = true;
54     } else if (Feature == "+htm") {
55       HasHTM = true;
56     } else if (Feature == "+float128") {
57       HasFloat128 = !getTriple().isOSAIX();
58     } else if (Feature == "+power9-vector") {
59       HasP9Vector = true;
60     } else if (Feature == "+power10-vector") {
61       HasP10Vector = true;
62     } else if (Feature == "+pcrelative-memops") {
63       HasPCRelativeMemops = true;
64     } else if (Feature == "+spe" || Feature == "+efpu2") {
65       HasStrictFP = false;
66       HasSPE = true;
67       LongDoubleWidth = LongDoubleAlign = 64;
68       LongDoubleFormat = &llvm::APFloat::IEEEdouble();
69     } else if (Feature == "+frsqrte") {
70       HasFrsqrte = true;
71     } else if (Feature == "+frsqrtes") {
72       HasFrsqrtes = true;
73     } else if (Feature == "-hard-float") {
74       FloatABI = SoftFloat;
75     } else if (Feature == "+mma") {
76       HasMMA = true;
77     } else if (Feature == "+rop-protect") {
78       HasROPProtect = true;
79     } else if (Feature == "+quadword-atomics") {
80       HasQuadwordAtomics = true;
81     } else if (Feature == "+longcall") {
82       UseLongCalls = true;
83     }
84     // TODO: Finish this list and add an assert that we've handled them
85     // all.
86   }
87 
88   return true;
89 }
90 
91 static void defineXLCompatMacros(MacroBuilder &Builder) {
92   Builder.defineMacro("__builtin_national2packed",
93                       "__builtin_ppc_national2packed");
94   Builder.defineMacro("__builtin_packed2national",
95                       "__builtin_ppc_packed2national");
96   Builder.defineMacro("__builtin_packed2zoned", "__builtin_ppc_packed2zoned");
97   Builder.defineMacro("__builtin_zoned2packed", "__builtin_ppc_zoned2packed");
98   Builder.defineMacro("__cdtbcd", "__builtin_ppc_cdtbcd");
99   Builder.defineMacro("__cbcdtd", "__builtin_ppc_cbcdtd");
100   Builder.defineMacro("__addg6s", "__builtin_ppc_addg6s");
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 & ArchDefinePwr11)
383     Builder.defineMacro("_ARCH_PWR11");
384   if (ArchDefs & ArchDefineA2)
385     Builder.defineMacro("_ARCH_A2");
386   if (ArchDefs & ArchDefineE500)
387     Builder.defineMacro("__NO_LWSYNC__");
388   if (ArchDefs & ArchDefineFuture)
389     Builder.defineMacro("_ARCH_PWR_FUTURE");
390 
391   if (HasAltivec) {
392     Builder.defineMacro("__VEC__", "10206");
393     Builder.defineMacro("__ALTIVEC__");
394   }
395   if (HasSPE)
396     Builder.defineMacro("__SPE__");
397   if (HasSPE || FloatABI == SoftFloat)
398     Builder.defineMacro("__NO_FPRS__");
399   if (FloatABI == SoftFloat) {
400     Builder.defineMacro("_SOFT_FLOAT");
401     Builder.defineMacro("_SOFT_DOUBLE");
402   } else {
403     if (HasFrsqrte)
404       Builder.defineMacro("__RSQRTE__");
405     if (HasFrsqrtes)
406       Builder.defineMacro("__RSQRTEF__");
407   }
408   if (HasVSX)
409     Builder.defineMacro("__VSX__");
410   if (HasP8Vector)
411     Builder.defineMacro("__POWER8_VECTOR__");
412   if (HasP8Crypto)
413     Builder.defineMacro("__CRYPTO__");
414   if (HasHTM)
415     Builder.defineMacro("__HTM__");
416   if (HasFloat128)
417     Builder.defineMacro("__FLOAT128__");
418   if (HasP9Vector)
419     Builder.defineMacro("__POWER9_VECTOR__");
420   if (HasMMA)
421     Builder.defineMacro("__MMA__");
422   if (HasROPProtect)
423     Builder.defineMacro("__ROP_PROTECT__");
424   if (HasP10Vector)
425     Builder.defineMacro("__POWER10_VECTOR__");
426   if (HasPCRelativeMemops)
427     Builder.defineMacro("__PCREL__");
428 
429   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
430   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
431   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
432   if (PointerWidth == 64)
433     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
434 
435   // We have support for the bswap intrinsics so we can define this.
436   Builder.defineMacro("__HAVE_BSWAP__", "1");
437 
438   // FIXME: The following are not yet generated here by Clang, but are
439   //        generated by GCC:
440   //
441   //   __RECIP_PRECISION__
442   //   __APPLE_ALTIVEC__
443   //   __RECIP__
444   //   __RECIPF__
445   //   __NO_LWSYNC__
446   //   __CMODEL_MEDIUM__
447   //   __CMODEL_LARGE__
448   //   _CALL_SYSV
449   //   _CALL_DARWIN
450 }
451 
452 // Handle explicit options being passed to the compiler here:
453 // - if we've explicitly turned off vsx and turned on any of:
454 //   - power8-vector
455 //   - direct-move
456 //   - float128
457 //   - power9-vector
458 //   - paired-vector-memops
459 //   - mma
460 //   - power10-vector
461 // - if we've explicitly turned on vsx and turned off altivec.
462 // - if we've explicitly turned off hard-float and turned on altivec.
463 // then go ahead and error since the customer has expressed an incompatible
464 // set of options.
465 static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
466                                  const std::vector<std::string> &FeaturesVec) {
467   auto FindVSXSubfeature = [&](StringRef Feature, StringRef SubOption,
468                                StringRef Option) {
469     if (llvm::is_contained(FeaturesVec, Feature)) {
470       Diags.Report(diag::err_opt_not_valid_with_opt) << SubOption << Option;
471       return true;
472     }
473     return false;
474   };
475 
476   // Cannot allow soft-float with VSX, Altivec, or any
477   // VSX subfeatures.
478   bool Found = false;
479   if (llvm::is_contained(FeaturesVec, "-hard-float")) {
480     Found |= FindVSXSubfeature("+vsx", "-mvsx", "-msoft-float");
481     Found |= FindVSXSubfeature("+altivec", "-maltivec", "-msoft-float");
482     Found |=
483         FindVSXSubfeature("+power8-vector", "-mpower8-vector", "-msoft-float");
484     Found |= FindVSXSubfeature("+direct-move", "-mdirect-move", "-msoft-float");
485     Found |= FindVSXSubfeature("+float128", "-mfloat128", "-msoft-float");
486     Found |=
487         FindVSXSubfeature("+power9-vector", "-mpower9-vector", "-msoft-float");
488     Found |= FindVSXSubfeature("+paired-vector-memops",
489                                "-mpaired-vector-memops", "-msoft-float");
490     Found |= FindVSXSubfeature("+mma", "-mmma", "-msoft-float");
491     Found |= FindVSXSubfeature("+crypto", "-mcrypto", "-msoft-float");
492     Found |= FindVSXSubfeature("+power10-vector", "-mpower10-vector",
493                                "-msoft-float");
494   }
495   if (Found)
496     return false;
497 
498   // Cannot allow VSX with no Altivec.
499   if (llvm::is_contained(FeaturesVec, "+vsx") &&
500       llvm::is_contained(FeaturesVec, "-altivec")) {
501     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mvsx"
502                                                    << "-mno-altivec";
503     return false;
504   }
505 
506   // vsx was not explicitly turned off.
507   if (!llvm::is_contained(FeaturesVec, "-vsx"))
508     return true;
509 
510   Found = FindVSXSubfeature("+power8-vector", "-mpower8-vector", "-mno-vsx");
511   Found |= FindVSXSubfeature("+direct-move", "-mdirect-move", "-mno-vsx");
512   Found |= FindVSXSubfeature("+float128", "-mfloat128", "-mno-vsx");
513   Found |= FindVSXSubfeature("+power9-vector", "-mpower9-vector", "-mno-vsx");
514   Found |= FindVSXSubfeature("+paired-vector-memops", "-mpaired-vector-memops",
515                              "-mno-vsx");
516   Found |= FindVSXSubfeature("+mma", "-mmma", "-mno-vsx");
517   Found |= FindVSXSubfeature("+power10-vector", "-mpower10-vector", "-mno-vsx");
518 
519   // Return false if any vsx subfeatures was found.
520   return !Found;
521 }
522 
523 bool PPCTargetInfo::initFeatureMap(
524     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
525     const std::vector<std::string> &FeaturesVec) const {
526 
527   const llvm::Triple &TheTriple = getTriple();
528 
529   std::optional<llvm::StringMap<bool>> FeaturesOpt =
530       llvm::PPC::getPPCDefaultTargetFeatures(TheTriple,
531                                              llvm::PPC::normalizeCPUName(CPU));
532   if (FeaturesOpt)
533     Features = FeaturesOpt.value();
534 
535   if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
536     return false;
537 
538   if (!(ArchDefs & ArchDefinePwr7) && (ArchDefs & ArchDefinePpcgr) &&
539       llvm::is_contained(FeaturesVec, "+float128")) {
540     // We have __float128 on PPC but not pre-VSX targets.
541     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU;
542     return false;
543   }
544 
545   if (!(ArchDefs & ArchDefinePwr10)) {
546     if (llvm::is_contained(FeaturesVec, "+mma")) {
547       // MMA operations are not available pre-Power10.
548       Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU;
549       return false;
550     }
551     if (llvm::is_contained(FeaturesVec, "+pcrel")) {
552       // PC-Relative instructions are not available pre-Power10,
553       // and these instructions also require prefixed instructions support.
554       Diags.Report(diag::err_opt_not_valid_without_opt)
555           << "-mpcrel"
556           << "-mcpu=pwr10 -mprefixed";
557       return false;
558     }
559     if (llvm::is_contained(FeaturesVec, "+prefixed")) {
560       // Prefixed instructions are not available pre-Power10.
561       Diags.Report(diag::err_opt_not_valid_without_opt) << "-mprefixed"
562                                                         << "-mcpu=pwr10";
563       return false;
564     }
565     if (llvm::is_contained(FeaturesVec, "+paired-vector-memops")) {
566       // Paired vector memops are not available pre-Power10.
567       Diags.Report(diag::err_opt_not_valid_without_opt)
568           << "-mpaired-vector-memops"
569           << "-mcpu=pwr10";
570       return false;
571     }
572   }
573 
574   if (llvm::is_contained(FeaturesVec, "+rop-protect")) {
575     if (PointerWidth == 32) {
576       Diags.Report(diag::err_opt_not_valid_on_target) << "-mrop-protect";
577       return false;
578     }
579 
580     if (!(ArchDefs & ArchDefinePwr8)) {
581       // We can turn on ROP Protect on Power 8 and above.
582       Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protect" << CPU;
583       return false;
584     }
585   }
586 
587   if (!(ArchDefs & ArchDefinePwr8) &&
588       llvm::is_contained(FeaturesVec, "+privileged")) {
589     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mprivileged" << CPU;
590     return false;
591   }
592   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
593 }
594 
595 bool PPCTargetInfo::hasFeature(StringRef Feature) const {
596   return llvm::StringSwitch<bool>(Feature)
597       .Case("powerpc", true)
598       .Case("altivec", HasAltivec)
599       .Case("vsx", HasVSX)
600       .Case("power8-vector", HasP8Vector)
601       .Case("crypto", HasP8Crypto)
602       .Case("htm", HasHTM)
603       .Case("float128", HasFloat128)
604       .Case("power9-vector", HasP9Vector)
605       .Case("power10-vector", HasP10Vector)
606       .Case("pcrelative-memops", HasPCRelativeMemops)
607       .Case("spe", HasSPE)
608       .Case("mma", HasMMA)
609       .Case("rop-protect", HasROPProtect)
610       .Case("quadword-atomics", HasQuadwordAtomics)
611       .Case("longcall", UseLongCalls)
612       .Default(false);
613 }
614 
615 void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
616                                       StringRef Name, bool Enabled) const {
617   if (Enabled) {
618     if (Name == "efpu2")
619       Features["spe"] = true;
620     // If we're enabling any of the vsx based features then enable vsx and
621     // altivec. We'll diagnose any problems later.
622     bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)
623                              .Case("vsx", true)
624                              .Case("direct-move", true)
625                              .Case("power8-vector", true)
626                              .Case("power9-vector", true)
627                              .Case("paired-vector-memops", true)
628                              .Case("power10-vector", true)
629                              .Case("float128", true)
630                              .Case("mma", true)
631                              .Default(false);
632     if (FeatureHasVSX)
633       Features["vsx"] = Features["altivec"] = true;
634     if (Name == "power9-vector")
635       Features["power8-vector"] = true;
636     else if (Name == "power10-vector")
637       Features["power8-vector"] = Features["power9-vector"] = true;
638     if (Name == "pcrel")
639       Features["pcrelative-memops"] = true;
640     else if (Name == "prefixed")
641       Features["prefix-instrs"] = true;
642     else
643       Features[Name] = true;
644   } else {
645     if (Name == "spe")
646       Features["efpu2"] = false;
647     // If we're disabling altivec, hard-float, or vsx go ahead and disable all
648     // of the vsx features.
649     if ((Name == "altivec") || (Name == "vsx") || (Name == "hard-float")) {
650       if (Name != "vsx")
651         Features["altivec"] = Features["crypto"] = false;
652       Features["vsx"] = Features["direct-move"] = Features["power8-vector"] =
653           Features["float128"] = Features["power9-vector"] =
654               Features["paired-vector-memops"] = Features["mma"] =
655                   Features["power10-vector"] = false;
656     }
657     if (Name == "power8-vector")
658       Features["power9-vector"] = Features["paired-vector-memops"] =
659           Features["mma"] = Features["power10-vector"] = false;
660     else if (Name == "power9-vector")
661       Features["paired-vector-memops"] = Features["mma"] =
662           Features["power10-vector"] = false;
663     if (Name == "pcrel")
664       Features["pcrelative-memops"] = false;
665     else if (Name == "prefixed")
666       Features["prefix-instrs"] = false;
667     else
668       Features[Name] = false;
669   }
670 }
671 
672 // Make sure that registers are added in the correct array index which should be
673 // the DWARF number for PPC registers.
674 const char *const PPCTargetInfo::GCCRegNames[] = {
675     "r0",  "r1",     "r2",   "r3",      "r4",      "r5",  "r6",  "r7",  "r8",
676     "r9",  "r10",    "r11",  "r12",     "r13",     "r14", "r15", "r16", "r17",
677     "r18", "r19",    "r20",  "r21",     "r22",     "r23", "r24", "r25", "r26",
678     "r27", "r28",    "r29",  "r30",     "r31",     "f0",  "f1",  "f2",  "f3",
679     "f4",  "f5",     "f6",   "f7",      "f8",      "f9",  "f10", "f11", "f12",
680     "f13", "f14",    "f15",  "f16",     "f17",     "f18", "f19", "f20", "f21",
681     "f22", "f23",    "f24",  "f25",     "f26",     "f27", "f28", "f29", "f30",
682     "f31", "mq",     "lr",   "ctr",     "ap",      "cr0", "cr1", "cr2", "cr3",
683     "cr4", "cr5",    "cr6",  "cr7",     "xer",     "v0",  "v1",  "v2",  "v3",
684     "v4",  "v5",     "v6",   "v7",      "v8",      "v9",  "v10", "v11", "v12",
685     "v13", "v14",    "v15",  "v16",     "v17",     "v18", "v19", "v20", "v21",
686     "v22", "v23",    "v24",  "v25",     "v26",     "v27", "v28", "v29", "v30",
687     "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp"
688 };
689 
690 ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {
691   return llvm::ArrayRef(GCCRegNames);
692 }
693 
694 const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
695     // While some of these aliases do map to different registers
696     // they still share the same register name.
697     {{"0"}, "r0"},     {{"1", "sp"}, "r1"}, {{"2"}, "r2"},
698     {{"3"}, "r3"},     {{"4"}, "r4"},       {{"5"}, "r5"},
699     {{"6"}, "r6"},     {{"7"}, "r7"},       {{"8"}, "r8"},
700     {{"9"}, "r9"},     {{"10"}, "r10"},     {{"11"}, "r11"},
701     {{"12"}, "r12"},   {{"13"}, "r13"},     {{"14"}, "r14"},
702     {{"15"}, "r15"},   {{"16"}, "r16"},     {{"17"}, "r17"},
703     {{"18"}, "r18"},   {{"19"}, "r19"},     {{"20"}, "r20"},
704     {{"21"}, "r21"},   {{"22"}, "r22"},     {{"23"}, "r23"},
705     {{"24"}, "r24"},   {{"25"}, "r25"},     {{"26"}, "r26"},
706     {{"27"}, "r27"},   {{"28"}, "r28"},     {{"29"}, "r29"},
707     {{"30"}, "r30"},   {{"31"}, "r31"},     {{"fr0"}, "f0"},
708     {{"fr1"}, "f1"},   {{"fr2"}, "f2"},     {{"fr3"}, "f3"},
709     {{"fr4"}, "f4"},   {{"fr5"}, "f5"},     {{"fr6"}, "f6"},
710     {{"fr7"}, "f7"},   {{"fr8"}, "f8"},     {{"fr9"}, "f9"},
711     {{"fr10"}, "f10"}, {{"fr11"}, "f11"},   {{"fr12"}, "f12"},
712     {{"fr13"}, "f13"}, {{"fr14"}, "f14"},   {{"fr15"}, "f15"},
713     {{"fr16"}, "f16"}, {{"fr17"}, "f17"},   {{"fr18"}, "f18"},
714     {{"fr19"}, "f19"}, {{"fr20"}, "f20"},   {{"fr21"}, "f21"},
715     {{"fr22"}, "f22"}, {{"fr23"}, "f23"},   {{"fr24"}, "f24"},
716     {{"fr25"}, "f25"}, {{"fr26"}, "f26"},   {{"fr27"}, "f27"},
717     {{"fr28"}, "f28"}, {{"fr29"}, "f29"},   {{"fr30"}, "f30"},
718     {{"fr31"}, "f31"}, {{"cc"}, "cr0"},
719 };
720 
721 ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
722   return llvm::ArrayRef(GCCRegAliases);
723 }
724 
725 // PPC ELFABIv2 DWARF Definition "Table 2.26. Mappings of Common Registers".
726 // vs0 ~ vs31 is mapping to 32 - 63,
727 // vs32 ~ vs63 is mapping to 77 - 108.
728 // And this mapping applies to all OSes which run on powerpc.
729 const TargetInfo::AddlRegName GCCAddlRegNames[] = {
730     // Table of additional register names to use in user input.
731     {{"vs0"}, 32},   {{"vs1"}, 33},   {{"vs2"}, 34},   {{"vs3"}, 35},
732     {{"vs4"}, 36},   {{"vs5"}, 37},   {{"vs6"}, 38},   {{"vs7"}, 39},
733     {{"vs8"}, 40},   {{"vs9"}, 41},   {{"vs10"}, 42},  {{"vs11"}, 43},
734     {{"vs12"}, 44},  {{"vs13"}, 45},  {{"vs14"}, 46},  {{"vs15"}, 47},
735     {{"vs16"}, 48},  {{"vs17"}, 49},  {{"vs18"}, 50},  {{"vs19"}, 51},
736     {{"vs20"}, 52},  {{"vs21"}, 53},  {{"vs22"}, 54},  {{"vs23"}, 55},
737     {{"vs24"}, 56},  {{"vs25"}, 57},  {{"vs26"}, 58},  {{"vs27"}, 59},
738     {{"vs28"}, 60},  {{"vs29"}, 61},  {{"vs30"}, 62},  {{"vs31"}, 63},
739     {{"vs32"}, 77},  {{"vs33"}, 78},  {{"vs34"}, 79},  {{"vs35"}, 80},
740     {{"vs36"}, 81},  {{"vs37"}, 82},  {{"vs38"}, 83},  {{"vs39"}, 84},
741     {{"vs40"}, 85},  {{"vs41"}, 86},  {{"vs42"}, 87},  {{"vs43"}, 88},
742     {{"vs44"}, 89},  {{"vs45"}, 90},  {{"vs46"}, 91},  {{"vs47"}, 92},
743     {{"vs48"}, 93},  {{"vs49"}, 94},  {{"vs50"}, 95},  {{"vs51"}, 96},
744     {{"vs52"}, 97},  {{"vs53"}, 98},  {{"vs54"}, 99},  {{"vs55"}, 100},
745     {{"vs56"}, 101}, {{"vs57"}, 102}, {{"vs58"}, 103}, {{"vs59"}, 104},
746     {{"vs60"}, 105}, {{"vs61"}, 106}, {{"vs62"}, 107}, {{"vs63"}, 108},
747 };
748 
749 ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const {
750   return llvm::ArrayRef(GCCAddlRegNames);
751 }
752 
753 bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
754   return llvm::PPC::isValidCPU(Name);
755 }
756 
757 void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
758   llvm::PPC::fillValidCPUList(Values);
759 }
760 
761 void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts,
762                            const TargetInfo *Aux) {
763   if (HasAltivec)
764     Opts.AltiVec = 1;
765   TargetInfo::adjust(Diags, Opts, Aux);
766   if (LongDoubleFormat != &llvm::APFloat::IEEEdouble())
767     LongDoubleFormat = Opts.PPCIEEELongDouble
768                            ? &llvm::APFloat::IEEEquad()
769                            : &llvm::APFloat::PPCDoubleDouble();
770   Opts.IEEE128 = 1;
771   if (getTriple().isOSAIX() && Opts.EnableAIXQuadwordAtomicsABI &&
772       HasQuadwordAtomics)
773     MaxAtomicInlineWidth = 128;
774 }
775 
776 llvm::SmallVector<Builtin::InfosShard>
777 PPCTargetInfo::getTargetBuiltins() const {
778   return {{&BuiltinStrings, BuiltinInfos}};
779 }
780 
781 bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const {
782   llvm::Triple Triple = getTriple();
783   if (Triple.isOSAIX()) {
784 #define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, COMP_OP,      \
785                         VALUE)                                                 \
786   .Case(NAME, true)
787     return llvm::StringSwitch<bool>(FeatureStr)
788 #include "llvm/TargetParser/PPCTargetParser.def"
789         .Default(false);
790   }
791 
792   assert(Triple.isOSLinux() &&
793          "__builtin_cpu_supports() is only supported for AIX and Linux.");
794 
795 #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true)
796   return llvm::StringSwitch<bool>(FeatureStr)
797 #include "llvm/TargetParser/PPCTargetParser.def"
798       .Default(false);
799 }
800 
801 bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const {
802   llvm::Triple Triple = getTriple();
803   assert((Triple.isOSAIX() || Triple.isOSLinux()) &&
804          "__builtin_cpu_is() is only supported for AIX and Linux.");
805 
806 #define PPC_CPU(NAME, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD,       \
807                 AIXID)                                                         \
808   .Case(NAME, {Linux_SUPPORT_METHOD, AIX_SUPPORT_METHOD})
809 
810   std::pair<unsigned, unsigned> SuppportMethod =
811       llvm::StringSwitch<std::pair<unsigned, unsigned>>(CPUName)
812 #include "llvm/TargetParser/PPCTargetParser.def"
813           .Default({BUILTIN_PPC_UNSUPPORTED, BUILTIN_PPC_UNSUPPORTED});
814   return Triple.isOSLinux()
815              ? (SuppportMethod.first != BUILTIN_PPC_UNSUPPORTED)
816              : (SuppportMethod.second != BUILTIN_PPC_UNSUPPORTED);
817 }
818