source: NonGTP/Boost/boost/numeric/interval/detail/x86_rounding_control.hpp @ 857

Revision 857, 3.1 KB checked in by igarcia, 19 years ago (diff)
Line 
1/* Boost interval/detail/x86_rounding_control.hpp file
2 *
3 * Copyright 2000 Jens Maurer
4 * Copyright 2002 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
5 *
6 * Distributed under the Boost Software License, Version 1.0.
7 * (See accompanying file LICENSE_1_0.txt or
8 * copy at http://www.boost.org/LICENSE_1_0.txt)
9 */
10
11#ifndef BOOST_NUMERIC_INTERVAL_DETAIL_X86_ROUNDING_CONTROL_HPP
12#define BOOST_NUMERIC_INTERVAL_DETAIL_X86_ROUNDING_CONTROL_HPP
13
14#ifdef __GNUC__
15#  include <boost/numeric/interval/detail/x86gcc_rounding_control.hpp>
16#elif defined(__BORLANDC__)
17#  include <boost/numeric/interval/detail/bcc_rounding_control.hpp>
18#elif defined(_MSC_VER)
19#  include <boost/numeric/interval/detail/msvc_rounding_control.hpp>
20#elif defined(__MWERKS__) || defined(__ICC)
21#  define BOOST_NUMERIC_INTERVAL_USE_C99_SUBSYSTEM
22#  include <boost/numeric/interval/detail/c99sub_rounding_control.hpp>
23#else
24#  error Unsupported C++ compiler.
25#endif
26
27namespace boost {
28namespace numeric {
29namespace interval_lib {
30
31namespace detail {
32
33#ifdef BOOST_NUMERIC_INTERVAL_USE_C99_SUBSYSTEM
34typedef c99_rounding x86_rounding_control;
35#undef BOOST_NUMERIC_INTERVAL_USE_C99_SUBSYSTEM
36#else
37struct fpu_rounding_modes
38{
39  unsigned short to_nearest;
40  unsigned short downward;
41  unsigned short upward;
42  unsigned short toward_zero;
43};
44
45// exceptions masked, extended precision
46// hardware default is 0x037f (0x1000 only has a meaning on 287)
47static const fpu_rounding_modes rnd_mode = { 0x137f, 0x177f, 0x1b7f, 0x1f7f };
48
49struct x86_rounding_control: x86_rounding
50{
51  static void to_nearest()  { set_rounding_mode(rnd_mode.to_nearest);  }
52  static void downward()    { set_rounding_mode(rnd_mode.downward);    }
53  static void upward()      { set_rounding_mode(rnd_mode.upward);      }
54  static void toward_zero() { set_rounding_mode(rnd_mode.toward_zero); }
55};
56#endif // BOOST_NUMERIC_INTERVAL_USE_C99_SUBSYSTEM
57
58} // namespace detail
59
60template<>
61struct rounding_control<float>: detail::x86_rounding_control
62{
63  static float force_rounding(const float& r)
64  { volatile float r_ = r; return r_; }
65};
66
67template<>
68struct rounding_control<double>: detail::x86_rounding_control
69{
70  /*static double force_rounding(double r)
71  { asm volatile ("" : "+m"(r) : ); return r; }*/
72  static double force_rounding(const double& r)
73  { volatile double r_ = r; return r_; }
74};
75
76namespace detail {
77
78template<bool>
79struct x86_rounding_control_long_double;
80
81template<>
82struct x86_rounding_control_long_double<false>: x86_rounding_control
83{
84  static long double force_rounding(long double const &r)
85  { volatile long double r_ = r; return r_; }
86};
87
88template<>
89struct x86_rounding_control_long_double<true>: x86_rounding_control
90{
91  static long double const &force_rounding(long double const &r)
92  { return r; }
93};
94
95} // namespace detail
96
97template<>
98struct rounding_control<long double>:
99  detail::x86_rounding_control_long_double< (sizeof(long double) >= 10) >
100{};
101
102} // namespace interval_lib
103} // namespace numeric
104} // namespace boost
105
106#undef BOOST_NUMERIC_INTERVAL_NO_HARDWARE
107
108#endif /* BOOST_NUMERIC_INTERVAL_DETAIL_X86_ROUNDING_CONTROL_HPP */
Note: See TracBrowser for help on using the repository browser.