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