diff options
author | Richard Osborne <richard@xmos.com> | 2012-12-17 16:28:02 +0000 |
---|---|---|
committer | Richard Osborne <richard@xmos.com> | 2012-12-17 16:28:02 +0000 |
commit | c47793c62c434bd27fee1d243c2081a34d4f3817 (patch) | |
tree | c67dbecb9a16e36c6d7e3df0495ff44fedfd3723 | |
parent | 9f84c05705f91686d00d0c200601eaa9df4193f0 (diff) |
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
-rw-r--r-- | lib/Target/XCore/Disassembler/XCoreDisassembler.cpp | 74 | ||||
-rw-r--r-- | lib/Target/XCore/XCoreInstrFormats.td | 15 | ||||
-rw-r--r-- | lib/Target/XCore/XCoreInstrInfo.td | 56 | ||||
-rw-r--r-- | test/MC/Disassembler/XCore/xcore.txt | 32 |
4 files changed, 144 insertions, 33 deletions
diff --git a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index 4f60724f65..094f18ceee 100644 --- a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -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; } diff --git a/lib/Target/XCore/XCoreInstrFormats.td b/lib/Target/XCore/XCoreInstrFormats.td index cccadaef9f..44ac45c72f 100644 --- a/lib/Target/XCore/XCoreInstrFormats.td +++ b/lib/Target/XCore/XCoreInstrFormats.td @@ -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> diff --git a/lib/Target/XCore/XCoreInstrInfo.td b/lib/Target/XCore/XCoreInstrInfo.td index 781ba2b096..95b076fdb4 100644 --- a/lib/Target/XCore/XCoreInstrInfo.td +++ b/lib/Target/XCore/XCoreInstrInfo.td @@ -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 diff --git a/test/MC/Disassembler/XCore/xcore.txt b/test/MC/Disassembler/XCore/xcore.txt index 2444a7d822..f6b9c90da0 100644 --- a/test/MC/Disassembler/XCore/xcore.txt +++ b/test/MC/Disassembler/XCore/xcore.txt @@ -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 |