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