diff options
| author | Daniel Sanders <daniel.sanders@imgtec.com> | 2016-06-14 10:13:47 +0000 |
|---|---|---|
| committer | Daniel Sanders <daniel.sanders@imgtec.com> | 2016-06-14 10:13:47 +0000 |
| commit | e858136d915ea23c5f2c7e44f1988e83029164f3 (patch) | |
| tree | c4facd230d217ba4ac69472386ad49aab484f46d /llvm/lib/Target/Mips | |
| parent | cf1165b86ec95268abf51b0e46e716e281f098d8 (diff) | |
| download | bcm5719-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.cpp | 55 |
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, |

