aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoakuma <koachan@protonmail.com>2024-06-27 19:45:53 +0700
committerGitHub <noreply@github.com>2024-06-27 19:45:53 +0700
commite9b8cd0c806db00f0981fb36717077c941426302 (patch)
treef3b92a07f3dfc6e70f36d1000605f36a3c15af46
parent468d668c5c4031366ae38804927b450f9faf409c (diff)
downloadllvm-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.cpp126
-rw-r--r--llvm/test/MC/Sparc/sparc-mem-asi-instructions.s4
-rw-r--r--llvm/test/MC/Sparc/sparcv9-instructions.s4
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