aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-01-30 08:02:57 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-01-30 08:02:57 +0000
commit6dab05363f94b279a3877fd79d68649b865e10d9 (patch)
tree18d03955fc4da9589b25889f03a912b9702640c6
parent19f3416d1cc7d21701bc7e0a21a854166dcbfe2c (diff)
Always use FP stack instructions to perform i64 to f64 as well as f64 to i64
conversions. SSE does not have instructions to handle these tasks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25817 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp72
-rw-r--r--lib/Target/X86/X86ISelLowering.h2
-rw-r--r--lib/Target/X86/X86InstrInfo.td7
3 files changed, 64 insertions, 17 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 9503bc13c4..e71ce868d4 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -68,11 +68,12 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
+ // We can handle SINT_TO_FP and FP_TO_SINT from/to i64 even though i64
+ // isn't legal.
+ setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom);
+ setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom);
+
if (!X86ScalarSSE) {
- // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64
- // isn't legal.
- setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom);
- setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom);
setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom);
setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom);
}
@@ -526,12 +527,11 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
Chain = RetVal.getValue(1);
InFlag = RetVal.getValue(2);
if (X86ScalarSSE) {
- // FIXME:Currently the FST is flagged to the FP_GET_RESULT. This
- // shouldn't be necessary except for RFP cannot be live across
+ // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This
+ // shouldn't be necessary except that RFP cannot be live across
// multiple blocks. When stackifier is fixed, they can be uncoupled.
- unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
MachineFunction &MF = DAG.getMachineFunction();
- int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
+ int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
Tys.clear();
Tys.push_back(MVT::Other);
@@ -1027,12 +1027,11 @@ X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy,
Chain = RetVal.getValue(1);
InFlag = RetVal.getValue(2);
if (X86ScalarSSE) {
- // FIXME:Currently the FST is flagged to the FP_GET_RESULT. This
- // shouldn't be necessary except for RFP cannot be live across
+ // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This
+ // shouldn't be necessary except that RFP cannot be live across
// multiple blocks. When stackifier is fixed, they can be uncoupled.
- unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
MachineFunction &MF = DAG.getMachineFunction();
- int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
+ int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
Tys.clear();
Tys.push_back(MVT::Other);
@@ -1461,12 +1460,38 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
// Build the FILD
std::vector<MVT::ValueType> Tys;
Tys.push_back(MVT::f64);
+ Tys.push_back(MVT::Other);
Tys.push_back(MVT::Flag);
std::vector<SDOperand> Ops;
Ops.push_back(Chain);
Ops.push_back(StackSlot);
Ops.push_back(DAG.getValueType(SrcVT));
Result = DAG.getNode(X86ISD::FILD, Tys, Ops);
+
+ if (X86ScalarSSE) {
+ assert(Op.getValueType() == MVT::f64 && "Invalid SINT_TO_FP to lower!");
+ Chain = Result.getValue(1);
+ SDOperand InFlag = Result.getValue(2);
+
+ // FIXME: Currently the FST is flagged to the FILD. This
+ // shouldn't be necessary except that RFP cannot be live across
+ // multiple blocks. When stackifier is fixed, they can be uncoupled.
+ MachineFunction &MF = DAG.getMachineFunction();
+ int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
+ SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+ std::vector<MVT::ValueType> Tys;
+ Tys.push_back(MVT::Other);
+ std::vector<SDOperand> Ops;
+ Ops.push_back(Chain);
+ Ops.push_back(Result);
+ Ops.push_back(StackSlot);
+ Ops.push_back(DAG.getValueType(MVT::f64));
+ Ops.push_back(InFlag);
+ Chain = DAG.getNode(X86ISD::FST, Tys, Ops);
+ Result = DAG.getLoad(Op.getValueType(), Chain, StackSlot,
+ DAG.getSrcValue(NULL));
+ }
+
return Result;
}
case ISD::FP_TO_SINT: {
@@ -1488,10 +1513,29 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break;
}
+ SDOperand Chain = DAG.getEntryNode();
+ SDOperand Value = Op.getOperand(0);
+ if (X86ScalarSSE) {
+ assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!");
+ Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Value, StackSlot,
+ DAG.getSrcValue(0));
+ std::vector<MVT::ValueType> Tys;
+ Tys.push_back(MVT::f64);
+ Tys.push_back(MVT::Other);
+ std::vector<SDOperand> Ops;
+ Ops.push_back(Chain);
+ Ops.push_back(StackSlot);
+ Ops.push_back(DAG.getValueType(MVT::f64));
+ Value = DAG.getNode(X86ISD::FLD, Tys, Ops);
+ Chain = Value.getValue(1);
+ SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
+ StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+ }
+
// Build the FP_TO_INT*_IN_MEM
std::vector<SDOperand> Ops;
- Ops.push_back(DAG.getEntryNode());
- Ops.push_back(Op.getOperand(0));
+ Ops.push_back(Chain);
+ Ops.push_back(Value);
Ops.push_back(StackSlot);
SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops);
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index fc601702d5..81ce0911d5 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -44,7 +44,7 @@ namespace llvm {
/// FILD - This instruction implements SINT_TO_FP with the integer source
/// in memory and FP reg result. This corresponds to the X86::FILD*m
/// instructions. It has three inputs (token chain, address, and source
- /// type) and two outputs (FP value and token chain).
+ /// type) and three outputs (FP value, token chain, and a flag).
FILD,
/// FP_TO_INT*_IN_MEM - This instruction implements FP_TO_SINT with the
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index b3941b4fc5..5c620627b2 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -103,7 +103,7 @@ def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld,
def X86fst : SDNode<"X86ISD::FST", SDTX86Fst,
[SDNPHasChain, SDNPInFlag]>;
def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild,
- [SDNPHasChain]>;
+ [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,
@@ -3018,10 +3018,13 @@ def : Pat<(X86fld addr:$src, f64), (FpLD64m addr:$src)>;
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
+// 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<(X86fild addr:$src, i64), (FpILD64m addr:$src)>, Requires<[HasSSE2]>;
+
//===----------------------------------------------------------------------===//
// Some peepholes
//===----------------------------------------------------------------------===//