Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -150,6 +150,8 @@ void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, SMRange Range, bool ShowColors = true); + void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands); + #define GET_ASSEMBLER_HEADER #include "MipsGenAsmMatcher.inc" @@ -2158,7 +2160,7 @@ } // if load/store if (inMicroMipsMode()) { - if (MCID.mayLoad()) { + if (MCID.mayLoad() && Inst.getOpcode() != Mips::LWP_MM) { // Try to create 16-bit GP relative load instruction. for (unsigned i = 0; i < MCID.getNumOperands(); i++) { const MCOperandInfo &OpInfo = MCID.OpInfo[i]; @@ -2275,13 +2277,18 @@ return Error(IDLoc, "immediate operand value out of range"); break; case Mips::ADDIUPC_MM: - MCOperand Opnd = Inst.getOperand(1); + Opnd = Inst.getOperand(1); if (!Opnd.isImm()) return Error(IDLoc, "expected immediate operand kind"); - int Imm = Opnd.getImm(); + Imm = Opnd.getImm(); if ((Imm % 4 != 0) || !isInt<25>(Imm)) return Error(IDLoc, "immediate operand value out of range"); break; + case Mips::LWP_MM: + case Mips::SWP_MM: + if (Inst.getOperand(0).getReg() == Mips::RA) + return Error(IDLoc, "invalid operand for instruction"); + break; } } @@ -5173,7 +5180,6 @@ return Match_RequiresDifferentSrcAndDst; return Match_Success; case Mips::LWP_MM: - case Mips::LWP_MMR6: if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) return Match_RequiresDifferentSrcAndDst; return Match_Success; @@ -5513,6 +5519,19 @@ Warning(Loc, "macro instruction expanded into multiple instructions"); } +void MipsAsmParser::ConvertXWPOperands(MCInst &Inst, + const OperandVector &Operands) { + assert( + (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) && + "Unexpected instruction!"); + ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1); + int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg()); + Inst.addOperand(MCOperand::createReg(NextReg)); + ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2); + + return; +} + void MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, SMRange Range, bool ShowColors) { Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -1895,8 +1895,7 @@ LLVM_FALLTHROUGH; default: Inst.addOperand(MCOperand::createReg(Reg)); - if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM || - Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6) + if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) 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 @@ -962,21 +962,6 @@ let Inst{5-0} = 0b111100; } -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; -} - class CMP_BRANCH_OFF21_FM_MMR6 funct> : MipsR6Inst { bits<5> rs; bits<21> offset; Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -114,7 +114,6 @@ 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 MFC0_MMR6_ENC : POOL32A_MFTC0_FM_MMR6<"mfc0", 0b00011, 0b111100>; @@ -148,7 +147,6 @@ 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 WRPGPR_MMR6_ENC : POOL32A_WRPGPR_WSBH_FM_MMR6<0x3c5>; class WSBH_MMR6_ENC : POOL32A_WRPGPR_WSBH_FM_MMR6<0x1ec>; class LB_MMR6_ENC : LB32_FM_MMR6; @@ -571,32 +569,6 @@ class LWPC_MMR6_DESC: PCREL_MMR6_DESC_BASE<"lwpc", GPR32Opnd, simm19_lsl2, II_LWPC>; -class LWP_MMR6_DESC : MMR6Arch<"lwp"> { - dag OutOperandList = (outs regpair:$rd); - dag InOperandList = (ins mem_simm12:$addr); - string AsmString = !strconcat("lwp", "\t$rd, $addr"); - list Pattern = []; - InstrItinClass Itinerary = II_LWP; - 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_simm12:$addr); - string AsmString = !strconcat("swp", "\t$rd, $addr"); - list Pattern = []; - InstrItinClass Itinerary = II_SWP; - 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); @@ -1406,7 +1378,6 @@ 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 MTC0_MMR6 : StdMMR6Rel, MTC0_MMR6_ENC, MTC0_MMR6_DESC, ISA_MICROMIPS32R6; @@ -1441,7 +1412,6 @@ 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 WRPGPR_MMR6 : StdMMR6Rel, WRPGPR_MMR6_ENC, WRPGPR_MMR6_DESC, ISA_MICROMIPS32R6; def WSBH_MMR6 : StdMMR6Rel, WSBH_MMR6_ENC, WSBH_MMR6_DESC, ISA_MICROMIPS32R6; Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -240,33 +240,20 @@ let isReMaterializable = 1; } -/// A register pair used by load/store pair instructions. -def RegPairAsmOperand : AsmOperandClass { - let Name = "RegPair"; - let ParserMethod = "parseRegisterPair"; - let PredicateMethod = "isRegPair"; -} - -def regpair : Operand { - let EncoderMethod = "getRegisterPairOpValue"; - let ParserMatchClass = RegPairAsmOperand; - let PrintMethod = "printRegisterPair"; - let DecoderMethod = "DecodeRegPairOperand"; - let MIOperandInfo = (ops ptr_rc, ptr_rc); -} - class StorePairMM - : InstSE<(outs), (ins regpair:$rt, mem_simm12:$addr), + : InstSE<(outs), (ins GPR32Opnd:$rt, GPR32Opnd:$rt2, mem_simm12:$addr), !strconcat(opstr, "\t$rt, $addr"), [], II_SWP, FrmI, opstr> { let DecoderMethod = "DecodeMemMMImm12"; let mayStore = 1; + let AsmMatchConverter = "ConvertXWPOperands"; } class LoadPairMM - : InstSE<(outs regpair:$rt), (ins mem_simm12:$addr), + : InstSE<(outs GPR32Opnd:$rt, GPR32Opnd:$rt2), (ins mem_simm12:$addr), !strconcat(opstr, "\t$rt, $addr"), [], II_LWP, FrmI, opstr> { let DecoderMethod = "DecodeMemMMImm12"; let mayLoad = 1; + let AsmMatchConverter = "ConvertXWPOperands"; } class LLBaseMM :