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

Chris Lattner lattner at cs.uiuc.edu
Sun Aug 21 11:50:49 PDT 2005



Changes in directory llvm/lib/Target/PowerPC:

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

Implement selection for branches.  




---
Diffs of the changes:  (+83 -0)

 PPC32ISelDAGToDAG.cpp |   83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 83 insertions(+)


Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.16 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.17
--- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.16	Fri Aug 19 17:38:53 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp	Sun Aug 21 13:50:37 2005
@@ -69,6 +69,10 @@
                                    bool Negate = false);
     SDNode *SelectBitfieldInsert(SDNode *N);
 
+    /// SelectCC - Select a comparison of the specified values with the
+    /// specified condition code, returning the CR# of the expression.
+    SDOperand SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC);
+
     /// InstructionSelectBasicBlock - This callback is invoked by
     /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
     virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
@@ -353,6 +357,47 @@
 }
 
 
+/// SelectCC - Select a comparison of the specified values with the specified
+/// condition code, returning the CR# of the expression.
+SDOperand PPC32DAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
+                                      ISD::CondCode CC) {
+  // Always select the LHS.
+  LHS = Select(LHS);
+
+  // Use U to determine whether the SETCC immediate range is signed or not.
+  if (MVT::isInteger(LHS.getValueType())) {
+    bool U = ISD::isUnsignedIntSetCC(CC);
+    unsigned Imm;
+    if (isIntImmediate(RHS, Imm) && 
+        ((U && isUInt16(Imm)) || (!U && isInt16(Imm))))
+      return CurDAG->getTargetNode(U ? PPC::CMPLWI : PPC::CMPWI, MVT::i32,
+                                   LHS, getI32Imm(Lo16(Imm)));
+    return CurDAG->getTargetNode(U ? PPC::CMPLW : PPC::CMPW, MVT::i32,
+                                 LHS, Select(RHS));
+  } else {
+    return CurDAG->getTargetNode(PPC::FCMPU, MVT::i32, LHS, Select(RHS));
+  }
+}
+
+/// getBCCForSetCC - Returns the PowerPC condition branch mnemonic corresponding
+/// to Condition.
+static unsigned getBCCForSetCC(ISD::CondCode CC) {
+  switch (CC) {
+  default: assert(0 && "Unknown condition!"); abort();
+  case ISD::SETEQ:  return PPC::BEQ;
+  case ISD::SETNE:  return PPC::BNE;
+  case ISD::SETULT:
+  case ISD::SETLT:  return PPC::BLT;
+  case ISD::SETULE:
+  case ISD::SETLE:  return PPC::BLE;
+  case ISD::SETUGT:
+  case ISD::SETGT:  return PPC::BGT;
+  case ISD::SETUGE:
+  case ISD::SETGE:  return PPC::BGE;
+  }
+  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) {
@@ -790,6 +835,44 @@
     CurDAG->SelectNodeTo(N, MVT::Other, PPC::BLR, Chain);
     break;
   }
+
+  case ISD::BR_CC:
+  case ISD::BRTWOWAY_CC: {
+    SDOperand Chain = Select(N->getOperand(0));
+    MachineBasicBlock *Dest =
+      cast<BasicBlockSDNode>(N->getOperand(4))->getBasicBlock();
+    ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
+    SDOperand CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC);
+    unsigned Opc = getBCCForSetCC(CC);
+
+    // If this is a two way branch, then grab the fallthrough basic block
+    // argument and build a PowerPC branch pseudo-op, suitable for long branch
+    // conversion if necessary by the branch selection pass.  Otherwise, emit a
+    // standard conditional branch.
+    if (N->getOpcode() == ISD::BRTWOWAY_CC) {
+      MachineBasicBlock *Fallthrough =
+        cast<BasicBlockSDNode>(N->getOperand(5))->getBasicBlock();
+      SDOperand CB = CurDAG->getTargetNode(PPC::COND_BRANCH, MVT::Other,
+                                           CondCode, getI32Imm(Opc),
+                                           N->getOperand(4), N->getOperand(5),
+                                           Chain);
+      CurDAG->SelectNodeTo(N, MVT::Other, PPC::B, N->getOperand(5), CB);
+    } else {
+      // Iterate to the next basic block
+      ilist<MachineBasicBlock>::iterator It = BB;
+      ++It;
+
+      // If the fallthrough path is off the end of the function, which would be
+      // undefined behavior, set it to be the same as the current block because
+      // we have nothing better to set it to, and leaving it alone will cause
+      // the PowerPC Branch Selection pass to crash.
+      if (It == BB->getParent()->end()) It = Dest;
+      CurDAG->SelectNodeTo(N, MVT::Other, PPC::COND_BRANCH, CondCode,
+                           getI32Imm(Opc), N->getOperand(4),
+                           CurDAG->getBasicBlock(It), Chain);
+    }
+    break;
+  }
   }
   return SDOperand(N, 0);
 }






More information about the llvm-commits mailing list