Add instruction encodings / disassembly support for 2r instructions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170323 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Osborne 2012-12-17 12:29:31 +00:00
parent dd78daa199
commit 1ffe48a84b
4 changed files with 222 additions and 70 deletions

View File

@ -67,12 +67,26 @@ static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
}
static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus Decode2RInstruction(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeR2RInstruction(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus Decode2RSrcDstInstruction(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder);
#include "XCoreGenDisassemblerTables.inc"
static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
@ -87,6 +101,57 @@ static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
return MCDisassembler::Success;
}
static DecodeStatus
Decode2OpInstruction(unsigned Insn, unsigned &Op1, unsigned &Op2) {
unsigned Combined = fieldFromInstruction(Insn, 6, 5) +
fieldFromInstruction(Insn, 5, 1) * 5 - 27;
if (Combined >= 9)
return MCDisassembler::Fail;
unsigned Op1High = Combined % 3;
unsigned Op2High = Combined / 3;
Op1 = (Op1High << 2) | fieldFromInstruction(Insn, 2, 2);
Op2 = (Op2High << 2) | fieldFromInstruction(Insn, 0, 2);
return MCDisassembler::Success;
}
static DecodeStatus
Decode2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
const void *Decoder) {
unsigned Op1, Op2;
DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
if (S == MCDisassembler::Success) {
DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
}
return S;
}
static DecodeStatus
DecodeR2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
const void *Decoder) {
unsigned Op1, Op2;
DecodeStatus S = Decode2OpInstruction(Insn, Op2, Op1);
if (S == MCDisassembler::Success) {
DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
}
return S;
}
static DecodeStatus
Decode2RSrcDstInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
const void *Decoder) {
unsigned Op1, Op2;
DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
if (S == MCDisassembler::Success) {
DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
}
return S;
}
MCDisassembler::DecodeStatus
XCoreDisassembler::getInstruction(MCInst &instr,
uint64_t &Size,

View File

@ -73,8 +73,23 @@ class _FLU10<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstXCore<4, outs, ins, asmstr, pattern> {
}
class _F2R<dag outs, dag ins, string asmstr, list<dag> pattern>
class _F2R<bits<6> opc, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstXCore<2, outs, ins, asmstr, pattern> {
let Inst{15-11} = opc{5-1};
let Inst{4} = opc{0};
let DecoderMethod = "Decode2RInstruction";
}
// 2R with first operand as both a source and a destination.
class _F2RSrcDst<bits<6> opc, dag outs, dag ins, string asmstr,
list<dag> pattern> : _F2R<opc, outs, ins, asmstr, pattern> {
let DecoderMethod = "Decode2RSrcDstInstruction";
}
// Same as 2R with last two operands swapped
class _FR2R<bits<6> opc, dag outs, dag ins, string asmstr, list<dag> pattern>
: _F2R<opc, outs, ins, asmstr, pattern> {
let DecoderMethod = "DecodeR2RInstruction";
}
class _FRUS<dag outs, dag ins, string asmstr, list<dag> pattern>

View File

@ -344,10 +344,9 @@ multiclass FU10_LU10_np<string OpcStr> {
// Two operand short
class F2R_np<string OpcStr> : _F2R<
(outs GRRegs:$dst), (ins GRRegs:$b),
!strconcat(OpcStr, " $dst, $b"),
[]>;
class F2R_np<bits<6> opc, string OpcStr> :
_F2R<opc, (outs GRRegs:$dst), (ins GRRegs:$b),
!strconcat(OpcStr, " $dst, $b"), []>;
// Two operand long
@ -753,13 +752,11 @@ def BL_lu10 : _FLU10<
// Two operand short
// TODO eet, eef, tsetmr
def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b),
"not $dst, $b",
[(set GRRegs:$dst, (not GRRegs:$b))]>;
def NOT : _F2R<0b100010, (outs GRRegs:$dst), (ins GRRegs:$b),
"not $dst, $b", [(set GRRegs:$dst, (not GRRegs:$b))]>;
def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b),
"neg $dst, $b",
[(set GRRegs:$dst, (ineg GRRegs:$b))]>;
def NEG : _F2R<0b100100, (outs GRRegs:$dst), (ins GRRegs:$b),
"neg $dst, $b", [(set GRRegs:$dst, (ineg GRRegs:$b))]>;
let Constraints = "$src1 = $dst" in {
def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2),
@ -777,14 +774,15 @@ def ZEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2),
[(set GRRegs:$dst, (int_xcore_zext GRRegs:$src1,
immBitp:$src2))]>;
def ZEXT_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2),
def ZEXT_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src2, GRRegs:$src1),
"zext $dst, $src2",
[(set GRRegs:$dst, (int_xcore_zext GRRegs:$src1,
GRRegs:$src2))]>;
def ANDNOT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2),
"andnot $dst, $src2",
[(set GRRegs:$dst, (and GRRegs:$src1, (not GRRegs:$src2)))]>;
def ANDNOT_2r :
_F2RSrcDst<0b001010, (outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2),
"andnot $dst, $src2",
[(set GRRegs:$dst, (and GRRegs:$src1, (not GRRegs:$src2)))]>;
}
let isReMaterializable = 1, neverHasSideEffects = 1 in
@ -792,99 +790,103 @@ def MKMSK_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$size),
"mkmsk $dst, $size",
[]>;
def MKMSK_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$size),
"mkmsk $dst, $size",
[(set GRRegs:$dst, (add (shl 1, GRRegs:$size), -1))]>;
def MKMSK_2r : _F2R<0b101000, (outs GRRegs:$dst), (ins GRRegs:$size),
"mkmsk $dst, $size",
[(set GRRegs:$dst, (add (shl 1, GRRegs:$size), -1))]>;
def GETR_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$type),
"getr $dst, $type",
[(set GRRegs:$dst, (int_xcore_getr immUs:$type))]>;
def GETTS_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r),
"getts $dst, res[$r]",
[(set GRRegs:$dst, (int_xcore_getts GRRegs:$r))]>;
def GETTS_2r : _F2R<0b001110, (outs GRRegs:$dst), (ins GRRegs:$r),
"getts $dst, res[$r]",
[(set GRRegs:$dst, (int_xcore_getts GRRegs:$r))]>;
def SETPT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val),
"setpt res[$r], $val",
[(int_xcore_setpt GRRegs:$r, GRRegs:$val)]>;
def SETPT_2r : _FR2R<0b001111, (outs), (ins GRRegs:$r, GRRegs:$val),
"setpt res[$r], $val",
[(int_xcore_setpt GRRegs:$r, GRRegs:$val)]>;
def OUTCT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val),
"outct res[$r], $val",
[(int_xcore_outct GRRegs:$r, GRRegs:$val)]>;
def OUTCT_2r : _F2R<0b010010, (outs), (ins GRRegs:$r, GRRegs:$val),
"outct res[$r], $val",
[(int_xcore_outct GRRegs:$r, GRRegs:$val)]>;
def OUTCT_rus : _F2R<(outs), (ins GRRegs:$r, i32imm:$val),
"outct res[$r], $val",
[(int_xcore_outct GRRegs:$r, immUs:$val)]>;
def OUTCT_rus : _F2RUS<(outs), (ins GRRegs:$r, i32imm:$val),
"outct res[$r], $val",
[(int_xcore_outct GRRegs:$r, immUs:$val)]>;
def OUTT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val),
"outt res[$r], $val",
[(int_xcore_outt GRRegs:$r, GRRegs:$val)]>;
def OUTT_2r : _FR2R<0b000011, (outs), (ins GRRegs:$r, GRRegs:$val),
"outt res[$r], $val",
[(int_xcore_outt GRRegs:$r, GRRegs:$val)]>;
def OUT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val),
"out res[$r], $val",
[(int_xcore_out GRRegs:$r, GRRegs:$val)]>;
def OUT_2r : _FR2R<0b101010, (outs), (ins GRRegs:$r, GRRegs:$val),
"out res[$r], $val",
[(int_xcore_out GRRegs:$r, GRRegs:$val)]>;
let Constraints = "$src = $dst" in
def OUTSHR_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r, GRRegs:$src),
"outshr res[$r], $src",
[(set GRRegs:$dst, (int_xcore_outshr GRRegs:$r,
GRRegs:$src))]>;
def OUTSHR_2r :
_F2RSrcDst<0b101011, (outs GRRegs:$dst), (ins GRRegs:$src, GRRegs:$r),
"outshr res[$r], $src",
[(set GRRegs:$dst, (int_xcore_outshr GRRegs:$r, GRRegs:$src))]>;
def INCT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r),
"inct $dst, res[$r]",
[(set GRRegs:$dst, (int_xcore_inct GRRegs:$r))]>;
def INCT_2r : _F2R<0b100001, (outs GRRegs:$dst), (ins GRRegs:$r),
"inct $dst, res[$r]",
[(set GRRegs:$dst, (int_xcore_inct GRRegs:$r))]>;
def INT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r),
"int $dst, res[$r]",
[(set GRRegs:$dst, (int_xcore_int GRRegs:$r))]>;
def INT_2r : _F2R<0b100011, (outs GRRegs:$dst), (ins GRRegs:$r),
"int $dst, res[$r]",
[(set GRRegs:$dst, (int_xcore_int GRRegs:$r))]>;
def IN_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r),
def IN_2r : _F2R<0b101100, (outs GRRegs:$dst), (ins GRRegs:$r),
"in $dst, res[$r]",
[(set GRRegs:$dst, (int_xcore_in GRRegs:$r))]>;
let Constraints = "$src = $dst" in
def INSHR_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r, GRRegs:$src),
"inshr $dst, res[$r]",
[(set GRRegs:$dst, (int_xcore_inshr GRRegs:$r,
GRRegs:$src))]>;
def INSHR_2r :
_F2RSrcDst<0b101101, (outs GRRegs:$dst), (ins GRRegs:$src, GRRegs:$r),
"inshr $dst, res[$r]",
[(set GRRegs:$dst, (int_xcore_inshr GRRegs:$r, GRRegs:$src))]>;
def CHKCT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val),
"chkct res[$r], $val",
[(int_xcore_chkct GRRegs:$r, GRRegs:$val)]>;
def CHKCT_2r : _F2R<0b110010, (outs), (ins GRRegs:$r, GRRegs:$val),
"chkct res[$r], $val",
[(int_xcore_chkct GRRegs:$r, GRRegs:$val)]>;
def CHKCT_rus : _F2R<(outs), (ins GRRegs:$r, i32imm:$val),
def CHKCT_rus : _F2RUS<(outs), (ins GRRegs:$r, i32imm:$val),
"chkct res[$r], $val",
[(int_xcore_chkct GRRegs:$r, immUs:$val)]>;
def TESTCT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src),
def TESTCT_2r : _F2R<0b101111, (outs GRRegs:$dst), (ins GRRegs:$src),
"testct $dst, res[$src]",
[(set GRRegs:$dst, (int_xcore_testct GRRegs:$src))]>;
def TESTWCT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src),
def TESTWCT_2r : _F2R<0b110001, (outs GRRegs:$dst), (ins GRRegs:$src),
"testwct $dst, res[$src]",
[(set GRRegs:$dst, (int_xcore_testwct GRRegs:$src))]>;
def SETD_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val),
"setd res[$r], $val",
[(int_xcore_setd GRRegs:$r, GRRegs:$val)]>;
def SETD_2r : _FR2R<0b000101, (outs), (ins GRRegs:$r, GRRegs:$val),
"setd res[$r], $val",
[(int_xcore_setd GRRegs:$r, GRRegs:$val)]>;
def GETST_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r),
def SETPSC_l2r : _FR2R<0b110000, (outs), (ins GRRegs:$src1, GRRegs:$src2),
"setpsc res[$src1], $src2",
[(int_xcore_setpsc GRRegs:$src1, GRRegs:$src2)]>;
def GETST_2r : _F2R<0b000001, (outs GRRegs:$dst), (ins GRRegs:$r),
"getst $dst, res[$r]",
[(set GRRegs:$dst, (int_xcore_getst GRRegs:$r))]>;
def INITSP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
def INITSP_2r : _F2R<0b000100, (outs), (ins GRRegs:$src, GRRegs:$t),
"init t[$t]:sp, $src",
[(int_xcore_initsp GRRegs:$t, GRRegs:$src)]>;
def INITPC_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
def INITPC_2r : _F2R<0b000000, (outs), (ins GRRegs:$src, GRRegs:$t),
"init t[$t]:pc, $src",
[(int_xcore_initpc GRRegs:$t, GRRegs:$src)]>;
def INITCP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
def INITCP_2r : _F2R<0b000110, (outs), (ins GRRegs:$src, GRRegs:$t),
"init t[$t]:cp, $src",
[(int_xcore_initcp GRRegs:$t, GRRegs:$src)]>;
def INITDP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
def INITDP_2r : _F2R<0b000010, (outs), (ins GRRegs:$src, GRRegs:$t),
"init t[$t]:dp, $src",
[(int_xcore_initdp GRRegs:$t, GRRegs:$src)]>;
@ -930,10 +932,6 @@ def SETRDY_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
"setrdy res[$src1], $src2",
[(int_xcore_setrdy GRRegs:$src1, GRRegs:$src2)]>;
def SETPSC_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
"setpsc res[$src1], $src2",
[(int_xcore_setpsc GRRegs:$src1, GRRegs:$src2)]>;
def PEEK_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
"peek $dst, res[$src]",
[(set GRRegs:$dst, (int_xcore_peek GRRegs:$src))]>;

View File

@ -58,3 +58,77 @@
# CHECK: eeu res[r11]
0xfb 0x07
# 2r instructions
# CHECK: not r1, r8
0x24 0x8f
# CHECK: neg r7, r6
0xce 0x97
# CHECK: andnot r10, r11
0xab 0x2f
# CHECK: mkmsk r11, r0
0x4c 0xa7
# CHECK: getts r8, res[r1]
0x41 0x3f
# CHECK: setpt res[r2], r3
0xde 0x3e
# CHECK: outct res[r1], r2
0xc6 0x4e
# CHECK: outt res[r5], r4
0xd1 0x0f
# CHECK: out res[r9], r10
0xa9 0xaf
# CHECK: outshr res[r0], r2
0xd8 0xae
# CHECK: inct r7, res[r4]
0xdc 0x87
# CHECK: int r8, res[r3]
0x53 0x8f
# CHECK: in r10, res[r0]
0x48 0xb7
# CHECK: inshr r4, res[r2]
0x12 0xb7
# CHECK: chkct res[r6], r0
0x08 0xcf
# CHECK: testct r8, res[r3]
0x53 0xbf
# CHECK: testwct r2, res[r9]
0x39 0xc7
# CHECK: setd res[r3], r4
0x13 0x17
# CHECK: getst r7, res[r1]
0x1d 0x07
# CHECK: init t[r1]:sp, r2
0xc9 0x16
# CHECK: init t[r10]:pc, r1
0x26 0x07
# CHECK: init t[r2]:cp, r10
0x4a 0x1f
# CHECK: init t[r2]:dp, r3
0xce 0x0e
# CHECK: setpsc res[r8], r2
0x28 0xc7