Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -963,9 +963,13 @@ void addRegPairOperands(MCInst &Inst, unsigned N) const { assert(N == 2 && "Invalid number of operands!"); + assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!"); unsigned RegNo = getRegPair(); - Inst.addOperand(MCOperand::createReg(RegNo++)); - Inst.addOperand(MCOperand::createReg(RegNo)); + AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc); + Inst.addOperand(MCOperand::createReg( + RegIdx.RegInfo->getRegClass(Mips::GPR32RegClassID).getRegister(RegNo++))); + Inst.addOperand(MCOperand::createReg( + RegIdx.RegInfo->getRegClass(Mips::GPR32RegClassID).getRegister(RegNo))); } void addMovePRegPairOperands(MCInst &Inst, unsigned N) const { @@ -1084,7 +1088,9 @@ assert(Kind == k_Token && "Invalid access!"); return StringRef(Tok.Data, Tok.Length); } - bool isRegPair() const { return Kind == k_RegPair; } + bool isRegPair() const { + return Kind == k_RegPair && RegIdx.Index <= 30; + } unsigned getReg() const override { // As a special case until we sort out the definition of div/divu, pretend @@ -1239,9 +1245,9 @@ } static std::unique_ptr - CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) { + CreateRegPair(MipsOperand MOP, SMLoc S, SMLoc E, MipsAsmParser &Parser) { auto Op = make_unique(k_RegPair, Parser); - Op->RegIdx.Index = RegNo; + Op->RegIdx.Index = MOP.RegIdx.Index; Op->StartLoc = S; Op->EndLoc = E; return Op; @@ -4261,9 +4267,9 @@ SMLoc E = Parser.getTok().getLoc(); MipsOperand &Op = static_cast(*Operands.back()); - unsigned Reg = Op.getGPR32Reg(); + Operands.pop_back(); - Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this)); + Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this)); return MatchOperand_Success; } Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -1524,7 +1524,8 @@ // fallthrough default: Inst.addOperand(MCOperand::createReg(Reg)); - if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) + if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM || + Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6) Inst.addOperand(MCOperand::createReg(Reg+1)); Inst.addOperand(MCOperand::createReg(Base)); Index: lib/Target/Mips/MicroMips32r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrFormats.td +++ lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -796,3 +796,18 @@ let Inst{15-6} = funct; let Inst{5-0} = 0x3c; } + +class POOL32B_LWP_SWP_FM_MMR6 funct> : MipsR6Inst { + bits<5> rd; + bits<21> addr; + bits<5> base = addr{20-16}; + bits<12> offset = addr{11-0}; + + bits<32> Inst; + + let Inst{31-26} = 0x8; + let Inst{25-21} = rd; + let Inst{20-16} = base; + let Inst{15-12} = funct; + let Inst{11-0} = offset; +} Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -54,6 +54,7 @@ class JRC16_MMR6_ENC: POOL16C_JALRC_FM_MM16R6<0x3>; class JRCADDIUSP_MMR6_ENC : POOL16C_JRCADDIUSP_FM_MM16R6<0x13>; class LSA_MMR6_ENC : POOL32A_LSA_FM<0b001111>; +class LWP_MMR6_ENC : POOL32B_LWP_SWP_FM_MMR6<0x1>; 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>; @@ -80,6 +81,7 @@ 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 SWP_MMR6_ENC : POOL32B_LWP_SWP_FM_MMR6<0x9>; 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>; @@ -445,6 +447,32 @@ class ADDIUPC_MMR6_DESC : PCREL_MMR6_DESC_BASE<"addiupc", GPR32Opnd, simm19_lsl2>; class LWPC_MMR6_DESC: PCREL_MMR6_DESC_BASE<"lwpc", GPR32Opnd, simm19_lsl2>; +class LWP_MMR6_DESC : MMR6Arch<"lwp"> { + dag OutOperandList = (outs regpair:$rd); + dag InOperandList = (ins mem_simm12gpr:$addr); + string AsmString = !strconcat("lwp", "\t$rd, $addr"); + list Pattern = []; + InstrItinClass Itin = NoItinerary; + ComplexPattern Addr = addr; + Format f = FrmI; + string BaseOpcode = "lwp"; + string DecoderMethod = "DecodeMemMMImm12"; + bit mayLoad = 1; +} + +class SWP_MMR6_DESC : MMR6Arch<"swp"> { + dag OutOperandList = (outs); + dag InOperandList = (ins regpair:$rd, mem_simm12gpr:$addr); + string AsmString = !strconcat("swp", "\t$rd, $addr"); + list Pattern = []; + InstrItinClass Itin = NoItinerary; + ComplexPattern Addr = addr; + Format f = FrmI; + string BaseOpcode = "swp"; + string DecoderMethod = "DecodeMemMMImm12"; + bit mayStore = 1; +} + class SELEQNE_Z_MMR6_DESC_BASE : MMR6Arch { dag OutOperandList = (outs GPROpnd:$rd); @@ -925,6 +953,7 @@ def JRCADDIUSP_MMR6 : R6MMR6Rel, JRCADDIUSP_MMR6_DESC, JRCADDIUSP_MMR6_ENC, ISA_MICROMIPS32R6; def LSA_MMR6 : R6MMR6Rel, LSA_MMR6_ENC, LSA_MMR6_DESC, ISA_MICROMIPS32R6; +def LWP_MMR6 : StdMMR6Rel, LWP_MMR6_ENC, LWP_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; @@ -951,6 +980,7 @@ 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 SWP_MMR6 : StdMMR6Rel, SWP_MMR6_ENC, SWP_MMR6_DESC, 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; Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -154,6 +154,20 @@ let OperandType = "OPERAND_MEMORY"; } +def MipsMemSimm12GPRAsmOperand : AsmOperandClass { + let Name = "MemOffsetSimm12GPR"; + let SuperClasses = [MipsMemAsmOperand]; + let RenderMethod = "addMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemWithSimmOffsetGPR<12>"; +} + +def mem_simm12gpr : mem_generic { + let MIOperandInfo = (ops ptr_rc, simm12); + let EncoderMethod = "getMemEncoding"; + let ParserMatchClass = MipsMemSimm12GPRAsmOperand; +} + def jmptarget_mm : Operand { let EncoderMethod = "getJumpTargetOpValueMM"; } @@ -243,6 +257,7 @@ def RegPairAsmOperand : AsmOperandClass { let Name = "RegPair"; let ParserMethod = "parseRegisterPair"; + let PredicateMethod = "isRegPair"; } def regpair : Operand { @@ -255,7 +270,7 @@ class StorePairMM : - InstSE<(outs), (ins regpair:$rt, mem_mm_12:$addr), + InstSE<(outs), (ins regpair:$rt, mem_simm12gpr:$addr), !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMemMMImm12"; let mayStore = 1; @@ -263,7 +278,7 @@ class LoadPairMM : - InstSE<(outs regpair:$rt), (ins mem_mm_12:$addr), + InstSE<(outs regpair:$rt), (ins mem_simm12gpr:$addr), !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMemMMImm12"; let mayLoad = 1; Index: test/MC/Disassembler/Mips/micromips32r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r6/valid.txt +++ test/MC/Disassembler/Mips/micromips32r6/valid.txt @@ -237,3 +237,5 @@ 0xea 0x11 # CHECK: sw16 $4, 4($17) 0xe8 0x11 # CHECK: sw16 $zero, 4($17) 0x45 0x2a # CHECK: swm16 $16, $17, $ra, 8($sp) +0x22 0x04 0x10 0x08 # CHECK: lwp $16, 8($4) +0x22 0x04 0x90 0x08 # CHECK: swp $16, 8($4) Index: test/MC/Disassembler/Mips/micromips64r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -150,3 +150,5 @@ 0xea 0x11 # CHECK: sw16 $4, 4($17) 0xe8 0x11 # CHECK: sw16 $zero, 4($17) 0x45 0x2a # CHECK: swm16 $16, $17, $ra, 8($sp) +0x22 0x04 0x10 0x08 # CHECK: lwp $16, 8($4) +0x22 0x04 0x90 0x08 # CHECK: swp $16, 8($4) Index: test/MC/Mips/micromips-invalid.s =================================================================== --- test/MC/Mips/micromips-invalid.s +++ test/MC/Mips/micromips-invalid.s @@ -88,3 +88,9 @@ jraddiusp 33 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction jraddiusp 125 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction jraddiusp 132 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips32r6/invalid.s =================================================================== --- test/MC/Mips/micromips32r6/invalid.s +++ test/MC/Mips/micromips32r6/invalid.s @@ -101,3 +101,9 @@ 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 + lwp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips32r6/valid.s =================================================================== --- test/MC/Mips/micromips32r6/valid.s +++ test/MC/Mips/micromips32r6/valid.s @@ -230,3 +230,5 @@ lbu $4, 8($5) # CHECK: lbu $4, 8($5) # encoding: [0x14,0x85,0x00,0x08] lbe $4, 8($5) # CHECK: lbe $4, 8($5) # encoding: [0x60,0x85,0x68,0x08] lbue $4, 8($5) # CHECK: lbue $4, 8($5) # encoding: [0x60,0x85,0x60,0x08] + lwp $16, 8($4) # CHECK: lwp $16, 8($4) # encoding: [0x22,0x04,0x10,0x08] + swp $16, 8($4) # CHECK: swp $16, 8($4) # encoding: [0x22,0x04,0x90,0x08] Index: test/MC/Mips/micromips64r6/invalid.s =================================================================== --- test/MC/Mips/micromips64r6/invalid.s +++ test/MC/Mips/micromips64r6/invalid.s @@ -109,3 +109,9 @@ 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 + lwp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips64r6/valid.s =================================================================== --- test/MC/Mips/micromips64r6/valid.s +++ test/MC/Mips/micromips64r6/valid.s @@ -130,5 +130,7 @@ 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] + lwp $16, 8($4) # CHECK: lwp $16, 8($4) # encoding: [0x22,0x04,0x10,0x08] + swp $16, 8($4) # CHECK: swp $16, 8($4) # encoding: [0x22,0x04,0x90,0x08] 1: