summaryrefslogtreecommitdiff
path: root/lib/Target/Mips
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Mips')
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp38
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp3
-rw-r--r--lib/Target/Mips/MipsInstrInfo.cpp29
-rw-r--r--lib/Target/Mips/MipsInstrInfo.h6
-rw-r--r--lib/Target/Mips/MipsMachineFunction.h10
5 files changed, 63 insertions, 23 deletions
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index f05ac702ccdd..53de1bbea66e 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -70,7 +70,19 @@ private:
// Include the pieces autogenerated from the target description.
#include "MipsGenDAGISel.inc"
- SDValue getGlobalBaseReg();
+ /// getTargetMachine - Return a reference to the TargetMachine, casted
+ /// to the target-specific type.
+ const MipsTargetMachine &getTargetMachine() {
+ return static_cast<const MipsTargetMachine &>(TM);
+ }
+
+ /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
+ /// to the target-specific type.
+ const MipsInstrInfo *getInstrInfo() {
+ return getTargetMachine().getInstrInfo();
+ }
+
+ SDNode *getGlobalBaseReg();
SDNode *Select(SDValue N);
// Complex Pattern.
@@ -116,19 +128,10 @@ InstructionSelect()
/// getGlobalBaseReg - Output the instructions required to put the
/// GOT address into a register.
-SDValue MipsDAGToDAGISel::getGlobalBaseReg() {
- MachineFunction* MF = BB->getParent();
- unsigned GP = 0;
- for(MachineRegisterInfo::livein_iterator ii = MF->getRegInfo().livein_begin(),
- ee = MF->getRegInfo().livein_end(); ii != ee; ++ii)
- if (ii->first == Mips::GP) {
- GP = ii->second;
- break;
- }
- assert(GP && "GOT PTR not in liveins");
- // FIXME is there a sensible place to get debug info for this?
- return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
- DebugLoc::getUnknownLoc(), GP, MVT::i32);
+SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
+ MachineFunction *MF = BB->getParent();
+ unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
+ return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
}
/// ComplexPattern used on MipsInstrInfo
@@ -321,11 +324,8 @@ Select(SDValue N)
}
// Get target GOT address.
- case ISD::GLOBAL_OFFSET_TABLE: {
- SDValue Result = getGlobalBaseReg();
- ReplaceUses(N, Result);
- return NULL;
- }
+ case ISD::GLOBAL_OFFSET_TABLE:
+ return getGlobalBaseReg();
/// Handle direct and indirect calls when using PIC. On PIC, when
/// GOT is smaller than about 64k (small code) the GA target is
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 9281940019a9..4517cfc96a43 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -941,9 +941,6 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG)
unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF);
- // GP must be live into PIC and non-PIC call target.
- AddLiveIn(MF, Mips::GP, Mips::CPURegsRegisterClass);
-
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp
index 6225fa9c9884..92af973b0d21 100644
--- a/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/lib/Target/Mips/MipsInstrInfo.cpp
@@ -13,8 +13,10 @@
#include "MipsInstrInfo.h"
#include "MipsTargetMachine.h"
+#include "MipsMachineFunction.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "MipsGenInstrInfo.inc"
using namespace llvm;
@@ -621,3 +623,30 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
Cond[0].setImm(GetOppositeBranchCondition((Mips::CondCode)Cond[0].getImm()));
return false;
}
+
+/// getGlobalBaseReg - Return a virtual register initialized with the
+/// the global base register value. Output instructions required to
+/// initialize the register in the function entry block, if necessary.
+///
+unsigned MipsInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
+ MipsFunctionInfo *MipsFI = MF->getInfo<MipsFunctionInfo>();
+ unsigned GlobalBaseReg = MipsFI->getGlobalBaseReg();
+ if (GlobalBaseReg != 0)
+ return GlobalBaseReg;
+
+ // Insert the set of GlobalBaseReg into the first MBB of the function
+ MachineBasicBlock &FirstMBB = MF->front();
+ MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+ MachineRegisterInfo &RegInfo = MF->getRegInfo();
+ const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
+
+ GlobalBaseReg = RegInfo.createVirtualRegister(Mips::CPURegsRegisterClass);
+ bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalBaseReg, Mips::GP,
+ Mips::CPURegsRegisterClass,
+ Mips::CPURegsRegisterClass);
+ assert(Ok && "Couldn't assign to global base register!");
+ RegInfo.addLiveIn(Mips::GP);
+
+ MipsFI->setGlobalBaseReg(GlobalBaseReg);
+ return GlobalBaseReg;
+}
diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h
index 334244e6601a..6655c6749fdf 100644
--- a/lib/Target/Mips/MipsInstrInfo.h
+++ b/lib/Target/Mips/MipsInstrInfo.h
@@ -216,6 +216,12 @@ public:
/// Insert nop instruction when hazard condition is found
virtual void insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
+
+ /// getGlobalBaseReg - Return a virtual register initialized with the
+ /// the global base register value. Output instructions required to
+ /// initialize the register in the function entry block, if necessary.
+ ///
+ unsigned getGlobalBaseReg(MachineFunction *MF) const;
};
}
diff --git a/lib/Target/Mips/MipsMachineFunction.h b/lib/Target/Mips/MipsMachineFunction.h
index b95394ec81ce..ac3cdfd38e16 100644
--- a/lib/Target/Mips/MipsMachineFunction.h
+++ b/lib/Target/Mips/MipsMachineFunction.h
@@ -75,11 +75,16 @@ private:
/// holds the virtual register into which the sret argument is passed.
unsigned SRetReturnReg;
+ /// GlobalBaseReg - keeps track of the virtual register initialized for
+ /// use as the global base register. This is used for PIC in some PIC
+ /// relocation models.
+ unsigned GlobalBaseReg;
+
public:
MipsFunctionInfo(MachineFunction& MF)
: FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0),
FPUTopSavedRegOff(0), GPHolder(-1,-1), HasLoadArgs(false),
- HasStoreVarArgs(false), SRetReturnReg(0)
+ HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0)
{}
int getFPStackOffset() const { return FPStackOffset; }
@@ -124,6 +129,9 @@ public:
unsigned getSRetReturnReg() const { return SRetReturnReg; }
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
+
+ unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
+ void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
};
} // end of namespace llvm