Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -980,8 +980,11 @@ return false; int Size = RegList.List->size(); - if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 || - RegList.List->back() != Mips::RA) + if (!(Size >= 2 && Size <= 5 && + ((*RegList.List->begin() == Mips::S0 && + RegList.List->back() == Mips::RA) || + (*RegList.List->begin() == Mips::S0_64 && + RegList.List->back() == Mips::RA_64)))) return false; int PrevReg = *RegList.List->begin(); @@ -1748,6 +1751,7 @@ return Error(IDLoc, "immediate operand value out of range"); break; case Mips::SB16_MM: + case Mips::SB16_MMR6: Opnd = Inst.getOperand(2); if (!Opnd.isImm()) return Error(IDLoc, "expected immediate operand kind"); @@ -1757,6 +1761,7 @@ break; case Mips::LHU16_MM: case Mips::SH16_MM: + case Mips::SH16_MMR6: Opnd = Inst.getOperand(2); if (!Opnd.isImm()) return Error(IDLoc, "expected immediate operand kind"); @@ -1766,6 +1771,7 @@ break; case Mips::LW16_MM: case Mips::SW16_MM: + case Mips::SW16_MMR6: Opnd = Inst.getOperand(2); if (!Opnd.isImm()) return Error(IDLoc, "expected immediate operand kind"); @@ -2565,10 +2571,16 @@ if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 && Inst.getOperand(OpNum - 1).getImm() >= 0 && - Inst.getOperand(OpNum - 2).getReg() == Mips::SP && - Inst.getOperand(OpNum - 3).getReg() == Mips::RA) + (Inst.getOperand(OpNum - 2).getReg() == Mips::SP || + Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) && + (Inst.getOperand(OpNum - 3).getReg() == Mips::RA || + Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) { // It can be implemented as SWM16 or LWM16 instruction. - NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM; + if (inMicroMipsMode() && (hasMips32r6() || hasMips64r6())) + NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6; + else + NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM; + } Inst.setOpcode(NewOpcode); Instructions.push_back(Inst); @@ -3963,12 +3975,16 @@ if (RegRange) { // Remove last register operand because registers from register range // should be inserted first. - if (RegNo == Mips::RA) { + if ((isGP64bit() && RegNo == Mips::RA_64) || + (!isGP64bit() && RegNo == Mips::RA)) { Regs.push_back(RegNo); } else { unsigned TmpReg = PrevReg + 1; while (TmpReg <= RegNo) { - if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) { + if ((isGP64bit() && ((TmpReg < Mips::S0_64) || + (TmpReg > Mips::S7_64))) || + (!isGP64bit() && ((TmpReg < Mips::S0) || + (TmpReg > Mips::S7)))) { Error(E, "invalid register operand"); return MatchOperand_ParseFail; } @@ -3980,16 +3996,26 @@ RegRange = false; } else { - if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) && - (RegNo != Mips::RA)) { + if ((PrevReg == Mips::NoRegister) && + ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) || + (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) { Error(E, "$16 or $31 expected"); return MatchOperand_ParseFail; - } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) && - (RegNo != Mips::FP) && (RegNo != Mips::RA)) { + } else if (((isGP64bit() && ((RegNo < Mips::S0_64) || + (RegNo > Mips::S7_64))) || + (!isGP64bit() && ((RegNo < Mips::S0) || + (RegNo > Mips::S7)))) && + ((isGP64bit() && (RegNo != Mips::FP_64) && + (RegNo != Mips::RA_64)) || + (!isGP64bit() && (RegNo != Mips::FP) && + (RegNo != Mips::RA)))) { Error(E, "invalid register operand"); return MatchOperand_ParseFail; } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) && - (RegNo != Mips::FP) && (RegNo != Mips::RA)) { + ((isGP64bit() && (RegNo != Mips::FP_64) && + (RegNo != Mips::RA_64)) || + (!isGP64bit() && (RegNo != Mips::FP) && + (RegNo != Mips::RA)))) { Error(E, "consecutive register numbers expected"); return MatchOperand_ParseFail; } Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -1242,8 +1242,11 @@ return MCDisassembler::Fail; break; case Mips::SB16_MM: + case Mips::SB16_MMR6: case Mips::SH16_MM: + case Mips::SH16_MMR6: case Mips::SW16_MM: + case Mips::SW16_MMR6: if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder) == MCDisassembler::Fail) return MCDisassembler::Fail; @@ -1262,14 +1265,17 @@ Inst.addOperand(MCOperand::createImm(Offset)); break; case Mips::SB16_MM: + case Mips::SB16_MMR6: Inst.addOperand(MCOperand::createImm(Offset)); break; case Mips::LHU16_MM: case Mips::SH16_MM: + case Mips::SH16_MMR6: Inst.addOperand(MCOperand::createImm(Offset << 1)); break; case Mips::LW16_MM: case Mips::SW16_MM: + case Mips::SW16_MMR6: Inst.addOperand(MCOperand::createImm(Offset << 2)); break; } @@ -1313,7 +1319,16 @@ unsigned Insn, uint64_t Address, const void *Decoder) { - int Offset = SignExtend32<4>(Insn & 0xf); + int Offset; + switch (Inst.getOpcode()) { + case Mips::LWM16_MMR6: + case Mips::SWM16_MMR6: + Offset = fieldFromInstruction(Insn, 4, 4); + break; + default: + Offset = SignExtend32<4>(Insn & 0xf); + break; + } if (DecodeRegListOperand16(Inst, Insn, Address, Decoder) == MCDisassembler::Fail) @@ -1854,7 +1869,17 @@ uint64_t Address, const void *Decoder) { unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; - unsigned RegLst = fieldFromInstruction(Insn, 4, 2); + unsigned RegLst; + switch(Inst.getOpcode()) + { + default: + RegLst = fieldFromInstruction(Insn, 4, 2); + break; + case Mips::LWM16_MMR6: + case Mips::SWM16_MMR6: + RegLst = fieldFromInstruction(Insn, 8, 2); + break; + } unsigned RegNum = RegLst & 0x3; for (unsigned i = 0; i <= RegNum; i++) Index: lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp =================================================================== --- lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp +++ lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp @@ -235,7 +235,9 @@ case Mips::SWM32_MM: case Mips::LWM32_MM: case Mips::SWM16_MM: + case Mips::SWM16_MMR6: case Mips::LWM16_MM: + case Mips::LWM16_MMR6: opNum = MI->getNumOperands() - 2; break; } Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -745,7 +745,8 @@ const MCSubtargetInfo &STI) const { // Register is encoded in bits 9-5, offset is encoded in bits 4-0. assert(MI.getOperand(OpNo).isReg() && - MI.getOperand(OpNo).getReg() == Mips::SP && + (MI.getOperand(OpNo).getReg() == Mips::SP || + MI.getOperand(OpNo).getReg() == Mips::SP_64) && "Unexpected base register!"); unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) >> 2; @@ -801,7 +802,9 @@ default: break; case Mips::SWM16_MM: + case Mips::SWM16_MMR6: case Mips::LWM16_MM: + case Mips::LWM16_MMR6: OpNo = MI.getNumOperands() - 2; break; } Index: lib/Target/Mips/MicroMips32r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrFormats.td +++ lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -42,6 +42,18 @@ let Inst{6-0} = offset; } +class LWM_FM_MM16R6 funct> { + bits<2> rt; + bits<4> addr; + + bits<16> Inst; + + let Inst{15-10} = 0x11; + let Inst{9-8} = rt; + let Inst{7-4} = addr; + let Inst{3-0} = funct; +} + class POOL32A_BITSWAP_FM_MMR6 funct> : MipsR6Inst { bits<5> rd; bits<5> rt; Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -52,6 +52,7 @@ class JIC_MMR6_ENC : JMP_IDX_COMPACT_FM<0b101000>; class LSA_MMR6_ENC : POOL32A_LSA_FM<0b001111>; class LWPC_MMR6_ENC : PCREL19_FM_MMR6<0b01>; +class LWM16_MMR6_ENC : LWM_FM_MM16R6<0x2>; class MOD_MMR6_ENC : ARITH_FM_MMR6<"mod", 0x158>; class MODU_MMR6_ENC : ARITH_FM_MMR6<"modu", 0x1d8>; class MUL_MMR6_ENC : ARITH_FM_MMR6<"mul", 0x18>; @@ -62,15 +63,20 @@ class OR_MMR6_ENC : ARITH_FM_MMR6<"or", 0x290>; class ORI_MMR6_ENC : ADDI_FM_MMR6<"ori", 0x14>; class PREF_MMR6_ENC : CACHE_PREF_FM_MMR6<0b011000, 0b0010>; +class SB16_MMR6_ENC : LOAD_STORE_FM_MM16<0x22>; class SEB_MMR6_ENC : SIGN_EXTEND_FM_MMR6<"seb", 0b0010101100>; class SEH_MMR6_ENC : SIGN_EXTEND_FM_MMR6<"seh", 0b0011101100>; class SELEQZ_MMR6_ENC : POOL32A_FM_MMR6<0b0101000000>; class SELNEZ_MMR6_ENC : POOL32A_FM_MMR6<0b0110000000>; +class SH16_MMR6_ENC : LOAD_STORE_FM_MM16<0x2a>; class SLL_MMR6_ENC : SHIFT_MMR6_ENC<"sll", 0x00, 0b0>; class SUB_MMR6_ENC : ARITH_FM_MMR6<"sub", 0x190>; class SUBU_MMR6_ENC : ARITH_FM_MMR6<"subu", 0x1d0>; class SW_MMR6_ENC : SW32_FM_MMR6<"sw", 0x3e>; class SWE_MMR6_ENC : POOL32C_SWE_FM_MMR6<"swe", 0x18, 0xa, 0x7>; +class SW16_MMR6_ENC : LOAD_STORE_FM_MM16<0x3a>; +class SWM16_MMR6_ENC : LWM_FM_MM16R6<0xa>; +class SWSP_MMR6_ENC : LOAD_STORE_SP_FM_MM16<0x32>; class XOR_MMR6_ENC : ARITH_FM_MMR6<"xor", 0x310>; class XORI_MMR6_ENC : ADDI_FM_MMR6<"xori", 0x1c>; @@ -537,6 +543,52 @@ ISA_MICROMIPS32R6; } +class LWM16_MMR6_DESC + : MicroMipsInst16<(outs reglist16:$rt), (ins mem_mm_4sp:$addr), + !strconcat("lwm16", "\t$rt, $addr"), [], + NoItinerary, FrmI>, + MMR6Arch<"lwm16">, MicroMipsR6Inst16 { + let DecoderMethod = "DecodeMemMMReglistImm4Lsl2"; + let mayLoad = 1; + InstrItinClass Itin = NoItinerary; + ComplexPattern Addr = addr; +} + +class SWM16_MMR6_DESC + : MicroMipsInst16<(outs), (ins reglist16:$rt, mem_mm_4sp:$addr), + !strconcat("swm16", "\t$rt, $addr"), [], + NoItinerary, FrmI>, + MMR6Arch<"swm16">, MicroMipsR6Inst16 { + let DecoderMethod = "DecodeMemMMReglistImm4Lsl2"; + let mayStore = 1; + InstrItinClass Itin = NoItinerary; + ComplexPattern Addr = addr; +} + +class SB16_MMR6_DESC_BASE + : MicroMipsInst16<(outs), (ins RTOpnd:$rt, MemOpnd:$addr), + !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI>, + MMR6Arch, MicroMipsR6Inst16 { + let DecoderMethod = "DecodeMemMMImm4"; + let mayStore = 1; +} +class SB16_MMR6_DESC : SB16_MMR6_DESC_BASE<"sb16", GPRMM16OpndZero, GPRMM16Opnd, + truncstorei8, II_SB, mem_mm_4>; +class SH16_MMR6_DESC : SB16_MMR6_DESC_BASE<"sh16", GPRMM16OpndZero, GPRMM16Opnd, + truncstorei16, II_SH, mem_mm_4_lsl1>; +class SW16_MMR6_DESC : SB16_MMR6_DESC_BASE<"sw16", GPRMM16OpndZero, GPRMM16Opnd, + store, II_SW, mem_mm_4_lsl2>; + +class SWSP_MMR6_DESC + : MicroMipsInst16<(outs), (ins GPR32Opnd:$rt, mem_mm_sp_imm5_lsl2:$offset), + !strconcat("sw", "\t$rt, $offset"), [], II_SW, FrmI>, + MMR6Arch<"sw">, MicroMipsR6Inst16 { + let DecoderMethod = "DecodeMemMMSPImm5Lsl2"; + let mayStore = 1; +} + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -592,6 +644,7 @@ def JIC_MMR6 : R6MMR6Rel, JIC_MMR6_ENC, JIC_MMR6_DESC, ISA_MICROMIPS32R6; def LSA_MMR6 : R6MMR6Rel, LSA_MMR6_ENC, LSA_MMR6_DESC, ISA_MICROMIPS32R6; def LWPC_MMR6 : R6MMR6Rel, LWPC_MMR6_ENC, LWPC_MMR6_DESC, ISA_MICROMIPS32R6; +def LWM16_MMR6 : StdMMR6Rel, LWM16_MMR6_DESC, LWM16_MMR6_ENC, ISA_MICROMIPS32R6; def MOD_MMR6 : R6MMR6Rel, MOD_MMR6_DESC, MOD_MMR6_ENC, ISA_MICROMIPS32R6; def MODU_MMR6 : R6MMR6Rel, MODU_MMR6_DESC, MODU_MMR6_ENC, ISA_MICROMIPS32R6; def MUL_MMR6 : R6MMR6Rel, MUL_MMR6_DESC, MUL_MMR6_ENC, ISA_MICROMIPS32R6; @@ -602,15 +655,20 @@ def OR_MMR6 : StdMMR6Rel, OR_MMR6_DESC, OR_MMR6_ENC, ISA_MICROMIPS32R6; def ORI_MMR6 : StdMMR6Rel, ORI_MMR6_DESC, ORI_MMR6_ENC, ISA_MICROMIPS32R6; def PREF_MMR6 : R6MMR6Rel, PREF_MMR6_ENC, PREF_MMR6_DESC, ISA_MICROMIPS32R6; +def SB16_MMR6 : StdMMR6Rel, SB16_MMR6_DESC, SB16_MMR6_ENC, ISA_MICROMIPS32R6; def SEB_MMR6 : StdMMR6Rel, SEB_MMR6_DESC, SEB_MMR6_ENC, ISA_MICROMIPS32R6; def SEH_MMR6 : StdMMR6Rel, SEH_MMR6_DESC, SEH_MMR6_ENC, ISA_MICROMIPS32R6; def SELEQZ_MMR6 : R6MMR6Rel, SELEQZ_MMR6_ENC, SELEQZ_MMR6_DESC, ISA_MICROMIPS32R6; def SELNEZ_MMR6 : R6MMR6Rel, SELNEZ_MMR6_ENC, SELNEZ_MMR6_DESC, ISA_MICROMIPS32R6; +def SH16_MMR6 : StdMMR6Rel, SH16_MMR6_DESC, SH16_MMR6_ENC, ISA_MICROMIPS32R6; def SLL_MMR6 : StdMMR6Rel, SLL_MMR6_DESC, SLL_MMR6_ENC, ISA_MICROMIPS32R6; def SUB_MMR6 : StdMMR6Rel, SUB_MMR6_DESC, SUB_MMR6_ENC, ISA_MICROMIPS32R6; def SUBU_MMR6 : StdMMR6Rel, SUBU_MMR6_DESC, SUBU_MMR6_ENC, ISA_MICROMIPS32R6; +def SW16_MMR6 : StdMMR6Rel, SW16_MMR6_DESC, SW16_MMR6_ENC, ISA_MICROMIPS32R6; +def SWM16_MMR6 : StdMMR6Rel, SWM16_MMR6_DESC, SWM16_MMR6_ENC, ISA_MICROMIPS32R6; +def SWSP_MMR6 : StdMMR6Rel, SWSP_MMR6_DESC, SWSP_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; let DecoderMethod = "DecodeMemMMImm16" in { @@ -699,3 +757,12 @@ def B_MMR6_Pseudo : MipsAsmPseudoInst<(outs), (ins brtarget_mm:$offset), !strconcat("b", "\t$offset")>, MicroMipsR6Inst16; + +//===----------------------------------------------------------------------===// +// +// MicroMips arbitrary patterns that map to one or more instructions +// +//===----------------------------------------------------------------------===// + +def : MipsPat<(store GPRMM16:$src, addrimm4lsl2:$addr), + (SW16_MMR6 GPRMM16:$src, addrimm4lsl2:$addr)>, ISA_MICROMIPS32R6; Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -526,7 +526,8 @@ InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> : MicroMipsInst16<(outs), (ins reglist16:$rt, mem_mm_4sp:$addr), - !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> { + !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI>, + PredicateControl { let DecoderMethod = "DecodeMemMMReglistImm4Lsl2"; let mayStore = 1; } @@ -535,7 +536,8 @@ InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> : MicroMipsInst16<(outs reglist16:$rt), (ins mem_mm_4sp:$addr), - !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> { + !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI>, + PredicateControl { let DecoderMethod = "DecodeMemMMReglistImm4Lsl2"; let mayLoad = 1; } @@ -610,6 +612,14 @@ def BREAK16_MM : BrkSdbbp16MM<"break16">, BRKSDBBP16_FM_MM<0x28>; def SDBBP16_MM : BrkSdbbp16MM<"sdbbp16">, BRKSDBBP16_FM_MM<0x2C>; +let DecoderNamespace = "MicroMips" in { + /// Load and Store Instructions - multiple + def SWM16_MM : StoreMultMM16<"swm16">, LWM_FM_MM16<0x5>, + ISA_MICROMIPS32_NOT_MIPS32R6; + def LWM16_MM : LoadMultMM16<"lwm16">, LWM_FM_MM16<0x4>, + ISA_MICROMIPS32_NOT_MIPS32R6; +} + class WaitMM : InstSE<(outs), (ins uimm10:$code_), !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmOther, opstr>; @@ -718,8 +728,6 @@ /// Load and Store Instructions - multiple def SWM32_MM : StoreMultMM<"swm32">, LWM_FM_MM<0xd>; def LWM32_MM : LoadMultMM<"lwm32">, LWM_FM_MM<0x5>; - def SWM16_MM : StoreMultMM16<"swm16">, LWM_FM_MM16<0x5>; - def LWM16_MM : LoadMultMM16<"lwm16">, LWM_FM_MM16<0x4>; /// Load and Store Pair Instructions def SWP_MM : StorePairMM<"swp">, LWM_FM_MM<0x9>; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -262,6 +262,9 @@ class ISA_MICROMIPS64R6 { list InsnPredicates = [HasMicroMips64r6]; } +class ISA_MICROMIPS32_NOT_MIPS32R6 { + list InsnPredicates = [InMicroMips, NotMips32r6]; +} // The portions of MIPS-III that were also added to MIPS32 class INSN_MIPS3_32 { list InsnPredicates = [HasMips3_32]; } Index: test/MC/Disassembler/Mips/micromips32r6.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r6.txt +++ test/MC/Disassembler/Mips/micromips32r6.txt @@ -94,6 +94,8 @@ 0x78 0x48 0x00 0x43 # CHECK: lwpc $2, 268 +0x45 0x22 # CHECK: lwm16 $16, $17, $ra, 8($sp) + 0x00 0x43 0x26 0x0f # CHECK: lsa $2, $3, $4, 3 0x00 0xa4 0x19 0x58 # CHECK: mod $3, $4, $5 @@ -118,16 +120,28 @@ 0x60 0x25 0x20 0x08 # CHECK: pref 1, 8($5) +0x89 0x84 # CHECK: sb16 $3, 4($16) + 0x00 0x83 0x11 0x40 # CHECK: seleqz $2, $3, $4 0x00 0x83 0x11 0x80 # CHECK: selnez $2, $3, $4 +0xaa 0x14 # CHECK: sh16 $4, 8($17) + 0x00 0x83 0x38 0x00 # CHECK: sll $4, $3, 7 0x00 0xa4 0x19 0x90 # CHECK: sub $3, $4, $5 0x00 0xa4 0x19 0xd0 # CHECK: subu $3, $4, $5 +0xc8 0x9f # CHECK: sw $4, 124($sp) + +0xea 0x11 # CHECK: sw16 $4, 4($17) + +0xe8 0x11 # CHECK: sw16 $zero, 4($17) + +0x45 0x2a # CHECK: swm16 $16, $17, $ra, 8($sp) + 0x00 0xa4 0x1b 0x10 # CHECK: xor $3, $4, $5 0x70 0x64 0x04 0xd2 # CHECK: xori $3, $4, 1234 Index: test/MC/Disassembler/Mips/micromips64r6.txt =================================================================== --- test/MC/Disassembler/Mips/micromips64r6.txt +++ test/MC/Disassembler/Mips/micromips64r6.txt @@ -177,3 +177,17 @@ 0x54,0x64,0x3b,0x7b # CHECK: cvt.s.w $f3, $f4 0x54,0x64,0x5b,0x7b # CHECK: cvt.s.l $f3, $f4 + +0x45 0x22 # CHECK: lwm16 $16, $17, $ra, 8($sp) + +0x89 0x84 # CHECK: sb16 $3, 4($16) + +0xaa 0x14 # CHECK: sh16 $4, 8($17) + +0xc8 0x9f # CHECK: sw $4, 124($sp) + +0xea 0x11 # CHECK: sw16 $4, 4($17) + +0xe8 0x11 # CHECK: sw16 $zero, 4($17) + +0x45 0x2a # CHECK: swm16 $16, $17, $ra, 8($sp) Index: test/MC/Mips/micromips32r6/invalid.s =================================================================== --- test/MC/Mips/micromips32r6/invalid.s +++ test/MC/Mips/micromips32r6/invalid.s @@ -20,3 +20,24 @@ swe $33, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction swe $5, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction swe $5, 512($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwm16 $5, $6, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected + lwm16 $16, $19, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected + lwm16 $16-$25, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand + lwm16 $16, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwm16 $16, $17, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sb16 $9, 4($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sb16 $3, 64($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + sb16 $16, 4($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sb16 $7, 4($9) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sh16 $9, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sh16 $4, 68($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + sh16 $16, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sh16 $7, 8($9) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sw16 $9, 4($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sw16 $4, 64($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + sw16 $16, 4($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sw16 $7, 4($10) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swm16 $5, $6, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected + swm16 $16, $19, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected + swm16 $16-$25, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand Index: test/MC/Mips/micromips32r6/valid.s =================================================================== --- test/MC/Mips/micromips32r6/valid.s +++ test/MC/Mips/micromips32r6/valid.s @@ -51,6 +51,8 @@ jic $5, 256 # CHECK: jic $5, 256 # encoding: [0xa0,0x05,0x01,0x00] lsa $2, $3, $4, 3 # CHECK: lsa $2, $3, $4, 3 # encoding: [0x00,0x43,0x26,0x0f] lwpc $2,268 # CHECK: lwpc $2, 268 # encoding: [0x78,0x48,0x00,0x43] + lwm $16, $17, $ra, 8($sp) # CHECK: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x22] + lwm16 $16, $17, $ra, 8($sp) # CHECK: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x22] mod $3, $4, $5 # CHECK: mod $3, $4, $5 # encoding: [0x00,0xa4,0x19,0x58] modu $3, $4, $5 # CHECK: modu $3, $4, $5 # encoding: [0x00,0xa4,0x19,0xd8] mul $3, $4, $5 # CHECK mul $3, $4, $5 # encoding: [0x00,0xa4,0x18,0x18] @@ -62,13 +64,20 @@ or $3, $4, $5 # CHECK: or $3, $4, $5 # encoding: [0x00,0xa4,0x1a,0x90] ori $3, $4, 1234 # CHECK: ori $3, $4, 1234 # encoding: [0x50,0x64,0x04,0xd2] pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0x60,0x25,0x20,0x08] + sb16 $3, 4($16) # CHECK: sb16 $3, 4($16) # encoding: [0x89,0x84] seb $3, $4 # CHECK: seb $3, $4 # encoding: [0x00,0x64,0x2b,0x3c] seh $3, $4 # CHECK: seh $3, $4 # encoding: [0x00,0x64,0x3b,0x3c] seleqz $2,$3,$4 # CHECK: seleqz $2, $3, $4 # encoding: [0x00,0x83,0x11,0x40] selnez $2,$3,$4 # CHECK: selnez $2, $3, $4 # encoding: [0x00,0x83,0x11,0x80] + sh16 $4, 8($17) # CHECK: sh16 $4, 8($17) # encoding: [0xaa,0x14] sll $4, $3, 7 # CHECK: sll $4, $3, 7 # encoding: [0x00,0x83,0x38,0x00] sub $3, $4, $5 # CHECK: sub $3, $4, $5 # encoding: [0x00,0xa4,0x19,0x90] subu $3, $4, $5 # CHECK: subu $3, $4, $5 # encoding: [0x00,0xa4,0x19,0xd0] + sw $4, 124($sp) # CHECK: sw $4, 124($sp) # encoding: [0xc8,0x9f] + sw16 $4, 4($17) # CHECK: sw16 $4, 4($17) # encoding: [0xea,0x11] + sw16 $0, 4($17) # CHECK: sw16 $zero, 4($17) # encoding: [0xe8,0x11] + swm $16, $17, $ra, 8($sp) # CHECK: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x2a] + swm16 $16, $17, $ra, 8($sp) # CHECK: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x2a] 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] sw $5, 4($6) # CHECK: sw $5, 4($6) # encoding: [0xf8,0xa6,0x00,0x04] Index: test/MC/Mips/micromips64r6/invalid.s =================================================================== --- test/MC/Mips/micromips64r6/invalid.s +++ test/MC/Mips/micromips64r6/invalid.s @@ -26,3 +26,24 @@ dmodu $32, $4, $5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction dmodu $3, $34, $5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction dmodu $3, $4, $35 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwm16 $5, $6, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected + lwm16 $16, $19, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected + lwm16 $16-$25, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand + lwm16 $16, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwm16 $16, $17, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sb16 $9, 4($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sb16 $3, 64($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + sb16 $16, 4($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sb16 $7, 4($9) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sh16 $9, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sh16 $4, 68($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + sh16 $16, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sh16 $7, 8($9) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sw16 $9, 4($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sw16 $4, 64($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + sw16 $16, 4($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sw16 $7, 4($10) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swm16 $5, $6, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected + swm16 $16, $19, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected + swm16 $16-$25, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand Index: test/MC/Mips/micromips64r6/valid.s =================================================================== --- test/MC/Mips/micromips64r6/valid.s +++ test/MC/Mips/micromips64r6/valid.s @@ -91,5 +91,14 @@ cvt.s.d $f2, $f4 # CHECK: cvt.s.d $f2, $f4 # encoding: [0x54,0x44,0x1b,0x7b] cvt.s.w $f3, $f4 # CHECK: cvt.s.w $f3, $f4 # encoding: [0x54,0x64,0x3b,0x7b] cvt.s.l $f3, $f4 # CHECK: cvt.s.l $f3, $f4 # encoding: [0x54,0x64,0x5b,0x7b] + lwm $16, $17, $ra, 8($sp) # CHECK: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x22] + lwm16 $16, $17, $ra, 8($sp) # CHECK: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x22] + sb16 $3, 4($16) # CHECK: sb16 $3, 4($16) # encoding: [0x89,0x84] + sh16 $4, 8($17) # CHECK: sh16 $4, 8($17) # encoding: [0xaa,0x14] + sw $4, 124($sp) # CHECK: sw $4, 124($sp) # encoding: [0xc8,0x9f] + sw16 $4, 4($17) # CHECK: sw16 $4, 4($17) # encoding: [0xea,0x11] + sw16 $0, 4($17) # CHECK: sw16 $zero, 4($17) # encoding: [0xe8,0x11] + swm $16, $17, $ra, 8($sp) # CHECK: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x2a] + swm16 $16, $17, $ra, 8($sp) # CHECK: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x2a] 1: