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("__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 98 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 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 141 ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const { 142 return ArrayRef<Builtin::Info>(); 143 } 144 145 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 219 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 291 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 310 unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const { 311 if (Size >= 32) 312 return 32; 313 return 0; 314 } 315