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