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