Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPARC][IAS] Rework ASI/Prefetch tag matching in prep for ParseForAllFeatures #96020

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 79 additions & 47 deletions llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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") {
Expand Down Expand Up @@ -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"

Expand Down Expand Up @@ -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());
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/MC/Sparc/sparc-mem-asi-instructions.s
Original file line number Diff line number Diff line change
@@ -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

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/MC/Sparc/sparcv9-instructions.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading