Index: llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -299,6 +299,11 @@ uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1304,6 +1309,22 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<4>(Insn & 0xf); + + if (DecodeRegListOperand16(Inst, Insn, Address, Decoder) + == MCDisassembler::Fail) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::CreateReg(Mips::SP)); + Inst.addOperand(MCOperand::CreateImm(Offset << 2)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1803,15 +1824,10 @@ uint64_t Address, const void *Decoder) { unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; - unsigned RegNum; - unsigned RegLst = fieldFromInstruction(Insn, 4, 2); - // Empty register lists are not allowed. - if (RegLst == 0) - return MCDisassembler::Fail; + unsigned RegNum = RegLst & 0x3; - RegNum = RegLst & 0x3; - for (unsigned i = 0; i < RegNum - 1; i++) + for (unsigned i = 0; i <= RegNum; i++) Inst.addOperand(MCOperand::CreateReg(Regs[i])); Inst.addOperand(MCOperand::CreateReg(Mips::RA)); Index: llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td @@ -505,6 +505,7 @@ ComplexPattern Addr = addr> : MicroMipsInst16<(outs), (ins reglist16:$rt, mem_mm_4sp:$addr), !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> { + let DecoderMethod = "DecodeMemMMReglistImm4Lsl2"; let mayStore = 1; } @@ -513,6 +514,7 @@ ComplexPattern Addr = addr> : MicroMipsInst16<(outs reglist16:$rt), (ins mem_mm_4sp:$addr), !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> { + let DecoderMethod = "DecodeMemMMReglistImm4Lsl2"; let mayLoad = 1; } Index: llvm/trunk/test/MC/Disassembler/Mips/micromips.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/Mips/micromips.txt +++ llvm/trunk/test/MC/Disassembler/Mips/micromips.txt @@ -489,3 +489,9 @@ # CHECK: lw $3, 32($gp) 0x65 0x88 + +# CHECK: lwm16 $16, $17, $ra, 8($sp) +0x45 0x12 + +# CHECK: swm16 $16, $17, $ra, 8($sp) +0x45 0x52 Index: llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt +++ llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt @@ -489,3 +489,9 @@ # CHECK: lw $3, 32($gp) 0x88 0x65 + +# CHECK: lwm16 $16, $17, $ra, 8($sp) +0x12 0x45 + +# CHECK: swm16 $16, $17, $ra, 8($sp) +0x52 0x45