blob: d642584e52b375f6d22d38bff4fe098f1edb7d19 [file] [edit]
// RUN: llvm-tblgen --gen-compress-inst-emitter -I %p/../../include -I %S %s -o - | FileCheck %s
include "Common/RegClassByHwModeCommon.td"
def IsPtr64 : Predicate<"Subtarget->isPtr64()">;
defvar Ptr32 = DefaultMode;
def Ptr64 : HwMode<[IsPtr64]>;
def PtrRC : RegClassByHwMode<[Ptr32, Ptr64], [XRegs, YRegs]>;
def X_MOV : TestInstruction {
let OutOperandList = (outs XRegs:$dst);
let InOperandList = (ins XRegs:$src);
let AsmString = "x_mov $dst, $src";
let opcode = 0;
}
def X_MOV_SMALL : TestInstruction {
let OutOperandList = (outs XRegs:$dst);
let InOperandList = (ins XRegs:$src);
let AsmString = "x_mov.small $dst, $src";
let opcode = 1;
let Size = 1;
}
def X_MOV_ZERO : TestInstruction {
let OutOperandList = (outs XRegs:$dst);
let InOperandList = (ins);
let AsmString = "x_mov.zero $dst";
let opcode = 2;
let Size = 1;
}
def X_MOV_TIED : TestInstruction {
let OutOperandList = (outs XRegs:$dst);
let InOperandList = (ins XRegs:$src);
let Constraints = "$src = $dst";
let AsmString = "x_mov.tied $dst, $src";
let opcode = 3;
let Size = 1;
}
def PTR_MOV : TestInstruction {
let OutOperandList = (outs PtrRC:$dst);
let InOperandList = (ins PtrRC:$src);
let AsmString = "ptr_mov $dst, $src";
let opcode = 3;
}
def PTR_MOV_SMALL : TestInstruction {
let OutOperandList = (outs PtrRC:$dst);
let InOperandList = (ins PtrRC:$src);
let AsmString = "ptr_mov.small $dst, $src";
let opcode = 4;
let Size = 1;
}
def PTR_MOV_ZERO : TestInstruction {
let OutOperandList = (outs PtrRC:$dst);
let InOperandList = (ins);
let AsmString = "ptr_mov.zero $dst";
let opcode = 3;
let Size = 1;
}
def PTR_MOV_TIED : TestInstruction {
let OutOperandList = (outs PtrRC:$dst);
let InOperandList = (ins PtrRC:$src);
let Constraints = "$src = $dst";
let AsmString = "ptr_mov.tied $dst, $src";
let opcode = 3;
let Size = 1;
}
def : CompressPat<(X_MOV XRegs:$dst, X0),
(X_MOV_ZERO XRegs:$dst)>;
def : CompressPat<(X_MOV XRegs:$dst, XRegs:$dst),
(X_MOV_TIED XRegs:$dst)>;
def : CompressPat<(X_MOV XRegs:$dst, XRegs:$src),
(X_MOV_SMALL XRegs:$dst, XRegs:$src)>;
// TODO: Should also be able to use a fixed register with RegClassByHwMode
// def : CompressPat<(PTR_MOV PtrRC:$dst, X0),
// (PTR_MOV_ZERO PtrRC:$dst)>;
def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$dst),
(PTR_MOV_TIED PtrRC:$dst)>;
def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$src),
(PTR_MOV_SMALL PtrRC:$dst, PtrRC:$src)>;
// CHECK: static bool compressInst(MCInst &OutInst,
// CHECK-NEXT: const MCInst &MI,
// CHECK-NEXT: const MCSubtargetInfo &STI) {
// CHECK-NEXT: {{\[\[}}maybe_unused]] unsigned HwModeId = STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo);
// CHECK-NEXT: switch (MI.getOpcode()) {
// CHECK-NEXT: default: return false;
// CHECK-NEXT: case MyTarget::PTR_MOV: {
// CHECK-NEXT: if (MI.getOperand(1).isReg() && MI.getOperand(0).isReg() &&
// CHECK-NEXT: (MI.getOperand(1).getReg() == MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(1).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(1).getReg())) {
// CHECK-NEXT: // ptr_mov.tied $dst, $src
// CHECK-NEXT: OutInst.setOpcode(MyTarget::PTR_MOV_TIED);
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(1).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(1).getReg())) {
// CHECK-NEXT: // ptr_mov.small $dst, $src
// CHECK-NEXT: OutInst.setOpcode(MyTarget::PTR_MOV_SMALL);
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: break;
// CHECK-NEXT: } // case PTR_MOV
// CHECK-NEXT: case MyTarget::X_MOV: {
// CHECK-NEXT: if (MI.getOperand(1).isReg() &&
// CHECK-NEXT: (MI.getOperand(1).getReg() == MyTarget::X0) &&
// CHECK-NEXT: MI.getOperand(0).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg())) {
// CHECK-NEXT: // x_mov.zero $dst
// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV_ZERO);
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: if (MI.getOperand(1).isReg() && MI.getOperand(0).isReg() &&
// CHECK-NEXT: (MI.getOperand(1).getReg() == MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(1).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(1).getReg())) {
// CHECK-NEXT: // x_mov.tied $dst, $src
// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV_TIED);
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(1).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(1).getReg())) {
// CHECK-NEXT: // x_mov.small $dst, $src
// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV_SMALL);
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: break;
// CHECK-NEXT: } // case X_MOV
// CHECK-NEXT: } // switch
// CHECK-NEXT: return false;
// CHECK-NEXT: }
// CHECK: static bool uncompressInst(MCInst &OutInst,
// CHECK-NEXT: const MCInst &MI,
// CHECK-NEXT: const MCSubtargetInfo &STI) {
// CHECK-NEXT: {{\[\[}}maybe_unused]] unsigned HwModeId = STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo);
// CHECK-NEXT: switch (MI.getOpcode()) {
// CHECK-NEXT: default: return false;
// CHECK-NEXT: case MyTarget::PTR_MOV_SMALL: {
// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(1).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(1).getReg())) {
// CHECK-NEXT: // ptr_mov $dst, $src
// CHECK-NEXT: OutInst.setOpcode(MyTarget::PTR_MOV);
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: break;
// CHECK-NEXT: } // case PTR_MOV_SMALL
// CHECK-NEXT: case MyTarget::PTR_MOV_TIED: {
// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(0).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(0).getReg())) {
// CHECK-NEXT: // ptr_mov $dst, $src
// CHECK-NEXT: OutInst.setOpcode(MyTarget::PTR_MOV);
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: break;
// CHECK-NEXT: } // case PTR_MOV_TIED
// CHECK-NEXT: case MyTarget::X_MOV_SMALL: {
// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(1).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(1).getReg())) {
// CHECK-NEXT: // x_mov $dst, $src
// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV);
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: break;
// CHECK-NEXT: } // case X_MOV_SMALL
// CHECK-NEXT: case MyTarget::X_MOV_TIED: {
// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(0).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg())) {
// CHECK-NEXT: // x_mov $dst, $src
// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV);
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: break;
// CHECK-NEXT: } // case X_MOV_TIED
// CHECK-NEXT: case MyTarget::X_MOV_ZERO: {
// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg())) {
// CHECK-NEXT: // x_mov $dst, $src
// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV);
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: OutInst.addOperand(MCOperand::createReg(MyTarget::X0));
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: break;
// CHECK-NEXT: } // case X_MOV_ZERO
// CHECK-NEXT: } // switch
// CHECK-NEXT: return false;
// CHECK-NEXT: }
// CHECK: static bool isCompressibleInst(const MachineInstr &MI,
// CHECK-NEXT: const MyTargetSubtarget &STI) {
// CHECK-NEXT: {{\[\[}}maybe_unused]] unsigned HwModeId = STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo);
// CHECK-NEXT: switch (MI.getOpcode()) {
// CHECK-NEXT: default: return false;
// CHECK-NEXT: case MyTarget::PTR_MOV: {
// CHECK-NEXT: if (MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isPhysical() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(1).isReg() && MI.getOperand(1).getReg().isPhysical() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(1).getReg())) {
// CHECK-NEXT: // ptr_mov.small $dst, $src
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: if (MI.getOperand(1).isReg() && MI.getOperand(0).isReg() &&
// CHECK-NEXT: (MI.getOperand(1).getReg() == MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(1).isReg() && MI.getOperand(1).getReg().isPhysical() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(1).getReg())) {
// CHECK-NEXT: // ptr_mov.tied $dst, $src
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: break;
// CHECK-NEXT: } // case PTR_MOV
// CHECK-NEXT: case MyTarget::X_MOV: {
// CHECK-NEXT: if (MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isPhysical() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(1).isReg() && MI.getOperand(1).getReg().isPhysical() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(1).getReg())) {
// CHECK-NEXT: // x_mov.small $dst, $src
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: if (MI.getOperand(1).isReg() && MI.getOperand(0).isReg() &&
// CHECK-NEXT: (MI.getOperand(1).getReg() == MI.getOperand(0).getReg()) &&
// CHECK-NEXT: MI.getOperand(1).isReg() && MI.getOperand(1).getReg().isPhysical() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(1).getReg())) {
// CHECK-NEXT: // x_mov.tied $dst, $src
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: // Operand: src
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: if (MI.getOperand(1).isReg() &&
// CHECK-NEXT: (MI.getOperand(1).getReg() == MyTarget::X0) &&
// CHECK-NEXT: MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isPhysical() &&
// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg())) {
// CHECK-NEXT: // x_mov.zero $dst
// CHECK-NEXT: // Operand: dst
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
// CHECK-NEXT: break;
// CHECK-NEXT: } // case X_MOV
// CHECK-NEXT: } // switch
// CHECK-NEXT: return false;
// CHECK-NEXT: }
def MyTargetISA : InstrInfo;
def MyTargetAsmWriter : AsmWriter {
int PassSubtarget = 1;
}
def MyTarget : Target {
let InstructionSet = MyTargetISA;
let AssemblyWriters = [MyTargetAsmWriter];
}