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