diff options
author | Wesley Peck <peckw@wesleypeck.com> | 2010-12-09 03:42:04 +0000 |
---|---|---|
committer | Wesley Peck <peckw@wesleypeck.com> | 2010-12-09 03:42:04 +0000 |
commit | 8397be042766f1913ceaa2b3e6782de0322bbe6a (patch) | |
tree | c9a36c534fb1fc85287eedf1e15bb4452c401334 | |
parent | 6b0fa635d5bfd80940e667cec1662e611f5d270f (diff) |
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.cpp | 6 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeCallingConv.td | 8 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeFrameInfo.cpp | 78 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeFrameInfo.h | 11 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeISelLowering.cpp | 98 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeMachineFunction.h | 15 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeRegisterInfo.cpp | 42 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeRegisterInfo.h | 3 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeTargetMachine.cpp | 8 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeTargetMachine.h | 7 | ||||
-rw-r--r-- | lib/Target/MBlaze/Makefile | 12 | ||||
-rw-r--r-- | lib/Target/MBlaze/TODO | 16 |
12 files changed, 127 insertions, 177 deletions
diff --git a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp index 50abd1a6a3..dfeed65929 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 d037b0ea62..4962573f96 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 09f8e43d78..bd968e474c 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 204d2f8c47..03c39f0502 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 18293dc058..c4c3e24655 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 da74712545..09b916effd 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 f8f77f1487..58aa151cd5 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 ac1635b119..431a6329b4 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 67a35d873c..0df6add38d 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 12573d8438..85a4c2f3b6 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 0150604084..e01c60bb8c 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 cc0aa48288..2e613eb0ca 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 |