diff options
author | Evan Cheng <evan.cheng@apple.com> | 2006-01-30 08:02:57 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2006-01-30 08:02:57 +0000 |
commit | 6dab05363f94b279a3877fd79d68649b865e10d9 (patch) | |
tree | 18d03955fc4da9589b25889f03a912b9702640c6 | |
parent | 19f3416d1cc7d21701bc7e0a21a854166dcbfe2c (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.cpp | 72 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 2 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 7 |
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 //===----------------------------------------------------------------------===// |