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