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