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