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