mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-05 10:27:02 +00:00
Add instruction encodings / disassembly support for l2r instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170345 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9f84c05705
commit
c47793c62c
@ -62,6 +62,23 @@ static bool readInstruction16(const MemoryObject ®ion,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool readInstruction32(const MemoryObject ®ion,
|
||||
uint64_t address,
|
||||
uint64_t &size,
|
||||
uint32_t &insn) {
|
||||
uint8_t Bytes[4];
|
||||
|
||||
// We want to read exactly 4 Bytes of data.
|
||||
if (region.readBytes(address, 4, Bytes, NULL) == -1) {
|
||||
size = 0;
|
||||
return false;
|
||||
}
|
||||
// Encoded as a little-endian 32-bit word in the stream.
|
||||
insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
|
||||
(Bytes[3] << 24);
|
||||
return true;
|
||||
}
|
||||
|
||||
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
|
||||
const XCoreDisassembler *Dis = static_cast<const XCoreDisassembler*>(D);
|
||||
return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
|
||||
@ -105,6 +122,16 @@ static DecodeStatus DecodeRUSSrcDstBitpInstruction(MCInst &Inst,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeL2RInstruction(MCInst &Inst,
|
||||
unsigned Insn,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeLR2RInstruction(MCInst &Inst,
|
||||
unsigned Insn,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
#include "XCoreGenDisassemblerTables.inc"
|
||||
|
||||
static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
|
||||
@ -218,6 +245,32 @@ DecodeRUSSrcDstBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
|
||||
return S;
|
||||
}
|
||||
|
||||
static DecodeStatus
|
||||
DecodeL2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
|
||||
const void *Decoder) {
|
||||
unsigned Op1, Op2;
|
||||
DecodeStatus S = Decode2OpInstruction(fieldFromInstruction(Insn, 0, 16),
|
||||
Op1, Op2);
|
||||
if (S == MCDisassembler::Success) {
|
||||
DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
|
||||
DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
|
||||
}
|
||||
return S;
|
||||
}
|
||||
|
||||
static DecodeStatus
|
||||
DecodeLR2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
|
||||
const void *Decoder) {
|
||||
unsigned Op1, Op2;
|
||||
DecodeStatus S = Decode2OpInstruction(fieldFromInstruction(Insn, 0, 16),
|
||||
Op1, Op2);
|
||||
if (S == MCDisassembler::Success) {
|
||||
DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
|
||||
DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
|
||||
}
|
||||
return S;
|
||||
}
|
||||
|
||||
MCDisassembler::DecodeStatus
|
||||
XCoreDisassembler::getInstruction(MCInst &instr,
|
||||
uint64_t &Size,
|
||||
@ -225,20 +278,33 @@ XCoreDisassembler::getInstruction(MCInst &instr,
|
||||
uint64_t Address,
|
||||
raw_ostream &vStream,
|
||||
raw_ostream &cStream) const {
|
||||
uint16_t low;
|
||||
uint16_t insn16;
|
||||
|
||||
if (!readInstruction16(Region, Address, Size, low)) {
|
||||
if (!readInstruction16(Region, Address, Size, insn16)) {
|
||||
return Fail;
|
||||
}
|
||||
|
||||
// Calling the auto-generated decoder function.
|
||||
DecodeStatus Result = decodeInstruction(DecoderTable16, instr, low, Address,
|
||||
this, STI);
|
||||
DecodeStatus Result = decodeInstruction(DecoderTable16, instr, insn16,
|
||||
Address, this, STI);
|
||||
if (Result != Fail) {
|
||||
Size = 2;
|
||||
return Result;
|
||||
}
|
||||
|
||||
uint32_t insn32;
|
||||
|
||||
if (!readInstruction32(Region, Address, Size, insn32)) {
|
||||
return Fail;
|
||||
}
|
||||
|
||||
// Calling the auto-generated decoder function.
|
||||
Result = decodeInstruction(DecoderTable32, instr, insn32, Address, this, STI);
|
||||
if (Result != Fail) {
|
||||
Size = 4;
|
||||
return Result;
|
||||
}
|
||||
|
||||
return Fail;
|
||||
}
|
||||
|
||||
|
@ -114,8 +114,21 @@ class _FRUSSrcDstBitp<bits<6> opc, dag outs, dag ins, string asmstr,
|
||||
let DecoderMethod = "DecodeRUSSrcDstBitpInstruction";
|
||||
}
|
||||
|
||||
class _FL2R<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
class _FL2R<bits<10> opc, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstXCore<4, outs, ins, asmstr, pattern> {
|
||||
let Inst{31-27} = opc{9-5};
|
||||
let Inst{26-20} = 0b1111110;
|
||||
let Inst{19-16} = opc{4-1};
|
||||
|
||||
let Inst{15-11} = 0b11111;
|
||||
let Inst{4} = opc{0};
|
||||
let DecoderMethod = "DecodeL2RInstruction";
|
||||
}
|
||||
|
||||
// Same as L2R with last two operands swapped
|
||||
class _FLR2R<bits<10> opc, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: _FL2R<opc, outs, ins, asmstr, pattern> {
|
||||
let DecoderMethod = "DecodeLR2RInstruction";
|
||||
}
|
||||
|
||||
class _F1R<bits<6> opc, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
|
@ -901,45 +901,45 @@ def ENDIN_2r : _F2R<0b100101, (outs GRRegs:$dst), (ins GRRegs:$src),
|
||||
|
||||
// Two operand long
|
||||
// getd, testlcl
|
||||
def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
|
||||
"bitrev $dst, $src",
|
||||
[(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>;
|
||||
def BITREV_l2r : _FL2R<0b0000011000, (outs GRRegs:$dst), (ins GRRegs:$src),
|
||||
"bitrev $dst, $src",
|
||||
[(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>;
|
||||
|
||||
def BYTEREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
|
||||
"byterev $dst, $src",
|
||||
[(set GRRegs:$dst, (bswap GRRegs:$src))]>;
|
||||
def BYTEREV_l2r : _FL2R<0b0000011001, (outs GRRegs:$dst), (ins GRRegs:$src),
|
||||
"byterev $dst, $src",
|
||||
[(set GRRegs:$dst, (bswap GRRegs:$src))]>;
|
||||
|
||||
def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
|
||||
"clz $dst, $src",
|
||||
[(set GRRegs:$dst, (ctlz GRRegs:$src))]>;
|
||||
def CLZ_l2r : _FL2R<0b000111000, (outs GRRegs:$dst), (ins GRRegs:$src),
|
||||
"clz $dst, $src",
|
||||
[(set GRRegs:$dst, (ctlz GRRegs:$src))]>;
|
||||
|
||||
def SETC_l2r : _FL2R<(outs), (ins GRRegs:$r, GRRegs:$val),
|
||||
"setc res[$r], $val",
|
||||
[(int_xcore_setc GRRegs:$r, GRRegs:$val)]>;
|
||||
def SETC_l2r : _FL2R<0b0010111001, (outs), (ins GRRegs:$r, GRRegs:$val),
|
||||
"setc res[$r], $val",
|
||||
[(int_xcore_setc GRRegs:$r, GRRegs:$val)]>;
|
||||
|
||||
def SETTW_l2r : _FL2R<(outs), (ins GRRegs:$r, GRRegs:$val),
|
||||
"settw res[$r], $val",
|
||||
[(int_xcore_settw GRRegs:$r, GRRegs:$val)]>;
|
||||
def SETTW_l2r : _FLR2R<0b0010011001, (outs), (ins GRRegs:$r, GRRegs:$val),
|
||||
"settw res[$r], $val",
|
||||
[(int_xcore_settw GRRegs:$r, GRRegs:$val)]>;
|
||||
|
||||
def GETPS_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
|
||||
"get $dst, ps[$src]",
|
||||
[(set GRRegs:$dst, (int_xcore_getps GRRegs:$src))]>;
|
||||
def GETPS_l2r : _FL2R<0b0001011001, (outs GRRegs:$dst), (ins GRRegs:$src),
|
||||
"get $dst, ps[$src]",
|
||||
[(set GRRegs:$dst, (int_xcore_getps GRRegs:$src))]>;
|
||||
|
||||
def SETPS_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
|
||||
"set ps[$src1], $src2",
|
||||
[(int_xcore_setps GRRegs:$src1, GRRegs:$src2)]>;
|
||||
def SETPS_l2r : _FLR2R<0b0001111000, (outs), (ins GRRegs:$src1, GRRegs:$src2),
|
||||
"set ps[$src1], $src2",
|
||||
[(int_xcore_setps GRRegs:$src1, GRRegs:$src2)]>;
|
||||
|
||||
def INITLR_l2r : _FL2R<(outs), (ins GRRegs:$t, GRRegs:$src),
|
||||
def INITLR_l2r : _FL2R<0b0001011000, (outs), (ins GRRegs:$src, GRRegs:$t),
|
||||
"init t[$t]:lr, $src",
|
||||
[(int_xcore_initlr GRRegs:$t, GRRegs:$src)]>;
|
||||
|
||||
def SETCLK_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
|
||||
"setclk res[$src1], $src2",
|
||||
[(int_xcore_setclk GRRegs:$src1, GRRegs:$src2)]>;
|
||||
def SETCLK_l2r : _FLR2R<0b0000111001, (outs), (ins GRRegs:$src1, GRRegs:$src2),
|
||||
"setclk res[$src1], $src2",
|
||||
[(int_xcore_setclk GRRegs:$src1, GRRegs:$src2)]>;
|
||||
|
||||
def SETRDY_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
|
||||
"setrdy res[$src1], $src2",
|
||||
[(int_xcore_setrdy GRRegs:$src1, GRRegs:$src2)]>;
|
||||
def SETRDY_l2r : _FLR2R<0b0010111000, (outs), (ins GRRegs:$src1, GRRegs:$src2),
|
||||
"setrdy res[$src1], $src2",
|
||||
[(int_xcore_setrdy GRRegs:$src1, GRRegs:$src2)]>;
|
||||
|
||||
// One operand short
|
||||
// TODO edu, eeu, waitet, waitef, tstart, clrtp
|
||||
|
@ -164,3 +164,35 @@
|
||||
|
||||
# CHECK: endin r10, res[r1]
|
||||
0x59 0x97
|
||||
|
||||
# l2r instructions
|
||||
|
||||
# CHECK: bitrev r1, r10
|
||||
0x26 0xff 0xec 0x07
|
||||
|
||||
# CHECK: byterev r4, r1
|
||||
0x11 0xff 0xec 0x07
|
||||
|
||||
# CHECK: clz r11, r10
|
||||
0xae 0xff 0xec 0x0f
|
||||
|
||||
# CHECK: get r3, ps[r6]
|
||||
0x9e 0xff 0xec 0x17
|
||||
|
||||
# CHECK: setc res[r5], r9
|
||||
0x75 0xff 0xec 0x2f
|
||||
|
||||
# CHECK: init t[r2]:lr, r1
|
||||
0xc6 0xfe 0xec 0x17
|
||||
|
||||
# CHECK: setclk res[r2], r1
|
||||
0xd6 0xfe 0xec 0x0f
|
||||
|
||||
# CHECK: set ps[r9], r10
|
||||
0xa9 0xff 0xec 0x1f
|
||||
|
||||
# CHECK: setrdy res[r3], r1
|
||||
0xc7 0xfe 0xec 0x2f
|
||||
|
||||
# CHECK: settw res[r7], r2
|
||||
0x9b 0xff 0xec 0x27
|
||||
|
Loading…
Reference in New Issue
Block a user