/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* Target Register and Register Classes Information                           *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

namespace llvm {

extern const MCRegisterClass LanaiMCRegisterClasses[];

static const MVT::SimpleValueType VTLists[] = {
  /* 0 */ MVT::i32, MVT::Other,
};

static const char *SubRegIndexNameTable[] = { "sub_32", "" };

static const TargetRegisterInfo::SubRegCoveredBits SubRegIdxRangeTable[] = {
  { 65535, 65535 },
  { 0, 32 },	// sub_32
};


static const LaneBitmask SubRegIndexLaneMaskTable[] = {
  LaneBitmask::getAll(),
  LaneBitmask(0x0000000000000001), // sub_32
 };



static const TargetRegisterInfo::RegClassInfo RegClassInfos[] = {
  // Mode = 0 (Default)
  { 32, 32, 32, /*VTLists+*/0 },    // GPR
  { 32, 32, 32, /*VTLists+*/0 },    // GPR_with_sub_32
  { 32, 32, 32, /*VTLists+*/0 },    // CCR
};
static const uint32_t GPRSubClassMask[] = {
  0x00000003, 
  0x00000002, // sub_32
};

static const uint32_t GPR_with_sub_32SubClassMask[] = {
  0x00000002, 
};

static const uint32_t CCRSubClassMask[] = {
  0x00000004, 
};

static const uint16_t SuperRegIdxSeqs[] = {
  /* 0 */ 1, 0,
};

static unsigned const GPR_with_sub_32Superclasses[] = {
  Lanai::GPRRegClassID,
};


namespace Lanai {   // Register class instances
  extern const TargetRegisterClass GPRRegClass = {
    &LanaiMCRegisterClasses[GPRRegClassID],
    GPRSubClassMask,
    SuperRegIdxSeqs + 0,
    LaneBitmask(0x0000000000000001),
    0,
    false,
    0x00, /* TSFlags */
    false, /* HasDisjunctSubRegs */
    false, /* CoveredBySubRegs */
    nullptr, 0,
    nullptr
  };

  extern const TargetRegisterClass GPR_with_sub_32RegClass = {
    &LanaiMCRegisterClasses[GPR_with_sub_32RegClassID],
    GPR_with_sub_32SubClassMask,
    SuperRegIdxSeqs + 1,
    LaneBitmask(0x0000000000000001),
    0,
    false,
    0x00, /* TSFlags */
    false, /* HasDisjunctSubRegs */
    false, /* CoveredBySubRegs */
    GPR_with_sub_32Superclasses,  1,
    nullptr
  };

  extern const TargetRegisterClass CCRRegClass = {
    &LanaiMCRegisterClasses[CCRRegClassID],
    CCRSubClassMask,
    SuperRegIdxSeqs + 1,
    LaneBitmask(0x0000000000000001),
    0,
    false,
    0x00, /* TSFlags */
    false, /* HasDisjunctSubRegs */
    false, /* CoveredBySubRegs */
    nullptr, 0,
    nullptr
  };

} // end namespace Lanai

namespace {
  const TargetRegisterClass *const RegisterClasses[] = {
    &Lanai::GPRRegClass,
    &Lanai::GPR_with_sub_32RegClass,
    &Lanai::CCRRegClass,
  };
} // end anonymous namespace

static const uint8_t CostPerUseTable[] = { 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };


static const bool InAllocatableClassTable[] = { 
false, true, true, true, true, true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, };


static const TargetRegisterInfoDesc LanaiRegInfoDesc = { // Extra Descriptors
CostPerUseTable, 1, InAllocatableClassTable};

unsigned LanaiGenRegisterInfo::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {
  static const uint8_t Rows[1][1] = {
    { 0, },
  };

  --IdxA; assert(IdxA < 1); (void) IdxA;
  --IdxB; assert(IdxB < 1);
  return Rows[0][IdxB];
}

unsigned LanaiGenRegisterInfo::reverseComposeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {
  static const uint8_t Table[1][1] = {
    { 0, },
  };

  --IdxA; assert(IdxA < 1);
  --IdxB; assert(IdxB < 1);
  return Table[IdxA][IdxB];
  }

  struct MaskRolOp {
    LaneBitmask Mask;
    uint8_t  RotateLeft;
  };
  static const MaskRolOp LaneMaskComposeSequences[] = {
    { LaneBitmask(0xFFFFFFFFFFFFFFFF),  0 }, { LaneBitmask::getNone(), 0 }  // Sequence 0
  };
  static const uint8_t CompositeSequences[] = {
    0 // to sub_32
  };

LaneBitmask LanaiGenRegisterInfo::composeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask) const {
  --IdxA; assert(IdxA < 1 && "Subregister index out of bounds");
  LaneBitmask Result;
  for (const MaskRolOp *Ops =
       &LaneMaskComposeSequences[CompositeSequences[IdxA]];
       Ops->Mask.any(); ++Ops) {
    LaneBitmask::Type M = LaneMask.getAsInteger() & Ops->Mask.getAsInteger();
    if (unsigned S = Ops->RotateLeft)
      Result |= LaneBitmask((M << S) | (M >> (LaneBitmask::BitWidth - S)));
    else
      Result |= LaneBitmask(M);
  }
  return Result;
}

LaneBitmask LanaiGenRegisterInfo::reverseComposeSubRegIndexLaneMaskImpl(unsigned IdxA,  LaneBitmask LaneMask) const {
  LaneMask &= getSubRegIndexLaneMask(IdxA);
  --IdxA; assert(IdxA < 1 && "Subregister index out of bounds");
  LaneBitmask Result;
  for (const MaskRolOp *Ops =
       &LaneMaskComposeSequences[CompositeSequences[IdxA]];
       Ops->Mask.any(); ++Ops) {
    LaneBitmask::Type M = LaneMask.getAsInteger();
    if (unsigned S = Ops->RotateLeft)
      Result |= LaneBitmask((M >> S) | (M << (LaneBitmask::BitWidth - S)));
    else
      Result |= LaneBitmask(M);
  }
  return Result;
}

const TargetRegisterClass *LanaiGenRegisterInfo::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const {
  static const uint8_t Table[3][1] = {
    {	// GPR
      2,	// sub_32 -> GPR_with_sub_32
    },
    {	// GPR_with_sub_32
      2,	// sub_32 -> GPR_with_sub_32
    },
    {	// CCR
      0,	// sub_32
    },
  };
  assert(RC && "Missing regclass");
  if (!Idx) return RC;
  --Idx;
  assert(Idx < 1 && "Bad subreg");
  unsigned TV = Table[RC->getID()][Idx];
  return TV ? getRegClass(TV - 1) : nullptr;
}

const TargetRegisterClass *LanaiGenRegisterInfo::getSubRegisterClass(const TargetRegisterClass *RC, unsigned Idx) const {
  static const uint8_t Table[3][1] = {
    {	// GPR
      1,	// GPR:sub_32 -> GPR
    },
    {	// GPR_with_sub_32
      1,	// GPR_with_sub_32:sub_32 -> GPR
    },
    {	// CCR
      0,	// CCR:sub_32
    },
  };
  assert(RC && "Missing regclass");
  if (!Idx) return RC;
  --Idx;
  assert(Idx < 1 && "Bad subreg");
  unsigned TV = Table[RC->getID()][Idx];
  return TV ? getRegClass(TV - 1) : nullptr;
}

/// Get the weight in units of pressure for this register class.
const RegClassWeight &LanaiGenRegisterInfo::
getRegClassWeight(const TargetRegisterClass *RC) const {
  static const RegClassWeight RCWeightTable[] = {
    {1, 32},  	// GPR
    {1, 7},  	// GPR_with_sub_32
    {0, 0},  	// CCR
  };
  return RCWeightTable[RC->getID()];
}

/// Get the weight in units of pressure for this register unit.
unsigned LanaiGenRegisterInfo::
getRegUnitWeight(MCRegUnit RegUnit) const {
  assert(static_cast<unsigned>(RegUnit) < 33 && "invalid register unit");
  // All register units have unit weight.
  return 1;
}


// Get the number of dimensions of register pressure.
unsigned LanaiGenRegisterInfo::getNumRegPressureSets() const {
  return 2;
}

// Get the name of this register unit pressure set.
const char *LanaiGenRegisterInfo::
getRegPressureSetName(unsigned Idx) const {
  static const char *PressureNameTable[] = {
    "GPR_with_sub_32",
    "GPR",
  };
  return PressureNameTable[Idx];
}

// Get the register unit pressure limit for this dimension.
// This limit must be adjusted dynamically for reserved registers.
unsigned LanaiGenRegisterInfo::
getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const {
  static const uint8_t PressureLimitTable[] = {
    7,  	// 0: GPR_with_sub_32
    32,  	// 1: GPR
  };
  return PressureLimitTable[Idx];
}

/// Table of pressure sets per register class or unit.
static const int RCSetsTable[] = {
  /* 0 */ 0, 1, -1,
};

/// Get the dimensions of register pressure impacted by this register class.
/// Returns a -1 terminated array of pressure set IDs
const int *LanaiGenRegisterInfo::
getRegClassPressureSets(const TargetRegisterClass *RC) const {
  static const uint8_t RCSetStartTable[] = {
    1,0,2,};
  return &RCSetsTable[RCSetStartTable[RC->getID()]];
}

/// Get the dimensions of register pressure impacted by this register unit.
/// Returns a -1 terminated array of pressure set IDs
const int *LanaiGenRegisterInfo::
getRegUnitPressureSets(MCRegUnit RegUnit) const {
  assert(static_cast<unsigned>(RegUnit) < 33 && "invalid register unit");
  static const uint8_t RUSetStartTable[] = {
    0,0,0,0,0,2,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,};
  return &RCSetsTable[RUSetStartTable[static_cast<unsigned>(RegUnit)]];
}

extern const MCRegisterDesc LanaiRegDesc[];
extern const int16_t LanaiRegDiffLists[];
extern const LaneBitmask LanaiLaneMaskLists[];
extern const char LanaiRegStrings[];
extern const char LanaiRegClassStrings[];
extern const MCPhysReg LanaiRegUnitRoots[][2];
extern const uint16_t LanaiSubRegIdxLists[];
extern const uint16_t LanaiRegEncodingTable[];
// Lanai Dwarf<->LLVM register mappings.
extern const MCRegisterInfo::DwarfLLVMRegPair LanaiDwarfFlavour0Dwarf2L[];
extern const unsigned LanaiDwarfFlavour0Dwarf2LSize;

extern const MCRegisterInfo::DwarfLLVMRegPair LanaiEHFlavour0Dwarf2L[];
extern const unsigned LanaiEHFlavour0Dwarf2LSize;

extern const MCRegisterInfo::DwarfLLVMRegPair LanaiDwarfFlavour0L2Dwarf[];
extern const unsigned LanaiDwarfFlavour0L2DwarfSize;

extern const MCRegisterInfo::DwarfLLVMRegPair LanaiEHFlavour0L2Dwarf[];
extern const unsigned LanaiEHFlavour0L2DwarfSize;

LanaiGenRegisterInfo::
LanaiGenRegisterInfo(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,
      unsigned PC, unsigned HwMode)
  : TargetRegisterInfo(&LanaiRegInfoDesc, RegisterClasses, RegisterClasses+3,
             SubRegIndexNameTable, SubRegIdxRangeTable, SubRegIndexLaneMaskTable,
             LaneBitmask(0xFFFFFFFFFFFFFFFE), RegClassInfos, VTLists, HwMode) {
  InitMCRegisterInfo(LanaiRegDesc, 41, RA, PC,
                     LanaiMCRegisterClasses, 3,
                     LanaiRegUnitRoots,
                     33,
                     LanaiRegDiffLists,
                     LanaiLaneMaskLists,
                     LanaiRegStrings,
                     LanaiRegClassStrings,
                     LanaiSubRegIdxLists,
                     2,
                     LanaiRegEncodingTable);

  switch (DwarfFlavour) {
  default:
    llvm_unreachable("Unknown DWARF flavour");
  case 0:
    mapDwarfRegsToLLVMRegs(LanaiDwarfFlavour0Dwarf2L, LanaiDwarfFlavour0Dwarf2LSize, false);
    break;
  }
  switch (EHFlavour) {
  default:
    llvm_unreachable("Unknown DWARF flavour");
  case 0:
    mapDwarfRegsToLLVMRegs(LanaiEHFlavour0Dwarf2L, LanaiEHFlavour0Dwarf2LSize, true);
    break;
  }
  switch (DwarfFlavour) {
  default:
    llvm_unreachable("Unknown DWARF flavour");
  case 0:
    mapLLVMRegsToDwarfRegs(LanaiDwarfFlavour0L2Dwarf, LanaiDwarfFlavour0L2DwarfSize, false);
    break;
  }
  switch (EHFlavour) {
  default:
    llvm_unreachable("Unknown DWARF flavour");
  case 0:
    mapLLVMRegsToDwarfRegs(LanaiEHFlavour0L2Dwarf, LanaiEHFlavour0L2DwarfSize, true);
    break;
  }
}

static const MCPhysReg CSR_SaveList[] = { 0 };
static const uint32_t CSR_RegMask[] = { 0x00000000, 0x00000000, };


ArrayRef<const uint32_t *> LanaiGenRegisterInfo::getRegMasks() const {
  static const uint32_t *const Masks[] = {
    CSR_RegMask,
  };
  return ArrayRef(Masks);
}

bool LanaiGenRegisterInfo::
isGeneralPurposeRegister(const MachineFunction &MF, MCRegister PhysReg) const {
  return
      false;
}

bool LanaiGenRegisterInfo::
isGeneralPurposeRegisterClass(const TargetRegisterClass *RC) const {
  return
      false;
}

bool LanaiGenRegisterInfo::
isFixedRegister(const MachineFunction &MF, MCRegister PhysReg) const {
  return
      false;
}

bool LanaiGenRegisterInfo::
isArgumentRegister(const MachineFunction &MF, MCRegister PhysReg) const {
  return
      false;
}

bool LanaiGenRegisterInfo::
isConstantPhysReg(MCRegister PhysReg) const {
  return
      false;
}

ArrayRef<const char *> LanaiGenRegisterInfo::getRegMaskNames() const {
  static const char *Names[] = {
    "CSR",
  };
  return ArrayRef(Names);
}

const LanaiFrameLowering *
LanaiGenRegisterInfo::getFrameLowering(const MachineFunction &MF) {
  return static_cast<const LanaiFrameLowering *>(
      MF.getSubtarget().getFrameLowering());
}

} // end namespace llvm

