summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@sifive.com>2023-05-17 10:31:39 -0700
committerCraig Topper <craig.topper@sifive.com>2023-05-17 10:31:39 -0700
commitfd6cd1a249136e93e73cc09c3408871255c5ae72 (patch)
treef521c283ee8bf81df59c64a0ed540dfec0353a2c
parent30c57e275e5aea5ec4c021f1a53687c3ae97b6f9 (diff)
downloadllvm-fd6cd1a249136e93e73cc09c3408871255c5ae72.tar.gz
[RISCV] Refactor parseVTypeI and use ParseFail if we parsed more than one identifier.
Previously we lexed into a SmallVector and unlexed the tokens if the parsing failed. This patch gets rid of the SmallVector and the unlexing. If the first token fails to parse, return MatchFail. This allows us to fallback to parsing as an immediate. If we successfully parsed the first token, use ParseFail if any later tokens fail to parse. This avoids needing to UnLex the tokens. I've used a state machine to keep track of what component we've parsed so far. Reviewed By: asb Differential Revision: https://reviews.llvm.org/D150753
-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]