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