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