aboutsummaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp45
-rw-r--r--lib/Target/X86/X86ISelLowering.h12
-rw-r--r--lib/Target/X86/X86Instr64bit.td86
-rw-r--r--lib/Target/X86/X86InstrInfo.td199
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]