Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -948,6 +948,15 @@ } template + void addSImmOperands(MCInst &Inst, unsigned N) const { + if (isImm() && !isConstantImm()) { + addExpr(Inst, getImm()); + return; + } + addConstantSImmOperands(Inst, N); + } + + template void addUImmOperands(MCInst &Inst, unsigned N) const { if (isImm() && !isConstantImm()) { addExpr(Inst, getImm()); @@ -1031,6 +1040,9 @@ template bool isConstantUImm() const { return isConstantImm() && isUInt(getConstantImm() - Offset); } + template bool isSImm() const { + return isConstantImm() ? isInt(getConstantImm()) : isImm(); + } template bool isUImm() const { return isConstantImm() ? isUInt(getConstantImm()) : isImm(); } @@ -3793,6 +3805,10 @@ case Match_UImm16_Relaxed: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 16-bit unsigned immediate"); + case Match_SImm16: + case Match_SImm16_Relaxed: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected 16-bit signed immediate"); case Match_UImm20_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 20-bit unsigned immediate"); @@ -3820,6 +3836,9 @@ case Match_MemSImm11: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected memory with 11-bit signed offset"); + case Match_MemSImm16: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected memory with 16-bit signed offset"); } llvm_unreachable("Implement any new match types added!"); Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -372,11 +372,6 @@ uint64_t Address, const void *Decoder); -static DecodeStatus DecodeSimm16(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - template static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address, @@ -1917,14 +1912,6 @@ return MCDisassembler::Success; } -static DecodeStatus DecodeSimm16(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Insn))); - return MCDisassembler::Success; -} - template static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address, Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -48,7 +48,7 @@ class AHI_ATI_DESC_BASE { dag OutOperandList = (outs GPROpnd:$rs); - dag InOperandList = (ins GPROpnd:$rt, simm16:$imm); + dag InOperandList = (ins GPROpnd:$rt, simm16_relaxed:$imm); string AsmString = !strconcat(instr_asm, "\t$rt, $imm"); string Constraints = "$rs = $rt"; InstrItinClass Itinerary = itin; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -421,6 +421,15 @@ let DiagnosticType = "UImmRange" # Bottom # "_" # Top; } +class SImmAsmOperandClass Supers = []> + : AsmOperandClass { + let Name = "SImm" # Bits; + let RenderMethod = "addSImmOperands<" # Bits # ">"; + let PredicateMethod = "isSImm<" # Bits # ">"; + let SuperClasses = Supers; + let DiagnosticType = "SImm" # Bits; +} + class UImmAsmOperandClass Supers = []> : AsmOperandClass { let Name = "UImm" # Bits; @@ -465,11 +474,19 @@ } def UImm16AsmOperandClass : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>; +def SImm16RelaxedAsmOperandClass + : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> { + let Name = "SImm16_Relaxed"; + let PredicateMethod = "isAnyImm<16>"; + let DiagnosticType = "SImm16_Relaxed"; +} +def SImm16AsmOperandClass + : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>; def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass { let Name = "SImm10Lsl3"; let RenderMethod = "addImmOperands"; let PredicateMethod = "isScaledSImm<10, 3>"; - let SuperClasses = [UImm16AsmOperandClass]; + let SuperClasses = [SImm16AsmOperandClass]; let DiagnosticType = "SImm10_Lsl3"; } def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass { @@ -600,10 +617,6 @@ def imm64: Operand; -def simm16 : Operand { - let DecoderMethod= "DecodeSimm16"; -} - def simm19_lsl2 : Operand { let EncoderMethod = "getSimm19Lsl2Encoding"; let DecoderMethod = "DecodeSimm19Lsl2"; @@ -618,10 +631,6 @@ def simm32 : Operand; -def simm16_64 : Operand { - let DecoderMethod = "DecodeSimm16"; -} - // Zero def uimmz : Operand { let PrintMethod = "printUImm<0>"; @@ -796,6 +805,22 @@ let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass; } +def simm16 : Operand { + let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>"; + let ParserMatchClass = !cast("SImm16AsmOperandClass"); +} + +// Like simm16 but coerces uimm16 to simm16. +def simm16_relaxed : Operand { + let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>"; + let ParserMatchClass = !cast("SImm16RelaxedAsmOperandClass"); +} + +def simm16_64 : Operand { + let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>"; + let ParserMatchClass = !cast("SImm16AsmOperandClass"); +} + // This is almost the same as a uimm7 but 0x7f is interpreted as -1. def li16_imm : Operand { let DecoderMethod = "DecodeLi16Imm"; @@ -863,6 +888,7 @@ let RenderMethod = "addMemOperands"; let ParserMethod = "parseMemOperand"; let PredicateMethod = "isMemWithSimmOffset<16>"; + let DiagnosticType = "MemSImm16"; } def MipsInvertedImmoperand : AsmOperandClass { @@ -1603,11 +1629,11 @@ /// Arithmetic Instructions (ALU Immediate) let AdditionalPredicates = [NotInMicroMips] in { -def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16, GPR32Opnd, +def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd, II_ADDIU, immSExt16, add>, ADDI_FM<0x9>, IsAsCheapAsAMove; } -def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>, +def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd>, ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6; def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>, SLTI_FM<0xa>; @@ -2110,19 +2136,19 @@ def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>, ISA_MIPS1_NOT_32R6_64R6; def : MipsInstAlias<"addu $rs, $rt, $imm", - (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; + (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; def : MipsInstAlias<"addu $rs, $imm", - (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>; + (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>; def : MipsInstAlias<"add $rs, $rt, $imm", - (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>, + (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6; def : MipsInstAlias<"add $rs, $imm", - (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>, + (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6; def : MipsInstAlias<"and $rs, $rt, $imm", - (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; + (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; def : MipsInstAlias<"and $rs, $imm", - (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>; + (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>; def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>; let Predicates = [NotInMicroMips] in { def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>; @@ -2137,9 +2163,9 @@ def : MipsInstAlias<"negu $rt, $rs", (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>; def : MipsInstAlias<"slt $rs, $rt, $imm", - (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; + (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; def : MipsInstAlias<"sltu $rt, $rs, $imm", - (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>; + (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm32:$imm), 0>; def : MipsInstAlias<"xor $rs, $rt, $imm", (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; def : MipsInstAlias<"xor $rs, $imm", @@ -2233,8 +2259,9 @@ def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs), "jal\t$rs"> ; -def NORImm : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), - "nor\t$rs, $rt, $imm"> ; +def NORImm : MipsAsmPseudoInst< + (outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), + "nor\t$rs, $rt, $imm"> ; let hasDelaySlot = 1, isCTI = 1 in { def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), Index: test/MC/Mips/mips1/invalid-mips2-wrong-error.s =================================================================== --- test/MC/Mips/mips1/invalid-mips2-wrong-error.s +++ test/MC/Mips/mips1/invalid-mips2-wrong-error.s @@ -7,12 +7,12 @@ .set noat ldc1 $f11,16391($s0) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction - ldc2 $8,-21181($at) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset - ldc2 $8,-1024($at) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset + ldc2 $8,-21181($at) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset + ldc2 $8,-1024($at) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset ldc3 $29,-28645($s1) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction ll $v0,-7321($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 9-bit signed offset sc $t7,18904($s3) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 9-bit signed offset sdc1 $f31,30574($t5) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction - sdc2 $20,23157($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset - sdc2 $20,-1024($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset + sdc2 $20,23157($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset + sdc2 $20,-1024($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset sdc3 $12,5835($t2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/mips1/invalid-mips3-wrong-error.s =================================================================== --- test/MC/Mips/mips1/invalid-mips3-wrong-error.s +++ test/MC/Mips/mips1/invalid-mips3-wrong-error.s @@ -8,8 +8,8 @@ .set noat ld $sp,-28645($s1) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction ldc1 $f11,16391($s0) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction - ldc2 $8,-21181($at) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset - ldc2 $20,-1024($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset + ldc2 $8,-21181($at) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset + ldc2 $20,-1024($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset ldl $24,-4167($24) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction ldr $14,-30358($s4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction ll $v0,-7321($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 9-bit signed offset @@ -19,7 +19,7 @@ scd $15,-8243($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 9-bit signed offset sd $12,5835($10) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction sdc1 $f31,30574($13) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction - sdc2 $20,23157($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset - sdc2 $20,-1024($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset + sdc2 $20,23157($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset + sdc2 $20,-1024($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset sdl $a3,-20961($s8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction sdr $11,-20423($12) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/mips1/invalid-mips4-wrong-error.s =================================================================== --- test/MC/Mips/mips1/invalid-mips4-wrong-error.s +++ test/MC/Mips/mips1/invalid-mips4-wrong-error.s @@ -10,8 +10,8 @@ bc1tl $fcc7,27 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction ld $sp,-28645($s1) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction ldc1 $f11,16391($s0) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction - ldc2 $8,-21181($at) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset - ldc2 $20,-1024($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset + ldc2 $8,-21181($at) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset + ldc2 $20,-1024($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset ldl $24,-4167($24) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction ldr $14,-30358($s4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction ll $v0,-7321($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 9-bit signed offset @@ -21,7 +21,7 @@ scd $15,-8243($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 9-bit signed offset sd $12,5835($10) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction sdc1 $f31,30574($13) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction - sdc2 $20,23157($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset - sdc2 $20,-1024($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 11-bit signed offset + sdc2 $20,23157($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset + sdc2 $20,-1024($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset sdl $a3,-20961($s8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction sdr $11,-20423($12) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/mips32r2/invalid.s =================================================================== --- test/MC/Mips/mips32r2/invalid.s +++ test/MC/Mips/mips32r2/invalid.s @@ -6,6 +6,8 @@ .text .set noreorder + addiu $2, $3, -32769 # CHECK: :[[@LINE]]:23: error: expected 16-bit signed immediate + addiu $2, $3, 65536 # CHECK: :[[@LINE]]:23: error: expected 16-bit signed immediate andi $2, $3, -1 # CHECK: :[[@LINE]]:22: error: expected 16-bit unsigned immediate andi $2, $3, 65536 # CHECK: :[[@LINE]]:22: error: expected 16-bit unsigned immediate cache -1, 255($7) # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate @@ -20,6 +22,8 @@ ins $2, $3, 32, 1 # CHECK: :[[@LINE]]:21: error: expected 5-bit unsigned immediate jalr.hb $31 # CHECK: :[[@LINE]]:9: error: source and destination must be different jalr.hb $31, $31 # CHECK: :[[@LINE]]:9: error: source and destination must be different + lwc2 $2, -32769($3) # CHECK: :[[@LINE]]:18: error: expected memory with 16-bit signed offset + lwc2 $2, 32768($3) # CHECK: :[[@LINE]]:18: error: expected memory with 16-bit signed offset ori $2, $3, -1 # CHECK: :[[@LINE]]:21: error: expected 16-bit unsigned immediate ori $2, $3, 65536 # CHECK: :[[@LINE]]:21: error: expected 16-bit unsigned immediate pref -1, 255($7) # CHECK: :[[@LINE]]:14: error: expected 5-bit unsigned immediate Index: test/MC/Mips/mips64r6/valid.s =================================================================== --- test/MC/Mips/mips64r6/valid.s +++ test/MC/Mips/mips64r6/valid.s @@ -105,8 +105,8 @@ daddu $24,$2,18079 # CHECK: daddiu $24, $2, 18079 # encoding: [0x64,0x58,0x46,0x9f] dahi $3,0x5678 # CHECK: dahi $3, 22136 # encoding: [0x04,0x66,0x56,0x78] dalign $4,$2,$3,5 # CHECK: dalign $4, $2, $3, 5 # encoding: [0x7c,0x43,0x23,0x64] - dati $3,0xabcd # CHECK: dati $3, 43981 # encoding: [0x04,0x7e,0xab,0xcd] - daui $3,$2,0x1234 # CHECK: daui $3, $2, 4660 # encoding: [0x74,0x62,0x12,0x34] + dati $3,0xabcd # CHECK: dati $3, -21555 # encoding: [0x04,0x7e,0xab,0xcd] + daui $3,$2,0x1234 # CHECK: daui $3, $2, 4660 # encoding: [0x74,0x62,0x12,0x34] dbitswap $4, $2 # CHECK: dbitswap $4, $2 # encoding: [0x7c,0x02,0x20,0x24] dclo $s2,$a2 # CHECK: dclo $18, $6 # encoding: [0x00,0xc0,0x90,0x53] dclz $s0,$25 # CHECK: dclz $16, $25 # encoding: [0x03,0x20,0x80,0x52]