mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-02 07:32:52 +00:00
[mips] Refactor subword-swap, EXT/INS, load-effective-address and read-hardware
instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170956 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e8bc10b902
commit
dbf51ee459
@ -185,31 +185,32 @@ def MFHI64 : MoveFromLOHI<"mfhi", CPU64Regs, [HI64]>, MFLO_FM<0x10>;
|
||||
def MFLO64 : MoveFromLOHI<"mflo", CPU64Regs, [LO64]>, MFLO_FM<0x12>;
|
||||
|
||||
/// Sign Ext In Register Instructions.
|
||||
def SEB64 : SignExtInReg<"seb", i8, CPU64Regs>, SEB_FM<0x10>;
|
||||
def SEH64 : SignExtInReg<"seh", i16, CPU64Regs>, SEB_FM<0x18>;
|
||||
def SEB64 : SignExtInReg<"seb", i8, CPU64Regs>, SEB_FM<0x10, 0x20>;
|
||||
def SEH64 : SignExtInReg<"seh", i16, CPU64Regs>, SEB_FM<0x18, 0x20>;
|
||||
|
||||
/// Count Leading
|
||||
def DCLZ : CountLeading0<"dclz", CPU64Regs>, CLO_FM<0x24>;
|
||||
def DCLO : CountLeading1<"dclo", CPU64Regs>, CLO_FM<0x25>;
|
||||
|
||||
/// Double Word Swap Bytes/HalfWords
|
||||
def DSBH : SubwordSwap<0x24, 0x2, "dsbh", CPU64Regs>;
|
||||
def DSHD : SubwordSwap<0x24, 0x5, "dshd", CPU64Regs>;
|
||||
def DSBH : SubwordSwap<"dsbh", CPU64Regs>, SEB_FM<2, 0x24>;
|
||||
def DSHD : SubwordSwap<"dshd", CPU64Regs>, SEB_FM<5, 0x24>;
|
||||
|
||||
def LEA_ADDiu64 : EffectiveAddress<"daddiu", CPU64Regs, mem_ea_64>, LW_FM<0x19>;
|
||||
|
||||
def LEA_ADDiu64 : EffectiveAddress<0x19,"daddiu\t$rt, $addr", CPU64Regs, mem_ea_64>;
|
||||
}
|
||||
let DecoderNamespace = "Mips64" in {
|
||||
def RDHWR64 : ReadHardware<CPU64Regs, HWRegs64>;
|
||||
def RDHWR64 : ReadHardware<CPU64Regs, HWRegs64>, RDHWR_FM;
|
||||
|
||||
def DEXT : ExtBase<3, "dext", CPU64Regs>;
|
||||
def DEXT : ExtBase<"dext", CPU64Regs>, EXT_FM<3>;
|
||||
let Pattern = []<dag> in {
|
||||
def DEXTU : ExtBase<2, "dextu", CPU64Regs>;
|
||||
def DEXTM : ExtBase<1, "dextm", CPU64Regs>;
|
||||
def DEXTU : ExtBase<"dextu", CPU64Regs>, EXT_FM<2>;
|
||||
def DEXTM : ExtBase<"dextm", CPU64Regs>, EXT_FM<1>;
|
||||
}
|
||||
def DINS : InsBase<7, "dins", CPU64Regs>;
|
||||
def DINS : InsBase<"dins", CPU64Regs>, EXT_FM<7>;
|
||||
let Pattern = []<dag> in {
|
||||
def DINSU : InsBase<6, "dinsu", CPU64Regs>;
|
||||
def DINSM : InsBase<5, "dinsm", CPU64Regs>;
|
||||
def DINSU : InsBase<"dinsu", CPU64Regs>, EXT_FM<6>;
|
||||
def DINSM : InsBase<"dinsm", CPU64Regs>, EXT_FM<5>;
|
||||
}
|
||||
|
||||
let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
|
||||
|
@ -326,7 +326,7 @@ class MTLO_FM<bits<6> funct> {
|
||||
let Inst{5-0} = funct;
|
||||
}
|
||||
|
||||
class SEB_FM<bits<5> funct> {
|
||||
class SEB_FM<bits<5> funct, bits<6> funct2> {
|
||||
bits<5> rd;
|
||||
bits<5> rt;
|
||||
|
||||
@ -337,7 +337,7 @@ class SEB_FM<bits<5> funct> {
|
||||
let Inst{20-16} = rt;
|
||||
let Inst{15-11} = rd;
|
||||
let Inst{10-6} = funct;
|
||||
let Inst{5-0} = 0x20;
|
||||
let Inst{5-0} = funct2;
|
||||
}
|
||||
|
||||
class CLO_FM<bits<6> funct> {
|
||||
@ -433,6 +433,36 @@ class MULT_FM<bits<6> op, bits<6> funct> {
|
||||
let Inst{5-0} = funct;
|
||||
}
|
||||
|
||||
class EXT_FM<bits<6> funct> {
|
||||
bits<5> rt;
|
||||
bits<5> rs;
|
||||
bits<5> pos;
|
||||
bits<5> size;
|
||||
|
||||
bits<32> Inst;
|
||||
|
||||
let Inst{31-26} = 0x1f;
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-16} = rt;
|
||||
let Inst{15-11} = size;
|
||||
let Inst{10-6} = pos;
|
||||
let Inst{5-0} = funct;
|
||||
}
|
||||
|
||||
class RDHWR_FM {
|
||||
bits<5> rt;
|
||||
bits<5> rd;
|
||||
|
||||
bits<32> Inst;
|
||||
|
||||
let Inst{31-26} = 0x1f;
|
||||
let Inst{25-21} = 0;
|
||||
let Inst{20-16} = rt;
|
||||
let Inst{15-11} = rd;
|
||||
let Inst{10-6} = 0;
|
||||
let Inst{5-0} = 0x3b;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// FLOATING POINT INSTRUCTION FORMATS
|
||||
|
@ -611,10 +611,11 @@ class MoveToLOHI<string opstr, RegisterClass RC, list<Register> DefRegs>:
|
||||
let neverHasSideEffects = 1;
|
||||
}
|
||||
|
||||
class EffectiveAddress<bits<6> opc, string instr_asm, RegisterClass RC, Operand Mem> :
|
||||
FMem<opc, (outs RC:$rt), (ins Mem:$addr),
|
||||
instr_asm, [(set RC:$rt, addr:$addr)], IIAlu> {
|
||||
let isCodeGenOnly = 1;
|
||||
class EffectiveAddress<string opstr, RegisterClass RC, Operand Mem> :
|
||||
InstSE<(outs RC:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
|
||||
[(set RC:$rt, addr:$addr)], NoItinerary, FrmI> {
|
||||
let isCodeGenOnly = 1;
|
||||
let DecoderMethod = "DecodeMem";
|
||||
}
|
||||
|
||||
// Count Leading Ones/Zeros in Word
|
||||
@ -637,45 +638,32 @@ class SignExtInReg<string opstr, ValueType vt, RegisterClass RC> :
|
||||
}
|
||||
|
||||
// Subword Swap
|
||||
class SubwordSwap<bits<6> func, bits<5> sa, string instr_asm, RegisterClass RC>:
|
||||
FR<0x1f, func, (outs RC:$rd), (ins RC:$rt),
|
||||
!strconcat(instr_asm, "\t$rd, $rt"), [], NoItinerary> {
|
||||
let rs = 0;
|
||||
let shamt = sa;
|
||||
class SubwordSwap<string opstr, RegisterClass RC>:
|
||||
InstSE<(outs RC:$rd), (ins RC:$rt), !strconcat(opstr, "\t$rd, $rt"), [],
|
||||
NoItinerary, FrmR> {
|
||||
let Predicates = [HasSwap, HasStdEnc];
|
||||
let neverHasSideEffects = 1;
|
||||
}
|
||||
|
||||
// Read Hardware
|
||||
class ReadHardware<RegisterClass CPURegClass, RegisterClass HWRegClass>
|
||||
: FR<0x1f, 0x3b, (outs CPURegClass:$rt), (ins HWRegClass:$rd),
|
||||
"rdhwr\t$rt, $rd", [], IIAlu> {
|
||||
let rs = 0;
|
||||
let shamt = 0;
|
||||
}
|
||||
class ReadHardware<RegisterClass CPURegClass, RegisterClass HWRegClass> :
|
||||
InstSE<(outs CPURegClass:$rt), (ins HWRegClass:$rd), "rdhwr\t$rt, $rd", [],
|
||||
IIAlu, FrmR>;
|
||||
|
||||
// Ext and Ins
|
||||
class ExtBase<bits<6> _funct, string instr_asm, RegisterClass RC>:
|
||||
FR<0x1f, _funct, (outs RC:$rt), (ins RC:$rs, uimm16:$pos, size_ext:$sz),
|
||||
!strconcat(instr_asm, " $rt, $rs, $pos, $sz"),
|
||||
[(set RC:$rt, (MipsExt RC:$rs, imm:$pos, imm:$sz))], NoItinerary> {
|
||||
bits<5> pos;
|
||||
bits<5> sz;
|
||||
let rd = sz;
|
||||
let shamt = pos;
|
||||
class ExtBase<string opstr, RegisterClass RC>:
|
||||
InstSE<(outs RC:$rt), (ins RC:$rs, uimm16:$pos, size_ext:$size),
|
||||
!strconcat(opstr, " $rt, $rs, $pos, $size"),
|
||||
[(set RC:$rt, (MipsExt RC:$rs, imm:$pos, imm:$size))], NoItinerary,
|
||||
FrmR> {
|
||||
let Predicates = [HasMips32r2, HasStdEnc];
|
||||
}
|
||||
|
||||
class InsBase<bits<6> _funct, string instr_asm, RegisterClass RC>:
|
||||
FR<0x1f, _funct, (outs RC:$rt),
|
||||
(ins RC:$rs, uimm16:$pos, size_ins:$sz, RC:$src),
|
||||
!strconcat(instr_asm, " $rt, $rs, $pos, $sz"),
|
||||
[(set RC:$rt, (MipsIns RC:$rs, imm:$pos, imm:$sz, RC:$src))],
|
||||
NoItinerary> {
|
||||
bits<5> pos;
|
||||
bits<5> sz;
|
||||
let rd = sz;
|
||||
let shamt = pos;
|
||||
class InsBase<string opstr, RegisterClass RC>:
|
||||
InstSE<(outs RC:$rt), (ins RC:$rs, uimm16:$pos, size_ins:$size, RC:$src),
|
||||
!strconcat(opstr, " $rt, $rs, $pos, $size"),
|
||||
[(set RC:$rt, (MipsIns RC:$rs, imm:$pos, imm:$size, RC:$src))],
|
||||
NoItinerary, FrmR> {
|
||||
let Predicates = [HasMips32r2, HasStdEnc];
|
||||
let Constraints = "$src = $rt";
|
||||
}
|
||||
@ -877,15 +865,15 @@ def MFHI : MoveFromLOHI<"mfhi", CPURegs, [HI]>, MFLO_FM<0x10>;
|
||||
def MFLO : MoveFromLOHI<"mflo", CPURegs, [LO]>, MFLO_FM<0x12>;
|
||||
|
||||
/// Sign Ext In Register Instructions.
|
||||
def SEB : SignExtInReg<"seb", i8, CPURegs>, SEB_FM<0x10>;
|
||||
def SEH : SignExtInReg<"seh", i16, CPURegs>, SEB_FM<0x18>;
|
||||
def SEB : SignExtInReg<"seb", i8, CPURegs>, SEB_FM<0x10, 0x20>;
|
||||
def SEH : SignExtInReg<"seh", i16, CPURegs>, SEB_FM<0x18, 0x20>;
|
||||
|
||||
/// Count Leading
|
||||
def CLZ : CountLeading0<"clz", CPURegs>, CLO_FM<0x20>;
|
||||
def CLO : CountLeading1<"clo", CPURegs>, CLO_FM<0x21>;
|
||||
|
||||
/// Word Swap Bytes Within Halfwords
|
||||
def WSBH : SubwordSwap<0x20, 0x2, "wsbh", CPURegs>;
|
||||
def WSBH : SubwordSwap<"wsbh", CPURegs>, SEB_FM<2, 0x20>;
|
||||
|
||||
/// No operation.
|
||||
/// FIXME: NOP should be an alias of "sll $0, $0, 0".
|
||||
@ -895,7 +883,7 @@ def NOP : InstSE<(outs), (ins), "nop", [], IIAlu, FrmJ>, NOP_FM;
|
||||
// instructions. The same not happens for stack address copies, so an
|
||||
// add op with mem ComplexPattern is used and the stack address copy
|
||||
// can be matched. It's similar to Sparc LEA_ADDRi
|
||||
def LEA_ADDiu : EffectiveAddress<0x09,"addiu\t$rt, $addr", CPURegs, mem_ea>;
|
||||
def LEA_ADDiu : EffectiveAddress<"addiu", CPURegs, mem_ea>, LW_FM<9>;
|
||||
|
||||
// MADD*/MSUB*
|
||||
def MADD : MArithR<"madd", MipsMAdd, 1>, MULT_FM<0x1c, 0>;
|
||||
@ -903,10 +891,10 @@ def MADDU : MArithR<"maddu", MipsMAddu, 1>, MULT_FM<0x1c, 1>;
|
||||
def MSUB : MArithR<"msub", MipsMSub>, MULT_FM<0x1c, 4>;
|
||||
def MSUBU : MArithR<"msubu", MipsMSubu>, MULT_FM<0x1c, 5>;
|
||||
|
||||
def RDHWR : ReadHardware<CPURegs, HWRegs>;
|
||||
def RDHWR : ReadHardware<CPURegs, HWRegs>, RDHWR_FM;
|
||||
|
||||
def EXT : ExtBase<0, "ext", CPURegs>;
|
||||
def INS : InsBase<4, "ins", CPURegs>;
|
||||
def EXT : ExtBase<"ext", CPURegs>, EXT_FM<0>;
|
||||
def INS : InsBase<"ins", CPURegs>, EXT_FM<4>;
|
||||
|
||||
/// Move Control Registers From/To CPU Registers
|
||||
def MFC0_3OP : MFC3OP<0x10, 0, (outs CPURegs:$rt),
|
||||
|
Loading…
Reference in New Issue
Block a user