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

source code of clang/lib/Basic/Targets/PPC.cpp