mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-25 17:20:48 +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:
@@ -14,6 +14,7 @@
|
|||||||
#include "MBlazeFrameInfo.h"
|
#include "MBlazeFrameInfo.h"
|
||||||
#include "MBlazeInstrInfo.h"
|
#include "MBlazeInstrInfo.h"
|
||||||
#include "MBlazeMachineFunction.h"
|
#include "MBlazeMachineFunction.h"
|
||||||
|
#include "InstPrinter/MBlazeInstPrinter.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
@@ -26,6 +27,14 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
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
|
// 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
|
// 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
|
// pointer register. This is true if the function has variable sized allocas or
|
||||||
// if frame pointer elimination is disabled.
|
// if frame pointer elimination is disabled.
|
||||||
@@ -56,11 +174,8 @@ void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
MachineBasicBlock::iterator MBBI = MBB.begin();
|
MachineBasicBlock::iterator MBBI = MBB.begin();
|
||||||
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
|
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
|
||||||
|
|
||||||
// Replace the dummy '0' SPOffset by the negative offsets, as explained on
|
// Determine the correct frame layout
|
||||||
// LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
|
determineFrameLayout(MF);
|
||||||
// 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.
|
// Get the number of bytes to allocate from the FrameInfo.
|
||||||
unsigned StackSize = MFI->getStackSize();
|
unsigned StackSize = MFI->getStackSize();
|
||||||
@@ -146,4 +261,6 @@ void MBlazeFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|||||||
MBlazeFI->setFPStackOffset(4);
|
MBlazeFI->setFPStackOffset(4);
|
||||||
MFI->CreateFixedObject(4,4,true);
|
MFI->CreateFixedObject(4,4,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
analyzeFrameIndexes(MF);
|
||||||
}
|
}
|
||||||
|
@@ -766,6 +766,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
|
|||||||
unsigned StackLoc = VA.getLocMemOffset() + 4;
|
unsigned StackLoc = VA.getLocMemOffset() + 4;
|
||||||
int FI = MFI->CreateFixedObject(ArgSize, 0, true);
|
int FI = MFI->CreateFixedObject(ArgSize, 0, true);
|
||||||
MBlazeFI->recordLoadArgsFI(FI, -StackLoc);
|
MBlazeFI->recordLoadArgsFI(FI, -StackLoc);
|
||||||
|
MBlazeFI->recordLiveIn(FI);
|
||||||
|
|
||||||
// Create load nodes to retrieve arguments from the stack
|
// Create load nodes to retrieve arguments from the stack
|
||||||
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
|
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
|
||||||
|
@@ -650,7 +650,7 @@ def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)),
|
|||||||
(BRLID (i32 R15), texternalsym:$dst)>;
|
(BRLID (i32 R15), texternalsym:$dst)>;
|
||||||
|
|
||||||
def : Pat<(MBlazeJmpLink GPR:$dst),
|
def : Pat<(MBlazeJmpLink GPR:$dst),
|
||||||
(BRLD (i32 R15), GPR:$dst)>;
|
(BRALD (i32 R15), GPR:$dst)>;
|
||||||
|
|
||||||
// Shift Instructions
|
// Shift Instructions
|
||||||
def : Pat<(shl GPR:$L, GPR:$R), (ShiftL GPR:$L, GPR:$R)>;
|
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
|
/// saved. This is used on Prologue and Epilogue to emit RA save/restore
|
||||||
int RAStackOffset;
|
int RAStackOffset;
|
||||||
|
|
||||||
|
/// Holds the stack adjustment necessary for each function.
|
||||||
|
int StackAdjust;
|
||||||
|
|
||||||
/// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
|
/// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
|
||||||
struct MBlazeFIHolder {
|
struct MBlazeFIHolder {
|
||||||
|
|
||||||
@@ -76,11 +79,15 @@ private:
|
|||||||
// VarArgsFrameIndex - FrameIndex for start of varargs area.
|
// VarArgsFrameIndex - FrameIndex for start of varargs area.
|
||||||
int VarArgsFrameIndex;
|
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:
|
public:
|
||||||
MBlazeFunctionInfo(MachineFunction& MF)
|
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),
|
HasLoadArgs(false), HasStoreVarArgs(false), SRetReturnReg(0),
|
||||||
GlobalBaseReg(0), VarArgsFrameIndex(0)
|
GlobalBaseReg(0), VarArgsFrameIndex(0), LiveInFI()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int getFPStackOffset() const { return FPStackOffset; }
|
int getFPStackOffset() const { return FPStackOffset; }
|
||||||
@@ -89,6 +96,9 @@ public:
|
|||||||
int getRAStackOffset() const { return RAStackOffset; }
|
int getRAStackOffset() const { return RAStackOffset; }
|
||||||
void setRAStackOffset(int Off) { RAStackOffset = Off; }
|
void setRAStackOffset(int Off) { RAStackOffset = Off; }
|
||||||
|
|
||||||
|
int getStackAdjust() const { return StackAdjust; }
|
||||||
|
void setStackAdjust(int Adj) { StackAdjust = Adj; }
|
||||||
|
|
||||||
int getGPStackOffset() const { return GPHolder.SPOffset; }
|
int getGPStackOffset() const { return GPHolder.SPOffset; }
|
||||||
int getGPFI() const { return GPHolder.FI; }
|
int getGPFI() const { return GPHolder.FI; }
|
||||||
void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
|
void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
|
||||||
@@ -98,6 +108,19 @@ public:
|
|||||||
bool hasLoadArgs() const { return HasLoadArgs; }
|
bool hasLoadArgs() const { return HasLoadArgs; }
|
||||||
bool hasStoreVarArgs() const { return HasStoreVarArgs; }
|
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) {
|
void recordLoadArgsFI(int FI, int SPOffset) {
|
||||||
if (!HasLoadArgs) HasLoadArgs=true;
|
if (!HasLoadArgs) HasLoadArgs=true;
|
||||||
FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset));
|
FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset));
|
||||||
|
@@ -210,6 +210,8 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
|
|||||||
RegScavenger *RS) const {
|
RegScavenger *RS) const {
|
||||||
MachineInstr &MI = *II;
|
MachineInstr &MI = *II;
|
||||||
MachineFunction &MF = *MI.getParent()->getParent();
|
MachineFunction &MF = *MI.getParent()->getParent();
|
||||||
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
|
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
|
||||||
|
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
while (!MI.getOperand(i).isFI()) {
|
while (!MI.getOperand(i).isFI()) {
|
||||||
@@ -233,11 +235,14 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
|
|||||||
|
|
||||||
// as explained on LowerFormalArguments, detect negative offsets
|
// as explained on LowerFormalArguments, detect negative offsets
|
||||||
// and adjust SPOffsets considering the final stack size.
|
// and adjust SPOffsets considering the final stack size.
|
||||||
spOffset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
|
int Offset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
|
||||||
spOffset += MI.getOperand(oi).getImm();
|
Offset += MI.getOperand(oi).getImm();
|
||||||
DEBUG(errs() << "Offset : " << spOffset << "\n" << "<--------->\n");
|
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);
|
MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user