Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -176,6 +176,10 @@ void expandMemInst(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions, bool isLoad, bool isImmOpnd); + + bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions); + bool reportParseError(Twine ErrorMsg); bool reportParseError(SMLoc Loc, Twine ErrorMsg); @@ -1211,6 +1215,8 @@ case Mips::LoadAddr32Imm: case Mips::LoadAddr32Reg: case Mips::LoadImm64Reg: + case Mips::LWM_MM: + case Mips::SWM_MM: return true; default: return false; @@ -1235,6 +1241,9 @@ return expandLoadAddressImm(Inst, IDLoc, Instructions); case Mips::LoadAddr32Reg: return expandLoadAddressReg(Inst, IDLoc, Instructions); + case Mips::SWM_MM: + case Mips::LWM_MM: + return expandLoadStoreMultiple(Inst, IDLoc, Instructions); } } @@ -1636,6 +1645,28 @@ TempInst.clear(); } +bool +MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions) { + unsigned opNum = Inst.getNumOperands(); + unsigned Opcode = Inst.getOpcode(); + unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM; + + if (opNum < 8 && (Inst.getOperand(opNum - 1).isImm() && + (Inst.getOperand(opNum - 1).getImm() <= 60) && + (Inst.getOperand(opNum - 1).getImm() >= 0)) && + (Inst.getOperand(opNum - 2).isReg() && + (Inst.getOperand(opNum - 2).getReg() == Mips::SP)) && + (Inst.getOperand(opNum - 3).isReg() && + (Inst.getOperand(opNum - 3).getReg() == Mips::RA))) + // It can be implemented as SWM16 or LWM16 instruction. + NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM; + + Inst.setOpcode(NewOpcode); + Instructions.push_back(Inst); + return false; +} + unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { // As described by the Mips32r2 spec, the registers Rd and Rs for // jalr.hb must be different. Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -369,6 +369,19 @@ def SWM16_MM : StoreMultMM16<"swm16">, LWM_FM_MM16<0x5>; def LWM16_MM : LoadMultMM16<"lwm16">, LWM_FM_MM16<0x4>; + /// Load and Store multiple pseudo Instructions + class LoadWordMultMM : + MipsAsmPseudoInst<(outs reglist:$rt), (ins mem_mm_12:$addr), + !strconcat(instr_asm, "\t$rt, $addr")> ; + + class StoreWordMultMM : + MipsAsmPseudoInst<(outs), (ins reglist:$rt, mem_mm_12:$addr), + !strconcat(instr_asm, "\t$rt, $addr")> ; + + + def SWM_MM : StoreWordMultMM<"swm">; + def LWM_MM : LoadWordMultMM<"lwm">; + /// Move Conditional def MOVZ_I_MM : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd, NoItinerary>, ADD_FM_MM<0, 0x58>; Index: test/MC/Mips/micromips-loadstore-instructions.s =================================================================== --- test/MC/Mips/micromips-loadstore-instructions.s +++ test/MC/Mips/micromips-loadstore-instructions.s @@ -26,6 +26,14 @@ # CHECK-EL: swm32 $16, $17, $18, $19, 8($4) # encoding: [0x84,0x20,0x08,0xd0] # CHECK-EL: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x12,0x45] # CHECK-EL: swm16 $16, $17, $ra, 8($sp) # encoding: [0x52,0x45] +# CHECK-EL: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x12,0x45] +# CHECK-EL: lwm32 $16, $17, $ra, 64($sp) # encoding: [0x5d,0x22,0x40,0x50] +# CHECK-EL: lwm32 $16, $17, $ra, 8($4) # encoding: [0x44,0x22,0x08,0x50] +# CHECK-EL: lwm32 $16, $17, 8($sp) # encoding: [0x5d,0x20,0x08,0x50] +# CHECK-EL: swm16 $16, $17, $ra, 8($sp) # encoding: [0x52,0x45] +# CHECK-EL: swm32 $16, $17, $ra, 64($sp) # encoding: [0x5d,0x22,0x40,0xd0] +# CHECK-EL: swm32 $16, $17, $ra, 8($4) # encoding: [0x44,0x22,0x08,0xd0] +# CHECK-EL: swm32 $16, $17, 8($sp) # encoding: [0x5d,0x20,0x08,0xd0] #------------------------------------------------------------------------------ # Big endian #------------------------------------------------------------------------------ @@ -42,6 +50,14 @@ # CHECK-EB: swm32 $16, $17, $18, $19, 8($4) # encoding: [0x20,0x84,0xd0,0x08] # CHECK-EB: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x12] # CHECK-EB: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x52] +# CHECK-EB: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x12] +# CHECK-EB: lwm32 $16, $17, $ra, 64($sp) # encoding: [0x22,0x5d,0x50,0x40] +# CHECK-EB: lwm32 $16, $17, $ra, 8($4) # encoding: [0x22,0x44,0x50,0x08] +# CHECK-EB: lwm32 $16, $17, 8($sp) # encoding: [0x20,0x5d,0x50,0x08] +# CHECK-EB: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x52] +# CHECK-EB: swm32 $16, $17, $ra, 64($sp) # encoding: [0x22,0x5d,0xd0,0x40] +# CHECK-EB: swm32 $16, $17, $ra, 8($4) # encoding: [0x22,0x44,0xd0,0x08] +# CHECK-EB: swm32 $16, $17, 8($sp) # encoding: [0x20,0x5d,0xd0,0x08] lb $5, 8($4) lbu $6, 8($4) lh $2, 8($4) @@ -59,3 +75,11 @@ swm32 $16 - $19, 8($4) lwm16 $16, $17, $ra, 8($sp) swm16 $16, $17, $ra, 8($sp) + lwm $16, $17, $ra, 8($sp) + lwm $16, $17, $ra, 64($sp) + lwm $16, $17, $ra, 8($4) + lwm $16, $17, 8($sp) + swm $16, $17, $ra, 8($sp) + swm $16, $17, $ra, 64($sp) + swm $16, $17, $ra, 8($4) + swm $16, $17, 8($sp)