[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp

Chris Lattner lattner at cs.uiuc.edu
Fri Aug 19 15:39:05 PDT 2005



Changes in directory llvm/lib/Target/PowerPC:

PPC32ISelDAGToDAG.cpp updated: 1.15 -> 1.16
---
Log message:

add support for global address, including PIC support.
This REALLY should be lowered by the legalizer!



---
Diffs of the changes:  (+48 -1)

 PPC32ISelDAGToDAG.cpp |   49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 48 insertions(+), 1 deletion(-)


Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.15 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.16
--- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.15	Fri Aug 19 16:33:02 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp	Fri Aug 19 17:38:53 2005
@@ -15,10 +15,14 @@
 #include "PowerPC.h"
 #include "PPC32TargetMachine.h"
 #include "PPC32ISelLowering.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/GlobalValue.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MathExtras.h"
 using namespace llvm;
@@ -34,16 +38,26 @@
   ///
   class PPC32DAGToDAGISel : public SelectionDAGISel {
     PPC32TargetLowering PPC32Lowering;
-    
+    unsigned GlobalBaseReg;
   public:
     PPC32DAGToDAGISel(TargetMachine &TM)
       : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM) {}
     
+    virtual bool runOnFunction(Function &Fn) {
+      // Make sure we re-emit a set of the global base reg if necessary
+      GlobalBaseReg = 0;
+      return SelectionDAGISel::runOnFunction(Fn);
+    }
+   
     /// getI32Imm - Return a target constant with the specified value, of type
     /// i32.
     inline SDOperand getI32Imm(unsigned Imm) {
       return CurDAG->getTargetConstant(Imm, MVT::i32);
     }
+
+    /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC
+    /// base register.  Return the virtual register that holds this value.
+    unsigned getGlobalBaseReg();
     
     // Select - Convert the specified operand from a target-independent to a
     // target-specific node if it hasn't already been changed.
@@ -73,6 +87,23 @@
   };
 }
 
+/// getGlobalBaseReg - Output the instructions required to put the
+/// base address to use for accessing globals into a register.
+///
+unsigned PPC32DAGToDAGISel::getGlobalBaseReg() {
+  if (!GlobalBaseReg) {
+    // Insert the set of GlobalBaseReg into the first MBB of the function
+    MachineBasicBlock &FirstMBB = BB->getParent()->front();
+    MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+    SSARegMap *RegMap = BB->getParent()->getSSARegMap();
+    GlobalBaseReg = RegMap->createVirtualRegister(PPC32::GPRCRegisterClass);
+    BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
+    BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg);
+  }
+  return GlobalBaseReg;
+}
+
+
 // isIntImmediate - This method tests to see if a constant operand.
 // If so Imm will receive the 32 bit value.
 static bool isIntImmediate(SDNode *N, unsigned& Imm) {
@@ -392,6 +423,22 @@
     }
     break;
   }
+  case ISD::GlobalAddress: {
+    GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
+    SDOperand Tmp;
+    SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i32);
+    if (PICEnabled) {
+      SDOperand PICBaseReg = CurDAG->getRegister(getGlobalBaseReg(), MVT::i32);
+      Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, PICBaseReg, GA);
+    } else {
+      Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, GA);
+    }
+    if (GV->hasWeakLinkage() || GV->isExternal())
+      CurDAG->SelectNodeTo(N, MVT::i32, PPC::LWZ, GA, Tmp);
+    else
+      CurDAG->SelectNodeTo(N, MVT::i32, PPC::LA, Tmp, GA);
+    break;
+  }
   case ISD::SIGN_EXTEND_INREG:
     switch(cast<VTSDNode>(N->getOperand(1))->getVT()) {
     default: assert(0 && "Illegal type in SIGN_EXTEND_INREG"); break;






More information about the llvm-commits mailing list