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