summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorWesley Peck <peckw@wesleypeck.com>2010-03-05 15:26:02 +0000
committerWesley Peck <peckw@wesleypeck.com>2010-03-05 15:26:02 +0000
commitc4155d591b2c28877695543dd8fe195e52922166 (patch)
treef2e0b5eaad2b5e589f4429a1e67ca1f4740fda15 /lib
parentc84a9566cb41ef19f25ab2685c503624d0c8ddd7 (diff)
downloadllvm-c4155d591b2c28877695543dd8fe195e52922166.tar.gz
llvm-c4155d591b2c28877695543dd8fe195e52922166.tar.bz2
llvm-c4155d591b2c28877695543dd8fe195e52922166.tar.xz
Reworking the stack layout that the MicroBlaze backend generates.
The MicroBlaze backend was generating stack layouts that did not conform correctly to the ABI. This update generates stack layouts which are closer to what GCC does. Variable arguments support was added as well but the stack layout for varargs has not been finalized. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97807 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp8
-rw-r--r--lib/Target/MBlaze/MBlazeISelLowering.cpp216
-rw-r--r--lib/Target/MBlaze/MBlazeISelLowering.h3
-rw-r--r--lib/Target/MBlaze/MBlazeRegisterInfo.cpp57
-rw-r--r--lib/Target/MBlaze/MBlazeRegisterInfo.h6
5 files changed, 243 insertions, 47 deletions
diff --git a/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp b/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp
index a0ebea0f35..7e59c4a164 100644
--- a/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp
+++ b/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp
@@ -129,15 +129,15 @@ SelectAddrRegReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) {
N.getOpcode() == ISD::TargetGlobalAddress)
return false; // direct calls.
- if (N.getOperand(0).getOpcode() == ISD::TargetJumpTable ||
- N.getOperand(1).getOpcode() == ISD::TargetJumpTable)
- return false; // jump tables.
-
int32_t imm = 0;
if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
if (isIntS32Immediate(N.getOperand(1), imm))
return false; // r+i
+ if (N.getOperand(0).getOpcode() == ISD::TargetJumpTable ||
+ N.getOperand(1).getOpcode() == ISD::TargetJumpTable)
+ return false; // jump tables.
+
Base = N.getOperand(1);
Index = N.getOperand(0);
return true;
diff --git a/lib/Target/MBlaze/MBlazeISelLowering.cpp b/lib/Target/MBlaze/MBlazeISelLowering.cpp
index 7790248669..b043b9188c 100644
--- a/lib/Target/MBlaze/MBlazeISelLowering.cpp
+++ b/lib/Target/MBlaze/MBlazeISelLowering.cpp
@@ -138,6 +138,13 @@ MBlazeTargetLowering::MBlazeTargetLowering(MBlazeTargetMachine &TM)
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
+ // Variable Argument support
+ setOperationAction(ISD::VASTART, MVT::Other, Custom);
+ setOperationAction(ISD::VAEND, MVT::Other, Expand);
+ setOperationAction(ISD::VAARG, MVT::Other, Expand);
+ setOperationAction(ISD::VACOPY, MVT::Other, Expand);
+
+
// Operations not directly supported by MBlaze.
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
@@ -186,6 +193,7 @@ SDValue MBlazeTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
+ case ISD::VASTART: return LowerVASTART(Op, DAG);
}
return SDValue();
}
@@ -440,7 +448,6 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) {
ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
Constant *C = N->getConstVal();
SDValue Zero = DAG.getConstant(0, PtrVT);
- // FIXME there isn't actually debug info here
DebugLoc dl = Op.getDebugLoc();
SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
@@ -448,12 +455,121 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) {
return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, CP);
}
+SDValue MBlazeTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) {
+ DebugLoc dl = Op.getDebugLoc();
+ SDValue FI = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
+
+ // vastart just stores the address of the VarArgsFrameIndex slot into the
+ // memory location argument.
+ const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
+ return DAG.getStore(Op.getOperand(0), dl, FI, Op.getOperand(1), SV, 0,
+ false, false, 0);
+}
+
//===----------------------------------------------------------------------===//
// Calling Convention Implementation
//===----------------------------------------------------------------------===//
#include "MBlazeGenCallingConv.inc"
+static bool CC_MBlaze2(unsigned ValNo, EVT ValVT,
+ EVT LocVT, CCValAssign::LocInfo LocInfo,
+ ISD::ArgFlagsTy ArgFlags, CCState &State) {
+ static const unsigned RegsSize=6;
+ static const unsigned IntRegs[] = {
+ MBlaze::R5, MBlaze::R6, MBlaze::R7,
+ MBlaze::R8, MBlaze::R9, MBlaze::R10
+ };
+
+ static const unsigned FltRegs[] = {
+ MBlaze::F5, MBlaze::F6, MBlaze::F7,
+ MBlaze::F8, MBlaze::F9, MBlaze::F10
+ };
+
+ unsigned Reg=0;
+ //unsigned UnallocIntReg = State.getFirstUnallocated(IntRegs, RegsSize);
+
+ // 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(FltRegs, 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;
+ unsigned Offset = State.AllocateStack(SizeInBytes, SizeInBytes);
+ State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
+ }
+
+ return false; // CC must always match
+}
+
+static bool CC_MBlaze_VarArg(unsigned ValNo, EVT ValVT,
+ EVT LocVT, CCValAssign::LocInfo LocInfo,
+ ISD::ArgFlagsTy ArgFlags, CCState &State) {
+ static const unsigned RegsSize=6;
+ static const unsigned IntRegs[] = {
+ MBlaze::R5, MBlaze::R6, MBlaze::R7,
+ MBlaze::R8, MBlaze::R9, MBlaze::R10
+ };
+
+ static const unsigned FltRegs[] = {
+ MBlaze::F5, MBlaze::F6, MBlaze::F7,
+ MBlaze::F8, MBlaze::F9, MBlaze::F10
+ };
+
+ // 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) {
+ if (unsigned Reg = State.AllocateReg(IntRegs, RegsSize)) {
+ unsigned SizeInBytes = ValVT.getSizeInBits() >> 3;
+ State.AllocateStack(SizeInBytes, SizeInBytes);
+ State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, MVT::i32, LocInfo));
+ return false;
+ }
+ } else if (ValVT == MVT::f32) {
+ if (unsigned Reg = State.AllocateReg(FltRegs, RegsSize)) {
+ unsigned SizeInBytes = ValVT.getSizeInBits() >> 3;
+ State.AllocateStack(SizeInBytes, SizeInBytes);
+ State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, MVT::i32, LocInfo));
+ return false;
+ }
+ }
+
+ unsigned SizeInBytes = ValVT.getSizeInBits() >> 3;
+ unsigned Off = State.AllocateStack(SizeInBytes, SizeInBytes);
+ State.addLoc(CCValAssign::getMem(ValNo, ValVT, Off, LocVT, LocInfo));
+ return false;
+}
+
+
+
//===----------------------------------------------------------------------===//
// Call Calling Convention Implementation
//===----------------------------------------------------------------------===//
@@ -468,6 +584,9 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // MBlaze does not yet support tail call optimization
+ isTailCall = false;
+
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
@@ -475,7 +594,7 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs,
*DAG.getContext());
- CCInfo.AnalyzeCallOperands(Outs, CC_MBlaze);
+ CCInfo.AnalyzeCallOperands(Outs, CC_MBlaze2);
// Get a count of how many bytes are to be pushed on the stack.
unsigned NumBytes = CCInfo.getNextStackOffset();
@@ -487,7 +606,7 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
// First/LastArgStackLoc contains the first/last
// "at stack" argument location.
int LastArgStackLoc = 0;
- unsigned FirstStackArgLoc = 4;
+ unsigned FirstStackArgLoc = 0;
// Walk the register/memloc assignments, inserting copies/loads.
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
@@ -508,9 +627,6 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
case CCValAssign::AExt:
Arg = DAG.getNode(ISD::ANY_EXTEND, dl, RegVT, Arg);
break;
- case CCValAssign::BCvt:
- Arg = DAG.getNode(ISD::BIT_CONVERT, dl, RegVT, Arg);
- break;
}
// Arguments that can be passed on register must be kept at
@@ -617,7 +733,7 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv,
RVLocs[i].getValVT(), InFlag).getValue(1);
InFlag = Chain.getValue(2);
InVals.push_back(Chain.getValue(0));
- }
+ }
return Chain;
}
@@ -629,7 +745,6 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv,
/// LowerFormalArguments - transform physical registers into
/// virtual registers and generate load operations for
/// arguments places on the stack.
-/// TODO: isVarArg
SDValue MBlazeTargetLowering::
LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
@@ -640,16 +755,23 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF);
+ VarArgsFrameIndex = 0;
+
+ // Used with vargs to acumulate store chains.
+ std::vector<SDValue> OutChains;
+
+ // Keep track of the last register used for arguments
+ unsigned ArgRegEnd = 0;
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
ArgLocs, *DAG.getContext());
- CCInfo.AnalyzeFormalArguments(Ins, CC_MBlaze);
+ CCInfo.AnalyzeFormalArguments(Ins, CC_MBlaze2);
SDValue StackPtr;
- unsigned FirstStackArgLoc = 4;
+ unsigned FirstStackArgLoc = 0;
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
CCValAssign &VA = ArgLocs[i];
@@ -657,6 +779,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
// Arguments stored on registers
if (VA.isRegLoc()) {
EVT RegVT = VA.getLocVT();
+ ArgRegEnd = VA.getLocReg();
TargetRegisterClass *RC = 0;
if (RegVT == MVT::i32)
@@ -668,12 +791,13 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
// Transform the arguments stored on
// physical registers into virtual ones
- unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC);
+ unsigned Reg = MF.addLiveIn(ArgRegEnd, RC);
SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
// If this is an 8 or 16-bit value, it has been passed promoted
// to 32 bits. Insert an assert[sz]ext to capture this, then
- // truncate to the right size.
+ // truncate to the right size. If if is a floating point value
+ // then convert to the correct type.
if (VA.getLocInfo() != CCValAssign::Full) {
unsigned Opcode = 0;
if (VA.getLocInfo() == CCValAssign::SExt)
@@ -688,35 +812,14 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
InVals.push_back(ArgValue);
- // To meet ABI, when VARARGS are passed on registers, the registers
- // must have their values written to the caller stack frame.
- if (isVarArg) {
- if (StackPtr.getNode() == 0)
- StackPtr = DAG.getRegister(StackReg, getPointerTy());
-
- // The stack pointer offset is relative to the caller stack frame.
- // Since the real stack size is unknown here, a negative SPOffset
- // is used so there's a way to adjust these offsets when the stack
- // size get known (on EliminateFrameIndex). A dummy SPOffset is
- // used instead of a direct negative address (which is recorded to
- // be used on emitPrologue) to avoid mis-calc of the first stack
- // offset on PEI::calculateFrameObjectOffsets.
- // Arguments are always 32-bit.
- int FI = MFI->CreateFixedObject(4, 0, true, false);
- MBlazeFI->recordStoreVarArgsFI(FI, -(FirstStackArgLoc+(i*4)));
- SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy());
-
- // emit ISD::STORE whichs stores the
- // parameter value to a stack Location
- InVals.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, NULL, 0,
- false, false, 0));
- }
-
} else { // VA.isRegLoc()
// sanity check
assert(VA.isMemLoc());
+ // The last argument is not a register
+ ArgRegEnd = 0;
+
// The stack pointer offset is relative to the caller stack frame.
// Since the real stack size is unknown here, a negative SPOffset
// is used so there's a way to adjust these offsets when the stack
@@ -737,6 +840,47 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
}
}
+ // To meet ABI, when VARARGS are passed on registers, the registers
+ // must have their values written to the caller stack frame. If the last
+ // argument was placed in the stack, there's no need to save any register.
+ if ((isVarArg) && ArgRegEnd) {
+ if (StackPtr.getNode() == 0)
+ StackPtr = DAG.getRegister(StackReg, getPointerTy());
+
+ // The last register argument that must be saved is MBlaze::R10
+ TargetRegisterClass *RC = MBlaze::CPURegsRegisterClass;
+
+ 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);
+
+ for (; Start <= End; ++Start, ++StackLoc) {
+ unsigned Reg = MBlazeRegisterInfo::getRegisterFromNumbering(Start);
+ unsigned LiveReg = MF.addLiveIn(Reg, RC);
+ SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, LiveReg, MVT::i32);
+
+ int FI = MFI->CreateFixedObject(4, 0, true, false);
+ MBlazeFI->recordStoreVarArgsFI(FI, -(4+(StackLoc*4)));
+ SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy());
+ OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, NULL, 0,
+ false, false, 0));
+
+ // Record the frame index of the first variable argument
+ // which is a value necessary to VASTART.
+ if (!VarArgsFrameIndex)
+ VarArgsFrameIndex = FI;
+ }
+ }
+
+ // All stores are grouped in one node to allow the matching between
+ // the size of Ins and InVals. This only happens when on varg functions
+ if (!OutChains.empty()) {
+ OutChains.push_back(Chain);
+ Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
+ &OutChains[0], OutChains.size());
+ }
+
return Chain;
}
diff --git a/lib/Target/MBlaze/MBlazeISelLowering.h b/lib/Target/MBlaze/MBlazeISelLowering.h
index 75d2552e73..f8b147024d 100644
--- a/lib/Target/MBlaze/MBlazeISelLowering.h
+++ b/lib/Target/MBlaze/MBlazeISelLowering.h
@@ -63,6 +63,8 @@ namespace llvm {
//===--------------------------------------------------------------------===//
class MBlazeTargetLowering : public TargetLowering {
+ int VarArgsFrameIndex; // FrameIndex for start of varargs area.
+
public:
explicit MBlazeTargetLowering(MBlazeTargetMachine &TM);
@@ -96,6 +98,7 @@ namespace llvm {
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG);
virtual SDValue
LowerFormalArguments(SDValue Chain,
diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
index 9067f8b357..8dfca81fb2 100644
--- a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
+++ b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
@@ -85,6 +85,47 @@ unsigned MBlazeRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
return 0; // Not reached
}
+/// getRegisterFromNumbering - Given the enum value for some register, e.g.
+/// MBlaze::R0, return the number that it corresponds to (e.g. 0).
+unsigned MBlazeRegisterInfo::getRegisterFromNumbering(unsigned Reg) {
+ switch (Reg) {
+ case 0 : return MBlaze::R0;
+ case 1 : return MBlaze::R1;
+ case 2 : return MBlaze::R2;
+ case 3 : return MBlaze::R3;
+ case 4 : return MBlaze::R4;
+ case 5 : return MBlaze::R5;
+ case 6 : return MBlaze::R6;
+ case 7 : return MBlaze::R7;
+ case 8 : return MBlaze::R8;
+ case 9 : return MBlaze::R9;
+ case 10 : return MBlaze::R10;
+ case 11 : return MBlaze::R11;
+ case 12 : return MBlaze::R12;
+ case 13 : return MBlaze::R13;
+ case 14 : return MBlaze::R14;
+ case 15 : return MBlaze::R15;
+ case 16 : return MBlaze::R16;
+ case 17 : return MBlaze::R17;
+ case 18 : return MBlaze::R18;
+ case 19 : return MBlaze::R19;
+ case 20 : return MBlaze::R20;
+ case 21 : return MBlaze::R21;
+ case 22 : return MBlaze::R22;
+ case 23 : return MBlaze::R23;
+ case 24 : return MBlaze::R24;
+ case 25 : return MBlaze::R25;
+ case 26 : return MBlaze::R26;
+ case 27 : return MBlaze::R27;
+ case 28 : return MBlaze::R28;
+ case 29 : return MBlaze::R29;
+ case 30 : return MBlaze::R30;
+ case 31 : return MBlaze::R31;
+ default: llvm_unreachable("Unknown register number!");
+ }
+ return 0; // Not reached
+}
+
unsigned MBlazeRegisterInfo::getPICCallReg() {
return MBlaze::R20;
}
@@ -180,9 +221,9 @@ void MBlazeRegisterInfo::adjustMBlazeStackFrame(MachineFunction &MF) const {
}
if (MFI->hasCalls()) {
+ MBlazeFI->setRAStackOffset(0);
MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
StackOffset);
- MBlazeFI->setRAStackOffset(StackOffset);
TopCPUSavedRegOff = StackOffset;
StackOffset += RegSize;
}
@@ -245,7 +286,7 @@ 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+4))) : (spOffset));
+ int Offset = (spOffset < 0) ? (stackSize - spOffset) : (spOffset + 4);
Offset += MI.getOperand(oi).getImm();
DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
@@ -272,6 +313,7 @@ emitPrologue(MachineFunction &MF) const {
// No need to allocate space on the stack.
if (StackSize == 0 && !MFI->hasCalls()) return;
+ if (StackSize < 28 && MFI->hasCalls()) StackSize = 28;
int FPOffset = MBlazeFI->getFPStackOffset();
int RAOffset = MBlazeFI->getRAStackOffset();
@@ -307,9 +349,6 @@ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
DebugLoc dl = MBBI->getDebugLoc();
- // Get the number of bytes from FrameInfo
- int NumBytes = (int) MFI->getStackSize();
-
// Get the FI's where RA and FP are saved.
int FPOffset = MBlazeFI->getFPStackOffset();
int RAOffset = MBlazeFI->getRAStackOffset();
@@ -333,11 +372,15 @@ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
.addImm(RAOffset).addReg(MBlaze::R1);
}
+ // Get the number of bytes from FrameInfo
+ int StackSize = (int) MFI->getStackSize();
+ if (StackSize < 28 && MFI->hasCalls()) StackSize = 28;
+
// adjust stack.
// addi R1, R1, imm
- if (NumBytes) {
+ if (StackSize) {
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDI), MBlaze::R1)
- .addReg(MBlaze::R1).addImm(NumBytes);
+ .addReg(MBlaze::R1).addImm(StackSize);
}
}
diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.h b/lib/Target/MBlaze/MBlazeRegisterInfo.h
index 4847f1ed52..cde7d3967a 100644
--- a/lib/Target/MBlaze/MBlazeRegisterInfo.h
+++ b/lib/Target/MBlaze/MBlazeRegisterInfo.h
@@ -43,6 +43,7 @@ struct MBlazeRegisterInfo : public MBlazeGenRegisterInfo {
/// getRegisterNumbering - Given the enum value for some register, e.g.
/// MBlaze::RA, return the number that it corresponds to (e.g. 31).
static unsigned getRegisterNumbering(unsigned RegEnum);
+ static unsigned getRegisterFromNumbering(unsigned RegEnum);
/// Get PIC indirect call register
static unsigned getPICCallReg();
@@ -82,6 +83,11 @@ struct MBlazeRegisterInfo : public MBlazeGenRegisterInfo {
unsigned getEHExceptionRegister() const;
unsigned getEHHandlerRegister() const;
+ /// targetHandlesStackFrameRounding - Returns true if the target is
+ /// responsible for rounding up the stack frame (probably at emitPrologue
+ /// time).
+ bool targetHandlesStackFrameRounding() const { return true; }
+
int getDwarfRegNum(unsigned RegNum, bool isEH) const;
};