diff options
author | Eli Bendersky <eliben@google.com> | 2013-02-21 20:05:00 +0000 |
---|---|---|
committer | Eli Bendersky <eliben@google.com> | 2013-02-21 20:05:00 +0000 |
commit | 700ed80d3da5e98e05ceb90e9bfb66058581a6db (patch) | |
tree | 9e56e69a7368d120c5de167f978f3b37cc310815 /lib/Target/XCore/XCoreFrameLowering.cpp | |
parent | fece442c697eb29f14b4718bdafa3a97d545b476 (diff) | |
download | external_llvm-700ed80d3da5e98e05ceb90e9bfb66058581a6db.zip external_llvm-700ed80d3da5e98e05ceb90e9bfb66058581a6db.tar.gz external_llvm-700ed80d3da5e98e05ceb90e9bfb66058581a6db.tar.bz2 |
Move the eliminateCallFramePseudoInstr method from TargetRegisterInfo
to TargetFrameLowering, where it belongs. Incidentally, this allows us
to delete some duplicated (and slightly different!) code in TRI.
There are potentially other layering problems that can be cleaned up
as a result, or in a similar manner.
The refactoring was OK'd by Anton Korobeynikov on llvmdev.
Note: this touches the target interfaces, so out-of-tree targets may
be affected.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175788 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/XCore/XCoreFrameLowering.cpp')
-rw-r--r-- | lib/Target/XCore/XCoreFrameLowering.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/Target/XCore/XCoreFrameLowering.cpp b/lib/Target/XCore/XCoreFrameLowering.cpp index bb9c77a..019c457 100644 --- a/lib/Target/XCore/XCoreFrameLowering.cpp +++ b/lib/Target/XCore/XCoreFrameLowering.cpp @@ -332,6 +332,58 @@ bool XCoreFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, return true; } +// This function eliminates ADJCALLSTACKDOWN, +// ADJCALLSTACKUP pseudo instructions +void XCoreFrameLowering:: +eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const { + const XCoreInstrInfo &TII = + *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); + if (!hasReservedCallFrame(MF)) { + // Turn the adjcallstackdown instruction into 'extsp <amt>' and the + // adjcallstackup instruction into 'ldaw sp, sp[<amt>]' + MachineInstr *Old = I; + uint64_t Amount = Old->getOperand(0).getImm(); + if (Amount != 0) { + // We need to keep the stack aligned properly. To do this, we round the + // amount of space needed for the outgoing arguments up to the next + // alignment boundary. + unsigned Align = getStackAlignment(); + Amount = (Amount+Align-1)/Align*Align; + + assert(Amount%4 == 0); + Amount /= 4; + + bool isU6 = isImmU6(Amount); + if (!isU6 && !isImmU16(Amount)) { + // FIX could emit multiple instructions in this case. +#ifndef NDEBUG + errs() << "eliminateCallFramePseudoInstr size too big: " + << Amount << "\n"; +#endif + llvm_unreachable(0); + } + + MachineInstr *New; + if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) { + int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; + New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode)) + .addImm(Amount); + } else { + assert(Old->getOpcode() == XCore::ADJCALLSTACKUP); + int Opcode = isU6 ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; + New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP) + .addImm(Amount); + } + + // Replace the pseudo instruction with a new instruction... + MBB.insert(I, New); + } + } + + MBB.erase(I); +} + void XCoreFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS) const { |