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