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_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 983 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, 984 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 985 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 986 #include "clang/Basic/BuiltinsARM.def" 987 }; 988 989 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const { 990 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin - 991 Builtin::FirstTSBuiltin); 992 } 993 994 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; } 995 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const { 996 return IsAAPCS 997 ? AAPCSABIBuiltinVaList 998 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList 999 : TargetInfo::VoidPtrBuiltinVaList); 1000 } 1001 1002 const char *const ARMTargetInfo::GCCRegNames[] = { 1003 // Integer registers 1004 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", 1005 "r12", "sp", "lr", "pc", 1006 1007 // Float registers 1008 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 1009 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 1010 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 1011 1012 // Double registers 1013 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 1014 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 1015 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 1016 1017 // Quad registers 1018 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", 1019 "q12", "q13", "q14", "q15"}; 1020 1021 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const { 1022 return llvm::makeArrayRef(GCCRegNames); 1023 } 1024 1025 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 1026 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"}, 1027 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"}, 1028 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"}, 1029 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"}, 1030 // The S, D and Q registers overlap, but aren't really aliases; we 1031 // don't want to substitute one of these for a different-sized one. 1032 }; 1033 1034 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const { 1035 return llvm::makeArrayRef(GCCRegAliases); 1036 } 1037 1038 bool ARMTargetInfo::validateAsmConstraint( 1039 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 1040 switch (*Name) { 1041 default: 1042 break; 1043 case 'l': // r0-r7 if thumb, r0-r15 if ARM 1044 Info.setAllowsRegister(); 1045 return true; 1046 case 'h': // r8-r15, thumb only 1047 if (isThumb()) { 1048 Info.setAllowsRegister(); 1049 return true; 1050 } 1051 break; 1052 case 's': // An integer constant, but allowing only relocatable values. 1053 return true; 1054 case 't': // s0-s31, d0-d31, or q0-q15 1055 case 'w': // s0-s15, d0-d7, or q0-q3 1056 case 'x': // s0-s31, d0-d15, or q0-q7 1057 if (FPRegsDisabled) 1058 return false; 1059 Info.setAllowsRegister(); 1060 return true; 1061 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW) 1062 // only available in ARMv6T2 and above 1063 if (CPUAttr.equals("6T2") || ArchVersion >= 7) { 1064 Info.setRequiresImmediate(0, 65535); 1065 return true; 1066 } 1067 break; 1068 case 'I': 1069 if (isThumb()) { 1070 if (!supportsThumb2()) 1071 Info.setRequiresImmediate(0, 255); 1072 else 1073 // FIXME: should check if immediate value would be valid for a Thumb2 1074 // data-processing instruction 1075 Info.setRequiresImmediate(); 1076 } else 1077 // FIXME: should check if immediate value would be valid for an ARM 1078 // data-processing instruction 1079 Info.setRequiresImmediate(); 1080 return true; 1081 case 'J': 1082 if (isThumb() && !supportsThumb2()) 1083 Info.setRequiresImmediate(-255, -1); 1084 else 1085 Info.setRequiresImmediate(-4095, 4095); 1086 return true; 1087 case 'K': 1088 if (isThumb()) { 1089 if (!supportsThumb2()) 1090 // FIXME: should check if immediate value can be obtained from shifting 1091 // a value between 0 and 255 left by any amount 1092 Info.setRequiresImmediate(); 1093 else 1094 // FIXME: should check if immediate value would be valid for a Thumb2 1095 // data-processing instruction when inverted 1096 Info.setRequiresImmediate(); 1097 } else 1098 // FIXME: should check if immediate value would be valid for an ARM 1099 // data-processing instruction when inverted 1100 Info.setRequiresImmediate(); 1101 return true; 1102 case 'L': 1103 if (isThumb()) { 1104 if (!supportsThumb2()) 1105 Info.setRequiresImmediate(-7, 7); 1106 else 1107 // FIXME: should check if immediate value would be valid for a Thumb2 1108 // data-processing instruction when negated 1109 Info.setRequiresImmediate(); 1110 } else 1111 // FIXME: should check if immediate value would be valid for an ARM 1112 // data-processing instruction when negated 1113 Info.setRequiresImmediate(); 1114 return true; 1115 case 'M': 1116 if (isThumb() && !supportsThumb2()) 1117 // FIXME: should check if immediate value is a multiple of 4 between 0 and 1118 // 1020 1119 Info.setRequiresImmediate(); 1120 else 1121 // FIXME: should check if immediate value is a power of two or a integer 1122 // between 0 and 32 1123 Info.setRequiresImmediate(); 1124 return true; 1125 case 'N': 1126 // Thumb1 only 1127 if (isThumb() && !supportsThumb2()) { 1128 Info.setRequiresImmediate(0, 31); 1129 return true; 1130 } 1131 break; 1132 case 'O': 1133 // Thumb1 only 1134 if (isThumb() && !supportsThumb2()) { 1135 // FIXME: should check if immediate value is a multiple of 4 between -508 1136 // and 508 1137 Info.setRequiresImmediate(); 1138 return true; 1139 } 1140 break; 1141 case 'Q': // A memory address that is a single base register. 1142 Info.setAllowsMemory(); 1143 return true; 1144 case 'T': 1145 switch (Name[1]) { 1146 default: 1147 break; 1148 case 'e': // Even general-purpose register 1149 case 'o': // Odd general-purpose register 1150 Info.setAllowsRegister(); 1151 Name++; 1152 return true; 1153 } 1154 break; 1155 case 'U': // a memory reference... 1156 switch (Name[1]) { 1157 case 'q': // ...ARMV4 ldrsb 1158 case 'v': // ...VFP load/store (reg+constant offset) 1159 case 'y': // ...iWMMXt load/store 1160 case 't': // address valid for load/store opaque types wider 1161 // than 128-bits 1162 case 'n': // valid address for Neon doubleword vector load/store 1163 case 'm': // valid address for Neon element and structure load/store 1164 case 's': // valid address for non-offset loads/stores of quad-word 1165 // values in four ARM registers 1166 Info.setAllowsMemory(); 1167 Name++; 1168 return true; 1169 } 1170 break; 1171 } 1172 return false; 1173 } 1174 1175 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const { 1176 std::string R; 1177 switch (*Constraint) { 1178 case 'U': // Two-character constraint; add "^" hint for later parsing. 1179 case 'T': 1180 R = std::string("^") + std::string(Constraint, 2); 1181 Constraint++; 1182 break; 1183 case 'p': // 'p' should be translated to 'r' by default. 1184 R = std::string("r"); 1185 break; 1186 default: 1187 return std::string(1, *Constraint); 1188 } 1189 return R; 1190 } 1191 1192 bool ARMTargetInfo::validateConstraintModifier( 1193 StringRef Constraint, char Modifier, unsigned Size, 1194 std::string &SuggestedModifier) const { 1195 bool isOutput = (Constraint[0] == '='); 1196 bool isInOut = (Constraint[0] == '+'); 1197 1198 // Strip off constraint modifiers. 1199 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 1200 Constraint = Constraint.substr(1); 1201 1202 switch (Constraint[0]) { 1203 default: 1204 break; 1205 case 'r': { 1206 switch (Modifier) { 1207 default: 1208 return (isInOut || isOutput || Size <= 64); 1209 case 'q': 1210 // A register of size 32 cannot fit a vector type. 1211 return false; 1212 } 1213 } 1214 } 1215 1216 return true; 1217 } 1218 const char *ARMTargetInfo::getClobbers() const { 1219 // FIXME: Is this really right? 1220 return ""; 1221 } 1222 1223 TargetInfo::CallingConvCheckResult 1224 ARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1225 switch (CC) { 1226 case CC_AAPCS: 1227 case CC_AAPCS_VFP: 1228 case CC_Swift: 1229 case CC_SwiftAsync: 1230 case CC_OpenCLKernel: 1231 return CCCR_OK; 1232 default: 1233 return CCCR_Warning; 1234 } 1235 } 1236 1237 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 1238 if (RegNo == 0) 1239 return 0; 1240 if (RegNo == 1) 1241 return 1; 1242 return -1; 1243 } 1244 1245 bool ARMTargetInfo::hasSjLjLowering() const { return true; } 1246 1247 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple, 1248 const TargetOptions &Opts) 1249 : ARMTargetInfo(Triple, Opts) {} 1250 1251 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1252 MacroBuilder &Builder) const { 1253 Builder.defineMacro("__ARMEL__"); 1254 ARMTargetInfo::getTargetDefines(Opts, Builder); 1255 } 1256 1257 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple, 1258 const TargetOptions &Opts) 1259 : ARMTargetInfo(Triple, Opts) {} 1260 1261 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts, 1262 MacroBuilder &Builder) const { 1263 Builder.defineMacro("__ARMEB__"); 1264 Builder.defineMacro("__ARM_BIG_ENDIAN"); 1265 ARMTargetInfo::getTargetDefines(Opts, Builder); 1266 } 1267 1268 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple, 1269 const TargetOptions &Opts) 1270 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) { 1271 } 1272 1273 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts, 1274 MacroBuilder &Builder) const { 1275 // FIXME: this is invalid for WindowsCE 1276 Builder.defineMacro("_M_ARM_NT", "1"); 1277 Builder.defineMacro("_M_ARMT", "_M_ARM"); 1278 Builder.defineMacro("_M_THUMB", "_M_ARM"); 1279 1280 assert((Triple.getArch() == llvm::Triple::arm || 1281 Triple.getArch() == llvm::Triple::thumb) && 1282 "invalid architecture for Windows ARM target info"); 1283 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6; 1284 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset)); 1285 1286 // TODO map the complete set of values 1287 // 31: VFPv3 40: VFPv4 1288 Builder.defineMacro("_M_ARM_FP", "31"); 1289 } 1290 1291 TargetInfo::BuiltinVaListKind 1292 WindowsARMTargetInfo::getBuiltinVaListKind() const { 1293 return TargetInfo::CharPtrBuiltinVaList; 1294 } 1295 1296 TargetInfo::CallingConvCheckResult 1297 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1298 switch (CC) { 1299 case CC_X86StdCall: 1300 case CC_X86ThisCall: 1301 case CC_X86FastCall: 1302 case CC_X86VectorCall: 1303 return CCCR_Ignore; 1304 case CC_C: 1305 case CC_OpenCLKernel: 1306 case CC_PreserveMost: 1307 case CC_PreserveAll: 1308 case CC_Swift: 1309 case CC_SwiftAsync: 1310 return CCCR_OK; 1311 default: 1312 return CCCR_Warning; 1313 } 1314 } 1315 1316 // Windows ARM + Itanium C++ ABI Target 1317 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo( 1318 const llvm::Triple &Triple, const TargetOptions &Opts) 1319 : WindowsARMTargetInfo(Triple, Opts) { 1320 TheCXXABI.set(TargetCXXABI::GenericARM); 1321 } 1322 1323 void ItaniumWindowsARMleTargetInfo::getTargetDefines( 1324 const LangOptions &Opts, MacroBuilder &Builder) const { 1325 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1326 1327 if (Opts.MSVCCompat) 1328 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1329 } 1330 1331 // Windows ARM, MS (C++) ABI 1332 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple, 1333 const TargetOptions &Opts) 1334 : WindowsARMTargetInfo(Triple, Opts) { 1335 TheCXXABI.set(TargetCXXABI::Microsoft); 1336 } 1337 1338 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1339 MacroBuilder &Builder) const { 1340 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1341 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1342 } 1343 1344 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple, 1345 const TargetOptions &Opts) 1346 : WindowsARMTargetInfo(Triple, Opts) { 1347 TheCXXABI.set(TargetCXXABI::GenericARM); 1348 } 1349 1350 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1351 MacroBuilder &Builder) const { 1352 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1353 Builder.defineMacro("_ARM_"); 1354 } 1355 1356 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple, 1357 const TargetOptions &Opts) 1358 : ARMleTargetInfo(Triple, Opts) { 1359 this->WCharType = TargetInfo::UnsignedShort; 1360 TLSSupported = false; 1361 DoubleAlign = LongLongAlign = 64; 1362 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 1363 } 1364 1365 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1366 MacroBuilder &Builder) const { 1367 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1368 Builder.defineMacro("_ARM_"); 1369 Builder.defineMacro("__CYGWIN__"); 1370 Builder.defineMacro("__CYGWIN32__"); 1371 DefineStd(Builder, "unix", Opts); 1372 if (Opts.CPlusPlus) 1373 Builder.defineMacro("_GNU_SOURCE"); 1374 } 1375 1376 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple, 1377 const TargetOptions &Opts) 1378 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) { 1379 HasAlignMac68kSupport = true; 1380 // iOS always has 64-bit atomic instructions. 1381 // FIXME: This should be based off of the target features in 1382 // ARMleTargetInfo. 1383 MaxAtomicInlineWidth = 64; 1384 1385 if (Triple.isWatchABI()) { 1386 // Darwin on iOS uses a variant of the ARM C++ ABI. 1387 TheCXXABI.set(TargetCXXABI::WatchOS); 1388 1389 // BOOL should be a real boolean on the new ABI 1390 UseSignedCharForObjCBool = false; 1391 } else 1392 TheCXXABI.set(TargetCXXABI::iOS); 1393 } 1394 1395 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts, 1396 const llvm::Triple &Triple, 1397 MacroBuilder &Builder) const { 1398 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 1399 } 1400 1401 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple, 1402 const TargetOptions &Opts) 1403 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(), 1404 Triple.getOSName(), 1405 Triple.getEnvironmentName()), 1406 Opts) { 1407 IsRenderScriptTarget = true; 1408 LongWidth = LongAlign = 64; 1409 } 1410 1411 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts, 1412 MacroBuilder &Builder) const { 1413 Builder.defineMacro("__RENDERSCRIPT__"); 1414 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1415 } 1416