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