mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-11 00:39:36 +00:00
1. Change MBlaze indirect branches to use absolute branch BRALD instead of pc relative branch BRLD.
2. Make sure that the MBlaze stack is aligned to 4-byte boundaries. 3. Determine frame indexes that should be placed in the callers stack frame, as per the MBlaze ABI, and place them in the correct locations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121639 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a30b7d2c70
commit
eb13382333
@ -14,6 +14,7 @@
|
||||
#include "MBlazeFrameInfo.h"
|
||||
#include "MBlazeInstrInfo.h"
|
||||
#include "MBlazeMachineFunction.h"
|
||||
#include "InstPrinter/MBlazeInstPrinter.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
@ -26,6 +27,14 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
cl::opt<bool> DisableStackAdjust(
|
||||
"disable-mblaze-stack-adjust",
|
||||
cl::init(false),
|
||||
cl::desc("Disable MBlaze stack layout adjustment."),
|
||||
cl::Hidden);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Stack Frame Processing methods
|
||||
@ -39,6 +48,115 @@ using namespace llvm;
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void analyzeFrameIndexes(MachineFunction &MF) {
|
||||
if (DisableStackAdjust) return;
|
||||
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
|
||||
MachineRegisterInfo::livein_iterator LII = MRI.livein_begin();
|
||||
MachineRegisterInfo::livein_iterator LIE = MRI.livein_end();
|
||||
const SmallVector<int, 16> &LiveInFI = MBlazeFI->getLiveIn();
|
||||
SmallVector<MachineInstr*, 16> EraseInstr;
|
||||
|
||||
MachineBasicBlock *MBB = MF.getBlockNumbered(0);
|
||||
MachineBasicBlock::iterator MIB = MBB->begin();
|
||||
MachineBasicBlock::iterator MIE = MBB->end();
|
||||
|
||||
int StackAdjust = 0;
|
||||
int StackOffset = -28;
|
||||
for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) {
|
||||
for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
|
||||
if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 ||
|
||||
!I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
|
||||
I->getOperand(1).getIndex() != LiveInFI[i]) continue;
|
||||
|
||||
unsigned FIReg = I->getOperand(0).getReg();
|
||||
MachineBasicBlock::iterator SI = I;
|
||||
for (SI++; SI != MIE; ++SI) {
|
||||
if (!SI->getOperand(0).isReg()) continue;
|
||||
if (!SI->getOperand(1).isFI()) continue;
|
||||
if (SI->getOpcode() != MBlaze::SWI) continue;
|
||||
|
||||
int FI = SI->getOperand(1).getIndex();
|
||||
if (SI->getOperand(0).getReg() != FIReg) continue;
|
||||
if (MFI->isFixedObjectIndex(FI)) continue;
|
||||
if (MFI->getObjectSize(FI) != 4) continue;
|
||||
if (SI->getOperand(0).isDef()) break;
|
||||
|
||||
if (SI->getOperand(0).isKill())
|
||||
EraseInstr.push_back(I);
|
||||
EraseInstr.push_back(SI);
|
||||
MBlazeFI->recordLoadArgsFI(FI, StackOffset);
|
||||
StackOffset -= 4;
|
||||
StackAdjust += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (MachineBasicBlock::iterator I=MBB->begin(), E=MBB->end(); I != E; ++I) {
|
||||
if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 ||
|
||||
!I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
|
||||
I->getOperand(1).getIndex() < 0) continue;
|
||||
|
||||
unsigned FIReg = 0;
|
||||
for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) {
|
||||
if (I->getOperand(0).getReg() == LI->first) {
|
||||
FIReg = LI->first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FIReg) {
|
||||
int FI = I->getOperand(1).getIndex();
|
||||
MBlazeFI->recordLiveIn(FI);
|
||||
|
||||
StackAdjust += 4;
|
||||
switch (FIReg) {
|
||||
default: llvm_unreachable("invalid incoming parameter!");
|
||||
case MBlaze::R5: MBlazeFI->recordLoadArgsFI(FI, -4); break;
|
||||
case MBlaze::R6: MBlazeFI->recordLoadArgsFI(FI, -8); break;
|
||||
case MBlaze::R7: MBlazeFI->recordLoadArgsFI(FI, -12); break;
|
||||
case MBlaze::R8: MBlazeFI->recordLoadArgsFI(FI, -16); break;
|
||||
case MBlaze::R9: MBlazeFI->recordLoadArgsFI(FI, -20); break;
|
||||
case MBlaze::R10: MBlazeFI->recordLoadArgsFI(FI, -24); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0, e = EraseInstr.size(); i < e; ++i)
|
||||
MBB->erase(EraseInstr[i]);
|
||||
|
||||
MBlazeFI->setStackAdjust(StackAdjust);
|
||||
}
|
||||
|
||||
static void determineFrameLayout(MachineFunction &MF) {
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
|
||||
|
||||
// Replace the dummy '0' SPOffset by the negative offsets, as explained on
|
||||
// LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
|
||||
// the approach done by calculateFrameObjectOffsets to the stack frame.
|
||||
MBlazeFI->adjustLoadArgsFI(MFI);
|
||||
MBlazeFI->adjustStoreVarArgsFI(MFI);
|
||||
|
||||
// Get the number of bytes to allocate from the FrameInfo
|
||||
unsigned FrameSize = MFI->getStackSize();
|
||||
FrameSize -= MBlazeFI->getStackAdjust();
|
||||
|
||||
// Get the alignments provided by the target, and the maximum alignment
|
||||
// (if any) of the fixed frame objects.
|
||||
// unsigned MaxAlign = MFI->getMaxAlignment();
|
||||
unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
|
||||
unsigned AlignMask = TargetAlign - 1;
|
||||
|
||||
// Make sure the frame is aligned.
|
||||
FrameSize = (FrameSize + AlignMask) & ~AlignMask;
|
||||
MFI->setStackSize(FrameSize);
|
||||
}
|
||||
|
||||
// hasFP - Return true if the specified function should have a dedicated frame
|
||||
// pointer register. This is true if the function has variable sized allocas or
|
||||
// if frame pointer elimination is disabled.
|
||||
@ -56,11 +174,8 @@ void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const {
|
||||
MachineBasicBlock::iterator MBBI = MBB.begin();
|
||||
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
|
||||
|
||||
// Replace the dummy '0' SPOffset by the negative offsets, as explained on
|
||||
// LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
|
||||
// the approach done by calculateFrameObjectOffsets to the stack frame.
|
||||
MBlazeFI->adjustLoadArgsFI(MFI);
|
||||
MBlazeFI->adjustStoreVarArgsFI(MFI);
|
||||
// Determine the correct frame layout
|
||||
determineFrameLayout(MF);
|
||||
|
||||
// Get the number of bytes to allocate from the FrameInfo.
|
||||
unsigned StackSize = MFI->getStackSize();
|
||||
@ -146,4 +261,6 @@ void MBlazeFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
MBlazeFI->setFPStackOffset(4);
|
||||
MFI->CreateFixedObject(4,4,true);
|
||||
}
|
||||
|
||||
analyzeFrameIndexes(MF);
|
||||
}
|
||||
|
@ -766,6 +766,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
|
||||
unsigned StackLoc = VA.getLocMemOffset() + 4;
|
||||
int FI = MFI->CreateFixedObject(ArgSize, 0, true);
|
||||
MBlazeFI->recordLoadArgsFI(FI, -StackLoc);
|
||||
MBlazeFI->recordLiveIn(FI);
|
||||
|
||||
// Create load nodes to retrieve arguments from the stack
|
||||
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
|
||||
|
@ -650,7 +650,7 @@ def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)),
|
||||
(BRLID (i32 R15), texternalsym:$dst)>;
|
||||
|
||||
def : Pat<(MBlazeJmpLink GPR:$dst),
|
||||
(BRLD (i32 R15), GPR:$dst)>;
|
||||
(BRALD (i32 R15), GPR:$dst)>;
|
||||
|
||||
// Shift Instructions
|
||||
def : Pat<(shl GPR:$L, GPR:$R), (ShiftL GPR:$L, GPR:$R)>;
|
||||
|
@ -34,6 +34,9 @@ private:
|
||||
/// saved. This is used on Prologue and Epilogue to emit RA save/restore
|
||||
int RAStackOffset;
|
||||
|
||||
/// Holds the stack adjustment necessary for each function.
|
||||
int StackAdjust;
|
||||
|
||||
/// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
|
||||
struct MBlazeFIHolder {
|
||||
|
||||
@ -76,11 +79,15 @@ private:
|
||||
// VarArgsFrameIndex - FrameIndex for start of varargs area.
|
||||
int VarArgsFrameIndex;
|
||||
|
||||
/// LiveInFI - keeps track of the frame indexes in a callers stack
|
||||
/// frame that are live into a function.
|
||||
SmallVector<int, 16> LiveInFI;
|
||||
|
||||
public:
|
||||
MBlazeFunctionInfo(MachineFunction& MF)
|
||||
: FPStackOffset(0), RAStackOffset(0), GPHolder(-1,-1),
|
||||
: FPStackOffset(0), RAStackOffset(0), StackAdjust(0), GPHolder(-1,-1),
|
||||
HasLoadArgs(false), HasStoreVarArgs(false), SRetReturnReg(0),
|
||||
GlobalBaseReg(0), VarArgsFrameIndex(0)
|
||||
GlobalBaseReg(0), VarArgsFrameIndex(0), LiveInFI()
|
||||
{}
|
||||
|
||||
int getFPStackOffset() const { return FPStackOffset; }
|
||||
@ -89,6 +96,9 @@ public:
|
||||
int getRAStackOffset() const { return RAStackOffset; }
|
||||
void setRAStackOffset(int Off) { RAStackOffset = Off; }
|
||||
|
||||
int getStackAdjust() const { return StackAdjust; }
|
||||
void setStackAdjust(int Adj) { StackAdjust = Adj; }
|
||||
|
||||
int getGPStackOffset() const { return GPHolder.SPOffset; }
|
||||
int getGPFI() const { return GPHolder.FI; }
|
||||
void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
|
||||
@ -98,6 +108,19 @@ public:
|
||||
bool hasLoadArgs() const { return HasLoadArgs; }
|
||||
bool hasStoreVarArgs() const { return HasStoreVarArgs; }
|
||||
|
||||
void recordLiveIn(int FI) {
|
||||
LiveInFI.push_back(FI);
|
||||
}
|
||||
|
||||
bool isLiveIn(int FI) {
|
||||
for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i)
|
||||
if (FI == LiveInFI[i]) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const SmallVector<int, 16>& getLiveIn() const { return LiveInFI; }
|
||||
|
||||
void recordLoadArgsFI(int FI, int SPOffset) {
|
||||
if (!HasLoadArgs) HasLoadArgs=true;
|
||||
FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset));
|
||||
|
@ -210,6 +210,8 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
|
||||
RegScavenger *RS) const {
|
||||
MachineInstr &MI = *II;
|
||||
MachineFunction &MF = *MI.getParent()->getParent();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
|
||||
|
||||
unsigned i = 0;
|
||||
while (!MI.getOperand(i).isFI()) {
|
||||
@ -233,11 +235,14 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
|
||||
|
||||
// as explained on LowerFormalArguments, detect negative offsets
|
||||
// and adjust SPOffsets considering the final stack size.
|
||||
spOffset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
|
||||
spOffset += MI.getOperand(oi).getImm();
|
||||
DEBUG(errs() << "Offset : " << spOffset << "\n" << "<--------->\n");
|
||||
int Offset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
|
||||
Offset += MI.getOperand(oi).getImm();
|
||||
if (!MFI->isFixedObjectIndex(FrameIndex) && !MBlazeFI->isLiveIn(FrameIndex) && spOffset >= 0)
|
||||
Offset -= MBlazeFI->getStackAdjust();
|
||||
|
||||
MI.getOperand(oi).ChangeToImmediate(spOffset);
|
||||
DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
|
||||
|
||||
MI.getOperand(oi).ChangeToImmediate(Offset);
|
||||
MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user