1 | //===--- PPC.cpp - Implement PPC target feature support -------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements PPC TargetInfo objects. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "PPC.h" |
14 | #include "clang/Basic/Diagnostic.h" |
15 | #include "clang/Basic/MacroBuilder.h" |
16 | #include "clang/Basic/TargetBuiltins.h" |
17 | |
18 | using namespace clang; |
19 | using namespace clang::targets; |
20 | |
21 | static constexpr Builtin::Info BuiltinInfo[] = { |
22 | #define BUILTIN(ID, TYPE, ATTRS) \ |
23 | {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, |
24 | #define 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. |
33 | bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, |
34 | DiagnosticsEngine &Diags) { |
35 | FloatABI = HardFloat; |
36 | for (const auto &Feature : Features) { |
37 | if (Feature == "+altivec" ) { |
38 | HasAltivec = true; |
39 | } else if (Feature == "+vsx" ) { |
40 | HasVSX = true; |
41 | } else if (Feature == "+crbits" ) { |
42 | UseCRBits = true; |
43 | } else if (Feature == "+bpermd" ) { |
44 | HasBPERMD = true; |
45 | } else if (Feature == "+extdiv" ) { |
46 | HasExtDiv = true; |
47 | } else if (Feature == "+power8-vector" ) { |
48 | HasP8Vector = true; |
49 | } else if (Feature == "+crypto" ) { |
50 | HasP8Crypto = true; |
51 | } else if (Feature == "+direct-move" ) { |
52 | HasDirectMove = true; |
53 | } else if (Feature == "+htm" ) { |
54 | HasHTM = true; |
55 | } else if (Feature == "+float128" ) { |
56 | HasFloat128 = !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 | |
106 | static 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. |
282 | void 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. |
466 | static 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 | |
516 | bool 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. |
697 | void 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. |
709 | void PPCTargetInfo::addP11SpecificFeatures( |
710 | llvm::StringMap<bool> &Features) const {} |
711 | |
712 | // Add features specific to the "Future" CPU. |
713 | void PPCTargetInfo::addFutureSpecificFeatures( |
714 | llvm::StringMap<bool> &Features) const {} |
715 | |
716 | bool 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 | |
750 | void 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. |
806 | const 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 | |
822 | ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const { |
823 | return llvm::ArrayRef(GCCRegNames); |
824 | } |
825 | |
826 | const 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 | |
853 | ArrayRef<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. |
861 | const 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 | |
881 | ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const { |
882 | return llvm::ArrayRef(GCCAddlRegNames); |
883 | } |
884 | |
885 | static 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 | |
898 | bool PPCTargetInfo::isValidCPUName(StringRef Name) const { |
899 | return llvm::is_contained(Range: ValidCPUNames, Element: Name); |
900 | } |
901 | |
902 | void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { |
903 | Values.append(in_start: std::begin(arr: ValidCPUNames), in_end: std::end(arr: ValidCPUNames)); |
904 | } |
905 | |
906 | void 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 | |
920 | ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const { |
921 | return llvm::ArrayRef(BuiltinInfo, |
922 | clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin); |
923 | } |
924 | |
925 | bool 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 | |
945 | bool 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 | |