1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "Sparc.h" |
14 | #include "Targets.h" |
15 | #include "clang/Basic/MacroBuilder.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 | |
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 | "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 | |
35 | ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const { |
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 | |
50 | ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const { |
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; |
63 | SparcTargetInfo::CPUKind Kind; |
64 | SparcTargetInfo::CPUGeneration Generation; |
65 | }; |
66 | |
67 | static constexpr SparcCPUInfo CPUInfo[] = { |
68 | {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8}, |
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"}, |
74 | SparcTargetInfo::CK_SPARCLITE86X, |
75 | SparcTargetInfo::CG_V8}, |
76 | {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8}, |
77 | {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8}, |
78 | {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9}, |
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 | |
97 | |
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 | |
112 | SparcTargetInfo::CPUGeneration |
113 | SparcTargetInfo::getCPUGeneration(CPUKind Kind) const { |
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 | |
123 | SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const { |
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 | |
132 | void SparcTargetInfo::fillValidCPUList( |
133 | SmallVectorImpl<StringRef> &Values) const { |
134 | for (const SparcCPUInfo &Info : CPUInfo) |
135 | Values.push_back(Info.Name); |
136 | } |
137 | |
138 | void SparcTargetInfo::getTargetDefines(const LangOptions &Opts, |
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 | |
147 | void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts, |
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 | |
232 | void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts, |
233 | MacroBuilder &Builder) const { |
234 | SparcTargetInfo::getTargetDefines(Opts, Builder); |
235 | Builder.defineMacro("__sparcv9"); |
236 | Builder.defineMacro("__arch64__"); |
237 | |
238 | if (getTriple().getOS() != llvm::Triple::Solaris) { |
239 | Builder.defineMacro("__sparc64__"); |
240 | Builder.defineMacro("__sparc_v9__"); |
241 | Builder.defineMacro("__sparcv9__"); |
242 | } |
243 | } |
244 | |
245 | void SparcV9TargetInfo::fillValidCPUList( |
246 | SmallVectorImpl<StringRef> &Values) const { |
247 | for (const SparcCPUInfo &Info : CPUInfo) |
248 | if (Info.Generation == CG_V9) |
249 | Values.push_back(Info.Name); |
250 | } |
251 | |