clang  10.0.0git
Sparc.cpp
Go to the documentation of this file.
1 //===--- Sparc.cpp - Implement Sparc 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 Sparc TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "Sparc.h"
14 #include "Targets.h"
16 #include "llvm/ADT/StringSwitch.h"
17 
18 using namespace clang;
19 using namespace clang::targets;
20 
21 const char *const SparcTargetInfo::GCCRegNames[] = {
22  // Integer registers
23  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
24  "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
25  "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
26 
27  // Floating-point registers
28  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10",
29  "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
30  "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32",
31  "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54",
32  "f56", "f58", "f60", "f62",
33 };
34 
36  return llvm::makeArrayRef(GCCRegNames);
37 }
38 
39 const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
40  {{"g0"}, "r0"}, {{"g1"}, "r1"}, {{"g2"}, "r2"}, {{"g3"}, "r3"},
41  {{"g4"}, "r4"}, {{"g5"}, "r5"}, {{"g6"}, "r6"}, {{"g7"}, "r7"},
42  {{"o0"}, "r8"}, {{"o1"}, "r9"}, {{"o2"}, "r10"}, {{"o3"}, "r11"},
43  {{"o4"}, "r12"}, {{"o5"}, "r13"}, {{"o6", "sp"}, "r14"}, {{"o7"}, "r15"},
44  {{"l0"}, "r16"}, {{"l1"}, "r17"}, {{"l2"}, "r18"}, {{"l3"}, "r19"},
45  {{"l4"}, "r20"}, {{"l5"}, "r21"}, {{"l6"}, "r22"}, {{"l7"}, "r23"},
46  {{"i0"}, "r24"}, {{"i1"}, "r25"}, {{"i2"}, "r26"}, {{"i3"}, "r27"},
47  {{"i4"}, "r28"}, {{"i5"}, "r29"}, {{"i6", "fp"}, "r30"}, {{"i7"}, "r31"},
48 };
49 
51  return llvm::makeArrayRef(GCCRegAliases);
52 }
53 
54 bool SparcTargetInfo::hasFeature(StringRef Feature) const {
55  return llvm::StringSwitch<bool>(Feature)
56  .Case("softfloat", SoftFloat)
57  .Case("sparc", true)
58  .Default(false);
59 }
60 
61 struct SparcCPUInfo {
62  llvm::StringLiteral Name;
65 };
66 
67 static constexpr SparcCPUInfo CPUInfo[] = {
69  {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8},
70  {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8},
71  {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8},
72  {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8},
73  {{"sparclite86x"},
75  SparcTargetInfo::CG_V8},
76  {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8},
77  {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8},
79  {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9},
80  {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9},
81  {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9},
82  {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9},
83  {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9},
84  {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9},
85  {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
86  {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8},
87  {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8},
88  {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8},
89  {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8},
90  {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
91  {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8},
92  {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8},
93  {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8},
94  {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8},
95  {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
96  // FIXME: the myriad2[.n] spellings are obsolete,
97  // but a grace period is needed to allow updating dependent builds.
98  {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
99  {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
100  {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
101  {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
102  {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8},
103  {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8},
104  {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8},
105  {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8},
106  {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8},
107  {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8},
108  {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8},
109  {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8},
110 };
111 
114  if (Kind == CK_GENERIC)
115  return CG_V8;
116  const SparcCPUInfo *Item = llvm::find_if(
117  CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
118  if (Item == std::end(CPUInfo))
119  llvm_unreachable("Unexpected CPU kind");
120  return Item->Generation;
121 }
122 
124  const SparcCPUInfo *Item = llvm::find_if(
125  CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
126 
127  if (Item == std::end(CPUInfo))
128  return CK_GENERIC;
129  return Item->Kind;
130 }
131 
133  SmallVectorImpl<StringRef> &Values) const {
134  for (const SparcCPUInfo &Info : CPUInfo)
135  Values.push_back(Info.Name);
136 }
137 
139  MacroBuilder &Builder) const {
140  DefineStd(Builder, "sparc", Opts);
141  Builder.defineMacro("__REGISTER_PREFIX__", "");
142 
143  if (SoftFloat)
144  Builder.defineMacro("SOFT_FLOAT", "1");
145 }
146 
148  MacroBuilder &Builder) const {
149  SparcTargetInfo::getTargetDefines(Opts, Builder);
150  switch (getCPUGeneration(CPU)) {
151  case CG_V8:
152  Builder.defineMacro("__sparcv8");
153  if (getTriple().getOS() != llvm::Triple::Solaris)
154  Builder.defineMacro("__sparcv8__");
155  break;
156  case CG_V9:
157  Builder.defineMacro("__sparcv9");
158  if (getTriple().getOS() != llvm::Triple::Solaris) {
159  Builder.defineMacro("__sparcv9__");
160  Builder.defineMacro("__sparc_v9__");
161  }
162  break;
163  }
164  if (getTriple().getVendor() == llvm::Triple::Myriad) {
165  std::string MyriadArchValue, Myriad2Value;
166  Builder.defineMacro("__sparc_v8__");
167  Builder.defineMacro("__leon__");
168  switch (CPU) {
169  case CK_MYRIAD2100:
170  MyriadArchValue = "__ma2100";
171  Myriad2Value = "1";
172  break;
173  case CK_MYRIAD2150:
174  MyriadArchValue = "__ma2150";
175  Myriad2Value = "2";
176  break;
177  case CK_MYRIAD2155:
178  MyriadArchValue = "__ma2155";
179  Myriad2Value = "2";
180  break;
181  case CK_MYRIAD2450:
182  MyriadArchValue = "__ma2450";
183  Myriad2Value = "2";
184  break;
185  case CK_MYRIAD2455:
186  MyriadArchValue = "__ma2455";
187  Myriad2Value = "2";
188  break;
189  case CK_MYRIAD2x5x:
190  Myriad2Value = "2";
191  break;
192  case CK_MYRIAD2080:
193  MyriadArchValue = "__ma2080";
194  Myriad2Value = "3";
195  break;
196  case CK_MYRIAD2085:
197  MyriadArchValue = "__ma2085";
198  Myriad2Value = "3";
199  break;
200  case CK_MYRIAD2480:
201  MyriadArchValue = "__ma2480";
202  Myriad2Value = "3";
203  break;
204  case CK_MYRIAD2485:
205  MyriadArchValue = "__ma2485";
206  Myriad2Value = "3";
207  break;
208  case CK_MYRIAD2x8x:
209  Myriad2Value = "3";
210  break;
211  default:
212  MyriadArchValue = "__ma2100";
213  Myriad2Value = "1";
214  break;
215  }
216  if (!MyriadArchValue.empty()) {
217  Builder.defineMacro(MyriadArchValue, "1");
218  Builder.defineMacro(MyriadArchValue + "__", "1");
219  }
220  if (Myriad2Value == "2") {
221  Builder.defineMacro("__ma2x5x", "1");
222  Builder.defineMacro("__ma2x5x__", "1");
223  } else if (Myriad2Value == "3") {
224  Builder.defineMacro("__ma2x8x", "1");
225  Builder.defineMacro("__ma2x8x__", "1");
226  }
227  Builder.defineMacro("__myriad2__", Myriad2Value);
228  Builder.defineMacro("__myriad2", Myriad2Value);
229  }
230 }
231 
233  MacroBuilder &Builder) const {
234  SparcTargetInfo::getTargetDefines(Opts, Builder);
235  Builder.defineMacro("__sparcv9");
236  Builder.defineMacro("__arch64__");
237  // Solaris doesn't need these variants, but the BSDs do.
238  if (getTriple().getOS() != llvm::Triple::Solaris) {
239  Builder.defineMacro("__sparc64__");
240  Builder.defineMacro("__sparc_v9__");
241  Builder.defineMacro("__sparcv9__");
242  }
243 }
244 
246  SmallVectorImpl<StringRef> &Values) const {
247  for (const SparcCPUInfo &Info : CPUInfo)
248  if (Info.Generation == CG_V9)
249  Values.push_back(Info.Name);
250 }
void DefineStd(MacroBuilder &Builder, StringRef MacroName, const LangOptions &Opts)
DefineStd - Define a macro name and standard variants.
Definition: Targets.cpp:54
Defines the clang::MacroBuilder utility class.
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
Definition: Sparc.cpp:132
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:994
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods --------------------——===//
Definition: Sparc.cpp:138
SparcTargetInfo::CPUGeneration Generation
Definition: Sparc.cpp:64
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
Definition: Sparc.cpp:245
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: Sparc.cpp:50
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods --------------------——===//
Definition: Sparc.cpp:232
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:53
SparcTargetInfo::CPUKind Kind
Definition: Sparc.cpp:63
static constexpr SparcCPUInfo CPUInfo[]
Definition: Sparc.cpp:67
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods --------------------——===//
Definition: Sparc.cpp:147
CPUGeneration getCPUGeneration(CPUKind Kind) const
Definition: Sparc.cpp:113
llvm::StringLiteral Name
Definition: Sparc.cpp:62
Kind
Dataflow Directional Tag Classes.
enum clang::targets::SparcTargetInfo::CPUKind CPU
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: Sparc.cpp:54
ArrayRef< const char * > getGCCRegNames() const override
Definition: Sparc.cpp:35
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:29
CPUKind getCPUKind(StringRef Name) const
Definition: Sparc.cpp:123