diff options
author | Daniel Sanders <daniel.sanders@imgtec.com> | 2015-09-22 10:50:09 +0000 |
---|---|---|
committer | Daniel Sanders <daniel.sanders@imgtec.com> | 2015-09-22 10:50:09 +0000 |
commit | f173dda0e221fb00e95bf9a223bb61e814866bde (patch) | |
tree | 100157d38922ada76c69fcf5f7fb6a2374532a4b /llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | |
parent | 254f3877238509dbad3bb7247b4bff5d49f5c175 (diff) | |
download | bcm5719-llvm-f173dda0e221fb00e95bf9a223bb61e814866bde.tar.gz bcm5719-llvm-f173dda0e221fb00e95bf9a223bb61e814866bde.zip |
[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
Diffstat (limited to 'llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
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(); |