diff options
| -rw-r--r-- | gnu/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 54 | ||||
| -rw-r--r-- | gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 34 | ||||
| -rw-r--r-- | gnu/llvm/lib/Target/Mips/MipsTargetStreamer.h | 5 |
3 files changed, 68 insertions, 25 deletions
diff --git a/gnu/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/gnu/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 0f618d6a5f6..271fbace41b 100644 --- a/gnu/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/gnu/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -145,6 +145,7 @@ class MipsAsmParser : public MCTargetAsmParser { bool IsPicEnabled; bool IsCpRestoreSet; int CpRestoreOffset; + unsigned GPRegister; unsigned CpSaveLocation; /// If true, then CpSaveLocation is a register, otherwise it's an offset. bool CpSaveLocationIsRegister; @@ -326,6 +327,7 @@ class MipsAsmParser : public MCTargetAsmParser { bool parseSetFeature(uint64_t Feature); bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup. bool parseDirectiveCpLoad(SMLoc Loc); + bool parseDirectiveCpLocal(SMLoc Loc); bool parseDirectiveCpRestore(SMLoc Loc); bool parseDirectiveCPSetup(); bool parseDirectiveCPReturn(); @@ -519,6 +521,7 @@ public: IsCpRestoreSet = false; CpRestoreOffset = -1; + GPRegister = ABI.GetGlobalPtr(); const Triple &TheTriple = sti.getTargetTriple(); IsLittleEndian = TheTriple.isLittleEndian(); @@ -2059,7 +2062,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext()); TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, - Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc, + GPRegister, MCOperand::createExpr(GotDispRelocExpr), IDLoc, STI); } } else { @@ -2070,7 +2073,8 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, const MCExpr *Call16RelocExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext()); - TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP, + TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, + GPRegister, MCOperand::createExpr(Call16RelocExpr), IDLoc, STI); } @@ -2889,7 +2893,7 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr, ELF::STB_LOCAL))) { const MCExpr *CallExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext()); - TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(), + TOut.emitRRX(Mips::LW, DstReg, GPRegister, MCOperand::createExpr(CallExpr), IDLoc, STI); return false; } @@ -2929,7 +2933,7 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr, TmpReg = ATReg; } - TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(), + TOut.emitRRX(Mips::LW, TmpReg, GPRegister, MCOperand::createExpr(GotExpr), IDLoc, STI); if (LoExpr) @@ -2965,7 +2969,7 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr, ELF::STB_LOCAL))) { const MCExpr *CallExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext()); - TOut.emitRRX(Mips::LD, DstReg, ABI.GetGlobalPtr(), + TOut.emitRRX(Mips::LD, DstReg, GPRegister, MCOperand::createExpr(CallExpr), IDLoc, STI); return false; } @@ -3008,7 +3012,7 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr, TmpReg = ATReg; } - TOut.emitRRX(Mips::LD, TmpReg, ABI.GetGlobalPtr(), + TOut.emitRRX(Mips::LD, TmpReg, GPRegister, MCOperand::createExpr(GotExpr), IDLoc, STI); if (LoExpr) @@ -3239,10 +3243,10 @@ bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext()); if(isABI_O32() || isABI_N32()) { - TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr), + TOut.emitRRX(Mips::LW, ATReg, GPRegister, MCOperand::createExpr(GotExpr), IDLoc, STI); } else { //isABI_N64() - TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr), + TOut.emitRRX(Mips::LD, ATReg, GPRegister, MCOperand::createExpr(GotExpr), IDLoc, STI); } } else { //!IsPicEnabled @@ -7127,6 +7131,36 @@ bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) { return false; } +bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) { + if (!isABI_N32() && !isABI_N64()) { + reportParseError(".cplocal is allowed only in N32 or N64 mode"); + return false; + } + + SmallVector<std::unique_ptr<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; + } + + // If this is not the end of the statement, report an error. + if (getLexer().isNot(AsmToken::EndOfStatement)) { + reportParseError("unexpected token, expected end of statement"); + return false; + } + + GPRegister = RegOpnd.getGPR32Reg(); + getTargetStreamer().setGPReg(GPRegister); + return false; +} + bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) { MCAsmParser &Parser = getParser(); @@ -7973,6 +8007,10 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { parseDirectiveCpLoad(DirectiveID.getLoc()); return false; } + if (IDVal == ".cplocal") { + parseDirectiveCpLocal(DirectiveID.getLoc()); + return false; + } if (IDVal == ".cprestore") { parseDirectiveCpRestore(DirectiveID.getLoc()); return false; diff --git a/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 58f9717e1cc..bb2152845e2 100644 --- a/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/gnu/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -38,6 +38,7 @@ static cl::opt<bool> RoundSectionSizes( MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) : MCTargetStreamer(S), ModuleDirectiveAllowed(true) { GPRInfoSet = FPRInfoSet = FrameInfoSet = false; + GPReg = Mips::GP; } void MipsTargetStreamer::emitDirectiveSetMicroMips() {} void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {} @@ -258,8 +259,7 @@ void MipsTargetStreamer::emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI) { /// Emit the $gp restore operation for .cprestore. void MipsTargetStreamer::emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI) { - emitLoadWithImmOffset(Mips::LW, Mips::GP, Mips::SP, Offset, Mips::GP, IDLoc, - STI); + emitLoadWithImmOffset(Mips::LW, GPReg, Mips::SP, Offset, GPReg, IDLoc, STI); } /// Emit a store instruction with an immediate offset. @@ -1133,7 +1133,7 @@ void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) { MCInst TmpInst; TmpInst.setOpcode(Mips::LUi); - TmpInst.addOperand(MCOperand::createReg(Mips::GP)); + TmpInst.addOperand(MCOperand::createReg(GPReg)); const MCExpr *HiSym = MipsMCExpr::create( MipsMCExpr::MEK_HI, MCSymbolRefExpr::create("_gp_disp", MCSymbolRefExpr::VK_None, @@ -1145,8 +1145,8 @@ void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) { TmpInst.clear(); TmpInst.setOpcode(Mips::ADDiu); - TmpInst.addOperand(MCOperand::createReg(Mips::GP)); - TmpInst.addOperand(MCOperand::createReg(Mips::GP)); + TmpInst.addOperand(MCOperand::createReg(GPReg)); + TmpInst.addOperand(MCOperand::createReg(GPReg)); const MCExpr *LoSym = MipsMCExpr::create( MipsMCExpr::MEK_LO, MCSymbolRefExpr::create("_gp_disp", MCSymbolRefExpr::VK_None, @@ -1158,8 +1158,8 @@ void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) { TmpInst.clear(); TmpInst.setOpcode(Mips::ADDu); - TmpInst.addOperand(MCOperand::createReg(Mips::GP)); - TmpInst.addOperand(MCOperand::createReg(Mips::GP)); + TmpInst.addOperand(MCOperand::createReg(GPReg)); + TmpInst.addOperand(MCOperand::createReg(GPReg)); TmpInst.addOperand(MCOperand::createReg(RegNo)); getStreamer().EmitInstruction(TmpInst, STI); @@ -1182,7 +1182,7 @@ bool MipsTargetELFStreamer::emitDirectiveCpRestore( return true; // Store the $gp on the stack. - emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, Offset, GetATReg, IDLoc, + emitStoreWithImmOffset(Mips::SW, GPReg, Mips::SP, Offset, GetATReg, IDLoc, STI); return true; } @@ -1203,10 +1203,10 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, // Either store the old $gp in a register or on the stack if (IsReg) { // move $save, $gpreg - emitRRR(Mips::OR64, RegOrOffset, Mips::GP, Mips::ZERO, SMLoc(), &STI); + emitRRR(Mips::OR64, RegOrOffset, GPReg, Mips::ZERO, SMLoc(), &STI); } else { // sd $gpreg, offset($sp) - emitRRI(Mips::SD, Mips::GP, Mips::SP, RegOrOffset, SMLoc(), &STI); + emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI); } if (getABI().IsN32()) { @@ -1219,10 +1219,10 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, MCA.getContext()); // lui $gp, %hi(__gnu_local_gp) - emitRX(Mips::LUi, Mips::GP, MCOperand::createExpr(HiExpr), SMLoc(), &STI); + emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI); // addiu $gp, $gp, %lo(__gnu_local_gp) - emitRRX(Mips::ADDiu, Mips::GP, Mips::GP, MCOperand::createExpr(LoExpr), + emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(), &STI); return; @@ -1236,14 +1236,14 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, MCA.getContext()); // lui $gp, %hi(%neg(%gp_rel(funcSym))) - emitRX(Mips::LUi, Mips::GP, MCOperand::createExpr(HiExpr), SMLoc(), &STI); + emitRX(Mips::LUi, GPReg, MCOperand::createExpr(HiExpr), SMLoc(), &STI); // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym))) - emitRRX(Mips::ADDiu, Mips::GP, Mips::GP, MCOperand::createExpr(LoExpr), + emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(), &STI); // daddu $gp, $gp, $funcreg - emitRRR(Mips::DADDu, Mips::GP, Mips::GP, RegNo, SMLoc(), &STI); + emitRRR(Mips::DADDu, GPReg, GPReg, RegNo, SMLoc(), &STI); } void MipsTargetELFStreamer::emitDirectiveCpreturn(unsigned SaveLocation, @@ -1256,12 +1256,12 @@ void MipsTargetELFStreamer::emitDirectiveCpreturn(unsigned SaveLocation, // Either restore the old $gp from a register or on the stack if (SaveLocationIsRegister) { Inst.setOpcode(Mips::OR); - Inst.addOperand(MCOperand::createReg(Mips::GP)); + Inst.addOperand(MCOperand::createReg(GPReg)); Inst.addOperand(MCOperand::createReg(SaveLocation)); Inst.addOperand(MCOperand::createReg(Mips::ZERO)); } else { Inst.setOpcode(Mips::LD); - Inst.addOperand(MCOperand::createReg(Mips::GP)); + Inst.addOperand(MCOperand::createReg(GPReg)); Inst.addOperand(MCOperand::createReg(Mips::SP)); Inst.addOperand(MCOperand::createImm(SaveLocation)); } diff --git a/gnu/llvm/lib/Target/Mips/MipsTargetStreamer.h b/gnu/llvm/lib/Target/Mips/MipsTargetStreamer.h index a282366f6d4..5bca0573680 100644 --- a/gnu/llvm/lib/Target/Mips/MipsTargetStreamer.h +++ b/gnu/llvm/lib/Target/Mips/MipsTargetStreamer.h @@ -185,6 +185,10 @@ public: return *ABI; } + void setGPReg(unsigned GPReg) { + this->GPReg = GPReg; + } + protected: llvm::Optional<MipsABIInfo> ABI; MipsABIFlagsSection ABIFlagsSection; @@ -199,6 +203,7 @@ protected: bool FrameInfoSet; int FrameOffset; + unsigned GPReg; unsigned FrameReg; unsigned ReturnReg; |
