From 3b6a5eefe0ab2199bc69094b390b736ae332b905 Mon Sep 17 00:00:00 2001 From: Richard Osborne Date: Fri, 25 Jan 2013 20:20:07 +0000 Subject: [PATCH] Add instruction encodings / disassembly support for l5r instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173479 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../XCore/Disassembler/XCoreDisassembler.cpp | 39 +++++++++++++++++++ lib/Target/XCore/XCoreInstrFormats.td | 7 +++- lib/Target/XCore/XCoreInstrInfo.td | 23 ++++++----- test/MC/Disassembler/XCore/xcore.txt | 11 ++++++ 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index 73aeb9c755e..e785030c387 100644 --- a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -175,6 +175,11 @@ static DecodeStatus DecodeL6RInstruction(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeL5RInstruction(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + #include "XCoreGenDisassemblerTables.inc" static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst, @@ -597,6 +602,40 @@ DecodeL6RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, return S; } +static DecodeStatus +DecodeL5RInstructionFail(MCInst &Inst, unsigned Insn, uint64_t Address, + const void *Decoder) { + // Try and decode as a L6R instruction. + Inst.clear(); + unsigned Opcode = fieldFromInstruction(Insn, 27, 5); + switch (Opcode) { + case 0x00: + Inst.setOpcode(XCore::LMUL_l6r); + return DecodeL6RInstruction(Inst, Insn, Address, Decoder); + } + return MCDisassembler::Fail; +} + +static DecodeStatus +DecodeL5RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, + const void *Decoder) { + unsigned Op1, Op2, Op3, Op4, Op5; + DecodeStatus S = + Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3); + if (S != MCDisassembler::Success) + return DecodeL5RInstructionFail(Inst, Insn, Address, Decoder); + S = Decode2OpInstruction(fieldFromInstruction(Insn, 16, 16), Op4, Op5); + if (S != MCDisassembler::Success) + return DecodeL5RInstructionFail(Inst, Insn, Address, Decoder); + + DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); + DecodeGRRegsRegisterClass(Inst, Op4, Address, Decoder); + DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder); + DecodeGRRegsRegisterClass(Inst, Op3, Address, Decoder); + DecodeGRRegsRegisterClass(Inst, Op5, Address, Decoder); + return S; +} + MCDisassembler::DecodeStatus XCoreDisassembler::getInstruction(MCInst &instr, uint64_t &Size, diff --git a/lib/Target/XCore/XCoreInstrFormats.td b/lib/Target/XCore/XCoreInstrFormats.td index fa360a77751..624036205c4 100644 --- a/lib/Target/XCore/XCoreInstrFormats.td +++ b/lib/Target/XCore/XCoreInstrFormats.td @@ -222,8 +222,13 @@ class _L4R pattern> : InstXCore<4, outs, ins, asmstr, pattern> { } -class _L5R pattern> +class _FL5R opc, dag outs, dag ins, string asmstr, list pattern> : InstXCore<4, outs, ins, asmstr, pattern> { + let Inst{31-27} = opc{5-1}; + let Inst{20} = opc{0}; + let Inst{15-11} = 0b11111; + + let DecoderMethod = "DecodeL5RInstruction"; } class _FL6R opc, dag outs, dag ins, string asmstr, list pattern> diff --git a/lib/Target/XCore/XCoreInstrInfo.td b/lib/Target/XCore/XCoreInstrInfo.td index e6e434c0123..1810a138344 100644 --- a/lib/Target/XCore/XCoreInstrInfo.td +++ b/lib/Target/XCore/XCoreInstrInfo.td @@ -485,19 +485,18 @@ def CRC8_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2), // Five operand long -def LADD_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), - (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), - "ladd $dst2, $dst1, $src1, $src2, $src3", - []>; - -def LSUB_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), - (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), - "lsub $dst2, $dst1, $src1, $src2, $src3", - []>; - -def LDIVU_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), +def LADD_l5r : _FL5R<0b000001, (outs GRRegs:$dst1, GRRegs:$dst2), (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), - "ldivu $dst1, $dst2, $src3, $src1, $src2", []>; + "ladd $dst2, $dst1, $src1, $src2, $src3", + []>; + +def LSUB_l5r : _FL5R<0b000010, (outs GRRegs:$dst1, GRRegs:$dst2), + (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), + "lsub $dst2, $dst1, $src1, $src2, $src3", []>; + +def LDIVU_l5r : _FL5R<0b000000, (outs GRRegs:$dst1, GRRegs:$dst2), + (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), + "ldivu $dst1, $dst2, $src3, $src1, $src2", []>; // Six operand long diff --git a/test/MC/Disassembler/XCore/xcore.txt b/test/MC/Disassembler/XCore/xcore.txt index d9d7e097bdd..fdc769649d0 100644 --- a/test/MC/Disassembler/XCore/xcore.txt +++ b/test/MC/Disassembler/XCore/xcore.txt @@ -461,3 +461,14 @@ # CHECK: lmul r11, r0, r2, r5, r8, r10 0xf9 0xfa 0x02 0x06 + +# l5r instructions + +# CHECK: ladd r10, r2, r5, r1, r7 +0xe5 0xf8 0xfb 0x06 + +# CHECK: ldivu r5, r6, r3, r9, r8 +0x54 0xfe 0x0b 0x07 + +# CHECK: lsub r1, r8, r7, r11, r5 +0xcf 0xfd 0x85 0x0f