Reworking the stack layout generated by the MBlaze backend.

llvm-svn: 121355
This commit is contained in:
Wesley Peck 2010-12-09 03:42:04 +00:00
parent 96545f21b9
commit 33ba317cf6
12 changed files with 128 additions and 178 deletions

View File

@ -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() {

View File

@ -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>>
]>;

View File

@ -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);
}
}

View File

@ -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

View File

@ -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(),

View File

@ -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; }

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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