Warning, file /include/boost/numeric/interval/detail/ppc_rounding_control.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_NUMERIC_INTERVAL_DETAIL_PPC_ROUNDING_CONTROL_HPP
0013 #define BOOST_NUMERIC_INTERVAL_DETAIL_PPC_ROUNDING_CONTROL_HPP
0014
0015 #if !defined(powerpc) && !defined(__powerpc__) && !defined(__ppc__)
0016 #error This header only works on PPC CPUs.
0017 #endif
0018
0019 #if defined(__GNUC__ ) || (__IBMCPP__ >= 700)
0020
0021 namespace boost {
0022 namespace numeric {
0023 namespace interval_lib {
0024 namespace detail {
0025
0026 typedef union {
0027 ::boost::long_long_type imode;
0028 double dmode;
0029 } rounding_mode_struct;
0030
0031 static const rounding_mode_struct mode_upward = { 0xFFF8000000000002LL };
0032 static const rounding_mode_struct mode_downward = { 0xFFF8000000000003LL };
0033 static const rounding_mode_struct mode_to_nearest = { 0xFFF8000000000000LL };
0034 static const rounding_mode_struct mode_toward_zero = { 0xFFF8000000000001LL };
0035
0036 struct ppc_rounding_control
0037 {
0038 typedef double rounding_mode;
0039
0040 static void set_rounding_mode(const rounding_mode mode)
0041 { __asm__ __volatile__ ("mtfsf 255,%0" : : "f"(mode)); }
0042
0043 static void get_rounding_mode(rounding_mode& mode)
0044 { __asm__ __volatile__ ("mffs %0" : "=f"(mode)); }
0045
0046 static void downward() { set_rounding_mode(mode_downward.dmode); }
0047 static void upward() { set_rounding_mode(mode_upward.dmode); }
0048 static void to_nearest() { set_rounding_mode(mode_to_nearest.dmode); }
0049 static void toward_zero() { set_rounding_mode(mode_toward_zero.dmode); }
0050 };
0051
0052 }
0053
0054
0055
0056 #if !defined(_ISOC99_SOURCE) && !defined(__USE_ISOC99)
0057 extern "C" {
0058 float rintf(float);
0059 double rint(double);
0060 }
0061 #endif
0062
0063 template<>
0064 struct rounding_control<float>:
0065 detail::ppc_rounding_control
0066 {
0067 static float force_rounding(const float r)
0068 {
0069 float tmp;
0070 __asm__ __volatile__ ("frsp %0, %1" : "=f" (tmp) : "f" (r));
0071 return tmp;
0072 }
0073 static float to_int(const float& x) { return rintf(x); }
0074 };
0075
0076 template<>
0077 struct rounding_control<double>:
0078 detail::ppc_rounding_control
0079 {
0080 static const double & force_rounding(const double& r) { return r; }
0081 static double to_int(const double& r) { return rint(r); }
0082 };
0083
0084 template<>
0085 struct rounding_control<long double>:
0086 detail::ppc_rounding_control
0087 {
0088 static const long double & force_rounding(const long double& r) { return r; }
0089 static long double to_int(const long double& r) { return rint(r); }
0090 };
0091
0092 }
0093 }
0094 }
0095
0096 #undef BOOST_NUMERIC_INTERVAL_NO_HARDWARE
0097 #endif
0098
0099 #endif