aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWesley Peck <peckw@wesleypeck.com>2010-12-09 03:42:04 +0000
committerWesley Peck <peckw@wesleypeck.com>2010-12-09 03:42:04 +0000
commit8397be042766f1913ceaa2b3e6782de0322bbe6a (patch)
treec9a36c534fb1fc85287eedf1e15bb4452c401334
parent6b0fa635d5bfd80940e667cec1662e611f5d270f (diff)
downloadexternal_llvm-8397be042766f1913ceaa2b3e6782de0322bbe6a.zip
external_llvm-8397be042766f1913ceaa2b3e6782de0322bbe6a.tar.gz
external_llvm-8397be042766f1913ceaa2b3e6782de0322bbe6a.tar.bz2
Reworking the stack layout generated by the MBlaze backend.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121355 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/MBlaze/MBlazeAsmPrinter.cpp6
-rw-r--r--lib/Target/MBlaze/MBlazeCallingConv.td8
-rw-r--r--lib/Target/MBlaze/MBlazeFrameInfo.cpp78
-rw-r--r--lib/Target/MBlaze/MBlazeFrameInfo.h11
-rw-r--r--lib/Target/MBlaze/MBlazeISelLowering.cpp98
-rw-r--r--lib/Target/MBlaze/MBlazeMachineFunction.h15
-rw-r--r--lib/Target/MBlaze/MBlazeRegisterInfo.cpp42
-rw-r--r--lib/Target/MBlaze/MBlazeRegisterInfo.h3
-rw-r--r--lib/Target/MBlaze/MBlazeTargetMachine.cpp8
-rw-r--r--lib/Target/MBlaze/MBlazeTargetMachine.h7
-rw-r--r--lib/Target/MBlaze/Makefile12
-rw-r--r--lib/Target/MBlaze/TODO16
12 files changed, 127 insertions, 177 deletions
diff --git a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
index 50abd1a..dfeed65 100644
--- a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
+++ b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
@@ -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() {
diff --git a/lib/Target/MBlaze/MBlazeCallingConv.td b/lib/Target/MBlaze/MBlazeCallingConv.td
index d037b0e..4962573 100644
--- a/lib/Target/MBlaze/MBlazeCallingConv.td
+++ b/lib/Target/MBlaze/MBlazeCallingConv.td
@@ -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]>>,
+ CCIfType<[i32,f32], CCAssignToReg<[R3, R4]>>
+]>;
- // f32 are returned in registers R3, R4
- CCIfType<[f32], CCAssignToReg<[R3, R4]>>
+def CC_MBlaze : CallingConv<[
+ CCIfType<[i32,f32], CCCustom<"CC_MBlaze_AssignReg">>,
+ CCIfType<[i32,f32], CCAssignToStack<4, 4>>
]>;
diff --git a/lib/Target/MBlaze/MBlazeFrameInfo.cpp b/lib/Target/MBlaze/MBlazeFrameInfo.cpp
index 09f8e43..bd968e4 100644
--- a/lib/Target/MBlaze/MBlazeFrameInfo.cpp
+++ b/lib/Target/MBlaze/MBlazeFrameInfo.cpp
@@ -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);
+ }
+}
diff --git a/lib/Target/MBlaze/MBlazeFrameInfo.h b/lib/Target/MBlaze/MBlazeFrameInfo.h
index 204d2f8..03c39f0 100644
--- a/lib/Target/MBlaze/MBlazeFrameInfo.h
+++ b/lib/Target/MBlaze/MBlazeFrameInfo.h
@@ -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
diff --git a/lib/Target/MBlaze/MBlazeISelLowering.cpp b/lib/Target/MBlaze/MBlazeISelLowering.cpp
index 18293dc..c4c3e24 100644
--- a/lib/Target/MBlaze/MBlazeISelLowering.cpp
+++ b/lib/Target/MBlaze/MBlazeISelLowering.cpp
@@ -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;
- }
-
- 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;
- }
+ unsigned SizeInBytes = ValVT.getSizeInBits() >> 3;
+ State.AllocateStack(SizeInBytes, SizeInBytes);
+ State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
- 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(),
diff --git a/lib/Target/MBlaze/MBlazeMachineFunction.h b/lib/Target/MBlaze/MBlazeMachineFunction.h
index da74712..09b916e 100644
--- a/lib/Target/MBlaze/MBlazeMachineFunction.h
+++ b/lib/Target/MBlaze/MBlazeMachineFunction.h
@@ -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; }
diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
index f8f77f1..58aa151 100644
--- a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
+++ b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
@@ -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();
-
- DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
+ spOffset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
+ spOffset += MI.getOperand(oi).getImm();
+ DEBUG(errs() << "Offset : " << spOffset << "\n" << "<--------->\n");
- MI.getOperand(oi).ChangeToImmediate(Offset);
+ MI.getOperand(oi).ChangeToImmediate(spOffset);
MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
}
diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.h b/lib/Target/MBlaze/MBlazeRegisterInfo.h
index ac1635b..431a632 100644
--- a/lib/Target/MBlaze/MBlazeRegisterInfo.h
+++ b/lib/Target/MBlaze/MBlazeRegisterInfo.h
@@ -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;
diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
index 67a35d8..0df6add 100644
--- a/lib/Target/MBlaze/MBlazeTargetMachine.cpp
+++ b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
@@ -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;
}
diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.h b/lib/Target/MBlaze/MBlazeTargetMachine.h
index 12573d8..85a4c2f 100644
--- a/lib/Target/MBlaze/MBlazeTargetMachine.h
+++ b/lib/Target/MBlaze/MBlazeTargetMachine.h
@@ -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
diff --git a/lib/Target/MBlaze/Makefile b/lib/Target/MBlaze/Makefile
index 0150604..e01c60b 100644
--- a/lib/Target/MBlaze/Makefile
+++ b/lib/Target/MBlaze/Makefile
@@ -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
diff --git a/lib/Target/MBlaze/TODO b/lib/Target/MBlaze/TODO
index cc0aa48..2e613eb 100644
--- a/lib/Target/MBlaze/TODO
+++ b/lib/Target/MBlaze/TODO
@@ -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