clang  8.0.0svn
PPC.cpp
Go to the documentation of this file.
1 //===--- PPC.cpp - Implement PPC target feature support -------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements PPC TargetInfo objects.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "PPC.h"
15 #include "clang/Basic/Diagnostic.h"
18 
19 using namespace clang;
20 using namespace clang::targets;
21 
22 const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
23 #define BUILTIN(ID, TYPE, ATTRS) \
24  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
25 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
26  {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
27 #include "clang/Basic/BuiltinsPPC.def"
28 };
29 
30 /// handleTargetFeatures - Perform initialization based on the user
31 /// configured set of features.
32 bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
33  DiagnosticsEngine &Diags) {
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 == "+qpx") {
50  HasQPX = true;
51  } else if (Feature == "+htm") {
52  HasHTM = true;
53  } else if (Feature == "+float128") {
54  HasFloat128 = true;
55  } else if (Feature == "+power9-vector") {
56  HasP9Vector = true;
57  }
58  // TODO: Finish this list and add an assert that we've handled them
59  // all.
60  }
61 
62  return true;
63 }
64 
65 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
66 /// #defines that are not tied to a specific subtarget.
68  MacroBuilder &Builder) const {
69  // Target identification.
70  Builder.defineMacro("__ppc__");
71  Builder.defineMacro("__PPC__");
72  Builder.defineMacro("_ARCH_PPC");
73  Builder.defineMacro("__powerpc__");
74  Builder.defineMacro("__POWERPC__");
75  if (PointerWidth == 64) {
76  Builder.defineMacro("_ARCH_PPC64");
77  Builder.defineMacro("__powerpc64__");
78  Builder.defineMacro("__ppc64__");
79  Builder.defineMacro("__PPC64__");
80  }
81 
82  // Target properties.
83  if (getTriple().getArch() == llvm::Triple::ppc64le) {
84  Builder.defineMacro("_LITTLE_ENDIAN");
85  } else {
86  if (getTriple().getOS() != llvm::Triple::NetBSD &&
87  getTriple().getOS() != llvm::Triple::OpenBSD)
88  Builder.defineMacro("_BIG_ENDIAN");
89  }
90 
91  // ABI options.
92  if (ABI == "elfv1" || ABI == "elfv1-qpx")
93  Builder.defineMacro("_CALL_ELF", "1");
94  if (ABI == "elfv2")
95  Builder.defineMacro("_CALL_ELF", "2");
96 
97  // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but
98  // our support post-dates this and it should work on all 64-bit ppc linux
99  // platforms. It is guaranteed to work on all elfv2 platforms.
100  if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64)
101  Builder.defineMacro("_CALL_LINUX", "1");
102 
103  // Subtarget options.
104  Builder.defineMacro("__NATURAL_ALIGNMENT__");
105  Builder.defineMacro("__REGISTER_PREFIX__", "");
106 
107  // FIXME: Should be controlled by command line option.
108  if (LongDoubleWidth == 128) {
109  Builder.defineMacro("__LONG_DOUBLE_128__");
110  Builder.defineMacro("__LONGDOUBLE128");
111  }
112 
113  // Define this for elfv2 (64-bit only) or 64-bit darwin.
114  if (ABI == "elfv2" ||
115  (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64))
116  Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");
117 
118  if (ArchDefs & ArchDefineName)
119  Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
120  if (ArchDefs & ArchDefinePpcgr)
121  Builder.defineMacro("_ARCH_PPCGR");
122  if (ArchDefs & ArchDefinePpcsq)
123  Builder.defineMacro("_ARCH_PPCSQ");
124  if (ArchDefs & ArchDefine440)
125  Builder.defineMacro("_ARCH_440");
126  if (ArchDefs & ArchDefine603)
127  Builder.defineMacro("_ARCH_603");
128  if (ArchDefs & ArchDefine604)
129  Builder.defineMacro("_ARCH_604");
130  if (ArchDefs & ArchDefinePwr4)
131  Builder.defineMacro("_ARCH_PWR4");
132  if (ArchDefs & ArchDefinePwr5)
133  Builder.defineMacro("_ARCH_PWR5");
134  if (ArchDefs & ArchDefinePwr5x)
135  Builder.defineMacro("_ARCH_PWR5X");
136  if (ArchDefs & ArchDefinePwr6)
137  Builder.defineMacro("_ARCH_PWR6");
138  if (ArchDefs & ArchDefinePwr6x)
139  Builder.defineMacro("_ARCH_PWR6X");
140  if (ArchDefs & ArchDefinePwr7)
141  Builder.defineMacro("_ARCH_PWR7");
142  if (ArchDefs & ArchDefinePwr8)
143  Builder.defineMacro("_ARCH_PWR8");
144  if (ArchDefs & ArchDefinePwr9)
145  Builder.defineMacro("_ARCH_PWR9");
146  if (ArchDefs & ArchDefineA2)
147  Builder.defineMacro("_ARCH_A2");
148  if (ArchDefs & ArchDefineA2q) {
149  Builder.defineMacro("_ARCH_A2Q");
150  Builder.defineMacro("_ARCH_QP");
151  }
152 
153  if (getTriple().getVendor() == llvm::Triple::BGQ) {
154  Builder.defineMacro("__bg__");
155  Builder.defineMacro("__THW_BLUEGENE__");
156  Builder.defineMacro("__bgq__");
157  Builder.defineMacro("__TOS_BGQ__");
158  }
159 
160  if (HasAltivec) {
161  Builder.defineMacro("__VEC__", "10206");
162  Builder.defineMacro("__ALTIVEC__");
163  }
164  if (HasVSX)
165  Builder.defineMacro("__VSX__");
166  if (HasP8Vector)
167  Builder.defineMacro("__POWER8_VECTOR__");
168  if (HasP8Crypto)
169  Builder.defineMacro("__CRYPTO__");
170  if (HasHTM)
171  Builder.defineMacro("__HTM__");
172  if (HasFloat128)
173  Builder.defineMacro("__FLOAT128__");
174  if (HasP9Vector)
175  Builder.defineMacro("__POWER9_VECTOR__");
176 
177  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
178  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
179  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
180  if (PointerWidth == 64)
181  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
182 
183  // We have support for the bswap intrinsics so we can define this.
184  Builder.defineMacro("__HAVE_BSWAP__", "1");
185 
186  // FIXME: The following are not yet generated here by Clang, but are
187  // generated by GCC:
188  //
189  // _SOFT_FLOAT_
190  // __RECIP_PRECISION__
191  // __APPLE_ALTIVEC__
192  // __RECIP__
193  // __RECIPF__
194  // __RSQRTE__
195  // __RSQRTEF__
196  // _SOFT_DOUBLE_
197  // __NO_LWSYNC__
198  // __CMODEL_MEDIUM__
199  // __CMODEL_LARGE__
200  // _CALL_SYSV
201  // _CALL_DARWIN
202  // __NO_FPRS__
203 }
204 
205 // Handle explicit options being passed to the compiler here: if we've
206 // explicitly turned off vsx and turned on any of:
207 // - power8-vector
208 // - direct-move
209 // - float128
210 // - power9-vector
211 // then go ahead and error since the customer has expressed an incompatible
212 // set of options.
214  const std::vector<std::string> &FeaturesVec) {
215 
216  if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "-vsx") !=
217  FeaturesVec.end()) {
218  if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power8-vector") !=
219  FeaturesVec.end()) {
220  Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower8-vector"
221  << "-mno-vsx";
222  return false;
223  }
224 
225  if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+direct-move") !=
226  FeaturesVec.end()) {
227  Diags.Report(diag::err_opt_not_valid_with_opt) << "-mdirect-move"
228  << "-mno-vsx";
229  return false;
230  }
231 
232  if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") !=
233  FeaturesVec.end()) {
234  Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128"
235  << "-mno-vsx";
236  return false;
237  }
238 
239  if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power9-vector") !=
240  FeaturesVec.end()) {
241  Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower9-vector"
242  << "-mno-vsx";
243  return false;
244  }
245  }
246 
247  return true;
248 }
249 
251  llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
252  const std::vector<std::string> &FeaturesVec) const {
253  Features["altivec"] = llvm::StringSwitch<bool>(CPU)
254  .Case("7400", true)
255  .Case("g4", true)
256  .Case("7450", true)
257  .Case("g4+", true)
258  .Case("970", true)
259  .Case("g5", true)
260  .Case("pwr6", true)
261  .Case("pwr7", true)
262  .Case("pwr8", true)
263  .Case("pwr9", true)
264  .Case("ppc64", true)
265  .Case("ppc64le", true)
266  .Default(false);
267 
268  Features["qpx"] = (CPU == "a2q");
269  Features["power9-vector"] = (CPU == "pwr9");
270  Features["crypto"] = llvm::StringSwitch<bool>(CPU)
271  .Case("ppc64le", true)
272  .Case("pwr9", true)
273  .Case("pwr8", true)
274  .Default(false);
275  Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)
276  .Case("ppc64le", true)
277  .Case("pwr9", true)
278  .Case("pwr8", true)
279  .Default(false);
280  Features["bpermd"] = llvm::StringSwitch<bool>(CPU)
281  .Case("ppc64le", true)
282  .Case("pwr9", true)
283  .Case("pwr8", true)
284  .Case("pwr7", true)
285  .Default(false);
286  Features["extdiv"] = llvm::StringSwitch<bool>(CPU)
287  .Case("ppc64le", true)
288  .Case("pwr9", true)
289  .Case("pwr8", true)
290  .Case("pwr7", true)
291  .Default(false);
292  Features["direct-move"] = llvm::StringSwitch<bool>(CPU)
293  .Case("ppc64le", true)
294  .Case("pwr9", true)
295  .Case("pwr8", true)
296  .Default(false);
297  Features["vsx"] = llvm::StringSwitch<bool>(CPU)
298  .Case("ppc64le", true)
299  .Case("pwr9", true)
300  .Case("pwr8", true)
301  .Case("pwr7", true)
302  .Default(false);
303  Features["htm"] = llvm::StringSwitch<bool>(CPU)
304  .Case("ppc64le", true)
305  .Case("pwr9", true)
306  .Case("pwr8", true)
307  .Default(false);
308 
309  if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
310  return false;
311 
312  if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) &&
313  std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") !=
314  FeaturesVec.end()) {
315  // We have __float128 on PPC but not power 9 and above.
316  Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU;
317  return false;
318  }
319 
320  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
321 }
322 
323 bool PPCTargetInfo::hasFeature(StringRef Feature) const {
324  return llvm::StringSwitch<bool>(Feature)
325  .Case("powerpc", true)
326  .Case("altivec", HasAltivec)
327  .Case("vsx", HasVSX)
328  .Case("power8-vector", HasP8Vector)
329  .Case("crypto", HasP8Crypto)
330  .Case("direct-move", HasDirectMove)
331  .Case("qpx", HasQPX)
332  .Case("htm", HasHTM)
333  .Case("bpermd", HasBPERMD)
334  .Case("extdiv", HasExtDiv)
335  .Case("float128", HasFloat128)
336  .Case("power9-vector", HasP9Vector)
337  .Default(false);
338 }
339 
340 void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
341  StringRef Name, bool Enabled) const {
342  if (Enabled) {
343  // If we're enabling any of the vsx based features then enable vsx and
344  // altivec. We'll diagnose any problems later.
345  bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)
346  .Case("vsx", true)
347  .Case("direct-move", true)
348  .Case("power8-vector", true)
349  .Case("power9-vector", true)
350  .Case("float128", true)
351  .Default(false);
352  if (FeatureHasVSX)
353  Features["vsx"] = Features["altivec"] = true;
354  if (Name == "power9-vector")
355  Features["power8-vector"] = true;
356  Features[Name] = true;
357  } else {
358  // If we're disabling altivec or vsx go ahead and disable all of the vsx
359  // features.
360  if ((Name == "altivec") || (Name == "vsx"))
361  Features["vsx"] = Features["direct-move"] = Features["power8-vector"] =
362  Features["float128"] = Features["power9-vector"] = false;
363  if (Name == "power8-vector")
364  Features["power9-vector"] = false;
365  Features[Name] = false;
366  }
367 }
368 
369 const char *const PPCTargetInfo::GCCRegNames[] = {
370  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
371  "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
372  "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
373  "r27", "r28", "r29", "r30", "r31", "f0", "f1", "f2", "f3",
374  "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12",
375  "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
376  "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30",
377  "f31", "mq", "lr", "ctr", "ap", "cr0", "cr1", "cr2", "cr3",
378  "cr4", "cr5", "cr6", "cr7", "xer", "v0", "v1", "v2", "v3",
379  "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12",
380  "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
381  "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30",
382  "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp"
383 };
384 
386  return llvm::makeArrayRef(GCCRegNames);
387 }
388 
389 const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
390  // While some of these aliases do map to different registers
391  // they still share the same register name.
392  {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"},
393  {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"},
394  {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"},
395  {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"},
396  {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"},
397  {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"},
398  {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"},
399  {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"},
400  {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"},
401  {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"},
402  {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"},
403  {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"},
404  {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"},
405  {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"},
406  {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"},
407  {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"},
408  {{"cc"}, "cr0"},
409 };
410 
412  return llvm::makeArrayRef(GCCRegAliases);
413 }
414 
415 static constexpr llvm::StringLiteral ValidCPUNames[] = {
416  {"generic"}, {"440"}, {"450"}, {"601"}, {"602"},
417  {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"},
418  {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"},
419  {"7450"}, {"g4+"}, {"750"}, {"970"}, {"g5"},
420  {"a2"}, {"a2q"}, {"e500mc"}, {"e5500"}, {"power3"},
421  {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"}, {"pwr5"},
422  {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"}, {"power6x"},
423  {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"}, {"pwr8"},
424  {"power9"}, {"pwr9"}, {"powerpc"}, {"ppc"}, {"powerpc64"},
425  {"ppc64"}, {"powerpc64le"}, {"ppc64le"},
426 };
427 
428 bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
429  return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
430 }
431 
433  Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
434 }
435 
437  if (HasAltivec)
438  Opts.AltiVec = 1;
439  TargetInfo::adjust(Opts);
440 }
441 
443  return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin -
445 }
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: PPC.cpp:323
Defines the clang::MacroBuilder utility class.
virtual void adjust(LangOptions &Opts)
Set forced language options.
Definition: TargetInfo.cpp:324
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:949
void setFeatureEnabled(llvm::StringMap< bool > &Features, StringRef Name, bool Enabled) const override
Enable or disable a specific target feature; the feature name must be valid.
Definition: PPC.cpp:340
ArrayRef< Builtin::Info > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
Definition: PPC.cpp:442
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1294
unsigned char LongDoubleWidth
Definition: TargetInfo.h:73
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
unsigned char PointerWidth
Definition: TargetInfo.h:67
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:149
Defines the Diagnostic-related interfaces.
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: PPC.cpp:411
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
Definition: TargetInfo.cpp:385
ArrayRef< const char * > getGCCRegNames() const override
Definition: PPC.cpp:385
Enumerates target-specific builtins in their own namespaces within namespace clang.
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
Definition: PPC.cpp:432
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
handleTargetFeatures - Perform initialization based on the user configured set of features...
Definition: PPC.cpp:32
bool isValidCPUName(StringRef Name) const override
brief Determine whether this TargetInfo supports the given CPU name.
Definition: PPC.cpp:428
Dataflow Directional Tag Classes.
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific #defines that are not tied to ...
Definition: PPC.cpp:67
void adjust(LangOptions &Opts) override
Set forced language options.
Definition: PPC.cpp:436
static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, const std::vector< std::string > &FeaturesVec)
Definition: PPC.cpp:213
void defineMacro(const Twine &Name, const Twine &Value="1")
Append a #define line for macro of the form "\#define Name Value\n".
Definition: MacroBuilder.h:30
bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeaturesVec) const override
Initialize the map with the default set of target features for the CPU this should include all legal ...
Definition: PPC.cpp:250
static constexpr llvm::StringLiteral ValidCPUNames[]
Definition: PPC.cpp:415