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