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