Warning, file /include/boost/numeric/interval/detail/sparc_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
0013 #ifndef BOOST_NUMERIC_INTERVAL_DETAIL_SPARC_ROUNDING_CONTROL_HPP
0014 #define BOOST_NUMERIC_INTERVAL_DETAIL_SPARC_ROUNDING_CONTROL_HPP
0015
0016 #if !defined(sparc) && !defined(__sparc__)
0017 # error This header is only intended for SPARC CPUs.
0018 #endif
0019
0020 #ifdef __SUNPRO_CC
0021 # include <ieeefp.h>
0022 #endif
0023
0024
0025 namespace boost {
0026 namespace numeric {
0027 namespace interval_lib {
0028 namespace detail {
0029
0030 struct sparc_rounding_control
0031 {
0032 typedef unsigned int rounding_mode;
0033
0034 static void set_rounding_mode(const rounding_mode& mode)
0035 {
0036 # if defined(__GNUC__)
0037 __asm__ __volatile__("ld %0, %%fsr" : : "m"(mode));
0038 # elif defined (__SUNPRO_CC)
0039 fpsetround(fp_rnd(mode));
0040 # elif defined(__KCC)
0041 asm("sethi %hi(mode), %o1");
0042 asm("ld [%o1+%lo(mode)], %fsr");
0043 # else
0044 # error Unsupported compiler for Sparc rounding control.
0045 # endif
0046 }
0047
0048 static void get_rounding_mode(rounding_mode& mode)
0049 {
0050 # if defined(__GNUC__)
0051 __asm__ __volatile__("st %%fsr, %0" : "=m"(mode));
0052 # elif defined (__SUNPRO_CC)
0053 mode = fpgetround();
0054 # elif defined(__KCC)
0055 # error KCC on Sun SPARC get_round_mode: please fix me
0056 asm("st %fsr, [mode]");
0057 # else
0058 # error Unsupported compiler for Sparc rounding control.
0059 # endif
0060 }
0061
0062 #if defined(__SUNPRO_CC)
0063 static void downward() { set_rounding_mode(FP_RM); }
0064 static void upward() { set_rounding_mode(FP_RP); }
0065 static void to_nearest() { set_rounding_mode(FP_RN); }
0066 static void toward_zero() { set_rounding_mode(FP_RZ); }
0067 #else
0068 static void downward() { set_rounding_mode(0xc0000000); }
0069 static void upward() { set_rounding_mode(0x80000000); }
0070 static void to_nearest() { set_rounding_mode(0x00000000); }
0071 static void toward_zero() { set_rounding_mode(0x40000000); }
0072 #endif
0073 };
0074
0075 }
0076
0077 extern "C" {
0078 float rintf(float);
0079 double rint(double);
0080 }
0081
0082 template<>
0083 struct rounding_control<float>:
0084 detail::sparc_rounding_control
0085 {
0086 static const float& force_rounding(const float& x) { return x; }
0087 static float to_int(const float& x) { return rintf(x); }
0088 };
0089
0090 template<>
0091 struct rounding_control<double>:
0092 detail::sparc_rounding_control
0093 {
0094 static const double& force_rounding(const double& x) { return x; }
0095 static double to_int(const double& x) { return rint(x); }
0096 };
0097
0098 template<>
0099 struct rounding_control<long double>:
0100 detail::sparc_rounding_control
0101 {
0102 static const long double& force_rounding(const long double& x) { return x; }
0103 static long double to_int(const long double& x) { return rint(x); }
0104 };
0105
0106 }
0107 }
0108 }
0109
0110 #undef BOOST_NUMERIC_INTERVAL_NO_HARDWARE
0111
0112 #endif