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