Back to home page

EIC code displayed by LXR

 
 

    


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 /* Boost interval/detail/ppc_rounding_control.hpp file
0002  *
0003  * Copyright 2000 Jens Maurer
0004  * Copyright 2002 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
0005  * Copyright 2005 Guillaume Melquiond
0006  *
0007  * Distributed under the Boost Software License, Version 1.0.
0008  * (See accompanying file LICENSE_1_0.txt or
0009  * copy at http://www.boost.org/LICENSE_1_0.txt)
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 } // namespace detail
0053 
0054 // Do not declare the following C99 symbols if <math.h> provides them.
0055 // Otherwise, conflicts may occur, due to differences between prototypes.
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 } // namespace interval_lib
0093 } // namespace numeric
0094 } // namespace boost
0095 
0096 #undef BOOST_NUMERIC_INTERVAL_NO_HARDWARE
0097 #endif
0098 
0099 #endif /* BOOST_NUMERIC_INTERVAL_DETAIL_PPC_ROUNDING_CONTROL_HPP */