Path: blob/main/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp
35234 views
//===--- TargetInfo.cpp - Information about Target machine ----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the TargetInfo interface.9//10//===----------------------------------------------------------------------===//1112#include "clang/Basic/TargetInfo.h"13#include "clang/Basic/AddressSpaces.h"14#include "clang/Basic/CharInfo.h"15#include "clang/Basic/Diagnostic.h"16#include "clang/Basic/DiagnosticFrontend.h"17#include "clang/Basic/LangOptions.h"18#include "llvm/ADT/APFloat.h"19#include "llvm/ADT/STLExtras.h"20#include "llvm/Support/ErrorHandling.h"21#include "llvm/TargetParser/TargetParser.h"22#include <cstdlib>23using namespace clang;2425static const LangASMap DefaultAddrSpaceMap = {0};26// The fake address space map must have a distinct entry for each27// language-specific address space.28static const LangASMap FakeAddrSpaceMap = {290, // Default301, // opencl_global313, // opencl_local322, // opencl_constant330, // opencl_private344, // opencl_generic355, // opencl_global_device366, // opencl_global_host377, // cuda_device388, // cuda_constant399, // cuda_shared401, // sycl_global415, // sycl_global_device426, // sycl_global_host433, // sycl_local440, // sycl_private4510, // ptr32_sptr4611, // ptr32_uptr4712, // ptr644813, // hlsl_groupshared4920, // wasm_funcref50};5152// TargetInfo Constructor.53TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {54// Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or55// SPARC. These should be overridden by concrete targets as needed.56BigEndian = !T.isLittleEndian();57TLSSupported = true;58VLASupported = true;59NoAsmVariants = false;60HasLegalHalfType = false;61HalfArgsAndReturns = false;62HasFloat128 = false;63HasIbm128 = false;64HasFloat16 = false;65HasBFloat16 = false;66HasFullBFloat16 = false;67HasLongDouble = true;68HasFPReturn = true;69HasStrictFP = false;70PointerWidth = PointerAlign = 32;71BoolWidth = BoolAlign = 8;72IntWidth = IntAlign = 32;73LongWidth = LongAlign = 32;74LongLongWidth = LongLongAlign = 64;75Int128Align = 128;7677// Fixed point default bit widths78ShortAccumWidth = ShortAccumAlign = 16;79AccumWidth = AccumAlign = 32;80LongAccumWidth = LongAccumAlign = 64;81ShortFractWidth = ShortFractAlign = 8;82FractWidth = FractAlign = 16;83LongFractWidth = LongFractAlign = 32;8485// Fixed point default integral and fractional bit sizes86// We give the _Accum 1 fewer fractional bits than their corresponding _Fract87// types by default to have the same number of fractional bits between _Accum88// and _Fract types.89PaddingOnUnsignedFixedPoint = false;90ShortAccumScale = 7;91AccumScale = 15;92LongAccumScale = 31;9394SuitableAlign = 64;95DefaultAlignForAttributeAligned = 128;96MinGlobalAlign = 0;97// From the glibc documentation, on GNU systems, malloc guarantees 16-byte98// alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See99// https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html.100// This alignment guarantee also applies to Windows and Android. On Darwin101// and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems.102if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() ||103T.isOHOSFamily())104NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;105else if (T.isOSDarwin() || T.isOSOpenBSD())106NewAlign = 128;107else108NewAlign = 0; // Infer from basic type alignment.109HalfWidth = 16;110HalfAlign = 16;111FloatWidth = 32;112FloatAlign = 32;113DoubleWidth = 64;114DoubleAlign = 64;115LongDoubleWidth = 64;116LongDoubleAlign = 64;117Float128Align = 128;118Ibm128Align = 128;119LargeArrayMinWidth = 0;120LargeArrayAlign = 0;121MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;122MaxVectorAlign = 0;123MaxTLSAlign = 0;124SizeType = UnsignedLong;125PtrDiffType = SignedLong;126IntMaxType = SignedLongLong;127IntPtrType = SignedLong;128WCharType = SignedInt;129WIntType = SignedInt;130Char16Type = UnsignedShort;131Char32Type = UnsignedInt;132Int64Type = SignedLongLong;133Int16Type = SignedShort;134SigAtomicType = SignedInt;135ProcessIDType = SignedInt;136UseSignedCharForObjCBool = true;137UseBitFieldTypeAlignment = true;138UseZeroLengthBitfieldAlignment = false;139UseLeadingZeroLengthBitfield = true;140UseExplicitBitFieldAlignment = true;141ZeroLengthBitfieldBoundary = 0;142MaxAlignedAttribute = 0;143HalfFormat = &llvm::APFloat::IEEEhalf();144FloatFormat = &llvm::APFloat::IEEEsingle();145DoubleFormat = &llvm::APFloat::IEEEdouble();146LongDoubleFormat = &llvm::APFloat::IEEEdouble();147Float128Format = &llvm::APFloat::IEEEquad();148Ibm128Format = &llvm::APFloat::PPCDoubleDouble();149MCountName = "mcount";150UserLabelPrefix = "_";151RegParmMax = 0;152SSERegParmMax = 0;153HasAlignMac68kSupport = false;154HasBuiltinMSVaList = false;155IsRenderScriptTarget = false;156HasAArch64SVETypes = false;157HasRISCVVTypes = false;158AllowAMDGPUUnsafeFPAtomics = false;159HasUnalignedAccess = false;160ARMCDECoprocMask = 0;161162// Default to no types using fpret.163RealTypeUsesObjCFPRetMask = 0;164165// Default to not using fp2ret for __Complex long double166ComplexLongDoubleUsesFP2Ret = false;167168// Set the C++ ABI based on the triple.169TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment()170? TargetCXXABI::Microsoft171: TargetCXXABI::GenericItanium);172173// Default to an empty address space map.174AddrSpaceMap = &DefaultAddrSpaceMap;175UseAddrSpaceMapMangling = false;176177// Default to an unknown platform name.178PlatformName = "unknown";179PlatformMinVersion = VersionTuple();180181MaxOpenCLWorkGroupSize = 1024;182183MaxBitIntWidth.reset();184}185186// Out of line virtual dtor for TargetInfo.187TargetInfo::~TargetInfo() {}188189void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) {190DataLayoutString = DL.str();191UserLabelPrefix = ULP;192}193194bool195TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const {196Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";197return false;198}199200bool201TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const {202Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return";203return false;204}205206/// getTypeName - Return the user string for the specified integer type enum.207/// For example, SignedShort -> "short".208const char *TargetInfo::getTypeName(IntType T) {209switch (T) {210default: llvm_unreachable("not an integer!");211case SignedChar: return "signed char";212case UnsignedChar: return "unsigned char";213case SignedShort: return "short";214case UnsignedShort: return "unsigned short";215case SignedInt: return "int";216case UnsignedInt: return "unsigned int";217case SignedLong: return "long int";218case UnsignedLong: return "long unsigned int";219case SignedLongLong: return "long long int";220case UnsignedLongLong: return "long long unsigned int";221}222}223224/// getTypeConstantSuffix - Return the constant suffix for the specified225/// integer type enum. For example, SignedLong -> "L".226const char *TargetInfo::getTypeConstantSuffix(IntType T) const {227switch (T) {228default: llvm_unreachable("not an integer!");229case SignedChar:230case SignedShort:231case SignedInt: return "";232case SignedLong: return "L";233case SignedLongLong: return "LL";234case UnsignedChar:235if (getCharWidth() < getIntWidth())236return "";237[[fallthrough]];238case UnsignedShort:239if (getShortWidth() < getIntWidth())240return "";241[[fallthrough]];242case UnsignedInt: return "U";243case UnsignedLong: return "UL";244case UnsignedLongLong: return "ULL";245}246}247248/// getTypeFormatModifier - Return the printf format modifier for the249/// specified integer type enum. For example, SignedLong -> "l".250251const char *TargetInfo::getTypeFormatModifier(IntType T) {252switch (T) {253default: llvm_unreachable("not an integer!");254case SignedChar:255case UnsignedChar: return "hh";256case SignedShort:257case UnsignedShort: return "h";258case SignedInt:259case UnsignedInt: return "";260case SignedLong:261case UnsignedLong: return "l";262case SignedLongLong:263case UnsignedLongLong: return "ll";264}265}266267/// getTypeWidth - Return the width (in bits) of the specified integer type268/// enum. For example, SignedInt -> getIntWidth().269unsigned TargetInfo::getTypeWidth(IntType T) const {270switch (T) {271default: llvm_unreachable("not an integer!");272case SignedChar:273case UnsignedChar: return getCharWidth();274case SignedShort:275case UnsignedShort: return getShortWidth();276case SignedInt:277case UnsignedInt: return getIntWidth();278case SignedLong:279case UnsignedLong: return getLongWidth();280case SignedLongLong:281case UnsignedLongLong: return getLongLongWidth();282};283}284285TargetInfo::IntType TargetInfo::getIntTypeByWidth(286unsigned BitWidth, bool IsSigned) const {287if (getCharWidth() == BitWidth)288return IsSigned ? SignedChar : UnsignedChar;289if (getShortWidth() == BitWidth)290return IsSigned ? SignedShort : UnsignedShort;291if (getIntWidth() == BitWidth)292return IsSigned ? SignedInt : UnsignedInt;293if (getLongWidth() == BitWidth)294return IsSigned ? SignedLong : UnsignedLong;295if (getLongLongWidth() == BitWidth)296return IsSigned ? SignedLongLong : UnsignedLongLong;297return NoInt;298}299300TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,301bool IsSigned) const {302if (getCharWidth() >= BitWidth)303return IsSigned ? SignedChar : UnsignedChar;304if (getShortWidth() >= BitWidth)305return IsSigned ? SignedShort : UnsignedShort;306if (getIntWidth() >= BitWidth)307return IsSigned ? SignedInt : UnsignedInt;308if (getLongWidth() >= BitWidth)309return IsSigned ? SignedLong : UnsignedLong;310if (getLongLongWidth() >= BitWidth)311return IsSigned ? SignedLongLong : UnsignedLongLong;312return NoInt;313}314315FloatModeKind TargetInfo::getRealTypeByWidth(unsigned BitWidth,316FloatModeKind ExplicitType) const {317if (getHalfWidth() == BitWidth)318return FloatModeKind::Half;319if (getFloatWidth() == BitWidth)320return FloatModeKind::Float;321if (getDoubleWidth() == BitWidth)322return FloatModeKind::Double;323324switch (BitWidth) {325case 96:326if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended())327return FloatModeKind::LongDouble;328break;329case 128:330// The caller explicitly asked for an IEEE compliant type but we still331// have to check if the target supports it.332if (ExplicitType == FloatModeKind::Float128)333return hasFloat128Type() ? FloatModeKind::Float128334: FloatModeKind::NoFloat;335if (ExplicitType == FloatModeKind::Ibm128)336return hasIbm128Type() ? FloatModeKind::Ibm128337: FloatModeKind::NoFloat;338if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() ||339&getLongDoubleFormat() == &llvm::APFloat::IEEEquad())340return FloatModeKind::LongDouble;341if (hasFloat128Type())342return FloatModeKind::Float128;343break;344}345346return FloatModeKind::NoFloat;347}348349/// getTypeAlign - Return the alignment (in bits) of the specified integer type350/// enum. For example, SignedInt -> getIntAlign().351unsigned TargetInfo::getTypeAlign(IntType T) const {352switch (T) {353default: llvm_unreachable("not an integer!");354case SignedChar:355case UnsignedChar: return getCharAlign();356case SignedShort:357case UnsignedShort: return getShortAlign();358case SignedInt:359case UnsignedInt: return getIntAlign();360case SignedLong:361case UnsignedLong: return getLongAlign();362case SignedLongLong:363case UnsignedLongLong: return getLongLongAlign();364};365}366367/// isTypeSigned - Return whether an integer types is signed. Returns true if368/// the type is signed; false otherwise.369bool TargetInfo::isTypeSigned(IntType T) {370switch (T) {371default: llvm_unreachable("not an integer!");372case SignedChar:373case SignedShort:374case SignedInt:375case SignedLong:376case SignedLongLong:377return true;378case UnsignedChar:379case UnsignedShort:380case UnsignedInt:381case UnsignedLong:382case UnsignedLongLong:383return false;384};385}386387/// adjust - Set forced language options.388/// Apply changes to the target information with respect to certain389/// language options which change the target configuration and adjust390/// the language based on the target options where applicable.391void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {392if (Opts.NoBitFieldTypeAlign)393UseBitFieldTypeAlignment = false;394395switch (Opts.WCharSize) {396default: llvm_unreachable("invalid wchar_t width");397case 0: break;398case 1: WCharType = Opts.WCharIsSigned ? SignedChar : UnsignedChar; break;399case 2: WCharType = Opts.WCharIsSigned ? SignedShort : UnsignedShort; break;400case 4: WCharType = Opts.WCharIsSigned ? SignedInt : UnsignedInt; break;401}402403if (Opts.AlignDouble) {404DoubleAlign = LongLongAlign = 64;405LongDoubleAlign = 64;406}407408// HLSL explicitly defines the sizes and formats of some data types, and we409// need to conform to those regardless of what architecture you are targeting.410if (Opts.HLSL) {411LongWidth = LongAlign = 64;412if (!Opts.NativeHalfType) {413HalfFormat = &llvm::APFloat::IEEEsingle();414HalfWidth = HalfAlign = 32;415}416}417418if (Opts.OpenCL) {419// OpenCL C requires specific widths for types, irrespective of420// what these normally are for the target.421// We also define long long and long double here, although the422// OpenCL standard only mentions these as "reserved".423IntWidth = IntAlign = 32;424LongWidth = LongAlign = 64;425LongLongWidth = LongLongAlign = 128;426HalfWidth = HalfAlign = 16;427FloatWidth = FloatAlign = 32;428429// Embedded 32-bit targets (OpenCL EP) might have double C type430// defined as float. Let's not override this as it might lead431// to generating illegal code that uses 64bit doubles.432if (DoubleWidth != FloatWidth) {433DoubleWidth = DoubleAlign = 64;434DoubleFormat = &llvm::APFloat::IEEEdouble();435}436LongDoubleWidth = LongDoubleAlign = 128;437438unsigned MaxPointerWidth = getMaxPointerWidth();439assert(MaxPointerWidth == 32 || MaxPointerWidth == 64);440bool Is32BitArch = MaxPointerWidth == 32;441SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;442PtrDiffType = Is32BitArch ? SignedInt : SignedLong;443IntPtrType = Is32BitArch ? SignedInt : SignedLong;444445IntMaxType = SignedLongLong;446Int64Type = SignedLong;447448HalfFormat = &llvm::APFloat::IEEEhalf();449FloatFormat = &llvm::APFloat::IEEEsingle();450LongDoubleFormat = &llvm::APFloat::IEEEquad();451452// OpenCL C v3.0 s6.7.5 - The generic address space requires support for453// OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space454// feature455// OpenCL C v3.0 s6.2.1 - OpenCL pipes require support of OpenCL C 2.0456// or later and __opencl_c_pipes feature457// FIXME: These language options are also defined in setLangDefaults()458// for OpenCL C 2.0 but with no access to target capabilities. Target459// should be immutable once created and thus these language options need460// to be defined only once.461if (Opts.getOpenCLCompatibleVersion() == 300) {462const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts();463Opts.OpenCLGenericAddressSpace = hasFeatureEnabled(464OpenCLFeaturesMap, "__opencl_c_generic_address_space");465Opts.OpenCLPipes =466hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes");467Opts.Blocks =468hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_device_enqueue");469}470}471472if (Opts.DoubleSize) {473if (Opts.DoubleSize == 32) {474DoubleWidth = 32;475LongDoubleWidth = 32;476DoubleFormat = &llvm::APFloat::IEEEsingle();477LongDoubleFormat = &llvm::APFloat::IEEEsingle();478} else if (Opts.DoubleSize == 64) {479DoubleWidth = 64;480LongDoubleWidth = 64;481DoubleFormat = &llvm::APFloat::IEEEdouble();482LongDoubleFormat = &llvm::APFloat::IEEEdouble();483}484}485486if (Opts.LongDoubleSize) {487if (Opts.LongDoubleSize == DoubleWidth) {488LongDoubleWidth = DoubleWidth;489LongDoubleAlign = DoubleAlign;490LongDoubleFormat = DoubleFormat;491} else if (Opts.LongDoubleSize == 128) {492LongDoubleWidth = LongDoubleAlign = 128;493LongDoubleFormat = &llvm::APFloat::IEEEquad();494} else if (Opts.LongDoubleSize == 80) {495LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();496if (getTriple().isWindowsMSVCEnvironment()) {497LongDoubleWidth = 128;498LongDoubleAlign = 128;499} else { // Linux500if (getTriple().getArch() == llvm::Triple::x86) {501LongDoubleWidth = 96;502LongDoubleAlign = 32;503} else {504LongDoubleWidth = 128;505LongDoubleAlign = 128;506}507}508}509}510511if (Opts.NewAlignOverride)512NewAlign = Opts.NewAlignOverride * getCharWidth();513514// Each unsigned fixed point type has the same number of fractional bits as515// its corresponding signed type.516PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint;517CheckFixedPointBits();518519if (Opts.ProtectParens && !checkArithmeticFenceSupported()) {520Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens";521Opts.ProtectParens = false;522}523524if (Opts.MaxBitIntWidth)525MaxBitIntWidth = static_cast<unsigned>(Opts.MaxBitIntWidth);526527if (Opts.FakeAddressSpaceMap)528AddrSpaceMap = &FakeAddrSpaceMap;529}530531bool TargetInfo::initFeatureMap(532llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,533const std::vector<std::string> &FeatureVec) const {534for (const auto &F : FeatureVec) {535StringRef Name = F;536if (Name.empty())537continue;538// Apply the feature via the target.539if (Name[0] != '+' && Name[0] != '-')540Diags.Report(diag::warn_fe_backend_invalid_feature_flag) << Name;541else542setFeatureEnabled(Features, Name.substr(1), Name[0] == '+');543}544return true;545}546547ParsedTargetAttr TargetInfo::parseTargetAttr(StringRef Features) const {548ParsedTargetAttr Ret;549if (Features == "default")550return Ret;551SmallVector<StringRef, 1> AttrFeatures;552Features.split(AttrFeatures, ",");553554// Grab the various features and prepend a "+" to turn on the feature to555// the backend and add them to our existing set of features.556for (auto &Feature : AttrFeatures) {557// Go ahead and trim whitespace rather than either erroring or558// accepting it weirdly.559Feature = Feature.trim();560561// TODO: Support the fpmath option. It will require checking562// overall feature validity for the function with the rest of the563// attributes on the function.564if (Feature.starts_with("fpmath="))565continue;566567if (Feature.starts_with("branch-protection=")) {568Ret.BranchProtection = Feature.split('=').second.trim();569continue;570}571572// While we're here iterating check for a different target cpu.573if (Feature.starts_with("arch=")) {574if (!Ret.CPU.empty())575Ret.Duplicate = "arch=";576else577Ret.CPU = Feature.split("=").second.trim();578} else if (Feature.starts_with("tune=")) {579if (!Ret.Tune.empty())580Ret.Duplicate = "tune=";581else582Ret.Tune = Feature.split("=").second.trim();583} else if (Feature.starts_with("no-"))584Ret.Features.push_back("-" + Feature.split("-").second.str());585else586Ret.Features.push_back("+" + Feature.str());587}588return Ret;589}590591TargetInfo::CallingConvKind592TargetInfo::getCallingConvKind(bool ClangABICompat4) const {593if (getCXXABI() != TargetCXXABI::Microsoft &&594(ClangABICompat4 || getTriple().isPS4()))595return CCK_ClangABI4OrPS4;596return CCK_Default;597}598599bool TargetInfo::areDefaultedSMFStillPOD(const LangOptions &LangOpts) const {600return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15;601}602603LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const {604switch (TK) {605case OCLTK_Image:606case OCLTK_Pipe:607return LangAS::opencl_global;608609case OCLTK_Sampler:610return LangAS::opencl_constant;611612default:613return LangAS::Default;614}615}616617//===----------------------------------------------------------------------===//618619620static StringRef removeGCCRegisterPrefix(StringRef Name) {621if (Name[0] == '%' || Name[0] == '#')622Name = Name.substr(1);623624return Name;625}626627/// isValidClobber - Returns whether the passed in string is628/// a valid clobber in an inline asm statement. This is used by629/// Sema.630bool TargetInfo::isValidClobber(StringRef Name) const {631return (isValidGCCRegisterName(Name) || Name == "memory" || Name == "cc" ||632Name == "unwind");633}634635/// isValidGCCRegisterName - Returns whether the passed in string636/// is a valid register name according to GCC. This is used by Sema for637/// inline asm statements.638bool TargetInfo::isValidGCCRegisterName(StringRef Name) const {639if (Name.empty())640return false;641642// Get rid of any register prefix.643Name = removeGCCRegisterPrefix(Name);644if (Name.empty())645return false;646647ArrayRef<const char *> Names = getGCCRegNames();648649// If we have a number it maps to an entry in the register name array.650if (isDigit(Name[0])) {651unsigned n;652if (!Name.getAsInteger(0, n))653return n < Names.size();654}655656// Check register names.657if (llvm::is_contained(Names, Name))658return true;659660// Check any additional names that we have.661for (const AddlRegName &ARN : getGCCAddlRegNames())662for (const char *AN : ARN.Names) {663if (!AN)664break;665// Make sure the register that the additional name is for is within666// the bounds of the register names from above.667if (AN == Name && ARN.RegNum < Names.size())668return true;669}670671// Now check aliases.672for (const GCCRegAlias &GRA : getGCCRegAliases())673for (const char *A : GRA.Aliases) {674if (!A)675break;676if (A == Name)677return true;678}679680return false;681}682683StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name,684bool ReturnCanonical) const {685assert(isValidGCCRegisterName(Name) && "Invalid register passed in");686687// Get rid of any register prefix.688Name = removeGCCRegisterPrefix(Name);689690ArrayRef<const char *> Names = getGCCRegNames();691692// First, check if we have a number.693if (isDigit(Name[0])) {694unsigned n;695if (!Name.getAsInteger(0, n)) {696assert(n < Names.size() && "Out of bounds register number!");697return Names[n];698}699}700701// Check any additional names that we have.702for (const AddlRegName &ARN : getGCCAddlRegNames())703for (const char *AN : ARN.Names) {704if (!AN)705break;706// Make sure the register that the additional name is for is within707// the bounds of the register names from above.708if (AN == Name && ARN.RegNum < Names.size())709return ReturnCanonical ? Names[ARN.RegNum] : Name;710}711712// Now check aliases.713for (const GCCRegAlias &RA : getGCCRegAliases())714for (const char *A : RA.Aliases) {715if (!A)716break;717if (A == Name)718return RA.Register;719}720721return Name;722}723724bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {725const char *Name = Info.getConstraintStr().c_str();726// An output constraint must start with '=' or '+'727if (*Name != '=' && *Name != '+')728return false;729730if (*Name == '+')731Info.setIsReadWrite();732733Name++;734while (*Name) {735switch (*Name) {736default:737if (!validateAsmConstraint(Name, Info)) {738// FIXME: We temporarily return false739// so we can add more constraints as we hit it.740// Eventually, an unknown constraint should just be treated as 'g'.741return false;742}743break;744case '&': // early clobber.745Info.setEarlyClobber();746break;747case '%': // commutative.748// FIXME: Check that there is a another register after this one.749break;750case 'r': // general register.751Info.setAllowsRegister();752break;753case 'm': // memory operand.754case 'o': // offsetable memory operand.755case 'V': // non-offsetable memory operand.756case '<': // autodecrement memory operand.757case '>': // autoincrement memory operand.758Info.setAllowsMemory();759break;760case 'g': // general register, memory operand or immediate integer.761case 'X': // any operand.762Info.setAllowsRegister();763Info.setAllowsMemory();764break;765case ',': // multiple alternative constraint. Pass it.766// Handle additional optional '=' or '+' modifiers.767if (Name[1] == '=' || Name[1] == '+')768Name++;769break;770case '#': // Ignore as constraint.771while (Name[1] && Name[1] != ',')772Name++;773break;774case '?': // Disparage slightly code.775case '!': // Disparage severely.776case '*': // Ignore for choosing register preferences.777case 'i': // Ignore i,n,E,F as output constraints (match from the other778// chars)779case 'n':780case 'E':781case 'F':782break; // Pass them.783}784785Name++;786}787788// Early clobber with a read-write constraint which doesn't permit registers789// is invalid.790if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister())791return false;792793// If a constraint allows neither memory nor register operands it contains794// only modifiers. Reject it.795return Info.allowsMemory() || Info.allowsRegister();796}797798bool TargetInfo::resolveSymbolicName(const char *&Name,799ArrayRef<ConstraintInfo> OutputConstraints,800unsigned &Index) const {801assert(*Name == '[' && "Symbolic name did not start with '['");802Name++;803const char *Start = Name;804while (*Name && *Name != ']')805Name++;806807if (!*Name) {808// Missing ']'809return false;810}811812std::string SymbolicName(Start, Name - Start);813814for (Index = 0; Index != OutputConstraints.size(); ++Index)815if (SymbolicName == OutputConstraints[Index].getName())816return true;817818return false;819}820821bool TargetInfo::validateInputConstraint(822MutableArrayRef<ConstraintInfo> OutputConstraints,823ConstraintInfo &Info) const {824const char *Name = Info.ConstraintStr.c_str();825826if (!*Name)827return false;828829while (*Name) {830switch (*Name) {831default:832// Check if we have a matching constraint833if (*Name >= '0' && *Name <= '9') {834const char *DigitStart = Name;835while (Name[1] >= '0' && Name[1] <= '9')836Name++;837const char *DigitEnd = Name;838unsigned i;839if (StringRef(DigitStart, DigitEnd - DigitStart + 1)840.getAsInteger(10, i))841return false;842843// Check if matching constraint is out of bounds.844if (i >= OutputConstraints.size()) return false;845846// A number must refer to an output only operand.847if (OutputConstraints[i].isReadWrite())848return false;849850// If the constraint is already tied, it must be tied to the851// same operand referenced to by the number.852if (Info.hasTiedOperand() && Info.getTiedOperand() != i)853return false;854855// The constraint should have the same info as the respective856// output constraint.857Info.setTiedOperand(i, OutputConstraints[i]);858} else if (!validateAsmConstraint(Name, Info)) {859// FIXME: This error return is in place temporarily so we can860// add more constraints as we hit it. Eventually, an unknown861// constraint should just be treated as 'g'.862return false;863}864break;865case '[': {866unsigned Index = 0;867if (!resolveSymbolicName(Name, OutputConstraints, Index))868return false;869870// If the constraint is already tied, it must be tied to the871// same operand referenced to by the number.872if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)873return false;874875// A number must refer to an output only operand.876if (OutputConstraints[Index].isReadWrite())877return false;878879Info.setTiedOperand(Index, OutputConstraints[Index]);880break;881}882case '%': // commutative883// FIXME: Fail if % is used with the last operand.884break;885case 'i': // immediate integer.886break;887case 'n': // immediate integer with a known value.888Info.setRequiresImmediate();889break;890case 'I': // Various constant constraints with target-specific meanings.891case 'J':892case 'K':893case 'L':894case 'M':895case 'N':896case 'O':897case 'P':898if (!validateAsmConstraint(Name, Info))899return false;900break;901case 'r': // general register.902Info.setAllowsRegister();903break;904case 'm': // memory operand.905case 'o': // offsettable memory operand.906case 'V': // non-offsettable memory operand.907case '<': // autodecrement memory operand.908case '>': // autoincrement memory operand.909Info.setAllowsMemory();910break;911case 'g': // general register, memory operand or immediate integer.912case 'X': // any operand.913Info.setAllowsRegister();914Info.setAllowsMemory();915break;916case 'E': // immediate floating point.917case 'F': // immediate floating point.918case 'p': // address operand.919break;920case ',': // multiple alternative constraint. Ignore comma.921break;922case '#': // Ignore as constraint.923while (Name[1] && Name[1] != ',')924Name++;925break;926case '?': // Disparage slightly code.927case '!': // Disparage severely.928case '*': // Ignore for choosing register preferences.929break; // Pass them.930}931932Name++;933}934935return true;936}937938bool TargetInfo::validatePointerAuthKey(const llvm::APSInt &value) const {939return false;940}941942void TargetInfo::CheckFixedPointBits() const {943// Check that the number of fractional and integral bits (and maybe sign) can944// fit into the bits given for a fixed point type.945assert(ShortAccumScale + getShortAccumIBits() + 1 <= ShortAccumWidth);946assert(AccumScale + getAccumIBits() + 1 <= AccumWidth);947assert(LongAccumScale + getLongAccumIBits() + 1 <= LongAccumWidth);948assert(getUnsignedShortAccumScale() + getUnsignedShortAccumIBits() <=949ShortAccumWidth);950assert(getUnsignedAccumScale() + getUnsignedAccumIBits() <= AccumWidth);951assert(getUnsignedLongAccumScale() + getUnsignedLongAccumIBits() <=952LongAccumWidth);953954assert(getShortFractScale() + 1 <= ShortFractWidth);955assert(getFractScale() + 1 <= FractWidth);956assert(getLongFractScale() + 1 <= LongFractWidth);957assert(getUnsignedShortFractScale() <= ShortFractWidth);958assert(getUnsignedFractScale() <= FractWidth);959assert(getUnsignedLongFractScale() <= LongFractWidth);960961// Each unsigned fract type has either the same number of fractional bits962// as, or one more fractional bit than, its corresponding signed fract type.963assert(getShortFractScale() == getUnsignedShortFractScale() ||964getShortFractScale() == getUnsignedShortFractScale() - 1);965assert(getFractScale() == getUnsignedFractScale() ||966getFractScale() == getUnsignedFractScale() - 1);967assert(getLongFractScale() == getUnsignedLongFractScale() ||968getLongFractScale() == getUnsignedLongFractScale() - 1);969970// When arranged in order of increasing rank (see 6.3.1.3a), the number of971// fractional bits is nondecreasing for each of the following sets of972// fixed-point types:973// - signed fract types974// - unsigned fract types975// - signed accum types976// - unsigned accum types.977assert(getLongFractScale() >= getFractScale() &&978getFractScale() >= getShortFractScale());979assert(getUnsignedLongFractScale() >= getUnsignedFractScale() &&980getUnsignedFractScale() >= getUnsignedShortFractScale());981assert(LongAccumScale >= AccumScale && AccumScale >= ShortAccumScale);982assert(getUnsignedLongAccumScale() >= getUnsignedAccumScale() &&983getUnsignedAccumScale() >= getUnsignedShortAccumScale());984985// When arranged in order of increasing rank (see 6.3.1.3a), the number of986// integral bits is nondecreasing for each of the following sets of987// fixed-point types:988// - signed accum types989// - unsigned accum types990assert(getLongAccumIBits() >= getAccumIBits() &&991getAccumIBits() >= getShortAccumIBits());992assert(getUnsignedLongAccumIBits() >= getUnsignedAccumIBits() &&993getUnsignedAccumIBits() >= getUnsignedShortAccumIBits());994995// Each signed accum type has at least as many integral bits as its996// corresponding unsigned accum type.997assert(getShortAccumIBits() >= getUnsignedShortAccumIBits());998assert(getAccumIBits() >= getUnsignedAccumIBits());999assert(getLongAccumIBits() >= getUnsignedLongAccumIBits());1000}10011002void TargetInfo::copyAuxTarget(const TargetInfo *Aux) {1003auto *Target = static_cast<TransferrableTargetInfo*>(this);1004auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);1005*Target = *Src;1006}100710081009