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