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