Changes in directory llvm/lib/Target/X86:
X86ISelLowering.cpp updated: 1.66 -> 1.67 X86ISelLowering.h updated: 1.20 -> 1.21 X86InstrInfo.td updated: 1.222 -> 1.223 --- Log message: 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. --- Diffs of the changes: (+64 -17) X86ISelLowering.cpp | 72 +++++++++++++++++++++++++++++++++++++++++----------- X86ISelLowering.h | 2 - X86InstrInfo.td | 7 +++-- 3 files changed, 64 insertions(+), 17 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.66 llvm/lib/Target/X86/X86ISelLowering.cpp:1.67 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.66 Sun Jan 29 22:09:04 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Jan 30 02:02:57 2006 @@ -68,11 +68,12 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.20 llvm/lib/Target/X86/X86ISelLowering.h:1.21 --- llvm/lib/Target/X86/X86ISelLowering.h:1.20 Sun Jan 29 22:09:04 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Jan 30 02:02:57 2006 @@ -44,7 +44,7 @@ /// 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 Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.222 llvm/lib/Target/X86/X86InstrInfo.td:1.223 --- llvm/lib/Target/X86/X86InstrInfo.td:1.222 Sun Jan 29 00:44:22 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Jan 30 02:02:57 2006 @@ -103,7 +103,7 @@ 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<(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 //===----------------------------------------------------------------------===// _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits