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