mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-07 18:21:58 +00:00
[mips][ias] Range check uimmz operands.
Reviewers: vkalintiris Subscribers: dsanders, atanasyan, llvm-commits Differential Revision: http://reviews.llvm.org/D14013 llvm-svn: 252294
This commit is contained in:
parent
ac58e2a800
commit
1aa37b1a8f
@ -383,7 +383,7 @@ class MipsAsmParser : public MCTargetAsmParser {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum MipsMatchResultTy {
|
enum MipsMatchResultTy {
|
||||||
Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
|
Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
|
||||||
#define GET_OPERAND_DIAGNOSTIC_TYPES
|
#define GET_OPERAND_DIAGNOSTIC_TYPES
|
||||||
#include "MipsGenAsmMatcher.inc"
|
#include "MipsGenAsmMatcher.inc"
|
||||||
#undef GET_OPERAND_DIAGNOSTIC_TYPES
|
#undef GET_OPERAND_DIAGNOSTIC_TYPES
|
||||||
@ -894,6 +894,13 @@ public:
|
|||||||
Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
|
Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <unsigned Bits>
|
||||||
|
void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
|
||||||
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
|
uint64_t Imm = getConstantImm() & ((1 << Bits) - 1);
|
||||||
|
Inst.addOperand(MCOperand::createImm(Imm));
|
||||||
|
}
|
||||||
|
|
||||||
void addImmOperands(MCInst &Inst, unsigned N) const {
|
void addImmOperands(MCInst &Inst, unsigned N) const {
|
||||||
assert(N == 1 && "Invalid number of operands!");
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
const MCExpr *Expr = getImm();
|
const MCExpr *Expr = getImm();
|
||||||
@ -953,6 +960,9 @@ public:
|
|||||||
bool isConstantImm() const {
|
bool isConstantImm() const {
|
||||||
return isImm() && dyn_cast<MCConstantExpr>(getImm());
|
return isImm() && dyn_cast<MCConstantExpr>(getImm());
|
||||||
}
|
}
|
||||||
|
bool isConstantImmz() const {
|
||||||
|
return isConstantImm() && getConstantImm() == 0;
|
||||||
|
}
|
||||||
template <unsigned Bits> bool isUImm() const {
|
template <unsigned Bits> bool isUImm() const {
|
||||||
return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
|
return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
|
||||||
}
|
}
|
||||||
@ -3234,6 +3244,17 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
|
|||||||
return Match_Success;
|
return Match_Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
|
||||||
|
uint64_t ErrorInfo) {
|
||||||
|
if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
|
||||||
|
SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
|
||||||
|
if (ErrorLoc == SMLoc())
|
||||||
|
return Loc;
|
||||||
|
return ErrorLoc;
|
||||||
|
}
|
||||||
|
return Loc;
|
||||||
|
}
|
||||||
|
|
||||||
bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||||
OperandVector &Operands,
|
OperandVector &Operands,
|
||||||
MCStreamer &Out,
|
MCStreamer &Out,
|
||||||
@ -3262,7 +3283,7 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||||||
if (ErrorInfo >= Operands.size())
|
if (ErrorInfo >= Operands.size())
|
||||||
return Error(IDLoc, "too few operands for instruction");
|
return Error(IDLoc, "too few operands for instruction");
|
||||||
|
|
||||||
ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
|
ErrorLoc = Operands[ErrorInfo]->getStartLoc();
|
||||||
if (ErrorLoc == SMLoc())
|
if (ErrorLoc == SMLoc())
|
||||||
ErrorLoc = IDLoc;
|
ErrorLoc = IDLoc;
|
||||||
}
|
}
|
||||||
@ -3273,6 +3294,8 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||||||
return Error(IDLoc, "invalid instruction");
|
return Error(IDLoc, "invalid instruction");
|
||||||
case Match_RequiresDifferentSrcAndDst:
|
case Match_RequiresDifferentSrcAndDst:
|
||||||
return Error(IDLoc, "source and destination must be different");
|
return Error(IDLoc, "source and destination must be different");
|
||||||
|
case Match_Immz:
|
||||||
|
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm_unreachable("Implement any new match types added!");
|
llvm_unreachable("Implement any new match types added!");
|
||||||
|
@ -381,6 +381,14 @@ include "MipsInstrFormats.td"
|
|||||||
// Mips Operand, Complex Patterns and Transformations Definitions.
|
// Mips Operand, Complex Patterns and Transformations Definitions.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def ConstantImmzAsmOperandClass : AsmOperandClass {
|
||||||
|
let Name = "ConstantImmz";
|
||||||
|
let RenderMethod = "addConstantUImmOperands<1>";
|
||||||
|
let PredicateMethod = "isConstantImmz";
|
||||||
|
let SuperClasses = [];
|
||||||
|
let DiagnosticType = "Immz";
|
||||||
|
}
|
||||||
|
|
||||||
def MipsJumpTargetAsmOperand : AsmOperandClass {
|
def MipsJumpTargetAsmOperand : AsmOperandClass {
|
||||||
let Name = "JumpTarget";
|
let Name = "JumpTarget";
|
||||||
let ParserMethod = "parseJumpTarget";
|
let ParserMethod = "parseJumpTarget";
|
||||||
@ -450,6 +458,7 @@ def simm16_64 : Operand<i64> {
|
|||||||
// Zero
|
// Zero
|
||||||
def uimmz : Operand<i32> {
|
def uimmz : Operand<i32> {
|
||||||
let PrintMethod = "printUnsignedImm";
|
let PrintMethod = "printUnsignedImm";
|
||||||
|
let ParserMatchClass = ConstantImmzAsmOperandClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsigned Operand
|
// Unsigned Operand
|
||||||
|
11
test/MC/Mips/msa/invalid-64.s
Normal file
11
test/MC/Mips/msa/invalid-64.s
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Instructions that are invalid
|
||||||
|
#
|
||||||
|
# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 -mattr=+msa \
|
||||||
|
# RUN: -show-encoding 2>%t1
|
||||||
|
# RUN: FileCheck %s < %t1
|
||||||
|
|
||||||
|
.set noat
|
||||||
|
insve.b $w25[3], $w9[1] # CHECK: :[[@LINE]]:26: error: expected '0'
|
||||||
|
insve.h $w24[2], $w2[1] # CHECK: :[[@LINE]]:26: error: expected '0'
|
||||||
|
insve.w $w0[2], $w13[1] # CHECK: :[[@LINE]]:26: error: expected '0'
|
||||||
|
insve.d $w3[0], $w18[1] # CHECK: :[[@LINE]]:26: error: expected '0'
|
11
test/MC/Mips/msa/invalid.s
Normal file
11
test/MC/Mips/msa/invalid.s
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Instructions that are invalid
|
||||||
|
#
|
||||||
|
# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 -mattr=+msa \
|
||||||
|
# RUN: -show-encoding 2>%t1
|
||||||
|
# RUN: FileCheck %s < %t1
|
||||||
|
|
||||||
|
.set noat
|
||||||
|
insve.b $w25[3], $w9[1] # CHECK: :[[@LINE]]:26: error: expected '0'
|
||||||
|
insve.h $w24[2], $w2[1] # CHECK: :[[@LINE]]:26: error: expected '0'
|
||||||
|
insve.w $w0[2], $w13[1] # CHECK: :[[@LINE]]:26: error: expected '0'
|
||||||
|
insve.d $w3[0], $w18[1] # CHECK: :[[@LINE]]:26: error: expected '0'
|
Loading…
x
Reference in New Issue
Block a user