Skip to content
X86InstrInfo.td 128 KiB
Newer Older
def AND16rm  : I<0x23, MRMSrcMem, 
                 (ops R16:$dst, R16:$src1, i16mem:$src2),
                 "and{w} {$src2, $dst|$dst, $src2}",
                [(set R16:$dst, (and R16:$src1, (load addr:$src2)))]>, OpSize;
def AND32rm  : I<0x23, MRMSrcMem,
                 (ops R32:$dst, R32:$src1, i32mem:$src2),
                 "and{l} {$src2, $dst|$dst, $src2}",
                [(set R32:$dst, (and R32:$src1, (load addr:$src2)))]>;

def AND8ri   : Ii8<0x80, MRM4r, 
                   (ops R8 :$dst, R8 :$src1, i8imm :$src2),
                   "and{b} {$src2, $dst|$dst, $src2}",
                   [(set R8:$dst, (and R8:$src1, imm:$src2))]>;
def AND16ri  : Ii16<0x81, MRM4r, 
                    (ops R16:$dst, R16:$src1, i16imm:$src2),
                    "and{w} {$src2, $dst|$dst, $src2}",
                    [(set R16:$dst, (and R16:$src1, imm:$src2))]>, OpSize;
def AND32ri  : Ii32<0x81, MRM4r, 
                    (ops R32:$dst, R32:$src1, i32imm:$src2),
                    "and{l} {$src2, $dst|$dst, $src2}",
                    [(set R32:$dst, (and R32:$src1, imm:$src2))]>;
                   (ops R16:$dst, R16:$src1, i16i8imm:$src2),
                   "and{w} {$src2, $dst|$dst, $src2}",
                   [(set R16:$dst, (and R16:$src1, i16immSExt8:$src2))]>,
                   OpSize;
                   (ops R32:$dst, R32:$src1, i32i8imm:$src2),
                   "and{l} {$src2, $dst|$dst, $src2}",
                   [(set R32:$dst, (and R32:$src1, i32immSExt8:$src2))]>;
  def AND8mr   : I<0x20, MRMDestMem,
                   (ops i8mem :$dst, R8 :$src),
                   "and{b} {$src, $dst|$dst, $src}",
                   [(store (and (load addr:$dst), R8:$src), addr:$dst)]>;
  def AND16mr  : I<0x21, MRMDestMem,
                   (ops i16mem:$dst, R16:$src),
                   "and{w} {$src, $dst|$dst, $src}",
                   [(store (and (load addr:$dst), R16:$src), addr:$dst)]>,
                   OpSize;
  def AND32mr  : I<0x21, MRMDestMem,
                   (ops i32mem:$dst, R32:$src),
                   "and{l} {$src, $dst|$dst, $src}",
                   [(store (and (load addr:$dst), R32:$src), addr:$dst)]>;
  def AND8mi   : Ii8<0x80, MRM4m,
                     (ops i8mem :$dst, i8imm :$src),
                     "and{b} {$src, $dst|$dst, $src}",
Evan Cheng's avatar
Evan Cheng committed
                      [(store (and (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
  def AND16mi  : Ii16<0x81, MRM4m,
                      (ops i16mem:$dst, i16imm:$src),
                      "and{w} {$src, $dst|$dst, $src}",
Evan Cheng's avatar
Evan Cheng committed
                      [(store (and (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
  def AND32mi  : Ii32<0x81, MRM4m,
                      (ops i32mem:$dst, i32imm:$src),
                      "and{l} {$src, $dst|$dst, $src}",
Evan Cheng's avatar
Evan Cheng committed
                      [(store (and (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
                     (ops i16mem:$dst, i16i8imm :$src),
                     "and{w} {$src, $dst|$dst, $src}",
                [(store (and (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
                     OpSize;
                     (ops i32mem:$dst, i32i8imm :$src),
                     "and{l} {$src, $dst|$dst, $src}",
                [(store (add (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
Chris Lattner's avatar
Chris Lattner committed
let isCommutable = 1 in {   // X = OR Y, Z   --> X = OR Z, Y
def OR8rr    : I<0x08, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "or{b} {$src2, $dst|$dst, $src2}",
                 [(set R8:$dst, (or R8:$src1, R8:$src2))]>;
def OR16rr   : I<0x09, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "or{w} {$src2, $dst|$dst, $src2}",
                 [(set R16:$dst, (or R16:$src1, R16:$src2))]>, OpSize;
def OR32rr   : I<0x09, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "or{l} {$src2, $dst|$dst, $src2}",
                 [(set R32:$dst, (or R32:$src1, R32:$src2))]>;
Chris Lattner's avatar
Chris Lattner committed
}
def OR8rm    : I<0x0A, MRMSrcMem , (ops R8 :$dst, R8 :$src1, i8mem :$src2),
                 "or{b} {$src2, $dst|$dst, $src2}",
                [(set R8:$dst, (or R8:$src1, (load addr:$src2)))]>;
def OR16rm   : I<0x0B, MRMSrcMem , (ops R16:$dst, R16:$src1, i16mem:$src2),
                 "or{w} {$src2, $dst|$dst, $src2}",
                [(set R16:$dst, (or R16:$src1, (load addr:$src2)))]>, OpSize;
def OR32rm   : I<0x0B, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
                 "or{l} {$src2, $dst|$dst, $src2}",
                [(set R32:$dst, (or R32:$src1, (load addr:$src2)))]>;
def OR8ri    : Ii8 <0x80, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
                    "or{b} {$src2, $dst|$dst, $src2}",
                    [(set R8:$dst, (or R8:$src1, imm:$src2))]>;
def OR16ri   : Ii16<0x81, MRM1r, (ops R16:$dst, R16:$src1, i16imm:$src2),
                    "or{w} {$src2, $dst|$dst, $src2}", 
                    [(set R16:$dst, (or R16:$src1, imm:$src2))]>, OpSize;
def OR32ri   : Ii32<0x81, MRM1r, (ops R32:$dst, R32:$src1, i32imm:$src2),
                    "or{l} {$src2, $dst|$dst, $src2}",
                    [(set R32:$dst, (or R32:$src1, imm:$src2))]>;
def OR16ri8  : Ii8<0x83, MRM1r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
                   "or{w} {$src2, $dst|$dst, $src2}",
                   [(set R16:$dst, (or R16:$src1, i16immSExt8:$src2))]>, OpSize;
def OR32ri8  : Ii8<0x83, MRM1r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
                   "or{l} {$src2, $dst|$dst, $src2}",
                   [(set R32:$dst, (or R32:$src1, i32immSExt8:$src2))]>;
  def OR8mr  : I<0x08, MRMDestMem, (ops i8mem:$dst, R8:$src),
                 "or{b} {$src, $dst|$dst, $src}",
                 [(store (or (load addr:$dst), R8:$src), addr:$dst)]>;
  def OR16mr : I<0x09, MRMDestMem, (ops i16mem:$dst, R16:$src),
                 "or{w} {$src, $dst|$dst, $src}",
                 [(store (or (load addr:$dst), R16:$src), addr:$dst)]>, OpSize;
  def OR32mr : I<0x09, MRMDestMem, (ops i32mem:$dst, R32:$src),
                 "or{l} {$src, $dst|$dst, $src}",
                 [(store (or (load addr:$dst), R32:$src), addr:$dst)]>;
  def OR8mi    : Ii8<0x80, MRM1m, (ops i8mem :$dst, i8imm:$src),
                 "or{b} {$src, $dst|$dst, $src}",
Evan Cheng's avatar
Evan Cheng committed
                 [(store (or (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
  def OR16mi   : Ii16<0x81, MRM1m, (ops i16mem:$dst, i16imm:$src),
                 "or{w} {$src, $dst|$dst, $src}",
Evan Cheng's avatar
Evan Cheng committed
                 [(store (or (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
  def OR32mi   : Ii32<0x81, MRM1m, (ops i32mem:$dst, i32imm:$src),
                 "or{l} {$src, $dst|$dst, $src}",
Evan Cheng's avatar
Evan Cheng committed
                 [(store (or (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
  def OR16mi8  : Ii8<0x83, MRM1m, (ops i16mem:$dst, i16i8imm:$src),
                 "or{w} {$src, $dst|$dst, $src}",
                 [(store (or (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
                     OpSize;
  def OR32mi8  : Ii8<0x83, MRM1m, (ops i32mem:$dst, i32i8imm:$src),
                 "or{l} {$src, $dst|$dst, $src}",
                 [(store (or (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
Chris Lattner's avatar
Chris Lattner committed
let isCommutable = 1 in {   // X = XOR Y, Z   --> X = XOR Z, Y
def XOR8rr   : I<0x30, MRMDestReg,
                 (ops R8 :$dst, R8 :$src1, R8 :$src2),
Evan Cheng's avatar
Evan Cheng committed
                 "xor{b} {$src2, $dst|$dst, $src2}",
                 [(set R8:$dst, (xor R8:$src1, R8:$src2))]>;
def XOR16rr  : I<0x31, MRMDestReg, 
                 (ops R16:$dst, R16:$src1, R16:$src2), 
Evan Cheng's avatar
Evan Cheng committed
                 "xor{w} {$src2, $dst|$dst, $src2}",
                 [(set R16:$dst, (xor R16:$src1, R16:$src2))]>, OpSize;
def XOR32rr  : I<0x31, MRMDestReg, 
                 (ops R32:$dst, R32:$src1, R32:$src2), 
Evan Cheng's avatar
Evan Cheng committed
                 "xor{l} {$src2, $dst|$dst, $src2}",
                 [(set R32:$dst, (xor R32:$src1, R32:$src2))]>;
def XOR8rm   : I<0x32, MRMSrcMem , 
                 (ops R8 :$dst, R8:$src1, i8mem :$src2), 
                 "xor{b} {$src2, $dst|$dst, $src2}",
                 [(set R8:$dst, (xor R8:$src1, (load addr:$src2)))]>;
                 (ops R16:$dst, R16:$src1, i16mem:$src2), 
                 "xor{w} {$src2, $dst|$dst, $src2}",
                 [(set R16:$dst, (xor R16:$src1, (load addr:$src2)))]>, OpSize;
                 (ops R32:$dst, R32:$src1, i32mem:$src2), 
                 "xor{l} {$src2, $dst|$dst, $src2}",
                 [(set R32:$dst, (xor R32:$src1, (load addr:$src2)))]>;

def XOR8ri   : Ii8<0x80, MRM6r, 
                   (ops R8:$dst, R8:$src1, i8imm:$src2), 
                   "xor{b} {$src2, $dst|$dst, $src2}",
                   [(set R8:$dst, (xor R8:$src1, imm:$src2))]>;
def XOR16ri  : Ii16<0x81, MRM6r, 
                    (ops R16:$dst, R16:$src1, i16imm:$src2), 
                    "xor{w} {$src2, $dst|$dst, $src2}",
                    [(set R16:$dst, (xor R16:$src1, imm:$src2))]>, OpSize;
def XOR32ri  : Ii32<0x81, MRM6r, 
                    (ops R32:$dst, R32:$src1, i32imm:$src2), 
                    "xor{l} {$src2, $dst|$dst, $src2}",
                    [(set R32:$dst, (xor R32:$src1, imm:$src2))]>;
                   (ops R16:$dst, R16:$src1, i16i8imm:$src2),
                   "xor{w} {$src2, $dst|$dst, $src2}",
                   [(set R16:$dst, (xor R16:$src1, i16immSExt8:$src2))]>,
                   OpSize;
                   (ops R32:$dst, R32:$src1, i32i8imm:$src2),
                   "xor{l} {$src2, $dst|$dst, $src2}",
                   [(set R32:$dst, (xor R32:$src1, i32immSExt8:$src2))]>;
  def XOR8mr   : I<0x30, MRMDestMem,
                   (ops i8mem :$dst, R8 :$src),
                   "xor{b} {$src, $dst|$dst, $src}",
                   [(store (xor (load addr:$dst), R8:$src), addr:$dst)]>;
  def XOR16mr  : I<0x31, MRMDestMem,
                   (ops i16mem:$dst, R16:$src),
                   "xor{w} {$src, $dst|$dst, $src}",
                   [(store (xor (load addr:$dst), R16:$src), addr:$dst)]>,
                   OpSize;
  def XOR32mr  : I<0x31, MRMDestMem,
                   (ops i32mem:$dst, R32:$src),
                   "xor{l} {$src, $dst|$dst, $src}",
                   [(store (xor (load addr:$dst), R32:$src), addr:$dst)]>;
  def XOR8mi   : Ii8<0x80, MRM6m,
                     (ops i8mem :$dst, i8imm :$src),
                     "xor{b} {$src, $dst|$dst, $src}",
Evan Cheng's avatar
Evan Cheng committed
                    [(store (xor (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
  def XOR16mi  : Ii16<0x81, MRM6m,
                      (ops i16mem:$dst, i16imm:$src),
                      "xor{w} {$src, $dst|$dst, $src}",
Evan Cheng's avatar
Evan Cheng committed
                   [(store (xor (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
  def XOR32mi  : Ii32<0x81, MRM6m,
                      (ops i32mem:$dst, i32imm:$src),
                      "xor{l} {$src, $dst|$dst, $src}",
Evan Cheng's avatar
Evan Cheng committed
                   [(store (xor (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
                     (ops i16mem:$dst, i16i8imm :$src),
                     "xor{w} {$src, $dst|$dst, $src}",
                 [(store (xor (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
                     OpSize;
                     (ops i32mem:$dst, i32i8imm :$src),
                     "xor{l} {$src, $dst|$dst, $src}",
                 [(store (xor (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
// FIXME: provide shorter instructions when imm8 == 1
def SHL8rCL  : I<0xD2, MRM4r, (ops R8 :$dst, R8 :$src),
                 "shl{b} {%cl, $dst|$dst, %CL}",
                 [(set R8:$dst, (shl R8:$src, CL))]>, Imp<[CL],[]>;
def SHL16rCL : I<0xD3, MRM4r, (ops R16:$dst, R16:$src),
                 "shl{w} {%cl, $dst|$dst, %CL}",
                 [(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),
                   "shr{b} {%cl, $dst|$dst, %CL}",
                   [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>,
                   Imp<[CL],[]>;
  def SHR16mCL : I<0xD3, MRM5m, (ops i16mem:$dst),
                   "shr{w} {%cl, $dst|$dst, %CL}",
                   [(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>,
                   Imp<[CL],[]>, OpSize;
  def SHR32mCL : I<0xD3, MRM5m, (ops i32mem:$dst),
                   "shr{l} {%cl, $dst|$dst, %CL}",
                   [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>,
                   Imp<[CL],[]>;
  def SHR8mi   : Ii8<0xC0, MRM5m, (ops i8mem :$dst, i8imm:$src),
                     "shr{b} {$src, $dst|$dst, $src}",
                  [(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
  def SHR16mi  : Ii8<0xC1, MRM5m, (ops i16mem:$dst, i8imm:$src),
                     "shr{w} {$src, $dst|$dst, $src}",
                 [(store (srl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
                     OpSize;
  def SHR32mi  : Ii8<0xC1, MRM5m, (ops i32mem:$dst, i8imm:$src),
                     "shr{l} {$src, $dst|$dst, $src}",
                 [(store (srl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
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),
                   "sar{b} {%cl, $dst|$dst, %CL}",
                   [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>,
                   Imp<[CL],[]>;
  def SAR16mCL : I<0xD3, MRM7m, (ops i16mem:$dst),
                   "sar{w} {%cl, $dst|$dst, %CL}",
                   [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>,
                   Imp<[CL],[]>, OpSize;
  def SAR32mCL : I<0xD3, MRM7m, (ops i32mem:$dst), 
                   "sar{l} {%cl, $dst|$dst, %CL}",
                   [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>,
                   Imp<[CL],[]>;
  def SAR8mi   : Ii8<0xC0, MRM7m, (ops i8mem :$dst, i8imm:$src),
                     "sar{b} {$src, $dst|$dst, $src}",
                  [(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
  def SAR16mi  : Ii8<0xC1, MRM7m, (ops i16mem:$dst, i8imm:$src),
                     "sar{w} {$src, $dst|$dst, $src}",
                 [(store (sra (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
                     OpSize;
  def SAR32mi  : Ii8<0xC1, MRM7m, (ops i32mem:$dst, i8imm:$src),
                     "sar{l} {$src, $dst|$dst, $src}",
                 [(store (sra (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
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}",
Evan Cheng's avatar
Evan Cheng committed
                   [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
  def ADD16mi  : Ii16<0x81, MRM0m, (ops i16mem:$dst, i16imm:$src2),
                      "add{w} {$src2, $dst|$dst, $src2}",
Evan Cheng's avatar
Evan Cheng committed
                  [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
  def ADD32mi  : Ii32<0x81, MRM0m, (ops i32mem:$dst, i32imm:$src2),
                      "add{l} {$src2, $dst|$dst, $src2}",
Evan Cheng's avatar
Evan Cheng committed
                  [(store (add (loadi32 addr:$dst), 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}",
Evan Cheng's avatar
Evan Cheng committed
                   [(store (sub (loadi8 addr:$dst), 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}",
Evan Cheng's avatar
Evan Cheng committed
                  [(store (sub (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
  def SUB32mi  : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2), 
Evan Cheng's avatar
Evan Cheng committed
                      "sub{l} {$src2, $dst|$dst, $src2}",
Evan Cheng's avatar
Evan Cheng committed
                  [(store (sub (loadi32 addr:$dst), 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),
                 "test{b} {$src2, $src1|$src1, $src2}",
                 [(set STATUS, (X86test R8:$src1, R8:$src2))]>,
               Imp<[],[STATUS]>;
def TEST16rr : I<0x85, MRMDestReg, (ops R16:$src1, R16:$src2),
                 "test{w} {$src2, $src1|$src1, $src2}",
                 [(set STATUS, (X86test R16:$src1, R16:$src2))]>,
               Imp<[],[STATUS]>, OpSize;
def TEST32rr : I<0x85, MRMDestReg, (ops R32:$src1, R32:$src2),
                 "test{l} {$src2, $src1|$src1, $src2}",
                 [(set STATUS, (X86test R32:$src1, R32:$src2))]>,
               Imp<[],[STATUS]>;
Chris Lattner's avatar
Chris Lattner committed
}
def TEST8mr  : I<0x84, MRMDestMem, (ops i8mem :$src1, R8 :$src2),
                 "test{b} {$src2, $src1|$src1, $src2}",
                 [(set STATUS, (X86test (loadi8 addr:$src1), R8:$src2))]>,
               Imp<[],[STATUS]>;
def TEST16mr : I<0x85, MRMDestMem, (ops i16mem:$src1, R16:$src2),
                 "test{w} {$src2, $src1|$src1, $src2}",
                 [(set STATUS, (X86test (loadi16 addr:$src1), R16:$src2))]>,
               Imp<[],[STATUS]>, OpSize;
def TEST32mr : I<0x85, MRMDestMem, (ops i32mem:$src1, R32:$src2),
                 "test{l} {$src2, $src1|$src1, $src2}",
                 [(set STATUS, (X86test (loadi32 addr:$src1), R32:$src2))]>,
               Imp<[],[STATUS]>;
def TEST8rm  : I<0x84, MRMSrcMem, (ops R8 :$src1, i8mem :$src2),
                 "test{b} {$src2, $src1|$src1, $src2}",
                 [(set STATUS, (X86test R8:$src1, (loadi8 addr:$src2)))]>,
               Imp<[],[STATUS]>;
def TEST16rm : I<0x85, MRMSrcMem, (ops R16:$src1, i16mem:$src2),
                 "test{w} {$src2, $src1|$src1, $src2}",
                 [(set STATUS, (X86test R16:$src1, (loadi16 addr:$src2)))]>,
               Imp<[],[STATUS]>, OpSize;
def TEST32rm : I<0x85, MRMSrcMem, (ops R32:$src1, i32mem:$src2),
                 "test{l} {$src2, $src1|$src1, $src2}",
                 [(set STATUS, (X86test R32:$src1, (loadi32 addr:$src2)))]>,
               Imp<[],[STATUS]>;
def TEST8ri  : Ii8 <0xF6, MRM0r,                     // flags = R8  & imm8
                    (ops R8:$src1, i8imm:$src2),
                    "test{b} {$src2, $src1|$src1, $src2}",
                    [(set STATUS, (X86test R8:$src1, imm:$src2))]>,
                   Imp<[],[STATUS]>;
def TEST16ri : Ii16<0xF7, MRM0r,                     // flags = R16 & imm16
                    (ops R16:$src1, i16imm:$src2),
                    "test{w} {$src2, $src1|$src1, $src2}",
                    [(set STATUS, (X86test R16:$src1, imm:$src2))]>,
                   Imp<[],[STATUS]>, OpSize;
def TEST32ri : Ii32<0xF7, MRM0r,                     // flags = R32 & imm32
                    (ops R32:$src1, i32imm:$src2),
                    "test{l} {$src2, $src1|$src1, $src2}",
                    [(set STATUS, (X86test R32:$src1, imm:$src2))]>,
                   Imp<[],[STATUS]>;
def TEST8mi  : Ii8 <0xF6, MRM0m,                     // flags = [mem8]  & imm8
                    (ops i8mem:$src1, i8imm:$src2),
                    "test{b} {$src2, $src1|$src1, $src2}",
                    [(set STATUS, (X86test (loadi8 addr:$src1), imm:$src2))]>,
                   Imp<[],[STATUS]>;
def TEST16mi : Ii16<0xF7, MRM0m,                     // flags = [mem16] & imm16
                    (ops i16mem:$src1, i16imm:$src2),
                    "test{w} {$src2, $src1|$src1, $src2}",
                    [(set STATUS, (X86test (loadi16 addr:$src1), imm:$src2))]>,
                   Imp<[],[STATUS]>, OpSize;
def TEST32mi : Ii32<0xF7, MRM0m,                     // flags = [mem32] & imm32
                    (ops i32mem:$src1, i32imm:$src2),
                    "test{l} {$src2, $src1|$src1, $src2}",
                    [(set STATUS, (X86test (loadi32 addr:$src1), imm:$src2))]>,
                   Imp<[],[STATUS]>;
// 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
                 "sete $dst", [(set R8:$dst, (X86SetCC SETEQ, STATUS))]>,
               TB;                        // R8 = ==
                 (ops i8mem:$dst),
                 "sete $dst", [(store (X86SetCC SETEQ, STATUS), addr:$dst)]>,
               TB;                        // [mem8] = ==
                 "setne $dst", [(set R8:$dst, (X86SetCC SETNE, STATUS))]>,
               TB;                        // R8 = !=
                 (ops i8mem:$dst),
                 "setne $dst", [(store (X86SetCC SETNE, STATUS), addr:$dst)]>,
               TB;                        // [mem8] = !=
def SETLr    : I<0x9C, MRM0r, 
                 (ops R8   :$dst),
                 "setl $dst", [(set R8:$dst, (X86SetCC SETLT, STATUS))]>,
               TB;                        // R8 = <  signed
def SETLm    : I<0x9C, MRM0m, 
                 (ops i8mem:$dst),
                 "setl $dst", [(store (X86SetCC SETLT, STATUS), addr:$dst)]>,
               TB;                        // [mem8] = <  signed
def SETGEr   : I<0x9D, MRM0r, 
                 (ops R8   :$dst),
                 "setge $dst", [(set R8:$dst, (X86SetCC SETGE, STATUS))]>,
               TB;                        // R8 = >= signed
def SETGEm   : I<0x9D, MRM0m, 
                 (ops i8mem:$dst),
                 "setge $dst", [(store (X86SetCC SETGE, STATUS), addr:$dst)]>,
               TB;                        // [mem8] = >= signed
def SETLEr   : I<0x9E, MRM0r, 
                 (ops R8   :$dst),
                 "setle $dst", [(set R8:$dst, (X86SetCC SETLE, STATUS))]>,
               TB;                        // R8 = <= signed
def SETLEm   : I<0x9E, MRM0m, 
                 (ops i8mem:$dst),
                 "setle $dst", [(store (X86SetCC SETLE, STATUS), addr:$dst)]>,
               TB;                        // [mem8] = <= signed
def SETGr    : I<0x9F, MRM0r, 
                 (ops R8   :$dst),
                 "setg $dst", [(set R8:$dst, (X86SetCC SETGT, STATUS))]>,
               TB;                        // R8 = >  signed
def SETGm    : I<0x9F, MRM0m, 
                 (ops i8mem:$dst),
                 "setg $dst", [(store (X86SetCC SETGT, STATUS), addr:$dst)]>,
               TB;                        // [mem8] = >  signed

def SETBr    : I<0x92, MRM0r,
                 (ops R8   :$dst),
                 "setb $dst", [(set R8:$dst, (X86SetCC SETULT, STATUS))]>,
               TB;                        // R8 = <  unsign
def SETBm    : I<0x92, MRM0m,
                 (ops i8mem:$dst),
                 "setb $dst", [(store (X86SetCC SETULT, STATUS), addr:$dst)]>,
               TB;                        // [mem8] = <  unsign
def SETAEr   : I<0x93, MRM0r, 
                 (ops R8   :$dst),
                 "setae $dst", [(set R8:$dst, (X86SetCC SETUGE, STATUS))]>,
               TB;                        // R8 = >= unsign
def SETAEm   : I<0x93, MRM0m, 
                 (ops i8mem:$dst),
                 "setae $dst", [(store (X86SetCC SETUGE, STATUS), addr:$dst)]>,
               TB;                        // [mem8] = >= unsign
                 "setbe $dst", [(set R8:$dst, (X86SetCC SETULE, STATUS))]>,
               TB;                        // R8 = <= unsign
                 (ops i8mem:$dst),
                 "setbe $dst", [(store (X86SetCC SETULE, STATUS), addr:$dst)]>,
               TB;                        // [mem8] = <= unsign
                 "seta $dst", [(set R8:$dst, (X86SetCC SETUGT, STATUS))]>,
               TB;                        // R8 = >  signed
                 (ops i8mem:$dst),
                 "seta $dst", [(store (X86SetCC SETUGT, STATUS), addr:$dst)]>,
               TB;                        // [mem8] = >  signed
                 (ops R8   :$dst),
                 "sets $dst", []>, TB;    // R8 = <sign bit>
                 (ops i8mem:$dst),
                 "sets $dst", []>, TB;    // [mem8] = <sign bit>
                 (ops R8   :$dst),
                 "setns $dst", []>, TB;   // R8 = !<sign bit>
                 (ops i8mem:$dst),
                 "setns $dst", []>, TB;   // [mem8] = !<sign bit>
                 (ops R8   :$dst),
                 "setp $dst", []>, TB;    // R8 = parity
                 (ops i8mem:$dst),
                 "setp $dst", []>, TB;    // [mem8] = parity
Chris Lattner's avatar
Chris Lattner committed
def SETNPr   : I<0x9B, MRM0r, 
                 (ops R8   :$dst),
                 "setnp $dst", []>, TB;   // R8 = not parity
Chris Lattner's avatar
Chris Lattner committed
def SETNPm   : I<0x9B, MRM0m, 
                 (ops i8mem:$dst),
                 "setnp $dst", []>, TB;   // [mem8] = not parity

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

// Sign/Zero extenders