abel-bernabeu updated this revision to Diff 532837. abel-bernabeu added a comment.
I just this flashback... For code coverage of one of the Lex() calls in ParseInstruction we needed one case where an instruction has no operands. We had, not one, but three. Am keeping just the "nop" case, which is the simplest and most known instruction and moving it to the top of the test suite, so the tests are listed in increasing complexity (from the simplest to reach test points to the most sophisticated and least frequently used parser features). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D153008/new/ https://reviews.llvm.org/D153008 Files: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp llvm/test/MC/RISCV/comments-zdinx.ll llvm/test/MC/RISCV/comments.ll
Index: llvm/test/MC/RISCV/comments.ll =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/comments.ll @@ -0,0 +1,61 @@ +# RUN: llvm-mc -triple=riscv64 --preserve-comments \ +# RUN: --mattr=+v,+experimental-zfa,+experimental-zcmp,+experimental-ztso %s \ +# RUN: | FileCheck %s --match-full-lines + +/*c0*/ nop /*c1*/ +# CHECK: nop #c0 #c1 + +/*c0*/ li /*c1*/ a0 /*c2*/ , /*c3*/ 0 /*c4*/ +# CHECK: li a0, 0 #c0 #c1 #c2 #c3 #c4 + +/*c0*/ lw /*c1*/ a0 /*c2*/ , /*c3*/ 0 /*c4*/ ( /*c5*/ a1 /*c6*/ ) /*c7*/ +# CHECK: lw a0, 0(a1) #c0 #c1 #c2 #c3 #c4 #c5 #c6 #c7 + +/*c0*/ lw /*c1*/ a0 /*c2*/ , /*c3*/ ( /*c4*/ a1 /*c5*/ ) /*c6*/ +# CHECK: lw a0, 0(a1) #c0 #c1 #c2 #c3 #c4 #c5 #c6 + +/*c0*/ fli.s /*c1*/ ft0 /*c2*/ , /*c3*/ nan /*c4*/ +# CHECK: fli.s ft0, nan #c0 #c1 #c2 #c3 #c4 + +/*c0*/ fli.s /*c1*/ ft0 /*c2*/ , /*c3*/ 1.0 /*c4*/ +# CHECK: fli.s ft0, 1.0 #c0 #c1 #c2 #c3 #c4 + +/*c0*/ auipc /*c1*/ a0 /*c2*/ , /*c3*/ %pcrel_hi /*c4*/ ( /*c5*/ a1 /*c6*/ ) /*c7*/ +# CHECK: auipc a0, %pcrel_hi(a1) #c0 #c1 #c2 #c3 #c4 #c5 #c6 #c7 + +/*c0*/ la /*c1*/ s0 /*c2*/ , /*c3*/ symbol /*c4*/ + /*c5*/ 10 /*c6*/ +# CHECK: .Lpcrel_hi0: #c0 #c1 #c2 #c3 #c4 #c5 #c6 +# CHECK-NEXT: auipc s0, %pcrel_hi(symbol+10) +# CHECK-NEXT: addi s0, s0, %pcrel_lo(.Lpcrel_hi0) + +/*c0*/ la /*c1*/ s0 /*c2*/ , /*c3*/ symbol /*c4*/ - /*c5*/ 10 /*c6*/ +# CHECK: .Lpcrel_hi1: #c0 #c1 #c2 #c3 #c4 #c5 #c6 +# CHECK-NEXT: auipc s0, %pcrel_hi(symbol-10) +# CHECK-NEXT: addi s0, s0, %pcrel_lo(.Lpcrel_hi1) + +/*c0*/ vsetivli /*c1*/ a2 /*c2*/ , /*c3*/ 31 /*c4*/ , /*c5*/ e32 /*c6*/ , /*c7*/ m1 /*c8*/ , /*c9*/ ta /*c10*/ , /*c11*/ ma /*c12*/ +# CHECK: vsetivli a2, 31, e32, m1, ta, ma #c0 #c1 #c2 #c3 #c4 #c5 #c6 #c7 #c8 #c9 #c10 #c11 #c12 + +/*c0*/ vadd.vv /*c1*/ v1 /*c2*/ , /*c3*/ v2 /*c4*/ , /*c5*/ v3 /*c6*/ , /*c7*/ v0.t /*c8*/ +# CHECK: vadd.vv v1, v2, v3, v0.t #c0 #c1 #c2 #c3 #c4 #c5 #c6 #c7 #c8 + +/*c0*/ cm.push /*c1*/ { /*c2*/ ra /*c3*/ , /*c4*/ s0 /*c5*/ - /*c6*/ s1 /*c7*/ } /*c8*/ , /*c9*/ - /*c10*/ 32 /*c11*/ +# CHECK: cm.push {ra, s0-s1}, -32 #c0 #c1 #c2 #c3 #c4 #c5 #c6 #c7 #c8 #c9 #c10 #c11 + +/*c0*/ cm.popret /*c0*/ { /*c1*/ x1 /*c2*/ , /*c3*/ x8 /*c4*/ - /*c5*/ x9 /*c6*/ , /*c7*/ x18 /*c8*/ - /*c9*/ x20 /*c10*/ } /*c11*/ , /*c12*/ 64 /*c13*/ +# CHECK: cm.popret {ra, s0-s4}, 64 #c0 #c0 #c1 #c2 #c3 #c4 #c5 #c6 #c7 #c8 #c9 #c10 #c11 #c12 #c13 + +/*c0*/ fence /*c1*/ 0 /*c2*/ , /*c3*/ 0 /*c4*/ +# CHECK: fence 0, 0 #c0 #c1 #c2 #c3 #c4 + +/*c0*/ fence /*c1*/ iorw /*c2*/ , /*c3*/ iorw /*c4*/ +# CHECK: fence #c0 #c1 #c2 #c3 #c4 + +/*c0*/ .option /*c1*/ arch /*c2*/ , /*c3*/ rv64gc /*c4*/ +# CHECK: .option arch, rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0 + +/*c0*/ .attribute /*c1*/ priv_spec /*c2*/ , /*c3*/ 2 /*c4*/ +# CHECK: .attribute 8, 2 + +/*c0*/ .attribute /*c1*/ arch /*c2*/ , /*c3*/ "rv32i_zvfbfmin0p6" /*c4*/ +# CHECK: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfmin0p6_zvl32b1p0" Index: llvm/test/MC/RISCV/comments-zdinx.ll =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/comments-zdinx.ll @@ -0,0 +1,4 @@ +# RUN: llvm-mc -triple=riscv64 --preserve-comments --mattr=+zdinx %s | FileCheck %s --match-full-lines + +/*c0*/ fmadd.d /*c1*/ x10 /*c2*/ , /*c3*/ x12 /*c4*/ , /*c5*/ x14 /*c6*/ , /*c7*/ x16 /*c8*/ , /*c9*/ dyn /*c10*/ +# CHECK: fmadd.d a0, a2, a4, a6 #c0 #c1 #c2 #c3 #c4 #c5 #c6 #c7 #c8 #c9 #c10 Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -107,6 +107,8 @@ uint64_t &ErrorInfo, bool MatchingInlineAsm) override; + AsmToken peekNextNext(); + bool parseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; OperandMatchResultTy tryParseRegister(MCRegister &RegNo, SMLoc &StartLoc, @@ -1577,10 +1579,38 @@ if (!RegNo) return MatchOperand_NoMatch; - getParser().Lex(); // Eat identifier token. + Lex(); // Eat identifier token. return MatchOperand_Success; } +/** +\brief Peeks next after next token + +This function looks ahead for the next after the next token, discarding +comments in the process. Proper handling of the discarded comments will +happen on the next Lex() call. +*/ +AsmToken RISCVAsmParser::peekNextNext() { + AsmToken NextNextToken; + size_t NonComments = 0; + size_t ReadCount; + do { + SmallVector<AsmToken> Buf(10); + ReadCount = getLexer().peekTokens(Buf); + for (size_t index = 0; index < ReadCount; ++index) { + AsmToken token = Buf[index]; + if (token.getKind() != AsmToken::Comment) { + NonComments++; + if (NonComments == 2) { + NextNextToken = token; + break; + } + } + } + } while (NonComments < 2 and ReadCount > 0); + return NextNextToken; +} + OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, bool AllowParens) { SMLoc FirstS = getLoc(); @@ -1590,12 +1620,11 @@ // If this is an LParen and a parenthesised register name is allowed, parse it // atomically. if (AllowParens && getLexer().is(AsmToken::LParen)) { - AsmToken Buf[2]; - size_t ReadCount = getLexer().peekTokens(Buf); - if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { + AsmToken NextNextToken = peekNextNext(); + if (NextNextToken.getKind() == AsmToken::RParen) { HadParens = true; LParen = getParser().getTok(); - getParser().Lex(); // Eat '(' + Lex(); // Eat '(' } } @@ -1617,12 +1646,12 @@ Operands.push_back(RISCVOperand::createToken("(", FirstS)); SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); - getLexer().Lex(); + Lex(); Operands.push_back(RISCVOperand::createReg(RegNo, S, E)); } if (HadParens) { - getParser().Lex(); // Eat ')' + Lex(); // Eat ')' Operands.push_back(RISCVOperand::createToken(")", getLoc())); } @@ -1925,7 +1954,7 @@ return MatchOperand_ParseFail; } - getParser().Lex(); // Eat the identifier + Lex(); // Eat the identifier if (parseToken(AsmToken::LParen, "expected '('")) return MatchOperand_ParseFail; @@ -1978,11 +2007,11 @@ return MatchOperand_Success; case AsmToken::Plus: Opcode = MCBinaryExpr::Add; - getLexer().Lex(); + Lex(); break; case AsmToken::Minus: Opcode = MCBinaryExpr::Sub; - getLexer().Lex(); + Lex(); break; } @@ -2131,7 +2160,7 @@ MaskAgnostic)) return MatchOperand_NoMatch; - getLexer().Lex(); + Lex(); while (parseOptionalToken(AsmToken::Comma)) { if (getLexer().isNot(AsmToken::Identifier)) @@ -2143,7 +2172,7 @@ MaskAgnostic)) break; - getLexer().Lex(); + Lex(); } if (getLexer().is(AsmToken::EndOfStatement) && State == VTypeState_Done) { @@ -2183,7 +2212,7 @@ return MatchOperand_NoMatch; SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); - getLexer().Lex(); + Lex(); Operands.push_back(RISCVOperand::createReg(RegNo, S, E)); return MatchOperand_Success; } @@ -2199,7 +2228,7 @@ return MatchOperand_NoMatch; SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); - getLexer().Lex(); + Lex(); Operands.push_back(RISCVOperand::createReg( RegNo, S, E, !getSTI().hasFeature(RISCV::FeatureStdExtF))); return MatchOperand_Success; @@ -2388,7 +2417,7 @@ Error(getLoc(), "register list must start from 'ra' or 'x1'"); return MatchOperand_ParseFail; } - getLexer().Lex(); + Lex(); // parse case like ,s0 if (parseOptionalToken(AsmToken::Comma)) { @@ -2406,7 +2435,7 @@ Error(getLoc(), "continuous register list must start from 's0' or 'x8'"); return MatchOperand_ParseFail; } - getLexer().Lex(); // eat reg + Lex(); // eat reg } // parse case like -s1 @@ -2423,7 +2452,7 @@ "'x8-x9' pair"); return MatchOperand_ParseFail; } - getLexer().Lex(); + Lex(); } if (!IsEABI) { @@ -2447,7 +2476,7 @@ "must start from 'x18'"); return MatchOperand_ParseFail; } - getLexer().Lex(); + Lex(); // parse '-x20' for extra part if (parseOptionalToken(AsmToken::Minus)) { @@ -2460,7 +2489,7 @@ Error(getLoc(), "invalid register"); return MatchOperand_ParseFail; } - getLexer().Lex(); + Lex(); } RegEnd = MatchRegisterName(EndName); } @@ -2500,7 +2529,7 @@ if (!RISCVZC::getSpimm(RlistVal, Spimm, StackAdjustment, isRV64(), IsEABI)) return MatchOperand_NoMatch; Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S)); - getLexer().Lex(); + Lex(); return MatchOperand_Success; } @@ -2557,7 +2586,7 @@ // If there are no more operands, then finish if (getLexer().is(AsmToken::EndOfStatement)) { - getParser().Lex(); // Consume the EndOfStatement. + Lex(); // Consume the EndOfStatement. return false; } @@ -2722,7 +2751,7 @@ StringRef Arch = Parser.getTok().getString(); SMLoc Loc = Parser.getTok().getLoc(); - Parser.Lex(); + Lex(); if (Type == RISCVOptionArchArgType::Full) { std::string Result; @@ -2868,7 +2897,7 @@ return false; } Tag = *Ret; - Parser.Lex(); + Lex(); } else { const MCExpr *AttrExpr; @@ -2910,7 +2939,7 @@ return Error(Parser.getTok().getLoc(), "expected string constant"); StringValue = Parser.getTok().getStringContents(); - Parser.Lex(); + Lex(); } if (Parser.parseEOL())
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits