summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCParser/AsmLexer.cpp
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2016-08-08 09:20:52 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2016-08-08 09:20:52 +0000
commit2ab623b5a31db5fecb08f822cc59433cfb7ccb58 (patch)
tree57ddef4d365f3169c35d5b8c3805b4d51120b8b5 /llvm/lib/MC/MCParser/AsmLexer.cpp
parent4dd6c249ac9988d80e32111a6e21f54fe5c34395 (diff)
downloadbcm5719-llvm-2ab623b5a31db5fecb08f822cc59433cfb7ccb58.tar.gz
bcm5719-llvm-2ab623b5a31db5fecb08f822cc59433cfb7ccb58.zip
[mips][ias] Fix all the hacks related to MIPS-specific unary operators (%hi/%lo/%gp_rel/etc.).
Summary: They are now lexed as a single token on targets where MCAsmInfo::HasMipsExpressions is true and then parsed in a similar way to the '~' operator as part of MCExpr::parseExpression. As a result: * expressions and immediates no longer have different parsing rules. The difference is now solely down to whether evaluateAsAbsolute() succeeds. * %hi(%neg(%gp_rel(x))) are no longer parsed as a single operator and decomposed into the three MipsMCExpr nodes. They are parsed directly as three MipsMCExpr nodes. * parseMemOperand no longer needs to eat all the surrounding parenthesis to get at the outermost operator to make this work * %hi(%neg(%gp_rel(x))) and %lo(%neg(%gp_rel(x))) are no longer the only 3-in-1 relocs that parse for N64. They're still the only combinations that are permitted in relocatable expressions though. Fixing that should be a later patch. * We no longer need to list all the tokens that can occur as the first token of an expression or immediate. test/MC/Mips/expr1.s: This change also prevents the incorrect lowering of %lo(2*4)+foo to %lo(8+foo) which is not an equivalent expression (the difference is whether foo is truncated to 16-bit or not) and the test has been updated to account for the macro expansion the correct expression requires. Reviewers: sdardis Subscribers: dsanders, sdardis, llvm-commits Differential Revision: https://reviews.llvm.org/D23110 llvm-svn: 277988
Diffstat (limited to 'llvm/lib/MC/MCParser/AsmLexer.cpp')
-rw-r--r--llvm/lib/MC/MCParser/AsmLexer.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp
index 7037bb1d5fa..be6e84460ea 100644
--- a/llvm/lib/MC/MCParser/AsmLexer.cpp
+++ b/llvm/lib/MC/MCParser/AsmLexer.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -600,7 +601,46 @@ AsmToken AsmLexer::LexToken() {
return AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
}
return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1));
- case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
+ case '%':
+ if (MAI.hasMipsExpressions()) {
+ AsmToken::TokenKind Operator;
+ unsigned OperatorLength;
+
+ std::tie(Operator, OperatorLength) =
+ StringSwitch<std::pair<AsmToken::TokenKind, unsigned>>(
+ StringRef(CurPtr))
+ .StartsWith("call16", {AsmToken::PercentCall16, 7})
+ .StartsWith("call_hi", {AsmToken::PercentCall_Hi, 8})
+ .StartsWith("call_lo", {AsmToken::PercentCall_Lo, 8})
+ .StartsWith("dtprel_hi", {AsmToken::PercentDtprel_Hi, 10})
+ .StartsWith("dtprel_lo", {AsmToken::PercentDtprel_Lo, 10})
+ .StartsWith("got_disp", {AsmToken::PercentGot_Disp, 9})
+ .StartsWith("got_hi", {AsmToken::PercentGot_Hi, 7})
+ .StartsWith("got_lo", {AsmToken::PercentGot_Lo, 7})
+ .StartsWith("got_ofst", {AsmToken::PercentGot_Ofst, 9})
+ .StartsWith("got_page", {AsmToken::PercentGot_Page, 9})
+ .StartsWith("gottprel", {AsmToken::PercentGottprel, 9})
+ .StartsWith("got", {AsmToken::PercentGot, 4})
+ .StartsWith("gp_rel", {AsmToken::PercentGp_Rel, 7})
+ .StartsWith("higher", {AsmToken::PercentHigher, 7})
+ .StartsWith("highest", {AsmToken::PercentHighest, 8})
+ .StartsWith("hi", {AsmToken::PercentHi, 3})
+ .StartsWith("lo", {AsmToken::PercentLo, 3})
+ .StartsWith("neg", {AsmToken::PercentNeg, 4})
+ .StartsWith("pcrel_hi", {AsmToken::PercentPcrel_Hi, 9})
+ .StartsWith("pcrel_lo", {AsmToken::PercentPcrel_Lo, 9})
+ .StartsWith("tlsgd", {AsmToken::PercentTlsgd, 6})
+ .StartsWith("tlsldm", {AsmToken::PercentTlsldm, 7})
+ .StartsWith("tprel_hi", {AsmToken::PercentTprel_Hi, 9})
+ .StartsWith("tprel_lo", {AsmToken::PercentTprel_Lo, 9})
+ .Default({AsmToken::Percent, 1});
+
+ if (Operator != AsmToken::Percent) {
+ CurPtr += OperatorLength - 1;
+ return AsmToken(Operator, StringRef(TokStart, OperatorLength));
+ }
+ }
+ return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
case '/':
IsAtStartOfStatement = OldIsAtStartOfStatement;
return LexSlash();
OpenPOWER on IntegriCloud