//
//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+// FPStack specific DAG Nodes.
+//===----------------------------------------------------------------------===//
+
+def SDTX86FpGet : SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>;
+def SDTX86FpSet : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
+def SDTX86Fld : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
+ SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
+def SDTX86Fst : SDTypeProfile<0, 3, [SDTCisFP<0>,
+ SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
+def SDTX86Fild : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisPtrTy<1>,
+ SDTCisVT<2, OtherVT>]>;
+def SDTX86FpToIMem: SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisPtrTy<1>]>;
+
+def X86fpget : SDNode<"X86ISD::FP_GET_RESULT", SDTX86FpGet,
+ [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
+def X86fpset : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet,
+ [SDNPHasChain, SDNPOutFlag]>;
+def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld,
+ [SDNPHasChain]>;
+def X86fst : SDNode<"X86ISD::FST", SDTX86Fst,
+ [SDNPHasChain, SDNPInFlag]>;
+def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild,
+ [SDNPHasChain]>;
+def X86fildflag: SDNode<"X86ISD::FILD_FLAG",SDTX86Fild,
+ [SDNPHasChain, SDNPOutFlag]>;
+def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem,
+ [SDNPHasChain]>;
+def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem,
+ [SDNPHasChain]>;
+def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
+ [SDNPHasChain]>;
+
+//===----------------------------------------------------------------------===//
+// FPStack pattern fragments
+//===----------------------------------------------------------------------===//
+
+def fp64imm0 : PatLeaf<(f64 fpimm), [{
+ return N->isExactlyValue(+0.0);
+}]>;
+
+def fp64immneg0 : PatLeaf<(f64 fpimm), [{
+ return N->isExactlyValue(-0.0);
+}]>;
+
+def fp64imm1 : PatLeaf<(f64 fpimm), [{
+ return N->isExactlyValue(+1.0);
+}]>;
+
+def fp64immneg1 : PatLeaf<(f64 fpimm), [{
+ return N->isExactlyValue(-1.0);
+}]>;
+
+def extloadf64f32 : PatFrag<(ops node:$ptr), (f64 (extload node:$ptr, f32))>;
+
+// Some 'special' instructions
+let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
+ def FP_TO_INT16_IN_MEM : I<0, Pseudo,
+ (ops i16mem:$dst, RFP:$src),
+ "#FP_TO_INT16_IN_MEM PSEUDO!",
+ [(X86fp_to_i16mem RFP:$src, addr:$dst)]>;
+ def FP_TO_INT32_IN_MEM : I<0, Pseudo,
+ (ops i32mem:$dst, RFP:$src),
+ "#FP_TO_INT32_IN_MEM PSEUDO!",
+ [(X86fp_to_i32mem RFP:$src, addr:$dst)]>;
+ def FP_TO_INT64_IN_MEM : I<0, Pseudo,
+ (ops i64mem:$dst, RFP:$src),
+ "#FP_TO_INT64_IN_MEM PSEUDO!",
+ [(X86fp_to_i64mem RFP:$src, addr:$dst)]>;
+}
+
+let isTerminator = 1 in
+ let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in
+ def FP_REG_KILL : I<0, Pseudo, (ops), "#FP_REG_KILL", []>;
+
// 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.
def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
(ops i16mem:$dst), "fldcw $dst", []>;
-
//===----------------------------------------------------------------------===//
-// Alias Instructions
+// Non-Instruction Patterns
//===----------------------------------------------------------------------===//
-// Alias instructions that map fld0 to pxor for sse.
-// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
-def FsFLD0SS : I<0xEF, MRMInitReg, (ops FR32:$dst),
- "pxor $dst, $dst", [(set FR32:$dst, fp32imm0)]>,
- Requires<[HasSSE1]>, TB, OpSize;
-def FsFLD0SD : I<0xEF, MRMInitReg, (ops FR64:$dst),
- "pxor $dst, $dst", [(set FR64:$dst, fp64imm0)]>,
- Requires<[HasSSE2]>, TB, OpSize;
-
-// Alias instructions to do FR32 / FR64 reg-to-reg copy using movaps / movapd.
-// Upper bits are disregarded.
-def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src),
- "movaps {$src, $dst|$dst, $src}", []>,
- Requires<[HasSSE1]>, TB;
-def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src),
- "movapd {$src, $dst|$dst, $src}", []>,
- Requires<[HasSSE2]>, TB, OpSize;
-
-// Alias instructions to load FR32 / FR64 from f128mem using movaps / movapd.
-// Upper bits are disregarded.
-def FsMOVAPSrm : I<0x28, MRMSrcMem, (ops FR32:$dst, f128mem:$src),
- "movaps {$src, $dst|$dst, $src}",
- [(set FR32:$dst, (X86loadpf32 addr:$src))]>,
- Requires<[HasSSE1]>, TB;
-def FsMOVAPDrm : I<0x28, MRMSrcMem, (ops FR64:$dst, f128mem:$src),
- "movapd {$src, $dst|$dst, $src}",
- [(set FR64:$dst, (X86loadpf64 addr:$src))]>,
- Requires<[HasSSE2]>, TB, OpSize;
-
-// Alias bitwise logical operations using SSE logical ops on packed FP values.
-let isTwoAddress = 1 in {
-let isCommutable = 1 in {
-def FsANDPSrr : 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 FsANDPDrr : 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 FsORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
- "orps {$src2, $dst|$dst, $src2}", []>,
- Requires<[HasSSE1]>, TB;
-def FsORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
- "orpd {$src2, $dst|$dst, $src2}", []>,
- Requires<[HasSSE2]>, TB, OpSize;
-def FsXORPSrr : 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 FsXORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
- "xorpd {$src2, $dst|$dst, $src2}",
- [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>,
- Requires<[HasSSE2]>, TB, OpSize;
-}
-def FsANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
- "andps {$src2, $dst|$dst, $src2}",
- [(set FR32:$dst, (X86fand FR32:$src1,
- (X86loadpf32 addr:$src2)))]>,
- Requires<[HasSSE1]>, TB;
-def FsANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
- "andpd {$src2, $dst|$dst, $src2}",
- [(set FR64:$dst, (X86fand FR64:$src1,
- (X86loadpf64 addr:$src2)))]>,
- Requires<[HasSSE2]>, TB, OpSize;
-def FsORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
- "orps {$src2, $dst|$dst, $src2}", []>,
- Requires<[HasSSE1]>, TB;
-def FsORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
- "orpd {$src2, $dst|$dst, $src2}", []>,
- Requires<[HasSSE2]>, TB, OpSize;
-def FsXORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
- "xorps {$src2, $dst|$dst, $src2}",
- [(set FR32:$dst, (X86fxor FR32:$src1,
- (X86loadpf32 addr:$src2)))]>,
- Requires<[HasSSE1]>, TB;
-def FsXORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
- "xorpd {$src2, $dst|$dst, $src2}",
- [(set FR64:$dst, (X86fxor FR64:$src1,
- (X86loadpf64 addr:$src2)))]>,
- Requires<[HasSSE2]>, TB, OpSize;
-
-def FsANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
- "andnps {$src2, $dst|$dst, $src2}", []>,
- Requires<[HasSSE1]>, TB;
-def FsANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
- "andnps {$src2, $dst|$dst, $src2}", []>,
- Requires<[HasSSE1]>, TB;
-def FsANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
- "andnpd {$src2, $dst|$dst, $src2}", []>,
- Requires<[HasSSE2]>, TB, OpSize;
-def FsANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
- "andnpd {$src2, $dst|$dst, $src2}", []>,
- Requires<[HasSSE2]>, TB, OpSize;
-}
+// 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)>;
+
+// Floating point constant -0.0 and -1.0
+def : Pat<(f64 fp64immneg0), (FpCHS (FpLD0))>, Requires<[FPStack]>;
+def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>;
+
+// Used to conv. i64 to f64 since there isn't a SSE version.
+def : Pat<(X86fildflag addr:$src, i64), (FpILD64m addr:$src)>;