Newer
Older
[(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 X86_COND_E, STATUS))]>,
TB; // R8 = ==
def SETEm : I<0x94, MRM0m,
"sete $dst",
[(store (X86setcc X86_COND_E, STATUS), addr:$dst)]>,
TB; // [mem8] = ==
def SETNEr : I<0x95, MRM0r,
"setne $dst",
[(set R8:$dst, (X86setcc X86_COND_NE, STATUS))]>,
TB; // R8 = !=
def SETNEm : I<0x95, MRM0m,
"setne $dst",
[(store (X86setcc X86_COND_NE, STATUS), addr:$dst)]>,
TB; // [mem8] = !=
def SETLr : I<0x9C, MRM0r,
(ops R8 :$dst),
"setl $dst",
[(set R8:$dst, (X86setcc X86_COND_L, STATUS))]>,
TB; // R8 = < signed
def SETLm : I<0x9C, MRM0m,
(ops i8mem:$dst),
"setl $dst",
[(store (X86setcc X86_COND_L, STATUS), addr:$dst)]>,
TB; // [mem8] = < signed
def SETGEr : I<0x9D, MRM0r,
(ops R8 :$dst),
"setge $dst",
[(set R8:$dst, (X86setcc X86_COND_GE, STATUS))]>,
TB; // R8 = >= signed
def SETGEm : I<0x9D, MRM0m,
(ops i8mem:$dst),
"setge $dst",
[(store (X86setcc X86_COND_GE, STATUS), addr:$dst)]>,
TB; // [mem8] = >= signed
def SETLEr : I<0x9E, MRM0r,
(ops R8 :$dst),
"setle $dst",
[(set R8:$dst, (X86setcc X86_COND_LE, STATUS))]>,
TB; // R8 = <= signed
def SETLEm : I<0x9E, MRM0m,
(ops i8mem:$dst),
"setle $dst",
[(store (X86setcc X86_COND_LE, STATUS), addr:$dst)]>,
TB; // [mem8] = <= signed
def SETGr : I<0x9F, MRM0r,
(ops R8 :$dst),
"setg $dst",
[(set R8:$dst, (X86setcc X86_COND_G, STATUS))]>,
TB; // R8 = > signed
def SETGm : I<0x9F, MRM0m,
(ops i8mem:$dst),
"setg $dst",
[(store (X86setcc X86_COND_G, STATUS), addr:$dst)]>,
TB; // [mem8] = > signed
def SETBr : I<0x92, MRM0r,
(ops R8 :$dst),
"setb $dst",
[(set R8:$dst, (X86setcc X86_COND_B, STATUS))]>,
TB; // R8 = < unsign
def SETBm : I<0x92, MRM0m,
(ops i8mem:$dst),
"setb $dst",
[(store (X86setcc X86_COND_B, STATUS), addr:$dst)]>,
TB; // [mem8] = < unsign
def SETAEr : I<0x93, MRM0r,
(ops R8 :$dst),
"setae $dst",
[(set R8:$dst, (X86setcc X86_COND_AE, STATUS))]>,
TB; // R8 = >= unsign
def SETAEm : I<0x93, MRM0m,
(ops i8mem:$dst),
"setae $dst",
[(store (X86setcc X86_COND_AE, STATUS), addr:$dst)]>,
TB; // [mem8] = >= unsign
def SETBEr : I<0x96, MRM0r,
"setbe $dst",
[(set R8:$dst, (X86setcc X86_COND_BE, STATUS))]>,
TB; // R8 = <= unsign
def SETBEm : I<0x96, MRM0m,
"setbe $dst",
[(store (X86setcc X86_COND_BE, STATUS), addr:$dst)]>,
TB; // [mem8] = <= unsign
def SETAr : I<0x97, MRM0r,
"seta $dst",
[(set R8:$dst, (X86setcc X86_COND_A, STATUS))]>,
TB; // R8 = > signed
def SETAm : I<0x97, MRM0m,
"seta $dst",
[(store (X86setcc X86_COND_A, STATUS), addr:$dst)]>,
TB; // [mem8] = > signed
def SETSr : I<0x98, MRM0r,
"sets $dst",
[(set R8:$dst, (X86setcc X86_COND_S, STATUS))]>,
TB; // R8 = <sign bit>
def SETSm : I<0x98, MRM0m,
"sets $dst",
[(store (X86setcc X86_COND_S, STATUS), addr:$dst)]>,
TB; // [mem8] = <sign bit>
def SETNSr : I<0x99, MRM0r,
"setns $dst",
[(set R8:$dst, (X86setcc X86_COND_NS, STATUS))]>,
TB; // R8 = !<sign bit>
def SETNSm : I<0x99, MRM0m,
"setns $dst",
[(store (X86setcc X86_COND_NS, STATUS), addr:$dst)]>,
TB; // [mem8] = !<sign bit>
def SETPr : I<0x9A, MRM0r,
"setp $dst",
[(set R8:$dst, (X86setcc X86_COND_P, STATUS))]>,
TB; // R8 = parity
def SETPm : I<0x9A, MRM0m,
"setp $dst",
[(store (X86setcc X86_COND_P, STATUS), addr:$dst)]>,
TB; // [mem8] = parity
"setnp $dst",
[(set R8:$dst, (X86setcc X86_COND_NP, STATUS))]>,
TB; // R8 = not parity
"setnp $dst",
[(store (X86setcc X86_COND_NP, STATUS), addr:$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]>;
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]>;
def CMP8ri : Ii8<0x80, MRM7r,
(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]>;
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 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 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 CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src),
"cvtsd2ss {$src, $dst|$dst, $src}",
[(set FR32:$dst, (fround FR64:$src))]>,
Requires<[HasSSE2]>, XS;
def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src),
"cvtsd2ss {$src, $dst|$dst, $src}",
[(set FR32:$dst, (fround (loadf64 addr:$src)))]>,
Requires<[HasSSE2]>, XS;
def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src),
"cvtss2sd {$src, $dst|$dst, $src}",
[(set FR64:$dst, (fextend FR32:$src))]>,
Requires<[HasSSE2]>, XD;
def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src),
"cvtss2sd {$src, $dst|$dst, $src}",
[(set FR64:$dst, (fextend (loadf32 addr:$src)))]>,
Requires<[HasSSE2]>, XD;
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 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 SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src),
"sqrtss {$src, $dst|$dst, $src}",
[(set FR32:$dst, (fsqrt FR32:$src))]>,
Requires<[HasSSE1]>, XS;
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 SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src),
"sqrtsd {$src, $dst|$dst, $src}",
[(set FR64:$dst, (fsqrt FR64:$src))]>,
Requires<[HasSSE2]>, XD;
def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2),
"ucomisd {$src2, $src1|$src1, $src2}",
[(set STATUS, (X86cmp FR64:$src1, FR64:$src2))]>,
def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2),
"ucomisd {$src2, $src1|$src1, $src2}",
[(set STATUS, (X86cmp FR64:$src1, (loadf64 addr:$src2)))]>,
Imp<[],[STATUS]>, Requires<[HasSSE2]>, TB, OpSize;
def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2),
"ucomiss {$src2, $src1|$src1, $src2}",
[(set STATUS, (X86cmp FR32:$src1, FR32:$src2))]>,
Imp<[],[STATUS]>, Requires<[HasSSE1]>, TB;
def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2),
"ucomiss {$src2, $src1|$src1, $src2}",
[(set STATUS, (X86cmp FR32:$src1, (loadf32 addr:$src2)))]>,
Imp<[],[STATUS]>, Requires<[HasSSE1]>, TB;
// Pseudo-instructions that map fld0 to xorps/xorpd for sse.
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
def FLD0SS : I<0x57, MRMSrcReg, (ops FR32:$dst),
def FLD0SD : I<0x57, MRMSrcReg, (ops FR64:$dst),
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),
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
[(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 Logical
let isCommutable = 1 in {
def ANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
"andps {$src2, $dst|$dst, $src2}", []>,
Requires<[HasSSE1]>, TB;
def ANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
"andpd {$src2, $dst|$dst, $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}", []>,
Requires<[HasSSE1]>, TB;
def XORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
"xorpd {$src2, $dst|$dst, $src2}", []>,
Requires<[HasSSE2]>, TB, OpSize;
}
def ANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$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 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;
}
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
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]
Chris Lattner
committed
def FpADD64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$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]
Chris Lattner
committed
def FpMUL64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$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]
Chris Lattner
committed
def FpSUB64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$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)
Chris Lattner
committed
def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$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]
Chris Lattner
committed
def FpDIV64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$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)
Chris Lattner
committed
def FpDIVR64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$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">;
// FIXME: Implement these when we have a dag-dag isel!
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
def FpIADD16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fadd RFP:$src1,
(sint_to_fp (loadi16 addr:$src2))))]>;
// ST(0) = ST(0) + [mem16int]
def FpIADD32m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fadd RFP:$src1,
(sint_to_fp (loadi32 addr:$src2))))]>;
// ST(0) = ST(0) + [mem32int]
def FpIMUL16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fmul RFP:$src1,
(sint_to_fp (loadi16 addr:$src2))))]>;
// ST(0) = ST(0) * [mem16int]
def FpIMUL32m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fmul RFP:$src1,
(sint_to_fp (loadi32 addr:$src2))))]>;
// ST(0) = ST(0) * [mem32int]
def FpISUB16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub RFP:$src1,
(sint_to_fp (loadi16 addr:$src2))))]>;
// ST(0) = ST(0) - [mem16int]
def FpISUB32m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub RFP:$src1,
(sint_to_fp (loadi32 addr:$src2))))]>;
// ST(0) = ST(0) - [mem32int]
def FpISUBR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub (sint_to_fp (loadi16 addr:$src2)),
RFP:$src1))]>;
// ST(0) = [mem16int] - ST(0)
def FpISUBR32m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fsub (sint_to_fp (loadi32 addr:$src2)),
RFP:$src1))]>;
// ST(0) = [mem32int] - ST(0)
def FpIDIV16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv RFP:$src1,
(sint_to_fp (loadi16 addr:$src2))))]>;
// ST(0) = ST(0) / [mem16int]
def FpIDIV32m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv RFP:$src1,
(sint_to_fp (loadi32 addr:$src2))))]>;
// ST(0) = ST(0) / [mem32int]
def FpIDIVR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv (sint_to_fp (loadi16 addr:$src2)),
RFP:$src1))]>;
// ST(0) = [mem16int] / ST(0)
def FpIDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
[(set RFP:$dst, (fdiv (sint_to_fp (loadi32 addr:$src2)),
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{s} $src">;
def FIDIVR16m : FPI<0xDE, MRM7m, (ops i16mem:$src), "fidivr{s} $src">;
def FIDIVR32m : FPI<0xDA, MRM7m, (ops i32mem:$src), "fidivr{s} $src">;
Chris Lattner
committed
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
// 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)}">;
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 {
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
def FpCMOVB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_B, STATUS))]>;
def FpCMOVBE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_BE, STATUS))]>;
def FpCMOVE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_E, STATUS))]>;
def FpCMOVP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_P, STATUS))]>;
def FpCMOVAE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_AE, STATUS))]>;
def FpCMOVA : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_A, STATUS))]>;
def FpCMOVNE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_NE, STATUS))]>;
def FpCMOVNP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
[(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
X86_COND_NP, STATUS))]>;
Chris Lattner
committed
def FCMOVB : FPI<0xC0, AddRegFrm, (ops RST:$op),
"fcmovb {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVBE : FPI<0xD0, AddRegFrm, (ops RST:$op),
"fcmovbe {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVE : FPI<0xC8, AddRegFrm, (ops RST:$op),
"fcmove {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVP : FPI<0xD8, AddRegFrm, (ops RST:$op),
"fcmovu {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVAE : FPI<0xC0, AddRegFrm, (ops RST:$op),
"fcmovae {$op, %ST(0)|%ST(0), $op}">, DB;
def FCMOVA : FPI<0xD0, AddRegFrm, (ops RST:$op),
"fcmova {$op, %ST(0)|%ST(0), $op}">, DB;
def FCMOVNE : FPI<0xC8, AddRegFrm, (ops RST:$op),
"fcmovne {$op, %ST(0)|%ST(0), $op}">, DB;
def FCMOVNP : FPI<0xD8, AddRegFrm, (ops RST:$op),
"fcmovnu {$op, %ST(0)|%ST(0), $op}">, DB;
// 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, (sint_to_fp (loadi16 addr:$src)))]>;
Chris Lattner
committed
def FpILD32m : FpI<(ops RFP:$dst, i32mem:$src), ZeroArgFP,
[(set RFP:$dst, (sint_to_fp (loadi32 addr:$src)))]>;
Chris Lattner
committed
def FpILD64m : FpI<(ops RFP:$dst, i64mem:$src), ZeroArgFP,
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
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
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">;
// 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,
[(set STATUS, (X86cmp RFP:$lhs, RFP:$rhs))]>,
Imp<[],[STATUS]>; // 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
(ops RST:$reg),
"fucomp $reg">, DD, Imp<[ST0],[]>;
def FUCOMPPr : FPI<0xE9, RawFrm, // cmp ST(0) with ST(1), pop, pop
(ops),
"fucompp">, DA, Imp<[ST0],[]>;
def FUCOMIr : FPI<0xE8, AddRegFrm, // CC = cmp ST(0) with ST(i)
(ops RST:$reg),
"fucomi {$reg, %ST(0)|%ST(0), $reg}">, DB, Imp<[ST0],[]>;
def FUCOMIPr : FPI<0xE8, AddRegFrm, // CC = cmp ST(0) with ST(i), pop
(ops RST:$reg),
"fucomip {$reg, %ST(0)|%ST(0), $reg}">, DF, Imp<[ST0],[]>;
// Floating point flag ops.
def FNSTSW8r : I<0xE0, RawFrm, // AX = fp flags
def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world
def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
//===----------------------------------------------------------------------===//
// Miscellaneous Instructions
//===----------------------------------------------------------------------===//
def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", [(X86rdtsc)]>,
TB, Imp<[],[EAX,EDX]>;
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
//===----------------------------------------------------------------------===//
// Calls
def : Pat<(X86call tglobaladdr:$dst),
(CALLpcrel32 tglobaladdr:$dst)>;
def : Pat<(X86call externalsym:$dst),
(CALLpcrel32 externalsym:$dst)>;
// X86 specific add which produces a flag.
def : Pat<(X86addflag R32:$src1, R32:$src2),
(ADD32rr R32:$src1, R32:$src2)>;
def : Pat<(X86addflag R32:$src1, (load addr:$src2)),
(ADD32rm R32:$src1, addr:$src2)>;
def : Pat<(X86addflag R32:$src1, imm:$src2),
(ADD32ri R32:$src1, imm:$src2)>;
def : Pat<(X86addflag R32:$src1, i32immSExt8:$src2),
(ADD32ri8 R32:$src1, i32immSExt8:$src2)>;
def : Pat<(X86subflag R32:$src1, R32:$src2),
(SUB32rr R32:$src1, R32:$src2)>;
def : Pat<(X86subflag R32:$src1, (load addr:$src2)),
(SUB32rm R32:$src1, addr:$src2)>;
def : Pat<(X86subflag R32:$src1, imm:$src2),
(SUB32ri R32:$src1, imm:$src2)>;
def : Pat<(X86subflag R32:$src1, i32immSExt8:$src2),
(SUB32ri8 R32:$src1, i32immSExt8:$src2)>;
// {s|z}extload bool -> {s|z}extload byte
def : Pat<(sextloadi16i1 addr:$src), (MOVSX16rm8 addr:$src)>;
def : Pat<(sextloadi32i1 addr:$src), (MOVSX32rm8 addr:$src)>;
def : Pat<(zextloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>;
def : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
// extload bool -> extload byte
def : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>;
// anyext -> zext
def : Pat<(i16 (anyext R8 :$src)), (MOVZX16rr8 R8 :$src)>;
def : Pat<(i32 (anyext R8 :$src)), (MOVZX32rr8 R8 :$src)>;
def : Pat<(i32 (anyext R16:$src)), (MOVZX32rr16 R16:$src)>;
// Required for RET of f32 / f64 values.
def : Pat<(X86fld addr:$src, f32), (FpLD32m addr:$src)>;
def : Pat<(X86fld addr:$src, f64), (FpLD64m addr:$src)>;
// Required for CALL which return f32 / f64 values.
def : Pat<(X86fst RFP:$src, addr:$op, f32), (FpST32m addr:$op, RFP:$src)>;
def : Pat<(X86fst RFP:$src, addr:$op, f64), (FpST64m addr:$op, RFP:$src)>;
// Floatin point constant -0.0 and -1.0
def : Pat<(f64 fp64immneg0), (FpCHS (FpLD0))>, Requires<[FPStack]>;
def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>;
// RFP undef
def : Pat<(f64 (undef)), (FpLD0)>, Requires<[FPStack]>;
//===----------------------------------------------------------------------===//
// Some peepholes
//===----------------------------------------------------------------------===//
// (shl x, 1) ==> (add x, x)
def : Pat<(shl R8 :$src1, (i8 1)), (ADD8rr R8 :$src1, R8 :$src1)>;
def : Pat<(shl R16:$src1, (i8 1)), (ADD16rr R16:$src1, R16:$src1)>;
def : Pat<(shl R32:$src1, (i8 1)), (ADD32rr R32:$src1, R32:$src1)>;