summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-05-14 06:52:07 +0000
committerChris Lattner <sabre@nondot.org>2005-05-14 06:52:07 +0000
commit67649dfc324e25755c2a2e0315062fd49c659b6f (patch)
treed0bc6d9f2a18982f8bd67d577d7693e41d7b64fb /lib
parent5fa4fa4e0fde8aebc55a05258d2a274f3c7e1df6 (diff)
downloadllvm-67649dfc324e25755c2a2e0315062fd49c659b6f.tar.gz
llvm-67649dfc324e25755c2a2e0315062fd49c659b6f.tar.bz2
llvm-67649dfc324e25755c2a2e0315062fd49c659b6f.tar.xz
use a target-specific node and custom expander to lower long->FP to FILD64m.
This should fix some missing symbols problems on BSD and improve performance of programs that use that operation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22012 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/X86ISelPattern.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp
index 3281cc25cd..efdb24419a 100644
--- a/lib/Target/X86/X86ISelPattern.cpp
+++ b/lib/Target/X86/X86ISelPattern.cpp
@@ -39,6 +39,22 @@ using namespace llvm;
static cl::opt<bool> EnableFastCC("enable-x86-fastcc", cl::Hidden,
cl::desc("Enable fastcc on X86"));
+namespace {
+ // X86 Specific DAG Nodes
+ namespace X86ISD {
+ enum NodeType {
+ // Start the numbering where the builtin ops leave off.
+ FIRST_NUMBER = ISD::BUILTIN_OP_END,
+
+ /// FILD64m - This instruction implements SINT_TO_FP with a
+ /// 64-bit source in memory and a FP reg result. This corresponds to
+ /// the X86::FILD64m instruction. It has two inputs (token chain and
+ /// address) and two outputs (FP value and token chain).
+ FILD64m,
+ };
+ }
+}
+
//===----------------------------------------------------------------------===//
// X86TargetLowering - X86 Implementation of the TargetLowering interface
namespace {
@@ -66,6 +82,7 @@ namespace {
// well.
/**/ addRegisterClass(MVT::i1, X86::R8RegisterClass);
+ setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom);
setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand);
setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand);
@@ -114,6 +131,10 @@ namespace {
//
unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; }
+ /// LowerOperation - Provide custom lowering hooks for some operations.
+ ///
+ virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+
/// LowerArguments - This hook must be implemented to indicate how we should
/// lower the arguments for the specified function, into the specified DAG.
virtual std::vector<SDOperand>
@@ -735,6 +756,36 @@ LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
return std::make_pair(Result, Chain);
}
+/// LowerOperation - Provide custom lowering hooks for some operations.
+///
+SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
+ switch (Op.getOpcode()) {
+ default: assert(0 && "Should not custom lower this!");
+ case ISD::SINT_TO_FP:
+ assert(Op.getValueType() == MVT::f64 &&
+ Op.getOperand(0).getValueType() == MVT::i64 &&
+ "Unknown SINT_TO_FP to lower!");
+ // We lower sint64->FP into a store to a temporary stack slot, followed by a
+ // FILD64m node.
+ MachineFunction &MF = DAG.getMachineFunction();
+ int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
+ SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+ SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+ Op.getOperand(0), StackSlot, DAG.getSrcValue(NULL));
+ std::vector<MVT::ValueType> RTs;
+ RTs.push_back(MVT::f64);
+ RTs.push_back(MVT::Other);
+ std::vector<SDOperand> Ops;
+ Ops.push_back(Store);
+ Ops.push_back(StackSlot);
+ return DAG.getNode(X86ISD::FILD64m, RTs, Ops);
+ }
+}
+
+
+//===----------------------------------------------------------------------===//
+// Pattern Matcher Implementation
+//===----------------------------------------------------------------------===//
namespace {
/// X86ISelAddressMode - This corresponds to X86AddressMode, but uses
@@ -2945,6 +2996,28 @@ unsigned ISel::SelectExpr(SDOperand N) {
addFullAddress(BuildMI(BB, Opc, 4, Result), AM);
}
return Result;
+ case X86ISD::FILD64m:
+ // Make sure we generate both values.
+ assert(Result != 1 && N.getValueType() == MVT::f64);
+ if (!ExprMap.insert(std::make_pair(N.getValue(1), 1)).second)
+ assert(0 && "Load already emitted!?");
+
+ {
+ X86AddressMode AM;
+
+ SDOperand Chain = N.getOperand(0);
+ SDOperand Address = N.getOperand(1);
+ if (getRegPressure(Chain) > getRegPressure(Address)) {
+ Select(Chain);
+ SelectAddress(Address, AM);
+ } else {
+ SelectAddress(Address, AM);
+ Select(Chain);
+ }
+
+ addFullAddress(BuildMI(BB, X86::FILD64m, 4, Result), AM);
+ }
+ return Result;
case ISD::EXTLOAD: // Arbitrarily codegen extloads as MOVZX*
case ISD::ZEXTLOAD: {
@@ -3619,6 +3692,7 @@ void ISel::Select(SDOperand N) {
SelectExpr(N);
return;
case ISD::CopyFromReg:
+ case X86ISD::FILD64m:
ExprMap.erase(N);
SelectExpr(N.getValue(0));
return;