1 //===--- CSKY.cpp - Implement CSKY 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 CSKY TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "CSKY.h"
14
15 using namespace clang;
16 using namespace clang::targets;
17
isValidCPUName(StringRef Name) const18 bool CSKYTargetInfo::isValidCPUName(StringRef Name) const {
19 return llvm::CSKY::parseCPUArch(Name) != llvm::CSKY::ArchKind::INVALID;
20 }
21
setCPU(const std::string & Name)22 bool CSKYTargetInfo::setCPU(const std::string &Name) {
23 llvm::CSKY::ArchKind archKind = llvm::CSKY::parseCPUArch(Name);
24 bool isValid = (archKind != llvm::CSKY::ArchKind::INVALID);
25
26 if (isValid) {
27 CPU = Name;
28 Arch = archKind;
29 }
30
31 return isValid;
32 }
33
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const34 void CSKYTargetInfo::getTargetDefines(const LangOptions &Opts,
35 MacroBuilder &Builder) const {
36 Builder.defineMacro("__ELF__");
37 Builder.defineMacro("__csky__", "2");
38 Builder.defineMacro("__CSKY__", "2");
39 Builder.defineMacro("__ckcore__", "2");
40 Builder.defineMacro("__CKCORE__", "2");
41
42 Builder.defineMacro("__CSKYABI__", ABI == "abiv2" ? "2" : "1");
43 Builder.defineMacro("__cskyabi__", ABI == "abiv2" ? "2" : "1");
44
45 StringRef ArchName = "ck810";
46 StringRef CPUName = "ck810";
47
48 if (Arch != llvm::CSKY::ArchKind::INVALID) {
49 ArchName = llvm::CSKY::getArchName(Arch);
50 CPUName = CPU;
51 }
52
53 Builder.defineMacro("__" + ArchName.upper() + "__");
54 Builder.defineMacro("__" + ArchName.lower() + "__");
55 Builder.defineMacro("__" + CPUName.upper() + "__");
56 Builder.defineMacro("__" + CPUName.lower() + "__");
57
58 // TODO: Add support for BE if BE was supported later
59 StringRef endian = "__cskyLE__";
60
61 Builder.defineMacro(endian);
62 Builder.defineMacro(endian.upper());
63 Builder.defineMacro(endian.lower());
64
65 if (DSPV2) {
66 StringRef dspv2 = "__CSKY_DSPV2__";
67 Builder.defineMacro(dspv2);
68 Builder.defineMacro(dspv2.lower());
69 }
70
71 if (VDSPV2) {
72 StringRef vdspv2 = "__CSKY_VDSPV2__";
73 Builder.defineMacro(vdspv2);
74 Builder.defineMacro(vdspv2.lower());
75
76 if (HardFloat) {
77 StringRef vdspv2_f = "__CSKY_VDSPV2_F__";
78 Builder.defineMacro(vdspv2_f);
79 Builder.defineMacro(vdspv2_f.lower());
80 }
81 }
82 if (VDSPV1) {
83 StringRef vdspv1_64 = "__CSKY_VDSP64__";
84 StringRef vdspv1_128 = "__CSKY_VDSP128__";
85
86 Builder.defineMacro(vdspv1_64);
87 Builder.defineMacro(vdspv1_64.lower());
88 Builder.defineMacro(vdspv1_128);
89 Builder.defineMacro(vdspv1_128.lower());
90 }
91 if (is3E3R1) {
92 StringRef is3e3r1 = "__CSKY_3E3R1__";
93 Builder.defineMacro(is3e3r1);
94 Builder.defineMacro(is3e3r1.lower());
95 }
96 }
97
hasFeature(StringRef Feature) const98 bool CSKYTargetInfo::hasFeature(StringRef Feature) const {
99 return llvm::StringSwitch<bool>(Feature)
100 .Case("hard-float", HardFloat)
101 .Case("hard-float-abi", HardFloatABI)
102 .Case("fpuv2_sf", FPUV2_SF)
103 .Case("fpuv2_df", FPUV2_DF)
104 .Case("fpuv3_sf", FPUV3_SF)
105 .Case("fpuv3_df", FPUV3_DF)
106 .Case("vdspv2", VDSPV2)
107 .Case("dspv2", DSPV2)
108 .Case("vdspv1", VDSPV1)
109 .Case("3e3r1", is3E3R1)
110 .Default(false);
111 }
112
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)113 bool CSKYTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
114 DiagnosticsEngine &Diags) {
115 for (const auto &Feature : Features) {
116 if (Feature == "+hard-float")
117 HardFloat = true;
118 if (Feature == "+hard-float-abi")
119 HardFloatABI = true;
120 if (Feature == "+fpuv2_sf")
121 FPUV2_SF = true;
122 if (Feature == "+fpuv2_df")
123 FPUV2_DF = true;
124 if (Feature == "+fpuv3_sf")
125 FPUV3_SF = true;
126 if (Feature == "+fpuv3_df")
127 FPUV3_DF = true;
128 if (Feature == "+vdspv2")
129 VDSPV2 = true;
130 if (Feature == "+dspv2")
131 DSPV2 = true;
132 if (Feature == "+vdspv1")
133 VDSPV1 = true;
134 if (Feature == "+3e3r1")
135 is3E3R1 = true;
136 }
137
138 return true;
139 }
140
getTargetBuiltins() const141 ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const {
142 return ArrayRef<Builtin::Info>();
143 }
144
getGCCRegNames() const145 ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const {
146 static const char *const GCCRegNames[] = {
147 // Integer registers
148 "r0",
149 "r1",
150 "r2",
151 "r3",
152 "r4",
153 "r5",
154 "r6",
155 "r7",
156 "r8",
157 "r9",
158 "r10",
159 "r11",
160 "r12",
161 "r13",
162 "r14",
163 "r15",
164 "r16",
165 "r17",
166 "r18",
167 "r19",
168 "r20",
169 "r21",
170 "r22",
171 "r23",
172 "r24",
173 "r25",
174 "r26",
175 "r27",
176 "r28",
177 "r29",
178 "r30",
179 "r31",
180
181 // Floating point registers
182 "fr0",
183 "fr1",
184 "fr2",
185 "fr3",
186 "fr4",
187 "fr5",
188 "fr6",
189 "fr7",
190 "fr8",
191 "fr9",
192 "fr10",
193 "fr11",
194 "fr12",
195 "fr13",
196 "fr14",
197 "fr15",
198 "fr16",
199 "fr17",
200 "fr18",
201 "fr19",
202 "fr20",
203 "fr21",
204 "fr22",
205 "fr23",
206 "fr24",
207 "fr25",
208 "fr26",
209 "fr27",
210 "fr28",
211 "fr29",
212 "fr30",
213 "fr31",
214
215 };
216 return llvm::ArrayRef(GCCRegNames);
217 }
218
getGCCRegAliases() const219 ArrayRef<TargetInfo::GCCRegAlias> CSKYTargetInfo::getGCCRegAliases() const {
220 static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
221 {{"a0"}, "r0"},
222 {{"a1"}, "r1"},
223 {{"a2"}, "r2"},
224 {{"a3"}, "r3"},
225 {{"l0"}, "r4"},
226 {{"l1"}, "r5"},
227 {{"l2"}, "r6"},
228 {{"l3"}, "r7"},
229 {{"l4"}, "r8"},
230 {{"l5"}, "r9"},
231 {{"l6"}, "r10"},
232 {{"l7"}, "r11"},
233 {{"t0"}, "r12"},
234 {{"t1"}, "r13"},
235 {{"sp"}, "r14"},
236 {{"lr"}, "r15"},
237 {{"l8"}, "r16"},
238 {{"l9"}, "r17"},
239 {{"t2"}, "r18"},
240 {{"t3"}, "r19"},
241 {{"t4"}, "r20"},
242 {{"t5"}, "r21"},
243 {{"t6"}, "r22"},
244 {{"t7", "fp"}, "r23"},
245 {{"t8", "top"}, "r24"},
246 {{"t9", "bsp"}, "r25"},
247 {{"r26"}, "r26"},
248 {{"r27"}, "r27"},
249 {{"gb", "rgb", "rdb"}, "r28"},
250 {{"tb", "rtb"}, "r29"},
251 {{"svbr"}, "r30"},
252 {{"tls"}, "r31"},
253
254 {{"vr0"}, "fr0"},
255 {{"vr1"}, "fr1"},
256 {{"vr2"}, "fr2"},
257 {{"vr3"}, "fr3"},
258 {{"vr4"}, "fr4"},
259 {{"vr5"}, "fr5"},
260 {{"vr6"}, "fr6"},
261 {{"vr7"}, "fr7"},
262 {{"vr8"}, "fr8"},
263 {{"vr9"}, "fr9"},
264 {{"vr10"}, "fr10"},
265 {{"vr11"}, "fr11"},
266 {{"vr12"}, "fr12"},
267 {{"vr13"}, "fr13"},
268 {{"vr14"}, "fr14"},
269 {{"vr15"}, "fr15"},
270 {{"vr16"}, "fr16"},
271 {{"vr17"}, "fr17"},
272 {{"vr18"}, "fr18"},
273 {{"vr19"}, "fr19"},
274 {{"vr20"}, "fr20"},
275 {{"vr21"}, "fr21"},
276 {{"vr22"}, "fr22"},
277 {{"vr23"}, "fr23"},
278 {{"vr24"}, "fr24"},
279 {{"vr25"}, "fr25"},
280 {{"vr26"}, "fr26"},
281 {{"vr27"}, "fr27"},
282 {{"vr28"}, "fr28"},
283 {{"vr29"}, "fr29"},
284 {{"vr30"}, "fr30"},
285 {{"vr31"}, "fr31"},
286
287 };
288 return llvm::ArrayRef(GCCRegAliases);
289 }
290
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const291 bool CSKYTargetInfo::validateAsmConstraint(
292 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
293 switch (*Name) {
294 default:
295 return false;
296 case 'a':
297 case 'b':
298 case 'c':
299 case 'y':
300 case 'l':
301 case 'h':
302 case 'w':
303 case 'v': // A floating-point and vector register.
304 case 'z':
305 Info.setAllowsRegister();
306 return true;
307 }
308 }
309
getMinGlobalAlign(uint64_t Size) const310 unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const {
311 if (Size >= 32)
312 return 32;
313 return 0;
314 }
315