mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-18 18:32:32 +00:00
Revert 72707 and 72709, for the moment.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72712 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5d16396a33
commit
874ae251c3
@ -324,14 +324,6 @@ public:
|
||||
return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
|
||||
getRegister(Reg, N.getValueType()), N);
|
||||
}
|
||||
// This version of getCopyToReg has the register (and its type) as an
|
||||
// explicit output.
|
||||
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, MVT VT, unsigned Reg,
|
||||
SDValue N) {
|
||||
SDVTList VTs = getVTList(MVT::Other, VT);
|
||||
SDValue Ops[] = { Chain, getRegister(Reg, VT), N};
|
||||
return getNode(ISD::CopyToReg, dl, VTs, Ops, 3);
|
||||
}
|
||||
|
||||
// This version of the getCopyToReg method takes an extra operand, which
|
||||
// indicates that there is potentially an incoming flag value (if Flag is not
|
||||
|
@ -242,11 +242,14 @@ namespace ISD {
|
||||
// remainder result.
|
||||
SDIVREM, UDIVREM,
|
||||
|
||||
// CARRY_FALSE - This node is used when folding other nodes,
|
||||
// like ADDC/SUBC, which indicate the carry result is always false.
|
||||
CARRY_FALSE,
|
||||
|
||||
// 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 (type i1 or whatever it got expanded to
|
||||
// for the target, value 0 or 1).
|
||||
// result is the carry flag result.
|
||||
ADDC, SUBC,
|
||||
|
||||
// Carry-using nodes for multiple precision addition and subtraction. These
|
||||
@ -255,8 +258,7 @@ namespace ISD {
|
||||
// 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. The carry flag (input and output) has type i1 or whatever it
|
||||
// got expanded to for the target, and has value 0 or 1.
|
||||
// values.
|
||||
ADDE, SUBE,
|
||||
|
||||
// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
|
||||
|
@ -326,11 +326,6 @@ class InstrInfo {
|
||||
// Sparc manual specifies its instructions in the format [31..0] (big), while
|
||||
// PowerPC specifies them using the format [0..31] (little).
|
||||
bit isLittleEndianEncoding = 0;
|
||||
|
||||
// Targets that can support the HasI1 argument on ADDC and ADDE, rather than
|
||||
// Flag, have this bit set. This is transitional and should go away when all
|
||||
// targets have been switched over.
|
||||
bit supportsHasI1 = 0;
|
||||
}
|
||||
|
||||
// Standard Instructions.
|
||||
|
@ -216,8 +216,6 @@ def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'.
|
||||
def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'.
|
||||
def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'.
|
||||
def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand
|
||||
def SDNPInI1 : SDNodeProperty; // Read an extra I1 operand
|
||||
def SDNPOutI1 : SDNodeProperty; // Write an extra I1 result
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Selection DAG Node definitions.
|
||||
@ -291,13 +289,13 @@ def or : SDNode<"ISD::OR" , SDTIntBinOp,
|
||||
def xor : SDNode<"ISD::XOR" , SDTIntBinOp,
|
||||
[SDNPCommutative, SDNPAssociative]>;
|
||||
def addc : SDNode<"ISD::ADDC" , SDTIntBinOp,
|
||||
[SDNPCommutative, SDNPOutI1]>;
|
||||
[SDNPCommutative, SDNPOutFlag]>;
|
||||
def adde : SDNode<"ISD::ADDE" , SDTIntBinOp,
|
||||
[SDNPCommutative, SDNPInI1, SDNPOutI1]>;
|
||||
[SDNPCommutative, SDNPOutFlag, SDNPInFlag]>;
|
||||
def subc : SDNode<"ISD::SUBC" , SDTIntBinOp,
|
||||
[SDNPOutI1]>;
|
||||
[SDNPOutFlag]>;
|
||||
def sube : SDNode<"ISD::SUBE" , SDTIntBinOp,
|
||||
[SDNPInI1, SDNPOutI1]>;
|
||||
[SDNPOutFlag, SDNPInFlag]>;
|
||||
|
||||
def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
|
||||
def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>;
|
||||
|
@ -1085,7 +1085,8 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
|
||||
// If the flag result is dead, turn this into an ADD.
|
||||
if (N->hasNUsesOfValue(0, 1))
|
||||
return CombineTo(N, DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N1, N0),
|
||||
DAG.getConstant(0, N->getValueType(1)));
|
||||
DAG.getNode(ISD::CARRY_FALSE,
|
||||
N->getDebugLoc(), MVT::Flag));
|
||||
|
||||
// canonicalize constant to RHS.
|
||||
if (N0C && !N1C)
|
||||
@ -1093,9 +1094,10 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
|
||||
|
||||
// fold (addc x, 0) -> x + no carry out
|
||||
if (N1C && N1C->isNullValue())
|
||||
return CombineTo(N, N0, DAG.getConstant(0, N1.getValueType()));
|
||||
return CombineTo(N, N0, DAG.getNode(ISD::CARRY_FALSE,
|
||||
N->getDebugLoc(), MVT::Flag));
|
||||
|
||||
// fold (addc a, b) -> (or a, b), 0 iff a and b share no bits.
|
||||
// fold (addc a, b) -> (or a, b), CARRY_FALSE iff a and b share no bits.
|
||||
APInt LHSZero, LHSOne;
|
||||
APInt RHSZero, RHSOne;
|
||||
APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits());
|
||||
@ -1109,7 +1111,8 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
|
||||
if ((RHSZero & (~LHSZero & Mask)) == (~LHSZero & Mask) ||
|
||||
(LHSZero & (~RHSZero & Mask)) == (~RHSZero & Mask))
|
||||
return CombineTo(N, DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N1),
|
||||
DAG.getConstant(0, N1.getValueType()));
|
||||
DAG.getNode(ISD::CARRY_FALSE,
|
||||
N->getDebugLoc(), MVT::Flag));
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
@ -1128,9 +1131,8 @@ SDValue DAGCombiner::visitADDE(SDNode *N) {
|
||||
N1, N0, CarryIn);
|
||||
|
||||
// fold (adde x, y, false) -> (addc x, y)
|
||||
if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(CarryIn))
|
||||
if (N2C->getAPIntValue()==0)
|
||||
return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(), N1, N0);
|
||||
if (CarryIn.getOpcode() == ISD::CARRY_FALSE)
|
||||
return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(), N1, N0);
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
@ -98,10 +98,6 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
|
||||
case ISD::USUBO: Res = PromoteIntRes_UADDSUBO(N, ResNo); break;
|
||||
case ISD::SMULO:
|
||||
case ISD::UMULO: Res = PromoteIntRes_XMULO(N, ResNo); break;
|
||||
case ISD::ADDC:
|
||||
case ISD::SUBC: Res = PromoteIntRes_ADDSUBC(N, ResNo); break;
|
||||
case ISD::ADDE:
|
||||
case ISD::SUBE: Res = PromoteIntRes_ADDSUBE(N, ResNo); break;
|
||||
|
||||
case ISD::ATOMIC_LOAD_ADD:
|
||||
case ISD::ATOMIC_LOAD_SUB:
|
||||
@ -125,35 +121,6 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
|
||||
SetPromotedInteger(SDValue(N, ResNo), Res);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBC(SDNode *N, unsigned ResNo) {
|
||||
// Only the carry bit result is expected to be promoted.
|
||||
assert(ResNo == 1 && "Only carry bit result promotion currently supported!");
|
||||
return PromoteIntRes_Overflow(N);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBE(SDNode *N, unsigned ResNo) {
|
||||
// Only the carry bit result is expected to be promoted.
|
||||
assert(ResNo == 1 && "Only carry bit result promotion currently supported!");
|
||||
// This is a ternary operator, so clone a slightly modified
|
||||
// PromoteIntRes_Overflow here (this is the only client).
|
||||
if (ResNo == 1) {
|
||||
// Simply change the return type of the boolean result.
|
||||
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
|
||||
MVT ValueVTs[] = { N->getValueType(0), NVT };
|
||||
SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2) };
|
||||
SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(),
|
||||
DAG.getVTList(ValueVTs, 2), Ops, 3);
|
||||
|
||||
// Modified the sum result - switch anything that used the old sum to use
|
||||
// the new one.
|
||||
ReplaceValueWith(SDValue(N, 0), Res);
|
||||
|
||||
return SDValue(Res.getNode(), 1);
|
||||
}
|
||||
assert(0 && "Do not know how to promote this operator!");
|
||||
abort();
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) {
|
||||
// Sign-extend the new bits, and continue the assertion.
|
||||
SDValue Op = SExtPromotedInteger(N->getOperand(0));
|
||||
@ -452,7 +419,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
|
||||
return Res;
|
||||
}
|
||||
|
||||
/// Promote the overflow or carry result of an overflowing arithmetic node.
|
||||
/// Promote the overflow flag of an overflowing arithmetic node.
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
|
||||
// Simply change the return type of the boolean result.
|
||||
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
|
||||
@ -699,8 +666,6 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
|
||||
assert(0 && "Do not know how to promote this operator's operand!");
|
||||
abort();
|
||||
|
||||
case ISD::ADDE:
|
||||
case ISD::SUBE: Res = PromoteIntOp_ADDSUBE(N, OpNo); break;
|
||||
case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break;
|
||||
case ISD::BIT_CONVERT: Res = PromoteIntOp_BIT_CONVERT(N); break;
|
||||
case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break;
|
||||
@ -778,13 +743,6 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS,
|
||||
}
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntOp_ADDSUBE(SDNode *N, unsigned OpNo) {
|
||||
assert(OpNo == 2 && "Don't know how to promote this operand!");
|
||||
return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
|
||||
N->getOperand(1),
|
||||
GetPromotedInteger(N->getOperand(2)));
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
|
||||
SDValue Op = GetPromotedInteger(N->getOperand(0));
|
||||
return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op);
|
||||
@ -1105,7 +1063,7 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
|
||||
TLI.isOperationLegalOrCustom(ISD::ADDC,
|
||||
TLI.getTypeToExpandTo(NVT))) {
|
||||
// Emit this X << 1 as X+X.
|
||||
SDVTList VTList = DAG.getVTList(NVT, MVT::i1);
|
||||
SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
|
||||
SDValue LoOps[2] = { InL, InL };
|
||||
Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
|
||||
SDValue HiOps[3] = { InH, InH, Lo.getValue(1) };
|
||||
@ -1341,7 +1299,7 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
|
||||
TLI.getTypeToExpandTo(NVT));
|
||||
|
||||
if (hasCarry) {
|
||||
SDVTList VTList = DAG.getVTList(NVT, MVT::i1);
|
||||
SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
|
||||
if (N->getOpcode() == ISD::ADD) {
|
||||
Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
|
||||
HiOps[2] = Lo.getValue(1);
|
||||
@ -1386,7 +1344,7 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
|
||||
GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
|
||||
SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::i1);
|
||||
SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
|
||||
SDValue LoOps[2] = { LHSL, RHSL };
|
||||
SDValue HiOps[3] = { LHSH, RHSH };
|
||||
|
||||
@ -1400,8 +1358,8 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
|
||||
Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
|
||||
}
|
||||
|
||||
// Legalized the second result (carry bit) - switch anything that used the
|
||||
// result to use the new one.
|
||||
// Legalized the flag result - switch anything that used the old flag to
|
||||
// use the new one.
|
||||
ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
|
||||
}
|
||||
|
||||
@ -1412,7 +1370,7 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
|
||||
GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
|
||||
SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::i1);
|
||||
SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
|
||||
SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
|
||||
SDValue HiOps[3] = { LHSH, RHSH };
|
||||
|
||||
@ -1420,8 +1378,8 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
|
||||
HiOps[2] = Lo.getValue(1);
|
||||
Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3);
|
||||
|
||||
// Legalized the second result (carry bit) - switch anything that used the
|
||||
// result to use the new one.
|
||||
// Legalized the flag result - switch anything that used the old flag to
|
||||
// use the new one.
|
||||
ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
|
||||
}
|
||||
|
||||
|
@ -242,8 +242,6 @@ private:
|
||||
|
||||
// Integer Result Promotion.
|
||||
void PromoteIntegerResult(SDNode *N, unsigned ResNo);
|
||||
SDValue PromoteIntRes_ADDSUBC(SDNode *N, unsigned ResNo);
|
||||
SDValue PromoteIntRes_ADDSUBE(SDNode *N, unsigned ResNo);
|
||||
SDValue PromoteIntRes_AssertSext(SDNode *N);
|
||||
SDValue PromoteIntRes_AssertZext(SDNode *N);
|
||||
SDValue PromoteIntRes_Atomic1(AtomicSDNode *N);
|
||||
@ -280,7 +278,6 @@ private:
|
||||
|
||||
// Integer Operand Promotion.
|
||||
bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo);
|
||||
SDValue PromoteIntOp_ADDSUBE(SDNode *N, unsigned OpNo);
|
||||
SDValue PromoteIntOp_ANY_EXTEND(SDNode *N);
|
||||
SDValue PromoteIntOp_BIT_CONVERT(SDNode *N);
|
||||
SDValue PromoteIntOp_BUILD_PAIR(SDNode *N);
|
||||
|
@ -268,13 +268,6 @@ unsigned ScheduleDAGSDNodes::ComputeMemOperandsEnd(SDNode *Node) {
|
||||
unsigned N = Node->getNumOperands();
|
||||
while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
|
||||
--N;
|
||||
// Skip hard registers set as a side effect (i.e. not result 0).
|
||||
while (N && Node->getOperand(N - 1).getOpcode() == ISD::CopyToReg &&
|
||||
Node->getOperand(N-1).getResNo() != 0 &&
|
||||
!TargetRegisterInfo::isVirtualRegister(
|
||||
dyn_cast<RegisterSDNode>(Node->getOperand(N-1).getOperand(1))
|
||||
->getReg()))
|
||||
--N;
|
||||
if (N && Node->getOperand(N - 1).getValueType() == MVT::Other)
|
||||
--N; // Ignore chain if it exists.
|
||||
return N;
|
||||
|
@ -5257,6 +5257,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
case ISD::EXTRACT_SUBVECTOR: return "extract_subvector";
|
||||
case ISD::SCALAR_TO_VECTOR: return "scalar_to_vector";
|
||||
case ISD::VECTOR_SHUFFLE: return "vector_shuffle";
|
||||
case ISD::CARRY_FALSE: return "carry_false";
|
||||
case ISD::ADDC: return "addc";
|
||||
case ISD::ADDE: return "adde";
|
||||
case ISD::SADDO: return "saddo";
|
||||
|
@ -151,8 +151,6 @@ def X86InstrInfo : InstrInfo {
|
||||
19,
|
||||
20,
|
||||
24];
|
||||
|
||||
let supportsHasI1 = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -190,28 +190,6 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
|
||||
setOperationAction(ISD::BIT_CONVERT , MVT::i32 , Expand);
|
||||
}
|
||||
|
||||
// ADDE and SUBE are lowered to local versions that contain EFLAGS explicitly.
|
||||
// ADDC and SUBC are lowered to local versions so EFLAGS will be an i32
|
||||
// rather than the Flag used by the generic patterns.
|
||||
setOperationAction(ISD::ADDC , MVT::i8 , Custom);
|
||||
setOperationAction(ISD::ADDC , MVT::i16 , Custom);
|
||||
setOperationAction(ISD::ADDC , MVT::i32 , Custom);
|
||||
setOperationAction(ISD::SUBC , MVT::i8 , Custom);
|
||||
setOperationAction(ISD::SUBC , MVT::i16 , Custom);
|
||||
setOperationAction(ISD::SUBC , MVT::i32 , Custom);
|
||||
setOperationAction(ISD::ADDE , MVT::i8 , Custom);
|
||||
setOperationAction(ISD::ADDE , MVT::i16 , Custom);
|
||||
setOperationAction(ISD::ADDE , MVT::i32 , Custom);
|
||||
setOperationAction(ISD::SUBE , MVT::i8 , Custom);
|
||||
setOperationAction(ISD::SUBE , MVT::i16 , Custom);
|
||||
setOperationAction(ISD::SUBE , MVT::i32 , Custom);
|
||||
if (Subtarget->is64Bit()) {
|
||||
setOperationAction(ISD::ADDC , MVT::i64 , Custom);
|
||||
setOperationAction(ISD::SUBC , MVT::i64 , Custom);
|
||||
setOperationAction(ISD::ADDE , MVT::i64 , Custom);
|
||||
setOperationAction(ISD::SUBE , MVT::i64 , Custom);
|
||||
}
|
||||
|
||||
// Scalar integer divide and remainder are lowered to use operations that
|
||||
// produce two results, to match the available instructions. This exposes
|
||||
// the two-result form to trivial CSE, which is able to combine x/y and x%y
|
||||
@ -6497,21 +6475,6 @@ SDValue X86TargetLowering::LowerXALUO(SDValue Op, SelectionDAG &DAG) {
|
||||
return Sum;
|
||||
}
|
||||
|
||||
SDValue X86TargetLowering::LowerADDSUBE(SDValue Op, SelectionDAG &DAG) {
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
|
||||
return DAG.getNode(Op.getOpcode()==ISD::ADDE ? X86ISD::ADDE : X86ISD::SUBE,
|
||||
dl, VTs, Op.getOperand(0), Op.getOperand(1),
|
||||
Op.getOperand(2).getValue(1));
|
||||
}
|
||||
|
||||
SDValue X86TargetLowering::LowerADDSUBC(SDValue Op, SelectionDAG &DAG) {
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
|
||||
return DAG.getNode(Op.getOpcode()==ISD::ADDC ? X86ISD::ADD : X86ISD::SUB,
|
||||
dl, VTs, Op.getOperand(0), Op.getOperand(1));
|
||||
}
|
||||
|
||||
SDValue X86TargetLowering::LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG) {
|
||||
MVT T = Op.getValueType();
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
@ -6580,10 +6543,6 @@ SDValue X86TargetLowering::LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG) {
|
||||
SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||
switch (Op.getOpcode()) {
|
||||
default: assert(0 && "Should not custom lower this!");
|
||||
case ISD::ADDC:
|
||||
case ISD::SUBC: return LowerADDSUBC(Op,DAG);
|
||||
case ISD::ADDE:
|
||||
case ISD::SUBE: return LowerADDSUBE(Op,DAG);
|
||||
case ISD::ATOMIC_CMP_SWAP: return LowerCMP_SWAP(Op,DAG);
|
||||
case ISD::ATOMIC_LOAD_SUB: return LowerLOAD_SUB(Op,DAG);
|
||||
case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);
|
||||
@ -6832,10 +6791,6 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case X86ISD::INC: return "X86ISD::INC";
|
||||
case X86ISD::DEC: return "X86ISD::DEC";
|
||||
case X86ISD::MUL_IMM: return "X86ISD::MUL_IMM";
|
||||
case X86ISD::ADDE: return "X86ISD::ADDE";
|
||||
case X86ISD::SUBE: return "X86ISD::SUBE";
|
||||
case X86ISD::ADDC: return "X86ISD::ADDC";
|
||||
case X86ISD::SUBC: return "X86ISD::SUBC";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,14 +243,6 @@ namespace llvm {
|
||||
ADD, SUB, SMUL, UMUL,
|
||||
INC, DEC,
|
||||
|
||||
// ADDC, SUBC - Arithmetic operations setting carry bit. The normal
|
||||
// arithmetic operations do this, but they represent it as Flag, and
|
||||
// we want the i32 EFLAGS register here.
|
||||
ADDC, SUBC,
|
||||
|
||||
// ADDE, SUBE - Arithmetic operations with extra FLAGS (EFLAGS) inputs.
|
||||
ADDE, SUBE,
|
||||
|
||||
// MUL_IMM - X86 specific multiply by immediate.
|
||||
MUL_IMM
|
||||
};
|
||||
@ -584,9 +576,7 @@ namespace llvm {
|
||||
|
||||
std::pair<SDValue,SDValue> FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG,
|
||||
bool isSigned);
|
||||
|
||||
SDValue LowerADDSUBC(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerADDSUBE(SDValue Op, SelectionDAG &DAG);
|
||||
|
||||
SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG);
|
||||
|
@ -383,52 +383,31 @@ def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2),
|
||||
let Uses = [EFLAGS] in {
|
||||
let isTwoAddress = 1 in {
|
||||
let isCommutable = 1 in
|
||||
def ADC64rr : RI<0x11, MRMDestReg, (outs GR64:$dst),
|
||||
(ins GR64:$src1, GR64:$src2),
|
||||
def ADC64rr : RI<0x11, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
|
||||
"adc{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR64:$dst,
|
||||
(X86adde_flag GR64:$src1, GR64:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>;
|
||||
|
||||
def ADC64rm : RI<0x13, MRMSrcMem , (outs GR64:$dst),
|
||||
(ins GR64:$src1, i64mem:$src2),
|
||||
def ADC64rm : RI<0x13, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
|
||||
"adc{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR64:$dst,
|
||||
(X86adde_flag GR64:$src1, (load addr:$src2), EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR64:$dst, (adde GR64:$src1, (load addr:$src2)))]>;
|
||||
|
||||
def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst),
|
||||
(ins GR64:$src1, i64i8imm:$src2),
|
||||
def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
|
||||
"adc{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR64:$dst,
|
||||
(X86adde_flag GR64:$src1, i64immSExt8:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst),
|
||||
(ins GR64:$src1, i64i32imm:$src2),
|
||||
[(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2))]>;
|
||||
def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
|
||||
"adc{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR64:$dst,
|
||||
(X86adde_flag GR64:$src1, i64immSExt32:$src2,
|
||||
EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2))]>;
|
||||
} // isTwoAddress
|
||||
|
||||
def ADC64mr : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
|
||||
"adc{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (load addr:$dst), GR64:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>;
|
||||
def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
|
||||
"adc{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (load addr:$dst), i64immSExt8:$src2,
|
||||
EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
|
||||
def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
|
||||
"adc{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (load addr:$dst), i64immSExt8:$src2,
|
||||
EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
|
||||
} // Uses = [EFLAGS]
|
||||
|
||||
let isTwoAddress = 1 in {
|
||||
@ -477,52 +456,31 @@ def SUB64mi32 : RIi32<0x81, MRM5m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
|
||||
|
||||
let Uses = [EFLAGS] in {
|
||||
let isTwoAddress = 1 in {
|
||||
def SBB64rr : RI<0x19, MRMDestReg, (outs GR64:$dst),
|
||||
(ins GR64:$src1, GR64:$src2),
|
||||
def SBB64rr : RI<0x19, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
|
||||
"sbb{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR64:$dst,
|
||||
(X86sube_flag GR64:$src1, GR64:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR64:$dst, (sube GR64:$src1, GR64:$src2))]>;
|
||||
|
||||
def SBB64rm : RI<0x1B, MRMSrcMem, (outs GR64:$dst),
|
||||
(ins GR64:$src1, i64mem:$src2),
|
||||
def SBB64rm : RI<0x1B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
|
||||
"sbb{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR64:$dst,
|
||||
(X86sube_flag GR64:$src1, (load addr:$src2), EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR64:$dst, (sube GR64:$src1, (load addr:$src2)))]>;
|
||||
|
||||
def SBB64ri8 : RIi8<0x83, MRM3r, (outs GR64:$dst),
|
||||
(ins GR64:$src1, i64i8imm:$src2),
|
||||
def SBB64ri8 : RIi8<0x83, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
|
||||
"sbb{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR64:$dst,
|
||||
(X86sube_flag GR64:$src1, i64immSExt8:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst),
|
||||
(ins GR64:$src1, i64i32imm:$src2),
|
||||
[(set GR64:$dst, (sube GR64:$src1, i64immSExt8:$src2))]>;
|
||||
def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
|
||||
"sbb{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR64:$dst,
|
||||
(X86sube_flag GR64:$src1, i64immSExt32:$src2,
|
||||
EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR64:$dst, (sube GR64:$src1, i64immSExt32:$src2))]>;
|
||||
} // isTwoAddress
|
||||
|
||||
def SBB64mr : RI<0x19, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
|
||||
"sbb{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (load addr:$dst), GR64:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (sube (load addr:$dst), GR64:$src2), addr:$dst)]>;
|
||||
def SBB64mi8 : RIi8<0x83, MRM3m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
|
||||
"sbb{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (load addr:$dst), i64immSExt8:$src2,
|
||||
EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (sube (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
|
||||
def SBB64mi32 : RIi32<0x81, MRM3m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
|
||||
"sbb{q}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (load addr:$dst), i64immSExt32:$src2,
|
||||
EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (sube (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>;
|
||||
} // Uses = [EFLAGS]
|
||||
} // Defs = [EFLAGS]
|
||||
|
||||
|
@ -34,11 +34,6 @@ def SDTBinaryArithWithFlags : SDTypeProfile<1, 2,
|
||||
[SDTCisSameAs<0, 1>,
|
||||
SDTCisSameAs<0, 2>,
|
||||
SDTCisInt<0>]>;
|
||||
// Unary and binary operators that both read and write EFLAGS as a side-effect.
|
||||
def SDTBinaryArithRWFlags : SDTypeProfile<1, 3,
|
||||
[SDTCisInt<0>, SDTCisSameAs<0, 1>,
|
||||
SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>;
|
||||
|
||||
def SDTX86BrCond : SDTypeProfile<0, 3,
|
||||
[SDTCisVT<0, OtherVT>,
|
||||
SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
|
||||
@ -161,8 +156,6 @@ def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags>;
|
||||
def X86umul_flag : SDNode<"X86ISD::UMUL", SDTUnaryArithWithFlags>;
|
||||
def X86inc_flag : SDNode<"X86ISD::INC", SDTUnaryArithWithFlags>;
|
||||
def X86dec_flag : SDNode<"X86ISD::DEC", SDTUnaryArithWithFlags>;
|
||||
def X86adde_flag : SDNode<"X86ISD::ADDE", SDTBinaryArithRWFlags, [SDNPInI1]>;
|
||||
def X86sube_flag : SDNode<"X86ISD::SUBE", SDTBinaryArithRWFlags, [SDNPInI1]>;
|
||||
|
||||
def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
|
||||
|
||||
@ -2281,127 +2274,81 @@ let isTwoAddress = 0 in {
|
||||
|
||||
let Uses = [EFLAGS] in {
|
||||
let isCommutable = 1 in { // X = ADC Y, Z --> X = ADC Z, Y
|
||||
def ADC8rr : I<0x10, MRMDestReg, (outs GR8:$dst),
|
||||
(ins GR8:$src1, GR8:$src2),
|
||||
def ADC8rr : I<0x10, MRMDestReg, (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
|
||||
"adc{b}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR8:$dst, (X86adde_flag GR8:$src1, GR8:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR8:$dst, (adde GR8:$src1, GR8:$src2))]>;
|
||||
def ADC16rr : I<0x11, MRMDestReg, (outs GR16:$dst),
|
||||
(ins GR16:$src1, GR16:$src2),
|
||||
"adc{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR16:$dst,
|
||||
(X86adde_flag GR16:$src1, GR16:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>,
|
||||
OpSize;
|
||||
[(set GR16:$dst, (adde GR16:$src1, GR16:$src2))]>, OpSize;
|
||||
def ADC32rr : I<0x11, MRMDestReg, (outs GR32:$dst),
|
||||
(ins GR32:$src1, GR32:$src2),
|
||||
"adc{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR32:$dst,
|
||||
(X86adde_flag GR32:$src1, GR32:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR32:$dst, (adde GR32:$src1, GR32:$src2))]>;
|
||||
}
|
||||
def ADC8rm : I<0x12, MRMSrcMem , (outs GR8:$dst),
|
||||
(ins GR8:$src1, i8mem:$src2),
|
||||
"adc{b}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR8:$dst,
|
||||
(X86adde_flag GR8:$src1, (load addr:$src2), EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR8:$dst, (adde GR8:$src1, (load addr:$src2)))]>;
|
||||
def ADC16rm : I<0x13, MRMSrcMem , (outs GR16:$dst),
|
||||
(ins GR16:$src1, i16mem:$src2),
|
||||
"adc{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR16:$dst,
|
||||
(X86adde_flag GR16:$src1, (load addr:$src2), EFLAGS)),
|
||||
(implicit EFLAGS)]>,
|
||||
[(set GR16:$dst, (adde GR16:$src1, (load addr:$src2)))]>,
|
||||
OpSize;
|
||||
def ADC32rm : I<0x13, MRMSrcMem , (outs GR32:$dst),
|
||||
(ins GR32:$src1, i32mem:$src2),
|
||||
"adc{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR32:$dst,
|
||||
(X86adde_flag GR32:$src1, (load addr:$src2), EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
def ADC8ri : Ii8<0x80, MRM2r, (outs GR8:$dst),
|
||||
(ins GR8:$src1, i8imm:$src2),
|
||||
[(set GR32:$dst, (adde GR32:$src1, (load addr:$src2)))]>;
|
||||
def ADC8ri : Ii8<0x80, MRM2r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
|
||||
"adc{b}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR8:$dst,
|
||||
(X86adde_flag GR8:$src1, imm:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR8:$dst, (adde GR8:$src1, imm:$src2))]>;
|
||||
def ADC16ri : Ii16<0x81, MRM2r, (outs GR16:$dst),
|
||||
(ins GR16:$src1, i16imm:$src2),
|
||||
"adc{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR16:$dst,
|
||||
(X86adde_flag GR16:$src1, imm:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>, OpSize;
|
||||
[(set GR16:$dst, (adde GR16:$src1, imm:$src2))]>, OpSize;
|
||||
def ADC16ri8 : Ii8<0x83, MRM2r, (outs GR16:$dst),
|
||||
(ins GR16:$src1, i16i8imm:$src2),
|
||||
"adc{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR16:$dst,
|
||||
(X86adde_flag GR16:$src1, i16immSExt8:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>, OpSize;
|
||||
[(set GR16:$dst, (adde GR16:$src1, i16immSExt8:$src2))]>,
|
||||
OpSize;
|
||||
def ADC32ri : Ii32<0x81, MRM2r, (outs GR32:$dst),
|
||||
(ins GR32:$src1, i32imm:$src2),
|
||||
"adc{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR32:$dst,
|
||||
(X86adde_flag GR32:$src1, imm:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR32:$dst, (adde GR32:$src1, imm:$src2))]>;
|
||||
def ADC32ri8 : Ii8<0x83, MRM2r, (outs GR32:$dst),
|
||||
(ins GR32:$src1, i32i8imm:$src2),
|
||||
"adc{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR32:$dst,
|
||||
(X86adde_flag GR32:$src1, i32immSExt8:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR32:$dst, (adde GR32:$src1, i32immSExt8:$src2))]>;
|
||||
|
||||
let isTwoAddress = 0 in {
|
||||
def ADC8mr : I<0x10, MRMDestMem, (outs),
|
||||
(ins i8mem:$dst, GR8:$src2),
|
||||
def ADC8mr : I<0x10, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src2),
|
||||
"adc{b}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (load addr:$dst), GR8:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
def ADC16mr : I<0x11, MRMDestMem, (outs),
|
||||
(ins i16mem:$dst, GR16:$src2),
|
||||
[(store (adde (load addr:$dst), GR8:$src2), addr:$dst)]>;
|
||||
def ADC16mr : I<0x11, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
|
||||
"adc{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (load addr:$dst), GR16:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>, OpSize;
|
||||
def ADC32mr : I<0x11, MRMDestMem, (outs),
|
||||
(ins i32mem:$dst, GR32:$src2),
|
||||
[(store (adde (load addr:$dst), GR16:$src2), addr:$dst)]>,
|
||||
OpSize;
|
||||
def ADC32mr : I<0x11, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
|
||||
"adc{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (load addr:$dst), GR32:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
def ADC8mi : Ii8<0x80, MRM2m, (outs),
|
||||
(ins i8mem:$dst, i8imm:$src2),
|
||||
[(store (adde (load addr:$dst), GR32:$src2), addr:$dst)]>;
|
||||
def ADC8mi : Ii8<0x80, MRM2m, (outs), (ins i8mem:$dst, i8imm:$src2),
|
||||
"adc{b}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (loadi8 addr:$dst), imm:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
def ADC16mi : Ii16<0x81, MRM2m, (outs),
|
||||
(ins i16mem:$dst, i16imm:$src2),
|
||||
[(store (adde (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
|
||||
def ADC16mi : Ii16<0x81, MRM2m, (outs), (ins i16mem:$dst, i16imm:$src2),
|
||||
"adc{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (loadi16 addr:$dst), imm:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>, OpSize;
|
||||
def ADC16mi8 : Ii8<0x83, MRM2m, (outs),
|
||||
(ins i16mem:$dst, i16i8imm :$src2),
|
||||
[(store (adde (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
|
||||
OpSize;
|
||||
def ADC16mi8 : Ii8<0x83, MRM2m, (outs), (ins i16mem:$dst, i16i8imm :$src2),
|
||||
"adc{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (load addr:$dst), i16immSExt8:$src2,
|
||||
EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>, OpSize;
|
||||
def ADC32mi : Ii32<0x81, MRM2m, (outs),
|
||||
(ins i32mem:$dst, i32imm:$src2),
|
||||
[(store (adde (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
|
||||
OpSize;
|
||||
def ADC32mi : Ii32<0x81, MRM2m, (outs), (ins i32mem:$dst, i32imm:$src2),
|
||||
"adc{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (loadi32 addr:$dst), imm:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
def ADC32mi8 : Ii8<0x83, MRM2m, (outs),
|
||||
(ins i32mem:$dst, i32i8imm:$src2),
|
||||
[(store (adde (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
|
||||
def ADC32mi8 : Ii8<0x83, MRM2m, (outs), (ins i32mem:$dst, i32i8imm :$src2),
|
||||
"adc{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86adde_flag (load addr:$dst), i32immSExt8:$src2,
|
||||
EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
}
|
||||
[(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
|
||||
}
|
||||
} // Uses = [EFLAGS]
|
||||
|
||||
// Register-Register Subtraction
|
||||
@ -2506,115 +2453,77 @@ let Uses = [EFLAGS] in {
|
||||
def SBB8rr : I<0x18, MRMDestReg, (outs GR8:$dst),
|
||||
(ins GR8:$src1, GR8:$src2),
|
||||
"sbb{b}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR8:$dst, (X86sube_flag GR8:$src1, GR8:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR8:$dst, (sube GR8:$src1, GR8:$src2))]>;
|
||||
def SBB16rr : I<0x19, MRMDestReg, (outs GR16:$dst),
|
||||
(ins GR16:$src1, GR16:$src2),
|
||||
"sbb{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR16:$dst,
|
||||
(X86sube_flag GR16:$src1, GR16:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>, OpSize;
|
||||
[(set GR16:$dst, (sube GR16:$src1, GR16:$src2))]>, OpSize;
|
||||
def SBB32rr : I<0x19, MRMDestReg, (outs GR32:$dst),
|
||||
(ins GR32:$src1, GR32:$src2),
|
||||
"sbb{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR32:$dst,
|
||||
(X86sube_flag GR32:$src1, GR32:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR32:$dst, (sube GR32:$src1, GR32:$src2))]>;
|
||||
|
||||
let isTwoAddress = 0 in {
|
||||
def SBB8mr : I<0x18, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src2),
|
||||
"sbb{b}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (load addr:$dst), GR8:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (sube (load addr:$dst), GR8:$src2), addr:$dst)]>;
|
||||
def SBB16mr : I<0x19, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
|
||||
"sbb{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (load addr:$dst), GR16:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>,
|
||||
[(store (sube (load addr:$dst), GR16:$src2), addr:$dst)]>,
|
||||
OpSize;
|
||||
def SBB32mr : I<0x19, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
|
||||
"sbb{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (load addr:$dst), GR32:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (sube (load addr:$dst), GR32:$src2), addr:$dst)]>;
|
||||
def SBB8mi : Ii32<0x80, MRM3m, (outs), (ins i8mem:$dst, i8imm:$src2),
|
||||
"sbb{b}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (loadi8 addr:$dst), imm:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (sube (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
|
||||
def SBB16mi : Ii16<0x81, MRM3m, (outs), (ins i16mem:$dst, i16imm:$src2),
|
||||
"sbb{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (loadi16 addr:$dst), imm:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>,
|
||||
[(store (sube (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
|
||||
OpSize;
|
||||
def SBB16mi8 : Ii8<0x83, MRM3m, (outs), (ins i16mem:$dst, i16i8imm :$src2),
|
||||
"sbb{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (load addr:$dst), i16immSExt8:$src2,
|
||||
EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>,
|
||||
[(store (sube (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
|
||||
OpSize;
|
||||
def SBB32mi : Ii32<0x81, MRM3m, (outs), (ins i32mem:$dst, i32imm:$src2),
|
||||
"sbb{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (loadi32 addr:$dst), imm:$src2, EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (sube (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
|
||||
def SBB32mi8 : Ii8<0x83, MRM3m, (outs), (ins i32mem:$dst, i32i8imm :$src2),
|
||||
"sbb{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(store (X86sube_flag (load addr:$dst), i32immSExt8:$src2,
|
||||
EFLAGS),
|
||||
addr:$dst),
|
||||
(implicit EFLAGS)]>;
|
||||
[(store (sube (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
|
||||
}
|
||||
def SBB8rm : I<0x1A, MRMSrcMem, (outs GR8:$dst), (ins GR8:$src1, i8mem:$src2),
|
||||
"sbb{b}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR8:$dst,
|
||||
(X86sube_flag GR8:$src1, (load addr:$src2), EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR8:$dst, (sube GR8:$src1, (load addr:$src2)))]>;
|
||||
def SBB16rm : I<0x1B, MRMSrcMem, (outs GR16:$dst),
|
||||
(ins GR16:$src1, i16mem:$src2),
|
||||
"sbb{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR16:$dst,
|
||||
(X86sube_flag GR16:$src1, (load addr:$src2), EFLAGS)),
|
||||
(implicit EFLAGS)]>,
|
||||
[(set GR16:$dst, (sube GR16:$src1, (load addr:$src2)))]>,
|
||||
OpSize;
|
||||
def SBB32rm : I<0x1B, MRMSrcMem, (outs GR32:$dst),
|
||||
(ins GR32:$src1, i32mem:$src2),
|
||||
"sbb{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR32:$dst,
|
||||
(X86sube_flag GR32:$src1, (load addr:$src2), EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR32:$dst, (sube GR32:$src1, (load addr:$src2)))]>;
|
||||
def SBB8ri : Ii8<0x80, MRM3r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
|
||||
"sbb{b}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR8:$dst,
|
||||
(X86sube_flag GR8:$src1, imm:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR8:$dst, (sube GR8:$src1, imm:$src2))]>;
|
||||
def SBB16ri : Ii16<0x81, MRM3r, (outs GR16:$dst),
|
||||
(ins GR16:$src1, i16imm:$src2),
|
||||
"sbb{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR16:$dst,
|
||||
(X86sube_flag GR16:$src1, imm:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>, OpSize;
|
||||
[(set GR16:$dst, (sube GR16:$src1, imm:$src2))]>, OpSize;
|
||||
def SBB16ri8 : Ii8<0x83, MRM3r, (outs GR16:$dst),
|
||||
(ins GR16:$src1, i16i8imm:$src2),
|
||||
"sbb{w}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR16:$dst,
|
||||
(X86sube_flag GR16:$src1, i16immSExt8:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>, OpSize;
|
||||
[(set GR16:$dst, (sube GR16:$src1, i16immSExt8:$src2))]>,
|
||||
OpSize;
|
||||
def SBB32ri : Ii32<0x81, MRM3r, (outs GR32:$dst),
|
||||
(ins GR32:$src1, i32imm:$src2),
|
||||
"sbb{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR32:$dst,
|
||||
(X86sube_flag GR32:$src1, imm:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR32:$dst, (sube GR32:$src1, imm:$src2))]>;
|
||||
def SBB32ri8 : Ii8<0x83, MRM3r, (outs GR32:$dst),
|
||||
(ins GR32:$src1, i32i8imm:$src2),
|
||||
"sbb{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR32:$dst,
|
||||
(X86sube_flag GR32:$src1, i32immSExt8:$src2, EFLAGS)),
|
||||
(implicit EFLAGS)]>;
|
||||
[(set GR32:$dst, (sube GR32:$src1, i32immSExt8:$src2))]>;
|
||||
} // Uses = [EFLAGS]
|
||||
} // Defs = [EFLAGS]
|
||||
|
||||
|
@ -399,13 +399,9 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
|
||||
} else if (PropList[i]->getName() == "SDNPHasChain") {
|
||||
Properties |= 1 << SDNPHasChain;
|
||||
} else if (PropList[i]->getName() == "SDNPOutFlag") {
|
||||
Properties |= 1 << SDNPOutFlag;
|
||||
assert(!(Properties & (1<<SDNPOutI1)) &&
|
||||
"Can't handle OutFlag and OutI1");
|
||||
Properties |= 1 << SDNPOutFlag;
|
||||
} else if (PropList[i]->getName() == "SDNPInFlag") {
|
||||
Properties |= 1 << SDNPInFlag;
|
||||
assert(!(Properties & (1<<SDNPInI1)) &&
|
||||
"Can't handle InFlag and InI1");
|
||||
} else if (PropList[i]->getName() == "SDNPOptInFlag") {
|
||||
Properties |= 1 << SDNPOptInFlag;
|
||||
} else if (PropList[i]->getName() == "SDNPMayStore") {
|
||||
@ -416,14 +412,6 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
|
||||
Properties |= 1 << SDNPSideEffect;
|
||||
} else if (PropList[i]->getName() == "SDNPMemOperand") {
|
||||
Properties |= 1 << SDNPMemOperand;
|
||||
} else if (PropList[i]->getName() == "SDNPInI1") {
|
||||
Properties |= 1 << SDNPInI1;
|
||||
assert(!(Properties & (1<<SDNPInFlag)) &&
|
||||
"Can't handle InFlag and InI1");
|
||||
} else if (PropList[i]->getName() == "SDNPOutI1") {
|
||||
Properties |= 1 << SDNPOutI1;
|
||||
assert(!(Properties & (1<<SDNPOutFlag)) &&
|
||||
"Can't handle OutFlag and OutI1");
|
||||
} else {
|
||||
cerr << "Unknown SD Node property '" << PropList[i]->getName()
|
||||
<< "' on node '" << R->getName() << "'!\n";
|
||||
|
@ -385,13 +385,6 @@ bool CodeGenTarget::isLittleEndianEncoding() const {
|
||||
return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
|
||||
}
|
||||
|
||||
/// supportsHasI1 - Return whether this target supports the implicit I1,
|
||||
/// rather than Flags, for ADDC/ADDE
|
||||
///
|
||||
bool CodeGenTarget::supportsHasI1() const {
|
||||
return getInstructionSet()->getValueAsBit("supportsHasI1");
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ComplexPattern implementation
|
||||
//
|
||||
|
@ -43,9 +43,7 @@ enum SDNP {
|
||||
SDNPMayLoad,
|
||||
SDNPMayStore,
|
||||
SDNPSideEffect,
|
||||
SDNPMemOperand,
|
||||
SDNPInI1,
|
||||
SDNPOutI1
|
||||
SDNPMemOperand
|
||||
};
|
||||
|
||||
// ComplexPattern attributes.
|
||||
@ -211,12 +209,10 @@ public:
|
||||
void getInstructionsByEnumValue(std::vector<const CodeGenInstruction*>
|
||||
&NumberedInstructions);
|
||||
|
||||
|
||||
/// isLittleEndianEncoding - are instruction bit patterns defined as [0..n]?
|
||||
///
|
||||
bool isLittleEndianEncoding() const;
|
||||
|
||||
/// supportsHasI1 - does this target understand HasI1 for ADDE and ADDC?
|
||||
bool supportsHasI1() const;
|
||||
};
|
||||
|
||||
/// ComplexPattern - ComplexPattern info, corresponding to the ComplexPattern
|
||||
|
@ -670,8 +670,7 @@ public:
|
||||
HasChain = true;
|
||||
FoldedChains.push_back(std::make_pair(RootName, CInfo.getNumResults()));
|
||||
}
|
||||
if (NodeHasProperty(Child, SDNPOutFlag, CGP) ||
|
||||
NodeHasProperty(Child, SDNPOutI1, CGP)) {
|
||||
if (NodeHasProperty(Child, SDNPOutFlag, CGP)) {
|
||||
assert(FoldedFlag.first == "" && FoldedFlag.second == 0 &&
|
||||
"Pattern folded multiple nodes which produce flags?");
|
||||
FoldedFlag = std::make_pair(RootName,
|
||||
@ -970,10 +969,6 @@ public:
|
||||
PatternHasProperty(Pattern, SDNPInFlag, CGP);
|
||||
bool NodeHasOutFlag = isRoot &&
|
||||
PatternHasProperty(Pattern, SDNPOutFlag, CGP);
|
||||
bool NodeHasInI1 = isRoot &&
|
||||
PatternHasProperty(Pattern, SDNPInI1, CGP);
|
||||
bool NodeHasOutI1 = isRoot &&
|
||||
PatternHasProperty(Pattern, SDNPOutI1, CGP);
|
||||
bool NodeHasChain = InstPatNode &&
|
||||
PatternHasProperty(InstPatNode, SDNPHasChain, CGP);
|
||||
bool InputHasChain = isRoot &&
|
||||
@ -1059,13 +1054,10 @@ public:
|
||||
|
||||
// Emit all the chain and CopyToReg stuff.
|
||||
bool ChainEmitted = NodeHasChain;
|
||||
// InFlag and InI1 cannot both be set (checked in
|
||||
// CodeGenDAGPatterns), so use the same variables for both.
|
||||
if (NodeHasInFlag || HasImpInputs || NodeHasInI1)
|
||||
if (NodeHasInFlag || HasImpInputs)
|
||||
EmitInFlagSelectCode(Pattern, "N", ChainEmitted,
|
||||
InFlagDecled, ResNodeDecled, true);
|
||||
if (NodeHasOptInFlag || NodeHasInFlag || HasImpInputs ||
|
||||
NodeHasInI1) {
|
||||
if (NodeHasOptInFlag || NodeHasInFlag || HasImpInputs) {
|
||||
if (!InFlagDecled) {
|
||||
emitCode("SDValue InFlag(0, 0);");
|
||||
InFlagDecled = true;
|
||||
@ -1121,7 +1113,7 @@ public:
|
||||
}
|
||||
if (NodeHasChain)
|
||||
Code += ", MVT::Other";
|
||||
if (NodeHasOutFlag || (NodeHasOutI1 && !CGT.supportsHasI1()))
|
||||
if (NodeHasOutFlag)
|
||||
Code += ", MVT::Flag";
|
||||
|
||||
// Inputs.
|
||||
@ -1181,8 +1173,7 @@ public:
|
||||
}
|
||||
Code += ", &Ops" + utostr(OpsNo) + "[0], Ops" + utostr(OpsNo) +
|
||||
".size()";
|
||||
} else if (NodeHasInFlag || NodeHasOptInFlag || HasImpInputs ||
|
||||
NodeHasInI1)
|
||||
} else if (NodeHasInFlag || NodeHasOptInFlag || HasImpInputs)
|
||||
AllOps.push_back("InFlag");
|
||||
|
||||
unsigned NumOps = AllOps.size();
|
||||
@ -1216,7 +1207,7 @@ public:
|
||||
NodeOps.push_back("Tmp" + utostr(ResNo));
|
||||
} else {
|
||||
|
||||
if (NodeHasOutFlag || NodeHasOutI1) {
|
||||
if (NodeHasOutFlag) {
|
||||
if (!InFlagDecled) {
|
||||
After.push_back("SDValue InFlag(ResNode, " +
|
||||
utostr(NumResults+NumDstRegs+(unsigned)NodeHasChain) +
|
||||
@ -1237,15 +1228,13 @@ public:
|
||||
utostr(NumResults+NumDstRegs) + ")");
|
||||
}
|
||||
|
||||
if (NodeHasOutFlag || NodeHasOutI1) {
|
||||
if (NodeHasOutFlag) {
|
||||
if (FoldedFlag.first != "") {
|
||||
ReplaceFroms.push_back("SDValue(" + FoldedFlag.first +
|
||||
".getNode(), " +
|
||||
ReplaceFroms.push_back("SDValue(" + FoldedFlag.first + ".getNode(), " +
|
||||
utostr(FoldedFlag.second) + ")");
|
||||
ReplaceTos.push_back("InFlag");
|
||||
} else {
|
||||
assert(NodeHasProperty(Pattern, SDNPOutFlag, CGP) ||
|
||||
NodeHasProperty(Pattern, SDNPOutI1, CGP));
|
||||
assert(NodeHasProperty(Pattern, SDNPOutFlag, CGP));
|
||||
ReplaceFroms.push_back("SDValue(N.getNode(), " +
|
||||
utostr(NumPatResults + (unsigned)InputHasChain)
|
||||
+ ")");
|
||||
@ -1262,8 +1251,7 @@ public:
|
||||
}
|
||||
|
||||
// User does not expect the instruction would produce a chain!
|
||||
if ((!InputHasChain && NodeHasChain) &&
|
||||
(NodeHasOutFlag || NodeHasOutI1)) {
|
||||
if ((!InputHasChain && NodeHasChain) && NodeHasOutFlag) {
|
||||
;
|
||||
} else if (InputHasChain && !NodeHasChain) {
|
||||
// One of the inner node produces a chain.
|
||||
@ -1403,8 +1391,6 @@ private:
|
||||
unsigned OpNo =
|
||||
(unsigned) NodeHasProperty(N, SDNPHasChain, CGP);
|
||||
bool HasInFlag = NodeHasProperty(N, SDNPInFlag, CGP);
|
||||
bool HasInI1 = NodeHasProperty(N, SDNPInI1, CGP);
|
||||
bool InFlagDefined = false;
|
||||
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
|
||||
TreePatternNode *Child = N->getChild(i);
|
||||
if (!Child->isLeaf()) {
|
||||
@ -1438,41 +1424,21 @@ private:
|
||||
emitCode("SDValue InFlag(0, 0);");
|
||||
InFlagDecled = true;
|
||||
}
|
||||
if (HasInI1) {
|
||||
if (!ResNodeDecled) {
|
||||
emitCode("SDNode * ResNode;");
|
||||
}
|
||||
if (T.supportsHasI1())
|
||||
emitCode("ResNode = CurDAG->getCopyToReg(" + ChainName +
|
||||
", " + RootName + ".getDebugLoc()" +
|
||||
", " + getEnumName(RVT) +
|
||||
", " + getQualifiedName(RR) +
|
||||
", " + RootName + utostr(OpNo) + ").getNode();");
|
||||
else
|
||||
emitCode("ResNode = CurDAG->getCopyToReg(" + ChainName +
|
||||
", " + RootName + ".getDebugLoc()" +
|
||||
", " + getQualifiedName(RR) +
|
||||
", " + RootName + utostr(OpNo) +
|
||||
", InFlag).getNode();");
|
||||
InFlagDefined = true;
|
||||
} else {
|
||||
std::string Decl = (!ResNodeDecled) ? "SDNode *" : "";
|
||||
emitCode(Decl + "ResNode = CurDAG->getCopyToReg(" + ChainName +
|
||||
std::string Decl = (!ResNodeDecled) ? "SDNode *" : "";
|
||||
emitCode(Decl + "ResNode = CurDAG->getCopyToReg(" + ChainName +
|
||||
", " + RootName + ".getDebugLoc()" +
|
||||
", " + getQualifiedName(RR) +
|
||||
", " + RootName + utostr(OpNo) +
|
||||
", InFlag).getNode();");
|
||||
}
|
||||
", " + RootName + utostr(OpNo) + ", InFlag).getNode();");
|
||||
ResNodeDecled = true;
|
||||
emitCode(ChainName + " = SDValue(ResNode, 0);");
|
||||
emitCode("InFlag = SDValue(ResNode, 1);");
|
||||
ResNodeDecled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HasInFlag || (HasInI1 && !InFlagDefined)) {
|
||||
if (HasInFlag) {
|
||||
if (!InFlagDecled) {
|
||||
emitCode("SDValue InFlag = " + RootName +
|
||||
".getOperand(" + utostr(OpNo) + ");");
|
||||
|
Loading…
x
Reference in New Issue
Block a user