diff options
author | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2011-02-21 03:42:44 +0000 |
---|---|---|
committer | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2011-02-21 03:42:44 +0000 |
commit | a82203f8757e617f26b9c4196c10ba0063c76a03 (patch) | |
tree | b612ee24c7bd9e57b4d022b91363449fb88206f2 /llvm/lib/Target/Sparc/DelaySlotFiller.cpp | |
parent | 66242b85f019c3a99cf85690549a91df6a4946a0 (diff) | |
download | llvm-a82203f8757e617f26b9c4196c10ba0063c76a03.zip llvm-a82203f8757e617f26b9c4196c10ba0063c76a03.tar.gz llvm-a82203f8757e617f26b9c4196c10ba0063c76a03.tar.bz2 |
Generate correct Sparc32 ABI compliant code for functions that return a struct.
llvm-svn: 126108
Diffstat (limited to 'llvm/lib/Target/Sparc/DelaySlotFiller.cpp')
-rw-r--r-- | llvm/lib/Target/Sparc/DelaySlotFiller.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/llvm/lib/Target/Sparc/DelaySlotFiller.cpp b/llvm/lib/Target/Sparc/DelaySlotFiller.cpp index ee29275..4b12852 100644 --- a/llvm/lib/Target/Sparc/DelaySlotFiller.cpp +++ b/llvm/lib/Target/Sparc/DelaySlotFiller.cpp @@ -79,6 +79,7 @@ namespace { MachineBasicBlock::iterator findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot); + bool needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize); }; char Filler::ID = 0; @@ -91,6 +92,7 @@ FunctionPass *llvm::createSparcDelaySlotFillerPass(TargetMachine &tm) { return new Filler(tm); } + /// runOnMachineBasicBlock - Fill in delay slots for the given basic block. /// We assume there is only one delay slot per delayed instruction. /// @@ -112,6 +114,13 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { BuildMI(MBB, ++J, I->getDebugLoc(), TII->get(SP::NOP)); else MBB.splice(++J, &MBB, D); + unsigned structSize = 0; + if (needsUnimp(I, structSize)) { + MachineBasicBlock::iterator J = I; + ++J; //skip the delay filler. + BuildMI(MBB, ++J, I->getDebugLoc(), + TII->get(SP::UNIMP)).addImm(structSize); + } } return Changed; } @@ -287,6 +296,28 @@ bool Filler::isDelayFiller(MachineBasicBlock &MBB, { if (candidate == MBB.begin()) return false; + if (candidate->getOpcode() == SP::UNIMP) + return true; const TargetInstrDesc &prevdesc = (--candidate)->getDesc(); return prevdesc.hasDelaySlot(); } + +bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize) +{ + if (!I->getDesc().isCall()) + return false; + + unsigned structSizeOpNum = 0; + switch (I->getOpcode()) { + default: llvm_unreachable("Unknown call opcode."); + case SP::CALL: structSizeOpNum = 1; break; + case SP::JMPLrr: + case SP::JMPLri: structSizeOpNum = 2; break; + } + + const MachineOperand &MO = I->getOperand(structSizeOpNum); + if (!MO.isImm()) + return false; + StructSize = MO.getImm(); + return true; +} |