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