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