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