blob: ec8f90c4a4113d0e9c27eaef0b20d225dfb82a0f [file] [log] [blame] [edit]
// RUN: llvm-tblgen --gen-subtarget -I %p/../../include -I %S %s -o - | FileCheck --check-prefix=SUBTARGET %s
// RUN: llvm-tblgen --gen-instr-info -I %p/../../include -I %S %s -o - | FileCheck --check-prefix=INSTRINFO %s
// RUN: llvm-tblgen --gen-asm-matcher -I %p/../../include -I %S %s -o - | FileCheck --check-prefix=ASMMATCHER %s
// RUN: llvm-tblgen --gen-pseudo-lowering -I %p/../../include -I %S %s -o - | FileCheck --check-prefix=PSEUDO %s
// RUN: llvm-tblgen --gen-asm-writer -I %p/../../include -I %S %s -o - | FileCheck --check-prefix=ASMWRITER %s
/// The RegInfo output is split over multiple files:
// RUN: llvm-tblgen --gen-register-info -I %p/../../include -I %S %s -o %t.inc
// RUN: FileCheck %s --input-file=%tEnums.inc --check-prefix=REGINFO-HEADER
// RUN: FileCheck %s --input-file=%tMCDesc.inc --check-prefix=REGINFO-MCDESC
/// Note: No impact on disassembler (handled by the alias expansion), so not tested here
/// Note: DAGIsel is not supported yet
// RUNTODO: llvm-tblgen --gen-dag-isel -I %p/../../include -I %S %s -o -
// RUNTODO: llvm-tblgen --gen-global-isel -I %p/../../include -I %S %s -o -
// REGINFO-HEADER-LABEL: // Registers by HwMode
// REGINFO-HEADER-NEXT: class MCRegister;
// REGINFO-HEADER-NEXT: namespace MyTarget::RegisterByHwMode {
// REGINFO-HEADER-EMPTY:
// REGINFO-HEADER-NEXT: LLVM_READONLY MCRegister getModeCountReg(unsigned HwMode);
// REGINFO-HEADER-NEXT: LLVM_READONLY MCRegister getNullReg(unsigned HwMode);
// REGINFO-HEADER-NEXT: LLVM_READONLY MCRegister getPtrRegFor64BitModesOnly(unsigned HwMode);
// REGINFO-HEADER-EMPTY:
// REGINFO-HEADER-NEXT: } // namespace MyTarget::RegisterByHwMode
// REGINFO-HEADER-EMPTY:
// REGINFO-HEADER-NEXT: } // namespace llvm
// REGINFO-MCDESC-LABEL: // Registers by HwMode
// REGINFO-MCDESC-NEXT: namespace MyTarget::RegisterByHwMode {
// REGINFO-MCDESC-EMPTY:
// REGINFO-MCDESC-NEXT: LLVM_READONLY MCRegister getModeCountReg(unsigned HwMode) {
// REGINFO-MCDESC-NEXT: switch (HwMode) {
// REGINFO-MCDESC-NEXT: case 0: return MyTarget::X0; // DefaultMode
// REGINFO-MCDESC-NEXT: case 1: return MyTarget::X1; // XPtr64
// REGINFO-MCDESC-NEXT: case 2: return MyTarget::X2; // YPtr32
// REGINFO-MCDESC-NEXT: case 3: return MyTarget::X3; // YPtr64
// REGINFO-MCDESC-NEXT: default: llvm_unreachable("Unhandled HwMode for Register ModeCountReg");
// REGINFO-MCDESC-NEXT: }
// REGINFO-MCDESC-NEXT: }
// REGINFO-MCDESC-NEXT: LLVM_READONLY MCRegister getNullReg(unsigned HwMode) {
// REGINFO-MCDESC-NEXT: switch (HwMode) {
// REGINFO-MCDESC-NEXT: case 0: return MyTarget::X0; // DefaultMode
// REGINFO-MCDESC-NEXT: case 1: return MyTarget::X0; // XPtr64
// REGINFO-MCDESC-NEXT: case 2: return MyTarget::Y0; // YPtr32
// REGINFO-MCDESC-NEXT: case 3: return MyTarget::Y0; // YPtr64
// REGINFO-MCDESC-NEXT: default: llvm_unreachable("Unhandled HwMode for Register NullReg");
// REGINFO-MCDESC-NEXT: }
// REGINFO-MCDESC-NEXT: }
// REGINFO-MCDESC-NEXT: LLVM_READONLY MCRegister getPtrRegFor64BitModesOnly(unsigned HwMode) {
// REGINFO-MCDESC-NEXT: switch (HwMode) {
// REGINFO-MCDESC-NEXT: case 1: return MyTarget::X1; // XPtr64
// REGINFO-MCDESC-NEXT: case 3: return MyTarget::Y1; // YPtr64
// REGINFO-MCDESC-NEXT: default: llvm_unreachable("Unhandled HwMode for Register PtrRegFor64BitModesOnly");
// REGINFO-MCDESC-NEXT: }
// REGINFO-MCDESC-NEXT: }
// REGINFO-MCDESC-EMPTY:
// REGINFO-MCDESC-NEXT: } // namespace MyTarget::RegisterByHwMode
// REGINFO-MCDESC-EMPTY:
// REGINFO-MCDESC-NEXT: } // namespace llvm
// SUBTARGET-LABEL: enum class MyTargetHwModeBits : unsigned {
// SUBTARGET-NEXT: DefaultMode = 0,
// SUBTARGET-NEXT: XPtr64 = (1 << 0),
// SUBTARGET-NEXT: YPtr32 = (1 << 1),
// SUBTARGET-NEXT: YPtr64 = (1 << 2),
// SUBTARGET-EMPTY:
// SUBTARGET-NEXT: LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/YPtr64),
// SUBTARGET-NEXT: };
// SUBTARGET-NEXT: unsigned getHwModeSet() const final;
// SUBTARGET-NEXT: unsigned getHwMode(enum HwModeType type = HwMode_Default) const final;
// SUBTARGET-LABEL: unsigned MyTargetGenSubtargetInfo::getHwModeSet() const {
// SUBTARGET{LITERAL}:[[maybe_unused]] const auto *Subtarget =
// SUBTARGET-NEXT: static_cast<const MyTargetSubtarget *>(this);
// SUBTARGET-NEXT: // Collect HwModes and store them as a bit set.
// SUBTARGET-NEXT: unsigned Modes = 0;
// SUBTARGET-NEXT: if ((Subtarget->is64Bit()) && (!Subtarget->useYRegForPtr())) Modes |= (1 << 0);
// SUBTARGET-NEXT: if ((!Subtarget->is64Bit()) && (Subtarget->useYRegForPtr())) Modes |= (1 << 1);
// SUBTARGET-NEXT: if ((Subtarget->is64Bit()) && (Subtarget->useYRegForPtr())) Modes |= (1 << 2);
// SUBTARGET-NEXT: return Modes;
// SUBTARGET-NEXT:}
// INSTRINFO-LABEL: extern const MyTargetInstrTable MyTargetDescs
// INSTRINFO: { MyTarget::EvenPtrRC, 0|(1<<MCOI::LookupRegClassByHwMode), MCOI::OPERAND_REGISTER, 0 },
// INSTRINFO-NEXT: { MyTarget::EvenXRegsRegClassID, 0, MCOI::OPERAND_REGISTER, 0 },
// INSTRINFO-NEXT: { MyTarget::PtrRC, 0|(1<<MCOI::LookupRegClassByHwMode), MCOI::OPERAND_REGISTER, 0 }, { MyTarget::PtrRC, 0|(1<<MCOI::LookupRegClassByHwMode), MCOI::OPERAND_REGISTER, 0 },
// INSTRINFO-NEXT: { MyTarget::XRegsRegClassID, 0, MCOI::OPERAND_REGISTER, 0 }, { MyTarget::XRegsRegClassID, 0, MCOI::OPERAND_REGISTER, 0 },
// INSTRINFO-NEXT: { MyTarget::YRegsRegClassID, 0, MCOI::OPERAND_REGISTER, 0 }, { MyTarget::YRegsRegClassID, 0, MCOI::OPERAND_REGISTER, 0 },
// INSTRINFO-LABEL: extern const int16_t MyTargetRegClassByHwModeTables[4][2] = {
// INSTRINFO-NEXT: { // DefaultMode
// INSTRINFO-NEXT: MyTarget::EvenXRegsRegClassID,
// INSTRINFO-NEXT: MyTarget::XRegsRegClassID,
// INSTRINFO-NEXT: },
// INSTRINFO-NEXT: { // XPtr64
// INSTRINFO-NEXT: MyTarget::EvenXRegsRegClassID,
// INSTRINFO-NEXT: MyTarget::XRegsRegClassID,
// INSTRINFO-NEXT: },
// INSTRINFO-NEXT: { // YPtr32
// INSTRINFO-NEXT: MyTarget::EvenYRegsRegClassID,
// INSTRINFO-NEXT: MyTarget::YRegsRegClassID,
// INSTRINFO-NEXT: },
// INSTRINFO-NEXT: { // YPtr64
// INSTRINFO-NEXT: MyTarget::EvenYRegsRegClassID,
// INSTRINFO-NEXT: MyTarget::YRegsRegClassID,
// INSTRINFO-NEXT: },
// INSTRINFO-NEXT: };
// ASMWRITER-LABEL: static const AliasPatternCond Conds[] = {
// ASMWRITER-NEXT: // (TEST_PTRREG PtrRC:$dst, PtrRC:$src) -
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClassByHwMode, MyTarget::PtrRC},
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClassByHwMode, MyTarget::PtrRC},
// ASMWRITER-NEXT: // (TEST_PTRREG EvenPtrRC:$dst, EvenPtrRC:$src) -
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClassByHwMode, MyTarget::EvenPtrRC},
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClassByHwMode, MyTarget::EvenPtrRC},
// ASMWRITER-NEXT: // (TEST_PTRREG NullReg, PtrRC:$src) -
// ASMWRITER-NEXT: {AliasPatternCond::K_Custom, 1/*NullReg*/},
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClassByHwMode, MyTarget::PtrRC},
// ASMWRITER-NEXT: // (TEST_PTRREG NullReg, EvenPtrRC:$src) -
// ASMWRITER-NEXT: {AliasPatternCond::K_Custom, 1/*NullReg*/},
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClassByHwMode, MyTarget::EvenPtrRC},
// ASMWRITER-NEXT: // (TEST_PTRREG PtrRegFor64BitModesOnly, PtrRC:$src) - 8
// ASMWRITER-NEXT: {AliasPatternCond::K_Custom, 2/*PtrRegFor64BitModesOnly*/},
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClassByHwMode, MyTarget::PtrRC},
// ASMWRITER-NEXT: // (TEST_XREG X0, XRegs:$src) -
// ASMWRITER-NEXT: {AliasPatternCond::K_Reg, MyTarget::X0},
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClass, MyTarget::XRegsRegClassID},
// ASMWRITER-NEXT: // (TEST_XREG X0, EvenXRegs:$src) -
// ASMWRITER-NEXT: {AliasPatternCond::K_Reg, MyTarget::X0},
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClass, MyTarget::EvenXRegsRegClassID},
// ASMWRITER-NEXT: // (TEST_XREG ModeCountReg, XRegs:$src) -
// ASMWRITER-NEXT: {AliasPatternCond::K_Custom, 3/*ModeCountReg*/},
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClass, MyTarget::XRegsRegClassID},
// ASMWRITER-NEXT: // (TEST_YREG Y0, YRegs:$src) -
// ASMWRITER-NEXT: {AliasPatternCond::K_Reg, MyTarget::Y0},
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClass, MyTarget::YRegsRegClassID},
// ASMWRITER-NEXT: // (TEST_YREG Y0, EvenYRegs:$src) -
// ASMWRITER-NEXT: {AliasPatternCond::K_Reg, MyTarget::Y0},
// ASMWRITER-NEXT: {AliasPatternCond::K_RegClass, MyTarget::EvenYRegsRegClassID},
// ASMWRITER-NEXT: };
// ASMWRITER-LABEL: static bool MyTargetInstPrinterValidateMCOperand(const MCOperand &MCOp,
// ASMWRITER-NEXT: const MCSubtargetInfo &STI,
// ASMWRITER-NEXT: unsigned PredicateIndex) {
// ASMWRITER-NEXT: switch (PredicateIndex) {
// ASMWRITER-NEXT: default:
// ASMWRITER-NEXT: llvm_unreachable("Unknown MCOperandPredicate kind");
// ASMWRITER-NEXT: break;
// ASMWRITER-NEXT: case 1: {
// ASMWRITER-NEXT: return MCOp.isReg() && MCOp.getReg() == MyTarget::RegisterByHwMode::getNullReg(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo));
// ASMWRITER-NEXT: }
// ASMWRITER-NEXT: case 2: {
// ASMWRITER-NEXT: return MCOp.isReg() && MCOp.getReg() == MyTarget::RegisterByHwMode::getPtrRegFor64BitModesOnly(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo));
// ASMWRITER-NEXT: }
// ASMWRITER-NEXT: case 3: {
// ASMWRITER-NEXT: return MCOp.isReg() && MCOp.getReg() == MyTarget::RegisterByHwMode::getModeCountReg(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo));
// ASMWRITER-NEXT: }
// ASMWRITER-NEXT: }
// ASMWRITER-NEXT: }
// ASMMATCHER-LABEL: enum InstructionConversionKind {
// ASMMATCHER-NEXT: Convert__regModeCountReg__Reg1_0,
// ASMMATCHER-NEXT: Convert__regNullReg__RegByHwMode_PtrRC1_0,
// ASMMATCHER-NEXT: Convert__regNullReg__RegByHwMode_EvenPtrRC1_0,
// ASMMATCHER-NEXT: Convert__regX0__Reg1_0,
// ASMMATCHER-NEXT: Convert__regY0__Reg1_0,
// ASMMATCHER-NEXT: Convert__regPtrRegFor64BitModesOnly__RegByHwMode_PtrRC1_0,
// ASMMATCHER-NEXT: Convert__RegByHwMode_PtrRC1_0__RegByHwMode_PtrRC1_1,
// ASMMATCHER-NEXT: Convert__RegByHwMode_EvenPtrRC1_0__RegByHwMode_EvenPtrRC1_1,
// ASMMATCHER-NEXT: Convert__Reg1_0__Reg1_1,
// ASMMATCHER-NEXT: CVT_NUM_SIGNATURES
// ASMMATCHER-NEXT: };
// ASMMATCHER-LABEL: static const uint8_t ConversionTable[CVT_NUM_SIGNATURES][5] = {
// ASMMATCHER-NEXT: // Convert__regModeCountReg__Reg1_0
// ASMMATCHER-NEXT: { CVT_regModeCountReg, 0, CVT_95_Reg, 1, CVT_Done },
// ASMMATCHER-NEXT: // Convert__regNullReg__RegByHwMode_PtrRC1_0
// ASMMATCHER-NEXT: { CVT_regNullReg, 0, CVT_95_addRegOperands, 1, CVT_Done },
// ASMMATCHER-NEXT: // Convert__regNullReg__RegByHwMode_EvenPtrRC1_0
// ASMMATCHER-NEXT: { CVT_regNullReg, 0, CVT_95_addRegOperands, 1, CVT_Done },
// ASMMATCHER-NEXT: // Convert__regX0__Reg1_0
// ASMMATCHER-NEXT: { CVT_regX0, 0, CVT_95_Reg, 1, CVT_Done },
// ASMMATCHER-NEXT: // Convert__regY0__Reg1_0
// ASMMATCHER-NEXT: { CVT_regY0, 0, CVT_95_Reg, 1, CVT_Done },
// ASMMATCHER-NEXT: // Convert__regPtrRegFor64BitModesOnly__RegByHwMode_PtrRC1_0
// ASMMATCHER-NEXT: { CVT_regPtrRegFor64BitModesOnly, 0, CVT_95_addRegOperands, 1, CVT_Done },
// ASMMATCHER-NEXT: // Convert__RegByHwMode_PtrRC1_0__RegByHwMode_PtrRC1_1
// ASMMATCHER-NEXT: { CVT_95_addRegOperands, 1, CVT_95_addRegOperands, 2, CVT_Done },
// ASMMATCHER-NEXT: // Convert__RegByHwMode_EvenPtrRC1_0__RegByHwMode_EvenPtrRC1_1
// ASMMATCHER-NEXT: { CVT_95_addRegOperands, 1, CVT_95_addRegOperands, 2, CVT_Done },
// ASMMATCHER-NEXT: // Convert__Reg1_0__Reg1_1
// ASMMATCHER-NEXT: { CVT_95_Reg, 1, CVT_95_Reg, 2, CVT_Done },
// ASMMATCHER-NEXT: };
// ASMMATCHER-LABEL: convertToMCInst(unsigned Kind, MCInst &Inst, unsigned Opcode,
// ASMMATCHER-LABEL: case CVT_regModeCountReg:
// ASMMATCHER-NEXT: Inst.addOperand(MCOperand::createReg(MyTarget::RegisterByHwMode::getModeCountReg(STI->getHwMode(MCSubtargetInfo::HwMode_RegInfo))));
// ASMMATCHER-NEXT: break;
// ASMMATCHER-NEXT: case CVT_95_Reg:
// ASMMATCHER-NEXT: static_cast<MyTargetOperand &>(*Operands[OpIdx]).addRegOperands(Inst, 1);
// ASMMATCHER-NEXT: break;
// ASMMATCHER-NEXT: case CVT_regNullReg:
// ASMMATCHER-NEXT: Inst.addOperand(MCOperand::createReg(MyTarget::RegisterByHwMode::getNullReg(STI->getHwMode(MCSubtargetInfo::HwMode_RegInfo))));
// ASMMATCHER-NEXT: break;
// ASMMATCHER-NEXT: case CVT_95_addRegOperands:
// ASMMATCHER-NEXT: static_cast<MyTargetOperand &>(*Operands[OpIdx]).addRegOperands(Inst, 1);
// ASMMATCHER-NEXT: break;
// ASMMATCHER-NEXT: case CVT_regX0:
// ASMMATCHER-NEXT: Inst.addOperand(MCOperand::createReg(MyTarget::X0));
// ASMMATCHER-NEXT: break;
// ASMMATCHER-NEXT: case CVT_regY0:
// ASMMATCHER-NEXT: Inst.addOperand(MCOperand::createReg(MyTarget::Y0));
// ASMMATCHER-NEXT: break;
// ASMMATCHER-NEXT: case CVT_regPtrRegFor64BitModesOnly:
// ASMMATCHER-NEXT: Inst.addOperand(MCOperand::createReg(MyTarget::RegisterByHwMode::getPtrRegFor64BitModesOnly(STI->getHwMode(MCSubtargetInfo::HwMode_RegInfo))));
// ASMMATCHER-NEXT: break;
// ASMMATCHER-NEXT: }
// ASMMATCHER-LABEL: enum MatchClassKind {
// ASMMATCHER-NEXT: InvalidMatchClass = 0,
// ASMMATCHER-NEXT: OptionalMatchClass = 1,
// ASMMATCHER-NEXT: MCK_LAST_TOKEN = OptionalMatchClass,
// ASMMATCHER-NEXT: MCK_EvenXRegs, // register class 'EvenXRegs'
// ASMMATCHER-NEXT: MCK_EvenYRegs, // register class 'EvenYRegs'
// ASMMATCHER-NEXT: MCK_XRegs, // register class 'XRegs'
// ASMMATCHER-NEXT: MCK_YRegs, // register class 'YRegs'
// ASMMATCHER-NEXT: MCK_LAST_REGISTER = MCK_YRegs,
// ASMMATCHER-NEXT: MCK_RegByHwMode_EvenPtrRC, // register class by hwmode
// ASMMATCHER-NEXT: MCK_RegByHwMode_PtrRC, // register class by hwmode
// ASMMATCHER-NEXT: MCK_LAST_REGCLASS_BY_HWMODE = MCK_RegByHwMode_PtrRC,
// ASMMATCHER-NEXT: MCK_Imm, // user defined class 'ImmAsmOperand'
// ASMMATCHER-NEXT: NumMatchClassKinds
// ASMMATCHER-NEXT: };
// ASMMATCHER-LABEL: static const MatchEntry MatchTable0[] = {
// ASMMATCHER-NEXT: /* mode_count */, MyTarget::TEST_XREG, Convert__regModeCountReg__Reg1_0, AMFBS_None, { MCK_XRegs }, },
// ASMMATCHER-NEXT: /* t_ptr */, MyTarget::TEST_PTRREG, Convert__regNullReg__RegByHwMode_PtrRC1_0, AMFBS_None, { MCK_RegByHwMode_PtrRC }, },
// ASMMATCHER-NEXT: /* t_ptr.even */, MyTarget::TEST_PTRREG, Convert__regNullReg__RegByHwMode_EvenPtrRC1_0, AMFBS_None, { MCK_RegByHwMode_EvenPtrRC }, },
// ASMMATCHER-NEXT: /* t_x */, MyTarget::TEST_XREG, Convert__regX0__Reg1_0, AMFBS_None, { MCK_XRegs }, },
// ASMMATCHER-NEXT: /* t_x.even */, MyTarget::TEST_XREG, Convert__regX0__Reg1_0, AMFBS_None, { MCK_EvenXRegs }, },
// ASMMATCHER-NEXT: /* t_y */, MyTarget::TEST_YREG, Convert__regY0__Reg1_0, AMFBS_None, { MCK_YRegs }, },
// ASMMATCHER-NEXT: /* t_y.even */, MyTarget::TEST_YREG, Convert__regY0__Reg1_0, AMFBS_None, { MCK_EvenYRegs }, },
// ASMMATCHER-NEXT: /* test_64_only */, MyTarget::TEST_PTRREG, Convert__regPtrRegFor64BitModesOnly__RegByHwMode_PtrRC1_0, AMFBS_None, { MCK_RegByHwMode_PtrRC }, },
// ASMMATCHER-NEXT: /* test_alias */, MyTarget::TEST_PTRREG, Convert__RegByHwMode_PtrRC1_0__RegByHwMode_PtrRC1_1, AMFBS_None, { MCK_RegByHwMode_PtrRC, MCK_RegByHwMode_PtrRC }, },
// ASMMATCHER-NEXT: /* test_alias.even */, MyTarget::TEST_PTRREG, Convert__RegByHwMode_EvenPtrRC1_0__RegByHwMode_EvenPtrRC1_1, AMFBS_None, { MCK_RegByHwMode_EvenPtrRC, MCK_RegByHwMode_EvenPtrRC }, },
// ASMMATCHER-NEXT: /* test_ptr */, MyTarget::TEST_PTRREG, Convert__RegByHwMode_PtrRC1_0__RegByHwMode_PtrRC1_1, AMFBS_None, { MCK_RegByHwMode_PtrRC, MCK_RegByHwMode_PtrRC }, },
// ASMMATCHER-NEXT: /* test_x */, MyTarget::TEST_XREG, Convert__Reg1_0__Reg1_1, AMFBS_None, { MCK_XRegs, MCK_XRegs }, },
// ASMMATCHER-NEXT: /* test_y */, MyTarget::TEST_YREG, Convert__Reg1_0__Reg1_1, AMFBS_None, { MCK_YRegs, MCK_YRegs }, },
// ASMMATCHER-NEXT: };
include "Common/RegisterByHwModeCommon.td"
// Define more restrictive subset classes to check that those are handled.
def EvenXRegs : RegisterClass<"MyTarget", [XLenVT], 32, (add X0, X2)> {
let RegInfos = XLenRI; // Needed to determine size of registers
}
def EvenYRegs : RegisterClass<"MyTarget", [YLenVT], 64, (add Y0, Y2)> {
let RegInfos = YLenRI; // Needed to determine size of registers
}
def EvenPtrRC : RegClassByHwMode<[XPtr32, XPtr64, YPtr32, YPtr64],
[EvenXRegs, EvenXRegs, EvenYRegs, EvenYRegs]>;
def MY_TEST_ALIAS : InstAlias<"test_alias $dst, $src", (TEST_PTRREG PtrRC:$dst, PtrRC:$src)>;
def MY_TEST_ALIAS_EVEN : InstAlias<"test_alias.even $dst, $src", (TEST_PTRREG EvenPtrRC:$dst, EvenPtrRC:$src)>;
def MY_T_X : InstAlias<"t_x $src", (TEST_XREG X0, XRegs:$src)>;
def MY_T_X_EVEN : InstAlias<"t_x.even $src", (TEST_XREG X0, EvenXRegs:$src)>;
def MY_T_Y : InstAlias<"t_y $src", (TEST_YREG Y0, YRegs:$src)>;
def MY_T_Y_EVEN : InstAlias<"t_y.even $src", (TEST_YREG Y0, EvenYRegs:$src)>;
def MY_T_PTR : InstAlias<"t_ptr $src", (TEST_PTRREG NullReg, PtrRC:$src)>;
def MY_T_PTR_EVEN : InstAlias<"t_ptr.even $src", (TEST_PTRREG NullReg, EvenPtrRC:$src)>;
/// Add another test where the register number varies, but the regclass doesn't
def ModeCountReg : RegisterByHwMode<XRegs, [XPtr32, XPtr64, YPtr32, YPtr64],
[X0, X1, X2, X3]>;
def TEST_MODE_COUNT : InstAlias<"mode_count $src", (TEST_XREG ModeCountReg, XRegs:$src)>;
/// Test where we don't have valid values for RegisterByHwMode cases:
def PtrRegFor64BitModesOnly : RegisterByHwMode<PtrRC, [XPtr64, YPtr64], [X1, Y1]>;
let Predicates = [Is64Bit] in
def TEST_64_ONLY : InstAlias<"test_64_only $src", (TEST_PTRREG PtrRegFor64BitModesOnly, PtrRC:$src)>;
/// Include a test for -gen-pseudo-lowering:
class Pseudo<dag outs, dag ins> : TestInstruction {
let OutOperandList = outs;
let InOperandList = ins;
let isPseudo = 1;
let isCodeGenOnly = 1;
}
// PSEUDO-LABEL: lowerPseudoInstExpansion(const MachineInstr *MI, MCInst &Inst)
// PSEUDO-NEXT: Inst.clear();
// PSEUDO-NEXT: switch (MI->getOpcode()) {
// PSEUDO-NEXT: default: return false;
// PSEUDO-NEXT: case MyTarget::Pseudo64Only: {
// PSEUDO-NEXT: MCOperand MCOp;
// PSEUDO-NEXT: Inst.setOpcode(MyTarget::TEST_PTRREG);
// PSEUDO-NEXT: // Operand: dst
// PSEUDO-NEXT: Inst.addOperand(MCOperand::createReg(MyTarget::RegisterByHwMode::getPtrRegFor64BitModesOnly(STI->getHwMode(MCSubtargetInfo::HwMode_RegInfo))));
// PSEUDO-NEXT: // Operand: src
// PSEUDO-NEXT: lowerOperand(MI->getOperand(0), MCOp);
// PSEUDO-NEXT: Inst.addOperand(MCOp);
// PSEUDO-NEXT: break;
// PSEUDO-NEXT: }
// PSEUDO-NEXT: case MyTarget::PseudoPtr: {
// PSEUDO-NEXT: MCOperand MCOp;
// PSEUDO-NEXT: Inst.setOpcode(MyTarget::TEST_PTRREG);
// PSEUDO-NEXT: // Operand: dst
// PSEUDO-NEXT: Inst.addOperand(MCOperand::createReg(MyTarget::RegisterByHwMode::getNullReg(STI->getHwMode(MCSubtargetInfo::HwMode_RegInfo))));
// PSEUDO-NEXT: // Operand: src
// PSEUDO-NEXT: lowerOperand(MI->getOperand(0), MCOp);
// PSEUDO-NEXT: Inst.addOperand(MCOp);
// PSEUDO-NEXT: break;
// PSEUDO-NEXT: }
// PSEUDO-NEXT: case MyTarget::PseudoX: {
// PSEUDO-NEXT: MCOperand MCOp;
// PSEUDO-NEXT: Inst.setOpcode(MyTarget::TEST_XREG);
// PSEUDO-NEXT: // Operand: dst
// PSEUDO-NEXT: Inst.addOperand(MCOperand::createReg(MyTarget::RegisterByHwMode::getModeCountReg(STI->getHwMode(MCSubtargetInfo::HwMode_RegInfo))));
// PSEUDO-NEXT: // Operand: src
// PSEUDO-NEXT: lowerOperand(MI->getOperand(0), MCOp);
// PSEUDO-NEXT: Inst.addOperand(MCOp);
// PSEUDO-NEXT: break;
// PSEUDO-NEXT: }
def PseudoX : Pseudo<(outs), (ins EvenXRegs:$rs1)>,
PseudoInstExpansion<(TEST_XREG ModeCountReg, XRegs:$rs1)>;
def PseudoPtr : Pseudo<(outs), (ins EvenPtrRC:$rs1)>,
PseudoInstExpansion<(TEST_PTRREG NullReg, PtrRegOperand:$rs1)>;
let Predicates = [Is64Bit] in
def Pseudo64Only : Pseudo<(outs), (ins PtrRC:$rs1)>,
PseudoInstExpansion<(TEST_PTRREG PtrRegFor64BitModesOnly, PtrRegOperand:$rs1)>;
// TODO: Add DAGISel support
def int_with_mode_reg : Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrWillReturn]>;
def int_with_null_reg : Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrWillReturn]>;
def : Pat<(int_with_mode_reg), (TEST_XREG ModeCountReg)>;
def : Pat<(int_with_mode_reg), (TEST_PTRREG NullReg)>;
defm : RemapAllTargetPseudoPointerOperands<PtrRC>;
def MyTargetISA : InstrInfo;
def MyTargetAsmWriter : AsmWriter {
int PassSubtarget = 1;
}
def MyTarget : Target {
let InstructionSet = MyTargetISA;
let AssemblyWriters = [MyTargetAsmWriter];
}