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