summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2016-06-14 10:13:47 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2016-06-14 10:13:47 +0000
commite858136d915ea23c5f2c7e44f1988e83029164f3 (patch)
treec4facd230d217ba4ac69472386ad49aab484f46d /llvm/lib/Target/Mips
parentcf1165b86ec95268abf51b0e46e716e281f098d8 (diff)
downloadbcm5719-llvm-e858136d915ea23c5f2c7e44f1988e83029164f3.tar.gz
bcm5719-llvm-e858136d915ea23c5f2c7e44f1988e83029164f3.zip
[mips][ias] Implement one N32 case (of two) for .cpsetup.
This patch implements the N32 case where -mno-shared is in effect. The case where -mshared is in effect will be added later since doing that now requires additional changes to how we handle %hi(%neg(%gp_rel(foo))) expressions to emit the three relocations as three relocations (currently only one of the three would be emitted) which then requires further changes to our MCFixup handling. While we could fix both cases together, fixing the -mno-shared case allows us to fix the ELFCLASS bug (where N32 incorrectly uses ELFCLASS64 instead of ELFCLASS32) in a way that allows cpsetup.s to check for a correct output instead of another incorrect output. Reviewers: sdardis Subscribers: dsanders, llvm-commits, sdardis Differential Revision: http://reviews.llvm.org/D21131 llvm-svn: 272652
Diffstat (limited to 'llvm/lib/Target/Mips')
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp55
1 files changed, 27 insertions, 28 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index 45296091e28..7f79eb400f5 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -1077,25 +1077,38 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
return;
+ forbidModuleDirective();
+
MCAssembler &MCA = getStreamer().getAssembler();
MCInst Inst;
// Either store the old $gp in a register or on the stack
if (IsReg) {
// move $save, $gpreg
- Inst.setOpcode(Mips::OR64);
- Inst.addOperand(MCOperand::createReg(RegOrOffset));
- Inst.addOperand(MCOperand::createReg(Mips::GP));
- Inst.addOperand(MCOperand::createReg(Mips::ZERO));
+ emitRRR(Mips::OR64, RegOrOffset, Mips::GP, Mips::ZERO, SMLoc(), &STI);
} else {
// sd $gpreg, offset($sp)
- Inst.setOpcode(Mips::SD);
- Inst.addOperand(MCOperand::createReg(Mips::GP));
- Inst.addOperand(MCOperand::createReg(Mips::SP));
- Inst.addOperand(MCOperand::createImm(RegOrOffset));
+ emitRRI(Mips::SD, Mips::GP, Mips::SP, RegOrOffset, SMLoc(), &STI);
+ }
+
+ if (getABI().IsN32()) {
+ MCSymbol *GPSym = MCA.getContext().getOrCreateSymbol("__gnu_local_gp");
+ const MipsMCExpr *HiExpr = MipsMCExpr::create(
+ MipsMCExpr::MEK_HI, MCSymbolRefExpr::create(GPSym, MCA.getContext()),
+ MCA.getContext());
+ const MipsMCExpr *LoExpr = MipsMCExpr::create(
+ MipsMCExpr::MEK_LO, MCSymbolRefExpr::create(GPSym, MCA.getContext()),
+ MCA.getContext());
+
+ // lui $gp, %hi(__gnu_local_gp)
+ emitRX(Mips::LUi, Mips::GP, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
+
+ // addiu $gp, $gp, %lo(__gnu_local_gp)
+ emitRRX(Mips::ADDiu, Mips::GP, Mips::GP, MCOperand::createExpr(LoExpr),
+ SMLoc(), &STI);
+
+ return;
}
- getStreamer().EmitInstruction(Inst, STI);
- Inst.clear();
const MipsMCExpr *HiExpr = MipsMCExpr::createGpOff(
MipsMCExpr::MEK_HI, MCSymbolRefExpr::create(&Sym, MCA.getContext()),
@@ -1105,28 +1118,14 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
MCA.getContext());
// lui $gp, %hi(%neg(%gp_rel(funcSym)))
- Inst.setOpcode(Mips::LUi);
- Inst.addOperand(MCOperand::createReg(Mips::GP));
- Inst.addOperand(MCOperand::createExpr(HiExpr));
- getStreamer().EmitInstruction(Inst, STI);
- Inst.clear();
+ emitRX(Mips::LUi, Mips::GP, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
// addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
- Inst.setOpcode(Mips::ADDiu);
- Inst.addOperand(MCOperand::createReg(Mips::GP));
- Inst.addOperand(MCOperand::createReg(Mips::GP));
- Inst.addOperand(MCOperand::createExpr(LoExpr));
- getStreamer().EmitInstruction(Inst, STI);
- Inst.clear();
+ emitRRX(Mips::ADDiu, Mips::GP, Mips::GP, MCOperand::createExpr(LoExpr),
+ SMLoc(), &STI);
// daddu $gp, $gp, $funcreg
- Inst.setOpcode(Mips::DADDu);
- Inst.addOperand(MCOperand::createReg(Mips::GP));
- Inst.addOperand(MCOperand::createReg(Mips::GP));
- Inst.addOperand(MCOperand::createReg(RegNo));
- getStreamer().EmitInstruction(Inst, STI);
-
- forbidModuleDirective();
+ emitRRR(Mips::DADDu, Mips::GP, Mips::GP, RegNo, SMLoc(), &STI);
}
void MipsTargetELFStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
OpenPOWER on IntegriCloud