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