diff --git a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index 96a985de28f..d24d9476cd6 100644 --- a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -157,6 +157,16 @@ static DecodeStatus DecodeL3RSrcDstInstruction(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeL2RUSInstruction(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeL2RUSBitpInstruction(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + #include "XCoreGenDisassemblerTables.inc" static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst, @@ -366,7 +376,7 @@ DecodeRUSSrcDstBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, static DecodeStatus DecodeL2OpInstructionFail(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { - // Try and decode as a L3R instruction. + // Try and decode as a L3R / L2RUS instruction. unsigned Opcode = fieldFromInstruction(Insn, 16, 4) | fieldFromInstruction(Insn, 27, 5) << 4; switch (Opcode) { @@ -406,6 +416,15 @@ DecodeL2OpInstructionFail(MCInst &Inst, unsigned Insn, uint64_t Address, case 0x11c: Inst.setOpcode(XCore::ST8_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); + case 0x12c: + Inst.setOpcode(XCore::ASHR_l2rus); + return DecodeL2RUSBitpInstruction(Inst, Insn, Address, Decoder); + case 0x13c: + Inst.setOpcode(XCore::LDAWF_l2rus); + return DecodeL2RUSInstruction(Inst, Insn, Address, Decoder); + case 0x14c: + Inst.setOpcode(XCore::LDAWB_l2rus); + return DecodeL2RUSInstruction(Inst, Insn, Address, Decoder); case 0x15c: Inst.setOpcode(XCore::CRC_l3r); return DecodeL3RSrcDstInstruction(Inst, Insn, Address, Decoder); @@ -515,6 +534,34 @@ DecodeL3RSrcDstInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, return S; } +static DecodeStatus +DecodeL2RUSInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, + const void *Decoder) { + unsigned Op1, Op2, Op3; + DecodeStatus S = + Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3); + if (S == MCDisassembler::Success) { + DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); + DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder); + Inst.addOperand(MCOperand::CreateImm(Op3)); + } + return S; +} + +static DecodeStatus +DecodeL2RUSBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, + const void *Decoder) { + unsigned Op1, Op2, Op3; + DecodeStatus S = + Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3); + if (S == MCDisassembler::Success) { + DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); + DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder); + DecodeBitpOperand(Inst, Op3, 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 817ba490bdd..01ed5cbf938 100644 --- a/lib/Target/XCore/XCoreInstrFormats.td +++ b/lib/Target/XCore/XCoreInstrFormats.td @@ -68,8 +68,21 @@ class _F2RUSBitp opc, dag outs, dag ins, string asmstr, let DecoderMethod = "Decode2RUSBitpInstruction"; } -class _FL2RUS pattern> +class _FL2RUS opc, dag outs, dag ins, string asmstr, list pattern> : InstXCore<4, outs, ins, asmstr, pattern> { + let Inst{31-27} = opc{8-4}; + let Inst{26-20} = 0b1111110; + let Inst{19-16} = opc{3-0}; + + let Inst{15-11} = 0b11111; + let DecoderMethod = "DecodeL2RUSInstruction"; +} + +// L2RUS with bitp operand +class _FL2RUSBitp opc, dag outs, dag ins, string asmstr, + list pattern> + : _FL2RUS { + let DecoderMethod = "DecodeL2RUSBitpInstruction"; } class _FRU6 pattern> diff --git a/lib/Target/XCore/XCoreInstrInfo.td b/lib/Target/XCore/XCoreInstrInfo.td index cb4dc650bcc..4018e317664 100644 --- a/lib/Target/XCore/XCoreInstrInfo.td +++ b/lib/Target/XCore/XCoreInstrInfo.td @@ -237,25 +237,25 @@ class F3R_np opc, string OpcStr> : // Three operand long /// FL3R_L2RUS multiclass - Define a normal FL3R/FL2RUS pattern in one shot. -multiclass FL3R_L2RUS opc, string OpcStr, SDNode OpNode> { - def _l3r: _FL3R opc1, bits<9> opc2, string OpcStr, + SDNode OpNode> { + def _l3r: _FL3R; - def _l2rus : _FL2RUS< - (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), - !strconcat(OpcStr, " $dst, $b, $c"), - [(set GRRegs:$dst, (OpNode GRRegs:$b, immUs:$c))]>; + def _l2rus : _FL2RUS; } /// FL3R_L2RUS multiclass - Define a normal FL3R/FL2RUS pattern in one shot. -multiclass FL3R_L2RBITP opc, string OpcStr, SDNode OpNode> { - def _l3r: _FL3R opc1, bits<9> opc2, string OpcStr, + SDNode OpNode> { + def _l3r: _FL3R; - def _l2rus : _FL2RUS< - (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), - !strconcat(OpcStr, " $dst, $b, $c"), - [(set GRRegs:$dst, (OpNode GRRegs:$b, immBitp:$c))]>; + def _l2rus : _FL2RUSBitp; } class FL3R opc, string OpcStr, SDNode OpNode> : @@ -430,10 +430,9 @@ def LDAWF_l3r : _FL3R<0b000111100, (outs GRRegs:$dst), (ldawf GRRegs:$addr, GRRegs:$offset))]>; let neverHasSideEffects = 1 in -def LDAWF_l2rus : _FL2RUS<(outs GRRegs:$dst), - (ins GRRegs:$addr, i32imm:$offset), - "ldaw $dst, $addr[$offset]", - []>; +def LDAWF_l2rus : _FL2RUS<0b100111100, (outs GRRegs:$dst), + (ins GRRegs:$addr, i32imm:$offset), + "ldaw $dst, $addr[$offset]", []>; def LDAWB_l3r : _FL3R<0b001001100, (outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), @@ -442,10 +441,9 @@ def LDAWB_l3r : _FL3R<0b001001100, (outs GRRegs:$dst), (ldawb GRRegs:$addr, GRRegs:$offset))]>; let neverHasSideEffects = 1 in -def LDAWB_l2rus : _FL2RUS<(outs GRRegs:$dst), - (ins GRRegs:$addr, i32imm:$offset), - "ldaw $dst, $addr[-$offset]", - []>; +def LDAWB_l2rus : _FL2RUS<0b101001100, (outs GRRegs:$dst), + (ins GRRegs:$addr, i32imm:$offset), + "ldaw $dst, $addr[-$offset]", []>; def LDA16F_l3r : _FL3R<0b001011100, (outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), @@ -468,7 +466,7 @@ def REMS_l3r : FL3R<0b110001100, "rems", srem>; def REMU_l3r : FL3R<0b110011100, "remu", urem>; } def XOR_l3r : FL3R<0b000011100, "xor", xor>; -defm ASHR : FL3R_L2RBITP<0b000101100, "ashr", sra>; +defm ASHR : FL3R_L2RBITP<0b000101100, 0b100101100, "ashr", sra>; let Constraints = "$src1 = $dst" in def CRC_l3r : _FL3RSrcDst<0b101011100, (outs GRRegs:$dst), diff --git a/test/MC/Disassembler/XCore/xcore.txt b/test/MC/Disassembler/XCore/xcore.txt index c86350e80a3..7b5d5123bd5 100644 --- a/test/MC/Disassembler/XCore/xcore.txt +++ b/test/MC/Disassembler/XCore/xcore.txt @@ -301,3 +301,14 @@ # CHECK: xor r4, r3, r9 0xcd 0xfc 0xec 0x0f + +# l2rus instructions + +# CHECK: ashr r5, r1, 3 +0x57 0xf8 0xec 0x97 + +# CHECK: ldaw r11, r10[6] +0x7a 0xfc 0xec 0x9f + +# CHECK: ldaw r8, r2[-9] +0x09 0xfd 0xec 0xa7