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

Chris Lattner lattner at cs.uiuc.edu
Sun Aug 21 15:31:20 PDT 2005



Changes in directory llvm/lib/Target/PowerPC:

PPC32ISelDAGToDAG.cpp updated: 1.17 -> 1.18
---
Log message:

Implement most of load support.  There is still a bug though.


---
Diffs of the changes:  (+96 -8)

 PPC32ISelDAGToDAG.cpp |  104 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 96 insertions(+), 8 deletions(-)


Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.17 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.18
--- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.17	Sun Aug 21 13:50:37 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp	Sun Aug 21 17:31:09 2005
@@ -57,7 +57,7 @@
 
     /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC
     /// base register.  Return the virtual register that holds this value.
-    unsigned getGlobalBaseReg();
+    SDOperand getGlobalBaseReg();
     
     // Select - Convert the specified operand from a target-independent to a
     // target-specific node if it hasn't already been changed.
@@ -73,6 +73,11 @@
     /// specified condition code, returning the CR# of the expression.
     SDOperand SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC);
 
+    /// SelectAddr - Given the specified address, return the two operands for a
+    /// load/store instruction, and return true if it should be an indexed [r+r]
+    /// operation.
+    bool SelectAddr(SDOperand Addr, SDOperand &Op1, SDOperand &Op2);
+
     /// InstructionSelectBasicBlock - This callback is invoked by
     /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
     virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
@@ -94,7 +99,7 @@
 /// getGlobalBaseReg - Output the instructions required to put the
 /// base address to use for accessing globals into a register.
 ///
-unsigned PPC32DAGToDAGISel::getGlobalBaseReg() {
+SDOperand PPC32DAGToDAGISel::getGlobalBaseReg() {
   if (!GlobalBaseReg) {
     // Insert the set of GlobalBaseReg into the first MBB of the function
     MachineBasicBlock &FirstMBB = BB->getParent()->front();
@@ -104,7 +109,7 @@
     BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
     BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg);
   }
-  return GlobalBaseReg;
+  return CurDAG->getRegister(GlobalBaseReg, MVT::i32);
 }
 
 
@@ -356,6 +361,58 @@
   return Opr0.Val;
 }
 
+/// SelectAddr - Given the specified address, return the two operands for a
+/// load/store instruction, and return true if it should be an indexed [r+r]
+/// operation.
+bool PPC32DAGToDAGISel::SelectAddr(SDOperand Addr, SDOperand &Op1,
+                                   SDOperand &Op2) {
+  unsigned imm = 0;
+  if (Addr.getOpcode() == ISD::ADD) {
+    if (isIntImmediate(Addr.getOperand(1), imm) && isInt16(imm)) {
+      Op1 = getI32Imm(Lo16(imm));
+      if (isa<FrameIndexSDNode>(Addr.getOperand(0))) {
+        ++FrameOff;
+        Op2 = Addr.getOperand(0);
+      } else {
+        Op2 = Select(Addr.getOperand(0));
+      }
+      return false;
+    } else {
+      Op1 = Select(Addr.getOperand(0));
+      Op2 = Select(Addr.getOperand(1));
+      return true;   // [r+r]
+    }
+  }
+
+  // Now check if we're dealing with a global, and whether or not we should emit
+  // an optimized load or store for statics.
+  if (GlobalAddressSDNode *GN = dyn_cast<GlobalAddressSDNode>(Addr)) {
+    GlobalValue *GV = GN->getGlobal();
+    if (!GV->hasWeakLinkage() && !GV->isExternal()) {
+      Op1 = CurDAG->getTargetGlobalAddress(GV, MVT::i32);
+      if (PICEnabled)
+        Op2 = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),
+                                    Op1);
+      else
+        Op2 = CurDAG->getTargetNode(PPC::LIS, MVT::i32, Op1);
+      return false;
+    }
+  } else if (isa<FrameIndexSDNode>(Addr)) {
+    Op1 = getI32Imm(0);
+    Op2 = Addr;
+    return false;
+  } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Addr)) {
+    Op1 = Addr;
+    if (PICEnabled)
+      Op2 = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),Op1);
+    else
+      Op2 = CurDAG->getTargetNode(PPC::LIS, MVT::i32, Op1);
+    return false;
+  }
+  Op1 = getI32Imm(0);
+  Op2 = Select(Addr);
+  return false;
+}
 
 /// SelectCC - Select a comparison of the specified values with the specified
 /// condition code, returning the CR# of the expression.
@@ -398,6 +455,7 @@
   return 0;
 }
 
+
 // Select - Convert the specified operand from a target-independent to a
 // target-specific node if it hasn't already been changed.
 SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
@@ -472,12 +530,11 @@
     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 {
+    if (PICEnabled)
+      Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(), 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
@@ -806,6 +863,37 @@
                          Select(N->getOperand(0)));
     break;
   }
+  case ISD::LOAD:
+  case ISD::EXTLOAD:
+  case ISD::ZEXTLOAD:
+  case ISD::SEXTLOAD: {
+    SDOperand Op1, Op2;
+    bool isIdx = SelectAddr(N->getOperand(1), Op1, Op2);
+
+    MVT::ValueType TypeBeingLoaded = (N->getOpcode() == ISD::LOAD) ?
+      N->getValueType(0) : cast<VTSDNode>(N->getOperand(3))->getVT();
+    unsigned Opc;
+    switch (TypeBeingLoaded) {
+    default: N->dump(); assert(0 && "Cannot load this type!");
+    case MVT::i1:
+    case MVT::i8:  Opc = isIdx ? PPC::LBZX : PPC::LBZ; break;
+    case MVT::i16:
+      if (N->getOpcode() == ISD::SEXTLOAD) { // SEXT load?
+        Opc = isIdx ? PPC::LHAX : PPC::LHA;
+      } else {
+        Opc = isIdx ? PPC::LHZX : PPC::LHZ;
+      }
+      break;
+    case MVT::i32: Opc = isIdx ? PPC::LWZX : PPC::LWZ; break;
+    case MVT::f32: Opc = isIdx ? PPC::LFSX : PPC::LFS; break;
+    case MVT::f64: Opc = isIdx ? PPC::LFDX : PPC::LFD; break;
+    }
+
+    CurDAG->SelectNodeTo(N, N->getValueType(0), MVT::Other, Opc,
+                         Op1, Op2, Select(N->getOperand(0)));
+    break;
+  }
+
   case ISD::RET: {
     SDOperand Chain = Select(N->getOperand(0));     // Token chain.
 






More information about the llvm-commits mailing list