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