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