diff options
| author | Matheus Almeida <matheus.almeida@imgtec.com> | 2014-04-30 11:28:42 +0000 |
|---|---|---|
| committer | Matheus Almeida <matheus.almeida@imgtec.com> | 2014-04-30 11:28:42 +0000 |
| commit | 525bc4f708c99546bb634e285c706cc3cd61d659 (patch) | |
| tree | a37ad54f92a05206deea285688eebbfdb56a5552 /llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | |
| parent | c0284d118f730e343d75762118385593e5aa6ce4 (diff) | |
| download | bcm5719-llvm-525bc4f708c99546bb634e285c706cc3cd61d659.tar.gz bcm5719-llvm-525bc4f708c99546bb634e285c706cc3cd61d659.zip | |
[mips] Add support for .cpload.
Summary:
This directive is used for setting up $gp in the beginning of a function.
It expands to three instructions if PIC is enabled:
lui $gp, %hi(_gp_disp)
addui $gp, $gp, %lo(_gp_disp)
addu $gp, $gp, $reg
_gp_disp is a special symbol that the linker sets to the distance between
the lui instruction and the context pointer (_gp).
Reviewers: dsanders
Reviewed By: dsanders
Differential Revision: http://reviews.llvm.org/D3480
llvm-svn: 207637
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
| -rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 4bc681b7a2d..4449cc20c98 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -137,6 +137,7 @@ class MipsAsmParser : public MCTargetAsmParser { SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd); bool reportParseError(StringRef ErrorMsg); + bool reportParseError(SMLoc Loc, StringRef ErrorMsg); bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); bool parseRelocOperand(const MCExpr *&Res); @@ -145,6 +146,7 @@ class MipsAsmParser : public MCTargetAsmParser { bool isEvaluated(const MCExpr *Expr); bool parseSetFeature(uint64_t Feature); + bool parseDirectiveCPLoad(SMLoc Loc); bool parseDirectiveCPSetup(); bool parseDirectiveNaN(); bool parseDirectiveSet(); @@ -2083,6 +2085,10 @@ bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { return Error(Loc, ErrorMsg); } +bool MipsAsmParser::reportParseError(SMLoc Loc, StringRef ErrorMsg) { + return Error(Loc, ErrorMsg); +} + bool MipsAsmParser::parseSetNoAtDirective() { // Line should look like: ".set noat". // set at reg to 0. @@ -2301,6 +2307,30 @@ bool MipsAsmParser::eatComma(StringRef ErrorStr) { return true; } +bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) { + if (Options.isReorder()) + Warning(Loc, ".cpload in reorder section"); + + // FIXME: Warn if cpload is used in Mips16 mode. + + SmallVector<MCParsedAsmOperand *, 1> Reg; + OperandMatchResultTy ResTy = ParseAnyRegister(Reg); + if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { + reportParseError("expected register containing function address"); + return false; + } + + MipsOperand *RegOpnd = static_cast<MipsOperand *>(Reg[0]); + if (!RegOpnd->isGPRAsmReg()) { + reportParseError(RegOpnd->getStartLoc(), "invalid register"); + return false; + } + + getTargetStreamer().emitDirectiveCpload(RegOpnd->getGPR32Reg()); + delete RegOpnd; + return false; +} + bool MipsAsmParser::parseDirectiveCPSetup() { unsigned FuncReg; unsigned Save; @@ -2550,6 +2580,8 @@ bool MipsAsmParser::parseDirectiveOption() { bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { StringRef IDVal = DirectiveID.getString(); + if (IDVal == ".cpload") + return parseDirectiveCPLoad(DirectiveID.getLoc()); if (IDVal == ".dword") { parseDataDirective(8, DirectiveID.getLoc()); return false; |

