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 | |
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')
-rw-r--r-- | llvm/lib/MC/MCParser/AsmLexer.cpp | 44 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 37 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 233 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 5 |
8 files changed, 171 insertions, 167 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; } } 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 diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 550c2894695..3ee0cd9c7ec 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -62,6 +62,8 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case FK_GPRel_4: case FK_Data_4: case FK_Data_8: + case Mips::fixup_Mips_SUB: + case Mips::fixup_MICROMIPS_SUB: break; case Mips::fixup_Mips_PC16: // The displacement is then divided by 4 to give us an 18 bit @@ -361,7 +363,9 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_MICROMIPS_TLS_DTPREL_HI16", 0, 16, 0 }, { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0, 16, 0 }, { "fixup_MICROMIPS_TLS_TPREL_HI16", 0, 16, 0 }, - { "fixup_MICROMIPS_TLS_TPREL_LO16", 0, 16, 0 } + { "fixup_MICROMIPS_TLS_TPREL_LO16", 0, 16, 0 }, + { "fixup_Mips_SUB", 0, 64, 0 }, + { "fixup_MICROMIPS_SUB", 0, 64, 0 } }; const static MCFixupKindInfo BigEndianInfos[Mips::NumTargetFixupKinds] = { @@ -430,7 +434,9 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16, 16, 0 }, { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16, 16, 0 }, { "fixup_MICROMIPS_TLS_TPREL_HI16", 16, 16, 0 }, - { "fixup_MICROMIPS_TLS_TPREL_LO16", 16, 16, 0 } + { "fixup_MICROMIPS_TLS_TPREL_LO16", 16, 16, 0 }, + { "fixup_Mips_SUB", 0, 64, 0 }, + { "fixup_MICROMIPS_SUB", 0, 64, 0 } }; if (Kind < FirstTargetFixupKind) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 20c5f3691d2..99ba18c972d 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -329,6 +329,8 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, return ELF::R_MIPS_HIGHER; case Mips::fixup_Mips_HIGHEST: return ELF::R_MIPS_HIGHEST; + case Mips::fixup_Mips_SUB: + return ELF::R_MIPS_SUB; case Mips::fixup_Mips_GOT_HI16: return ELF::R_MIPS_GOT_HI16; case Mips::fixup_Mips_GOT_LO16: @@ -365,6 +367,8 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, return ELF::R_MICROMIPS_TLS_TPREL_HI16; case Mips::fixup_MICROMIPS_TLS_TPREL_LO16: return ELF::R_MICROMIPS_TLS_TPREL_LO16; + case Mips::fixup_MICROMIPS_SUB: + return ELF::R_MICROMIPS_SUB; } llvm_unreachable("invalid fixup kind!"); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h index b4d8e949465..149296212ec 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -209,6 +209,10 @@ namespace Mips { // resulting in - R_MICROMIPS_TLS_TPREL_LO16 fixup_MICROMIPS_TLS_TPREL_LO16, + // resulting in - R_MIPS_SUB/R_MICROMIPS_SUB + fixup_Mips_SUB, + fixup_MICROMIPS_SUB, + // Marker LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp index 1ce8f07092b..2c01f919bef 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp @@ -49,6 +49,7 @@ MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple) { SupportsDebugInformation = true; ExceptionsType = ExceptionHandling::DwarfCFI; DwarfRegNumForCFI = true; + HasMipsExpressions = true; // Enable IAS by default for O32. if (TheTriple.getArch() == Triple::mips || diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index c15c8a929bf..4cc55f86a99 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -637,7 +637,6 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, Mips::Fixups FixupKind = Mips::Fixups(0); switch (MipsExpr->getKind()) { - case MipsMCExpr::MEK_NEG: case MipsMCExpr::MEK_None: case MipsMCExpr::MEK_Special: llvm_unreachable("Unhandled fixup kind!"); @@ -735,6 +734,10 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 : Mips::fixup_Mips_TPREL_LO; break; + case MipsMCExpr::MEK_NEG: + FixupKind = + isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; + break; } Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); return 0; |