diff options
Diffstat (limited to 'llvm/lib/Target/Sparc/SparcAsmPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/Sparc/SparcAsmPrinter.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp index cca624e..215a8ea 100644 --- a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/SparcInstPrinter.h" #include "MCTargetDesc/SparcMCExpr.h" +#include "MCTargetDesc/SparcMCTargetDesc.h" #include "MCTargetDesc/SparcTargetStreamer.h" #include "Sparc.h" #include "SparcInstrInfo.h" @@ -111,6 +112,15 @@ static void EmitCall(MCStreamer &OutStreamer, OutStreamer.emitInstruction(CallInst, STI); } +static void EmitRDPC(MCStreamer &OutStreamer, MCOperand &RD, + const MCSubtargetInfo &STI) { + MCInst RDPCInst; + RDPCInst.setOpcode(SP::RDASR); + RDPCInst.addOperand(RD); + RDPCInst.addOperand(MCOperand::createReg(SP::ASR5)); + OutStreamer.emitInstruction(RDPCInst, STI); +} + static void EmitSETHI(MCStreamer &OutStreamer, MCOperand &Imm, MCOperand &RD, const MCSubtargetInfo &STI) @@ -226,7 +236,7 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, MCOperand RegO7 = MCOperand::createReg(SP::O7); // <StartLabel>: - // call <EndLabel> + // <GET-PC> // This will be either `call <EndLabel>` or `rd %pc, %o7`. // <SethiLabel>: // sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO> // <EndLabel>: @@ -234,8 +244,17 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, // add <MO>, %o7, <MO> OutStreamer->emitLabel(StartLabel); - MCOperand Callee = createPCXCallOP(EndLabel, OutContext); - EmitCall(*OutStreamer, Callee, STI); + if (!STI.getTargetTriple().isSPARC64() || + STI.hasFeature(Sparc::TuneSlowRDPC)) { + MCOperand Callee = createPCXCallOP(EndLabel, OutContext); + EmitCall(*OutStreamer, Callee, STI); + } else { + // TODO find out whether it is possible to store PC + // in other registers, to enable leaf function optimization. + // (On the other hand, approx. over 97.8% of GETPCXes happen + // in non-leaf functions, so would this be worth the effort?) + EmitRDPC(*OutStreamer, RegO7, STI); + } OutStreamer->emitLabel(SethiLabel); MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC22, GOTLabel, StartLabel, SethiLabel, |