Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -255,6 +255,11 @@ static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMemMMImm4(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -911,7 +916,11 @@ unsigned RegNo, uint64_t Address, const void *Decoder) { - return MCDisassembler::Fail; + if (RegNo > 7) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo); + Inst.addOperand(MCOperand::CreateReg(Reg)); + return MCDisassembler::Success; } static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, @@ -1084,6 +1093,58 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeMemMMImm4(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned Offset = Insn & 0xf; + unsigned Reg = fieldFromInstruction(Insn, 7, 3); + unsigned Base = fieldFromInstruction(Insn, 4, 3); + + switch (Inst.getOpcode()) { + case Mips::LBU16_MM: + case Mips::LHU16_MM: + case Mips::LW16_MM: + if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder) + == MCDisassembler::Fail) + return MCDisassembler::Fail; + break; + case Mips::SB16_MM: + case Mips::SH16_MM: + case Mips::SW16_MM: + if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder) + == MCDisassembler::Fail) + return MCDisassembler::Fail; + break; + } + + if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder) + == MCDisassembler::Fail) + return MCDisassembler::Fail; + + switch (Inst.getOpcode()) { + case Mips::LBU16_MM: + if (Offset == 0xf) + Inst.addOperand(MCOperand::CreateImm(-1)); + else + Inst.addOperand(MCOperand::CreateImm(Offset)); + break; + case Mips::SB16_MM: + Inst.addOperand(MCOperand::CreateImm(Offset)); + break; + case Mips::LHU16_MM: + case Mips::SH16_MM: + Inst.addOperand(MCOperand::CreateImm(Offset << 1)); + break; + case Mips::LW16_MM: + case Mips::SW16_MM: + Inst.addOperand(MCOperand::CreateImm(Offset << 2)); + break; + } + + return MCDisassembler::Success; +} + static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -186,6 +186,7 @@ InstrItinClass Itin, Operand MemOpnd> : MicroMipsInst16<(outs RO:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> { + let DecoderMethod = "DecodeMemMMImm4"; let canFoldAsLoad = 1; let mayLoad = 1; } @@ -194,6 +195,7 @@ SDPatternOperator OpNode, InstrItinClass Itin, Operand MemOpnd> : MicroMipsInst16<(outs), (ins RTOpnd:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> { + let DecoderMethod = "DecodeMemMMImm4"; let mayStore = 1; } Index: lib/Target/Mips/MipsRegisterInfo.td =================================================================== --- lib/Target/Mips/MipsRegisterInfo.td +++ lib/Target/Mips/MipsRegisterInfo.td @@ -297,10 +297,10 @@ def GPRMM16Zero : RegisterClass<"Mips", [i32], 32, (add // Reserved ZERO, - // Return Values and Arguments - V0, V1, A0, A1, A2, A3, // Callee save - S1)>; + S1, + // Return Values and Arguments + V0, V1, A0, A1, A2, A3)>; def GPR64 : RegisterClass<"Mips", [i64], 64, (add // Reserved Index: test/MC/Disassembler/Mips/micromips.txt =================================================================== --- test/MC/Disassembler/Mips/micromips.txt +++ test/MC/Disassembler/Mips/micromips.txt @@ -346,6 +346,30 @@ # CHECK: srl16 $4, $17, 6 0x26 0x1d +# CHECK: lbu16 $3, 4($17) +0x09 0x94 + +# CHECK: lbu16 $3, -1($16) +0x09 0x8f + +# CHECK: lhu16 $3, 4($16) +0x29 0x82 + +# CHECK: lw16 $4, 8($17) +0x6a 0x12 + +# CHECK: sb16 $3, 4($16) +0x89 0x84 + +# CHECK: sh16 $4, 8($17) +0xaa 0x14 + +# CHECK: sw16 $4, 4($17) +0xea 0x11 + +# CHECK: sw16 $zero, 4($17) +0xe8 0x11 + # CHECK: mfhi $9 0x46 0x09 Index: test/MC/Disassembler/Mips/micromips_le.txt =================================================================== --- test/MC/Disassembler/Mips/micromips_le.txt +++ test/MC/Disassembler/Mips/micromips_le.txt @@ -346,6 +346,30 @@ # CHECK: srl16 $4, $17, 6 0x1d 0x26 +# CHECK: lbu16 $3, 4($17) +0x94 0x09 + +# CHECK: lbu16 $3, -1($16) +0x8f 0x09 + +# CHECK: lhu16 $3, 4($16) +0x82 0x29 + +# CHECK: lw16 $4, 8($17) +0x12 0x6a + +# CHECK: sb16 $3, 4($16) +0x84 0x89 + +# CHECK: sh16 $4, 8($17) +0x14 0xaa + +# CHECK: sw16 $4, 4($17) +0x11 0xea + +# CHECK: sw16 $zero, 4($17) +0x11 0xe8 + # CHECK: mfhi $9 0x09 0x46 Index: test/MC/Mips/micromips-16-bit-instructions.s =================================================================== --- test/MC/Mips/micromips-16-bit-instructions.s +++ test/MC/Mips/micromips-16-bit-instructions.s @@ -19,6 +19,7 @@ # CHECK-EL: sll16 $3, $16, 5 # encoding: [0x8a,0x25] # CHECK-EL: srl16 $4, $17, 6 # encoding: [0x1d,0x26] # CHECK-EL: lbu16 $3, 4($17) # encoding: [0x94,0x09] +# CHECK-EL: lbu16 $3, -1($16) # encoding: [0x8f,0x09] # CHECK-EL: lhu16 $3, 4($16) # encoding: [0x82,0x29] # CHECK-EL: lw16 $4, 8($17) # encoding: [0x12,0x6a] # CHECK-EL: sb16 $3, 4($16) # encoding: [0x84,0x89] @@ -56,6 +57,7 @@ # CHECK-EB: sll16 $3, $16, 5 # encoding: [0x25,0x8a] # CHECK-EB: srl16 $4, $17, 6 # encoding: [0x26,0x1d] # CHECK-EB: lbu16 $3, 4($17) # encoding: [0x09,0x94] +# CHECK-EB: lbu16 $3, -1($16) # encoding: [0x09,0x8f] # CHECK-EB: lhu16 $3, 4($16) # encoding: [0x29,0x82] # CHECK-EB: lw16 $4, 8($17) # encoding: [0x6a,0x12] # CHECK-EB: sb16 $3, 4($16) # encoding: [0x89,0x84] @@ -91,6 +93,7 @@ sll16 $3, $16, 5 srl16 $4, $17, 6 lbu16 $3, 4($17) + lbu16 $3, -1($16) lhu16 $3, 4($16) lw16 $4, 8($17) sb16 $3, 4($16)