Index: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1007,8 +1007,13 @@ 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) + return false; + + unsigned R0 = RegList.List->front(); + unsigned R1 = RegList.List->back(); + if (!((R0 == Mips::S0 && R1 == Mips::RA) || + (R0 == Mips::S0_64 && R1 == Mips::RA_64))) return false; int PrevReg = *RegList.List->begin(); @@ -1841,6 +1846,7 @@ case Mips::TLTU_MM: case Mips::TNE_MM: case Mips::SB16_MM: + case Mips::SB16_MMR6: Opnd = Inst.getOperand(2); if (!Opnd.isImm()) return Error(IDLoc, "expected immediate operand kind"); @@ -1850,6 +1856,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"); @@ -1859,6 +1866,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"); @@ -2612,10 +2620,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()) + 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); @@ -4145,12 +4159,15 @@ 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 ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) || + (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) && + isGP64bit())) { Error(E, "invalid register operand"); return MatchOperand_ParseFail; } @@ -4162,16 +4179,23 @@ 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 (!(((RegNo == Mips::FP || RegNo == Mips::RA || + (RegNo >= Mips::S0 && RegNo <= Mips::S7)) && + !isGP64bit()) || + ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 || + (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) && + isGP64bit()))) { Error(E, "invalid register operand"); return MatchOperand_ParseFail; } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) && - (RegNo != Mips::FP) && (RegNo != Mips::RA)) { + ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) || + (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && + isGP64bit()))) { Error(E, "consecutive register numbers expected"); return MatchOperand_ParseFail; } 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 @@ -1380,8 +1380,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; @@ -1400,14 +1403,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; } @@ -1451,7 +1457,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) @@ -2009,7 +2024,16 @@ 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: llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp +++ llvm/trunk/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: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -832,7 +832,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: llvm/trunk/lib/Target/Mips/MicroMips32r6InstrFormats.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMips32r6InstrFormats.td +++ llvm/trunk/lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -62,6 +62,18 @@ let Inst{4-0} = op; } +class POOL16C_LWM_SWM_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: llvm/trunk/lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ llvm/trunk/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -55,6 +55,7 @@ class JRCADDIUSP_MMR6_ENC : POOL16C_JRCADDIUSP_FM_MM16R6<0x13>; class LSA_MMR6_ENC : POOL32A_LSA_FM<0b001111>; class LWPC_MMR6_ENC : PCREL19_FM_MMR6<0b01>; +class LWM16_MMR6_ENC : POOL16C_LWM_SWM_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>; @@ -65,15 +66,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 : POOL16C_LWM_SWM_FM_MM16R6<0xa>; +class SWSP_MMR6_ENC : LOAD_STORE_SP_FM_MM16<0x32>; class PREFE_MMR6_ENC : POOL32C_ST_EVA_FM_MMR6<0b011000, 0b010>; class CACHEE_MMR6_ENC : POOL32C_ST_EVA_FM_MMR6<0b011000, 0b011>; class WRPGPR_MMR6_ENC : POOL32A_WRPGPR_WSBH_FM_MMR6<0x3c5>; @@ -814,6 +820,52 @@ list Pattern = []; } +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 @@ -874,6 +926,7 @@ 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; @@ -884,15 +937,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 PREFE_MMR6 : StdMMR6Rel, PREFE_MMR6_ENC, PREFE_MMR6_DESC, ISA_MICROMIPS32R6; def CACHEE_MMR6 : StdMMR6Rel, CACHEE_MMR6_ENC, CACHEE_MMR6_DESC, ISA_MICROMIPS32R6; @@ -1075,3 +1133,12 @@ def : MipsInstAlias<"rdhwr $rt, $rs", (RDHWR_MMR6 GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MICROMIPS32R6; + +//===----------------------------------------------------------------------===// +// +// 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: llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td +++ llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td @@ -943,7 +943,7 @@ let Inst{11-0} = addr{11-0}; } -class LWM_FM_MM16 funct> : MMArch { +class LWM_FM_MM16 funct> : MMArch, PredicateControl { bits<2> rt; bits<4> addr; Index: llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td @@ -660,6 +660,14 @@ def SDBBP16_MM : BrkSdbbp16MM<"sdbbp16">, BRKSDBBP16_FM_MM<0x2C>, ISA_MICROMIPS_NOT_32R6_64R6; +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>; @@ -790,8 +798,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: llvm/trunk/test/MC/Disassembler/Mips/micromips32r6/valid.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/Mips/micromips32r6/valid.txt +++ llvm/trunk/test/MC/Disassembler/Mips/micromips32r6/valid.txt @@ -230,3 +230,10 @@ 0x00 0x69 0xe1 0x7c # CHECK: rdpgpr $3, $9 0x00 0x00 0xdb 0x7c # CHECK: sdbbp 0x00 0x22 0xdb 0x7c # CHECK: sdbbp 34 +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: llvm/trunk/test/MC/Disassembler/Mips/micromips64r6/valid.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ llvm/trunk/test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -143,3 +143,10 @@ 0x46 0x3b # CHECK: sdbbp16 8 0x04 0x3b # CHECK: subu16 $5, $16, $3 0x44 0xd8 # CHECK: xor16 $17, $5 +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: llvm/trunk/test/MC/Mips/micromips32r6/invalid.s =================================================================== --- llvm/trunk/test/MC/Mips/micromips32r6/invalid.s +++ llvm/trunk/test/MC/Mips/micromips32r6/invalid.s @@ -73,3 +73,31 @@ jrcaddiusp 33 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction jrcaddiusp 125 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction jrcaddiusp 132 # 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 + lwm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwm16 $16, $17, $ra, 64($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 + swm16 $16, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swm16 $16, $17, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swm16 $16, $17, $ra, 64($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: llvm/trunk/test/MC/Mips/micromips32r6/valid.s =================================================================== --- llvm/trunk/test/MC/Mips/micromips32r6/valid.s +++ llvm/trunk/test/MC/Mips/micromips32r6/valid.s @@ -54,6 +54,8 @@ jrcaddiusp 20 # CHECK: jrcaddiusp 20 # encoding: [0x44,0xb3] lsa $2, $3, $4, 3 # CHECK: lsa $2, $3, $4, 3 # encoding: [0x00,0x43,0x24,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] @@ -65,13 +67,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] wrpgpr $3, $4 # CHECK: wrpgpr $3, $4 # encoding: [0x00,0x64,0xf1,0x7c] wsbh $3, $4 # CHECK: wsbh $3, $4 # encoding: [0x00,0x64,0x7b,0x3c] pause # CHECK: pause # encoding: [0x00,0x00,0x28,0x00] Index: llvm/trunk/test/MC/Mips/micromips64r6/invalid.s =================================================================== --- llvm/trunk/test/MC/Mips/micromips64r6/invalid.s +++ llvm/trunk/test/MC/Mips/micromips64r6/invalid.s @@ -81,3 +81,31 @@ jrcaddiusp 33 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction jrcaddiusp 125 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction jrcaddiusp 132 # 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 + lwm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwm16 $16, $17, $ra, 64($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 + swm16 $16, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swm16 $16, $17, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swm16 $16, $17, $ra, 64($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: llvm/trunk/test/MC/Mips/micromips64r6/valid.s =================================================================== --- llvm/trunk/test/MC/Mips/micromips64r6/valid.s +++ llvm/trunk/test/MC/Mips/micromips64r6/valid.s @@ -121,5 +121,14 @@ sdbbp16 8 # CHECK: sdbbp16 8 # encoding: [0x46,0x3b] subu16 $5, $16, $3 # CHECK: subu16 $5, $16, $3 # encoding: [0x04,0x3b] xor16 $17, $5 # CHECK: xor16 $17, $5 # encoding: [0x44,0xd8] + 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: