diff options
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/MCParser/AsmLexer.cpp | 44 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 37 |
2 files changed, 80 insertions, 1 deletions
diff --git a/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp index 7037bb1d5fa..832c39a2c75 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" @@ -19,6 +20,8 @@ #include <cerrno> #include <cstdio> #include <cstdlib> +#include <tuple> + using namespace llvm; AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) { @@ -600,7 +603,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(); diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 6d3240a3e11..7a6d5dbd2d3 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -1064,6 +1064,43 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { return true; Res = MCUnaryExpr::createNot(Res, getContext()); return false; + // MIPS unary expression operators. The lexer won't generate these tokens if + // MCAsmInfo::HasMipsExpressions is false for the target. + case AsmToken::PercentCall16: + case AsmToken::PercentCall_Hi: + case AsmToken::PercentCall_Lo: + case AsmToken::PercentDtprel_Hi: + case AsmToken::PercentDtprel_Lo: + case AsmToken::PercentGot: + case AsmToken::PercentGot_Disp: + case AsmToken::PercentGot_Hi: + case AsmToken::PercentGot_Lo: + case AsmToken::PercentGot_Ofst: + case AsmToken::PercentGot_Page: + case AsmToken::PercentGottprel: + case AsmToken::PercentGp_Rel: + case AsmToken::PercentHi: + case AsmToken::PercentHigher: + case AsmToken::PercentHighest: + case AsmToken::PercentLo: + case AsmToken::PercentNeg: + case AsmToken::PercentPcrel_Hi: + case AsmToken::PercentPcrel_Lo: + case AsmToken::PercentTlsgd: + case AsmToken::PercentTlsldm: + case AsmToken::PercentTprel_Hi: + case AsmToken::PercentTprel_Lo: + Lex(); // Eat the operator. + if (Lexer.isNot(AsmToken::LParen)) + return TokError("expected '(' after operator"); + Lex(); // Eat the operator. + if (parseExpression(Res, EndLoc)) + return true; + if (Lexer.isNot(AsmToken::RParen)) + return TokError("expected ')'"); + Lex(); // Eat the operator. + Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx); + return !Res; } } |