Skip to content
X86InstrInfo.td 106 KiB
Newer Older
                 [(set R16:$dst, (shl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
def SHL32rCL : I<0xD3, MRM4r, (ops R32:$dst, R32:$src),
                 "shl{l} {%cl, $dst|$dst, %CL}",
                 [(set R32:$dst, (shl R32:$src, CL))]>, Imp<[CL],[]>;
Chris Lattner's avatar
Chris Lattner committed

def SHL8ri   : Ii8<0xC0, MRM4r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
                   "shl{b} {$src2, $dst|$dst, $src2}",
Chris Lattner's avatar
Chris Lattner committed
                   [(set R8:$dst, (shl R8:$src1, (i8 imm:$src2)))]>;
Chris Lattner's avatar
Chris Lattner committed
let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
Chris Lattner's avatar
Chris Lattner committed
def SHL16ri  : Ii8<0xC1, MRM4r, (ops R16:$dst, R16:$src1, i8imm:$src2),
                   "shl{w} {$src2, $dst|$dst, $src2}",
Chris Lattner's avatar
Chris Lattner committed
                   [(set R16:$dst, (shl R16:$src1, (i8 imm:$src2)))]>, OpSize;
def SHL32ri  : Ii8<0xC1, MRM4r, (ops R32:$dst, R32:$src1, i8imm:$src2),
                   "shl{l} {$src2, $dst|$dst, $src2}",
Chris Lattner's avatar
Chris Lattner committed
                   [(set R32:$dst, (shl R32:$src1, (i8 imm:$src2)))]>;
Chris Lattner's avatar
Chris Lattner committed
}
  def SHL8mCL  : I<0xD2, MRM4m, (ops i8mem :$dst),
                   "shl{b} {%cl, $dst|$dst, %CL}",
                   [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>,
                   Imp<[CL],[]>;
  def SHL16mCL : I<0xD3, MRM4m, (ops i16mem:$dst),
                   "shl{w} {%cl, $dst|$dst, %CL}",
                   [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>,
                   Imp<[CL],[]>, OpSize;
  def SHL32mCL : I<0xD3, MRM4m, (ops i32mem:$dst),
                   "shl{l} {%cl, $dst|$dst, %CL}",
                   [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>,
                   Imp<[CL],[]>;
  def SHL8mi   : Ii8<0xC0, MRM4m, (ops i8mem :$dst, i8imm:$src),
                     "shl{b} {$src, $dst|$dst, $src}",
                  [(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
  def SHL16mi  : Ii8<0xC1, MRM4m, (ops i16mem:$dst, i8imm:$src),
                     "shl{w} {$src, $dst|$dst, $src}",
                 [(store (shl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
                     OpSize;
  def SHL32mi  : Ii8<0xC1, MRM4m, (ops i32mem:$dst, i8imm:$src),
                     "shl{l} {$src, $dst|$dst, $src}",
                 [(store (shl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
def SHR8rCL  : I<0xD2, MRM5r, (ops R8 :$dst, R8 :$src),
                 "shr{b} {%cl, $dst|$dst, %CL}",
                 [(set R8:$dst, (srl R8:$src, CL))]>, Imp<[CL],[]>;
def SHR16rCL : I<0xD3, MRM5r, (ops R16:$dst, R16:$src),
                 "shr{w} {%cl, $dst|$dst, %CL}",
                 [(set R16:$dst, (srl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
def SHR32rCL : I<0xD3, MRM5r, (ops R32:$dst, R32:$src),
                 "shr{l} {%cl, $dst|$dst, %CL}",
                 [(set R32:$dst, (srl R32:$src, CL))]>, Imp<[CL],[]>;
def SHR8ri   : Ii8<0xC0, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
                   "shr{b} {$src2, $dst|$dst, $src2}",
Chris Lattner's avatar
Chris Lattner committed
                   [(set R8:$dst, (srl R8:$src1, (i8 imm:$src2)))]>;
def SHR16ri  : Ii8<0xC1, MRM5r, (ops R16:$dst, R16:$src1, i8imm:$src2),
                   "shr{w} {$src2, $dst|$dst, $src2}",
Chris Lattner's avatar
Chris Lattner committed
                   [(set R16:$dst, (srl R16:$src1, (i8 imm:$src2)))]>, OpSize;
def SHR32ri  : Ii8<0xC1, MRM5r, (ops R32:$dst, R32:$src1, i8imm:$src2),
                   "shr{l} {$src2, $dst|$dst, $src2}",
Chris Lattner's avatar
Chris Lattner committed
                   [(set R32:$dst, (srl R32:$src1, (i8 imm:$src2)))]>;
  def SHR8mCL  : I<0xD2, MRM5m, (ops i8mem :$dst),
Evan Cheng's avatar
Evan Cheng committed
                   "shr{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
  def SHR16mCL : I<0xD3, MRM5m, (ops i16mem:$dst),
Evan Cheng's avatar
Evan Cheng committed
                   "shr{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
  def SHR32mCL : I<0xD3, MRM5m, (ops i32mem:$dst),
Evan Cheng's avatar
Evan Cheng committed
                   "shr{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
  def SHR8mi   : Ii8<0xC0, MRM5m, (ops i8mem :$dst, i8imm:$src),
                     "shr{b} {$src, $dst|$dst, $src}", []>;
  def SHR16mi  : Ii8<0xC1, MRM5m, (ops i16mem:$dst, i8imm:$src),
                     "shr{w} {$src, $dst|$dst, $src}", []>, OpSize;
  def SHR32mi  : Ii8<0xC1, MRM5m, (ops i32mem:$dst, i8imm:$src),
                     "shr{l} {$src, $dst|$dst, $src}", []>;
def SAR8rCL  : I<0xD2, MRM7r, (ops R8 :$dst, R8 :$src),
                 "sar{b} {%cl, $dst|$dst, %CL}",
                 [(set R8:$dst, (sra R8:$src, CL))]>, Imp<[CL],[]>;
def SAR16rCL : I<0xD3, MRM7r, (ops R16:$dst, R16:$src),
                 "sar{w} {%cl, $dst|$dst, %CL}",
                 [(set R16:$dst, (sra R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
def SAR32rCL : I<0xD3, MRM7r, (ops R32:$dst, R32:$src),
                 "sar{l} {%cl, $dst|$dst, %CL}",
                 [(set R32:$dst, (sra R32:$src, CL))]>, Imp<[CL],[]>;
def SAR8ri   : Ii8<0xC0, MRM7r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
                   "sar{b} {$src2, $dst|$dst, $src2}",
Chris Lattner's avatar
Chris Lattner committed
                   [(set R8:$dst, (sra R8:$src1, (i8 imm:$src2)))]>;
def SAR16ri  : Ii8<0xC1, MRM7r, (ops R16:$dst, R16:$src1, i8imm:$src2),
                   "sar{w} {$src2, $dst|$dst, $src2}",
Chris Lattner's avatar
Chris Lattner committed
                   [(set R16:$dst, (sra R16:$src1, (i8 imm:$src2)))]>,
                   OpSize;
def SAR32ri  : Ii8<0xC1, MRM7r, (ops R32:$dst, R32:$src1, i8imm:$src2),
                   "sar{l} {$src2, $dst|$dst, $src2}",
Chris Lattner's avatar
Chris Lattner committed
                   [(set R32:$dst, (sra R32:$src1, (i8 imm:$src2)))]>;
  def SAR8mCL  : I<0xD2, MRM7m, (ops i8mem :$dst),
Evan Cheng's avatar
Evan Cheng committed
                   "sar{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
  def SAR16mCL : I<0xD3, MRM7m, (ops i16mem:$dst),
Evan Cheng's avatar
Evan Cheng committed
                   "sar{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
  def SAR32mCL : I<0xD3, MRM7m, (ops i32mem:$dst), 
Evan Cheng's avatar
Evan Cheng committed
                   "sar{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
  def SAR8mi   : Ii8<0xC0, MRM7m, (ops i8mem :$dst, i8imm:$src),
                     "sar{b} {$src, $dst|$dst, $src}", []>;
  def SAR16mi  : Ii8<0xC1, MRM7m, (ops i16mem:$dst, i8imm:$src),
                     "sar{w} {$src, $dst|$dst, $src}", []>, OpSize;
  def SAR32mi  : Ii8<0xC1, MRM7m, (ops i32mem:$dst, i8imm:$src),
                     "sar{l} {$src, $dst|$dst, $src}", []>;
Chris Lattner's avatar
Chris Lattner committed
// Rotate instructions
// FIXME: provide shorter instructions when imm8 == 1
def ROL8rCL  : I<0xD2, MRM0r, (ops R8 :$dst, R8 :$src),
Evan Cheng's avatar
Evan Cheng committed
                 "rol{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
Chris Lattner's avatar
Chris Lattner committed
def ROL16rCL : I<0xD3, MRM0r, (ops R16:$dst, R16:$src),
Evan Cheng's avatar
Evan Cheng committed
                 "rol{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
Chris Lattner's avatar
Chris Lattner committed
def ROL32rCL : I<0xD3, MRM0r, (ops R32:$dst, R32:$src),
Evan Cheng's avatar
Evan Cheng committed
                 "rol{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
Chris Lattner's avatar
Chris Lattner committed

def ROL8ri   : Ii8<0xC0, MRM0r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
                   "rol{b} {$src2, $dst|$dst, $src2}", []>;
Chris Lattner's avatar
Chris Lattner committed
def ROL16ri  : Ii8<0xC1, MRM0r, (ops R16:$dst, R16:$src1, i8imm:$src2),
                   "rol{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
Chris Lattner's avatar
Chris Lattner committed
def ROL32ri  : Ii8<0xC1, MRM0r, (ops R32:$dst, R32:$src1, i8imm:$src2),
                   "rol{l} {$src2, $dst|$dst, $src2}", []>;
Chris Lattner's avatar
Chris Lattner committed

let isTwoAddress = 0 in {
  def ROL8mCL  : I<0xD2, MRM0m, (ops i8mem :$dst),
Evan Cheng's avatar
Evan Cheng committed
                   "rol{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
Chris Lattner's avatar
Chris Lattner committed
  def ROL16mCL : I<0xD3, MRM0m, (ops i16mem:$dst),
Evan Cheng's avatar
Evan Cheng committed
                   "rol{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
Chris Lattner's avatar
Chris Lattner committed
  def ROL32mCL : I<0xD3, MRM0m, (ops i32mem:$dst),
Evan Cheng's avatar
Evan Cheng committed
                   "rol{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
Chris Lattner's avatar
Chris Lattner committed
  def ROL8mi   : Ii8<0xC0, MRM0m, (ops i8mem :$dst, i8imm:$src),
                     "rol{b} {$src, $dst|$dst, $src}", []>;
Chris Lattner's avatar
Chris Lattner committed
  def ROL16mi  : Ii8<0xC1, MRM0m, (ops i16mem:$dst, i8imm:$src),
                     "rol{w} {$src, $dst|$dst, $src}", []>, OpSize;
Chris Lattner's avatar
Chris Lattner committed
  def ROL32mi  : Ii8<0xC1, MRM0m, (ops i32mem:$dst, i8imm:$src),
                     "rol{l} {$src, $dst|$dst, $src}", []>;
Chris Lattner's avatar
Chris Lattner committed
}

def ROR8rCL  : I<0xD2, MRM1r, (ops R8 :$dst, R8 :$src),
Evan Cheng's avatar
Evan Cheng committed
                 "ror{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
Chris Lattner's avatar
Chris Lattner committed
def ROR16rCL : I<0xD3, MRM1r, (ops R16:$dst, R16:$src),
Evan Cheng's avatar
Evan Cheng committed
                 "ror{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
Chris Lattner's avatar
Chris Lattner committed
def ROR32rCL : I<0xD3, MRM1r, (ops R32:$dst, R32:$src),
Evan Cheng's avatar
Evan Cheng committed
                 "ror{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
Chris Lattner's avatar
Chris Lattner committed

def ROR8ri   : Ii8<0xC0, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
                   "ror{b} {$src2, $dst|$dst, $src2}", []>;
Chris Lattner's avatar
Chris Lattner committed
def ROR16ri  : Ii8<0xC1, MRM1r, (ops R16:$dst, R16:$src1, i8imm:$src2),
                   "ror{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
Chris Lattner's avatar
Chris Lattner committed
def ROR32ri  : Ii8<0xC1, MRM1r, (ops R32:$dst, R32:$src1, i8imm:$src2),
                   "ror{l} {$src2, $dst|$dst, $src2}", []>;
Chris Lattner's avatar
Chris Lattner committed
let isTwoAddress = 0 in {
  def ROR8mCL  : I<0xD2, MRM1m, (ops i8mem :$dst),
Evan Cheng's avatar
Evan Cheng committed
                   "ror{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
Chris Lattner's avatar
Chris Lattner committed
  def ROR16mCL : I<0xD3, MRM1m, (ops i16mem:$dst),
Evan Cheng's avatar
Evan Cheng committed
                   "ror{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
Chris Lattner's avatar
Chris Lattner committed
  def ROR32mCL : I<0xD3, MRM1m, (ops i32mem:$dst), 
Evan Cheng's avatar
Evan Cheng committed
                   "ror{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
Chris Lattner's avatar
Chris Lattner committed
  def ROR8mi   : Ii8<0xC0, MRM1m, (ops i8mem :$dst, i8imm:$src),
                     "ror{b} {$src, $dst|$dst, $src}", []>;
Chris Lattner's avatar
Chris Lattner committed
  def ROR16mi  : Ii8<0xC1, MRM1m, (ops i16mem:$dst, i8imm:$src),
                     "ror{w} {$src, $dst|$dst, $src}", []>, OpSize;
Chris Lattner's avatar
Chris Lattner committed
  def ROR32mi  : Ii8<0xC1, MRM1m, (ops i32mem:$dst, i8imm:$src),
                     "ror{l} {$src, $dst|$dst, $src}", []>;
Chris Lattner's avatar
Chris Lattner committed
}



// Double shift instructions (generalizations of rotate)

def SHLD32rrCL : I<0xA5, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                   "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
def SHRD32rrCL : I<0xAD, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                   "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
def SHLD16rrCL : I<0xA5, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                   "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
                   Imp<[CL],[]>, TB, OpSize;
def SHRD16rrCL : I<0xAD, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                   "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,

let isCommutable = 1 in {  // These instructions commute to each other.
def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
                     (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
                     "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>, TB;
def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
                     (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
                     "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>, TB;
def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
                     (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
                     "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
                     TB, OpSize;
def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
                     (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
                     "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,

let isTwoAddress = 0 in {
  def SHLD32mrCL : I<0xA5, MRMDestMem, (ops i32mem:$dst, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                     "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
  def SHRD32mrCL : I<0xAD, MRMDestMem, (ops i32mem:$dst, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                    "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
                    Imp<[CL],[]>, TB;
  def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
                      (ops i32mem:$dst, R32:$src2, i8imm:$src3),
                      "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
                      TB;
  def SHRD32mri8 : Ii8<0xAC, MRMDestMem, 
                       (ops i32mem:$dst, R32:$src2, i8imm:$src3),
                       "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
                       TB;

  def SHLD16mrCL : I<0xA5, MRMDestMem, (ops i16mem:$dst, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                     "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
                     Imp<[CL],[]>, TB, OpSize;
  def SHRD16mrCL : I<0xAD, MRMDestMem, (ops i16mem:$dst, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                    "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
                    Imp<[CL],[]>, TB, OpSize;
  def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
                      (ops i16mem:$dst, R16:$src2, i8imm:$src3),
                      "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
                      TB, OpSize;
  def SHRD16mri8 : Ii8<0xAC, MRMDestMem, 
                       (ops i16mem:$dst, R16:$src2, i8imm:$src3),
                       "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
Chris Lattner's avatar
Chris Lattner committed
// Arithmetic.
let isCommutable = 1 in {   // X = ADD Y, Z   --> X = ADD Z, Y
def ADD8rr   : I<0x00, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "add{b} {$src2, $dst|$dst, $src2}",
                 [(set R8:$dst, (add R8:$src1, R8:$src2))]>;
Chris Lattner's avatar
Chris Lattner committed
let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
def ADD16rr  : I<0x01, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "add{w} {$src2, $dst|$dst, $src2}",
                 [(set R16:$dst, (add R16:$src1, R16:$src2))]>, OpSize;
def ADD32rr  : I<0x01, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "add{l} {$src2, $dst|$dst, $src2}",
                 [(set R32:$dst, (add R32:$src1, R32:$src2))]>;
Chris Lattner's avatar
Chris Lattner committed
} // end isConvertibleToThreeAddress
} // end isCommutable
def ADD8rm   : I<0x02, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
                 "add{b} {$src2, $dst|$dst, $src2}",
                 [(set R8:$dst, (add R8:$src1, (load addr:$src2)))]>;
def ADD16rm  : I<0x03, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
                 "add{w} {$src2, $dst|$dst, $src2}",
                 [(set R16:$dst, (add R16:$src1, (load addr:$src2)))]>, OpSize;
def ADD32rm  : I<0x03, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
                 "add{l} {$src2, $dst|$dst, $src2}",
                 [(set R32:$dst, (add R32:$src1, (load addr:$src2)))]>;

def ADD8ri   : Ii8<0x80, MRM0r, (ops R8:$dst, R8:$src1, i8imm:$src2),
                   "add{b} {$src2, $dst|$dst, $src2}",
                   [(set R8:$dst, (add R8:$src1, imm:$src2))]>;
Chris Lattner's avatar
Chris Lattner committed

let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
def ADD16ri  : Ii16<0x81, MRM0r, (ops R16:$dst, R16:$src1, i16imm:$src2),
                    "add{w} {$src2, $dst|$dst, $src2}",
                    [(set R16:$dst, (add R16:$src1, imm:$src2))]>, OpSize;
def ADD32ri  : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2),
                    "add{l} {$src2, $dst|$dst, $src2}",
                    [(set R32:$dst, (add R32:$src1, imm:$src2))]>;
Chris Lattner's avatar
Chris Lattner committed
}
// FIXME: move ADD16ri8 above ADD16ri to optimize for space.
def ADD16ri8 : Ii8<0x83, MRM0r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
                   "add{w} {$src2, $dst|$dst, $src2}",
                   [(set R16:$dst, (add R16:$src1, i16immSExt8:$src2))]>,
                   OpSize;
def ADD32ri8 : Ii8<0x83, MRM0r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
                   "add{l} {$src2, $dst|$dst, $src2}",
                   [(set R32:$dst, (add R32:$src1, i32immSExt8:$src2))]>;
  def ADD8mr   : I<0x00, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
                   "add{b} {$src2, $dst|$dst, $src2}",
                   [(store (add (load addr:$dst), R8:$src2), addr:$dst)]>;
  def ADD16mr  : I<0x01, MRMDestMem, (ops i16mem:$dst, R16:$src2),
                   "add{w} {$src2, $dst|$dst, $src2}",
                   [(store (add (load addr:$dst), R16:$src2), addr:$dst)]>,
                   OpSize;
  def ADD32mr  : I<0x01, MRMDestMem, (ops i32mem:$dst, R32:$src2),
                   "add{l} {$src2, $dst|$dst, $src2}",
                   [(store (add (load addr:$dst), R32:$src2), addr:$dst)]>;
  def ADD8mi   : Ii8<0x80, MRM0m, (ops i8mem :$dst, i8imm :$src2),
                     "add{b} {$src2, $dst|$dst, $src2}",
                   [(store (add (load addr:$dst), (i8 imm:$src2)), addr:$dst)]>;
  def ADD16mi  : Ii16<0x81, MRM0m, (ops i16mem:$dst, i16imm:$src2),
                      "add{w} {$src2, $dst|$dst, $src2}",
                  [(store (add (load addr:$dst), (i16 imm:$src2)), addr:$dst)]>,
                   OpSize;
  def ADD32mi  : Ii32<0x81, MRM0m, (ops i32mem:$dst, i32imm:$src2),
                      "add{l} {$src2, $dst|$dst, $src2}",
                  [(store (add (load addr:$dst), (i32 imm:$src2)), addr:$dst)]>;
  def ADD16mi8 : Ii8<0x83, MRM0m, (ops i16mem:$dst, i16i8imm :$src2),
                     "add{w} {$src2, $dst|$dst, $src2}",
                [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
                   OpSize;
  def ADD32mi8 : Ii8<0x83, MRM0m, (ops i32mem:$dst, i32i8imm :$src2),
                     "add{l} {$src2, $dst|$dst, $src2}",
                [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
let isCommutable = 1 in {  // X = ADC Y, Z --> X = ADC Z, Y
def ADC32rr  : I<0x11, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "adc{l} {$src2, $dst|$dst, $src2}", []>;
def ADC32rm  : I<0x13, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "adc{l} {$src2, $dst|$dst, $src2}", []>;
def ADC32ri  : Ii32<0x81, MRM2r, (ops R32:$dst, R32:$src1, i32imm:$src2),
                    "adc{l} {$src2, $dst|$dst, $src2}", []>;
def ADC32ri8 : Ii8<0x83, MRM2r, (ops R32:$dst, R32:$src1, i8imm:$src2),
                   "adc{l} {$src2, $dst|$dst, $src2}", []>;
  def ADC32mr  : I<0x11, MRMDestMem, (ops i32mem:$dst, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                   "adc{l} {$src2, $dst|$dst, $src2}", []>;
  def ADC32mi  : Ii32<0x81, MRM2m, (ops i32mem:$dst, i32imm:$src2),
                      "adc{l} {$src2, $dst|$dst, $src2}", []>;
  def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i8imm :$src2),
                     "adc{l} {$src2, $dst|$dst, $src2}", []>;
def SUB8rr   : I<0x28, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "sub{b} {$src2, $dst|$dst, $src2}",
                 [(set R8:$dst, (sub R8:$src1, R8:$src2))]>;
def SUB16rr  : I<0x29, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "sub{w} {$src2, $dst|$dst, $src2}",
                 [(set R16:$dst, (sub R16:$src1, R16:$src2))]>, OpSize;
def SUB32rr  : I<0x29, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "sub{l} {$src2, $dst|$dst, $src2}",
                 [(set R32:$dst, (sub R32:$src1, R32:$src2))]>;
def SUB8rm   : I<0x2A, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "sub{b} {$src2, $dst|$dst, $src2}",
                 [(set R8:$dst, (sub R8:$src1, (load addr:$src2)))]>;
def SUB16rm  : I<0x2B, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "sub{w} {$src2, $dst|$dst, $src2}",
                 [(set R16:$dst, (sub R16:$src1, (load addr:$src2)))]>, OpSize;
def SUB32rm  : I<0x2B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "sub{l} {$src2, $dst|$dst, $src2}",
                 [(set R32:$dst, (sub R32:$src1, (load addr:$src2)))]>;
def SUB8ri   : Ii8 <0x80, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
                    "sub{b} {$src2, $dst|$dst, $src2}",
                    [(set R8:$dst, (sub R8:$src1, imm:$src2))]>;
def SUB16ri  : Ii16<0x81, MRM5r, (ops R16:$dst, R16:$src1, i16imm:$src2),
                    "sub{w} {$src2, $dst|$dst, $src2}",
                    [(set R16:$dst, (sub R16:$src1, imm:$src2))]>, OpSize;
def SUB32ri  : Ii32<0x81, MRM5r, (ops R32:$dst, R32:$src1, i32imm:$src2),
                    "sub{l} {$src2, $dst|$dst, $src2}",
                    [(set R32:$dst, (sub R32:$src1, imm:$src2))]>;
def SUB16ri8 : Ii8<0x83, MRM5r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
                   "sub{w} {$src2, $dst|$dst, $src2}",
                   [(set R16:$dst, (sub R16:$src1, i16immSExt8:$src2))]>,
                   OpSize;
def SUB32ri8 : Ii8<0x83, MRM5r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
                   "sub{l} {$src2, $dst|$dst, $src2}",
                   [(set R32:$dst, (sub R32:$src1, i32immSExt8:$src2))]>;
  def SUB8mr   : I<0x28, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
Evan Cheng's avatar
Evan Cheng committed
                   "sub{b} {$src2, $dst|$dst, $src2}",
                   [(store (sub (load addr:$dst), R8:$src2), addr:$dst)]>;
  def SUB16mr  : I<0x29, MRMDestMem, (ops i16mem:$dst, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                   "sub{w} {$src2, $dst|$dst, $src2}",
                   [(store (sub (load addr:$dst), R16:$src2), addr:$dst)]>,
                   OpSize;
  def SUB32mr  : I<0x29, MRMDestMem, (ops i32mem:$dst, R32:$src2), 
Evan Cheng's avatar
Evan Cheng committed
                   "sub{l} {$src2, $dst|$dst, $src2}",
                   [(store (sub (load addr:$dst), R32:$src2), addr:$dst)]>;
  def SUB8mi   : Ii8<0x80, MRM5m, (ops i8mem :$dst, i8imm:$src2), 
Evan Cheng's avatar
Evan Cheng committed
                     "sub{b} {$src2, $dst|$dst, $src2}",
                   [(store (sub (load addr:$dst), (i8 imm:$src2)), addr:$dst)]>;
  def SUB16mi  : Ii16<0x81, MRM5m, (ops i16mem:$dst, i16imm:$src2), 
Evan Cheng's avatar
Evan Cheng committed
                      "sub{w} {$src2, $dst|$dst, $src2}",
                  [(store (sub (load addr:$dst), (i16 imm:$src2)), addr:$dst)]>,
                   OpSize;
  def SUB32mi  : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2), 
Evan Cheng's avatar
Evan Cheng committed
                      "sub{l} {$src2, $dst|$dst, $src2}",
                  [(store (sub (load addr:$dst), (i32 imm:$src2)), addr:$dst)]>;
Evan Cheng's avatar
Evan Cheng committed
  def SUB16mi8 : Ii8<0x83, MRM5m, (ops i16mem:$dst, i16i8imm :$src2), 
                     "sub{w} {$src2, $dst|$dst, $src2}",
                [(store (sub (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
                   OpSize;
Evan Cheng's avatar
Evan Cheng committed
  def SUB32mi8 : Ii8<0x83, MRM5m, (ops i32mem:$dst, i32i8imm :$src2), 
                     "sub{l} {$src2, $dst|$dst, $src2}",
                [(store (sub (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
def SBB32rr    : I<0x19, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                  "sbb{l} {$src2, $dst|$dst, $src2}", []>;
  def SBB32mr  : I<0x19, MRMDestMem, (ops i32mem:$dst, R32:$src2), 
Evan Cheng's avatar
Evan Cheng committed
                   "sbb{l} {$src2, $dst|$dst, $src2}", []>;
  def SBB8mi  : Ii32<0x80, MRM3m, (ops i8mem:$dst, i8imm:$src2), 
                      "sbb{b} {$src2, $dst|$dst, $src2}", []>;
  def SBB16mi  : Ii32<0x81, MRM3m, (ops i16mem:$dst, i16imm:$src2), 
                      "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
  def SBB32mi  : Ii32<0x81, MRM3m, (ops i32mem:$dst, i32imm:$src2), 
                      "sbb{l} {$src2, $dst|$dst, $src2}", []>;
  def SBB16mi8 : Ii8<0x83, MRM3m, (ops i16mem:$dst, i8imm :$src2), 
                     "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
  def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i8imm :$src2), 
                     "sbb{l} {$src2, $dst|$dst, $src2}", []>;
def SBB8ri   : Ii8<0x80, MRM3r, (ops R8:$dst, R8:$src1, i8imm:$src2),
                    "sbb{b} {$src2, $dst|$dst, $src2}", []>;
def SBB16ri  : Ii16<0x81, MRM3r, (ops R16:$dst, R16:$src1, i16imm:$src2),
                    "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
def SBB32rm  : I<0x1B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
Evan Cheng's avatar
Evan Cheng committed
                    "sbb{l} {$src2, $dst|$dst, $src2}", []>;
def SBB32ri  : Ii32<0x81, MRM3r, (ops R32:$dst, R32:$src1, i32imm:$src2),
                    "sbb{l} {$src2, $dst|$dst, $src2}", []>;
def SBB16ri8 : Ii8<0x83, MRM3r, (ops R16:$dst, R16:$src1, i8imm:$src2),
                   "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
def SBB32ri8 : Ii8<0x83, MRM3r, (ops R32:$dst, R32:$src1, i8imm:$src2),
                   "sbb{l} {$src2, $dst|$dst, $src2}", []>;
let isCommutable = 1 in {  // X = IMUL Y, Z --> X = IMUL Z, Y
def IMUL16rr : I<0xAF, MRMSrcReg, (ops R16:$dst, R16:$src1, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "imul{w} {$src2, $dst|$dst, $src2}",
                 [(set R16:$dst, (mul R16:$src1, R16:$src2))]>, TB, OpSize;
def IMUL32rr : I<0xAF, MRMSrcReg, (ops R32:$dst, R32:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "imul{l} {$src2, $dst|$dst, $src2}",
                 [(set R32:$dst, (mul R32:$src1, R32:$src2))]>, TB;
def IMUL16rm : I<0xAF, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
                 "imul{w} {$src2, $dst|$dst, $src2}",
                 [(set R16:$dst, (mul R16:$src1, (load addr:$src2)))]>,
                 TB, OpSize;
def IMUL32rm : I<0xAF, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
                 "imul{l} {$src2, $dst|$dst, $src2}",
                 [(set R32:$dst, (mul R32:$src1, (load addr:$src2)))]>, TB;
// Suprisingly enough, these are not two address instructions!
def IMUL16rri  : Ii16<0x69, MRMSrcReg,                      // R16 = R16*I16
                      (ops R16:$dst, R16:$src1, i16imm:$src2),
                      "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
                      [(set R16:$dst, (mul R16:$src1, imm:$src2))]>, OpSize;
def IMUL32rri  : Ii32<0x69, MRMSrcReg,                      // R32 = R32*I32
                      (ops R32:$dst, R32:$src1, i32imm:$src2),
                      "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
                      [(set R32:$dst, (mul R32:$src1, imm:$src2))]>;
def IMUL16rri8 : Ii8<0x6B, MRMSrcReg,                       // R16 = R16*I8
                     (ops R16:$dst, R16:$src1, i16i8imm:$src2),
                     "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
                     [(set R16:$dst, (mul R16:$src1, i16immSExt8:$src2))]>,
                     OpSize;
def IMUL32rri8 : Ii8<0x6B, MRMSrcReg,                       // R32 = R32*I8
                     (ops R32:$dst, R32:$src1, i32i8imm:$src2),
                     "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
                     [(set R32:$dst, (mul R32:$src1, i32immSExt8:$src2))]>;

def IMUL16rmi  : Ii16<0x69, MRMSrcMem,                      // R16 = [mem16]*I16
                      (ops R16:$dst, i16mem:$src1, i16imm:$src2),
                      "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
                      [(set R16:$dst, (mul (load addr:$src1), imm:$src2))]>,
                      OpSize;
def IMUL32rmi  : Ii32<0x69, MRMSrcMem,                      // R32 = [mem32]*I32
                      (ops R32:$dst, i32mem:$src1, i32imm:$src2),
                      "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
                      [(set R32:$dst, (mul (load addr:$src1), imm:$src2))]>;
def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem,                       // R16 = [mem16]*I8
                     (ops R16:$dst, i16mem:$src1, i16i8imm :$src2),
                     "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
                  [(set R16:$dst, (mul (load addr:$src1), i16immSExt8:$src2))]>,
                     OpSize;
def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem,                       // R32 = [mem32]*I8
                     (ops R32:$dst, i32mem:$src1, i32i8imm: $src2),
                     "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
                  [(set R32:$dst, (mul (load addr:$src1), i32immSExt8:$src2))]>;
//===----------------------------------------------------------------------===//
// 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, (ops R8:$src1, R8:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "test{b} {$src2, $src1|$src1, $src2}", []>;
def TEST16rr : I<0x85, MRMDestReg, (ops R16:$src1, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "test{w} {$src2, $src1|$src1, $src2}", []>, OpSize;
def TEST32rr : I<0x85, MRMDestReg, (ops R32:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "test{l} {$src2, $src1|$src1, $src2}", []>;
Chris Lattner's avatar
Chris Lattner committed
}
def TEST8mr  : I<0x84, MRMDestMem, (ops i8mem :$src1, R8 :$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "test{b} {$src2, $src1|$src1, $src2}", []>;
def TEST16mr : I<0x85, MRMDestMem, (ops i16mem:$src1, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "test{w} {$src2, $src1|$src1, $src2}", []>, OpSize;
def TEST32mr : I<0x85, MRMDestMem, (ops i32mem:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "test{l} {$src2, $src1|$src1, $src2}", []>;
def TEST8rm  : I<0x84, MRMSrcMem, (ops R8 :$src1, i8mem :$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "test{b} {$src2, $src1|$src1, $src2}", []>;
def TEST16rm : I<0x85, MRMSrcMem, (ops R16:$src1, i16mem:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "test{w} {$src2, $src1|$src1, $src2}", []>, OpSize;
def TEST32rm : I<0x85, MRMSrcMem, (ops R32:$src1, i32mem:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "test{l} {$src2, $src1|$src1, $src2}", []>;
def TEST8ri  : Ii8 <0xF6, MRM0r,                     // flags = R8  & imm8
                    (ops R8:$src1, i8imm:$src2),
                    "test{b} {$src2, $src1|$src1, $src2}", []>;
def TEST16ri : Ii16<0xF7, MRM0r,                     // flags = R16 & imm16
                    (ops R16:$src1, i16imm:$src2),
                    "test{w} {$src2, $src1|$src1, $src2}", []>, OpSize;
def TEST32ri : Ii32<0xF7, MRM0r,                     // flags = R32 & imm32
                    (ops R32:$src1, i32imm:$src2),
                    "test{l} {$src2, $src1|$src1, $src2}", []>;
def TEST8mi  : Ii8 <0xF6, MRM0m,                     // flags = [mem8]  & imm8
                    (ops i32mem:$src1, i8imm:$src2),
                    "test{b} {$src2, $src1|$src1, $src2}", []>;
def TEST16mi : Ii16<0xF7, MRM0m,                     // flags = [mem16] & imm16
                    (ops i16mem:$src1, i16imm:$src2),
                    "test{w} {$src2, $src1|$src1, $src2}", []>, OpSize;
def TEST32mi : Ii32<0xF7, MRM0m,                     // flags = [mem32] & imm32
                    (ops i32mem:$src1, i32imm:$src2),
                    "test{l} {$src2, $src1|$src1, $src2}", []>;
// Condition code ops, incl. set if equal/not equal/...
Evan Cheng's avatar
Evan Cheng committed
def SAHF     : I<0x9E, RawFrm, (ops), "sahf", []>, Imp<[AH],[]>;  // flags = AH
def LAHF     : I<0x9F, RawFrm, (ops), "lahf", []>, Imp<[],[AH]>;  // AH = flags
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setb $dst", []>, TB;    // R8 = <  unsign
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setb $dst", []>, TB;    // [mem8] = <  unsign
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setae $dst", []>, TB;   // R8 = >= unsign
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setae $dst", []>, TB;   // [mem8] = >= unsign
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "sete $dst", []>, TB;    // R8 = ==
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "sete $dst", []>, TB;    // [mem8] = ==
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setne $dst", []>, TB;   // R8 = !=
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setne $dst", []>, TB;   // [mem8] = !=
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setbe $dst", []>, TB;   // R8 = <= unsign
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setbe $dst", []>, TB;   // [mem8] = <= unsign
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "seta $dst", []>, TB;    // R8 = >  signed
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "seta $dst", []>, TB;    // [mem8] = >  signed
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "sets $dst", []>, TB;    // R8 = <sign bit>
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "sets $dst", []>, TB;    // [mem8] = <sign bit>
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setns $dst", []>, TB;   // R8 = !<sign bit>
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setns $dst", []>, TB;   // [mem8] = !<sign bit>
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setp $dst", []>, TB;    // R8 = parity
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setp $dst", []>, TB;    // [mem8] = parity
Chris Lattner's avatar
Chris Lattner committed
def SETNPr   : I<0x9B, MRM0r, 
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setnp $dst", []>, TB;   // R8 = not parity
Chris Lattner's avatar
Chris Lattner committed
def SETNPm   : I<0x9B, MRM0m, 
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setnp $dst", []>, TB;   // [mem8] = not parity
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setl $dst", []>, TB;    // R8 = <  signed
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setl $dst", []>, TB;    // [mem8] = <  signed
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setge $dst", []>, TB;   // R8 = >= signed
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setge $dst", []>, TB;   // [mem8] = >= signed
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setle $dst", []>, TB;   // R8 = <= signed
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setle $dst", []>, TB;   // [mem8] = <= signed
Evan Cheng's avatar
Evan Cheng committed
                 (ops R8   :$dst), "setg $dst", []>, TB;    // R8 = <  signed
Evan Cheng's avatar
Evan Cheng committed
                 (ops i8mem:$dst), "setg $dst", []>, TB;    // [mem8] = <  signed

// Integer comparisons
def CMP8rr  : I<0x38, MRMDestReg,
                (ops R8 :$src1, R8 :$src2),
Evan Cheng's avatar
Evan Cheng committed
                "cmp{b} {$src2, $src1|$src1, $src2}", []>;
def CMP16rr : I<0x39, MRMDestReg,
                (ops R16:$src1, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                "cmp{w} {$src2, $src1|$src1, $src2}", []>, OpSize;
def CMP32rr : I<0x39, MRMDestReg,
                (ops R32:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                "cmp{l} {$src2, $src1|$src1, $src2}", []>;
def CMP8mr  : I<0x38, MRMDestMem,
                (ops i8mem :$src1, R8 :$src2),
Evan Cheng's avatar
Evan Cheng committed
                "cmp{b} {$src2, $src1|$src1, $src2}", []>;
def CMP16mr : I<0x39, MRMDestMem,
                (ops i16mem:$src1, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                "cmp{w} {$src2, $src1|$src1, $src2}", []>, OpSize;
def CMP32mr : I<0x39, MRMDestMem,
                (ops i32mem:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                "cmp{l} {$src2, $src1|$src1, $src2}", []>;
def CMP8rm  : I<0x3A, MRMSrcMem,
                (ops R8 :$src1, i8mem :$src2),
Evan Cheng's avatar
Evan Cheng committed
                "cmp{b} {$src2, $src1|$src1, $src2}", []>;
def CMP16rm : I<0x3B, MRMSrcMem,
                (ops R16:$src1, i16mem:$src2),
Evan Cheng's avatar
Evan Cheng committed
                "cmp{w} {$src2, $src1|$src1, $src2}", []>, OpSize;
def CMP32rm : I<0x3B, MRMSrcMem,
                (ops R32:$src1, i32mem:$src2),
Evan Cheng's avatar
Evan Cheng committed
                "cmp{l} {$src2, $src1|$src1, $src2}", []>;
def CMP8ri  : Ii8<0x80, MRM7r,
                  (ops R16:$src1, i8imm:$src2),
                  "cmp{b} {$src2, $src1|$src1, $src2}", []>;
def CMP16ri : Ii16<0x81, MRM7r,
                   (ops R16:$src1, i16imm:$src2),
                   "cmp{w} {$src2, $src1|$src1, $src2}", []>, OpSize;
def CMP32ri : Ii32<0x81, MRM7r,
                   (ops R32:$src1, i32imm:$src2),
                   "cmp{l} {$src2, $src1|$src1, $src2}", []>;
def CMP8mi  : Ii8 <0x80, MRM7m,
                   (ops i8mem :$src1, i8imm :$src2),
                   "cmp{b} {$src2, $src1|$src1, $src2}", []>;
def CMP16mi : Ii16<0x81, MRM7m,
                   (ops i16mem:$src1, i16imm:$src2),
                   "cmp{w} {$src2, $src1|$src1, $src2}", []>, OpSize;
def CMP32mi : Ii32<0x81, MRM7m,
                   (ops i32mem:$src1, i32imm:$src2),
                   "cmp{l} {$src2, $src1|$src1, $src2}", []>;

// Sign/Zero extenders
def MOVSX16rr8 : I<0xBE, MRMSrcReg, (ops R16:$dst, R8 :$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movs{bw|x} {$src, $dst|$dst, $src}",
                   [(set R16:$dst, (sext R8:$src))]>, TB, OpSize;
def MOVSX16rm8 : I<0xBE, MRMSrcMem, (ops R16:$dst, i8mem :$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movs{bw|x} {$src, $dst|$dst, $src}", []>, TB, OpSize;
def MOVSX32rr8 : I<0xBE, MRMSrcReg, (ops R32:$dst, R8 :$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movs{bl|x} {$src, $dst|$dst, $src}",
                   [(set R32:$dst, (sext R8:$src))]>, TB;
def MOVSX32rm8 : I<0xBE, MRMSrcMem, (ops R32:$dst, i8mem :$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movs{bl|x} {$src, $dst|$dst, $src}", []>, TB;
def MOVSX32rr16: I<0xBF, MRMSrcReg, (ops R32:$dst, R16:$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movs{wl|x} {$src, $dst|$dst, $src}",
                   [(set R32:$dst, (sext R16:$src))]>, TB;
def MOVSX32rm16: I<0xBF, MRMSrcMem, (ops R32:$dst, i16mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movs{wl|x} {$src, $dst|$dst, $src}", []>, TB;

def MOVZX16rr8 : I<0xB6, MRMSrcReg, (ops R16:$dst, R8 :$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movz{bw|x} {$src, $dst|$dst, $src}",
                   [(set R16:$dst, (zext R8:$src))]>, TB, OpSize;
def MOVZX16rm8 : I<0xB6, MRMSrcMem, (ops R16:$dst, i8mem :$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movz{bw|x} {$src, $dst|$dst, $src}", []>, TB, OpSize;
def MOVZX32rr8 : I<0xB6, MRMSrcReg, (ops R32:$dst, R8 :$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movz{bl|x} {$src, $dst|$dst, $src}",
                   [(set R32:$dst, (zext R8:$src))]>, TB;
def MOVZX32rm8 : I<0xB6, MRMSrcMem, (ops R32:$dst, i8mem :$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movz{bl|x} {$src, $dst|$dst, $src}", []>, TB;
def MOVZX32rr16: I<0xB7, MRMSrcReg, (ops R32:$dst, R16:$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movz{wl|x} {$src, $dst|$dst, $src}",
                   [(set R32:$dst, (zext R16:$src))]>, TB;
def MOVZX32rm16: I<0xB7, MRMSrcMem, (ops R32:$dst, i16mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                   "movz{wl|x} {$src, $dst|$dst, $src}", []>, TB;
//===----------------------------------------------------------------------===//
// XMM Floating point support (requires SSE2)
//===----------------------------------------------------------------------===//

def MOVSSrr : I<0x10, MRMSrcReg, (ops V4F4:$dst, V4F4:$src),
Evan Cheng's avatar
Evan Cheng committed
                "movss {$src, $dst|$dst, $src}", []>, XS;
def MOVSSrm : I<0x10, MRMSrcMem, (ops V4F4:$dst, f32mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "movss {$src, $dst|$dst, $src}", []>, XS;
def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, V4F4:$src),
Evan Cheng's avatar
Evan Cheng committed
                "movss {$src, $dst|$dst, $src}", []>, XS;
def MOVSDrr : I<0x10, MRMSrcReg, (ops V2F8:$dst, V2F8:$src),
Evan Cheng's avatar
Evan Cheng committed
                "movsd {$src, $dst|$dst, $src}", []>, XD;
def MOVSDrm : I<0x10, MRMSrcMem, (ops V2F8:$dst, f64mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "movsd {$src, $dst|$dst, $src}", []>, XD;
def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, V2F8:$src),
Evan Cheng's avatar
Evan Cheng committed
                "movsd {$src, $dst|$dst, $src}", []>, XD;

def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, V2F8:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvttsd2si {$src, $dst|$dst, $src}",
                [(set R32:$dst, (fp_to_sint V2F8:$src))]>, XD;
def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvttsd2si {$src, $dst|$dst, $src}", []>, XD;
def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, V4F4:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvttss2si {$src, $dst|$dst, $src}",
                [(set R32:$dst, (fp_to_sint V4F4:$src))]>, XS;
def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvttss2si {$src, $dst|$dst, $src}", []>, XS;
def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops V4F4:$dst, V2F8:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvtsd2ss {$src, $dst|$dst, $src}",
                [(set V4F4:$dst, (fround V2F8:$src))]>, XS;
def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops V4F4:$dst, f64mem:$src), 
Evan Cheng's avatar
Evan Cheng committed
                "cvtsd2ss {$src, $dst|$dst, $src}", []>, XS;
def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops V2F8:$dst, V4F4:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvtss2sd {$src, $dst|$dst, $src}",
                [(set V2F8:$dst, (fextend V4F4:$src))]>, XD;
def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops V2F8:$dst, f32mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvtss2sd {$src, $dst|$dst, $src}", []>, XD;
def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops V4F4:$dst, R32:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvtsi2ss {$src, $dst|$dst, $src}",
                [(set V4F4:$dst, (sint_to_fp R32:$src))]>, XS;
def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops V4F4:$dst, i32mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvtsi2ss {$src, $dst|$dst, $src}", []>, XS;
def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops V2F8:$dst, R32:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvtsi2sd {$src, $dst|$dst, $src}",
                [(set V2F8:$dst, (sint_to_fp R32:$src))]>, XD;
def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops V2F8:$dst, i32mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "cvtsi2sd {$src, $dst|$dst, $src}", []>, XD;
def SQRTSSrm : I<0x51, MRMSrcMem, (ops V4F4:$dst, f32mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "sqrtss {$src, $dst|$dst, $src}", []>, XS;
def SQRTSSrr : I<0x51, MRMSrcReg, (ops V4F4:$dst, V4F4:$src),
Evan Cheng's avatar
Evan Cheng committed
                "sqrtss {$src, $dst|$dst, $src}",
                [(set V4F4:$dst, (fsqrt V4F4:$src))]>, XS;
def SQRTSDrm : I<0x51, MRMSrcMem, (ops V2F8:$dst, f64mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "sqrtsd {$src, $dst|$dst, $src}", []>, XD;
def SQRTSDrr : I<0x51, MRMSrcReg, (ops V2F8:$dst, V2F8:$src),
Evan Cheng's avatar
Evan Cheng committed
                "sqrtsd {$src, $dst|$dst, $src}",
                [(set V2F8:$dst, (fsqrt V2F8:$src))]>, XD;
def UCOMISDrr: I<0x2E, MRMSrcReg, (ops V2F8:$dst, V2F8:$src),
Evan Cheng's avatar
Evan Cheng committed
                "ucomisd {$src, $dst|$dst, $src}", []>, TB, OpSize;
def UCOMISDrm: I<0x2E, MRMSrcMem, (ops V2F8:$dst, f64mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "ucomisd {$src, $dst|$dst, $src}", []>, TB, OpSize;
def UCOMISSrr: I<0x2E, MRMSrcReg, (ops V4F4:$dst, V4F4:$src),
Evan Cheng's avatar
Evan Cheng committed
                "ucomiss {$src, $dst|$dst, $src}", []>, TB;
def UCOMISSrm: I<0x2E, MRMSrcMem, (ops V4F4:$dst, f32mem:$src),
Evan Cheng's avatar
Evan Cheng committed
                "ucomiss {$src, $dst|$dst, $src}", []>, TB;
Evan Cheng's avatar
Evan Cheng committed
// Pseudo-instructions that map fld0 to xorps/xorpd for sse.
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
def FLD0SS : I<0x57, MRMSrcReg, (ops V4F4:$dst),
Evan Cheng's avatar
Evan Cheng committed
                "xorps $dst, $dst", []>, TB;
def FLD0SD : I<0x57, MRMSrcReg, (ops V2F8:$dst),
Evan Cheng's avatar
Evan Cheng committed
                "xorpd $dst, $dst", []>, TB, OpSize;
let isTwoAddress = 1 in {
let isCommutable = 1 in {
Evan Cheng's avatar
Evan Cheng committed
def ADDSSrr : I<0x58, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
                "addss {$src2, $dst|$dst, $src2}",
                [(set V4F4:$dst, (fadd V4F4:$src1, V4F4:$src2))]>, XS;
def ADDSDrr : I<0x58, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
                "addsd {$src2, $dst|$dst, $src2}",
                [(set V2F8:$dst, (fadd V2F8:$src1, V2F8:$src2))]>, XD;
def ANDPSrr : I<0x54, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
                "andps {$src2, $dst|$dst, $src2}", []>, TB;
def ANDPDrr : I<0x54, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
                "andpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
def MULSSrr : I<0x59, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
                "mulss {$src2, $dst|$dst, $src2}",
                [(set V4F4:$dst, (fmul V4F4:$src1, V4F4:$src2))]>, XS;
def MULSDrr : I<0x59, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
                "mulsd {$src2, $dst|$dst, $src2}",
                [(set V2F8:$dst, (fmul V2F8:$src1, V2F8:$src2))]>, XD;
def ORPSrr : I<0x56, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
                "orps {$src2, $dst|$dst, $src2}", []>, TB;
def ORPDrr : I<0x56, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
                "orpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
def XORPSrr : I<0x57, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
                "xorps {$src2, $dst|$dst, $src2}", []>, TB;
def XORPDrr : I<0x57, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
                "xorpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
Evan Cheng's avatar
Evan Cheng committed
def ANDNPSrr : I<0x55, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
                "andnps {$src2, $dst|$dst, $src2}", []>, TB;
def ANDNPDrr : I<0x55, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
                "andnpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
def ADDSSrm : I<0x58, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src2),
                "addss {$src2, $dst|$dst, $src2}", []>, XS;
def ADDSDrm : I<0x58, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src2),
                "addsd {$src2, $dst|$dst, $src2}", []>, XD;
def MULSSrm : I<0x59, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src2),
                "mulss {$src2, $dst|$dst, $src2}", []>, XS;
def MULSDrm : I<0x59, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src2),
                "mulsd {$src2, $dst|$dst, $src2}", []>, XD;

def DIVSSrm : I<0x5E, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src2),
                "divss {$src2, $dst|$dst, $src2}", []>, XS;
def DIVSSrr : I<0x5E, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
                "divss {$src2, $dst|$dst, $src2}",
                [(set V4F4:$dst, (fdiv V4F4:$src1, V4F4:$src2))]>, XS;
def DIVSDrm : I<0x5E, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src2),
                "divsd {$src2, $dst|$dst, $src2}", []>, XD;
def DIVSDrr : I<0x5E, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
                "divsd {$src2, $dst|$dst, $src2}",
                [(set V2F8:$dst, (fdiv V2F8:$src1, V2F8:$src2))]>, XD;

def SUBSSrm : I<0x5C, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src2),
                "subss {$src2, $dst|$dst, $src2}", []>, XS;
def SUBSSrr : I<0x5C, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
                "subss {$src2, $dst|$dst, $src2}",
                [(set V4F4:$dst, (fsub V4F4:$src1, V4F4:$src2))]>, XS;
def SUBSDrm : I<0x5C, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src2),
                "subsd {$src2, $dst|$dst, $src2}", []>, XD;
def SUBSDrr : I<0x5C, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
                "subsd {$src2, $dst|$dst, $src2}",
                [(set V2F8:$dst, (fsub V2F8:$src1, V2F8:$src2))]>, XD;
                (ops V4F4:$dst, V4F4:$src1, V4F4:$src, SSECC:$cc),
Evan Cheng's avatar
Evan Cheng committed
                "cmp${cc}ss {$src, $dst|$dst, $src}", []>, XS;
                (ops V4F4:$dst, V4F4:$src1, f32mem:$src, SSECC:$cc),
Evan Cheng's avatar
Evan Cheng committed
                "cmp${cc}ss {$src, $dst|$dst, $src}", []>, XS;
                (ops V2F8:$dst, V2F8:$src1, V2F8:$src, SSECC:$cc),
Evan Cheng's avatar
Evan Cheng committed
                "cmp${cc}sd {$src, $dst|$dst, $src}", []>, XD;
                (ops V2F8:$dst, V2F8:$src1, f64mem:$src, SSECC:$cc),
Evan Cheng's avatar
Evan Cheng committed
                "cmp${cc}sd {$src, $dst|$dst, $src}", []>, XD;
Chris Lattner's avatar
Chris Lattner committed
//===----------------------------------------------------------------------===//
// Miscellaneous Instructions
//===----------------------------------------------------------------------===//

Evan Cheng's avatar
Evan Cheng committed
def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", []>, TB, Imp<[],[EAX,EDX]>;
//===----------------------------------------------------------------------===//
// Stack-based Floating point support
//===----------------------------------------------------------------------===//

// FIXME: These need to indicate mod/ref sets for FP regs... & FP 'TOP'

// Floating point instruction template
class FPI<bits<8> o, Format F, FPFormat fp, dag ops, string asm>
  let FPForm = fp; let FPFormBits = FPForm.Value;
}
// Pseudo instructions for floating point.  We use these pseudo instructions
// because they can be expanded by the fp spackifier into one of many different
// forms of instructions for doing these operations.  Until the stackifier runs,
// we prefer to be abstract.
def FpMOV : FPI<0, Pseudo, SpecialFP,
Chris Lattner's avatar
Chris Lattner committed
                (ops RFP:$dst, RFP:$src), "">;   // f1 = fmov f2
def FpADD : FPI<0, Pseudo, TwoArgFP ,
Chris Lattner's avatar
Chris Lattner committed
                (ops RFP:$dst, RFP:$src1, RFP:$src2), "">; // f1 = fadd f2, f3
def FpSUB : FPI<0, Pseudo, TwoArgFP ,
Chris Lattner's avatar
Chris Lattner committed
                (ops RFP:$dst, RFP:$src1, RFP:$src2), "">;    // f1 = fsub f2, f3
def FpMUL : FPI<0, Pseudo, TwoArgFP ,
Chris Lattner's avatar
Chris Lattner committed
                (ops RFP:$dst, RFP:$src1, RFP:$src2), "">;    // f1 = fmul f2, f3
def FpDIV : FPI<0, Pseudo, TwoArgFP ,
Chris Lattner's avatar
Chris Lattner committed
                (ops RFP:$dst, RFP:$src1, RFP:$src2), "">;    // f1 = fdiv f2, f3
Chris Lattner's avatar
Chris Lattner committed
def FpGETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$dst), "">,
Chris Lattner's avatar
Chris Lattner committed
def FpSETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$src), "">,
// FADD reg, mem: Before stackification, these are represented by:
// R1 = FADD* R2, [mem]
def FADD32m  : FPI<0xD8, MRM0m, OneArgFPRW,    // ST(0) = ST(0) + [mem32real]
                   (ops f32mem:$src, variable_ops),
                   "fadd{s} $src">;
def FADD64m  : FPI<0xDC, MRM0m, OneArgFPRW,    // ST(0) = ST(0) + [mem64real]
                   (ops f64mem:$src, variable_ops),
                   "fadd{l} $src">;
//def FIADD16m : FPI<0xDE, MRM0m, OneArgFPRW>;    // ST(0) = ST(0) + [mem16int]
//def FIADD32m : FPI<0xDA, MRM0m, OneArgFPRW>;    // ST(0) = ST(0) + [mem32int]
// FMUL reg, mem: Before stackification, these are represented by:
// R1 = FMUL* R2, [mem]
def FMUL32m  : FPI<0xD8, MRM1m, OneArgFPRW,    // ST(0) = ST(0) * [mem32real]
                   (ops f32mem:$src, variable_ops),
                   "fmul{s} $src">;
def FMUL64m  : FPI<0xDC, MRM1m, OneArgFPRW,    // ST(0) = ST(0) * [mem64real]
                   (ops f64mem:$src, variable_ops),
                   "fmul{l} $src">;
// ST(0) = ST(0) * [mem16int]
//def FIMUL16m : FPI16m<"fimul", 0xDE, MRM1m, OneArgFPRW>;
// ST(0) = ST(0) * [mem32int]
//def FIMUL32m : FPI32m<"fimul", 0xDA, MRM1m, OneArgFPRW>;

// FSUB reg, mem: Before stackification, these are represented by:
// R1 = FSUB* R2, [mem]
def FSUB32m  : FPI<0xD8, MRM4m, OneArgFPRW,    // ST(0) = ST(0) - [mem32real]
Chris Lattner's avatar
Chris Lattner committed
                   (ops f32mem:$src, variable_ops),
                   "fsub{s} $src">;
def FSUB64m  : FPI<0xDC, MRM4m, OneArgFPRW,    // ST(0) = ST(0) - [mem64real]
Chris Lattner's avatar
Chris Lattner committed
                   (ops f64mem:$src, variable_ops),
                   "fsub{l} $src">;
// ST(0) = ST(0) - [mem16int]
//def FISUB16m : FPI16m<"fisub", 0xDE, MRM4m, OneArgFPRW>;
// ST(0) = ST(0) - [mem32int]
//def FISUB32m : FPI32m<"fisub", 0xDA, MRM4m, OneArgFPRW>;

// FSUBR reg, mem: Before stackification, these are represented by:
// R1 = FSUBR* R2, [mem]

// Note that the order of operands does not reflect the operation being
// performed.
def FSUBR32m  : FPI<0xD8, MRM5m, OneArgFPRW,  // ST(0) = [mem32real] - ST(0)
                    (ops f32mem:$src, variable_ops),
                    "fsubr{s} $src">;
def FSUBR64m  : FPI<0xDC, MRM5m, OneArgFPRW,  // ST(0) = [mem64real] - ST(0)
                    (ops f64mem:$src, variable_ops),
                    "fsubr{l} $src">;
// ST(0) = [mem16int] - ST(0)
//def FISUBR16m : FPI16m<"fisubr", 0xDE, MRM5m, OneArgFPRW>;
// ST(0) = [mem32int] - ST(0)
//def FISUBR32m : FPI32m<"fisubr", 0xDA, MRM5m, OneArgFPRW>;

// FDIV reg, mem: Before stackification, these are represented by:
// R1 = FDIV* R2, [mem]
def FDIV32m  : FPI<0xD8, MRM6m, OneArgFPRW,    // ST(0) = ST(0) / [mem32real]
                   (ops f32mem:$src, variable_ops),
                   "fdiv{s} $src">;
def FDIV64m  : FPI<0xDC, MRM6m, OneArgFPRW,    // ST(0) = ST(0) / [mem64real]
                   (ops f64mem:$src, variable_ops),
                   "fdiv{l} $src">;
// ST(0) = ST(0) / [mem16int]
//def FIDIV16m : FPI16m<"fidiv", 0xDE, MRM6m, OneArgFPRW>;
// ST(0) = ST(0) / [mem32int]
//def FIDIV32m : FPI32m<"fidiv", 0xDA, MRM6m, OneArgFPRW>;

// FDIVR reg, mem: Before stackification, these are represented by:
// R1 = FDIVR* R2, [mem]
// Note that the order of operands does not reflect the operation being
// performed.
def FDIVR32m  : FPI<0xD8, MRM7m, OneArgFPRW,  // ST(0) = [mem32real] / ST(0)
Chris Lattner's avatar
Chris Lattner committed
                    (ops f32mem:$src, variable_ops),
                    "fdivr{s} $src">;
def FDIVR64m  : FPI<0xDC, MRM7m, OneArgFPRW,  // ST(0) = [mem64real] / ST(0)
Chris Lattner's avatar
Chris Lattner committed
                    (ops f64mem:$src, variable_ops),
                    "fdivr{l} $src">;
// ST(0) = [mem16int] / ST(0)
//def FIDIVR16m : FPI16m<"fidivr", 0xDE, MRM7m, OneArgFPRW>;
// ST(0) = [mem32int] / ST(0)
//def FIDIVR32m : FPI32m<"fidivr", 0xDA, MRM7m, OneArgFPRW>;
let isTwoAddress = 1, Uses = [ST0], Defs = [ST0] in {
  def FCMOVB  : FPI<0xC0, AddRegFrm, CondMovFP,
                    (ops RST:$op, variable_ops),
                    "fcmovb {$op, %ST(0)|%ST(0), $op}">, DA;
  def FCMOVBE : FPI<0xD0, AddRegFrm, CondMovFP,
                    (ops RST:$op, variable_ops),
                    "fcmovbe {$op, %ST(0)|%ST(0), $op}">, DA;
  def FCMOVE  : FPI<0xC8, AddRegFrm, CondMovFP,
                    (ops RST:$op, variable_ops),
                    "fcmove {$op, %ST(0)|%ST(0), $op}">, DA;
  def FCMOVP  : FPI<0xD8, AddRegFrm, CondMovFP,
                    (ops RST:$op, variable_ops),
                    "fcmovu  {$op, %ST(0)|%ST(0), $op}">, DA;
  def FCMOVAE : FPI<0xC0, AddRegFrm, CondMovFP,
                    (ops RST:$op, variable_ops),
                    "fcmovae {$op, %ST(0)|%ST(0), $op}">, DB;
  def FCMOVA  : FPI<0xD0, AddRegFrm, CondMovFP,
                    (ops RST:$op, variable_ops),
                    "fcmova {$op, %ST(0)|%ST(0), $op}">, DB;
  def FCMOVNE : FPI<0xC8, AddRegFrm, CondMovFP,
                    (ops RST:$op, variable_ops),
                    "fcmovne {$op, %ST(0)|%ST(0), $op}">, DB;
  def FCMOVNP : FPI<0xD8, AddRegFrm, CondMovFP,
                    (ops RST:$op, variable_ops),
                    "fcmovnu {$op, %ST(0)|%ST(0), $op}">, DB;
// Floating point loads & stores...
// FIXME: these are all marked variable_ops because they have an implicit 
// destination.  Instructions like FILD* that are generated by the instruction
//  selector (not the fp stackifier) need more accurate operand accounting.
def FLDrr   : FPI<0xC0, AddRegFrm, NotFP,
                  (ops RST:$src, variable_ops),
                  "fld $src">, D9;
def FLD32m  : FPI<0xD9, MRM0m, ZeroArgFP,
                  (ops f32mem:$src, variable_ops),
                  "fld{s} $src">;
def FLD64m  : FPI<0xDD, MRM0m, ZeroArgFP,
                  (ops f64mem:$src, variable_ops),
                  "fld{l} $src">;
def FLD80m  : FPI<0xDB, MRM5m, ZeroArgFP,
                  (ops f80mem:$src, variable_ops),
                  "fld{t} $src">;
def FILD16m : FPI<0xDF, MRM0m, ZeroArgFP,
                  (ops i16mem:$src, variable_ops),
                  "fild{s} $src">;
def FILD32m : FPI<0xDB, MRM0m, ZeroArgFP,
                  (ops i32mem:$src, variable_ops),
                  "fild{l} $src">;
def FILD64m : FPI<0xDF, MRM5m, ZeroArgFP,
                  (ops i64mem:$src, variable_ops),
                  "fild{ll} $src">;