mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-04 01:11:44 +00:00
Reworking the stack layout generated by the MBlaze backend.
llvm-svn: 121355
This commit is contained in:
parent
96545f21b9
commit
33ba317cf6
@ -163,7 +163,6 @@ void MBlazeAsmPrinter::emitFrameDirective() {
|
||||
unsigned stkReg = RI.getFrameRegister(*MF);
|
||||
unsigned retReg = RI.getRARegister();
|
||||
unsigned stkSze = MF->getFrameInfo()->getStackSize();
|
||||
if (stkSze < 28 && MF->getFrameInfo()->adjustsStack()) stkSze = 28;
|
||||
|
||||
OutStreamer.EmitRawText("\t.frame\t" +
|
||||
Twine(MBlazeInstPrinter::getRegisterName(stkReg)) +
|
||||
@ -183,11 +182,6 @@ void MBlazeAsmPrinter::EmitFunctionBodyStart() {
|
||||
|
||||
emitFrameDirective();
|
||||
printSavedRegsBitmask();
|
||||
|
||||
// SmallString<128> Str;
|
||||
// raw_svector_ostream OS(Str);
|
||||
// printSavedRegsBitmask(OS);
|
||||
// OutStreamer.EmitRawText(OS.str());
|
||||
}
|
||||
|
||||
void MBlazeAsmPrinter::EmitFunctionBodyEnd() {
|
||||
|
@ -19,8 +19,10 @@ class CCIfSubtarget<string F, CCAction A>:
|
||||
|
||||
def RetCC_MBlaze : CallingConv<[
|
||||
// i32 are returned in registers R3, R4
|
||||
CCIfType<[i32], CCAssignToReg<[R3, R4]>>,
|
||||
|
||||
// f32 are returned in registers R3, R4
|
||||
CCIfType<[f32], CCAssignToReg<[R3, R4]>>
|
||||
CCIfType<[i32,f32], CCAssignToReg<[R3, R4]>>
|
||||
]>;
|
||||
|
||||
def CC_MBlaze : CallingConv<[
|
||||
CCIfType<[i32,f32], CCCustom<"CC_MBlaze_AssignReg">>,
|
||||
CCIfType<[i32,f32], CCAssignToStack<4, 4>>
|
||||
]>;
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Stack Frame Processing methods
|
||||
@ -48,51 +47,6 @@ bool MBlazeFrameInfo::hasFP(const MachineFunction &MF) const {
|
||||
return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
|
||||
}
|
||||
|
||||
void MBlazeFrameInfo::adjustMBlazeStackFrame(MachineFunction &MF) const {
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
|
||||
|
||||
// See the description at MicroBlazeMachineFunction.h
|
||||
int TopCPUSavedRegOff = -1;
|
||||
|
||||
// Adjust CPU Callee Saved Registers Area. Registers RA and FP must
|
||||
// be saved in this CPU Area there is the need. This whole Area must
|
||||
// be aligned to the default Stack Alignment requirements.
|
||||
unsigned StackOffset = MFI->getStackSize();
|
||||
unsigned RegSize = 4;
|
||||
|
||||
// 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);
|
||||
|
||||
if (hasFP(MF)) {
|
||||
MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
|
||||
StackOffset);
|
||||
MBlazeFI->setFPStackOffset(StackOffset);
|
||||
TopCPUSavedRegOff = StackOffset;
|
||||
StackOffset += RegSize;
|
||||
}
|
||||
|
||||
if (MFI->adjustsStack()) {
|
||||
MBlazeFI->setRAStackOffset(0);
|
||||
MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
|
||||
StackOffset);
|
||||
TopCPUSavedRegOff = StackOffset;
|
||||
StackOffset += RegSize;
|
||||
}
|
||||
|
||||
// Update frame info
|
||||
MFI->setStackSize(StackOffset);
|
||||
|
||||
// Recalculate the final tops offset. The final values must be '0'
|
||||
// if there isn't a callee saved register for CPU or FPU, otherwise
|
||||
// a negative offset is needed.
|
||||
if (TopCPUSavedRegOff >= 0)
|
||||
MBlazeFI->setCPUTopSavedRegOff(TopCPUSavedRegOff-StackOffset);
|
||||
}
|
||||
|
||||
void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const {
|
||||
MachineBasicBlock &MBB = MF.front();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
@ -102,15 +56,17 @@ void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const {
|
||||
MachineBasicBlock::iterator MBBI = MBB.begin();
|
||||
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
|
||||
|
||||
// Get the right frame order for MBlaze.
|
||||
adjustMBlazeStackFrame(MF);
|
||||
// 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 StackSize = MFI->getStackSize();
|
||||
|
||||
// No need to allocate space on the stack.
|
||||
if (StackSize == 0 && !MFI->adjustsStack()) return;
|
||||
if (StackSize < 28 && MFI->adjustsStack()) StackSize = 28;
|
||||
|
||||
int FPOffset = MBlazeFI->getFPStackOffset();
|
||||
int RAOffset = MBlazeFI->getRAStackOffset();
|
||||
@ -119,15 +75,12 @@ void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const {
|
||||
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDI), MBlaze::R1)
|
||||
.addReg(MBlaze::R1).addImm(-StackSize);
|
||||
|
||||
// Save the return address only if the function isnt a leaf one.
|
||||
// swi R15, R1, stack_loc
|
||||
if (MFI->adjustsStack()) {
|
||||
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
|
||||
.addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset);
|
||||
}
|
||||
|
||||
// if framepointer enabled, save it and set it
|
||||
// to point to the stack pointer
|
||||
if (hasFP(MF)) {
|
||||
// swi R19, R1, stack_loc
|
||||
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
|
||||
@ -153,8 +106,6 @@ void MBlazeFrameInfo::emitEpilogue(MachineFunction &MF,
|
||||
int FPOffset = MBlazeFI->getFPStackOffset();
|
||||
int RAOffset = MBlazeFI->getRAStackOffset();
|
||||
|
||||
// if framepointer enabled, restore it and restore the
|
||||
// stack pointer
|
||||
if (hasFP(MF)) {
|
||||
// add R1, R19, R0
|
||||
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1)
|
||||
@ -165,7 +116,6 @@ void MBlazeFrameInfo::emitEpilogue(MachineFunction &MF,
|
||||
.addReg(MBlaze::R1).addImm(FPOffset);
|
||||
}
|
||||
|
||||
// Restore the return address only if the function isnt a leaf one.
|
||||
// lwi R15, R1, stack_loc
|
||||
if (MFI->adjustsStack()) {
|
||||
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15)
|
||||
@ -174,12 +124,26 @@ void MBlazeFrameInfo::emitEpilogue(MachineFunction &MF,
|
||||
|
||||
// Get the number of bytes from FrameInfo
|
||||
int StackSize = (int) MFI->getStackSize();
|
||||
if (StackSize < 28 && MFI->adjustsStack()) StackSize = 28;
|
||||
|
||||
// adjust stack.
|
||||
// addi R1, R1, imm
|
||||
if (StackSize) {
|
||||
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDI), MBlaze::R1)
|
||||
.addReg(MBlaze::R1).addImm(StackSize);
|
||||
}
|
||||
}
|
||||
|
||||
void MBlazeFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS)
|
||||
const {
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
|
||||
|
||||
if (MFI->adjustsStack()) {
|
||||
MBlazeFI->setRAStackOffset(0);
|
||||
MFI->CreateFixedObject(4,0,true);
|
||||
}
|
||||
|
||||
if (hasFP(MF)) {
|
||||
MBlazeFI->setFPStackOffset(4);
|
||||
MFI->CreateFixedObject(4,4,true);
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHA_FRAMEINFO_H
|
||||
#define ALPHA_FRAMEINFO_H
|
||||
#ifndef MBLAZE_FRAMEINFO_H
|
||||
#define MBLAZE_FRAMEINFO_H
|
||||
|
||||
#include "MBlaze.h"
|
||||
#include "MBlazeSubtarget.h"
|
||||
@ -27,11 +27,9 @@ protected:
|
||||
|
||||
public:
|
||||
explicit MBlazeFrameInfo(const MBlazeSubtarget &sti)
|
||||
: TargetFrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0), STI(sti) {
|
||||
: TargetFrameInfo(TargetFrameInfo::StackGrowsUp, 4, 0), STI(sti) {
|
||||
}
|
||||
|
||||
void adjustMBlazeStackFrame(MachineFunction &MF) const;
|
||||
|
||||
/// targetHandlesStackFrameRounding - Returns true if the target is
|
||||
/// responsible for rounding up the stack frame (probably at emitPrologue
|
||||
/// time).
|
||||
@ -43,6 +41,9 @@ public:
|
||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||
|
||||
bool hasFP(const MachineFunction &MF) const;
|
||||
|
||||
virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
RegScavenger *RS) const;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -35,6 +35,11 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
static bool CC_MBlaze_AssignReg(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State);
|
||||
|
||||
const char *MBlazeTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch (Opcode) {
|
||||
case MBlazeISD::JmpLink : return "MBlazeISD::JmpLink";
|
||||
@ -468,47 +473,24 @@ SDValue MBlazeTargetLowering::LowerVASTART(SDValue Op,
|
||||
|
||||
#include "MBlazeGenCallingConv.inc"
|
||||
|
||||
static bool CC_MBlaze2(unsigned ValNo, MVT ValVT,
|
||||
MVT LocVT, CCValAssign::LocInfo LocInfo,
|
||||
ISD::ArgFlagsTy ArgFlags, CCState &State) {
|
||||
static const unsigned RegsSize=6;
|
||||
static const unsigned IntRegs[] = {
|
||||
static bool CC_MBlaze_AssignReg(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
static const unsigned ArgRegs[] = {
|
||||
MBlaze::R5, MBlaze::R6, MBlaze::R7,
|
||||
MBlaze::R8, MBlaze::R9, MBlaze::R10
|
||||
};
|
||||
|
||||
unsigned Reg=0;
|
||||
const unsigned NumArgRegs = array_lengthof(ArgRegs);
|
||||
unsigned Reg = State.AllocateReg(ArgRegs, NumArgRegs);
|
||||
if (!Reg) return false;
|
||||
|
||||
// Promote i8 and i16
|
||||
if (LocVT == MVT::i8 || LocVT == MVT::i16) {
|
||||
LocVT = MVT::i32;
|
||||
if (ArgFlags.isSExt())
|
||||
LocInfo = CCValAssign::SExt;
|
||||
else if (ArgFlags.isZExt())
|
||||
LocInfo = CCValAssign::ZExt;
|
||||
else
|
||||
LocInfo = CCValAssign::AExt;
|
||||
}
|
||||
unsigned SizeInBytes = ValVT.getSizeInBits() >> 3;
|
||||
State.AllocateStack(SizeInBytes, SizeInBytes);
|
||||
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
|
||||
if (ValVT == MVT::i32) {
|
||||
Reg = State.AllocateReg(IntRegs, RegsSize);
|
||||
LocVT = MVT::i32;
|
||||
} else if (ValVT == MVT::f32) {
|
||||
Reg = State.AllocateReg(IntRegs, RegsSize);
|
||||
LocVT = MVT::f32;
|
||||
}
|
||||
|
||||
if (!Reg) {
|
||||
unsigned SizeInBytes = ValVT.getSizeInBits() >> 3;
|
||||
unsigned Offset = State.AllocateStack(SizeInBytes, SizeInBytes);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
|
||||
} else {
|
||||
unsigned SizeInBytes = ValVT.getSizeInBits() >> 3;
|
||||
State.AllocateStack(SizeInBytes, SizeInBytes);
|
||||
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
}
|
||||
|
||||
return false; // CC must always match
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -529,27 +511,31 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
|
||||
// MBlaze does not yet support tail call optimization
|
||||
isTailCall = false;
|
||||
|
||||
// The MBlaze requires stack slots for arguments passed to var arg
|
||||
// functions even if they are passed in registers.
|
||||
bool needsRegArgSlots = isVarArg;
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
|
||||
|
||||
// Analyze operands of the call, assigning locations to each operand.
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs,
|
||||
*DAG.getContext());
|
||||
CCInfo.AnalyzeCallOperands(Outs, CC_MBlaze2);
|
||||
CCInfo.AnalyzeCallOperands(Outs, CC_MBlaze);
|
||||
|
||||
// Get a count of how many bytes are to be pushed on the stack.
|
||||
unsigned NumBytes = CCInfo.getNextStackOffset();
|
||||
|
||||
// Variable argument function calls require a minimum of 24-bytes of stack
|
||||
if (isVarArg && NumBytes < 24) NumBytes = 24;
|
||||
|
||||
Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true));
|
||||
|
||||
SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
|
||||
SmallVector<SDValue, 8> MemOpChains;
|
||||
|
||||
// First/LastArgStackLoc contains the first/last
|
||||
// "at stack" argument location.
|
||||
int LastArgStackLoc = 0;
|
||||
unsigned FirstStackArgLoc = 0;
|
||||
|
||||
// Walk the register/memloc assignments, inserting copies/loads.
|
||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
@ -579,10 +565,15 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
|
||||
// Register can't get to this point...
|
||||
assert(VA.isMemLoc());
|
||||
|
||||
// Since we are alread passing values on the stack we don't
|
||||
// need to worry about creating additional slots for the
|
||||
// values passed via registers.
|
||||
needsRegArgSlots = false;
|
||||
|
||||
// Create the frame index object for this incoming parameter
|
||||
LastArgStackLoc = (FirstStackArgLoc + VA.getLocMemOffset());
|
||||
int FI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8,
|
||||
LastArgStackLoc, true);
|
||||
unsigned ArgSize = VA.getValVT().getSizeInBits()/8;
|
||||
unsigned StackLoc = VA.getLocMemOffset() + 4;
|
||||
int FI = MFI->CreateFixedObject(ArgSize, StackLoc, true);
|
||||
|
||||
SDValue PtrOff = DAG.getFrameIndex(FI,getPointerTy());
|
||||
|
||||
@ -594,6 +585,11 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
|
||||
}
|
||||
}
|
||||
|
||||
// If we need to reserve stack space for the arguments passed via registers
|
||||
// then create a fixed stack object at the beginning of the stack.
|
||||
if (needsRegArgSlots && TFI.hasReservedCallFrame(MF))
|
||||
MFI->CreateFixedObject(28,0,true);
|
||||
|
||||
// Transform all store nodes into one single node because all store
|
||||
// nodes are independent of each other.
|
||||
if (!MemOpChains.empty())
|
||||
@ -710,11 +706,9 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
|
||||
CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
|
||||
ArgLocs, *DAG.getContext());
|
||||
|
||||
CCInfo.AnalyzeFormalArguments(Ins, CC_MBlaze2);
|
||||
CCInfo.AnalyzeFormalArguments(Ins, CC_MBlaze);
|
||||
SDValue StackPtr;
|
||||
|
||||
unsigned FirstStackArgLoc = 0;
|
||||
|
||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
|
||||
@ -753,9 +747,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
|
||||
}
|
||||
|
||||
InVals.push_back(ArgValue);
|
||||
|
||||
} else { // VA.isRegLoc()
|
||||
|
||||
// sanity check
|
||||
assert(VA.isMemLoc());
|
||||
|
||||
@ -771,9 +763,9 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
|
||||
// offset on PEI::calculateFrameObjectOffsets.
|
||||
// Arguments are always 32-bit.
|
||||
unsigned ArgSize = VA.getLocVT().getSizeInBits()/8;
|
||||
unsigned StackLoc = VA.getLocMemOffset() + 4;
|
||||
int FI = MFI->CreateFixedObject(ArgSize, 0, true);
|
||||
MBlazeFI->recordLoadArgsFI(FI, -(ArgSize+
|
||||
(FirstStackArgLoc + VA.getLocMemOffset())));
|
||||
MBlazeFI->recordLoadArgsFI(FI, -StackLoc);
|
||||
|
||||
// Create load nodes to retrieve arguments from the stack
|
||||
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
|
||||
@ -796,7 +788,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
|
||||
unsigned Begin = MBlazeRegisterInfo::getRegisterNumbering(MBlaze::R5);
|
||||
unsigned Start = MBlazeRegisterInfo::getRegisterNumbering(ArgRegEnd+1);
|
||||
unsigned End = MBlazeRegisterInfo::getRegisterNumbering(MBlaze::R10);
|
||||
unsigned StackLoc = ArgLocs.size()-1 + (Start - Begin);
|
||||
unsigned StackLoc = Start - Begin + 1;
|
||||
|
||||
for (; Start <= End; ++Start, ++StackLoc) {
|
||||
unsigned Reg = MBlazeRegisterInfo::getRegisterFromNumbering(Start);
|
||||
@ -804,7 +796,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
|
||||
SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, LiveReg, MVT::i32);
|
||||
|
||||
int FI = MFI->CreateFixedObject(4, 0, true);
|
||||
MBlazeFI->recordStoreVarArgsFI(FI, -(4+(StackLoc*4)));
|
||||
MBlazeFI->recordStoreVarArgsFI(FI, -(StackLoc*4));
|
||||
SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy());
|
||||
OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff,
|
||||
MachinePointerInfo(),
|
||||
|
@ -34,12 +34,6 @@ private:
|
||||
/// saved. This is used on Prologue and Epilogue to emit RA save/restore
|
||||
int RAStackOffset;
|
||||
|
||||
/// At each function entry a special bitmask directive must be emitted
|
||||
/// to help in debugging CPU callee saved registers. It needs a negative
|
||||
/// offset from the final stack size and its higher register location on
|
||||
/// the stack.
|
||||
int CPUTopSavedRegOff;
|
||||
|
||||
/// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
|
||||
struct MBlazeFIHolder {
|
||||
|
||||
@ -84,9 +78,9 @@ private:
|
||||
|
||||
public:
|
||||
MBlazeFunctionInfo(MachineFunction& MF)
|
||||
: FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0),
|
||||
GPHolder(-1,-1), HasLoadArgs(false), HasStoreVarArgs(false),
|
||||
SRetReturnReg(0), GlobalBaseReg(0), VarArgsFrameIndex(0)
|
||||
: FPStackOffset(0), RAStackOffset(0), GPHolder(-1,-1),
|
||||
HasLoadArgs(false), HasStoreVarArgs(false), SRetReturnReg(0),
|
||||
GlobalBaseReg(0), VarArgsFrameIndex(0)
|
||||
{}
|
||||
|
||||
int getFPStackOffset() const { return FPStackOffset; }
|
||||
@ -95,9 +89,6 @@ public:
|
||||
int getRAStackOffset() const { return RAStackOffset; }
|
||||
void setRAStackOffset(int Off) { RAStackOffset = Off; }
|
||||
|
||||
int getCPUTopSavedRegOff() const { return CPUTopSavedRegOff; }
|
||||
void setCPUTopSavedRegOff(int Off) { CPUTopSavedRegOff = Off; }
|
||||
|
||||
int getGPStackOffset() const { return GPHolder.SPOffset; }
|
||||
int getGPFI() const { return GPHolder.FI; }
|
||||
void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
|
||||
|
@ -164,11 +164,40 @@ getReservedRegs(const MachineFunction &MF) const {
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
// This function eliminate ADJCALLSTACKDOWN,
|
||||
// ADJCALLSTACKUP pseudo instructions
|
||||
// This function eliminate ADJCALLSTACKDOWN/ADJCALLSTACKUP pseudo instructions
|
||||
void MBlazeRegisterInfo::
|
||||
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I) const {
|
||||
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
|
||||
|
||||
if (!TFI->hasReservedCallFrame(MF)) {
|
||||
// If we have a frame pointer, turn the adjcallstackup instruction into a
|
||||
// 'addi r1, r1, -<amt>' and the adjcallstackdown instruction into
|
||||
// 'addi r1, r1, <amt>'
|
||||
MachineInstr *Old = I;
|
||||
int Amount = Old->getOperand(0).getImm() + 4;
|
||||
if (Amount != 0) {
|
||||
// We need to keep the stack aligned properly. To do this, we round the
|
||||
// amount of space needed for the outgoing arguments up to the next
|
||||
// alignment boundary.
|
||||
unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
|
||||
Amount = (Amount+Align-1)/Align*Align;
|
||||
|
||||
MachineInstr *New;
|
||||
if (Old->getOpcode() == MBlaze::ADJCALLSTACKDOWN) {
|
||||
New = BuildMI(MF, Old->getDebugLoc(), TII.get(MBlaze::ADDI), MBlaze::R1)
|
||||
.addReg(MBlaze::R1).addImm(-Amount);
|
||||
} else {
|
||||
assert(Old->getOpcode() == MBlaze::ADJCALLSTACKUP);
|
||||
New = BuildMI(MF, Old->getDebugLoc(), TII.get(MBlaze::ADDI), MBlaze::R1)
|
||||
.addReg(MBlaze::R1).addImm(Amount);
|
||||
}
|
||||
|
||||
// Replace the pseudo instruction with a new instruction...
|
||||
MBB.insert(I, New);
|
||||
}
|
||||
}
|
||||
|
||||
// Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
|
||||
MBB.erase(I);
|
||||
}
|
||||
@ -204,12 +233,11 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
|
||||
|
||||
// as explained on LowerFormalArguments, detect negative offsets
|
||||
// and adjust SPOffsets considering the final stack size.
|
||||
int Offset = (spOffset < 0) ? (stackSize - spOffset) : (spOffset + 4);
|
||||
Offset += MI.getOperand(oi).getImm();
|
||||
spOffset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
|
||||
spOffset += MI.getOperand(oi).getImm();
|
||||
DEBUG(errs() << "Offset : " << spOffset << "\n" << "<--------->\n");
|
||||
|
||||
DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
|
||||
|
||||
MI.getOperand(oi).ChangeToImmediate(Offset);
|
||||
MI.getOperand(oi).ChangeToImmediate(spOffset);
|
||||
MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
|
||||
}
|
||||
|
||||
|
@ -48,9 +48,6 @@ struct MBlazeRegisterInfo : public MBlazeGenRegisterInfo {
|
||||
/// Get PIC indirect call register
|
||||
static unsigned getPICCallReg();
|
||||
|
||||
/// Adjust the MBlaze stack frame.
|
||||
void adjustMBlazeStackFrame(MachineFunction &MF) const;
|
||||
|
||||
/// Code Generation virtual methods...
|
||||
const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const;
|
||||
|
||||
|
@ -97,8 +97,8 @@ MBlazeTargetMachine(const Target &T, const std::string &TT,
|
||||
|
||||
// Install an instruction selector pass using
|
||||
// the ISelDag to gen MBlaze code.
|
||||
bool MBlazeTargetMachine::
|
||||
addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel) {
|
||||
bool MBlazeTargetMachine::addInstSelector(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel) {
|
||||
PM.add(createMBlazeISelDag(*this));
|
||||
return false;
|
||||
}
|
||||
@ -106,8 +106,8 @@ addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel) {
|
||||
// Implemented by targets that want to run passes immediately before
|
||||
// machine code is emitted. return true if -print-machineinstrs should
|
||||
// print out the code after the passes.
|
||||
bool MBlazeTargetMachine::
|
||||
addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel) {
|
||||
bool MBlazeTargetMachine::addPreEmitPass(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel) {
|
||||
PM.add(createMBlazeDelaySlotFillerPass(*this));
|
||||
return true;
|
||||
}
|
||||
|
@ -71,11 +71,8 @@ namespace llvm {
|
||||
}
|
||||
|
||||
// Pass Pipeline Configuration
|
||||
virtual bool addInstSelector(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
|
||||
virtual bool addPreEmitPass(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level Opt);
|
||||
virtual bool addPreEmitPass(PassManagerBase &PM,CodeGenOpt::Level Opt);
|
||||
};
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -12,12 +12,12 @@ TARGET = MBlaze
|
||||
|
||||
# Make sure that tblgen is run, first thing.
|
||||
BUILT_SOURCES = MBlazeGenRegisterInfo.h.inc MBlazeGenRegisterNames.inc \
|
||||
MBlazeGenRegisterInfo.inc MBlazeGenInstrNames.inc \
|
||||
MBlazeGenInstrInfo.inc MBlazeGenAsmWriter.inc \
|
||||
MBlazeGenDAGISel.inc MBlazeGenAsmMatcher.inc \
|
||||
MBlazeGenCodeEmitter.inc MBlazeGenCallingConv.inc \
|
||||
MBlazeGenSubtarget.inc MBlazeGenIntrinsics.inc \
|
||||
MBlazeGenEDInfo.inc
|
||||
MBlazeGenRegisterInfo.inc MBlazeGenInstrNames.inc \
|
||||
MBlazeGenInstrInfo.inc MBlazeGenAsmWriter.inc \
|
||||
MBlazeGenDAGISel.inc MBlazeGenAsmMatcher.inc \
|
||||
MBlazeGenCodeEmitter.inc MBlazeGenCallingConv.inc \
|
||||
MBlazeGenSubtarget.inc MBlazeGenIntrinsics.inc \
|
||||
MBlazeGenEDInfo.inc
|
||||
|
||||
DIRS = InstPrinter AsmParser Disassembler TargetInfo
|
||||
|
||||
|
@ -1,30 +1,14 @@
|
||||
* Writing out ELF files is close to working but the following needs to
|
||||
be examined more closely:
|
||||
- ELF relocation records are incorrect because the function
|
||||
ELFObjectWriter::RecordRelocation is hard coded for X86/X86-64.
|
||||
- Relocations use 2-byte / 4-byte to terminology in reference to
|
||||
the size of the immediate value being changed. The Xilinx
|
||||
terminology seems to be (???) 4-byte / 8-byte in reference
|
||||
to the number of bytes of instructions that are being changed.
|
||||
- BRLID and like instructions are always assumed to use a 4-byte
|
||||
immediate value for the relocation and BEQID and like instructions
|
||||
are always assumed to use a 2-byte immediate value for the relocation.
|
||||
I think this means that conditional branches like BEQID can only
|
||||
branch += 32768 bytes (~8192 instructions). We should allow conditional
|
||||
branches to use 4-byte relocations but I'm not sure how to do that
|
||||
right now.
|
||||
- Relocation records for indirect calls are not being generated
|
||||
correctly. These should emit and IMM 0 directly before the ORI
|
||||
instruction that loads the register (just like when a BRLID
|
||||
instruction is used instead of an ORI).
|
||||
|
||||
* Code generation seems to work relatively well now but the following
|
||||
needs to be examined more closely:
|
||||
- The stack layout needs to be examined to make sure it meets
|
||||
the standard, especially in regards to var arg functions.
|
||||
- The delay slot filler is ad hoc but seems to work. Load and
|
||||
store instructions were prevented from being moved to delay
|
||||
slots but I'm not sure that is necessary.
|
||||
- The processor itineraries are copied from a different backend
|
||||
and need to be updated to model the MicroBlaze correctly.
|
||||
- Look at the MBlazeGenFastISel.inc stuff and make use of it
|
||||
|
Loading…
Reference in New Issue
Block a user