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