Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -101,33 +101,6 @@ } } -// Pick a DINS instruction variant based on the pos and size operands -static void LowerDins(MCInst& InstIn) { - assert(InstIn.getNumOperands() == 5 && - "Invalid no. of machine operands for DINS!"); - - assert(InstIn.getOperand(2).isImm()); - int64_t pos = InstIn.getOperand(2).getImm(); - assert(InstIn.getOperand(3).isImm()); - int64_t size = InstIn.getOperand(3).getImm(); - - assert((pos + size) <= 64 && - "DINS cannot have position plus size over 64"); - if (pos < 32) { - if ((pos + size) > 0 && (pos + size) <= 32) - return; // DINS, do nothing - else if ((pos + size) > 32) { - //DINSM - InstIn.getOperand(3).setImm(size - 32); - InstIn.setOpcode(Mips::DINSM); - } - } else if ((pos + size) > 32 && (pos + size) <= 64) { - // DINSU - InstIn.getOperand(2).setImm(pos - 32); - InstIn.setOpcode(Mips::DINSU); - } -} - // Fix a bad compact branch encoding for beqc/bnec. void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const { // Encoding may be illegal !(rs < rt), but this situation is @@ -211,10 +184,6 @@ case Mips::DROTR_MM64R6: LowerLargeShift(TmpInst); break; - // Double extract instruction is chosen by pos and size operands - case Mips::DINS: - LowerDins(TmpInst); - break; // Compact branches, enforce encoding restrictions. case Mips::BEQC: case Mips::BNEC: Index: lib/Target/Mips/MicroMips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips64r6InstrInfo.td +++ lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -164,10 +164,12 @@ } class DINSU_MM64R6_DESC : InsBase<"dinsu", GPR64Opnd, uimm5_plus32, - uimm5_inssize_plus1, MipsIns>; -class DINSM_MM64R6_DESC : InsBase<"dinsm", GPR64Opnd, uimm5, uimm_range_2_64>; + uimm5_inssize_plus1, immZExt5Plus32, + immZExt5Plus1, MipsIns>; +class DINSM_MM64R6_DESC : InsBase<"dinsm", GPR64Opnd, uimm5, uimm_range_2_64, + immZExt5, immZExtRange2To64, MipsIns>; class DINS_MM64R6_DESC : InsBase<"dins", GPR64Opnd, uimm5, uimm5_inssize_plus1, - MipsIns>; + immZExt5, immZExt5Plus1, MipsIns>; class DMTC0_MM64R6_DESC : MTC0_MMR6_DESC_BASE<"dmtc0", COP0Opnd, GPR64Opnd, II_DMTC0>; class DMTC1_MM64R6_DESC : MTC1_MMR6_DESC_BASE<"dmtc1", FGR64Opnd, GPR64Opnd, Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -884,7 +884,8 @@ def EXT_MM : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, immZExt5, immZExt5Plus1, MipsExt>, EXT_FM_MM<0x2c>; def INS_MM : MMRel, InsBase<"ins", GPR32Opnd, uimm5, uimm5_inssize_plus1, - MipsIns>, EXT_FM_MM<0x0c>; + immZExt5, immZExt5Plus1, MipsIns>, + EXT_FM_MM<0x0c>; /// Jump Instructions let DecoderMethod = "DecodeJumpTargetMM" in { Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -318,11 +318,13 @@ def DEXTU : ExtBase<"dextu", GPR64Opnd, uimm5_plus32, uimm5_plus1, immZExt5Plus32, immZExt5Plus1, MipsExt>, EXT_FM<2>, ISA_MIPS64R2; - def DINS : InsBase<"dins", GPR64Opnd, uimm6, uimm5_inssize_plus1, MipsIns>, - EXT_FM<7>, ISA_MIPS64R2; - def DINSU : InsBase<"dinsu", GPR64Opnd, uimm5_plus32, uimm5_inssize_plus1>, + def DINS : InsBase<"dins", GPR64Opnd, uimm6, uimm5_inssize_plus1, immZExt5, + immZExt5Plus1, MipsIns>, EXT_FM<7>, ISA_MIPS64R2; + def DINSU : InsBase<"dinsu", GPR64Opnd, uimm5_plus32, uimm5_inssize_plus1, + immZExt5Plus32, immZExt5Plus1, MipsIns>, EXT_FM<6>, ISA_MIPS64R2; - def DINSM : InsBase<"dinsm", GPR64Opnd, uimm5, uimm5_inssize_plus1>, + def DINSM : InsBase<"dinsm", GPR64Opnd, uimm5, uimm5_inssize_plus1, + immZExt5, immZExtRange2To64, MipsIns>, EXT_FM<5>, ISA_MIPS64R2; } Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -1188,6 +1188,11 @@ return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1); }]>; +def immZExtRange2To64 : PatLeaf<(imm), [{ + return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) && + (N->getZExtValue() <= 64); +}]>; + // Mips Address Mode! SDNode frameindex could possibily be a match // since load and store instructions from stack used it. def addr : @@ -1659,10 +1664,11 @@ FrmR, opstr>, ISA_MIPS32R2; class InsBase: + Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm, + SDPatternOperator Op = null_frag>: InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src), !strconcat(opstr, " $rt, $rs, $pos, $size"), - [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))], + [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size, RO:$src))], II_INS, FrmR, opstr>, ISA_MIPS32R2 { let Constraints = "$src = $rt"; } @@ -2166,7 +2172,8 @@ immZExt5, immZExt5Plus1, MipsExt>, EXT_FM<0>; def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5, - uimm5_inssize_plus1, MipsIns>, + uimm5_inssize_plus1, immZExt5, + immZExt5Plus1, MipsIns>, EXT_FM<4>; } /// Move Control Registers From/To CPU Registers Index: test/CodeGen/Mips/dins.ll =================================================================== --- test/CodeGen/Mips/dins.ll +++ test/CodeGen/Mips/dins.ll @@ -58,13 +58,13 @@ ; CHECK-LABEL: f123: ; MIPS64R2: daddiu $[[R0:[0-9]+]], $zero, 123 -; MIPS64R2: dins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 27, 37 +; MIPS64R2: dinsm $[[R0:[0-9]+]], $[[R1:[0-9]+]], 27, 37 ; MIPS64R2: daddiu $[[R0:[0-9]+]], $zero, 5 ; MIPS64R2: daddiu $[[R0:[0-9]+]], $zero, 4 ; MIPS64R2: dins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 28, 6 -; MIPS64R2: dins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 50, 14 +; MIPS64R2: dinsu $[[R0:[0-9]+]], $[[R1:[0-9]+]], 50, 14 ; MIPS64R2: dsrl $[[R0:[0-9]+]], $[[R1:[0-9]+]], 50 -; MIPS64R2: dins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 34, 16 +; MIPS64R2: dinsu $[[R0:[0-9]+]], $[[R1:[0-9]+]], 34, 16 ; MIPS32R2: ins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 2, 16 ; MIPS32R2-NOT: ins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 18, 46 ; MIPS16-NOT: ins{{[[:space:]].*}} @@ -94,4 +94,4 @@ ; MIPS32R2: ori $[[R0:[0-9]+]], $[[R0:[0-9]+]], 8 ; MIPS32R2-NOT: ins {{[[:space:]].*}} ; MIPS64R2N32: ori $[[R0:[0-9]+]], $[[R0:[0-9]+]], 8 -; MIPS64R2N32-NOT: ins {{[[:space:]].*}} \ No newline at end of file +; MIPS64R2N32-NOT: ins {{[[:space:]].*}} Index: test/CodeGen/Mips/fcopysign-f32-f64.ll =================================================================== --- test/CodeGen/Mips/fcopysign-f32-f64.ll +++ test/CodeGen/Mips/fcopysign-f32-f64.ll @@ -48,7 +48,7 @@ ; 64: dmtc1 $[[OR]], $f0 ; 64R2: ext ${{[0-9]+}}, ${{[0-9]+}}, 31, 1 -; 64R2: dins $[[INS:[0-9]+]], ${{[0-9]+}}, 63, 1 +; 64R2: dinsu $[[INS:[0-9]+]], ${{[0-9]+}}, 63, 1 ; 64R2: dmtc1 $[[INS]], $f0 %add = fadd double %d, 1.000000e+00 Index: test/CodeGen/Mips/fcopysign.ll =================================================================== --- test/CodeGen/Mips/fcopysign.ll +++ test/CodeGen/Mips/fcopysign.ll @@ -28,8 +28,8 @@ ; 64: dmtc1 $[[OR]], $f0 ; 64R2: dextu $[[EXT:[0-9]+]], ${{[0-9]+}}, 63, 1 -; 64R2: dins $[[INS:[0-9]+]], $[[EXT]], 63, 1 -; 64R2: dmtc1 $[[INS]], $f0 +; 64R2: dinsu $[[INS:[0-9]+]], $[[EXT]], 63, 1 +; 64R2: dmtc1 $[[INS]], $f0 %call = tail call double @copysign(double %d0, double %d1) nounwind readnone ret double %call Index: test/CodeGen/Mips/mips64-f128.ll =================================================================== --- test/CodeGen/Mips/mips64-f128.ll +++ test/CodeGen/Mips/mips64-f128.ll @@ -425,7 +425,7 @@ ; NOT-R2R6-DAG: and $[[R4:[0-9]+]], $[[R1]], $[[R3]] ; ALL-DAG: ld $[[R5:[0-9]+]], %got_disp(gld0) ; ALL-DAG: ld $[[R6:[0-9]+]], 8($[[R5]]) -; R2R6: dins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 63, 1 +; R2R6: dinsu $[[R0:[0-9]+]], $[[R1:[0-9]+]], 63, 1 ; NOT-R2R6-DAG: daddiu $[[R7:[0-9]+]], $[[R3]], -1 ; NOT-R2R6-DAG: and $[[R8:[0-9]+]], $[[R6]], $[[R7]] ; NOT-R2R6-DAG: or $4, $[[R8]], $[[R4]] Index: test/CodeGen/Mips/mips64extins.ll =================================================================== --- test/CodeGen/Mips/mips64extins.ll +++ test/CodeGen/Mips/mips64extins.ll @@ -41,7 +41,7 @@ define i64 @dinsm(i64 %i, i64 %j) nounwind readnone { entry: ; CHECK-LABEL: dinsm: -; CHECK: dins ${{[0-9]+}}, ${{[0-9]+}}, 10, 33 +; CHECK: dinsm ${{[0-9]+}}, ${{[0-9]+}}, 10, 33 %shl4 = shl i64 %j, 10 %and = and i64 %shl4, 8796093021184 %and5 = and i64 %i, -8796093021185 @@ -52,7 +52,7 @@ define i64 @dinsu(i64 %i, i64 %j) nounwind readnone { entry: ; CHECK-LABEL: dinsu: -; CHECK: dins ${{[0-9]+}}, ${{[0-9]+}}, 40, 13 +; CHECK: dinsu ${{[0-9]+}}, ${{[0-9]+}}, 40, 13 %shl4 = shl i64 %j, 40 %and = and i64 %shl4, 9006099743113216 %and5 = and i64 %i, -9006099743113217