Skip to content
X86InstrInfo.td 173 KiB
Newer Older
Chris Lattner's avatar
Chris Lattner committed

// Register-Integer Addition
def ADD8ri    : Ii8<0x80, MRM0r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
                    "add{b}\t{$src2, $dst|$dst, $src2}",
                    [(set GR8:$dst, (add GR8:$src1, imm:$src2))]>;

// Register-Integer Addition with Overflow
def ADDOvf8ri  : Ii8<0x80, MRM0r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
                     "add{b}\t{$src2, $dst|$dst, $src2}",
                     [(set GR8:$dst, (X86add_ovf GR8:$src1, imm:$src2)),
                      (implicit EFLAGS)]>;

Chris Lattner's avatar
Chris Lattner committed
let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
def ADD16ri  : Ii16<0x81, MRM0r, (outs GR16:$dst),
                                 (ins GR16:$src1, i16imm:$src2),
                    "add{w}\t{$src2, $dst|$dst, $src2}",
                    [(set GR16:$dst, (add GR16:$src1, imm:$src2))]>, OpSize;
def ADD32ri  : Ii32<0x81, MRM0r, (outs GR32:$dst),
                                 (ins GR32:$src1, i32imm:$src2),
                    "add{l}\t{$src2, $dst|$dst, $src2}",
                    [(set GR32:$dst, (add GR32:$src1, imm:$src2))]>;
def ADD16ri8 : Ii8<0x83, MRM0r, (outs GR16:$dst),
                                (ins GR16:$src1, i16i8imm:$src2),
                   "add{w}\t{$src2, $dst|$dst, $src2}",
                [(set GR16:$dst, (add GR16:$src1, i16immSExt8:$src2))]>, OpSize;
def ADD32ri8 : Ii8<0x83, MRM0r, (outs GR32:$dst),
                                (ins GR32:$src1, i32i8imm:$src2),
                   "add{l}\t{$src2, $dst|$dst, $src2}",
                [(set GR32:$dst, (add GR32:$src1, i32immSExt8:$src2))]>;

// Register-Integer Addition with Overflow
def ADDOvf16ri  : Ii16<0x81, MRM0r, (outs GR16:$dst),
                                    (ins GR16:$src1, i16imm:$src2),
                       "add{w}\t{$src2, $dst|$dst, $src2}",
                       [(set GR16:$dst, (X86add_ovf GR16:$src1, imm:$src2)),
                        (implicit EFLAGS)]>, OpSize;
def ADDOvf32ri  : Ii32<0x81, MRM0r, (outs GR32:$dst),
                                    (ins GR32:$src1, i32imm:$src2),
                       "add{l}\t{$src2, $dst|$dst, $src2}",
                       [(set GR32:$dst, (X86add_ovf GR32:$src1, imm:$src2)),
                        (implicit EFLAGS)]>;
def ADDOvf16ri8 : Ii8<0x83, MRM0r, (outs GR16:$dst),
                                   (ins GR16:$src1, i16i8imm:$src2),
                      "add{w}\t{$src2, $dst|$dst, $src2}",
                      [(set GR16:$dst, (X86add_ovf GR16:$src1,
                                                   i16immSExt8:$src2)),
                       (implicit EFLAGS)]>, OpSize;
def ADDOvf32ri8 : Ii8<0x83, MRM0r, (outs GR32:$dst),
                                   (ins GR32:$src1, i32i8imm:$src2),
                      "add{l}\t{$src2, $dst|$dst, $src2}",
                      [(set GR32:$dst, (X86add_ovf GR32:$src1,
                                        i32immSExt8:$src2)),
                       (implicit EFLAGS)]>;
  def ADD8mr   : I<0x00, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src2),
                   "add{b}\t{$src2, $dst|$dst, $src2}",
                   [(store (add (load addr:$dst), GR8:$src2), addr:$dst)]>;
  def ADD16mr  : I<0x01, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
                   "add{w}\t{$src2, $dst|$dst, $src2}",
                   [(store (add (load addr:$dst), GR16:$src2), addr:$dst)]>,
                   OpSize;
  def ADD32mr  : I<0x01, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
                   "add{l}\t{$src2, $dst|$dst, $src2}",
                   [(store (add (load addr:$dst), GR32:$src2), addr:$dst)]>;
  def ADD8mi   : Ii8<0x80, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src2),
                     "add{b}\t{$src2, $dst|$dst, $src2}",
                   [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
  def ADD16mi  : Ii16<0x81, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src2),
                      "add{w}\t{$src2, $dst|$dst, $src2}",
                  [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
                  OpSize;
  def ADD32mi  : Ii32<0x81, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src2),
                      "add{l}\t{$src2, $dst|$dst, $src2}",
                  [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
  def ADD16mi8 : Ii8<0x83, MRM0m, (outs), (ins i16mem:$dst, i16i8imm :$src2),
                     "add{w}\t{$src2, $dst|$dst, $src2}",
                  [(store (add (load addr:$dst), i16immSExt8:$src2),
                               addr:$dst)]>, OpSize;
  def ADD32mi8 : Ii8<0x83, MRM0m, (outs), (ins i32mem:$dst, i32i8imm :$src2),
                     "add{l}\t{$src2, $dst|$dst, $src2}",
                  [(store (add (load addr:$dst), i32immSExt8:$src2),
                               addr:$dst)]>;

  // Memory-Register Addition with Overflow
  def ADDOvf8mr   : I<0x00, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src2),
                      "add{b}\t{$src2, $dst|$dst, $src2}",
                      [(store (X86add_ovf (load addr:$dst), GR8:$src2),
                                          addr:$dst),
                       (implicit EFLAGS)]>;
  def ADDOvf16mr  : I<0x01, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
                      "add{w}\t{$src2, $dst|$dst, $src2}",
                      [(store (X86add_ovf (load addr:$dst), GR16:$src2),
                                          addr:$dst),
                       (implicit EFLAGS)]>, OpSize;
  def ADDOvf32mr  : I<0x01, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
                      "add{l}\t{$src2, $dst|$dst, $src2}",
                      [(store (X86add_ovf (load addr:$dst), GR32:$src2),
                                          addr:$dst),
                       (implicit EFLAGS)]>;
  def ADDOvf8mi   : Ii8<0x80, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src2),
                        "add{b}\t{$src2, $dst|$dst, $src2}",
                        [(store (X86add_ovf (loadi8 addr:$dst), imm:$src2),
                                            addr:$dst),
                        (implicit EFLAGS)]>;
  def ADDOvf16mi  : Ii16<0x81, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src2),
                         "add{w}\t{$src2, $dst|$dst, $src2}",
                         [(store (X86add_ovf (loadi16 addr:$dst), imm:$src2),
                                             addr:$dst),
                          (implicit EFLAGS)]>, OpSize;
  def ADDOvf32mi  : Ii32<0x81, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src2),
                         "add{l}\t{$src2, $dst|$dst, $src2}",
                         [(store (X86add_ovf (loadi32 addr:$dst), imm:$src2),
                                             addr:$dst),
                          (implicit EFLAGS)]>;
  def ADDOvf16mi8 : Ii8<0x83, MRM0m, (outs), (ins i16mem:$dst, i16i8imm :$src2),
                        "add{w}\t{$src2, $dst|$dst, $src2}",
                        [(store (X86add_ovf (load addr:$dst),i16immSExt8:$src2),
                                            addr:$dst),
                         (implicit EFLAGS)]>, OpSize;
  def ADDOvf32mi8 : Ii8<0x83, MRM0m, (outs), (ins i32mem:$dst, i32i8imm :$src2),
                        "add{l}\t{$src2, $dst|$dst, $src2}",
                        [(store (X86add_ovf (load addr:$dst),i32immSExt8:$src2),
                                            addr:$dst),
                         (implicit EFLAGS)]>;
Evan Cheng's avatar
Evan Cheng committed
let Uses = [EFLAGS] in {
let isCommutable = 1 in {  // X = ADC Y, Z --> X = ADC Z, Y
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))]>;
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 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))]>;
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))]>;
  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 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),
                     "adc{l}\t{$src2, $dst|$dst, $src2}",
               [(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
Evan Cheng's avatar
Evan Cheng committed
} // Uses = [EFLAGS]
// Register-Register Subtraction
def SUB8rr  : I<0x28, MRMDestReg, (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
                "sub{b}\t{$src2, $dst|$dst, $src2}",
                [(set GR8:$dst, (sub GR8:$src1, GR8:$src2))]>;
def SUB16rr : I<0x29, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1,GR16:$src2),
                "sub{w}\t{$src2, $dst|$dst, $src2}",
                [(set GR16:$dst, (sub GR16:$src1, GR16:$src2))]>, OpSize;
def SUB32rr : I<0x29, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1,GR32:$src2),
                "sub{l}\t{$src2, $dst|$dst, $src2}",
                [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;

// Register-Register Subtraction with Overflow
def SUBOvf8rr  : I<0x28, MRMDestReg, (outs GR8:$dst),
                                     (ins GR8:$src1, GR8:$src2),
                   "sub{b}\t{$src2, $dst|$dst, $src2}",
                   [(set GR8:$dst, (X86sub_ovf GR8:$src1, GR8:$src2)),
                    (implicit EFLAGS)]>;
def SUBOvf16rr : I<0x29, MRMDestReg, (outs GR16:$dst),
                                     (ins GR16:$src1, GR16:$src2),
                   "sub{w}\t{$src2, $dst|$dst, $src2}",
                   [(set GR16:$dst, (X86sub_ovf GR16:$src1, GR16:$src2)),
                    (implicit EFLAGS)]>, OpSize;
def SUBOvf32rr : I<0x29, MRMDestReg, (outs GR32:$dst),
                                     (ins GR32:$src1, GR32:$src2),
                   "sub{l}\t{$src2, $dst|$dst, $src2}",
                   [(set GR32:$dst, (X86sub_ovf GR32:$src1, GR32:$src2)),
                    (implicit EFLAGS)]>;

// Register-Memory Subtraction
def SUB8rm  : I<0x2A, MRMSrcMem, (outs GR8 :$dst),
                                 (ins GR8 :$src1, i8mem :$src2),
                "sub{b}\t{$src2, $dst|$dst, $src2}",
                [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2)))]>;
def SUB16rm : I<0x2B, MRMSrcMem, (outs GR16:$dst),
                                 (ins GR16:$src1, i16mem:$src2),
                "sub{w}\t{$src2, $dst|$dst, $src2}",
                [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2)))]>, OpSize;
def SUB32rm : I<0x2B, MRMSrcMem, (outs GR32:$dst),
                                 (ins GR32:$src1, i32mem:$src2),
                "sub{l}\t{$src2, $dst|$dst, $src2}",
                [(set GR32:$dst, (sub GR32:$src1, (load addr:$src2)))]>;

// Register-Memory Subtraction with Overflow
def SUBOvf8rm  : I<0x2A, MRMSrcMem, (outs GR8:$dst),
                                    (ins GR8:$src1, i8mem:$src2),
                    "sub{b}\t{$src2, $dst|$dst, $src2}",
                    [(set GR8:$dst, (X86sub_ovf GR8:$src1, (load addr:$src2))),
                     (implicit EFLAGS)]>;
def SUBOvf16rm : I<0x2B, MRMSrcMem, (outs GR16:$dst),
                                    (ins GR16:$src1, i16mem:$src2),
                   "sub{w}\t{$src2, $dst|$dst, $src2}",
                   [(set GR16:$dst, (X86sub_ovf GR16:$src1, (load addr:$src2))),
                    (implicit EFLAGS)]>, OpSize;
def SUBOvf32rm : I<0x2B, MRMSrcMem, (outs GR32:$dst),
                                    (ins GR32:$src1, i32mem:$src2),
                   "sub{l}\t{$src2, $dst|$dst, $src2}",
                   [(set GR32:$dst, (X86sub_ovf GR32:$src1, (load addr:$src2))),

// Register-Integer Subtraction
def SUB8ri   : Ii8 <0x80, MRM5r, (outs GR8:$dst),
                                 (ins GR8:$src1, i8imm:$src2),
                    "sub{b}\t{$src2, $dst|$dst, $src2}",
                    [(set GR8:$dst, (sub GR8:$src1, imm:$src2))]>;
def SUB16ri  : Ii16<0x81, MRM5r, (outs GR16:$dst),
                                 (ins GR16:$src1, i16imm:$src2),
                    "sub{w}\t{$src2, $dst|$dst, $src2}",
                    [(set GR16:$dst, (sub GR16:$src1, imm:$src2))]>, OpSize;
def SUB32ri  : Ii32<0x81, MRM5r, (outs GR32:$dst),
                                 (ins GR32:$src1, i32imm:$src2),
                    "sub{l}\t{$src2, $dst|$dst, $src2}",
                    [(set GR32:$dst, (sub GR32:$src1, imm:$src2))]>;
def SUB16ri8 : Ii8<0x83, MRM5r, (outs GR16:$dst),
                                (ins GR16:$src1, i16i8imm:$src2),
                   "sub{w}\t{$src2, $dst|$dst, $src2}",
                   [(set GR16:$dst, (sub GR16:$src1, i16immSExt8:$src2))]>,
                   OpSize;
def SUB32ri8 : Ii8<0x83, MRM5r, (outs GR32:$dst),
                                (ins GR32:$src1, i32i8imm:$src2),
                   "sub{l}\t{$src2, $dst|$dst, $src2}",
                   [(set GR32:$dst, (sub GR32:$src1, i32immSExt8:$src2))]>;

// Register-Integer Subtraction with Overflow
def SUBOvf8ri   : Ii8 <0x80, MRM5r, (outs GR8:$dst),
                                    (ins GR8:$src1, i8imm:$src2),
                       "sub{b}\t{$src2, $dst|$dst, $src2}",
                       [(set GR8:$dst, (X86sub_ovf GR8:$src1, imm:$src2)),
                        (implicit EFLAGS)]>;
def SUBOvf16ri  : Ii16<0x81, MRM5r, (outs GR16:$dst),
                                    (ins GR16:$src1, i16imm:$src2),
                       "sub{w}\t{$src2, $dst|$dst, $src2}",
                       [(set GR16:$dst, (X86sub_ovf GR16:$src1, imm:$src2)),
                        (implicit EFLAGS)]>, OpSize;
def SUBOvf32ri  : Ii32<0x81, MRM5r, (outs GR32:$dst),
                                    (ins GR32:$src1, i32imm:$src2),
                       "sub{l}\t{$src2, $dst|$dst, $src2}",
                       [(set GR32:$dst, (X86sub_ovf GR32:$src1, imm:$src2)),
                        (implicit EFLAGS)]>;
def SUBOvf16ri8 : Ii8<0x83, MRM5r, (outs GR16:$dst),
                                   (ins GR16:$src1, i16i8imm:$src2),
                      "sub{w}\t{$src2, $dst|$dst, $src2}",
                      [(set GR16:$dst, (X86sub_ovf GR16:$src1,
                                                   i16immSExt8:$src2)),
                       (implicit EFLAGS)]>, OpSize;
def SUBOvf32ri8 : Ii8<0x83, MRM5r, (outs GR32:$dst),
                                   (ins GR32:$src1, i32i8imm:$src2),
                      "sub{l}\t{$src2, $dst|$dst, $src2}",
                      [(set GR32:$dst, (X86sub_ovf GR32:$src1,
                                                   i32immSExt8:$src2)),
                       (implicit EFLAGS)]>;

  def SUB8mr   : I<0x28, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src2),
                   "sub{b}\t{$src2, $dst|$dst, $src2}",
                   [(store (sub (load addr:$dst), GR8:$src2), addr:$dst)]>;
  def SUB16mr  : I<0x29, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
                   "sub{w}\t{$src2, $dst|$dst, $src2}",
                   [(store (sub (load addr:$dst), GR16:$src2), addr:$dst)]>,
                   OpSize;
  def SUB32mr  : I<0x29, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), 
                   "sub{l}\t{$src2, $dst|$dst, $src2}",
                   [(store (sub (load addr:$dst), GR32:$src2), addr:$dst)]>;

  // Memory-Register Subtraction with Overflow
  def SUBOvf8mr  : I<0x28, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src2),
                     "sub{b}\t{$src2, $dst|$dst, $src2}",
                     [(store (X86sub_ovf (load addr:$dst), GR8:$src2),
                                         addr:$dst),
                      (implicit EFLAGS)]>;
  def SUBOvf16mr : I<0x29, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
                     "sub{w}\t{$src2, $dst|$dst, $src2}",
                     [(store (X86sub_ovf (load addr:$dst), GR16:$src2),
                                         addr:$dst),
                      (implicit EFLAGS)]>, OpSize;
  def SUBOvf32mr : I<0x29, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), 
                     "sub{l}\t{$src2, $dst|$dst, $src2}",
                     [(store (X86sub_ovf (load addr:$dst), GR32:$src2),
                                         addr:$dst),
                      (implicit EFLAGS)]>;

  // Memory-Integer Subtraction
  def SUB8mi   : Ii8<0x80, MRM5m, (outs), (ins i8mem :$dst, i8imm:$src2), 
                     "sub{b}\t{$src2, $dst|$dst, $src2}",
                     [(store (sub (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
  def SUB16mi  : Ii16<0x81, MRM5m, (outs), (ins i16mem:$dst, i16imm:$src2), 
                      "sub{w}\t{$src2, $dst|$dst, $src2}",
                      [(store (sub (loadi16 addr:$dst), imm:$src2),addr:$dst)]>,
                      OpSize;
  def SUB32mi  : Ii32<0x81, MRM5m, (outs), (ins i32mem:$dst, i32imm:$src2), 
                      "sub{l}\t{$src2, $dst|$dst, $src2}",
                      [(store (sub (loadi32 addr:$dst), imm:$src2),addr:$dst)]>;
  def SUB16mi8 : Ii8<0x83, MRM5m, (outs), (ins i16mem:$dst, i16i8imm :$src2), 
                     "sub{w}\t{$src2, $dst|$dst, $src2}",
                     [(store (sub (load addr:$dst), i16immSExt8:$src2),
                             addr:$dst)]>, OpSize;
  def SUB32mi8 : Ii8<0x83, MRM5m, (outs), (ins i32mem:$dst, i32i8imm :$src2),
                     "sub{l}\t{$src2, $dst|$dst, $src2}",
                     [(store (sub (load addr:$dst), i32immSExt8:$src2),
                             addr:$dst)]>;

  // Memory-Integer Subtraction with Overflow
  def SUBOvf8mi   : Ii8<0x80, MRM5m, (outs), (ins i8mem :$dst, i8imm:$src2), 
                        "sub{b}\t{$src2, $dst|$dst, $src2}",
                        [(store (X86sub_ovf (loadi8 addr:$dst), imm:$src2),
                                addr:$dst),
                         (implicit EFLAGS)]>;
  def SUBOvf16mi  : Ii16<0x81, MRM5m, (outs), (ins i16mem:$dst, i16imm:$src2), 
                         "sub{w}\t{$src2, $dst|$dst, $src2}",
                         [(store (X86sub_ovf (loadi16 addr:$dst), imm:$src2),
                                 addr:$dst),
                          (implicit EFLAGS)]>, OpSize;
  def SUBOvf32mi  : Ii32<0x81, MRM5m, (outs), (ins i32mem:$dst, i32imm:$src2), 
                         "sub{l}\t{$src2, $dst|$dst, $src2}",
                         [(store (X86sub_ovf (loadi32 addr:$dst), imm:$src2),
                                             addr:$dst),
                          (implicit EFLAGS)]>;
  def SUBOvf16mi8 : Ii8<0x83, MRM5m, (outs), (ins i16mem:$dst, i16i8imm :$src2), 
                        "sub{w}\t{$src2, $dst|$dst, $src2}",
                        [(store (X86sub_ovf (load addr:$dst),i16immSExt8:$src2),
                                            addr:$dst),
                         (implicit EFLAGS)]>, OpSize;
  def SUBOvf32mi8 : Ii8<0x83, MRM5m, (outs), (ins i32mem:$dst, i32i8imm :$src2), 
                        "sub{l}\t{$src2, $dst|$dst, $src2}",
                        [(store (X86sub_ovf (load addr:$dst),i32immSExt8:$src2),
                                            addr:$dst),
                         (implicit EFLAGS)]>;
Evan Cheng's avatar
Evan Cheng committed
let Uses = [EFLAGS] in {
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))]>;
  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)]>;
  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)]>;
  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)]>;
  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)]>;
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)))]>;
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))]>;
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))]>;
Evan Cheng's avatar
Evan Cheng committed
} // Uses = [EFLAGS]
let isCommutable = 1 in {  // X = IMUL Y, Z --> X = IMUL Z, Y
// Register-Register 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, (mul GR16:$src1, GR16:$src2))]>, TB, OpSize;
def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1,GR32:$src2),
                 "imul{l}\t{$src2, $dst|$dst, $src2}",
                 [(set GR32:$dst, (mul GR32:$src1, GR32:$src2))]>, TB;

// Register-Register Integer Multiply
def IMULOvf16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst),
                                     (ins GR16:$src1, GR16:$src2),
                    "imul{w}\t{$src2, $dst|$dst, $src2}",
                    [(set GR16:$dst, (X86mul_ovf GR16:$src1, GR16:$src2)),
                     (implicit EFLAGS)]>, TB, OpSize;
def IMULOvf32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst),
                                     (ins GR32:$src1, GR32:$src2),
                    "imul{l}\t{$src2, $dst|$dst, $src2}",
                    [(set GR32:$dst, (X86mul_ovf GR32:$src1, GR32:$src2)),
                     (implicit EFLAGS)]>, TB;

// Register-Memory 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, (mul GR16:$src1, (load addr:$src2)))]>,
def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2),
                 "imul{l}\t{$src2, $dst|$dst, $src2}",
                 [(set GR32:$dst, (mul GR32:$src1, (load addr:$src2)))]>, TB;

// Register-Memory Integer Multiply with Overflow
def IMULOvf16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst),
                                     (ins GR16:$src1, i16mem:$src2),
                    "imul{w}\t{$src2, $dst|$dst, $src2}",
                    [(set GR16:$dst, (X86mul_ovf GR16:$src1,(load addr:$src2))),
                     (implicit EFLAGS)]>,
                    TB, OpSize;
def IMULOvf32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst),
                                     (ins GR32:$src1, i32mem:$src2),
                    "imul{l}\t{$src2, $dst|$dst, $src2}",
                    [(set GR32:$dst, (X86mul_ovf GR32:$src1,(load addr:$src2))),
                     (implicit EFLAGS)]>, TB;
// Suprisingly enough, these are not two address instructions!
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, (mul GR16:$src1, imm:$src2))]>, OpSize;
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, (mul GR32:$src1, imm:$src2))]>;
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, (mul GR16:$src1, i16immSExt8:$src2))]>,
                     OpSize;
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, (mul GR32:$src1, i32immSExt8:$src2))]>;

// Register-Integer Integer Multiply with Overflow
def IMULOvf16rri  : 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, (X86mul_ovf GR16:$src1, imm:$src2)),
                         (implicit EFLAGS)]>, OpSize;
def IMULOvf32rri  : 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, (X86mul_ovf GR32:$src1, imm:$src2)),
                         (implicit EFLAGS)]>;
def IMULOvf16rri8 : 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, (X86mul_ovf GR16:$src1,
                                         i16immSExt8:$src2)),
                        (implicit EFLAGS)]>, OpSize;
def IMULOvf32rri8 : 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, (X86mul_ovf GR32:$src1,
                                         i32immSExt8:$src2)),
                        (implicit EFLAGS)]>;

// Memory-Integer Integer Multiply
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, (mul (load addr:$src1), imm:$src2))]>,
                      OpSize;
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, (mul (load addr:$src1), imm:$src2))]>;
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, (mul (load addr:$src1),
                                       i16immSExt8:$src2))]>, OpSize;
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, (mul (load addr:$src1),
                                           i32immSExt8:$src2))]>;

// Memory-Integer Integer Multiply with Overflow
def IMULOvf16rmi  : 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, (X86mul_ovf (load addr:$src1),
                                                     imm:$src2)),
                         (implicit EFLAGS)]>, OpSize;
def IMULOvf32rmi  : 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, (X86mul_ovf (load addr:$src1),
                                                     imm:$src2)),
                         (implicit EFLAGS)]>;
def IMULOvf16rmi8 : 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, (X86mul_ovf (load addr:$src1),
                                                     i16immSExt8:$src2)),
                         (implicit EFLAGS)]>, OpSize;
def IMULOvf32rmi8 : 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, (X86mul_ovf (load addr:$src1),
                                                     i32immSExt8:$src2)),
                         (implicit EFLAGS)]>;
//===----------------------------------------------------------------------===//
// Test instructions are just like AND, except they don't generate a result.
Chris Lattner's avatar
Chris Lattner committed
let isCommutable = 1 in {   // TEST X, Y   --> TEST Y, X
def TEST8rr  : I<0x84, MRMDestReg, (outs),  (ins GR8:$src1, GR8:$src2),
                     "test{b}\t{$src2, $src1|$src1, $src2}",
                     [(X86cmp (and_su GR8:$src1, GR8:$src2), 0),
def TEST16rr : I<0x85, MRMDestReg, (outs),  (ins GR16:$src1, GR16:$src2),
                     "test{w}\t{$src2, $src1|$src1, $src2}",
                     [(X86cmp (and_su GR16:$src1, GR16:$src2), 0),
def TEST32rr : I<0x85, MRMDestReg, (outs),  (ins GR32:$src1, GR32:$src2),
                     "test{l}\t{$src2, $src1|$src1, $src2}",
                     [(X86cmp (and_su GR32:$src1, GR32:$src2), 0),
def TEST8rm  : I<0x84, MRMSrcMem, (outs),  (ins GR8 :$src1, i8mem :$src2),
                     "test{b}\t{$src2, $src1|$src1, $src2}",
                     [(X86cmp (and GR8:$src1, (loadi8 addr:$src2)), 0),
def TEST16rm : I<0x85, MRMSrcMem, (outs),  (ins GR16:$src1, i16mem:$src2),
                     "test{w}\t{$src2, $src1|$src1, $src2}",
                     [(X86cmp (and GR16:$src1, (loadi16 addr:$src2)), 0),
def TEST32rm : I<0x85, MRMSrcMem, (outs),  (ins GR32:$src1, i32mem:$src2),
                     "test{l}\t{$src2, $src1|$src1, $src2}",
                     [(X86cmp (and GR32:$src1, (loadi32 addr:$src2)), 0),
def TEST8ri  : Ii8 <0xF6, MRM0r,                     // flags = GR8  & imm8
                    (outs),  (ins GR8:$src1, i8imm:$src2),
                    "test{b}\t{$src2, $src1|$src1, $src2}",
                    [(X86cmp (and_su GR8:$src1, imm:$src2), 0),
def TEST16ri : Ii16<0xF7, MRM0r,                     // flags = GR16 & imm16
                    (outs),  (ins GR16:$src1, i16imm:$src2),
                    "test{w}\t{$src2, $src1|$src1, $src2}",
                    [(X86cmp (and_su GR16:$src1, imm:$src2), 0),
def TEST32ri : Ii32<0xF7, MRM0r,                     // flags = GR32 & imm32
                    (outs),  (ins GR32:$src1, i32imm:$src2),
                    "test{l}\t{$src2, $src1|$src1, $src2}",
                    [(X86cmp (and_su GR32:$src1, imm:$src2), 0),
def TEST8mi  : Ii8 <0xF6, MRM0m,                   // flags = [mem8]  & imm8
                    (outs), (ins i8mem:$src1, i8imm:$src2),
                    "test{b}\t{$src2, $src1|$src1, $src2}",
                    [(X86cmp (and (loadi8 addr:$src1), imm:$src2), 0),
def TEST16mi : Ii16<0xF7, MRM0m,                   // flags = [mem16] & imm16
                    (outs), (ins i16mem:$src1, i16imm:$src2),
                    "test{w}\t{$src2, $src1|$src1, $src2}",
                    [(X86cmp (and (loadi16 addr:$src1), imm:$src2), 0),
def TEST32mi : Ii32<0xF7, MRM0m,                   // flags = [mem32] & imm32
                    (outs), (ins i32mem:$src1, i32imm:$src2),
                    "test{l}\t{$src2, $src1|$src1, $src2}",
                    [(X86cmp (and (loadi32 addr:$src1), imm:$src2), 0),
// Condition code ops, incl. set if equal/not equal/...
let Defs = [EFLAGS], Uses = [AH], neverHasSideEffects = 1 in
def SAHF     : I<0x9E, RawFrm, (outs),  (ins), "sahf", []>;  // flags = AH
let Defs = [AH], Uses = [EFLAGS], neverHasSideEffects = 1 in
def LAHF     : I<0x9F, RawFrm, (outs),  (ins), "lahf", []>;  // AH = flags
                 [(set GR8:$dst, (X86setcc X86_COND_E, EFLAGS))]>,
                 [(store (X86setcc X86_COND_E, EFLAGS), addr:$dst)]>,
                 [(set GR8:$dst, (X86setcc X86_COND_NE, EFLAGS))]>,
                 [(store (X86setcc X86_COND_NE, EFLAGS), addr:$dst)]>,
                 [(set GR8:$dst, (X86setcc X86_COND_L, EFLAGS))]>,
                 [(store (X86setcc X86_COND_L, EFLAGS), addr:$dst)]>,
                 [(set GR8:$dst, (X86setcc X86_COND_GE, EFLAGS))]>,
                 [(store (X86setcc X86_COND_GE, EFLAGS), addr:$dst)]>,
                 [(set GR8:$dst, (X86setcc X86_COND_LE, EFLAGS))]>,
                 [(store (X86setcc X86_COND_LE, EFLAGS), addr:$dst)]>,
                 [(set GR8:$dst, (X86setcc X86_COND_G, EFLAGS))]>,
                 [(store (X86setcc X86_COND_G, EFLAGS), addr:$dst)]>,
               TB;                        // [mem8] = >  signed

def SETBr    : I<0x92, MRM0r,
                 [(set GR8:$dst, (X86setcc X86_COND_B, EFLAGS))]>,
                 [(store (X86setcc X86_COND_B, EFLAGS), addr:$dst)]>,
                 [(set GR8:$dst, (X86setcc X86_COND_AE, EFLAGS))]>,
                 [(store (X86setcc X86_COND_AE, EFLAGS), addr:$dst)]>,
                 [(set GR8:$dst, (X86setcc X86_COND_BE, EFLAGS))]>,
                 [(store (X86setcc X86_COND_BE, EFLAGS), addr:$dst)]>,
                 [(set GR8:$dst, (X86setcc X86_COND_A, EFLAGS))]>,
                 [(store (X86setcc X86_COND_A, EFLAGS), addr:$dst)]>,
Evan Cheng's avatar
Evan Cheng committed

                 [(set GR8:$dst, (X86setcc X86_COND_S, EFLAGS))]>,
                 [(store (X86setcc X86_COND_S, EFLAGS), addr:$dst)]>,
Evan Cheng's avatar
Evan Cheng committed
               TB;                        // [mem8] = <sign bit>
                 [(set GR8:$dst, (X86setcc X86_COND_NS, EFLAGS))]>,
                 [(store (X86setcc X86_COND_NS, EFLAGS), addr:$dst)]>,
Evan Cheng's avatar
Evan Cheng committed
               TB;                        // [mem8] = !<sign bit>
                 [(set GR8:$dst, (X86setcc X86_COND_P, EFLAGS))]>,
                 [(store (X86setcc X86_COND_P, EFLAGS), addr:$dst)]>,
Evan Cheng's avatar
Evan Cheng committed
               TB;                        // [mem8] = parity
Chris Lattner's avatar
Chris Lattner committed
def SETNPr   : I<0x9B, MRM0r, 
                 [(set GR8:$dst, (X86setcc X86_COND_NP, EFLAGS))]>,
Chris Lattner's avatar
Chris Lattner committed
def SETNPm   : I<0x9B, MRM0m, 
                 [(store (X86setcc X86_COND_NP, EFLAGS), addr:$dst)]>,
Evan Cheng's avatar
Evan Cheng committed
               TB;                        // [mem8] = not parity

def SETOr    : I<0x90, MRM0r, 
                 (outs GR8   :$dst), (ins),
                 "seto\t$dst",
                 [(set GR8:$dst, (X86setcc X86_COND_O, EFLAGS))]>,
               TB;                        // GR8 = overflow
def SETOm    : I<0x90, MRM0m, 
                 (outs), (ins i8mem:$dst),
                 "seto\t$dst",
                 [(store (X86setcc X86_COND_O, EFLAGS), addr:$dst)]>,
               TB;                        // [mem8] = overflow
def SETNOr   : I<0x91, MRM0r, 
                 (outs GR8   :$dst), (ins),
                 "setno\t$dst",
                 [(set GR8:$dst, (X86setcc X86_COND_NO, EFLAGS))]>,
               TB;                        // GR8 = not overflow
def SETNOm   : I<0x91, MRM0m, 
                 (outs), (ins i8mem:$dst),
                 "setno\t$dst",
                 [(store (X86setcc X86_COND_NO, EFLAGS), addr:$dst)]>,
               TB;                        // [mem8] = not overflow

def SETCr    : I<0x92, MRM0r, 
                 (outs GR8   :$dst), (ins),
                 "setc\t$dst",
                 [(set GR8:$dst, (X86setcc X86_COND_C, EFLAGS))]>,
               TB;                        // GR8 = carry
def SETCm    : I<0x92, MRM0m, 
                 (outs), (ins i8mem:$dst),
                 "setc\t$dst",
                 [(store (X86setcc X86_COND_C, EFLAGS), addr:$dst)]>,
               TB;                        // [mem8] = carry
def SETNCr   : I<0x93, MRM0r, 
                 (outs GR8   :$dst), (ins),
                 "setnc\t$dst",
                 [(set GR8:$dst, (X86setcc X86_COND_NC, EFLAGS))]>,
               TB;                        // GR8 = not carry
def SETNCm   : I<0x93, MRM0m, 
                 (outs), (ins i8mem:$dst),
                 "setnc\t$dst",
                 [(store (X86setcc X86_COND_NC, EFLAGS), addr:$dst)]>,
               TB;                        // [mem8] = not carry

// Integer comparisons
                (outs), (ins GR8 :$src1, GR8 :$src2),
                "cmp{b}\t{$src2, $src1|$src1, $src2}",
                [(X86cmp GR8:$src1, GR8:$src2), (implicit EFLAGS)]>;
                (outs), (ins GR16:$src1, GR16:$src2),
                "cmp{w}\t{$src2, $src1|$src1, $src2}",
                [(X86cmp GR16:$src1, GR16:$src2), (implicit EFLAGS)]>, OpSize;
                (outs), (ins GR32:$src1, GR32:$src2),
                "cmp{l}\t{$src2, $src1|$src1, $src2}",
                [(X86cmp GR32:$src1, GR32:$src2), (implicit EFLAGS)]>;
                (outs), (ins i8mem :$src1, GR8 :$src2),
                "cmp{b}\t{$src2, $src1|$src1, $src2}",
                [(X86cmp (loadi8 addr:$src1), GR8:$src2),
                 (implicit EFLAGS)]>;
                (outs), (ins i16mem:$src1, GR16:$src2),
                "cmp{w}\t{$src2, $src1|$src1, $src2}",
                [(X86cmp (loadi16 addr:$src1), GR16:$src2),
                 (implicit EFLAGS)]>, OpSize;
                (outs), (ins i32mem:$src1, GR32:$src2),
                "cmp{l}\t{$src2, $src1|$src1, $src2}",
                [(X86cmp (loadi32 addr:$src1), GR32:$src2),
                 (implicit EFLAGS)]>;
                (outs), (ins GR8 :$src1, i8mem :$src2),
                "cmp{b}\t{$src2, $src1|$src1, $src2}",
                [(X86cmp GR8:$src1, (loadi8 addr:$src2)),
                 (implicit EFLAGS)]>;
                (outs), (ins GR16:$src1, i16mem:$src2),
                "cmp{w}\t{$src2, $src1|$src1, $src2}",
                [(X86cmp GR16:$src1, (loadi16 addr:$src2)),
                 (implicit EFLAGS)]>, OpSize;
                (outs), (ins GR32:$src1, i32mem:$src2),
                "cmp{l}\t{$src2, $src1|$src1, $src2}",
                [(X86cmp GR32:$src1, (loadi32 addr:$src2)),
                 (implicit EFLAGS)]>;
                  (outs), (ins GR8:$src1, i8imm:$src2),
                  "cmp{b}\t{$src2, $src1|$src1, $src2}",
                  [(X86cmp GR8:$src1, imm:$src2), (implicit EFLAGS)]>;
                   (outs), (ins GR16:$src1, i16imm:$src2),
                   "cmp{w}\t{$src2, $src1|$src1, $src2}",
                   [(X86cmp GR16:$src1, imm:$src2),
                    (implicit EFLAGS)]>, OpSize;
                   (outs), (ins GR32:$src1, i32imm:$src2),
                   "cmp{l}\t{$src2, $src1|$src1, $src2}",
                   [(X86cmp GR32:$src1, imm:$src2), (implicit EFLAGS)]>;
                   (outs), (ins i8mem :$src1, i8imm :$src2),
                   "cmp{b}\t{$src2, $src1|$src1, $src2}",
                   [(X86cmp (loadi8 addr:$src1), imm:$src2),
def CMP16mi : Ii16<0x81, MRM7m,
                   (outs), (ins i16mem:$src1, i16imm:$src2),
                   "cmp{w}\t{$src2, $src1|$src1, $src2}",
                   [(X86cmp (loadi16 addr:$src1), imm:$src2),
def CMP32mi : Ii32<0x81, MRM7m,
                   (outs), (ins i32mem:$src1, i32imm:$src2),
                   "cmp{l}\t{$src2, $src1|$src1, $src2}",
                   [(X86cmp (loadi32 addr:$src1), imm:$src2),
def CMP16ri8 : Ii8<0x83, MRM7r,
                   (outs), (ins GR16:$src1, i16i8imm:$src2),
                   "cmp{w}\t{$src2, $src1|$src1, $src2}",
                   [(X86cmp GR16:$src1, i16immSExt8:$src2),
def CMP16mi8 : Ii8<0x83, MRM7m,
                   (outs), (ins i16mem:$src1, i16i8imm:$src2),
                   "cmp{w}\t{$src2, $src1|$src1, $src2}",
                   [(X86cmp (loadi16 addr:$src1), i16immSExt8:$src2),
def CMP32mi8 : Ii8<0x83, MRM7m,
                   (outs), (ins i32mem:$src1, i32i8imm:$src2),
                   "cmp{l}\t{$src2, $src1|$src1, $src2}",
                   [(X86cmp (loadi32 addr:$src1), i32immSExt8:$src2),
def CMP32ri8 : Ii8<0x83, MRM7r,
                   (outs), (ins GR32:$src1, i32i8imm:$src2),
                   "cmp{l}\t{$src2, $src1|$src1, $src2}",
                   [(X86cmp GR32:$src1, i32immSExt8:$src2),
// Sign/Zero extenders
// Use movsbl intead of movsbw; we don't care about the high 16 bits
// of the register here. This has a smaller encoding and avoids a
// partial-register update.
def MOVSX16rr8 : I<0xBE, MRMSrcReg, (outs GR16:$dst), (ins GR8 :$src),
                   "movs{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
                   [(set GR16:$dst, (sext GR8:$src))]>, TB;
def MOVSX16rm8 : I<0xBE, MRMSrcMem, (outs GR16:$dst), (ins i8mem :$src),
                   "movs{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
                   [(set GR16:$dst, (sextloadi16i8 addr:$src))]>, TB;
def MOVSX32rr8 : I<0xBE, MRMSrcReg, (outs GR32:$dst), (ins GR8 :$src),
                   "movs{bl|x}\t{$src, $dst|$dst, $src}",
def MOVSX32rm8 : I<0xBE, MRMSrcMem, (outs GR32:$dst), (ins i8mem :$src),
                   "movs{bl|x}\t{$src, $dst|$dst, $src}",
                   [(set GR32:$dst, (sextloadi32i8 addr:$src))]>, TB;
def MOVSX32rr16: I<0xBF, MRMSrcReg, (outs GR32:$dst), (ins GR16:$src),
                   "movs{wl|x}\t{$src, $dst|$dst, $src}",
def MOVSX32rm16: I<0xBF, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src),
                   "movs{wl|x}\t{$src, $dst|$dst, $src}",
                   [(set GR32:$dst, (sextloadi32i16 addr:$src))]>, TB;
// Use movzbl intead of movzbw; we don't care about the high 16 bits
// of the register here. This has a smaller encoding and avoids a
// partial-register update.
def MOVZX16rr8 : I<0xB6, MRMSrcReg, (outs GR16:$dst), (ins GR8 :$src),
                   "movz{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
                   [(set GR16:$dst, (zext GR8:$src))]>, TB;
def MOVZX16rm8 : I<0xB6, MRMSrcMem, (outs GR16:$dst), (ins i8mem :$src),
                   "movz{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
                   [(set GR16:$dst, (zextloadi16i8 addr:$src))]>, TB;
def MOVZX32rr8 : I<0xB6, MRMSrcReg, (outs GR32:$dst), (ins GR8 :$src),
                   "movz{bl|x}\t{$src, $dst|$dst, $src}",
def MOVZX32rm8 : I<0xB6, MRMSrcMem, (outs GR32:$dst), (ins i8mem :$src),
                   "movz{bl|x}\t{$src, $dst|$dst, $src}",
                   [(set GR32:$dst, (zextloadi32i8 addr:$src))]>, TB;
def MOVZX32rr16: I<0xB7, MRMSrcReg, (outs GR32:$dst), (ins GR16:$src),
                   "movz{wl|x}\t{$src, $dst|$dst, $src}",
def MOVZX32rm16: I<0xB7, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src),
                   "movz{wl|x}\t{$src, $dst|$dst, $src}",
                   [(set GR32:$dst, (zextloadi32i16 addr:$src))]>, TB;
let neverHasSideEffects = 1 in {
  let Defs = [AX], Uses = [AL] in
  def CBW : I<0x98, RawFrm, (outs), (ins),
              "{cbtw|cbw}", []>, OpSize;   // AX = signext(AL)
  let Defs = [EAX], Uses = [AX] in
  def CWDE : I<0x98, RawFrm, (outs), (ins),
              "{cwtl|cwde}", []>;   // EAX = signext(AX)

  let Defs = [AX,DX], Uses = [AX] in
  def CWD : I<0x99, RawFrm, (outs), (ins),
              "{cwtd|cwd}", []>, OpSize; // DX:AX = signext(AX)
  let Defs = [EAX,EDX], Uses = [EAX] in
  def CDQ : I<0x99, RawFrm, (outs), (ins),
              "{cltd|cdq}", []>; // EDX:EAX = signext(EAX)
}

//===----------------------------------------------------------------------===//
// Alias Instructions
//===----------------------------------------------------------------------===//

// Alias instructions that map movr0 to xor.
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
let Defs = [EFLAGS], isReMaterializable = 1, isAsCheapAsAMove = 1 in {
def MOV8r0   : I<0x30, MRMInitReg, (outs GR8 :$dst), (ins),
// Use xorl instead of xorw since we don't care about the high 16 bits,
// it's smaller, and it avoids a partial-register update.
def MOV16r0  : I<0x31, MRMInitReg,  (outs GR16:$dst), (ins),
                 "xor{l}\t${dst:subreg32}, ${dst:subreg32}",
                 [(set GR16:$dst, 0)]>;
def MOV32r0  : I<0x31, MRMInitReg,  (outs GR32:$dst), (ins),
// Basic operations on GR16 / GR32 subclasses GR16_ and GR32_ which contains only
// those registers that have GR8 sub-registers (i.e. AX - DX, EAX - EDX).
def MOV16to16_ : I<0x89, MRMDestReg, (outs GR16_:$dst), (ins GR16:$src),
                "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
def MOV32to32_ : I<0x89, MRMDestReg, (outs GR32_:$dst), (ins GR32:$src),
                "mov{l}\t{$src, $dst|$dst, $src}", []>;
def MOV16_rr : I<0x89, MRMDestReg, (outs GR16_:$dst), (ins GR16_:$src),
                "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
def MOV32_rr : I<0x89, MRMDestReg, (outs GR32_:$dst), (ins GR32_:$src),
                "mov{l}\t{$src, $dst|$dst, $src}", []>;
let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
def MOV16_rm : I<0x8B, MRMSrcMem, (outs GR16_:$dst), (ins i16mem:$src),
                "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
def MOV32_rm : I<0x8B, MRMSrcMem, (outs GR32_:$dst), (ins i32mem:$src),
                "mov{l}\t{$src, $dst|$dst, $src}", []>;
let mayStore = 1, neverHasSideEffects = 1 in {
def MOV16_mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16_:$src),
                "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
def MOV32_mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32_:$src),
                "mov{l}\t{$src, $dst|$dst, $src}", []>;
//===----------------------------------------------------------------------===//
// Thread Local Storage Instructions
//

def TLS_addr32 : I<0, Pseudo, (outs GR32:$dst), (ins i32imm:$sym),
                  "leal\t${sym:mem}(,%ebx,1), $dst",