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