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.

llvm-svn: 26255
This commit is contained in:
Nate Begeman 2006-02-17 05:43:56 +00:00
parent 9ec392b2aa
commit 5965bd19f8
12 changed files with 130 additions and 271 deletions

View 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:

View 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);

View 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: {

View 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";

View 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;

View 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)>;

View 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.

View 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)>;

View 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()); }]>;

View 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";

View 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,

View 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),