[X86][NFC] Refactor X86InstrArithmetic.td by class
authorWang, Xin10 <xin10.wang@intel.com>
Wed, 22 Feb 2023 00:41:12 +0000 (08:41 +0800)
committerShengchen Kan <shengchen.kan@intel.com>
Wed, 22 Feb 2023 01:19:53 +0000 (09:19 +0800)
1. Extract the common code of some instructions into a class to reduce duplication
2. Refine some comments to the make the description of the class clearer

By this way, the records defined here will be consistent and easier to
maintain, I think.

Reviewed By: skan

Differential Revision: https://reviews.llvm.org/D144154

llvm/lib/Target/X86/X86InstrArithmetic.td
llvm/lib/Target/X86/X86InstrInfo.td

index 0fa79eb..6e2b636 100644 (file)
@@ -51,488 +51,6 @@ class SchedLoadReg<X86FoldableSchedWrite Sched> : Sched<[Sched.Folded,
   // Register reads (implicit or explicit).
   Sched.ReadAfterFold, Sched.ReadAfterFold]>;
 
-// Extra precision multiplication
-
-// AL is really implied by AX, but the registers in Defs must match the
-// SDNode results (i8, i32).
-// AL,AH = AL*GR8
-let Defs = [AL,EFLAGS,AX], Uses = [AL] in
-def MUL8r  : I<0xF6, MRM4r, (outs),  (ins GR8:$src), "mul{b}\t$src",
-               // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
-               // This probably ought to be moved to a def : Pat<> if the
-               // syntax can be accepted.
-               [(set AL, (mul AL, GR8:$src)),
-                (implicit EFLAGS)]>, Sched<[WriteIMul8]>;
-// AX,DX = AX*GR16
-let Defs = [AX,DX,EFLAGS], Uses = [AX], hasSideEffects = 0 in
-def MUL16r : I<0xF7, MRM4r, (outs),  (ins GR16:$src),
-               "mul{w}\t$src",
-               []>, OpSize16, Sched<[WriteIMul16]>;
-// EAX,EDX = EAX*GR32
-let Defs = [EAX,EDX,EFLAGS], Uses = [EAX], hasSideEffects = 0 in
-def MUL32r : I<0xF7, MRM4r, (outs),  (ins GR32:$src),
-               "mul{l}\t$src",
-               [/*(set EAX, EDX, EFLAGS, (X86umul_flag EAX, GR32:$src))*/]>,
-               OpSize32, Sched<[WriteIMul32]>;
-// RAX,RDX = RAX*GR64
-let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], hasSideEffects = 0 in
-def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
-                "mul{q}\t$src",
-                [/*(set RAX, RDX, EFLAGS, (X86umul_flag RAX, GR64:$src))*/]>,
-                Sched<[WriteIMul64]>;
-// AL,AH = AL*[mem8]
-let Defs = [AL,EFLAGS,AX], Uses = [AL] in
-def MUL8m  : I<0xF6, MRM4m, (outs), (ins i8mem :$src),
-               "mul{b}\t$src",
-               // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
-               // This probably ought to be moved to a def : Pat<> if the
-               // syntax can be accepted.
-               [(set AL, (mul AL, (loadi8 addr:$src))),
-                (implicit EFLAGS)]>, SchedLoadReg<WriteIMul8>;
-// AX,DX = AX*[mem16]
-let mayLoad = 1, hasSideEffects = 0 in {
-let Defs = [AX,DX,EFLAGS], Uses = [AX] in
-def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src),
-               "mul{w}\t$src", []>, OpSize16, SchedLoadReg<WriteIMul16>;
-// EAX,EDX = EAX*[mem32]
-let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
-def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
-              "mul{l}\t$src", []>, OpSize32, SchedLoadReg<WriteIMul32>;
-// RAX,RDX = RAX*[mem64]
-let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
-def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
-                "mul{q}\t$src", []>, SchedLoadReg<WriteIMul64>,
-                Requires<[In64BitMode]>;
-}
-
-let hasSideEffects = 0 in {
-// AL,AH = AL*GR8
-let Defs = [AL,EFLAGS,AX], Uses = [AL] in
-def IMUL8r  : I<0xF6, MRM5r, (outs),  (ins GR8:$src), "imul{b}\t$src", []>,
-                Sched<[WriteIMul8]>;
-// AX,DX = AX*GR16
-let Defs = [AX,DX,EFLAGS], Uses = [AX] in
-def IMUL16r : I<0xF7, MRM5r, (outs),  (ins GR16:$src), "imul{w}\t$src", []>,
-                OpSize16, Sched<[WriteIMul16]>;
-// EAX,EDX = EAX*GR32
-let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
-def IMUL32r : I<0xF7, MRM5r, (outs),  (ins GR32:$src), "imul{l}\t$src", []>,
-                OpSize32, Sched<[WriteIMul32]>;
-// RAX,RDX = RAX*GR64
-let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
-def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), "imul{q}\t$src", []>,
-                 Sched<[WriteIMul64]>;
-
-let mayLoad = 1 in {
-// AL,AH = AL*[mem8]
-let Defs = [AL,EFLAGS,AX], Uses = [AL] in
-def IMUL8m  : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
-                "imul{b}\t$src", []>, SchedLoadReg<WriteIMul8>;
-// AX,DX = AX*[mem16]
-let Defs = [AX,DX,EFLAGS], Uses = [AX] in
-def IMUL16m : I<0xF7, MRM5m, (outs), (ins i16mem:$src),
-                "imul{w}\t$src", []>, OpSize16, SchedLoadReg<WriteIMul16>;
-// EAX,EDX = EAX*[mem32]
-let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
-def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
-                "imul{l}\t$src", []>, OpSize32, SchedLoadReg<WriteIMul32>;
-// RAX,RDX = RAX*[mem64]
-let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
-def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
-                 "imul{q}\t$src", []>, SchedLoadReg<WriteIMul64>,
-                 Requires<[In64BitMode]>;
-}
-} // hasSideEffects
-
-
-let Defs = [EFLAGS] in {
-let Constraints = "$src1 = $dst" in {
-
-let isCommutable = 1 in {
-// X = IMUL Y, Z --> X = IMUL Z, Y
-// Register-Register Signed Integer Multiply
-def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src1,GR16:$src2),
-                 "imul{w}\t{$src2, $dst|$dst, $src2}",
-                 [(set GR16:$dst, EFLAGS,
-                       (X86smul_flag GR16:$src1, GR16:$src2))]>,
-                 Sched<[WriteIMul16Reg]>, TB, OpSize16;
-def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1,GR32:$src2),
-                 "imul{l}\t{$src2, $dst|$dst, $src2}",
-                 [(set GR32:$dst, EFLAGS,
-                       (X86smul_flag GR32:$src1, GR32:$src2))]>,
-                 Sched<[WriteIMul32Reg]>, TB, OpSize32;
-def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
-                                   (ins GR64:$src1, GR64:$src2),
-                  "imul{q}\t{$src2, $dst|$dst, $src2}",
-                  [(set GR64:$dst, EFLAGS,
-                        (X86smul_flag GR64:$src1, GR64:$src2))]>,
-                  Sched<[WriteIMul64Reg]>, TB;
-} // isCommutable
-
-// Register-Memory Signed Integer Multiply
-def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst),
-                                  (ins GR16:$src1, i16mem:$src2),
-                 "imul{w}\t{$src2, $dst|$dst, $src2}",
-                 [(set GR16:$dst, EFLAGS,
-                       (X86smul_flag GR16:$src1, (loadi16 addr:$src2)))]>,
-                 Sched<[WriteIMul16Reg.Folded, WriteIMul16Reg.ReadAfterFold]>, TB, OpSize16;
-def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst),
-                 (ins GR32:$src1, i32mem:$src2),
-                 "imul{l}\t{$src2, $dst|$dst, $src2}",
-                 [(set GR32:$dst, EFLAGS,
-                       (X86smul_flag GR32:$src1, (loadi32 addr:$src2)))]>,
-                 Sched<[WriteIMul32Reg.Folded, WriteIMul32Reg.ReadAfterFold]>, TB, OpSize32;
-def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
-                                   (ins GR64:$src1, i64mem:$src2),
-                  "imul{q}\t{$src2, $dst|$dst, $src2}",
-                  [(set GR64:$dst, EFLAGS,
-                        (X86smul_flag GR64:$src1, (loadi64 addr:$src2)))]>,
-                  Sched<[WriteIMul64Reg.Folded, WriteIMul32Reg.ReadAfterFold]>, TB;
-} // Constraints = "$src1 = $dst"
-
-} // Defs = [EFLAGS]
-
-// Surprisingly enough, these are not two address instructions!
-let Defs = [EFLAGS] in {
-// NOTE: These are order specific, we want the ri8 forms to be listed
-// first so that they are slightly preferred to the ri forms.
-
-// Register-Integer Signed Integer Multiply
-def IMUL16rri8 : Ii8<0x6B, MRMSrcReg,                       // GR16 = GR16*I8
-                     (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
-                     "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                     [(set GR16:$dst, EFLAGS,
-                           (X86smul_flag GR16:$src1, i16immSExt8:$src2))]>,
-                     Sched<[WriteIMul16Imm]>, OpSize16;
-def IMUL16rri  : Ii16<0x69, MRMSrcReg,                      // GR16 = GR16*I16
-                      (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
-                      "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                      [(set GR16:$dst, EFLAGS,
-                            (X86smul_flag GR16:$src1, imm:$src2))]>,
-                      Sched<[WriteIMul16Imm]>, OpSize16;
-def IMUL32rri  : Ii32<0x69, MRMSrcReg,                      // GR32 = GR32*I32
-                      (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
-                      "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                      [(set GR32:$dst, EFLAGS,
-                            (X86smul_flag GR32:$src1, imm:$src2))]>,
-                      Sched<[WriteIMul32Imm]>, OpSize32;
-def IMUL32rri8 : Ii8<0x6B, MRMSrcReg,                       // GR32 = GR32*I8
-                     (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
-                     "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                     [(set GR32:$dst, EFLAGS,
-                           (X86smul_flag GR32:$src1, i32immSExt8:$src2))]>,
-                     Sched<[WriteIMul32Imm]>, OpSize32;
-def IMUL64rri8 : RIi8<0x6B, MRMSrcReg,                      // GR64 = GR64*I8
-                      (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
-                      "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                      [(set GR64:$dst, EFLAGS,
-                            (X86smul_flag GR64:$src1, i64immSExt8:$src2))]>,
-                      Sched<[WriteIMul64Imm]>;
-def IMUL64rri32 : RIi32S<0x69, MRMSrcReg,                    // GR64 = GR64*I32
-                         (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
-                         "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                         [(set GR64:$dst, EFLAGS,
-                             (X86smul_flag GR64:$src1, i64immSExt32:$src2))]>,
-                         Sched<[WriteIMul64Imm]>;
-
-// Memory-Integer Signed Integer Multiply
-def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem,                       // GR16 = [mem16]*I8
-                     (outs GR16:$dst), (ins i16mem:$src1, i16i8imm :$src2),
-                     "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                     [(set GR16:$dst, EFLAGS,
-                           (X86smul_flag (loadi16 addr:$src1),
-                                         i16immSExt8:$src2))]>,
-                     Sched<[WriteIMul16Imm.Folded]>, OpSize16;
-def IMUL16rmi  : Ii16<0x69, MRMSrcMem,                     // GR16 = [mem16]*I16
-                      (outs GR16:$dst), (ins i16mem:$src1, i16imm:$src2),
-                      "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                      [(set GR16:$dst, EFLAGS,
-                            (X86smul_flag (loadi16 addr:$src1), imm:$src2))]>,
-                      Sched<[WriteIMul16Imm.Folded]>, OpSize16;
-def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem,                       // GR32 = [mem32]*I8
-                     (outs GR32:$dst), (ins i32mem:$src1, i32i8imm: $src2),
-                     "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                     [(set GR32:$dst, EFLAGS,
-                           (X86smul_flag (loadi32 addr:$src1),
-                                         i32immSExt8:$src2))]>,
-                     Sched<[WriteIMul32Imm.Folded]>, OpSize32;
-def IMUL32rmi  : Ii32<0x69, MRMSrcMem,                     // GR32 = [mem32]*I32
-                      (outs GR32:$dst), (ins i32mem:$src1, i32imm:$src2),
-                      "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                      [(set GR32:$dst, EFLAGS,
-                            (X86smul_flag (loadi32 addr:$src1), imm:$src2))]>,
-                      Sched<[WriteIMul32Imm.Folded]>, OpSize32;
-def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem,                      // GR64 = [mem64]*I8
-                      (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
-                      "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                      [(set GR64:$dst, EFLAGS,
-                            (X86smul_flag (loadi64 addr:$src1),
-                                          i64immSExt8:$src2))]>,
-                      Sched<[WriteIMul64Imm.Folded]>;
-def IMUL64rmi32 : RIi32S<0x69, MRMSrcMem,                   // GR64 = [mem64]*I32
-                         (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
-                         "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
-                         [(set GR64:$dst, EFLAGS,
-                              (X86smul_flag (loadi64 addr:$src1),
-                                            i64immSExt32:$src2))]>,
-                         Sched<[WriteIMul64Imm.Folded]>;
-} // Defs = [EFLAGS]
-
-// unsigned division/remainder
-let hasSideEffects = 1 in { // so that we don't speculatively execute
-let Defs = [AL,AH,EFLAGS], Uses = [AX] in
-def DIV8r  : I<0xF6, MRM6r, (outs),  (ins GR8:$src),    // AX/r8 = AL,AH
-               "div{b}\t$src", []>, Sched<[WriteDiv8]>;
-let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
-def DIV16r : I<0xF7, MRM6r, (outs),  (ins GR16:$src),   // DX:AX/r16 = AX,DX
-               "div{w}\t$src", []>, Sched<[WriteDiv16]>, OpSize16;
-let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
-def DIV32r : I<0xF7, MRM6r, (outs),  (ins GR32:$src),   // EDX:EAX/r32 = EAX,EDX
-               "div{l}\t$src", []>, Sched<[WriteDiv32]>, OpSize32;
-// RDX:RAX/r64 = RAX,RDX
-let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
-def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),
-                "div{q}\t$src", []>, Sched<[WriteDiv64]>;
-
-let mayLoad = 1 in {
-let Defs = [AL,AH,EFLAGS], Uses = [AX] in
-def DIV8m  : I<0xF6, MRM6m, (outs), (ins i8mem:$src),   // AX/[mem8] = AL,AH
-               "div{b}\t$src", []>, SchedLoadReg<WriteDiv8>;
-let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
-def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src),  // DX:AX/[mem16] = AX,DX
-               "div{w}\t$src", []>, OpSize16, SchedLoadReg<WriteDiv16>;
-let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
-def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src),
-               "div{l}\t$src", []>, SchedLoadReg<WriteDiv32>, OpSize32;
-// RDX:RAX/[mem64] = RAX,RDX
-let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
-def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),
-                "div{q}\t$src", []>, SchedLoadReg<WriteDiv64>,
-                Requires<[In64BitMode]>;
-}
-
-// Signed division/remainder.
-let Defs = [AL,AH,EFLAGS], Uses = [AX] in
-def IDIV8r : I<0xF6, MRM7r, (outs),  (ins GR8:$src),    // AX/r8 = AL,AH
-               "idiv{b}\t$src", []>, Sched<[WriteIDiv8]>;
-let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
-def IDIV16r: I<0xF7, MRM7r, (outs),  (ins GR16:$src),   // DX:AX/r16 = AX,DX
-               "idiv{w}\t$src", []>, Sched<[WriteIDiv16]>, OpSize16;
-let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
-def IDIV32r: I<0xF7, MRM7r, (outs),  (ins GR32:$src),   // EDX:EAX/r32 = EAX,EDX
-               "idiv{l}\t$src", []>, Sched<[WriteIDiv32]>, OpSize32;
-// RDX:RAX/r64 = RAX,RDX
-let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
-def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),
-                "idiv{q}\t$src", []>, Sched<[WriteIDiv64]>;
-
-let mayLoad = 1 in {
-let Defs = [AL,AH,EFLAGS], Uses = [AX] in
-def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src),   // AX/[mem8] = AL,AH
-               "idiv{b}\t$src", []>, SchedLoadReg<WriteIDiv8>;
-let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
-def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src),  // DX:AX/[mem16] = AX,DX
-               "idiv{w}\t$src", []>, OpSize16, SchedLoadReg<WriteIDiv16>;
-let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
-def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src),
-               "idiv{l}\t$src", []>, OpSize32, SchedLoadReg<WriteIDiv32>;
-let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in // RDX:RAX/[mem64] = RAX,RDX
-def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src),
-                "idiv{q}\t$src", []>, SchedLoadReg<WriteIDiv64>,
-                Requires<[In64BitMode]>;
-}
-} // hasSideEffects = 0
-
-//===----------------------------------------------------------------------===//
-//  Two address Instructions.
-//
-
-// unary instructions
-let CodeSize = 2 in {
-let Defs = [EFLAGS] in {
-let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
-def NEG8r  : I<0xF6, MRM3r, (outs GR8 :$dst), (ins GR8 :$src1),
-               "neg{b}\t$dst",
-               [(set GR8:$dst, (ineg GR8:$src1)),
-                (implicit EFLAGS)]>;
-def NEG16r : I<0xF7, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
-               "neg{w}\t$dst",
-               [(set GR16:$dst, (ineg GR16:$src1)),
-                (implicit EFLAGS)]>, OpSize16;
-def NEG32r : I<0xF7, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
-               "neg{l}\t$dst",
-               [(set GR32:$dst, (ineg GR32:$src1)),
-                (implicit EFLAGS)]>, OpSize32;
-def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src1), "neg{q}\t$dst",
-                [(set GR64:$dst, (ineg GR64:$src1)),
-                 (implicit EFLAGS)]>;
-} // Constraints = "$src1 = $dst", SchedRW
-
-// Read-modify-write negate.
-let SchedRW = [WriteALURMW] in {
-def NEG8m  : I<0xF6, MRM3m, (outs), (ins i8mem :$dst),
-               "neg{b}\t$dst",
-               [(store (ineg (loadi8 addr:$dst)), addr:$dst),
-                (implicit EFLAGS)]>;
-def NEG16m : I<0xF7, MRM3m, (outs), (ins i16mem:$dst),
-               "neg{w}\t$dst",
-               [(store (ineg (loadi16 addr:$dst)), addr:$dst),
-                (implicit EFLAGS)]>, OpSize16;
-def NEG32m : I<0xF7, MRM3m, (outs), (ins i32mem:$dst),
-               "neg{l}\t$dst",
-               [(store (ineg (loadi32 addr:$dst)), addr:$dst),
-                (implicit EFLAGS)]>, OpSize32;
-def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
-                [(store (ineg (loadi64 addr:$dst)), addr:$dst),
-                 (implicit EFLAGS)]>,
-                Requires<[In64BitMode]>;
-} // SchedRW
-} // Defs = [EFLAGS]
-
-
-// Note: NOT does not set EFLAGS!
-
-let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
-def NOT8r  : I<0xF6, MRM2r, (outs GR8 :$dst), (ins GR8 :$src1),
-               "not{b}\t$dst",
-               [(set GR8:$dst, (not GR8:$src1))]>;
-def NOT16r : I<0xF7, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
-               "not{w}\t$dst",
-               [(set GR16:$dst, (not GR16:$src1))]>, OpSize16;
-def NOT32r : I<0xF7, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
-               "not{l}\t$dst",
-               [(set GR32:$dst, (not GR32:$src1))]>, OpSize32;
-def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src1), "not{q}\t$dst",
-                [(set GR64:$dst, (not GR64:$src1))]>;
-} // Constraints = "$src1 = $dst", SchedRW
-
-let SchedRW = [WriteALURMW] in {
-def NOT8m  : I<0xF6, MRM2m, (outs), (ins i8mem :$dst),
-               "not{b}\t$dst",
-               [(store (not (loadi8 addr:$dst)), addr:$dst)]>;
-def NOT16m : I<0xF7, MRM2m, (outs), (ins i16mem:$dst),
-               "not{w}\t$dst",
-               [(store (not (loadi16 addr:$dst)), addr:$dst)]>,
-               OpSize16;
-def NOT32m : I<0xF7, MRM2m, (outs), (ins i32mem:$dst),
-               "not{l}\t$dst",
-               [(store (not (loadi32 addr:$dst)), addr:$dst)]>,
-               OpSize32;
-def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
-                [(store (not (loadi64 addr:$dst)), addr:$dst)]>,
-                Requires<[In64BitMode]>;
-} // SchedRW
-} // CodeSize
-
-def X86add_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
-                               (X86add_flag node:$lhs, node:$rhs), [{
-  return hasNoCarryFlagUses(SDValue(N, 1));
-}]>;
-
-def X86sub_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
-                               (X86sub_flag node:$lhs, node:$rhs), [{
-  // Only use DEC if the result is used.
-  return !SDValue(N, 0).use_empty() && hasNoCarryFlagUses(SDValue(N, 1));
-}]>;
-
-// TODO: inc/dec is slow for P4, but fast for Pentium-M.
-let Defs = [EFLAGS] in {
-let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
-let isConvertibleToThreeAddress = 1, CodeSize = 2 in { // Can xform into LEA.
-def INC8r  : I<0xFE, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
-               "inc{b}\t$dst",
-               [(set GR8:$dst, EFLAGS, (X86add_flag_nocf GR8:$src1, 1))]>;
-def INC16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
-               "inc{w}\t$dst",
-               [(set GR16:$dst, EFLAGS, (X86add_flag_nocf GR16:$src1, 1))]>,
-               OpSize16;
-def INC32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
-               "inc{l}\t$dst",
-               [(set GR32:$dst, EFLAGS, (X86add_flag_nocf GR32:$src1, 1))]>,
-               OpSize32;
-def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "inc{q}\t$dst",
-                [(set GR64:$dst, EFLAGS, (X86add_flag_nocf GR64:$src1, 1))]>;
-} // isConvertibleToThreeAddress = 1, CodeSize = 2
-
-// Short forms only valid in 32-bit mode. Selected during MCInst lowering.
-let CodeSize = 1, hasSideEffects = 0 in {
-def INC16r_alt : I<0x40, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
-                   "inc{w}\t$dst", []>,
-                 OpSize16, Requires<[Not64BitMode]>;
-def INC32r_alt : I<0x40, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
-                   "inc{l}\t$dst", []>,
-                 OpSize32, Requires<[Not64BitMode]>;
-} // CodeSize = 1, hasSideEffects = 0
-} // Constraints = "$src1 = $dst", SchedRW
-
-let CodeSize = 2, SchedRW = [WriteALURMW] in {
-let Predicates = [UseIncDec] in {
-  def INC8m  : I<0xFE, MRM0m, (outs), (ins i8mem :$dst), "inc{b}\t$dst",
-               [(store (add (loadi8 addr:$dst), 1), addr:$dst),
-                (implicit EFLAGS)]>;
-  def INC16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
-               [(store (add (loadi16 addr:$dst), 1), addr:$dst),
-                (implicit EFLAGS)]>, OpSize16;
-  def INC32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
-               [(store (add (loadi32 addr:$dst), 1), addr:$dst),
-                (implicit EFLAGS)]>, OpSize32;
-} // Predicates
-let Predicates = [UseIncDec, In64BitMode] in {
-  def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
-                  [(store (add (loadi64 addr:$dst), 1), addr:$dst),
-                   (implicit EFLAGS)]>;
-} // Predicates
-} // CodeSize = 2, SchedRW
-
-let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
-let isConvertibleToThreeAddress = 1, CodeSize = 2 in { // Can xform into LEA.
-def DEC8r  : I<0xFE, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
-               "dec{b}\t$dst",
-               [(set GR8:$dst, EFLAGS, (X86sub_flag_nocf GR8:$src1, 1))]>;
-def DEC16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
-               "dec{w}\t$dst",
-               [(set GR16:$dst, EFLAGS, (X86sub_flag_nocf GR16:$src1, 1))]>,
-               OpSize16;
-def DEC32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
-               "dec{l}\t$dst",
-               [(set GR32:$dst, EFLAGS, (X86sub_flag_nocf GR32:$src1, 1))]>,
-               OpSize32;
-def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src1), "dec{q}\t$dst",
-                [(set GR64:$dst, EFLAGS, (X86sub_flag_nocf GR64:$src1, 1))]>;
-} // isConvertibleToThreeAddress = 1, CodeSize = 2
-
-// Short forms only valid in 32-bit mode. Selected during MCInst lowering.
-let CodeSize = 1, hasSideEffects = 0 in {
-def DEC16r_alt : I<0x48, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
-                   "dec{w}\t$dst", []>,
-                 OpSize16, Requires<[Not64BitMode]>;
-def DEC32r_alt : I<0x48, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
-                   "dec{l}\t$dst", []>,
-                 OpSize32, Requires<[Not64BitMode]>;
-} // CodeSize = 1, hasSideEffects = 0
-} // Constraints = "$src1 = $dst", SchedRW
-
-
-let CodeSize = 2, SchedRW = [WriteALURMW] in {
-let Predicates = [UseIncDec] in {
-  def DEC8m  : I<0xFE, MRM1m, (outs), (ins i8mem :$dst), "dec{b}\t$dst",
-               [(store (add (loadi8 addr:$dst), -1), addr:$dst),
-                (implicit EFLAGS)]>;
-  def DEC16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
-               [(store (add (loadi16 addr:$dst), -1), addr:$dst),
-                (implicit EFLAGS)]>, OpSize16;
-  def DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
-               [(store (add (loadi32 addr:$dst), -1), addr:$dst),
-                (implicit EFLAGS)]>, OpSize32;
-} // Predicates
-let Predicates = [UseIncDec, In64BitMode] in {
-  def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
-                  [(store (add (loadi64 addr:$dst), -1), addr:$dst),
-                   (implicit EFLAGS)]>;
-} // Predicates
-} // CodeSize = 2, SchedRW
-} // Defs = [EFLAGS]
-
 /// ITy - This instruction base class takes the type info for the instruction.
 /// Using this, it:
 /// 1. Concatenates together the instruction mnemonic with the appropriate
@@ -553,7 +71,7 @@ class ITy<bits<8> opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins,
   let hasREX_W  = typeinfo.HasREX_W;
 }
 
-// BinOpRR - Instructions like "add reg, reg, reg".
+// BinOpRR - Binary instructions with inputs "reg, reg".
 class BinOpRR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
               dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
   : ITy<opcode, MRMDestReg, typeinfo, outlist,
@@ -561,24 +79,24 @@ class BinOpRR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
         mnemonic, "{$src2, $src1|$src1, $src2}", pattern>,
     Sched<[sched]>;
 
-// BinOpRR_F - Instructions like "cmp reg, Reg", where the pattern has
-// just a EFLAGS as a result.
+// BinOpRR_F - Binary instructions with inputs "reg, reg", where the pattern
+// has just a EFLAGS as a result.
 class BinOpRR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                 SDPatternOperator opnode>
   : BinOpRR<opcode, mnemonic, typeinfo, (outs), WriteALU,
             [(set EFLAGS,
                   (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))]>;
 
-// BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has
-// both a regclass and EFLAGS as a result.
+// BinOpRR_RF - Binary instructions with inputs "reg, reg", where the pattern
+// has both a regclass and EFLAGS as a result.
 class BinOpRR_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                  SDNode opnode>
   : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteALU,
             [(set typeinfo.RegClass:$dst, EFLAGS,
                   (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))]>;
 
-// BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has
-// both a regclass and EFLAGS as a result, and has EFLAGS as input.
+// BinOpRR_RFF - Binary instructions with inputs "reg, reg", where the pattern
+// has both a regclass and EFLAGS as a result, and has EFLAGS as input.
 class BinOpRR_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                   SDNode opnode>
   : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteADC,
@@ -586,7 +104,7 @@ class BinOpRR_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                   (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2,
                           EFLAGS))]>;
 
-// BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding).
+// BinOpRR_Rev - Binary instructions with inputs "reg, reg"(reversed encoding).
 class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                   X86FoldableSchedWrite sched = WriteALU>
   : ITy<opcode, MRMSrcReg, typeinfo,
@@ -600,11 +118,13 @@ class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
   let hasSideEffects = 0;
 }
 
-// BinOpRR_RDD_Rev - Instructions like "adc reg, reg, reg" (reversed encoding).
+// BinOpRR_RFF_Rev - Binary instructions with inputs "reg, reg"(reversed 
+// encoding), with sched = WriteADC.
 class BinOpRR_RFF_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
   : BinOpRR_Rev<opcode, mnemonic, typeinfo, WriteADC>;
 
-// BinOpRR_F_Rev - Instructions like "cmp reg, reg" (reversed encoding).
+// BinOpRR_F_Rev - Binary instructions with inputs "reg, reg"(reversed 
+// encoding), without outlist dag.
 class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
   : ITy<opcode, MRMSrcReg, typeinfo, (outs),
         (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
@@ -616,7 +136,7 @@ class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
   let hasSideEffects = 0;
 }
 
-// BinOpRM - Instructions like "add reg, reg, [mem]".
+// BinOpRM - Binary instructions with inputs "reg, [mem]".
 class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
               dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
   : ITy<opcode, MRMSrcMem, typeinfo, outlist,
@@ -624,10 +144,10 @@ class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
         mnemonic, "{$src2, $src1|$src1, $src2}", pattern>,
     Sched<[sched.Folded, sched.ReadAfterFold]>;
 
-// BinOpRM - Instructions like "adc reg, reg, [mem]".
+// BinOpRM_ImplicitUse - Binary instructions with inputs "reg, [mem]".
 // There is an implicit register read at the end of the operand sequence.
 class BinOpRM_ImplicitUse<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
-              dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
+                          dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
   : ITy<opcode, MRMSrcMem, typeinfo, outlist,
         (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2),
         mnemonic, "{$src2, $src1|$src1, $src2}", pattern>,
@@ -637,29 +157,33 @@ class BinOpRM_ImplicitUse<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
            // implicit register read.
            sched.ReadAfterFold]>;
 
-// BinOpRM_F - Instructions like "cmp reg, [mem]".
+// BinOpRM_F - Binary instructions with inputs "reg, [mem]", where the pattern
+// has just a EFLAGS as a result.
 class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                 SDNode opnode>
   : BinOpRM<opcode, mnemonic, typeinfo, (outs), WriteALU,
             [(set EFLAGS,
             (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
 
-// BinOpRM_RF - Instructions like "add reg, reg, [mem]".
+// BinOpRM_RF - Binary instructions with inputs "reg, [mem]", where the pattern
+// has both a regclass and EFLAGS as a result.
 class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                  SDNode opnode>
   : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteALU,
             [(set typeinfo.RegClass:$dst, EFLAGS,
             (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
 
-// BinOpRM_RFF - Instructions like "adc reg, reg, [mem]".
+// BinOpRM_RFF - Binary instructions with inputs "reg, [mem]", where the pattern
+// has both a regclass and EFLAGS as a result, and has EFLAGS as input.
 class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
-                 SDNode opnode>
-  : BinOpRM_ImplicitUse<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteADC,
-            [(set typeinfo.RegClass:$dst, EFLAGS,
-            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2),
-                    EFLAGS))]>;
+                  SDNode opnode>
+  : BinOpRM_ImplicitUse<opcode, mnemonic, typeinfo, 
+                        (outs typeinfo.RegClass:$dst), WriteADC,
+                        [(set typeinfo.RegClass:$dst, EFLAGS,
+                         (opnode typeinfo.RegClass:$src1, 
+                         (typeinfo.LoadNode addr:$src2), EFLAGS))]>;
 
-// BinOpRI - Instructions like "add reg, reg, imm".
+// BinOpRI - Binary instructions with inputs "reg, imm".
 class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
               Format f, dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
   : ITy<opcode, f, typeinfo, outlist,
@@ -669,28 +193,32 @@ class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
   let ImmT = typeinfo.ImmEncoding;
 }
 
-// BinOpRI_F - Instructions like "cmp reg, imm".
+// BinOpRI_F - Binary instructions with inputs "reg, imm", where the pattern
+// has EFLAGS as a result.
 class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                 SDPatternOperator opnode, Format f>
   : BinOpRI<opcode, mnemonic, typeinfo, f, (outs), WriteALU,
             [(set EFLAGS,
                 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
 
-// BinOpRI_RF - Instructions like "add reg, reg, imm".
+// BinOpRI_RF - Binary instructions with inputs "reg, imm", where the pattern
+// has both a regclass and EFLAGS as a result.
 class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                  SDNode opnode, Format f>
   : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteALU,
             [(set typeinfo.RegClass:$dst, EFLAGS,
                 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
-// BinOpRI_RFF - Instructions like "adc reg, reg, imm".
+
+// BinOpRI_RFF - Binary instructions with inputs "reg, imm", where the pattern
+// has both a regclass and EFLAGS as a result, and has EFLAGS as input.
 class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
-                 SDNode opnode, Format f>
+                  SDNode opnode, Format f>
   : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteADC,
             [(set typeinfo.RegClass:$dst, EFLAGS,
                 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2,
                         EFLAGS))]>;
 
-// BinOpRI8 - Instructions like "add reg, reg, imm8".
+// BinOpRI8 - Binary instructions with inputs "reg, imm8".
 class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                Format f, dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
   : ITy<opcode, f, typeinfo, outlist,
@@ -700,21 +228,24 @@ class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
   let ImmT = Imm8; // Always 8-bit immediate.
 }
 
-// BinOpRI8_F - Instructions like "cmp reg, imm8".
+// BinOpRI8_F - Binary instructions with inputs "reg, imm8", where the pattern
+// has EFLAGS as a result.
 class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                   SDPatternOperator opnode, Format f>
   : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs), WriteALU,
              [(set EFLAGS,
                (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
 
-// BinOpRI8_RF - Instructions like "add reg, reg, imm8".
+// BinOpRI8_RF - Binary instructions with inputs "reg, imm8", where the pattern
+// has both a regclass and EFLAGS as a result.
 class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                   SDPatternOperator opnode, Format f>
   : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteALU,
              [(set typeinfo.RegClass:$dst, EFLAGS,
                (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
 
-// BinOpRI8_RFF - Instructions like "adc reg, reg, imm8".
+// BinOpRI8_RFF - Binary instructions with inputs "reg, imm8", where the pattern
+// has both a regclass and EFLAGS as a result, and has EFLAGS as input.
 class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                    SDPatternOperator opnode, Format f>
   : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteADC,
@@ -722,47 +253,52 @@ class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2,
                        EFLAGS))]>;
 
-// BinOpMR - Instructions like "add [mem], reg".
+// BinOpMR - Binary instructions with inputs "[mem], reg".
 class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
               list<dag> pattern>
   : ITy<opcode, MRMDestMem, typeinfo,
         (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src),
         mnemonic, "{$src, $dst|$dst, $src}", pattern>;
 
-// BinOpMR_RMW - Instructions like "add [mem], reg".
+// BinOpMR_RMW - Binary instructions with inputs "[mem], reg", where the pattern
+// implicitly use EFLAGS.
 class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                   SDNode opnode>
   : BinOpMR<opcode, mnemonic, typeinfo,
-          [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst),
-           (implicit EFLAGS)]>, Sched<[WriteALURMW,
-                                       // base, scale, index, offset, segment
-                                       ReadDefault, ReadDefault, ReadDefault,
-                                       ReadDefault, ReadDefault,
-                                       WriteALU.ReadAfterFold]>;  // reg
-
-// BinOpMR_RMW_FF - Instructions like "adc [mem], reg".
+            [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst),
+             (implicit EFLAGS)]>, 
+    Sched<[WriteALURMW,
+           // base, scale, index, offset, segment
+           ReadDefault, ReadDefault, ReadDefault,
+           ReadDefault, ReadDefault,
+           WriteALU.ReadAfterFold]>;  // reg
+
+// BinOpMR_RMW_FF - Binary instructions with inputs "[mem], reg", where the 
+// pattern use EFLAGS as operand and implicitly use EFLAGS.
 class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                     SDNode opnode>
   : BinOpMR<opcode, mnemonic, typeinfo,
             [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS),
                     addr:$dst),
-             (implicit EFLAGS)]>, Sched<[WriteADCRMW,
-                                         // base, scale, index, offset, segment
-                                         ReadDefault, ReadDefault, ReadDefault,
-                                         ReadDefault, ReadDefault,
-                                         WriteALU.ReadAfterFold,    // reg
-                                         WriteALU.ReadAfterFold]>;  // EFLAGS
-
-// BinOpMR_F - Instructions like "cmp [mem], reg".
+             (implicit EFLAGS)]>, 
+    Sched<[WriteADCRMW,
+          // base, scale, index, offset, segment
+          ReadDefault, ReadDefault, ReadDefault,
+          ReadDefault, ReadDefault,
+          WriteALU.ReadAfterFold,    // reg
+          WriteALU.ReadAfterFold]>;  // EFLAGS
+
+// BinOpMR_F - Binary instructions with inputs "[mem], reg", where the pattern
+// has EFLAGS as a result.
 class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                 SDPatternOperator opnode>
   : BinOpMR<opcode, mnemonic, typeinfo,
             [(set EFLAGS, (opnode (typeinfo.LoadNode addr:$dst),
                                    typeinfo.RegClass:$src))]>,
-            Sched<[WriteALU.Folded, ReadDefault, ReadDefault, ReadDefault,
-                   ReadDefault, ReadDefault, WriteALU.ReadAfterFold]>;
+    Sched<[WriteALU.Folded, ReadDefault, ReadDefault, ReadDefault,
+            ReadDefault, ReadDefault, WriteALU.ReadAfterFold]>;
 
-// BinOpMI - Instructions like "add [mem], imm".
+// BinOpMI - Binary instructions with inputs "[mem], imm".
 class BinOpMI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
               Format f, list<dag> pattern>
   : ITy<opcode, f, typeinfo,
@@ -771,30 +307,36 @@ class BinOpMI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
   let ImmT = typeinfo.ImmEncoding;
 }
 
-// BinOpMI_RMW - Instructions like "add [mem], imm".
+// BinOpMI_RMW - Binary instructions with inputs "add [mem], imm", where the
+// pattern implicitly use EFLAGS.
 class BinOpMI_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                   SDNode opnode, Format f>
   : BinOpMI<opcode, mnemonic, typeinfo, f,
             [(store (opnode (typeinfo.VT (load addr:$dst)),
                             typeinfo.ImmOperator:$src), addr:$dst),
-             (implicit EFLAGS)]>, Sched<[WriteALURMW]>;
-// BinOpMI_RMW_FF - Instructions like "adc [mem], imm".
+             (implicit EFLAGS)]>, 
+    Sched<[WriteALURMW]>;
+
+// BinOpMI_RMW_FF - Binary instructions with inputs "[mem], imm", where the
+// pattern use EFLAGS as operand and implicitly use EFLAGS.
 class BinOpMI_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                      SDNode opnode, Format f>
   : BinOpMI<opcode, mnemonic, typeinfo, f,
             [(store (opnode (typeinfo.VT (load addr:$dst)),
                              typeinfo.ImmOperator:$src, EFLAGS), addr:$dst),
-             (implicit EFLAGS)]>, Sched<[WriteADCRMW]>;
+                             (implicit EFLAGS)]>, 
+    Sched<[WriteADCRMW]>;
 
-// BinOpMI_F - Instructions like "cmp [mem], imm".
+// BinOpMI_F - Binary instructions with inputs "[mem], imm", where the pattern
+// has EFLAGS as a result.
 class BinOpMI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                 SDPatternOperator opnode, Format f>
   : BinOpMI<opcode, mnemonic, typeinfo, f,
             [(set EFLAGS, (opnode (typeinfo.LoadNode addr:$dst),
                                   typeinfo.ImmOperator:$src))]>,
-            Sched<[WriteALU.Folded]>;
+    Sched<[WriteALU.Folded]>;
 
-// BinOpMI8 - Instructions like "add [mem], imm8".
+// BinOpMI8 - Binary instructions with inputs "[mem], imm8".
 class BinOpMI8<string mnemonic, X86TypeInfo typeinfo,
                Format f, list<dag> pattern>
   : ITy<0x82, f, typeinfo,
@@ -803,57 +345,514 @@ class BinOpMI8<string mnemonic, X86TypeInfo typeinfo,
   let ImmT = Imm8; // Always 8-bit immediate.
 }
 
-// BinOpMI8_RMW - Instructions like "add [mem], imm8".
+// BinOpMI8_RMW - Binary instructions with inputs "[mem], imm8", where the
+// pattern implicitly use EFLAGS.
 class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo,
                    SDPatternOperator opnode, Format f>
   : BinOpMI8<mnemonic, typeinfo, f,
              [(store (opnode (load addr:$dst),
                              typeinfo.Imm8Operator:$src), addr:$dst),
-              (implicit EFLAGS)]>, Sched<[WriteALURMW]>;
+              (implicit EFLAGS)]>, 
+    Sched<[WriteALURMW]>;
 
-// BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8".
+// BinOpMI8_RMW_FF - Binary instructions with inputs "[mem], imm8", where the
+// pattern use EFLAGS as operand and implicitly use EFLAGS.
 class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
                       SDPatternOperator opnode, Format f>
   : BinOpMI8<mnemonic, typeinfo, f,
              [(store (opnode (load addr:$dst),
                              typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst),
-              (implicit EFLAGS)]>, Sched<[WriteADCRMW]>;
+              (implicit EFLAGS)]>, 
+    Sched<[WriteADCRMW]>;
 
-// BinOpMI8_F - Instructions like "cmp [mem], imm8".
+// BinOpMI8_F - Binary instructions with inputs "[mem], imm8", where the pattern
+// has EFLAGS as a result.
 class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo,
                  SDPatternOperator opnode, Format f>
   : BinOpMI8<mnemonic, typeinfo, f,
              [(set EFLAGS, (opnode (typeinfo.LoadNode addr:$dst),
                                     typeinfo.Imm8Operator:$src))]>,
-             Sched<[WriteALU.Folded]>;
+    Sched<[WriteALU.Folded]>;
 
-// BinOpAI - Instructions like "add %eax, %eax, imm", that imp-def EFLAGS.
+// BinOpAI - Binary instructions with input imm, that implicitly use A reg and
+// implicitly define Areg and EFLAGS.
 class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
               Register areg, string operands, X86FoldableSchedWrite sched = WriteALU>
   : ITy<opcode, RawFrm, typeinfo,
         (outs), (ins typeinfo.ImmOperand:$src),
-        mnemonic, operands, []>, Sched<[sched]> {
+        mnemonic, operands, []>, 
+    Sched<[sched]> {
   let ImmT = typeinfo.ImmEncoding;
   let Uses = [areg];
   let Defs = [areg, EFLAGS];
   let hasSideEffects = 0;
 }
 
-// BinOpAI_RFF - Instructions like "adc %eax, %eax, imm", that implicitly define
-// and use EFLAGS.
+// BinOpAI_RFF - Binary instructions with input imm, that implicitly use and
+// define Areg and EFLAGS.
 class BinOpAI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                   Register areg, string operands>
   : BinOpAI<opcode, mnemonic, typeinfo, areg, operands, WriteADC> {
   let Uses = [areg, EFLAGS];
 }
 
-// BinOpAI_F - Instructions like "cmp %eax, %eax, imm", that imp-def EFLAGS.
+// BinOpAI_F - Binary instructions with input imm, that implicitly use A reg and
+// implicitly define EFLAGS.
 class BinOpAI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                 Register areg, string operands>
   : BinOpAI<opcode, mnemonic, typeinfo, areg, operands> {
   let Defs = [EFLAGS];
 }
 
+//  UnaryOpM - Unary instructions with a memory operand.
+class UnaryOpM<bits<8> opcode, Format f, string mnemonic, X86TypeInfo info,
+               list<dag> pattern>
+  : ITy<opcode, f, info, (outs), (ins info.MemOperand:$dst), mnemonic,
+        "$dst", pattern>;
+
+//  UnaryOpR - Unary instructions with a register.
+class UnaryOpR<bits<8> opcode, Format f, string mnemonic, X86TypeInfo info,
+               list<dag> pattern>
+  : ITy<opcode, f, info, (outs info.RegClass:$dst),
+        (ins info.RegClass:$src1), mnemonic, "$dst", pattern>;
+
+//  INCDECR - Instructions like "inc reg".
+class INCDECR<Format f, string mnemonic, X86TypeInfo info,
+              SDPatternOperator node>
+  : UnaryOpR<0xFE, f, mnemonic, info,
+               [(set info.RegClass:$dst, EFLAGS, 
+               (node info.RegClass:$src1, 1))]>;
+
+//  INCDECM - Instructions like "inc [mem]".
+class INCDECM<Format f, string mnemonic, X86TypeInfo info, int num>
+  : UnaryOpM<0xFE, f, mnemonic, info,
+             [(store (add (info.LoadNode addr:$dst), num), addr:$dst),
+              (implicit EFLAGS)]>;
+
+//  INCDECR_ALT - Instructions like "inc reg" short forms.
+class INCDECR_ALT<bits<8> opcode, string mnemonic, X86TypeInfo info>
+  : UnaryOpR<opcode, AddRegFrm, mnemonic, info, []>{
+  let Predicates = [Not64BitMode];
+  let Opcode = opcode;
+}
+
+//  MulOpR - Instructions like "mul reg".
+class MulOpR<bits<8> opcode, Format f, string mnemonic, X86TypeInfo info, 
+             X86FoldableSchedWrite sched, list<dag> pattern>
+  : ITy<opcode, f, info, (outs), (ins info.RegClass:$src), mnemonic, 
+        "$src", pattern>, 
+    Sched<[sched]>;
+
+//  MulOpM - Instructions like "mul [mem]".
+class MulOpM<bits<8> opcode, Format f, string mnemonic, X86TypeInfo info, 
+             X86FoldableSchedWrite sched, list<dag> pattern>
+  : ITy<opcode, f, info, (outs), (ins info.MemOperand:$src), mnemonic, 
+        "$src", pattern>, SchedLoadReg<sched>;
+
+//  NegOpR - Instructions like "neg reg", with implicit EFLAGS.
+class NegOpR<bits<8> opcode, string mnemonic, X86TypeInfo info>
+  : UnaryOpR<opcode, MRM3r, mnemonic, info,
+               [(set info.RegClass:$dst, (ineg info.RegClass:$src1)),
+                (implicit EFLAGS)]>;
+
+//  NotOpR - Instructions like "not reg".
+class NotOpR<bits<8> opcode, string mnemonic, X86TypeInfo info>
+  : UnaryOpR<opcode, MRM2r, mnemonic, info,
+               [(set info.RegClass:$dst, 
+                (not info.RegClass:$src1))]>;
+
+//  NegOpM - Instructions like "neg [mem]", with implicit EFLAGS.
+class NegOpM<bits<8> opcode, string mnemonic, X86TypeInfo info>
+  : UnaryOpM<opcode, MRM3m, mnemonic, info,
+             [(store (ineg (info.LoadNode addr:$dst)), addr:$dst),
+              (implicit EFLAGS)]>;
+
+//  NotOpM - Instructions like "neg [mem]".
+class NotOpM<bits<8> opcode, string mnemonic, X86TypeInfo info>
+  : UnaryOpM<opcode, MRM2m, mnemonic,  info,
+             [(store (not (info.LoadNode addr:$dst)), addr:$dst)]>;
+
+// BinOpRR_C - Binary instructions with inputs "reg, reg", which used mainly
+// with Constraints = "$src1 = $dst".
+class BinOpRR_C<bits<8> opcode, Format f, string mnemonic, X86TypeInfo info,
+                list<dag> pattern>
+  : ITy<opcode, f, info, (outs info.RegClass:$dst),
+        (ins info.RegClass:$src1, info.RegClass:$src2),
+        mnemonic, "{$src2, $dst|$dst, $src2}", pattern>;
+
+// BinOpRM_C - Binary instructions with inputs "reg, [mem]", which used mainly
+// with Constraints = "$src1 = $dst".
+class BinOpRM_C<bits<8> opcode, Format f, string mnemonic, X86TypeInfo info,
+                list<dag> pattern>
+  : ITy<opcode, f, info, (outs info.RegClass:$dst),
+        (ins info.RegClass:$src1, info.MemOperand:$src2),
+        mnemonic, "{$src2, $dst|$dst, $src2}", pattern>;
+
+// IMulOpRR - Instructions like "imul reg, reg, i8".
+class IMulOpRR<bits<8> opcode, string mnemonic, X86TypeInfo info, 
+               X86FoldableSchedWrite sched>
+  : BinOpRR_C<opcode, MRMSrcReg, mnemonic, info,
+              [(set info.RegClass:$dst, EFLAGS,
+                (X86smul_flag info.RegClass:$src1, 
+                info.RegClass:$src2))]>, 
+    Sched<[sched]>, TB;
+
+// IMulOpRM - Instructions like "imul reg, reg, [mem]".
+class IMulOpRM<bits<8> opcode, string mnemonic, X86TypeInfo info, 
+               X86FoldableSchedWrite sched>
+  : BinOpRM_C<opcode, MRMSrcMem, mnemonic, info,
+              [(set info.RegClass:$dst, EFLAGS,
+                (X86smul_flag info.RegClass:$src1, (info.LoadNode addr:$src2)))]>,
+    Sched<[sched.Folded, sched.ReadAfterFold]>, TB;
+
+// IMulOpRRI8 - Instructions like "imul reg, reg, i8".
+class IMulOpRRI8<bits<8> opcode, string mnemonic, X86TypeInfo info, 
+                 X86FoldableSchedWrite sched>
+  : ITy<opcode, MRMSrcReg, info, (outs info.RegClass:$dst),
+               (ins info.RegClass:$src1, 
+               info.Imm8Operand:$src2), mnemonic,
+               "{$src2, $src1, $dst|$dst, $src1, $src2}",
+               [(set info.RegClass:$dst, EFLAGS,
+                (X86smul_flag info.RegClass:$src1, 
+                info.Imm8NoSuOperator:$src2))]>, 
+    Sched<[sched]>{
+  let ImmT = Imm8;
+}
+
+// IMulOpRRI - Instructions like "imul reg, reg, i16/i32/i64".
+class IMulOpRRI<bits<8> opcode, string mnemonic, X86TypeInfo info, 
+                X86FoldableSchedWrite sched>
+  : ITy<opcode, MRMSrcReg, info, (outs info.RegClass:$dst),
+               (ins info.RegClass:$src1, 
+               info.ImmOperand:$src2), mnemonic, 
+               "{$src2, $src1, $dst|$dst, $src1, $src2}",
+               [(set info.RegClass:$dst, EFLAGS,
+                (X86smul_flag info.RegClass:$src1, 
+                info.ImmNoSuOperator:$src2))]>, 
+    Sched<[sched]>{
+  let ImmT = info.ImmEncoding;
+}
+
+// IMulOpRMI8 - Instructions like "imul reg, [mem], i8".
+class IMulOpRMI8<bits<8> opcode, string mnemonic, X86TypeInfo info, 
+                 X86FoldableSchedWrite sched>
+  : ITy<opcode, MRMSrcMem, info, (outs info.RegClass:$dst),
+               (ins info.MemOperand:$src1, 
+               info.Imm8Operand:$src2), mnemonic, 
+                "{$src2, $src1, $dst|$dst, $src1, $src2}",
+               [(set info.RegClass:$dst, EFLAGS,
+                (X86smul_flag (info.LoadNode addr:$src1),
+                info.Imm8NoSuOperator:$src2))]>, 
+    Sched<[sched.Folded]>{
+  let ImmT = Imm8;
+}
+
+// IMulOpRMI - Instructions like "imul reg, [mem], i16/i32/i64".
+class IMulOpRMI<bits<8> opcode, string mnemonic, X86TypeInfo info, 
+                X86FoldableSchedWrite sched>
+  : ITy<opcode, MRMSrcMem, info, (outs info.RegClass:$dst),
+               (ins info.MemOperand:$src1,
+               info.ImmOperand:$src2), mnemonic, 
+               "{$src2, $src1, $dst|$dst, $src1, $src2}",
+               [(set info.RegClass:$dst, EFLAGS,
+                  (X86smul_flag (info.LoadNode addr:$src1),
+                  info.ImmNoSuOperator:$src2))]>, 
+    Sched<[sched.Folded]>{
+  let ImmT = info.ImmEncoding;
+}
+
+def X86add_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
+                               (X86add_flag node:$lhs, node:$rhs), [{
+  return hasNoCarryFlagUses(SDValue(N, 1));
+}]>;
+
+def X86sub_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
+                               (X86sub_flag node:$lhs, node:$rhs), [{
+  // Only use DEC if the result is used.
+  return !SDValue(N, 0).use_empty() && hasNoCarryFlagUses(SDValue(N, 1));
+}]>;
+
+let Defs = [EFLAGS] in {
+let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
+let isConvertibleToThreeAddress = 1, CodeSize = 2 in { // Can xform into LEA.
+def INC8r  : INCDECR<MRM0r, "inc", Xi8, X86add_flag_nocf>;
+def INC16r : INCDECR<MRM0r, "inc", Xi16, X86add_flag_nocf>;
+def INC32r : INCDECR<MRM0r, "inc", Xi32, X86add_flag_nocf>;
+def INC64r : INCDECR<MRM0r, "inc", Xi64, X86add_flag_nocf>;
+} // isConvertibleToThreeAddress = 1, CodeSize = 2
+
+// Short forms only valid in 32-bit mode. Selected during MCInst lowering.
+let CodeSize = 1, hasSideEffects = 0 in {
+def INC16r_alt : INCDECR_ALT<0x40, "inc", Xi16>;
+def INC32r_alt : INCDECR_ALT<0x40, "inc", Xi32>;
+} // CodeSize = 1, hasSideEffects = 0
+} // Constraints = "$src1 = $dst", SchedRW
+
+let CodeSize = 2, SchedRW = [WriteALURMW] in {
+let Predicates = [UseIncDec] in {
+  def INC8m  : INCDECM<MRM0m, "inc", Xi8, 1>;
+  def INC16m : INCDECM<MRM0m, "inc", Xi16, 1>;
+  def INC32m : INCDECM<MRM0m, "inc", Xi32, 1>;
+} // Predicates
+let Predicates = [UseIncDec, In64BitMode] in {
+  def INC64m : INCDECM<MRM0m, "inc", Xi64, 1>;
+} // Predicates
+} // CodeSize = 2, SchedRW
+
+let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
+let isConvertibleToThreeAddress = 1, CodeSize = 2 in { // Can xform into LEA.
+def DEC8r  : INCDECR<MRM1r, "dec", Xi8, X86sub_flag_nocf>;
+def DEC16r : INCDECR<MRM1r, "dec", Xi16, X86sub_flag_nocf>;
+def DEC32r : INCDECR<MRM1r, "dec", Xi32, X86sub_flag_nocf>;
+def DEC64r : INCDECR<MRM1r, "dec", Xi64, X86sub_flag_nocf>;
+} // isConvertibleToThreeAddress = 1, CodeSize = 2
+
+// Short forms only valid in 32-bit mode. Selected during MCInst lowering.
+let CodeSize = 1, hasSideEffects = 0 in {
+def DEC16r_alt : INCDECR_ALT<0x48, "dec", Xi16>;
+def DEC32r_alt : INCDECR_ALT<0x48, "dec", Xi32>;
+} // CodeSize = 1, hasSideEffects = 0
+} // Constraints = "$src1 = $dst", SchedRW
+
+let CodeSize = 2, SchedRW = [WriteALURMW] in {
+let Predicates = [UseIncDec] in {
+  def DEC8m  : INCDECM<MRM1m, "dec", Xi8, -1>;
+  def DEC16m : INCDECM<MRM1m, "dec", Xi16, -1>;
+  def DEC32m : INCDECM<MRM1m, "dec", Xi32, -1>;
+} // Predicates
+let Predicates = [UseIncDec, In64BitMode] in {
+  def DEC64m : INCDECM<MRM1m, "dec", Xi64, -1>;
+} // Predicates
+} // CodeSize = 2, SchedRW
+} // Defs = [EFLAGS]
+
+// Extra precision multiplication
+
+// AL is really implied by AX, but the registers in Defs must match the
+// SDNode results (i8, i32).
+// AL,AH = AL*GR8
+let Defs = [AL,EFLAGS,AX], Uses = [AL] in
+def MUL8r  : MulOpR<0xF6, MRM4r, "mul", Xi8, WriteIMul8, 
+               // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
+               // This probably ought to be moved to a def : Pat<> if the
+               // syntax can be accepted.
+               [(set AL, (mul AL, GR8:$src)), (implicit EFLAGS)]>;
+// AX,DX = AX*GR16
+let Defs = [AX,DX,EFLAGS], Uses = [AX], hasSideEffects = 0 in
+def MUL16r : MulOpR<0xF7, MRM4r, "mul", Xi16, WriteIMul16, []>;
+// EAX,EDX = EAX*GR32
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX], hasSideEffects = 0 in
+def MUL32r : MulOpR<0xF7, MRM4r, "mul", Xi32, WriteIMul32,
+               [/*(set EAX, EDX, EFLAGS, (X86umul_flag EAX, GR32:$src))*/]>;
+// RAX,RDX = RAX*GR64
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], hasSideEffects = 0 in
+def MUL64r : MulOpR<0xF7, MRM4r, "mul", Xi64, WriteIMul64,
+                [/*(set RAX, RDX, EFLAGS, (X86umul_flag RAX, GR64:$src))*/]>;
+// AL,AH = AL*[mem8]
+let Defs = [AL,EFLAGS,AX], Uses = [AL] in
+def MUL8m  : MulOpM<0xF6, MRM4m, "mul", Xi8, WriteIMul8,
+               // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
+               // This probably ought to be moved to a def : Pat<> if the
+               // syntax can be accepted.
+               [(set AL, (mul AL, (loadi8 addr:$src))),
+                (implicit EFLAGS)]>;
+// AX,DX = AX*[mem16]
+let mayLoad = 1, hasSideEffects = 0 in {
+let Defs = [AX,DX,EFLAGS], Uses = [AX] in
+def MUL16m : MulOpM<0xF7, MRM4m, "mul", Xi16, WriteIMul16, []>;
+// EAX,EDX = EAX*[mem32]
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
+def MUL32m : MulOpM<0xF7, MRM4m, "mul", Xi32, WriteIMul32, []>;
+// RAX,RDX = RAX*[mem64]
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
+def MUL64m : MulOpM<0xF7, MRM4m, "mul", Xi64, WriteIMul64, []>,
+                Requires<[In64BitMode]>;
+}
+
+let hasSideEffects = 0 in {
+// AL,AH = AL*GR8
+let Defs = [AL,EFLAGS,AX], Uses = [AL] in
+def IMUL8r  : MulOpR<0xF6, MRM5r, "imul", Xi8, WriteIMul8, []>;
+// AX,DX = AX*GR16
+let Defs = [AX,DX,EFLAGS], Uses = [AX] in
+def IMUL16r : MulOpR<0xF7, MRM5r, "imul", Xi16, WriteIMul16, []>;
+// EAX,EDX = EAX*GR32
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
+def IMUL32r : MulOpR<0xF7, MRM5r, "imul", Xi32, WriteIMul32, []>;
+// RAX,RDX = RAX*GR64
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
+def IMUL64r : MulOpR<0xF7, MRM5r, "imul", Xi64, WriteIMul64, []>;
+
+let mayLoad = 1 in {
+// AL,AH = AL*[mem8]
+let Defs = [AL,EFLAGS,AX], Uses = [AL] in
+def IMUL8m  : MulOpM<0xF6, MRM5m, "imul", Xi8, WriteIMul8, []>;
+// AX,DX = AX*[mem16]
+let Defs = [AX,DX,EFLAGS], Uses = [AX] in
+def IMUL16m : MulOpM<0xF7, MRM5m, "imul", Xi16, WriteIMul16, []>;
+// EAX,EDX = EAX*[mem32]
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
+def IMUL32m : MulOpM<0xF7, MRM5m, "imul", Xi32, WriteIMul32, []>;
+// RAX,RDX = RAX*[mem64]
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
+def IMUL64m : MulOpM<0xF7, MRM5m, "imul", Xi64, WriteIMul64, []>,
+                 Requires<[In64BitMode]>;
+}
+
+let Defs = [EFLAGS] in {
+let Constraints = "$src1 = $dst" in {
+let isCommutable = 1 in {
+// X = IMUL Y, Z --> X = IMUL Z, Y
+// Register-Register Signed Integer Multiply
+def IMUL16rr : IMulOpRR<0xAF, "imul", Xi16, WriteIMul16Reg>;
+def IMUL32rr : IMulOpRR<0xAF, "imul", Xi32, WriteIMul32Reg>;
+def IMUL64rr : IMulOpRR<0xAF, "imul", Xi64, WriteIMul64Reg>;
+} // isCommutable
+
+// Register-Memory Signed Integer Multiply
+def IMUL16rm : IMulOpRM<0xAF, "imul", Xi16, WriteIMul16Reg>;
+def IMUL32rm : IMulOpRM<0xAF, "imul", Xi32, WriteIMul32Reg>;
+def IMUL64rm : IMulOpRM<0xAF, "imul", Xi64, WriteIMul64Reg>;
+} // Constraints = "$src1 = $dst"
+} // Defs = [EFLAGS]
+} // hasSideEffects
+
+// Surprisingly enough, these are not two address instructions!
+let Defs = [EFLAGS] in {
+// NOTE: These are order specific, we want the ri8 forms to be listed
+// first so that they are slightly preferred to the ri forms.
+
+// Register-Integer Signed Integer Multiply
+// GR16 = GR16*I8
+def IMUL16rri8 : IMulOpRRI8<0x6B, "imul", Xi16, WriteIMul16Imm>;
+// GR16 = GR16*I16
+def IMUL16rri  : IMulOpRRI<0x69, "imul", Xi16, WriteIMul16Imm>;
+// GR32 = GR32*I32
+def IMUL32rri  : IMulOpRRI<0x69, "imul", Xi32, WriteIMul32Imm>;
+// GR32 = GR32*I8
+def IMUL32rri8 : IMulOpRRI8<0x6B, "imul", Xi32, WriteIMul32Imm>;
+// GR64 = GR64*I8
+def IMUL64rri8 : IMulOpRRI8<0x6B, "imul", Xi64, WriteIMul64Imm>;
+// GR64 = GR64*I32
+def IMUL64rri32 : IMulOpRRI<0x69, "imul", Xi64, WriteIMul64Imm>;
+
+// Memory-Integer Signed Integer Multiply
+// GR16 = [mem16]*I8
+def IMUL16rmi8 : IMulOpRMI8<0x6B, "imul", Xi16, WriteIMul16Imm>;
+// GR16 = [mem16]*I16
+def IMUL16rmi  : IMulOpRMI<0x69, "imul", Xi16, WriteIMul16Imm>;
+// GR32 = [mem32]*I8
+def IMUL32rmi8 : IMulOpRMI8<0x6B, "imul", Xi32, WriteIMul32Imm>;
+// GR32 = [mem32]*I32
+def IMUL32rmi  : IMulOpRMI<0x69, "imul", Xi32, WriteIMul32Imm>;
+// GR64 = [mem64]*I8
+def IMUL64rmi8 : IMulOpRMI8<0x6B, "imul", Xi64, WriteIMul64Imm>;
+// GR64 = [mem64]*I32
+def IMUL64rmi32 : IMulOpRMI<0x69, "imul", Xi64, WriteIMul64Imm>;
+} // Defs = [EFLAGS]
+
+// unsigned division/remainder
+let hasSideEffects = 1 in { // so that we don't speculatively execute
+let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+// AX/r8 = AL,AH
+def DIV8r  : MulOpR<0xF6, MRM6r, "div", Xi8, WriteDiv8, []>;
+let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
+// DX:AX/r16 = AX,DX
+def DIV16r : MulOpR<0xF7, MRM6r, "div", Xi16, WriteDiv16, []>;
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
+// EDX:EAX/r32 = EAX,EDX
+def DIV32r : MulOpR<0xF7, MRM6r, "div", Xi32, WriteDiv32, []>;
+// RDX:RAX/r64 = RAX,RDX
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
+def DIV64r : MulOpR<0xF7, MRM6r, "div", Xi64, WriteDiv64, []>;
+
+let mayLoad = 1 in {
+let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+// AX/[mem8] = AL,AH
+def DIV8m  : MulOpM<0xF6, MRM6m, "div", Xi8, WriteDiv8, []>;
+let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
+// DX:AX/[mem16] = AX,DX
+def DIV16m : MulOpM<0xF7, MRM6m, "div", Xi16, WriteDiv16, []>;
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
+def DIV32m : MulOpM<0xF7, MRM6m, "div", Xi32, WriteDiv32, []>;
+// RDX:RAX/[mem64] = RAX,RDX
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
+def DIV64m : MulOpM<0xF7, MRM6m, "div", Xi64, WriteDiv64, []>,
+             Requires<[In64BitMode]>;
+}
+
+// Signed division/remainder.
+let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+// AX/r8 = AL,AH
+def IDIV8r : MulOpR<0xF6, MRM7r, "idiv", Xi8, WriteIDiv8, []>;
+let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
+// DX:AX/r16 = AX,DX
+def IDIV16r: MulOpR<0xF7, MRM7r, "idiv", Xi16, WriteIDiv16, []>;
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
+// EDX:EAX/r32 = EAX,EDX
+def IDIV32r: MulOpR<0xF7, MRM7r, "idiv", Xi32, WriteIDiv32, []>;
+// RDX:RAX/r64 = RAX,RDX
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
+def IDIV64r: MulOpR<0xF7, MRM7r, "idiv", Xi64, WriteIDiv64, []>;
+
+let mayLoad = 1 in {
+let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+// AX/[mem8] = AL,AH
+def IDIV8m : MulOpM<0xF6, MRM7m, "idiv", Xi8, WriteIDiv8, []>;
+let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
+// DX:AX/[mem16] = AX,DX
+def IDIV16m: MulOpM<0xF7, MRM7m, "idiv", Xi16, WriteIDiv16, []>;
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
+// EDX:EAX/[mem32] = EAX,EDX
+def IDIV32m: MulOpM<0xF7, MRM7m, "idiv", Xi32, WriteIDiv32, []>;
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in // RDX:RAX/[mem64] = RAX,RDX
+// RDX:RAX/[mem64] = RAX,RDX
+def IDIV64m: MulOpM<0xF7, MRM7m, "idiv", Xi64, WriteIDiv64, []>,
+             Requires<[In64BitMode]>;
+}
+} // hasSideEffects = 0
+
+//===----------------------------------------------------------------------===//
+//  Two address Instructions.
+//
+
+// unary instructions
+let CodeSize = 2 in {
+let Defs = [EFLAGS] in {
+let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
+def NEG8r  : NegOpR<0xF6, "neg", Xi8>;
+def NEG16r : NegOpR<0xF7, "neg", Xi16>;
+def NEG32r : NegOpR<0xF7, "neg", Xi32>;
+def NEG64r : NegOpR<0xF7, "neg", Xi64>;
+} // Constraints = "$src1 = $dst", SchedRW
+
+// Read-modify-write negate.
+let SchedRW = [WriteALURMW] in {
+def NEG8m  : NegOpM<0xF6, "neg", Xi8>;
+def NEG16m : NegOpM<0xF7, "neg", Xi16>;
+def NEG32m : NegOpM<0xF7, "neg", Xi32>;
+def NEG64m : NegOpM<0xF7, "neg", Xi64>, Requires<[In64BitMode]>;
+} // SchedRW
+} // Defs = [EFLAGS]
+
+
+// Note: NOT does not set EFLAGS!
+
+let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
+def NOT8r  : NotOpR<0xF6, "not", Xi8>;
+def NOT16r : NotOpR<0xF7, "not", Xi16>;
+def NOT32r : NotOpR<0xF7, "not", Xi32>;
+def NOT64r : NotOpR<0xF7, "not", Xi64>;
+} // Constraints = "$src1 = $dst", SchedRW
+
+let SchedRW = [WriteALURMW] in {
+def NOT8m  : NotOpM<0xF6, "not", Xi8>;
+def NOT16m : NotOpM<0xF7, "not", Xi16>;
+def NOT32m : NotOpM<0xF7, "not", Xi32>;
+def NOT64m : NotOpM<0xF7, "not", Xi64>, Requires<[In64BitMode]>;
+} // SchedRW
+} // CodeSize
+
 /// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
 /// defined with "(set GPR:$dst, EFLAGS, (...".
 ///
@@ -1448,23 +1447,26 @@ let Predicates = [HasBMI2] in {
 //
 // We don't have patterns for these as there is no advantage over ADC for
 // most code.
+class ADCOXOpRR <bits<8> opcode, string mnemonic, X86TypeInfo info>
+  : BinOpRR_C<opcode, MRMSrcReg, mnemonic, info, []>{
+  let Opcode = opcode;
+  let OpSize = OpSizeFixed;
+}
+
+class ADCOXOpRM <bits<8> opcode, string mnemonic, X86TypeInfo info>
+  : BinOpRM_C<opcode, MRMSrcMem, mnemonic, info, []>{
+  let Opcode = opcode;
+  let OpSize = OpSizeFixed;
+}
+
 let Predicates = [HasADX], Defs = [EFLAGS], Uses = [EFLAGS],
     Constraints = "$src1 = $dst", hasSideEffects = 0 in {
   let SchedRW = [WriteADC], isCommutable = 1 in {
-  def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst),
-                   (ins GR32:$src1, GR32:$src2),
-                   "adcx{l}\t{$src2, $dst|$dst, $src2}", []>, T8PD;
-  def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst),
-                    (ins GR64:$src1, GR64:$src2),
-                    "adcx{q}\t{$src2, $dst|$dst, $src2}", []>, T8PD;
-
-  def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst),
-                   (ins GR32:$src1, GR32:$src2),
-                   "adox{l}\t{$src2, $dst|$dst, $src2}", []>, T8XS;
-
-  def ADOX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst),
-                    (ins GR64:$src1, GR64:$src2),
-                    "adox{q}\t{$src2, $dst|$dst, $src2}", []>, T8XS;
+  def ADCX32rr : ADCOXOpRR<0xF6, "adcx", Xi32>, T8PD;
+  def ADCX64rr : ADCOXOpRR<0xF6, "adcx", Xi64>, T8PD;
+
+  def ADOX32rr : ADCOXOpRR<0xF6, "adox", Xi32>, T8XS;
+  def ADOX64rr : ADCOXOpRR<0xF6, "adox", Xi64>, T8XS;
   } // SchedRW
 
   let mayLoad = 1,
@@ -1473,20 +1475,10 @@ let Predicates = [HasADX], Defs = [EFLAGS], Uses = [EFLAGS],
                  ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
                  // Implicit read of EFLAGS
                  WriteADC.ReadAfterFold] in {
-  def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst),
-                   (ins GR32:$src1, i32mem:$src2),
-                   "adcx{l}\t{$src2, $dst|$dst, $src2}", []>, T8PD;
-
-  def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst),
-                    (ins GR64:$src1, i64mem:$src2),
-                    "adcx{q}\t{$src2, $dst|$dst, $src2}", []>, T8PD;
-
-  def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst),
-                   (ins GR32:$src1, i32mem:$src2),
-                   "adox{l}\t{$src2, $dst|$dst, $src2}", []>, T8XS;
+  def ADCX32rm : ADCOXOpRM<0xF6, "adcx", Xi32>, T8PD;
+  def ADCX64rm : ADCOXOpRM<0xF6, "adcx", Xi64>, T8PD;
 
-  def ADOX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst),
-                    (ins GR64:$src1, i64mem:$src2),
-                    "adox{q}\t{$src2, $dst|$dst, $src2}", []>, T8XS;
+  def ADOX32rm : ADCOXOpRM<0xF6, "adox", Xi32>, T8XS;
+  def ADOX64rm : ADCOXOpRM<0xF6, "adox", Xi64>, T8XS;
   } // mayLoad, SchedRW
 }
index 6c326b5..b832b15 100644 (file)
@@ -1294,7 +1294,8 @@ def trunc_su : unop_oneuse<trunc>;
 class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
                   PatFrag loadnode, X86MemOperand memoperand, ImmType immkind,
                   Operand immoperand, SDPatternOperator immoperator,
-                  Operand imm8operand, SDPatternOperator imm8operator,
+                  SDPatternOperator immnosuoperator, Operand imm8operand, 
+                  SDPatternOperator imm8operator, SDPatternOperator imm8nosuoperator,
                   bit hasOddOpcode, OperandSize opSize,
                   bit hasREX_W> {
   /// VT - This is the value type itself.
@@ -1332,6 +1333,8 @@ class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
   /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32).
   SDPatternOperator ImmOperator = immoperator;
 
+  SDPatternOperator ImmNoSuOperator = immnosuoperator;
+
   /// Imm8Operand - This is the operand kind to use for an imm8 of this type.
   /// For example, i8 -> <invalid>, i16 -> i16i8imm, i32 -> i32i8imm.  This is
   /// only used for instructions that have a sign-extended imm8 field form.
@@ -1341,6 +1344,8 @@ class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
   /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8).
   SDPatternOperator Imm8Operator = imm8operator;
 
+  SDPatternOperator Imm8NoSuOperator = imm8nosuoperator;
+
   /// HasOddOpcode - This bit is true if the instruction should have an odd (as
   /// opposed to even) opcode.  Operations on i8 are usually even, operations on
   /// other datatypes are odd.
@@ -1358,20 +1363,18 @@ class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
 
 def invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
 
-
-def Xi8  : X86TypeInfo<i8, "b", GR8, loadi8, i8mem,
-                       Imm8, i8imm, imm_su, i8imm, invalid_node,
+def Xi8  : X86TypeInfo<i8, "b", GR8, loadi8, i8mem, Imm8, i8imm, 
+                       imm_su, imm, i8imm, invalid_node, invalid_node,
                        0, OpSizeFixed, 0>;
-def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem,
-                       Imm16, i16imm, imm_su, i16i8imm, i16immSExt8_su,
+def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem, Imm16, i16imm, 
+                       imm_su, imm, i16i8imm, i16immSExt8_su, i16immSExt8,
                        1, OpSize16, 0>;
-def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem,
-                       Imm32, i32imm, imm_su, i32i8imm, i32immSExt8_su,
+def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem, Imm32, i32imm, 
+                       imm_su, imm, i32i8imm, i32immSExt8_su, i32immSExt8,
                        1, OpSize32, 0>;
-def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem,
-                       Imm32S, i64i32imm, i64immSExt32_su, i64i8imm, i64immSExt8_su,
-                       1, OpSizeFixed, 1>;
-
+def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem, Imm32S, i64i32imm, 
+                      i64immSExt32_su, i64immSExt32, i64i8imm, i64immSExt8_su,
+                      i64immSExt8, 1, OpSizeFixed, 1>;
 //===----------------------------------------------------------------------===//
 // Subsystems.
 //===----------------------------------------------------------------------===//