mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-27 14:24:40 +00:00
More X86 floating point patterns.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24990 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -227,8 +227,6 @@ SDOperand X86TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MVT::f32:
|
case MVT::f32:
|
||||||
assert(X86ScalarSSE && "MVT::f32 only legal with scalar sse fp");
|
|
||||||
// Fallthrough intended
|
|
||||||
case MVT::f64:
|
case MVT::f64:
|
||||||
if (!X86ScalarSSE) {
|
if (!X86ScalarSSE) {
|
||||||
std::vector<MVT::ValueType> Tys;
|
std::vector<MVT::ValueType> Tys;
|
||||||
@ -236,6 +234,8 @@ SDOperand X86TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
|
|||||||
Tys.push_back(MVT::Flag);
|
Tys.push_back(MVT::Flag);
|
||||||
std::vector<SDOperand> Ops;
|
std::vector<SDOperand> Ops;
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
|
if (OpVT == MVT::f32)
|
||||||
|
Op = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Op);
|
||||||
Ops.push_back(Op);
|
Ops.push_back(Op);
|
||||||
Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
|
Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
|
||||||
} else {
|
} else {
|
||||||
@ -1053,7 +1053,7 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
|
return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
|
||||||
Op.getOperand(0), Op.getOperand(2), CC, Cond);
|
Op.getOperand(0), Op.getOperand(2), CC, Cond);
|
||||||
}
|
}
|
||||||
case ISD::GlobalAddress:
|
case ISD::GlobalAddress: {
|
||||||
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
|
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
|
||||||
SDOperand GVOp = DAG.getTargetGlobalAddress(GV, getPointerTy());
|
SDOperand GVOp = DAG.getTargetGlobalAddress(GV, getPointerTy());
|
||||||
// For Darwin, external and weak symbols are indirect, so we want to load
|
// For Darwin, external and weak symbols are indirect, so we want to load
|
||||||
@ -1069,6 +1069,7 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
return GVOp;
|
return GVOp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||||
|
@ -42,8 +42,8 @@ namespace llvm {
|
|||||||
|
|
||||||
/// FLD - This instruction implements an extending load to FP stack slots.
|
/// FLD - This instruction implements an extending load to FP stack slots.
|
||||||
/// This corresponds to the X86::FLD32m / X86::FLD64m. It takes a chain
|
/// This corresponds to the X86::FLD32m / X86::FLD64m. It takes a chain
|
||||||
/// operand, ptr to load from, and a VALUETYPE node indicating the type
|
/// operand, ptr to load from, and a ValueType node indicating the type
|
||||||
/// to load.
|
/// to load to.
|
||||||
FLD,
|
FLD,
|
||||||
|
|
||||||
/// FP_SET_RESULT - This corresponds to FpSETRESULT pseudo instrcuction
|
/// FP_SET_RESULT - This corresponds to FpSETRESULT pseudo instrcuction
|
||||||
|
@ -35,7 +35,7 @@ def SDTX86SetCC : SDTypeProfile<1, 2,
|
|||||||
def SDTX86RetFlag : SDTypeProfile<0, 2, [SDTCisVT<0, i16>,
|
def SDTX86RetFlag : SDTypeProfile<0, 2, [SDTCisVT<0, i16>,
|
||||||
SDTCisVT<1, FlagVT>]>;
|
SDTCisVT<1, FlagVT>]>;
|
||||||
|
|
||||||
def SDTX86Fld : SDTypeProfile<1, 2, [SDTCisFP<0>,
|
def SDTX86Fld : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
|
||||||
SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
|
SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
|
||||||
|
|
||||||
def SDTX86FpSet : SDTypeProfile<1, 1, [SDTCisVT<0, FlagVT>, SDTCisFP<1>]>;
|
def SDTX86FpSet : SDTypeProfile<1, 1, [SDTCisVT<0, FlagVT>, SDTCisFP<1>]>;
|
||||||
@ -128,6 +128,7 @@ def MRM6m : Format<30>; def MRM7m : Format<31>;
|
|||||||
def HasSSE1 : Predicate<"X86Vector >= SSE">;
|
def HasSSE1 : Predicate<"X86Vector >= SSE">;
|
||||||
def HasSSE2 : Predicate<"X86Vector >= SSE2">;
|
def HasSSE2 : Predicate<"X86Vector >= SSE2">;
|
||||||
def HasSSE3 : Predicate<"X86Vector >= SSE3">;
|
def HasSSE3 : Predicate<"X86Vector >= SSE3">;
|
||||||
|
def FPStack : Predicate<"X86Vector < SSE2">;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// X86 specific pattern fragments.
|
// X86 specific pattern fragments.
|
||||||
@ -245,8 +246,8 @@ def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextload node:$ptr, i8))>;
|
|||||||
def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i8))>;
|
def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i8))>;
|
||||||
def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i16))>;
|
def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i16))>;
|
||||||
|
|
||||||
def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extload node:$ptr, i1))>;
|
def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extload node:$ptr, i1))>;
|
||||||
|
def extloadf64f32 : PatFrag<(ops node:$ptr), (f64 (extload node:$ptr, f32))>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Instruction templates...
|
// Instruction templates...
|
||||||
@ -2044,189 +2045,237 @@ def : Pat<(i32 (anyext R8 :$src)), (MOVZX32rr8 R8 :$src)>;
|
|||||||
def : Pat<(i32 (anyext R16:$src)), (MOVZX32rr16 R16:$src)>;
|
def : Pat<(i32 (anyext R16:$src)), (MOVZX32rr16 R16:$src)>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// XMM Floating point support (requires SSE2)
|
// XMM Floating point support (requires SSE / SSE2)
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src),
|
def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src),
|
||||||
"movss {$src, $dst|$dst, $src}", []>, XS;
|
"movss {$src, $dst|$dst, $src}", []>,
|
||||||
|
Requires<[HasSSE1]>, XS;
|
||||||
def MOVSDrr : I<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src),
|
def MOVSDrr : I<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src),
|
||||||
"movsd {$src, $dst|$dst, $src}", []>, XD;
|
"movsd {$src, $dst|$dst, $src}", []>,
|
||||||
|
Requires<[HasSSE2]>, XD;
|
||||||
|
|
||||||
def MOVSSrm : I<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
|
def MOVSSrm : I<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
|
||||||
"movss {$src, $dst|$dst, $src}",
|
"movss {$src, $dst|$dst, $src}",
|
||||||
[(set FR32:$dst, (loadf32 addr:$src))]>,
|
[(set FR32:$dst, (loadf32 addr:$src))]>,
|
||||||
Requires<[HasSSE2]>, XS;
|
Requires<[HasSSE1]>, XS;
|
||||||
def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, FR32:$src),
|
def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, FR32:$src),
|
||||||
"movss {$src, $dst|$dst, $src}",
|
"movss {$src, $dst|$dst, $src}",
|
||||||
[(store FR32:$src, addr:$dst)]>, XS;
|
[(store FR32:$src, addr:$dst)]>,
|
||||||
|
Requires<[HasSSE1]>, XS;
|
||||||
def MOVSDrm : I<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
|
def MOVSDrm : I<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
|
||||||
"movsd {$src, $dst|$dst, $src}",
|
"movsd {$src, $dst|$dst, $src}",
|
||||||
[(set FR64:$dst, (loadf64 addr:$src))]>,
|
[(set FR64:$dst, (loadf64 addr:$src))]>,
|
||||||
Requires<[HasSSE2]>, XD;
|
Requires<[HasSSE2]>, XD;
|
||||||
def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, FR64:$src),
|
def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, FR64:$src),
|
||||||
"movsd {$src, $dst|$dst, $src}",
|
"movsd {$src, $dst|$dst, $src}",
|
||||||
[(store FR64:$src, addr:$dst)]>,
|
[(store FR64:$src, addr:$dst)]>,
|
||||||
Requires<[HasSSE2]>, XD;
|
Requires<[HasSSE2]>, XD;
|
||||||
|
|
||||||
def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src),
|
def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src),
|
||||||
"cvttsd2si {$src, $dst|$dst, $src}",
|
"cvttsd2si {$src, $dst|$dst, $src}",
|
||||||
[(set R32:$dst, (fp_to_sint FR64:$src))]>,
|
[(set R32:$dst, (fp_to_sint FR64:$src))]>,
|
||||||
Requires<[HasSSE2]>, XD;
|
Requires<[HasSSE2]>, XD;
|
||||||
def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src),
|
def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src),
|
||||||
"cvttsd2si {$src, $dst|$dst, $src}",
|
"cvttsd2si {$src, $dst|$dst, $src}",
|
||||||
[(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>,
|
[(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>,
|
||||||
Requires<[HasSSE2]>, XD;
|
Requires<[HasSSE2]>, XD;
|
||||||
def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src),
|
def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src),
|
||||||
"cvttss2si {$src, $dst|$dst, $src}",
|
"cvttss2si {$src, $dst|$dst, $src}",
|
||||||
[(set R32:$dst, (fp_to_sint FR32:$src))]>,
|
[(set R32:$dst, (fp_to_sint FR32:$src))]>,
|
||||||
Requires<[HasSSE2]>, XS;
|
Requires<[HasSSE1]>, XS;
|
||||||
def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src),
|
def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src),
|
||||||
"cvttss2si {$src, $dst|$dst, $src}",
|
"cvttss2si {$src, $dst|$dst, $src}",
|
||||||
[(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>,
|
[(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>,
|
||||||
Requires<[HasSSE2]>, XS;
|
Requires<[HasSSE1]>, XS;
|
||||||
def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src),
|
def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src),
|
||||||
"cvtsd2ss {$src, $dst|$dst, $src}",
|
"cvtsd2ss {$src, $dst|$dst, $src}",
|
||||||
[(set FR32:$dst, (fround FR64:$src))]>,
|
[(set FR32:$dst, (fround FR64:$src))]>,
|
||||||
Requires<[HasSSE2]>, XS;
|
Requires<[HasSSE2]>, XS;
|
||||||
def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src),
|
def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src),
|
||||||
"cvtsd2ss {$src, $dst|$dst, $src}",
|
"cvtsd2ss {$src, $dst|$dst, $src}",
|
||||||
[(set FR32:$dst, (fround (loadf64 addr:$src)))]>,
|
[(set FR32:$dst, (fround (loadf64 addr:$src)))]>,
|
||||||
Requires<[HasSSE2]>, XS;
|
Requires<[HasSSE2]>, XS;
|
||||||
def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src),
|
def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src),
|
||||||
"cvtss2sd {$src, $dst|$dst, $src}",
|
"cvtss2sd {$src, $dst|$dst, $src}",
|
||||||
[(set FR64:$dst, (fextend FR32:$src))]>,
|
[(set FR64:$dst, (fextend FR32:$src))]>,
|
||||||
Requires<[HasSSE2]>, XD;
|
Requires<[HasSSE2]>, XD;
|
||||||
def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src),
|
def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src),
|
||||||
"cvtss2sd {$src, $dst|$dst, $src}",
|
"cvtss2sd {$src, $dst|$dst, $src}",
|
||||||
[(set FR64:$dst, (fextend (loadf32 addr:$src)))]>,
|
[(set FR64:$dst, (fextend (loadf32 addr:$src)))]>,
|
||||||
Requires<[HasSSE2]>, XD;
|
Requires<[HasSSE2]>, XD;
|
||||||
def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src),
|
def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src),
|
||||||
"cvtsi2ss {$src, $dst|$dst, $src}",
|
"cvtsi2ss {$src, $dst|$dst, $src}",
|
||||||
[(set FR32:$dst, (sint_to_fp R32:$src))]>,
|
[(set FR32:$dst, (sint_to_fp R32:$src))]>,
|
||||||
Requires<[HasSSE2]>, XS;
|
Requires<[HasSSE2]>, XS;
|
||||||
def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops FR32:$dst, i32mem:$src),
|
def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops FR32:$dst, i32mem:$src),
|
||||||
"cvtsi2ss {$src, $dst|$dst, $src}",
|
"cvtsi2ss {$src, $dst|$dst, $src}",
|
||||||
[(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
|
[(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
|
||||||
Requires<[HasSSE2]>, XS;
|
Requires<[HasSSE2]>, XS;
|
||||||
def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops FR64:$dst, R32:$src),
|
def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops FR64:$dst, R32:$src),
|
||||||
"cvtsi2sd {$src, $dst|$dst, $src}",
|
"cvtsi2sd {$src, $dst|$dst, $src}",
|
||||||
[(set FR64:$dst, (sint_to_fp R32:$src))]>,
|
[(set FR64:$dst, (sint_to_fp R32:$src))]>,
|
||||||
Requires<[HasSSE2]>, XD;
|
Requires<[HasSSE2]>, XD;
|
||||||
def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops FR64:$dst, i32mem:$src),
|
def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops FR64:$dst, i32mem:$src),
|
||||||
"cvtsi2sd {$src, $dst|$dst, $src}",
|
"cvtsi2sd {$src, $dst|$dst, $src}",
|
||||||
[(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
|
[(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
|
||||||
Requires<[HasSSE2]>, XD;
|
Requires<[HasSSE2]>, XD;
|
||||||
|
|
||||||
def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
|
def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
|
||||||
"sqrtss {$src, $dst|$dst, $src}", []>, XS;
|
"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),
|
def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src),
|
||||||
"sqrtss {$src, $dst|$dst, $src}",
|
"sqrtss {$src, $dst|$dst, $src}",
|
||||||
[(set FR32:$dst, (fsqrt FR32:$src))]>, XS;
|
[(set FR32:$dst, (fsqrt FR32:$src))]>,
|
||||||
|
Requires<[HasSSE1]>, XS;
|
||||||
def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
|
def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
|
||||||
"sqrtsd {$src, $dst|$dst, $src}", []>, XD;
|
"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),
|
def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src),
|
||||||
"sqrtsd {$src, $dst|$dst, $src}",
|
"sqrtsd {$src, $dst|$dst, $src}",
|
||||||
[(set FR64:$dst, (fsqrt FR64:$src))]>, XD;
|
[(set FR64:$dst, (fsqrt FR64:$src))]>,
|
||||||
|
Requires<[HasSSE2]>, XD;
|
||||||
|
|
||||||
def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$dst, FR64:$src),
|
def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$dst, FR64:$src),
|
||||||
"ucomisd {$src, $dst|$dst, $src}", []>, TB, OpSize;
|
"ucomisd {$src, $dst|$dst, $src}", []>,
|
||||||
|
Requires<[HasSSE2]>, TB, OpSize;
|
||||||
def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
|
def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
|
||||||
"ucomisd {$src, $dst|$dst, $src}", []>, TB, OpSize;
|
"ucomisd {$src, $dst|$dst, $src}", []>,
|
||||||
|
Requires<[HasSSE2]>, TB, OpSize;
|
||||||
def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$dst, FR32:$src),
|
def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$dst, FR32:$src),
|
||||||
"ucomiss {$src, $dst|$dst, $src}", []>, TB;
|
"ucomiss {$src, $dst|$dst, $src}", []>,
|
||||||
|
Requires<[HasSSE1]>, TB;
|
||||||
def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
|
def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
|
||||||
"ucomiss {$src, $dst|$dst, $src}", []>, TB;
|
"ucomiss {$src, $dst|$dst, $src}", []>,
|
||||||
|
Requires<[HasSSE1]>, TB;
|
||||||
|
|
||||||
// Pseudo-instructions that map fld0 to xorps/xorpd for sse.
|
// Pseudo-instructions that map fld0 to xorps/xorpd for sse.
|
||||||
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
|
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
|
||||||
def FLD0SS : I<0x57, MRMSrcReg, (ops FR32:$dst),
|
def FLD0SS : I<0x57, MRMSrcReg, (ops FR32:$dst),
|
||||||
"xorps $dst, $dst", []>, TB;
|
"xorps $dst, $dst", []>, Requires<[HasSSE1]>, TB;
|
||||||
def FLD0SD : I<0x57, MRMSrcReg, (ops FR64:$dst),
|
def FLD0SD : I<0x57, MRMSrcReg, (ops FR64:$dst),
|
||||||
"xorpd $dst, $dst", []>, TB, OpSize;
|
"xorpd $dst, $dst", []>, Requires<[HasSSE2]>, TB, OpSize;
|
||||||
|
|
||||||
let isTwoAddress = 1 in {
|
let isTwoAddress = 1 in {
|
||||||
|
// SSE Scalar Arithmetic
|
||||||
let isCommutable = 1 in {
|
let isCommutable = 1 in {
|
||||||
def ADDSSrr : I<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
def ADDSSrr : I<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
||||||
"addss {$src2, $dst|$dst, $src2}",
|
"addss {$src2, $dst|$dst, $src2}",
|
||||||
[(set FR32:$dst, (fadd FR32:$src1, FR32:$src2))]>, XS;
|
[(set FR32:$dst, (fadd FR32:$src1, FR32:$src2))]>,
|
||||||
|
Requires<[HasSSE1]>, XS;
|
||||||
def ADDSDrr : I<0x58, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
|
def ADDSDrr : I<0x58, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
|
||||||
"addsd {$src2, $dst|$dst, $src2}",
|
"addsd {$src2, $dst|$dst, $src2}",
|
||||||
[(set FR64:$dst, (fadd FR64:$src1, FR64:$src2))]>, XD;
|
[(set FR64:$dst, (fadd FR64:$src1, FR64:$src2))]>,
|
||||||
def ANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
Requires<[HasSSE2]>, XD;
|
||||||
"andps {$src2, $dst|$dst, $src2}", []>, TB;
|
|
||||||
def ANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
|
|
||||||
"andpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
|
|
||||||
def MULSSrr : I<0x59, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
def MULSSrr : I<0x59, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
||||||
"mulss {$src2, $dst|$dst, $src2}",
|
"mulss {$src2, $dst|$dst, $src2}",
|
||||||
[(set FR32:$dst, (fmul FR32:$src1, FR32:$src2))]>, XS;
|
[(set FR32:$dst, (fmul FR32:$src1, FR32:$src2))]>,
|
||||||
|
Requires<[HasSSE1]>, XS;
|
||||||
def MULSDrr : I<0x59, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
|
def MULSDrr : I<0x59, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
|
||||||
"mulsd {$src2, $dst|$dst, $src2}",
|
"mulsd {$src2, $dst|$dst, $src2}",
|
||||||
[(set FR64:$dst, (fmul FR64:$src1, FR64:$src2))]>, XD;
|
[(set FR64:$dst, (fmul FR64:$src1, FR64:$src2))]>,
|
||||||
def ORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
Requires<[HasSSE2]>, XD;
|
||||||
"orps {$src2, $dst|$dst, $src2}", []>, TB;
|
|
||||||
def ORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
|
|
||||||
"orpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
|
|
||||||
def XORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
|
||||||
"xorps {$src2, $dst|$dst, $src2}", []>, TB;
|
|
||||||
def XORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
|
|
||||||
"xorpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
|
|
||||||
}
|
}
|
||||||
def ANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
|
||||||
"andnps {$src2, $dst|$dst, $src2}", []>, TB;
|
|
||||||
def ANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
|
|
||||||
"andnpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
|
|
||||||
def ADDSSrm : I<0x58, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
|
|
||||||
"addss {$src2, $dst|$dst, $src2}", []>, XS;
|
|
||||||
def ADDSDrm : I<0x58, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
|
|
||||||
"addsd {$src2, $dst|$dst, $src2}", []>, XD;
|
|
||||||
def MULSSrm : I<0x59, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
|
|
||||||
"mulss {$src2, $dst|$dst, $src2}", []>, XS;
|
|
||||||
def MULSDrm : I<0x59, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
|
|
||||||
"mulsd {$src2, $dst|$dst, $src2}", []>, XD;
|
|
||||||
|
|
||||||
def DIVSSrm : I<0x5E, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
|
def ADDSSrm : I<0x58, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
|
||||||
"divss {$src2, $dst|$dst, $src2}", []>, XS;
|
"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),
|
def DIVSSrr : I<0x5E, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
||||||
"divss {$src2, $dst|$dst, $src2}",
|
"divss {$src2, $dst|$dst, $src2}",
|
||||||
[(set FR32:$dst, (fdiv FR32:$src1, FR32:$src2))]>, XS;
|
[(set FR32:$dst, (fdiv FR32:$src1, FR32:$src2))]>,
|
||||||
def DIVSDrm : I<0x5E, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
|
Requires<[HasSSE1]>, XS;
|
||||||
"divsd {$src2, $dst|$dst, $src2}", []>, XD;
|
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),
|
def DIVSDrr : I<0x5E, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
|
||||||
"divsd {$src2, $dst|$dst, $src2}",
|
"divsd {$src2, $dst|$dst, $src2}",
|
||||||
[(set FR64:$dst, (fdiv FR64:$src1, FR64:$src2))]>, XD;
|
[(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 SUBSSrm : I<0x5C, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
|
|
||||||
"subss {$src2, $dst|$dst, $src2}", []>, XS;
|
|
||||||
def SUBSSrr : I<0x5C, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
def SUBSSrr : I<0x5C, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
|
||||||
"subss {$src2, $dst|$dst, $src2}",
|
"subss {$src2, $dst|$dst, $src2}",
|
||||||
[(set FR32:$dst, (fsub FR32:$src1, FR32:$src2))]>, XS;
|
[(set FR32:$dst, (fsub FR32:$src1, FR32:$src2))]>,
|
||||||
def SUBSDrm : I<0x5C, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
|
Requires<[HasSSE1]>, XS;
|
||||||
"subsd {$src2, $dst|$dst, $src2}", []>, XD;
|
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),
|
def SUBSDrr : I<0x5C, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
|
||||||
"subsd {$src2, $dst|$dst, $src2}",
|
"subsd {$src2, $dst|$dst, $src2}",
|
||||||
[(set FR64:$dst, (fsub FR64:$src1, FR64:$src2))]>, XD;
|
[(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,
|
def CMPSSrr : I<0xC2, MRMSrcReg,
|
||||||
(ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc),
|
(ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc),
|
||||||
"cmp${cc}ss {$src, $dst|$dst, $src}", []>, XS;
|
"cmp${cc}ss {$src, $dst|$dst, $src}", []>,
|
||||||
|
Requires<[HasSSE1]>, XS;
|
||||||
def CMPSSrm : I<0xC2, MRMSrcMem,
|
def CMPSSrm : I<0xC2, MRMSrcMem,
|
||||||
(ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc),
|
(ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc),
|
||||||
"cmp${cc}ss {$src, $dst|$dst, $src}", []>, XS;
|
"cmp${cc}ss {$src, $dst|$dst, $src}", []>,
|
||||||
|
Requires<[HasSSE1]>, XS;
|
||||||
def CMPSDrr : I<0xC2, MRMSrcReg,
|
def CMPSDrr : I<0xC2, MRMSrcReg,
|
||||||
(ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc),
|
(ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc),
|
||||||
"cmp${cc}sd {$src, $dst|$dst, $src}", []>, XD;
|
"cmp${cc}sd {$src, $dst|$dst, $src}", []>,
|
||||||
|
Requires<[HasSSE1]>, XD;
|
||||||
def CMPSDrm : I<0xC2, MRMSrcMem,
|
def CMPSDrm : I<0xC2, MRMSrcMem,
|
||||||
(ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc),
|
(ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc),
|
||||||
"cmp${cc}sd {$src, $dst|$dst, $src}", []>, XD;
|
"cmp${cc}sd {$src, $dst|$dst, $src}", []>,
|
||||||
|
Requires<[HasSSE2]>, XD;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Miscellaneous Instructions
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", []>, TB, Imp<[],[EAX,EDX]>;
|
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Floating Point Stack Support
|
// Floating Point Stack Support
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -2248,45 +2297,92 @@ class FPI<bits<8> o, Format F, dag ops, string asm> : I<o, F, ops, asm, []> {}
|
|||||||
|
|
||||||
// FpI - Floating Point Psuedo Instruction template.
|
// FpI - Floating Point Psuedo Instruction template.
|
||||||
class FpI<dag ops, FPFormat fp, list<dag> pattern>
|
class FpI<dag ops, FPFormat fp, list<dag> pattern>
|
||||||
|
: X86Inst<0, Pseudo, NoImm, ops, "">, Requires<[FPStack]> {
|
||||||
|
let FPForm = fp; let FPFormBits = FPForm.Value;
|
||||||
|
let Pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FpI - Floating Point Psuedo Instruction template.
|
||||||
|
// TEMPORARY: for FpGETRESULT and FpSETRESULT only. Since
|
||||||
|
// they must match regardless of X86Vector.
|
||||||
|
class FpPseudoI<dag ops, FPFormat fp, list<dag> pattern>
|
||||||
: X86Inst<0, Pseudo, NoImm, ops, ""> {
|
: X86Inst<0, Pseudo, NoImm, ops, ""> {
|
||||||
let FPForm = fp; let FPFormBits = FPForm.Value;
|
let FPForm = fp; let FPFormBits = FPForm.Value;
|
||||||
let Pattern = pattern;
|
let Pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Random Pseudo Instructions.
|
// Random Pseudo Instructions.
|
||||||
def FpGETRESULT : FpI<(ops RFP:$dst), SpecialFP, // FPR = ST(0)
|
def FpGETRESULT : FpPseudoI<(ops RFP:$dst), SpecialFP, // FPR = ST(0)
|
||||||
[]>;
|
[]>;
|
||||||
def FpSETRESULT : FpI<(ops RFP:$src), SpecialFP,
|
def FpSETRESULT : FpPseudoI<(ops RFP:$src), SpecialFP,
|
||||||
[(set FLAG, (X86fpset RFP:$src))]>,
|
[(set FLAG, (X86fpset RFP:$src))]>,
|
||||||
Imp<[], [ST0]>; // ST(0) = FPR
|
Imp<[], [ST0]>; // ST(0) = FPR
|
||||||
|
|
||||||
def FpMOV : FpI<(ops RFP:$dst, RFP:$src), SpecialFP,
|
def FpMOV : FpI<(ops RFP:$dst, RFP:$src), SpecialFP,
|
||||||
[]>; // f1 = fmov f2
|
[]>; // f1 = fmov f2
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
// Binary Ops with a memory source.
|
// Binary Ops with a memory source.
|
||||||
def FpADD32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpADD32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = ST(0) + [mem32]
|
[(set RFP:$dst, (fadd RFP:$src1,
|
||||||
|
(extloadf64f32 addr:$src2)))]>;
|
||||||
|
// ST(0) = ST(0) + [mem32]
|
||||||
def FpADD64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpADD64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = ST(0) + [mem32]
|
[(set RFP:$dst, (fadd RFP:$src1, (loadf64 addr:$src2)))]>;
|
||||||
|
// ST(0) = ST(0) + [mem64]
|
||||||
def FpMUL32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpMUL32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = ST(0) * [mem32]
|
[(set RFP:$dst, (fmul RFP:$src1,
|
||||||
|
(extloadf64f32 addr:$src2)))]>;
|
||||||
|
// ST(0) = ST(0) * [mem32]
|
||||||
def FpMUL64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpMUL64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = ST(0) * [mem32]
|
[(set RFP:$dst, (fmul RFP:$src1, (loadf64 addr:$src2)))]>;
|
||||||
|
// ST(0) = ST(0) * [mem64]
|
||||||
def FpSUB32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpSUB32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = ST(0) - [mem32]
|
[(set RFP:$dst, (fsub RFP:$src1,
|
||||||
|
(extloadf64f32 addr:$src2)))]>;
|
||||||
|
// ST(0) = ST(0) - [mem32]
|
||||||
def FpSUB64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpSUB64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = ST(0) - [mem32]
|
[(set RFP:$dst, (fsub RFP:$src1, (loadf64 addr:$src2)))]>;
|
||||||
|
// ST(0) = ST(0) - [mem64]
|
||||||
def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = [mem32] - ST(0)
|
[(set RFP:$dst, (fadd (extloadf64f32 addr:$src2),
|
||||||
|
RFP:$src1))]>;
|
||||||
|
// ST(0) = [mem32] - ST(0)
|
||||||
def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = [mem32] - ST(0)
|
[(set RFP:$dst, (fsub (loadf64 addr:$src2), RFP:$src1))]>;
|
||||||
|
// ST(0) = [mem64] - ST(0)
|
||||||
def FpDIV32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpDIV32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = ST(0) / [mem32]
|
[(set RFP:$dst, (fdiv RFP:$src1,
|
||||||
|
(extloadf64f32 addr:$src2)))]>;
|
||||||
|
// ST(0) = ST(0) / [mem32]
|
||||||
def FpDIV64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpDIV64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = ST(0) / [mem32]
|
[(set RFP:$dst, (fdiv RFP:$src1, (loadf64 addr:$src2)))]>;
|
||||||
|
// ST(0) = ST(0) / [mem64]
|
||||||
def FpDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = [mem32] / ST(0)
|
[(set RFP:$dst, (fdiv (extloadf64f32 addr:$src2),
|
||||||
|
RFP:$src1))]>;
|
||||||
|
// ST(0) = [mem32] / ST(0)
|
||||||
def FpDIVR64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
def FpDIVR64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
|
||||||
[]>; // ST(0) = [mem32] / ST(0)
|
[(set RFP:$dst, (fdiv (loadf64 addr:$src2), RFP:$src1))]>;
|
||||||
|
// ST(0) = [mem64] / ST(0)
|
||||||
|
|
||||||
|
|
||||||
def FADD32m : FPI<0xD8, MRM0m, (ops f32mem:$src), "fadd{s} $src">;
|
def FADD32m : FPI<0xD8, MRM0m, (ops f32mem:$src), "fadd{s} $src">;
|
||||||
@ -2317,6 +2413,51 @@ def FDIVR64m : FPI<0xDC, MRM7m, (ops f64mem:$src), "fdivr{l} $src">;
|
|||||||
//def FIDIVR32m : FPI<0xDA, MRM7m>; // ST(0) = [mem32int] / ST(0)
|
//def FIDIVR32m : FPI<0xDA, MRM7m>; // ST(0) = [mem32int] / ST(0)
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
|
||||||
// Floating point cmovs.
|
// Floating point cmovs.
|
||||||
let isTwoAddress = 1 in {
|
let isTwoAddress = 1 in {
|
||||||
def FpCMOVB : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
|
def FpCMOVB : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
|
||||||
@ -2348,9 +2489,9 @@ def FCMOVNP : FPI<0xD8, AddRegFrm, (ops RST:$op),
|
|||||||
|
|
||||||
// Floating point loads & stores.
|
// Floating point loads & stores.
|
||||||
def FpLD32m : FpI<(ops RFP:$dst, f32mem:$src), ZeroArgFP,
|
def FpLD32m : FpI<(ops RFP:$dst, f32mem:$src), ZeroArgFP,
|
||||||
[(set RFP:$dst, (X86fld addr:$src, f32))]>;
|
[(set RFP:$dst, (extloadf64f32 addr:$src))]>;
|
||||||
def FpLD64m : FpI<(ops RFP:$dst, f64mem:$src), ZeroArgFP,
|
def FpLD64m : FpI<(ops RFP:$dst, f64mem:$src), ZeroArgFP,
|
||||||
[(set RFP:$dst, (X86fld addr:$src, f64))]>;
|
[(set RFP:$dst, (loadf64 addr:$src))]>;
|
||||||
def FpILD16m : FpI<(ops RFP:$dst, i16mem:$src), ZeroArgFP,
|
def FpILD16m : FpI<(ops RFP:$dst, i16mem:$src), ZeroArgFP,
|
||||||
[]>;
|
[]>;
|
||||||
def FpILD32m : FpI<(ops RFP:$dst, i32mem:$src), ZeroArgFP,
|
def FpILD32m : FpI<(ops RFP:$dst, i32mem:$src), ZeroArgFP,
|
||||||
@ -2358,8 +2499,14 @@ def FpILD32m : FpI<(ops RFP:$dst, i32mem:$src), ZeroArgFP,
|
|||||||
def FpILD64m : FpI<(ops RFP:$dst, i64mem:$src), ZeroArgFP,
|
def FpILD64m : FpI<(ops RFP:$dst, i64mem:$src), ZeroArgFP,
|
||||||
[]>;
|
[]>;
|
||||||
|
|
||||||
def FpST32m : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>;
|
// Required for RET of f32 / f64 values.
|
||||||
def FpST64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>;
|
def : Pat<(X86fld addr:$src, f32), (FpLD32m addr:$src)>;
|
||||||
|
def : Pat<(X86fld addr:$src, f64), (FpLD64m addr:$src)>;
|
||||||
|
|
||||||
|
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)]>;
|
||||||
def FpSTP32m : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>;
|
def FpSTP32m : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>;
|
||||||
def FpSTP64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>;
|
def FpSTP64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>;
|
||||||
def FpIST16m : FpI<(ops i16mem:$op, RFP:$src), OneArgFP, []>;
|
def FpIST16m : FpI<(ops i16mem:$op, RFP:$src), OneArgFP, []>;
|
||||||
@ -2395,68 +2542,6 @@ def FLD0 : FPI<0xEE, RawFrm, (ops), "fldz">, D9;
|
|||||||
def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9;
|
def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9;
|
||||||
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// 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">;
|
|
||||||
|
|
||||||
// Floating point compares.
|
// Floating point compares.
|
||||||
def FpUCOMr : FpI<(ops RST:$lhs, RST:$rhs), CompareFP,
|
def FpUCOMr : FpI<(ops RST:$lhs, RST:$rhs), CompareFP,
|
||||||
[]>; // FPSW = cmp ST(0) with ST(i)
|
[]>; // FPSW = cmp ST(0) with ST(i)
|
||||||
@ -2489,3 +2574,10 @@ def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world
|
|||||||
(ops i16mem:$dst), "fnstcw $dst", []>;
|
(ops i16mem:$dst), "fnstcw $dst", []>;
|
||||||
def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
|
def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
|
||||||
(ops i16mem:$dst), "fldcw $dst", []>;
|
(ops i16mem:$dst), "fldcw $dst", []>;
|
||||||
|
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Miscellaneous Instructions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", []>, TB, Imp<[],[EAX,EDX]>;
|
||||||
|
Reference in New Issue
Block a user