mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-04 09:37:20 +00:00
Make $fp and $ra callee-saved registers and let PrologEpilogInserter handle
saving and restoring them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131745 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f85092c255
commit
17a1e87751
@ -156,26 +156,6 @@ void MipsFrameLowering::adjustMipsStackFrame(MachineFunction &MF) const {
|
|||||||
StackOffset += MFI->getObjectAlignment(CSI[i].getFrameIdx());
|
StackOffset += MFI->getObjectAlignment(CSI[i].getFrameIdx());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stack locations for FP and RA. If only one of them is used,
|
|
||||||
// the space must be allocated for both, otherwise no space at all.
|
|
||||||
if (hasFP(MF) || MFI->adjustsStack()) {
|
|
||||||
// FP stack location
|
|
||||||
MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
|
|
||||||
StackOffset);
|
|
||||||
MipsFI->setFPStackOffset(StackOffset);
|
|
||||||
TopCPUSavedRegOff = StackOffset;
|
|
||||||
StackOffset += RegSize;
|
|
||||||
|
|
||||||
// SP stack location
|
|
||||||
MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
|
|
||||||
StackOffset);
|
|
||||||
MipsFI->setRAStackOffset(StackOffset);
|
|
||||||
StackOffset += RegSize;
|
|
||||||
|
|
||||||
if (MFI->adjustsStack())
|
|
||||||
TopCPUSavedRegOff += RegSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
StackOffset = ((StackOffset+StackAlign-1)/StackAlign*StackAlign);
|
StackOffset = ((StackOffset+StackAlign-1)/StackAlign*StackAlign);
|
||||||
|
|
||||||
// Adjust FPU Callee Saved Registers Area. This Area must be
|
// Adjust FPU Callee Saved Registers Area. This Area must be
|
||||||
@ -267,9 +247,6 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
// No need to allocate space on the stack.
|
// No need to allocate space on the stack.
|
||||||
if (StackSize == 0 && !MFI->adjustsStack()) return;
|
if (StackSize == 0 && !MFI->adjustsStack()) return;
|
||||||
|
|
||||||
int FPOffset = MipsFI->getFPStackOffset();
|
|
||||||
int RAOffset = MipsFI->getRAStackOffset();
|
|
||||||
|
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::NOREORDER));
|
BuildMI(MBB, MBBI, dl, TII.get(Mips::NOREORDER));
|
||||||
|
|
||||||
// TODO: check need from GP here.
|
// TODO: check need from GP here.
|
||||||
@ -288,36 +265,11 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
if (ATUsed)
|
if (ATUsed)
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
|
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
|
||||||
|
|
||||||
// Save the return address only if the function isn't a leaf one.
|
// if framepointer enabled, set it to point to the stack pointer.
|
||||||
// sw $ra, stack_loc($sp)
|
if (hasFP(MF))
|
||||||
if (MFI->adjustsStack()) {
|
|
||||||
ATUsed = expandRegLargeImmPair(Mips::SP, RAOffset, NewReg, NewImm, MBB,
|
|
||||||
MBBI);
|
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::SW))
|
|
||||||
.addReg(Mips::RA).addImm(NewImm).addReg(NewReg);
|
|
||||||
|
|
||||||
// FIXME: change this when mips goes MC".
|
|
||||||
if (ATUsed)
|
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
|
|
||||||
}
|
|
||||||
|
|
||||||
// if framepointer enabled, save it and set it
|
|
||||||
// to point to the stack pointer
|
|
||||||
if (hasFP(MF)) {
|
|
||||||
// sw $fp,stack_loc($sp)
|
|
||||||
ATUsed = expandRegLargeImmPair(Mips::SP, FPOffset, NewReg, NewImm, MBB,
|
|
||||||
MBBI);
|
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::SW))
|
|
||||||
.addReg(Mips::FP).addImm(NewImm).addReg(NewReg);
|
|
||||||
|
|
||||||
// FIXME: change this when mips goes MC".
|
|
||||||
if (ATUsed)
|
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
|
|
||||||
|
|
||||||
// move $fp, $sp
|
// move $fp, $sp
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::FP)
|
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::FP)
|
||||||
.addReg(Mips::SP).addReg(Mips::ZERO);
|
.addReg(Mips::SP).addReg(Mips::ZERO);
|
||||||
}
|
|
||||||
|
|
||||||
// Restore GP from the saved stack location
|
// Restore GP from the saved stack location
|
||||||
if (MipsFI->needGPSaveRestore())
|
if (MipsFI->needGPSaveRestore())
|
||||||
@ -329,7 +281,6 @@ void MipsFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||||||
MachineBasicBlock &MBB) const {
|
MachineBasicBlock &MBB) const {
|
||||||
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
|
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
|
||||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
|
|
||||||
const MipsInstrInfo &TII =
|
const MipsInstrInfo &TII =
|
||||||
*static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo());
|
*static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo());
|
||||||
DebugLoc dl = MBBI->getDebugLoc();
|
DebugLoc dl = MBBI->getDebugLoc();
|
||||||
@ -337,45 +288,16 @@ void MipsFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||||||
// Get the number of bytes from FrameInfo
|
// Get the number of bytes from FrameInfo
|
||||||
int NumBytes = (int) MFI->getStackSize();
|
int NumBytes = (int) MFI->getStackSize();
|
||||||
|
|
||||||
// Get the FI's where RA and FP are saved.
|
|
||||||
int FPOffset = MipsFI->getFPStackOffset();
|
|
||||||
int RAOffset = MipsFI->getRAStackOffset();
|
|
||||||
|
|
||||||
unsigned NewReg = 0;
|
unsigned NewReg = 0;
|
||||||
int NewImm = 0;
|
int NewImm = 0;
|
||||||
bool ATUsed = false;
|
bool ATUsed = false;
|
||||||
|
|
||||||
// if framepointer enabled, restore it and restore the
|
// if framepointer enabled, restore the stack pointer.
|
||||||
// stack pointer
|
if (hasFP(MF))
|
||||||
if (hasFP(MF)) {
|
|
||||||
// move $sp, $fp
|
// move $sp, $fp
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::SP)
|
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::SP)
|
||||||
.addReg(Mips::FP).addReg(Mips::ZERO);
|
.addReg(Mips::FP).addReg(Mips::ZERO);
|
||||||
|
|
||||||
// lw $fp,stack_loc($sp)
|
|
||||||
ATUsed = expandRegLargeImmPair(Mips::SP, FPOffset, NewReg, NewImm, MBB,
|
|
||||||
MBBI);
|
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::LW), Mips::FP)
|
|
||||||
.addImm(NewImm).addReg(NewReg);
|
|
||||||
|
|
||||||
// FIXME: change this when mips goes MC".
|
|
||||||
if (ATUsed)
|
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore the return address only if the function isn't a leaf one.
|
|
||||||
// lw $ra, stack_loc($sp)
|
|
||||||
if (MFI->adjustsStack()) {
|
|
||||||
ATUsed = expandRegLargeImmPair(Mips::SP, RAOffset, NewReg, NewImm, MBB,
|
|
||||||
MBBI);
|
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::LW), Mips::RA)
|
|
||||||
.addImm(NewImm).addReg(NewReg);
|
|
||||||
|
|
||||||
// FIXME: change this when mips goes MC".
|
|
||||||
if (ATUsed)
|
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
|
|
||||||
}
|
|
||||||
|
|
||||||
// adjust stack : insert addi sp, sp, (imm)
|
// adjust stack : insert addi sp, sp, (imm)
|
||||||
if (NumBytes) {
|
if (NumBytes) {
|
||||||
ATUsed = expandRegLargeImmPair(Mips::SP, NumBytes, NewReg, NewImm, MBB,
|
ATUsed = expandRegLargeImmPair(Mips::SP, NumBytes, NewReg, NewImm, MBB,
|
||||||
@ -389,6 +311,30 @@ void MipsFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MipsFrameLowering::
|
||||||
|
processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||||
|
RegScavenger *RS) const {
|
||||||
|
MachineRegisterInfo& MRI = MF.getRegInfo();
|
||||||
|
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
|
||||||
|
|
||||||
|
// FIXME: remove this code if register allocator can correctly mark
|
||||||
|
// $fp and $ra used or unused.
|
||||||
|
|
||||||
|
// Mark $fp and $ra as used or unused.
|
||||||
|
if (hasFP(MF))
|
||||||
|
MRI.setPhysRegUsed(Mips::FP);
|
||||||
|
|
||||||
|
// The register allocator might determine $ra is used after seeing
|
||||||
|
// instruction "jr $ra", but we do not want PrologEpilogInserter to insert
|
||||||
|
// instructions to save/restore $ra unless there is a function call.
|
||||||
|
// To correct this, $ra is explicitly marked unused if there is no
|
||||||
|
// function call.
|
||||||
|
if (MipsFI->hasCall())
|
||||||
|
MRI.setPhysRegUsed(Mips::RA);
|
||||||
|
else
|
||||||
|
MRI.setPhysRegUnused(Mips::RA);
|
||||||
|
}
|
||||||
|
|
||||||
void MipsFrameLowering::
|
void MipsFrameLowering::
|
||||||
processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
|
processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
|
||||||
const MipsRegisterInfo *RegInfo =
|
const MipsRegisterInfo *RegInfo =
|
||||||
|
@ -40,6 +40,8 @@ public:
|
|||||||
|
|
||||||
bool hasFP(const MachineFunction &MF) const;
|
bool hasFP(const MachineFunction &MF) const;
|
||||||
|
|
||||||
|
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||||
|
RegScavenger *RS) const;
|
||||||
void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
|
void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1042,6 +1042,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||||||
MachineFunction &MF = DAG.getMachineFunction();
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
|
bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
|
||||||
|
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
|
||||||
|
|
||||||
// Analyze operands of the call, assigning locations to each operand.
|
// Analyze operands of the call, assigning locations to each operand.
|
||||||
SmallVector<CCValAssign, 16> ArgLocs;
|
SmallVector<CCValAssign, 16> ArgLocs;
|
||||||
@ -1066,6 +1067,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||||||
int LastArgStackLoc = 0;
|
int LastArgStackLoc = 0;
|
||||||
unsigned FirstStackArgLoc = (Subtarget->isABI_EABI() ? 0 : 16);
|
unsigned FirstStackArgLoc = (Subtarget->isABI_EABI() ? 0 : 16);
|
||||||
|
|
||||||
|
MipsFI->setHasCall();
|
||||||
|
|
||||||
// Walk the register/memloc assignments, inserting copies/loads.
|
// Walk the register/memloc assignments, inserting copies/loads.
|
||||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||||
SDValue Arg = OutVals[i];
|
SDValue Arg = OutVals[i];
|
||||||
@ -1226,7 +1229,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||||||
// Function can have an arbitrary number of calls, so
|
// Function can have an arbitrary number of calls, so
|
||||||
// hold the LastArgStackLoc with the biggest offset.
|
// hold the LastArgStackLoc with the biggest offset.
|
||||||
int FI;
|
int FI;
|
||||||
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
|
|
||||||
if (LastArgStackLoc >= MipsFI->getGPStackOffset()) {
|
if (LastArgStackLoc >= MipsFI->getGPStackOffset()) {
|
||||||
LastArgStackLoc = (!LastArgStackLoc) ? (16) : (LastArgStackLoc+4);
|
LastArgStackLoc = (!LastArgStackLoc) ? (16) : (LastArgStackLoc+4);
|
||||||
// Create the frame index only once. SPOffset here can be anything
|
// Create the frame index only once. SPOffset here can be anything
|
||||||
|
@ -27,14 +27,6 @@ namespace llvm {
|
|||||||
class MipsFunctionInfo : public MachineFunctionInfo {
|
class MipsFunctionInfo : public MachineFunctionInfo {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Holds for each function where on the stack the Frame Pointer must be
|
|
||||||
/// saved. This is used on Prologue and Epilogue to emit FP save/restore
|
|
||||||
int FPStackOffset;
|
|
||||||
|
|
||||||
/// Holds for each function where on the stack the Return Address must be
|
|
||||||
/// saved. This is used on Prologue and Epilogue to emit RA save/restore
|
|
||||||
int RAStackOffset;
|
|
||||||
|
|
||||||
/// At each function entry, two special bitmask directives must be emitted
|
/// At each function entry, two special bitmask directives must be emitted
|
||||||
/// to help debugging, for CPU and FPU callee saved registers. Both need
|
/// to help debugging, for CPU and FPU callee saved registers. Both need
|
||||||
/// the negative offset from the final stack size and its higher registers
|
/// the negative offset from the final stack size and its higher registers
|
||||||
@ -94,19 +86,13 @@ private:
|
|||||||
bool HasCall; // True if function has a function call.
|
bool HasCall; // True if function has a function call.
|
||||||
public:
|
public:
|
||||||
MipsFunctionInfo(MachineFunction& MF)
|
MipsFunctionInfo(MachineFunction& MF)
|
||||||
: FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0),
|
: CPUTopSavedRegOff(0),
|
||||||
FPUTopSavedRegOff(0), GPHolder(-1,-1), HasLoadArgs(false),
|
FPUTopSavedRegOff(0), GPHolder(-1,-1), HasLoadArgs(false),
|
||||||
HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0),
|
HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0),
|
||||||
VarArgsFrameIndex(0), InArgFIRange(std::make_pair(-1, 0)),
|
VarArgsFrameIndex(0), InArgFIRange(std::make_pair(-1, 0)),
|
||||||
OutArgFIRange(std::make_pair(-1, 0)), GPFI(0), HasCall(false)
|
OutArgFIRange(std::make_pair(-1, 0)), GPFI(0), HasCall(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int getFPStackOffset() const { return FPStackOffset; }
|
|
||||||
void setFPStackOffset(int Off) { FPStackOffset = Off; }
|
|
||||||
|
|
||||||
int getRAStackOffset() const { return RAStackOffset; }
|
|
||||||
void setRAStackOffset(int Off) { RAStackOffset = Off; }
|
|
||||||
|
|
||||||
int getCPUTopSavedRegOff() const { return CPUTopSavedRegOff; }
|
int getCPUTopSavedRegOff() const { return CPUTopSavedRegOff; }
|
||||||
void setCPUTopSavedRegOff(int Off) { CPUTopSavedRegOff = Off; }
|
void setCPUTopSavedRegOff(int Off) { CPUTopSavedRegOff = Off; }
|
||||||
|
|
||||||
|
@ -99,20 +99,20 @@ getCalleeSavedRegs(const MachineFunction *MF) const
|
|||||||
// Mips callee-save register range is $16-$23, $f20-$f30
|
// Mips callee-save register range is $16-$23, $f20-$f30
|
||||||
static const unsigned SingleFloatOnlyCalleeSavedRegs[] = {
|
static const unsigned SingleFloatOnlyCalleeSavedRegs[] = {
|
||||||
Mips::S0, Mips::S1, Mips::S2, Mips::S3,
|
Mips::S0, Mips::S1, Mips::S2, Mips::S3,
|
||||||
Mips::S4, Mips::S5, Mips::S6, Mips::S7,
|
Mips::S4, Mips::S5, Mips::S6, Mips::S7, Mips::FP, Mips::RA,
|
||||||
Mips::F20, Mips::F21, Mips::F22, Mips::F23, Mips::F24, Mips::F25,
|
Mips::F20, Mips::F21, Mips::F22, Mips::F23, Mips::F24, Mips::F25,
|
||||||
Mips::F26, Mips::F27, Mips::F28, Mips::F29, Mips::F30, 0
|
Mips::F26, Mips::F27, Mips::F28, Mips::F29, Mips::F30, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned BitMode32CalleeSavedRegs[] = {
|
static const unsigned BitMode32CalleeSavedRegs[] = {
|
||||||
Mips::S0, Mips::S1, Mips::S2, Mips::S3,
|
Mips::S0, Mips::S1, Mips::S2, Mips::S3,
|
||||||
Mips::S4, Mips::S5, Mips::S6, Mips::S7,
|
Mips::S4, Mips::S5, Mips::S6, Mips::S7, Mips::FP, Mips::RA,
|
||||||
Mips::F20, Mips::F22, Mips::F24, Mips::F26, Mips::F28, Mips::F30, 0
|
Mips::F20, Mips::F22, Mips::F24, Mips::F26, Mips::F28, Mips::F30, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned Mips32CalleeSavedRegs[] = {
|
static const unsigned Mips32CalleeSavedRegs[] = {
|
||||||
Mips::S0, Mips::S1, Mips::S2, Mips::S3,
|
Mips::S0, Mips::S1, Mips::S2, Mips::S3,
|
||||||
Mips::S4, Mips::S5, Mips::S6, Mips::S7,
|
Mips::S4, Mips::S5, Mips::S6, Mips::S7, Mips::FP, Mips::RA,
|
||||||
Mips::D10, Mips::D11, Mips::D12, Mips::D13, Mips::D14, Mips::D15, 0
|
Mips::D10, Mips::D11, Mips::D12, Mips::D13, Mips::D14, Mips::D15, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,8 +10,8 @@ entry:
|
|||||||
; CHECK: jalr
|
; CHECK: jalr
|
||||||
tail call void @ff1(i32 %i, i64 1085102592623924856) nounwind
|
tail call void @ff1(i32 %i, i64 1085102592623924856) nounwind
|
||||||
; CHECK: lw $25, %call16(ff2)
|
; CHECK: lw $25, %call16(ff2)
|
||||||
; CHECK: lw $[[R2:[0-9]+]], 88($sp)
|
; CHECK: lw $[[R2:[0-9]+]], 80($sp)
|
||||||
; CHECK: lw $[[R3:[0-9]+]], 92($sp)
|
; CHECK: lw $[[R3:[0-9]+]], 84($sp)
|
||||||
; CHECK: addu $4, $zero, $[[R2]]
|
; CHECK: addu $4, $zero, $[[R2]]
|
||||||
; CHECK: addu $5, $zero, $[[R3]]
|
; CHECK: addu $5, $zero, $[[R3]]
|
||||||
; CHECK: jalr $25
|
; CHECK: jalr $25
|
||||||
|
Loading…
x
Reference in New Issue
Block a user