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 @@ -1032,6 +1032,10 @@ template bool isConstantSImm() const { return isConstantImm() && isInt(getConstantImm()); } + template bool isConstantUImmRange() const { + return isConstantImm() && getConstantImm() >= Bottom && + getConstantImm() <= Top; + } bool isToken() const override { // Note: It's not possible to pretend that other operand kinds are tokens. // The matcher emitter checks tokens first. @@ -3749,6 +3753,9 @@ case Match_UImm5_Lsl2: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected both 7-bit unsigned immediate and multiple of 4"); + case Match_UImmRange2_64: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected immediate in range 2 .. 64"); case Match_UImm6_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 6-bit unsigned immediate"); Index: llvm/trunk/lib/Target/Mips/MicroMips64r6InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMips64r6InstrInfo.td +++ llvm/trunk/lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -28,6 +28,9 @@ class DMOD_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmod", 0b101011000>; class DDIVU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"ddivu", 0b110011000>; class DMODU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmodu", 0b111011000>; +class DINSU_MM64R6_ENC : POOL32S_EXTBITS_FM_MMR6<0b110100>; +class DINSM_MM64R6_ENC : POOL32S_EXTBITS_FM_MMR6<0b000100>; +class DINS_MM64R6_ENC : POOL32S_EXTBITS_FM_MMR6<0b001100>; //===----------------------------------------------------------------------===// // @@ -90,6 +93,12 @@ class DDIVU_MM64R6_DESC : ArithLogicR<"ddivu", GPR32Opnd>; class DMODU_MM64R6_DESC : ArithLogicR<"dmodu", GPR32Opnd>; +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>; +class DINS_MM64R6_DESC : InsBase<"dins", GPR64Opnd, uimm5, uimm5_inssize_plus1, + MipsIns>; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -116,4 +125,10 @@ ISA_MICROMIPS64R6; def DMODU_MM64R6 : R6MMR6Rel, DMODU_MM64R6_DESC, DMODU_MM64R6_ENC, ISA_MICROMIPS64R6; + def DINSU_MM64R6: R6MMR6Rel, DINSU_MM64R6_DESC, DINSU_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DINSM_MM64R6: R6MMR6Rel, DINSM_MM64R6_DESC, DINSM_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DINS_MM64R6: R6MMR6Rel, DINS_MM64R6_DESC, DINS_MM64R6_ENC, + ISA_MICROMIPS64R6; } Index: llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td @@ -847,8 +847,8 @@ // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction def EXT_MM : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, MipsExt>, EXT_FM_MM<0x2c>; - def INS_MM : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, - EXT_FM_MM<0x0c>; + def INS_MM : MMRel, InsBase<"ins", GPR32Opnd, uimm5, uimm5_inssize_plus1, + MipsIns>, EXT_FM_MM<0x0c>; /// Jump Instructions let DecoderMethod = "DecodeJumpTargetMM" in { Index: llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td +++ llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td @@ -277,12 +277,14 @@ EXT_FM<1>; def DEXTU : ExtBase<"dextu", GPR64Opnd, uimm5_plus32, uimm5_plus1, MipsExt>, EXT_FM<2>; + def DINS : InsBase<"dins", GPR64Opnd, uimm6, uimm5_inssize_plus1, MipsIns>, + EXT_FM<7>; + def DINSU : InsBase<"dinsu", GPR64Opnd, uimm5_plus32, uimm5_inssize_plus1>, + EXT_FM<6>; + def DINSM : InsBase<"dinsm", GPR64Opnd, uimm5, uimm5_inssize_plus1>, + EXT_FM<5>; } -def DINS : InsBase<"dins", GPR64Opnd, uimm6, MipsIns>, EXT_FM<7>; -def DINSU : InsBase<"dinsu", GPR64Opnd, uimm5_plus32>, EXT_FM<6>; -def DINSM : InsBase<"dinsm", GPR64Opnd, uimm5>, EXT_FM<5>; - let isCodeGenOnly = 1, rs = 0, shamt = 0 in { def DSLL64_32 : FR<0x00, 0x3c, (outs GPR64:$rd), (ins GPR32:$rt), "dsll\t$rd, $rt, 32", [], II_DSLL>; Index: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td @@ -403,6 +403,16 @@ let DiagnosticType = "UImm" # Bits # "_" # Offset; } +class ConstantUImmRangeAsmOperandClass Supers = []> + : AsmOperandClass { + let Name = "ConstantUImmRange" # Bottom # "_" # Top; + let RenderMethod = "addImmOperands"; + let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">"; + let SuperClasses = Supers; + let DiagnosticType = "UImmRange" # Bottom # "_" # Top; +} + class UImmAsmOperandClass Supers = []> : AsmOperandClass { let Name = "UImm" # Bits; @@ -432,6 +442,8 @@ : ConstantSImmAsmOperandClass<6, [ConstantUImm7AsmOperandClass]>; def ConstantUImm5Plus1AsmOperandClass : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass], 1>; +def ConstantUImm5_Range2_64AsmOperandClass + : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm6AsmOperandClass]>; def ConstantUImm5Plus32AsmOperandClass : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass], 32>; def ConstantUImm5Plus33AsmOperandClass @@ -542,6 +554,14 @@ let ParserMatchClass = ConstantImmzAsmOperandClass; } +// size operand of ins instruction +def uimm_range_2_64 : Operand { + let PrintMethod = "printUnsignedImm"; + let EncoderMethod = "getSizeInsEncoding"; + let DecoderMethod = "DecodeInsSize"; + let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass; +} + // Unsigned Operands foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10} in def uimm # I : Operand { @@ -576,6 +596,13 @@ let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass; } +def uimm5_inssize_plus1 : Operand { + let PrintMethod = "printUnsignedImm"; + let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass; + let EncoderMethod = "getSizeInsEncoding"; + let DecoderMethod = "DecodeInsSize"; +} + def uimm5_plus32_normalize : Operand { let PrintMethod = "printUnsignedImm"; let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass; @@ -1253,8 +1280,8 @@ FrmR, opstr>, ISA_MIPS32R2; class InsBase: - InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src), + Operand SizeOpnd, 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))], II_INS, FrmR, opstr>, ISA_MIPS32R2 { @@ -1738,7 +1765,8 @@ // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, MipsExt>, EXT_FM<0>; -def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>; +def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, uimm5_inssize_plus1, MipsIns>, + EXT_FM<4>; /// Move Control Registers From/To CPU Registers def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32; 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 @@ -171,3 +171,6 @@ 0x00 0x0f 0x47 0x7c # CHECK: di $15 0x00 0x00 0x43 0x7c # CHECK: tlbinv 0x00 0x00 0x53 0x7c # CHECK: tlbinvf +0x58 0x82 0x20 0x34 # CHECK: dinsu $4, $2, 0, 5 +0x58 0x82 0x38 0xc4 # CHECK: dinsm $4, $2, 3, 5 +0x58 0x82 0x38 0xcc # CHECK: dins $4, $2, 3, 5 Index: llvm/trunk/test/MC/Mips/cnmips/invalid.s =================================================================== --- llvm/trunk/test/MC/Mips/cnmips/invalid.s +++ llvm/trunk/test/MC/Mips/cnmips/invalid.s @@ -13,3 +13,7 @@ bbit1 $19, 64, foo # CHECK: :[[@LINE]]:16: error: expected 6-bit unsigned immediate bbit132 $19, -1, foo # CHECK: :[[@LINE]]:18: error: expected 5-bit unsigned immediate bbit132 $19, 32, foo # CHECK: :[[@LINE]]:18: error: expected 5-bit unsigned immediate + ins $2, $3, -1, 1 # CHECK: :[[@LINE]]:17: error: expected 5-bit unsigned immediate + ins $2, $3, 32, 1 # CHECK: :[[@LINE]]:17: error: expected 5-bit unsigned immediate + ins $2, $3, 0, -1 # CHECK: :[[@LINE]]:20: error: expected immediate in range 1 .. 32 + ins $2, $3, 0, 33 # CHECK: :[[@LINE]]:20: error: expected immediate in range 1 .. 32 Index: llvm/trunk/test/MC/Mips/micromips/invalid.s =================================================================== --- llvm/trunk/test/MC/Mips/micromips/invalid.s +++ llvm/trunk/test/MC/Mips/micromips/invalid.s @@ -33,3 +33,7 @@ sra $2, $3, 32 # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate srl $2, $3, -1 # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate srl $2, $3, 32 # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate + ins $2, $3, -1, 1 # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate + ins $2, $3, 32, 1 # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate + ins $2, $3, 0, -1 # CHECK: :[[@LINE]]:18: error: expected immediate in range 1 .. 32 + ins $2, $3, 0, 33 # CHECK: :[[@LINE]]:18: error: expected immediate in range 1 .. 32 Index: llvm/trunk/test/MC/Mips/micromips64r6/invalid-wrong-error.s =================================================================== --- llvm/trunk/test/MC/Mips/micromips64r6/invalid-wrong-error.s +++ llvm/trunk/test/MC/Mips/micromips64r6/invalid-wrong-error.s @@ -25,3 +25,5 @@ tne $8, $9, $2 # CHECK: :[[@LINE]]:15: error: expected 10-bit unsigned immediate tne $8, $9, -1 # CHECK: :[[@LINE]]:15: error: expected 10-bit unsigned immediate tne $8, $9, 16 # CHECK: :[[@LINE]]:3: error: instruction requires a CPU feature not currently enabled + dins $2, $3, -1, 1 # CHECK: :[[@LINE]]:16: error: expected 6-bit unsigned immediate + dins $2, $3, 32, 1 # CHECK: :[[@LINE]]:3: error: instruction requires a CPU feature not currently enabled 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 @@ -33,13 +33,17 @@ dextu $2, $3, 64, 1 # CHECK: :[[@LINE]]:17: error: expected immediate in range 32 .. 63 dextu $2, $3, 32, 0 # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 32 dextu $2, $3, 32, 33 # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 32 - # FIXME: Check size on dins* - dins $2, $3, -1, 1 # CHECK: :[[@LINE]]:16: error: expected 6-bit unsigned immediate - dins $2, $3, 64, 1 # CHECK: :[[@LINE]]:16: error: expected 6-bit unsigned immediate + dins $2, $3, 31, 33 # CHECK: :[[@LINE]]:20: error: expected immediate in range 1 .. 32 + dins $2, $3, 31, 0 # CHECK: :[[@LINE]]:20: error: expected immediate in range 1 .. 32 + # FIXME: Check '32 <= pos + size <= 64' constraint on dinsm dinsm $2, $3, -1, 1 # CHECK: :[[@LINE]]:17: error: expected 5-bit unsigned immediate dinsm $2, $3, 32, 1 # CHECK: :[[@LINE]]:17: error: expected 5-bit unsigned immediate + dinsm $2, $3, 31, 0 # CHECK: :[[@LINE]]:21: error: expected immediate in range 2 .. 64 + dinsm $2, $3, 31, 65 # CHECK: :[[@LINE]]:21: error: expected immediate in range 2 .. 64 dinsu $2, $3, 31, 1 # CHECK: :[[@LINE]]:17: error: expected immediate in range 32 .. 63 dinsu $2, $3, 64, 1 # CHECK: :[[@LINE]]:17: error: expected immediate in range 32 .. 63 + dinsu $2, $3, 63, 0 # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 32 + dinsu $2, $3, 32, 33 # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 32 # FIXME: Check '0 < pos + size <= 32' constraint on ext ext $2, $3, -1, 31 # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate ext $2, $3, 32, 31 # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate 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 @@ -156,5 +156,7 @@ floor.l.d $f1, $f3 # CHECK: floor.l.d $f1, $f3 # encoding: [0x54,0x23,0x43,0x3b] tlbinv # CHECK: tlbinv # encoding: [0x00,0x00,0x43,0x7c] tlbinvf # CHECK: tlbinvf # encoding: [0x00,0x00,0x53,0x7c] - + dinsu $4, $2, 32, 5 # CHECK: dinsu $4, $2, 32, 5 # encoding: [0x58,0x82,0x20,0x34] + dinsm $4, $2, 3, 5 # CHECK: dinsm $4, $2, 3, 5 # encoding: [0x58,0x82,0x38,0xc4] + dins $4, $2, 3, 5 # CHECK: dins $4, $2, 3, 5 # encoding: [0x58,0x82,0x38,0xcc] 1: Index: llvm/trunk/test/MC/Mips/mips64/invalid-mips64r2.s =================================================================== --- llvm/trunk/test/MC/Mips/mips64/invalid-mips64r2.s +++ llvm/trunk/test/MC/Mips/mips64/invalid-mips64r2.s @@ -23,3 +23,13 @@ seb $25,$15 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled seh $v1,$12 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled wsbh $k1,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + dins $2, $3, -1, 1 # CHECK: :[[@LINE]]:22: error: expected 6-bit unsigned immediate + dins $2, $3, 64, 1 # CHECK: :[[@LINE]]:22: error: expected 6-bit unsigned immediate + dinsm $2, $3, -1, 1 # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate + dinsm $2, $3, 32, 1 # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate + dinsm $2, $3, 31, 0 # CHECK: :[[@LINE]]:27: error: expected immediate in range 2 .. 64 + dinsm $2, $3, 31, 65 # CHECK: :[[@LINE]]:27: error: expected immediate in range 2 .. 64 + dinsu $2, $3, 31, 1 # CHECK: :[[@LINE]]:23: error: expected immediate in range 32 .. 63 + dinsu $2, $3, 64, 1 # CHECK: :[[@LINE]]:23: error: expected immediate in range 32 .. 63 + dinsu $2, $3, 63, 0 # CHECK: :[[@LINE]]:27: error: expected immediate in range 1 .. 32 + dinsu $2, $3, 32, 33 # CHECK: :[[@LINE]]:27: error: expected immediate in range 1 .. 32