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 @@ -1520,80 +1520,84 @@ OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) { SMLoc S = getLoc(); - if (getLexer().getKind() != AsmToken::Identifier) - return MatchOperand_NoMatch; - - // Parse "e8,m1,t[a|u],m[a|u]" - StringRef Name = getLexer().getTok().getIdentifier(); - if (!Name.consume_front("e")) - return MatchOperand_NoMatch; - unsigned Sew; - if (Name.getAsInteger(10, Sew)) - return MatchOperand_NoMatch; - if (!RISCVVType::isValidSEW(Sew)) - return MatchOperand_NoMatch; - getLexer().Lex(); - - if (!getLexer().is(AsmToken::Comma)) - return MatchOperand_NoMatch; - getLexer().Lex(); - - Name = getLexer().getTok().getIdentifier(); - if (!Name.consume_front("m")) - return MatchOperand_NoMatch; - // "m" or "mf" - bool Fractional = Name.consume_front("f"); - unsigned Lmul; - if (Name.getAsInteger(10, Lmul)) - return MatchOperand_NoMatch; - if (!RISCVVType::isValidLMUL(Lmul, Fractional)) - return MatchOperand_NoMatch; - getLexer().Lex(); - - if (!getLexer().is(AsmToken::Comma)) - return MatchOperand_NoMatch; - getLexer().Lex(); - - Name = getLexer().getTok().getIdentifier(); - // ta or tu - bool TailAgnostic; - if (Name == "ta") - TailAgnostic = true; - else if (Name == "tu") - TailAgnostic = false; - else + if (getLexer().isNot(AsmToken::Identifier)) return MatchOperand_NoMatch; - getLexer().Lex(); - if (!getLexer().is(AsmToken::Comma)) - return MatchOperand_NoMatch; - getLexer().Lex(); - - Name = getLexer().getTok().getIdentifier(); - // ma or mu - bool MaskAgnostic; - if (Name == "ma") - MaskAgnostic = true; - else if (Name == "mu") - MaskAgnostic = false; - else - return MatchOperand_NoMatch; - getLexer().Lex(); + SmallVector VTypeIElements; + // Put all the tokens for vtypei operand into VTypeIElements vector. + while (getLexer().isNot(AsmToken::EndOfStatement)) { + 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 (getLexer().getKind() != AsmToken::EndOfStatement) - return MatchOperand_NoMatch; + 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; + if (!RISCVVType::isValidLMUL(Lmul, Fractional)) + goto MatchFail; + + // ta or tu + Name = VTypeIElements[4].getIdentifier(); + bool TailAgnostic; + if (Name == "ta") + TailAgnostic = true; + else if (Name == "tu") + TailAgnostic = false; + else + goto MatchFail; + + // ma or mu + Name = VTypeIElements[6].getIdentifier(); + bool MaskAgnostic; + if (Name == "ma") + MaskAgnostic = true; + else if (Name == "mu") + MaskAgnostic = false; + else + goto MatchFail; - unsigned SewLog2 = Log2_32(Sew / 8); - unsigned LmulLog2 = Log2_32(Lmul); - RISCVVSEW VSEW = static_cast(SewLog2); - RISCVVLMUL VLMUL = - static_cast(Fractional ? 8 - LmulLog2 : LmulLog2); + unsigned SewLog2 = Log2_32(Sew / 8); + unsigned LmulLog2 = Log2_32(Lmul); + RISCVVSEW VSEW = static_cast(SewLog2); + RISCVVLMUL VLMUL = + static_cast(Fractional ? 8 - LmulLog2 : LmulLog2); - unsigned VTypeI = - RISCVVType::encodeVTYPE(VLMUL, VSEW, TailAgnostic, MaskAgnostic); - Operands.push_back(RISCVOperand::createVType(VTypeI, S, isRV64())); + unsigned VTypeI = + RISCVVType::encodeVTYPE(VLMUL, VSEW, TailAgnostic, MaskAgnostic); + Operands.push_back(RISCVOperand::createVType(VTypeI, S, isRV64())); + return MatchOperand_Success; + } - 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; } 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: unknown operand +# CHECK-ERROR: immediate must be an integer in the range [0, 31] vsetivli a2, zero, e8,m1 -# CHECK-ERROR: unknown operand +# CHECK-ERROR: immediate must be an integer in the range [0, 31] vsetivli a2, 5, e31 # 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] @@ -55,6 +55,15 @@ vsetvli a2, a0, e8,m1,tut,mu # 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] +vsetvli a2, a0, e8 +# 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] + +vsetvli a2, a0, e8,m1 +# 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] + +vsetvli a2, a0, e8,m1,ta +# 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] + vadd.vv v1, v3, v2, v4.t # CHECK-ERROR: operand must be v0.t