1 //===--- Sparc.cpp - Implement Sparc 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 Sparc TargetInfo objects.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "Sparc.h"
15 #include "Targets.h"
16 #include "clang/Basic/MacroBuilder.h"
17 #include "llvm/ADT/StringSwitch.h"
18 
19 using namespace clang;
20 using namespace clang::targets;
21 
22 const char *const SparcTargetInfo::GCCRegNames[] = {
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 
28 ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
29   return llvm::makeArrayRef(GCCRegNames);
30 }
31 
32 const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
33     {{"g0"}, "r0"},  {{"g1"}, "r1"},  {{"g2"}, "r2"},        {{"g3"}, "r3"},
34     {{"g4"}, "r4"},  {{"g5"}, "r5"},  {{"g6"}, "r6"},        {{"g7"}, "r7"},
35     {{"o0"}, "r8"},  {{"o1"}, "r9"},  {{"o2"}, "r10"},       {{"o3"}, "r11"},
36     {{"o4"}, "r12"}, {{"o5"}, "r13"}, {{"o6", "sp"}, "r14"}, {{"o7"}, "r15"},
37     {{"l0"}, "r16"}, {{"l1"}, "r17"}, {{"l2"}, "r18"},       {{"l3"}, "r19"},
38     {{"l4"}, "r20"}, {{"l5"}, "r21"}, {{"l6"}, "r22"},       {{"l7"}, "r23"},
39     {{"i0"}, "r24"}, {{"i1"}, "r25"}, {{"i2"}, "r26"},       {{"i3"}, "r27"},
40     {{"i4"}, "r28"}, {{"i5"}, "r29"}, {{"i6", "fp"}, "r30"}, {{"i7"}, "r31"},
41 };
42 
43 ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
44   return llvm::makeArrayRef(GCCRegAliases);
45 }
46 
47 bool SparcTargetInfo::hasFeature(StringRef Feature) const {
48   return llvm::StringSwitch<bool>(Feature)
49       .Case("softfloat", SoftFloat)
50       .Case("sparc", true)
51       .Default(false);
52 }
53 
54 struct SparcCPUInfo {
55   llvm::StringLiteral Name;
56   SparcTargetInfo::CPUKind Kind;
57   SparcTargetInfo::CPUGeneration Generation;
58 };
59 
60 static constexpr SparcCPUInfo CPUInfo[] = {
61     {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8},
62     {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8},
63     {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8},
64     {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8},
65     {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8},
66     {{"sparclite86x"},
67      SparcTargetInfo::CK_SPARCLITE86X,
68      SparcTargetInfo::CG_V8},
69     {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8},
70     {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8},
71     {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9},
72     {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9},
73     {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9},
74     {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9},
75     {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9},
76     {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9},
77     {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9},
78     {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
79     {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8},
80     {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8},
81     {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8},
82     {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8},
83     {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
84     {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8},
85     {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8},
86     {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8},
87     {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8},
88     {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
89     // FIXME: the myriad2[.n] spellings are obsolete,
90     // but a grace period is needed to allow updating dependent builds.
91     {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
92     {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
93     {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
94     {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
95     {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8},
96     {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8},
97     {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8},
98     {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8},
99     {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8},
100     {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8},
101     {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8},
102     {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8},
103 };
104 
105 SparcTargetInfo::CPUGeneration
106 SparcTargetInfo::getCPUGeneration(CPUKind Kind) const {
107   if (Kind == CK_GENERIC)
108     return CG_V8;
109   const SparcCPUInfo *Item = llvm::find_if(
110       CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
111   if (Item == std::end(CPUInfo))
112     llvm_unreachable("Unexpected CPU kind");
113   return Item->Generation;
114 }
115 
116 SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const {
117   const SparcCPUInfo *Item = llvm::find_if(
118       CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
119 
120   if (Item == std::end(CPUInfo))
121     return CK_GENERIC;
122   return Item->Kind;
123 }
124 
125 void SparcTargetInfo::fillValidCPUList(
126     SmallVectorImpl<StringRef> &Values) const {
127   for (const SparcCPUInfo &Info : CPUInfo)
128     Values.push_back(Info.Name);
129 }
130 
131 void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
132                                        MacroBuilder &Builder) const {
133   DefineStd(Builder, "sparc", Opts);
134   Builder.defineMacro("__REGISTER_PREFIX__", "");
135 
136   if (SoftFloat)
137     Builder.defineMacro("SOFT_FLOAT", "1");
138 }
139 
140 void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
141                                          MacroBuilder &Builder) const {
142   SparcTargetInfo::getTargetDefines(Opts, Builder);
143   switch (getCPUGeneration(CPU)) {
144   case CG_V8:
145     Builder.defineMacro("__sparcv8");
146     if (getTriple().getOS() != llvm::Triple::Solaris)
147       Builder.defineMacro("__sparcv8__");
148     break;
149   case CG_V9:
150     Builder.defineMacro("__sparcv9");
151     if (getTriple().getOS() != llvm::Triple::Solaris) {
152       Builder.defineMacro("__sparcv9__");
153       Builder.defineMacro("__sparc_v9__");
154     }
155     break;
156   }
157   if (getTriple().getVendor() == llvm::Triple::Myriad) {
158     std::string MyriadArchValue, Myriad2Value;
159     Builder.defineMacro("__sparc_v8__");
160     Builder.defineMacro("__leon__");
161     switch (CPU) {
162     case CK_MYRIAD2100:
163       MyriadArchValue = "__ma2100";
164       Myriad2Value = "1";
165       break;
166     case CK_MYRIAD2150:
167       MyriadArchValue = "__ma2150";
168       Myriad2Value = "2";
169       break;
170     case CK_MYRIAD2155:
171       MyriadArchValue = "__ma2155";
172       Myriad2Value = "2";
173       break;
174     case CK_MYRIAD2450:
175       MyriadArchValue = "__ma2450";
176       Myriad2Value = "2";
177       break;
178     case CK_MYRIAD2455:
179       MyriadArchValue = "__ma2455";
180       Myriad2Value = "2";
181       break;
182     case CK_MYRIAD2x5x:
183       Myriad2Value = "2";
184       break;
185     case CK_MYRIAD2080:
186       MyriadArchValue = "__ma2080";
187       Myriad2Value = "3";
188       break;
189     case CK_MYRIAD2085:
190       MyriadArchValue = "__ma2085";
191       Myriad2Value = "3";
192       break;
193     case CK_MYRIAD2480:
194       MyriadArchValue = "__ma2480";
195       Myriad2Value = "3";
196       break;
197     case CK_MYRIAD2485:
198       MyriadArchValue = "__ma2485";
199       Myriad2Value = "3";
200       break;
201     case CK_MYRIAD2x8x:
202       Myriad2Value = "3";
203       break;
204     default:
205       MyriadArchValue = "__ma2100";
206       Myriad2Value = "1";
207       break;
208     }
209     if (!MyriadArchValue.empty()) {
210       Builder.defineMacro(MyriadArchValue, "1");
211       Builder.defineMacro(MyriadArchValue + "__", "1");
212     }
213     if (Myriad2Value == "2") {
214       Builder.defineMacro("__ma2x5x", "1");
215       Builder.defineMacro("__ma2x5x__", "1");
216     } else if (Myriad2Value == "3") {
217       Builder.defineMacro("__ma2x8x", "1");
218       Builder.defineMacro("__ma2x8x__", "1");
219     }
220     Builder.defineMacro("__myriad2__", Myriad2Value);
221     Builder.defineMacro("__myriad2", Myriad2Value);
222   }
223 }
224 
225 void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
226                                          MacroBuilder &Builder) const {
227   SparcTargetInfo::getTargetDefines(Opts, Builder);
228   Builder.defineMacro("__sparcv9");
229   Builder.defineMacro("__arch64__");
230   // Solaris doesn't need these variants, but the BSDs do.
231   if (getTriple().getOS() != llvm::Triple::Solaris) {
232     Builder.defineMacro("__sparc64__");
233     Builder.defineMacro("__sparc_v9__");
234     Builder.defineMacro("__sparcv9__");
235   }
236 }
237 
238 void SparcV9TargetInfo::fillValidCPUList(
239     SmallVectorImpl<StringRef> &Values) const {
240   for (const SparcCPUInfo &Info : CPUInfo)
241     if (Info.Generation == CG_V9)
242       Values.push_back(Info.Name);
243 }
244