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::handleTargetFeatures(std::vector<std::string> &Features, 99 DiagnosticsEngine &Diags) { 100 HardFloat = false; 101 VDSPV2 = false; 102 VDSPV1 = false; 103 DSPV2 = false; 104 is3E3R1 = false; 105 106 for (const auto &Feature : Features) { 107 if (Feature == "+hard-float") 108 HardFloat = true; 109 if (Feature == "+vdspv2") 110 VDSPV2 = true; 111 if (Feature == "+dspv2") 112 DSPV2 = true; 113 if (Feature == "+vdspv1") 114 VDSPV1 = true; 115 if (Feature == "+3e3r1") 116 is3E3R1 = true; 117 } 118 119 return true; 120 } 121 122 ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const { 123 return ArrayRef<Builtin::Info>(); 124 } 125 126 ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const { 127 static const char *const GCCRegNames[] = { 128 // Integer registers 129 "r0", 130 "r1", 131 "r2", 132 "r3", 133 "r4", 134 "r5", 135 "r6", 136 "r7", 137 "r8", 138 "r9", 139 "r10", 140 "r11", 141 "r12", 142 "r13", 143 "r14", 144 "r15", 145 "r16", 146 "r17", 147 "r18", 148 "r19", 149 "r20", 150 "r21", 151 "r22", 152 "r23", 153 "r24", 154 "r25", 155 "r26", 156 "r27", 157 "r28", 158 "r29", 159 "r30", 160 "r31", 161 162 // Floating point registers 163 "fr0", 164 "fr1", 165 "fr2", 166 "fr3", 167 "fr4", 168 "fr5", 169 "fr6", 170 "fr7", 171 "fr8", 172 "fr9", 173 "fr10", 174 "fr11", 175 "fr12", 176 "fr13", 177 "fr14", 178 "fr15", 179 "fr16", 180 "fr17", 181 "fr18", 182 "fr19", 183 "fr20", 184 "fr21", 185 "fr22", 186 "fr23", 187 "fr24", 188 "fr25", 189 "fr26", 190 "fr27", 191 "fr28", 192 "fr29", 193 "fr30", 194 "fr31", 195 196 }; 197 return llvm::makeArrayRef(GCCRegNames); 198 } 199 200 ArrayRef<TargetInfo::GCCRegAlias> CSKYTargetInfo::getGCCRegAliases() const { 201 static const TargetInfo::GCCRegAlias GCCRegAliases[] = { 202 {{"a0"}, "r0"}, 203 {{"a1"}, "r1"}, 204 {{"a2"}, "r2"}, 205 {{"a3"}, "r3"}, 206 {{"l0"}, "r4"}, 207 {{"l1"}, "r5"}, 208 {{"l2"}, "r6"}, 209 {{"l3"}, "r7"}, 210 {{"l4"}, "r8"}, 211 {{"l5"}, "r9"}, 212 {{"l6"}, "r10"}, 213 {{"l7"}, "r11"}, 214 {{"t0"}, "r12"}, 215 {{"t1"}, "r13"}, 216 {{"sp"}, "r14"}, 217 {{"lr"}, "r15"}, 218 {{"l8"}, "r16"}, 219 {{"l9"}, "r17"}, 220 {{"t2"}, "r18"}, 221 {{"t3"}, "r19"}, 222 {{"t4"}, "r20"}, 223 {{"t5"}, "r21"}, 224 {{"t6"}, "r22"}, 225 {{"t7", "fp"}, "r23"}, 226 {{"t8", "top"}, "r24"}, 227 {{"t9", "bsp"}, "r25"}, 228 {{"r26"}, "r26"}, 229 {{"r27"}, "r27"}, 230 {{"gb", "rgb", "rdb"}, "r28"}, 231 {{"tb", "rtb"}, "r29"}, 232 {{"svbr"}, "r30"}, 233 {{"tls"}, "r31"}, 234 235 {{"vr0"}, "fr0"}, 236 {{"vr1"}, "fr1"}, 237 {{"vr2"}, "fr2"}, 238 {{"vr3"}, "fr3"}, 239 {{"vr4"}, "fr4"}, 240 {{"vr5"}, "fr5"}, 241 {{"vr6"}, "fr6"}, 242 {{"vr7"}, "fr7"}, 243 {{"vr8"}, "fr8"}, 244 {{"vr9"}, "fr9"}, 245 {{"vr10"}, "fr10"}, 246 {{"vr11"}, "fr11"}, 247 {{"vr12"}, "fr12"}, 248 {{"vr13"}, "fr13"}, 249 {{"vr14"}, "fr14"}, 250 {{"vr15"}, "fr15"}, 251 {{"vr16"}, "fr16"}, 252 {{"vr17"}, "fr17"}, 253 {{"vr18"}, "fr18"}, 254 {{"vr19"}, "fr19"}, 255 {{"vr20"}, "fr20"}, 256 {{"vr21"}, "fr21"}, 257 {{"vr22"}, "fr22"}, 258 {{"vr23"}, "fr23"}, 259 {{"vr24"}, "fr24"}, 260 {{"vr25"}, "fr25"}, 261 {{"vr26"}, "fr26"}, 262 {{"vr27"}, "fr27"}, 263 {{"vr28"}, "fr28"}, 264 {{"vr29"}, "fr29"}, 265 {{"vr30"}, "fr30"}, 266 {{"vr31"}, "fr31"}, 267 268 }; 269 return llvm::makeArrayRef(GCCRegAliases); 270 } 271 272 bool CSKYTargetInfo::validateAsmConstraint( 273 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 274 switch (*Name) { 275 default: 276 return false; 277 case 'a': 278 case 'b': 279 case 'c': 280 case 'y': 281 case 'l': 282 case 'h': 283 case 'w': 284 case 'v': // A floating-point and vector register. 285 case 'z': 286 Info.setAllowsRegister(); 287 return true; 288 } 289 } 290 291 unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const { 292 if (Size >= 32) 293 return 32; 294 return 0; 295 } 296