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 |
Definitions
- NumBuiltins
- BuiltinStrings
- BuiltinInfos
- handleTargetFeatures
- defineXLCompatMacros
- getTargetDefines
- ppcUserFeaturesCheck
- initFeatureMap
- addP10SpecificFeatures
- addP11SpecificFeatures
- addFutureSpecificFeatures
- hasFeature
- setFeatureEnabled
- GCCRegNames
- getGCCRegNames
- GCCRegAliases
- getGCCRegAliases
- GCCAddlRegNames
- getGCCAddlRegNames
- isValidCPUName
- fillValidCPUList
- adjust
- getTargetBuiltins
- validateCpuSupports
Learn to use CMake with our Intro Training
Find out more