forked from OSchip/llvm-project
[mips] Move initGlobalBaseReg to MipsFunctionInfo. NFC
Move initGlobalBaseReg from MipsSEDAGToDAGISel to MipsFunctionInfo. This way functions used for handling position independent code during instruction selection, getGlobalBaseReg and initGlobalBaseReg, end up in same class. Differential Revision: https://reviews.llvm.org/D62586 llvm-svn: 362206
This commit is contained in:
parent
b457e430f3
commit
9058b50fb2
|
@ -51,6 +51,94 @@ unsigned MipsFunctionInfo::getGlobalBaseReg() {
|
|||
return GlobalBaseReg;
|
||||
}
|
||||
|
||||
void MipsFunctionInfo::initGlobalBaseReg() {
|
||||
if (!GlobalBaseReg)
|
||||
return;
|
||||
|
||||
MachineBasicBlock &MBB = MF.front();
|
||||
MachineBasicBlock::iterator I = MBB.begin();
|
||||
MachineRegisterInfo &RegInfo = MF.getRegInfo();
|
||||
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
|
||||
DebugLoc DL;
|
||||
unsigned V0, V1;
|
||||
const TargetRegisterClass *RC;
|
||||
const MipsABIInfo &ABI =
|
||||
static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI();
|
||||
RC = (ABI.IsN64()) ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
|
||||
|
||||
V0 = RegInfo.createVirtualRegister(RC);
|
||||
V1 = RegInfo.createVirtualRegister(RC);
|
||||
|
||||
if (ABI.IsN64()) {
|
||||
MF.getRegInfo().addLiveIn(Mips::T9_64);
|
||||
MBB.addLiveIn(Mips::T9_64);
|
||||
|
||||
// lui $v0, %hi(%neg(%gp_rel(fname)))
|
||||
// daddu $v1, $v0, $t9
|
||||
// daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
|
||||
const GlobalValue *FName = &MF.getFunction();
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)
|
||||
.addReg(Mips::T9_64);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MF.getTarget().isPositionIndependent()) {
|
||||
// Set global register to __gnu_local_gp.
|
||||
//
|
||||
// lui $v0, %hi(__gnu_local_gp)
|
||||
// addiu $globalbasereg, $v0, %lo(__gnu_local_gp)
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
|
||||
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
|
||||
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
|
||||
return;
|
||||
}
|
||||
|
||||
MF.getRegInfo().addLiveIn(Mips::T9);
|
||||
MBB.addLiveIn(Mips::T9);
|
||||
|
||||
if (ABI.IsN32()) {
|
||||
// lui $v0, %hi(%neg(%gp_rel(fname)))
|
||||
// addu $v1, $v0, $t9
|
||||
// addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
|
||||
const GlobalValue *FName = &MF.getFunction();
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(ABI.IsO32());
|
||||
|
||||
// For O32 ABI, the following instruction sequence is emitted to initialize
|
||||
// the global base register:
|
||||
//
|
||||
// 0. lui $2, %hi(_gp_disp)
|
||||
// 1. addiu $2, $2, %lo(_gp_disp)
|
||||
// 2. addu $globalbasereg, $2, $t9
|
||||
//
|
||||
// We emit only the last instruction here.
|
||||
//
|
||||
// GNU linker requires that the first two instructions appear at the beginning
|
||||
// of a function and no instructions be inserted before or between them.
|
||||
// The two instructions are emitted during lowering to MC layer in order to
|
||||
// avoid any reordering.
|
||||
//
|
||||
// Register $2 (Mips::V0) is added to the list of live-in registers to ensure
|
||||
// the value instruction 1 (addiu) defines is valid when instruction 2 (addu)
|
||||
// reads it.
|
||||
MF.getRegInfo().addLiveIn(Mips::V0);
|
||||
MBB.addLiveIn(Mips::V0);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)
|
||||
.addReg(Mips::V0).addReg(Mips::T9);
|
||||
}
|
||||
|
||||
void MipsFunctionInfo::createEhDataRegsFI() {
|
||||
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
|
||||
for (int I = 0; I < 4; ++I) {
|
||||
|
|
|
@ -34,6 +34,10 @@ public:
|
|||
bool globalBaseRegSet() const;
|
||||
unsigned getGlobalBaseReg();
|
||||
|
||||
// Insert instructions to initialize the global base register in the
|
||||
// first MBB of the function.
|
||||
void initGlobalBaseReg();
|
||||
|
||||
int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
|
||||
void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
|
||||
|
||||
|
|
|
@ -134,97 +134,8 @@ bool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI,
|
|||
return true;
|
||||
}
|
||||
|
||||
void MipsSEDAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) {
|
||||
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
|
||||
|
||||
if (!MipsFI->globalBaseRegSet())
|
||||
return;
|
||||
|
||||
MachineBasicBlock &MBB = MF.front();
|
||||
MachineBasicBlock::iterator I = MBB.begin();
|
||||
MachineRegisterInfo &RegInfo = MF.getRegInfo();
|
||||
const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
|
||||
DebugLoc DL;
|
||||
unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg();
|
||||
const TargetRegisterClass *RC;
|
||||
const MipsABIInfo &ABI = static_cast<const MipsTargetMachine &>(TM).getABI();
|
||||
RC = (ABI.IsN64()) ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
|
||||
|
||||
V0 = RegInfo.createVirtualRegister(RC);
|
||||
V1 = RegInfo.createVirtualRegister(RC);
|
||||
|
||||
if (ABI.IsN64()) {
|
||||
MF.getRegInfo().addLiveIn(Mips::T9_64);
|
||||
MBB.addLiveIn(Mips::T9_64);
|
||||
|
||||
// lui $v0, %hi(%neg(%gp_rel(fname)))
|
||||
// daddu $v1, $v0, $t9
|
||||
// daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
|
||||
const GlobalValue *FName = &MF.getFunction();
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)
|
||||
.addReg(Mips::T9_64);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MF.getTarget().isPositionIndependent()) {
|
||||
// Set global register to __gnu_local_gp.
|
||||
//
|
||||
// lui $v0, %hi(__gnu_local_gp)
|
||||
// addiu $globalbasereg, $v0, %lo(__gnu_local_gp)
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
|
||||
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
|
||||
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
|
||||
return;
|
||||
}
|
||||
|
||||
MF.getRegInfo().addLiveIn(Mips::T9);
|
||||
MBB.addLiveIn(Mips::T9);
|
||||
|
||||
if (ABI.IsN32()) {
|
||||
// lui $v0, %hi(%neg(%gp_rel(fname)))
|
||||
// addu $v1, $v0, $t9
|
||||
// addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
|
||||
const GlobalValue *FName = &MF.getFunction();
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(ABI.IsO32());
|
||||
|
||||
// For O32 ABI, the following instruction sequence is emitted to initialize
|
||||
// the global base register:
|
||||
//
|
||||
// 0. lui $2, %hi(_gp_disp)
|
||||
// 1. addiu $2, $2, %lo(_gp_disp)
|
||||
// 2. addu $globalbasereg, $2, $t9
|
||||
//
|
||||
// We emit only the last instruction here.
|
||||
//
|
||||
// GNU linker requires that the first two instructions appear at the beginning
|
||||
// of a function and no instructions be inserted before or between them.
|
||||
// The two instructions are emitted during lowering to MC layer in order to
|
||||
// avoid any reordering.
|
||||
//
|
||||
// Register $2 (Mips::V0) is added to the list of live-in registers to ensure
|
||||
// the value instruction 1 (addiu) defines is valid when instruction 2 (addu)
|
||||
// reads it.
|
||||
MF.getRegInfo().addLiveIn(Mips::V0);
|
||||
MBB.addLiveIn(Mips::V0);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)
|
||||
.addReg(Mips::V0).addReg(Mips::T9);
|
||||
}
|
||||
|
||||
void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {
|
||||
initGlobalBaseReg(MF);
|
||||
MF.getInfo<MipsFunctionInfo>()->initGlobalBaseReg();
|
||||
|
||||
MachineRegisterInfo *MRI = &MF.getRegInfo();
|
||||
|
||||
|
|
|
@ -130,10 +130,6 @@ private:
|
|||
|
||||
void processFunctionAfterISel(MachineFunction &MF) override;
|
||||
|
||||
// Insert instructions to initialize the global base register in the
|
||||
// first MBB of the function.
|
||||
void initGlobalBaseReg(MachineFunction &MF);
|
||||
|
||||
bool SelectInlineAsmMemoryOperand(const SDValue &Op,
|
||||
unsigned ConstraintID,
|
||||
std::vector<SDValue> &OutOps) override;
|
||||
|
|
Loading…
Reference in New Issue