Skip to content

Commit

Permalink
[mips][ias] Range check uimmz operands.
Browse files Browse the repository at this point in the history
Reviewers: vkalintiris

Subscribers: dsanders, atanasyan, llvm-commits

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

llvm-svn: 252294
  • Loading branch information
dsandersllvm committed Nov 6, 2015
1 parent b04672c commit 52da7af
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 2 deletions.
27 changes: 25 additions & 2 deletions llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Expand Up @@ -383,7 +383,7 @@ class MipsAsmParser : public MCTargetAsmParser {

public:
enum MipsMatchResultTy {
Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
#define GET_OPERAND_DIAGNOSTIC_TYPES
#include "MipsGenAsmMatcher.inc"
#undef GET_OPERAND_DIAGNOSTIC_TYPES
Expand Down Expand Up @@ -894,6 +894,13 @@ class MipsOperand : public MCParsedAsmOperand {
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 {
assert(N == 1 && "Invalid number of operands!");
const MCExpr *Expr = getImm();
Expand Down Expand Up @@ -953,6 +960,9 @@ class MipsOperand : public MCParsedAsmOperand {
bool isConstantImm() const {
return isImm() && dyn_cast<MCConstantExpr>(getImm());
}
bool isConstantImmz() const {
return isConstantImm() && getConstantImm() == 0;
}
template <unsigned Bits> bool isUImm() const {
return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
}
Expand Down Expand Up @@ -3234,6 +3244,17 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
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,
OperandVector &Operands,
MCStreamer &Out,
Expand Down Expand Up @@ -3262,7 +3283,7 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
if (ErrorInfo >= Operands.size())
return Error(IDLoc, "too few operands for instruction");

ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
ErrorLoc = Operands[ErrorInfo]->getStartLoc();
if (ErrorLoc == SMLoc())
ErrorLoc = IDLoc;
}
Expand All @@ -3273,6 +3294,8 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return Error(IDLoc, "invalid instruction");
case Match_RequiresDifferentSrcAndDst:
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!");
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/Mips/MipsInstrInfo.td
Expand Up @@ -381,6 +381,14 @@ include "MipsInstrFormats.td"
// 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 {
let Name = "JumpTarget";
let ParserMethod = "parseJumpTarget";
Expand Down Expand Up @@ -450,6 +458,7 @@ def simm16_64 : Operand<i64> {
// Zero
def uimmz : Operand<i32> {
let PrintMethod = "printUnsignedImm";
let ParserMatchClass = ConstantImmzAsmOperandClass;
}

// Unsigned Operand
Expand Down
11 changes: 11 additions & 0 deletions llvm/test/MC/Mips/msa/invalid-64.s
@@ -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 changes: 11 additions & 0 deletions llvm/test/MC/Mips/msa/invalid.s
@@ -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'

0 comments on commit 52da7af

Please sign in to comment.