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