Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/numeric/interval/detail/ppc_rounding_control.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /* Boost interval/detail/ppc_rounding_control.hpp file | |
2 * | |
3 * Copyright 2000 Jens Maurer | |
4 * Copyright 2002 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion | |
5 * Copyright 2005 Guillaume Melquiond | |
6 * | |
7 * Distributed under the Boost Software License, Version 1.0. | |
8 * (See accompanying file LICENSE_1_0.txt or | |
9 * copy at http://www.boost.org/LICENSE_1_0.txt) | |
10 */ | |
11 | |
12 #ifndef BOOST_NUMERIC_INTERVAL_DETAIL_PPC_ROUNDING_CONTROL_HPP | |
13 #define BOOST_NUMERIC_INTERVAL_DETAIL_PPC_ROUNDING_CONTROL_HPP | |
14 | |
15 #if !defined(powerpc) && !defined(__powerpc__) && !defined(__ppc__) | |
16 #error This header only works on PPC CPUs. | |
17 #endif | |
18 | |
19 #if defined(__GNUC__ ) || (__IBMCPP__ >= 700) | |
20 | |
21 namespace boost { | |
22 namespace numeric { | |
23 namespace interval_lib { | |
24 namespace detail { | |
25 | |
26 typedef union { | |
27 ::boost::long_long_type imode; | |
28 double dmode; | |
29 } rounding_mode_struct; | |
30 | |
31 static const rounding_mode_struct mode_upward = { 0xFFF8000000000002LL }; | |
32 static const rounding_mode_struct mode_downward = { 0xFFF8000000000003LL }; | |
33 static const rounding_mode_struct mode_to_nearest = { 0xFFF8000000000000LL }; | |
34 static const rounding_mode_struct mode_toward_zero = { 0xFFF8000000000001LL }; | |
35 | |
36 struct ppc_rounding_control | |
37 { | |
38 typedef double rounding_mode; | |
39 | |
40 static void set_rounding_mode(const rounding_mode mode) | |
41 { __asm__ __volatile__ ("mtfsf 255,%0" : : "f"(mode)); } | |
42 | |
43 static void get_rounding_mode(rounding_mode& mode) | |
44 { __asm__ __volatile__ ("mffs %0" : "=f"(mode)); } | |
45 | |
46 static void downward() { set_rounding_mode(mode_downward.dmode); } | |
47 static void upward() { set_rounding_mode(mode_upward.dmode); } | |
48 static void to_nearest() { set_rounding_mode(mode_to_nearest.dmode); } | |
49 static void toward_zero() { set_rounding_mode(mode_toward_zero.dmode); } | |
50 }; | |
51 | |
52 } // namespace detail | |
53 | |
54 // Do not declare the following C99 symbols if <math.h> provides them. | |
55 // Otherwise, conflicts may occur, due to differences between prototypes. | |
56 #if !defined(_ISOC99_SOURCE) && !defined(__USE_ISOC99) | |
57 extern "C" { | |
58 float rintf(float); | |
59 double rint(double); | |
60 } | |
61 #endif | |
62 | |
63 template<> | |
64 struct rounding_control<float>: | |
65 detail::ppc_rounding_control | |
66 { | |
67 static float force_rounding(const float r) | |
68 { | |
69 float tmp; | |
70 __asm__ __volatile__ ("frsp %0, %1" : "=f" (tmp) : "f" (r)); | |
71 return tmp; | |
72 } | |
73 static float to_int(const float& x) { return rintf(x); } | |
74 }; | |
75 | |
76 template<> | |
77 struct rounding_control<double>: | |
78 detail::ppc_rounding_control | |
79 { | |
80 static const double & force_rounding(const double& r) { return r; } | |
81 static double to_int(const double& r) { return rint(r); } | |
82 }; | |
83 | |
84 template<> | |
85 struct rounding_control<long double>: | |
86 detail::ppc_rounding_control | |
87 { | |
88 static const long double & force_rounding(const long double& r) { return r; } | |
89 static long double to_int(const long double& r) { return rint(r); } | |
90 }; | |
91 | |
92 } // namespace interval_lib | |
93 } // namespace numeric | |
94 } // namespace boost | |
95 | |
96 #undef BOOST_NUMERIC_INTERVAL_NO_HARDWARE | |
97 #endif | |
98 | |
99 #endif /* BOOST_NUMERIC_INTERVAL_DETAIL_PPC_ROUNDING_CONTROL_HPP */ |