summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp169
-rw-r--r--llvm/test/MC/RISCV/rvv/invalid.s4
2 files changed, 109 insertions, 64 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 4c1bd2a6e6ff..31d5e134b10a 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -64,6 +64,18 @@ struct ParserOptionsSet {
};
class RISCVAsmParser : public MCTargetAsmParser {
+ // This tracks the parsing of the 4 operands that make up the vtype portion
+ // of vset(i)vli instructions which are separated by commas. The state names
+ // represent the next expected operand with Done meaning no other operands are
+ // expected.
+ enum VTypeState {
+ VTypeState_SEW,
+ VTypeState_LMUL,
+ VTypeState_TailPolicy,
+ VTypeState_MaskPolicy,
+ VTypeState_Done,
+ };
+
SmallVector<FeatureBitset, 4> FeatureBitStack;
SmallVector<ParserOptionsSet, 4> ParserOptionsStack;
@@ -105,6 +117,11 @@ class RISCVAsmParser : public MCTargetAsmParser {
bool ParseDirective(AsmToken DirectiveID) override;
+ bool parseVTypeToken(StringRef Identifier, VTypeState &State, unsigned &Sew,
+ unsigned &Lmul, bool &Fractional, bool &TailAgnostic,
+ bool &MaskAgnostic);
+ bool generateVTypeError(SMLoc ErrorLoc);
+
// Helper to actually emit an instruction to the MCStreamer. Also, when
// possible, compression of the instruction is performed.
void emitToStreamer(MCStreamer &S, const MCInst &Inst);
@@ -1471,10 +1488,7 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
}
case Match_InvalidVTypeI: {
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
- return Error(
- ErrorLoc,
- "operand must be "
- "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
+ return generateVTypeError(ErrorLoc);
}
case Match_InvalidVMaskRegister: {
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
@@ -2037,69 +2051,96 @@ OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
return parseImmediate(Operands);
}
-OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
- SMLoc S = getLoc();
-
- SmallVector<AsmToken, 7> VTypeIElements;
- // Put all the tokens for vtypei operand into VTypeIElements vector.
- while (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Identifier))
- goto MatchFail;
- VTypeIElements.push_back(getLexer().getTok());
- getLexer().Lex();
- if (getLexer().is(AsmToken::EndOfStatement))
+bool RISCVAsmParser::parseVTypeToken(StringRef Identifier, VTypeState &State,
+ unsigned &Sew, unsigned &Lmul,
+ bool &Fractional, bool &TailAgnostic,
+ bool &MaskAgnostic) {
+ switch (State) {
+ case VTypeState_SEW:
+ if (!Identifier.consume_front("e"))
+ break;
+ if (Identifier.getAsInteger(10, Sew))
break;
- if (getLexer().isNot(AsmToken::Comma))
- goto MatchFail;
- AsmToken Comma = getLexer().getTok();
- VTypeIElements.push_back(Comma);
- getLexer().Lex();
- }
-
- if (VTypeIElements.size() == 7) {
- // The VTypeIElements layout is:
- // SEW comma LMUL comma TA comma MA
- // 0 1 2 3 4 5 6
- StringRef Name = VTypeIElements[0].getIdentifier();
- if (!Name.consume_front("e"))
- goto MatchFail;
- unsigned Sew;
- if (Name.getAsInteger(10, Sew))
- goto MatchFail;
if (!RISCVVType::isValidSEW(Sew))
- goto MatchFail;
-
- Name = VTypeIElements[2].getIdentifier();
- if (!Name.consume_front("m"))
- goto MatchFail;
- // "m" or "mf"
- bool Fractional = Name.consume_front("f");
- unsigned Lmul;
- if (Name.getAsInteger(10, Lmul))
- goto MatchFail;
+ break;
+ State = VTypeState_LMUL;
+ return false;
+ case VTypeState_LMUL: {
+ if (!Identifier.consume_front("m"))
+ break;
+ Fractional = Identifier.consume_front("f");
+ if (Identifier.getAsInteger(10, Lmul))
+ break;
if (!RISCVVType::isValidLMUL(Lmul, Fractional))
- goto MatchFail;
-
- // ta or tu
- Name = VTypeIElements[4].getIdentifier();
- bool TailAgnostic;
- if (Name == "ta")
+ break;
+ State = VTypeState_TailPolicy;
+ return false;
+ }
+ case VTypeState_TailPolicy:
+ if (Identifier == "ta")
TailAgnostic = true;
- else if (Name == "tu")
+ else if (Identifier == "tu")
TailAgnostic = false;
else
- goto MatchFail;
-
- // ma or mu
- Name = VTypeIElements[6].getIdentifier();
- bool MaskAgnostic;
- if (Name == "ma")
+ break;
+ State = VTypeState_MaskPolicy;
+ return false;
+ case VTypeState_MaskPolicy:
+ if (Identifier == "ma")
MaskAgnostic = true;
- else if (Name == "mu")
+ else if (Identifier == "mu")
MaskAgnostic = false;
else
- goto MatchFail;
+ break;
+ State = VTypeState_Done;
+ return false;
+ case VTypeState_Done:
+ // Extra token?
+ break;
+ }
+ return true;
+}
+
+OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
+ SMLoc S = getLoc();
+
+ unsigned Sew = 0;
+ unsigned Lmul = 0;
+ bool Fractional = false;
+ bool TailAgnostic = false;
+ bool MaskAgnostic = false;
+
+ VTypeState State = VTypeState_SEW;
+
+ if (getLexer().isNot(AsmToken::Identifier))
+ return MatchOperand_NoMatch;
+
+ StringRef Identifier = getTok().getIdentifier();
+
+ if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
+ MaskAgnostic))
+ return MatchOperand_NoMatch;
+
+ getLexer().Lex();
+
+ while (getLexer().is(AsmToken::Comma)) {
+ // Consume comma.
+ getLexer().Lex();
+
+ if (getLexer().isNot(AsmToken::Identifier))
+ break;
+
+ Identifier = getTok().getIdentifier();
+
+ if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
+ MaskAgnostic))
+ break;
+
+ getLexer().Lex();
+ }
+
+ if (getLexer().is(AsmToken::EndOfStatement) && State == VTypeState_Done) {
RISCVII::VLMUL VLMUL = RISCVVType::encodeLMUL(Lmul, Fractional);
unsigned VTypeI =
@@ -2108,11 +2149,15 @@ OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
return MatchOperand_Success;
}
-// If NoMatch, unlex all the tokens that comprise a vtypei operand
-MatchFail:
- while (!VTypeIElements.empty())
- getLexer().UnLex(VTypeIElements.pop_back_val());
- return MatchOperand_NoMatch;
+ generateVTypeError(S);
+ return MatchOperand_ParseFail;
+}
+
+bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
+ return Error(
+ ErrorLoc,
+ "operand must be "
+ "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
}
OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
diff --git a/llvm/test/MC/RISCV/rvv/invalid.s b/llvm/test/MC/RISCV/rvv/invalid.s
index 16f64cf46fd5..09fd2c3bebf0 100644
--- a/llvm/test/MC/RISCV/rvv/invalid.s
+++ b/llvm/test/MC/RISCV/rvv/invalid.s
@@ -2,10 +2,10 @@
# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
vsetivli a2, 32, e8,m1
-# CHECK-ERROR: immediate must be an integer in the range [0, 31]
+# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
vsetivli a2, zero, e8,m1
-# CHECK-ERROR: immediate must be an integer in the range [0, 31]
+# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
vsetivli a2, 5, (1 << 10)
# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]