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