summaryrefslogtreecommitdiff
path: root/lib/Target/Alpha
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-06-03 21:10:15 +0000
committerEd Schouten <ed@FreeBSD.org>2009-06-03 21:10:15 +0000
commit68eb509bdc5c7007520d5231cd92de28106236df (patch)
treedb103e2a0755ab86f18c181a2d208a6a63284c97 /lib/Target/Alpha
parent33a8e4360f5050416130517e5c7a1007d06aa90f (diff)
Diffstat (limited to 'lib/Target/Alpha')
-rw-r--r--lib/Target/Alpha/AlphaISelDAGToDAG.cpp68
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.cpp3
-rw-r--r--lib/Target/Alpha/AlphaInstrInfo.cpp53
-rw-r--r--lib/Target/Alpha/AlphaInstrInfo.h12
-rw-r--r--lib/Target/Alpha/AlphaMachineFunctionInfo.h48
5 files changed, 142 insertions, 42 deletions
diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
index affcd3e7fec8..e3f631a1f5be 100644
--- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
+++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
@@ -185,8 +185,20 @@ namespace {
#include "AlphaGenDAGISel.inc"
private:
- SDValue getGlobalBaseReg();
- SDValue getGlobalRetAddr();
+ /// getTargetMachine - Return a reference to the TargetMachine, casted
+ /// to the target-specific type.
+ const AlphaTargetMachine &getTargetMachine() {
+ return static_cast<const AlphaTargetMachine &>(TM);
+ }
+
+ /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
+ /// to the target-specific type.
+ const AlphaInstrInfo *getInstrInfo() {
+ return getTargetMachine().getInstrInfo();
+ }
+
+ SDNode *getGlobalBaseReg();
+ SDNode *getGlobalRetAddr();
void SelectCALL(SDValue Op);
};
@@ -195,34 +207,18 @@ private:
/// getGlobalBaseReg - Output the instructions required to put the
/// GOT address into a register.
///
-SDValue AlphaDAGToDAGISel::getGlobalBaseReg() {
- unsigned GP = 0;
- for(MachineRegisterInfo::livein_iterator ii = RegInfo->livein_begin(),
- ee = RegInfo->livein_end(); ii != ee; ++ii)
- if (ii->first == Alpha::R29) {
- GP = ii->second;
- break;
- }
- assert(GP && "GOT PTR not in liveins");
- // FIXME is there anywhere sensible to get a DebugLoc here?
- return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
- DebugLoc::getUnknownLoc(), GP, MVT::i64);
+SDNode *AlphaDAGToDAGISel::getGlobalBaseReg() {
+ MachineFunction *MF = BB->getParent();
+ unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
+ return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
}
-/// getRASaveReg - Grab the return address
+/// getGlobalRetAddr - Grab the return address.
///
-SDValue AlphaDAGToDAGISel::getGlobalRetAddr() {
- unsigned RA = 0;
- for(MachineRegisterInfo::livein_iterator ii = RegInfo->livein_begin(),
- ee = RegInfo->livein_end(); ii != ee; ++ii)
- if (ii->first == Alpha::R26) {
- RA = ii->second;
- break;
- }
- assert(RA && "RA PTR not in liveins");
- // FIXME is there anywhere sensible to get a DebugLoc here?
- return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
- DebugLoc::getUnknownLoc(), RA, MVT::i64);
+SDNode *AlphaDAGToDAGISel::getGlobalRetAddr() {
+ MachineFunction *MF = BB->getParent();
+ unsigned GlobalRetAddr = getInstrInfo()->getGlobalRetAddr(MF);
+ return CurDAG->getRegister(GlobalRetAddr, TLI.getPointerTy()).getNode();
}
/// InstructionSelect - This callback is invoked by
@@ -256,16 +252,10 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
CurDAG->getTargetFrameIndex(FI, MVT::i32),
getI64Imm(0));
}
- case ISD::GLOBAL_OFFSET_TABLE: {
- SDValue Result = getGlobalBaseReg();
- ReplaceUses(Op, Result);
- return NULL;
- }
- case AlphaISD::GlobalRetAddr: {
- SDValue Result = getGlobalRetAddr();
- ReplaceUses(Op, Result);
- return NULL;
- }
+ case ISD::GLOBAL_OFFSET_TABLE:
+ return getGlobalBaseReg();
+ case AlphaISD::GlobalRetAddr:
+ return getGlobalRetAddr();
case AlphaISD::DivCall: {
SDValue Chain = CurDAG->getEntryNode();
@@ -315,7 +305,7 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
ConstantInt *C = ConstantInt::get(Type::Int64Ty, uval);
SDValue CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
SDNode *Tmp = CurDAG->getTargetNode(Alpha::LDAHr, dl, MVT::i64, CPI,
- getGlobalBaseReg());
+ SDValue(getGlobalBaseReg(), 0));
return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other,
CPI, SDValue(Tmp, 0), CurDAG->getEntryNode());
}
@@ -503,7 +493,7 @@ void AlphaDAGToDAGISel::SelectCALL(SDValue Op) {
// Finally, once everything is in registers to pass to the call, emit the
// call itself.
if (Addr.getOpcode() == AlphaISD::GPRelLo) {
- SDValue GOT = getGlobalBaseReg();
+ SDValue GOT = SDValue(getGlobalBaseReg(), 0);
Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R29, GOT, InFlag);
InFlag = Chain.getValue(1);
Chain = SDValue(CurDAG->getTargetNode(Alpha::BSR, dl, MVT::Other,
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index 10011125cf85..7ed8ef60302d 100644
--- a/lib/Target/Alpha/AlphaISelLowering.cpp
+++ b/lib/Target/Alpha/AlphaISelLowering.cpp
@@ -223,9 +223,6 @@ static SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG,
SDValue Root = Op.getOperand(0);
DebugLoc dl = Op.getDebugLoc();
- AddLiveIn(MF, Alpha::R29, &Alpha::GPRCRegClass); //GP
- AddLiveIn(MF, Alpha::R26, &Alpha::GPRCRegClass); //RA
-
unsigned args_int[] = {
Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21};
unsigned args_float[] = {
diff --git a/lib/Target/Alpha/AlphaInstrInfo.cpp b/lib/Target/Alpha/AlphaInstrInfo.cpp
index a54d97d33c40..229f9d4784a4 100644
--- a/lib/Target/Alpha/AlphaInstrInfo.cpp
+++ b/lib/Target/Alpha/AlphaInstrInfo.cpp
@@ -13,7 +13,9 @@
#include "Alpha.h"
#include "AlphaInstrInfo.h"
+#include "AlphaMachineFunctionInfo.h"
#include "AlphaGenInstrInfo.inc"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -448,3 +450,54 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
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 AlphaInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
+ AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>();
+ unsigned GlobalBaseReg = AlphaFI->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(&Alpha::GPRCRegClass);
+ bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalBaseReg, Alpha::R29,
+ &Alpha::GPRCRegClass, &Alpha::GPRCRegClass);
+ assert(Ok && "Couldn't assign to global base register!");
+ RegInfo.addLiveIn(Alpha::R29);
+
+ AlphaFI->setGlobalBaseReg(GlobalBaseReg);
+ return GlobalBaseReg;
+}
+
+/// getGlobalRetAddr - 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 AlphaInstrInfo::getGlobalRetAddr(MachineFunction *MF) const {
+ AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>();
+ unsigned GlobalRetAddr = AlphaFI->getGlobalRetAddr();
+ if (GlobalRetAddr != 0)
+ return GlobalRetAddr;
+
+ // Insert the set of GlobalRetAddr 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();
+
+ GlobalRetAddr = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
+ bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalRetAddr, Alpha::R26,
+ &Alpha::GPRCRegClass, &Alpha::GPRCRegClass);
+ assert(Ok && "Couldn't assign to global return address register!");
+ RegInfo.addLiveIn(Alpha::R26);
+
+ AlphaFI->setGlobalRetAddr(GlobalRetAddr);
+ return GlobalRetAddr;
+}
diff --git a/lib/Target/Alpha/AlphaInstrInfo.h b/lib/Target/Alpha/AlphaInstrInfo.h
index 182aa32f447a..ea0988553acc 100644
--- a/lib/Target/Alpha/AlphaInstrInfo.h
+++ b/lib/Target/Alpha/AlphaInstrInfo.h
@@ -90,6 +90,18 @@ public:
MachineBasicBlock::iterator MI) const;
bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) 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;
+
+ /// getGlobalRetAddr - Return a virtual register initialized with the
+ /// the global return address register value. Output instructions required to
+ /// initialize the register in the function entry block, if necessary.
+ ///
+ unsigned getGlobalRetAddr(MachineFunction *MF) const;
};
}
diff --git a/lib/Target/Alpha/AlphaMachineFunctionInfo.h b/lib/Target/Alpha/AlphaMachineFunctionInfo.h
new file mode 100644
index 000000000000..47de5dfad94d
--- /dev/null
+++ b/lib/Target/Alpha/AlphaMachineFunctionInfo.h
@@ -0,0 +1,48 @@
+//====- AlphaMachineFuctionInfo.h - Alpha machine function info -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares Alpha-specific per-machine-function information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ALPHAMACHINEFUNCTIONINFO_H
+#define ALPHAMACHINEFUNCTIONINFO_H
+
+#include "llvm/CodeGen/MachineFunction.h"
+
+namespace llvm {
+
+/// AlphaMachineFunctionInfo - This class is derived from MachineFunction
+/// private Alpha target-specific information for each MachineFunction.
+class AlphaMachineFunctionInfo : public MachineFunctionInfo {
+ /// 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;
+
+ /// GlobalRetAddr = keeps track of the virtual register initialized for
+ /// the return address value.
+ unsigned GlobalRetAddr;
+
+public:
+ AlphaMachineFunctionInfo() : GlobalBaseReg(0), GlobalRetAddr(0) {}
+
+ AlphaMachineFunctionInfo(MachineFunction &MF) : GlobalBaseReg(0),
+ GlobalRetAddr(0) {}
+
+ unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
+ void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
+
+ unsigned getGlobalRetAddr() const { return GlobalRetAddr; }
+ void setGlobalRetAddr(unsigned Reg) { GlobalRetAddr = Reg; }
+};
+
+} // End llvm namespace
+
+#endif