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.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72707 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index dc15e4a..a221adf 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -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]