Prologue / epilogue emission

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75940 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anton Korobeynikov 2009-07-16 13:49:49 +00:00
parent 51f613fb2b
commit 3c98c616c5
3 changed files with 92 additions and 3 deletions

View File

@ -178,7 +178,7 @@ def laaddr : Operand<i64>,
//
// FIXME: Provide proper encoding!
let isReturn = 1, isTerminator = 1 in {
let isReturn = 1, isTerminator = 1, Uses = [R14D] in {
def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
}

View File

@ -18,6 +18,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/BitVector.h"
@ -120,13 +121,100 @@ void SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MI.getOperand(i+1).ChangeToImmediate(Offset);
}
/// emitSPUpdate - Emit a series of instructions to increment / decrement the
/// stack pointer by a constant value.
static
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
int64_t NumBytes, const TargetInstrInfo &TII) {
// FIXME: Handle different stack sizes here.
bool isSub = NumBytes < 0;
uint64_t Offset = isSub ? -NumBytes : NumBytes;
unsigned Opc = SystemZ::ADD64ri16;
uint64_t Chunk = (1LL << 15) - 1;
DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
DebugLoc::getUnknownLoc());
while (Offset) {
uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
MachineInstr *MI =
BuildMI(MBB, MBBI, DL, TII.get(Opc), SystemZ::R15D)
.addReg(SystemZ::R15D).addImm((isSub ? -(int64_t)ThisVal : ThisVal));
// The PSW implicit def is dead.
MI->getOperand(3).setIsDead();
Offset -= ThisVal;
}
}
void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const {
// Nothing here yet
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
DebugLoc::getUnknownLoc());
// Get the number of bytes to allocate from the FrameInfo.
uint64_t StackSize = MFI->getStackSize();
// FIXME: Skip the callee-saved push instructions.
if (MBBI != MBB.end())
DL = MBBI->getDebugLoc();
uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
if (StackSize) // adjust stack pointer: R15 -= numbytes
emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, TII);
if (hasFP(MF)) {
// Update R11 with the new base value...
BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D)
.addReg(SystemZ::R15D);
// Mark the FramePtr as live-in in every block except the entry.
for (MachineFunction::iterator I = next(MF.begin()), E = MF.end();
I != E; ++I)
I->addLiveIn(SystemZ::R11D);
}
}
void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
// Nothing here yet
const MachineFrameInfo *MFI = MF.getFrameInfo();
const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
MachineBasicBlock::iterator MBBI = prior(MBB.end());
unsigned RetOpcode = MBBI->getOpcode();
DebugLoc DL = MBBI->getDebugLoc();
switch (RetOpcode) {
case SystemZ::RET: break; // These are ok
default:
assert(0 && "Can only insert epilog into returning blocks");
}
// Get the number of bytes to allocate from the FrameInfo
uint64_t StackSize = MFI->getStackSize();
uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
// Skip the callee-saved regs load instructions.
MachineBasicBlock::iterator LastCSPop = MBBI;
while (MBBI != MBB.begin()) {
MachineBasicBlock::iterator PI = prior(MBBI);
if (!PI->getDesc().isTerminator())
break;
--MBBI;
}
DL = MBBI->getDebugLoc();
if (MFI->hasVarSizedObjects()) {
assert(0 && "Not implemented yet!");
} else {
// adjust stack pointer back: R15 += numbytes
if (StackSize)
emitSPUpdate(MBB, MBBI, NumBytes, TII);
}
}
unsigned SystemZRegisterInfo::getRARegister() const {

View File

@ -1,5 +1,6 @@
; RUN: llvm-as < %s | llc | grep 160 | count 1
; RUN: llvm-as < %s | llc | grep 328 | count 1
; RUN: llvm-as < %s | llc | grep 168 | count 2
target datalayout = "E-p:64:64:64-i1:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128"
target triple = "s390x-unknown-linux-gnu"