2525#include " llvm/ADT/StringRef.h"
2626#include " llvm/ADT/StringSwitch.h"
2727#include " llvm/ADT/Twine.h"
28+ #include " llvm/MC/MCAsmInfo.h"
2829#include " llvm/MC/MCContext.h"
2930#include " llvm/MC/MCExpr.h"
3031#include " llvm/MC/MCInst.h"
@@ -180,6 +181,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
180181 bool showMatchError (SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo,
181182 OperandVector &Operands);
182183
184+ bool parseDataExpr (const MCExpr *&Res) override ;
183185 bool parseAuthExpr (const MCExpr *&Res, SMLoc &EndLoc);
184186
185187 bool parseDirectiveArch (SMLoc L);
@@ -335,8 +337,6 @@ class AArch64AsmParser : public MCTargetAsmParser {
335337 unsigned validateTargetOperandClass (MCParsedAsmOperand &Op,
336338 unsigned Kind) override ;
337339
338- bool parsePrimaryExpr (const MCExpr *&Res, SMLoc &EndLoc) override ;
339-
340340 static bool classifySymbolRef (const MCExpr *Expr,
341341 AArch64MCExpr::Specifier &ELFSpec,
342342 AArch64MCExpr::Specifier &DarwinSpec,
@@ -4478,6 +4478,19 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
44784478 if (HasELFModifier)
44794479 ImmVal = AArch64MCExpr::create (ImmVal, RefKind, getContext ());
44804480
4481+ SMLoc EndLoc;
4482+ if (getContext ().getAsmInfo ()->hasSubsectionsViaSymbols ()) {
4483+ if (getParser ().parseAtSpecifier (ImmVal, EndLoc))
4484+ return true ;
4485+ const MCExpr *Term;
4486+ if (parseOptionalToken (AsmToken::Plus)) {
4487+ if (getParser ().parseExpression (Term, EndLoc))
4488+ return true ;
4489+ ImmVal =
4490+ MCBinaryExpr::create (MCBinaryExpr::Add, ImmVal, Term, getContext ());
4491+ }
4492+ }
4493+
44814494 return false ;
44824495}
44834496
@@ -5007,11 +5020,18 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
50075020
50085021 // This was not a register so parse other operands that start with an
50095022 // identifier (like labels) as expressions and create them as immediates.
5010- const MCExpr *IdVal;
5023+ const MCExpr *IdVal, *Term ;
50115024 S = getLoc ();
50125025 if (getParser ().parseExpression (IdVal))
50135026 return true ;
5014- E = SMLoc::getFromPointer (getLoc ().getPointer () - 1 );
5027+ if (getParser ().parseAtSpecifier (IdVal, E))
5028+ return true ;
5029+ if (parseOptionalToken (AsmToken::Plus)) {
5030+ if (getParser ().parseExpression (Term, E))
5031+ return true ;
5032+ IdVal =
5033+ MCBinaryExpr::create (MCBinaryExpr::Add, IdVal, Term, getContext ());
5034+ }
50155035 Operands.push_back (AArch64Operand::CreateImm (IdVal, S, E, getContext ()));
50165036
50175037 // Parse an optional shift/extend modifier.
@@ -8086,11 +8106,56 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
80868106 return false ;
80878107}
80888108
8089- bool AArch64AsmParser::parsePrimaryExpr (const MCExpr *&Res, SMLoc &EndLoc) {
8090- // Try @AUTH expressions: they're more complex than the usual symbol variants.
8091- if (!parseAuthExpr (Res, EndLoc))
8109+ bool AArch64AsmParser::parseDataExpr (const MCExpr *&Res) {
8110+ SMLoc EndLoc;
8111+
8112+ if (getParser ().parseExpression (Res))
8113+ return true ;
8114+ MCAsmParser &Parser = getParser ();
8115+ if (!parseOptionalToken (AsmToken::At))
80928116 return false ;
8093- return getParser ().parsePrimaryExpr (Res, EndLoc, nullptr );
8117+ if (getLexer ().getKind () != AsmToken::Identifier)
8118+ return Error (getLoc (), " expected relocation specifier" );
8119+
8120+ std::string Identifier = Parser.getTok ().getIdentifier ().lower ();
8121+ SMLoc Loc = getLoc ();
8122+ Lex ();
8123+ if (Identifier == " auth" )
8124+ return parseAuthExpr (Res, EndLoc);
8125+
8126+ auto Spec = AArch64MCExpr::None;
8127+ if (STI->getTargetTriple ().isOSBinFormatMachO ()) {
8128+ if (Identifier == " got" )
8129+ Spec = AArch64MCExpr::M_GOT;
8130+ } else {
8131+ // Unofficial, experimental syntax that will be changed.
8132+ if (Identifier == " gotpcrel" )
8133+ Spec = AArch64MCExpr::VK_GOTPCREL;
8134+ else if (Identifier == " plt" )
8135+ Spec = AArch64MCExpr::VK_PLT;
8136+ }
8137+ if (Spec == AArch64MCExpr::None)
8138+ return Error (Loc, " invalid relocation specifier" );
8139+ if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Res))
8140+ Res = MCSymbolRefExpr::create (&SRE->getSymbol (), Spec, getContext (),
8141+ SRE->getLoc ());
8142+ else
8143+ return Error (Loc, " @ specifier only allowed after a symbol" );
8144+
8145+ for (;;) {
8146+ std::optional<MCBinaryExpr::Opcode> Opcode;
8147+ if (parseOptionalToken (AsmToken::Plus))
8148+ Opcode = MCBinaryExpr::Add;
8149+ else if (parseOptionalToken (AsmToken::Minus))
8150+ Opcode = MCBinaryExpr::Sub;
8151+ else
8152+ break ;
8153+ const MCExpr *Term;
8154+ if (getParser ().parsePrimaryExpr (Term, EndLoc, nullptr ))
8155+ return true ;
8156+ Res = MCBinaryExpr::create (*Opcode, Res, Term, getContext ());
8157+ }
8158+ return false ;
80948159}
80958160
80968161// / parseAuthExpr
@@ -8100,54 +8165,8 @@ bool AArch64AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
81008165bool AArch64AsmParser::parseAuthExpr (const MCExpr *&Res, SMLoc &EndLoc) {
81018166 MCAsmParser &Parser = getParser ();
81028167 MCContext &Ctx = getContext ();
8103-
81048168 AsmToken Tok = Parser.getTok ();
81058169
8106- // Look for '_sym@AUTH' ...
8107- if (Tok.is (AsmToken::Identifier) && Tok.getIdentifier ().ends_with (" @AUTH" )) {
8108- StringRef SymName = Tok.getIdentifier ().drop_back (strlen (" @AUTH" ));
8109- if (SymName.contains (' @' ))
8110- return TokError (
8111- " combination of @AUTH with other modifiers not supported" );
8112- Res = MCSymbolRefExpr::create (Ctx.getOrCreateSymbol (SymName), Ctx);
8113-
8114- Parser.Lex (); // Eat the identifier.
8115- } else {
8116- // ... or look for a more complex symbol reference, such as ...
8117- SmallVector<AsmToken, 6 > Tokens;
8118-
8119- // ... '"_long sym"@AUTH' ...
8120- if (Tok.is (AsmToken::String))
8121- Tokens.resize (2 );
8122- // ... or '(_sym + 5)@AUTH'.
8123- else if (Tok.is (AsmToken::LParen))
8124- Tokens.resize (6 );
8125- else
8126- return true ;
8127-
8128- if (Parser.getLexer ().peekTokens (Tokens) != Tokens.size ())
8129- return true ;
8130-
8131- // In either case, the expression ends with '@' 'AUTH'.
8132- if (Tokens[Tokens.size () - 2 ].isNot (AsmToken::At) ||
8133- Tokens[Tokens.size () - 1 ].isNot (AsmToken::Identifier) ||
8134- Tokens[Tokens.size () - 1 ].getIdentifier () != " AUTH" )
8135- return true ;
8136-
8137- if (Tok.is (AsmToken::String)) {
8138- StringRef SymName;
8139- if (Parser.parseIdentifier (SymName))
8140- return true ;
8141- Res = MCSymbolRefExpr::create (Ctx.getOrCreateSymbol (SymName), Ctx);
8142- } else {
8143- if (Parser.parsePrimaryExpr (Res, EndLoc, nullptr ))
8144- return true ;
8145- }
8146-
8147- Parser.Lex (); // '@'
8148- Parser.Lex (); // 'AUTH'
8149- }
8150-
81518170 // At this point, we encountered "<id>@AUTH". There is no fallback anymore.
81528171 if (parseToken (AsmToken::LParen, " expected '('" ))
81538172 return true ;
0 commit comments