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