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