brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.8 KiB · c0ed900 Raw
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