Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -256,6 +256,11 @@ uint64_t Address, const void *Decoder); +static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1142,6 +1147,24 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<9>(Insn & 0x1ff); + unsigned Reg = fieldFromInstruction(Insn, 21, 5); + unsigned Base = fieldFromInstruction(Insn, 16, 5); + + Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address, Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -172,6 +172,9 @@ unsigned getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -768,6 +768,19 @@ return OffBits & 0x7F; } + unsigned MipsMCCodeEmitter:: +getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. + assert(MI.getOperand(OpNo).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI) << 16; + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + + return (OffBits & 0x1FF) | RegBits; +} + unsigned MipsMCCodeEmitter:: getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, Index: lib/Target/Mips/MicroMips32r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrFormats.td +++ lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -198,6 +198,32 @@ let Inst{5-0} = funct; } +class STORE_FM_MMR6 op> { + bits<5> rt; + bits<21> addr; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = rt; + let Inst{20-16} = addr{20-16}; + let Inst{15-0} = addr{15-0}; +} + +class STORE_EVA_FM_MMR6 funct> { + bits<5> rt; + bits<21> addr; + + bits<32> Inst; + + let Inst{31-26} = 0b011000; + let Inst{25-21} = rt; + let Inst{20-16} = addr{20-16}; // base + let Inst{15-12} = 0b1010; + let Inst{11-9} = funct; + let Inst{8-0} = addr{8-0}; // offset +} + class CMP_BRANCH_1R_RT_OFF16_FM_MMR6 funct> : MipsR6Inst { bits<5> rt; bits<16> offset; Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -68,6 +68,11 @@ class SUBU_MMR6_ENC : ARITH_FM_MMR6<"subu", 0x1d0>; class XOR_MMR6_ENC : ARITH_FM_MMR6<"xor", 0x310>; class XORI_MMR6_ENC : ADDI_FM_MMR6<"xori", 0x1c>; +class SB_MMR6_ENC : STORE_FM_MMR6<0b000110>; +class SBE_MMR6_ENC : STORE_EVA_FM_MMR6<0b100>; +class SCE_MMR6_ENC : STORE_EVA_FM_MMR6<0b110>; +class SH_MMR6_ENC : STORE_FM_MMR6<0b001110>; +class SHE_MMR6_ENC : STORE_EVA_FM_MMR6<0b101>; class CMP_CBR_RT_Z_MMR6_DESC_BASE @@ -114,6 +119,14 @@ // //===----------------------------------------------------------------------===// +def mem_mm_9 : Operand { + let PrintMethod = "printMemOperand"; + let MIOperandInfo = (ops GPR32, simm9); + let EncoderMethod = "getMemEncodingMMImm9"; + let ParserMatchClass = MipsMemAsmOperand; + let OperandType = "OPERAND_MEMORY"; +} + class ADD_MMR6_DESC : ArithLogicR<"add", GPR32Opnd>; class ADDIU_MMR6_DESC : ArithLogicI<"addiu", simm16, GPR32Opnd>; class ADDU_MMR6_DESC : ArithLogicR<"addu", GPR32Opnd>; @@ -277,6 +290,25 @@ class XOR_MMR6_DESC : ArithLogicR<"xor", GPR32Opnd>; class XORI_MMR6_DESC : ArithLogicI<"xori", simm16, GPR32Opnd>; +class STORE_MMR6_DESC_BASE : + Store, MMR6Arch { + let DecoderMethod = "DecodeMemMMImm16"; +} +class SB_MMR6_DESC : STORE_MMR6_DESC_BASE<"sb", GPR32Opnd>; + +class STORE_EVA_MMR6_DESC_BASE : + MMR6Arch, MipsR6Inst { + dag OutOperandList = (outs); + dag InOperandList = (ins RO:$rt, mem_mm_9:$addr); + string AsmString = !strconcat(instr_asm, "\t$rt, $addr"); + string DecoderMethod = "DecodeStoreEvaOpMM"; + bit mayStore = 1; +} +class SBE_MMR6_DESC : STORE_EVA_MMR6_DESC_BASE<"sbe", GPR32Opnd>; +class SCE_MMR6_DESC : STORE_EVA_MMR6_DESC_BASE<"sce", GPR32Opnd>; +class SH_MMR6_DESC : STORE_MMR6_DESC_BASE<"sh", GPR32Opnd>; +class SHE_MMR6_DESC : STORE_EVA_MMR6_DESC_BASE<"she", GPR32Opnd>; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -348,6 +380,11 @@ def SUBU_MMR6 : StdMMR6Rel, SUBU_MMR6_DESC, SUBU_MMR6_ENC, ISA_MICROMIPS32R6; def XOR_MMR6 : StdMMR6Rel, XOR_MMR6_DESC, XOR_MMR6_ENC, ISA_MICROMIPS32R6; def XORI_MMR6 : StdMMR6Rel, XORI_MMR6_DESC, XORI_MMR6_ENC, ISA_MICROMIPS32R6; +def SB_MMR6 : StdMMR6Rel, SB_MMR6_DESC, SB_MMR6_ENC, ISA_MICROMIPS32R6; +def SBE_MMR6 : StdMMR6Rel, SBE_MMR6_DESC, SBE_MMR6_ENC, ISA_MICROMIPS32R6; +def SCE_MMR6 : StdMMR6Rel, SCE_MMR6_DESC, SCE_MMR6_ENC, ISA_MICROMIPS32R6; +def SH_MMR6 : StdMMR6Rel, SH_MMR6_DESC, SH_MMR6_ENC, ISA_MICROMIPS32R6; +def SHE_MMR6 : StdMMR6Rel, SHE_MMR6_DESC, SHE_MMR6_ENC, ISA_MICROMIPS32R6; } //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -1221,7 +1221,8 @@ def LW : Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel, LW_FM<0x23>; } -def SB : Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, LW_FM<0x28>; +def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, + LW_FM<0x28>; def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>; let AdditionalPredicates = [NotInMicroMips] in { def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>; Index: test/MC/Disassembler/Mips/micromips32r6.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r6.txt +++ test/MC/Disassembler/Mips/micromips32r6.txt @@ -108,6 +108,16 @@ 0x70 0x64 0x04 0xd2 # CHECK: xori $3, $4, 1234 +0x18 0x85 0x00 0x06 # CHECK: sb $4, 6($5) + +0x60 0x85 0xa8 0x06 # CHECK: sbe $4, 6($5) + +0x60 0x85 0xac 0x06 # CHECK: sce $4, 6($5) + +0x38 0x85 0x00 0x06 # CHECK: sh $4, 6($5) + +0x60 0x85 0xaa 0x06 # CHECK: she $4, 6($5) + 0x00 0x64 0x2b 0x3c # CHECK: seb $3, $4 0x00 0x64 0x3b 0x3c # CHECK: seh $3, $4 Index: test/MC/Mips/micromips32r6/valid.s =================================================================== --- test/MC/Mips/micromips32r6/valid.s +++ test/MC/Mips/micromips32r6/valid.s @@ -58,4 +58,9 @@ subu $3, $4, $5 # CHECK: subu $3, $4, $5 # encoding: [0x00,0xa4,0x19,0xd0] xor $3, $4, $5 # CHECK: xor $3, $4, $5 # encoding: [0x00,0xa4,0x1b,0x10] xori $3, $4, 1234 # CHECK: xori $3, $4, 1234 # encoding: [0x70,0x64,0x04,0xd2] + sb $4, 6($5) # CHECK: sb $4, 6($5) # encoding: [0x18,0x85,0x00,0x06] + sbe $4, 6($5) # CHECK: sbe $4, 6($5) # encoding: [0x60,0x85,0xa8,0x06] + sce $4, 6($5) # CHECK: sce $4, 6($5) # encoding: [0x60,0x85,0xac,0x06] + sh $4, 6($5) # CHECK: sh $4, 6($5) # encoding: [0x38,0x85,0x00,0x06] + she $4, 6($5) # CHECK: she $4, 6($5) # encoding: [0x60,0x85,0xaa,0x06]