xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.cpp (revision a2fda816eb054d5873be223ef2461741dfcc253c)
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<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const {
143    return ArrayRef<Builtin::Info>();
144  }
145  
146  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  
220  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  
292  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  
311  unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const {
312    if (Size >= 32)
313      return 32;
314    return 0;
315  }
316