1106 lines · cpp
1//===--- TargetInfo.cpp - Information about Target machine ----------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the TargetInfo interface.10//11//===----------------------------------------------------------------------===//12 13#include "clang/Basic/TargetInfo.h"14#include "clang/Basic/AddressSpaces.h"15#include "clang/Basic/CharInfo.h"16#include "clang/Basic/Diagnostic.h"17#include "clang/Basic/DiagnosticFrontend.h"18#include "clang/Basic/LangOptions.h"19#include "llvm/ADT/APFloat.h"20#include "llvm/ADT/STLExtras.h"21#include "llvm/ADT/StringExtras.h"22#include "llvm/Support/ErrorHandling.h"23#include "llvm/TargetParser/TargetParser.h"24#include <cstdlib>25using namespace clang;26 27static const LangASMap DefaultAddrSpaceMap = {0};28// The fake address space map must have a distinct entry for each29// language-specific address space.30static const LangASMap FakeAddrSpaceMap = {31 0, // Default32 1, // opencl_global33 3, // opencl_local34 2, // opencl_constant35 0, // opencl_private36 4, // opencl_generic37 5, // opencl_global_device38 6, // opencl_global_host39 7, // cuda_device40 8, // cuda_constant41 9, // cuda_shared42 1, // sycl_global43 5, // sycl_global_device44 6, // sycl_global_host45 3, // sycl_local46 0, // sycl_private47 10, // ptr32_sptr48 11, // ptr32_uptr49 12, // ptr6450 13, // hlsl_groupshared51 14, // hlsl_constant52 15, // hlsl_private53 16, // hlsl_device54 17, // hlsl_input55 20, // wasm_funcref56};57 58// TargetInfo Constructor.59TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {60 // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or61 // SPARC. These should be overridden by concrete targets as needed.62 HasMustTail = true;63 BigEndian = !T.isLittleEndian();64 TLSSupported = true;65 VLASupported = true;66 NoAsmVariants = false;67 HasFastHalfType = false;68 HalfArgsAndReturns = false;69 HasFloat128 = false;70 HasIbm128 = false;71 HasFloat16 = false;72 HasBFloat16 = false;73 HasFullBFloat16 = false;74 HasLongDouble = true;75 HasFPReturn = true;76 HasStrictFP = false;77 PointerWidth = PointerAlign = 32;78 BoolWidth = BoolAlign = 8;79 ShortWidth = ShortAlign = 16;80 IntWidth = IntAlign = 32;81 LongWidth = LongAlign = 32;82 LongLongWidth = LongLongAlign = 64;83 Int128Align = 128;84 85 // Fixed point default bit widths86 ShortAccumWidth = ShortAccumAlign = 16;87 AccumWidth = AccumAlign = 32;88 LongAccumWidth = LongAccumAlign = 64;89 ShortFractWidth = ShortFractAlign = 8;90 FractWidth = FractAlign = 16;91 LongFractWidth = LongFractAlign = 32;92 93 // Fixed point default integral and fractional bit sizes94 // We give the _Accum 1 fewer fractional bits than their corresponding _Fract95 // types by default to have the same number of fractional bits between _Accum96 // and _Fract types.97 PaddingOnUnsignedFixedPoint = false;98 ShortAccumScale = 7;99 AccumScale = 15;100 LongAccumScale = 31;101 102 SuitableAlign = 64;103 DefaultAlignForAttributeAligned = 128;104 MinGlobalAlign = 0;105 // From the glibc documentation, on GNU systems, malloc guarantees 16-byte106 // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See107 // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html.108 // This alignment guarantee also applies to Windows and Android. On Darwin109 // and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems.110 if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() ||111 T.isOHOSFamily())112 NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;113 else if (T.isOSDarwin() || T.isOSOpenBSD())114 NewAlign = 128;115 else116 NewAlign = 0; // Infer from basic type alignment.117 HalfWidth = 16;118 HalfAlign = 16;119 FloatWidth = 32;120 FloatAlign = 32;121 DoubleWidth = 64;122 DoubleAlign = 64;123 LongDoubleWidth = 64;124 LongDoubleAlign = 64;125 Float128Align = 128;126 Ibm128Align = 128;127 LargeArrayMinWidth = 0;128 LargeArrayAlign = 0;129 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;130 MaxVectorAlign = 0;131 MaxTLSAlign = 0;132 SizeType = UnsignedLong;133 PtrDiffType = SignedLong;134 IntMaxType = SignedLongLong;135 IntPtrType = SignedLong;136 WCharType = SignedInt;137 WIntType = SignedInt;138 Char16Type = UnsignedShort;139 Char32Type = UnsignedInt;140 Int64Type = SignedLongLong;141 Int16Type = SignedShort;142 SigAtomicType = SignedInt;143 ProcessIDType = SignedInt;144 UseSignedCharForObjCBool = true;145 UseBitFieldTypeAlignment = true;146 UseZeroLengthBitfieldAlignment = false;147 UseLeadingZeroLengthBitfield = true;148 UseExplicitBitFieldAlignment = true;149 ZeroLengthBitfieldBoundary = 0;150 LargestOverSizedBitfieldContainer = 64;151 MaxAlignedAttribute = 0;152 HalfFormat = &llvm::APFloat::IEEEhalf();153 FloatFormat = &llvm::APFloat::IEEEsingle();154 DoubleFormat = &llvm::APFloat::IEEEdouble();155 LongDoubleFormat = &llvm::APFloat::IEEEdouble();156 Float128Format = &llvm::APFloat::IEEEquad();157 Ibm128Format = &llvm::APFloat::PPCDoubleDouble();158 MCountName = "mcount";159 UserLabelPrefix = "_";160 RegParmMax = 0;161 SSERegParmMax = 0;162 HasAlignMac68kSupport = false;163 HasBuiltinMSVaList = false;164 HasAArch64ACLETypes = false;165 HasRISCVVTypes = false;166 AllowAMDGPUUnsafeFPAtomics = false;167 HasUnalignedAccess = false;168 ARMCDECoprocMask = 0;169 170 // Default to no types using fpret.171 RealTypeUsesObjCFPRetMask = 0;172 173 // Default to not using fp2ret for __Complex long double174 ComplexLongDoubleUsesFP2Ret = false;175 176 // Set the C++ ABI based on the triple.177 TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment() || Triple.isUEFI()178 ? TargetCXXABI::Microsoft179 : TargetCXXABI::GenericItanium);180 181 HasMicrosoftRecordLayout = TheCXXABI.isMicrosoft();182 183 // Default to an empty address space map.184 AddrSpaceMap = &DefaultAddrSpaceMap;185 UseAddrSpaceMapMangling = false;186 187 // Default to an unknown platform name.188 PlatformName = "unknown";189 PlatformMinVersion = VersionTuple();190 191 MaxOpenCLWorkGroupSize = 1024;192 193 MaxBitIntWidth.reset();194}195 196// Out of line virtual dtor for TargetInfo.197TargetInfo::~TargetInfo() {}198 199void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) {200 DataLayoutString = DL.str();201 UserLabelPrefix = ULP;202}203 204bool205TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const {206 Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";207 return false;208}209 210CFBranchLabelSchemeKind TargetInfo::getDefaultCFBranchLabelScheme() const {211 // if this hook is called, the target should override it to return a212 // non-default scheme213 llvm::report_fatal_error("not implemented");214}215 216bool TargetInfo::checkCFBranchLabelSchemeSupported(217 const CFBranchLabelSchemeKind Scheme, DiagnosticsEngine &Diags) const {218 if (Scheme != CFBranchLabelSchemeKind::Default)219 Diags.Report(diag::err_opt_not_valid_on_target)220 << (Twine("mcf-branch-label-scheme=") +221 getCFBranchLabelSchemeFlagVal(Scheme))222 .str();223 return false;224}225 226bool227TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const {228 Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return";229 return false;230}231 232/// getTypeName - Return the user string for the specified integer type enum.233/// For example, SignedShort -> "short".234const char *TargetInfo::getTypeName(IntType T) {235 switch (T) {236 default: llvm_unreachable("not an integer!");237 case SignedChar: return "signed char";238 case UnsignedChar: return "unsigned char";239 case SignedShort: return "short";240 case UnsignedShort: return "unsigned short";241 case SignedInt: return "int";242 case UnsignedInt: return "unsigned int";243 case SignedLong: return "long int";244 case UnsignedLong: return "long unsigned int";245 case SignedLongLong: return "long long int";246 case UnsignedLongLong: return "long long unsigned int";247 }248}249 250/// getTypeConstantSuffix - Return the constant suffix for the specified251/// integer type enum. For example, SignedLong -> "L".252const char *TargetInfo::getTypeConstantSuffix(IntType T) const {253 switch (T) {254 default: llvm_unreachable("not an integer!");255 case SignedChar:256 case SignedShort:257 case SignedInt: return "";258 case SignedLong: return "L";259 case SignedLongLong: return "LL";260 case UnsignedChar:261 if (getCharWidth() < getIntWidth())262 return "";263 [[fallthrough]];264 case UnsignedShort:265 if (getShortWidth() < getIntWidth())266 return "";267 [[fallthrough]];268 case UnsignedInt: return "U";269 case UnsignedLong: return "UL";270 case UnsignedLongLong: return "ULL";271 }272}273 274/// getTypeFormatModifier - Return the printf format modifier for the275/// specified integer type enum. For example, SignedLong -> "l".276 277const char *TargetInfo::getTypeFormatModifier(IntType T) {278 switch (T) {279 default: llvm_unreachable("not an integer!");280 case SignedChar:281 case UnsignedChar: return "hh";282 case SignedShort:283 case UnsignedShort: return "h";284 case SignedInt:285 case UnsignedInt: return "";286 case SignedLong:287 case UnsignedLong: return "l";288 case SignedLongLong:289 case UnsignedLongLong: return "ll";290 }291}292 293/// getTypeWidth - Return the width (in bits) of the specified integer type294/// enum. For example, SignedInt -> getIntWidth().295unsigned TargetInfo::getTypeWidth(IntType T) const {296 switch (T) {297 default: llvm_unreachable("not an integer!");298 case SignedChar:299 case UnsignedChar: return getCharWidth();300 case SignedShort:301 case UnsignedShort: return getShortWidth();302 case SignedInt:303 case UnsignedInt: return getIntWidth();304 case SignedLong:305 case UnsignedLong: return getLongWidth();306 case SignedLongLong:307 case UnsignedLongLong: return getLongLongWidth();308 };309}310 311TargetInfo::IntType TargetInfo::getIntTypeByWidth(312 unsigned BitWidth, bool IsSigned) const {313 if (getCharWidth() == BitWidth)314 return IsSigned ? SignedChar : UnsignedChar;315 if (getShortWidth() == BitWidth)316 return IsSigned ? SignedShort : UnsignedShort;317 if (getIntWidth() == BitWidth)318 return IsSigned ? SignedInt : UnsignedInt;319 if (getLongWidth() == BitWidth)320 return IsSigned ? SignedLong : UnsignedLong;321 if (getLongLongWidth() == BitWidth)322 return IsSigned ? SignedLongLong : UnsignedLongLong;323 return NoInt;324}325 326TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,327 bool IsSigned) const {328 if (getCharWidth() >= BitWidth)329 return IsSigned ? SignedChar : UnsignedChar;330 if (getShortWidth() >= BitWidth)331 return IsSigned ? SignedShort : UnsignedShort;332 if (getIntWidth() >= BitWidth)333 return IsSigned ? SignedInt : UnsignedInt;334 if (getLongWidth() >= BitWidth)335 return IsSigned ? SignedLong : UnsignedLong;336 if (getLongLongWidth() >= BitWidth)337 return IsSigned ? SignedLongLong : UnsignedLongLong;338 return NoInt;339}340 341FloatModeKind TargetInfo::getRealTypeByWidth(unsigned BitWidth,342 FloatModeKind ExplicitType) const {343 if (getHalfWidth() == BitWidth)344 return FloatModeKind::Half;345 if (getFloatWidth() == BitWidth)346 return FloatModeKind::Float;347 if (getDoubleWidth() == BitWidth)348 return FloatModeKind::Double;349 350 switch (BitWidth) {351 case 96:352 if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended())353 return FloatModeKind::LongDouble;354 break;355 case 128:356 // The caller explicitly asked for an IEEE compliant type but we still357 // have to check if the target supports it.358 if (ExplicitType == FloatModeKind::Float128)359 return hasFloat128Type() ? FloatModeKind::Float128360 : FloatModeKind::NoFloat;361 if (ExplicitType == FloatModeKind::Ibm128)362 return hasIbm128Type() ? FloatModeKind::Ibm128363 : FloatModeKind::NoFloat;364 if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() ||365 &getLongDoubleFormat() == &llvm::APFloat::IEEEquad())366 return FloatModeKind::LongDouble;367 if (hasFloat128Type())368 return FloatModeKind::Float128;369 break;370 }371 372 return FloatModeKind::NoFloat;373}374 375/// getTypeAlign - Return the alignment (in bits) of the specified integer type376/// enum. For example, SignedInt -> getIntAlign().377unsigned TargetInfo::getTypeAlign(IntType T) const {378 switch (T) {379 default: llvm_unreachable("not an integer!");380 case SignedChar:381 case UnsignedChar: return getCharAlign();382 case SignedShort:383 case UnsignedShort: return getShortAlign();384 case SignedInt:385 case UnsignedInt: return getIntAlign();386 case SignedLong:387 case UnsignedLong: return getLongAlign();388 case SignedLongLong:389 case UnsignedLongLong: return getLongLongAlign();390 };391}392 393/// isTypeSigned - Return whether an integer types is signed. Returns true if394/// the type is signed; false otherwise.395bool TargetInfo::isTypeSigned(IntType T) {396 switch (T) {397 default: llvm_unreachable("not an integer!");398 case SignedChar:399 case SignedShort:400 case SignedInt:401 case SignedLong:402 case SignedLongLong:403 return true;404 case UnsignedChar:405 case UnsignedShort:406 case UnsignedInt:407 case UnsignedLong:408 case UnsignedLongLong:409 return false;410 };411}412 413/// adjust - Set forced language options.414/// Apply changes to the target information with respect to certain415/// language options which change the target configuration and adjust416/// the language based on the target options where applicable.417void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts,418 const TargetInfo *Aux) {419 if (Opts.NoBitFieldTypeAlign)420 UseBitFieldTypeAlignment = false;421 422 switch (Opts.WCharSize) {423 default: llvm_unreachable("invalid wchar_t width");424 case 0: break;425 case 1: WCharType = Opts.WCharIsSigned ? SignedChar : UnsignedChar; break;426 case 2: WCharType = Opts.WCharIsSigned ? SignedShort : UnsignedShort; break;427 case 4: WCharType = Opts.WCharIsSigned ? SignedInt : UnsignedInt; break;428 }429 430 if (Opts.AlignDouble) {431 DoubleAlign = LongLongAlign = 64;432 LongDoubleAlign = 64;433 }434 435 // HLSL explicitly defines the sizes and formats of some data types, and we436 // need to conform to those regardless of what architecture you are targeting.437 if (Opts.HLSL) {438 BoolWidth = BoolAlign = 32;439 LongWidth = LongAlign = 64;440 if (!Opts.NativeHalfType) {441 HalfFormat = &llvm::APFloat::IEEEsingle();442 HalfWidth = HalfAlign = 32;443 }444 }445 446 if (Opts.OpenCL) {447 // OpenCL C requires specific widths for types, irrespective of448 // what these normally are for the target.449 // We also define long long and long double here, although the450 // OpenCL standard only mentions these as "reserved".451 ShortWidth = ShortAlign = 16;452 IntWidth = IntAlign = 32;453 LongWidth = LongAlign = 64;454 LongLongWidth = LongLongAlign = 128;455 HalfWidth = HalfAlign = 16;456 FloatWidth = FloatAlign = 32;457 458 // Embedded 32-bit targets (OpenCL EP) might have double C type459 // defined as float. Let's not override this as it might lead460 // to generating illegal code that uses 64bit doubles.461 if (DoubleWidth != FloatWidth) {462 DoubleWidth = DoubleAlign = 64;463 DoubleFormat = &llvm::APFloat::IEEEdouble();464 }465 LongDoubleWidth = LongDoubleAlign = 128;466 467 unsigned MaxPointerWidth = getMaxPointerWidth();468 assert(MaxPointerWidth == 32 || MaxPointerWidth == 64);469 bool Is32BitArch = MaxPointerWidth == 32;470 SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;471 PtrDiffType = Is32BitArch ? SignedInt : SignedLong;472 IntPtrType = Is32BitArch ? SignedInt : SignedLong;473 474 IntMaxType = SignedLongLong;475 Int64Type = SignedLong;476 477 HalfFormat = &llvm::APFloat::IEEEhalf();478 FloatFormat = &llvm::APFloat::IEEEsingle();479 LongDoubleFormat = &llvm::APFloat::IEEEquad();480 481 // OpenCL C v3.0 s6.7.5 - The generic address space requires support for482 // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space483 // feature484 // OpenCL C v3.0 s6.2.1 - OpenCL pipes require support of OpenCL C 2.0485 // or later and __opencl_c_pipes feature486 // FIXME: These language options are also defined in setLangDefaults()487 // for OpenCL C 2.0 but with no access to target capabilities. Target488 // should be immutable once created and thus these language options need489 // to be defined only once.490 if (Opts.getOpenCLCompatibleVersion() == 300) {491 const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts();492 Opts.OpenCLGenericAddressSpace = hasFeatureEnabled(493 OpenCLFeaturesMap, "__opencl_c_generic_address_space");494 Opts.OpenCLPipes =495 hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes");496 Opts.Blocks =497 hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_device_enqueue");498 }499 }500 501 if (Opts.DoubleSize) {502 if (Opts.DoubleSize == 32) {503 DoubleWidth = 32;504 LongDoubleWidth = 32;505 DoubleFormat = &llvm::APFloat::IEEEsingle();506 LongDoubleFormat = &llvm::APFloat::IEEEsingle();507 } else if (Opts.DoubleSize == 64) {508 DoubleWidth = 64;509 LongDoubleWidth = 64;510 DoubleFormat = &llvm::APFloat::IEEEdouble();511 LongDoubleFormat = &llvm::APFloat::IEEEdouble();512 }513 }514 515 if (Opts.LongDoubleSize) {516 if (Opts.LongDoubleSize == DoubleWidth) {517 LongDoubleWidth = DoubleWidth;518 LongDoubleAlign = DoubleAlign;519 LongDoubleFormat = DoubleFormat;520 } else if (Opts.LongDoubleSize == 128) {521 LongDoubleWidth = LongDoubleAlign = 128;522 LongDoubleFormat = &llvm::APFloat::IEEEquad();523 } else if (Opts.LongDoubleSize == 80) {524 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();525 if (getTriple().isWindowsMSVCEnvironment()) {526 LongDoubleWidth = 128;527 LongDoubleAlign = 128;528 } else { // Linux529 if (getTriple().getArch() == llvm::Triple::x86) {530 LongDoubleWidth = 96;531 LongDoubleAlign = 32;532 } else {533 LongDoubleWidth = 128;534 LongDoubleAlign = 128;535 }536 }537 }538 }539 540 if (Opts.NewAlignOverride)541 NewAlign = Opts.NewAlignOverride * getCharWidth();542 543 // Each unsigned fixed point type has the same number of fractional bits as544 // its corresponding signed type.545 PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint;546 CheckFixedPointBits();547 548 if (Opts.ProtectParens && !checkArithmeticFenceSupported()) {549 Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens";550 Opts.ProtectParens = false;551 }552 553 if (Opts.MaxBitIntWidth)554 MaxBitIntWidth = static_cast<unsigned>(Opts.MaxBitIntWidth);555 556 if (Opts.FakeAddressSpaceMap)557 AddrSpaceMap = &FakeAddrSpaceMap;558 559 // Check if it's CUDA device compilation; ensure layout consistency with host.560 if (Opts.CUDA && Opts.CUDAIsDevice && Aux && !HasMicrosoftRecordLayout)561 HasMicrosoftRecordLayout = Aux->getCXXABI().isMicrosoft();562}563 564bool TargetInfo::initFeatureMap(565 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,566 const std::vector<std::string> &FeatureVec) const {567 for (StringRef Name : FeatureVec) {568 if (Name.empty())569 continue;570 // Apply the feature via the target.571 if (Name[0] != '+' && Name[0] != '-')572 Diags.Report(diag::warn_fe_backend_invalid_feature_flag) << Name;573 else574 setFeatureEnabled(Features, Name.substr(1), Name[0] == '+');575 }576 return true;577}578 579ParsedTargetAttr TargetInfo::parseTargetAttr(StringRef Features) const {580 ParsedTargetAttr Ret;581 if (Features == "default")582 return Ret;583 SmallVector<StringRef, 1> AttrFeatures;584 Features.split(AttrFeatures, ",");585 586 // Grab the various features and prepend a "+" to turn on the feature to587 // the backend and add them to our existing set of features.588 for (auto &Feature : AttrFeatures) {589 // Go ahead and trim whitespace rather than either erroring or590 // accepting it weirdly.591 Feature = Feature.trim();592 593 // TODO: Support the fpmath option. It will require checking594 // overall feature validity for the function with the rest of the595 // attributes on the function.596 if (Feature.starts_with("fpmath="))597 continue;598 599 if (Feature.starts_with("branch-protection=")) {600 Ret.BranchProtection = Feature.split('=').second.trim();601 continue;602 }603 604 // While we're here iterating check for a different target cpu.605 if (Feature.starts_with("arch=")) {606 if (!Ret.CPU.empty())607 Ret.Duplicate = "arch=";608 else609 Ret.CPU = Feature.split("=").second.trim();610 } else if (Feature.starts_with("tune=")) {611 if (!Ret.Tune.empty())612 Ret.Duplicate = "tune=";613 else614 Ret.Tune = Feature.split("=").second.trim();615 } else if (Feature.starts_with("no-"))616 Ret.Features.push_back("-" + Feature.split("-").second.str());617 else618 Ret.Features.push_back("+" + Feature.str());619 }620 return Ret;621}622 623TargetInfo::CallingConvKind624TargetInfo::getCallingConvKind(bool ClangABICompat4) const {625 if (getCXXABI() != TargetCXXABI::Microsoft &&626 (ClangABICompat4 || getTriple().isPS4()))627 return CCK_ClangABI4OrPS4;628 return CCK_Default;629}630 631bool TargetInfo::callGlobalDeleteInDeletingDtor(632 const LangOptions &LangOpts) const {633 if (getCXXABI() == TargetCXXABI::Microsoft &&634 LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver21)635 return true;636 return false;637}638 639bool TargetInfo::areDefaultedSMFStillPOD(const LangOptions &LangOpts) const {640 return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15;641}642 643void TargetInfo::setDependentOpenCLOpts() {644 auto &Opts = getSupportedOpenCLOpts();645 if (!hasFeatureEnabled(Opts, "cl_khr_fp64") ||646 !hasFeatureEnabled(Opts, "__opencl_c_fp64")) {647 setFeatureEnabled(Opts, "__opencl_c_ext_fp64_global_atomic_add", false);648 setFeatureEnabled(Opts, "__opencl_c_ext_fp64_local_atomic_add", false);649 setFeatureEnabled(Opts, "__opencl_c_ext_fp64_global_atomic_min_max", false);650 setFeatureEnabled(Opts, "__opencl_c_ext_fp64_local_atomic_min_max", false);651 }652}653 654LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const {655 switch (TK) {656 case OCLTK_Image:657 case OCLTK_Pipe:658 return LangAS::opencl_global;659 660 case OCLTK_Sampler:661 return LangAS::opencl_constant;662 663 default:664 return LangAS::Default;665 }666}667 668//===----------------------------------------------------------------------===//669 670 671static StringRef removeGCCRegisterPrefix(StringRef Name) {672 if (Name[0] == '%' || Name[0] == '#')673 Name = Name.substr(1);674 675 return Name;676}677 678/// isValidClobber - Returns whether the passed in string is679/// a valid clobber in an inline asm statement. This is used by680/// Sema.681bool TargetInfo::isValidClobber(StringRef Name) const {682 return (isValidGCCRegisterName(Name) || Name == "memory" || Name == "cc" ||683 Name == "unwind");684}685 686/// isValidGCCRegisterName - Returns whether the passed in string687/// is a valid register name according to GCC. This is used by Sema for688/// inline asm statements.689bool TargetInfo::isValidGCCRegisterName(StringRef Name) const {690 if (Name.empty())691 return false;692 693 // Get rid of any register prefix.694 Name = removeGCCRegisterPrefix(Name);695 if (Name.empty())696 return false;697 698 ArrayRef<const char *> Names = getGCCRegNames();699 700 // If we have a number it maps to an entry in the register name array.701 if (isDigit(Name[0])) {702 unsigned n;703 if (!Name.getAsInteger(0, n))704 return n < Names.size();705 }706 707 // Check register names.708 if (llvm::is_contained(Names, Name))709 return true;710 711 // Check any additional names that we have.712 for (const AddlRegName &ARN : getGCCAddlRegNames())713 for (const char *AN : ARN.Names) {714 if (!AN)715 break;716 // Make sure the register that the additional name is for is within717 // the bounds of the register names from above.718 if (AN == Name && ARN.RegNum < Names.size())719 return true;720 }721 722 // Now check aliases.723 for (const GCCRegAlias &GRA : getGCCRegAliases())724 for (const char *A : GRA.Aliases) {725 if (!A)726 break;727 if (A == Name)728 return true;729 }730 731 return false;732}733 734StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name,735 bool ReturnCanonical) const {736 assert(isValidGCCRegisterName(Name) && "Invalid register passed in");737 738 // Get rid of any register prefix.739 Name = removeGCCRegisterPrefix(Name);740 741 ArrayRef<const char *> Names = getGCCRegNames();742 743 // First, check if we have a number.744 if (isDigit(Name[0])) {745 unsigned n;746 if (!Name.getAsInteger(0, n)) {747 assert(n < Names.size() && "Out of bounds register number!");748 return Names[n];749 }750 }751 752 // Check any additional names that we have.753 for (const AddlRegName &ARN : getGCCAddlRegNames())754 for (const char *AN : ARN.Names) {755 if (!AN)756 break;757 // Make sure the register that the additional name is for is within758 // the bounds of the register names from above.759 if (AN == Name && ARN.RegNum < Names.size())760 return ReturnCanonical ? Names[ARN.RegNum] : Name;761 }762 763 // Now check aliases.764 for (const GCCRegAlias &RA : getGCCRegAliases())765 for (const char *A : RA.Aliases) {766 if (!A)767 break;768 if (A == Name)769 return RA.Register;770 }771 772 return Name;773}774 775bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {776 const char *Name = Info.getConstraintStr().c_str();777 // An output constraint must start with '=' or '+'778 if (*Name != '=' && *Name != '+')779 return false;780 781 if (*Name == '+')782 Info.setIsReadWrite();783 784 Name++;785 while (*Name) {786 switch (*Name) {787 default:788 if (!validateAsmConstraint(Name, Info)) {789 // FIXME: We temporarily return false790 // so we can add more constraints as we hit it.791 // Eventually, an unknown constraint should just be treated as 'g'.792 return false;793 }794 break;795 case '&': // early clobber.796 Info.setEarlyClobber();797 break;798 case '%': // commutative.799 // FIXME: Check that there is a another register after this one.800 break;801 case 'r': // general register.802 Info.setAllowsRegister();803 break;804 case 'm': // memory operand.805 case 'o': // offsetable memory operand.806 case 'V': // non-offsetable memory operand.807 case '<': // autodecrement memory operand.808 case '>': // autoincrement memory operand.809 Info.setAllowsMemory();810 break;811 case 'g': // general register, memory operand or immediate integer.812 case 'X': // any operand.813 Info.setAllowsRegister();814 Info.setAllowsMemory();815 break;816 case ',': // multiple alternative constraint. Pass it.817 // Handle additional optional '=' or '+' modifiers.818 if (Name[1] == '=' || Name[1] == '+')819 Name++;820 break;821 case '#': // Ignore as constraint.822 while (Name[1] && Name[1] != ',')823 Name++;824 break;825 case '?': // Disparage slightly code.826 case '!': // Disparage severely.827 case '*': // Ignore for choosing register preferences.828 case 'i': // Ignore i,n,E,F as output constraints (match from the other829 // chars)830 case 'n':831 case 'E':832 case 'F':833 break; // Pass them.834 }835 836 Name++;837 }838 839 // Early clobber with a read-write constraint which doesn't permit registers840 // is invalid.841 if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister())842 return false;843 844 // If a constraint allows neither memory nor register operands it contains845 // only modifiers. Reject it.846 return Info.allowsMemory() || Info.allowsRegister();847}848 849bool TargetInfo::resolveSymbolicName(const char *&Name,850 ArrayRef<ConstraintInfo> OutputConstraints,851 unsigned &Index) const {852 assert(*Name == '[' && "Symbolic name did not start with '['");853 Name++;854 const char *Start = Name;855 while (*Name && *Name != ']')856 Name++;857 858 if (!*Name) {859 // Missing ']'860 return false;861 }862 863 std::string SymbolicName(Start, Name - Start);864 865 for (Index = 0; Index != OutputConstraints.size(); ++Index)866 if (SymbolicName == OutputConstraints[Index].getName())867 return true;868 869 return false;870}871 872bool TargetInfo::validateInputConstraint(873 MutableArrayRef<ConstraintInfo> OutputConstraints,874 ConstraintInfo &Info) const {875 const char *Name = Info.ConstraintStr.c_str();876 877 if (!*Name)878 return false;879 880 while (*Name) {881 switch (*Name) {882 default:883 // Check if we have a matching constraint884 if (*Name >= '0' && *Name <= '9') {885 const char *DigitStart = Name;886 while (Name[1] >= '0' && Name[1] <= '9')887 Name++;888 const char *DigitEnd = Name;889 unsigned i;890 if (StringRef(DigitStart, DigitEnd - DigitStart + 1)891 .getAsInteger(10, i))892 return false;893 894 // Check if matching constraint is out of bounds.895 if (i >= OutputConstraints.size()) return false;896 897 // A number must refer to an output only operand.898 if (OutputConstraints[i].isReadWrite())899 return false;900 901 // If the constraint is already tied, it must be tied to the902 // same operand referenced to by the number.903 if (Info.hasTiedOperand() && Info.getTiedOperand() != i)904 return false;905 906 // The constraint should have the same info as the respective907 // output constraint.908 Info.setTiedOperand(i, OutputConstraints[i]);909 } else if (!validateAsmConstraint(Name, Info)) {910 // FIXME: This error return is in place temporarily so we can911 // add more constraints as we hit it. Eventually, an unknown912 // constraint should just be treated as 'g'.913 return false;914 }915 break;916 case '[': {917 unsigned Index = 0;918 if (!resolveSymbolicName(Name, OutputConstraints, Index))919 return false;920 921 // If the constraint is already tied, it must be tied to the922 // same operand referenced to by the number.923 if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)924 return false;925 926 // A number must refer to an output only operand.927 if (OutputConstraints[Index].isReadWrite())928 return false;929 930 Info.setTiedOperand(Index, OutputConstraints[Index]);931 break;932 }933 case '%': // commutative934 // FIXME: Fail if % is used with the last operand.935 break;936 case 'i': // immediate integer.937 break;938 case 'n': // immediate integer with a known value.939 Info.setRequiresImmediate();940 break;941 case 'I': // Various constant constraints with target-specific meanings.942 case 'J':943 case 'K':944 case 'L':945 case 'M':946 case 'N':947 case 'O':948 case 'P':949 if (!validateAsmConstraint(Name, Info))950 return false;951 break;952 case 'r': // general register.953 Info.setAllowsRegister();954 break;955 case 'm': // memory operand.956 case 'o': // offsettable memory operand.957 case 'V': // non-offsettable memory operand.958 case '<': // autodecrement memory operand.959 case '>': // autoincrement memory operand.960 Info.setAllowsMemory();961 break;962 case 'g': // general register, memory operand or immediate integer.963 case 'X': // any operand.964 Info.setAllowsRegister();965 Info.setAllowsMemory();966 break;967 case 'E': // immediate floating point.968 case 'F': // immediate floating point.969 case 'p': // address operand.970 break;971 case ',': // multiple alternative constraint. Ignore comma.972 break;973 case '#': // Ignore as constraint.974 while (Name[1] && Name[1] != ',')975 Name++;976 break;977 case '?': // Disparage slightly code.978 case '!': // Disparage severely.979 case '*': // Ignore for choosing register preferences.980 break; // Pass them.981 }982 983 Name++;984 }985 986 return true;987}988 989bool TargetInfo::validatePointerAuthKey(const llvm::APSInt &value) const {990 return false;991}992 993void TargetInfo::CheckFixedPointBits() const {994 // Check that the number of fractional and integral bits (and maybe sign) can995 // fit into the bits given for a fixed point type.996 assert(ShortAccumScale + getShortAccumIBits() + 1 <= ShortAccumWidth);997 assert(AccumScale + getAccumIBits() + 1 <= AccumWidth);998 assert(LongAccumScale + getLongAccumIBits() + 1 <= LongAccumWidth);999 assert(getUnsignedShortAccumScale() + getUnsignedShortAccumIBits() <=1000 ShortAccumWidth);1001 assert(getUnsignedAccumScale() + getUnsignedAccumIBits() <= AccumWidth);1002 assert(getUnsignedLongAccumScale() + getUnsignedLongAccumIBits() <=1003 LongAccumWidth);1004 1005 assert(getShortFractScale() + 1 <= ShortFractWidth);1006 assert(getFractScale() + 1 <= FractWidth);1007 assert(getLongFractScale() + 1 <= LongFractWidth);1008 assert(getUnsignedShortFractScale() <= ShortFractWidth);1009 assert(getUnsignedFractScale() <= FractWidth);1010 assert(getUnsignedLongFractScale() <= LongFractWidth);1011 1012 // Each unsigned fract type has either the same number of fractional bits1013 // as, or one more fractional bit than, its corresponding signed fract type.1014 assert(getShortFractScale() == getUnsignedShortFractScale() ||1015 getShortFractScale() == getUnsignedShortFractScale() - 1);1016 assert(getFractScale() == getUnsignedFractScale() ||1017 getFractScale() == getUnsignedFractScale() - 1);1018 assert(getLongFractScale() == getUnsignedLongFractScale() ||1019 getLongFractScale() == getUnsignedLongFractScale() - 1);1020 1021 // When arranged in order of increasing rank (see 6.3.1.3a), the number of1022 // fractional bits is nondecreasing for each of the following sets of1023 // fixed-point types:1024 // - signed fract types1025 // - unsigned fract types1026 // - signed accum types1027 // - unsigned accum types.1028 assert(getLongFractScale() >= getFractScale() &&1029 getFractScale() >= getShortFractScale());1030 assert(getUnsignedLongFractScale() >= getUnsignedFractScale() &&1031 getUnsignedFractScale() >= getUnsignedShortFractScale());1032 assert(LongAccumScale >= AccumScale && AccumScale >= ShortAccumScale);1033 assert(getUnsignedLongAccumScale() >= getUnsignedAccumScale() &&1034 getUnsignedAccumScale() >= getUnsignedShortAccumScale());1035 1036 // When arranged in order of increasing rank (see 6.3.1.3a), the number of1037 // integral bits is nondecreasing for each of the following sets of1038 // fixed-point types:1039 // - signed accum types1040 // - unsigned accum types1041 assert(getLongAccumIBits() >= getAccumIBits() &&1042 getAccumIBits() >= getShortAccumIBits());1043 assert(getUnsignedLongAccumIBits() >= getUnsignedAccumIBits() &&1044 getUnsignedAccumIBits() >= getUnsignedShortAccumIBits());1045 1046 // Each signed accum type has at least as many integral bits as its1047 // corresponding unsigned accum type.1048 assert(getShortAccumIBits() >= getUnsignedShortAccumIBits());1049 assert(getAccumIBits() >= getUnsignedAccumIBits());1050 assert(getLongAccumIBits() >= getUnsignedLongAccumIBits());1051}1052 1053void TargetInfo::copyAuxTarget(const TargetInfo *Aux) {1054 auto *Target = static_cast<TransferrableTargetInfo*>(this);1055 auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);1056 *Target = *Src;1057}1058 1059std::string1060TargetInfo::simplifyConstraint(StringRef Constraint,1061 SmallVectorImpl<ConstraintInfo> *OutCons) const {1062 std::string Result;1063 1064 for (const char *I = Constraint.begin(), *E = Constraint.end(); I < E; I++) {1065 switch (*I) {1066 default:1067 Result += convertConstraint(I);1068 break;1069 // Ignore these1070 case '*':1071 case '?':1072 case '!':1073 case '=': // Will see this and the following in mult-alt constraints.1074 case '+':1075 break;1076 case '#': // Ignore the rest of the constraint alternative.1077 while (I + 1 != E && I[1] != ',')1078 I++;1079 break;1080 case '&':1081 case '%':1082 Result += *I;1083 while (I + 1 != E && I[1] == *I)1084 I++;1085 break;1086 case ',':1087 Result += "|";1088 break;1089 case 'g':1090 Result += "imr";1091 break;1092 case '[': {1093 assert(OutCons &&1094 "Must pass output names to constraints with a symbolic name");1095 unsigned Index;1096 bool ResolveResult = resolveSymbolicName(I, *OutCons, Index);1097 assert(ResolveResult && "Could not resolve symbolic name");1098 (void)ResolveResult;1099 Result += llvm::utostr(Index);1100 break;1101 }1102 }1103 }1104 return Result;1105}1106