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