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