Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -950,6 +950,16 @@ addConstantUImmOperands(Inst, N); } + template + void addConstantSImmOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + int64_t Imm = getConstantImm() - Offset; + Imm = SignExtend64(Imm); + Imm += Offset; + Imm += AdjustOffset; + Inst.addOperand(MCOperand::createImm(Imm)); + } + void addImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); const MCExpr *Expr = getImm(); @@ -1023,8 +1033,8 @@ isUInt(getConstantImm())) : isImm(); } - template bool isConstantSImm() const { - return isConstantImm() && isInt(getConstantImm()); + template bool isConstantSImm() const { + return isConstantImm() && isInt(getConstantImm() - Offset); } bool isToken() const override { // Note: It's not possible to pretend that other operand kinds are tokens. @@ -1800,14 +1810,6 @@ switch (Inst.getOpcode()) { default: break; - case Mips::ADDIUS5_MM: - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (Imm < -8 || Imm > 7) - return Error(IDLoc, "immediate operand value out of range"); - break; case Mips::ADDIUSP_MM: Opnd = Inst.getOperand(0); if (!Opnd.isImm()) @@ -3676,6 +3678,9 @@ case Match_UImm4_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 4-bit unsigned immediate"); + case Match_SImm4_0: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected 4-bit signed immediate"); case Match_UImm5_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 5-bit unsigned immediate"); @@ -3699,7 +3704,7 @@ case Match_UImm6_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 6-bit unsigned immediate"); - case Match_SImm6: + case Match_SImm6_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 6-bit signed immediate"); case Match_UImm7_0: Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -377,11 +377,6 @@ uint64_t Address, const void *Decoder); -static DecodeStatus DecodeSimm4(MCInst &Inst, - unsigned Value, - uint64_t Address, - const void *Decoder); - static DecodeStatus DecodeSimm16(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -391,6 +386,10 @@ static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, uint64_t Address, const void *Decoder); +template +static DecodeStatus DecodeSImmWithOffset(MCInst &Inst, unsigned Value, + uint64_t Address, const void *Decoder); + static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1924,14 +1923,6 @@ return MCDisassembler::Success; } -static DecodeStatus DecodeSimm4(MCInst &Inst, - unsigned Value, - uint64_t Address, - const void *Decoder) { - Inst.addOperand(MCOperand::createImm(SignExtend32<4>(Value))); - return MCDisassembler::Success; -} - static DecodeStatus DecodeSimm16(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1949,6 +1940,15 @@ return MCDisassembler::Success; } +template +static DecodeStatus DecodeSImmWithOffset(MCInst &Inst, unsigned Value, + uint64_t Address, + const void *Decoder) { + int32_t Imm = SignExtend32(Value); + Inst.addOperand(MCOperand::createImm(Imm + Offset)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address, Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -1,9 +1,6 @@ def addrimm12 : ComplexPattern; def addrimm4lsl2 : ComplexPattern; -def simm4 : Operand { - let DecoderMethod = "DecodeSimm4"; -} def simm7 : Operand; def li_simm7 : Operand { let DecoderMethod = "DecodeLiSimm7"; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -385,15 +385,19 @@ // Mips Operand, Complex Patterns and Transformations Definitions. //===----------------------------------------------------------------------===// -class ConstantSImmAsmOperandClass Supers = []> - : AsmOperandClass { - let Name = "ConstantSImm" # Bits; - let RenderMethod = "addImmOperands"; - let PredicateMethod = "isConstantSImm<" # Bits # ">"; +class ConstantSImmAsmOperandClass Supers = [], + int Offset = 0> : AsmOperandClass { + let Name = "ConstantSImm" # Bits # "_" # Offset; + let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">"; + let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">"; let SuperClasses = Supers; - let DiagnosticType = "SImm" # Bits; + let DiagnosticType = "SImm" # Bits # "_" # Offset; } +def ConstantSImm4AsmOperandClass + : ConstantSImmAsmOperandClass< + 4, []>; + class ConstantUImmAsmOperandClass Supers = [], int Offset = 0> : AsmOperandClass { let Name = "ConstantUImm" # Bits # "_" # Offset; @@ -464,7 +468,8 @@ ConstantUImm5Plus32AsmOperandClass, ConstantUImm5Plus32NormalizeAsmOperandClass]>; def ConstantUImm3AsmOperandClass - : ConstantUImmAsmOperandClass<3, [ConstantUImm4AsmOperandClass]>; + : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass, + ConstantUImm4AsmOperandClass]>; def ConstantUImm2Plus1AsmOperandClass : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>; def ConstantUImm2AsmOperandClass @@ -639,6 +644,15 @@ let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass; } +// Signed operands +foreach I = {4} in + def simm # I : Operand { + let DecoderMethod = "DecodeSImmWithOffset<" # I # ">"; + let ParserMatchClass = + !cast("ConstantSImm" # I # "AsmOperandClass"); + } + + def pcrel16 : Operand { } Index: test/MC/Mips/micromips-invalid.s =================================================================== --- test/MC/Mips/micromips-invalid.s +++ test/MC/Mips/micromips-invalid.s @@ -4,7 +4,6 @@ addiur1sp $7, 260 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range addiur1sp $7, 241 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: misaligned immediate operand value addiur1sp $8, 240 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction - addius5 $7, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range addiusp 1032 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range addu16 $6, $14, $4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction subu16 $5, $16, $9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips/invalid.s =================================================================== --- test/MC/Mips/micromips/invalid.s +++ test/MC/Mips/micromips/invalid.s @@ -1,6 +1,8 @@ # RUN: not llvm-mc %s -triple=mips -show-encoding -mattr=micromips 2>%t1 # RUN: FileCheck %s < %t1 + addius5 $2, -9 # CHECK: :[[@LINE]]:15: error: expected 4-bit signed immediate + addius5 $2, 8 # CHECK: :[[@LINE]]:15: error: expected 4-bit signed immediate break -1 # CHECK: :[[@LINE]]:9: error: expected 10-bit unsigned immediate break 1024 # CHECK: :[[@LINE]]:9: error: expected 10-bit unsigned immediate break -1, 5 # CHECK: :[[@LINE]]:9: error: expected 10-bit unsigned immediate Index: test/MC/Mips/micromips32r6/invalid.s =================================================================== --- test/MC/Mips/micromips32r6/invalid.s +++ test/MC/Mips/micromips32r6/invalid.s @@ -6,7 +6,8 @@ addiur1sp $8, 240 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction addiur2 $9, $7, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction addiur2 $6, $7, 10 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range - addius5 $7, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + addius5 $2, -9 # CHECK: :[[@LINE]]:15: error: expected 4-bit signed immediate + addius5 $2, 8 # CHECK: :[[@LINE]]:15: error: expected 4-bit signed immediate addiusp 1032 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range align $4, $2, $3, -1 # CHECK: :[[@LINE]]:21: error: expected 2-bit unsigned immediate align $4, $2, $3, 4 # CHECK: :[[@LINE]]:21: error: expected 2-bit unsigned immediate Index: test/MC/Mips/micromips64r6/invalid.s =================================================================== --- test/MC/Mips/micromips64r6/invalid.s +++ test/MC/Mips/micromips64r6/invalid.s @@ -6,7 +6,8 @@ addiur1sp $8, 240 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction addiur2 $9, $7, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction addiur2 $6, $7, 10 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range - addius5 $7, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + addius5 $2, -9 # CHECK: :[[@LINE]]:15: error: expected 4-bit signed immediate + addius5 $2, 8 # CHECK: :[[@LINE]]:15: error: expected 4-bit signed immediate addiusp 1032 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range align $4, $2, $3, -1 # CHECK: :[[@LINE]]:21: error: expected 2-bit unsigned immediate align $4, $2, $3, 4 # CHECK: :[[@LINE]]:21: error: expected 2-bit unsigned immediate