diff options
Diffstat (limited to 'lib/Target/Mips')
-rw-r--r-- | lib/Target/Mips/MipsISelDAGToDAG.cpp | 38 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 3 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.cpp | 29 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.h | 6 | ||||
-rw-r--r-- | lib/Target/Mips/MipsMachineFunction.h | 10 |
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 |