kill ADD_PARTS & SUB_PARTS and replace them with fancy new ADDC, ADDE, SUBC
authorNate Begeman <natebegeman@mac.com>
Fri, 17 Feb 2006 05:43:56 +0000 (05:43 +0000)
committerNate Begeman <natebegeman@mac.com>
Fri, 17 Feb 2006 05:43:56 +0000 (05:43 +0000)
and SUBE nodes that actually expose what's going on and allow for
significant simplifications in the targets.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26255 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/Target/PowerPC/PPCISelDAGToDAG.cpp
lib/Target/PowerPC/PPCInstrInfo.td
lib/Target/Sparc/SparcISelDAGToDAG.cpp
lib/Target/Sparc/SparcInstrInfo.td
lib/Target/TargetSelectionDAG.td
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrInfo.td

index 1eeb7b31e50fe1a31c241aa57b3e9d5d2f9b8831..fe75a202d7e3715ee33bedae6e83e53cd4f11fb0 100644 (file)
@@ -118,6 +118,21 @@ namespace ISD {
     // Simple integer binary arithmetic operators.
     ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
     
+    // Carry-setting nodes for multiple precision addition and subtraction.
+    // These nodes take two operands of the same value type, and produce two
+    // results.  The first result is the normal add or sub result, the second
+    // result is the carry flag result.
+    ADDC, SUBC,
+    
+    // Carry-using nodes for multiple precision addition and subtraction.  These
+    // nodes take three operands: The first two are the normal lhs and rhs to
+    // the add or sub, and the third is the input carry flag.  These nodes
+    // produce two results; the normal result of the add or sub, and the output
+    // carry flag.  These nodes both read and write a carry flag to allow them
+    // to them to be chained together for add and sub of arbitrarily large
+    // values.
+    ADDE, SUBE,
+    
     // Simple binary floating point operators.
     FADD, FSUB, FMUL, FDIV, FREM,
     
@@ -156,13 +171,6 @@ namespace ISD {
     // (op #2) as a CondCodeSDNode.
     SETCC,
 
-    // ADD_PARTS/SUB_PARTS - These operators take two logical operands which are
-    // broken into a multiple pieces each, and return the resulting pieces of
-    // doing an atomic add/sub operation.  This is used to handle add/sub of
-    // expanded types.  The operation ordering is:
-    //       [Lo,Hi] = op [LoLHS,HiLHS], [LoRHS,HiRHS]
-    ADD_PARTS, SUB_PARTS,
-
     // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
     // integer shift operations, just like ADD/SUB_PARTS.  The operation
     // ordering is:
index e40be3e3ca2c6ff39101337b26c34b4d472d69ff..48bb2024e4dc82228351a5148b0d5085a370c4f0 100644 (file)
@@ -157,14 +157,11 @@ namespace {
     SDOperand visitSELECT(SDNode *N);
     SDOperand visitSELECT_CC(SDNode *N);
     SDOperand visitSETCC(SDNode *N);
-    SDOperand visitADD_PARTS(SDNode *N);
-    SDOperand visitSUB_PARTS(SDNode *N);
     SDOperand visitSIGN_EXTEND(SDNode *N);
     SDOperand visitZERO_EXTEND(SDNode *N);
     SDOperand visitSIGN_EXTEND_INREG(SDNode *N);
     SDOperand visitTRUNCATE(SDNode *N);
     SDOperand visitBIT_CONVERT(SDNode *N);
-    
     SDOperand visitFADD(SDNode *N);
     SDOperand visitFSUB(SDNode *N);
     SDOperand visitFMUL(SDNode *N);
@@ -183,7 +180,6 @@ namespace {
     SDOperand visitBRCONDTWOWAY(SDNode *N);
     SDOperand visitBR_CC(SDNode *N);
     SDOperand visitBRTWOWAY_CC(SDNode *N);
-
     SDOperand visitLOAD(SDNode *N);
     SDOperand visitSTORE(SDNode *N);
 
@@ -550,8 +546,6 @@ SDOperand DAGCombiner::visit(SDNode *N) {
   case ISD::SELECT:             return visitSELECT(N);
   case ISD::SELECT_CC:          return visitSELECT_CC(N);
   case ISD::SETCC:              return visitSETCC(N);
-  case ISD::ADD_PARTS:          return visitADD_PARTS(N);
-  case ISD::SUB_PARTS:          return visitSUB_PARTS(N);
   case ISD::SIGN_EXTEND:        return visitSIGN_EXTEND(N);
   case ISD::ZERO_EXTEND:        return visitZERO_EXTEND(N);
   case ISD::SIGN_EXTEND_INREG:  return visitSIGN_EXTEND_INREG(N);
@@ -1509,46 +1503,6 @@ SDOperand DAGCombiner::visitSETCC(SDNode *N) {
                        cast<CondCodeSDNode>(N->getOperand(2))->get());
 }
 
-SDOperand DAGCombiner::visitADD_PARTS(SDNode *N) {
-  SDOperand LHSLo = N->getOperand(0);
-  SDOperand RHSLo = N->getOperand(2);
-  MVT::ValueType VT = LHSLo.getValueType();
-  
-  // fold (a_Hi, 0) + (b_Hi, b_Lo) -> (b_Hi + a_Hi, b_Lo)
-  if (TLI.MaskedValueIsZero(LHSLo, (1ULL << MVT::getSizeInBits(VT))-1)) {
-    SDOperand Hi = DAG.getNode(ISD::ADD, VT, N->getOperand(1),
-                               N->getOperand(3));
-    WorkList.push_back(Hi.Val);
-    CombineTo(N, RHSLo, Hi);
-    return SDOperand();
-  }
-  // fold (a_Hi, a_Lo) + (b_Hi, 0) -> (a_Hi + b_Hi, a_Lo)
-  if (TLI.MaskedValueIsZero(RHSLo, (1ULL << MVT::getSizeInBits(VT))-1)) {
-    SDOperand Hi = DAG.getNode(ISD::ADD, VT, N->getOperand(1),
-                               N->getOperand(3));
-    WorkList.push_back(Hi.Val);
-    CombineTo(N, LHSLo, Hi);
-    return SDOperand();
-  }
-  return SDOperand();
-}
-
-SDOperand DAGCombiner::visitSUB_PARTS(SDNode *N) {
-  SDOperand LHSLo = N->getOperand(0);
-  SDOperand RHSLo = N->getOperand(2);
-  MVT::ValueType VT = LHSLo.getValueType();
-  
-  // fold (a_Hi, a_Lo) - (b_Hi, 0) -> (a_Hi - b_Hi, a_Lo)
-  if (TLI.MaskedValueIsZero(RHSLo, (1ULL << MVT::getSizeInBits(VT))-1)) {
-    SDOperand Hi = DAG.getNode(ISD::SUB, VT, N->getOperand(1),
-                               N->getOperand(3));
-    WorkList.push_back(Hi.Val);
-    CombineTo(N, LHSLo, Hi);
-    return SDOperand();
-  }
-  return SDOperand();
-}
-
 SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
index 70e97ab52e996d4f78105e956822f1359fe7ab99..5a45323c38a580062b75124bc15fe7fd489d7457 100644 (file)
@@ -575,7 +575,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
       break;
     }
-    break;    
+    break;
 
   case ISD::Constant:
     // We know we don't need to expand constants here, constants only have one
@@ -1749,8 +1749,6 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     }
     break;
 
-  case ISD::ADD_PARTS:
-  case ISD::SUB_PARTS:
   case ISD::SHL_PARTS:
   case ISD::SRA_PARTS:
   case ISD::SRL_PARTS: {
@@ -1830,7 +1828,32 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       break;
     }
     break;
+  
+  case ISD::ADDC:
+  case ISD::SUBC:
+    Tmp1 = LegalizeOp(Node->getOperand(0));
+    Tmp2 = LegalizeOp(Node->getOperand(1));
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+    // Since this produces two values, make sure to remember that we legalized
+    // both of them.
+    AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
+    AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
+    return Result;
+    break;
 
+  case ISD::ADDE:
+  case ISD::SUBE:
+    Tmp1 = LegalizeOp(Node->getOperand(0));
+    Tmp2 = LegalizeOp(Node->getOperand(1));
+    Tmp3 = LegalizeOp(Node->getOperand(2));
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
+    // Since this produces two values, make sure to remember that we legalized
+    // both of them.
+    AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
+    AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
+    return Result;
+    break;
+    
   case ISD::BUILD_PAIR: {
     MVT::ValueType PairTy = Node->getValueType(0);
     // TODO: handle the case where the Lo and Hi operands are not of legal type
@@ -3980,17 +4003,23 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     SDOperand LHSL, LHSH, RHSL, RHSH;
     ExpandOp(Node->getOperand(0), LHSL, LHSH);
     ExpandOp(Node->getOperand(1), RHSL, RHSH);
-    
-    std::vector<SDOperand> Ops;
-    Ops.push_back(LHSL);
-    Ops.push_back(LHSH);
-    Ops.push_back(RHSL);
-    Ops.push_back(RHSH);
-    std::vector<MVT::ValueType> VTs(2, LHSL.getValueType());
-    unsigned Opc = 
-      Node->getOpcode() == ISD::ADD ? ISD::ADD_PARTS : ISD::SUB_PARTS;
-    Lo = DAG.getNode(Opc, VTs, Ops);
-    Hi = Lo.getValue(1);
+    std::vector<MVT::ValueType> VTs;
+    std::vector<SDOperand> LoOps, HiOps;
+    VTs.push_back(LHSL.getValueType());
+    VTs.push_back(MVT::Flag);
+    LoOps.push_back(LHSL);
+    LoOps.push_back(RHSL);
+    HiOps.push_back(LHSH);
+    HiOps.push_back(RHSH);
+    if (Node->getOpcode() == ISD::ADD) {
+      Lo = DAG.getNode(ISD::ADDC, VTs, LoOps);
+      HiOps.push_back(Lo.getValue(1));
+      Hi = DAG.getNode(ISD::ADDE, VTs, HiOps);
+    } else {
+      Lo = DAG.getNode(ISD::SUBC, VTs, LoOps);
+      HiOps.push_back(Lo.getValue(1));
+      Hi = DAG.getNode(ISD::SUBE, VTs, HiOps);
+    }
     break;
   }
   case ISD::MUL: {
index 23d1dc34cc1003549022d9f65905c5e4454b9603..5fc09671c6c23ce4c94f45cc5a9f103c36d75355 100644 (file)
@@ -2552,8 +2552,10 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
   case ISD::SETCC:       return "setcc";
   case ISD::SELECT:      return "select";
   case ISD::SELECT_CC:   return "select_cc";
-  case ISD::ADD_PARTS:   return "add_parts";
-  case ISD::SUB_PARTS:   return "sub_parts";
+  case ISD::ADDC:        return "addc";
+  case ISD::ADDE:        return "adde";
+  case ISD::SUBC:        return "subc";
+  case ISD::SUBE:        return "sube";
   case ISD::SHL_PARTS:   return "shl_parts";
   case ISD::SRA_PARTS:   return "sra_parts";
   case ISD::SRL_PARTS:   return "srl_parts";
index b781ca5cd8f4494831b88f2b4ba89dafdfe18067..78dbaa64a3df6d856959c1c843b8f11df1f9306d 100644 (file)
@@ -535,75 +535,6 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool& Inv) {
   return 0;
 }
 
-
-SDOperand PPCDAGToDAGISel::SelectADD_PARTS(SDOperand Op) {
-  SDNode *N = Op.Val;
-  SDOperand LHSL, LHSH;
-  Select(LHSL, N->getOperand(0));
-  Select(LHSH, N->getOperand(1));
-  
-  unsigned Imm;
-  bool ME = false, ZE = false;
-  if (isIntImmediate(N->getOperand(3), Imm)) {
-    ME = (signed)Imm == -1;
-    ZE = Imm == 0;
-  }
-  
-  std::vector<SDOperand> Result;
-  SDOperand Tmp;
-  SDNode *CarryFromLo;
-  if (isIntImmediate(N->getOperand(2), Imm) &&
-      ((signed)Imm >= -32768 || (signed)Imm < 32768)) {
-    // Codegen the low 32 bits of the add.  Interestingly, there is no
-    // shifted form of add immediate carrying.
-    CarryFromLo = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
-                                        LHSL, getI32Imm(Imm));
-  } else {
-    Select(Tmp, N->getOperand(2));
-    CarryFromLo = CurDAG->getTargetNode(PPC::ADDC, MVT::i32, MVT::Flag,
-                                        LHSL, Tmp);
-  }
-  
-  // Codegen the high 32 bits, adding zero, minus one, or the full value
-  // along with the carry flag produced by addc/addic.
-  SDOperand ResultHi;
-  if (ZE)
-    ResultHi = SDOperand(CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, LHSH,
-                                               SDOperand(CarryFromLo, 1)), 0);
-  else if (ME)
-    ResultHi = SDOperand(CurDAG->getTargetNode(PPC::ADDME, MVT::i32, LHSH,
-                                               SDOperand(CarryFromLo, 1)), 0);
-  else {
-    Select(Tmp, N->getOperand(3));
-    ResultHi = SDOperand(CurDAG->getTargetNode(PPC::ADDE, MVT::i32, LHSH,
-                                            Tmp, SDOperand(CarryFromLo, 1)), 0);
-  }
-  Result.push_back(SDOperand(CarryFromLo, 0));
-  Result.push_back(ResultHi);
-  
-  CodeGenMap[Op.getValue(0)] = Result[0];
-  CodeGenMap[Op.getValue(1)] = Result[1];
-  return Result[Op.ResNo];
-}
-SDOperand PPCDAGToDAGISel::SelectSUB_PARTS(SDOperand Op) {
-  SDNode *N = Op.Val;
-  SDOperand LHSL, LHSH, RHSL, RHSH;
-  Select(LHSL, N->getOperand(0));
-  Select(LHSH, N->getOperand(1));
-  Select(RHSL, N->getOperand(2));
-  Select(RHSH, N->getOperand(3));
-  
-  std::vector<SDOperand> Result;
-  Result.push_back(SDOperand(CurDAG->getTargetNode(PPC::SUBFC, MVT::i32,
-                                                   MVT::Flag, RHSL, LHSL), 0));
-  Result.push_back(SDOperand(CurDAG->getTargetNode(PPC::SUBFE, MVT::i32,
-                                                   RHSH, LHSH,
-                                                   Result[0].getValue(1)), 0));
-  CodeGenMap[Op.getValue(0)] = Result[0];
-  CodeGenMap[Op.getValue(1)] = Result[1];
-  return Result[Op.ResNo];
-}
-
 SDOperand PPCDAGToDAGISel::SelectSETCC(SDOperand Op) {
   SDNode *N = Op.Val;
   unsigned Imm;
@@ -846,12 +777,6 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
   
   switch (N->getOpcode()) {
   default: break;
-  case ISD::ADD_PARTS:
-    Result = SelectADD_PARTS(Op);
-    return;
-  case ISD::SUB_PARTS:
-    Result = SelectSUB_PARTS(Op);
-    return;
   case ISD::SETCC:
     Result = SelectSETCC(Op);
     return;
index 7c184ab4bccdc671866fcd369328301d260280e6..30f4e9bd2f5bcb557f8acd70ed1a8c016892f6b6 100644 (file)
@@ -302,7 +302,7 @@ def ADDI   : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
                      [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>;
 def ADDIC  : DForm_2<12, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
                      "addic $rD, $rA, $imm", IntGeneral,
-                     []>;
+                     [(set GPRC:$rD, (addc GPRC:$rA, immSExt16:$imm))]>;
 def ADDICo : DForm_2<13, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
                      "addic. $rD, $rA, $imm", IntGeneral,
                      []>;
@@ -684,10 +684,10 @@ def ADD8  : XOForm_1<31, 266, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB),
                      [(set G8RC:$rT, (add G8RC:$rA, G8RC:$rB))]>;
 def ADDC  : XOForm_1<31, 10, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
                      "addc $rT, $rA, $rB", IntGeneral,
-                     []>;
+                     [(set GPRC:$rT, (addc GPRC:$rA, GPRC:$rB))]>;
 def ADDE  : XOForm_1<31, 138, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
                      "adde $rT, $rA, $rB", IntGeneral,
-                     []>;
+                     [(set GPRC:$rT, (adde GPRC:$rA, GPRC:$rB))]>;
 def DIVD  : XOForm_1<31, 489, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB),
                      "divd $rT, $rA, $rB", IntDivD,
                      [(set G8RC:$rT, (sdiv G8RC:$rA, G8RC:$rB))]>, isPPC64;
@@ -723,22 +723,25 @@ def SUBF  : XOForm_1<31, 40, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
                      [(set GPRC:$rT, (sub GPRC:$rB, GPRC:$rA))]>;
 def SUBFC : XOForm_1<31, 8, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
                      "subfc $rT, $rA, $rB", IntGeneral,
-                     []>;
+                     [(set GPRC:$rT, (subc GPRC:$rB, GPRC:$rA))]>;
 def SUBFE : XOForm_1<31, 136, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
                      "subfe $rT, $rA, $rB", IntGeneral,
-                     []>;
+                     [(set GPRC:$rT, (sube GPRC:$rB, GPRC:$rA))]>;
 def ADDME  : XOForm_3<31, 234, 0, (ops GPRC:$rT, GPRC:$rA),
                       "addme $rT, $rA", IntGeneral,
-                      []>;
+                      [(set GPRC:$rT, (adde GPRC:$rA, immAllOnes))]>;
 def ADDZE  : XOForm_3<31, 202, 0, (ops GPRC:$rT, GPRC:$rA),
                       "addze $rT, $rA", IntGeneral,
-                      []>;
+                      [(set GPRC:$rT, (adde GPRC:$rA, 0))]>;
 def NEG    : XOForm_3<31, 104, 0, (ops GPRC:$rT, GPRC:$rA),
                       "neg $rT, $rA", IntGeneral,
                       [(set GPRC:$rT, (ineg GPRC:$rA))]>;
+def SUBFME : XOForm_3<31, 232, 0, (ops GPRC:$rT, GPRC:$rA),
+                      "subfme $rT, $rA", IntGeneral,
+                      [(set GPRC:$rT, (sube immAllOnes, GPRC:$rA))]>;
 def SUBFZE : XOForm_3<31, 200, 0, (ops GPRC:$rT, GPRC:$rA),
                       "subfze $rT, $rA", IntGeneral,
-                      []>;
+                      [(set GPRC:$rT, (sube 0, GPRC:$rA))]>;
 
 // A-Form instructions.  Most of the instructions executed in the FPU are of
 // this type.
@@ -983,6 +986,9 @@ def : Pat<(or GPRC:$in, imm:$imm),
 // XOR an arbitrary immediate.
 def : Pat<(xor GPRC:$in, imm:$imm),
           (XORIS (XORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>;
+// SUBFIC
+def : Pat<(subc immSExt16:$imm, GPRC:$in),
+          (SUBFIC GPRC:$in, imm:$imm)>;
 
 // Return void support.
 def : Pat<(ret), (BLR)>;
index d80c0064f3594df1d8c3df233461860c57eef10b..e66e713cda18540e3e3078157679f740768368b8 100644 (file)
@@ -1075,41 +1075,6 @@ void SparcDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
   
   switch (N->getOpcode()) {
   default: break;
-  case ISD::ADD_PARTS: {
-    SDOperand LHSL, LHSH, RHSL, RHSH;
-    Select(LHSL, N->getOperand(0));
-    Select(LHSH, N->getOperand(1));
-    Select(RHSL, N->getOperand(2));
-    Select(RHSH, N->getOperand(3));
-    // FIXME, handle immediate RHS.
-    SDOperand Low =
-      SDOperand(CurDAG->getTargetNode(SP::ADDCCrr, MVT::i32, MVT::Flag,
-                                      LHSL, RHSL), 0);
-    SDOperand Hi =
-      SDOperand(CurDAG->getTargetNode(SP::ADDXrr, MVT::i32, LHSH, RHSH, 
-                                      Low.getValue(1)), 0);
-    CodeGenMap[SDOperand(N, 0)] = Low;
-    CodeGenMap[SDOperand(N, 1)] = Hi;
-    Result = Op.ResNo ? Hi : Low;
-    return;
-  }
-  case ISD::SUB_PARTS: {
-    SDOperand LHSL, LHSH, RHSL, RHSH;
-    Select(LHSL, N->getOperand(0));
-    Select(LHSH, N->getOperand(1));
-    Select(RHSL, N->getOperand(2));
-    Select(RHSH, N->getOperand(3));
-    SDOperand Low =
-      SDOperand(CurDAG->getTargetNode(SP::SUBCCrr, MVT::i32, MVT::Flag,
-                                      LHSL, RHSL), 0);
-    SDOperand Hi =
-      SDOperand(CurDAG->getTargetNode(SP::SUBXrr, MVT::i32, LHSH, RHSH, 
-                                      Low.getValue(1)), 0);
-    CodeGenMap[SDOperand(N, 0)] = Low;
-    CodeGenMap[SDOperand(N, 1)] = Hi;
-    Result = Op.ResNo ? Hi : Low;
-    return;
-  }
   case ISD::SDIV:
   case ISD::UDIV: {
     // FIXME: should use a custom expander to expose the SRA to the dag.
index 6a1b01255a8307f1f4d68a6856c68ffe3c01e16f..3d610635ccb099e5ae93b13dc59b143d637d17ab 100644 (file)
@@ -453,16 +453,20 @@ def LEA_ADDri   : F3_2<2, 0b000000,
                    
 def ADDCCrr : F3_1<2, 0b010000, 
                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
-                   "addcc $b, $c, $dst", []>;
+                   "addcc $b, $c, $dst",
+                   [(set IntRegs:$dst, (addc IntRegs:$b, IntRegs:$c))]>;
 def ADDCCri : F3_2<2, 0b010000,
                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
-                   "addcc $b, $c, $dst", []>;
+                   "addcc $b, $c, $dst", 
+                   [(set IntRegs:$dst, (addc IntRegs:$b, simm13:$c))]>;
 def ADDXrr  : F3_1<2, 0b001000, 
                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
-                   "addx $b, $c, $dst", []>;
+                   "addx $b, $c, $dst",
+                   [(set IntRegs:$dst, (adde IntRegs:$b, IntRegs:$c))]>;
 def ADDXri  : F3_2<2, 0b001000,
                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
-                   "addx $b, $c, $dst", []>;
+                   "addx $b, $c, $dst",
+                   [(set IntRegs:$dst, (adde IntRegs:$b, simm13:$c))]>;
 
 // Section B.15 - Subtract Instructions, p. 110
 def SUBrr   : F3_1<2, 0b000100, 
@@ -475,10 +479,12 @@ def SUBri   : F3_2<2, 0b000100,
                    [(set IntRegs:$dst, (sub IntRegs:$b, simm13:$c))]>;
 def SUBXrr  : F3_1<2, 0b001100, 
                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
-                   "subx $b, $c, $dst", []>;
+                   "subx $b, $c, $dst",
+                   [(set IntRegs:$dst, (sube IntRegs:$b, IntRegs:$c))]>;
 def SUBXri  : F3_2<2, 0b001100,
                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
-                   "subx $b, $c, $dst", []>;
+                   "subx $b, $c, $dst",
+                   [(set IntRegs:$dst, (sube IntRegs:$b, simm13:$c))]>;
 def SUBCCrr : F3_1<2, 0b010100, 
                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
                    "subcc $b, $c, $dst",
@@ -866,6 +872,12 @@ def : Pat<(i32 simm13:$val),
 def : Pat<(i32 imm:$val),
           (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;
 
+// subc
+def : Pat<(subc IntRegs:$b, IntRegs:$c),
+          (SUBCCrr IntRegs:$b, IntRegs:$c)>;
+def : Pat<(subc IntRegs:$b, simm13:$val),
+          (SUBCCri IntRegs:$b, imm:$val)>;
+
 // Global addresses, constant pool entries
 def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>;
 def : Pat<(SPlo tglobaladdr:$in), (ORri G0, tglobaladdr:$in)>;
index 03c3e69b63c5f3a41a33685a79e9ad713232a2c8..ab9430e7a3bc58f695c6247c63e976c72a6046e8 100644 (file)
@@ -238,6 +238,14 @@ def or         : SDNode<"ISD::OR"        , SDTIntBinOp,
                         [SDNPCommutative, SDNPAssociative]>;
 def xor        : SDNode<"ISD::XOR"       , SDTIntBinOp,
                         [SDNPCommutative, SDNPAssociative]>;
+def addc       : SDNode<"ISD::ADDC"      , SDTIntBinOp,
+                        [SDNPCommutative, SDNPOutFlag]>;
+def adde       : SDNode<"ISD::ADDE"      , SDTIntBinOp,
+                        [SDNPCommutative, SDNPOutFlag, SDNPInFlag]>;
+def subc       : SDNode<"ISD::SUBC"      , SDTIntBinOp,
+                        [SDNPOutFlag]>;
+def sube       : SDNode<"ISD::SUBE"      , SDTIntBinOp,
+                        [SDNPOutFlag, SDNPInFlag]>;
                         
 def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
 def bswap      : SDNode<"ISD::BSWAP"      , SDTIntUnaryOp>;
@@ -346,7 +354,6 @@ class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
 // Leaf fragments.
 
 def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>;
-def immZero    : PatLeaf<(imm), [{ return N->isNullValue(); }]>;
 def vtInt      : PatLeaf<(vt),  [{ return MVT::isInteger(N->getVT()); }]>;
 def vtFP       : PatLeaf<(vt),  [{ return MVT::isFloatingPoint(N->getVT()); }]>;
 
index 32c2a1fe81173088b5be754d3d4c9e3c7c94e731..ed82adbe3db751bc1a0fcaa3b933c922c4bf54c6 100644 (file)
@@ -160,8 +160,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   // Darwin ABI issue.
   setOperationAction(ISD::GlobalAddress  , MVT::i32  , Custom);
   // 64-bit addm sub, shl, sra, srl (iff 32-bit x86)
-  setOperationAction(ISD::ADD_PARTS      , MVT::i32  , Custom);
-  setOperationAction(ISD::SUB_PARTS      , MVT::i32  , Custom);
   setOperationAction(ISD::SHL_PARTS      , MVT::i32  , Custom);
   setOperationAction(ISD::SRA_PARTS      , MVT::i32  , Custom);
   setOperationAction(ISD::SRL_PARTS      , MVT::i32  , Custom);
@@ -1270,30 +1268,6 @@ X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
 SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   switch (Op.getOpcode()) {
   default: assert(0 && "Should not custom lower this!");
-  case ISD::ADD_PARTS:
-  case ISD::SUB_PARTS: {
-    assert(Op.getNumOperands() == 4 && Op.getValueType() == MVT::i32 &&
-           "Not an i64 add/sub!");
-    bool isAdd = Op.getOpcode() == ISD::ADD_PARTS;
-    std::vector<MVT::ValueType> Tys;
-    Tys.push_back(MVT::i32);
-    Tys.push_back(MVT::Flag);
-    std::vector<SDOperand> Ops;
-    Ops.push_back(Op.getOperand(0));
-    Ops.push_back(Op.getOperand(2));
-    SDOperand Lo = DAG.getNode(isAdd ? X86ISD::ADD_FLAG : X86ISD::SUB_FLAG,
-                               Tys, Ops);
-    SDOperand Hi = DAG.getNode(isAdd ? X86ISD::ADC : X86ISD::SBB, MVT::i32,
-                               Op.getOperand(1), Op.getOperand(3),
-                               Lo.getValue(1));
-    Tys.clear();
-    Tys.push_back(MVT::i32);
-    Tys.push_back(MVT::i32);
-    Ops.clear();
-    Ops.push_back(Lo);
-    Ops.push_back(Hi);
-    return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
-  }
   case ISD::SHL_PARTS:
   case ISD::SRA_PARTS:
   case ISD::SRL_PARTS: {
@@ -1910,10 +1884,6 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
 const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   switch (Opcode) {
   default: return NULL;
-  case X86ISD::ADD_FLAG:           return "X86ISD::ADD_FLAG";
-  case X86ISD::SUB_FLAG:           return "X86ISD::SUB_FLAG";
-  case X86ISD::ADC:                return "X86ISD::ADC";
-  case X86ISD::SBB:                return "X86ISD::SBB";
   case X86ISD::SHLD:               return "X86ISD::SHLD";
   case X86ISD::SHRD:               return "X86ISD::SHRD";
   case X86ISD::FAND:               return "X86ISD::FAND";
index dc1a13c79fa557ed15d8d101291a3b247e8f6818..2aa365959a6300cf9f46c27699663a3d541d454c 100644 (file)
@@ -26,16 +26,6 @@ namespace llvm {
       // Start the numbering where the builtin ops leave off.
       FIRST_NUMBER = ISD::BUILTIN_OP_END+X86::INSTRUCTION_LIST_END,
 
-      /// ADD_FLAG, SUB_FLAG - Same as ISD::ADD and ISD::SUB except it also
-      /// produces a flag result.
-      ADD_FLAG,
-      SUB_FLAG,
-
-      /// ADC, SBB - Add with carry and subtraction with borrow. These
-      /// correspond to X86::ADCxx and X86::SBBxx instructions.
-      ADC,
-      SBB,
-
       /// SHLD, SHRD - Double shift instructions. These correspond to
       /// X86::SHLDxx and X86::SHRDxx instructions.
       SHLD,
index c6b1ff55e5f87527cc9acacb425f2fbea69ea0c8..d1c58d7127c929c5fdb27f656bb0818f6862173b 100644 (file)
@@ -56,15 +56,6 @@ def SDTX86RepStr  : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
 
 def SDTX86RdTsc   : SDTypeProfile<0, 0, []>;
 
-def X86addflag : SDNode<"X86ISD::ADD_FLAG", SDTIntBinOp ,
-                        [SDNPCommutative, SDNPAssociative, SDNPOutFlag]>;
-def X86subflag : SDNode<"X86ISD::SUB_FLAG", SDTIntBinOp,
-                        [SDNPOutFlag]>;
-def X86adc     : SDNode<"X86ISD::ADC" ,     SDTIntBinOp ,
-                        [SDNPCommutative, SDNPAssociative, SDNPInFlag]>;
-def X86sbb     : SDNode<"X86ISD::SBB" ,     SDTIntBinOp,
-                        [SDNPInFlag]>;
-
 def X86shld    : SDNode<"X86ISD::SHLD",     SDTIntShiftDOp>;
 def X86shrd    : SDNode<"X86ISD::SHRD",     SDTIntShiftDOp>;
 
@@ -1873,28 +1864,28 @@ let isTwoAddress = 0 in {
 let isCommutable = 1 in {  // X = ADC Y, Z --> X = ADC Z, Y
 def ADC32rr  : I<0x11, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
                  "adc{l} {$src2, $dst|$dst, $src2}",
-                 [(set R32:$dst, (X86adc R32:$src1, R32:$src2))]>;
+                 [(set R32:$dst, (adde R32:$src1, R32:$src2))]>;
 }
 def ADC32rm  : I<0x13, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
                  "adc{l} {$src2, $dst|$dst, $src2}",
-                 [(set R32:$dst, (X86adc R32:$src1, (load addr:$src2)))]>;
+                 [(set R32:$dst, (adde R32:$src1, (load addr:$src2)))]>;
 def ADC32ri  : Ii32<0x81, MRM2r, (ops R32:$dst, R32:$src1, i32imm:$src2),
                     "adc{l} {$src2, $dst|$dst, $src2}",
-                 [(set R32:$dst, (X86adc R32:$src1, imm:$src2))]>;
+                 [(set R32:$dst, (adde R32:$src1, imm:$src2))]>;
 def ADC32ri8 : Ii8<0x83, MRM2r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
                    "adc{l} {$src2, $dst|$dst, $src2}",
-                 [(set R32:$dst, (X86adc R32:$src1, i32immSExt8:$src2))]>;
+                 [(set R32:$dst, (adde R32:$src1, i32immSExt8:$src2))]>;
 
 let isTwoAddress = 0 in {
   def ADC32mr  : I<0x11, MRMDestMem, (ops i32mem:$dst, R32:$src2),
                    "adc{l} {$src2, $dst|$dst, $src2}",
-                   [(store (X86adc (load addr:$dst), R32:$src2), addr:$dst)]>;
+                   [(store (adde (load addr:$dst), R32:$src2), addr:$dst)]>;
   def ADC32mi  : Ii32<0x81, MRM2m, (ops i32mem:$dst, i32imm:$src2),
                       "adc{l} {$src2, $dst|$dst, $src2}",
-                  [(store (X86adc (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
+                  [(store (adde (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
   def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i32i8imm :$src2),
                      "adc{l} {$src2, $dst|$dst, $src2}",
-             [(store (X86adc (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
+             [(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
 }
 
 def SUB8rr   : I<0x28, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
@@ -1964,51 +1955,51 @@ let isTwoAddress = 0 in {
 
 def SBB32rr    : I<0x19, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
                   "sbb{l} {$src2, $dst|$dst, $src2}",
-                  [(set R32:$dst, (X86sbb R32:$src1, R32:$src2))]>;
+                  [(set R32:$dst, (sube R32:$src1, R32:$src2))]>;
 
 let isTwoAddress = 0 in {
   def SBB32mr  : I<0x19, MRMDestMem, (ops i32mem:$dst, R32:$src2), 
                    "sbb{l} {$src2, $dst|$dst, $src2}",
-                   [(store (X86sbb (load addr:$dst), R32:$src2), addr:$dst)]>;
+                   [(store (sube (load addr:$dst), R32:$src2), addr:$dst)]>;
   def SBB8mi  : Ii32<0x80, MRM3m, (ops i8mem:$dst, i8imm:$src2), 
                       "sbb{b} {$src2, $dst|$dst, $src2}",
-                   [(store (X86sbb (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
+                   [(store (sube (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
   def SBB16mi  : Ii32<0x81, MRM3m, (ops i16mem:$dst, i16imm:$src2), 
                       "sbb{w} {$src2, $dst|$dst, $src2}",
-                  [(store (X86sbb (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
+                  [(store (sube (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
                      OpSize;
   def SBB32mi  : Ii32<0x81, MRM3m, (ops i32mem:$dst, i32imm:$src2), 
                       "sbb{l} {$src2, $dst|$dst, $src2}",
-                  [(store (X86sbb (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
+                  [(store (sube (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
   def SBB16mi8 : Ii8<0x83, MRM3m, (ops i16mem:$dst, i16i8imm :$src2), 
                      "sbb{w} {$src2, $dst|$dst, $src2}",
-             [(store (X86sbb (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
+             [(store (sube (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
                      OpSize;
   def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i32i8imm :$src2), 
                      "sbb{l} {$src2, $dst|$dst, $src2}",
-             [(store (X86sbb (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
+             [(store (sube (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
 }
 def SBB8ri   : Ii8<0x80, MRM3r, (ops R8:$dst, R8:$src1, i8imm:$src2),
                     "sbb{b} {$src2, $dst|$dst, $src2}",
-                    [(set R8:$dst, (X86sbb R8:$src1, imm:$src2))]>;
+                    [(set R8:$dst, (sube R8:$src1, imm:$src2))]>;
 def SBB16ri  : Ii16<0x81, MRM3r, (ops R16:$dst, R16:$src1, i16imm:$src2),
                     "sbb{w} {$src2, $dst|$dst, $src2}",
-                    [(set R16:$dst, (X86sbb R16:$src1, imm:$src2))]>, OpSize;
+                    [(set R16:$dst, (sube R16:$src1, imm:$src2))]>, OpSize;
 
 def SBB32rm  : I<0x1B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
                     "sbb{l} {$src2, $dst|$dst, $src2}",
-                    [(set R32:$dst, (X86sbb R32:$src1, (load addr:$src2)))]>;
+                    [(set R32:$dst, (sube R32:$src1, (load addr:$src2)))]>;
 def SBB32ri  : Ii32<0x81, MRM3r, (ops R32:$dst, R32:$src1, i32imm:$src2),
                     "sbb{l} {$src2, $dst|$dst, $src2}",
-                    [(set R32:$dst, (X86sbb R32:$src1, imm:$src2))]>;
+                    [(set R32:$dst, (sube R32:$src1, imm:$src2))]>;
 
 def SBB16ri8 : Ii8<0x83, MRM3r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
                    "sbb{w} {$src2, $dst|$dst, $src2}",
-                   [(set R16:$dst, (X86sbb R16:$src1, i16immSExt8:$src2))]>,
+                   [(set R16:$dst, (sube R16:$src1, i16immSExt8:$src2))]>,
                    OpSize;
 def SBB32ri8 : Ii8<0x83, MRM3r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
                    "sbb{l} {$src2, $dst|$dst, $src2}",
-                   [(set R32:$dst, (X86sbb R32:$src1, i32immSExt8:$src2))]>;
+                   [(set R32:$dst, (sube R32:$src1, i32immSExt8:$src2))]>;
 
 let isCommutable = 1 in {  // X = IMUL Y, Z --> X = IMUL Z, Y
 def IMUL16rr : I<0xAF, MRMSrcReg, (ops R16:$dst, R16:$src1, R16:$src2),
@@ -3077,22 +3068,22 @@ def : Pat<(X86call texternalsym:$dst),
           (CALLpcrel32 texternalsym:$dst)>;
 
 // X86 specific add which produces a flag.
-def : Pat<(X86addflag R32:$src1, R32:$src2),
+def : Pat<(addc R32:$src1, R32:$src2),
           (ADD32rr R32:$src1, R32:$src2)>;
-def : Pat<(X86addflag R32:$src1, (load addr:$src2)),
+def : Pat<(addc R32:$src1, (load addr:$src2)),
           (ADD32rm R32:$src1, addr:$src2)>;
-def : Pat<(X86addflag R32:$src1, imm:$src2),
+def : Pat<(addc R32:$src1, imm:$src2),
           (ADD32ri R32:$src1, imm:$src2)>;
-def : Pat<(X86addflag R32:$src1, i32immSExt8:$src2),
+def : Pat<(addc R32:$src1, i32immSExt8:$src2),
           (ADD32ri8 R32:$src1, i32immSExt8:$src2)>;
 
-def : Pat<(X86subflag R32:$src1, R32:$src2),
+def : Pat<(subc R32:$src1, R32:$src2),
           (SUB32rr R32:$src1, R32:$src2)>;
-def : Pat<(X86subflag R32:$src1, (load addr:$src2)),
+def : Pat<(subc R32:$src1, (load addr:$src2)),
           (SUB32rm R32:$src1, addr:$src2)>;
-def : Pat<(X86subflag R32:$src1, imm:$src2),
+def : Pat<(subc R32:$src1, imm:$src2),
           (SUB32ri R32:$src1, imm:$src2)>;
-def : Pat<(X86subflag R32:$src1, i32immSExt8:$src2),
+def : Pat<(subc R32:$src1, i32immSExt8:$src2),
           (SUB32ri8 R32:$src1, i32immSExt8:$src2)>;
 
 def : Pat<(truncstore (i8 imm:$src), addr:$dst, i1),