[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td
Evan Cheng
evan.cheng at apple.com
Mon Jan 30 00:03:10 PST 2006
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
//===----------------------------------------------------------------------===//
More information about the llvm-commits
mailing list