From f173dda0e221fb00e95bf9a223bb61e814866bde Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Tue, 22 Sep 2015 10:50:09 +0000 Subject: [mips][ias] Implement .cpreturn directive. Summary: Based on a patch by David Chisnall. I've modified the original patch as follows: * Moved the expansion to the TargetStreamers so that the directive isn't expanded when emitting assembly. * Fixed an operand order bug. * Changed the move instructions from DADDu to OR to match recent changes to GAS. Reviewers: vkalintiris Subscribers: llvm-commits, emaste, seanbruno, theraven Differential Revision: http://reviews.llvm.org/D13017 llvm-svn: 248258 --- .../Mips/MCTargetDesc/MipsTargetStreamer.cpp | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp') diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 4e865663fc0..994126e83b6 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -96,6 +96,8 @@ void MipsTargetStreamer::emitDirectiveCpRestore( void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg) { } +void MipsTargetStreamer::emitDirectiveCpreturn(unsigned SaveLocation, + bool SaveLocationIsRegister) {} void MipsTargetStreamer::emitDirectiveModuleFP() {} @@ -387,6 +389,12 @@ void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo, forbidModuleDirective(); } +void MipsTargetAsmStreamer::emitDirectiveCpreturn(unsigned SaveLocation, + bool SaveLocationIsRegister) { + OS << "\t.cpreturn"; + forbidModuleDirective(); +} + void MipsTargetAsmStreamer::emitDirectiveModuleFP() { OS << "\t.module\tfp="; OS << ABIFlagsSection.getFpABIString(ABIFlagsSection.getFpABI()) << "\n"; @@ -838,6 +846,30 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, forbidModuleDirective(); } +void MipsTargetELFStreamer::emitDirectiveCpreturn(unsigned SaveLocation, + bool SaveLocationIsRegister) { + // Only N32 and N64 emit anything for .cpreturn iff PIC is set. + if (!Pic || !(getABI().IsN32() || getABI().IsN64())) + return; + + MCInst Inst; + // 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(SaveLocation)); + Inst.addOperand(MCOperand::createReg(Mips::ZERO)); + } else { + Inst.setOpcode(Mips::LD); + Inst.addOperand(MCOperand::createReg(Mips::GP)); + Inst.addOperand(MCOperand::createReg(Mips::SP)); + Inst.addOperand(MCOperand::createImm(SaveLocation)); + } + getStreamer().EmitInstruction(Inst, STI); + + forbidModuleDirective(); +} + void MipsTargetELFStreamer::emitMipsAbiFlags() { MCAssembler &MCA = getStreamer().getAssembler(); MCContext &Context = MCA.getContext(); -- cgit v1.2.3