//===-- RISCVBaseInfo.h - Top level definitions for RISC-V MC ---*- C++ -*-===//
//
// 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 contains small standalone enum definitions for the RISC-V target
// useful for the compiler back-end and the MC libraries.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVBASEINFO_H
#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVBASEINFO_H

#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/TargetParser/RISCVISAInfo.h"
#include "llvm/TargetParser/RISCVTargetParser.h"
#include "llvm/TargetParser/SubtargetFeature.h"

namespace llvm {

// RISCVII - This namespace holds all of the target specific flags that
// instruction info tracks. All definitions must match RISCVInstrFormats.td.
namespace RISCVII {
enum {
  InstFormatPseudo = 0,
  InstFormatR = 1,
  InstFormatR4 = 2,
  InstFormatI = 3,
  InstFormatS = 4,
  InstFormatB = 5,
  InstFormatU = 6,
  InstFormatJ = 7,
  InstFormatCR = 8,
  InstFormatCI = 9,
  InstFormatCSS = 10,
  InstFormatCIW = 11,
  InstFormatCL = 12,
  InstFormatCS = 13,
  InstFormatCA = 14,
  InstFormatCB = 15,
  InstFormatCJ = 16,
  InstFormatCU = 17,
  InstFormatCLB = 18,
  InstFormatCLH = 19,
  InstFormatCSB = 20,
  InstFormatCSH = 21,
  InstFormatQC_EAI = 22,
  InstFormatQC_EI = 23,
  InstFormatQC_EB = 24,
  InstFormatQC_EJ = 25,
  InstFormatQC_ES = 26,
  InstFormatOther = 31,

  InstFormatMask = 31,
  InstFormatShift = 0,

  ConstraintShift = InstFormatShift + 5,
  VS2Constraint = 0b001 << ConstraintShift,
  VS1Constraint = 0b010 << ConstraintShift,
  VMConstraint = 0b100 << ConstraintShift,
  ConstraintMask = 0b111 << ConstraintShift,

  VLMulShift = ConstraintShift + 3,
  VLMulMask = 0b111 << VLMulShift,

  // Is this a _TIED vector pseudo instruction. For these instructions we
  // shouldn't skip the tied operand when converting to MC instructions.
  IsTiedPseudoShift = VLMulShift + 3,
  IsTiedPseudoMask = 1 << IsTiedPseudoShift,

  // Does this instruction have a SEW operand. It will be the last explicit
  // operand unless there is a vector policy operand. Used by RVV Pseudos.
  HasSEWOpShift = IsTiedPseudoShift + 1,
  HasSEWOpMask = 1 << HasSEWOpShift,

  // Does this instruction have a VL operand. It will be the second to last
  // explicit operand unless there is a vector policy operand. Used by RVV
  // Pseudos.
  HasVLOpShift = HasSEWOpShift + 1,
  HasVLOpMask = 1 << HasVLOpShift,

  // Does this instruction have a vector policy operand. It will be the last
  // explicit operand. Used by RVV Pseudos.
  HasVecPolicyOpShift = HasVLOpShift + 1,
  HasVecPolicyOpMask = 1 << HasVecPolicyOpShift,

  // Is this instruction a vector widening reduction instruction. Used by RVV
  // Pseudos.
  IsRVVWideningReductionShift = HasVecPolicyOpShift + 1,
  IsRVVWideningReductionMask = 1 << IsRVVWideningReductionShift,

  // Does this instruction care about mask policy. If it is not, the mask policy
  // could be either agnostic or undisturbed. For example, unmasked, store, and
  // reduction operations result would not be affected by mask policy, so
  // compiler has free to select either one.
  UsesMaskPolicyShift = IsRVVWideningReductionShift + 1,
  UsesMaskPolicyMask = 1 << UsesMaskPolicyShift,

  // Indicates that the result can be considered sign extended from bit 31. Some
  // instructions with this flag aren't W instructions, but are either sign
  // extended from a smaller size, always outputs a small integer, or put zeros
  // in bits 63:31. Used by the SExtWRemoval pass.
  IsSignExtendingOpWShift = UsesMaskPolicyShift + 1,
  IsSignExtendingOpWMask = 1ULL << IsSignExtendingOpWShift,

  HasRoundModeOpShift = IsSignExtendingOpWShift + 1,
  HasRoundModeOpMask = 1 << HasRoundModeOpShift,

  UsesVXRMShift = HasRoundModeOpShift + 1,
  UsesVXRMMask = 1 << UsesVXRMShift,

  // Indicates whether these instructions can partially overlap between source
  // registers and destination registers according to the vector spec.
  // 0 -> not a vector pseudo
  // 1 -> default value for vector pseudos. not widening or narrowing.
  // 2 -> narrowing case
  // 3 -> widening case
  TargetOverlapConstraintTypeShift = UsesVXRMShift + 1,
  TargetOverlapConstraintTypeMask = 3ULL << TargetOverlapConstraintTypeShift,

  ElementsDependOnVLShift = TargetOverlapConstraintTypeShift + 2,
  ElementsDependOnVLMask = 1ULL << ElementsDependOnVLShift,

  ElementsDependOnMaskShift = ElementsDependOnVLShift + 1,
  ElementsDependOnMaskMask = 1ULL << ElementsDependOnMaskShift,

  // Indicates the EEW of a vector instruction's destination operand.
  // 0 -> 1
  // 1 -> SEW
  // 2 -> SEW * 2
  // 3 -> SEW * 4
  DestEEWShift = ElementsDependOnMaskShift + 1,
  DestEEWMask = 3ULL << DestEEWShift,
};

// Helper functions to read TSFlags.
/// \returns the format of the instruction.
static inline unsigned getFormat(uint64_t TSFlags) {
  return (TSFlags & InstFormatMask) >> InstFormatShift;
}
/// \returns the LMUL for the instruction.
static inline RISCVVType::VLMUL getLMul(uint64_t TSFlags) {
  return static_cast<RISCVVType::VLMUL>((TSFlags & VLMulMask) >> VLMulShift);
}
/// \returns true if this a _TIED pseudo.
static inline bool isTiedPseudo(uint64_t TSFlags) {
  return TSFlags & IsTiedPseudoMask;
}
/// \returns true if there is a SEW operand for the instruction.
static inline bool hasSEWOp(uint64_t TSFlags) {
  return TSFlags & HasSEWOpMask;
}
/// \returns true if there is a VL operand for the instruction.
static inline bool hasVLOp(uint64_t TSFlags) {
  return TSFlags & HasVLOpMask;
}
/// \returns true if there is a vector policy operand for this instruction.
static inline bool hasVecPolicyOp(uint64_t TSFlags) {
  return TSFlags & HasVecPolicyOpMask;
}
/// \returns true if it is a vector widening reduction instruction.
static inline bool isRVVWideningReduction(uint64_t TSFlags) {
  return TSFlags & IsRVVWideningReductionMask;
}
/// \returns true if mask policy is valid for the instruction.
static inline bool usesMaskPolicy(uint64_t TSFlags) {
  return TSFlags & UsesMaskPolicyMask;
}

/// \returns true if there is a rounding mode operand for this instruction
static inline bool hasRoundModeOp(uint64_t TSFlags) {
  return TSFlags & HasRoundModeOpMask;
}

/// \returns true if this instruction uses vxrm
static inline bool usesVXRM(uint64_t TSFlags) { return TSFlags & UsesVXRMMask; }

/// \returns true if the elements in the body are affected by VL,
/// e.g. vslide1down.vx/vredsum.vs/viota.m
static inline bool elementsDependOnVL(uint64_t TSFlags) {
  return TSFlags & ElementsDependOnVLMask;
}

/// \returns true if the elements in the body are affected by the mask,
/// e.g. vredsum.vs/viota.m
static inline bool elementsDependOnMask(uint64_t TSFlags) {
  return TSFlags & ElementsDependOnMaskMask;
}

static inline unsigned getVLOpNum(const MCInstrDesc &Desc) {
  const uint64_t TSFlags = Desc.TSFlags;
  // This method is only called if we expect to have a VL operand, and all
  // instructions with VL also have SEW.
  assert(hasSEWOp(TSFlags) && hasVLOp(TSFlags));
  unsigned Offset = 2;
  if (hasVecPolicyOp(TSFlags))
    Offset = 3;
  return Desc.getNumOperands() - Offset;
}

static inline MCRegister
getTailExpandUseRegNo(const FeatureBitset &FeatureBits) {
  // For Zicfilp, PseudoTAIL should be expanded to a software guarded branch.
  // It means to use t2(x7) as rs1 of JALR to expand PseudoTAIL.
  return FeatureBits[RISCV::FeatureStdExtZicfilp] ? RISCV::X7 : RISCV::X6;
}

static inline unsigned getSEWOpNum(const MCInstrDesc &Desc) {
  const uint64_t TSFlags = Desc.TSFlags;
  assert(hasSEWOp(TSFlags));
  unsigned Offset = 1;
  if (hasVecPolicyOp(TSFlags))
    Offset = 2;
  return Desc.getNumOperands() - Offset;
}

static inline unsigned getVecPolicyOpNum(const MCInstrDesc &Desc) {
  assert(hasVecPolicyOp(Desc.TSFlags));
  return Desc.getNumOperands() - 1;
}

/// \returns  the index to the rounding mode immediate value if any, otherwise
/// returns -1.
static inline int getFRMOpNum(const MCInstrDesc &Desc) {
  const uint64_t TSFlags = Desc.TSFlags;
  if (!hasRoundModeOp(TSFlags) || usesVXRM(TSFlags))
    return -1;

  // The operand order
  // --------------------------------------
  // | n-1 (if any)   | n-2  | n-3 | n-4 |
  // | policy         | sew  | vl  | frm |
  // --------------------------------------
  return getVLOpNum(Desc) - 1;
}

/// \returns  the index to the rounding mode immediate value if any, otherwise
/// returns -1.
static inline int getVXRMOpNum(const MCInstrDesc &Desc) {
  const uint64_t TSFlags = Desc.TSFlags;
  if (!hasRoundModeOp(TSFlags) || !usesVXRM(TSFlags))
    return -1;
  // The operand order
  // --------------------------------------
  // | n-1 (if any)   | n-2  | n-3 | n-4  |
  // | policy         | sew  | vl  | vxrm |
  // --------------------------------------
  return getVLOpNum(Desc) - 1;
}

// Is the first def operand tied to the first use operand. This is true for
// vector pseudo instructions that have a merge operand for tail/mask
// undisturbed. It's also true for vector FMA instructions where one of the
// operands is also the destination register.
static inline bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc) {
  return Desc.getNumDefs() < Desc.getNumOperands() &&
         Desc.getOperandConstraint(Desc.getNumDefs(), MCOI::TIED_TO) == 0;
}

// RISC-V Specific Machine Operand Flags
enum {
  MO_None = 0,
  MO_CALL = 1,
  MO_LO = 3,
  MO_HI = 4,
  MO_PCREL_LO = 5,
  MO_PCREL_HI = 6,
  MO_GOT_HI = 7,
  MO_TPREL_LO = 8,
  MO_TPREL_HI = 9,
  MO_TPREL_ADD = 10,
  MO_TLS_GOT_HI = 11,
  MO_TLS_GD_HI = 12,
  MO_TLSDESC_HI = 13,
  MO_TLSDESC_LOAD_LO = 14,
  MO_TLSDESC_ADD_LO = 15,
  MO_TLSDESC_CALL = 16,

  // Used to differentiate between target-specific "direct" flags and "bitmask"
  // flags. A machine operand can only have one "direct" flag, but can have
  // multiple "bitmask" flags.
  MO_DIRECT_FLAG_MASK = 31
};
} // namespace RISCVII

namespace RISCVOp {
enum OperandType : unsigned {
  OPERAND_FIRST_RISCV_IMM = MCOI::OPERAND_FIRST_TARGET,
  OPERAND_UIMM1 = OPERAND_FIRST_RISCV_IMM,
  OPERAND_UIMM2,
  OPERAND_UIMM2_LSB0,
  OPERAND_UIMM3,
  OPERAND_UIMM4,
  OPERAND_UIMM5,
  OPERAND_UIMM5_NONZERO,
  OPERAND_UIMM5_GT3,
  OPERAND_UIMM5_PLUS1,
  OPERAND_UIMM5_GE6_PLUS1,
  OPERAND_UIMM5_LSB0,
  OPERAND_UIMM5_SLIST,
  OPERAND_UIMM6,
  OPERAND_UIMM6_LSB0,
  OPERAND_UIMM7,
  OPERAND_UIMM7_LSB00,
  OPERAND_UIMM7_LSB000,
  OPERAND_UIMM8_LSB00,
  OPERAND_UIMM8,
  OPERAND_UIMM8_LSB000,
  OPERAND_UIMM8_GE32,
  OPERAND_UIMM9_LSB000,
  OPERAND_UIMM10,
  OPERAND_UIMM10_LSB00_NONZERO,
  OPERAND_UIMM11,
  OPERAND_UIMM12,
  OPERAND_UIMM14_LSB00,
  OPERAND_UIMM16,
  OPERAND_UIMM16_NONZERO,
  OPERAND_UIMM20,
  OPERAND_UIMMLOG2XLEN,
  OPERAND_UIMMLOG2XLEN_NONZERO,
  OPERAND_UIMM32,
  OPERAND_UIMM48,
  OPERAND_UIMM64,
  OPERAND_ZERO,
  OPERAND_SIMM5,
  OPERAND_SIMM5_NONZERO,
  OPERAND_SIMM5_PLUS1,
  OPERAND_SIMM6,
  OPERAND_SIMM6_NONZERO,
  OPERAND_SIMM10_LSB0000_NONZERO,
  OPERAND_SIMM11,
  OPERAND_SIMM12,
  OPERAND_SIMM12_LSB00000,
  OPERAND_SIMM16,
  OPERAND_SIMM16_NONZERO,
  OPERAND_SIMM20,
  OPERAND_SIMM26,
  OPERAND_SIMM32,
  OPERAND_CLUI_IMM,
  OPERAND_VTYPEI10,
  OPERAND_VTYPEI11,
  OPERAND_RVKRNUM,
  OPERAND_RVKRNUM_0_7,
  OPERAND_RVKRNUM_1_10,
  OPERAND_RVKRNUM_2_14,
  OPERAND_RLIST,
  OPERAND_RLIST_S0,
  OPERAND_STACKADJ,
  // Operand is a 3-bit rounding mode, '111' indicates FRM register.
  // Represents 'frm' argument passing to floating-point operations.
  OPERAND_FRMARG,
  // Operand is a 3-bit rounding mode where only RTZ is valid.
  OPERAND_RTZARG,
  // Condition code used by select and short forward branch pseudos.
  OPERAND_COND_CODE,
  // Vector policy operand.
  OPERAND_VEC_POLICY,
  // Vector SEW operand. Stores in log2(SEW).
  OPERAND_SEW,
  // Special SEW for mask only instructions. Always 0.
  OPERAND_SEW_MASK,
  // Vector rounding mode for VXRM or FRM.
  OPERAND_VEC_RM,
  OPERAND_LAST_RISCV_IMM = OPERAND_VEC_RM,
  // Operand is either a register or uimm5, this is used by V extension pseudo
  // instructions to represent a value that be passed as AVL to either vsetvli
  // or vsetivli.
  OPERAND_AVL,
};
} // namespace RISCVOp

// Describes the predecessor/successor bits used in the FENCE instruction.
namespace RISCVFenceField {
enum FenceField {
  I = 8,
  O = 4,
  R = 2,
  W = 1
};
}

// Describes the supported floating point rounding mode encodings.
namespace RISCVFPRndMode {
enum RoundingMode {
  RNE = 0,
  RTZ = 1,
  RDN = 2,
  RUP = 3,
  RMM = 4,
  DYN = 7,
  Invalid
};

inline static StringRef roundingModeToString(RoundingMode RndMode) {
  switch (RndMode) {
  default:
    llvm_unreachable("Unknown floating point rounding mode");
  case RISCVFPRndMode::RNE:
    return "rne";
  case RISCVFPRndMode::RTZ:
    return "rtz";
  case RISCVFPRndMode::RDN:
    return "rdn";
  case RISCVFPRndMode::RUP:
    return "rup";
  case RISCVFPRndMode::RMM:
    return "rmm";
  case RISCVFPRndMode::DYN:
    return "dyn";
  }
}

inline static RoundingMode stringToRoundingMode(StringRef Str) {
  return StringSwitch<RoundingMode>(Str)
      .Case("rne", RISCVFPRndMode::RNE)
      .Case("rtz", RISCVFPRndMode::RTZ)
      .Case("rdn", RISCVFPRndMode::RDN)
      .Case("rup", RISCVFPRndMode::RUP)
      .Case("rmm", RISCVFPRndMode::RMM)
      .Case("dyn", RISCVFPRndMode::DYN)
      .Default(RISCVFPRndMode::Invalid);
}

inline static bool isValidRoundingMode(unsigned Mode) {
  switch (Mode) {
  default:
    return false;
  case RISCVFPRndMode::RNE:
  case RISCVFPRndMode::RTZ:
  case RISCVFPRndMode::RDN:
  case RISCVFPRndMode::RUP:
  case RISCVFPRndMode::RMM:
  case RISCVFPRndMode::DYN:
    return true;
  }
}
} // namespace RISCVFPRndMode

namespace RISCVVXRndMode {
enum RoundingMode {
  RNU = 0,
  RNE = 1,
  RDN = 2,
  ROD = 3,
  Invalid
};

inline static StringRef roundingModeToString(RoundingMode RndMode) {
  switch (RndMode) {
  default:
    llvm_unreachable("Unknown vector fixed-point rounding mode");
  case RISCVVXRndMode::RNU:
    return "rnu";
  case RISCVVXRndMode::RNE:
    return "rne";
  case RISCVVXRndMode::RDN:
    return "rdn";
  case RISCVVXRndMode::ROD:
    return "rod";
  }
}

inline static RoundingMode stringToRoundingMode(StringRef Str) {
  return StringSwitch<RoundingMode>(Str)
      .Case("rnu", RISCVVXRndMode::RNU)
      .Case("rne", RISCVVXRndMode::RNE)
      .Case("rdn", RISCVVXRndMode::RDN)
      .Case("rod", RISCVVXRndMode::ROD)
      .Default(RISCVVXRndMode::Invalid);
}

inline static bool isValidRoundingMode(unsigned Mode) {
  switch (Mode) {
  default:
    return false;
  case RISCVVXRndMode::RNU:
  case RISCVVXRndMode::RNE:
  case RISCVVXRndMode::RDN:
  case RISCVVXRndMode::ROD:
    return true;
  }
}
} // namespace RISCVVXRndMode

//===----------------------------------------------------------------------===//
// Floating-point Immediates
//

namespace RISCVLoadFPImm {
float getFPImm(unsigned Imm);

/// getLoadFPImm - Return a 5-bit binary encoding of the floating-point
/// immediate value. If the value cannot be represented as a 5-bit binary
/// encoding, then return -1.
int getLoadFPImm(APFloat FPImm);
} // namespace RISCVLoadFPImm

namespace RISCVSysReg {
struct SysReg {
  const char Name[32];
  unsigned Encoding;
  // FIXME: add these additional fields when needed.
  // Privilege Access: Read, Write, Read-Only.
  // unsigned ReadWrite;
  // Privilege Mode: User, System or Machine.
  // unsigned Mode;
  // Check field name.
  // unsigned Extra;
  // Register number without the privilege bits.
  // unsigned Number;
  FeatureBitset FeaturesRequired;
  bool IsRV32Only;
  bool IsAltName;
  bool IsDeprecatedName;

  bool haveRequiredFeatures(const FeatureBitset &ActiveFeatures) const {
    // Not in 32-bit mode.
    if (IsRV32Only && ActiveFeatures[RISCV::Feature64Bit])
      return false;
    // No required feature associated with the system register.
    if (FeaturesRequired.none())
      return true;
    return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
  }
};

#define GET_SysRegEncodings_DECL
#define GET_SysRegsList_DECL
#include "RISCVGenSearchableTables.inc"
} // end namespace RISCVSysReg

namespace RISCVInsnOpcode {
struct RISCVOpcode {
  char Name[10];
  uint8_t Value;
};

#define GET_RISCVOpcodesList_DECL
#include "RISCVGenSearchableTables.inc"
} // end namespace RISCVInsnOpcode

namespace RISCVABI {

enum ABI {
  ABI_ILP32,
  ABI_ILP32F,
  ABI_ILP32D,
  ABI_ILP32E,
  ABI_LP64,
  ABI_LP64F,
  ABI_LP64D,
  ABI_LP64E,
  ABI_Unknown
};

// Returns the target ABI, or else a StringError if the requested ABIName is
// not supported for the given TT and FeatureBits combination.
ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits,
                     StringRef ABIName);

ABI getTargetABI(StringRef ABIName);

// Returns the register used to hold the stack pointer after realignment.
MCRegister getBPReg();

// Returns the register holding shadow call stack pointer.
MCRegister getSCSPReg();

} // namespace RISCVABI

namespace RISCVFeatures {

// Validates if the given combination of features are valid for the target
// triple. Exits with report_fatal_error if not.
void validate(const Triple &TT, const FeatureBitset &FeatureBits);

llvm::Expected<std::unique_ptr<RISCVISAInfo>>
parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits);

} // namespace RISCVFeatures

namespace RISCVRVC {
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI);
bool uncompress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI);
} // namespace RISCVRVC

namespace RISCVZC {
enum RLISTENCODE {
  RA = 4,
  RA_S0,
  RA_S0_S1,
  RA_S0_S2,
  RA_S0_S3,
  RA_S0_S4,
  RA_S0_S5,
  RA_S0_S6,
  RA_S0_S7,
  RA_S0_S8,
  RA_S0_S9,
  // note - to include s10, s11 must also be included
  RA_S0_S11,
  INVALID_RLIST,
};

inline unsigned encodeRegList(MCRegister EndReg, bool IsRVE = false) {
  assert((!IsRVE || EndReg <= RISCV::X9) && "Invalid Rlist for RV32E");
  switch (EndReg) {
  case RISCV::X1:
    return RLISTENCODE::RA;
  case RISCV::X8:
    return RLISTENCODE::RA_S0;
  case RISCV::X9:
    return RLISTENCODE::RA_S0_S1;
  case RISCV::X18:
    return RLISTENCODE::RA_S0_S2;
  case RISCV::X19:
    return RLISTENCODE::RA_S0_S3;
  case RISCV::X20:
    return RLISTENCODE::RA_S0_S4;
  case RISCV::X21:
    return RLISTENCODE::RA_S0_S5;
  case RISCV::X22:
    return RLISTENCODE::RA_S0_S6;
  case RISCV::X23:
    return RLISTENCODE::RA_S0_S7;
  case RISCV::X24:
    return RLISTENCODE::RA_S0_S8;
  case RISCV::X25:
    return RLISTENCODE::RA_S0_S9;
  case RISCV::X27:
    return RLISTENCODE::RA_S0_S11;
  default:
    llvm_unreachable("Undefined input.");
  }
}

inline static unsigned encodeRegListNumRegs(unsigned NumRegs) {
  assert(NumRegs > 0 && NumRegs < 14 && NumRegs != 12 &&
         "Unexpected number of registers");
  if (NumRegs == 13)
    return RLISTENCODE::RA_S0_S11;

  return RLISTENCODE::RA + (NumRegs - 1);
}

inline static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64) {
  assert(RlistVal >= RLISTENCODE::RA && RlistVal <= RLISTENCODE::RA_S0_S11 &&
         "Invalid Rlist");
  unsigned NumRegs = (RlistVal - RLISTENCODE::RA) + 1;
  // s10 and s11 are saved together.
  if (RlistVal == RLISTENCODE::RA_S0_S11)
    ++NumRegs;

  unsigned RegSize = IsRV64 ? 8 : 4;
  return alignTo(NumRegs * RegSize, 16);
}

void printRegList(unsigned RlistEncode, raw_ostream &OS);
} // namespace RISCVZC

namespace RISCVVInversePseudosTable {
struct PseudoInfo {
  uint16_t Pseudo;
  uint16_t BaseInstr;
  uint8_t VLMul;
  uint8_t SEW;
};

#define GET_RISCVVInversePseudosTable_DECL
#include "RISCVGenSearchableTables.inc"
} // namespace RISCVVInversePseudosTable

namespace RISCV {
struct VLSEGPseudo {
  uint16_t NF : 4;
  uint16_t Masked : 1;
  uint16_t Strided : 1;
  uint16_t FF : 1;
  uint16_t Log2SEW : 3;
  uint16_t LMUL : 3;
  uint16_t Pseudo;
};

struct VLXSEGPseudo {
  uint16_t NF : 4;
  uint16_t Masked : 1;
  uint16_t Ordered : 1;
  uint16_t Log2SEW : 3;
  uint16_t LMUL : 3;
  uint16_t IndexLMUL : 3;
  uint16_t Pseudo;
};

struct VSSEGPseudo {
  uint16_t NF : 4;
  uint16_t Masked : 1;
  uint16_t Strided : 1;
  uint16_t Log2SEW : 3;
  uint16_t LMUL : 3;
  uint16_t Pseudo;
};

struct VSXSEGPseudo {
  uint16_t NF : 4;
  uint16_t Masked : 1;
  uint16_t Ordered : 1;
  uint16_t Log2SEW : 3;
  uint16_t LMUL : 3;
  uint16_t IndexLMUL : 3;
  uint16_t Pseudo;
};

struct VLEPseudo {
  uint16_t Masked : 1;
  uint16_t Strided : 1;
  uint16_t FF : 1;
  uint16_t Log2SEW : 3;
  uint16_t LMUL : 3;
  uint16_t Pseudo;
};

struct VSEPseudo {
  uint16_t Masked : 1;
  uint16_t Strided : 1;
  uint16_t Log2SEW : 3;
  uint16_t LMUL : 3;
  uint16_t Pseudo;
};

struct VLX_VSXPseudo {
  uint16_t Masked : 1;
  uint16_t Ordered : 1;
  uint16_t Log2SEW : 3;
  uint16_t LMUL : 3;
  uint16_t IndexLMUL : 3;
  uint16_t Pseudo;
};

#define GET_RISCVVSSEGTable_DECL
#define GET_RISCVVLSEGTable_DECL
#define GET_RISCVVLXSEGTable_DECL
#define GET_RISCVVSXSEGTable_DECL
#define GET_RISCVVLETable_DECL
#define GET_RISCVVSETable_DECL
#define GET_RISCVVLXTable_DECL
#define GET_RISCVVSXTable_DECL
#include "RISCVGenSearchableTables.inc"
} // namespace RISCV

} // namespace llvm

#endif
