mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 20:29:48 +00:00
X86ISD::CMP now produces a chain as well as a flag. Make that the chain
operand of a conditional branch to allow load folding into CMP / TEST instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30241 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
019f851ab2
commit
734503be59
@ -3394,9 +3394,9 @@ SDOperand X86TargetLowering::LowerShift(SDOperand Op, SelectionDAG &DAG) {
|
||||
SDOperand ShOpLo = Op.getOperand(0);
|
||||
SDOperand ShOpHi = Op.getOperand(1);
|
||||
SDOperand ShAmt = Op.getOperand(2);
|
||||
SDOperand Tmp1 = isSRA ? DAG.getNode(ISD::SRA, MVT::i32, ShOpHi,
|
||||
DAG.getConstant(31, MVT::i8))
|
||||
: DAG.getConstant(0, MVT::i32);
|
||||
SDOperand Tmp1 = isSRA ?
|
||||
DAG.getNode(ISD::SRA, MVT::i32, ShOpHi, DAG.getConstant(31, MVT::i8)) :
|
||||
DAG.getConstant(0, MVT::i32);
|
||||
|
||||
SDOperand Tmp2, Tmp3;
|
||||
if (Op.getOpcode() == ISD::SHL_PARTS) {
|
||||
@ -3407,25 +3407,23 @@ SDOperand X86TargetLowering::LowerShift(SDOperand Op, SelectionDAG &DAG) {
|
||||
Tmp3 = DAG.getNode(isSRA ? ISD::SRA : ISD::SRL, MVT::i32, ShOpHi, ShAmt);
|
||||
}
|
||||
|
||||
SDOperand InFlag =
|
||||
DAG.getNode(X86ISD::CMP, MVT::Flag,
|
||||
DAG.getNode(ISD::AND, MVT::i8,
|
||||
ShAmt, DAG.getConstant(32, MVT::i8)),
|
||||
DAG.getConstant(0, MVT::i8));
|
||||
const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
|
||||
SDOperand AndNode = DAG.getNode(ISD::AND, MVT::i8, ShAmt,
|
||||
DAG.getConstant(32, MVT::i8));
|
||||
SDOperand COps[]={DAG.getEntryNode(), AndNode, DAG.getConstant(0, MVT::i8)};
|
||||
SDOperand InFlag = DAG.getNode(X86ISD::CMP, VTs, 2, COps, 3).getValue(1);
|
||||
|
||||
SDOperand Hi, Lo;
|
||||
SDOperand CC = DAG.getConstant(X86ISD::COND_NE, MVT::i8);
|
||||
|
||||
std::vector<MVT::ValueType> Tys;
|
||||
Tys.push_back(MVT::i32);
|
||||
Tys.push_back(MVT::Flag);
|
||||
std::vector<SDOperand> Ops;
|
||||
VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag);
|
||||
SmallVector<SDOperand, 4> Ops;
|
||||
if (Op.getOpcode() == ISD::SHL_PARTS) {
|
||||
Ops.push_back(Tmp2);
|
||||
Ops.push_back(Tmp3);
|
||||
Ops.push_back(CC);
|
||||
Ops.push_back(InFlag);
|
||||
Hi = DAG.getNode(X86ISD::CMOV, Tys, &Ops[0], Ops.size());
|
||||
Hi = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
|
||||
InFlag = Hi.getValue(1);
|
||||
|
||||
Ops.clear();
|
||||
@ -3433,13 +3431,13 @@ SDOperand X86TargetLowering::LowerShift(SDOperand Op, SelectionDAG &DAG) {
|
||||
Ops.push_back(Tmp1);
|
||||
Ops.push_back(CC);
|
||||
Ops.push_back(InFlag);
|
||||
Lo = DAG.getNode(X86ISD::CMOV, Tys, &Ops[0], Ops.size());
|
||||
Lo = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
|
||||
} else {
|
||||
Ops.push_back(Tmp2);
|
||||
Ops.push_back(Tmp3);
|
||||
Ops.push_back(CC);
|
||||
Ops.push_back(InFlag);
|
||||
Lo = DAG.getNode(X86ISD::CMOV, Tys, &Ops[0], Ops.size());
|
||||
Lo = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
|
||||
InFlag = Lo.getValue(1);
|
||||
|
||||
Ops.clear();
|
||||
@ -3447,16 +3445,14 @@ SDOperand X86TargetLowering::LowerShift(SDOperand Op, SelectionDAG &DAG) {
|
||||
Ops.push_back(Tmp1);
|
||||
Ops.push_back(CC);
|
||||
Ops.push_back(InFlag);
|
||||
Hi = DAG.getNode(X86ISD::CMOV, Tys, &Ops[0], Ops.size());
|
||||
Hi = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
|
||||
}
|
||||
|
||||
Tys.clear();
|
||||
Tys.push_back(MVT::i32);
|
||||
Tys.push_back(MVT::i32);
|
||||
VTs = DAG.getNodeValueTypes(MVT::i32, MVT::i32);
|
||||
Ops.clear();
|
||||
Ops.push_back(Lo);
|
||||
Ops.push_back(Hi);
|
||||
return DAG.getNode(ISD::MERGE_VALUES, Tys, &Ops[0], Ops.size());
|
||||
return DAG.getNode(ISD::MERGE_VALUES, VTs, 2, &Ops[0], Ops.size());
|
||||
}
|
||||
|
||||
SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
|
||||
@ -3613,163 +3609,139 @@ SDOperand X86TargetLowering::LowerFNEG(SDOperand Op, SelectionDAG &DAG) {
|
||||
return DAG.getNode(X86ISD::FXOR, VT, Op.getOperand(0), Mask);
|
||||
}
|
||||
|
||||
SDOperand X86TargetLowering::LowerSETCC(SDOperand Op, SelectionDAG &DAG) {
|
||||
SDOperand X86TargetLowering::LowerSETCC(SDOperand Op, SelectionDAG &DAG,
|
||||
SDOperand Chain) {
|
||||
assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");
|
||||
SDOperand Cond;
|
||||
SDOperand Op0 = Op.getOperand(0);
|
||||
SDOperand Op1 = Op.getOperand(1);
|
||||
SDOperand CC = Op.getOperand(2);
|
||||
ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
|
||||
const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
|
||||
bool isFP = MVT::isFloatingPoint(Op.getOperand(1).getValueType());
|
||||
bool Flip;
|
||||
unsigned X86CC;
|
||||
if (translateX86CC(CC, isFP, X86CC, Flip)) {
|
||||
if (Flip)
|
||||
Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
|
||||
Op.getOperand(1), Op.getOperand(0));
|
||||
else
|
||||
Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
|
||||
Op.getOperand(0), Op.getOperand(1));
|
||||
return DAG.getNode(X86ISD::SETCC, MVT::i8,
|
||||
DAG.getConstant(X86CC, MVT::i8), Cond);
|
||||
} else {
|
||||
assert(isFP && "Illegal integer SetCC!");
|
||||
|
||||
Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
|
||||
Op.getOperand(0), Op.getOperand(1));
|
||||
std::vector<MVT::ValueType> Tys;
|
||||
std::vector<SDOperand> Ops;
|
||||
switch (SetCCOpcode) {
|
||||
default: assert(false && "Illegal floating point SetCC!");
|
||||
case ISD::SETOEQ: { // !PF & ZF
|
||||
Tys.push_back(MVT::i8);
|
||||
Tys.push_back(MVT::Flag);
|
||||
Ops.push_back(DAG.getConstant(X86ISD::COND_NP, MVT::i8));
|
||||
Ops.push_back(Cond);
|
||||
SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, &Ops[0], Ops.size());
|
||||
SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8,
|
||||
DAG.getConstant(X86ISD::COND_E, MVT::i8),
|
||||
Tmp1.getValue(1));
|
||||
return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2);
|
||||
}
|
||||
case ISD::SETUNE: { // PF | !ZF
|
||||
Tys.push_back(MVT::i8);
|
||||
Tys.push_back(MVT::Flag);
|
||||
Ops.push_back(DAG.getConstant(X86ISD::COND_P, MVT::i8));
|
||||
Ops.push_back(Cond);
|
||||
SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, &Ops[0], Ops.size());
|
||||
SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8,
|
||||
DAG.getConstant(X86ISD::COND_NE, MVT::i8),
|
||||
Tmp1.getValue(1));
|
||||
return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2);
|
||||
}
|
||||
}
|
||||
VTs = DAG.getNodeValueTypes(MVT::i8, MVT::Flag);
|
||||
if (translateX86CC(CC, isFP, X86CC, Flip)) {
|
||||
if (Flip) std::swap(Op0, Op1);
|
||||
SDOperand Ops1[] = { Chain, Op0, Op1 };
|
||||
Cond = DAG.getNode(X86ISD::CMP, VTs, 2, Ops1, 3).getValue(1);
|
||||
SDOperand Ops2[] = { DAG.getConstant(X86CC, MVT::i8), Cond };
|
||||
return DAG.getNode(X86ISD::SETCC, VTs, 2, Ops2, 2);
|
||||
}
|
||||
|
||||
assert(isFP && "Illegal integer SetCC!");
|
||||
|
||||
SDOperand COps[] = { Chain, Op0, Op1 };
|
||||
Cond = DAG.getNode(X86ISD::CMP, VTs, 2, COps, 3).getValue(1);
|
||||
|
||||
switch (SetCCOpcode) {
|
||||
default: assert(false && "Illegal floating point SetCC!");
|
||||
case ISD::SETOEQ: { // !PF & ZF
|
||||
SDOperand Ops1[] = { DAG.getConstant(X86ISD::COND_NP, MVT::i8), Cond };
|
||||
SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, VTs, 2, Ops1, 2);
|
||||
SDOperand Ops2[] = { DAG.getConstant(X86ISD::COND_E, MVT::i8),
|
||||
Tmp1.getValue(1) };
|
||||
SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, VTs, 2, Ops2, 2);
|
||||
return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2);
|
||||
}
|
||||
case ISD::SETUNE: { // PF | !ZF
|
||||
SDOperand Ops1[] = { DAG.getConstant(X86ISD::COND_P, MVT::i8), Cond };
|
||||
SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, VTs, 2, Ops1, 2);
|
||||
SDOperand Ops2[] = { DAG.getConstant(X86ISD::COND_NE, MVT::i8),
|
||||
Tmp1.getValue(1) };
|
||||
SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, VTs, 2, Ops2, 2);
|
||||
return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDOperand X86TargetLowering::LowerSELECT(SDOperand Op, SelectionDAG &DAG) {
|
||||
MVT::ValueType VT = Op.getValueType();
|
||||
bool isFPStack = MVT::isFloatingPoint(VT) && !X86ScalarSSE;
|
||||
bool addTest = false;
|
||||
SDOperand Op0 = Op.getOperand(0);
|
||||
SDOperand Cond, CC;
|
||||
if (Op0.getOpcode() == ISD::SETCC)
|
||||
Op0 = LowerOperation(Op0, DAG);
|
||||
bool addTest = true;
|
||||
SDOperand Chain = DAG.getEntryNode();
|
||||
SDOperand Cond = Op.getOperand(0);
|
||||
SDOperand CC;
|
||||
const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
|
||||
|
||||
if (Cond.getOpcode() == ISD::SETCC)
|
||||
Cond = LowerSETCC(Cond, DAG, Chain);
|
||||
|
||||
if (Cond.getOpcode() == X86ISD::SETCC) {
|
||||
CC = Cond.getOperand(0);
|
||||
|
||||
if (Op0.getOpcode() == X86ISD::SETCC) {
|
||||
// If condition flag is set by a X86ISD::CMP, then make a copy of it
|
||||
// (since flag operand cannot be shared). If the X86ISD::SETCC does not
|
||||
// have another use it will be eliminated.
|
||||
// If the X86ISD::SETCC has more than one use, then it's probably better
|
||||
// (since flag operand cannot be shared). Use it as the condition setting
|
||||
// operand in place of the X86ISD::SETCC.
|
||||
// If the X86ISD::SETCC has more than one use, then perhaps it's better
|
||||
// to use a test instead of duplicating the X86ISD::CMP (for register
|
||||
// pressure reason).
|
||||
unsigned CmpOpc = Op0.getOperand(1).getOpcode();
|
||||
if (CmpOpc == X86ISD::CMP || CmpOpc == X86ISD::COMI ||
|
||||
CmpOpc == X86ISD::UCOMI) {
|
||||
if (!Op0.hasOneUse()) {
|
||||
std::vector<MVT::ValueType> Tys;
|
||||
for (unsigned i = 0; i < Op0.Val->getNumValues(); ++i)
|
||||
Tys.push_back(Op0.Val->getValueType(i));
|
||||
std::vector<SDOperand> Ops;
|
||||
for (unsigned i = 0; i < Op0.getNumOperands(); ++i)
|
||||
Ops.push_back(Op0.getOperand(i));
|
||||
Op0 = DAG.getNode(X86ISD::SETCC, Tys, &Ops[0], Ops.size());
|
||||
}
|
||||
|
||||
CC = Op0.getOperand(0);
|
||||
Cond = Op0.getOperand(1);
|
||||
// Make a copy as flag result cannot be used by more than one.
|
||||
Cond = DAG.getNode(CmpOpc, MVT::Flag,
|
||||
Cond.getOperand(0), Cond.getOperand(1));
|
||||
addTest =
|
||||
isFPStack && !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
|
||||
} else
|
||||
addTest = true;
|
||||
} else
|
||||
addTest = true;
|
||||
// pressure reason)?
|
||||
SDOperand Cmp = Cond.getOperand(1);
|
||||
unsigned Opc = Cmp.getOpcode();
|
||||
bool IllegalFPCMov = !X86ScalarSSE &&
|
||||
MVT::isFloatingPoint(Op.getValueType()) &&
|
||||
!hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
|
||||
if ((Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI) &&
|
||||
!IllegalFPCMov) {
|
||||
SDOperand Ops[] = { Chain, Cmp.getOperand(1), Cmp.getOperand(2) };
|
||||
Cond = DAG.getNode(Opc, VTs, 2, Ops, 3);
|
||||
addTest = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (addTest) {
|
||||
CC = DAG.getConstant(X86ISD::COND_NE, MVT::i8);
|
||||
Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Op0,
|
||||
DAG.getConstant(0, MVT::i8));
|
||||
SDOperand Ops[] = { Chain, Cond, DAG.getConstant(0, MVT::i8) };
|
||||
Cond = DAG.getNode(X86ISD::CMP, VTs, 2, Ops, 3);
|
||||
}
|
||||
|
||||
std::vector<MVT::ValueType> Tys;
|
||||
Tys.push_back(Op.getValueType());
|
||||
Tys.push_back(MVT::Flag);
|
||||
std::vector<SDOperand> Ops;
|
||||
VTs = DAG.getNodeValueTypes(Op.getValueType(), MVT::Flag);
|
||||
SmallVector<SDOperand, 4> Ops;
|
||||
// X86ISD::CMOV means set the result (which is operand 1) to the RHS if
|
||||
// condition is true.
|
||||
Ops.push_back(Op.getOperand(2));
|
||||
Ops.push_back(Op.getOperand(1));
|
||||
Ops.push_back(CC);
|
||||
Ops.push_back(Cond);
|
||||
return DAG.getNode(X86ISD::CMOV, Tys, &Ops[0], Ops.size());
|
||||
Ops.push_back(Cond.getValue(1));
|
||||
return DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
|
||||
}
|
||||
|
||||
SDOperand X86TargetLowering::LowerBRCOND(SDOperand Op, SelectionDAG &DAG) {
|
||||
bool addTest = false;
|
||||
bool addTest = true;
|
||||
SDOperand Chain = Op.getOperand(0);
|
||||
SDOperand Cond = Op.getOperand(1);
|
||||
SDOperand Dest = Op.getOperand(2);
|
||||
SDOperand CC;
|
||||
const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
|
||||
|
||||
if (Cond.getOpcode() == ISD::SETCC)
|
||||
Cond = LowerOperation(Cond, DAG);
|
||||
Cond = LowerSETCC(Cond, DAG, Chain);
|
||||
|
||||
if (Cond.getOpcode() == X86ISD::SETCC) {
|
||||
// If condition flag is set by a X86ISD::CMP, then make a copy of it
|
||||
// (since flag operand cannot be shared). If the X86ISD::SETCC does not
|
||||
// have another use it will be eliminated.
|
||||
// If the X86ISD::SETCC has more than one use, then it's probably better
|
||||
// to use a test instead of duplicating the X86ISD::CMP (for register
|
||||
// pressure reason).
|
||||
unsigned CmpOpc = Cond.getOperand(1).getOpcode();
|
||||
if (CmpOpc == X86ISD::CMP || CmpOpc == X86ISD::COMI ||
|
||||
CmpOpc == X86ISD::UCOMI) {
|
||||
if (!Cond.hasOneUse()) {
|
||||
std::vector<MVT::ValueType> Tys;
|
||||
for (unsigned i = 0; i < Cond.Val->getNumValues(); ++i)
|
||||
Tys.push_back(Cond.Val->getValueType(i));
|
||||
std::vector<SDOperand> Ops;
|
||||
for (unsigned i = 0; i < Cond.getNumOperands(); ++i)
|
||||
Ops.push_back(Cond.getOperand(i));
|
||||
Cond = DAG.getNode(X86ISD::SETCC, Tys, &Ops[0], Ops.size());
|
||||
}
|
||||
CC = Cond.getOperand(0);
|
||||
|
||||
CC = Cond.getOperand(0);
|
||||
Cond = Cond.getOperand(1);
|
||||
// Make a copy as flag result cannot be used by more than one.
|
||||
Cond = DAG.getNode(CmpOpc, MVT::Flag,
|
||||
Cond.getOperand(0), Cond.getOperand(1));
|
||||
} else
|
||||
addTest = true;
|
||||
} else
|
||||
addTest = true;
|
||||
// If condition flag is set by a X86ISD::CMP, then make a copy of it
|
||||
// (since flag operand cannot be shared). Use it as the condition setting
|
||||
// operand in place of the X86ISD::SETCC.
|
||||
// If the X86ISD::SETCC has more than one use, then perhaps it's better
|
||||
// to use a test instead of duplicating the X86ISD::CMP (for register
|
||||
// pressure reason)?
|
||||
SDOperand Cmp = Cond.getOperand(1);
|
||||
unsigned Opc = Cmp.getOpcode();
|
||||
if (Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI) {
|
||||
SDOperand Ops[] = { Chain, Cmp.getOperand(1), Cmp.getOperand(2) };
|
||||
Cond = DAG.getNode(Opc, VTs, 2, Ops, 3);
|
||||
addTest = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (addTest) {
|
||||
CC = DAG.getConstant(X86ISD::COND_NE, MVT::i8);
|
||||
Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Cond,
|
||||
DAG.getConstant(0, MVT::i8));
|
||||
SDOperand Ops[] = { Chain, Cond, DAG.getConstant(0, MVT::i8) };
|
||||
Cond = DAG.getNode(X86ISD::CMP, VTs, 2, Ops, 3);
|
||||
}
|
||||
return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
|
||||
Op.getOperand(0), Op.getOperand(2), CC, Cond);
|
||||
Cond, Op.getOperand(2), CC, Cond.getValue(1));
|
||||
}
|
||||
|
||||
SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
|
||||
@ -4382,13 +4354,18 @@ X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG) {
|
||||
CC = ISD::SETNE;
|
||||
break;
|
||||
}
|
||||
|
||||
bool Flip;
|
||||
unsigned X86CC;
|
||||
translateX86CC(CC, true, X86CC, Flip);
|
||||
SDOperand Cond = DAG.getNode(Opc, MVT::Flag, Op.getOperand(Flip?2:1),
|
||||
Op.getOperand(Flip?1:2));
|
||||
SDOperand SetCC = DAG.getNode(X86ISD::SETCC, MVT::i8,
|
||||
DAG.getConstant(X86CC, MVT::i8), Cond);
|
||||
|
||||
const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
|
||||
SDOperand Ops1[] = { DAG.getEntryNode(), Op.getOperand(Flip?2:1),
|
||||
Op.getOperand(Flip?1:2) };
|
||||
SDOperand Cond = DAG.getNode(Opc, VTs, 2, Ops1, 3);
|
||||
VTs = DAG.getNodeValueTypes(MVT::i8, MVT::Flag);
|
||||
SDOperand Ops2[] = { DAG.getConstant(X86CC, MVT::i8), Cond };
|
||||
SDOperand SetCC = DAG.getNode(X86ISD::SETCC, VTs, 2, Ops2, 2);
|
||||
return DAG.getNode(ISD::ANY_EXTEND, MVT::i32, SetCC);
|
||||
}
|
||||
}
|
||||
@ -4414,7 +4391,7 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
|
||||
case ISD::FABS: return LowerFABS(Op, DAG);
|
||||
case ISD::FNEG: return LowerFNEG(Op, DAG);
|
||||
case ISD::SETCC: return LowerSETCC(Op, DAG);
|
||||
case ISD::SETCC: return LowerSETCC(Op, DAG, DAG.getEntryNode());
|
||||
case ISD::SELECT: return LowerSELECT(Op, DAG);
|
||||
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
|
||||
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
|
||||
|
@ -381,7 +381,7 @@ namespace llvm {
|
||||
SDOperand LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerFABS(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerFNEG(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerSETCC(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerSETCC(SDOperand Op, SelectionDAG &DAG, SDOperand Chain);
|
||||
SDOperand LowerSELECT(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerBRCOND(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerMEMSET(SDOperand Op, SelectionDAG &DAG);
|
||||
|
@ -51,7 +51,7 @@ def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
|
||||
def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
|
||||
|
||||
def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest,
|
||||
[SDNPOutFlag]>;
|
||||
[SDNPHasChain, SDNPOutFlag]>;
|
||||
|
||||
def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov,
|
||||
[SDNPInFlag, SDNPOutFlag]>;
|
||||
@ -2093,18 +2093,17 @@ def TEST32rr : I<0x85, MRMDestReg, (ops GR32:$src1, GR32:$src2),
|
||||
"test{l} {$src2, $src1|$src1, $src2}",
|
||||
[(X86cmp (and GR32:$src1, GR32:$src2), 0)]>;
|
||||
}
|
||||
// FIXME: These patterns are disabled until isel issue surrounding
|
||||
//CodeGen/X86/test-load-fold.ll is fixed.
|
||||
|
||||
def TEST8rm : I<0x84, MRMSrcMem, (ops GR8 :$src1, i8mem :$src2),
|
||||
"test{b} {$src2, $src1|$src1, $src2}",
|
||||
[/*(X86cmp (and GR8:$src1, (loadi8 addr:$src2)), 0)*/]>;
|
||||
[(X86cmp (and GR8:$src1, (loadi8 addr:$src2)), 0)]>;
|
||||
def TEST16rm : I<0x85, MRMSrcMem, (ops GR16:$src1, i16mem:$src2),
|
||||
"test{w} {$src2, $src1|$src1, $src2}",
|
||||
[/*(X86cmp (and GR16:$src1, (loadi16 addr:$src2)), 0)*/]>,
|
||||
[(X86cmp (and GR16:$src1, (loadi16 addr:$src2)), 0)]>,
|
||||
OpSize;
|
||||
def TEST32rm : I<0x85, MRMSrcMem, (ops GR32:$src1, i32mem:$src2),
|
||||
"test{l} {$src2, $src1|$src1, $src2}",
|
||||
[/*(X86cmp (and GR32:$src1, (loadi32 addr:$src2)), 0)*/]>;
|
||||
[(X86cmp (and GR32:$src1, (loadi32 addr:$src2)), 0)]>;
|
||||
|
||||
def TEST8ri : Ii8 <0xF6, MRM0r, // flags = GR8 & imm8
|
||||
(ops GR8:$src1, i8imm:$src2),
|
||||
@ -2118,21 +2117,20 @@ def TEST32ri : Ii32<0xF7, MRM0r, // flags = GR32 & imm32
|
||||
(ops GR32:$src1, i32imm:$src2),
|
||||
"test{l} {$src2, $src1|$src1, $src2}",
|
||||
[(X86cmp (and GR32:$src1, imm:$src2), 0)]>;
|
||||
// FIXME: These patterns are disabled until isel issue surrounding
|
||||
//CodeGen/X86/test-load-fold.ll is fixed.
|
||||
|
||||
def TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8
|
||||
(ops i8mem:$src1, i8imm:$src2),
|
||||
"test{b} {$src2, $src1|$src1, $src2}",
|
||||
[/*(X86cmp (and (loadi8 addr:$src1), imm:$src2), 0)*/]>;
|
||||
[(X86cmp (and (loadi8 addr:$src1), imm:$src2), 0)]>;
|
||||
def TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16
|
||||
(ops i16mem:$src1, i16imm:$src2),
|
||||
"test{w} {$src2, $src1|$src1, $src2}",
|
||||
[/*(X86cmp (and (loadi16 addr:$src1), imm:$src2), 0)*/]>,
|
||||
[(X86cmp (and (loadi16 addr:$src1), imm:$src2), 0)]>,
|
||||
OpSize;
|
||||
def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32
|
||||
(ops i32mem:$src1, i32imm:$src2),
|
||||
"test{l} {$src2, $src1|$src1, $src2}",
|
||||
[/*(X86cmp (and (loadi32 addr:$src1), imm:$src2), 0)*/]>;
|
||||
[(X86cmp (and (loadi32 addr:$src1), imm:$src2), 0)]>;
|
||||
|
||||
|
||||
// Condition code ops, incl. set if equal/not equal/...
|
||||
|
@ -26,9 +26,9 @@ def X86fand : SDNode<"X86ISD::FAND", SDTFPBinOp,
|
||||
def X86fxor : SDNode<"X86ISD::FXOR", SDTFPBinOp,
|
||||
[SDNPCommutative, SDNPAssociative]>;
|
||||
def X86comi : SDNode<"X86ISD::COMI", SDTX86CmpTest,
|
||||
[SDNPOutFlag]>;
|
||||
[SDNPHasChain, SDNPOutFlag]>;
|
||||
def X86ucomi : SDNode<"X86ISD::UCOMI", SDTX86CmpTest,
|
||||
[SDNPOutFlag]>;
|
||||
[SDNPHasChain, SDNPOutFlag]>;
|
||||
def X86s2vec : SDNode<"X86ISD::S2VEC",
|
||||
SDTypeProfile<1, 1, []>, []>;
|
||||
def X86pextrw : SDNode<"X86ISD::PEXTRW",
|
||||
|
@ -711,14 +711,13 @@ def TEST64rr : RI<0x85, MRMDestReg, (ops GR64:$src1, GR64:$src2),
|
||||
[(X86cmp (and GR64:$src1, GR64:$src2), 0)]>;
|
||||
def TEST64rm : RI<0x85, MRMSrcMem, (ops GR64:$src1, i64mem:$src2),
|
||||
"test{q} {$src2, $src1|$src1, $src2}",
|
||||
[/*(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0)*/]>;
|
||||
[(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0)]>;
|
||||
def TEST64ri32 : RIi32<0xF7, MRM0r, (ops GR64:$src1, i64i32imm:$src2),
|
||||
"test{q} {$src2, $src1|$src1, $src2}",
|
||||
[(X86cmp (and GR64:$src1, i64immSExt32:$src2), 0)]>;
|
||||
def TEST64mi32 : RIi32<0xF7, MRM0m, (ops i64mem:$src1, i64i32imm:$src2),
|
||||
"test{q} {$src2, $src1|$src1, $src2}",
|
||||
[/*(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2),
|
||||
0)*/]>;
|
||||
[(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2), 0)]>;
|
||||
|
||||
def CMP64rr : RI<0x39, MRMDestReg, (ops GR64:$src1, GR64:$src2),
|
||||
"cmp{q} {$src2, $src1|$src1, $src2}",
|
||||
|
Loading…
Reference in New Issue
Block a user