diff options
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 45 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 12 | ||||
-rw-r--r-- | lib/Target/X86/X86Instr64bit.td | 86 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 199 |
4 files changed, 265 insertions, 77 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 882ee3a01f..14406b5df1 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -190,6 +190,28 @@ 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 @@ -6475,6 +6497,21 @@ 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(); @@ -6543,6 +6580,10 @@ 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); @@ -6791,6 +6832,10 @@ 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"; } } diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 550f8bdf9b..78d95c0cdd 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -243,6 +243,14 @@ 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 }; @@ -576,7 +584,9 @@ 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); diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td index dc15e4aa4e..a221adf211 100644 --- a/lib/Target/X86/X86Instr64bit.td +++ b/lib/Target/X86/X86Instr64bit.td @@ -383,31 +383,52 @@ 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, (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 @@ 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, (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] diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 50ae417641..196c81740e 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -34,6 +34,11 @@ 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>]>; @@ -156,6 +161,8 @@ 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>; @@ -2274,81 +2281,127 @@ 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, (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 @@ 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, (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] |