[llvm-commits] [llvm] r72707 - in /llvm/trunk: include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/SelectionDAG/ lib/Target/X86/ utils/TableGen/
Dale Johannesen
dalej at apple.com
Tue Jun 2 11:23:04 PDT 2009
On Jun 2, 2009, at 11:00 AMPDT, Evan Cheng wrote:
> Hi Dale,
>
> On first glance, the patch mostly looks good. But I don't care for
> "supportsHasI1". I would have added ADDC_FLAG / ADDE_FLAG opcodes and
> have those use MVT::EFLAGS
I assume you mean MVT::Flag
> and change ADDC / ADDE to use MVT::i1 to
> represent the flag value.
Offhand I don't like that, it means a fair amount of parallel but
subtly different code in the target-independent parts and calls for
changing all non-x86 BEs to use addc_flag. This way, the target-
independent code is clean and the complexities are all in TableGen.
I agree HasI1 is not a thing of beauty; let me think about it more.
This is not far off Eli's suggestion of hijacking UADDO to replace
ADDC with i1, what do you think of that?
> Thanks,
>
> Evan
>
> On Jun 1, 2009, at 4:27 PM, Dale Johannesen wrote:
>
>> Author: johannes
>> Date: Mon Jun 1 18:27:20 2009
>> New Revision: 72707
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=72707&view=rev
>> Log:
>> Make the implicit inputs and outputs of target-independent
>> ADDC/ADDE use MVT::i1 (later, whatever it gets legalized to)
>> instead of MVT::Flag. Remove CARRY_FALSE in favor of 0; adjust
>> all target-independent code to use this format.
>>
>> Most targets will still produce a Flag-setting target-dependent
>> version when selection is done. X86 is converted to use i32
>> instead, which means TableGen needs to produce different code
>> in xxxGenDAGISel.inc. This keys off the new supportsHasI1 bit
>> in xxxInstrInfo, currently set only for X86; in principle this
>> is temporary and should go away when all other targets have
>> been converted. All relevant X86 instruction patterns are
>> modified to represent setting and using EFLAGS explicitly. The
>> same can be done on other targets.
>>
>> The immediate behavior change is that an ADC/ADD pair are no
>> longer tightly coupled in the X86 scheduler; they can be
>> separated by instructions that don't clobber the flags (MOV).
>> I will soon add some peephole optimizations based on using
>> other instructions that set the flags to feed into ADC.
>>
>>
>> Modified:
>> llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
>> llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
>> llvm/trunk/include/llvm/Target/Target.td
>> llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
>> llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>> llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
>> llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
>> llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
>> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>> llvm/trunk/lib/Target/X86/X86ISelLowering.h
>> llvm/trunk/lib/Target/X86/X86Instr64bit.td
>> llvm/trunk/lib/Target/X86/X86InstrInfo.td
>> llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
>> llvm/trunk/utils/TableGen/CodeGenTarget.cpp
>> llvm/trunk/utils/TableGen/CodeGenTarget.h
>> llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
>>
>> Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
>> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Jun 1
>> 18:27:20 2009
>> @@ -324,6 +324,14 @@
>> 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
>>
>> Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
>> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Mon Jun 1
>> 18:27:20 2009
>> @@ -242,14 +242,11 @@
>> // 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.
>> + // result is the carry flag result (type i1 or whatever it got
>> expanded to
>> + // for the target, value 0 or 1).
>> ADDC, SUBC,
>>
>> // Carry-using nodes for multiple precision addition and
>> subtraction. These
>> @@ -258,7 +255,8 @@
>> // 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.
>> + // 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.
>> ADDE, SUBE,
>>
>> // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for
>> addition.
>>
>> Modified: llvm/trunk/include/llvm/Target/Target.td
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/include/llvm/Target/Target.td (original)
>> +++ llvm/trunk/include/llvm/Target/Target.td Mon Jun 1 18:27:20 2009
>> @@ -326,6 +326,11 @@
>> // 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.
>>
>> Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original)
>> +++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Mon Jun 1
>> 18:27:20 2009
>> @@ -216,6 +216,8 @@
>> 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.
>> @@ -289,13 +291,13 @@
>> def xor : SDNode<"ISD::XOR" , SDTIntBinOp,
>> [SDNPCommutative, SDNPAssociative]>;
>> def addc : SDNode<"ISD::ADDC" , SDTIntBinOp,
>> - [SDNPCommutative, SDNPOutFlag]>;
>> + [SDNPCommutative, SDNPOutI1]>;
>> def adde : SDNode<"ISD::ADDE" , SDTIntBinOp,
>> - [SDNPCommutative, SDNPOutFlag, SDNPInFlag]>;
>> + [SDNPCommutative, SDNPInI1, SDNPOutI1]>;
>> def subc : SDNode<"ISD::SUBC" , SDTIntBinOp,
>> - [SDNPOutFlag]>;
>> + [SDNPOutI1]>;
>> def sube : SDNode<"ISD::SUBE" , SDTIntBinOp,
>> - [SDNPOutFlag, SDNPInFlag]>;
>> + [SDNPInI1, SDNPOutI1]>;
>>
>> def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
>> def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>;
>>
>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Jun 1
>> 18:27:20 2009
>> @@ -1085,8 +1085,7 @@
>> // 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.getNode(ISD::CARRY_FALSE,
>> - N->getDebugLoc(), MVT::Flag));
>> + DAG.getConstant(0, N->getValueType(1)));
>>
>> // canonicalize constant to RHS.
>> if (N0C && !N1C)
>> @@ -1094,10 +1093,9 @@
>>
>> // fold (addc x, 0) -> x + no carry out
>> if (N1C && N1C->isNullValue())
>> - return CombineTo(N, N0, DAG.getNode(ISD::CARRY_FALSE,
>> - N->getDebugLoc(),
>> MVT::Flag));
>> + return CombineTo(N, N0, DAG.getConstant(0, N1.getValueType()));
>>
>> - // fold (addc a, b) -> (or a, b), CARRY_FALSE iff a and b share
>> no bits.
>> + // fold (addc a, b) -> (or a, b), 0 iff a and b share no bits.
>> APInt LHSZero, LHSOne;
>> APInt RHSZero, RHSOne;
>> APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits());
>> @@ -1111,8 +1109,7 @@
>> if ((RHSZero & (~LHSZero & Mask)) == (~LHSZero & Mask) ||
>> (LHSZero & (~RHSZero & Mask)) == (~RHSZero & Mask))
>> return CombineTo(N, DAG.getNode(ISD::OR, N->getDebugLoc(), VT,
>> N0, N1),
>> - DAG.getNode(ISD::CARRY_FALSE,
>> - N->getDebugLoc(), MVT::Flag));
>> + DAG.getConstant(0, N1.getValueType()));
>> }
>>
>> return SDValue();
>> @@ -1131,8 +1128,9 @@
>> N1, N0, CarryIn);
>>
>> // fold (adde x, y, false) -> (addc x, y)
>> - if (CarryIn.getOpcode() == ISD::CARRY_FALSE)
>> - return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(),
>> N1, N0);
>> + if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(CarryIn))
>> + if (N2C->getAPIntValue()==0)
>> + return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList
>> (), N1, N0);
>>
>> return SDValue();
>> }
>>
>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/
>> LegalizeIntegerTypes.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
>> (original)
>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Mon
>> Jun 1 18:27:20 2009
>> @@ -98,6 +98,10 @@
>> 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:
>> @@ -121,6 +125,35 @@
>> 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));
>> @@ -419,7 +452,7 @@
>> return Res;
>> }
>>
>> -/// Promote the overflow flag of an overflowing arithmetic node.
>> +/// Promote the overflow or carry result 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));
>> @@ -666,6 +699,8 @@
>> 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;
>> @@ -743,6 +778,13 @@
>> }
>> }
>>
>> +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);
>> @@ -1063,7 +1105,7 @@
>> TLI.isOperationLegalOrCustom(ISD::ADDC,
>> TLI.getTypeToExpandTo
>> (NVT))) {
>> // Emit this X << 1 as X+X.
>> - SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
>> + SDVTList VTList = DAG.getVTList(NVT, MVT::i1);
>> SDValue LoOps[2] = { InL, InL };
>> Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
>> SDValue HiOps[3] = { InH, InH, Lo.getValue(1) };
>> @@ -1299,7 +1341,7 @@
>> TLI.getTypeToExpandTo(NVT));
>>
>> if (hasCarry) {
>> - SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
>> + SDVTList VTList = DAG.getVTList(NVT, MVT::i1);
>> if (N->getOpcode() == ISD::ADD) {
>> Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
>> HiOps[2] = Lo.getValue(1);
>> @@ -1344,7 +1386,7 @@
>> DebugLoc dl = N->getDebugLoc();
>> GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
>> GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
>> - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
>> + SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::i1);
>> SDValue LoOps[2] = { LHSL, RHSL };
>> SDValue HiOps[3] = { LHSH, RHSH };
>>
>> @@ -1358,8 +1400,8 @@
>> Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
>> }
>>
>> - // Legalized the flag result - switch anything that used the old
>> flag to
>> - // use the new one.
>> + // Legalized the second result (carry bit) - switch anything that
>> used the
>> + // result to use the new one.
>> ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
>> }
>>
>> @@ -1370,7 +1412,7 @@
>> DebugLoc dl = N->getDebugLoc();
>> GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
>> GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
>> - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
>> + SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::i1);
>> SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
>> SDValue HiOps[3] = { LHSH, RHSH };
>>
>> @@ -1378,8 +1420,8 @@
>> HiOps[2] = Lo.getValue(1);
>> Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3);
>>
>> - // Legalized the flag result - switch anything that used the old
>> flag to
>> - // use the new one.
>> + // Legalized the second result (carry bit) - switch anything that
>> used the
>> + // result to use the new one.
>> ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
>> }
>>
>>
>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Mon Jun 1
>> 18:27:20 2009
>> @@ -242,6 +242,8 @@
>>
>> // 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);
>> @@ -278,6 +280,7 @@
>>
>> // 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);
>>
>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
>> (original)
>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Mon
>> Jun 1 18:27:20 2009
>> @@ -268,6 +268,13 @@
>> 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;
>>
>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Jun 1
>> 18:27:20 2009
>> @@ -5257,7 +5257,6 @@
>> 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";
>>
>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Jun 1
>> 18:27:20 2009
>> @@ -190,6 +190,28 @@
>> 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
>> @@ -6475,6 +6497,21 @@
>> 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();
>> @@ -6543,6 +6580,10 @@
>> 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);
>> @@ -6791,6 +6832,10 @@
>> 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";
>> }
>> }
>>
>>
>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Jun 1 18:27:20
>> 2009
>> @@ -243,6 +243,14 @@
>> 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
>> };
>> @@ -576,7 +584,9 @@
>>
>> 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);
>>
>> Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original)
>> +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon Jun 1 18:27:20
>> 2009
>> @@ -383,31 +383,52 @@
>> 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, (adde GR64:$src1, GR64:$src2))]>;
>> + [(set GR64:$dst,
>> + (X86adde_flag GR64:$src1, GR64:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>;
>>
>> -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, (adde GR64:$src1, (load addr:
>> $src2)))]>;
>> + [(set GR64:$dst,
>> + (X86adde_flag GR64:$src1, (load addr:
>> $src2), EFLAGS)),
>> + (implicit EFLAGS)]>;
>>
>> -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, (adde GR64:$src1,
>> i64immSExt8:$src2))]>;
>> -def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst), (ins
>> GR64:$src1, i64i32imm:$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),
>> "adc{q}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR64:$dst, (adde GR64:$src1,
>> i64immSExt32:$src2))]>;
>> + [(set GR64:$dst,
>> + (X86adde_flag GR64:$src1,
>> i64immSExt32:$src2,
>> + EFLAGS)),
>> + (implicit EFLAGS)]>;
>> } // isTwoAddress
>>
>> def ADC64mr : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst,
>> GR64:$src2),
>> "adc{q}\t{$src2, $dst|$dst, $src2}",
>> - [(store (adde (load addr:$dst), GR64:$src2), addr:
>> $dst)]>;
>> + [(store (X86adde_flag (load addr:$dst),
>> GR64:$src2, EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :
>> $src2),
>> "adc{q}\t{$src2, $dst|$dst, $src2}",
>> - [(store (adde (load addr:$dst),
>> i64immSExt8:$src2), addr:$dst)]>;
>> + [(store (X86adde_flag (load addr:$dst),
>> i64immSExt8:$src2,
>> + EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst,
>> i64i32imm:$src2),
>> "adc{q}\t{$src2, $dst|$dst, $src2}",
>> - [(store (adde (load addr:$dst),
>> i64immSExt8:$src2), addr:$dst)]>;
>> + [(store (X86adde_flag (load addr:$dst),
>> i64immSExt8:$src2,
>> + EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> } // Uses = [EFLAGS]
>>
>> let isTwoAddress = 1 in {
>> @@ -456,31 +477,52 @@
>>
>> 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, (sube GR64:$src1, GR64:$src2))]
>>> ;
>> + [(set GR64:$dst,
>> + (X86sube_flag GR64:$src1, GR64:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>;
>>
>> -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, (sube GR64:$src1, (load addr:
>> $src2)))]>;
>> + [(set GR64:$dst,
>> + (X86sube_flag GR64:$src1, (load addr:
>> $src2), EFLAGS)),
>> + (implicit EFLAGS)]>;
>>
>> -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, (sube GR64:$src1,
>> i64immSExt8:$src2))]>;
>> -def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst), (ins
>> GR64:$src1, i64i32imm:$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),
>> "sbb{q}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR64:$dst, (sube GR64:$src1,
>> i64immSExt32:$src2))]>;
>> + [(set GR64:$dst,
>> + (X86sube_flag GR64:$src1,
>> i64immSExt32:$src2,
>> + EFLAGS)),
>> + (implicit EFLAGS)]>;
>> } // isTwoAddress
>>
>> def SBB64mr : RI<0x19, MRMDestMem, (outs), (ins i64mem:$dst,
>> GR64:$src2),
>> "sbb{q}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (load addr:$dst), GR64:$src2), addr:
>> $dst)]>;
>> + [(store (X86sube_flag (load addr:$dst),
>> GR64:$src2, EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> def SBB64mi8 : RIi8<0x83, MRM3m, (outs), (ins i64mem:$dst, i64i8imm :
>> $src2),
>> "sbb{q}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (load addr:$dst), i64immSExt8:$src2),
>> addr:$dst)]>;
>> + [(store (X86sube_flag (load addr:$dst),
>> i64immSExt8:$src2,
>> + EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> def SBB64mi32 : RIi32<0x81, MRM3m, (outs), (ins i64mem:$dst,
>> i64i32imm:$src2),
>> "sbb{q}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (load addr:$dst), i64immSExt32:$src2),
>> addr:$dst)]>;
>> + [(store (X86sube_flag (load addr:$dst),
>> i64immSExt32:$src2,
>> + EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> } // Uses = [EFLAGS]
>> } // Defs = [EFLAGS]
>>
>>
>> Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
>> +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Jun 1 18:27:20
>> 2009
>> @@ -34,6 +34,11 @@
>> [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>]
>>> ;
>> @@ -156,6 +161,8 @@
>> 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>;
>>
>> @@ -2274,81 +2281,127 @@
>>
>> 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, (adde GR8:$src1, GR8:$src2))]>;
>> + [(set GR8:$dst, (X86adde_flag GR8:$src1,
>> GR8:$src2, EFLAGS)),
>> + (implicit EFLAGS)]>;
>> def ADC16rr : I<0x11, MRMDestReg, (outs GR16:$dst),
>> (ins GR16:$src1, GR16:$src2),
>> "adc{w}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR16:$dst, (adde GR16:$src1, GR16:$src2))]>,
>> OpSize;
>> + [(set GR16:$dst,
>> + (X86adde_flag GR16:$src1, GR16:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>,
>> + OpSize;
>> def ADC32rr : I<0x11, MRMDestReg, (outs GR32:$dst),
>> (ins GR32:$src1, GR32:$src2),
>> "adc{l}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR32:$dst, (adde GR32:$src1, GR32:$src2))]>;
>> + [(set GR32:$dst,
>> + (X86adde_flag GR32:$src1, GR32:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>;
>> }
>> def ADC8rm : I<0x12, MRMSrcMem , (outs GR8:$dst),
>> (ins GR8:$src1, i8mem:$src2),
>> "adc{b}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR8:$dst, (adde GR8:$src1, (load addr:
>> $src2)))]>;
>> + [(set GR8:$dst,
>> + (X86adde_flag GR8:$src1, (load addr:$src2),
>> EFLAGS)),
>> + (implicit EFLAGS)]>;
>> def ADC16rm : I<0x13, MRMSrcMem , (outs GR16:$dst),
>> (ins GR16:$src1, i16mem:$src2),
>> "adc{w}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR16:$dst, (adde GR16:$src1, (load addr:
>> $src2)))]>,
>> + [(set GR16:$dst,
>> + (X86adde_flag GR16:$src1, (load addr:$src2),
>> EFLAGS)),
>> + (implicit EFLAGS)]>,
>> OpSize;
>> def ADC32rm : I<0x13, MRMSrcMem , (outs GR32:$dst),
>> (ins GR32:$src1, i32mem:$src2),
>> "adc{l}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR32:$dst, (adde GR32:$src1, (load addr:
>> $src2)))]>;
>> -def ADC8ri : Ii8<0x80, MRM2r, (outs GR8:$dst), (ins GR8:$src1,
>> i8imm:$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),
>> "adc{b}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR8:$dst, (adde GR8:$src1, imm:$src2))]>;
>> + [(set GR8:$dst,
>> + (X86adde_flag GR8:$src1, imm:$src2, EFLAGS)),
>> + (implicit EFLAGS)]>;
>> def ADC16ri : Ii16<0x81, MRM2r, (outs GR16:$dst),
>> (ins GR16:$src1, i16imm:$src2),
>> "adc{w}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR16:$dst, (adde GR16:$src1, imm:$src2))]>,
>> OpSize;
>> + [(set GR16:$dst,
>> + (X86adde_flag GR16:$src1, imm:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>, OpSize;
>> def ADC16ri8 : Ii8<0x83, MRM2r, (outs GR16:$dst),
>> (ins GR16:$src1, i16i8imm:$src2),
>> "adc{w}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR16:$dst, (adde GR16:$src1,
>> i16immSExt8:$src2))]>,
>> - OpSize;
>> + [(set GR16:$dst,
>> + (X86adde_flag GR16:$src1, i16immSExt8:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>, OpSize;
>> def ADC32ri : Ii32<0x81, MRM2r, (outs GR32:$dst),
>> (ins GR32:$src1, i32imm:$src2),
>> "adc{l}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR32:$dst, (adde GR32:$src1, imm:$src2))]>;
>> + [(set GR32:$dst,
>> + (X86adde_flag GR32:$src1, imm:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>;
>> def ADC32ri8 : Ii8<0x83, MRM2r, (outs GR32:$dst),
>> (ins GR32:$src1, i32i8imm:$src2),
>> "adc{l}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR32:$dst, (adde GR32:$src1,
>> i32immSExt8:$src2))]>;
>> + [(set GR32:$dst,
>> + (X86adde_flag GR32:$src1, i32immSExt8:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>;
>>
>> 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 (adde (load addr:$dst), GR8:$src2), addr:
>> $dst)]>;
>> - def ADC16mr : I<0x11, MRMDestMem, (outs), (ins i16mem:$dst,
>> GR16:$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),
>> "adc{w}\t{$src2, $dst|$dst, $src2}",
>> - [(store (adde (load addr:$dst), GR16:$src2),
>> addr:$dst)]>,
>> - OpSize;
>> - def ADC32mr : I<0x11, MRMDestMem, (outs), (ins i32mem:$dst,
>> GR32:$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),
>> "adc{l}\t{$src2, $dst|$dst, $src2}",
>> - [(store (adde (load addr:$dst), GR32:$src2),
>> addr:$dst)]>;
>> - def ADC8mi : Ii8<0x80, MRM2m, (outs), (ins i8mem:$dst, i8imm:
>> $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),
>> "adc{b}\t{$src2, $dst|$dst, $src2}",
>> - [(store (adde (loadi8 addr:$dst), imm:$src2),
>> addr:$dst)]>;
>> - def ADC16mi : Ii16<0x81, MRM2m, (outs), (ins i16mem:$dst, i16imm:
>> $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),
>> "adc{w}\t{$src2, $dst|$dst, $src2}",
>> - [(store (adde (loadi16 addr:$dst), imm:$src2),
>> addr:$dst)]>,
>> - OpSize;
>> - def ADC16mi8 : Ii8<0x83, MRM2m, (outs), (ins i16mem:$dst,
>> i16i8imm :$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),
>> "adc{w}\t{$src2, $dst|$dst, $src2}",
>> - [(store (adde (load addr:$dst), i16immSExt8:$src2),
>> addr:$dst)]>,
>> - OpSize;
>> - def ADC32mi : Ii32<0x81, MRM2m, (outs), (ins i32mem:$dst, i32imm:
>> $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),
>> "adc{l}\t{$src2, $dst|$dst, $src2}",
>> - [(store (adde (loadi32 addr:$dst), imm:$src2),
>> addr:$dst)]>;
>> - def ADC32mi8 : Ii8<0x83, MRM2m, (outs), (ins i32mem:$dst,
>> i32i8imm :$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),
>> "adc{l}\t{$src2, $dst|$dst, $src2}",
>> - [(store (adde (load addr:$dst), i32immSExt8:$src2),
>> addr:$dst)]>;
>> -}
>> + [(store (X86adde_flag (load addr:$dst),
>> i32immSExt8:$src2,
>> + EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> + }
>> } // Uses = [EFLAGS]
>>
>> // Register-Register Subtraction
>> @@ -2453,77 +2506,115 @@
>> def SBB8rr : I<0x18, MRMDestReg, (outs GR8:$dst),
>> (ins GR8:$src1, GR8:$src2),
>> "sbb{b}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR8:$dst, (sube GR8:$src1, GR8:$src2))]>;
>> + [(set GR8:$dst, (X86sube_flag GR8:$src1,
>> GR8:$src2, EFLAGS)),
>> + (implicit EFLAGS)]>;
>> def SBB16rr : I<0x19, MRMDestReg, (outs GR16:$dst),
>> (ins GR16:$src1, GR16:$src2),
>> "sbb{w}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR16:$dst, (sube GR16:$src1, GR16:$src2))]>,
>> OpSize;
>> + [(set GR16:$dst,
>> + (X86sube_flag GR16:$src1, GR16:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>, OpSize;
>> def SBB32rr : I<0x19, MRMDestReg, (outs GR32:$dst),
>> (ins GR32:$src1, GR32:$src2),
>> "sbb{l}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR32:$dst, (sube GR32:$src1, GR32:$src2))]>;
>> + [(set GR32:$dst,
>> + (X86sube_flag GR32:$src1, GR32:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>;
>>
>> let isTwoAddress = 0 in {
>> def SBB8mr : I<0x18, MRMDestMem, (outs), (ins i8mem:$dst,
>> GR8:$src2),
>> "sbb{b}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (load addr:$dst), GR8:$src2), addr:
>> $dst)]>;
>> + [(store (X86sube_flag (load addr:$dst),
>> GR8:$src2, EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> def SBB16mr : I<0x19, MRMDestMem, (outs), (ins i16mem:$dst,
>> GR16:$src2),
>> "sbb{w}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (load addr:$dst), GR16:$src2),
>> addr:$dst)]>,
>> + [(store (X86sube_flag (load addr:$dst),
>> GR16:$src2, EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>,
>> OpSize;
>> def SBB32mr : I<0x19, MRMDestMem, (outs), (ins i32mem:$dst,
>> GR32:$src2),
>> "sbb{l}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (load addr:$dst), GR32:$src2),
>> addr:$dst)]>;
>> + [(store (X86sube_flag (load addr:$dst),
>> GR32:$src2, EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> def SBB8mi : Ii32<0x80, MRM3m, (outs), (ins i8mem:$dst, i8imm:
>> $src2),
>> "sbb{b}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (loadi8 addr:$dst), imm:$src2),
>> addr:$dst)]>;
>> + [(store (X86sube_flag (loadi8 addr:$dst), imm:
>> $src2, EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> def SBB16mi : Ii16<0x81, MRM3m, (outs), (ins i16mem:$dst, i16imm:
>> $src2),
>> "sbb{w}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (loadi16 addr:$dst), imm:$src2),
>> addr:$dst)]>,
>> + [(store (X86sube_flag (loadi16 addr:$dst), imm:
>> $src2, EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>,
>> OpSize;
>> def SBB16mi8 : Ii8<0x83, MRM3m, (outs), (ins i16mem:$dst,
>> i16i8imm :$src2),
>> "sbb{w}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (load addr:$dst), i16immSExt8:$src2),
>> addr:$dst)]>,
>> + [(store (X86sube_flag (load addr:$dst),
>> i16immSExt8:$src2,
>> + EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>,
>> OpSize;
>> def SBB32mi : Ii32<0x81, MRM3m, (outs), (ins i32mem:$dst, i32imm:
>> $src2),
>> "sbb{l}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (loadi32 addr:$dst), imm:$src2),
>> addr:$dst)]>;
>> + [(store (X86sube_flag (loadi32 addr:$dst), imm:
>> $src2, EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> def SBB32mi8 : Ii8<0x83, MRM3m, (outs), (ins i32mem:$dst,
>> i32i8imm :$src2),
>> "sbb{l}\t{$src2, $dst|$dst, $src2}",
>> - [(store (sube (load addr:$dst), i32immSExt8:$src2),
>> addr:$dst)]>;
>> + [(store (X86sube_flag (load addr:$dst),
>> i32immSExt8:$src2,
>> + EFLAGS),
>> + addr:$dst),
>> + (implicit EFLAGS)]>;
>> }
>> def SBB8rm : I<0x1A, MRMSrcMem, (outs GR8:$dst), (ins GR8:$src1,
>> i8mem:$src2),
>> "sbb{b}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR8:$dst, (sube GR8:$src1, (load addr:
>> $src2)))]>;
>> + [(set GR8:$dst,
>> + (X86sube_flag GR8:$src1, (load addr:
>> $src2), EFLAGS)),
>> + (implicit EFLAGS)]>;
>> def SBB16rm : I<0x1B, MRMSrcMem, (outs GR16:$dst),
>> (ins GR16:$src1, i16mem:$src2),
>> "sbb{w}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR16:$dst, (sube GR16:$src1, (load addr:
>> $src2)))]>,
>> + [(set GR16:$dst,
>> + (X86sube_flag GR16:$src1, (load addr:
>> $src2), EFLAGS)),
>> + (implicit EFLAGS)]>,
>> OpSize;
>> def SBB32rm : I<0x1B, MRMSrcMem, (outs GR32:$dst),
>> (ins GR32:$src1, i32mem:$src2),
>> "sbb{l}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR32:$dst, (sube GR32:$src1, (load addr:
>> $src2)))]>;
>> + [(set GR32:$dst,
>> + (X86sube_flag GR32:$src1, (load addr:
>> $src2), EFLAGS)),
>> + (implicit EFLAGS)]>;
>> def SBB8ri : Ii8<0x80, MRM3r, (outs GR8:$dst), (ins GR8:$src1,
>> i8imm:$src2),
>> "sbb{b}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR8:$dst, (sube GR8:$src1, imm:$src2))]>;
>> + [(set GR8:$dst,
>> + (X86sube_flag GR8:$src1, imm:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>;
>> def SBB16ri : Ii16<0x81, MRM3r, (outs GR16:$dst),
>> (ins GR16:$src1, i16imm:$src2),
>> "sbb{w}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR16:$dst, (sube GR16:$src1, imm:$src2))]
>>> , OpSize;
>> + [(set GR16:$dst,
>> + (X86sube_flag GR16:$src1, imm:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>, OpSize;
>> def SBB16ri8 : Ii8<0x83, MRM3r, (outs GR16:$dst),
>> (ins GR16:$src1, i16i8imm:$src2),
>> "sbb{w}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR16:$dst, (sube GR16:$src1,
>> i16immSExt8:$src2))]>,
>> - OpSize;
>> + [(set GR16:$dst,
>> + (X86sube_flag GR16:$src1,
>> i16immSExt8:$src2, EFLAGS)),
>> + (implicit EFLAGS)]>, OpSize;
>> def SBB32ri : Ii32<0x81, MRM3r, (outs GR32:$dst),
>> (ins GR32:$src1, i32imm:$src2),
>> "sbb{l}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR32:$dst, (sube GR32:$src1, imm:
>> $src2))]>;
>> + [(set GR32:$dst,
>> + (X86sube_flag GR32:$src1, imm:$src2,
>> EFLAGS)),
>> + (implicit EFLAGS)]>;
>> def SBB32ri8 : Ii8<0x83, MRM3r, (outs GR32:$dst),
>> (ins GR32:$src1, i32i8imm:$src2),
>> "sbb{l}\t{$src2, $dst|$dst, $src2}",
>> - [(set GR32:$dst, (sube GR32:$src1,
>> i32immSExt8:$src2))]>;
>> + [(set GR32:$dst,
>> + (X86sube_flag GR32:$src1,
>> i32immSExt8:$src2, EFLAGS)),
>> + (implicit EFLAGS)]>;
>> } // Uses = [EFLAGS]
>> } // Defs = [EFLAGS]
>>
>>
>> Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
>> +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Mon Jun 1
>> 18:27:20 2009
>> @@ -399,9 +399,13 @@
>> } else if (PropList[i]->getName() == "SDNPHasChain") {
>> Properties |= 1 << SDNPHasChain;
>> } else if (PropList[i]->getName() == "SDNPOutFlag") {
>> - Properties |= 1 << SDNPOutFlag;
>> + Properties |= 1 << SDNPOutFlag;
>> + assert(!(Properties & (1<<SDNPOutI1)) &&
>> + "Can't handle OutFlag and OutI1");
>> } 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") {
>> @@ -412,6 +416,14 @@
>> 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";
>>
>> Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original)
>> +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Mon Jun 1 18:27:20
>> 2009
>> @@ -385,6 +385,13 @@
>> 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
>> //
>>
>> Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/utils/TableGen/CodeGenTarget.h (original)
>> +++ llvm/trunk/utils/TableGen/CodeGenTarget.h Mon Jun 1 18:27:20
>> 2009
>> @@ -43,7 +43,9 @@
>> SDNPMayLoad,
>> SDNPMayStore,
>> SDNPSideEffect,
>> - SDNPMemOperand
>> + SDNPMemOperand,
>> + SDNPInI1,
>> + SDNPOutI1
>> };
>>
>> // ComplexPattern attributes.
>> @@ -209,10 +211,12 @@
>> 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
>>
>> Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
>> +++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Mon Jun 1 18:27:20
>> 2009
>> @@ -670,7 +670,8 @@
>> HasChain = true;
>> FoldedChains.push_back(std::make_pair(RootName,
>> CInfo.getNumResults()));
>> }
>> - if (NodeHasProperty(Child, SDNPOutFlag, CGP)) {
>> + if (NodeHasProperty(Child, SDNPOutFlag, CGP) ||
>> + NodeHasProperty(Child, SDNPOutI1, CGP)) {
>> assert(FoldedFlag.first == "" && FoldedFlag.second == 0 &&
>> "Pattern folded multiple nodes which produce flags?");
>> FoldedFlag = std::make_pair(RootName,
>> @@ -969,6 +970,10 @@
>> 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 &&
>> @@ -1054,10 +1059,13 @@
>>
>> // Emit all the chain and CopyToReg stuff.
>> bool ChainEmitted = NodeHasChain;
>> - if (NodeHasInFlag || HasImpInputs)
>> + // InFlag and InI1 cannot both be set (checked in
>> + // CodeGenDAGPatterns), so use the same variables for both.
>> + if (NodeHasInFlag || HasImpInputs || NodeHasInI1)
>> EmitInFlagSelectCode(Pattern, "N", ChainEmitted,
>> InFlagDecled, ResNodeDecled, true);
>> - if (NodeHasOptInFlag || NodeHasInFlag || HasImpInputs) {
>> + if (NodeHasOptInFlag || NodeHasInFlag || HasImpInputs ||
>> + NodeHasInI1) {
>> if (!InFlagDecled) {
>> emitCode("SDValue InFlag(0, 0);");
>> InFlagDecled = true;
>> @@ -1113,7 +1121,7 @@
>> }
>> if (NodeHasChain)
>> Code += ", MVT::Other";
>> - if (NodeHasOutFlag)
>> + if (NodeHasOutFlag || (NodeHasOutI1 && !CGT.supportsHasI1()))
>> Code += ", MVT::Flag";
>>
>> // Inputs.
>> @@ -1173,7 +1181,8 @@
>> }
>> Code += ", &Ops" + utostr(OpsNo) + "[0], Ops" + utostr
>> (OpsNo) +
>> ".size()";
>> - } else if (NodeHasInFlag || NodeHasOptInFlag || HasImpInputs)
>> + } else if (NodeHasInFlag || NodeHasOptInFlag || HasImpInputs
>> ||
>> + NodeHasInI1)
>> AllOps.push_back("InFlag");
>>
>> unsigned NumOps = AllOps.size();
>> @@ -1207,7 +1216,7 @@
>> NodeOps.push_back("Tmp" + utostr(ResNo));
>> } else {
>>
>> - if (NodeHasOutFlag) {
>> + if (NodeHasOutFlag || NodeHasOutI1) {
>> if (!InFlagDecled) {
>> After.push_back("SDValue InFlag(ResNode, " +
>> utostr(NumResults+NumDstRegs+(unsigned)
>> NodeHasChain) +
>> @@ -1228,13 +1237,15 @@
>> utostr(NumResults+NumDstRegs) + ")");
>> }
>>
>> - if (NodeHasOutFlag) {
>> + if (NodeHasOutFlag || NodeHasOutI1) {
>> 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));
>> + assert(NodeHasProperty(Pattern, SDNPOutFlag, CGP) ||
>> + NodeHasProperty(Pattern, SDNPOutI1, CGP));
>> ReplaceFroms.push_back("SDValue(N.getNode(), " +
>> utostr(NumPatResults + (unsigned)
>> InputHasChain)
>> + ")");
>> @@ -1251,7 +1262,8 @@
>> }
>>
>> // User does not expect the instruction would produce a chain!
>> - if ((!InputHasChain && NodeHasChain) && NodeHasOutFlag) {
>> + if ((!InputHasChain && NodeHasChain) &&
>> + (NodeHasOutFlag || NodeHasOutI1)) {
>> ;
>> } else if (InputHasChain && !NodeHasChain) {
>> // One of the inner node produces a chain.
>> @@ -1391,6 +1403,8 @@
>> 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()) {
>> @@ -1424,21 +1438,41 @@
>> emitCode("SDValue InFlag(0, 0);");
>> InFlagDecled = true;
>> }
>> - std::string Decl = (!ResNodeDecled) ? "SDNode *" : "";
>> - emitCode(Decl + "ResNode = CurDAG->getCopyToReg(" +
>> ChainName +
>> + 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 +
>> ", " + RootName + ".getDebugLoc()" +
>> ", " + getQualifiedName(RR) +
>> - ", " + RootName + utostr(OpNo) + ",
>> InFlag).getNode();");
>> - ResNodeDecled = true;
>> + ", " + RootName + utostr(OpNo) +
>> + ", InFlag).getNode();");
>> + }
>> emitCode(ChainName + " = SDValue(ResNode, 0);");
>> emitCode("InFlag = SDValue(ResNode, 1);");
>> + ResNodeDecled = true;
>> }
>> }
>> }
>> }
>> }
>>
>> - if (HasInFlag) {
>> + if (HasInFlag || (HasInI1 && !InFlagDefined)) {
>> if (!InFlagDecled) {
>> emitCode("SDValue InFlag = " + RootName +
>> ".getOperand(" + utostr(OpNo) + ");");
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list