Newer
Older
[(set R32:$dst, (sube R32:$src1, imm:$src2))]>;
def SBB16ri8 : Ii8<0x83, MRM3r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
"sbb{w} {$src2, $dst|$dst, $src2}",
[(set R16:$dst, (sube R16:$src1, i16immSExt8:$src2))]>,
OpSize;
def SBB32ri8 : Ii8<0x83, MRM3r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
"sbb{l} {$src2, $dst|$dst, $src2}",
[(set R32:$dst, (sube R32:$src1, i32immSExt8:$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}",
[(X86test R8:$src1, R8:$src2)]>;
Chris Lattner
committed
def TEST16rr : I<0x85, MRMDestReg, (ops R16:$src1, R16:$src2),
"test{w} {$src2, $src1|$src1, $src2}",
[(X86test R16:$src1, R16:$src2)]>, OpSize;
Chris Lattner
committed
def TEST32rr : I<0x85, MRMDestReg, (ops R32:$src1, R32:$src2),
"test{l} {$src2, $src1|$src1, $src2}",
[(X86test R32:$src1, R32:$src2)]>;
Chris Lattner
committed
def TEST8mr : I<0x84, MRMDestMem, (ops i8mem :$src1, R8 :$src2),
"test{b} {$src2, $src1|$src1, $src2}",
[(X86test (loadi8 addr:$src1), R8:$src2)]>;
Chris Lattner
committed
def TEST16mr : I<0x85, MRMDestMem, (ops i16mem:$src1, R16:$src2),
"test{w} {$src2, $src1|$src1, $src2}",
[(X86test (loadi16 addr:$src1), R16:$src2)]>,
OpSize;
Chris Lattner
committed
def TEST32mr : I<0x85, MRMDestMem, (ops i32mem:$src1, R32:$src2),
"test{l} {$src2, $src1|$src1, $src2}",
[(X86test (loadi32 addr:$src1), R32:$src2)]>;
Chris Lattner
committed
def TEST8rm : I<0x84, MRMSrcMem, (ops R8 :$src1, i8mem :$src2),
"test{b} {$src2, $src1|$src1, $src2}",
[(X86test R8:$src1, (loadi8 addr:$src2))]>;
Chris Lattner
committed
def TEST16rm : I<0x85, MRMSrcMem, (ops R16:$src1, i16mem:$src2),
"test{w} {$src2, $src1|$src1, $src2}",
[(X86test R16:$src1, (loadi16 addr:$src2))]>,
OpSize;
Chris Lattner
committed
def TEST32rm : I<0x85, MRMSrcMem, (ops R32:$src1, i32mem:$src2),
"test{l} {$src2, $src1|$src1, $src2}",
[(X86test R32:$src1, (loadi32 addr:$src2))]>;
def TEST8ri : Ii8 <0xF6, MRM0r, // flags = R8 & imm8
(ops R8:$src1, i8imm:$src2),
"test{b} {$src2, $src1|$src1, $src2}",
[(X86test R8:$src1, imm:$src2)]>;
def TEST16ri : Ii16<0xF7, MRM0r, // flags = R16 & imm16
(ops R16:$src1, i16imm:$src2),
"test{w} {$src2, $src1|$src1, $src2}",
[(X86test R16:$src1, imm:$src2)]>, OpSize;
def TEST32ri : Ii32<0xF7, MRM0r, // flags = R32 & imm32
(ops R32:$src1, i32imm:$src2),
"test{l} {$src2, $src1|$src1, $src2}",
[(X86test R32:$src1, imm:$src2)]>;
def TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8
(ops i8mem:$src1, i8imm:$src2),
"test{b} {$src2, $src1|$src1, $src2}",
[(X86test (loadi8 addr:$src1), imm:$src2)]>;
def TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16
(ops i16mem:$src1, i16imm:$src2),
"test{w} {$src2, $src1|$src1, $src2}",
[(X86test (loadi16 addr:$src1), imm:$src2)]>,
OpSize;
def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32
(ops i32mem:$src1, i32imm:$src2),
"test{l} {$src2, $src1|$src1, $src2}",
[(X86test (loadi32 addr:$src1), imm:$src2)]>;
// 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,
[(set R8:$dst, (X86setcc X86_COND_E))]>,
TB; // R8 = ==
def SETEm : I<0x94, MRM0m,
[(store (X86setcc X86_COND_E), addr:$dst)]>,
TB; // [mem8] = ==
def SETNEr : I<0x95, MRM0r,
[(set R8:$dst, (X86setcc X86_COND_NE))]>,
TB; // R8 = !=
def SETNEm : I<0x95, MRM0m,
[(store (X86setcc X86_COND_NE), addr:$dst)]>,
TB; // [mem8] = !=
def SETLr : I<0x9C, MRM0r,
(ops R8 :$dst),
[(set R8:$dst, (X86setcc X86_COND_L))]>,
TB; // R8 = < signed
def SETLm : I<0x9C, MRM0m,
(ops i8mem:$dst),
[(store (X86setcc X86_COND_L), addr:$dst)]>,
TB; // [mem8] = < signed
def SETGEr : I<0x9D, MRM0r,
(ops R8 :$dst),
[(set R8:$dst, (X86setcc X86_COND_GE))]>,
TB; // R8 = >= signed
def SETGEm : I<0x9D, MRM0m,
(ops i8mem:$dst),
[(store (X86setcc X86_COND_GE), addr:$dst)]>,
TB; // [mem8] = >= signed
def SETLEr : I<0x9E, MRM0r,
(ops R8 :$dst),
[(set R8:$dst, (X86setcc X86_COND_LE))]>,
TB; // R8 = <= signed
def SETLEm : I<0x9E, MRM0m,
(ops i8mem:$dst),
[(store (X86setcc X86_COND_LE), addr:$dst)]>,
TB; // [mem8] = <= signed
def SETGr : I<0x9F, MRM0r,
(ops R8 :$dst),
[(set R8:$dst, (X86setcc X86_COND_G))]>,
TB; // R8 = > signed
def SETGm : I<0x9F, MRM0m,
(ops i8mem:$dst),
[(store (X86setcc X86_COND_G), addr:$dst)]>,
TB; // [mem8] = > signed
def SETBr : I<0x92, MRM0r,
(ops R8 :$dst),
[(set R8:$dst, (X86setcc X86_COND_B))]>,
TB; // R8 = < unsign
def SETBm : I<0x92, MRM0m,
(ops i8mem:$dst),
[(store (X86setcc X86_COND_B), addr:$dst)]>,
TB; // [mem8] = < unsign
def SETAEr : I<0x93, MRM0r,
(ops R8 :$dst),
[(set R8:$dst, (X86setcc X86_COND_AE))]>,
TB; // R8 = >= unsign
def SETAEm : I<0x93, MRM0m,
(ops i8mem:$dst),
[(store (X86setcc X86_COND_AE), addr:$dst)]>,
TB; // [mem8] = >= unsign
def SETBEr : I<0x96, MRM0r,
[(set R8:$dst, (X86setcc X86_COND_BE))]>,
TB; // R8 = <= unsign
def SETBEm : I<0x96, MRM0m,
[(store (X86setcc X86_COND_BE), addr:$dst)]>,
TB; // [mem8] = <= unsign
def SETAr : I<0x97, MRM0r,
[(set R8:$dst, (X86setcc X86_COND_A))]>,
TB; // R8 = > signed
def SETAm : I<0x97, MRM0m,
[(store (X86setcc X86_COND_A), addr:$dst)]>,
TB; // [mem8] = > signed
def SETSr : I<0x98, MRM0r,
[(set R8:$dst, (X86setcc X86_COND_S))]>,
def SETSm : I<0x98, MRM0m,
[(store (X86setcc X86_COND_S), addr:$dst)]>,
def SETNSr : I<0x99, MRM0r,
[(set R8:$dst, (X86setcc X86_COND_NS))]>,
def SETNSm : I<0x99, MRM0m,
[(store (X86setcc X86_COND_NS), addr:$dst)]>,
def SETPr : I<0x9A, MRM0r,
[(set R8:$dst, (X86setcc X86_COND_P))]>,
def SETPm : I<0x9A, MRM0m,
[(store (X86setcc X86_COND_P), addr:$dst)]>,
[(set R8:$dst, (X86setcc X86_COND_NP))]>,
[(store (X86setcc X86_COND_NP), addr:$dst)]>,
def CMP8rr : I<0x38, MRMDestReg,
(ops R8 :$src1, R8 :$src2),
"cmp{b} {$src2, $src1|$src1, $src2}",
[(X86cmp R8:$src1, R8:$src2)]>;
def CMP16rr : I<0x39, MRMDestReg,
(ops R16:$src1, R16:$src2),
"cmp{w} {$src2, $src1|$src1, $src2}",
[(X86cmp R16:$src1, R16:$src2)]>, OpSize;
def CMP32rr : I<0x39, MRMDestReg,
(ops R32:$src1, R32:$src2),
"cmp{l} {$src2, $src1|$src1, $src2}",
[(X86cmp R32:$src1, R32:$src2)]>;
def CMP8mr : I<0x38, MRMDestMem,
(ops i8mem :$src1, R8 :$src2),
"cmp{b} {$src2, $src1|$src1, $src2}",
[(X86cmp (loadi8 addr:$src1), R8:$src2)]>;
def CMP16mr : I<0x39, MRMDestMem,
(ops i16mem:$src1, R16:$src2),
"cmp{w} {$src2, $src1|$src1, $src2}",
[(X86cmp (loadi16 addr:$src1), R16:$src2)]>, OpSize;
def CMP32mr : I<0x39, MRMDestMem,
(ops i32mem:$src1, R32:$src2),
"cmp{l} {$src2, $src1|$src1, $src2}",
[(X86cmp (loadi32 addr:$src1), R32:$src2)]>;
def CMP8rm : I<0x3A, MRMSrcMem,
(ops R8 :$src1, i8mem :$src2),
"cmp{b} {$src2, $src1|$src1, $src2}",
[(X86cmp R8:$src1, (loadi8 addr:$src2))]>;
def CMP16rm : I<0x3B, MRMSrcMem,
(ops R16:$src1, i16mem:$src2),
"cmp{w} {$src2, $src1|$src1, $src2}",
[(X86cmp R16:$src1, (loadi16 addr:$src2))]>, OpSize;
def CMP32rm : I<0x3B, MRMSrcMem,
(ops R32:$src1, i32mem:$src2),
"cmp{l} {$src2, $src1|$src1, $src2}",
[(X86cmp R32:$src1, (loadi32 addr:$src2))]>;
def CMP8ri : Ii8<0x80, MRM7r,
(ops R8:$src1, i8imm:$src2),
"cmp{b} {$src2, $src1|$src1, $src2}",
[(X86cmp R8:$src1, imm:$src2)]>;
def CMP16ri : Ii16<0x81, MRM7r,
(ops R16:$src1, i16imm:$src2),
"cmp{w} {$src2, $src1|$src1, $src2}",
[(X86cmp R16:$src1, imm:$src2)]>, OpSize;
def CMP32ri : Ii32<0x81, MRM7r,
(ops R32:$src1, i32imm:$src2),
"cmp{l} {$src2, $src1|$src1, $src2}",
[(X86cmp R32:$src1, imm:$src2)]>;
def CMP8mi : Ii8 <0x80, MRM7m,
(ops i8mem :$src1, i8imm :$src2),
"cmp{b} {$src2, $src1|$src1, $src2}",
[(X86cmp (loadi8 addr:$src1), imm:$src2)]>;
def CMP16mi : Ii16<0x81, MRM7m,
(ops i16mem:$src1, i16imm:$src2),
"cmp{w} {$src2, $src1|$src1, $src2}",
[(X86cmp (loadi16 addr:$src1), imm:$src2)]>, OpSize;
def CMP32mi : Ii32<0x81, MRM7m,
(ops i32mem:$src1, i32imm:$src2),
"cmp{l} {$src2, $src1|$src1, $src2}",
[(X86cmp (loadi32 addr:$src1), imm:$src2)]>;
def MOVSX16rr8 : I<0xBE, MRMSrcReg, (ops R16:$dst, R8 :$src),
"movs{bw|x} {$src, $dst|$dst, $src}",
[(set R16:$dst, (sext R8:$src))]>, TB, OpSize;
def MOVSX16rm8 : I<0xBE, MRMSrcMem, (ops R16:$dst, i8mem :$src),
"movs{bw|x} {$src, $dst|$dst, $src}",
[(set R16:$dst, (sextloadi16i8 addr:$src))]>, TB, OpSize;
def MOVSX32rr8 : I<0xBE, MRMSrcReg, (ops R32:$dst, R8 :$src),
"movs{bl|x} {$src, $dst|$dst, $src}",
[(set R32:$dst, (sext R8:$src))]>, TB;
def MOVSX32rm8 : I<0xBE, MRMSrcMem, (ops R32:$dst, i8mem :$src),
"movs{bl|x} {$src, $dst|$dst, $src}",
[(set R32:$dst, (sextloadi32i8 addr:$src))]>, TB;
def MOVSX32rr16: I<0xBF, MRMSrcReg, (ops R32:$dst, R16:$src),
"movs{wl|x} {$src, $dst|$dst, $src}",
[(set R32:$dst, (sext R16:$src))]>, TB;
def MOVSX32rm16: I<0xBF, MRMSrcMem, (ops R32:$dst, i16mem:$src),
"movs{wl|x} {$src, $dst|$dst, $src}",
[(set R32:$dst, (sextloadi32i16 addr:$src))]>, TB;
def MOVZX16rr8 : I<0xB6, MRMSrcReg, (ops R16:$dst, R8 :$src),
"movz{bw|x} {$src, $dst|$dst, $src}",
[(set R16:$dst, (zext R8:$src))]>, TB, OpSize;
def MOVZX16rm8 : I<0xB6, MRMSrcMem, (ops R16:$dst, i8mem :$src),
"movz{bw|x} {$src, $dst|$dst, $src}",
[(set R16:$dst, (zextloadi16i8 addr:$src))]>, TB, OpSize;
def MOVZX32rr8 : I<0xB6, MRMSrcReg, (ops R32:$dst, R8 :$src),
"movz{bl|x} {$src, $dst|$dst, $src}",
[(set R32:$dst, (zext R8:$src))]>, TB;
def MOVZX32rm8 : I<0xB6, MRMSrcMem, (ops R32:$dst, i8mem :$src),
"movz{bl|x} {$src, $dst|$dst, $src}",
[(set R32:$dst, (zextloadi32i8 addr:$src))]>, TB;
def MOVZX32rr16: I<0xB7, MRMSrcReg, (ops R32:$dst, R16:$src),
"movz{wl|x} {$src, $dst|$dst, $src}",
[(set R32:$dst, (zext R16:$src))]>, TB;
def MOVZX32rm16: I<0xB7, MRMSrcMem, (ops R32:$dst, i16mem:$src),
"movz{wl|x} {$src, $dst|$dst, $src}",
[(set R32:$dst, (zextloadi32i16 addr:$src))]>, TB;
//===----------------------------------------------------------------------===//
// XMM Floating point support (requires SSE / SSE2)
//===----------------------------------------------------------------------===//
def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src),
"movss {$src, $dst|$dst, $src}", []>,
Requires<[HasSSE1]>, XS;
def MOVSDrr : I<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src),
"movsd {$src, $dst|$dst, $src}", []>,
Requires<[HasSSE2]>, XD;
def MOVSSrm : I<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
"movss {$src, $dst|$dst, $src}",
[(set FR32:$dst, (loadf32 addr:$src))]>,
def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, FR32:$src),
"movss {$src, $dst|$dst, $src}",
[(store FR32:$src, addr:$dst)]>,
Requires<[HasSSE1]>, XS;
def MOVSDrm : I<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
"movsd {$src, $dst|$dst, $src}",
[(set FR64:$dst, (loadf64 addr:$src))]>,
def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, FR64:$src),
"movsd {$src, $dst|$dst, $src}",
[(store FR64:$src, addr:$dst)]>,
def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src),
"cvttss2si {$src, $dst|$dst, $src}",
[(set R32:$dst, (fp_to_sint FR32:$src))]>,
Requires<[HasSSE1]>, XS;
def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src),
"cvttss2si {$src, $dst|$dst, $src}",
[(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>,
Requires<[HasSSE1]>, XS;
def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src),
"cvttsd2si {$src, $dst|$dst, $src}",
[(set R32:$dst, (fp_to_sint FR64:$src))]>,
Requires<[HasSSE2]>, XD;
def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src),
"cvttsd2si {$src, $dst|$dst, $src}",
[(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>,
Requires<[HasSSE2]>, XD;
def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src),
"cvtss2sd {$src, $dst|$dst, $src}",
[(set FR64:$dst, (fextend FR32:$src))]>,
def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src),
"cvtss2sd {$src, $dst|$dst, $src}",
[(set FR64:$dst, (fextend (loadf32 addr:$src)))]>,
def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src),
"cvtsd2ss {$src, $dst|$dst, $src}",
[(set FR32:$dst, (fround FR64:$src))]>,
def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src),
"cvtsd2ss {$src, $dst|$dst, $src}",
[(set FR32:$dst, (fround (loadf64 addr:$src)))]>,
def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src),
"cvtsi2ss {$src, $dst|$dst, $src}",
[(set FR32:$dst, (sint_to_fp R32:$src))]>,
Requires<[HasSSE2]>, XS;
def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops FR32:$dst, i32mem:$src),
"cvtsi2ss {$src, $dst|$dst, $src}",
[(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
Requires<[HasSSE2]>, XS;
def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops FR64:$dst, R32:$src),
"cvtsi2sd {$src, $dst|$dst, $src}",
[(set FR64:$dst, (sint_to_fp R32:$src))]>,
Requires<[HasSSE2]>, XD;
def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops FR64:$dst, i32mem:$src),
"cvtsi2sd {$src, $dst|$dst, $src}",
[(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
Requires<[HasSSE2]>, XD;
def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src),
"sqrtss {$src, $dst|$dst, $src}",
[(set FR32:$dst, (fsqrt FR32:$src))]>,
Requires<[HasSSE1]>, XS;
def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
"sqrtss {$src, $dst|$dst, $src}",
[(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>,
Requires<[HasSSE1]>, XS;
def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src),
"sqrtsd {$src, $dst|$dst, $src}",
[(set FR64:$dst, (fsqrt FR64:$src))]>,
Requires<[HasSSE2]>, XD;
def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
"sqrtsd {$src, $dst|$dst, $src}",
[(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>,
Requires<[HasSSE2]>, XD;
def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2),
"ucomiss {$src2, $src1|$src1, $src2}",
[(X86cmp FR32:$src1, FR32:$src2)]>,
Requires<[HasSSE1]>, TB;
def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2),
"ucomiss {$src2, $src1|$src1, $src2}",
[(X86cmp FR32:$src1, (loadf32 addr:$src2))]>,
Requires<[HasSSE1]>, TB;
def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2),
"ucomisd {$src2, $src1|$src1, $src2}",
[(X86cmp FR64:$src1, FR64:$src2)]>,
Requires<[HasSSE2]>, TB, OpSize;
def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2),
"ucomisd {$src2, $src1|$src1, $src2}",
[(X86cmp FR64:$src1, (loadf64 addr:$src2))]>,
Requires<[HasSSE2]>, TB, OpSize;
// Pseudo-instructions that map fld0 to pxor for sse.
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
def FLD0SS : I<0xEF, MRMInitReg, (ops FR32:$dst),
"pxor $dst, $dst", [(set FR32:$dst, fp32imm0)]>,
Requires<[HasSSE1]>, TB, OpSize;
def FLD0SD : I<0xEF, MRMInitReg, (ops FR64:$dst),
"pxor $dst, $dst", [(set FR64:$dst, fp64imm0)]>,
let isTwoAddress = 1 in {
let isCommutable = 1 in {
def ADDSSrr : I<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
[(set FR32:$dst, (fadd FR32:$src1, FR32:$src2))]>,
Requires<[HasSSE1]>, XS;
def ADDSDrr : I<0x58, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
[(set FR64:$dst, (fadd FR64:$src1, FR64:$src2))]>,
Requires<[HasSSE2]>, XD;
def MULSSrr : I<0x59, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
[(set FR32:$dst, (fmul FR32:$src1, FR32:$src2))]>,
Requires<[HasSSE1]>, XS;
def MULSDrr : I<0x59, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
[(set FR64:$dst, (fmul FR64:$src1, FR64:$src2))]>,
Requires<[HasSSE2]>, XD;
}
def ADDSSrm : I<0x58, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
"addss {$src2, $dst|$dst, $src2}",
[(set FR32:$dst, (fadd FR32:$src1, (loadf32 addr:$src2)))]>,
Requires<[HasSSE1]>, XS;
def ADDSDrm : I<0x58, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
"addsd {$src2, $dst|$dst, $src2}",
[(set FR64:$dst, (fadd FR64:$src1, (loadf64 addr:$src2)))]>,
Requires<[HasSSE2]>, XD;
def MULSSrm : I<0x59, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
"mulss {$src2, $dst|$dst, $src2}",
[(set FR32:$dst, (fmul FR32:$src1, (loadf32 addr:$src2)))]>,
Requires<[HasSSE1]>, XS;
def MULSDrm : I<0x59, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
"mulsd {$src2, $dst|$dst, $src2}",
[(set FR64:$dst, (fmul FR64:$src1, (loadf64 addr:$src2)))]>,
Requires<[HasSSE2]>, XD;
def DIVSSrr : I<0x5E, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
[(set FR32:$dst, (fdiv FR32:$src1, FR32:$src2))]>,
Requires<[HasSSE1]>, XS;
def DIVSSrm : I<0x5E, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
"divss {$src2, $dst|$dst, $src2}",
[(set FR32:$dst, (fdiv FR32:$src1, (loadf32 addr:$src2)))]>,
Requires<[HasSSE1]>, XS;
def DIVSDrr : I<0x5E, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
[(set FR64:$dst, (fdiv FR64:$src1, FR64:$src2))]>,
Requires<[HasSSE2]>, XD;
def DIVSDrm : I<0x5E, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
"divsd {$src2, $dst|$dst, $src2}",
[(set FR64:$dst, (fdiv FR64:$src1, (loadf64 addr:$src2)))]>,
Requires<[HasSSE2]>, XD;
def SUBSSrr : I<0x5C, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
[(set FR32:$dst, (fsub FR32:$src1, FR32:$src2))]>,
Requires<[HasSSE1]>, XS;
def SUBSSrm : I<0x5C, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
"subss {$src2, $dst|$dst, $src2}",
[(set FR32:$dst, (fsub FR32:$src1, (loadf32 addr:$src2)))]>,
Requires<[HasSSE1]>, XS;
def SUBSDrr : I<0x5C, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
[(set FR64:$dst, (fsub FR64:$src1, FR64:$src2))]>,
Requires<[HasSSE2]>, XD;
def SUBSDrm : I<0x5C, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
"subsd {$src2, $dst|$dst, $src2}",
[(set FR64:$dst, (fsub FR64:$src1, (loadf64 addr:$src2)))]>,
Requires<[HasSSE2]>, XD;
// SSE compare
def CMPSSrr : I<0xC2, MRMSrcReg,
(ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc),
"cmp${cc}ss {$src, $dst|$dst, $src}", []>,
Requires<[HasSSE1]>, XS;
def CMPSSrm : I<0xC2, MRMSrcMem,
(ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc),
"cmp${cc}ss {$src, $dst|$dst, $src}", []>,
Requires<[HasSSE1]>, XS;
def CMPSDrr : I<0xC2, MRMSrcReg,
(ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc),
"cmp${cc}sd {$src, $dst|$dst, $src}", []>,
Requires<[HasSSE1]>, XD;
def CMPSDrm : I<0xC2, MRMSrcMem,
(ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc),
"cmp${cc}sd {$src, $dst|$dst, $src}", []>,
Requires<[HasSSE2]>, XD;
// SSE Logical - these all operate on packed values
let isCommutable = 1 in {
def ANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
"andps {$src2, $dst|$dst, $src2}",
[(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>,
Requires<[HasSSE1]>, TB;
def ANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
"andpd {$src2, $dst|$dst, $src2}",
[(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>,
Requires<[HasSSE2]>, TB, OpSize;
def ORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
"orps {$src2, $dst|$dst, $src2}", []>,
Requires<[HasSSE1]>, TB;
def ORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
"orpd {$src2, $dst|$dst, $src2}", []>,
Requires<[HasSSE2]>, TB, OpSize;
def XORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
"xorps {$src2, $dst|$dst, $src2}",
[(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>,
Requires<[HasSSE1]>, TB;
def XORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
"xorpd {$src2, $dst|$dst, $src2}",
[(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>,
def ANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
[(set FR32:$dst, (X86fand FR32:$src1,
(X86loadpf32 addr:$src2)))]>,
def ANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
[(set FR64:$dst, (X86fand FR64:$src1,
(X86loadpf64 addr:$src2)))]>,
def ORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
"orps {$src2, $dst|$dst, $src2}", []>,
Requires<[HasSSE1]>, TB;
def ORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
"orpd {$src2, $dst|$dst, $src2}", []>,
Requires<[HasSSE2]>, TB, OpSize;
def XORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
"xorps {$src2, $dst|$dst, $src2}",
[(set FR32:$dst, (X86fxor FR32:$src1,
(X86loadpf32 addr:$src2)))]>,
def XORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
"xorpd {$src2, $dst|$dst, $src2}",
[(set FR64:$dst, (X86fxor FR64:$src1,
(X86loadpf64 addr:$src2)))]>,
def ANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
"andnps {$src2, $dst|$dst, $src2}", []>,
Requires<[HasSSE1]>, TB;
def ANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
"andnps {$src2, $dst|$dst, $src2}", []>,
Requires<[HasSSE1]>, TB;
def ANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
"andnpd {$src2, $dst|$dst, $src2}", []>,
Requires<[HasSSE2]>, TB, OpSize;
def ANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
"andnpd {$src2, $dst|$dst, $src2}", []>,
Requires<[HasSSE2]>, TB, OpSize;
}
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
Chris Lattner
committed
// Floating point support. All FP Stack operations are represented with two
// instructions here. The first instruction, generated by the instruction
// selector, uses "RFP" registers: a traditional register file to reference
// floating point values. These instructions are all psuedo instructions and
// use the "Fp" prefix. The second instruction is defined with FPI, which is
// the actual instruction emitted by the assembler. The FP stackifier pass
// converts one to the other after register allocation occurs.
//
// Note that the FpI instruction should have instruction selection info (e.g.
// a pattern) and the FPI instruction should have emission info (e.g. opcode
// encoding and asm printing info).
// FPI - Floating Point Instruction template.
class FPI<bits<8> o, Format F, dag ops, string asm> : I<o, F, ops, asm, []> {}
// FpI_ - Floating Point Psuedo Instruction template. Not Predicated.
class FpI_<dag ops, FPFormat fp, list<dag> pattern>
: X86Inst<0, Pseudo, NoImm, ops, ""> {
let FPForm = fp; let FPFormBits = FPForm.Value;
let Pattern = pattern;
}
Chris Lattner
committed
// Random Pseudo Instructions.
def FpGETRESULT : FpI_<(ops RFP:$dst), SpecialFP,
[(set RFP:$dst, X86fpget)]>; // FPR = ST(0)
let noResults = 1 in
def FpSETRESULT : FpI_<(ops RFP:$src), SpecialFP,
[(X86fpset RFP:$src)]>, Imp<[], [ST0]>; // ST(0) = FPR
// FpI - Floating Point Psuedo Instruction template. Predicated on FPStack.
class FpI<dag ops, FPFormat fp, list<dag> pattern> :
FpI_<ops, fp, pattern>, Requires<[FPStack]>;
def FpMOV : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2
Chris Lattner
committed
// Arithmetic
// Add, Sub, Mul, Div.
def FpADD : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
[(set RFP:$dst, (fadd RFP:$src1, RFP:$src2))]>;
def FpSUB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
[(set RFP:$dst, (fsub RFP:$src1, RFP:$src2))]>;
def FpMUL : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
[(set RFP:$dst, (fmul RFP:$src1, RFP:$src2))]>;
def FpDIV : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
[(set RFP:$dst, (fdiv RFP:$src1, RFP:$src2))]>;
class FPST0rInst<bits<8> o, string asm>
: FPI<o, AddRegFrm, (ops RST:$op), asm>, D8;
class FPrST0Inst<bits<8> o, string asm>
: FPI<o, AddRegFrm, (ops RST:$op), asm>, DC;
class FPrST0PInst<bits<8> o, string asm>
: FPI<o, AddRegFrm, (ops RST:$op), asm>, DE;
Chris Lattner
committed
// Binary Ops with a memory source.
def FpADD32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fadd RFP:$src1,
(extloadf64f32 addr:$src2)))]>;
// ST(0) = ST(0) + [mem32]
def FpADD64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fadd RFP:$src1, (loadf64 addr:$src2)))]>;
// ST(0) = ST(0) + [mem64]
Chris Lattner
committed
def FpMUL32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fmul RFP:$src1,
(extloadf64f32 addr:$src2)))]>;
// ST(0) = ST(0) * [mem32]
def FpMUL64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fmul RFP:$src1, (loadf64 addr:$src2)))]>;
// ST(0) = ST(0) * [mem64]
Chris Lattner
committed
def FpSUB32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub RFP:$src1,
(extloadf64f32 addr:$src2)))]>;
// ST(0) = ST(0) - [mem32]
def FpSUB64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub RFP:$src1, (loadf64 addr:$src2)))]>;
// ST(0) = ST(0) - [mem64]
Chris Lattner
committed
def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub (extloadf64f32 addr:$src2),
RFP:$src1))]>;
// ST(0) = [mem32] - ST(0)
def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub (loadf64 addr:$src2), RFP:$src1))]>;
// ST(0) = [mem64] - ST(0)
Chris Lattner
committed
def FpDIV32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv RFP:$src1,
(extloadf64f32 addr:$src2)))]>;
// ST(0) = ST(0) / [mem32]
def FpDIV64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv RFP:$src1, (loadf64 addr:$src2)))]>;
// ST(0) = ST(0) / [mem64]
Chris Lattner
committed
def FpDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv (extloadf64f32 addr:$src2),
RFP:$src1))]>;
// ST(0) = [mem32] / ST(0)
def FpDIVR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv (loadf64 addr:$src2), RFP:$src1))]>;
// ST(0) = [mem64] / ST(0)
Chris Lattner
committed
def FADD32m : FPI<0xD8, MRM0m, (ops f32mem:$src), "fadd{s} $src">;
def FADD64m : FPI<0xDC, MRM0m, (ops f64mem:$src), "fadd{l} $src">;
def FMUL32m : FPI<0xD8, MRM1m, (ops f32mem:$src), "fmul{s} $src">;
def FMUL64m : FPI<0xDC, MRM1m, (ops f64mem:$src), "fmul{l} $src">;
def FSUB32m : FPI<0xD8, MRM4m, (ops f32mem:$src), "fsub{s} $src">;
def FSUB64m : FPI<0xDC, MRM4m, (ops f64mem:$src), "fsub{l} $src">;
def FSUBR32m : FPI<0xD8, MRM5m, (ops f32mem:$src), "fsubr{s} $src">;
def FSUBR64m : FPI<0xDC, MRM5m, (ops f64mem:$src), "fsubr{l} $src">;
def FDIV32m : FPI<0xD8, MRM6m, (ops f32mem:$src), "fdiv{s} $src">;
def FDIV64m : FPI<0xDC, MRM6m, (ops f64mem:$src), "fdiv{l} $src">;
def FDIVR32m : FPI<0xD8, MRM7m, (ops f32mem:$src), "fdivr{s} $src">;
def FDIVR64m : FPI<0xDC, MRM7m, (ops f64mem:$src), "fdivr{l} $src">;
def FpIADD16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fadd RFP:$src1,
def FpIADD32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
// ST(0) = ST(0) + [mem32int]
def FpIMUL16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fmul RFP:$src1,
def FpIMUL32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
// ST(0) = ST(0) * [mem32int]
def FpISUB16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub RFP:$src1,
def FpISUB32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
// ST(0) = ST(0) - [mem32int]
def FpISUBR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub (X86fild addr:$src2, i16),
def FpISUBR32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub (X86fild addr:$src2, i32),
RFP:$src1))]>;
// ST(0) = [mem32int] - ST(0)
def FpIDIV16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv RFP:$src1,
def FpIDIV32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
// ST(0) = ST(0) / [mem32int]
def FpIDIVR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv (X86fild addr:$src2, i16),
def FpIDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv (X86fild addr:$src2, i32),
RFP:$src1))]>;
// ST(0) = [mem32int] / ST(0)
def FIADD16m : FPI<0xDE, MRM0m, (ops i16mem:$src), "fiadd{s} $src">;
def FIADD32m : FPI<0xDA, MRM0m, (ops i32mem:$src), "fiadd{l} $src">;
def FIMUL16m : FPI<0xDE, MRM1m, (ops i16mem:$src), "fimul{s} $src">;
def FIMUL32m : FPI<0xDA, MRM1m, (ops i32mem:$src), "fimul{l} $src">;
def FISUB16m : FPI<0xDE, MRM4m, (ops i16mem:$src), "fisub{s} $src">;
def FISUB32m : FPI<0xDA, MRM4m, (ops i32mem:$src), "fisub{l} $src">;
def FISUBR16m : FPI<0xDE, MRM5m, (ops i16mem:$src), "fisubr{s} $src">;
def FISUBR32m : FPI<0xDA, MRM5m, (ops i32mem:$src), "fisubr{l} $src">;
def FIDIV16m : FPI<0xDE, MRM6m, (ops i16mem:$src), "fidiv{s} $src">;
def FIDIV32m : FPI<0xDA, MRM6m, (ops i32mem:$src), "fidiv{l} $src">;
def FIDIVR16m : FPI<0xDE, MRM7m, (ops i16mem:$src), "fidivr{s} $src">;
def FIDIVR32m : FPI<0xDA, MRM7m, (ops i32mem:$src), "fidivr{l} $src">;
Chris Lattner
committed
// NOTE: GAS and apparently all other AT&T style assemblers have a broken notion
// of some of the 'reverse' forms of the fsub and fdiv instructions. As such,
// we have to put some 'r's in and take them out of weird places.
def FADDST0r : FPST0rInst <0xC0, "fadd $op">;
def FADDrST0 : FPrST0Inst <0xC0, "fadd {%st(0), $op|$op, %ST(0)}">;
def FADDPrST0 : FPrST0PInst<0xC0, "faddp $op">;
def FSUBRST0r : FPST0rInst <0xE8, "fsubr $op">;
def FSUBrST0 : FPrST0Inst <0xE8, "fsub{r} {%st(0), $op|$op, %ST(0)}">;
def FSUBPrST0 : FPrST0PInst<0xE8, "fsub{r}p $op">;
def FSUBST0r : FPST0rInst <0xE0, "fsub $op">;
def FSUBRrST0 : FPrST0Inst <0xE0, "fsub{|r} {%st(0), $op|$op, %ST(0)}">;
def FSUBRPrST0 : FPrST0PInst<0xE0, "fsub{|r}p $op">;
def FMULST0r : FPST0rInst <0xC8, "fmul $op">;
def FMULrST0 : FPrST0Inst <0xC8, "fmul {%st(0), $op|$op, %ST(0)}">;
def FMULPrST0 : FPrST0PInst<0xC8, "fmulp $op">;
def FDIVRST0r : FPST0rInst <0xF8, "fdivr $op">;
def FDIVrST0 : FPrST0Inst <0xF8, "fdiv{r} {%st(0), $op|$op, %ST(0)}">;
def FDIVPrST0 : FPrST0PInst<0xF8, "fdiv{r}p $op">;
def FDIVST0r : FPST0rInst <0xF0, "fdiv $op">;
def FDIVRrST0 : FPrST0Inst <0xF0, "fdiv{|r} {%st(0), $op|$op, %ST(0)}">;
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
def FDIVRPrST0 : FPrST0PInst<0xF0, "fdiv{|r}p $op">;
// Unary operations.
def FpCHS : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
[(set RFP:$dst, (fneg RFP:$src))]>;
def FpABS : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
[(set RFP:$dst, (fabs RFP:$src))]>;
def FpSQRT : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
[(set RFP:$dst, (fsqrt RFP:$src))]>;
def FpSIN : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
[(set RFP:$dst, (fsin RFP:$src))]>;
def FpCOS : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
[(set RFP:$dst, (fcos RFP:$src))]>;
def FpTST : FpI<(ops RFP:$src), OneArgFP,
[]>;
def FCHS : FPI<0xE0, RawFrm, (ops), "fchs">, D9;
def FABS : FPI<0xE1, RawFrm, (ops), "fabs">, D9;
def FSQRT : FPI<0xFA, RawFrm, (ops), "fsqrt">, D9;
def FSIN : FPI<0xFE, RawFrm, (ops), "fsin">, D9;
def FCOS : FPI<0xFF, RawFrm, (ops), "fcos">, D9;
def FTST : FPI<0xE4, RawFrm, (ops), "ftst">, D9;
Chris Lattner
committed
// Floating point cmovs.
let isTwoAddress = 1 in {
def FpCMOVB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_B))]>;
def FpCMOVBE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_BE))]>;
def FpCMOVE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_E))]>;
def FpCMOVP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_P))]>;
def FpCMOVNB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_AE))]>;
def FpCMOVNBE: FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_A))]>;
def FpCMOVNE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_NE))]>;
def FpCMOVNP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_NP))]>;
Chris Lattner
committed
def FCMOVB : FPI<0xC0, AddRegFrm, (ops RST:$op),
"fcmovb {$op, %st(0)|%ST(0), $op}">, DA;
Chris Lattner
committed
def FCMOVBE : FPI<0xD0, AddRegFrm, (ops RST:$op),
"fcmovbe {$op, %st(0)|%ST(0), $op}">, DA;
Chris Lattner
committed
def FCMOVE : FPI<0xC8, AddRegFrm, (ops RST:$op),
"fcmove {$op, %st(0)|%ST(0), $op}">, DA;
Chris Lattner
committed
def FCMOVP : FPI<0xD8, AddRegFrm, (ops RST:$op),
"fcmovu {$op, %st(0)|%ST(0), $op}">, DA;
def FCMOVNB : FPI<0xC0, AddRegFrm, (ops RST:$op),
"fcmovnb {$op, %st(0)|%ST(0), $op}">, DB;
def FCMOVNBE : FPI<0xD0, AddRegFrm, (ops RST:$op),
"fcmovnbe {$op, %st(0)|%ST(0), $op}">, DB;
Chris Lattner
committed
def FCMOVNE : FPI<0xC8, AddRegFrm, (ops RST:$op),
"fcmovne {$op, %st(0)|%ST(0), $op}">, DB;
Chris Lattner
committed
def FCMOVNP : FPI<0xD8, AddRegFrm, (ops RST:$op),
"fcmovnu {$op, %st(0)|%ST(0), $op}">, DB;
Chris Lattner
committed
// Floating point loads & stores.
def FpLD32m : FpI<(ops RFP:$dst, f32mem:$src), ZeroArgFP,
[(set RFP:$dst, (extloadf64f32 addr:$src))]>;
Chris Lattner
committed
def FpLD64m : FpI<(ops RFP:$dst, f64mem:$src), ZeroArgFP,
Chris Lattner
committed
def FpILD16m : FpI<(ops RFP:$dst, i16mem:$src), ZeroArgFP,
[(set RFP:$dst, (X86fild addr:$src, i16))]>;
Chris Lattner
committed
def FpILD32m : FpI<(ops RFP:$dst, i32mem:$src), ZeroArgFP,
[(set RFP:$dst, (X86fild addr:$src, i32))]>;
Chris Lattner
committed
def FpILD64m : FpI<(ops RFP:$dst, i64mem:$src), ZeroArgFP,
[(set RFP:$dst, (X86fild addr:$src, i64))]>;
Chris Lattner
committed
def FpST32m : FpI<(ops f32mem:$op, RFP:$src), OneArgFP,
[(truncstore RFP:$src, addr:$op, f32)]>;
def FpST64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP,
[(store RFP:$src, addr:$op)]>;
Chris Lattner
committed
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
def FpSTP32m : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>;
def FpSTP64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>;
def FpIST16m : FpI<(ops i16mem:$op, RFP:$src), OneArgFP, []>;
def FpIST32m : FpI<(ops i32mem:$op, RFP:$src), OneArgFP, []>;
def FpIST64m : FpI<(ops i64mem:$op, RFP:$src), OneArgFP, []>;
def FLD32m : FPI<0xD9, MRM0m, (ops f32mem:$src), "fld{s} $src">;
def FLD64m : FPI<0xDD, MRM0m, (ops f64mem:$src), "fld{l} $src">;
def FILD16m : FPI<0xDF, MRM0m, (ops i16mem:$src), "fild{s} $src">;
def FILD32m : FPI<0xDB, MRM0m, (ops i32mem:$src), "fild{l} $src">;
def FILD64m : FPI<0xDF, MRM5m, (ops i64mem:$src), "fild{ll} $src">;
def FST32m : FPI<0xD9, MRM2m, (ops f32mem:$dst), "fst{s} $dst">;
def FST64m : FPI<0xDD, MRM2m, (ops f64mem:$dst), "fst{l} $dst">;
def FSTP32m : FPI<0xD9, MRM3m, (ops f32mem:$dst), "fstp{s} $dst">;
def FSTP64m : FPI<0xDD, MRM3m, (ops f64mem:$dst), "fstp{l} $dst">;
def FIST16m : FPI<0xDF, MRM2m, (ops i16mem:$dst), "fist{s} $dst">;
def FIST32m : FPI<0xDB, MRM2m, (ops i32mem:$dst), "fist{l} $dst">;
def FISTP16m : FPI<0xDF, MRM3m, (ops i16mem:$dst), "fistp{s} $dst">;
def FISTP32m : FPI<0xDB, MRM3m, (ops i32mem:$dst), "fistp{l} $dst">;
def FISTP64m : FPI<0xDF, MRM7m, (ops i64mem:$dst), "fistp{ll} $dst">;
// FISTTP requires SSE3 even though it's a FPStack op.
def FpISTT16m : FpI_<(ops i16mem:$op, RFP:$src), OneArgFP,
[(X86fp_to_i16mem RFP:$src, addr:$op)]>,
Requires<[HasSSE3]>;
def FpISTT32m : FpI_<(ops i32mem:$op, RFP:$src), OneArgFP,
[(X86fp_to_i32mem RFP:$src, addr:$op)]>,
Requires<[HasSSE3]>;
def FpISTT64m : FpI_<(ops i64mem:$op, RFP:$src), OneArgFP,
[(X86fp_to_i64mem RFP:$src, addr:$op)]>,
Requires<[HasSSE3]>;
def FISTTP16m : FPI<0xDF, MRM1m, (ops i16mem:$dst), "fisttp{s} $dst">;
def FISTTP32m : FPI<0xDB, MRM1m, (ops i32mem:$dst), "fisttp{l} $dst">;
def FISTTP64m : FPI<0xDD, MRM1m, (ops i64mem:$dst), "fisttp{ll} $dst">;
Chris Lattner
committed
// FP Stack manipulation instructions.
def FLDrr : FPI<0xC0, AddRegFrm, (ops RST:$op), "fld $op">, D9;
def FSTrr : FPI<0xD0, AddRegFrm, (ops RST:$op), "fst $op">, DD;
def FSTPrr : FPI<0xD8, AddRegFrm, (ops RST:$op), "fstp $op">, DD;
def FXCH : FPI<0xC8, AddRegFrm, (ops RST:$op), "fxch $op">, D9;
// Floating point constant loads.
def FpLD0 : FpI<(ops RFP:$dst), ZeroArgFP,
[(set RFP:$dst, fp64imm0)]>;
def FpLD1 : FpI<(ops RFP:$dst), ZeroArgFP,
[(set RFP:$dst, fp64imm1)]>;
Chris Lattner
committed
def FLD0 : FPI<0xEE, RawFrm, (ops), "fldz">, D9;
def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9;
// Floating point compares.
def FpUCOMr : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP,
Chris Lattner
committed
[]>; // FPSW = cmp ST(0) with ST(i)
def FpUCOMIr : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP,
[(X86cmp RFP:$lhs, RFP:$rhs)]>; // CC = cmp ST(0) with ST(i)
Chris Lattner
committed
def FUCOMr : FPI<0xE0, AddRegFrm, // FPSW = cmp ST(0) with ST(i)
(ops RST:$reg),
"fucom $reg">, DD, Imp<[ST0],[]>;
def FUCOMPr : FPI<0xE8, AddRegFrm, // FPSW = cmp ST(0) with ST(i), pop