diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 76 |
1 files changed, 51 insertions, 25 deletions
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index a46f84bd1c9c..e3bdb3b140a8 100644 --- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -1,9 +1,8 @@ //===-- MipsTargetStreamer.cpp - Mips Target Streamer Methods -------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -12,7 +11,7 @@ //===----------------------------------------------------------------------===// #include "MipsTargetStreamer.h" -#include "InstPrinter/MipsInstPrinter.h" +#include "MipsInstPrinter.h" #include "MCTargetDesc/MipsABIInfo.h" #include "MipsELFStreamer.h" #include "MipsMCExpr.h" @@ -36,7 +35,7 @@ static cl::opt<bool> RoundSectionSizes( } // end anonymous namespace MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) - : MCTargetStreamer(S), ModuleDirectiveAllowed(true) { + : MCTargetStreamer(S), GPReg(Mips::GP), ModuleDirectiveAllowed(true) { GPRInfoSet = FPRInfoSet = FrameInfoSet = false; } void MipsTargetStreamer::emitDirectiveSetMicroMips() {} @@ -107,6 +106,23 @@ void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetDspr2() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {} +void MipsTargetStreamer::emitDirectiveCpLocal(unsigned RegNo) { + // .cplocal $reg + // This directive forces to use the alternate register for context pointer. + // For example + // .cplocal $4 + // jal foo + // expands to + // ld $25, %call16(foo)($4) + // jalr $25 + + if (!getABI().IsN32() && !getABI().IsN64()) + return; + + GPReg = RegNo; + + forbidModuleDirective(); +} bool MipsTargetStreamer::emitDirectiveCpRestore( int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI) { @@ -258,8 +274,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. @@ -666,6 +681,12 @@ void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) { forbidModuleDirective(); } +void MipsTargetAsmStreamer::emitDirectiveCpLocal(unsigned RegNo) { + OS << "\t.cplocal\t$" + << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n"; + MipsTargetStreamer::emitDirectiveCpLocal(RegNo); +} + bool MipsTargetAsmStreamer::emitDirectiveCpRestore( int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI) { @@ -1136,7 +1157,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, @@ -1148,8 +1169,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, @@ -1161,14 +1182,19 @@ 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); forbidModuleDirective(); } +void MipsTargetELFStreamer::emitDirectiveCpLocal(unsigned RegNo) { + if (Pic) + MipsTargetStreamer::emitDirectiveCpLocal(RegNo); +} + bool MipsTargetELFStreamer::emitDirectiveCpRestore( int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI) { @@ -1185,7 +1211,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; } @@ -1206,10 +1232,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()) { @@ -1222,11 +1248,11 @@ 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), - SMLoc(), &STI); + emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(), + &STI); return; } @@ -1239,14 +1265,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), - SMLoc(), &STI); + 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, @@ -1259,12 +1285,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)); } |