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