forked from OSchip/llvm-project
parent
b638a8fd73
commit
8695a30066
|
@ -26,7 +26,30 @@ using namespace llvm;
|
||||||
|
|
||||||
SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm)
|
SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm)
|
||||||
: TargetInstrInfoImpl(SystemZInsts, array_lengthof(SystemZInsts)),
|
: TargetInstrInfoImpl(SystemZInsts, array_lengthof(SystemZInsts)),
|
||||||
RI(tm, *this), TM(tm) {}
|
RI(tm, *this), TM(tm) {
|
||||||
|
// Fill the spill offsets map
|
||||||
|
static const unsigned SpillOffsTab[][2] = {
|
||||||
|
{ SystemZ::R2D, 0x10 },
|
||||||
|
{ SystemZ::R3D, 0x18 },
|
||||||
|
{ SystemZ::R4D, 0x20 },
|
||||||
|
{ SystemZ::R5D, 0x28 },
|
||||||
|
{ SystemZ::R6D, 0x30 },
|
||||||
|
{ SystemZ::R7D, 0x38 },
|
||||||
|
{ SystemZ::R8D, 0x40 },
|
||||||
|
{ SystemZ::R9D, 0x48 },
|
||||||
|
{ SystemZ::R10D, 0x50 },
|
||||||
|
{ SystemZ::R11D, 0x58 },
|
||||||
|
{ SystemZ::R12D, 0x60 },
|
||||||
|
{ SystemZ::R13D, 0x68 },
|
||||||
|
{ SystemZ::R14D, 0x70 },
|
||||||
|
{ SystemZ::R15D, 0x78 }
|
||||||
|
};
|
||||||
|
|
||||||
|
RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS);
|
||||||
|
|
||||||
|
for (unsigned i = 0, e = array_lengthof(SpillOffsTab); i != e; ++i)
|
||||||
|
RegSpillOffsets[SpillOffsTab[i][0]] = SpillOffsTab[i][1];
|
||||||
|
}
|
||||||
|
|
||||||
void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
|
@ -117,13 +140,52 @@ bool
|
||||||
SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI) const {
|
||||||
if (CSI.empty())
|
DebugLoc DL = DebugLoc::getUnknownLoc();
|
||||||
return false;
|
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
||||||
|
|
||||||
MachineFunction &MF = *MBB.getParent();
|
MachineFunction &MF = *MBB.getParent();
|
||||||
SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
|
SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
|
||||||
MFI->setCalleeSavedFrameSize(CSI.size() * 8);
|
MFI->setCalleeSavedFrameSize(CSI.size() * 8);
|
||||||
|
|
||||||
|
// Scan the callee-saved and find the bounds of register spill area.
|
||||||
|
unsigned LowReg = 0, HighReg = 0, StartOffset = -1U, EndOffset = 0;
|
||||||
|
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||||
|
unsigned Reg = CSI[i].getReg();
|
||||||
|
unsigned Offset = RegSpillOffsets[Reg];
|
||||||
|
if (StartOffset > Offset) {
|
||||||
|
LowReg = Reg; StartOffset = Offset;
|
||||||
|
}
|
||||||
|
if (EndOffset < Offset) {
|
||||||
|
HighReg = Reg; EndOffset = RegSpillOffsets[Reg];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save information for epilogue inserter.
|
||||||
|
MFI->setLowReg(LowReg); MFI->setHighReg(HighReg);
|
||||||
|
|
||||||
|
// Build a store instruction. Use STORE MULTIPLE instruction if there are many
|
||||||
|
// registers to store, otherwise - just STORE.
|
||||||
|
MachineInstrBuilder MIB =
|
||||||
|
BuildMI(MBB, MI, DL, get((LowReg == HighReg ?
|
||||||
|
SystemZ::MOV64mr : SystemZ::MOV64mrm)));
|
||||||
|
|
||||||
|
// Add store operands.
|
||||||
|
MIB.addReg(SystemZ::R15D).addImm(StartOffset);
|
||||||
|
if (LowReg == HighReg)
|
||||||
|
MIB.addReg(0);
|
||||||
|
MIB.addReg(LowReg, RegState::Kill);
|
||||||
|
if (LowReg != HighReg)
|
||||||
|
MIB.addReg(HighReg, RegState::Kill);
|
||||||
|
|
||||||
|
// Do a second scan adding regs as being killed by instruction
|
||||||
|
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||||
|
unsigned Reg = CSI[i].getReg();
|
||||||
|
// Add the callee-saved register as live-in. It's killed at the spill.
|
||||||
|
MBB.addLiveIn(Reg);
|
||||||
|
if (Reg != LowReg && Reg != HighReg)
|
||||||
|
MIB.addReg(Reg, RegState::ImplicitKill);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +193,41 @@ bool
|
||||||
SystemZInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
SystemZInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI) const {
|
||||||
|
if (CSI.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DebugLoc DL = DebugLoc::getUnknownLoc();
|
||||||
|
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
||||||
|
|
||||||
|
MachineFunction &MF = *MBB.getParent();
|
||||||
|
const TargetRegisterInfo *RegInfo= MF.getTarget().getRegisterInfo();
|
||||||
|
SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
|
||||||
|
|
||||||
|
unsigned LowReg = MFI->getLowReg(), HighReg = MFI->getHighReg();
|
||||||
|
unsigned StartOffset = RegSpillOffsets[LowReg];
|
||||||
|
|
||||||
|
// Build a load instruction. Use LOAD MULTIPLE instruction if there are many
|
||||||
|
// registers to load, otherwise - just LOAD.
|
||||||
|
MachineInstrBuilder MIB =
|
||||||
|
BuildMI(MBB, MI, DL, get((LowReg == HighReg ?
|
||||||
|
SystemZ::MOV64rm : SystemZ::MOV64rmm)));
|
||||||
|
// Add store operands.
|
||||||
|
MIB.addReg(LowReg, RegState::Define);
|
||||||
|
if (LowReg != HighReg)
|
||||||
|
MIB.addReg(HighReg, RegState::Define);
|
||||||
|
|
||||||
|
MIB.addReg((RegInfo->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D));
|
||||||
|
MIB.addImm(StartOffset);
|
||||||
|
if (LowReg == HighReg)
|
||||||
|
MIB.addReg(0);
|
||||||
|
|
||||||
|
// Do a second scan adding regs as being defined by instruction
|
||||||
|
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||||
|
unsigned Reg = CSI[i].getReg();
|
||||||
|
if (Reg != LowReg && Reg != HighReg)
|
||||||
|
MIB.addReg(Reg, RegState::ImplicitDefine);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
#ifndef LLVM_TARGET_SYSTEMZINSTRINFO_H
|
#ifndef LLVM_TARGET_SYSTEMZINSTRINFO_H
|
||||||
#define LLVM_TARGET_SYSTEMZINSTRINFO_H
|
#define LLVM_TARGET_SYSTEMZINSTRINFO_H
|
||||||
|
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
|
||||||
#include "SystemZRegisterInfo.h"
|
#include "SystemZRegisterInfo.h"
|
||||||
|
#include "llvm/ADT/IndexedMap.h"
|
||||||
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
@ -24,6 +25,7 @@ class SystemZTargetMachine;
|
||||||
class SystemZInstrInfo : public TargetInstrInfoImpl {
|
class SystemZInstrInfo : public TargetInstrInfoImpl {
|
||||||
const SystemZRegisterInfo RI;
|
const SystemZRegisterInfo RI;
|
||||||
SystemZTargetMachine &TM;
|
SystemZTargetMachine &TM;
|
||||||
|
IndexedMap<unsigned> RegSpillOffsets;
|
||||||
public:
|
public:
|
||||||
explicit SystemZInstrInfo(SystemZTargetMachine &TM);
|
explicit SystemZInstrInfo(SystemZTargetMachine &TM);
|
||||||
|
|
||||||
|
|
|
@ -195,19 +195,12 @@ def laaddr : Operand<i64>,
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Instruction list..
|
// Instruction list..
|
||||||
|
|
||||||
// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
|
|
||||||
// a stack adjustment and the codegen must know that they may modify the stack
|
|
||||||
// pointer before prolog-epilog rewriting occurs.
|
|
||||||
// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
|
|
||||||
// sub / add which can clobber R15D.
|
|
||||||
let Defs = [R15D], Uses = [R15D] in {
|
|
||||||
def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt),
|
def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt),
|
||||||
"#ADJCALLSTACKDOWN",
|
"#ADJCALLSTACKDOWN",
|
||||||
[(SystemZcallseq_start timm:$amt)]>;
|
[(SystemZcallseq_start timm:$amt)]>;
|
||||||
def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
|
def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
|
||||||
"#ADJCALLSTACKUP",
|
"#ADJCALLSTACKUP",
|
||||||
[(SystemZcallseq_end timm:$amt1, timm:$amt2)]>;
|
[(SystemZcallseq_end timm:$amt1, timm:$amt2)]>;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -215,7 +208,7 @@ def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
|
||||||
//
|
//
|
||||||
|
|
||||||
// FIXME: Provide proper encoding!
|
// FIXME: Provide proper encoding!
|
||||||
let isReturn = 1, isTerminator = 1, Uses = [R14D] in {
|
let isReturn = 1, isTerminator = 1 in {
|
||||||
def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
|
def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,12 +217,9 @@ let isReturn = 1, isTerminator = 1, Uses = [R14D] in {
|
||||||
//
|
//
|
||||||
|
|
||||||
let isCall = 1 in
|
let isCall = 1 in
|
||||||
// All calls clobber the non-callee saved registers. R15 is marked as
|
// All calls clobber the non-callee saved registers (except R14 which we
|
||||||
// a use to prevent stack-pointer assignments that appear immediately
|
// handle separately). Uses for argument registers are added manually.
|
||||||
// before calls from potentially appearing dead. Uses for argument
|
let Defs = [R0D, R1D, R3D, R4D, R5D] in {
|
||||||
// registers are added manually.
|
|
||||||
let Defs = [R0D, R1D, R3D, R4D, R5D, R14D, R15D],
|
|
||||||
Uses = [R15D] in {
|
|
||||||
def CALLi : Pseudo<(outs), (ins i64imm:$dst, variable_ops),
|
def CALLi : Pseudo<(outs), (ins i64imm:$dst, variable_ops),
|
||||||
"brasl\t%r14, $dst", [(SystemZcall imm:$dst)]>;
|
"brasl\t%r14, $dst", [(SystemZcall imm:$dst)]>;
|
||||||
def CALLr : Pseudo<(outs), (ins ADDR64:$dst, variable_ops),
|
def CALLr : Pseudo<(outs), (ins ADDR64:$dst, variable_ops),
|
||||||
|
@ -370,6 +360,22 @@ def MOV64m32r : Pseudo<(outs), (ins rriaddr:$dst, GR64:$src),
|
||||||
"sty\t{$src, $dst}",
|
"sty\t{$src, $dst}",
|
||||||
[(truncstorei32 GR64:$src, rriaddr:$dst)]>;
|
[(truncstorei32 GR64:$src, rriaddr:$dst)]>;
|
||||||
|
|
||||||
|
// multiple regs moves
|
||||||
|
// FIXME: should we use multiple arg nodes?
|
||||||
|
def MOV32mrm : Pseudo<(outs), (ins riaddr:$dst, GR32:$from, GR32:$to),
|
||||||
|
"stmy\t{$from, $to, $dst}",
|
||||||
|
[]>;
|
||||||
|
def MOV64mrm : Pseudo<(outs), (ins riaddr:$dst, GR64:$from, GR64:$to),
|
||||||
|
"stmg\t{$from, $to, $dst}",
|
||||||
|
[]>;
|
||||||
|
def MOV32rmm : Pseudo<(outs GR32:$from, GR32:$to), (ins riaddr:$dst),
|
||||||
|
"lmy\t{$from, $to, $dst}",
|
||||||
|
[]>;
|
||||||
|
def MOV64rmm : Pseudo<(outs GR64:$from, GR64:$to), (ins riaddr:$dst),
|
||||||
|
"lmg\t{$from, $to, $dst}",
|
||||||
|
[]>;
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Arithmetic Instructions
|
// Arithmetic Instructions
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,11 @@ class SystemZMachineFunctionInfo : public MachineFunctionInfo {
|
||||||
/// stack frame in bytes.
|
/// stack frame in bytes.
|
||||||
unsigned CalleeSavedFrameSize;
|
unsigned CalleeSavedFrameSize;
|
||||||
|
|
||||||
|
/// LowReg - Low register of range of callee-saved registers to store.
|
||||||
|
unsigned LowReg;
|
||||||
|
|
||||||
|
/// HighReg - High register of range of callee-saved registers to store.
|
||||||
|
unsigned HighReg;
|
||||||
public:
|
public:
|
||||||
SystemZMachineFunctionInfo() : CalleeSavedFrameSize(0) {}
|
SystemZMachineFunctionInfo() : CalleeSavedFrameSize(0) {}
|
||||||
|
|
||||||
|
@ -32,6 +37,12 @@ public:
|
||||||
|
|
||||||
unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
|
unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
|
||||||
void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; }
|
void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; }
|
||||||
|
|
||||||
|
unsigned getLowReg() const { return LowReg; }
|
||||||
|
void setLowReg(unsigned Reg) { LowReg = Reg; }
|
||||||
|
|
||||||
|
unsigned getHighReg() const { return HighReg; }
|
||||||
|
void setHighReg(unsigned Reg) { HighReg = Reg; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/Target/TargetFrameInfo.h"
|
#include "llvm/Target/TargetFrameInfo.h"
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
@ -35,7 +36,8 @@ const unsigned*
|
||||||
SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
||||||
static const unsigned CalleeSavedRegs[] = {
|
static const unsigned CalleeSavedRegs[] = {
|
||||||
SystemZ::R6D, SystemZ::R7D, SystemZ::R8D, SystemZ::R9D,
|
SystemZ::R6D, SystemZ::R7D, SystemZ::R8D, SystemZ::R9D,
|
||||||
SystemZ::R10D, SystemZ::R11D, SystemZ::R12D, SystemZ::R13D, SystemZ::R14D,
|
SystemZ::R10D, SystemZ::R11D, SystemZ::R12D, SystemZ::R13D,
|
||||||
|
SystemZ::R14D, SystemZ::R15D,
|
||||||
SystemZ::F1, SystemZ::F3, SystemZ::F5, SystemZ::F7,
|
SystemZ::F1, SystemZ::F3, SystemZ::F5, SystemZ::F7,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
@ -50,7 +52,7 @@ SystemZRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
|
||||||
&SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
|
&SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
|
||||||
&SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
|
&SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
|
||||||
&SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
|
&SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
|
||||||
&SystemZ::GR64RegClass,
|
&SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
|
||||||
&SystemZ::FP64RegClass, &SystemZ::FP64RegClass,
|
&SystemZ::FP64RegClass, &SystemZ::FP64RegClass,
|
||||||
&SystemZ::FP64RegClass, &SystemZ::FP64RegClass, 0
|
&SystemZ::FP64RegClass, &SystemZ::FP64RegClass, 0
|
||||||
};
|
};
|
||||||
|
@ -66,16 +68,16 @@ BitVector SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const
|
||||||
return Reserved;
|
return Reserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
// needsFP - Return true if the specified function should have a dedicated frame
|
/// needsFP - Return true if the specified function should have a dedicated
|
||||||
// pointer register. This is true if the function has variable sized allocas or
|
/// frame pointer register. This is true if the function has variable sized
|
||||||
// if frame pointer elimination is disabled.
|
/// allocas or if frame pointer elimination is disabled.
|
||||||
//
|
|
||||||
bool SystemZRegisterInfo::hasFP(const MachineFunction &MF) const {
|
bool SystemZRegisterInfo::hasFP(const MachineFunction &MF) const {
|
||||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
return NoFramePointerElim || MFI->hasVarSizedObjects();
|
return NoFramePointerElim || MFI->hasVarSizedObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SystemZRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
|
bool SystemZRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
|
||||||
|
// FIXME: Should we always have reserved call frame?
|
||||||
return !MF.getFrameInfo()->hasVarSizedObjects();
|
return !MF.getFrameInfo()->hasVarSizedObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +139,25 @@ void SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||||
MI.getOperand(i+1).ChangeToImmediate(Offset);
|
MI.getOperand(i+1).ChangeToImmediate(Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SystemZRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||||
|
RegScavenger *RS) const {
|
||||||
|
// Determine whether R15/R14 will ever be clobbered inside the function. And
|
||||||
|
// if yes - mark it as 'callee' saved.
|
||||||
|
MachineFrameInfo *FFI = MF.getFrameInfo();
|
||||||
|
|
||||||
|
if (FFI->hasCalls()
|
||||||
|
/* FIXME: function is varargs */
|
||||||
|
/* FIXME: function grabs RA */
|
||||||
|
/* FIXME: function calls eh_return */)
|
||||||
|
MF.getRegInfo().setPhysRegUsed(SystemZ::R14D);
|
||||||
|
|
||||||
|
if (FFI->getObjectIndexEnd() != 0 || // Contains automatic variables
|
||||||
|
FFI->hasVarSizedObjects() // Function calls dynamic alloca's
|
||||||
|
/* FIXME: function is varargs */)
|
||||||
|
MF.getRegInfo().setPhysRegUsed(SystemZ::R15D);
|
||||||
|
}
|
||||||
|
|
||||||
/// emitSPUpdate - Emit a series of instructions to increment / decrement the
|
/// emitSPUpdate - Emit a series of instructions to increment / decrement the
|
||||||
/// stack pointer by a constant value.
|
/// stack pointer by a constant value.
|
||||||
static
|
static
|
||||||
|
@ -177,7 +198,11 @@ void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
uint64_t StackSize =
|
uint64_t StackSize =
|
||||||
MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
|
MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
|
||||||
|
|
||||||
// FIXME: Skip the callee-saved push instructions.
|
// Skip the callee-saved push instructions.
|
||||||
|
while (MBBI != MBB.end() &&
|
||||||
|
(MBBI->getOpcode() == SystemZ::MOV64mr ||
|
||||||
|
MBBI->getOpcode() == SystemZ::MOV64mrm))
|
||||||
|
++MBBI;
|
||||||
|
|
||||||
if (MBBI != MBB.end())
|
if (MBBI != MBB.end())
|
||||||
DL = MBBI->getDebugLoc();
|
DL = MBBI->getDebugLoc();
|
||||||
|
@ -223,23 +248,30 @@ void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||||
MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
|
MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
|
||||||
uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
|
uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
|
||||||
|
|
||||||
// Skip the callee-saved regs load instructions.
|
// Skip the final terminator instruction.
|
||||||
MachineBasicBlock::iterator LastCSPop = MBBI;
|
|
||||||
while (MBBI != MBB.begin()) {
|
while (MBBI != MBB.begin()) {
|
||||||
MachineBasicBlock::iterator PI = prior(MBBI);
|
MachineBasicBlock::iterator PI = prior(MBBI);
|
||||||
|
--MBBI;
|
||||||
if (!PI->getDesc().isTerminator())
|
if (!PI->getDesc().isTerminator())
|
||||||
break;
|
break;
|
||||||
--MBBI;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DL = MBBI->getDebugLoc();
|
// During callee-saved restores emission stack frame was not yet finialized
|
||||||
|
// (and thus - the stack size was unknown). Tune the offset having full stack
|
||||||
|
// size in hands.
|
||||||
|
if (SystemZMFI->getCalleeSavedFrameSize()) {
|
||||||
|
assert((MBBI->getOpcode() == SystemZ::MOV64rmm ||
|
||||||
|
MBBI->getOpcode() == SystemZ::MOV64rm) &&
|
||||||
|
"Expected to see callee-save register restore code");
|
||||||
|
|
||||||
if (MFI->hasVarSizedObjects()) {
|
unsigned i = 0;
|
||||||
assert(0 && "Not implemented yet!");
|
MachineInstr &MI = *MBBI;
|
||||||
} else {
|
while (!MI.getOperand(i).isImm()) {
|
||||||
// adjust stack pointer back: R15 += numbytes
|
++i;
|
||||||
if (StackSize)
|
assert(i < MI.getNumOperands() && "Unexpected restore code!");
|
||||||
emitSPUpdate(MBB, MBBI, NumBytes, TII);
|
}
|
||||||
|
|
||||||
|
MI.getOperand(i).ChangeToImmediate(NumBytes + MI.getOperand(i).getImm());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,10 @@ struct SystemZRegisterInfo : public SystemZGenRegisterInfo {
|
||||||
void eliminateFrameIndex(MachineBasicBlock::iterator II,
|
void eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||||
int SPAdj, RegScavenger *RS = NULL) const;
|
int SPAdj, RegScavenger *RS = NULL) const;
|
||||||
|
|
||||||
|
|
||||||
|
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||||
|
RegScavenger *RS) const;
|
||||||
|
|
||||||
void emitPrologue(MachineFunction &MF) const;
|
void emitPrologue(MachineFunction &MF) const;
|
||||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: llvm-as < %s | llc | grep 168 | count 2
|
; RUN: llvm-as < %s | llc | grep 168 | count 1
|
||||||
; RUN: llvm-as < %s | llc | grep 160 | count 3
|
; RUN: llvm-as < %s | llc | grep 160 | count 3
|
||||||
; RUN: llvm-as < %s | llc | grep 328 | count 1
|
; RUN: llvm-as < %s | llc | grep 328 | count 1
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; RUN: llvm-as < %s | llc | grep 160 | count 1
|
; RUN: llvm-as < %s | llc | grep 160 | count 1
|
||||||
; RUN: llvm-as < %s | llc | grep 328 | count 1
|
; RUN: llvm-as < %s | llc | grep 328 | count 1
|
||||||
; RUN: llvm-as < %s | llc | grep 168 | count 2
|
; RUN: llvm-as < %s | llc | grep 168 | count 1
|
||||||
|
|
||||||
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 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"
|
target triple = "s390x-unknown-linux-gnu"
|
||||||
|
|
Loading…
Reference in New Issue