diff options
author | Nate Begeman <natebegeman@mac.com> | 2006-02-17 05:43:56 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2006-02-17 05:43:56 +0000 |
commit | 551bf3f80058a026b6a128dffd5530019e1df1b9 (patch) | |
tree | e6f8e7aca7b09c6bd795ff14bb5598d7e1f022bc | |
parent | 25125697fb0a761da440b222671cf2d6d4deaeac (diff) |
kill ADD_PARTS & SUB_PARTS and replace them with fancy new ADDC, ADDE, SUBC
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
-rw-r--r-- | include/llvm/CodeGen/SelectionDAGNodes.h | 22 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 46 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 57 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 6 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 75 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.td | 22 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcISelDAGToDAG.cpp | 35 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrInfo.td | 24 | ||||
-rw-r--r-- | lib/Target/TargetSelectionDAG.td | 9 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 30 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 10 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 65 |
12 files changed, 130 insertions, 271 deletions
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 1eeb7b31e5..fe75a202d7 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -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: diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e40be3e3ca..48bb2024e4 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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); diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 70e97ab52e..5a45323c38 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -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: { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 23d1dc34cc..5fc09671c6 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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"; diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index b781ca5cd8..78dbaa64a3 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -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; diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 7c184ab4bc..30f4e9bd2f 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -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)>; diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index d80c0064f3..e66e713cda 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -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. diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index 6a1b01255a..3d610635cc 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -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)>; diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td index 03c3e69b63..ab9430e7a3 100644 --- a/lib/Target/TargetSelectionDAG.td +++ b/lib/Target/TargetSelectionDAG.td @@ -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()); }]>; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 32c2a1fe81..ed82adbe3d 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -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"; diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index dc1a13c79f..2aa365959a 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -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, diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index c6b1ff55e5..d1c58d7127 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -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), |