Add new SIGN_EXTEND_INREG, ZERO_EXTEND_INREG, and FP_ROUND_INREG operators.
authorChris Lattner <sabre@nondot.org>
Sat, 15 Jan 2005 06:17:04 +0000 (06:17 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 15 Jan 2005 06:17:04 +0000 (06:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19568 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAG.h
include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 4feaf909f2f168605f9a5e94fcafe1bcb0ee2a1e..12c3c215628187f1aa303fe8670b73c3dfce99fc 100644 (file)
@@ -145,9 +145,11 @@ public:
                     std::vector<SDOperand> &Children);
 
   // getNode - These versions take an extra value type for extending and
-  // truncating loads and stores.
+  // truncating loads, stores, rounds, extends etc.
   SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1,
                     SDOperand N2, MVT::ValueType EVT);
+  SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+                    SDOperand N, MVT::ValueType EVT);
   SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1,
                     SDOperand N2, SDOperand N3, MVT::ValueType EVT);
 
index b82671e0aee0fe7fadbd67b1a714dd46ac033603..d872222c8a6841c1d3f01d995c32b092c47e57ec 100644 (file)
@@ -126,15 +126,30 @@ namespace ISD {
     SINT_TO_FP,
     UINT_TO_FP,
 
+    // SIGN_EXTEND_INREG/ZERO_EXTEND_INREG - These operators atomically performs
+    // a SHL/(SRA|SHL) pair to (sign|zero) extend a small value in a large
+    // integer register (e.g. sign extending the low 8 bits of a 32-bit register
+    // to fill the top 24 bits with the 7th bit).  The size of the smaller type
+    // is indicated by the ExtraValueType in the MVTSDNode for the operator.
+    SIGN_EXTEND_INREG,
+    ZERO_EXTEND_INREG,
+
     // FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
     // integer.
     FP_TO_SINT,
     FP_TO_UINT,
 
     // FP_ROUND - Perform a rounding operation from the current
-    // precision down to the specified precision.
+    // precision down to the specified precision (currently always 64->32).
     FP_ROUND,
 
+    // FP_ROUND_INREG - This operator takes a floating point register, and
+    // rounds it to a floating point value.  It then promotes it and returns it
+    // in a register of the same size.  This operation effectively just discards
+    // excess precision.  The type to round down to is specified by the
+    // ExtraValueType in the MVTSDNode (currently always 64->32->64).
+    FP_ROUND_INREG,
+
     // FP_EXTEND - Extend a smaller FP type into a larger FP type.
     FP_EXTEND,
 
@@ -706,6 +721,10 @@ class MVTSDNode : public SDNode {
   MVT::ValueType ExtraValueType;
 protected:
   friend class SelectionDAG;
+  MVTSDNode(unsigned Opc, MVT::ValueType VT1, SDOperand Op0, MVT::ValueType EVT)
+    : SDNode(Opc, Op0), ExtraValueType(EVT) {
+    setValueTypes(VT1);
+  }
   MVTSDNode(unsigned Opc, MVT::ValueType VT1, MVT::ValueType VT2,
             SDOperand Op0, SDOperand Op1, MVT::ValueType EVT)
     : SDNode(Opc, Op0, Op1), ExtraValueType(EVT) {
@@ -723,6 +742,9 @@ public:
   static bool classof(const MVTSDNode *) { return true; }
   static bool classof(const SDNode *N) {
     return 
+      N->getOpcode() == ISD::SIGN_EXTEND_INREG ||
+      N->getOpcode() == ISD::ZERO_EXTEND_INREG ||
+      N->getOpcode() == ISD::FP_ROUND_INREG ||
       N->getOpcode() == ISD::EXTLOAD  ||
       N->getOpcode() == ISD::SEXTLOAD || 
       N->getOpcode() == ISD::ZEXTLOAD ||
index e1b52019e965ddf19bb9aedee46b39ca8cbf4b72..c18dd40f6dd844283dd9865188cbdcd5adc03d49 100644 (file)
@@ -220,26 +220,19 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
                                                N->getOperand(1)),
                                 cast<SetCCSDNode>(N)->getCondition()));
     break;
-  case ISD::TRUNCSTORE: {
-    EVTStruct NN;
-    NN.Opcode = ISD::TRUNCSTORE;
-    NN.VT = N->getValueType(0);
-    NN.EVT = cast<MVTSDNode>(N)->getExtraValueType();
-    NN.Ops.push_back(N->getOperand(0));
-    NN.Ops.push_back(N->getOperand(1));
-    NN.Ops.push_back(N->getOperand(2));
-    MVTSDNodes.erase(NN);
-    break;
-  }
+  case ISD::TRUNCSTORE:
+  case ISD::SIGN_EXTEND_INREG:
+  case ISD::ZERO_EXTEND_INREG:
+  case ISD::FP_ROUND_INREG:
   case ISD::EXTLOAD:
   case ISD::SEXTLOAD:
   case ISD::ZEXTLOAD: {
     EVTStruct NN;
-    NN.Opcode = N->getOpcode();
+    NN.Opcode = ISD::TRUNCSTORE;
     NN.VT = N->getValueType(0);
     NN.EVT = cast<MVTSDNode>(N)->getExtraValueType();
-    NN.Ops.push_back(N->getOperand(0));
-    NN.Ops.push_back(N->getOperand(1));
+    for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+      NN.Ops.push_back(N->getOperand(i));
     MVTSDNodes.erase(NN);
     break;
   }
@@ -856,6 +849,41 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
   }
 }
 
+SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
+                                MVT::ValueType EVT) {
+
+  switch (Opcode) {
+  default: assert(0 && "Bad opcode for this accessor!");
+  case ISD::FP_ROUND_INREG:
+    assert(VT == N1.getValueType() && "Not an inreg round!");
+    assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) &&
+           "Cannot FP_ROUND_INREG integer types");
+    if (EVT == VT) return N1;  // Not actually rounding
+    assert(EVT < VT && "Not rounding down!");
+    break;
+  case ISD::ZERO_EXTEND_INREG:
+  case ISD::SIGN_EXTEND_INREG:
+    assert(VT == N1.getValueType() && "Not an inreg extend!");
+    assert(MVT::isInteger(VT) && MVT::isInteger(EVT) &&
+           "Cannot *_EXTEND_INREG FP types");
+    if (EVT == VT) return N1;  // Not actually extending
+    assert(EVT < VT && "Not extending!");
+    break;
+  }
+
+  EVTStruct NN;
+  NN.Opcode = Opcode;
+  NN.VT = VT;
+  NN.EVT = EVT;
+  NN.Ops.push_back(N1);
+
+  SDNode *&N = MVTSDNodes[NN];
+  if (N) return SDOperand(N, 0);
+  N = new MVTSDNode(Opcode, VT, N1, EVT);
+  AllNodes.push_back(N);
+  return SDOperand(N, 0);
+}
+
 SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
                                 SDOperand N2, MVT::ValueType EVT) {
   switch (Opcode) {
@@ -894,10 +922,20 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
   switch (Opcode) {
   default:  assert(0 && "Bad opcode for this accessor!");
   case ISD::TRUNCSTORE:
+#if 0 // FIXME: If the target supports EVT natively, convert to a truncate/store
+    // If this is a truncating store of a constant, convert to the desired type
+    // and store it instead.
+    if (isa<Constant>(N1)) {
+      SDOperand Op = getNode(ISD::TRUNCATE, EVT, N1);
+      if (isa<Constant>(Op))
+        N1 = Op;      
+    }
+    // Also for ConstantFP?
+#endif
     if (N1.getValueType() == EVT)       // Normal store?
       return getNode(ISD::STORE, VT, N1, N2, N3);
-    assert(N1.getValueType() > EVT && "Not a truncation?");
-    assert(MVT::isInteger(N1.getValueType()) == MVT::isInteger(EVT) &&
+    assert(N2.getValueType() > EVT && "Not a truncation?");
+    assert(MVT::isInteger(N2.getValueType()) == MVT::isInteger(EVT) &&
            "Can't do FP-INT conversion!");
     break;
   }
@@ -988,8 +1026,11 @@ const char *SDNode::getOperationName() const {
     // Conversion operators.
   case ISD::SIGN_EXTEND: return "sign_extend";
   case ISD::ZERO_EXTEND: return "zero_extend";
+  case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg";
+  case ISD::ZERO_EXTEND_INREG: return "zero_extend_inreg";
   case ISD::TRUNCATE:    return "truncate";
   case ISD::FP_ROUND:    return "fp_round";
+  case ISD::FP_ROUND_INREG: return "fp_round_inreg";
   case ISD::FP_EXTEND:   return "fp_extend";
 
   case ISD::SINT_TO_FP:  return "sint_to_fp";
index 2d264c0ed2f35a1350182416ec8dca710bb1b9eb..3250760acadf8891d2ea6b283badf6e6533e3c8f 100644 (file)
@@ -570,7 +570,6 @@ void SelectionDAGLowering::visitStore(StoreInst &I) {
   SDOperand Src = getValue(SrcV);
   SDOperand Ptr = getValue(I.getOperand(1));
   DAG.setRoot(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), Src, Ptr));
-  return;
 }
 
 void SelectionDAGLowering::visitCall(CallInst &I) {