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