1 //===--- ARM.cpp - Implement ARM 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 ARM TargetInfo objects. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ARM.h" 14 #include "clang/Basic/Builtins.h" 15 #include "clang/Basic/Diagnostic.h" 16 #include "clang/Basic/TargetBuiltins.h" 17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/StringSwitch.h" 20 21 using namespace clang; 22 using namespace clang::targets; 23 24 void ARMTargetInfo::setABIAAPCS() { 25 IsAAPCS = true; 26 27 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; 28 BFloat16Width = BFloat16Align = 16; 29 BFloat16Format = &llvm::APFloat::BFloat(); 30 31 const llvm::Triple &T = getTriple(); 32 33 bool IsNetBSD = T.isOSNetBSD(); 34 bool IsOpenBSD = T.isOSOpenBSD(); 35 if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD) 36 WCharType = UnsignedInt; 37 38 UseBitFieldTypeAlignment = true; 39 40 ZeroLengthBitfieldBoundary = 0; 41 42 // Thumb1 add sp, #imm requires the immediate value be multiple of 4, 43 // so set preferred for small types to 32. 44 if (T.isOSBinFormatMachO()) { 45 resetDataLayout(BigEndian 46 ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" 47 : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", 48 "_"); 49 } else if (T.isOSWindows()) { 50 assert(!BigEndian && "Windows on ARM does not support big endian"); 51 resetDataLayout("e" 52 "-m:w" 53 "-p:32:32" 54 "-Fi8" 55 "-i64:64" 56 "-v128:64:128" 57 "-a:0:32" 58 "-n32" 59 "-S64"); 60 } else if (T.isOSNaCl()) { 61 assert(!BigEndian && "NaCl on ARM does not support big endian"); 62 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128"); 63 } else { 64 resetDataLayout(BigEndian 65 ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" 66 : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 67 } 68 69 // FIXME: Enumerated types are variable width in straight AAPCS. 70 } 71 72 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) { 73 const llvm::Triple &T = getTriple(); 74 75 IsAAPCS = false; 76 77 if (IsAAPCS16) 78 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; 79 else 80 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32; 81 BFloat16Width = BFloat16Align = 16; 82 BFloat16Format = &llvm::APFloat::BFloat(); 83 84 WCharType = SignedInt; 85 86 // Do not respect the alignment of bit-field types when laying out 87 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc. 88 UseBitFieldTypeAlignment = false; 89 90 /// gcc forces the alignment to 4 bytes, regardless of the type of the 91 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in 92 /// gcc. 93 ZeroLengthBitfieldBoundary = 32; 94 95 if (T.isOSBinFormatMachO() && IsAAPCS16) { 96 assert(!BigEndian && "AAPCS16 does not support big-endian"); 97 resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_"); 98 } else if (T.isOSBinFormatMachO()) 99 resetDataLayout( 100 BigEndian 101 ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" 102 : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32", 103 "_"); 104 else 105 resetDataLayout( 106 BigEndian 107 ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" 108 : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); 109 110 // FIXME: Override "preferred align" for double and long long. 111 } 112 113 void ARMTargetInfo::setArchInfo() { 114 StringRef ArchName = getTriple().getArchName(); 115 116 ArchISA = llvm::ARM::parseArchISA(ArchName); 117 CPU = std::string(llvm::ARM::getDefaultCPU(ArchName)); 118 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName); 119 if (AK != llvm::ARM::ArchKind::INVALID) 120 ArchKind = AK; 121 setArchInfo(ArchKind); 122 } 123 124 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) { 125 StringRef SubArch; 126 127 // cache TargetParser info 128 ArchKind = Kind; 129 SubArch = llvm::ARM::getSubArch(ArchKind); 130 ArchProfile = llvm::ARM::parseArchProfile(SubArch); 131 ArchVersion = llvm::ARM::parseArchVersion(SubArch); 132 133 // cache CPU related strings 134 CPUAttr = getCPUAttr(); 135 CPUProfile = getCPUProfile(); 136 } 137 138 void ARMTargetInfo::setAtomic() { 139 // when triple does not specify a sub arch, 140 // then we are not using inline atomics 141 bool ShouldUseInlineAtomic = 142 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) || 143 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7); 144 // Cortex M does not support 8 byte atomics, while general Thumb2 does. 145 if (ArchProfile == llvm::ARM::ProfileKind::M) { 146 MaxAtomicPromoteWidth = 32; 147 if (ShouldUseInlineAtomic) 148 MaxAtomicInlineWidth = 32; 149 } else { 150 MaxAtomicPromoteWidth = 64; 151 if (ShouldUseInlineAtomic) 152 MaxAtomicInlineWidth = 64; 153 } 154 } 155 156 bool ARMTargetInfo::hasMVE() const { 157 return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0; 158 } 159 160 bool ARMTargetInfo::hasMVEFloat() const { 161 return hasMVE() && (MVE & MVE_FP); 162 } 163 164 bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; } 165 166 bool ARMTargetInfo::isThumb() const { 167 return ArchISA == llvm::ARM::ISAKind::THUMB; 168 } 169 170 bool ARMTargetInfo::supportsThumb() const { 171 return CPUAttr.count('T') || ArchVersion >= 6; 172 } 173 174 bool ARMTargetInfo::supportsThumb2() const { 175 return CPUAttr.equals("6T2") || 176 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE")); 177 } 178 179 StringRef ARMTargetInfo::getCPUAttr() const { 180 // For most sub-arches, the build attribute CPU name is enough. 181 // For Cortex variants, it's slightly different. 182 switch (ArchKind) { 183 default: 184 return llvm::ARM::getCPUAttr(ArchKind); 185 case llvm::ARM::ArchKind::ARMV6M: 186 return "6M"; 187 case llvm::ARM::ArchKind::ARMV7S: 188 return "7S"; 189 case llvm::ARM::ArchKind::ARMV7A: 190 return "7A"; 191 case llvm::ARM::ArchKind::ARMV7R: 192 return "7R"; 193 case llvm::ARM::ArchKind::ARMV7M: 194 return "7M"; 195 case llvm::ARM::ArchKind::ARMV7EM: 196 return "7EM"; 197 case llvm::ARM::ArchKind::ARMV7VE: 198 return "7VE"; 199 case llvm::ARM::ArchKind::ARMV8A: 200 return "8A"; 201 case llvm::ARM::ArchKind::ARMV8_1A: 202 return "8_1A"; 203 case llvm::ARM::ArchKind::ARMV8_2A: 204 return "8_2A"; 205 case llvm::ARM::ArchKind::ARMV8_3A: 206 return "8_3A"; 207 case llvm::ARM::ArchKind::ARMV8_4A: 208 return "8_4A"; 209 case llvm::ARM::ArchKind::ARMV8_5A: 210 return "8_5A"; 211 case llvm::ARM::ArchKind::ARMV8_6A: 212 return "8_6A"; 213 case llvm::ARM::ArchKind::ARMV8_7A: 214 return "8_7A"; 215 case llvm::ARM::ArchKind::ARMV8_8A: 216 return "8_8A"; 217 case llvm::ARM::ArchKind::ARMV9A: 218 return "9A"; 219 case llvm::ARM::ArchKind::ARMV9_1A: 220 return "9_1A"; 221 case llvm::ARM::ArchKind::ARMV9_2A: 222 return "9_2A"; 223 case llvm::ARM::ArchKind::ARMV9_3A: 224 return "9_3A"; 225 case llvm::ARM::ArchKind::ARMV8MBaseline: 226 return "8M_BASE"; 227 case llvm::ARM::ArchKind::ARMV8MMainline: 228 return "8M_MAIN"; 229 case llvm::ARM::ArchKind::ARMV8R: 230 return "8R"; 231 case llvm::ARM::ArchKind::ARMV8_1MMainline: 232 return "8_1M_MAIN"; 233 } 234 } 235 236 StringRef ARMTargetInfo::getCPUProfile() const { 237 switch (ArchProfile) { 238 case llvm::ARM::ProfileKind::A: 239 return "A"; 240 case llvm::ARM::ProfileKind::R: 241 return "R"; 242 case llvm::ARM::ProfileKind::M: 243 return "M"; 244 default: 245 return ""; 246 } 247 } 248 249 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, 250 const TargetOptions &Opts) 251 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0), 252 HW_FP(0) { 253 bool IsOpenBSD = Triple.isOSOpenBSD(); 254 bool IsNetBSD = Triple.isOSNetBSD(); 255 256 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like 257 // environment where size_t is `unsigned long` rather than `unsigned int` 258 259 PtrDiffType = IntPtrType = 260 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || 261 IsNetBSD) 262 ? SignedLong 263 : SignedInt; 264 265 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || 266 IsNetBSD) 267 ? UnsignedLong 268 : UnsignedInt; 269 270 // ptrdiff_t is inconsistent on Darwin 271 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) && 272 !Triple.isWatchABI()) 273 PtrDiffType = SignedInt; 274 275 // Cache arch related info. 276 setArchInfo(); 277 278 // {} in inline assembly are neon specifiers, not assembly variant 279 // specifiers. 280 NoAsmVariants = true; 281 282 // FIXME: This duplicates code from the driver that sets the -target-abi 283 // option - this code is used if -target-abi isn't passed and should 284 // be unified in some way. 285 if (Triple.isOSBinFormatMachO()) { 286 // The backend is hardwired to assume AAPCS for M-class processors, ensure 287 // the frontend matches that. 288 if (Triple.getEnvironment() == llvm::Triple::EABI || 289 Triple.getOS() == llvm::Triple::UnknownOS || 290 ArchProfile == llvm::ARM::ProfileKind::M) { 291 setABI("aapcs"); 292 } else if (Triple.isWatchABI()) { 293 setABI("aapcs16"); 294 } else { 295 setABI("apcs-gnu"); 296 } 297 } else if (Triple.isOSWindows()) { 298 // FIXME: this is invalid for WindowsCE 299 setABI("aapcs"); 300 } else { 301 // Select the default based on the platform. 302 switch (Triple.getEnvironment()) { 303 case llvm::Triple::Android: 304 case llvm::Triple::GNUEABI: 305 case llvm::Triple::GNUEABIHF: 306 case llvm::Triple::MuslEABI: 307 case llvm::Triple::MuslEABIHF: 308 setABI("aapcs-linux"); 309 break; 310 case llvm::Triple::EABIHF: 311 case llvm::Triple::EABI: 312 setABI("aapcs"); 313 break; 314 case llvm::Triple::GNU: 315 setABI("apcs-gnu"); 316 break; 317 default: 318 if (IsNetBSD) 319 setABI("apcs-gnu"); 320 else if (IsOpenBSD) 321 setABI("aapcs-linux"); 322 else 323 setABI("aapcs"); 324 break; 325 } 326 } 327 328 // ARM targets default to using the ARM C++ ABI. 329 TheCXXABI.set(TargetCXXABI::GenericARM); 330 331 // ARM has atomics up to 8 bytes 332 setAtomic(); 333 334 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS) 335 // as well the default alignment 336 if (IsAAPCS && !Triple.isAndroid()) 337 DefaultAlignForAttributeAligned = MaxVectorAlign = 64; 338 339 // Do force alignment of members that follow zero length bitfields. If 340 // the alignment of the zero-length bitfield is greater than the member 341 // that follows it, `bar', `bar' will be aligned as the type of the 342 // zero length bitfield. 343 UseZeroLengthBitfieldAlignment = true; 344 345 if (Triple.getOS() == llvm::Triple::Linux || 346 Triple.getOS() == llvm::Triple::UnknownOS) 347 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU 348 ? "llvm.arm.gnu.eabi.mcount" 349 : "\01mcount"; 350 351 SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi"); 352 } 353 354 StringRef ARMTargetInfo::getABI() const { return ABI; } 355 356 bool ARMTargetInfo::setABI(const std::string &Name) { 357 ABI = Name; 358 359 // The defaults (above) are for AAPCS, check if we need to change them. 360 // 361 // FIXME: We need support for -meabi... we could just mangle it into the 362 // name. 363 if (Name == "apcs-gnu" || Name == "aapcs16") { 364 setABIAPCS(Name == "aapcs16"); 365 return true; 366 } 367 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") { 368 setABIAAPCS(); 369 return true; 370 } 371 return false; 372 } 373 374 bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const { 375 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch); 376 if (CPUArch == llvm::ARM::ArchKind::INVALID) 377 CPUArch = llvm::ARM::parseArch(getTriple().getArchName()); 378 379 if (CPUArch == llvm::ARM::ArchKind::INVALID) 380 return false; 381 382 StringRef ArchFeature = llvm::ARM::getArchName(CPUArch); 383 auto a = 384 llvm::Triple(ArchFeature, getTriple().getVendorName(), 385 getTriple().getOSName(), getTriple().getEnvironmentName()); 386 387 StringRef SubArch = llvm::ARM::getSubArch(CPUArch); 388 llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch); 389 return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M); 390 } 391 392 bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch, 393 BranchProtectionInfo &BPI, 394 StringRef &Err) const { 395 llvm::ARM::ParsedBranchProtection PBP; 396 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) 397 return false; 398 399 if (!isBranchProtectionSupportedArch(Arch)) 400 return false; 401 402 BPI.SignReturnAddr = 403 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope) 404 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf) 405 .Case("all", LangOptions::SignReturnAddressScopeKind::All) 406 .Default(LangOptions::SignReturnAddressScopeKind::None); 407 408 // Don't care for the sign key, beyond issuing a warning. 409 if (PBP.Key == "b_key") 410 Err = "b-key"; 411 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey; 412 413 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; 414 return true; 415 } 416 417 // FIXME: This should be based on Arch attributes, not CPU names. 418 bool ARMTargetInfo::initFeatureMap( 419 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, 420 const std::vector<std::string> &FeaturesVec) const { 421 422 std::string ArchFeature; 423 std::vector<StringRef> TargetFeatures; 424 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName()); 425 426 // Map the base architecture to an appropriate target feature, so we don't 427 // rely on the target triple. 428 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU); 429 if (CPUArch == llvm::ARM::ArchKind::INVALID) 430 CPUArch = Arch; 431 if (CPUArch != llvm::ARM::ArchKind::INVALID) { 432 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str(); 433 TargetFeatures.push_back(ArchFeature); 434 } 435 436 // get default FPU features 437 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch); 438 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures); 439 440 // get default Extension features 441 uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch); 442 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures); 443 444 for (auto Feature : TargetFeatures) 445 if (Feature[0] == '+') 446 Features[Feature.drop_front(1)] = true; 447 448 // Enable or disable thumb-mode explicitly per function to enable mixed 449 // ARM and Thumb code generation. 450 if (isThumb()) 451 Features["thumb-mode"] = true; 452 else 453 Features["thumb-mode"] = false; 454 455 // Convert user-provided arm and thumb GNU target attributes to 456 // [-|+]thumb-mode target features respectively. 457 std::vector<std::string> UpdatedFeaturesVec; 458 for (const auto &Feature : FeaturesVec) { 459 // Skip soft-float-abi; it's something we only use to initialize a bit of 460 // class state, and is otherwise unrecognized. 461 if (Feature == "+soft-float-abi") 462 continue; 463 464 StringRef FixedFeature; 465 if (Feature == "+arm") 466 FixedFeature = "-thumb-mode"; 467 else if (Feature == "+thumb") 468 FixedFeature = "+thumb-mode"; 469 else 470 FixedFeature = Feature; 471 UpdatedFeaturesVec.push_back(FixedFeature.str()); 472 } 473 474 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec); 475 } 476 477 478 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 479 DiagnosticsEngine &Diags) { 480 FPU = 0; 481 MVE = 0; 482 CRC = 0; 483 Crypto = 0; 484 SHA2 = 0; 485 AES = 0; 486 DSP = 0; 487 Unaligned = 1; 488 SoftFloat = false; 489 // Note that SoftFloatABI is initialized in our constructor. 490 HWDiv = 0; 491 DotProd = 0; 492 HasMatMul = 0; 493 HasPAC = 0; 494 HasBTI = 0; 495 HasFloat16 = true; 496 ARMCDECoprocMask = 0; 497 HasBFloat16 = false; 498 FPRegsDisabled = false; 499 500 // This does not diagnose illegal cases like having both 501 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64". 502 for (const auto &Feature : Features) { 503 if (Feature == "+soft-float") { 504 SoftFloat = true; 505 } else if (Feature == "+vfp2sp" || Feature == "+vfp2") { 506 FPU |= VFP2FPU; 507 HW_FP |= HW_FP_SP; 508 if (Feature == "+vfp2") 509 HW_FP |= HW_FP_DP; 510 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" || 511 Feature == "+vfp3" || Feature == "+vfp3d16") { 512 FPU |= VFP3FPU; 513 HW_FP |= HW_FP_SP; 514 if (Feature == "+vfp3" || Feature == "+vfp3d16") 515 HW_FP |= HW_FP_DP; 516 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" || 517 Feature == "+vfp4" || Feature == "+vfp4d16") { 518 FPU |= VFP4FPU; 519 HW_FP |= HW_FP_SP | HW_FP_HP; 520 if (Feature == "+vfp4" || Feature == "+vfp4d16") 521 HW_FP |= HW_FP_DP; 522 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" || 523 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") { 524 FPU |= FPARMV8; 525 HW_FP |= HW_FP_SP | HW_FP_HP; 526 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16") 527 HW_FP |= HW_FP_DP; 528 } else if (Feature == "+neon") { 529 FPU |= NeonFPU; 530 HW_FP |= HW_FP_SP; 531 } else if (Feature == "+hwdiv") { 532 HWDiv |= HWDivThumb; 533 } else if (Feature == "+hwdiv-arm") { 534 HWDiv |= HWDivARM; 535 } else if (Feature == "+crc") { 536 CRC = 1; 537 } else if (Feature == "+crypto") { 538 Crypto = 1; 539 } else if (Feature == "+sha2") { 540 SHA2 = 1; 541 } else if (Feature == "+aes") { 542 AES = 1; 543 } else if (Feature == "+dsp") { 544 DSP = 1; 545 } else if (Feature == "+fp64") { 546 HW_FP |= HW_FP_DP; 547 } else if (Feature == "+8msecext") { 548 if (CPUProfile != "M" || ArchVersion != 8) { 549 Diags.Report(diag::err_target_unsupported_mcmse) << CPU; 550 return false; 551 } 552 } else if (Feature == "+strict-align") { 553 Unaligned = 0; 554 } else if (Feature == "+fp16") { 555 HW_FP |= HW_FP_HP; 556 } else if (Feature == "+fullfp16") { 557 HasLegalHalfType = true; 558 } else if (Feature == "+dotprod") { 559 DotProd = true; 560 } else if (Feature == "+mve") { 561 MVE |= MVE_INT; 562 } else if (Feature == "+mve.fp") { 563 HasLegalHalfType = true; 564 FPU |= FPARMV8; 565 MVE |= MVE_INT | MVE_FP; 566 HW_FP |= HW_FP_SP | HW_FP_HP; 567 } else if (Feature == "+i8mm") { 568 HasMatMul = 1; 569 } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" && 570 Feature <= "+cdecp7") { 571 unsigned Coproc = Feature.back() - '0'; 572 ARMCDECoprocMask |= (1U << Coproc); 573 } else if (Feature == "+bf16") { 574 HasBFloat16 = true; 575 } else if (Feature == "-fpregs") { 576 FPRegsDisabled = true; 577 } else if (Feature == "+pacbti") { 578 HasPAC = 1; 579 HasBTI = 1; 580 } 581 } 582 583 switch (ArchVersion) { 584 case 6: 585 if (ArchProfile == llvm::ARM::ProfileKind::M) 586 LDREX = 0; 587 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K) 588 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 589 else 590 LDREX = LDREX_W; 591 break; 592 case 7: 593 if (ArchProfile == llvm::ARM::ProfileKind::M) 594 LDREX = LDREX_W | LDREX_H | LDREX_B; 595 else 596 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 597 break; 598 case 8: 599 case 9: 600 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 601 } 602 603 if (!(FPU & NeonFPU) && FPMath == FP_Neon) { 604 Diags.Report(diag::err_target_unsupported_fpmath) << "neon"; 605 return false; 606 } 607 608 if (FPMath == FP_Neon) 609 Features.push_back("+neonfp"); 610 else if (FPMath == FP_VFP) 611 Features.push_back("-neonfp"); 612 613 return true; 614 } 615 616 bool ARMTargetInfo::hasFeature(StringRef Feature) const { 617 return llvm::StringSwitch<bool>(Feature) 618 .Case("arm", true) 619 .Case("aarch32", true) 620 .Case("softfloat", SoftFloat) 621 .Case("thumb", isThumb()) 622 .Case("neon", (FPU & NeonFPU) && !SoftFloat) 623 .Case("vfp", FPU && !SoftFloat) 624 .Case("hwdiv", HWDiv & HWDivThumb) 625 .Case("hwdiv-arm", HWDiv & HWDivARM) 626 .Case("mve", hasMVE()) 627 .Default(false); 628 } 629 630 bool ARMTargetInfo::hasBFloat16Type() const { 631 return HasBFloat16 && !SoftFloat; 632 } 633 634 bool ARMTargetInfo::isValidCPUName(StringRef Name) const { 635 return Name == "generic" || 636 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID; 637 } 638 639 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { 640 llvm::ARM::fillValidCPUArchList(Values); 641 } 642 643 bool ARMTargetInfo::setCPU(const std::string &Name) { 644 if (Name != "generic") 645 setArchInfo(llvm::ARM::parseCPUArch(Name)); 646 647 if (ArchKind == llvm::ARM::ArchKind::INVALID) 648 return false; 649 setAtomic(); 650 CPU = Name; 651 return true; 652 } 653 654 bool ARMTargetInfo::setFPMath(StringRef Name) { 655 if (Name == "neon") { 656 FPMath = FP_Neon; 657 return true; 658 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" || 659 Name == "vfp4") { 660 FPMath = FP_VFP; 661 return true; 662 } 663 return false; 664 } 665 666 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, 667 MacroBuilder &Builder) const { 668 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); 669 } 670 671 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts, 672 MacroBuilder &Builder) const { 673 // Also include the ARMv8.1-A defines 674 getTargetDefinesARMV81A(Opts, Builder); 675 } 676 677 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts, 678 MacroBuilder &Builder) const { 679 // Also include the ARMv8.2-A defines 680 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1"); 681 getTargetDefinesARMV82A(Opts, Builder); 682 } 683 684 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, 685 MacroBuilder &Builder) const { 686 // Target identification. 687 Builder.defineMacro("__arm"); 688 Builder.defineMacro("__arm__"); 689 // For bare-metal none-eabi. 690 if (getTriple().getOS() == llvm::Triple::UnknownOS && 691 (getTriple().getEnvironment() == llvm::Triple::EABI || 692 getTriple().getEnvironment() == llvm::Triple::EABIHF)) 693 Builder.defineMacro("__ELF__"); 694 695 // Target properties. 696 Builder.defineMacro("__REGISTER_PREFIX__", ""); 697 698 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU 699 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__. 700 if (getTriple().isWatchABI()) 701 Builder.defineMacro("__ARM_ARCH_7K__", "2"); 702 703 if (!CPUAttr.empty()) 704 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__"); 705 706 // ACLE 6.4.1 ARM/Thumb instruction set architecture 707 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA 708 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion)); 709 710 if (ArchVersion >= 8) { 711 // ACLE 6.5.7 Crypto Extension 712 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained 713 // feature macros for AES and SHA2 714 if (SHA2 && AES) 715 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1"); 716 if (SHA2) 717 Builder.defineMacro("__ARM_FEATURE_SHA2", "1"); 718 if (AES) 719 Builder.defineMacro("__ARM_FEATURE_AES", "1"); 720 // ACLE 6.5.8 CRC32 Extension 721 if (CRC) 722 Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); 723 // ACLE 6.5.10 Numeric Maximum and Minimum 724 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1"); 725 // ACLE 6.5.9 Directed Rounding 726 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1"); 727 } 728 729 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It 730 // is not defined for the M-profile. 731 // NOTE that the default profile is assumed to be 'A' 732 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M) 733 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1"); 734 735 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original 736 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the 737 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all 738 // v7 and v8 architectures excluding v8-M Baseline. 739 if (supportsThumb2()) 740 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2"); 741 else if (supportsThumb()) 742 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1"); 743 744 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit 745 // instruction set such as ARM or Thumb. 746 Builder.defineMacro("__ARM_32BIT_STATE", "1"); 747 748 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex) 749 750 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset. 751 if (!CPUProfile.empty()) 752 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'"); 753 754 // ACLE 6.4.3 Unaligned access supported in hardware 755 if (Unaligned) 756 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); 757 758 // ACLE 6.4.4 LDREX/STREX 759 if (LDREX) 760 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX)); 761 762 // ACLE 6.4.5 CLZ 763 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") || 764 ArchVersion > 6) 765 Builder.defineMacro("__ARM_FEATURE_CLZ", "1"); 766 767 // ACLE 6.5.1 Hardware Floating Point 768 if (HW_FP) 769 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP)); 770 771 // ACLE predefines. 772 Builder.defineMacro("__ARM_ACLE", "200"); 773 774 // FP16 support (we currently only support IEEE format). 775 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1"); 776 Builder.defineMacro("__ARM_FP16_ARGS", "1"); 777 778 // ACLE 6.5.3 Fused multiply-accumulate (FMA) 779 if (ArchVersion >= 7 && (FPU & VFP4FPU)) 780 Builder.defineMacro("__ARM_FEATURE_FMA", "1"); 781 782 // Subtarget options. 783 784 // FIXME: It's more complicated than this and we don't really support 785 // interworking. 786 // Windows on ARM does not "support" interworking 787 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows()) 788 Builder.defineMacro("__THUMB_INTERWORK__"); 789 790 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") { 791 // Embedded targets on Darwin follow AAPCS, but not EABI. 792 // Windows on ARM follows AAPCS VFP, but does not conform to EABI. 793 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows()) 794 Builder.defineMacro("__ARM_EABI__"); 795 Builder.defineMacro("__ARM_PCS", "1"); 796 } 797 798 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16") 799 Builder.defineMacro("__ARM_PCS_VFP", "1"); 800 801 if (SoftFloat) 802 Builder.defineMacro("__SOFTFP__"); 803 804 // ACLE position independent code macros. 805 if (Opts.ROPI) 806 Builder.defineMacro("__ARM_ROPI", "1"); 807 if (Opts.RWPI) 808 Builder.defineMacro("__ARM_RWPI", "1"); 809 810 if (ArchKind == llvm::ARM::ArchKind::XSCALE) 811 Builder.defineMacro("__XSCALE__"); 812 813 if (isThumb()) { 814 Builder.defineMacro("__THUMBEL__"); 815 Builder.defineMacro("__thumb__"); 816 if (supportsThumb2()) 817 Builder.defineMacro("__thumb2__"); 818 } 819 820 // ACLE 6.4.9 32-bit SIMD instructions 821 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP)) 822 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1"); 823 824 // ACLE 6.4.10 Hardware Integer Divide 825 if (((HWDiv & HWDivThumb) && isThumb()) || 826 ((HWDiv & HWDivARM) && !isThumb())) { 827 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); 828 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1"); 829 } 830 831 // Note, this is always on in gcc, even though it doesn't make sense. 832 Builder.defineMacro("__APCS_32__"); 833 834 // __VFP_FP__ means that the floating-point format is VFP, not that a hardware 835 // FPU is present. Moreover, the VFP format is the only one supported by 836 // clang. For these reasons, this macro is always defined. 837 Builder.defineMacro("__VFP_FP__"); 838 839 if (FPUModeIsVFP((FPUMode)FPU)) { 840 if (FPU & VFP2FPU) 841 Builder.defineMacro("__ARM_VFPV2__"); 842 if (FPU & VFP3FPU) 843 Builder.defineMacro("__ARM_VFPV3__"); 844 if (FPU & VFP4FPU) 845 Builder.defineMacro("__ARM_VFPV4__"); 846 if (FPU & FPARMV8) 847 Builder.defineMacro("__ARM_FPV5__"); 848 } 849 850 // This only gets set when Neon instructions are actually available, unlike 851 // the VFP define, hence the soft float and arch check. This is subtly 852 // different from gcc, we follow the intent which was that it should be set 853 // when Neon instructions are actually available. 854 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) { 855 Builder.defineMacro("__ARM_NEON", "1"); 856 Builder.defineMacro("__ARM_NEON__"); 857 // current AArch32 NEON implementations do not support double-precision 858 // floating-point even when it is present in VFP. 859 Builder.defineMacro("__ARM_NEON_FP", 860 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP)); 861 } 862 863 if (hasMVE()) { 864 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1"); 865 } 866 867 if (hasCDE()) { 868 Builder.defineMacro("__ARM_FEATURE_CDE", "1"); 869 Builder.defineMacro("__ARM_FEATURE_CDE_COPROC", 870 "0x" + Twine::utohexstr(getARMCDECoprocMask())); 871 } 872 873 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", 874 Twine(Opts.WCharSize ? Opts.WCharSize : 4)); 875 876 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); 877 878 // CMSE 879 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M) 880 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1"); 881 882 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") { 883 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 884 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 885 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 886 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 887 } 888 889 // ACLE 6.4.7 DSP instructions 890 if (DSP) { 891 Builder.defineMacro("__ARM_FEATURE_DSP", "1"); 892 } 893 894 // ACLE 6.4.8 Saturation instructions 895 bool SAT = false; 896 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) { 897 Builder.defineMacro("__ARM_FEATURE_SAT", "1"); 898 SAT = true; 899 } 900 901 // ACLE 6.4.6 Q (saturation) flag 902 if (DSP || SAT) 903 Builder.defineMacro("__ARM_FEATURE_QBIT", "1"); 904 905 if (Opts.UnsafeFPMath) 906 Builder.defineMacro("__ARM_FP_FAST", "1"); 907 908 // Armv8.2-A FP16 vector intrinsic 909 if ((FPU & NeonFPU) && HasLegalHalfType) 910 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); 911 912 // Armv8.2-A FP16 scalar intrinsics 913 if (HasLegalHalfType) 914 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); 915 916 // Armv8.2-A dot product intrinsics 917 if (DotProd) 918 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); 919 920 if (HasMatMul) 921 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); 922 923 if (HasPAC) 924 Builder.defineMacro("__ARM_FEATURE_PAUTH", "1"); 925 926 if (HasBTI) 927 Builder.defineMacro("__ARM_FEATURE_BTI", "1"); 928 929 if (HasBFloat16) { 930 Builder.defineMacro("__ARM_FEATURE_BF16", "1"); 931 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); 932 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); 933 } 934 935 if (Opts.BranchTargetEnforcement) 936 Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); 937 938 if (Opts.hasSignReturnAddress()) { 939 unsigned Value = 1; 940 if (Opts.isSignReturnAddressScopeAll()) 941 Value |= 1 << 2; 942 Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value)); 943 } 944 945 switch (ArchKind) { 946 default: 947 break; 948 case llvm::ARM::ArchKind::ARMV8_1A: 949 getTargetDefinesARMV81A(Opts, Builder); 950 break; 951 case llvm::ARM::ArchKind::ARMV8_2A: 952 getTargetDefinesARMV82A(Opts, Builder); 953 break; 954 case llvm::ARM::ArchKind::ARMV8_3A: 955 case llvm::ARM::ArchKind::ARMV8_4A: 956 case llvm::ARM::ArchKind::ARMV8_5A: 957 case llvm::ARM::ArchKind::ARMV8_6A: 958 case llvm::ARM::ArchKind::ARMV8_7A: 959 case llvm::ARM::ArchKind::ARMV8_8A: 960 case llvm::ARM::ArchKind::ARMV9A: 961 case llvm::ARM::ArchKind::ARMV9_1A: 962 case llvm::ARM::ArchKind::ARMV9_2A: 963 case llvm::ARM::ArchKind::ARMV9_3A: 964 getTargetDefinesARMV83A(Opts, Builder); 965 break; 966 } 967 } 968 969 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = { 970 #define BUILTIN(ID, TYPE, ATTRS) \ 971 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 972 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 973 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, 974 #include "clang/Basic/BuiltinsNEON.def" 975 976 #define BUILTIN(ID, TYPE, ATTRS) \ 977 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 978 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ 979 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, 980 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 981 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, 982 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 983 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 984 #include "clang/Basic/BuiltinsARM.def" 985 }; 986 987 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const { 988 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin - 989 Builtin::FirstTSBuiltin); 990 } 991 992 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; } 993 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const { 994 return IsAAPCS 995 ? AAPCSABIBuiltinVaList 996 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList 997 : TargetInfo::VoidPtrBuiltinVaList); 998 } 999 1000 const char *const ARMTargetInfo::GCCRegNames[] = { 1001 // Integer registers 1002 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", 1003 "r12", "sp", "lr", "pc", 1004 1005 // Float registers 1006 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 1007 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 1008 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 1009 1010 // Double registers 1011 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 1012 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 1013 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 1014 1015 // Quad registers 1016 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", 1017 "q12", "q13", "q14", "q15"}; 1018 1019 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const { 1020 return llvm::makeArrayRef(GCCRegNames); 1021 } 1022 1023 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 1024 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"}, 1025 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"}, 1026 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"}, 1027 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"}, 1028 // The S, D and Q registers overlap, but aren't really aliases; we 1029 // don't want to substitute one of these for a different-sized one. 1030 }; 1031 1032 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const { 1033 return llvm::makeArrayRef(GCCRegAliases); 1034 } 1035 1036 bool ARMTargetInfo::validateAsmConstraint( 1037 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 1038 switch (*Name) { 1039 default: 1040 break; 1041 case 'l': // r0-r7 if thumb, r0-r15 if ARM 1042 Info.setAllowsRegister(); 1043 return true; 1044 case 'h': // r8-r15, thumb only 1045 if (isThumb()) { 1046 Info.setAllowsRegister(); 1047 return true; 1048 } 1049 break; 1050 case 's': // An integer constant, but allowing only relocatable values. 1051 return true; 1052 case 't': // s0-s31, d0-d31, or q0-q15 1053 case 'w': // s0-s15, d0-d7, or q0-q3 1054 case 'x': // s0-s31, d0-d15, or q0-q7 1055 if (FPRegsDisabled) 1056 return false; 1057 Info.setAllowsRegister(); 1058 return true; 1059 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW) 1060 // only available in ARMv6T2 and above 1061 if (CPUAttr.equals("6T2") || ArchVersion >= 7) { 1062 Info.setRequiresImmediate(0, 65535); 1063 return true; 1064 } 1065 break; 1066 case 'I': 1067 if (isThumb()) { 1068 if (!supportsThumb2()) 1069 Info.setRequiresImmediate(0, 255); 1070 else 1071 // FIXME: should check if immediate value would be valid for a Thumb2 1072 // data-processing instruction 1073 Info.setRequiresImmediate(); 1074 } else 1075 // FIXME: should check if immediate value would be valid for an ARM 1076 // data-processing instruction 1077 Info.setRequiresImmediate(); 1078 return true; 1079 case 'J': 1080 if (isThumb() && !supportsThumb2()) 1081 Info.setRequiresImmediate(-255, -1); 1082 else 1083 Info.setRequiresImmediate(-4095, 4095); 1084 return true; 1085 case 'K': 1086 if (isThumb()) { 1087 if (!supportsThumb2()) 1088 // FIXME: should check if immediate value can be obtained from shifting 1089 // a value between 0 and 255 left by any amount 1090 Info.setRequiresImmediate(); 1091 else 1092 // FIXME: should check if immediate value would be valid for a Thumb2 1093 // data-processing instruction when inverted 1094 Info.setRequiresImmediate(); 1095 } else 1096 // FIXME: should check if immediate value would be valid for an ARM 1097 // data-processing instruction when inverted 1098 Info.setRequiresImmediate(); 1099 return true; 1100 case 'L': 1101 if (isThumb()) { 1102 if (!supportsThumb2()) 1103 Info.setRequiresImmediate(-7, 7); 1104 else 1105 // FIXME: should check if immediate value would be valid for a Thumb2 1106 // data-processing instruction when negated 1107 Info.setRequiresImmediate(); 1108 } else 1109 // FIXME: should check if immediate value would be valid for an ARM 1110 // data-processing instruction when negated 1111 Info.setRequiresImmediate(); 1112 return true; 1113 case 'M': 1114 if (isThumb() && !supportsThumb2()) 1115 // FIXME: should check if immediate value is a multiple of 4 between 0 and 1116 // 1020 1117 Info.setRequiresImmediate(); 1118 else 1119 // FIXME: should check if immediate value is a power of two or a integer 1120 // between 0 and 32 1121 Info.setRequiresImmediate(); 1122 return true; 1123 case 'N': 1124 // Thumb1 only 1125 if (isThumb() && !supportsThumb2()) { 1126 Info.setRequiresImmediate(0, 31); 1127 return true; 1128 } 1129 break; 1130 case 'O': 1131 // Thumb1 only 1132 if (isThumb() && !supportsThumb2()) { 1133 // FIXME: should check if immediate value is a multiple of 4 between -508 1134 // and 508 1135 Info.setRequiresImmediate(); 1136 return true; 1137 } 1138 break; 1139 case 'Q': // A memory address that is a single base register. 1140 Info.setAllowsMemory(); 1141 return true; 1142 case 'T': 1143 switch (Name[1]) { 1144 default: 1145 break; 1146 case 'e': // Even general-purpose register 1147 case 'o': // Odd general-purpose register 1148 Info.setAllowsRegister(); 1149 Name++; 1150 return true; 1151 } 1152 break; 1153 case 'U': // a memory reference... 1154 switch (Name[1]) { 1155 case 'q': // ...ARMV4 ldrsb 1156 case 'v': // ...VFP load/store (reg+constant offset) 1157 case 'y': // ...iWMMXt load/store 1158 case 't': // address valid for load/store opaque types wider 1159 // than 128-bits 1160 case 'n': // valid address for Neon doubleword vector load/store 1161 case 'm': // valid address for Neon element and structure load/store 1162 case 's': // valid address for non-offset loads/stores of quad-word 1163 // values in four ARM registers 1164 Info.setAllowsMemory(); 1165 Name++; 1166 return true; 1167 } 1168 break; 1169 } 1170 return false; 1171 } 1172 1173 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const { 1174 std::string R; 1175 switch (*Constraint) { 1176 case 'U': // Two-character constraint; add "^" hint for later parsing. 1177 case 'T': 1178 R = std::string("^") + std::string(Constraint, 2); 1179 Constraint++; 1180 break; 1181 case 'p': // 'p' should be translated to 'r' by default. 1182 R = std::string("r"); 1183 break; 1184 default: 1185 return std::string(1, *Constraint); 1186 } 1187 return R; 1188 } 1189 1190 bool ARMTargetInfo::validateConstraintModifier( 1191 StringRef Constraint, char Modifier, unsigned Size, 1192 std::string &SuggestedModifier) const { 1193 bool isOutput = (Constraint[0] == '='); 1194 bool isInOut = (Constraint[0] == '+'); 1195 1196 // Strip off constraint modifiers. 1197 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 1198 Constraint = Constraint.substr(1); 1199 1200 switch (Constraint[0]) { 1201 default: 1202 break; 1203 case 'r': { 1204 switch (Modifier) { 1205 default: 1206 return (isInOut || isOutput || Size <= 64); 1207 case 'q': 1208 // A register of size 32 cannot fit a vector type. 1209 return false; 1210 } 1211 } 1212 } 1213 1214 return true; 1215 } 1216 const char *ARMTargetInfo::getClobbers() const { 1217 // FIXME: Is this really right? 1218 return ""; 1219 } 1220 1221 TargetInfo::CallingConvCheckResult 1222 ARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1223 switch (CC) { 1224 case CC_AAPCS: 1225 case CC_AAPCS_VFP: 1226 case CC_Swift: 1227 case CC_SwiftAsync: 1228 case CC_OpenCLKernel: 1229 return CCCR_OK; 1230 default: 1231 return CCCR_Warning; 1232 } 1233 } 1234 1235 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 1236 if (RegNo == 0) 1237 return 0; 1238 if (RegNo == 1) 1239 return 1; 1240 return -1; 1241 } 1242 1243 bool ARMTargetInfo::hasSjLjLowering() const { return true; } 1244 1245 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple, 1246 const TargetOptions &Opts) 1247 : ARMTargetInfo(Triple, Opts) {} 1248 1249 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1250 MacroBuilder &Builder) const { 1251 Builder.defineMacro("__ARMEL__"); 1252 ARMTargetInfo::getTargetDefines(Opts, Builder); 1253 } 1254 1255 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple, 1256 const TargetOptions &Opts) 1257 : ARMTargetInfo(Triple, Opts) {} 1258 1259 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts, 1260 MacroBuilder &Builder) const { 1261 Builder.defineMacro("__ARMEB__"); 1262 Builder.defineMacro("__ARM_BIG_ENDIAN"); 1263 ARMTargetInfo::getTargetDefines(Opts, Builder); 1264 } 1265 1266 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple, 1267 const TargetOptions &Opts) 1268 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) { 1269 } 1270 1271 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts, 1272 MacroBuilder &Builder) const { 1273 // FIXME: this is invalid for WindowsCE 1274 Builder.defineMacro("_M_ARM_NT", "1"); 1275 Builder.defineMacro("_M_ARMT", "_M_ARM"); 1276 Builder.defineMacro("_M_THUMB", "_M_ARM"); 1277 1278 assert((Triple.getArch() == llvm::Triple::arm || 1279 Triple.getArch() == llvm::Triple::thumb) && 1280 "invalid architecture for Windows ARM target info"); 1281 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6; 1282 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset)); 1283 1284 // TODO map the complete set of values 1285 // 31: VFPv3 40: VFPv4 1286 Builder.defineMacro("_M_ARM_FP", "31"); 1287 } 1288 1289 TargetInfo::BuiltinVaListKind 1290 WindowsARMTargetInfo::getBuiltinVaListKind() const { 1291 return TargetInfo::CharPtrBuiltinVaList; 1292 } 1293 1294 TargetInfo::CallingConvCheckResult 1295 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1296 switch (CC) { 1297 case CC_X86StdCall: 1298 case CC_X86ThisCall: 1299 case CC_X86FastCall: 1300 case CC_X86VectorCall: 1301 return CCCR_Ignore; 1302 case CC_C: 1303 case CC_OpenCLKernel: 1304 case CC_PreserveMost: 1305 case CC_PreserveAll: 1306 case CC_Swift: 1307 case CC_SwiftAsync: 1308 return CCCR_OK; 1309 default: 1310 return CCCR_Warning; 1311 } 1312 } 1313 1314 // Windows ARM + Itanium C++ ABI Target 1315 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo( 1316 const llvm::Triple &Triple, const TargetOptions &Opts) 1317 : WindowsARMTargetInfo(Triple, Opts) { 1318 TheCXXABI.set(TargetCXXABI::GenericARM); 1319 } 1320 1321 void ItaniumWindowsARMleTargetInfo::getTargetDefines( 1322 const LangOptions &Opts, MacroBuilder &Builder) const { 1323 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1324 1325 if (Opts.MSVCCompat) 1326 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1327 } 1328 1329 // Windows ARM, MS (C++) ABI 1330 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple, 1331 const TargetOptions &Opts) 1332 : WindowsARMTargetInfo(Triple, Opts) { 1333 TheCXXABI.set(TargetCXXABI::Microsoft); 1334 } 1335 1336 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1337 MacroBuilder &Builder) const { 1338 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1339 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1340 } 1341 1342 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple, 1343 const TargetOptions &Opts) 1344 : WindowsARMTargetInfo(Triple, Opts) { 1345 TheCXXABI.set(TargetCXXABI::GenericARM); 1346 } 1347 1348 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1349 MacroBuilder &Builder) const { 1350 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1351 Builder.defineMacro("_ARM_"); 1352 } 1353 1354 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple, 1355 const TargetOptions &Opts) 1356 : ARMleTargetInfo(Triple, Opts) { 1357 this->WCharType = TargetInfo::UnsignedShort; 1358 TLSSupported = false; 1359 DoubleAlign = LongLongAlign = 64; 1360 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 1361 } 1362 1363 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1364 MacroBuilder &Builder) const { 1365 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1366 Builder.defineMacro("_ARM_"); 1367 Builder.defineMacro("__CYGWIN__"); 1368 Builder.defineMacro("__CYGWIN32__"); 1369 DefineStd(Builder, "unix", Opts); 1370 if (Opts.CPlusPlus) 1371 Builder.defineMacro("_GNU_SOURCE"); 1372 } 1373 1374 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple, 1375 const TargetOptions &Opts) 1376 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) { 1377 HasAlignMac68kSupport = true; 1378 // iOS always has 64-bit atomic instructions. 1379 // FIXME: This should be based off of the target features in 1380 // ARMleTargetInfo. 1381 MaxAtomicInlineWidth = 64; 1382 1383 if (Triple.isWatchABI()) { 1384 // Darwin on iOS uses a variant of the ARM C++ ABI. 1385 TheCXXABI.set(TargetCXXABI::WatchOS); 1386 1387 // BOOL should be a real boolean on the new ABI 1388 UseSignedCharForObjCBool = false; 1389 } else 1390 TheCXXABI.set(TargetCXXABI::iOS); 1391 } 1392 1393 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts, 1394 const llvm::Triple &Triple, 1395 MacroBuilder &Builder) const { 1396 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 1397 } 1398 1399 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple, 1400 const TargetOptions &Opts) 1401 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(), 1402 Triple.getOSName(), 1403 Triple.getEnvironmentName()), 1404 Opts) { 1405 IsRenderScriptTarget = true; 1406 LongWidth = LongAlign = 64; 1407 } 1408 1409 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts, 1410 MacroBuilder &Builder) const { 1411 Builder.defineMacro("__RENDERSCRIPT__"); 1412 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1413 } 1414