#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"
case Mips::SP : case Mips::F29: return 29;
case Mips::FP : case Mips::F30: case Mips::D15: return 30;
case Mips::RA : case Mips::F31: return 31;
- default: assert(0 && "Unknown register number!");
+ default: llvm_unreachable("Unknown register number!");
}
return 0; // Not reached
}
-unsigned MipsRegisterInfo::getPICCallReg(void) { return Mips::T9; }
+unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
//===----------------------------------------------------------------------===//
// Callee Saved Registers methods
static const unsigned BitMode32CalleeSavedRegs[] = {
Mips::S0, Mips::S1, Mips::S2, Mips::S3,
Mips::S4, Mips::S5, Mips::S6, Mips::S7,
- Mips::F20, Mips::F22, Mips::F24, Mips::F26, Mips::F28, Mips::F30,
- Mips::D10, Mips::D11, Mips::D12, Mips::D13, Mips::D14, Mips::D15,0
+ Mips::F20, Mips::F22, Mips::F24, Mips::F26, Mips::F28, Mips::F30, 0
};
if (Subtarget.isSingleFloat())
&Mips::CPURegsRegClass, &Mips::CPURegsRegClass, &Mips::CPURegsRegClass,
&Mips::CPURegsRegClass, &Mips::CPURegsRegClass,
&Mips::FGR32RegClass, &Mips::FGR32RegClass, &Mips::FGR32RegClass,
- &Mips::FGR32RegClass, &Mips::FGR32RegClass, &Mips::FGR32RegClass,
- &Mips::AFGR64RegClass, &Mips::AFGR64RegClass, &Mips::AFGR64RegClass,
- &Mips::AFGR64RegClass, &Mips::AFGR64RegClass, &Mips::AFGR64RegClass, 0
+ &Mips::FGR32RegClass, &Mips::FGR32RegClass, &Mips::FGR32RegClass, 0
};
if (Subtarget.isSingleFloat())
//
// The stack is allocated decrementing the stack pointer on
// the first instruction of a function prologue. Once decremented,
-// all stack referencesare are done thought a positive offset
+// all stack references are done thought a positive offset
// from the stack/frame pointer, so the stack is considering
// to grow up! Otherwise terrible hacks would have to be made
// to get this stack ABI compliant :)
// The emitted instruction will be something like:
// lw REGX, 16+StackSize(SP)
//
-// Since the total stack size is unknown on LowerFORMAL_ARGUMENTS, all
+// Since the total stack size is unknown on LowerFormalArguments, all
// stack references (ObjectOffset) created to reference the function
// arguments, are negative numbers. This way, on eliminateFrameIndex it's
// possible to detect those references and the offsets are adjusted to
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
+ unsigned RegSize = Subtarget.isGP32bit() ? 4 : 8;
+ bool HasGP = MipsFI->needGPSaveRestore();
// Min and Max CSI FrameIndex.
int MinCSFI = -1, MaxCSFI = -1;
int TopCPUSavedRegOff = -1, TopFPUSavedRegOff = -1;
// Replace the dummy '0' SPOffset by the negative offsets, as explained on
- // LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
+ // LowerFormalArguments. Leaving '0' for while is necessary to avoid
// the approach done by calculateFrameObjectOffsets to the stack frame.
MipsFI->adjustLoadArgsFI(MFI);
MipsFI->adjustStoreVarArgsFI(MFI);
for (unsigned i = 0, e = CSI.size(); i != e; ++i)
CalleeSavedAreaSize += MFI->getObjectAlignment(CSI[i].getFrameIdx());
+ unsigned StackOffset = HasGP ? (MipsFI->getGPStackOffset()+RegSize)
+ : (Subtarget.isABI_O32() ? 16 : 0);
+
// Adjust local variables. They should come on the stack right
// after the arguments.
int LastOffsetFI = -1;
continue;
if (MFI->isDeadObjectIndex(i))
continue;
- unsigned Offset = MFI->getObjectOffset(i) - CalleeSavedAreaSize;
+ unsigned Offset =
+ StackOffset + MFI->getObjectOffset(i) - CalleeSavedAreaSize;
if (LastOffsetFI == -1)
LastOffsetFI = i;
if (Offset > MFI->getObjectOffset(LastOffsetFI))
}
// 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 = 0;
- unsigned RegSize = Subtarget.isGP32bit() ? 4 : 8;
-
+ // be saved in this CPU Area. This whole area must be aligned to the
+ // default Stack Alignment requirements.
if (LastOffsetFI >= 0)
StackOffset = MFI->getObjectOffset(LastOffsetFI)+
MFI->getObjectSize(LastOffsetFI);
StackOffset += MFI->getObjectAlignment(CSI[i].getFrameIdx());
}
- if (hasFP(MF)) {
- MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize),
+ // Stack locations for FP and RA. If only one of them is used,
+ // the space must be allocated for both, otherwise no space at all.
+ if (hasFP(MF) || MFI->hasCalls()) {
+ // FP stack location
+ MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
StackOffset);
MipsFI->setFPStackOffset(StackOffset);
TopCPUSavedRegOff = StackOffset;
StackOffset += RegSize;
- }
- if (MFI->hasCalls()) {
- MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize),
+ // SP stack location
+ MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
StackOffset);
MipsFI->setRAStackOffset(StackOffset);
- TopCPUSavedRegOff = StackOffset;
StackOffset += RegSize;
+
+ if (MFI->hasCalls())
+ TopCPUSavedRegOff += RegSize;
}
+
StackOffset = ((StackOffset+StackAlign-1)/StackAlign*StackAlign);
// Adjust FPU Callee Saved Registers Area. This Area must be
// FrameIndex represent objects inside a abstract stack.
// We must replace FrameIndex with an stack/frame pointer
// direct reference.
-void MipsRegisterInfo::
-eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
- RegScavenger *RS) const
+unsigned MipsRegisterInfo::
+eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
+ int *Value, RegScavenger *RS) const
{
MachineInstr &MI = *II;
MachineFunction &MF = *MI.getParent()->getParent();
"Instr doesn't have FrameIndex operand!");
}
- #ifndef NDEBUG
- DOUT << "\nFunction : " << MF.getFunction()->getName() << "\n";
- DOUT << "<--------->\n";
- MI.print(DOUT);
- #endif
+ 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);
- #ifndef NDEBUG
- DOUT << "FrameIndex : " << FrameIndex << "\n";
- DOUT << "spOffset : " << spOffset << "\n";
- DOUT << "stackSize : " << stackSize << "\n";
- #endif
+ DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
+ << "spOffset : " << spOffset << "\n"
+ << "stackSize : " << stackSize << "\n");
- // as explained on LowerFORMAL_ARGUMENTS, detect negative offsets
+ // as explained on LowerFormalArguments, detect negative offsets
// and adjust SPOffsets considering the final stack size.
int Offset = ((spOffset < 0) ? (stackSize + (-(spOffset+4))) : (spOffset));
Offset += MI.getOperand(i-1).getImm();
- #ifndef NDEBUG
- DOUT << "Offset : " << Offset << "\n";
- DOUT << "<--------->\n";
- #endif
+ DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
MI.getOperand(i-1).ChangeToImmediate(Offset);
MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
+ return 0;
}
void MipsRegisterInfo::
.addReg(Mips::SP).addReg(Mips::ZERO);
}
- // PIC speficic function prologue
- if ((isPIC) && (MFI->hasCalls())) {
+ // Restore GP from the saved stack location
+ if (MipsFI->needGPSaveRestore())
BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE))
.addImm(MipsFI->getGPStackOffset());
- }
}
void MipsRegisterInfo::
.addReg(Mips::FP).addReg(Mips::ZERO);
// lw $fp,stack_loc($sp)
- BuildMI(MBB, MBBI, dl, TII.get(Mips::LW))
- .addReg(Mips::FP).addImm(FPOffset).addReg(Mips::SP);
+ BuildMI(MBB, MBBI, dl, TII.get(Mips::LW), Mips::FP)
+ .addImm(FPOffset).addReg(Mips::SP);
}
// Restore the return address only if the function isnt a leaf one.
// lw $ra, stack_loc($sp)
if (MFI->hasCalls()) {
- BuildMI(MBB, MBBI, dl, TII.get(Mips::LW))
- .addReg(Mips::RA).addImm(RAOffset).addReg(Mips::SP);
+ BuildMI(MBB, MBBI, dl, TII.get(Mips::LW), Mips::RA)
+ .addImm(RAOffset).addReg(Mips::SP);
}
// adjust stack : insert addi sp, sp, (imm)
void MipsRegisterInfo::
processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
- // Set the SPOffset on the FI where GP must be saved/loaded.
+ // Set the stack offset where GP must be saved/loaded from.
MachineFrameInfo *MFI = MF.getFrameInfo();
- bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_);
- if (MFI->hasCalls() && isPIC) {
- MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
+ MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
+ if (MipsFI->needGPSaveRestore())
MFI->setObjectOffset(MipsFI->getGPFI(), MipsFI->getGPStackOffset());
- }
}
unsigned MipsRegisterInfo::
}
unsigned MipsRegisterInfo::
-getFrameRegister(MachineFunction &MF) const {
+getFrameRegister(const MachineFunction &MF) const {
return hasFP(MF) ? Mips::FP : Mips::SP;
}
unsigned MipsRegisterInfo::
getEHExceptionRegister() const {
- assert(0 && "What is the exception register");
+ llvm_unreachable("What is the exception register");
return 0;
}
unsigned MipsRegisterInfo::
getEHHandlerRegister() const {
- assert(0 && "What is the exception handler register");
+ llvm_unreachable("What is the exception handler register");
return 0;
}
int MipsRegisterInfo::
getDwarfRegNum(unsigned RegNum, bool isEH) const {
- assert(0 && "What is the dwarf register number");
+ llvm_unreachable("What is the dwarf register number");
return -1;
}