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