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