1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
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 | |
30 | |
31 | bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, |
32 | DiagnosticsEngine &Diags) { |
33 | for (const auto &Feature : Features) { |
34 | if (Feature == "+altivec") { |
35 | HasAltivec = true; |
36 | } else if (Feature == "+vsx") { |
37 | HasVSX = true; |
38 | } else if (Feature == "+bpermd") { |
39 | HasBPERMD = true; |
40 | } else if (Feature == "+extdiv") { |
41 | HasExtDiv = true; |
42 | } else if (Feature == "+power8-vector") { |
43 | HasP8Vector = true; |
44 | } else if (Feature == "+crypto") { |
45 | HasP8Crypto = true; |
46 | } else if (Feature == "+direct-move") { |
47 | HasDirectMove = true; |
48 | } else if (Feature == "+qpx") { |
49 | HasQPX = true; |
50 | } else if (Feature == "+htm") { |
51 | HasHTM = true; |
52 | } else if (Feature == "+float128") { |
53 | HasFloat128 = true; |
54 | } else if (Feature == "+power9-vector") { |
55 | HasP9Vector = true; |
56 | } |
57 | |
58 | |
59 | } |
60 | |
61 | return true; |
62 | } |
63 | |
64 | |
65 | |
66 | void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, |
67 | MacroBuilder &Builder) const { |
68 | |
69 | Builder.defineMacro("__ppc__"); |
70 | Builder.defineMacro("__PPC__"); |
71 | Builder.defineMacro("_ARCH_PPC"); |
72 | Builder.defineMacro("__powerpc__"); |
73 | Builder.defineMacro("__POWERPC__"); |
74 | if (PointerWidth == 64) { |
75 | Builder.defineMacro("_ARCH_PPC64"); |
76 | Builder.defineMacro("__powerpc64__"); |
77 | Builder.defineMacro("__ppc64__"); |
78 | Builder.defineMacro("__PPC64__"); |
79 | } |
80 | |
81 | |
82 | if (getTriple().getArch() == llvm::Triple::ppc64le) { |
83 | Builder.defineMacro("_LITTLE_ENDIAN"); |
84 | } else { |
85 | if (!getTriple().isOSNetBSD() && |
86 | !getTriple().isOSOpenBSD()) |
87 | Builder.defineMacro("_BIG_ENDIAN"); |
88 | } |
89 | |
90 | |
91 | if (ABI == "elfv1" || ABI == "elfv1-qpx") |
92 | Builder.defineMacro("_CALL_ELF", "1"); |
93 | if (ABI == "elfv2") |
94 | Builder.defineMacro("_CALL_ELF", "2"); |
95 | |
96 | |
97 | |
98 | |
99 | if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64) |
100 | Builder.defineMacro("_CALL_LINUX", "1"); |
101 | |
102 | |
103 | if (!getTriple().isOSAIX()){ |
104 | Builder.defineMacro("__NATURAL_ALIGNMENT__"); |
105 | } |
106 | Builder.defineMacro("__REGISTER_PREFIX__", ""); |
107 | |
108 | |
109 | if (LongDoubleWidth == 128) { |
110 | Builder.defineMacro("__LONG_DOUBLE_128__"); |
111 | Builder.defineMacro("__LONGDOUBLE128"); |
112 | } |
113 | |
114 | |
115 | if (ABI == "elfv2" || |
116 | (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64)) |
117 | Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16"); |
118 | |
119 | if (ArchDefs & ArchDefineName) |
120 | Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper())); |
121 | if (ArchDefs & ArchDefinePpcgr) |
122 | Builder.defineMacro("_ARCH_PPCGR"); |
123 | if (ArchDefs & ArchDefinePpcsq) |
124 | Builder.defineMacro("_ARCH_PPCSQ"); |
125 | if (ArchDefs & ArchDefine440) |
126 | Builder.defineMacro("_ARCH_440"); |
127 | if (ArchDefs & ArchDefine603) |
128 | Builder.defineMacro("_ARCH_603"); |
129 | if (ArchDefs & ArchDefine604) |
130 | Builder.defineMacro("_ARCH_604"); |
131 | if (ArchDefs & ArchDefinePwr4) |
132 | Builder.defineMacro("_ARCH_PWR4"); |
133 | if (ArchDefs & ArchDefinePwr5) |
134 | Builder.defineMacro("_ARCH_PWR5"); |
135 | if (ArchDefs & ArchDefinePwr5x) |
136 | Builder.defineMacro("_ARCH_PWR5X"); |
137 | if (ArchDefs & ArchDefinePwr6) |
138 | Builder.defineMacro("_ARCH_PWR6"); |
139 | if (ArchDefs & ArchDefinePwr6x) |
140 | Builder.defineMacro("_ARCH_PWR6X"); |
141 | if (ArchDefs & ArchDefinePwr7) |
142 | Builder.defineMacro("_ARCH_PWR7"); |
143 | if (ArchDefs & ArchDefinePwr8) |
144 | Builder.defineMacro("_ARCH_PWR8"); |
145 | if (ArchDefs & ArchDefinePwr9) |
146 | Builder.defineMacro("_ARCH_PWR9"); |
147 | if (ArchDefs & ArchDefineA2) |
148 | Builder.defineMacro("_ARCH_A2"); |
149 | if (ArchDefs & ArchDefineA2q) { |
150 | Builder.defineMacro("_ARCH_A2Q"); |
151 | Builder.defineMacro("_ARCH_QP"); |
152 | } |
153 | |
154 | if (getTriple().getVendor() == llvm::Triple::BGQ) { |
155 | Builder.defineMacro("__bg__"); |
156 | Builder.defineMacro("__THW_BLUEGENE__"); |
157 | Builder.defineMacro("__bgq__"); |
158 | Builder.defineMacro("__TOS_BGQ__"); |
159 | } |
160 | |
161 | if (HasAltivec) { |
162 | Builder.defineMacro("__VEC__", "10206"); |
163 | Builder.defineMacro("__ALTIVEC__"); |
164 | } |
165 | if (HasVSX) |
166 | Builder.defineMacro("__VSX__"); |
167 | if (HasP8Vector) |
168 | Builder.defineMacro("__POWER8_VECTOR__"); |
169 | if (HasP8Crypto) |
170 | Builder.defineMacro("__CRYPTO__"); |
171 | if (HasHTM) |
172 | Builder.defineMacro("__HTM__"); |
173 | if (HasFloat128) |
174 | Builder.defineMacro("__FLOAT128__"); |
175 | if (HasP9Vector) |
176 | Builder.defineMacro("__POWER9_VECTOR__"); |
177 | |
178 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); |
179 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); |
180 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); |
181 | if (PointerWidth == 64) |
182 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); |
183 | |
184 | |
185 | Builder.defineMacro("__HAVE_BSWAP__", "1"); |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | } |
205 | |
206 | |
207 | |
208 | |
209 | |
210 | |
211 | |
212 | |
213 | |
214 | static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, |
215 | const std::vector<std::string> &FeaturesVec) { |
216 | |
217 | if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "-vsx") != |
218 | FeaturesVec.end()) { |
219 | if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power8-vector") != |
220 | FeaturesVec.end()) { |
221 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower8-vector" |
222 | << "-mno-vsx"; |
223 | return false; |
224 | } |
225 | |
226 | if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+direct-move") != |
227 | FeaturesVec.end()) { |
228 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mdirect-move" |
229 | << "-mno-vsx"; |
230 | return false; |
231 | } |
232 | |
233 | if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") != |
234 | FeaturesVec.end()) { |
235 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" |
236 | << "-mno-vsx"; |
237 | return false; |
238 | } |
239 | |
240 | if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power9-vector") != |
241 | FeaturesVec.end()) { |
242 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower9-vector" |
243 | << "-mno-vsx"; |
244 | return false; |
245 | } |
246 | } |
247 | |
248 | return true; |
249 | } |
250 | |
251 | bool PPCTargetInfo::initFeatureMap( |
252 | llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, |
253 | const std::vector<std::string> &FeaturesVec) const { |
254 | Features["altivec"] = llvm::StringSwitch<bool>(CPU) |
255 | .Case("7400", true) |
256 | .Case("g4", true) |
257 | .Case("7450", true) |
258 | .Case("g4+", true) |
259 | .Case("970", true) |
260 | .Case("g5", true) |
261 | .Case("pwr6", true) |
262 | .Case("pwr7", true) |
263 | .Case("pwr8", true) |
264 | .Case("pwr9", true) |
265 | .Case("ppc64", true) |
266 | .Case("ppc64le", true) |
267 | .Default(false); |
268 | |
269 | Features["qpx"] = (CPU == "a2q"); |
270 | Features["power9-vector"] = (CPU == "pwr9"); |
271 | Features["crypto"] = llvm::StringSwitch<bool>(CPU) |
272 | .Case("ppc64le", true) |
273 | .Case("pwr9", true) |
274 | .Case("pwr8", true) |
275 | .Default(false); |
276 | Features["power8-vector"] = llvm::StringSwitch<bool>(CPU) |
277 | .Case("ppc64le", true) |
278 | .Case("pwr9", true) |
279 | .Case("pwr8", true) |
280 | .Default(false); |
281 | Features["bpermd"] = llvm::StringSwitch<bool>(CPU) |
282 | .Case("ppc64le", true) |
283 | .Case("pwr9", true) |
284 | .Case("pwr8", true) |
285 | .Case("pwr7", true) |
286 | .Default(false); |
287 | Features["extdiv"] = llvm::StringSwitch<bool>(CPU) |
288 | .Case("ppc64le", true) |
289 | .Case("pwr9", true) |
290 | .Case("pwr8", true) |
291 | .Case("pwr7", true) |
292 | .Default(false); |
293 | Features["direct-move"] = llvm::StringSwitch<bool>(CPU) |
294 | .Case("ppc64le", true) |
295 | .Case("pwr9", true) |
296 | .Case("pwr8", true) |
297 | .Default(false); |
298 | Features["vsx"] = llvm::StringSwitch<bool>(CPU) |
299 | .Case("ppc64le", true) |
300 | .Case("pwr9", true) |
301 | .Case("pwr8", true) |
302 | .Case("pwr7", true) |
303 | .Default(false); |
304 | Features["htm"] = llvm::StringSwitch<bool>(CPU) |
305 | .Case("ppc64le", true) |
306 | .Case("pwr9", true) |
307 | .Case("pwr8", true) |
308 | .Default(false); |
309 | |
310 | if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) |
311 | return false; |
312 | |
313 | if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) && |
314 | std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") != |
315 | FeaturesVec.end()) { |
316 | |
317 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU; |
318 | return false; |
319 | } |
320 | |
321 | return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); |
322 | } |
323 | |
324 | bool PPCTargetInfo::hasFeature(StringRef Feature) const { |
325 | return llvm::StringSwitch<bool>(Feature) |
326 | .Case("powerpc", true) |
327 | .Case("altivec", HasAltivec) |
328 | .Case("vsx", HasVSX) |
329 | .Case("power8-vector", HasP8Vector) |
330 | .Case("crypto", HasP8Crypto) |
331 | .Case("direct-move", HasDirectMove) |
332 | .Case("qpx", HasQPX) |
333 | .Case("htm", HasHTM) |
334 | .Case("bpermd", HasBPERMD) |
335 | .Case("extdiv", HasExtDiv) |
336 | .Case("float128", HasFloat128) |
337 | .Case("power9-vector", HasP9Vector) |
338 | .Default(false); |
339 | } |
340 | |
341 | void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, |
342 | StringRef Name, bool Enabled) const { |
343 | if (Enabled) { |
344 | |
345 | |
346 | bool FeatureHasVSX = llvm::StringSwitch<bool>(Name) |
347 | .Case("vsx", true) |
348 | .Case("direct-move", true) |
349 | .Case("power8-vector", true) |
350 | .Case("power9-vector", true) |
351 | .Case("float128", true) |
352 | .Default(false); |
353 | if (FeatureHasVSX) |
354 | Features["vsx"] = Features["altivec"] = true; |
355 | if (Name == "power9-vector") |
356 | Features["power8-vector"] = true; |
357 | Features[Name] = true; |
358 | } else { |
359 | |
360 | |
361 | if ((Name == "altivec") || (Name == "vsx")) |
362 | Features["vsx"] = Features["direct-move"] = Features["power8-vector"] = |
363 | Features["float128"] = Features["power9-vector"] = false; |
364 | if (Name == "power8-vector") |
365 | Features["power9-vector"] = false; |
366 | Features[Name] = false; |
367 | } |
368 | } |
369 | |
370 | const char *const PPCTargetInfo::GCCRegNames[] = { |
371 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", |
372 | "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", |
373 | "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", |
374 | "r27", "r28", "r29", "r30", "r31", "f0", "f1", "f2", "f3", |
375 | "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", |
376 | "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", |
377 | "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", |
378 | "f31", "mq", "lr", "ctr", "ap", "cr0", "cr1", "cr2", "cr3", |
379 | "cr4", "cr5", "cr6", "cr7", "xer", "v0", "v1", "v2", "v3", |
380 | "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", |
381 | "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", |
382 | "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", |
383 | "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp" |
384 | }; |
385 | |
386 | ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const { |
387 | return llvm::makeArrayRef(GCCRegNames); |
388 | } |
389 | |
390 | const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { |
391 | |
392 | |
393 | {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"}, |
394 | {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"}, |
395 | {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"}, |
396 | {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"}, |
397 | {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"}, |
398 | {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"}, |
399 | {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"}, |
400 | {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"}, |
401 | {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"}, |
402 | {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"}, |
403 | {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"}, |
404 | {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"}, |
405 | {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"}, |
406 | {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"}, |
407 | {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"}, |
408 | {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"}, |
409 | {{"cc"}, "cr0"}, |
410 | }; |
411 | |
412 | ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const { |
413 | return llvm::makeArrayRef(GCCRegAliases); |
414 | } |
415 | |
416 | |
417 | |
418 | |
419 | const TargetInfo::AddlRegName GCCAddlRegNames[] = { |
420 | |
421 | {{"vs0"}, 32}, {{"vs1"}, 33}, {{"vs2"}, 34}, {{"vs3"}, 35}, |
422 | {{"vs4"}, 36}, {{"vs5"}, 37}, {{"vs6"}, 38}, {{"vs7"}, 39}, |
423 | {{"vs8"}, 40}, {{"vs9"}, 41}, {{"vs10"}, 42}, {{"vs11"}, 43}, |
424 | {{"vs12"}, 44}, {{"vs13"}, 45}, {{"vs14"}, 46}, {{"vs15"}, 47}, |
425 | {{"vs16"}, 48}, {{"vs17"}, 49}, {{"vs18"}, 50}, {{"vs19"}, 51}, |
426 | {{"vs20"}, 52}, {{"vs21"}, 53}, {{"vs22"}, 54}, {{"vs23"}, 55}, |
427 | {{"vs24"}, 56}, {{"vs25"}, 57}, {{"vs26"}, 58}, {{"vs27"}, 59}, |
428 | {{"vs28"}, 60}, {{"vs29"}, 61}, {{"vs30"}, 62}, {{"vs31"}, 63}, |
429 | {{"vs32"}, 77}, {{"vs33"}, 78}, {{"vs34"}, 79}, {{"vs35"}, 80}, |
430 | {{"vs36"}, 81}, {{"vs37"}, 82}, {{"vs38"}, 83}, {{"vs39"}, 84}, |
431 | {{"vs40"}, 85}, {{"vs41"}, 86}, {{"vs42"}, 87}, {{"vs43"}, 88}, |
432 | {{"vs44"}, 89}, {{"vs45"}, 90}, {{"vs46"}, 91}, {{"vs47"}, 92}, |
433 | {{"vs48"}, 93}, {{"vs49"}, 94}, {{"vs50"}, 95}, {{"vs51"}, 96}, |
434 | {{"vs52"}, 97}, {{"vs53"}, 98}, {{"vs54"}, 99}, {{"vs55"}, 100}, |
435 | {{"vs56"}, 101}, {{"vs57"}, 102}, {{"vs58"}, 103}, {{"vs59"}, 104}, |
436 | {{"vs60"}, 105}, {{"vs61"}, 106}, {{"vs62"}, 107}, {{"vs63"}, 108}, |
437 | }; |
438 | |
439 | ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const { |
440 | if (ABI == "elfv2") |
441 | return llvm::makeArrayRef(GCCAddlRegNames); |
442 | else |
443 | return TargetInfo::getGCCAddlRegNames(); |
444 | } |
445 | |
446 | static constexpr llvm::StringLiteral ValidCPUNames[] = { |
447 | {"generic"}, {"440"}, {"450"}, {"601"}, {"602"}, |
448 | {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"}, |
449 | {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"}, |
450 | {"7450"}, {"g4+"}, {"750"}, {"970"}, {"g5"}, |
451 | {"a2"}, {"a2q"}, {"e500mc"}, {"e5500"}, {"power3"}, |
452 | {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"}, {"pwr5"}, |
453 | {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"}, {"power6x"}, |
454 | {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"}, {"pwr8"}, |
455 | {"power9"}, {"pwr9"}, {"powerpc"}, {"ppc"}, {"powerpc64"}, |
456 | {"ppc64"}, {"powerpc64le"}, {"ppc64le"}, |
457 | }; |
458 | |
459 | bool PPCTargetInfo::isValidCPUName(StringRef Name) const { |
460 | return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); |
461 | } |
462 | |
463 | void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { |
464 | Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); |
465 | } |
466 | |
467 | void PPCTargetInfo::adjust(LangOptions &Opts) { |
468 | if (HasAltivec) |
469 | Opts.AltiVec = 1; |
470 | TargetInfo::adjust(Opts); |
471 | } |
472 | |
473 | ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const { |
474 | return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin - |
475 | Builtin::FirstTSBuiltin); |
476 | } |
477 | |