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