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