Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -535,7 +535,7 @@ uint64_t Address, const void *Decoder); -static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair, uint64_t Address, const void *Decoder); @@ -2481,10 +2481,8 @@ return MCDisassembler::Success; } -static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn, +static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair, uint64_t Address, const void *Decoder) { - unsigned RegPair = fieldFromInstruction(Insn, 7, 3); - switch (RegPair) { default: return MCDisassembler::Fail; Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -252,6 +252,9 @@ unsigned getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; unsigned getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1115,6 +1115,29 @@ } unsigned +MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + assert(((OpNo == 2) || (OpNo == 3)) && + "Unexpected OpNo for movep operand encoding!"); + + MCOperand Op = MI.getOperand(OpNo); + assert(Op.isReg() && "Operand of movep is not a register!"); + switch (Op.getReg()) { + default: + llvm_unreachable("Unknown register for movep!"); + case Mips::ZERO: return 0; + case Mips::S1: return 1; + case Mips::V0: return 2; + case Mips::V1: return 3; + case Mips::S0: return 4; + case Mips::S2: return 5; + case Mips::S3: return 6; + case Mips::S4: return 7; + } +} + +unsigned MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { Index: lib/Target/Mips/MicroMips32r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrFormats.td +++ lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -829,6 +829,21 @@ let Inst{3-0} = 0b0000; } +class POOL16C_MOVEP16_FM_MMR6 : MicroMipsR6Inst16 { + bits<3> dst_regs; + bits<3> rt; + bits<3> rs; + + bits<16> Inst; + + let Inst{15-10} = 0b010001; + let Inst{9-7} = dst_regs; + let Inst{6-4} = rt; + let Inst{3} = rs{2}; + let Inst{2} = 0b1; + let Inst{1-0} = rs{1-0}; +} + class POOL16C_OR16_XOR16_FM_MMR6 op> : MicroMipsR6Inst16 { bits<3> rt; bits<3> rs; Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -229,6 +229,7 @@ class BREAK16_MMR6_ENC : POOL16C_BREAKPOINT_FM_MMR6<0b011011>; class LI16_MMR6_ENC : LI_FM_MM16; class MOVE16_MMR6_ENC : MOVE_FM_MM16<0b000011>; +class MOVEP_MMR6_ENC : POOL16C_MOVEP16_FM_MMR6; class SDBBP16_MMR6_ENC : POOL16C_BREAKPOINT_FM_MMR6<0b111011>; class SUBU16_MMR6_ENC : POOL16A_SUBU16_FM_MMR6; class XOR16_MMR6_ENC : POOL16C_OR16_XOR16_FM_MMR6<0b1000>; @@ -1204,6 +1205,7 @@ MMR6Arch<"li16">, MicroMipsR6Inst16, IsAsCheapAsAMove; class MOVE16_MMR6_DESC : MoveMM16<"move16", GPR32Opnd>, MMR6Arch<"move16">, MicroMipsR6Inst16; +class MOVEP_MMR6_DESC :MovePMM16<"movep", GPRMM16OpndMoveP>, MMR6Arch<"movep">; class SDBBP16_MMR6_DESC : BrkSdbbp16MM<"sdbbp16", II_SDBBP>, MMR6Arch<"sdbbp16">, MicroMipsR6Inst16; class SUBU16_MMR6_DESC : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>, @@ -1679,6 +1681,8 @@ ISA_MICROMIPS32R6; def MOVE16_MMR6 : StdMMR6Rel, MOVE16_MMR6_DESC, MOVE16_MMR6_ENC, ISA_MICROMIPS32R6; +def MOVEP_MMR6 : StdMMR6Rel, MOVEP_MMR6_DESC, MOVEP_MMR6_ENC, + ISA_MICROMIPS32R6; def SDBBP16_MMR6 : StdMMR6Rel, SDBBP16_MMR6_DESC, SDBBP16_MMR6_ENC, ISA_MICROMIPS32R6; def SUBU16_MMR6 : StdMMR6Rel, SUBU16_MMR6_DESC, SUBU16_MMR6_ENC, Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -631,7 +631,8 @@ def MFHI16_MM : MoveFromHILOMM<"mfhi", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x10>; def MFLO16_MM : MoveFromHILOMM<"mflo", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x12>; def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>; -def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMoveP>, MOVEP_FM_MM16; +def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMoveP>, MOVEP_FM_MM16, + ISA_MICROMIPS_NOT_32R6_64R6; def LI16_MM : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>, LI_FM_MM16, IsAsCheapAsAMove; def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>, Index: lib/Target/Mips/MipsRegisterInfo.td =================================================================== --- lib/Target/Mips/MipsRegisterInfo.td +++ lib/Target/Mips/MipsRegisterInfo.td @@ -616,6 +616,7 @@ def GPRMM16OpndMoveP : RegisterOperand { let ParserMatchClass = GPRMM16AsmOperandMoveP; + let EncoderMethod = "getMovePRegSingleOpValue"; } def GPR64Opnd : RegisterOperand { Index: lib/Target/Mips/MipsScheduleGeneric.td =================================================================== --- lib/Target/Mips/MipsScheduleGeneric.td +++ lib/Target/Mips/MipsScheduleGeneric.td @@ -736,6 +736,7 @@ def : InstRW<[GenericDSPShort], (instregex "^MFLO_DSP_MM$")>; def : InstRW<[GenericDSPShort], (instregex "^MODSUB_MM$")>; def : InstRW<[GenericDSPShort], (instregex "^MOVEP_MM$")>; +def : InstRW<[GenericDSPShort], (instregex "^MOVEP_MMR6$")>; def : InstRW<[GenericDSPShort], (instregex "^MOVN_I_MM$")>; def : InstRW<[GenericDSPShort], (instregex "^MOVZ_I_MM$")>; def : InstRW<[GenericDSPShort], (instregex "^MSUBU_DSP_MM$")>; Index: test/MC/Disassembler/Mips/micromips32r3/valid-el.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r3/valid-el.txt +++ test/MC/Disassembler/Mips/micromips32r3/valid-el.txt @@ -27,6 +27,7 @@ 0x09 0x46 # CHECK: mfhi $9 0x49 0x46 # CHECK: mflo $9 0x21 0x0f # CHECK: move $25, $1 +0x9a 0x85 # CHECK: movep $4, $21, $18, $17 0xa9 0x45 # CHECK: jrc $9 0xc9 0x45 # CHECK: jalr $9 0xe9 0x45 # CHECK: jalrs16 $9 Index: test/MC/Disassembler/Mips/micromips32r3/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r3/valid.txt +++ test/MC/Disassembler/Mips/micromips32r3/valid.txt @@ -27,6 +27,7 @@ 0x46 0x09 # CHECK: mfhi $9 0x46 0x49 # CHECK: mflo $9 0x0f 0x21 # CHECK: move $25, $1 +0x85 0x9a # CHECK: movep $4, $21, $18, $17 0x45 0xa9 # CHECK: jrc $9 0x45 0xc9 # CHECK: jalr $9 0x45 0xe9 # CHECK: jalrs16 $9 Index: test/MC/Disassembler/Mips/micromips32r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r6/valid.txt +++ test/MC/Disassembler/Mips/micromips32r6/valid.txt @@ -21,7 +21,7 @@ 0x29 0x82 # CHECK: lhu16 $3, 4($16) 0x09 0x94 # CHECK: lbu16 $3, 4($17) 0x09 0x9f # CHECK: lbu16 $3, -1($17) -0x84 0x34 # CHECK: movep $5, $6, $2, $3 +0x44 0x36 # CHECK: movep $5, $6, $2, $3 0x04 0xcc # CHECK: addu16 $6, $17, $4 0x44 0x21 # CHECK: and16 $16, $2 0x2e 0x56 # CHECK: andi16 $4, $5, 8 Index: test/MC/Disassembler/Mips/micromips64r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -23,7 +23,7 @@ 0x45 0x2b # CHECK: jalr $9 0x45 0x23 # CHECK: jrc16 $9 0x44 0xb3 # CHECK: jrcaddiusp 20 -0x84 0x34 # CHECK: movep $5, $6, $2, $3 +0x44 0x36 # CHECK: movep $5, $6, $2, $3 0x45 0xf9 # CHECK: or16 $3, $7 0x60 0x44 0x30 0x08 # CHECK: ll $2, 8($4) 0x20 0x44 0x50 0x08 # CHECK: lwm32 $16, $17, 8($4) Index: test/MC/Mips/micromips32r6/valid.s =================================================================== --- test/MC/Mips/micromips32r6/valid.s +++ test/MC/Mips/micromips32r6/valid.s @@ -84,7 +84,7 @@ lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, 8($4) # CHECK: lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, 8($4) # encoding: [0x21,0x24,0x50,0x08] lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, $ra, 8($4) # CHECK: lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, $ra, 8($4) # encoding: [0x23,0x24,0x50,0x08] lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, $ra, 8($4) # CHECK: lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, $ra, 8($4) # encoding: [0x23,0x24,0x50,0x08] - movep $5, $6, $2, $3 # CHECK: movep $5, $6, $2, $3 # encoding: [0x84,0x34] + movep $5, $6, $2, $3 # CHECK: movep $5, $6, $2, $3 # encoding: [0x44,0x36] rotr $2, 7 # CHECK: rotr $2, $2, 7 # encoding: [0x00,0x42,0x38,0xc0] rotr $9, $6, 7 # CHECK: rotr $9, $6, 7 # encoding: [0x01,0x26,0x38,0xc0] rotrv $9, $6, $7 # CHECK: rotrv $9, $6, $7 # encoding: [0x00,0xc7,0x48,0xd0] Index: test/MC/Mips/micromips64r6/valid.s =================================================================== --- test/MC/Mips/micromips64r6/valid.s +++ test/MC/Mips/micromips64r6/valid.s @@ -35,7 +35,7 @@ lhu16 $3, 4($16) # CHECK: lhu16 $3, 4($16) # encoding: [0x29,0x82] lbu16 $3, 4($17) # CHECK: lbu16 $3, 4($17) # encoding: [0x09,0x94] lbu16 $3, -1($17) # CHECK: lbu16 $3, -1($17) # encoding: [0x09,0x9f] - movep $5, $6, $2, $3 # CHECK: movep $5, $6, $2, $3 # encoding: [0x84,0x34] + movep $5, $6, $2, $3 # CHECK: movep $5, $6, $2, $3 # encoding: [0x44,0x36] not16 $4, $7 # CHECK: not16 $4, $7 # encoding: [0x46,0x70] or16 $3, $7 # CHECK: or16 $3, $7 # encoding: [0x45,0xf9] ll $2, 8($4) # CHECK: ll $2, 8($4) # encoding: [0x60,0x44,0x30,0x08]