MBlazeRegisterInfo.cpp [plain text]
#define DEBUG_TYPE "mblaze-reg-info"
#include "MBlaze.h"
#include "MBlazeSubtarget.h"
#include "MBlazeRegisterInfo.h"
#include "MBlazeMachineFunction.h"
#include "llvm/Constants.h"
#include "llvm/Type.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
using namespace llvm;
MBlazeRegisterInfo::
MBlazeRegisterInfo(const MBlazeSubtarget &ST, const TargetInstrInfo &tii)
: MBlazeGenRegisterInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP),
Subtarget(ST), TII(tii) {}
unsigned MBlazeRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
switch (RegEnum) {
case MBlaze::R0 : case MBlaze::F0 : return 0;
case MBlaze::R1 : case MBlaze::F1 : return 1;
case MBlaze::R2 : case MBlaze::F2 : return 2;
case MBlaze::R3 : case MBlaze::F3 : return 3;
case MBlaze::R4 : case MBlaze::F4 : return 4;
case MBlaze::R5 : case MBlaze::F5 : return 5;
case MBlaze::R6 : case MBlaze::F6 : return 6;
case MBlaze::R7 : case MBlaze::F7 : return 7;
case MBlaze::R8 : case MBlaze::F8 : return 8;
case MBlaze::R9 : case MBlaze::F9 : return 9;
case MBlaze::R10 : case MBlaze::F10 : return 10;
case MBlaze::R11 : case MBlaze::F11 : return 11;
case MBlaze::R12 : case MBlaze::F12 : return 12;
case MBlaze::R13 : case MBlaze::F13 : return 13;
case MBlaze::R14 : case MBlaze::F14 : return 14;
case MBlaze::R15 : case MBlaze::F15 : return 15;
case MBlaze::R16 : case MBlaze::F16 : return 16;
case MBlaze::R17 : case MBlaze::F17 : return 17;
case MBlaze::R18 : case MBlaze::F18 : return 18;
case MBlaze::R19 : case MBlaze::F19 : return 19;
case MBlaze::R20 : case MBlaze::F20 : return 20;
case MBlaze::R21 : case MBlaze::F21 : return 21;
case MBlaze::R22 : case MBlaze::F22 : return 22;
case MBlaze::R23 : case MBlaze::F23 : return 23;
case MBlaze::R24 : case MBlaze::F24 : return 24;
case MBlaze::R25 : case MBlaze::F25 : return 25;
case MBlaze::R26 : case MBlaze::F26 : return 26;
case MBlaze::R27 : case MBlaze::F27 : return 27;
case MBlaze::R28 : case MBlaze::F28 : return 28;
case MBlaze::R29 : case MBlaze::F29 : return 29;
case MBlaze::R30 : case MBlaze::F30 : return 30;
case MBlaze::R31 : case MBlaze::F31 : return 31;
default: llvm_unreachable("Unknown register number!");
}
return 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; }
unsigned MBlazeRegisterInfo::getPICCallReg() {
return MBlaze::R20;
}
const unsigned* MBlazeRegisterInfo::
getCalleeSavedRegs(const MachineFunction *MF) const {
static const unsigned CalleeSavedRegs[] = {
MBlaze::R20, MBlaze::R21, MBlaze::R22, MBlaze::R23,
MBlaze::R24, MBlaze::R25, MBlaze::R26, MBlaze::R27,
MBlaze::R28, MBlaze::R29, MBlaze::R30, MBlaze::R31,
0
};
return CalleeSavedRegs;
}
const TargetRegisterClass* const* MBlazeRegisterInfo::
getCalleeSavedRegClasses(const MachineFunction *MF) const {
static const TargetRegisterClass * const CalleeSavedRC[] = {
&MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
&MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
&MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
&MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
&MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
&MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
0
};
return CalleeSavedRC;
}
BitVector MBlazeRegisterInfo::
getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
Reserved.set(MBlaze::R0);
Reserved.set(MBlaze::R1);
Reserved.set(MBlaze::R2);
Reserved.set(MBlaze::R13);
Reserved.set(MBlaze::R14);
Reserved.set(MBlaze::R15);
Reserved.set(MBlaze::R16);
Reserved.set(MBlaze::R17);
Reserved.set(MBlaze::R18);
Reserved.set(MBlaze::R19);
return Reserved;
}
void MBlazeRegisterInfo::adjustMBlazeStackFrame(MachineFunction &MF) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
int TopCPUSavedRegOff = -1;
unsigned StackOffset = MFI->getStackSize();
unsigned RegSize = 4;
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;
}
MFI->setStackSize(StackOffset);
if (TopCPUSavedRegOff >= 0)
MBlazeFI->setCPUTopSavedRegOff(TopCPUSavedRegOff-StackOffset);
}
bool MBlazeRegisterInfo::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
}
void MBlazeRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
MBB.erase(I);
}
unsigned MBlazeRegisterInfo::
eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
FrameIndexValue *Value, RegScavenger *RS) const {
MachineInstr &MI = *II;
MachineFunction &MF = *MI.getParent()->getParent();
unsigned i = 0;
while (!MI.getOperand(i).isFI()) {
++i;
assert(i < MI.getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
}
unsigned oi = i == 2 ? 1 : 2;
DEBUG(errs() << "\nFunction : " << MF.getFunction()->getName() << "\n";
errs() << "<--------->\n" << MI);
int FrameIndex = MI.getOperand(i).getIndex();
int stackSize = MF.getFrameInfo()->getStackSize();
int spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
<< "spOffset : " << spOffset << "\n"
<< "stackSize : " << stackSize << "\n");
int Offset = (spOffset < 0) ? (stackSize - spOffset) : (spOffset + 4);
Offset += MI.getOperand(oi).getImm();
DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
MI.getOperand(oi).ChangeToImmediate(Offset);
MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
return 0;
}
void MBlazeRegisterInfo::
emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
adjustMBlazeStackFrame(MF);
unsigned StackSize = MFI->getStackSize();
if (StackSize == 0 && !MFI->adjustsStack()) return;
if (StackSize < 28 && MFI->adjustsStack()) StackSize = 28;
int FPOffset = MBlazeFI->getFPStackOffset();
int RAOffset = MBlazeFI->getRAStackOffset();
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDI), MBlaze::R1)
.addReg(MBlaze::R1).addImm(-StackSize);
if (MFI->adjustsStack()) {
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
.addReg(MBlaze::R15).addImm(RAOffset).addReg(MBlaze::R1);
}
if (hasFP(MF)) {
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
.addReg(MBlaze::R19).addImm(FPOffset).addReg(MBlaze::R1);
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19)
.addReg(MBlaze::R1).addReg(MBlaze::R0);
}
}
void MBlazeRegisterInfo::
emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = prior(MBB.end());
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
DebugLoc dl = MBBI->getDebugLoc();
int FPOffset = MBlazeFI->getFPStackOffset();
int RAOffset = MBlazeFI->getRAStackOffset();
if (hasFP(MF)) {
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1)
.addReg(MBlaze::R19).addReg(MBlaze::R0);
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19)
.addImm(FPOffset).addReg(MBlaze::R1);
}
if (MFI->adjustsStack()) {
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15)
.addImm(RAOffset).addReg(MBlaze::R1);
}
int StackSize = (int) MFI->getStackSize();
if (StackSize < 28 && MFI->adjustsStack()) StackSize = 28;
if (StackSize) {
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDI), MBlaze::R1)
.addReg(MBlaze::R1).addImm(StackSize);
}
}
void MBlazeRegisterInfo::
processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
if (MBlazeFI->needGPSaveRestore())
MFI->setObjectOffset(MBlazeFI->getGPFI(), MBlazeFI->getGPStackOffset());
}
unsigned MBlazeRegisterInfo::getRARegister() const {
return MBlaze::R15;
}
unsigned MBlazeRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
return hasFP(MF) ? MBlaze::R19 : MBlaze::R1;
}
unsigned MBlazeRegisterInfo::getEHExceptionRegister() const {
llvm_unreachable("What is the exception register");
return 0;
}
unsigned MBlazeRegisterInfo::getEHHandlerRegister() const {
llvm_unreachable("What is the exception handler register");
return 0;
}
int MBlazeRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
llvm_unreachable("What is the dwarf register number");
return -1;
}
#include "MBlazeGenRegisterInfo.inc"