diff options
author | Koakuma <koachan@protonmail.com> | 2024-06-27 19:45:53 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-27 19:45:53 +0700 |
commit | e9b8cd0c806db00f0981fb36717077c941426302 (patch) | |
tree | f3b92a07f3dfc6e70f36d1000605f36a3c15af46 | |
parent | 468d668c5c4031366ae38804927b450f9faf409c (diff) | |
download | llvm-e9b8cd0c806db00f0981fb36717077c941426302.zip llvm-e9b8cd0c806db00f0981fb36717077c941426302.tar.gz llvm-e9b8cd0c806db00f0981fb36717077c941426302.tar.bz2 |
[SPARC][IAS] Rework ASI/Prefetch tag matching in prep for `ParseForAllFeatures`
Unify parts of ASI and Prefetch tag matching at `parseASITag`
and `parsePrefetchTag` to use a common function to parse any immediate
expressions. This introduces a slight regression to error messages,
but is needed so we can enable `ParseForAllFeatures`
in `MatchOperandParserImpl` in a future patch.
Reviewers: jrtc27, brad0, rorth, s-barannikov
Reviewed By: s-barannikov
Pull Request: https://github.com/llvm/llvm-project/pull/96020
-rw-r--r-- | llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp | 126 | ||||
-rw-r--r-- | llvm/test/MC/Sparc/sparc-mem-asi-instructions.s | 4 | ||||
-rw-r--r-- | llvm/test/MC/Sparc/sparcv9-instructions.s | 4 |
3 files changed, 83 insertions, 51 deletions
diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index f0a3a4e..af634a7 100644 --- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -107,10 +107,15 @@ class SparcAsmParser : public MCTargetAsmParser { ParseStatus parseBranchModifiers(OperandVector &Operands); + ParseStatus parseExpression(int64_t &Val); + // Helper function for dealing with %lo / %hi in PIC mode. const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK, const MCExpr *subExpr); + // Helper function to see if current token can start an expression. + bool isPossibleExpression(const AsmToken &Token); + // returns true if Tok is matched to a register and returns register in RegNo. MCRegister matchRegisterName(const AsmToken &Tok, unsigned &RegKind); @@ -1085,32 +1090,35 @@ ParseStatus SparcAsmParser::parseASITag(OperandVector &Operands) { SMLoc E = Parser.getTok().getEndLoc(); int64_t ASIVal = 0; - if (is64Bit() && (getLexer().getKind() == AsmToken::Hash)) { - // For now we only support named tags for 64-bit/V9 systems. - // TODO: add support for 32-bit/V8 systems. - SMLoc TagStart = getLexer().peekTok(false).getLoc(); - Parser.Lex(); // Eat the '#'. - auto ASIName = Parser.getTok().getString(); - auto ASITag = SparcASITag::lookupASITagByName(ASIName); - if (!ASITag) - ASITag = SparcASITag::lookupASITagByAltName(ASIName); - Parser.Lex(); // Eat the identifier token. + if (getLexer().getKind() != AsmToken::Hash) { + // If the ASI tag provided is not a named tag, then it + // must be a constant expression. + ParseStatus ParseExprStatus = parseExpression(ASIVal); + if (!ParseExprStatus.isSuccess()) + return ParseExprStatus; - if (!ASITag) - return Error(TagStart, "unknown ASI tag"); - - ASIVal = ASITag->Encoding; - } else if (!getParser().parseAbsoluteExpression(ASIVal)) { if (!isUInt<8>(ASIVal)) return Error(S, "invalid ASI number, must be between 0 and 255"); - } else { - return Error( - S, is64Bit() - ? "malformed ASI tag, must be %asi, a constant integer " - "expression, or a named tag" - : "malformed ASI tag, must be a constant integer expression"); + + Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E)); + return ParseStatus::Success; } + // For now we only support named tags for 64-bit/V9 systems. + // TODO: add support for 32-bit/V8 systems. + SMLoc TagStart = getLexer().peekTok(false).getLoc(); + Parser.Lex(); // Eat the '#'. + const StringRef ASIName = Parser.getTok().getString(); + const SparcASITag::ASITag *ASITag = SparcASITag::lookupASITagByName(ASIName); + if (!ASITag) + ASITag = SparcASITag::lookupASITagByAltName(ASIName); + Parser.Lex(); // Eat the identifier token. + + if (!ASITag) + return Error(TagStart, "unknown ASI tag"); + + ASIVal = ASITag->Encoding; + Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E)); return ParseStatus::Success; } @@ -1120,35 +1128,32 @@ ParseStatus SparcAsmParser::parsePrefetchTag(OperandVector &Operands) { SMLoc E = Parser.getTok().getEndLoc(); int64_t PrefetchVal = 0; - switch (getLexer().getKind()) { - case AsmToken::LParen: - case AsmToken::Integer: - case AsmToken::Identifier: - case AsmToken::Plus: - case AsmToken::Minus: - case AsmToken::Tilde: - if (getParser().parseAbsoluteExpression(PrefetchVal) || - !isUInt<5>(PrefetchVal)) - return Error(S, "invalid prefetch number, must be between 0 and 31"); - break; - case AsmToken::Hash: { - SMLoc TagStart = getLexer().peekTok(false).getLoc(); - Parser.Lex(); // Eat the '#'. - const StringRef PrefetchName = Parser.getTok().getString(); - const SparcPrefetchTag::PrefetchTag *PrefetchTag = - SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName); - Parser.Lex(); // Eat the identifier token. + if (getLexer().getKind() != AsmToken::Hash) { + // If the prefetch tag provided is not a named tag, then it + // must be a constant expression. + ParseStatus ParseExprStatus = parseExpression(PrefetchVal); + if (!ParseExprStatus.isSuccess()) + return ParseExprStatus; - if (!PrefetchTag) - return Error(TagStart, "unknown prefetch tag"); + if (!isUInt<8>(PrefetchVal)) + return Error(S, "invalid prefetch number, must be between 0 and 31"); - PrefetchVal = PrefetchTag->Encoding; - break; - } - default: - return ParseStatus::NoMatch; + Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E)); + return ParseStatus::Success; } + SMLoc TagStart = getLexer().peekTok(false).getLoc(); + Parser.Lex(); // Eat the '#'. + const StringRef PrefetchName = Parser.getTok().getString(); + const SparcPrefetchTag::PrefetchTag *PrefetchTag = + SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName); + Parser.Lex(); // Eat the identifier token. + + if (!PrefetchTag) + return Error(TagStart, "unknown prefetch tag"); + + PrefetchVal = PrefetchTag->Encoding; + Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E)); return ParseStatus::Success; } @@ -1230,8 +1235,12 @@ ParseStatus SparcAsmParser::parseOperand(OperandVector &Operands, // Parse an optional address-space identifier after the address. // This will be either an immediate constant expression, or, on 64-bit // processors, the %asi register. - if (is64Bit() && getLexer().is(AsmToken::Percent)) { + if (getLexer().is(AsmToken::Percent)) { SMLoc S = Parser.getTok().getLoc(); + if (!is64Bit()) + return Error( + S, "malformed ASI tag, must be a constant integer expression"); + Parser.Lex(); // Eat the %. const AsmToken Tok = Parser.getTok(); if (Tok.is(AsmToken::Identifier) && Tok.getString() == "asi") { @@ -1360,6 +1369,15 @@ ParseStatus SparcAsmParser::parseBranchModifiers(OperandVector &Operands) { return ParseStatus::Success; } +ParseStatus SparcAsmParser::parseExpression(int64_t &Val) { + AsmToken Tok = getLexer().getTok(); + + if (!isPossibleExpression(Tok)) + return ParseStatus::NoMatch; + + return getParser().parseAbsoluteExpression(Val); +} + #define GET_REGISTER_MATCHER #include "SparcGenAsmMatcher.inc" @@ -1590,6 +1608,20 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal, return true; } +bool SparcAsmParser::isPossibleExpression(const AsmToken &Token) { + switch (Token.getKind()) { + case AsmToken::LParen: + case AsmToken::Integer: + case AsmToken::Identifier: + case AsmToken::Plus: + case AsmToken::Minus: + case AsmToken::Tilde: + return true; + default: + return false; + } +} + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser() { RegisterMCAsmParser<SparcAsmParser> A(getTheSparcTarget()); RegisterMCAsmParser<SparcAsmParser> B(getTheSparcV9Target()); diff --git a/llvm/test/MC/Sparc/sparc-mem-asi-instructions.s b/llvm/test/MC/Sparc/sparc-mem-asi-instructions.s index 39abe7b..8b8503c 100644 --- a/llvm/test/MC/Sparc/sparc-mem-asi-instructions.s +++ b/llvm/test/MC/Sparc/sparc-mem-asi-instructions.s @@ -1,9 +1,9 @@ ! RUN: not llvm-mc %s -triple=sparc -show-encoding 2>&1 | FileCheck %s --check-prefix=V8 ! RUN: not llvm-mc %s -triple=sparcv9 -show-encoding 2>&1 | FileCheck %s --check-prefix=V9 -! V8: error: malformed ASI tag, must be a constant integer expression +! V8: error: expected absolute expression ! V8-NEXT: lduba [%i0] asi, %o2 -! V9: error: malformed ASI tag, must be %asi, a constant integer expression, or a named tag +! V9: error: unexpected token ! V9-NEXT: lduba [%i0] asi, %o2 lduba [%i0] asi, %o2 diff --git a/llvm/test/MC/Sparc/sparcv9-instructions.s b/llvm/test/MC/Sparc/sparcv9-instructions.s index 1b11171..a7761c1 100644 --- a/llvm/test/MC/Sparc/sparcv9-instructions.s +++ b/llvm/test/MC/Sparc/sparcv9-instructions.s @@ -657,12 +657,12 @@ ! V9: prefetcha [%i1+3968] %asi, #one_read ! encoding: [0xc3,0xee,0x6f,0x80] prefetcha [ %i1 + 0xf80 ] %asi, #one_read - ! V8: error: malformed ASI tag, must be a constant integer expression + ! V8: error: invalid operand for instruction ! V8-NEXT: prefetcha [ %i1 + %i2 ] #ASI_SNF, 1 ! V9: prefetcha [%i1+%i2] #ASI_SNF, #one_read ! encoding: [0xc3,0xee,0x50,0x7a] prefetcha [ %i1 + %i2 ] #ASI_SNF, 1 - ! V8: error: malformed ASI tag, must be a constant integer expression + ! V8: error: unexpected token ! V8-NEXT: prefetcha [ %i1 + %i2 ] #ASI_SNF, #one_read ! V9: prefetcha [%i1+%i2] #ASI_SNF, #one_read ! encoding: [0xc3,0xee,0x50,0x7a] prefetcha [ %i1 + %i2 ] #ASI_SNF, #one_read |