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