mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-05 19:29:54 +00:00
[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:
parent
8e27cb2f34
commit
7662955e2e
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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";
|
||||
|
@ -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> {
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user