Newer
Older
Chris Lattner
committed
let isTwoAddress = 0 in {
def INC8m : I<0xFE, MRM0m, (ops i8mem :$dst), "inc{b} $dst",
[(store (add (loadi8 addr:$dst), 1), addr:$dst)]>;
def INC16m : I<0xFF, MRM0m, (ops i16mem:$dst), "inc{w} $dst",
[(store (add (loadi16 addr:$dst), 1), addr:$dst)]>, OpSize;
def INC32m : I<0xFF, MRM0m, (ops i32mem:$dst), "inc{l} $dst",
[(store (add (loadi32 addr:$dst), 1), addr:$dst)]>;
Chris Lattner
committed
}
def DEC8r : I<0xFE, MRM1r, (ops R8 :$dst, R8 :$src), "dec{b} $dst",
[(set R8:$dst, (add R8:$src, -1))]>;
let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
def DEC16r : I<0xFF, MRM1r, (ops R16:$dst, R16:$src), "dec{w} $dst",
[(set R16:$dst, (add R16:$src, -1))]>, OpSize;
def DEC32r : I<0xFF, MRM1r, (ops R32:$dst, R32:$src), "dec{l} $dst",
[(set R32:$dst, (add R32:$src, -1))]>;
Chris Lattner
committed
let isTwoAddress = 0 in {
def DEC8m : I<0xFE, MRM1m, (ops i8mem :$dst), "dec{b} $dst",
[(store (add (loadi8 addr:$dst), -1), addr:$dst)]>;
def DEC16m : I<0xFF, MRM1m, (ops i16mem:$dst), "dec{w} $dst",
[(store (add (loadi16 addr:$dst), -1), addr:$dst)]>, OpSize;
def DEC32m : I<0xFF, MRM1m, (ops i32mem:$dst), "dec{l} $dst",
[(store (add (loadi32 addr:$dst), -1), addr:$dst)]>;
Chris Lattner
committed
}
// Logical operators...
let isCommutable = 1 in { // X = AND Y, Z --> X = AND Z, Y
def AND8rr : I<0x20, MRMDestReg,
(ops R8 :$dst, R8 :$src1, R8 :$src2),
"and{b} {$src2, $dst|$dst, $src2}",
[(set R8:$dst, (and R8:$src1, R8:$src2))]>;
def AND16rr : I<0x21, MRMDestReg,
(ops R16:$dst, R16:$src1, R16:$src2),
"and{w} {$src2, $dst|$dst, $src2}",
[(set R16:$dst, (and R16:$src1, R16:$src2))]>, OpSize;
def AND32rr : I<0x21, MRMDestReg,
(ops R32:$dst, R32:$src1, R32:$src2),
"and{l} {$src2, $dst|$dst, $src2}",
[(set R32:$dst, (and R32:$src1, R32:$src2))]>;
def AND8rm : I<0x22, MRMSrcMem,
(ops R8 :$dst, R8 :$src1, i8mem :$src2),
"and{b} {$src2, $dst|$dst, $src2}",
[(set R8:$dst, (and R8:$src1, (load addr:$src2)))]>;
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))]>;
def AND16ri8 : Ii8<0x83, MRM4r,
(ops R16:$dst, R16:$src1, i16i8imm:$src2),
"and{w} {$src2, $dst|$dst, $src2}",
[(set R16:$dst, (and R16:$src1, i16immSExt8:$src2))]>,
OpSize;
def AND32ri8 : Ii8<0x83, MRM4r,
(ops R32:$dst, R32:$src1, i32i8imm:$src2),
"and{l} {$src2, $dst|$dst, $src2}",
[(set R32:$dst, (and R32:$src1, i32immSExt8:$src2))]>;
Chris Lattner
committed
let isTwoAddress = 0 in {
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}",
[(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}",
[(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}",
[(store (and (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
def AND16mi8 : Ii8<0x83, MRM4m,
(ops i16mem:$dst, i16i8imm :$src),
"and{w} {$src, $dst|$dst, $src}",
[(store (and (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
OpSize;
def AND32mi8 : Ii8<0x83, MRM4m,
(ops i32mem:$dst, i32i8imm :$src),
"and{l} {$src, $dst|$dst, $src}",
[(store (add (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
Chris Lattner
committed
}
let isCommutable = 1 in { // X = OR Y, Z --> X = OR Z, Y
Chris Lattner
committed
def OR8rr : I<0x08, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
"or{b} {$src2, $dst|$dst, $src2}",
[(set R8:$dst, (or R8:$src1, R8:$src2))]>;
Chris Lattner
committed
def OR16rr : I<0x09, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
"or{w} {$src2, $dst|$dst, $src2}",
[(set R16:$dst, (or R16:$src1, R16:$src2))]>, OpSize;
Chris Lattner
committed
def OR32rr : I<0x09, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
"or{l} {$src2, $dst|$dst, $src2}",
[(set R32:$dst, (or R32:$src1, R32:$src2))]>;
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)))]>;
Chris Lattner
committed
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;
Chris Lattner
committed
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)))]>;
Chris Lattner
committed
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))]>;
Chris Lattner
committed
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;
Chris Lattner
committed
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))]>;
Chris Lattner
committed
let isTwoAddress = 0 in {
Chris Lattner
committed
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)]>;
Chris Lattner
committed
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;
Chris Lattner
committed
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}",
[(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}",
[(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}",
[(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
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),
"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),
"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),
"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)))]>;
def XOR16rm : I<0x33, MRMSrcMem ,
(ops R16:$dst, R16:$src1, i16mem:$src2),
"xor{w} {$src2, $dst|$dst, $src2}",
[(set R16:$dst, (xor R16:$src1, (load addr:$src2)))]>, OpSize;
def XOR32rm : I<0x33, MRMSrcMem ,
(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))]>;
def XOR16ri8 : Ii8<0x83, MRM6r,
(ops R16:$dst, R16:$src1, i16i8imm:$src2),
"xor{w} {$src2, $dst|$dst, $src2}",
[(set R16:$dst, (xor R16:$src1, i16immSExt8:$src2))]>,
OpSize;
def XOR32ri8 : Ii8<0x83, MRM6r,
(ops R32:$dst, R32:$src1, i32i8imm:$src2),
"xor{l} {$src2, $dst|$dst, $src2}",
[(set R32:$dst, (xor R32:$src1, i32immSExt8:$src2))]>;
Chris Lattner
committed
let isTwoAddress = 0 in {
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}",
[(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}",
[(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}",
[(store (xor (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
def XOR16mi8 : Ii8<0x83, MRM6m,
(ops i16mem:$dst, i16i8imm :$src),
"xor{w} {$src, $dst|$dst, $src}",
[(store (xor (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
OpSize;
def XOR32mi8 : Ii8<0x83, MRM6m,
(ops i32mem:$dst, i32i8imm :$src),
"xor{l} {$src, $dst|$dst, $src}",
[(store (xor (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
Chris Lattner
committed
}
// Shift instructions
// 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
committed
def SHL8ri : Ii8<0xC0, MRM4r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
"shl{b} {$src2, $dst|$dst, $src2}",
let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
def SHL16ri : Ii8<0xC1, MRM4r, (ops R16:$dst, R16:$src1, i8imm:$src2),
"shl{w} {$src2, $dst|$dst, $src2}",
[(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
committed
let isTwoAddress = 0 in {
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)]>;
Chris Lattner
committed
}
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}",
[(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}",
[(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
committed
Chris Lattner
committed
let isTwoAddress = 0 in {
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)]>;
Chris Lattner
committed
}
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],[]>;
Chris Lattner
committed
def SAR8ri : Ii8<0xC0, MRM7r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
"sar{b} {$src2, $dst|$dst, $src2}",
[(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}",
[(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
committed
let isTwoAddress = 0 in {
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
committed
}
// Rotate instructions
// FIXME: provide shorter instructions when imm8 == 1
def ROL8rCL : I<0xD2, MRM0r, (ops R8 :$dst, R8 :$src),
"rol{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
def ROL16rCL : I<0xD3, MRM0r, (ops R16:$dst, R16:$src),
"rol{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
def ROL32rCL : I<0xD3, MRM0r, (ops R32:$dst, R32:$src),
"rol{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
def ROL8ri : Ii8<0xC0, MRM0r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
"rol{b} {$src2, $dst|$dst, $src2}", []>;
def ROL16ri : Ii8<0xC1, MRM0r, (ops R16:$dst, R16:$src1, i8imm:$src2),
"rol{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
def ROL32ri : Ii8<0xC1, MRM0r, (ops R32:$dst, R32:$src1, i8imm:$src2),
"rol{l} {$src2, $dst|$dst, $src2}", []>;
let isTwoAddress = 0 in {
def ROL8mCL : I<0xD2, MRM0m, (ops i8mem :$dst),
"rol{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
def ROL16mCL : I<0xD3, MRM0m, (ops i16mem:$dst),
"rol{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
def ROL32mCL : I<0xD3, MRM0m, (ops i32mem:$dst),
"rol{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
def ROL8mi : Ii8<0xC0, MRM0m, (ops i8mem :$dst, i8imm:$src),
"rol{b} {$src, $dst|$dst, $src}", []>;
def ROL16mi : Ii8<0xC1, MRM0m, (ops i16mem:$dst, i8imm:$src),
"rol{w} {$src, $dst|$dst, $src}", []>, OpSize;
def ROL32mi : Ii8<0xC1, MRM0m, (ops i32mem:$dst, i8imm:$src),
"rol{l} {$src, $dst|$dst, $src}", []>;
}
def ROR8rCL : I<0xD2, MRM1r, (ops R8 :$dst, R8 :$src),
"ror{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
def ROR16rCL : I<0xD3, MRM1r, (ops R16:$dst, R16:$src),
"ror{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
def ROR32rCL : I<0xD3, MRM1r, (ops R32:$dst, R32:$src),
"ror{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
def ROR8ri : Ii8<0xC0, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
"ror{b} {$src2, $dst|$dst, $src2}", []>;
def ROR16ri : Ii8<0xC1, MRM1r, (ops R16:$dst, R16:$src1, i8imm:$src2),
"ror{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
def ROR32ri : Ii8<0xC1, MRM1r, (ops R32:$dst, R32:$src1, i8imm:$src2),
"ror{l} {$src2, $dst|$dst, $src2}", []>;
let isTwoAddress = 0 in {
def ROR8mCL : I<0xD2, MRM1m, (ops i8mem :$dst),
"ror{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
def ROR16mCL : I<0xD3, MRM1m, (ops i16mem:$dst),
"ror{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
def ROR32mCL : I<0xD3, MRM1m, (ops i32mem:$dst),
"ror{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
def ROR8mi : Ii8<0xC0, MRM1m, (ops i8mem :$dst, i8imm:$src),
"ror{b} {$src, $dst|$dst, $src}", []>;
def ROR16mi : Ii8<0xC1, MRM1m, (ops i16mem:$dst, i8imm:$src),
"ror{w} {$src, $dst|$dst, $src}", []>, OpSize;
def ROR32mi : Ii8<0xC1, MRM1m, (ops i32mem:$dst, i8imm:$src),
"ror{l} {$src, $dst|$dst, $src}", []>;
}
// Double shift instructions (generalizations of rotate)
Chris Lattner
committed
def SHLD32rrCL : I<0xA5, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
"shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
Imp<[CL],[]>, TB;
Chris Lattner
committed
def SHRD32rrCL : I<0xAD, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
"shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
Imp<[CL],[]>, TB;
def SHLD16rrCL : I<0xA5, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
"shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
Imp<[CL],[]>, TB, OpSize;
def SHRD16rrCL : I<0xAD, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
"shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
Imp<[CL],[]>, TB, OpSize;
Chris Lattner
committed
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}", []>,
TB, OpSize;
Chris Lattner
committed
}
Chris Lattner
committed
let isTwoAddress = 0 in {
def SHLD32mrCL : I<0xA5, MRMDestMem, (ops i32mem:$dst, R32:$src2),
"shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
Imp<[CL],[]>, TB;
Chris Lattner
committed
def SHRD32mrCL : I<0xAD, MRMDestMem, (ops i32mem:$dst, R32:$src2),
"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),
"shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
Imp<[CL],[]>, TB, OpSize;
def SHRD16mrCL : I<0xAD, MRMDestMem, (ops i16mem:$dst, R16:$src2),
"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}", []>,
TB, OpSize;
// 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),
"add{b} {$src2, $dst|$dst, $src2}",
[(set R8:$dst, (add R8:$src1, R8:$src2))]>;
let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
def ADD16rr : I<0x01, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
"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),
"add{l} {$src2, $dst|$dst, $src2}",
[(set R32:$dst, (add R32:$src1, R32:$src2))]>;
} // end isConvertibleToThreeAddress
} // end isCommutable
def ADD8rm : I<0x02, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
Evan Cheng
committed
"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),
Evan Cheng
committed
"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),
Evan Cheng
committed
"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))]>;
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))]>;
// 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))]>;
Chris Lattner
committed
let isTwoAddress = 0 in {
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 (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
def ADD16mi : Ii16<0x81, MRM0m, (ops i16mem:$dst, i16imm:$src2),
"add{w} {$src2, $dst|$dst, $src2}",
[(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}",
[(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)]>;
Chris Lattner
committed
}
let isCommutable = 1 in { // X = ADC Y, Z --> X = ADC Z, Y
def ADC32rr : I<0x11, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
def ADC32rm : I<0x13, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$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}", []>;
Chris Lattner
committed
let isTwoAddress = 0 in {
def ADC32mr : I<0x11, MRMDestMem, (ops i32mem:$dst, R32:$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}", []>;
Chris Lattner
committed
}
def SUB8rr : I<0x28, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
"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),
"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),
"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),
"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),
"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),
"sub{l} {$src2, $dst|$dst, $src2}",
[(set R32:$dst, (sub R32:$src1, (load addr:$src2)))]>;
Chris Lattner
committed
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))]>;
Chris Lattner
committed
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;
Chris Lattner
committed
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))]>;
Chris Lattner
committed
let isTwoAddress = 0 in {
def SUB8mr : I<0x28, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
"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),
[(store (sub (load addr:$dst), R16:$src2), addr:$dst)]>,
OpSize;
def SUB32mr : I<0x29, MRMDestMem, (ops i32mem:$dst, R32:$src2),
"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),
[(store (sub (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
def SUB16mi : Ii16<0x81, MRM5m, (ops i16mem:$dst, i16imm:$src2),
[(store (sub (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
def SUB32mi : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2),
[(store (sub (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
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;
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)]>;
Chris Lattner
committed
}
def SBB32rr : I<0x19, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
Chris Lattner
committed
let isTwoAddress = 0 in {
def SBB32mr : I<0x19, MRMDestMem, (ops i32mem:$dst, R32:$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}", []>;
Chris Lattner
committed
}
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;
Chris Lattner
committed
def SBB32rm : I<0x1B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
Chris Lattner
committed
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;
Chris Lattner
committed
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),
"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),
"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),
[(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;
} // end Two Address instructions
Chris Lattner
committed
// 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
committed
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]>;
Chris Lattner
committed
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;
Chris Lattner
committed
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
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]>;
Chris Lattner
committed
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;
Chris Lattner
committed
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]>;
Chris Lattner
committed
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]>;
Chris Lattner
committed
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;
Chris Lattner
committed
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/...
def SAHF : I<0x9E, RawFrm, (ops), "sahf", []>, Imp<[AH],[]>; // flags = AH
def LAHF : I<0x9F, RawFrm, (ops), "lahf", []>, Imp<[],[AH]>; // AH = flags
def SETEr : I<0x94, MRM0r,
"sete $dst", [(set R8:$dst, (X86SetCC SETEQ, STATUS))]>,
TB; // R8 = ==
def SETEm : I<0x94, MRM0m,
"sete $dst", [(store (X86SetCC SETEQ, STATUS), addr:$dst)]>,
TB; // [mem8] = ==
def SETNEr : I<0x95, MRM0r,
"setne $dst", [(set R8:$dst, (X86SetCC SETNE, STATUS))]>,
TB; // R8 = !=
def SETNEm : I<0x95, MRM0m,
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
"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
def SETBEr : I<0x96, MRM0r,
"setbe $dst", [(set R8:$dst, (X86SetCC SETULE, STATUS))]>,
TB; // R8 = <= unsign
def SETBEm : I<0x96, MRM0m,
"setbe $dst", [(store (X86SetCC SETULE, STATUS), addr:$dst)]>,
TB; // [mem8] = <= unsign
def SETAr : I<0x97, MRM0r,
"seta $dst", [(set R8:$dst, (X86SetCC SETUGT, STATUS))]>,
TB; // R8 = > signed
def SETAm : I<0x97, MRM0m,
"seta $dst", [(store (X86SetCC SETUGT, STATUS), addr:$dst)]>,
TB; // [mem8] = > signed
def SETSr : I<0x98, MRM0r,
(ops R8 :$dst),
"sets $dst", []>, TB; // R8 = <sign bit>
def SETSm : I<0x98, MRM0m,
(ops i8mem:$dst),
"sets $dst", []>, TB; // [mem8] = <sign bit>
def SETNSr : I<0x99, MRM0r,
(ops R8 :$dst),
"setns $dst", []>, TB; // R8 = !<sign bit>
def SETNSm : I<0x99, MRM0m,
(ops i8mem:$dst),
"setns $dst", []>, TB; // [mem8] = !<sign bit>
def SETPr : I<0x9A, MRM0r,
(ops R8 :$dst),
"setp $dst", []>, TB; // R8 = parity
def SETPm : I<0x9A, MRM0m,
(ops i8mem:$dst),
"setp $dst", []>, TB; // [mem8] = parity
(ops R8 :$dst),
"setnp $dst", []>, TB; // R8 = not parity
(ops i8mem:$dst),
"setnp $dst", []>, TB; // [mem8] = not parity
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]>;