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