Skip to content

Commit e9b8cd0

Browse files
authored
[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: #96020
1 parent 468d668 commit e9b8cd0

File tree

3 files changed

+83
-51
lines changed

3 files changed

+83
-51
lines changed

llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp

Lines changed: 79 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,15 @@ class SparcAsmParser : public MCTargetAsmParser {
107107

108108
ParseStatus parseBranchModifiers(OperandVector &Operands);
109109

110+
ParseStatus parseExpression(int64_t &Val);
111+
110112
// Helper function for dealing with %lo / %hi in PIC mode.
111113
const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
112114
const MCExpr *subExpr);
113115

116+
// Helper function to see if current token can start an expression.
117+
bool isPossibleExpression(const AsmToken &Token);
118+
114119
// returns true if Tok is matched to a register and returns register in RegNo.
115120
MCRegister matchRegisterName(const AsmToken &Tok, unsigned &RegKind);
116121

@@ -1085,32 +1090,35 @@ ParseStatus SparcAsmParser::parseASITag(OperandVector &Operands) {
10851090
SMLoc E = Parser.getTok().getEndLoc();
10861091
int64_t ASIVal = 0;
10871092

1088-
if (is64Bit() && (getLexer().getKind() == AsmToken::Hash)) {
1089-
// For now we only support named tags for 64-bit/V9 systems.
1090-
// TODO: add support for 32-bit/V8 systems.
1091-
SMLoc TagStart = getLexer().peekTok(false).getLoc();
1092-
Parser.Lex(); // Eat the '#'.
1093-
auto ASIName = Parser.getTok().getString();
1094-
auto ASITag = SparcASITag::lookupASITagByName(ASIName);
1095-
if (!ASITag)
1096-
ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1097-
Parser.Lex(); // Eat the identifier token.
1093+
if (getLexer().getKind() != AsmToken::Hash) {
1094+
// If the ASI tag provided is not a named tag, then it
1095+
// must be a constant expression.
1096+
ParseStatus ParseExprStatus = parseExpression(ASIVal);
1097+
if (!ParseExprStatus.isSuccess())
1098+
return ParseExprStatus;
10981099

1099-
if (!ASITag)
1100-
return Error(TagStart, "unknown ASI tag");
1101-
1102-
ASIVal = ASITag->Encoding;
1103-
} else if (!getParser().parseAbsoluteExpression(ASIVal)) {
11041100
if (!isUInt<8>(ASIVal))
11051101
return Error(S, "invalid ASI number, must be between 0 and 255");
1106-
} else {
1107-
return Error(
1108-
S, is64Bit()
1109-
? "malformed ASI tag, must be %asi, a constant integer "
1110-
"expression, or a named tag"
1111-
: "malformed ASI tag, must be a constant integer expression");
1102+
1103+
Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1104+
return ParseStatus::Success;
11121105
}
11131106

1107+
// For now we only support named tags for 64-bit/V9 systems.
1108+
// TODO: add support for 32-bit/V8 systems.
1109+
SMLoc TagStart = getLexer().peekTok(false).getLoc();
1110+
Parser.Lex(); // Eat the '#'.
1111+
const StringRef ASIName = Parser.getTok().getString();
1112+
const SparcASITag::ASITag *ASITag = SparcASITag::lookupASITagByName(ASIName);
1113+
if (!ASITag)
1114+
ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1115+
Parser.Lex(); // Eat the identifier token.
1116+
1117+
if (!ASITag)
1118+
return Error(TagStart, "unknown ASI tag");
1119+
1120+
ASIVal = ASITag->Encoding;
1121+
11141122
Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
11151123
return ParseStatus::Success;
11161124
}
@@ -1120,35 +1128,32 @@ ParseStatus SparcAsmParser::parsePrefetchTag(OperandVector &Operands) {
11201128
SMLoc E = Parser.getTok().getEndLoc();
11211129
int64_t PrefetchVal = 0;
11221130

1123-
switch (getLexer().getKind()) {
1124-
case AsmToken::LParen:
1125-
case AsmToken::Integer:
1126-
case AsmToken::Identifier:
1127-
case AsmToken::Plus:
1128-
case AsmToken::Minus:
1129-
case AsmToken::Tilde:
1130-
if (getParser().parseAbsoluteExpression(PrefetchVal) ||
1131-
!isUInt<5>(PrefetchVal))
1132-
return Error(S, "invalid prefetch number, must be between 0 and 31");
1133-
break;
1134-
case AsmToken::Hash: {
1135-
SMLoc TagStart = getLexer().peekTok(false).getLoc();
1136-
Parser.Lex(); // Eat the '#'.
1137-
const StringRef PrefetchName = Parser.getTok().getString();
1138-
const SparcPrefetchTag::PrefetchTag *PrefetchTag =
1139-
SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);
1140-
Parser.Lex(); // Eat the identifier token.
1131+
if (getLexer().getKind() != AsmToken::Hash) {
1132+
// If the prefetch tag provided is not a named tag, then it
1133+
// must be a constant expression.
1134+
ParseStatus ParseExprStatus = parseExpression(PrefetchVal);
1135+
if (!ParseExprStatus.isSuccess())
1136+
return ParseExprStatus;
11411137

1142-
if (!PrefetchTag)
1143-
return Error(TagStart, "unknown prefetch tag");
1138+
if (!isUInt<8>(PrefetchVal))
1139+
return Error(S, "invalid prefetch number, must be between 0 and 31");
11441140

1145-
PrefetchVal = PrefetchTag->Encoding;
1146-
break;
1147-
}
1148-
default:
1149-
return ParseStatus::NoMatch;
1141+
Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1142+
return ParseStatus::Success;
11501143
}
11511144

1145+
SMLoc TagStart = getLexer().peekTok(false).getLoc();
1146+
Parser.Lex(); // Eat the '#'.
1147+
const StringRef PrefetchName = Parser.getTok().getString();
1148+
const SparcPrefetchTag::PrefetchTag *PrefetchTag =
1149+
SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);
1150+
Parser.Lex(); // Eat the identifier token.
1151+
1152+
if (!PrefetchTag)
1153+
return Error(TagStart, "unknown prefetch tag");
1154+
1155+
PrefetchVal = PrefetchTag->Encoding;
1156+
11521157
Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
11531158
return ParseStatus::Success;
11541159
}
@@ -1230,8 +1235,12 @@ ParseStatus SparcAsmParser::parseOperand(OperandVector &Operands,
12301235
// Parse an optional address-space identifier after the address.
12311236
// This will be either an immediate constant expression, or, on 64-bit
12321237
// processors, the %asi register.
1233-
if (is64Bit() && getLexer().is(AsmToken::Percent)) {
1238+
if (getLexer().is(AsmToken::Percent)) {
12341239
SMLoc S = Parser.getTok().getLoc();
1240+
if (!is64Bit())
1241+
return Error(
1242+
S, "malformed ASI tag, must be a constant integer expression");
1243+
12351244
Parser.Lex(); // Eat the %.
12361245
const AsmToken Tok = Parser.getTok();
12371246
if (Tok.is(AsmToken::Identifier) && Tok.getString() == "asi") {
@@ -1360,6 +1369,15 @@ ParseStatus SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
13601369
return ParseStatus::Success;
13611370
}
13621371

1372+
ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {
1373+
AsmToken Tok = getLexer().getTok();
1374+
1375+
if (!isPossibleExpression(Tok))
1376+
return ParseStatus::NoMatch;
1377+
1378+
return getParser().parseAbsoluteExpression(Val);
1379+
}
1380+
13631381
#define GET_REGISTER_MATCHER
13641382
#include "SparcGenAsmMatcher.inc"
13651383

@@ -1590,6 +1608,20 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
15901608
return true;
15911609
}
15921610

1611+
bool SparcAsmParser::isPossibleExpression(const AsmToken &Token) {
1612+
switch (Token.getKind()) {
1613+
case AsmToken::LParen:
1614+
case AsmToken::Integer:
1615+
case AsmToken::Identifier:
1616+
case AsmToken::Plus:
1617+
case AsmToken::Minus:
1618+
case AsmToken::Tilde:
1619+
return true;
1620+
default:
1621+
return false;
1622+
}
1623+
}
1624+
15931625
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser() {
15941626
RegisterMCAsmParser<SparcAsmParser> A(getTheSparcTarget());
15951627
RegisterMCAsmParser<SparcAsmParser> B(getTheSparcV9Target());

llvm/test/MC/Sparc/sparc-mem-asi-instructions.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
! RUN: not llvm-mc %s -triple=sparc -show-encoding 2>&1 | FileCheck %s --check-prefix=V8
22
! RUN: not llvm-mc %s -triple=sparcv9 -show-encoding 2>&1 | FileCheck %s --check-prefix=V9
33

4-
! V8: error: malformed ASI tag, must be a constant integer expression
4+
! V8: error: expected absolute expression
55
! V8-NEXT: lduba [%i0] asi, %o2
6-
! V9: error: malformed ASI tag, must be %asi, a constant integer expression, or a named tag
6+
! V9: error: unexpected token
77
! V9-NEXT: lduba [%i0] asi, %o2
88
lduba [%i0] asi, %o2
99

llvm/test/MC/Sparc/sparcv9-instructions.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,12 +657,12 @@
657657
! V9: prefetcha [%i1+3968] %asi, #one_read ! encoding: [0xc3,0xee,0x6f,0x80]
658658
prefetcha [ %i1 + 0xf80 ] %asi, #one_read
659659

660-
! V8: error: malformed ASI tag, must be a constant integer expression
660+
! V8: error: invalid operand for instruction
661661
! V8-NEXT: prefetcha [ %i1 + %i2 ] #ASI_SNF, 1
662662
! V9: prefetcha [%i1+%i2] #ASI_SNF, #one_read ! encoding: [0xc3,0xee,0x50,0x7a]
663663
prefetcha [ %i1 + %i2 ] #ASI_SNF, 1
664664

665-
! V8: error: malformed ASI tag, must be a constant integer expression
665+
! V8: error: unexpected token
666666
! V8-NEXT: prefetcha [ %i1 + %i2 ] #ASI_SNF, #one_read
667667
! V9: prefetcha [%i1+%i2] #ASI_SNF, #one_read ! encoding: [0xc3,0xee,0x50,0x7a]
668668
prefetcha [ %i1 + %i2 ] #ASI_SNF, #one_read

0 commit comments

Comments
 (0)