summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/AsmParser
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2016-08-08 09:33:14 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2016-08-08 09:33:14 +0000
commitcae9aeed3934c1f97d8628732bcd58968fe52656 (patch)
tree6893b35492d7c1ca1c68abeed8dee0dad4ee764b /llvm/lib/Target/Mips/AsmParser
parent44583ce65a81c4e6e4e629d259e9e2851c0c6e6e (diff)
downloadbcm5719-llvm-cae9aeed3934c1f97d8628732bcd58968fe52656.tar.gz
bcm5719-llvm-cae9aeed3934c1f97d8628732bcd58968fe52656.zip
Revert r277988: [mips][ias] Fix all the hacks related to MIPS-specific unary operators (%hi/%lo/%gp_rel/etc.).
It seems that MSVC doesn't like std::tie(). llvm-svn: 277990
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp233
1 files changed, 163 insertions, 70 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index e3f0d16d660..0291ef929e2 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -252,6 +252,9 @@ class MipsAsmParser : public MCTargetAsmParser {
bool reportParseError(SMLoc Loc, Twine ErrorMsg);
bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
+ bool parseRelocOperand(const MCExpr *&Res);
+
+ const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
bool isEvaluated(const MCExpr *Expr);
bool parseSetMips0Directive();
@@ -549,64 +552,6 @@ public:
void warnIfNoMacro(SMLoc Loc);
bool isLittle() const { return IsLittleEndian; }
-
- const MCExpr *createTargetUnaryExpr(const MCExpr *E,
- AsmToken::TokenKind OperatorToken,
- MCContext &Ctx) override {
- switch(OperatorToken) {
- default:
- llvm_unreachable("Unknown token");
- return nullptr;
- case AsmToken::PercentCall16:
- return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
- case AsmToken::PercentCall_Hi:
- return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
- case AsmToken::PercentCall_Lo:
- return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
- case AsmToken::PercentDtprel_Hi:
- return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
- case AsmToken::PercentDtprel_Lo:
- return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
- case AsmToken::PercentGot:
- return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
- case AsmToken::PercentGot_Disp:
- return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
- case AsmToken::PercentGot_Hi:
- return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
- case AsmToken::PercentGot_Lo:
- return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
- case AsmToken::PercentGot_Ofst:
- return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
- case AsmToken::PercentGot_Page:
- return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
- case AsmToken::PercentGottprel:
- return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
- case AsmToken::PercentGp_Rel:
- return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
- case AsmToken::PercentHi:
- return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
- case AsmToken::PercentHigher:
- return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
- case AsmToken::PercentHighest:
- return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
- case AsmToken::PercentLo:
- return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
- case AsmToken::PercentNeg:
- return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
- case AsmToken::PercentPcrel_Hi:
- return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
- case AsmToken::PercentPcrel_Lo:
- return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
- case AsmToken::PercentTlsgd:
- return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
- case AsmToken::PercentTlsldm:
- return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
- case AsmToken::PercentTprel_Hi:
- return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
- case AsmToken::PercentTprel_Lo:
- return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
- }
- }
};
}
@@ -4242,6 +4187,9 @@ bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
DEBUG(dbgs() << ".. Generic Parser\n");
switch (getLexer().getKind()) {
+ default:
+ Error(Parser.getTok().getLoc(), "unexpected token in operand");
+ return true;
case AsmToken::Dollar: {
// Parse the register.
SMLoc S = Parser.getTok().getLoc();
@@ -4268,23 +4216,72 @@ bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
return false;
}
- default: {
- DEBUG(dbgs() << ".. generic integer expression\n");
-
- const MCExpr *Expr;
+ // Else drop to expression parsing.
+ case AsmToken::LParen:
+ case AsmToken::Minus:
+ case AsmToken::Plus:
+ case AsmToken::Integer:
+ case AsmToken::Tilde:
+ case AsmToken::String: {
+ DEBUG(dbgs() << ".. generic integer\n");
+ OperandMatchResultTy ResTy = parseImm(Operands);
+ return ResTy != MatchOperand_Success;
+ }
+ case AsmToken::Percent: {
+ // It is a symbol reference or constant expression.
+ const MCExpr *IdVal;
SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
- if (getParser().parseExpression(Expr))
+ if (parseRelocOperand(IdVal))
return true;
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
- Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
+ Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
return false;
- }
+ } // case AsmToken::Percent
} // switch(getLexer().getKind())
return true;
}
+const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
+ StringRef RelocStr) {
+ if (RelocStr == "hi(%neg(%gp_rel")
+ return MipsMCExpr::createGpOff(MipsMCExpr::MEK_HI, Expr, getContext());
+ else if (RelocStr == "lo(%neg(%gp_rel")
+ return MipsMCExpr::createGpOff(MipsMCExpr::MEK_LO, Expr, getContext());
+
+ MipsMCExpr::MipsExprKind Kind =
+ StringSwitch<MipsMCExpr::MipsExprKind>(RelocStr)
+ .Case("call16", MipsMCExpr::MEK_GOT_CALL)
+ .Case("call_hi", MipsMCExpr::MEK_CALL_HI16)
+ .Case("call_lo", MipsMCExpr::MEK_CALL_LO16)
+ .Case("dtprel_hi", MipsMCExpr::MEK_DTPREL_HI)
+ .Case("dtprel_lo", MipsMCExpr::MEK_DTPREL_LO)
+ .Case("got", MipsMCExpr::MEK_GOT)
+ .Case("got_disp", MipsMCExpr::MEK_GOT_DISP)
+ .Case("got_hi", MipsMCExpr::MEK_GOT_HI16)
+ .Case("got_lo", MipsMCExpr::MEK_GOT_LO16)
+ .Case("got_ofst", MipsMCExpr::MEK_GOT_OFST)
+ .Case("got_page", MipsMCExpr::MEK_GOT_PAGE)
+ .Case("gottprel", MipsMCExpr::MEK_GOTTPREL)
+ .Case("gp_rel", MipsMCExpr::MEK_GPREL)
+ .Case("hi", MipsMCExpr::MEK_HI)
+ .Case("higher", MipsMCExpr::MEK_HIGHER)
+ .Case("highest", MipsMCExpr::MEK_HIGHEST)
+ .Case("lo", MipsMCExpr::MEK_LO)
+ .Case("neg", MipsMCExpr::MEK_NEG)
+ .Case("pcrel_hi", MipsMCExpr::MEK_PCREL_HI16)
+ .Case("pcrel_lo", MipsMCExpr::MEK_PCREL_LO16)
+ .Case("tlsgd", MipsMCExpr::MEK_TLSGD)
+ .Case("tlsldm", MipsMCExpr::MEK_TLSLDM)
+ .Case("tprel_hi", MipsMCExpr::MEK_TPREL_HI)
+ .Case("tprel_lo", MipsMCExpr::MEK_TPREL_LO)
+ .Default(MipsMCExpr::MEK_None);
+
+ assert(Kind != MipsMCExpr::MEK_None);
+ return MipsMCExpr::create(Kind, Expr, getContext());
+}
+
bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
switch (Expr->getKind()) {
@@ -4306,6 +4303,49 @@ bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
return false;
}
+bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
+ MCAsmParser &Parser = getParser();
+ Parser.Lex(); // Eat the % token.
+ const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
+ if (Tok.isNot(AsmToken::Identifier))
+ return true;
+
+ std::string Str = Tok.getIdentifier();
+
+ Parser.Lex(); // Eat the identifier.
+ // Now make an expression from the rest of the operand.
+ const MCExpr *IdVal;
+ SMLoc EndLoc;
+
+ if (getLexer().getKind() == AsmToken::LParen) {
+ while (1) {
+ Parser.Lex(); // Eat the '(' token.
+ if (getLexer().getKind() == AsmToken::Percent) {
+ Parser.Lex(); // Eat the % token.
+ const AsmToken &nextTok = Parser.getTok();
+ if (nextTok.isNot(AsmToken::Identifier))
+ return true;
+ Str += "(%";
+ Str += nextTok.getIdentifier();
+ Parser.Lex(); // Eat the identifier.
+ if (getLexer().getKind() != AsmToken::LParen)
+ return true;
+ } else
+ break;
+ }
+ if (getParser().parseParenExpression(IdVal, EndLoc))
+ return true;
+
+ while (getLexer().getKind() == AsmToken::RParen)
+ Parser.Lex(); // Eat the ')' token.
+
+ } else
+ return true; // Parenthesis must follow the relocation operand.
+
+ Res = evaluateRelocExpr(IdVal, Str);
+ return false;
+}
+
bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc) {
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
@@ -4333,11 +4373,35 @@ bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
}
bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
+ MCAsmParser &Parser = getParser();
SMLoc S;
+ bool Result = true;
+ unsigned NumOfLParen = 0;
+
+ while (getLexer().getKind() == AsmToken::LParen) {
+ Parser.Lex();
+ ++NumOfLParen;
+ }
- if (isParenExpr)
- return getParser().parseParenExprOfDepth(0, Res, S);
- return getParser().parseExpression(Res);
+ switch (getLexer().getKind()) {
+ default:
+ return true;
+ case AsmToken::Identifier:
+ case AsmToken::LParen:
+ case AsmToken::Integer:
+ case AsmToken::Minus:
+ case AsmToken::Plus:
+ if (isParenExpr)
+ Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
+ else
+ Result = (getParser().parseExpression(Res));
+ while (getLexer().getKind() == AsmToken::RParen)
+ Parser.Lex();
+ break;
+ case AsmToken::Percent:
+ Result = parseRelocOperand(Res);
+ }
+ return Result;
}
MipsAsmParser::OperandMatchResultTy
@@ -4568,18 +4632,47 @@ MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
}
MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseImm(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
+ switch (getLexer().getKind()) {
+ default:
+ return MatchOperand_NoMatch;
+ case AsmToken::LParen:
+ case AsmToken::Minus:
+ case AsmToken::Plus:
+ case AsmToken::Integer:
+ case AsmToken::Tilde:
+ case AsmToken::String:
+ break;
+ }
+
+ const MCExpr *IdVal;
+ SMLoc S = Parser.getTok().getLoc();
+ if (getParser().parseExpression(IdVal))
+ return MatchOperand_ParseFail;
+
+ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
+ return MatchOperand_Success;
+}
+
+MipsAsmParser::OperandMatchResultTy
MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
DEBUG(dbgs() << "parseJumpTarget\n");
SMLoc S = getLexer().getLoc();
+ // Integers and expressions are acceptable
+ OperandMatchResultTy ResTy = parseImm(Operands);
+ if (ResTy != MatchOperand_NoMatch)
+ return ResTy;
+
// Registers are a valid target and have priority over symbols.
- OperandMatchResultTy ResTy = parseAnyRegister(Operands);
+ ResTy = parseAnyRegister(Operands);
if (ResTy != MatchOperand_NoMatch)
return ResTy;
- // Integers and expressions are acceptable
const MCExpr *Expr = nullptr;
if (Parser.parseExpression(Expr)) {
// We have no way of knowing if a symbol was consumed so we must ParseFail
OpenPOWER on IntegriCloud