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 const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
22 #define BUILTIN(ID, TYPE, ATTRS)                                               \
23   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
24 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
25   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
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     Builder.defineMacro("__PPC64__");
286   } else if (getTriple().isOSAIX()) {
287     // The XL compilers on AIX define _ARCH_PPC64 for both 32 and 64-bit modes.
288     Builder.defineMacro("_ARCH_PPC64");
289   }
290   if (getTriple().isOSAIX()) {
291     Builder.defineMacro("__THW_PPC__");
292     // Define __PPC and __powerpc for AIX XL C/C++ compatibility
293     Builder.defineMacro("__PPC");
294     Builder.defineMacro("__powerpc");
295   }
296 
297   // Target properties.
298   if (getTriple().getArch() == llvm::Triple::ppc64le ||
299       getTriple().getArch() == llvm::Triple::ppcle) {
300     Builder.defineMacro("_LITTLE_ENDIAN");
301   } else {
302     if (!getTriple().isOSNetBSD() &&
303         !getTriple().isOSOpenBSD())
304       Builder.defineMacro("_BIG_ENDIAN");
305   }
306 
307   // ABI options.
308   if (ABI == "elfv1")
309     Builder.defineMacro("_CALL_ELF", "1");
310   if (ABI == "elfv2")
311     Builder.defineMacro("_CALL_ELF", "2");
312 
313   // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but
314   // our support post-dates this and it should work on all 64-bit ppc linux
315   // platforms. It is guaranteed to work on all elfv2 platforms.
316   if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64)
317     Builder.defineMacro("_CALL_LINUX", "1");
318 
319   // Subtarget options.
320   if (!getTriple().isOSAIX()){
321     Builder.defineMacro("__NATURAL_ALIGNMENT__");
322   }
323   Builder.defineMacro("__REGISTER_PREFIX__", "");
324 
325   // FIXME: Should be controlled by command line option.
326   if (LongDoubleWidth == 128) {
327     Builder.defineMacro("__LONG_DOUBLE_128__");
328     Builder.defineMacro("__LONGDOUBLE128");
329     if (Opts.PPCIEEELongDouble)
330       Builder.defineMacro("__LONG_DOUBLE_IEEE128__");
331     else
332       Builder.defineMacro("__LONG_DOUBLE_IBM128__");
333   }
334 
335   if (getTriple().isOSAIX() && Opts.LongDoubleSize == 64) {
336     assert(LongDoubleWidth == 64);
337     Builder.defineMacro("__LONGDOUBLE64");
338   }
339 
340   // Define this for elfv2 (64-bit only) or 64-bit darwin.
341   if (ABI == "elfv2" ||
342       (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64))
343     Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");
344 
345   if (ArchDefs & ArchDefineName)
346     Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
347   if (ArchDefs & ArchDefinePpcgr)
348     Builder.defineMacro("_ARCH_PPCGR");
349   if (ArchDefs & ArchDefinePpcsq)
350     Builder.defineMacro("_ARCH_PPCSQ");
351   if (ArchDefs & ArchDefine440)
352     Builder.defineMacro("_ARCH_440");
353   if (ArchDefs & ArchDefine603)
354     Builder.defineMacro("_ARCH_603");
355   if (ArchDefs & ArchDefine604)
356     Builder.defineMacro("_ARCH_604");
357   if (ArchDefs & ArchDefinePwr4)
358     Builder.defineMacro("_ARCH_PWR4");
359   if (ArchDefs & ArchDefinePwr5)
360     Builder.defineMacro("_ARCH_PWR5");
361   if (ArchDefs & ArchDefinePwr5x)
362     Builder.defineMacro("_ARCH_PWR5X");
363   if (ArchDefs & ArchDefinePwr6)
364     Builder.defineMacro("_ARCH_PWR6");
365   if (ArchDefs & ArchDefinePwr6x)
366     Builder.defineMacro("_ARCH_PWR6X");
367   if (ArchDefs & ArchDefinePwr7)
368     Builder.defineMacro("_ARCH_PWR7");
369   if (ArchDefs & ArchDefinePwr8)
370     Builder.defineMacro("_ARCH_PWR8");
371   if (ArchDefs & ArchDefinePwr9)
372     Builder.defineMacro("_ARCH_PWR9");
373   if (ArchDefs & ArchDefinePwr10)
374     Builder.defineMacro("_ARCH_PWR10");
375   if (ArchDefs & ArchDefineA2)
376     Builder.defineMacro("_ARCH_A2");
377   if (ArchDefs & ArchDefineE500)
378     Builder.defineMacro("__NO_LWSYNC__");
379   if (ArchDefs & ArchDefineFuture)
380     Builder.defineMacro("_ARCH_PWR_FUTURE");
381 
382   if (HasAltivec) {
383     Builder.defineMacro("__VEC__", "10206");
384     Builder.defineMacro("__ALTIVEC__");
385   }
386   if (HasSPE) {
387     Builder.defineMacro("__SPE__");
388     Builder.defineMacro("__NO_FPRS__");
389   }
390   if (HasVSX)
391     Builder.defineMacro("__VSX__");
392   if (HasP8Vector)
393     Builder.defineMacro("__POWER8_VECTOR__");
394   if (HasP8Crypto)
395     Builder.defineMacro("__CRYPTO__");
396   if (HasHTM)
397     Builder.defineMacro("__HTM__");
398   if (HasFloat128)
399     Builder.defineMacro("__FLOAT128__");
400   if (HasP9Vector)
401     Builder.defineMacro("__POWER9_VECTOR__");
402   if (HasMMA)
403     Builder.defineMacro("__MMA__");
404   if (HasROPProtect)
405     Builder.defineMacro("__ROP_PROTECT__");
406   if (HasP10Vector)
407     Builder.defineMacro("__POWER10_VECTOR__");
408   if (HasPCRelativeMemops)
409     Builder.defineMacro("__PCREL__");
410 
411   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
412   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
413   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
414   if (PointerWidth == 64)
415     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
416 
417   // We have support for the bswap intrinsics so we can define this.
418   Builder.defineMacro("__HAVE_BSWAP__", "1");
419 
420   // FIXME: The following are not yet generated here by Clang, but are
421   //        generated by GCC:
422   //
423   //   _SOFT_FLOAT_
424   //   __RECIP_PRECISION__
425   //   __APPLE_ALTIVEC__
426   //   __RECIP__
427   //   __RECIPF__
428   //   __RSQRTE__
429   //   __RSQRTEF__
430   //   _SOFT_DOUBLE_
431   //   __NO_LWSYNC__
432   //   __CMODEL_MEDIUM__
433   //   __CMODEL_LARGE__
434   //   _CALL_SYSV
435   //   _CALL_DARWIN
436 }
437 
438 // Handle explicit options being passed to the compiler here: if we've
439 // explicitly turned off vsx and turned on any of:
440 // - power8-vector
441 // - direct-move
442 // - float128
443 // - power9-vector
444 // - paired-vector-memops
445 // - mma
446 // - power10-vector
447 // then go ahead and error since the customer has expressed an incompatible
448 // set of options.
449 static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
450                                  const std::vector<std::string> &FeaturesVec) {
451 
452   // vsx was not explicitly turned off.
453   if (!llvm::is_contained(FeaturesVec, "-vsx"))
454     return true;
455 
456   auto FindVSXSubfeature = [&](StringRef Feature, StringRef Option) {
457     if (llvm::is_contained(FeaturesVec, Feature)) {
458       Diags.Report(diag::err_opt_not_valid_with_opt) << Option << "-mno-vsx";
459       return true;
460     }
461     return false;
462   };
463 
464   bool Found = FindVSXSubfeature("+power8-vector", "-mpower8-vector");
465   Found |= FindVSXSubfeature("+direct-move", "-mdirect-move");
466   Found |= FindVSXSubfeature("+float128", "-mfloat128");
467   Found |= FindVSXSubfeature("+power9-vector", "-mpower9-vector");
468   Found |= FindVSXSubfeature("+paired-vector-memops", "-mpaired-vector-memops");
469   Found |= FindVSXSubfeature("+mma", "-mmma");
470   Found |= FindVSXSubfeature("+power10-vector", "-mpower10-vector");
471 
472   // Return false if any vsx subfeatures was found.
473   return !Found;
474 }
475 
476 bool PPCTargetInfo::initFeatureMap(
477     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
478     const std::vector<std::string> &FeaturesVec) const {
479   Features["altivec"] = llvm::StringSwitch<bool>(CPU)
480                             .Case("7400", true)
481                             .Case("g4", true)
482                             .Case("7450", true)
483                             .Case("g4+", true)
484                             .Case("970", true)
485                             .Case("g5", true)
486                             .Case("pwr6", true)
487                             .Case("pwr7", true)
488                             .Case("pwr8", true)
489                             .Case("pwr9", true)
490                             .Case("ppc64", true)
491                             .Case("ppc64le", true)
492                             .Default(false);
493 
494   Features["power9-vector"] = (CPU == "pwr9");
495   Features["crypto"] = llvm::StringSwitch<bool>(CPU)
496                            .Case("ppc64le", true)
497                            .Case("pwr9", true)
498                            .Case("pwr8", true)
499                            .Default(false);
500   Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)
501                                   .Case("ppc64le", true)
502                                   .Case("pwr9", true)
503                                   .Case("pwr8", true)
504                                   .Default(false);
505   Features["bpermd"] = llvm::StringSwitch<bool>(CPU)
506                            .Case("ppc64le", true)
507                            .Case("pwr9", true)
508                            .Case("pwr8", true)
509                            .Case("pwr7", true)
510                            .Default(false);
511   Features["extdiv"] = llvm::StringSwitch<bool>(CPU)
512                            .Case("ppc64le", true)
513                            .Case("pwr9", true)
514                            .Case("pwr8", true)
515                            .Case("pwr7", true)
516                            .Default(false);
517   Features["direct-move"] = llvm::StringSwitch<bool>(CPU)
518                                 .Case("ppc64le", true)
519                                 .Case("pwr9", true)
520                                 .Case("pwr8", true)
521                                 .Default(false);
522   Features["crbits"] = llvm::StringSwitch<bool>(CPU)
523                                 .Case("ppc64le", true)
524                                 .Case("pwr9", true)
525                                 .Case("pwr8", true)
526                                 .Default(false);
527   Features["vsx"] = llvm::StringSwitch<bool>(CPU)
528                         .Case("ppc64le", true)
529                         .Case("pwr9", true)
530                         .Case("pwr8", true)
531                         .Case("pwr7", true)
532                         .Default(false);
533   Features["htm"] = llvm::StringSwitch<bool>(CPU)
534                         .Case("ppc64le", true)
535                         .Case("pwr9", true)
536                         .Case("pwr8", true)
537                         .Default(false);
538 
539   // ROP Protect is off by default.
540   Features["rop-protect"] = false;
541   // Privileged instructions are off by default.
542   Features["privileged"] = false;
543 
544   Features["spe"] = llvm::StringSwitch<bool>(CPU)
545                         .Case("8548", true)
546                         .Case("e500", true)
547                         .Default(false);
548 
549   Features["isa-v206-instructions"] = llvm::StringSwitch<bool>(CPU)
550                                           .Case("ppc64le", true)
551                                           .Case("pwr9", true)
552                                           .Case("pwr8", true)
553                                           .Case("pwr7", true)
554                                           .Case("a2", true)
555                                           .Default(false);
556 
557   Features["isa-v207-instructions"] = llvm::StringSwitch<bool>(CPU)
558                                           .Case("ppc64le", true)
559                                           .Case("pwr9", true)
560                                           .Case("pwr8", true)
561                                           .Default(false);
562 
563   Features["isa-v30-instructions"] =
564       llvm::StringSwitch<bool>(CPU).Case("pwr9", true).Default(false);
565 
566   Features["quadword-atomics"] =
567       getTriple().isArch64Bit() && llvm::StringSwitch<bool>(CPU)
568                                        .Case("pwr9", true)
569                                        .Case("pwr8", true)
570                                        .Default(false);
571 
572   // Power10 includes all the same features as Power9 plus any features specific
573   // to the Power10 core.
574   if (CPU == "pwr10" || CPU == "power10") {
575     initFeatureMap(Features, Diags, "pwr9", FeaturesVec);
576     addP10SpecificFeatures(Features);
577   }
578 
579   // Future CPU should include all of the features of Power 10 as well as any
580   // additional features (yet to be determined) specific to it.
581   if (CPU == "future") {
582     initFeatureMap(Features, Diags, "pwr10", FeaturesVec);
583     addFutureSpecificFeatures(Features);
584   }
585 
586   if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
587     return false;
588 
589   if (!(ArchDefs & ArchDefinePwr7) && (ArchDefs & ArchDefinePpcgr) &&
590       llvm::is_contained(FeaturesVec, "+float128")) {
591     // We have __float128 on PPC but not pre-VSX targets.
592     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU;
593     return false;
594   }
595 
596   if (!(ArchDefs & ArchDefinePwr10)) {
597     if (llvm::is_contained(FeaturesVec, "+mma")) {
598       // MMA operations are not available pre-Power10.
599       Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU;
600       return false;
601     }
602     if (llvm::is_contained(FeaturesVec, "+pcrel")) {
603       // PC-Relative instructions are not available pre-Power10,
604       // and these instructions also require prefixed instructions support.
605       Diags.Report(diag::err_opt_not_valid_without_opt)
606           << "-mpcrel"
607           << "-mcpu=pwr10 -mprefixed";
608       return false;
609     }
610     if (llvm::is_contained(FeaturesVec, "+prefixed")) {
611       // Prefixed instructions are not available pre-Power10.
612       Diags.Report(diag::err_opt_not_valid_without_opt) << "-mprefixed"
613                                                         << "-mcpu=pwr10";
614       return false;
615     }
616     if (llvm::is_contained(FeaturesVec, "+paired-vector-memops")) {
617       // Paired vector memops are not available pre-Power10.
618       Diags.Report(diag::err_opt_not_valid_without_opt)
619           << "-mpaired-vector-memops"
620           << "-mcpu=pwr10";
621       return false;
622     }
623   }
624 
625   if (!(ArchDefs & ArchDefinePwr8) &&
626       llvm::is_contained(FeaturesVec, "+rop-protect")) {
627     // We can turn on ROP Protect on Power 8 and above.
628     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protect" << CPU;
629     return false;
630   }
631 
632   if (!(ArchDefs & ArchDefinePwr8) &&
633       llvm::is_contained(FeaturesVec, "+privileged")) {
634     Diags.Report(diag::err_opt_not_valid_with_opt) << "-mprivileged" << CPU;
635     return false;
636   }
637 
638   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
639 }
640 
641 // Add any Power10 specific features.
642 void PPCTargetInfo::addP10SpecificFeatures(
643     llvm::StringMap<bool> &Features) const {
644   Features["htm"] = false; // HTM was removed for P10.
645   Features["paired-vector-memops"] = true;
646   Features["mma"] = true;
647   Features["power10-vector"] = true;
648   Features["pcrelative-memops"] = true;
649   Features["prefix-instrs"] = true;
650   Features["isa-v31-instructions"] = true;
651 }
652 
653 // Add features specific to the "Future" CPU.
654 void PPCTargetInfo::addFutureSpecificFeatures(
655     llvm::StringMap<bool> &Features) const {}
656 
657 bool PPCTargetInfo::hasFeature(StringRef Feature) const {
658   return llvm::StringSwitch<bool>(Feature)
659       .Case("powerpc", true)
660       .Case("altivec", HasAltivec)
661       .Case("vsx", HasVSX)
662       .Case("crbits", UseCRBits)
663       .Case("power8-vector", HasP8Vector)
664       .Case("crypto", HasP8Crypto)
665       .Case("direct-move", HasDirectMove)
666       .Case("htm", HasHTM)
667       .Case("bpermd", HasBPERMD)
668       .Case("extdiv", HasExtDiv)
669       .Case("float128", HasFloat128)
670       .Case("power9-vector", HasP9Vector)
671       .Case("paired-vector-memops", PairedVectorMemops)
672       .Case("power10-vector", HasP10Vector)
673       .Case("pcrelative-memops", HasPCRelativeMemops)
674       .Case("prefix-instrs", HasPrefixInstrs)
675       .Case("spe", HasSPE)
676       .Case("mma", HasMMA)
677       .Case("rop-protect", HasROPProtect)
678       .Case("privileged", HasPrivileged)
679       .Case("isa-v206-instructions", IsISA2_06)
680       .Case("isa-v207-instructions", IsISA2_07)
681       .Case("isa-v30-instructions", IsISA3_0)
682       .Case("isa-v31-instructions", IsISA3_1)
683       .Case("quadword-atomics", HasQuadwordAtomics)
684       .Default(false);
685 }
686 
687 void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
688                                       StringRef Name, bool Enabled) const {
689   if (Enabled) {
690     if (Name == "efpu2")
691       Features["spe"] = true;
692     // If we're enabling any of the vsx based features then enable vsx and
693     // altivec. We'll diagnose any problems later.
694     bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)
695                              .Case("vsx", true)
696                              .Case("direct-move", true)
697                              .Case("power8-vector", true)
698                              .Case("power9-vector", true)
699                              .Case("paired-vector-memops", true)
700                              .Case("power10-vector", true)
701                              .Case("float128", true)
702                              .Case("mma", true)
703                              .Default(false);
704     if (FeatureHasVSX)
705       Features["vsx"] = Features["altivec"] = true;
706     if (Name == "power9-vector")
707       Features["power8-vector"] = true;
708     else if (Name == "power10-vector")
709       Features["power8-vector"] = Features["power9-vector"] = true;
710     if (Name == "pcrel")
711       Features["pcrelative-memops"] = true;
712     else if (Name == "prefixed")
713       Features["prefix-instrs"] = true;
714     else
715       Features[Name] = true;
716   } else {
717     if (Name == "spe")
718       Features["efpu2"] = false;
719     // If we're disabling altivec or vsx go ahead and disable all of the vsx
720     // features.
721     if ((Name == "altivec") || (Name == "vsx"))
722       Features["vsx"] = Features["direct-move"] = Features["power8-vector"] =
723           Features["float128"] = Features["power9-vector"] =
724               Features["paired-vector-memops"] = Features["mma"] =
725                   Features["power10-vector"] = false;
726     if (Name == "power8-vector")
727       Features["power9-vector"] = Features["paired-vector-memops"] =
728           Features["mma"] = Features["power10-vector"] = false;
729     else if (Name == "power9-vector")
730       Features["paired-vector-memops"] = Features["mma"] =
731           Features["power10-vector"] = false;
732     if (Name == "pcrel")
733       Features["pcrelative-memops"] = false;
734     else if (Name == "prefixed")
735       Features["prefix-instrs"] = false;
736     else
737       Features[Name] = false;
738   }
739 }
740 
741 const char *const PPCTargetInfo::GCCRegNames[] = {
742     "r0",  "r1",     "r2",   "r3",      "r4",      "r5",  "r6",  "r7",  "r8",
743     "r9",  "r10",    "r11",  "r12",     "r13",     "r14", "r15", "r16", "r17",
744     "r18", "r19",    "r20",  "r21",     "r22",     "r23", "r24", "r25", "r26",
745     "r27", "r28",    "r29",  "r30",     "r31",     "f0",  "f1",  "f2",  "f3",
746     "f4",  "f5",     "f6",   "f7",      "f8",      "f9",  "f10", "f11", "f12",
747     "f13", "f14",    "f15",  "f16",     "f17",     "f18", "f19", "f20", "f21",
748     "f22", "f23",    "f24",  "f25",     "f26",     "f27", "f28", "f29", "f30",
749     "f31", "mq",     "lr",   "ctr",     "ap",      "cr0", "cr1", "cr2", "cr3",
750     "cr4", "cr5",    "cr6",  "cr7",     "xer",     "v0",  "v1",  "v2",  "v3",
751     "v4",  "v5",     "v6",   "v7",      "v8",      "v9",  "v10", "v11", "v12",
752     "v13", "v14",    "v15",  "v16",     "v17",     "v18", "v19", "v20", "v21",
753     "v22", "v23",    "v24",  "v25",     "v26",     "v27", "v28", "v29", "v30",
754     "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp"
755 };
756 
757 ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {
758   return llvm::makeArrayRef(GCCRegNames);
759 }
760 
761 const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
762     // While some of these aliases do map to different registers
763     // they still share the same register name.
764     {{"0"}, "r0"},     {{"1", "sp"}, "r1"}, {{"2"}, "r2"},
765     {{"3"}, "r3"},     {{"4"}, "r4"},       {{"5"}, "r5"},
766     {{"6"}, "r6"},     {{"7"}, "r7"},       {{"8"}, "r8"},
767     {{"9"}, "r9"},     {{"10"}, "r10"},     {{"11"}, "r11"},
768     {{"12"}, "r12"},   {{"13"}, "r13"},     {{"14"}, "r14"},
769     {{"15"}, "r15"},   {{"16"}, "r16"},     {{"17"}, "r17"},
770     {{"18"}, "r18"},   {{"19"}, "r19"},     {{"20"}, "r20"},
771     {{"21"}, "r21"},   {{"22"}, "r22"},     {{"23"}, "r23"},
772     {{"24"}, "r24"},   {{"25"}, "r25"},     {{"26"}, "r26"},
773     {{"27"}, "r27"},   {{"28"}, "r28"},     {{"29"}, "r29"},
774     {{"30"}, "r30"},   {{"31"}, "r31"},     {{"fr0"}, "f0"},
775     {{"fr1"}, "f1"},   {{"fr2"}, "f2"},     {{"fr3"}, "f3"},
776     {{"fr4"}, "f4"},   {{"fr5"}, "f5"},     {{"fr6"}, "f6"},
777     {{"fr7"}, "f7"},   {{"fr8"}, "f8"},     {{"fr9"}, "f9"},
778     {{"fr10"}, "f10"}, {{"fr11"}, "f11"},   {{"fr12"}, "f12"},
779     {{"fr13"}, "f13"}, {{"fr14"}, "f14"},   {{"fr15"}, "f15"},
780     {{"fr16"}, "f16"}, {{"fr17"}, "f17"},   {{"fr18"}, "f18"},
781     {{"fr19"}, "f19"}, {{"fr20"}, "f20"},   {{"fr21"}, "f21"},
782     {{"fr22"}, "f22"}, {{"fr23"}, "f23"},   {{"fr24"}, "f24"},
783     {{"fr25"}, "f25"}, {{"fr26"}, "f26"},   {{"fr27"}, "f27"},
784     {{"fr28"}, "f28"}, {{"fr29"}, "f29"},   {{"fr30"}, "f30"},
785     {{"fr31"}, "f31"}, {{"cc"}, "cr0"},
786 };
787 
788 ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
789   return llvm::makeArrayRef(GCCRegAliases);
790 }
791 
792 // PPC ELFABIv2 DWARF Definitoin "Table 2.26. Mappings of Common Registers".
793 // vs0 ~ vs31 is mapping to 32 - 63,
794 // vs32 ~ vs63 is mapping to 77 - 108.
795 const TargetInfo::AddlRegName GCCAddlRegNames[] = {
796     // Table of additional register names to use in user input.
797     {{"vs0"}, 32},   {{"vs1"}, 33},   {{"vs2"}, 34},   {{"vs3"}, 35},
798     {{"vs4"}, 36},   {{"vs5"}, 37},   {{"vs6"}, 38},   {{"vs7"}, 39},
799     {{"vs8"}, 40},   {{"vs9"}, 41},   {{"vs10"}, 42},  {{"vs11"}, 43},
800     {{"vs12"}, 44},  {{"vs13"}, 45},  {{"vs14"}, 46},  {{"vs15"}, 47},
801     {{"vs16"}, 48},  {{"vs17"}, 49},  {{"vs18"}, 50},  {{"vs19"}, 51},
802     {{"vs20"}, 52},  {{"vs21"}, 53},  {{"vs22"}, 54},  {{"vs23"}, 55},
803     {{"vs24"}, 56},  {{"vs25"}, 57},  {{"vs26"}, 58},  {{"vs27"}, 59},
804     {{"vs28"}, 60},  {{"vs29"}, 61},  {{"vs30"}, 62},  {{"vs31"}, 63},
805     {{"vs32"}, 77},  {{"vs33"}, 78},  {{"vs34"}, 79},  {{"vs35"}, 80},
806     {{"vs36"}, 81},  {{"vs37"}, 82},  {{"vs38"}, 83},  {{"vs39"}, 84},
807     {{"vs40"}, 85},  {{"vs41"}, 86},  {{"vs42"}, 87},  {{"vs43"}, 88},
808     {{"vs44"}, 89},  {{"vs45"}, 90},  {{"vs46"}, 91},  {{"vs47"}, 92},
809     {{"vs48"}, 93},  {{"vs49"}, 94},  {{"vs50"}, 95},  {{"vs51"}, 96},
810     {{"vs52"}, 97},  {{"vs53"}, 98},  {{"vs54"}, 99},  {{"vs55"}, 100},
811     {{"vs56"}, 101}, {{"vs57"}, 102}, {{"vs58"}, 103}, {{"vs59"}, 104},
812     {{"vs60"}, 105}, {{"vs61"}, 106}, {{"vs62"}, 107}, {{"vs63"}, 108},
813 };
814 
815 ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const {
816   if (ABI == "elfv2")
817     return llvm::makeArrayRef(GCCAddlRegNames);
818   else
819     return TargetInfo::getGCCAddlRegNames();
820 }
821 
822 static constexpr llvm::StringLiteral ValidCPUNames[] = {
823     {"generic"},     {"440"},     {"450"},    {"601"},       {"602"},
824     {"603"},         {"603e"},    {"603ev"},  {"604"},       {"604e"},
825     {"620"},         {"630"},     {"g3"},     {"7400"},      {"g4"},
826     {"7450"},        {"g4+"},     {"750"},    {"8548"},      {"970"},
827     {"g5"},          {"a2"},      {"e500"},   {"e500mc"},    {"e5500"},
828     {"power3"},      {"pwr3"},    {"power4"}, {"pwr4"},      {"power5"},
829     {"pwr5"},        {"power5x"}, {"pwr5x"},  {"power6"},    {"pwr6"},
830     {"power6x"},     {"pwr6x"},   {"power7"}, {"pwr7"},      {"power8"},
831     {"pwr8"},        {"power9"},  {"pwr9"},   {"power10"},   {"pwr10"},
832     {"powerpc"},     {"ppc"},     {"ppc32"},  {"powerpc64"}, {"ppc64"},
833     {"powerpc64le"}, {"ppc64le"}, {"future"}};
834 
835 bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
836   return llvm::is_contained(ValidCPUNames, Name);
837 }
838 
839 void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
840   Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
841 }
842 
843 void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
844   if (HasAltivec)
845     Opts.AltiVec = 1;
846   TargetInfo::adjust(Diags, Opts);
847   if (LongDoubleFormat != &llvm::APFloat::IEEEdouble())
848     LongDoubleFormat = Opts.PPCIEEELongDouble
849                            ? &llvm::APFloat::IEEEquad()
850                            : &llvm::APFloat::PPCDoubleDouble();
851   Opts.IEEE128 = 1;
852   if (getTriple().isOSAIX() && Opts.EnableAIXQuadwordAtomicsABI &&
853       HasQuadwordAtomics)
854     MaxAtomicInlineWidth = 128;
855 }
856 
857 ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
858   return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin -
859                                              Builtin::FirstTSBuiltin);
860 }
861