[llvm-commits] [llvm] r44183 - in /llvm/trunk/lib/Target/X86: X86ISelLowering.cpp X86ISelLowering.h X86InstrFPStack.td
Anton Korobeynikov
asl at math.spbu.ru
Thu Nov 15 17:31:52 PST 2007
Author: asl
Date: Thu Nov 15 19:31:51 2007
New Revision: 44183
URL: http://llvm.org/viewvc/llvm-project?rev=44183&view=rev
Log:
Implement codegen for flt_rounds on x86
Modified:
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.h
llvm/trunk/lib/Target/X86/X86InstrFPStack.td
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=44183&r1=44182&r2=44183&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Nov 15 19:31:51 2007
@@ -205,7 +205,8 @@
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand);
setOperationAction(ISD::FREM , MVT::f64 , Expand);
-
+ setOperationAction(ISD::FLT_ROUNDS , MVT::i32 , Custom);
+
setOperationAction(ISD::CTPOP , MVT::i8 , Expand);
setOperationAction(ISD::CTTZ , MVT::i8 , Expand);
setOperationAction(ISD::CTLZ , MVT::i8 , Expand);
@@ -4940,6 +4941,66 @@
}
}
+SDOperand X86TargetLowering::LowerFLT_ROUNDS(SDOperand Op, SelectionDAG &DAG) {
+ /*
+ The rounding mode is in bits 11:10 of FPSR, and has the following
+ settings:
+ 00 Round to nearest
+ 01 Round to -inf
+ 10 Round to +inf
+ 11 Round to 0
+
+ FLT_ROUNDS, on the other hand, expects the following:
+ -1 Undefined
+ 0 Round to 0
+ 1 Round to nearest
+ 2 Round to +inf
+ 3 Round to -inf
+
+ To perform the conversion, we do:
+ (((((FPSR & 0x800) >> 11) | ((FPSR & 0x400) >> 9)) + 1) & 3)
+ */
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ const TargetMachine &TM = MF.getTarget();
+ const TargetFrameInfo &TFI = *TM.getFrameInfo();
+ unsigned StackAlignment = TFI.getStackAlignment();
+ MVT::ValueType VT = Op.getValueType();
+
+ // Save FP Control Word to stack slot
+ int SSFI = MF.getFrameInfo()->CreateStackObject(2, StackAlignment);
+ SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+
+ SDOperand Chain = DAG.getNode(X86ISD::FNSTCW16m, MVT::Other,
+ DAG.getEntryNode(), StackSlot);
+
+ // Load FP Control Word from stack slot
+ SDOperand CWD = DAG.getLoad(MVT::i16, Chain, StackSlot, NULL, 0);
+
+ // Transform as necessary
+ SDOperand CWD1 =
+ DAG.getNode(ISD::SRL, MVT::i16,
+ DAG.getNode(ISD::AND, MVT::i16,
+ CWD, DAG.getConstant(0x800, MVT::i16)),
+ DAG.getConstant(11, MVT::i8));
+ SDOperand CWD2 =
+ DAG.getNode(ISD::SRL, MVT::i16,
+ DAG.getNode(ISD::AND, MVT::i16,
+ CWD, DAG.getConstant(0x400, MVT::i16)),
+ DAG.getConstant(9, MVT::i8));
+
+ SDOperand RetVal =
+ DAG.getNode(ISD::AND, MVT::i16,
+ DAG.getNode(ISD::ADD, MVT::i16,
+ DAG.getNode(ISD::OR, MVT::i16, CWD1, CWD2),
+ DAG.getConstant(1, MVT::i16)),
+ DAG.getConstant(3, MVT::i16));
+
+
+ return DAG.getNode((MVT::getSizeInBits(VT) < 16 ?
+ ISD::TRUNCATE : ISD::ZERO_EXTEND), VT, RetVal);
+}
+
/// LowerOperation - Provide custom lowering hooks for some operations.
///
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
@@ -4982,6 +5043,7 @@
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
case ISD::TRAMPOLINE: return LowerTRAMPOLINE(Op, DAG);
+ case ISD::FLT_ROUNDS: return LowerFLT_ROUNDS(Op, DAG);
}
return SDOperand();
}
@@ -5029,6 +5091,7 @@
case X86ISD::THREAD_POINTER: return "X86ISD::THREAD_POINTER";
case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN";
case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN";
+ case X86ISD::FNSTCW16m: return "X86ISD::FNSTCW16m";
}
}
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=44183&r1=44182&r2=44183&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Thu Nov 15 19:31:51 2007
@@ -188,7 +188,10 @@
// operand #1 callee (register or absolute)
// operand #2 stack adjustment
// operand #3 optional in flag
- TC_RETURN
+ TC_RETURN,
+
+ // Store FP control world into i16 memory
+ FNSTCW16m
};
}
@@ -477,6 +480,7 @@
SDOperand LowerFRAME_TO_ARGS_OFFSET(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerTRAMPOLINE(SDOperand Op, SelectionDAG &DAG);
+ SDOperand LowerFLT_ROUNDS(SDOperand Op, SelectionDAG &DAG);
};
}
Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=44183&r1=44182&r2=44183&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Thu Nov 15 19:31:51 2007
@@ -29,6 +29,8 @@
SDTCisVT<2, OtherVT>]>;
def SDTX86FpToIMem : SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisPtrTy<1>]>;
+def SDTX86CwdStore : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
+
def X86fpget : SDNode<"X86ISD::FP_GET_RESULT", SDTX86FpGet,
[SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
def X86fpset : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet,
@@ -47,6 +49,8 @@
[SDNPHasChain]>;
def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
[SDNPHasChain]>;
+def X86fp_cwd_get16 : SDNode<"X86ISD::FNSTCW16m", SDTX86CwdStore,
+ [SDNPHasChain]>;
//===----------------------------------------------------------------------===//
// FPStack pattern fragments
@@ -524,7 +528,8 @@
(outs), (ins), "fnstsw", []>, DF;
def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world
- (outs), (ins i16mem:$dst), "fnstcw\t$dst", []>;
+ (outs), (ins i16mem:$dst), "fnstcw\t$dst",
+ [(X86fp_cwd_get16 addr:$dst)]>;
def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
(outs), (ins i16mem:$dst), "fldcw\t$dst", []>;
More information about the llvm-commits
mailing list