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

namespace llvm {

extern const MCRegisterClass AVRMCRegisterClasses[];

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

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

static const TargetRegisterInfo::SubRegCoveredBits SubRegIdxRangeTable[] = {
  { 65535, 65535 },
  { 8, 8 },	// sub_hi
  { 0, 8 },	// sub_lo
};


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



static const TargetRegisterInfo::RegClassInfo RegClassInfos[] = {
  // Mode = 0 (Default)
  { 8, 8, 8, /*VTLists+*/0 },    // GPR8
  { 8, 8, 8, /*VTLists+*/0 },    // GPR8NOZ
  { 8, 8, 8, /*VTLists+*/0 },    // GPR8lo
  { 8, 8, 8, /*VTLists+*/0 },    // LD8
  { 8, 8, 8, /*VTLists+*/0 },    // GPR8NOZ_and_LD8
  { 8, 8, 8, /*VTLists+*/0 },    // LD8lo
  { 8, 8, 8, /*VTLists+*/0 },    // CCR
  { 16, 16, 8, /*VTLists+*/2 },    // DREGS
  { 16, 16, 8, /*VTLists+*/2 },    // DREGSNOZ
  { 16, 16, 8, /*VTLists+*/2 },    // DREGSMOVW
  { 16, 16, 8, /*VTLists+*/2 },    // DREGSMOVW_and_DREGSNOZ
  { 16, 16, 8, /*VTLists+*/2 },    // DREGS_with_sub_hi_in_LD8
  { 16, 16, 8, /*VTLists+*/2 },    // DREGSNOZ_and_DREGS_with_sub_hi_in_LD8
  { 16, 16, 8, /*VTLists+*/2 },    // DREGS_with_sub_lo_in_LD8
  { 16, 16, 8, /*VTLists+*/2 },    // DREGSNOZ_and_DREGS_with_sub_lo_in_LD8
  { 16, 16, 8, /*VTLists+*/2 },    // DREGS_with_sub_lo_in_GPR8lo
  { 16, 16, 8, /*VTLists+*/2 },    // DREGS_with_sub_hi_in_GPR8lo
  { 16, 16, 8, /*VTLists+*/2 },    // DLDREGS
  { 16, 16, 8, /*VTLists+*/2 },    // DREGS_with_sub_hi_in_LD8lo
  { 16, 16, 8, /*VTLists+*/2 },    // DREGS_with_sub_lo_in_LD8lo
  { 16, 16, 8, /*VTLists+*/2 },    // DREGSlo
  { 16, 16, 8, /*VTLists+*/2 },    // DLDREGS_and_DREGSNOZ
  { 16, 16, 8, /*VTLists+*/2 },    // DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8
  { 16, 16, 8, /*VTLists+*/2 },    // DREGSLD8lo
  { 16, 16, 8, /*VTLists+*/2 },    // IWREGS
  { 16, 16, 8, /*VTLists+*/2 },    // DREGSNOZ_and_IWREGS
  { 16, 16, 8, /*VTLists+*/2 },    // PTRREGS
  { 16, 16, 8, /*VTLists+*/2 },    // DREGSNOZ_and_PTRREGS
  { 16, 16, 8, /*VTLists+*/2 },    // PTRDISPREGS
  { 16, 16, 8, /*VTLists+*/2 },    // DREGSNOZ_and_PTRDISPREGS
  { 16, 16, 8, /*VTLists+*/2 },    // DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8lo
  { 16, 16, 8, /*VTLists+*/2 },    // GPRSP
  { 16, 16, 8, /*VTLists+*/2 },    // ZREG
};
static const uint32_t GPR8SubClassMask[] = {
  0x0000003f, 0x00000000, 
  0x7fffff80, 0x00000001, // sub_hi
  0x7fffff80, 0x00000001, // sub_lo
};

static const uint32_t GPR8NOZSubClassMask[] = {
  0x00000036, 0x00000000, 
  0x6afdd500, 0x00000000, // sub_hi
  0x6afdd500, 0x00000000, // sub_lo
};

static const uint32_t GPR8loSubClassMask[] = {
  0x00000004, 0x00000000, 
  0x00110000, 0x00000000, // sub_hi
  0x40118000, 0x00000000, // sub_lo
};

static const uint32_t LD8SubClassMask[] = {
  0x00000038, 0x00000000, 
  0x7fee7800, 0x00000001, // sub_hi
  0x3fea6000, 0x00000001, // sub_lo
};

static const uint32_t GPR8NOZ_and_LD8SubClassMask[] = {
  0x00000030, 0x00000000, 
  0x6aec5000, 0x00000000, // sub_hi
  0x2ae84000, 0x00000000, // sub_lo
};

static const uint32_t LD8loSubClassMask[] = {
  0x00000020, 0x00000000, 
  0x40c40000, 0x00000000, // sub_hi
  0x00c80000, 0x00000000, // sub_lo
};

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

static const uint32_t DREGSSubClassMask[] = {
  0x7fffff80, 0x00000001, 
};

static const uint32_t DREGSNOZSubClassMask[] = {
  0x6afdd500, 0x00000000, 
};

static const uint32_t DREGSMOVWSubClassMask[] = {
  0x3fb20600, 0x00000001, 
};

static const uint32_t DREGSMOVW_and_DREGSNOZSubClassMask[] = {
  0x2ab00400, 0x00000000, 
};

static const uint32_t DREGS_with_sub_hi_in_LD8SubClassMask[] = {
  0x7fee7800, 0x00000001, 
};

static const uint32_t DREGSNOZ_and_DREGS_with_sub_hi_in_LD8SubClassMask[] = {
  0x6aec5000, 0x00000000, 
};

static const uint32_t DREGS_with_sub_lo_in_LD8SubClassMask[] = {
  0x3fea6000, 0x00000001, 
};

static const uint32_t DREGSNOZ_and_DREGS_with_sub_lo_in_LD8SubClassMask[] = {
  0x2ae84000, 0x00000000, 
};

static const uint32_t DREGS_with_sub_lo_in_GPR8loSubClassMask[] = {
  0x40118000, 0x00000000, 
};

static const uint32_t DREGS_with_sub_hi_in_GPR8loSubClassMask[] = {
  0x00110000, 0x00000000, 
};

static const uint32_t DLDREGSSubClassMask[] = {
  0x3fa20000, 0x00000001, 
};

static const uint32_t DREGS_with_sub_hi_in_LD8loSubClassMask[] = {
  0x40c40000, 0x00000000, 
};

static const uint32_t DREGS_with_sub_lo_in_LD8loSubClassMask[] = {
  0x00c80000, 0x00000000, 
};

static const uint32_t DREGSloSubClassMask[] = {
  0x00100000, 0x00000000, 
};

static const uint32_t DLDREGS_and_DREGSNOZSubClassMask[] = {
  0x2aa00000, 0x00000000, 
};

static const uint32_t DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8SubClassMask[] = {
  0x00c00000, 0x00000000, 
};

static const uint32_t DREGSLD8loSubClassMask[] = {
  0x00800000, 0x00000000, 
};

static const uint32_t IWREGSSubClassMask[] = {
  0x3f000000, 0x00000001, 
};

static const uint32_t DREGSNOZ_and_IWREGSSubClassMask[] = {
  0x2a000000, 0x00000000, 
};

static const uint32_t PTRREGSSubClassMask[] = {
  0x3c000000, 0x00000001, 
};

static const uint32_t DREGSNOZ_and_PTRREGSSubClassMask[] = {
  0x28000000, 0x00000000, 
};

static const uint32_t PTRDISPREGSSubClassMask[] = {
  0x30000000, 0x00000001, 
};

static const uint32_t DREGSNOZ_and_PTRDISPREGSSubClassMask[] = {
  0x20000000, 0x00000000, 
};

static const uint32_t DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8loSubClassMask[] = {
  0x40000000, 0x00000000, 
};

static const uint32_t GPRSPSubClassMask[] = {
  0x80000000, 0x00000000, 
};

static const uint32_t ZREGSubClassMask[] = {
  0x00000000, 0x00000001, 
};

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

static unsigned const GPR8NOZSuperclasses[] = {
  AVR::GPR8RegClassID,
};

static unsigned const GPR8loSuperclasses[] = {
  AVR::GPR8RegClassID,
  AVR::GPR8NOZRegClassID,
};

static unsigned const LD8Superclasses[] = {
  AVR::GPR8RegClassID,
};

static unsigned const GPR8NOZ_and_LD8Superclasses[] = {
  AVR::GPR8RegClassID,
  AVR::GPR8NOZRegClassID,
  AVR::LD8RegClassID,
};

static unsigned const LD8loSuperclasses[] = {
  AVR::GPR8RegClassID,
  AVR::GPR8NOZRegClassID,
  AVR::LD8RegClassID,
  AVR::GPR8NOZ_and_LD8RegClassID,
};

static unsigned const DREGSNOZSuperclasses[] = {
  AVR::DREGSRegClassID,
};

static unsigned const DREGSMOVWSuperclasses[] = {
  AVR::DREGSRegClassID,
};

static unsigned const DREGSMOVW_and_DREGSNOZSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGSMOVWRegClassID,
};

static unsigned const DREGS_with_sub_hi_in_LD8Superclasses[] = {
  AVR::DREGSRegClassID,
};

static unsigned const DREGSNOZ_and_DREGS_with_sub_hi_in_LD8Superclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
};

static unsigned const DREGS_with_sub_lo_in_LD8Superclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
};

static unsigned const DREGSNOZ_and_DREGS_with_sub_lo_in_LD8Superclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
};

static unsigned const DREGS_with_sub_lo_in_GPR8loSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
};

static unsigned const DREGS_with_sub_hi_in_GPR8loSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGS_with_sub_lo_in_GPR8loRegClassID,
};

static unsigned const DLDREGSSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
};

static unsigned const DREGS_with_sub_hi_in_LD8loSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID,
};

static unsigned const DREGS_with_sub_lo_in_LD8loSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_lo_in_LD8RegClassID,
};

static unsigned const DREGSloSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGSMOVW_and_DREGSNOZRegClassID,
  AVR::DREGS_with_sub_lo_in_GPR8loRegClassID,
  AVR::DREGS_with_sub_hi_in_GPR8loRegClassID,
};

static unsigned const DLDREGS_and_DREGSNOZSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGSMOVW_and_DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DLDREGSRegClassID,
};

static unsigned const DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8Superclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DREGS_with_sub_hi_in_LD8loRegClassID,
  AVR::DREGS_with_sub_lo_in_LD8loRegClassID,
};

static unsigned const DREGSLD8loSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGSMOVW_and_DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DLDREGSRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8loRegClassID,
  AVR::DREGS_with_sub_lo_in_LD8loRegClassID,
  AVR::DLDREGS_and_DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8RegClassID,
};

static unsigned const IWREGSSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DLDREGSRegClassID,
};

static unsigned const DREGSNOZ_and_IWREGSSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGSMOVW_and_DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DLDREGSRegClassID,
  AVR::DLDREGS_and_DREGSNOZRegClassID,
  AVR::IWREGSRegClassID,
};

static unsigned const PTRREGSSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DLDREGSRegClassID,
  AVR::IWREGSRegClassID,
};

static unsigned const DREGSNOZ_and_PTRREGSSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGSMOVW_and_DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DLDREGSRegClassID,
  AVR::DLDREGS_and_DREGSNOZRegClassID,
  AVR::IWREGSRegClassID,
  AVR::DREGSNOZ_and_IWREGSRegClassID,
  AVR::PTRREGSRegClassID,
};

static unsigned const PTRDISPREGSSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DLDREGSRegClassID,
  AVR::IWREGSRegClassID,
  AVR::PTRREGSRegClassID,
};

static unsigned const DREGSNOZ_and_PTRDISPREGSSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGSMOVW_and_DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DLDREGSRegClassID,
  AVR::DLDREGS_and_DREGSNOZRegClassID,
  AVR::IWREGSRegClassID,
  AVR::DREGSNOZ_and_IWREGSRegClassID,
  AVR::PTRREGSRegClassID,
  AVR::DREGSNOZ_and_PTRREGSRegClassID,
  AVR::PTRDISPREGSRegClassID,
};

static unsigned const DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8loSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSNOZRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_GPR8loRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8loRegClassID,
};

static unsigned const ZREGSuperclasses[] = {
  AVR::DREGSRegClassID,
  AVR::DREGSMOVWRegClassID,
  AVR::DREGS_with_sub_hi_in_LD8RegClassID,
  AVR::DREGS_with_sub_lo_in_LD8RegClassID,
  AVR::DLDREGSRegClassID,
  AVR::IWREGSRegClassID,
  AVR::PTRREGSRegClassID,
  AVR::PTRDISPREGSRegClassID,
};


namespace AVR {   // Register class instances
  extern const TargetRegisterClass GPR8RegClass = {
    &AVRMCRegisterClasses[GPR8RegClassID],
    GPR8SubClassMask,
    SuperRegIdxSeqs + 0,
    LaneBitmask(0x0000000000000001),
    0,
    false,
    0x00, /* TSFlags */
    false, /* HasDisjunctSubRegs */
    false, /* CoveredBySubRegs */
    nullptr, 0,
    nullptr
  };

  extern const TargetRegisterClass GPR8NOZRegClass = {
    &AVRMCRegisterClasses[GPR8NOZRegClassID],
    GPR8NOZSubClassMask,
    SuperRegIdxSeqs + 0,
    LaneBitmask(0x0000000000000001),
    0,
    false,
    0x00, /* TSFlags */
    false, /* HasDisjunctSubRegs */
    false, /* CoveredBySubRegs */
    GPR8NOZSuperclasses,  1,
    nullptr
  };

  extern const TargetRegisterClass GPR8loRegClass = {
    &AVRMCRegisterClasses[GPR8loRegClassID],
    GPR8loSubClassMask,
    SuperRegIdxSeqs + 0,
    LaneBitmask(0x0000000000000001),
    0,
    false,
    0x00, /* TSFlags */
    false, /* HasDisjunctSubRegs */
    false, /* CoveredBySubRegs */
    GPR8loSuperclasses,  2,
    nullptr
  };

  extern const TargetRegisterClass LD8RegClass = {
    &AVRMCRegisterClasses[LD8RegClassID],
    LD8SubClassMask,
    SuperRegIdxSeqs + 0,
    LaneBitmask(0x0000000000000001),
    0,
    false,
    0x00, /* TSFlags */
    false, /* HasDisjunctSubRegs */
    false, /* CoveredBySubRegs */
    LD8Superclasses,  1,
    nullptr
  };

  extern const TargetRegisterClass GPR8NOZ_and_LD8RegClass = {
    &AVRMCRegisterClasses[GPR8NOZ_and_LD8RegClassID],
    GPR8NOZ_and_LD8SubClassMask,
    SuperRegIdxSeqs + 0,
    LaneBitmask(0x0000000000000001),
    0,
    false,
    0x00, /* TSFlags */
    false, /* HasDisjunctSubRegs */
    false, /* CoveredBySubRegs */
    GPR8NOZ_and_LD8Superclasses,  3,
    nullptr
  };

  extern const TargetRegisterClass LD8loRegClass = {
    &AVRMCRegisterClasses[LD8loRegClassID],
    LD8loSubClassMask,
    SuperRegIdxSeqs + 0,
    LaneBitmask(0x0000000000000001),
    0,
    false,
    0x00, /* TSFlags */
    false, /* HasDisjunctSubRegs */
    false, /* CoveredBySubRegs */
    LD8loSuperclasses,  4,
    nullptr
  };

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

  extern const TargetRegisterClass DREGSRegClass = {
    &AVRMCRegisterClasses[DREGSRegClassID],
    DREGSSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    nullptr, 0,
    nullptr
  };

  extern const TargetRegisterClass DREGSNOZRegClass = {
    &AVRMCRegisterClasses[DREGSNOZRegClassID],
    DREGSNOZSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGSNOZSuperclasses,  1,
    nullptr
  };

  extern const TargetRegisterClass DREGSMOVWRegClass = {
    &AVRMCRegisterClasses[DREGSMOVWRegClassID],
    DREGSMOVWSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGSMOVWSuperclasses,  1,
    nullptr
  };

  extern const TargetRegisterClass DREGSMOVW_and_DREGSNOZRegClass = {
    &AVRMCRegisterClasses[DREGSMOVW_and_DREGSNOZRegClassID],
    DREGSMOVW_and_DREGSNOZSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGSMOVW_and_DREGSNOZSuperclasses,  3,
    nullptr
  };

  extern const TargetRegisterClass DREGS_with_sub_hi_in_LD8RegClass = {
    &AVRMCRegisterClasses[DREGS_with_sub_hi_in_LD8RegClassID],
    DREGS_with_sub_hi_in_LD8SubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGS_with_sub_hi_in_LD8Superclasses,  1,
    nullptr
  };

  extern const TargetRegisterClass DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClass = {
    &AVRMCRegisterClasses[DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClassID],
    DREGSNOZ_and_DREGS_with_sub_hi_in_LD8SubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGSNOZ_and_DREGS_with_sub_hi_in_LD8Superclasses,  3,
    nullptr
  };

  extern const TargetRegisterClass DREGS_with_sub_lo_in_LD8RegClass = {
    &AVRMCRegisterClasses[DREGS_with_sub_lo_in_LD8RegClassID],
    DREGS_with_sub_lo_in_LD8SubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGS_with_sub_lo_in_LD8Superclasses,  2,
    nullptr
  };

  extern const TargetRegisterClass DREGSNOZ_and_DREGS_with_sub_lo_in_LD8RegClass = {
    &AVRMCRegisterClasses[DREGSNOZ_and_DREGS_with_sub_lo_in_LD8RegClassID],
    DREGSNOZ_and_DREGS_with_sub_lo_in_LD8SubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGSNOZ_and_DREGS_with_sub_lo_in_LD8Superclasses,  5,
    nullptr
  };

  extern const TargetRegisterClass DREGS_with_sub_lo_in_GPR8loRegClass = {
    &AVRMCRegisterClasses[DREGS_with_sub_lo_in_GPR8loRegClassID],
    DREGS_with_sub_lo_in_GPR8loSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGS_with_sub_lo_in_GPR8loSuperclasses,  2,
    nullptr
  };

  extern const TargetRegisterClass DREGS_with_sub_hi_in_GPR8loRegClass = {
    &AVRMCRegisterClasses[DREGS_with_sub_hi_in_GPR8loRegClassID],
    DREGS_with_sub_hi_in_GPR8loSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGS_with_sub_hi_in_GPR8loSuperclasses,  3,
    nullptr
  };

  extern const TargetRegisterClass DLDREGSRegClass = {
    &AVRMCRegisterClasses[DLDREGSRegClassID],
    DLDREGSSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DLDREGSSuperclasses,  4,
    nullptr
  };

  extern const TargetRegisterClass DREGS_with_sub_hi_in_LD8loRegClass = {
    &AVRMCRegisterClasses[DREGS_with_sub_hi_in_LD8loRegClassID],
    DREGS_with_sub_hi_in_LD8loSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGS_with_sub_hi_in_LD8loSuperclasses,  4,
    nullptr
  };

  extern const TargetRegisterClass DREGS_with_sub_lo_in_LD8loRegClass = {
    &AVRMCRegisterClasses[DREGS_with_sub_lo_in_LD8loRegClassID],
    DREGS_with_sub_lo_in_LD8loSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGS_with_sub_lo_in_LD8loSuperclasses,  6,
    nullptr
  };

  extern const TargetRegisterClass DREGSloRegClass = {
    &AVRMCRegisterClasses[DREGSloRegClassID],
    DREGSloSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGSloSuperclasses,  6,
    nullptr
  };

  extern const TargetRegisterClass DLDREGS_and_DREGSNOZRegClass = {
    &AVRMCRegisterClasses[DLDREGS_and_DREGSNOZRegClassID],
    DLDREGS_and_DREGSNOZSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DLDREGS_and_DREGSNOZSuperclasses,  9,
    nullptr
  };

  extern const TargetRegisterClass DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8RegClass = {
    &AVRMCRegisterClasses[DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8RegClassID],
    DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8SubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8Superclasses,  8,
    nullptr
  };

  extern const TargetRegisterClass DREGSLD8loRegClass = {
    &AVRMCRegisterClasses[DREGSLD8loRegClassID],
    DREGSLD8loSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGSLD8loSuperclasses,  13,
    nullptr
  };

  extern const TargetRegisterClass IWREGSRegClass = {
    &AVRMCRegisterClasses[IWREGSRegClassID],
    IWREGSSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    IWREGSSuperclasses,  5,
    nullptr
  };

  extern const TargetRegisterClass DREGSNOZ_and_IWREGSRegClass = {
    &AVRMCRegisterClasses[DREGSNOZ_and_IWREGSRegClassID],
    DREGSNOZ_and_IWREGSSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGSNOZ_and_IWREGSSuperclasses,  11,
    nullptr
  };

  extern const TargetRegisterClass PTRREGSRegClass = {
    &AVRMCRegisterClasses[PTRREGSRegClassID],
    PTRREGSSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    PTRREGSSuperclasses,  6,
    nullptr
  };

  extern const TargetRegisterClass DREGSNOZ_and_PTRREGSRegClass = {
    &AVRMCRegisterClasses[DREGSNOZ_and_PTRREGSRegClassID],
    DREGSNOZ_and_PTRREGSSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGSNOZ_and_PTRREGSSuperclasses,  13,
    nullptr
  };

  extern const TargetRegisterClass PTRDISPREGSRegClass = {
    &AVRMCRegisterClasses[PTRDISPREGSRegClassID],
    PTRDISPREGSSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    PTRDISPREGSSuperclasses,  7,
    nullptr
  };

  extern const TargetRegisterClass DREGSNOZ_and_PTRDISPREGSRegClass = {
    &AVRMCRegisterClasses[DREGSNOZ_and_PTRDISPREGSRegClassID],
    DREGSNOZ_and_PTRDISPREGSSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGSNOZ_and_PTRDISPREGSSuperclasses,  15,
    nullptr
  };

  extern const TargetRegisterClass DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8loRegClass = {
    &AVRMCRegisterClasses[DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8loRegClassID],
    DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8loSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8loSuperclasses,  6,
    nullptr
  };

  extern const TargetRegisterClass GPRSPRegClass = {
    &AVRMCRegisterClasses[GPRSPRegClassID],
    GPRSPSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    nullptr, 0,
    nullptr
  };

  extern const TargetRegisterClass ZREGRegClass = {
    &AVRMCRegisterClasses[ZREGRegClassID],
    ZREGSubClassMask,
    SuperRegIdxSeqs + 2,
    LaneBitmask(0x0000000000000003),
    0,
    false,
    0x00, /* TSFlags */
    true, /* HasDisjunctSubRegs */
    true, /* CoveredBySubRegs */
    ZREGSuperclasses,  8,
    nullptr
  };

} // end namespace AVR

namespace {
  const TargetRegisterClass *const RegisterClasses[] = {
    &AVR::GPR8RegClass,
    &AVR::GPR8NOZRegClass,
    &AVR::GPR8loRegClass,
    &AVR::LD8RegClass,
    &AVR::GPR8NOZ_and_LD8RegClass,
    &AVR::LD8loRegClass,
    &AVR::CCRRegClass,
    &AVR::DREGSRegClass,
    &AVR::DREGSNOZRegClass,
    &AVR::DREGSMOVWRegClass,
    &AVR::DREGSMOVW_and_DREGSNOZRegClass,
    &AVR::DREGS_with_sub_hi_in_LD8RegClass,
    &AVR::DREGSNOZ_and_DREGS_with_sub_hi_in_LD8RegClass,
    &AVR::DREGS_with_sub_lo_in_LD8RegClass,
    &AVR::DREGSNOZ_and_DREGS_with_sub_lo_in_LD8RegClass,
    &AVR::DREGS_with_sub_lo_in_GPR8loRegClass,
    &AVR::DREGS_with_sub_hi_in_GPR8loRegClass,
    &AVR::DLDREGSRegClass,
    &AVR::DREGS_with_sub_hi_in_LD8loRegClass,
    &AVR::DREGS_with_sub_lo_in_LD8loRegClass,
    &AVR::DREGSloRegClass,
    &AVR::DLDREGS_and_DREGSNOZRegClass,
    &AVR::DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8RegClass,
    &AVR::DREGSLD8loRegClass,
    &AVR::IWREGSRegClass,
    &AVR::DREGSNOZ_and_IWREGSRegClass,
    &AVR::PTRREGSRegClass,
    &AVR::DREGSNOZ_and_PTRREGSRegClass,
    &AVR::PTRDISPREGSRegClass,
    &AVR::DREGSNOZ_and_PTRDISPREGSRegClass,
    &AVR::DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8loRegClass,
    &AVR::GPRSPRegClass,
    &AVR::ZREGRegClass,
  };
} // 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, 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, false, 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, 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 AVRRegInfoDesc = { // Extra Descriptors
CostPerUseTable, 1, InAllocatableClassTable};

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

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

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

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

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

LaneBitmask AVRGenRegisterInfo::composeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask) const {
  --IdxA; assert(IdxA < 2 && "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 AVRGenRegisterInfo::reverseComposeSubRegIndexLaneMaskImpl(unsigned IdxA,  LaneBitmask LaneMask) const {
  LaneMask &= getSubRegIndexLaneMask(IdxA);
  --IdxA; assert(IdxA < 2 && "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 *AVRGenRegisterInfo::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const {
  static const uint8_t Table[33][2] = {
    {	// GPR8
      0,	// sub_hi
      0,	// sub_lo
    },
    {	// GPR8NOZ
      0,	// sub_hi
      0,	// sub_lo
    },
    {	// GPR8lo
      0,	// sub_hi
      0,	// sub_lo
    },
    {	// LD8
      0,	// sub_hi
      0,	// sub_lo
    },
    {	// GPR8NOZ_and_LD8
      0,	// sub_hi
      0,	// sub_lo
    },
    {	// LD8lo
      0,	// sub_hi
      0,	// sub_lo
    },
    {	// CCR
      0,	// sub_hi
      0,	// sub_lo
    },
    {	// DREGS
      8,	// sub_hi -> DREGS
      8,	// sub_lo -> DREGS
    },
    {	// DREGSNOZ
      9,	// sub_hi -> DREGSNOZ
      9,	// sub_lo -> DREGSNOZ
    },
    {	// DREGSMOVW
      10,	// sub_hi -> DREGSMOVW
      10,	// sub_lo -> DREGSMOVW
    },
    {	// DREGSMOVW_and_DREGSNOZ
      11,	// sub_hi -> DREGSMOVW_and_DREGSNOZ
      11,	// sub_lo -> DREGSMOVW_and_DREGSNOZ
    },
    {	// DREGS_with_sub_hi_in_LD8
      12,	// sub_hi -> DREGS_with_sub_hi_in_LD8
      12,	// sub_lo -> DREGS_with_sub_hi_in_LD8
    },
    {	// DREGSNOZ_and_DREGS_with_sub_hi_in_LD8
      13,	// sub_hi -> DREGSNOZ_and_DREGS_with_sub_hi_in_LD8
      13,	// sub_lo -> DREGSNOZ_and_DREGS_with_sub_hi_in_LD8
    },
    {	// DREGS_with_sub_lo_in_LD8
      14,	// sub_hi -> DREGS_with_sub_lo_in_LD8
      14,	// sub_lo -> DREGS_with_sub_lo_in_LD8
    },
    {	// DREGSNOZ_and_DREGS_with_sub_lo_in_LD8
      15,	// sub_hi -> DREGSNOZ_and_DREGS_with_sub_lo_in_LD8
      15,	// sub_lo -> DREGSNOZ_and_DREGS_with_sub_lo_in_LD8
    },
    {	// DREGS_with_sub_lo_in_GPR8lo
      16,	// sub_hi -> DREGS_with_sub_lo_in_GPR8lo
      16,	// sub_lo -> DREGS_with_sub_lo_in_GPR8lo
    },
    {	// DREGS_with_sub_hi_in_GPR8lo
      17,	// sub_hi -> DREGS_with_sub_hi_in_GPR8lo
      17,	// sub_lo -> DREGS_with_sub_hi_in_GPR8lo
    },
    {	// DLDREGS
      18,	// sub_hi -> DLDREGS
      18,	// sub_lo -> DLDREGS
    },
    {	// DREGS_with_sub_hi_in_LD8lo
      19,	// sub_hi -> DREGS_with_sub_hi_in_LD8lo
      19,	// sub_lo -> DREGS_with_sub_hi_in_LD8lo
    },
    {	// DREGS_with_sub_lo_in_LD8lo
      20,	// sub_hi -> DREGS_with_sub_lo_in_LD8lo
      20,	// sub_lo -> DREGS_with_sub_lo_in_LD8lo
    },
    {	// DREGSlo
      21,	// sub_hi -> DREGSlo
      21,	// sub_lo -> DREGSlo
    },
    {	// DLDREGS_and_DREGSNOZ
      22,	// sub_hi -> DLDREGS_and_DREGSNOZ
      22,	// sub_lo -> DLDREGS_and_DREGSNOZ
    },
    {	// DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8
      23,	// sub_hi -> DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8
      23,	// sub_lo -> DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8
    },
    {	// DREGSLD8lo
      24,	// sub_hi -> DREGSLD8lo
      24,	// sub_lo -> DREGSLD8lo
    },
    {	// IWREGS
      25,	// sub_hi -> IWREGS
      25,	// sub_lo -> IWREGS
    },
    {	// DREGSNOZ_and_IWREGS
      26,	// sub_hi -> DREGSNOZ_and_IWREGS
      26,	// sub_lo -> DREGSNOZ_and_IWREGS
    },
    {	// PTRREGS
      27,	// sub_hi -> PTRREGS
      27,	// sub_lo -> PTRREGS
    },
    {	// DREGSNOZ_and_PTRREGS
      28,	// sub_hi -> DREGSNOZ_and_PTRREGS
      28,	// sub_lo -> DREGSNOZ_and_PTRREGS
    },
    {	// PTRDISPREGS
      29,	// sub_hi -> PTRDISPREGS
      29,	// sub_lo -> PTRDISPREGS
    },
    {	// DREGSNOZ_and_PTRDISPREGS
      30,	// sub_hi -> DREGSNOZ_and_PTRDISPREGS
      30,	// sub_lo -> DREGSNOZ_and_PTRDISPREGS
    },
    {	// DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8lo
      31,	// sub_hi -> DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8lo
      31,	// sub_lo -> DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8lo
    },
    {	// GPRSP
      32,	// sub_hi -> GPRSP
      32,	// sub_lo -> GPRSP
    },
    {	// ZREG
      33,	// sub_hi -> ZREG
      33,	// sub_lo -> ZREG
    },
  };
  assert(RC && "Missing regclass");
  if (!Idx) return RC;
  --Idx;
  assert(Idx < 2 && "Bad subreg");
  unsigned TV = Table[RC->getID()][Idx];
  return TV ? getRegClass(TV - 1) : nullptr;
}

const TargetRegisterClass *AVRGenRegisterInfo::getSubRegisterClass(const TargetRegisterClass *RC, unsigned Idx) const {
  static const uint8_t Table[33][2] = {
    {	// GPR8
      0,	// GPR8:sub_hi
      0,	// GPR8:sub_lo
    },
    {	// GPR8NOZ
      0,	// GPR8NOZ:sub_hi
      0,	// GPR8NOZ:sub_lo
    },
    {	// GPR8lo
      0,	// GPR8lo:sub_hi
      0,	// GPR8lo:sub_lo
    },
    {	// LD8
      0,	// LD8:sub_hi
      0,	// LD8:sub_lo
    },
    {	// GPR8NOZ_and_LD8
      0,	// GPR8NOZ_and_LD8:sub_hi
      0,	// GPR8NOZ_and_LD8:sub_lo
    },
    {	// LD8lo
      0,	// LD8lo:sub_hi
      0,	// LD8lo:sub_lo
    },
    {	// CCR
      0,	// CCR:sub_hi
      0,	// CCR:sub_lo
    },
    {	// DREGS
      1,	// DREGS:sub_hi -> GPR8
      1,	// DREGS:sub_lo -> GPR8
    },
    {	// DREGSNOZ
      2,	// DREGSNOZ:sub_hi -> GPR8NOZ
      2,	// DREGSNOZ:sub_lo -> GPR8NOZ
    },
    {	// DREGSMOVW
      1,	// DREGSMOVW:sub_hi -> GPR8
      1,	// DREGSMOVW:sub_lo -> GPR8
    },
    {	// DREGSMOVW_and_DREGSNOZ
      2,	// DREGSMOVW_and_DREGSNOZ:sub_hi -> GPR8NOZ
      2,	// DREGSMOVW_and_DREGSNOZ:sub_lo -> GPR8NOZ
    },
    {	// DREGS_with_sub_hi_in_LD8
      4,	// DREGS_with_sub_hi_in_LD8:sub_hi -> LD8
      1,	// DREGS_with_sub_hi_in_LD8:sub_lo -> GPR8
    },
    {	// DREGSNOZ_and_DREGS_with_sub_hi_in_LD8
      5,	// DREGSNOZ_and_DREGS_with_sub_hi_in_LD8:sub_hi -> GPR8NOZ_and_LD8
      2,	// DREGSNOZ_and_DREGS_with_sub_hi_in_LD8:sub_lo -> GPR8NOZ
    },
    {	// DREGS_with_sub_lo_in_LD8
      4,	// DREGS_with_sub_lo_in_LD8:sub_hi -> LD8
      4,	// DREGS_with_sub_lo_in_LD8:sub_lo -> LD8
    },
    {	// DREGSNOZ_and_DREGS_with_sub_lo_in_LD8
      5,	// DREGSNOZ_and_DREGS_with_sub_lo_in_LD8:sub_hi -> GPR8NOZ_and_LD8
      5,	// DREGSNOZ_and_DREGS_with_sub_lo_in_LD8:sub_lo -> GPR8NOZ_and_LD8
    },
    {	// DREGS_with_sub_lo_in_GPR8lo
      2,	// DREGS_with_sub_lo_in_GPR8lo:sub_hi -> GPR8NOZ
      3,	// DREGS_with_sub_lo_in_GPR8lo:sub_lo -> GPR8lo
    },
    {	// DREGS_with_sub_hi_in_GPR8lo
      3,	// DREGS_with_sub_hi_in_GPR8lo:sub_hi -> GPR8lo
      3,	// DREGS_with_sub_hi_in_GPR8lo:sub_lo -> GPR8lo
    },
    {	// DLDREGS
      4,	// DLDREGS:sub_hi -> LD8
      4,	// DLDREGS:sub_lo -> LD8
    },
    {	// DREGS_with_sub_hi_in_LD8lo
      6,	// DREGS_with_sub_hi_in_LD8lo:sub_hi -> LD8lo
      2,	// DREGS_with_sub_hi_in_LD8lo:sub_lo -> GPR8NOZ
    },
    {	// DREGS_with_sub_lo_in_LD8lo
      5,	// DREGS_with_sub_lo_in_LD8lo:sub_hi -> GPR8NOZ_and_LD8
      6,	// DREGS_with_sub_lo_in_LD8lo:sub_lo -> LD8lo
    },
    {	// DREGSlo
      3,	// DREGSlo:sub_hi -> GPR8lo
      3,	// DREGSlo:sub_lo -> GPR8lo
    },
    {	// DLDREGS_and_DREGSNOZ
      5,	// DLDREGS_and_DREGSNOZ:sub_hi -> GPR8NOZ_and_LD8
      5,	// DLDREGS_and_DREGSNOZ:sub_lo -> GPR8NOZ_and_LD8
    },
    {	// DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8
      6,	// DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8:sub_hi -> LD8lo
      6,	// DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8:sub_lo -> LD8lo
    },
    {	// DREGSLD8lo
      6,	// DREGSLD8lo:sub_hi -> LD8lo
      6,	// DREGSLD8lo:sub_lo -> LD8lo
    },
    {	// IWREGS
      4,	// IWREGS:sub_hi -> LD8
      4,	// IWREGS:sub_lo -> LD8
    },
    {	// DREGSNOZ_and_IWREGS
      5,	// DREGSNOZ_and_IWREGS:sub_hi -> GPR8NOZ_and_LD8
      5,	// DREGSNOZ_and_IWREGS:sub_lo -> GPR8NOZ_and_LD8
    },
    {	// PTRREGS
      4,	// PTRREGS:sub_hi -> LD8
      4,	// PTRREGS:sub_lo -> LD8
    },
    {	// DREGSNOZ_and_PTRREGS
      5,	// DREGSNOZ_and_PTRREGS:sub_hi -> GPR8NOZ_and_LD8
      5,	// DREGSNOZ_and_PTRREGS:sub_lo -> GPR8NOZ_and_LD8
    },
    {	// PTRDISPREGS
      4,	// PTRDISPREGS:sub_hi -> LD8
      4,	// PTRDISPREGS:sub_lo -> LD8
    },
    {	// DREGSNOZ_and_PTRDISPREGS
      5,	// DREGSNOZ_and_PTRDISPREGS:sub_hi -> GPR8NOZ_and_LD8
      5,	// DREGSNOZ_and_PTRDISPREGS:sub_lo -> GPR8NOZ_and_LD8
    },
    {	// DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8lo
      6,	// DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8lo:sub_hi -> LD8lo
      3,	// DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8lo:sub_lo -> GPR8lo
    },
    {	// GPRSP
      0,	// GPRSP:sub_hi
      0,	// GPRSP:sub_lo
    },
    {	// ZREG
      4,	// ZREG:sub_hi -> LD8
      4,	// ZREG:sub_lo -> LD8
    },
  };
  assert(RC && "Missing regclass");
  if (!Idx) return RC;
  --Idx;
  assert(Idx < 2 && "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 &AVRGenRegisterInfo::
getRegClassWeight(const TargetRegisterClass *RC) const {
  static const RegClassWeight RCWeightTable[] = {
    {1, 32},  	// GPR8
    {1, 30},  	// GPR8NOZ
    {1, 16},  	// GPR8lo
    {1, 16},  	// LD8
    {1, 14},  	// GPR8NOZ_and_LD8
    {1, 8},  	// LD8lo
    {1, 1},  	// CCR
    {2, 32},  	// DREGS
    {2, 30},  	// DREGSNOZ
    {2, 32},  	// DREGSMOVW
    {2, 30},  	// DREGSMOVW_and_DREGSNOZ
    {2, 17},  	// DREGS_with_sub_hi_in_LD8
    {2, 15},  	// DREGSNOZ_and_DREGS_with_sub_hi_in_LD8
    {2, 16},  	// DREGS_with_sub_lo_in_LD8
    {2, 14},  	// DREGSNOZ_and_DREGS_with_sub_lo_in_LD8
    {2, 17},  	// DREGS_with_sub_lo_in_GPR8lo
    {2, 16},  	// DREGS_with_sub_hi_in_GPR8lo
    {2, 16},  	// DLDREGS
    {2, 9},  	// DREGS_with_sub_hi_in_LD8lo
    {2, 9},  	// DREGS_with_sub_lo_in_LD8lo
    {2, 16},  	// DREGSlo
    {2, 14},  	// DLDREGS_and_DREGSNOZ
    {2, 8},  	// DREGS_with_sub_hi_in_LD8lo_and_DREGS_with_sub_lo_in_LD8
    {2, 8},  	// DREGSLD8lo
    {2, 8},  	// IWREGS
    {2, 6},  	// DREGSNOZ_and_IWREGS
    {2, 6},  	// PTRREGS
    {2, 4},  	// DREGSNOZ_and_PTRREGS
    {2, 4},  	// PTRDISPREGS
    {2, 2},  	// DREGSNOZ_and_PTRDISPREGS
    {2, 2},  	// DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8lo
    {2, 2},  	// GPRSP
    {2, 2},  	// ZREG
  };
  return RCWeightTable[RC->getID()];
}

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


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

// Get the name of this register unit pressure set.
const char *AVRGenRegisterInfo::
getRegPressureSetName(unsigned Idx) const {
  static const char *PressureNameTable[] = {
    "CCR",
    "DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8lo",
    "GPRSP",
    "IWREGS",
    "LD8lo",
    "LD8",
    "GPR8lo",
    "GPR8lo_with_LD8lo",
    "GPR8",
  };
  return PressureNameTable[Idx];
}

// Get the register unit pressure limit for this dimension.
// This limit must be adjusted dynamically for reserved registers.
unsigned AVRGenRegisterInfo::
getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const {
  static const uint8_t PressureLimitTable[] = {
    1,  	// 0: CCR
    2,  	// 1: DREGS_with_sub_hi_in_LD8_and_DREGS_with_sub_lo_in_GPR8lo
    2,  	// 2: GPRSP
    8,  	// 3: IWREGS
    10,  	// 4: LD8lo
    17,  	// 5: LD8
    17,  	// 6: GPR8lo
    25,  	// 7: GPR8lo_with_LD8lo
    32,  	// 8: GPR8
  };
  return PressureLimitTable[Idx];
}

/// Table of pressure sets per register class or unit.
static const int RCSetsTable[] = {
  /* 0 */ 0, -1,
  /* 2 */ 2, -1,
  /* 4 */ 3, 5, 8, -1,
  /* 8 */ 3, 4, 5, 7, 8, -1,
  /* 14 */ 1, 4, 5, 6, 7, 8, -1,
};

/// Get the dimensions of register pressure impacted by this register class.
/// Returns a -1 terminated array of pressure set IDs
const int *AVRGenRegisterInfo::
getRegClassPressureSets(const TargetRegisterClass *RC) const {
  static const uint8_t RCSetStartTable[] = {
    6,6,17,5,5,9,0,6,6,6,6,5,5,5,5,17,17,5,9,9,17,5,9,9,4,4,4,4,4,4,14,2,4,};
  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 *AVRGenRegisterInfo::
getRegUnitPressureSets(MCRegUnit RegUnit) const {
  assert(static_cast<unsigned>(RegUnit) < 35 && "invalid register unit");
  static const uint8_t RUSetStartTable[] = {
    2,2,0,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,14,14,9,9,9,9,9,9,9,8,4,4,4,4,4,4,4,};
  return &RCSetsTable[RUSetStartTable[static_cast<unsigned>(RegUnit)]];
}

extern const MCRegisterDesc AVRRegDesc[];
extern const int16_t AVRRegDiffLists[];
extern const LaneBitmask AVRLaneMaskLists[];
extern const char AVRRegStrings[];
extern const char AVRRegClassStrings[];
extern const MCPhysReg AVRRegUnitRoots[][2];
extern const uint16_t AVRSubRegIdxLists[];
extern const uint16_t AVRRegEncodingTable[];
// AVR Dwarf<->LLVM register mappings.
extern const MCRegisterInfo::DwarfLLVMRegPair AVRDwarfFlavour0Dwarf2L[];
extern const unsigned AVRDwarfFlavour0Dwarf2LSize;

extern const MCRegisterInfo::DwarfLLVMRegPair AVREHFlavour0Dwarf2L[];
extern const unsigned AVREHFlavour0Dwarf2LSize;

extern const MCRegisterInfo::DwarfLLVMRegPair AVRDwarfFlavour0L2Dwarf[];
extern const unsigned AVRDwarfFlavour0L2DwarfSize;

extern const MCRegisterInfo::DwarfLLVMRegPair AVREHFlavour0L2Dwarf[];
extern const unsigned AVREHFlavour0L2DwarfSize;

AVRGenRegisterInfo::
AVRGenRegisterInfo(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,
      unsigned PC, unsigned HwMode)
  : TargetRegisterInfo(&AVRRegInfoDesc, RegisterClasses, RegisterClasses+33,
             SubRegIndexNameTable, SubRegIdxRangeTable, SubRegIndexLaneMaskTable,
             LaneBitmask(0xFFFFFFFFFFFFFFFF), RegClassInfos, VTLists, HwMode) {
  InitMCRegisterInfo(AVRRegDesc, 62, RA, PC,
                     AVRMCRegisterClasses, 33,
                     AVRRegUnitRoots,
                     35,
                     AVRRegDiffLists,
                     AVRLaneMaskLists,
                     AVRRegStrings,
                     AVRRegClassStrings,
                     AVRSubRegIdxLists,
                     3,
                     AVRRegEncodingTable);

  switch (DwarfFlavour) {
  default:
    llvm_unreachable("Unknown DWARF flavour");
  case 0:
    mapDwarfRegsToLLVMRegs(AVRDwarfFlavour0Dwarf2L, AVRDwarfFlavour0Dwarf2LSize, false);
    break;
  }
  switch (EHFlavour) {
  default:
    llvm_unreachable("Unknown DWARF flavour");
  case 0:
    mapDwarfRegsToLLVMRegs(AVREHFlavour0Dwarf2L, AVREHFlavour0Dwarf2LSize, true);
    break;
  }
  switch (DwarfFlavour) {
  default:
    llvm_unreachable("Unknown DWARF flavour");
  case 0:
    mapLLVMRegsToDwarfRegs(AVRDwarfFlavour0L2Dwarf, AVRDwarfFlavour0L2DwarfSize, false);
    break;
  }
  switch (EHFlavour) {
  default:
    llvm_unreachable("Unknown DWARF flavour");
  case 0:
    mapLLVMRegsToDwarfRegs(AVREHFlavour0L2Dwarf, AVREHFlavour0L2DwarfSize, true);
    break;
  }
}

static const MCPhysReg CSR_Interrupts_SaveList[] = { AVR::R31, AVR::R30, AVR::R29, AVR::R28, AVR::R27, AVR::R26, AVR::R25, AVR::R24, AVR::R23, AVR::R22, AVR::R21, AVR::R20, AVR::R19, AVR::R18, AVR::R17, AVR::R16, AVR::R15, AVR::R14, AVR::R13, AVR::R12, AVR::R11, AVR::R10, AVR::R9, AVR::R8, AVR::R7, AVR::R6, AVR::R5, AVR::R4, AVR::R3, AVR::R2, 0 };
static const uint32_t CSR_Interrupts_RegMask[] = { 0xffffff80, 0x3fffffdf, };
static const MCPhysReg CSR_InterruptsTiny_SaveList[] = { AVR::R31, AVR::R30, AVR::R29, AVR::R28, AVR::R27, AVR::R26, AVR::R25, AVR::R24, AVR::R23, AVR::R22, AVR::R21, AVR::R20, AVR::R19, AVR::R18, 0 };
static const uint32_t CSR_InterruptsTiny_RegMask[] = { 0xff800000, 0x3ff8001f, };
static const MCPhysReg CSR_Normal_SaveList[] = { AVR::R29, AVR::R28, AVR::R17, AVR::R16, AVR::R15, AVR::R14, AVR::R13, AVR::R12, AVR::R11, AVR::R10, AVR::R9, AVR::R8, AVR::R7, AVR::R6, AVR::R5, AVR::R4, AVR::R3, AVR::R2, 0 };
static const uint32_t CSR_Normal_RegMask[] = { 0x007fff80, 0x1003ffc6, };
static const MCPhysReg CSR_NormalTiny_SaveList[] = { AVR::R29, AVR::R28, AVR::R19, AVR::R18, 0 };
static const uint32_t CSR_NormalTiny_RegMask[] = { 0x01800000, 0x10080006, };


ArrayRef<const uint32_t *> AVRGenRegisterInfo::getRegMasks() const {
  static const uint32_t *const Masks[] = {
    CSR_Interrupts_RegMask,
    CSR_InterruptsTiny_RegMask,
    CSR_Normal_RegMask,
    CSR_NormalTiny_RegMask,
  };
  return ArrayRef(Masks);
}

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

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

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

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

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

ArrayRef<const char *> AVRGenRegisterInfo::getRegMaskNames() const {
  static const char *Names[] = {
    "CSR_Interrupts",
    "CSR_InterruptsTiny",
    "CSR_Normal",
    "CSR_NormalTiny",
  };
  return ArrayRef(Names);
}

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

} // end namespace llvm

