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 // __VFP_FP__ means that the floating-point format is VFP, not that a hardware 759 // FPU is present. Moreover, the VFP format is the only one supported by 760 // clang. For these reasons, this macro is always defined. 761 Builder.defineMacro("__VFP_FP__"); 762 763 if (FPUModeIsVFP((FPUMode)FPU)) { 764 if (FPU & VFP2FPU) 765 Builder.defineMacro("__ARM_VFPV2__"); 766 if (FPU & VFP3FPU) 767 Builder.defineMacro("__ARM_VFPV3__"); 768 if (FPU & VFP4FPU) 769 Builder.defineMacro("__ARM_VFPV4__"); 770 if (FPU & FPARMV8) 771 Builder.defineMacro("__ARM_FPV5__"); 772 } 773 774 // This only gets set when Neon instructions are actually available, unlike 775 // the VFP define, hence the soft float and arch check. This is subtly 776 // different from gcc, we follow the intent which was that it should be set 777 // when Neon instructions are actually available. 778 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) { 779 Builder.defineMacro("__ARM_NEON", "1"); 780 Builder.defineMacro("__ARM_NEON__"); 781 // current AArch32 NEON implementations do not support double-precision 782 // floating-point even when it is present in VFP. 783 Builder.defineMacro("__ARM_NEON_FP", 784 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP)); 785 } 786 787 if (hasMVE()) { 788 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1"); 789 } 790 791 if (hasCDE()) { 792 Builder.defineMacro("__ARM_FEATURE_CDE", "1"); 793 Builder.defineMacro("__ARM_FEATURE_CDE_COPROC", 794 "0x" + Twine::utohexstr(getARMCDECoprocMask())); 795 } 796 797 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", 798 Twine(Opts.WCharSize ? Opts.WCharSize : 4)); 799 800 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); 801 802 // CMSE 803 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M) 804 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1"); 805 806 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") { 807 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 808 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 809 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 810 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 811 } 812 813 // ACLE 6.4.7 DSP instructions 814 if (DSP) { 815 Builder.defineMacro("__ARM_FEATURE_DSP", "1"); 816 } 817 818 // ACLE 6.4.8 Saturation instructions 819 bool SAT = false; 820 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) { 821 Builder.defineMacro("__ARM_FEATURE_SAT", "1"); 822 SAT = true; 823 } 824 825 // ACLE 6.4.6 Q (saturation) flag 826 if (DSP || SAT) 827 Builder.defineMacro("__ARM_FEATURE_QBIT", "1"); 828 829 if (Opts.UnsafeFPMath) 830 Builder.defineMacro("__ARM_FP_FAST", "1"); 831 832 // Armv8.2-A FP16 vector intrinsic 833 if ((FPU & NeonFPU) && HasLegalHalfType) 834 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); 835 836 // Armv8.2-A FP16 scalar intrinsics 837 if (HasLegalHalfType) 838 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); 839 840 // Armv8.2-A dot product intrinsics 841 if (DotProd) 842 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); 843 844 if (HasMatMul) 845 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); 846 847 if (HasBFloat16) { 848 Builder.defineMacro("__ARM_FEATURE_BF16", "1"); 849 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); 850 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); 851 } 852 853 switch (ArchKind) { 854 default: 855 break; 856 case llvm::ARM::ArchKind::ARMV8_1A: 857 getTargetDefinesARMV81A(Opts, Builder); 858 break; 859 case llvm::ARM::ArchKind::ARMV8_2A: 860 getTargetDefinesARMV82A(Opts, Builder); 861 break; 862 case llvm::ARM::ArchKind::ARMV8_3A: 863 case llvm::ARM::ArchKind::ARMV8_4A: 864 case llvm::ARM::ArchKind::ARMV8_5A: 865 case llvm::ARM::ArchKind::ARMV8_6A: 866 getTargetDefinesARMV83A(Opts, Builder); 867 break; 868 } 869 } 870 871 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = { 872 #define BUILTIN(ID, TYPE, ATTRS) \ 873 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 874 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 875 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, 876 #include "clang/Basic/BuiltinsNEON.def" 877 878 #define BUILTIN(ID, TYPE, ATTRS) \ 879 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 880 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ 881 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, 882 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 883 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, 884 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 885 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 886 #include "clang/Basic/BuiltinsARM.def" 887 }; 888 889 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const { 890 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin - 891 Builtin::FirstTSBuiltin); 892 } 893 894 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; } 895 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const { 896 return IsAAPCS 897 ? AAPCSABIBuiltinVaList 898 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList 899 : TargetInfo::VoidPtrBuiltinVaList); 900 } 901 902 const char *const ARMTargetInfo::GCCRegNames[] = { 903 // Integer registers 904 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", 905 "r12", "sp", "lr", "pc", 906 907 // Float registers 908 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 909 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 910 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 911 912 // Double registers 913 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 914 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 915 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 916 917 // Quad registers 918 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", 919 "q12", "q13", "q14", "q15"}; 920 921 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const { 922 return llvm::makeArrayRef(GCCRegNames); 923 } 924 925 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 926 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"}, 927 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"}, 928 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"}, 929 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"}, 930 // The S, D and Q registers overlap, but aren't really aliases; we 931 // don't want to substitute one of these for a different-sized one. 932 }; 933 934 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const { 935 return llvm::makeArrayRef(GCCRegAliases); 936 } 937 938 bool ARMTargetInfo::validateAsmConstraint( 939 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 940 switch (*Name) { 941 default: 942 break; 943 case 'l': // r0-r7 if thumb, r0-r15 if ARM 944 Info.setAllowsRegister(); 945 return true; 946 case 'h': // r8-r15, thumb only 947 if (isThumb()) { 948 Info.setAllowsRegister(); 949 return true; 950 } 951 break; 952 case 's': // An integer constant, but allowing only relocatable values. 953 return true; 954 case 't': // s0-s31, d0-d31, or q0-q15 955 case 'w': // s0-s15, d0-d7, or q0-q3 956 case 'x': // s0-s31, d0-d15, or q0-q7 957 Info.setAllowsRegister(); 958 return true; 959 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW) 960 // only available in ARMv6T2 and above 961 if (CPUAttr.equals("6T2") || ArchVersion >= 7) { 962 Info.setRequiresImmediate(0, 65535); 963 return true; 964 } 965 break; 966 case 'I': 967 if (isThumb()) { 968 if (!supportsThumb2()) 969 Info.setRequiresImmediate(0, 255); 970 else 971 // FIXME: should check if immediate value would be valid for a Thumb2 972 // data-processing instruction 973 Info.setRequiresImmediate(); 974 } else 975 // FIXME: should check if immediate value would be valid for an ARM 976 // data-processing instruction 977 Info.setRequiresImmediate(); 978 return true; 979 case 'J': 980 if (isThumb() && !supportsThumb2()) 981 Info.setRequiresImmediate(-255, -1); 982 else 983 Info.setRequiresImmediate(-4095, 4095); 984 return true; 985 case 'K': 986 if (isThumb()) { 987 if (!supportsThumb2()) 988 // FIXME: should check if immediate value can be obtained from shifting 989 // a value between 0 and 255 left by any amount 990 Info.setRequiresImmediate(); 991 else 992 // FIXME: should check if immediate value would be valid for a Thumb2 993 // data-processing instruction when inverted 994 Info.setRequiresImmediate(); 995 } else 996 // FIXME: should check if immediate value would be valid for an ARM 997 // data-processing instruction when inverted 998 Info.setRequiresImmediate(); 999 return true; 1000 case 'L': 1001 if (isThumb()) { 1002 if (!supportsThumb2()) 1003 Info.setRequiresImmediate(-7, 7); 1004 else 1005 // FIXME: should check if immediate value would be valid for a Thumb2 1006 // data-processing instruction when negated 1007 Info.setRequiresImmediate(); 1008 } else 1009 // FIXME: should check if immediate value would be valid for an ARM 1010 // data-processing instruction when negated 1011 Info.setRequiresImmediate(); 1012 return true; 1013 case 'M': 1014 if (isThumb() && !supportsThumb2()) 1015 // FIXME: should check if immediate value is a multiple of 4 between 0 and 1016 // 1020 1017 Info.setRequiresImmediate(); 1018 else 1019 // FIXME: should check if immediate value is a power of two or a integer 1020 // between 0 and 32 1021 Info.setRequiresImmediate(); 1022 return true; 1023 case 'N': 1024 // Thumb1 only 1025 if (isThumb() && !supportsThumb2()) { 1026 Info.setRequiresImmediate(0, 31); 1027 return true; 1028 } 1029 break; 1030 case 'O': 1031 // Thumb1 only 1032 if (isThumb() && !supportsThumb2()) { 1033 // FIXME: should check if immediate value is a multiple of 4 between -508 1034 // and 508 1035 Info.setRequiresImmediate(); 1036 return true; 1037 } 1038 break; 1039 case 'Q': // A memory address that is a single base register. 1040 Info.setAllowsMemory(); 1041 return true; 1042 case 'T': 1043 switch (Name[1]) { 1044 default: 1045 break; 1046 case 'e': // Even general-purpose register 1047 case 'o': // Odd general-purpose register 1048 Info.setAllowsRegister(); 1049 Name++; 1050 return true; 1051 } 1052 break; 1053 case 'U': // a memory reference... 1054 switch (Name[1]) { 1055 case 'q': // ...ARMV4 ldrsb 1056 case 'v': // ...VFP load/store (reg+constant offset) 1057 case 'y': // ...iWMMXt load/store 1058 case 't': // address valid for load/store opaque types wider 1059 // than 128-bits 1060 case 'n': // valid address for Neon doubleword vector load/store 1061 case 'm': // valid address for Neon element and structure load/store 1062 case 's': // valid address for non-offset loads/stores of quad-word 1063 // values in four ARM registers 1064 Info.setAllowsMemory(); 1065 Name++; 1066 return true; 1067 } 1068 break; 1069 } 1070 return false; 1071 } 1072 1073 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const { 1074 std::string R; 1075 switch (*Constraint) { 1076 case 'U': // Two-character constraint; add "^" hint for later parsing. 1077 case 'T': 1078 R = std::string("^") + std::string(Constraint, 2); 1079 Constraint++; 1080 break; 1081 case 'p': // 'p' should be translated to 'r' by default. 1082 R = std::string("r"); 1083 break; 1084 default: 1085 return std::string(1, *Constraint); 1086 } 1087 return R; 1088 } 1089 1090 bool ARMTargetInfo::validateConstraintModifier( 1091 StringRef Constraint, char Modifier, unsigned Size, 1092 std::string &SuggestedModifier) const { 1093 bool isOutput = (Constraint[0] == '='); 1094 bool isInOut = (Constraint[0] == '+'); 1095 1096 // Strip off constraint modifiers. 1097 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 1098 Constraint = Constraint.substr(1); 1099 1100 switch (Constraint[0]) { 1101 default: 1102 break; 1103 case 'r': { 1104 switch (Modifier) { 1105 default: 1106 return (isInOut || isOutput || Size <= 64); 1107 case 'q': 1108 // A register of size 32 cannot fit a vector type. 1109 return false; 1110 } 1111 } 1112 } 1113 1114 return true; 1115 } 1116 const char *ARMTargetInfo::getClobbers() const { 1117 // FIXME: Is this really right? 1118 return ""; 1119 } 1120 1121 TargetInfo::CallingConvCheckResult 1122 ARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1123 switch (CC) { 1124 case CC_AAPCS: 1125 case CC_AAPCS_VFP: 1126 case CC_Swift: 1127 case CC_OpenCLKernel: 1128 return CCCR_OK; 1129 default: 1130 return CCCR_Warning; 1131 } 1132 } 1133 1134 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 1135 if (RegNo == 0) 1136 return 0; 1137 if (RegNo == 1) 1138 return 1; 1139 return -1; 1140 } 1141 1142 bool ARMTargetInfo::hasSjLjLowering() const { return true; } 1143 1144 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple, 1145 const TargetOptions &Opts) 1146 : ARMTargetInfo(Triple, Opts) {} 1147 1148 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1149 MacroBuilder &Builder) const { 1150 Builder.defineMacro("__ARMEL__"); 1151 ARMTargetInfo::getTargetDefines(Opts, Builder); 1152 } 1153 1154 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple, 1155 const TargetOptions &Opts) 1156 : ARMTargetInfo(Triple, Opts) {} 1157 1158 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts, 1159 MacroBuilder &Builder) const { 1160 Builder.defineMacro("__ARMEB__"); 1161 Builder.defineMacro("__ARM_BIG_ENDIAN"); 1162 ARMTargetInfo::getTargetDefines(Opts, Builder); 1163 } 1164 1165 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple, 1166 const TargetOptions &Opts) 1167 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) { 1168 } 1169 1170 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts, 1171 MacroBuilder &Builder) const { 1172 // FIXME: this is invalid for WindowsCE 1173 Builder.defineMacro("_M_ARM_NT", "1"); 1174 Builder.defineMacro("_M_ARMT", "_M_ARM"); 1175 Builder.defineMacro("_M_THUMB", "_M_ARM"); 1176 1177 assert((Triple.getArch() == llvm::Triple::arm || 1178 Triple.getArch() == llvm::Triple::thumb) && 1179 "invalid architecture for Windows ARM target info"); 1180 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6; 1181 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset)); 1182 1183 // TODO map the complete set of values 1184 // 31: VFPv3 40: VFPv4 1185 Builder.defineMacro("_M_ARM_FP", "31"); 1186 } 1187 1188 TargetInfo::BuiltinVaListKind 1189 WindowsARMTargetInfo::getBuiltinVaListKind() const { 1190 return TargetInfo::CharPtrBuiltinVaList; 1191 } 1192 1193 TargetInfo::CallingConvCheckResult 1194 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1195 switch (CC) { 1196 case CC_X86StdCall: 1197 case CC_X86ThisCall: 1198 case CC_X86FastCall: 1199 case CC_X86VectorCall: 1200 return CCCR_Ignore; 1201 case CC_C: 1202 case CC_OpenCLKernel: 1203 case CC_PreserveMost: 1204 case CC_PreserveAll: 1205 case CC_Swift: 1206 return CCCR_OK; 1207 default: 1208 return CCCR_Warning; 1209 } 1210 } 1211 1212 // Windows ARM + Itanium C++ ABI Target 1213 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo( 1214 const llvm::Triple &Triple, const TargetOptions &Opts) 1215 : WindowsARMTargetInfo(Triple, Opts) { 1216 TheCXXABI.set(TargetCXXABI::GenericARM); 1217 } 1218 1219 void ItaniumWindowsARMleTargetInfo::getTargetDefines( 1220 const LangOptions &Opts, MacroBuilder &Builder) const { 1221 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1222 1223 if (Opts.MSVCCompat) 1224 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1225 } 1226 1227 // Windows ARM, MS (C++) ABI 1228 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple, 1229 const TargetOptions &Opts) 1230 : WindowsARMTargetInfo(Triple, Opts) { 1231 TheCXXABI.set(TargetCXXABI::Microsoft); 1232 } 1233 1234 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1235 MacroBuilder &Builder) const { 1236 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1237 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1238 } 1239 1240 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple, 1241 const TargetOptions &Opts) 1242 : WindowsARMTargetInfo(Triple, Opts) { 1243 TheCXXABI.set(TargetCXXABI::GenericARM); 1244 } 1245 1246 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1247 MacroBuilder &Builder) const { 1248 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1249 Builder.defineMacro("_ARM_"); 1250 } 1251 1252 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple, 1253 const TargetOptions &Opts) 1254 : ARMleTargetInfo(Triple, Opts) { 1255 this->WCharType = TargetInfo::UnsignedShort; 1256 TLSSupported = false; 1257 DoubleAlign = LongLongAlign = 64; 1258 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 1259 } 1260 1261 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1262 MacroBuilder &Builder) const { 1263 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1264 Builder.defineMacro("_ARM_"); 1265 Builder.defineMacro("__CYGWIN__"); 1266 Builder.defineMacro("__CYGWIN32__"); 1267 DefineStd(Builder, "unix", Opts); 1268 if (Opts.CPlusPlus) 1269 Builder.defineMacro("_GNU_SOURCE"); 1270 } 1271 1272 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple, 1273 const TargetOptions &Opts) 1274 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) { 1275 HasAlignMac68kSupport = true; 1276 // iOS always has 64-bit atomic instructions. 1277 // FIXME: This should be based off of the target features in 1278 // ARMleTargetInfo. 1279 MaxAtomicInlineWidth = 64; 1280 1281 if (Triple.isWatchABI()) { 1282 // Darwin on iOS uses a variant of the ARM C++ ABI. 1283 TheCXXABI.set(TargetCXXABI::WatchOS); 1284 1285 // BOOL should be a real boolean on the new ABI 1286 UseSignedCharForObjCBool = false; 1287 } else 1288 TheCXXABI.set(TargetCXXABI::iOS); 1289 } 1290 1291 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts, 1292 const llvm::Triple &Triple, 1293 MacroBuilder &Builder) const { 1294 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 1295 } 1296 1297 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple, 1298 const TargetOptions &Opts) 1299 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(), 1300 Triple.getOSName(), 1301 Triple.getEnvironmentName()), 1302 Opts) { 1303 IsRenderScriptTarget = true; 1304 LongWidth = LongAlign = 64; 1305 } 1306 1307 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts, 1308 MacroBuilder &Builder) const { 1309 Builder.defineMacro("__RENDERSCRIPT__"); 1310 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1311 } 1312