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