diff options
author | Daniel Sanders <daniel.sanders@imgtec.com> | 2016-08-08 11:50:25 +0000 |
---|---|---|
committer | Daniel Sanders <daniel.sanders@imgtec.com> | 2016-08-08 11:50:25 +0000 |
commit | 3feeb9c851a193f42d890b35f36816fae198860f (patch) | |
tree | 33bec59719202621269a2a0240eb562e98befd2b /llvm/lib/Target/Mips/AsmParser | |
parent | 4981ec9a56089db4302f0c508bcbe941154dfebe (diff) | |
download | bcm5719-llvm-3feeb9c851a193f42d890b35f36816fae198860f.tar.gz bcm5719-llvm-3feeb9c851a193f42d890b35f36816fae198860f.zip |
Re-commit r277988: [mips][ias] Fix all the hacks related to MIPS-specific unary operators (%hi/%lo/%gp_rel/etc.).
Hopefully with the MSVC builds fixed. I've added a missing '#include <tuple>'
that gcc and clang don't seem to need.
llvm-svn: 277995
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser')
-rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 233 |
1 files changed, 70 insertions, 163 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 0291ef929e2..e3f0d16d660 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -252,9 +252,6 @@ 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(); @@ -552,6 +549,64 @@ 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); + } + } }; } @@ -4187,9 +4242,6 @@ 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(); @@ -4216,72 +4268,23 @@ bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); return false; } - // 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; + default: { + DEBUG(dbgs() << ".. generic integer expression\n"); + + const MCExpr *Expr; SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. - if (parseRelocOperand(IdVal)) + if (getParser().parseExpression(Expr)) return true; SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); + Operands.push_back(MipsOperand::CreateImm(Expr, 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()) { @@ -4303,49 +4306,6 @@ 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; @@ -4373,35 +4333,11 @@ 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; - } - 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; + if (isParenExpr) + return getParser().parseParenExprOfDepth(0, Res, S); + return getParser().parseExpression(Res); } MipsAsmParser::OperandMatchResultTy @@ -4632,47 +4568,18 @@ 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. - ResTy = parseAnyRegister(Operands); + OperandMatchResultTy 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 |