/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/PPC.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- PPC.cpp - Implement PPC target feature support -------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file implements PPC TargetInfo objects. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "PPC.h" |
14 | | #include "clang/Basic/Diagnostic.h" |
15 | | #include "clang/Basic/MacroBuilder.h" |
16 | | #include "clang/Basic/TargetBuiltins.h" |
17 | | |
18 | | using namespace clang; |
19 | | using namespace clang::targets; |
20 | | |
21 | | const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { |
22 | | #define BUILTIN(ID, TYPE, ATTRS) \ |
23 | | {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, |
24 | | #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ |
25 | | {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, |
26 | | #include "clang/Basic/BuiltinsPPC.def" |
27 | | }; |
28 | | |
29 | | /// handleTargetFeatures - Perform initialization based on the user |
30 | | /// configured set of features. |
31 | | bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, |
32 | 3.95k | DiagnosticsEngine &Diags) { |
33 | 3.95k | FloatABI = HardFloat; |
34 | 43.6k | for (const auto &Feature : Features) { |
35 | 43.6k | if (Feature == "+altivec") { |
36 | 210 | HasAltivec = true; |
37 | 43.4k | } else if (Feature == "+vsx") { |
38 | 153 | HasVSX = true; |
39 | 43.2k | } else if (Feature == "+bpermd") { |
40 | 116 | HasBPERMD = true; |
41 | 43.1k | } else if (Feature == "+extdiv") { |
42 | 116 | HasExtDiv = true; |
43 | 43.0k | } else if (Feature == "+power8-vector") { |
44 | 124 | HasP8Vector = true; |
45 | 42.9k | } else if (Feature == "+crypto") { |
46 | 111 | HasP8Crypto = true; |
47 | 42.8k | } else if (Feature == "+direct-move") { |
48 | 110 | HasDirectMove = true; |
49 | 42.6k | } else if (Feature == "+htm") { |
50 | 83 | HasHTM = true; |
51 | 42.6k | } else if (Feature == "+float128") { |
52 | 15 | HasFloat128 = true; |
53 | 42.5k | } else if (Feature == "+power9-vector") { |
54 | 59 | HasP9Vector = true; |
55 | 42.5k | } else if (Feature == "+power10-vector") { |
56 | 32 | HasP10Vector = true; |
57 | 42.5k | } else if (Feature == "+pcrelative-memops") { |
58 | 33 | HasPCRelativeMemops = true; |
59 | 42.4k | } else if (Feature == "+spe" || Feature == "+efpu2"42.4k ) { |
60 | 2 | HasSPE = true; |
61 | 2 | LongDoubleWidth = LongDoubleAlign = 64; |
62 | 2 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
63 | 42.4k | } else if (Feature == "-hard-float") { |
64 | 2 | FloatABI = SoftFloat; |
65 | 42.4k | } else if (Feature == "+paired-vector-memops") { |
66 | 33 | PairedVectorMemops = true; |
67 | 42.4k | } else if (Feature == "+mma") { |
68 | 33 | HasMMA = true; |
69 | 42.4k | } else if (Feature == "+rop-protection") { |
70 | 9 | HasROPProtection = true; |
71 | 9 | } |
72 | | // TODO: Finish this list and add an assert that we've handled them |
73 | | // all. |
74 | 43.6k | } |
75 | | |
76 | 3.95k | return true; |
77 | 3.95k | } |
78 | | |
79 | | /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific |
80 | | /// #defines that are not tied to a specific subtarget. |
81 | | void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, |
82 | 3.94k | MacroBuilder &Builder) const { |
83 | | // Target identification. |
84 | 3.94k | Builder.defineMacro("__ppc__"); |
85 | 3.94k | Builder.defineMacro("__PPC__"); |
86 | 3.94k | Builder.defineMacro("_ARCH_PPC"); |
87 | 3.94k | Builder.defineMacro("__powerpc__"); |
88 | 3.94k | Builder.defineMacro("__POWERPC__"); |
89 | 3.94k | if (PointerWidth == 64) { |
90 | 3.79k | Builder.defineMacro("_ARCH_PPC64"); |
91 | 3.79k | Builder.defineMacro("__powerpc64__"); |
92 | 3.79k | Builder.defineMacro("__ppc64__"); |
93 | 3.79k | Builder.defineMacro("__PPC64__"); |
94 | 3.79k | } |
95 | | |
96 | | // Target properties. |
97 | 3.94k | if (getTriple().getArch() == llvm::Triple::ppc64le || |
98 | 3.57k | getTriple().getArch() == llvm::Triple::ppcle384 ) { |
99 | 3.57k | Builder.defineMacro("_LITTLE_ENDIAN"); |
100 | 377 | } else { |
101 | 377 | if (!getTriple().isOSNetBSD() && |
102 | 371 | !getTriple().isOSOpenBSD()) |
103 | 361 | Builder.defineMacro("_BIG_ENDIAN"); |
104 | 377 | } |
105 | | |
106 | | // ABI options. |
107 | 3.94k | if (ABI == "elfv1") |
108 | 170 | Builder.defineMacro("_CALL_ELF", "1"); |
109 | 3.94k | if (ABI == "elfv2") |
110 | 3.56k | Builder.defineMacro("_CALL_ELF", "2"); |
111 | | |
112 | | // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but |
113 | | // our support post-dates this and it should work on all 64-bit ppc linux |
114 | | // platforms. It is guaranteed to work on all elfv2 platforms. |
115 | 3.94k | if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64298 ) |
116 | 264 | Builder.defineMacro("_CALL_LINUX", "1"); |
117 | | |
118 | | // Subtarget options. |
119 | 3.94k | if (!getTriple().isOSAIX()){ |
120 | 3.81k | Builder.defineMacro("__NATURAL_ALIGNMENT__"); |
121 | 3.81k | } |
122 | 3.94k | Builder.defineMacro("__REGISTER_PREFIX__", ""); |
123 | | |
124 | | // FIXME: Should be controlled by command line option. |
125 | 3.94k | if (LongDoubleWidth == 128) { |
126 | 3.78k | Builder.defineMacro("__LONG_DOUBLE_128__"); |
127 | 3.78k | Builder.defineMacro("__LONGDOUBLE128"); |
128 | 3.78k | if (Opts.PPCIEEELongDouble) |
129 | 6 | Builder.defineMacro("__LONG_DOUBLE_IEEE128__"); |
130 | 3.77k | else |
131 | 3.77k | Builder.defineMacro("__LONG_DOUBLE_IBM128__"); |
132 | 3.78k | } |
133 | | |
134 | | // Define this for elfv2 (64-bit only) or 64-bit darwin. |
135 | 3.94k | if (ABI == "elfv2" || |
136 | 381 | (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 645 )) |
137 | 3.56k | Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16"); |
138 | | |
139 | 3.94k | if (ArchDefs & ArchDefineName) |
140 | 3 | Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper())); |
141 | 3.94k | if (ArchDefs & ArchDefinePpcgr) |
142 | 144 | Builder.defineMacro("_ARCH_PPCGR"); |
143 | 3.94k | if (ArchDefs & ArchDefinePpcsq) |
144 | 139 | Builder.defineMacro("_ARCH_PPCSQ"); |
145 | 3.94k | if (ArchDefs & ArchDefine440) |
146 | 0 | Builder.defineMacro("_ARCH_440"); |
147 | 3.94k | if (ArchDefs & ArchDefine603) |
148 | 2 | Builder.defineMacro("_ARCH_603"); |
149 | 3.94k | if (ArchDefs & ArchDefine604) |
150 | 0 | Builder.defineMacro("_ARCH_604"); |
151 | 3.94k | if (ArchDefs & ArchDefinePwr4) |
152 | 139 | Builder.defineMacro("_ARCH_PWR4"); |
153 | 3.94k | if (ArchDefs & ArchDefinePwr5) |
154 | 135 | Builder.defineMacro("_ARCH_PWR5"); |
155 | 3.94k | if (ArchDefs & ArchDefinePwr5x) |
156 | 133 | Builder.defineMacro("_ARCH_PWR5X"); |
157 | 3.94k | if (ArchDefs & ArchDefinePwr6) |
158 | 131 | Builder.defineMacro("_ARCH_PWR6"); |
159 | 3.94k | if (ArchDefs & ArchDefinePwr6x) |
160 | 2 | Builder.defineMacro("_ARCH_PWR6X"); |
161 | 3.94k | if (ArchDefs & ArchDefinePwr7) |
162 | 123 | Builder.defineMacro("_ARCH_PWR7"); |
163 | 3.94k | if (ArchDefs & ArchDefinePwr8) |
164 | 116 | Builder.defineMacro("_ARCH_PWR8"); |
165 | 3.94k | if (ArchDefs & ArchDefinePwr9) |
166 | 55 | Builder.defineMacro("_ARCH_PWR9"); |
167 | 3.94k | if (ArchDefs & ArchDefinePwr10) |
168 | 34 | Builder.defineMacro("_ARCH_PWR10"); |
169 | 3.94k | if (ArchDefs & ArchDefineA2) |
170 | 0 | Builder.defineMacro("_ARCH_A2"); |
171 | 3.94k | if (ArchDefs & ArchDefineE500) |
172 | 1 | Builder.defineMacro("__NO_LWSYNC__"); |
173 | 3.94k | if (ArchDefs & ArchDefineFuture) |
174 | 11 | Builder.defineMacro("_ARCH_PWR_FUTURE"); |
175 | | |
176 | 3.94k | if (HasAltivec) { |
177 | 210 | Builder.defineMacro("__VEC__", "10206"); |
178 | 210 | Builder.defineMacro("__ALTIVEC__"); |
179 | 210 | } |
180 | 3.94k | if (HasSPE) { |
181 | 2 | Builder.defineMacro("__SPE__"); |
182 | 2 | Builder.defineMacro("__NO_FPRS__"); |
183 | 2 | } |
184 | 3.94k | if (HasVSX) |
185 | 153 | Builder.defineMacro("__VSX__"); |
186 | 3.94k | if (HasP8Vector) |
187 | 124 | Builder.defineMacro("__POWER8_VECTOR__"); |
188 | 3.94k | if (HasP8Crypto) |
189 | 111 | Builder.defineMacro("__CRYPTO__"); |
190 | 3.94k | if (HasHTM) |
191 | 83 | Builder.defineMacro("__HTM__"); |
192 | 3.94k | if (HasFloat128) |
193 | 15 | Builder.defineMacro("__FLOAT128__"); |
194 | 3.94k | if (HasP9Vector) |
195 | 59 | Builder.defineMacro("__POWER9_VECTOR__"); |
196 | 3.94k | if (HasMMA) |
197 | 33 | Builder.defineMacro("__MMA__"); |
198 | 3.94k | if (HasROPProtection) |
199 | 9 | Builder.defineMacro("__ROP_PROTECTION__"); |
200 | 3.94k | if (HasP10Vector) |
201 | 32 | Builder.defineMacro("__POWER10_VECTOR__"); |
202 | | |
203 | 3.94k | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); |
204 | 3.94k | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); |
205 | 3.94k | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); |
206 | 3.94k | if (PointerWidth == 64) |
207 | 3.79k | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); |
208 | | |
209 | | // We have support for the bswap intrinsics so we can define this. |
210 | 3.94k | Builder.defineMacro("__HAVE_BSWAP__", "1"); |
211 | | |
212 | | // FIXME: The following are not yet generated here by Clang, but are |
213 | | // generated by GCC: |
214 | | // |
215 | | // _SOFT_FLOAT_ |
216 | | // __RECIP_PRECISION__ |
217 | | // __APPLE_ALTIVEC__ |
218 | | // __RECIP__ |
219 | | // __RECIPF__ |
220 | | // __RSQRTE__ |
221 | | // __RSQRTEF__ |
222 | | // _SOFT_DOUBLE_ |
223 | | // __NO_LWSYNC__ |
224 | | // __CMODEL_MEDIUM__ |
225 | | // __CMODEL_LARGE__ |
226 | | // _CALL_SYSV |
227 | | // _CALL_DARWIN |
228 | 3.94k | } |
229 | | |
230 | | // Handle explicit options being passed to the compiler here: if we've |
231 | | // explicitly turned off vsx and turned on any of: |
232 | | // - power8-vector |
233 | | // - direct-move |
234 | | // - float128 |
235 | | // - power9-vector |
236 | | // - paired-vector-memops |
237 | | // - mma |
238 | | // - power10-vector |
239 | | // then go ahead and error since the customer has expressed an incompatible |
240 | | // set of options. |
241 | | static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, |
242 | 4.02k | const std::vector<std::string> &FeaturesVec) { |
243 | | |
244 | | // vsx was not explicitly turned off. |
245 | 4.02k | if (llvm::find(FeaturesVec, "-vsx") == FeaturesVec.end()) |
246 | 4.00k | return true; |
247 | | |
248 | 175 | auto FindVSXSubfeature = [&](StringRef Feature, StringRef Option) 25 { |
249 | 175 | if (llvm::find(FeaturesVec, Feature) != FeaturesVec.end()) { |
250 | 19 | Diags.Report(diag::err_opt_not_valid_with_opt) << Option << "-mno-vsx"; |
251 | 19 | return true; |
252 | 19 | } |
253 | 156 | return false; |
254 | 156 | }; |
255 | | |
256 | 25 | bool Found = FindVSXSubfeature("+power8-vector", "-mpower8-vector"); |
257 | 25 | Found |= FindVSXSubfeature("+direct-move", "-mdirect-move"); |
258 | 25 | Found |= FindVSXSubfeature("+float128", "-mfloat128"); |
259 | 25 | Found |= FindVSXSubfeature("+power9-vector", "-mpower9-vector"); |
260 | 25 | Found |= FindVSXSubfeature("+paired-vector-memops", "-mpaired-vector-memops"); |
261 | 25 | Found |= FindVSXSubfeature("+mma", "-mmma"); |
262 | 25 | Found |= FindVSXSubfeature("+power10-vector", "-mpower10-vector"); |
263 | | |
264 | | // Return false if any vsx subfeatures was found. |
265 | 25 | return !Found; |
266 | 25 | } |
267 | | |
268 | | bool PPCTargetInfo::initFeatureMap( |
269 | | llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, |
270 | 4.02k | const std::vector<std::string> &FeaturesVec) const { |
271 | 4.02k | Features["altivec"] = llvm::StringSwitch<bool>(CPU) |
272 | 4.02k | .Case("7400", true) |
273 | 4.02k | .Case("g4", true) |
274 | 4.02k | .Case("7450", true) |
275 | 4.02k | .Case("g4+", true) |
276 | 4.02k | .Case("970", true) |
277 | 4.02k | .Case("g5", true) |
278 | 4.02k | .Case("pwr6", true) |
279 | 4.02k | .Case("pwr7", true) |
280 | 4.02k | .Case("pwr8", true) |
281 | 4.02k | .Case("pwr9", true) |
282 | 4.02k | .Case("ppc64", true) |
283 | 4.02k | .Case("ppc64le", true) |
284 | 4.02k | .Default(false); |
285 | | |
286 | 4.02k | Features["power9-vector"] = (CPU == "pwr9"); |
287 | 4.02k | Features["crypto"] = llvm::StringSwitch<bool>(CPU) |
288 | 4.02k | .Case("ppc64le", true) |
289 | 4.02k | .Case("pwr9", true) |
290 | 4.02k | .Case("pwr8", true) |
291 | 4.02k | .Default(false); |
292 | 4.02k | Features["power8-vector"] = llvm::StringSwitch<bool>(CPU) |
293 | 4.02k | .Case("ppc64le", true) |
294 | 4.02k | .Case("pwr9", true) |
295 | 4.02k | .Case("pwr8", true) |
296 | 4.02k | .Default(false); |
297 | 4.02k | Features["bpermd"] = llvm::StringSwitch<bool>(CPU) |
298 | 4.02k | .Case("ppc64le", true) |
299 | 4.02k | .Case("pwr9", true) |
300 | 4.02k | .Case("pwr8", true) |
301 | 4.02k | .Case("pwr7", true) |
302 | 4.02k | .Default(false); |
303 | 4.02k | Features["extdiv"] = llvm::StringSwitch<bool>(CPU) |
304 | 4.02k | .Case("ppc64le", true) |
305 | 4.02k | .Case("pwr9", true) |
306 | 4.02k | .Case("pwr8", true) |
307 | 4.02k | .Case("pwr7", true) |
308 | 4.02k | .Default(false); |
309 | 4.02k | Features["direct-move"] = llvm::StringSwitch<bool>(CPU) |
310 | 4.02k | .Case("ppc64le", true) |
311 | 4.02k | .Case("pwr9", true) |
312 | 4.02k | .Case("pwr8", true) |
313 | 4.02k | .Default(false); |
314 | 4.02k | Features["vsx"] = llvm::StringSwitch<bool>(CPU) |
315 | 4.02k | .Case("ppc64le", true) |
316 | 4.02k | .Case("pwr9", true) |
317 | 4.02k | .Case("pwr8", true) |
318 | 4.02k | .Case("pwr7", true) |
319 | 4.02k | .Default(false); |
320 | 4.02k | Features["htm"] = llvm::StringSwitch<bool>(CPU) |
321 | 4.02k | .Case("ppc64le", true) |
322 | 4.02k | .Case("pwr9", true) |
323 | 4.02k | .Case("pwr8", true) |
324 | 4.02k | .Default(false); |
325 | | |
326 | | // ROP Protection is off by default. |
327 | 4.02k | Features["rop-protection"] = false; |
328 | | |
329 | 4.02k | Features["spe"] = llvm::StringSwitch<bool>(CPU) |
330 | 4.02k | .Case("8548", true) |
331 | 4.02k | .Case("e500", true) |
332 | 4.02k | .Default(false); |
333 | | |
334 | | // Power10 includes all the same features as Power9 plus any features specific |
335 | | // to the Power10 core. |
336 | 4.02k | if (CPU == "pwr10" || CPU == "power10"3.99k ) { |
337 | 38 | initFeatureMap(Features, Diags, "pwr9", FeaturesVec); |
338 | 38 | addP10SpecificFeatures(Features); |
339 | 38 | } |
340 | | |
341 | | // Future CPU should include all of the features of Power 10 as well as any |
342 | | // additional features (yet to be determined) specific to it. |
343 | 4.02k | if (CPU == "future") { |
344 | 12 | initFeatureMap(Features, Diags, "pwr10", FeaturesVec); |
345 | 12 | addFutureSpecificFeatures(Features); |
346 | 12 | } |
347 | | |
348 | 4.02k | if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) |
349 | 18 | return false; |
350 | | |
351 | 4.01k | if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr)3.91k && |
352 | 97 | llvm::find(FeaturesVec, "+float128") != FeaturesVec.end()) { |
353 | | // We have __float128 on PPC but not power 9 and above. |
354 | 3 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU; |
355 | 3 | return false; |
356 | 3 | } |
357 | | |
358 | 4.00k | if (!(ArchDefs & ArchDefinePwr10) && |
359 | 3.92k | llvm::find(FeaturesVec, "+mma") != FeaturesVec.end()) { |
360 | | // We have MMA on PPC but not power 10 and above. |
361 | 4 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU; |
362 | 4 | return false; |
363 | 4 | } |
364 | | |
365 | 4.00k | if (!(ArchDefs & ArchDefinePwr8) && |
366 | 3.84k | llvm::find(FeaturesVec, "+rop-protection") != FeaturesVec.end()) { |
367 | | // We can turn on ROP Protection on Power 8 and above. |
368 | 2 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protection" << CPU; |
369 | 2 | return false; |
370 | 2 | } |
371 | | |
372 | 4.00k | return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); |
373 | 4.00k | } |
374 | | |
375 | | // Add any Power10 specific features. |
376 | | void PPCTargetInfo::addP10SpecificFeatures( |
377 | 38 | llvm::StringMap<bool> &Features) const { |
378 | 38 | Features["htm"] = false; // HTM was removed for P10. |
379 | 38 | Features["paired-vector-memops"] = true; |
380 | 38 | Features["mma"] = true; |
381 | 38 | Features["power10-vector"] = true; |
382 | 38 | Features["pcrelative-memops"] = true; |
383 | 38 | return; |
384 | 38 | } |
385 | | |
386 | | // Add features specific to the "Future" CPU. |
387 | | void PPCTargetInfo::addFutureSpecificFeatures( |
388 | 12 | llvm::StringMap<bool> &Features) const { |
389 | 12 | return; |
390 | 12 | } |
391 | | |
392 | 31.9k | bool PPCTargetInfo::hasFeature(StringRef Feature) const { |
393 | 31.9k | return llvm::StringSwitch<bool>(Feature) |
394 | 31.9k | .Case("powerpc", true) |
395 | 31.9k | .Case("altivec", HasAltivec) |
396 | 31.9k | .Case("vsx", HasVSX) |
397 | 31.9k | .Case("power8-vector", HasP8Vector) |
398 | 31.9k | .Case("crypto", HasP8Crypto) |
399 | 31.9k | .Case("direct-move", HasDirectMove) |
400 | 31.9k | .Case("htm", HasHTM) |
401 | 31.9k | .Case("bpermd", HasBPERMD) |
402 | 31.9k | .Case("extdiv", HasExtDiv) |
403 | 31.9k | .Case("float128", HasFloat128) |
404 | 31.9k | .Case("power9-vector", HasP9Vector) |
405 | 31.9k | .Case("paired-vector-memops", PairedVectorMemops) |
406 | 31.9k | .Case("power10-vector", HasP10Vector) |
407 | 31.9k | .Case("pcrelative-memops", HasPCRelativeMemops) |
408 | 31.9k | .Case("spe", HasSPE) |
409 | 31.9k | .Case("mma", HasMMA) |
410 | 31.9k | .Case("rop-protection", HasROPProtection) |
411 | 31.9k | .Default(false); |
412 | 31.9k | } |
413 | | |
414 | | void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, |
415 | 259 | StringRef Name, bool Enabled) const { |
416 | 259 | if (Enabled) { |
417 | 184 | if (Name == "efpu2") |
418 | 0 | Features["spe"] = true; |
419 | | // If we're enabling any of the vsx based features then enable vsx and |
420 | | // altivec. We'll diagnose any problems later. |
421 | 184 | bool FeatureHasVSX = llvm::StringSwitch<bool>(Name) |
422 | 184 | .Case("vsx", true) |
423 | 184 | .Case("direct-move", true) |
424 | 184 | .Case("power8-vector", true) |
425 | 184 | .Case("power9-vector", true) |
426 | 184 | .Case("paired-vector-memops", true) |
427 | 184 | .Case("power10-vector", true) |
428 | 184 | .Case("float128", true) |
429 | 184 | .Case("mma", true) |
430 | 184 | .Default(false); |
431 | 184 | if (FeatureHasVSX) |
432 | 77 | Features["vsx"] = Features["altivec"] = true; |
433 | 184 | if (Name == "power9-vector") |
434 | 7 | Features["power8-vector"] = true; |
435 | 177 | else if (Name == "power10-vector") |
436 | 4 | Features["power8-vector"] = Features["power9-vector"] = true; |
437 | 184 | if (Name == "pcrel") |
438 | 2 | Features["pcrelative-memops"] = true; |
439 | 182 | else |
440 | 182 | Features[Name] = true; |
441 | 75 | } else { |
442 | 75 | if (Name == "spe") |
443 | 5 | Features["efpu2"] = false; |
444 | | // If we're disabling altivec or vsx go ahead and disable all of the vsx |
445 | | // features. |
446 | 75 | if ((Name == "altivec") || (Name == "vsx")70 ) |
447 | 12 | Features["vsx"] = Features["direct-move"] = Features["power8-vector"] = |
448 | 12 | Features["float128"] = Features["power9-vector"] = |
449 | 12 | Features["paired-vector-memops"] = Features["mma"] = |
450 | 12 | Features["power10-vector"] = false; |
451 | 75 | if (Name == "power8-vector") |
452 | 6 | Features["power9-vector"] = Features["paired-vector-memops"] = |
453 | 6 | Features["mma"] = Features["power10-vector"] = false; |
454 | 69 | else if (Name == "power9-vector") |
455 | 5 | Features["paired-vector-memops"] = Features["mma"] = |
456 | 5 | Features["power10-vector"] = false; |
457 | 75 | if (Name == "pcrel") |
458 | 2 | Features["pcrelative-memops"] = false; |
459 | 73 | else |
460 | 73 | Features[Name] = false; |
461 | 75 | } |
462 | 259 | } |
463 | | |
464 | | const char *const PPCTargetInfo::GCCRegNames[] = { |
465 | | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", |
466 | | "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", |
467 | | "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", |
468 | | "r27", "r28", "r29", "r30", "r31", "f0", "f1", "f2", "f3", |
469 | | "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", |
470 | | "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", |
471 | | "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", |
472 | | "f31", "mq", "lr", "ctr", "ap", "cr0", "cr1", "cr2", "cr3", |
473 | | "cr4", "cr5", "cr6", "cr7", "xer", "v0", "v1", "v2", "v3", |
474 | | "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", |
475 | | "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", |
476 | | "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", |
477 | | "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp" |
478 | | }; |
479 | | |
480 | 114 | ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const { |
481 | 114 | return llvm::makeArrayRef(GCCRegNames); |
482 | 114 | } |
483 | | |
484 | | const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { |
485 | | // While some of these aliases do map to different registers |
486 | | // they still share the same register name. |
487 | | {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"}, |
488 | | {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"}, |
489 | | {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"}, |
490 | | {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"}, |
491 | | {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"}, |
492 | | {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"}, |
493 | | {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"}, |
494 | | {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"}, |
495 | | {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"}, |
496 | | {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"}, |
497 | | {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"}, |
498 | | {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"}, |
499 | | {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"}, |
500 | | {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"}, |
501 | | {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"}, |
502 | | {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"}, |
503 | | {{"cc"}, "cr0"}, |
504 | | }; |
505 | | |
506 | 100 | ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const { |
507 | 100 | return llvm::makeArrayRef(GCCRegAliases); |
508 | 100 | } |
509 | | |
510 | | // PPC ELFABIv2 DWARF Definitoin "Table 2.26. Mappings of Common Registers". |
511 | | // vs0 ~ vs31 is mapping to 32 - 63, |
512 | | // vs32 ~ vs63 is mapping to 77 - 108. |
513 | | const TargetInfo::AddlRegName GCCAddlRegNames[] = { |
514 | | // Table of additional register names to use in user input. |
515 | | {{"vs0"}, 32}, {{"vs1"}, 33}, {{"vs2"}, 34}, {{"vs3"}, 35}, |
516 | | {{"vs4"}, 36}, {{"vs5"}, 37}, {{"vs6"}, 38}, {{"vs7"}, 39}, |
517 | | {{"vs8"}, 40}, {{"vs9"}, 41}, {{"vs10"}, 42}, {{"vs11"}, 43}, |
518 | | {{"vs12"}, 44}, {{"vs13"}, 45}, {{"vs14"}, 46}, {{"vs15"}, 47}, |
519 | | {{"vs16"}, 48}, {{"vs17"}, 49}, {{"vs18"}, 50}, {{"vs19"}, 51}, |
520 | | {{"vs20"}, 52}, {{"vs21"}, 53}, {{"vs22"}, 54}, {{"vs23"}, 55}, |
521 | | {{"vs24"}, 56}, {{"vs25"}, 57}, {{"vs26"}, 58}, {{"vs27"}, 59}, |
522 | | {{"vs28"}, 60}, {{"vs29"}, 61}, {{"vs30"}, 62}, {{"vs31"}, 63}, |
523 | | {{"vs32"}, 77}, {{"vs33"}, 78}, {{"vs34"}, 79}, {{"vs35"}, 80}, |
524 | | {{"vs36"}, 81}, {{"vs37"}, 82}, {{"vs38"}, 83}, {{"vs39"}, 84}, |
525 | | {{"vs40"}, 85}, {{"vs41"}, 86}, {{"vs42"}, 87}, {{"vs43"}, 88}, |
526 | | {{"vs44"}, 89}, {{"vs45"}, 90}, {{"vs46"}, 91}, {{"vs47"}, 92}, |
527 | | {{"vs48"}, 93}, {{"vs49"}, 94}, {{"vs50"}, 95}, {{"vs51"}, 96}, |
528 | | {{"vs52"}, 97}, {{"vs53"}, 98}, {{"vs54"}, 99}, {{"vs55"}, 100}, |
529 | | {{"vs56"}, 101}, {{"vs57"}, 102}, {{"vs58"}, 103}, {{"vs59"}, 104}, |
530 | | {{"vs60"}, 105}, {{"vs61"}, 106}, {{"vs62"}, 107}, {{"vs63"}, 108}, |
531 | | }; |
532 | | |
533 | 105 | ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const { |
534 | 105 | if (ABI == "elfv2") |
535 | 44 | return llvm::makeArrayRef(GCCAddlRegNames); |
536 | 61 | else |
537 | 61 | return TargetInfo::getGCCAddlRegNames(); |
538 | 105 | } |
539 | | |
540 | | static constexpr llvm::StringLiteral ValidCPUNames[] = { |
541 | | {"generic"}, {"440"}, {"450"}, {"601"}, {"602"}, |
542 | | {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"}, |
543 | | {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"}, |
544 | | {"7450"}, {"g4+"}, {"750"}, {"8548"}, {"970"}, |
545 | | {"g5"}, {"a2"}, {"e500"}, {"e500mc"}, {"e5500"}, |
546 | | {"power3"}, {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"}, |
547 | | {"pwr5"}, {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"}, |
548 | | {"power6x"}, {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"}, |
549 | | {"pwr8"}, {"power9"}, {"pwr9"}, {"power10"}, {"pwr10"}, |
550 | | {"powerpc"}, {"ppc"}, {"powerpc64"}, {"ppc64"}, {"powerpc64le"}, |
551 | | {"ppc64le"}, {"future"}}; |
552 | | |
553 | 184 | bool PPCTargetInfo::isValidCPUName(StringRef Name) const { |
554 | 184 | return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); |
555 | 184 | } |
556 | | |
557 | 1 | void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { |
558 | 1 | Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); |
559 | 1 | } |
560 | | |
561 | 7.76k | void PPCTargetInfo::adjust(LangOptions &Opts) { |
562 | 7.76k | if (HasAltivec) |
563 | 408 | Opts.AltiVec = 1; |
564 | 7.76k | TargetInfo::adjust(Opts); |
565 | 7.76k | if (LongDoubleFormat != &llvm::APFloat::IEEEdouble()) |
566 | 7.43k | LongDoubleFormat = Opts.PPCIEEELongDouble |
567 | 12 | ? &llvm::APFloat::IEEEquad() |
568 | 7.42k | : &llvm::APFloat::PPCDoubleDouble(); |
569 | 7.76k | } |
570 | | |
571 | 3.94k | ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const { |
572 | 3.94k | return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin - |
573 | 3.94k | Builtin::FirstTSBuiltin); |
574 | 3.94k | } |