//===--- TargetInfo.cpp - Information about Target machine ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file implements the TargetInfo and TargetInfoImpl interfaces.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetParser.h"
#include <cstdlib>
using namespace clang;

static const LangASMap DefaultAddrSpaceMap = {0};

// TargetInfo Constructor.
TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
  // Set defaults.  Defaults are set for a 32-bit RISC platform, like PPC or
  // SPARC.  These should be overridden by concrete targets as needed.
  BigEndian = !T.isLittleEndian();
  TLSSupported = true;
  VLASupported = true;
  NoAsmVariants = false;
  HasLegalHalfType = false;
  HasFloat128 = false;
  HasFloat16 = false;
  PointerWidth = PointerAlign = 32;
  BoolWidth = BoolAlign = 8;
  IntWidth = IntAlign = 32;
  LongWidth = LongAlign = 32;
  LongLongWidth = LongLongAlign = 64;

  // Fixed point default bit widths
  ShortAccumWidth = ShortAccumAlign = 16;
  AccumWidth = AccumAlign = 32;
  LongAccumWidth = LongAccumAlign = 64;
  ShortFractWidth = ShortFractAlign = 8;
  FractWidth = FractAlign = 16;
  LongFractWidth = LongFractAlign = 32;

  // Fixed point default integral and fractional bit sizes
  // We give the _Accum 1 fewer fractional bits than their corresponding _Fract
  // types by default to have the same number of fractional bits between _Accum
  // and _Fract types.
  PaddingOnUnsignedFixedPoint = false;
  ShortAccumScale = 7;
  AccumScale = 15;
  LongAccumScale = 31;

  SuitableAlign = 64;
  DefaultAlignForAttributeAligned = 128;
  MinGlobalAlign = 0;
  // From the glibc documentation, on GNU systems, malloc guarantees 16-byte
  // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See
  // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html.
  // This alignment guarantee also applies to Windows and Android.
  if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid())
    NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;
  else
    NewAlign = 0; // Infer from basic type alignment.
  HalfWidth = 16;
  HalfAlign = 16;
  FloatWidth = 32;
  FloatAlign = 32;
  DoubleWidth = 64;
  DoubleAlign = 64;
  LongDoubleWidth = 64;
  LongDoubleAlign = 64;
  Float128Align = 128;
  LargeArrayMinWidth = 0;
  LargeArrayAlign = 0;
  MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
  MaxVectorAlign = 0;
  MaxTLSAlign = 0;
  SimdDefaultAlign = 0;
  SizeType = UnsignedLong;
  PtrDiffType = SignedLong;
  IntMaxType = SignedLongLong;
  IntPtrType = SignedLong;
  WCharType = SignedInt;
  WIntType = SignedInt;
  Char16Type = UnsignedShort;
  Char32Type = UnsignedInt;
  Int64Type = SignedLongLong;
  SigAtomicType = SignedInt;
  ProcessIDType = SignedInt;
  UseSignedCharForObjCBool = true;
  UseBitFieldTypeAlignment = true;
  UseZeroLengthBitfieldAlignment = false;
  UseExplicitBitFieldAlignment = true;
  ZeroLengthBitfieldBoundary = 0;
  HalfFormat = &llvm::APFloat::IEEEhalf();
  FloatFormat = &llvm::APFloat::IEEEsingle();
  DoubleFormat = &llvm::APFloat::IEEEdouble();
  LongDoubleFormat = &llvm::APFloat::IEEEdouble();
  Float128Format = &llvm::APFloat::IEEEquad();
  MCountName = "mcount";
  RegParmMax = 0;
  SSERegParmMax = 0;
  HasAlignMac68kSupport = false;
  HasBuiltinMSVaList = false;
  IsRenderScriptTarget = false;
  HasAArch64SVETypes = false;

  // Default to no types using fpret.
  RealTypeUsesObjCFPRet = 0;

  // Default to not using fp2ret for __Complex long double
  ComplexLongDoubleUsesFP2Ret = false;

  // Set the C++ ABI based on the triple.
  TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment()
                    ? TargetCXXABI::Microsoft
                    : TargetCXXABI::GenericItanium);

  // Default to an empty address space map.
  AddrSpaceMap = &DefaultAddrSpaceMap;
  UseAddrSpaceMapMangling = false;

  // Default to an unknown platform name.
  PlatformName = "unknown";
  PlatformMinVersion = VersionTuple();
}

// Out of line virtual dtor for TargetInfo.
TargetInfo::~TargetInfo() {}

void TargetInfo::resetDataLayout(StringRef DL) {
  DataLayout.reset(new llvm::DataLayout(DL));
}

bool
TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const {
  Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";
  return false;
}

bool
TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const {
  Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return";
  return false;
}

/// getTypeName - Return the user string for the specified integer type enum.
/// For example, SignedShort -> "short".
const char *TargetInfo::getTypeName(IntType T) {
  switch (T) {
  default: llvm_unreachable("not an integer!");
  case SignedChar:       return "signed char";
  case UnsignedChar:     return "unsigned char";
  case SignedShort:      return "short";
  case UnsignedShort:    return "unsigned short";
  case SignedInt:        return "int";
  case UnsignedInt:      return "unsigned int";
  case SignedLong:       return "long int";
  case UnsignedLong:     return "long unsigned int";
  case SignedLongLong:   return "long long int";
  case UnsignedLongLong: return "long long unsigned int";
  }
}

/// getTypeConstantSuffix - Return the constant suffix for the specified
/// integer type enum. For example, SignedLong -> "L".
const char *TargetInfo::getTypeConstantSuffix(IntType T) const {
  switch (T) {
  default: llvm_unreachable("not an integer!");
  case SignedChar:
  case SignedShort:
  case SignedInt:        return "";
  case SignedLong:       return "L";
  case SignedLongLong:   return "LL";
  case UnsignedChar:
    if (getCharWidth() < getIntWidth())
      return "";
    LLVM_FALLTHROUGH;
  case UnsignedShort:
    if (getShortWidth() < getIntWidth())
      return "";
    LLVM_FALLTHROUGH;
  case UnsignedInt:      return "U";
  case UnsignedLong:     return "UL";
  case UnsignedLongLong: return "ULL";
  }
}

/// getTypeFormatModifier - Return the printf format modifier for the
/// specified integer type enum. For example, SignedLong -> "l".

const char *TargetInfo::getTypeFormatModifier(IntType T) {
  switch (T) {
  default: llvm_unreachable("not an integer!");
  case SignedChar:
  case UnsignedChar:     return "hh";
  case SignedShort:
  case UnsignedShort:    return "h";
  case SignedInt:
  case UnsignedInt:      return "";
  case SignedLong:
  case UnsignedLong:     return "l";
  case SignedLongLong:
  case UnsignedLongLong: return "ll";
  }
}

/// getTypeWidth - Return the width (in bits) of the specified integer type
/// enum. For example, SignedInt -> getIntWidth().
unsigned TargetInfo::getTypeWidth(IntType T) const {
  switch (T) {
  default: llvm_unreachable("not an integer!");
  case SignedChar:
  case UnsignedChar:     return getCharWidth();
  case SignedShort:
  case UnsignedShort:    return getShortWidth();
  case SignedInt:
  case UnsignedInt:      return getIntWidth();
  case SignedLong:
  case UnsignedLong:     return getLongWidth();
  case SignedLongLong:
  case UnsignedLongLong: return getLongLongWidth();
  };
}

TargetInfo::IntType TargetInfo::getIntTypeByWidth(
    unsigned BitWidth, bool IsSigned) const {
  if (getCharWidth() == BitWidth)
    return IsSigned ? SignedChar : UnsignedChar;
  if (getShortWidth() == BitWidth)
    return IsSigned ? SignedShort : UnsignedShort;
  if (getIntWidth() == BitWidth)
    return IsSigned ? SignedInt : UnsignedInt;
  if (getLongWidth() == BitWidth)
    return IsSigned ? SignedLong : UnsignedLong;
  if (getLongLongWidth() == BitWidth)
    return IsSigned ? SignedLongLong : UnsignedLongLong;
  return NoInt;
}

TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,
                                                       bool IsSigned) const {
  if (getCharWidth() >= BitWidth)
    return IsSigned ? SignedChar : UnsignedChar;
  if (getShortWidth() >= BitWidth)
    return IsSigned ? SignedShort : UnsignedShort;
  if (getIntWidth() >= BitWidth)
    return IsSigned ? SignedInt : UnsignedInt;
  if (getLongWidth() >= BitWidth)
    return IsSigned ? SignedLong : UnsignedLong;
  if (getLongLongWidth() >= BitWidth)
    return IsSigned ? SignedLongLong : UnsignedLongLong;
  return NoInt;
}

TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const {
  if (getFloatWidth() == BitWidth)
    return Float;
  if (getDoubleWidth() == BitWidth)
    return Double;

  switch (BitWidth) {
  case 96:
    if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended())
      return LongDouble;
    break;
  case 128:
    if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() ||
        &getLongDoubleFormat() == &llvm::APFloat::IEEEquad())
      return LongDouble;
    if (hasFloat128Type())
      return Float128;
    break;
  }

  return NoFloat;
}

/// getTypeAlign - Return the alignment (in bits) of the specified integer type
/// enum. For example, SignedInt -> getIntAlign().
unsigned TargetInfo::getTypeAlign(IntType T) const {
  switch (T) {
  default: llvm_unreachable("not an integer!");
  case SignedChar:
  case UnsignedChar:     return getCharAlign();
  case SignedShort:
  case UnsignedShort:    return getShortAlign();
  case SignedInt:
  case UnsignedInt:      return getIntAlign();
  case SignedLong:
  case UnsignedLong:     return getLongAlign();
  case SignedLongLong:
  case UnsignedLongLong: return getLongLongAlign();
  };
}

/// isTypeSigned - Return whether an integer types is signed. Returns true if
/// the type is signed; false otherwise.
bool TargetInfo::isTypeSigned(IntType T) {
  switch (T) {
  default: llvm_unreachable("not an integer!");
  case SignedChar:
  case SignedShort:
  case SignedInt:
  case SignedLong:
  case SignedLongLong:
    return true;
  case UnsignedChar:
  case UnsignedShort:
  case UnsignedInt:
  case UnsignedLong:
  case UnsignedLongLong:
    return false;
  };
}

/// adjust - Set forced language options.
/// Apply changes to the target information with respect to certain
/// language options which change the target configuration and adjust
/// the language based on the target options where applicable.
void TargetInfo::adjust(LangOptions &Opts) {
  if (Opts.NoBitFieldTypeAlign)
    UseBitFieldTypeAlignment = false;

  switch (Opts.WCharSize) {
  default: llvm_unreachable("invalid wchar_t width");
  case 0: break;
  case 1: WCharType = Opts.WCharIsSigned ? SignedChar : UnsignedChar; break;
  case 2: WCharType = Opts.WCharIsSigned ? SignedShort : UnsignedShort; break;
  case 4: WCharType = Opts.WCharIsSigned ? SignedInt : UnsignedInt; break;
  }

  if (Opts.AlignDouble) {
    DoubleAlign = LongLongAlign = 64;
    LongDoubleAlign = 64;
  }

  if (Opts.OpenCL) {
    // OpenCL C requires specific widths for types, irrespective of
    // what these normally are for the target.
    // We also define long long and long double here, although the
    // OpenCL standard only mentions these as "reserved".
    IntWidth = IntAlign = 32;
    LongWidth = LongAlign = 64;
    LongLongWidth = LongLongAlign = 128;
    HalfWidth = HalfAlign = 16;
    FloatWidth = FloatAlign = 32;

    // Embedded 32-bit targets (OpenCL EP) might have double C type
    // defined as float. Let's not override this as it might lead
    // to generating illegal code that uses 64bit doubles.
    if (DoubleWidth != FloatWidth) {
      DoubleWidth = DoubleAlign = 64;
      DoubleFormat = &llvm::APFloat::IEEEdouble();
    }
    LongDoubleWidth = LongDoubleAlign = 128;

    unsigned MaxPointerWidth = getMaxPointerWidth();
    assert(MaxPointerWidth == 32 || MaxPointerWidth == 64);
    bool Is32BitArch = MaxPointerWidth == 32;
    SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;
    PtrDiffType = Is32BitArch ? SignedInt : SignedLong;
    IntPtrType = Is32BitArch ? SignedInt : SignedLong;

    IntMaxType = SignedLongLong;
    Int64Type = SignedLong;

    HalfFormat = &llvm::APFloat::IEEEhalf();
    FloatFormat = &llvm::APFloat::IEEEsingle();
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
  }

  if (Opts.LongDoubleSize) {
    if (Opts.LongDoubleSize == DoubleWidth) {
      LongDoubleWidth = DoubleWidth;
      LongDoubleAlign = DoubleAlign;
      LongDoubleFormat = DoubleFormat;
    } else if (Opts.LongDoubleSize == 128) {
      LongDoubleWidth = LongDoubleAlign = 128;
      LongDoubleFormat = &llvm::APFloat::IEEEquad();
    }
  }

  if (Opts.NewAlignOverride)
    NewAlign = Opts.NewAlignOverride * getCharWidth();

  // Each unsigned fixed point type has the same number of fractional bits as
  // its corresponding signed type.
  PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint;
  CheckFixedPointBits();
}

bool TargetInfo::initFeatureMap(
    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
    const std::vector<std::string> &FeatureVec) const {
  for (const auto &F : FeatureVec) {
    StringRef Name = F;
    // Apply the feature via the target.
    bool Enabled = Name[0] == '+';
    setFeatureEnabled(Features, Name.substr(1), Enabled);
  }
  return true;
}

TargetInfo::CallingConvKind
TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
  if (getCXXABI() != TargetCXXABI::Microsoft &&
      (ClangABICompat4 || getTriple().getOS() == llvm::Triple::PS4))
    return CCK_ClangABI4OrPS4;
  return CCK_Default;
}

LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const {
  switch (TK) {
  case OCLTK_Image:
  case OCLTK_Pipe:
    return LangAS::opencl_global;

  case OCLTK_Sampler:
    return LangAS::opencl_constant;

  default:
    return LangAS::Default;
  }
}

//===----------------------------------------------------------------------===//


static StringRef removeGCCRegisterPrefix(StringRef Name) {
  if (Name[0] == '%' || Name[0] == '#')
    Name = Name.substr(1);

  return Name;
}

/// isValidClobber - Returns whether the passed in string is
/// a valid clobber in an inline asm statement. This is used by
/// Sema.
bool TargetInfo::isValidClobber(StringRef Name) const {
  return (isValidGCCRegisterName(Name) ||
          Name == "memory" || Name == "cc");
}

/// isValidGCCRegisterName - Returns whether the passed in string
/// is a valid register name according to GCC. This is used by Sema for
/// inline asm statements.
bool TargetInfo::isValidGCCRegisterName(StringRef Name) const {
  if (Name.empty())
    return false;

  // Get rid of any register prefix.
  Name = removeGCCRegisterPrefix(Name);
  if (Name.empty())
    return false;

  ArrayRef<const char *> Names = getGCCRegNames();

  // If we have a number it maps to an entry in the register name array.
  if (isDigit(Name[0])) {
    unsigned n;
    if (!Name.getAsInteger(0, n))
      return n < Names.size();
  }

  // Check register names.
  if (llvm::is_contained(Names, Name))
    return true;

  // Check any additional names that we have.
  for (const AddlRegName &ARN : getGCCAddlRegNames())
    for (const char *AN : ARN.Names) {
      if (!AN)
        break;
      // Make sure the register that the additional name is for is within
      // the bounds of the register names from above.
      if (AN == Name && ARN.RegNum < Names.size())
        return true;
    }

  // Now check aliases.
  for (const GCCRegAlias &GRA : getGCCRegAliases())
    for (const char *A : GRA.Aliases) {
      if (!A)
        break;
      if (A == Name)
        return true;
    }

  return false;
}

StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name,
                                                   bool ReturnCanonical) const {
  assert(isValidGCCRegisterName(Name) && "Invalid register passed in");

  // Get rid of any register prefix.
  Name = removeGCCRegisterPrefix(Name);

  ArrayRef<const char *> Names = getGCCRegNames();

  // First, check if we have a number.
  if (isDigit(Name[0])) {
    unsigned n;
    if (!Name.getAsInteger(0, n)) {
      assert(n < Names.size() && "Out of bounds register number!");
      return Names[n];
    }
  }

  // Check any additional names that we have.
  for (const AddlRegName &ARN : getGCCAddlRegNames())
    for (const char *AN : ARN.Names) {
      if (!AN)
        break;
      // Make sure the register that the additional name is for is within
      // the bounds of the register names from above.
      if (AN == Name && ARN.RegNum < Names.size())
        return ReturnCanonical ? Names[ARN.RegNum] : Name;
    }

  // Now check aliases.
  for (const GCCRegAlias &RA : getGCCRegAliases())
    for (const char *A : RA.Aliases) {
      if (!A)
        break;
      if (A == Name)
        return RA.Register;
    }

  return Name;
}

bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
  const char *Name = Info.getConstraintStr().c_str();
  // An output constraint must start with '=' or '+'
  if (*Name != '=' && *Name != '+')
    return false;

  if (*Name == '+')
    Info.setIsReadWrite();

  Name++;
  while (*Name) {
    switch (*Name) {
    default:
      if (!validateAsmConstraint(Name, Info)) {
        // FIXME: We temporarily return false
        // so we can add more constraints as we hit it.
        // Eventually, an unknown constraint should just be treated as 'g'.
        return false;
      }
      break;
    case '&': // early clobber.
      Info.setEarlyClobber();
      break;
    case '%': // commutative.
      // FIXME: Check that there is a another register after this one.
      break;
    case 'r': // general register.
      Info.setAllowsRegister();
      break;
    case 'm': // memory operand.
    case 'o': // offsetable memory operand.
    case 'V': // non-offsetable memory operand.
    case '<': // autodecrement memory operand.
    case '>': // autoincrement memory operand.
      Info.setAllowsMemory();
      break;
    case 'g': // general register, memory operand or immediate integer.
    case 'X': // any operand.
      Info.setAllowsRegister();
      Info.setAllowsMemory();
      break;
    case ',': // multiple alternative constraint.  Pass it.
      // Handle additional optional '=' or '+' modifiers.
      if (Name[1] == '=' || Name[1] == '+')
        Name++;
      break;
    case '#': // Ignore as constraint.
      while (Name[1] && Name[1] != ',')
        Name++;
      break;
    case '?': // Disparage slightly code.
    case '!': // Disparage severely.
    case '*': // Ignore for choosing register preferences.
    case 'i': // Ignore i,n,E,F as output constraints (match from the other
              // chars)
    case 'n':
    case 'E':
    case 'F':
      break;  // Pass them.
    }

    Name++;
  }

  // Early clobber with a read-write constraint which doesn't permit registers
  // is invalid.
  if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister())
    return false;

  // If a constraint allows neither memory nor register operands it contains
  // only modifiers. Reject it.
  return Info.allowsMemory() || Info.allowsRegister();
}

bool TargetInfo::resolveSymbolicName(const char *&Name,
                                     ArrayRef<ConstraintInfo> OutputConstraints,
                                     unsigned &Index) const {
  assert(*Name == '[' && "Symbolic name did not start with '['");
  Name++;
  const char *Start = Name;
  while (*Name && *Name != ']')
    Name++;

  if (!*Name) {
    // Missing ']'
    return false;
  }

  std::string SymbolicName(Start, Name - Start);

  for (Index = 0; Index != OutputConstraints.size(); ++Index)
    if (SymbolicName == OutputConstraints[Index].getName())
      return true;

  return false;
}

bool TargetInfo::validateInputConstraint(
                              MutableArrayRef<ConstraintInfo> OutputConstraints,
                              ConstraintInfo &Info) const {
  const char *Name = Info.ConstraintStr.c_str();

  if (!*Name)
    return false;

  while (*Name) {
    switch (*Name) {
    default:
      // Check if we have a matching constraint
      if (*Name >= '0' && *Name <= '9') {
        const char *DigitStart = Name;
        while (Name[1] >= '0' && Name[1] <= '9')
          Name++;
        const char *DigitEnd = Name;
        unsigned i;
        if (StringRef(DigitStart, DigitEnd - DigitStart + 1)
                .getAsInteger(10, i))
          return false;

        // Check if matching constraint is out of bounds.
        if (i >= OutputConstraints.size()) return false;

        // A number must refer to an output only operand.
        if (OutputConstraints[i].isReadWrite())
          return false;

        // If the constraint is already tied, it must be tied to the
        // same operand referenced to by the number.
        if (Info.hasTiedOperand() && Info.getTiedOperand() != i)
          return false;

        // The constraint should have the same info as the respective
        // output constraint.
        Info.setTiedOperand(i, OutputConstraints[i]);
      } else if (!validateAsmConstraint(Name, Info)) {
        // FIXME: This error return is in place temporarily so we can
        // add more constraints as we hit it.  Eventually, an unknown
        // constraint should just be treated as 'g'.
        return false;
      }
      break;
    case '[': {
      unsigned Index = 0;
      if (!resolveSymbolicName(Name, OutputConstraints, Index))
        return false;

      // If the constraint is already tied, it must be tied to the
      // same operand referenced to by the number.
      if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)
        return false;

      // A number must refer to an output only operand.
      if (OutputConstraints[Index].isReadWrite())
        return false;

      Info.setTiedOperand(Index, OutputConstraints[Index]);
      break;
    }
    case '%': // commutative
      // FIXME: Fail if % is used with the last operand.
      break;
    case 'i': // immediate integer.
      break;
    case 'n': // immediate integer with a known value.
      Info.setRequiresImmediate();
      break;
    case 'I':  // Various constant constraints with target-specific meanings.
    case 'J':
    case 'K':
    case 'L':
    case 'M':
    case 'N':
    case 'O':
    case 'P':
      if (!validateAsmConstraint(Name, Info))
        return false;
      break;
    case 'r': // general register.
      Info.setAllowsRegister();
      break;
    case 'm': // memory operand.
    case 'o': // offsettable memory operand.
    case 'V': // non-offsettable memory operand.
    case '<': // autodecrement memory operand.
    case '>': // autoincrement memory operand.
      Info.setAllowsMemory();
      break;
    case 'g': // general register, memory operand or immediate integer.
    case 'X': // any operand.
      Info.setAllowsRegister();
      Info.setAllowsMemory();
      break;
    case 'E': // immediate floating point.
    case 'F': // immediate floating point.
    case 'p': // address operand.
      break;
    case ',': // multiple alternative constraint.  Ignore comma.
      break;
    case '#': // Ignore as constraint.
      while (Name[1] && Name[1] != ',')
        Name++;
      break;
    case '?': // Disparage slightly code.
    case '!': // Disparage severely.
    case '*': // Ignore for choosing register preferences.
      break;  // Pass them.
    }

    Name++;
  }

  return true;
}

void TargetInfo::CheckFixedPointBits() const {
  // Check that the number of fractional and integral bits (and maybe sign) can
  // fit into the bits given for a fixed point type.
  assert(ShortAccumScale + getShortAccumIBits() + 1 <= ShortAccumWidth);
  assert(AccumScale + getAccumIBits() + 1 <= AccumWidth);
  assert(LongAccumScale + getLongAccumIBits() + 1 <= LongAccumWidth);
  assert(getUnsignedShortAccumScale() + getUnsignedShortAccumIBits() <=
         ShortAccumWidth);
  assert(getUnsignedAccumScale() + getUnsignedAccumIBits() <= AccumWidth);
  assert(getUnsignedLongAccumScale() + getUnsignedLongAccumIBits() <=
         LongAccumWidth);

  assert(getShortFractScale() + 1 <= ShortFractWidth);
  assert(getFractScale() + 1 <= FractWidth);
  assert(getLongFractScale() + 1 <= LongFractWidth);
  assert(getUnsignedShortFractScale() <= ShortFractWidth);
  assert(getUnsignedFractScale() <= FractWidth);
  assert(getUnsignedLongFractScale() <= LongFractWidth);

  // Each unsigned fract type has either the same number of fractional bits
  // as, or one more fractional bit than, its corresponding signed fract type.
  assert(getShortFractScale() == getUnsignedShortFractScale() ||
         getShortFractScale() == getUnsignedShortFractScale() - 1);
  assert(getFractScale() == getUnsignedFractScale() ||
         getFractScale() == getUnsignedFractScale() - 1);
  assert(getLongFractScale() == getUnsignedLongFractScale() ||
         getLongFractScale() == getUnsignedLongFractScale() - 1);

  // When arranged in order of increasing rank (see 6.3.1.3a), the number of
  // fractional bits is nondecreasing for each of the following sets of
  // fixed-point types:
  // - signed fract types
  // - unsigned fract types
  // - signed accum types
  // - unsigned accum types.
  assert(getLongFractScale() >= getFractScale() &&
         getFractScale() >= getShortFractScale());
  assert(getUnsignedLongFractScale() >= getUnsignedFractScale() &&
         getUnsignedFractScale() >= getUnsignedShortFractScale());
  assert(LongAccumScale >= AccumScale && AccumScale >= ShortAccumScale);
  assert(getUnsignedLongAccumScale() >= getUnsignedAccumScale() &&
         getUnsignedAccumScale() >= getUnsignedShortAccumScale());

  // When arranged in order of increasing rank (see 6.3.1.3a), the number of
  // integral bits is nondecreasing for each of the following sets of
  // fixed-point types:
  // - signed accum types
  // - unsigned accum types
  assert(getLongAccumIBits() >= getAccumIBits() &&
         getAccumIBits() >= getShortAccumIBits());
  assert(getUnsignedLongAccumIBits() >= getUnsignedAccumIBits() &&
         getUnsignedAccumIBits() >= getUnsignedShortAccumIBits());

  // Each signed accum type has at least as many integral bits as its
  // corresponding unsigned accum type.
  assert(getShortAccumIBits() >= getUnsignedShortAccumIBits());
  assert(getAccumIBits() >= getUnsignedAccumIBits());
  assert(getLongAccumIBits() >= getUnsignedLongAccumIBits());
}

void TargetInfo::copyAuxTarget(const TargetInfo *Aux) {
  auto *Target = static_cast<TransferrableTargetInfo*>(this);
  auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);
  *Target = *Src;
}
