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