diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -64,6 +64,14 @@ }; class RISCVAsmParser : public MCTargetAsmParser { + enum VTypeState { + VTypeState_SEW, + VTypeState_LMUL, + VTypeState_TailPolicy, + VTypeState_MaskPolicy, + VTypeState_Done, + }; + SmallVector FeatureBitStack; SmallVector ParserOptionsStack; @@ -105,6 +113,11 @@ 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); @@ -1466,10 +1479,7 @@ } 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(); @@ -2032,69 +2042,94 @@ return parseImmediate(Operands); } -OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) { - SMLoc S = getLoc(); - - SmallVector 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)) - 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; +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")) + return true; + if (Identifier.getAsInteger(10, Sew)) + return true; 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; + return true; + State = VTypeState_LMUL; + return false; + case VTypeState_LMUL: { + if (!Identifier.consume_front("m")) + return true; + Fractional = Identifier.consume_front("f"); + if (Identifier.getAsInteger(10, Lmul)) + return true; if (!RISCVVType::isValidLMUL(Lmul, Fractional)) - goto MatchFail; - - // ta or tu - Name = VTypeIElements[4].getIdentifier(); - bool TailAgnostic; - if (Name == "ta") + return true; + 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") + return true; + 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; + return true; + State = VTypeState_Done; + return false; + case VTypeState_Done: + // Extra token? + 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 = @@ -2103,11 +2138,15 @@ 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 --- 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]