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