25
25
#include " llvm/ADT/StringRef.h"
26
26
#include " llvm/ADT/StringSwitch.h"
27
27
#include " llvm/ADT/Twine.h"
28
+ #include " llvm/MC/MCAsmInfo.h"
28
29
#include " llvm/MC/MCContext.h"
29
30
#include " llvm/MC/MCExpr.h"
30
31
#include " llvm/MC/MCInst.h"
@@ -180,6 +181,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
180
181
bool showMatchError (SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo,
181
182
OperandVector &Operands);
182
183
184
+ bool parseDataExpr (const MCExpr *&Res) override ;
183
185
bool parseAuthExpr (const MCExpr *&Res, SMLoc &EndLoc);
184
186
185
187
bool parseDirectiveArch (SMLoc L);
@@ -335,8 +337,6 @@ class AArch64AsmParser : public MCTargetAsmParser {
335
337
unsigned validateTargetOperandClass (MCParsedAsmOperand &Op,
336
338
unsigned Kind) override ;
337
339
338
- bool parsePrimaryExpr (const MCExpr *&Res, SMLoc &EndLoc) override ;
339
-
340
340
static bool classifySymbolRef (const MCExpr *Expr,
341
341
AArch64MCExpr::Specifier &ELFSpec,
342
342
AArch64MCExpr::Specifier &DarwinSpec,
@@ -4478,6 +4478,19 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
4478
4478
if (HasELFModifier)
4479
4479
ImmVal = AArch64MCExpr::create (ImmVal, RefKind, getContext ());
4480
4480
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
+
4481
4494
return false ;
4482
4495
}
4483
4496
@@ -5007,11 +5020,18 @@ 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 =
5033
+ MCBinaryExpr::create (MCBinaryExpr::Add, IdVal, Term, getContext ());
5034
+ }
5015
5035
Operands.push_back (AArch64Operand::CreateImm (IdVal, S, E, getContext ()));
5016
5036
5017
5037
// Parse an optional shift/extend modifier.
@@ -8086,11 +8106,56 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8086
8106
return false ;
8087
8107
}
8088
8108
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))
8092
8116
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 ;
8094
8159
}
8095
8160
8096
8161
// / parseAuthExpr
@@ -8100,54 +8165,8 @@ bool AArch64AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
8100
8165
bool AArch64AsmParser::parseAuthExpr (const MCExpr *&Res, SMLoc &EndLoc) {
8101
8166
MCAsmParser &Parser = getParser ();
8102
8167
MCContext &Ctx = getContext ();
8103
-
8104
8168
AsmToken Tok = Parser.getTok ();
8105
8169
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
8170
// At this point, we encountered "<id>@AUTH". There is no fallback anymore.
8152
8171
if (parseToken (AsmToken::LParen, " expected '('" ))
8153
8172
return true ;
0 commit comments