[mips] Range check simm4.

Summary:

Reviewers: vkalintiris

Subscribers: dsanders, llvm-commits

Differential Revision: http://reviews.llvm.org/D16811


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263220 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Sanders 2016-03-11 11:37:50 +00:00
parent 8e27cb2f34
commit 7662955e2e
8 changed files with 56 additions and 37 deletions

View File

@ -956,6 +956,16 @@ public:
addConstantUImmOperands<Bits, 0, 0>(Inst, N);
}
template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
int64_t Imm = getConstantImm() - Offset;
Imm = SignExtend64<Bits>(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();
@ -1029,8 +1039,8 @@ public:
isUInt<Bits>(getConstantImm()))
: isImm();
}
template <unsigned Bits> bool isConstantSImm() const {
return isConstantImm() && isInt<Bits>(getConstantImm());
template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
}
template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
return isConstantImm() && getConstantImm() >= Bottom &&
@ -1810,14 +1820,6 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
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())
@ -3734,6 +3736,9 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
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");
@ -3760,7 +3765,7 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
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:

View File

@ -377,11 +377,6 @@ static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
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 @@ template <unsigned Bits, int Offset>
static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
uint64_t Address, const void *Decoder);
template <unsigned Bits, int Offset = 0>
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 @@ static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
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 @@ static DecodeStatus DecodeUImmWithOffset(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);
Inst.addOperand(MCOperand::createImm(Imm + Offset));
return MCDisassembler::Success;
}
static DecodeStatus DecodeInsSize(MCInst &Inst,
unsigned Insn,
uint64_t Address,

View File

@ -1,9 +1,6 @@
def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddrMM", [frameindex]>;
def addrimm4lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrLSL2MM", [frameindex]>;
def simm4 : Operand<i32> {
let DecoderMethod = "DecodeSimm4";
}
def simm7 : Operand<i32>;
def li_simm7 : Operand<i32> {
let DecoderMethod = "DecodeLiSimm7";

View File

@ -385,15 +385,19 @@ include "MipsInstrFormats.td"
// Mips Operand, Complex Patterns and Transformations Definitions.
//===----------------------------------------------------------------------===//
class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
: AsmOperandClass {
let Name = "ConstantSImm" # Bits;
let RenderMethod = "addImmOperands";
let PredicateMethod = "isConstantSImm<" # Bits # ">";
class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> 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<int Bits, list<AsmOperandClass> Supers = [],
int Offset = 0> : AsmOperandClass {
let Name = "ConstantUImm" # Bits # "_" # Offset;
@ -476,7 +480,8 @@ def ConstantUImm4AsmOperandClass
ConstantUImm5Plus32AsmOperandClass,
ConstantUImm5Plus32NormalizeAsmOperandClass]>;
def ConstantUImm3AsmOperandClass
: ConstantUImmAsmOperandClass<3, [ConstantUImm4AsmOperandClass]>;
: ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass,
ConstantUImm4AsmOperandClass]>;
def ConstantUImm2Plus1AsmOperandClass
: ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
def ConstantUImm2AsmOperandClass
@ -666,6 +671,15 @@ def uimm5_64_report_uimm6 : Operand<i64> {
let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
}
// Signed operands
foreach I = {4} in
def simm # I : Operand<i32> {
let DecoderMethod = "DecodeSImmWithOffset<" # I # ">";
let ParserMatchClass =
!cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
}
def pcrel16 : Operand<i32> {
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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