forked from OSchip/llvm-project
[mips] Range check simm7.
Summary: Also renamed li_simm7 to li16_imm since it's not a simm7 and has an unusual encoding (it's a uimm7 except that 0x7f represents -1). Reviewers: vkalintiris Subscribers: dsanders, llvm-commits Differential Revision: http://reviews.llvm.org/D18145 llvm-svn: 264056
This commit is contained in:
parent
8fc7a1e992
commit
97297770a6
|
@ -1080,6 +1080,11 @@ public:
|
|||
return isConstantImm() &&
|
||||
isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
|
||||
}
|
||||
template <unsigned Bits, unsigned ShiftLeftAmount>
|
||||
bool isScaledSImm() const {
|
||||
return isConstantImm() &&
|
||||
isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm());
|
||||
}
|
||||
bool isRegList16() const {
|
||||
if (!isRegList())
|
||||
return false;
|
||||
|
@ -3764,6 +3769,12 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
case Match_UImm7_0:
|
||||
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
|
||||
"expected 7-bit unsigned immediate");
|
||||
case Match_UImm7_N1:
|
||||
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
|
||||
"expected immediate in range -1 .. 126");
|
||||
case Match_SImm7_Lsl2:
|
||||
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
|
||||
"expected both 9-bit signed immediate and multiple of 4");
|
||||
case Match_UImm8_0:
|
||||
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
|
||||
"expected 8-bit unsigned immediate");
|
||||
|
|
|
@ -362,7 +362,7 @@ static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
|
|||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeLiSimm7(MCInst &Inst,
|
||||
static DecodeStatus DecodeLi16Imm(MCInst &Inst,
|
||||
unsigned Value,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
@ -390,9 +390,10 @@ static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
|
|||
Decoder);
|
||||
}
|
||||
|
||||
template <unsigned Bits, int Offset = 0>
|
||||
static DecodeStatus DecodeSImmWithOffset(MCInst &Inst, unsigned Value,
|
||||
uint64_t Address, const void *Decoder);
|
||||
template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
|
||||
static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeInsSize(MCInst &Inst,
|
||||
unsigned Insn,
|
||||
|
@ -1897,7 +1898,7 @@ static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
|
|||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeLiSimm7(MCInst &Inst,
|
||||
static DecodeStatus DecodeLi16Imm(MCInst &Inst,
|
||||
unsigned Value,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
|
@ -1934,11 +1935,11 @@ static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
|
|||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
template <unsigned Bits, int Offset>
|
||||
static DecodeStatus DecodeSImmWithOffset(MCInst &Inst, unsigned Value,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
int32_t Imm = SignExtend32<Bits>(Value);
|
||||
template <unsigned Bits, int Offset, int ScaleBy>
|
||||
static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
|
||||
Inst.addOperand(MCOperand::createImm(Imm + Offset));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
|
|
@ -821,7 +821,7 @@ class SRL16_MMR6_DESC : ShiftIMM16<"srl16", uimm3_shift, GPRMM16Opnd, II_SRL>,
|
|||
MMR6Arch<"srl16">;
|
||||
class BREAK16_MMR6_DESC : BrkSdbbp16MM<"break16">, MMR6Arch<"srl16">,
|
||||
MicroMipsR6Inst16;
|
||||
class LI16_MMR6_DESC : LoadImmMM16<"li16", li_simm7, GPRMM16Opnd>,
|
||||
class LI16_MMR6_DESC : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>,
|
||||
MMR6Arch<"srl16">, MicroMipsR6Inst16, IsAsCheapAsAMove;
|
||||
class MOVE16_MMR6_DESC : MoveMM16<"move16", GPR32Opnd>, MMR6Arch<"srl16">,
|
||||
MicroMipsR6Inst16;
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddrMM", [frameindex]>;
|
||||
def addrimm4lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrLSL2MM", [frameindex]>;
|
||||
|
||||
def simm7 : Operand<i32>;
|
||||
def li_simm7 : Operand<i32> {
|
||||
let DecoderMethod = "DecodeLiSimm7";
|
||||
}
|
||||
|
||||
def simm12 : Operand<i32> {
|
||||
let DecoderMethod = "DecodeSimm12";
|
||||
}
|
||||
|
@ -88,7 +83,7 @@ def mem_mm_sp_imm5_lsl2 : Operand<i32> {
|
|||
|
||||
def mem_mm_gp_imm7_lsl2 : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops GPRMM16:$base, simm7:$offset);
|
||||
let MIOperandInfo = (ops GPRMM16:$base, simm7_lsl2:$offset);
|
||||
let OperandType = "OPERAND_MEMORY";
|
||||
let EncoderMethod = "getMemEncodingMMGPImm7Lsl2";
|
||||
}
|
||||
|
@ -621,7 +616,7 @@ 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 LI16_MM : LoadImmMM16<"li16", li_simm7, GPRMM16Opnd>, LI_FM_MM16,
|
||||
def LI16_MM : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>, LI_FM_MM16,
|
||||
IsAsCheapAsAMove;
|
||||
def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>,
|
||||
ISA_MICROMIPS32_NOT_MIPS32R6;
|
||||
|
|
|
@ -461,10 +461,23 @@ def UImm16AsmOperandClass
|
|||
: UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
|
||||
def ConstantUImm10AsmOperandClass
|
||||
: ConstantUImmAsmOperandClass<10, [UImm16AsmOperandClass]>;
|
||||
def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
|
||||
let Name = "SImm7Lsl2";
|
||||
let RenderMethod = "addImmOperands";
|
||||
let PredicateMethod = "isScaledSImm<7, 2>";
|
||||
let SuperClasses = [ConstantUImm10AsmOperandClass];
|
||||
let DiagnosticType = "SImm7_Lsl2";
|
||||
}
|
||||
def ConstantUImm8AsmOperandClass
|
||||
: ConstantUImmAsmOperandClass<8, [ConstantUImm10AsmOperandClass]>;
|
||||
: ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
|
||||
def ConstantUImm7Sub1AsmOperandClass
|
||||
: ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
|
||||
// Specify the names since the -1 offset causes invalid identifiers otherwise.
|
||||
let Name = "UImm7_N1";
|
||||
let DiagnosticType = "UImm7_N1";
|
||||
}
|
||||
def ConstantUImm7AsmOperandClass
|
||||
: ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass]>;
|
||||
: ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
|
||||
def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
|
||||
let Name = "UImm6Lsl2";
|
||||
let RenderMethod = "addImmOperands";
|
||||
|
@ -728,11 +741,23 @@ foreach I = {1, 2, 3, 4, 5, 6, 8} in
|
|||
// Signed operands
|
||||
foreach I = {4, 5} in
|
||||
def simm # I : Operand<i32> {
|
||||
let DecoderMethod = "DecodeSImmWithOffset<" # I # ">";
|
||||
let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
|
||||
let ParserMatchClass =
|
||||
!cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
|
||||
}
|
||||
|
||||
def simm7_lsl2 : Operand<OtherVT> {
|
||||
let EncoderMethod = "getSImm7Lsl2Encoding";
|
||||
let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
|
||||
let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
|
||||
}
|
||||
|
||||
// This is almost the same as a uimm7 but 0x7f is interpreted as -1.
|
||||
def li16_imm : Operand<i32> {
|
||||
let DecoderMethod = "DecodeLi16Imm";
|
||||
let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
|
||||
}
|
||||
|
||||
|
||||
def pcrel16 : Operand<i32> {
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
srl16 $4, $9, 6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
sll16 $3, $16, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
|
||||
srl16 $4, $5, 15 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
|
||||
li16 $8, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
li16 $4, -2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
|
||||
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
|
||||
lwm16 $5, $6, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
jraddiusp -4 # CHECK: :[[@LINE]]:13: error: expected both 7-bit unsigned immediate and multiple of 4
|
||||
jraddiusp 125 # CHECK: :[[@LINE]]:13: error: expected both 7-bit unsigned immediate and multiple of 4
|
||||
jraddiusp 128 # CHECK: :[[@LINE]]:13: error: expected both 7-bit unsigned immediate and multiple of 4
|
||||
li16 $4, -2 # CHECK: :[[@LINE]]:12: error: expected immediate in range -1 .. 126
|
||||
li16 $4, 127 # CHECK: :[[@LINE]]:12: error: expected immediate in range -1 .. 126
|
||||
pref -1, 255($7) # CHECK: :[[@LINE]]:8: error: expected 5-bit unsigned immediate
|
||||
pref 32, 255($7) # CHECK: :[[@LINE]]:8: error: expected 5-bit unsigned immediate
|
||||
rotr $2, $3, 32 # CHECK: :[[@LINE]]:16: error: expected 5-bit unsigned immediate
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
lhu16 $3, 64($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
|
||||
lhu16 $3, 64($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
|
||||
lhu16 $16, 4($9) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
li16 $4, -2 # CHECK: :[[@LINE]]:12: error: expected immediate in range -1 .. 126
|
||||
li16 $4, 127 # CHECK: :[[@LINE]]:12: error: expected immediate in range -1 .. 126
|
||||
lsa $4, $2, $3, 0 # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 4
|
||||
lsa $4, $2, $3, 5 # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 4
|
||||
lw16 $9, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
|
|
|
@ -188,7 +188,11 @@
|
|||
sqrt.d $f2, $f4 # CHECK: sqrt.d $f2, $f4 # encoding: [0x54,0x44,0x4a,0x3b]
|
||||
rsqrt.s $f3, $f5 # CHECK: rsqrt.s $f3, $f5 # encoding: [0x54,0x65,0x02,0x3b]
|
||||
rsqrt.d $f2, $f4 # CHECK: rsqrt.d $f2, $f4 # encoding: [0x54,0x44,0x42,0x3b]
|
||||
lw $3, -260($gp) # CHECK: lw $3, -260($gp) # encoding: [0xfc,0x7c,0xfe,0xfc]
|
||||
lw $3, -256($gp) # CHECK: lw $3, -256($gp) # encoding: [0x65,0xc0]
|
||||
lw $3, 32($gp) # CHECK: lw $3, 32($gp) # encoding: [0x65,0x88]
|
||||
lw $3, 252($gp) # CHECK: lw $3, 252($gp) # encoding: [0x65,0xbf]
|
||||
lw $3, 256($gp) # CHECK: lw $3, 256($gp) # encoding: [0xfc,0x7c,0x01,0x00]
|
||||
lw $3, 24($sp) # CHECK: lw $3, 24($sp) # encoding: [0x48,0x66]
|
||||
lw $3, 124($sp) # CHECK: lw $3, 124($sp) # encoding: [0x48,0x7f]
|
||||
lw $3, 128($sp) # CHECK: lw $3, 128($sp) # encoding: [0xfc,0x7d,0x00,0x80]
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
lhu16 $3, 64($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
|
||||
lhu16 $3, 64($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
|
||||
lhu16 $16, 4($9) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
li16 $4, -2 # CHECK: :[[@LINE]]:12: error: expected immediate in range -1 .. 126
|
||||
li16 $4, 127 # CHECK: :[[@LINE]]:12: error: expected immediate in range -1 .. 126
|
||||
lsa $4, $2, $3, 0 # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 4
|
||||
lsa $4, $2, $3, 5 # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 4
|
||||
lw16 $9, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
|
|
Loading…
Reference in New Issue