1818#include " llvm/ADT/APInt.h"
1919#include " llvm/ADT/ArrayRef.h"
2020#include " llvm/ADT/STLExtras.h"
21+ #include " llvm/ADT/ScopeExit.h"
2122#include " llvm/ADT/SmallSet.h"
2223#include " llvm/ADT/SmallVector.h"
2324#include " llvm/ADT/StringExtras.h"
2425#include " llvm/ADT/StringMap.h"
2526#include " llvm/ADT/StringRef.h"
2627#include " llvm/ADT/StringSwitch.h"
2728#include " llvm/ADT/Twine.h"
29+ #include " llvm/MC/MCAsmInfo.h"
2830#include " llvm/MC/MCContext.h"
2931#include " llvm/MC/MCExpr.h"
3032#include " llvm/MC/MCInst.h"
@@ -180,6 +182,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
180182 bool showMatchError (SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo,
181183 OperandVector &Operands);
182184
185+ bool parseDataExpr (const MCExpr *&Res) override ;
183186 bool parseAuthExpr (const MCExpr *&Res, SMLoc &EndLoc);
184187
185188 bool parseDirectiveArch (SMLoc L);
@@ -335,8 +338,6 @@ class AArch64AsmParser : public MCTargetAsmParser {
335338 unsigned validateTargetOperandClass (MCParsedAsmOperand &Op,
336339 unsigned Kind) override ;
337340
338- bool parsePrimaryExpr (const MCExpr *&Res, SMLoc &EndLoc) override ;
339-
340341 static bool classifySymbolRef (const MCExpr *Expr,
341342 AArch64MCExpr::Specifier &ELFSpec,
342343 MCSymbolRefExpr::VariantKind &DarwinRefKind,
@@ -4478,6 +4479,19 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
44784479 if (HasELFModifier)
44794480 ImmVal = AArch64MCExpr::create (ImmVal, RefKind, getContext ());
44804481
4482+ SMLoc EndLoc;
4483+ if (getContext ().getAsmInfo ()->hasSubsectionsViaSymbols ()) {
4484+ if (getParser ().parseAtSpecifier (ImmVal, EndLoc))
4485+ return true ;
4486+ const MCExpr *Term;
4487+ if (parseOptionalToken (AsmToken::Plus)) {
4488+ if (getParser ().parseExpression (Term, EndLoc))
4489+ return true ;
4490+ ImmVal =
4491+ MCBinaryExpr::create (MCBinaryExpr::Add, ImmVal, Term, getContext ());
4492+ }
4493+ }
4494+
44814495 return false ;
44824496}
44834497
@@ -5007,11 +5021,18 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
50075021
50085022 // This was not a register so parse other operands that start with an
50095023 // identifier (like labels) as expressions and create them as immediates.
5010- const MCExpr *IdVal;
5024+ const MCExpr *IdVal, *Term ;
50115025 S = getLoc ();
50125026 if (getParser ().parseExpression (IdVal))
50135027 return true ;
5014- E = SMLoc::getFromPointer (getLoc ().getPointer () - 1 );
5028+ if (getParser ().parseAtSpecifier (IdVal, E))
5029+ return true ;
5030+ if (parseOptionalToken (AsmToken::Plus)) {
5031+ if (getParser ().parseExpression (Term, E))
5032+ return true ;
5033+ IdVal =
5034+ MCBinaryExpr::create (MCBinaryExpr::Add, IdVal, Term, getContext ());
5035+ }
50155036 Operands.push_back (AArch64Operand::CreateImm (IdVal, S, E, getContext ()));
50165037
50175038 // Parse an optional shift/extend modifier.
@@ -8086,11 +8107,52 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
80868107 return false ;
80878108}
80888109
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))
8110+ bool AArch64AsmParser::parseDataExpr (const MCExpr *&Res) {
8111+ SMLoc EndLoc;
8112+
8113+ if (getParser ().parseExpression (Res))
8114+ return true ;
8115+ MCAsmParser &Parser = getParser ();
8116+ if (!parseOptionalToken (AsmToken::At))
80928117 return false ;
8093- return getParser ().parsePrimaryExpr (Res, EndLoc, nullptr );
8118+ if (getLexer ().getKind () != AsmToken::Identifier)
8119+ return Error (getLoc (), " expected relocation specifier" );
8120+
8121+ std::string Identifier = Parser.getTok ().getIdentifier ().lower ();
8122+ SMLoc Loc = getLoc ();
8123+ Lex ();
8124+ if (Identifier == " auth" )
8125+ return parseAuthExpr (Res, EndLoc);
8126+
8127+ auto Spec = MCSymbolRefExpr::VK_PLT;
8128+ if (Identifier == " gotpcrel" )
8129+ Spec = MCSymbolRefExpr::VK_GOTPCREL;
8130+ else if (Identifier == " plt" )
8131+ Spec = MCSymbolRefExpr::VK_PLT;
8132+ else if (Identifier == " got" ) // Mach-O specific
8133+ Spec = MCSymbolRefExpr::VK_GOT;
8134+ else
8135+ return Error (Loc, " invalid relocation specifier" );
8136+ if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Res))
8137+ Res = MCSymbolRefExpr::create (&SRE->getSymbol (), Spec, getContext (),
8138+ SRE->getLoc ());
8139+ else
8140+ return Error (Loc, " this relocation specifier must follow a symbol" );
8141+
8142+ for (;;) {
8143+ std::optional<MCBinaryExpr::Opcode> Opcode;
8144+ if (parseOptionalToken (AsmToken::Plus))
8145+ Opcode = MCBinaryExpr::Add;
8146+ else if (parseOptionalToken (AsmToken::Minus))
8147+ Opcode = MCBinaryExpr::Sub;
8148+ else
8149+ break ;
8150+ const MCExpr *Term;
8151+ if (getParser ().parsePrimaryExpr (Term, EndLoc, nullptr ))
8152+ return true ;
8153+ Res = MCBinaryExpr::create (*Opcode, Res, Term, getContext ());
8154+ }
8155+ return false ;
80948156}
80958157
80968158// / parseAuthExpr
@@ -8100,54 +8162,8 @@ bool AArch64AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
81008162bool AArch64AsmParser::parseAuthExpr (const MCExpr *&Res, SMLoc &EndLoc) {
81018163 MCAsmParser &Parser = getParser ();
81028164 MCContext &Ctx = getContext ();
8103-
81048165 AsmToken Tok = Parser.getTok ();
81058166
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-
81518167 // At this point, we encountered "<id>@AUTH". There is no fallback anymore.
81528168 if (parseToken (AsmToken::LParen, " expected '('" ))
81538169 return true ;
0 commit comments