xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
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 
18 bool CSKYTargetInfo::isValidCPUName(StringRef Name) const {
19   return llvm::CSKY::parseCPUArch(Name) != llvm::CSKY::ArchKind::INVALID;
20 }
21 
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 
34 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 
99 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 
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 
142 ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const {
143   static const char *const GCCRegNames[] = {
144       // Integer registers
145       "r0",
146       "r1",
147       "r2",
148       "r3",
149       "r4",
150       "r5",
151       "r6",
152       "r7",
153       "r8",
154       "r9",
155       "r10",
156       "r11",
157       "r12",
158       "r13",
159       "r14",
160       "r15",
161       "r16",
162       "r17",
163       "r18",
164       "r19",
165       "r20",
166       "r21",
167       "r22",
168       "r23",
169       "r24",
170       "r25",
171       "r26",
172       "r27",
173       "r28",
174       "r29",
175       "r30",
176       "r31",
177 
178       // Floating point registers
179       "fr0",
180       "fr1",
181       "fr2",
182       "fr3",
183       "fr4",
184       "fr5",
185       "fr6",
186       "fr7",
187       "fr8",
188       "fr9",
189       "fr10",
190       "fr11",
191       "fr12",
192       "fr13",
193       "fr14",
194       "fr15",
195       "fr16",
196       "fr17",
197       "fr18",
198       "fr19",
199       "fr20",
200       "fr21",
201       "fr22",
202       "fr23",
203       "fr24",
204       "fr25",
205       "fr26",
206       "fr27",
207       "fr28",
208       "fr29",
209       "fr30",
210       "fr31",
211 
212   };
213   return llvm::ArrayRef(GCCRegNames);
214 }
215 
216 ArrayRef<TargetInfo::GCCRegAlias> CSKYTargetInfo::getGCCRegAliases() const {
217   static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
218       {{"a0"}, "r0"},
219       {{"a1"}, "r1"},
220       {{"a2"}, "r2"},
221       {{"a3"}, "r3"},
222       {{"l0"}, "r4"},
223       {{"l1"}, "r5"},
224       {{"l2"}, "r6"},
225       {{"l3"}, "r7"},
226       {{"l4"}, "r8"},
227       {{"l5"}, "r9"},
228       {{"l6"}, "r10"},
229       {{"l7"}, "r11"},
230       {{"t0"}, "r12"},
231       {{"t1"}, "r13"},
232       {{"sp"}, "r14"},
233       {{"lr"}, "r15"},
234       {{"l8"}, "r16"},
235       {{"l9"}, "r17"},
236       {{"t2"}, "r18"},
237       {{"t3"}, "r19"},
238       {{"t4"}, "r20"},
239       {{"t5"}, "r21"},
240       {{"t6"}, "r22"},
241       {{"t7", "fp"}, "r23"},
242       {{"t8", "top"}, "r24"},
243       {{"t9", "bsp"}, "r25"},
244       {{"r26"}, "r26"},
245       {{"r27"}, "r27"},
246       {{"gb", "rgb", "rdb"}, "r28"},
247       {{"tb", "rtb"}, "r29"},
248       {{"svbr"}, "r30"},
249       {{"tls"}, "r31"},
250 
251       {{"vr0"}, "fr0"},
252       {{"vr1"}, "fr1"},
253       {{"vr2"}, "fr2"},
254       {{"vr3"}, "fr3"},
255       {{"vr4"}, "fr4"},
256       {{"vr5"}, "fr5"},
257       {{"vr6"}, "fr6"},
258       {{"vr7"}, "fr7"},
259       {{"vr8"}, "fr8"},
260       {{"vr9"}, "fr9"},
261       {{"vr10"}, "fr10"},
262       {{"vr11"}, "fr11"},
263       {{"vr12"}, "fr12"},
264       {{"vr13"}, "fr13"},
265       {{"vr14"}, "fr14"},
266       {{"vr15"}, "fr15"},
267       {{"vr16"}, "fr16"},
268       {{"vr17"}, "fr17"},
269       {{"vr18"}, "fr18"},
270       {{"vr19"}, "fr19"},
271       {{"vr20"}, "fr20"},
272       {{"vr21"}, "fr21"},
273       {{"vr22"}, "fr22"},
274       {{"vr23"}, "fr23"},
275       {{"vr24"}, "fr24"},
276       {{"vr25"}, "fr25"},
277       {{"vr26"}, "fr26"},
278       {{"vr27"}, "fr27"},
279       {{"vr28"}, "fr28"},
280       {{"vr29"}, "fr29"},
281       {{"vr30"}, "fr30"},
282       {{"vr31"}, "fr31"},
283 
284   };
285   return llvm::ArrayRef(GCCRegAliases);
286 }
287 
288 bool CSKYTargetInfo::validateAsmConstraint(
289     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
290   switch (*Name) {
291   default:
292     return false;
293   case 'a':
294   case 'b':
295   case 'c':
296   case 'y':
297   case 'l':
298   case 'h':
299   case 'w':
300   case 'v': // A floating-point and vector register.
301   case 'z':
302     Info.setAllowsRegister();
303     return true;
304   }
305 }
306 
307 unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size,
308                                            bool HasNonWeakDef) const {
309   if (Size >= 32)
310     return 32;
311   return 0;
312 }
313