18
18
#include " llvm/ADT/APInt.h"
19
19
#include " llvm/ADT/ArrayRef.h"
20
20
#include " llvm/ADT/STLExtras.h"
21
+ #include " llvm/ADT/ScopeExit.h"
21
22
#include " llvm/ADT/SmallSet.h"
22
23
#include " llvm/ADT/SmallVector.h"
23
24
#include " llvm/ADT/StringExtras.h"
24
25
#include " llvm/ADT/StringMap.h"
25
26
#include " llvm/ADT/StringRef.h"
26
27
#include " llvm/ADT/StringSwitch.h"
27
28
#include " llvm/ADT/Twine.h"
29
+ #include " llvm/MC/MCAsmInfo.h"
28
30
#include " llvm/MC/MCContext.h"
29
31
#include " llvm/MC/MCExpr.h"
30
32
#include " llvm/MC/MCInst.h"
@@ -180,6 +182,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
180
182
bool showMatchError (SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo,
181
183
OperandVector &Operands);
182
184
185
+ bool parseDataExpr (const MCExpr *&Res) override ;
183
186
bool parseAuthExpr (const MCExpr *&Res, SMLoc &EndLoc);
184
187
185
188
bool parseDirectiveArch (SMLoc L);
@@ -335,8 +338,6 @@ class AArch64AsmParser : public MCTargetAsmParser {
335
338
unsigned validateTargetOperandClass (MCParsedAsmOperand &Op,
336
339
unsigned Kind) override ;
337
340
338
- bool parsePrimaryExpr (const MCExpr *&Res, SMLoc &EndLoc) override ;
339
-
340
341
static bool classifySymbolRef (const MCExpr *Expr,
341
342
AArch64MCExpr::Specifier &ELFSpec,
342
343
MCSymbolRefExpr::VariantKind &DarwinRefKind,
@@ -4478,6 +4479,18 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
4478
4479
if (HasELFModifier)
4479
4480
ImmVal = AArch64MCExpr::create (ImmVal, RefKind, getContext ());
4480
4481
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 = MCBinaryExpr::create (MCBinaryExpr::Add, ImmVal, Term, getContext ());
4491
+ }
4492
+ }
4493
+
4481
4494
return false ;
4482
4495
}
4483
4496
@@ -5007,11 +5020,17 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
5007
5020
5008
5021
// This was not a register so parse other operands that start with an
5009
5022
// identifier (like labels) as expressions and create them as immediates.
5010
- const MCExpr *IdVal;
5023
+ const MCExpr *IdVal, *Term ;
5011
5024
S = getLoc ();
5012
5025
if (getParser ().parseExpression (IdVal))
5013
5026
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 = MCBinaryExpr::create (MCBinaryExpr::Add, IdVal, Term, getContext ());
5033
+ }
5015
5034
Operands.push_back (AArch64Operand::CreateImm (IdVal, S, E, getContext ()));
5016
5035
5017
5036
// Parse an optional shift/extend modifier.
@@ -8086,11 +8105,48 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8086
8105
return false ;
8087
8106
}
8088
8107
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))
8108
+ bool AArch64AsmParser::parseDataExpr (const MCExpr *&Res) {
8109
+ SMLoc EndLoc;
8110
+
8111
+ if (getParser ().parseExpression (Res))
8112
+ return true ;
8113
+ MCAsmParser &Parser = getParser ();
8114
+ if (!parseOptionalToken (AsmToken::At))
8092
8115
return false ;
8093
- return getParser ().parsePrimaryExpr (Res, EndLoc, nullptr );
8116
+ if (getLexer ().getKind () != AsmToken::Identifier)
8117
+ return Error (getLoc (), " expected relocation specifier" );
8118
+
8119
+ std::string Identifier = Parser.getTok ().getIdentifier ().lower ();
8120
+ SMLoc Loc = getLoc ();
8121
+ Lex ();
8122
+ if (Identifier == " auth" )
8123
+ return parseAuthExpr (Res, EndLoc);
8124
+
8125
+ auto Spec = MCSymbolRefExpr::VK_PLT;
8126
+ if (Identifier == " gotpcrel" )
8127
+ Spec = MCSymbolRefExpr::VK_GOTPCREL;
8128
+ else if (Identifier != " plt" )
8129
+ return Error (Loc, " invalid relocation specifier" );
8130
+ if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Res))
8131
+ Res = MCSymbolRefExpr::create (&SRE->getSymbol (), Spec, getContext (),
8132
+ SRE->getLoc ());
8133
+ else
8134
+ return Error (Loc, " this relocation specifier must follow a symbol" );
8135
+
8136
+ for (;;) {
8137
+ std::optional<MCBinaryExpr::Opcode> Opcode;
8138
+ if (parseOptionalToken (AsmToken::Plus))
8139
+ Opcode = MCBinaryExpr::Add;
8140
+ else if (parseOptionalToken (AsmToken::Minus))
8141
+ Opcode = MCBinaryExpr::Sub;
8142
+ else
8143
+ break ;
8144
+ const MCExpr *Term;
8145
+ if (getParser ().parsePrimaryExpr (Term, EndLoc, nullptr ))
8146
+ return true ;
8147
+ Res = MCBinaryExpr::create (*Opcode, Res, Term, getContext ());
8148
+ }
8149
+ return false ;
8094
8150
}
8095
8151
8096
8152
// / parseAuthExpr
@@ -8100,54 +8156,8 @@ bool AArch64AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
8100
8156
bool AArch64AsmParser::parseAuthExpr (const MCExpr *&Res, SMLoc &EndLoc) {
8101
8157
MCAsmParser &Parser = getParser ();
8102
8158
MCContext &Ctx = getContext ();
8103
-
8104
8159
AsmToken Tok = Parser.getTok ();
8105
8160
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
-
8151
8161
// At this point, we encountered "<id>@AUTH". There is no fallback anymore.
8152
8162
if (parseToken (AsmToken::LParen, " expected '('" ))
8153
8163
return true ;
0 commit comments