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 DSP = 0; 432 Unaligned = 1; 433 SoftFloat = false; 434 // Note that SoftFloatABI is initialized in our constructor. 435 HWDiv = 0; 436 DotProd = 0; 437 HasMatMul = 0; 438 HasFloat16 = true; 439 ARMCDECoprocMask = 0; 440 HasBFloat16 = false; 441 442 // This does not diagnose illegal cases like having both 443 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64". 444 for (const auto &Feature : Features) { 445 if (Feature == "+soft-float") { 446 SoftFloat = true; 447 } else if (Feature == "+vfp2sp" || Feature == "+vfp2") { 448 FPU |= VFP2FPU; 449 HW_FP |= HW_FP_SP; 450 if (Feature == "+vfp2") 451 HW_FP |= HW_FP_DP; 452 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" || 453 Feature == "+vfp3" || Feature == "+vfp3d16") { 454 FPU |= VFP3FPU; 455 HW_FP |= HW_FP_SP; 456 if (Feature == "+vfp3" || Feature == "+vfp3d16") 457 HW_FP |= HW_FP_DP; 458 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" || 459 Feature == "+vfp4" || Feature == "+vfp4d16") { 460 FPU |= VFP4FPU; 461 HW_FP |= HW_FP_SP | HW_FP_HP; 462 if (Feature == "+vfp4" || Feature == "+vfp4d16") 463 HW_FP |= HW_FP_DP; 464 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" || 465 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") { 466 FPU |= FPARMV8; 467 HW_FP |= HW_FP_SP | HW_FP_HP; 468 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16") 469 HW_FP |= HW_FP_DP; 470 } else if (Feature == "+neon") { 471 FPU |= NeonFPU; 472 HW_FP |= HW_FP_SP; 473 } else if (Feature == "+hwdiv") { 474 HWDiv |= HWDivThumb; 475 } else if (Feature == "+hwdiv-arm") { 476 HWDiv |= HWDivARM; 477 } else if (Feature == "+crc") { 478 CRC = 1; 479 } else if (Feature == "+crypto") { 480 Crypto = 1; 481 } else if (Feature == "+dsp") { 482 DSP = 1; 483 } else if (Feature == "+fp64") { 484 HW_FP |= HW_FP_DP; 485 } else if (Feature == "+8msecext") { 486 if (CPUProfile != "M" || ArchVersion != 8) { 487 Diags.Report(diag::err_target_unsupported_mcmse) << CPU; 488 return false; 489 } 490 } else if (Feature == "+strict-align") { 491 Unaligned = 0; 492 } else if (Feature == "+fp16") { 493 HW_FP |= HW_FP_HP; 494 } else if (Feature == "+fullfp16") { 495 HasLegalHalfType = true; 496 } else if (Feature == "+dotprod") { 497 DotProd = true; 498 } else if (Feature == "+mve") { 499 MVE |= MVE_INT; 500 } else if (Feature == "+mve.fp") { 501 HasLegalHalfType = true; 502 FPU |= FPARMV8; 503 MVE |= MVE_INT | MVE_FP; 504 HW_FP |= HW_FP_SP | HW_FP_HP; 505 } else if (Feature == "+i8mm") { 506 HasMatMul = 1; 507 } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" && 508 Feature <= "+cdecp7") { 509 unsigned Coproc = Feature.back() - '0'; 510 ARMCDECoprocMask |= (1U << Coproc); 511 } else if (Feature == "+bf16") { 512 HasBFloat16 = true; 513 } 514 } 515 516 switch (ArchVersion) { 517 case 6: 518 if (ArchProfile == llvm::ARM::ProfileKind::M) 519 LDREX = 0; 520 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K) 521 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 522 else 523 LDREX = LDREX_W; 524 break; 525 case 7: 526 if (ArchProfile == llvm::ARM::ProfileKind::M) 527 LDREX = LDREX_W | LDREX_H | LDREX_B; 528 else 529 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 530 break; 531 case 8: 532 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 533 } 534 535 if (!(FPU & NeonFPU) && FPMath == FP_Neon) { 536 Diags.Report(diag::err_target_unsupported_fpmath) << "neon"; 537 return false; 538 } 539 540 if (FPMath == FP_Neon) 541 Features.push_back("+neonfp"); 542 else if (FPMath == FP_VFP) 543 Features.push_back("-neonfp"); 544 545 return true; 546 } 547 548 bool ARMTargetInfo::hasFeature(StringRef Feature) const { 549 return llvm::StringSwitch<bool>(Feature) 550 .Case("arm", true) 551 .Case("aarch32", true) 552 .Case("softfloat", SoftFloat) 553 .Case("thumb", isThumb()) 554 .Case("neon", (FPU & NeonFPU) && !SoftFloat) 555 .Case("vfp", FPU && !SoftFloat) 556 .Case("hwdiv", HWDiv & HWDivThumb) 557 .Case("hwdiv-arm", HWDiv & HWDivARM) 558 .Case("mve", hasMVE()) 559 .Default(false); 560 } 561 562 bool ARMTargetInfo::hasBFloat16Type() const { 563 return HasBFloat16 && !SoftFloat; 564 } 565 566 bool ARMTargetInfo::isValidCPUName(StringRef Name) const { 567 return Name == "generic" || 568 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID; 569 } 570 571 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { 572 llvm::ARM::fillValidCPUArchList(Values); 573 } 574 575 bool ARMTargetInfo::setCPU(const std::string &Name) { 576 if (Name != "generic") 577 setArchInfo(llvm::ARM::parseCPUArch(Name)); 578 579 if (ArchKind == llvm::ARM::ArchKind::INVALID) 580 return false; 581 setAtomic(); 582 CPU = Name; 583 return true; 584 } 585 586 bool ARMTargetInfo::setFPMath(StringRef Name) { 587 if (Name == "neon") { 588 FPMath = FP_Neon; 589 return true; 590 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" || 591 Name == "vfp4") { 592 FPMath = FP_VFP; 593 return true; 594 } 595 return false; 596 } 597 598 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, 599 MacroBuilder &Builder) const { 600 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); 601 } 602 603 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts, 604 MacroBuilder &Builder) const { 605 // Also include the ARMv8.1-A defines 606 getTargetDefinesARMV81A(Opts, Builder); 607 } 608 609 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts, 610 MacroBuilder &Builder) const { 611 // Also include the ARMv8.2-A defines 612 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1"); 613 getTargetDefinesARMV82A(Opts, Builder); 614 } 615 616 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, 617 MacroBuilder &Builder) const { 618 // Target identification. 619 Builder.defineMacro("__arm"); 620 Builder.defineMacro("__arm__"); 621 // For bare-metal none-eabi. 622 if (getTriple().getOS() == llvm::Triple::UnknownOS && 623 (getTriple().getEnvironment() == llvm::Triple::EABI || 624 getTriple().getEnvironment() == llvm::Triple::EABIHF)) 625 Builder.defineMacro("__ELF__"); 626 627 // Target properties. 628 Builder.defineMacro("__REGISTER_PREFIX__", ""); 629 630 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU 631 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__. 632 if (getTriple().isWatchABI()) 633 Builder.defineMacro("__ARM_ARCH_7K__", "2"); 634 635 if (!CPUAttr.empty()) 636 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__"); 637 638 // ACLE 6.4.1 ARM/Thumb instruction set architecture 639 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA 640 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion)); 641 642 if (ArchVersion >= 8) { 643 // ACLE 6.5.7 Crypto Extension 644 if (Crypto) 645 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1"); 646 // ACLE 6.5.8 CRC32 Extension 647 if (CRC) 648 Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); 649 // ACLE 6.5.10 Numeric Maximum and Minimum 650 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1"); 651 // ACLE 6.5.9 Directed Rounding 652 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1"); 653 } 654 655 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It 656 // is not defined for the M-profile. 657 // NOTE that the default profile is assumed to be 'A' 658 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M) 659 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1"); 660 661 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original 662 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the 663 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all 664 // v7 and v8 architectures excluding v8-M Baseline. 665 if (supportsThumb2()) 666 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2"); 667 else if (supportsThumb()) 668 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1"); 669 670 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit 671 // instruction set such as ARM or Thumb. 672 Builder.defineMacro("__ARM_32BIT_STATE", "1"); 673 674 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex) 675 676 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset. 677 if (!CPUProfile.empty()) 678 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'"); 679 680 // ACLE 6.4.3 Unaligned access supported in hardware 681 if (Unaligned) 682 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); 683 684 // ACLE 6.4.4 LDREX/STREX 685 if (LDREX) 686 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX)); 687 688 // ACLE 6.4.5 CLZ 689 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") || 690 ArchVersion > 6) 691 Builder.defineMacro("__ARM_FEATURE_CLZ", "1"); 692 693 // ACLE 6.5.1 Hardware Floating Point 694 if (HW_FP) 695 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP)); 696 697 // ACLE predefines. 698 Builder.defineMacro("__ARM_ACLE", "200"); 699 700 // FP16 support (we currently only support IEEE format). 701 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1"); 702 Builder.defineMacro("__ARM_FP16_ARGS", "1"); 703 704 // ACLE 6.5.3 Fused multiply-accumulate (FMA) 705 if (ArchVersion >= 7 && (FPU & VFP4FPU)) 706 Builder.defineMacro("__ARM_FEATURE_FMA", "1"); 707 708 // Subtarget options. 709 710 // FIXME: It's more complicated than this and we don't really support 711 // interworking. 712 // Windows on ARM does not "support" interworking 713 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows()) 714 Builder.defineMacro("__THUMB_INTERWORK__"); 715 716 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") { 717 // Embedded targets on Darwin follow AAPCS, but not EABI. 718 // Windows on ARM follows AAPCS VFP, but does not conform to EABI. 719 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows()) 720 Builder.defineMacro("__ARM_EABI__"); 721 Builder.defineMacro("__ARM_PCS", "1"); 722 } 723 724 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16") 725 Builder.defineMacro("__ARM_PCS_VFP", "1"); 726 727 if (SoftFloat) 728 Builder.defineMacro("__SOFTFP__"); 729 730 // ACLE position independent code macros. 731 if (Opts.ROPI) 732 Builder.defineMacro("__ARM_ROPI", "1"); 733 if (Opts.RWPI) 734 Builder.defineMacro("__ARM_RWPI", "1"); 735 736 if (ArchKind == llvm::ARM::ArchKind::XSCALE) 737 Builder.defineMacro("__XSCALE__"); 738 739 if (isThumb()) { 740 Builder.defineMacro("__THUMBEL__"); 741 Builder.defineMacro("__thumb__"); 742 if (supportsThumb2()) 743 Builder.defineMacro("__thumb2__"); 744 } 745 746 // ACLE 6.4.9 32-bit SIMD instructions 747 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP)) 748 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1"); 749 750 // ACLE 6.4.10 Hardware Integer Divide 751 if (((HWDiv & HWDivThumb) && isThumb()) || 752 ((HWDiv & HWDivARM) && !isThumb())) { 753 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); 754 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1"); 755 } 756 757 // Note, this is always on in gcc, even though it doesn't make sense. 758 Builder.defineMacro("__APCS_32__"); 759 760 // __VFP_FP__ means that the floating-point format is VFP, not that a hardware 761 // FPU is present. Moreover, the VFP format is the only one supported by 762 // clang. For these reasons, this macro is always defined. 763 Builder.defineMacro("__VFP_FP__"); 764 765 if (FPUModeIsVFP((FPUMode)FPU)) { 766 if (FPU & VFP2FPU) 767 Builder.defineMacro("__ARM_VFPV2__"); 768 if (FPU & VFP3FPU) 769 Builder.defineMacro("__ARM_VFPV3__"); 770 if (FPU & VFP4FPU) 771 Builder.defineMacro("__ARM_VFPV4__"); 772 if (FPU & FPARMV8) 773 Builder.defineMacro("__ARM_FPV5__"); 774 } 775 776 // This only gets set when Neon instructions are actually available, unlike 777 // the VFP define, hence the soft float and arch check. This is subtly 778 // different from gcc, we follow the intent which was that it should be set 779 // when Neon instructions are actually available. 780 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) { 781 Builder.defineMacro("__ARM_NEON", "1"); 782 Builder.defineMacro("__ARM_NEON__"); 783 // current AArch32 NEON implementations do not support double-precision 784 // floating-point even when it is present in VFP. 785 Builder.defineMacro("__ARM_NEON_FP", 786 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP)); 787 } 788 789 if (hasMVE()) { 790 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1"); 791 } 792 793 if (hasCDE()) { 794 Builder.defineMacro("__ARM_FEATURE_CDE", "1"); 795 Builder.defineMacro("__ARM_FEATURE_CDE_COPROC", 796 "0x" + Twine::utohexstr(getARMCDECoprocMask())); 797 } 798 799 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", 800 Twine(Opts.WCharSize ? Opts.WCharSize : 4)); 801 802 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); 803 804 // CMSE 805 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M) 806 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1"); 807 808 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") { 809 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 810 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 811 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 812 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 813 } 814 815 // ACLE 6.4.7 DSP instructions 816 if (DSP) { 817 Builder.defineMacro("__ARM_FEATURE_DSP", "1"); 818 } 819 820 // ACLE 6.4.8 Saturation instructions 821 bool SAT = false; 822 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) { 823 Builder.defineMacro("__ARM_FEATURE_SAT", "1"); 824 SAT = true; 825 } 826 827 // ACLE 6.4.6 Q (saturation) flag 828 if (DSP || SAT) 829 Builder.defineMacro("__ARM_FEATURE_QBIT", "1"); 830 831 if (Opts.UnsafeFPMath) 832 Builder.defineMacro("__ARM_FP_FAST", "1"); 833 834 // Armv8.2-A FP16 vector intrinsic 835 if ((FPU & NeonFPU) && HasLegalHalfType) 836 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); 837 838 // Armv8.2-A FP16 scalar intrinsics 839 if (HasLegalHalfType) 840 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); 841 842 // Armv8.2-A dot product intrinsics 843 if (DotProd) 844 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); 845 846 if (HasMatMul) 847 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); 848 849 if (HasBFloat16) { 850 Builder.defineMacro("__ARM_FEATURE_BF16", "1"); 851 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); 852 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); 853 } 854 855 switch (ArchKind) { 856 default: 857 break; 858 case llvm::ARM::ArchKind::ARMV8_1A: 859 getTargetDefinesARMV81A(Opts, Builder); 860 break; 861 case llvm::ARM::ArchKind::ARMV8_2A: 862 getTargetDefinesARMV82A(Opts, Builder); 863 break; 864 case llvm::ARM::ArchKind::ARMV8_3A: 865 case llvm::ARM::ArchKind::ARMV8_4A: 866 case llvm::ARM::ArchKind::ARMV8_5A: 867 case llvm::ARM::ArchKind::ARMV8_6A: 868 getTargetDefinesARMV83A(Opts, Builder); 869 break; 870 } 871 } 872 873 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = { 874 #define BUILTIN(ID, TYPE, ATTRS) \ 875 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 876 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 877 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, 878 #include "clang/Basic/BuiltinsNEON.def" 879 880 #define BUILTIN(ID, TYPE, ATTRS) \ 881 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 882 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ 883 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, 884 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 885 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, 886 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 887 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 888 #include "clang/Basic/BuiltinsARM.def" 889 }; 890 891 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const { 892 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin - 893 Builtin::FirstTSBuiltin); 894 } 895 896 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; } 897 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const { 898 return IsAAPCS 899 ? AAPCSABIBuiltinVaList 900 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList 901 : TargetInfo::VoidPtrBuiltinVaList); 902 } 903 904 const char *const ARMTargetInfo::GCCRegNames[] = { 905 // Integer registers 906 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", 907 "r12", "sp", "lr", "pc", 908 909 // Float registers 910 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 911 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 912 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 913 914 // Double registers 915 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 916 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 917 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 918 919 // Quad registers 920 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", 921 "q12", "q13", "q14", "q15"}; 922 923 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const { 924 return llvm::makeArrayRef(GCCRegNames); 925 } 926 927 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 928 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"}, 929 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"}, 930 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"}, 931 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"}, 932 // The S, D and Q registers overlap, but aren't really aliases; we 933 // don't want to substitute one of these for a different-sized one. 934 }; 935 936 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const { 937 return llvm::makeArrayRef(GCCRegAliases); 938 } 939 940 bool ARMTargetInfo::validateAsmConstraint( 941 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 942 switch (*Name) { 943 default: 944 break; 945 case 'l': // r0-r7 if thumb, r0-r15 if ARM 946 Info.setAllowsRegister(); 947 return true; 948 case 'h': // r8-r15, thumb only 949 if (isThumb()) { 950 Info.setAllowsRegister(); 951 return true; 952 } 953 break; 954 case 's': // An integer constant, but allowing only relocatable values. 955 return true; 956 case 't': // s0-s31, d0-d31, or q0-q15 957 case 'w': // s0-s15, d0-d7, or q0-q3 958 case 'x': // s0-s31, d0-d15, or q0-q7 959 Info.setAllowsRegister(); 960 return true; 961 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW) 962 // only available in ARMv6T2 and above 963 if (CPUAttr.equals("6T2") || ArchVersion >= 7) { 964 Info.setRequiresImmediate(0, 65535); 965 return true; 966 } 967 break; 968 case 'I': 969 if (isThumb()) { 970 if (!supportsThumb2()) 971 Info.setRequiresImmediate(0, 255); 972 else 973 // FIXME: should check if immediate value would be valid for a Thumb2 974 // data-processing instruction 975 Info.setRequiresImmediate(); 976 } else 977 // FIXME: should check if immediate value would be valid for an ARM 978 // data-processing instruction 979 Info.setRequiresImmediate(); 980 return true; 981 case 'J': 982 if (isThumb() && !supportsThumb2()) 983 Info.setRequiresImmediate(-255, -1); 984 else 985 Info.setRequiresImmediate(-4095, 4095); 986 return true; 987 case 'K': 988 if (isThumb()) { 989 if (!supportsThumb2()) 990 // FIXME: should check if immediate value can be obtained from shifting 991 // a value between 0 and 255 left by any amount 992 Info.setRequiresImmediate(); 993 else 994 // FIXME: should check if immediate value would be valid for a Thumb2 995 // data-processing instruction when inverted 996 Info.setRequiresImmediate(); 997 } else 998 // FIXME: should check if immediate value would be valid for an ARM 999 // data-processing instruction when inverted 1000 Info.setRequiresImmediate(); 1001 return true; 1002 case 'L': 1003 if (isThumb()) { 1004 if (!supportsThumb2()) 1005 Info.setRequiresImmediate(-7, 7); 1006 else 1007 // FIXME: should check if immediate value would be valid for a Thumb2 1008 // data-processing instruction when negated 1009 Info.setRequiresImmediate(); 1010 } else 1011 // FIXME: should check if immediate value would be valid for an ARM 1012 // data-processing instruction when negated 1013 Info.setRequiresImmediate(); 1014 return true; 1015 case 'M': 1016 if (isThumb() && !supportsThumb2()) 1017 // FIXME: should check if immediate value is a multiple of 4 between 0 and 1018 // 1020 1019 Info.setRequiresImmediate(); 1020 else 1021 // FIXME: should check if immediate value is a power of two or a integer 1022 // between 0 and 32 1023 Info.setRequiresImmediate(); 1024 return true; 1025 case 'N': 1026 // Thumb1 only 1027 if (isThumb() && !supportsThumb2()) { 1028 Info.setRequiresImmediate(0, 31); 1029 return true; 1030 } 1031 break; 1032 case 'O': 1033 // Thumb1 only 1034 if (isThumb() && !supportsThumb2()) { 1035 // FIXME: should check if immediate value is a multiple of 4 between -508 1036 // and 508 1037 Info.setRequiresImmediate(); 1038 return true; 1039 } 1040 break; 1041 case 'Q': // A memory address that is a single base register. 1042 Info.setAllowsMemory(); 1043 return true; 1044 case 'T': 1045 switch (Name[1]) { 1046 default: 1047 break; 1048 case 'e': // Even general-purpose register 1049 case 'o': // Odd general-purpose register 1050 Info.setAllowsRegister(); 1051 Name++; 1052 return true; 1053 } 1054 break; 1055 case 'U': // a memory reference... 1056 switch (Name[1]) { 1057 case 'q': // ...ARMV4 ldrsb 1058 case 'v': // ...VFP load/store (reg+constant offset) 1059 case 'y': // ...iWMMXt load/store 1060 case 't': // address valid for load/store opaque types wider 1061 // than 128-bits 1062 case 'n': // valid address for Neon doubleword vector load/store 1063 case 'm': // valid address for Neon element and structure load/store 1064 case 's': // valid address for non-offset loads/stores of quad-word 1065 // values in four ARM registers 1066 Info.setAllowsMemory(); 1067 Name++; 1068 return true; 1069 } 1070 break; 1071 } 1072 return false; 1073 } 1074 1075 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const { 1076 std::string R; 1077 switch (*Constraint) { 1078 case 'U': // Two-character constraint; add "^" hint for later parsing. 1079 case 'T': 1080 R = std::string("^") + std::string(Constraint, 2); 1081 Constraint++; 1082 break; 1083 case 'p': // 'p' should be translated to 'r' by default. 1084 R = std::string("r"); 1085 break; 1086 default: 1087 return std::string(1, *Constraint); 1088 } 1089 return R; 1090 } 1091 1092 bool ARMTargetInfo::validateConstraintModifier( 1093 StringRef Constraint, char Modifier, unsigned Size, 1094 std::string &SuggestedModifier) const { 1095 bool isOutput = (Constraint[0] == '='); 1096 bool isInOut = (Constraint[0] == '+'); 1097 1098 // Strip off constraint modifiers. 1099 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 1100 Constraint = Constraint.substr(1); 1101 1102 switch (Constraint[0]) { 1103 default: 1104 break; 1105 case 'r': { 1106 switch (Modifier) { 1107 default: 1108 return (isInOut || isOutput || Size <= 64); 1109 case 'q': 1110 // A register of size 32 cannot fit a vector type. 1111 return false; 1112 } 1113 } 1114 } 1115 1116 return true; 1117 } 1118 const char *ARMTargetInfo::getClobbers() const { 1119 // FIXME: Is this really right? 1120 return ""; 1121 } 1122 1123 TargetInfo::CallingConvCheckResult 1124 ARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1125 switch (CC) { 1126 case CC_AAPCS: 1127 case CC_AAPCS_VFP: 1128 case CC_Swift: 1129 case CC_OpenCLKernel: 1130 return CCCR_OK; 1131 default: 1132 return CCCR_Warning; 1133 } 1134 } 1135 1136 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 1137 if (RegNo == 0) 1138 return 0; 1139 if (RegNo == 1) 1140 return 1; 1141 return -1; 1142 } 1143 1144 bool ARMTargetInfo::hasSjLjLowering() const { return true; } 1145 1146 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple, 1147 const TargetOptions &Opts) 1148 : ARMTargetInfo(Triple, Opts) {} 1149 1150 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1151 MacroBuilder &Builder) const { 1152 Builder.defineMacro("__ARMEL__"); 1153 ARMTargetInfo::getTargetDefines(Opts, Builder); 1154 } 1155 1156 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple, 1157 const TargetOptions &Opts) 1158 : ARMTargetInfo(Triple, Opts) {} 1159 1160 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts, 1161 MacroBuilder &Builder) const { 1162 Builder.defineMacro("__ARMEB__"); 1163 Builder.defineMacro("__ARM_BIG_ENDIAN"); 1164 ARMTargetInfo::getTargetDefines(Opts, Builder); 1165 } 1166 1167 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple, 1168 const TargetOptions &Opts) 1169 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) { 1170 } 1171 1172 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts, 1173 MacroBuilder &Builder) const { 1174 // FIXME: this is invalid for WindowsCE 1175 Builder.defineMacro("_M_ARM_NT", "1"); 1176 Builder.defineMacro("_M_ARMT", "_M_ARM"); 1177 Builder.defineMacro("_M_THUMB", "_M_ARM"); 1178 1179 assert((Triple.getArch() == llvm::Triple::arm || 1180 Triple.getArch() == llvm::Triple::thumb) && 1181 "invalid architecture for Windows ARM target info"); 1182 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6; 1183 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset)); 1184 1185 // TODO map the complete set of values 1186 // 31: VFPv3 40: VFPv4 1187 Builder.defineMacro("_M_ARM_FP", "31"); 1188 } 1189 1190 TargetInfo::BuiltinVaListKind 1191 WindowsARMTargetInfo::getBuiltinVaListKind() const { 1192 return TargetInfo::CharPtrBuiltinVaList; 1193 } 1194 1195 TargetInfo::CallingConvCheckResult 1196 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1197 switch (CC) { 1198 case CC_X86StdCall: 1199 case CC_X86ThisCall: 1200 case CC_X86FastCall: 1201 case CC_X86VectorCall: 1202 return CCCR_Ignore; 1203 case CC_C: 1204 case CC_OpenCLKernel: 1205 case CC_PreserveMost: 1206 case CC_PreserveAll: 1207 case CC_Swift: 1208 return CCCR_OK; 1209 default: 1210 return CCCR_Warning; 1211 } 1212 } 1213 1214 // Windows ARM + Itanium C++ ABI Target 1215 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo( 1216 const llvm::Triple &Triple, const TargetOptions &Opts) 1217 : WindowsARMTargetInfo(Triple, Opts) { 1218 TheCXXABI.set(TargetCXXABI::GenericARM); 1219 } 1220 1221 void ItaniumWindowsARMleTargetInfo::getTargetDefines( 1222 const LangOptions &Opts, MacroBuilder &Builder) const { 1223 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1224 1225 if (Opts.MSVCCompat) 1226 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1227 } 1228 1229 // Windows ARM, MS (C++) ABI 1230 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple, 1231 const TargetOptions &Opts) 1232 : WindowsARMTargetInfo(Triple, Opts) { 1233 TheCXXABI.set(TargetCXXABI::Microsoft); 1234 } 1235 1236 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1237 MacroBuilder &Builder) const { 1238 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1239 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1240 } 1241 1242 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple, 1243 const TargetOptions &Opts) 1244 : WindowsARMTargetInfo(Triple, Opts) { 1245 TheCXXABI.set(TargetCXXABI::GenericARM); 1246 } 1247 1248 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1249 MacroBuilder &Builder) const { 1250 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1251 Builder.defineMacro("_ARM_"); 1252 } 1253 1254 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple, 1255 const TargetOptions &Opts) 1256 : ARMleTargetInfo(Triple, Opts) { 1257 this->WCharType = TargetInfo::UnsignedShort; 1258 TLSSupported = false; 1259 DoubleAlign = LongLongAlign = 64; 1260 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 1261 } 1262 1263 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1264 MacroBuilder &Builder) const { 1265 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1266 Builder.defineMacro("_ARM_"); 1267 Builder.defineMacro("__CYGWIN__"); 1268 Builder.defineMacro("__CYGWIN32__"); 1269 DefineStd(Builder, "unix", Opts); 1270 if (Opts.CPlusPlus) 1271 Builder.defineMacro("_GNU_SOURCE"); 1272 } 1273 1274 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple, 1275 const TargetOptions &Opts) 1276 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) { 1277 HasAlignMac68kSupport = true; 1278 // iOS always has 64-bit atomic instructions. 1279 // FIXME: This should be based off of the target features in 1280 // ARMleTargetInfo. 1281 MaxAtomicInlineWidth = 64; 1282 1283 if (Triple.isWatchABI()) { 1284 // Darwin on iOS uses a variant of the ARM C++ ABI. 1285 TheCXXABI.set(TargetCXXABI::WatchOS); 1286 1287 // BOOL should be a real boolean on the new ABI 1288 UseSignedCharForObjCBool = false; 1289 } else 1290 TheCXXABI.set(TargetCXXABI::iOS); 1291 } 1292 1293 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts, 1294 const llvm::Triple &Triple, 1295 MacroBuilder &Builder) const { 1296 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 1297 } 1298 1299 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple, 1300 const TargetOptions &Opts) 1301 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(), 1302 Triple.getOSName(), 1303 Triple.getEnvironmentName()), 1304 Opts) { 1305 IsRenderScriptTarget = true; 1306 LongWidth = LongAlign = 64; 1307 } 1308 1309 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts, 1310 MacroBuilder &Builder) const { 1311 Builder.defineMacro("__RENDERSCRIPT__"); 1312 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1313 } 1314