]>
Commit | Line | Data |
---|---|---|
6c9b0f68 | 1 | /* Determine floating-point rounding mode within libc. Generic version. |
688903eb | 2 | Copyright (C) 2012-2018 Free Software Foundation, Inc. |
6c9b0f68 JM |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, see | |
17 | <http://www.gnu.org/licenses/>. */ | |
18 | ||
19 | #ifndef _GET_ROUNDING_MODE_H | |
20 | #define _GET_ROUNDING_MODE_H 1 | |
21 | ||
22 | #include <fpu_control.h> | |
aba8ef95 | 23 | #include <stdlib.h> |
6c9b0f68 JM |
24 | |
25 | /* Define values for FE_* modes not defined for this architecture. */ | |
26 | #ifdef FE_DOWNWARD | |
27 | # define ORIG_FE_DOWNWARD FE_DOWNWARD | |
28 | #else | |
29 | # define ORIG_FE_DOWNWARD 0 | |
30 | #endif | |
31 | #ifdef FE_TONEAREST | |
32 | # define ORIG_FE_TONEAREST FE_TONEAREST | |
33 | #else | |
34 | # define ORIG_FE_TONEAREST 0 | |
35 | #endif | |
36 | #ifdef FE_TOWARDZERO | |
37 | # define ORIG_FE_TOWARDZERO FE_TOWARDZERO | |
38 | #else | |
39 | # define ORIG_FE_TOWARDZERO 0 | |
40 | #endif | |
41 | #ifdef FE_UPWARD | |
42 | # define ORIG_FE_UPWARD FE_UPWARD | |
43 | #else | |
44 | # define ORIG_FE_UPWARD 0 | |
45 | #endif | |
46 | #define FE_CONSTRUCT_DISTINCT_VALUE(X, Y, Z) \ | |
47 | ((((X) & 1) | ((Y) & 2) | ((Z) & 4)) ^ 7) | |
48 | #ifndef FE_DOWNWARD | |
49 | # define FE_DOWNWARD FE_CONSTRUCT_DISTINCT_VALUE (ORIG_FE_TONEAREST, \ | |
50 | ORIG_FE_TOWARDZERO, \ | |
51 | ORIG_FE_UPWARD) | |
52 | #endif | |
53 | #ifndef FE_TONEAREST | |
54 | # define FE_TONEAREST FE_CONSTRUCT_DISTINCT_VALUE (FE_DOWNWARD, \ | |
55 | ORIG_FE_TOWARDZERO, \ | |
56 | ORIG_FE_UPWARD) | |
57 | #endif | |
58 | #ifndef FE_TOWARDZERO | |
59 | # define FE_TOWARDZERO FE_CONSTRUCT_DISTINCT_VALUE (FE_DOWNWARD, \ | |
60 | FE_TONEAREST, \ | |
61 | ORIG_FE_UPWARD) | |
62 | #endif | |
63 | #ifndef FE_UPWARD | |
64 | # define FE_UPWARD FE_CONSTRUCT_DISTINCT_VALUE (FE_DOWNWARD, \ | |
65 | FE_TONEAREST, \ | |
66 | FE_TOWARDZERO) | |
67 | #endif | |
68 | ||
69 | /* Return the floating-point rounding mode. */ | |
70 | ||
71 | static inline int | |
72 | get_rounding_mode (void) | |
73 | { | |
74 | #if (defined _FPU_RC_DOWN \ | |
75 | || defined _FPU_RC_NEAREST \ | |
76 | || defined _FPU_RC_ZERO \ | |
77 | || defined _FPU_RC_UP) | |
78 | fpu_control_t fc; | |
79 | const fpu_control_t mask = (0 | |
80 | # ifdef _FPU_RC_DOWN | |
81 | | _FPU_RC_DOWN | |
82 | # endif | |
83 | # ifdef _FPU_RC_NEAREST | |
84 | | _FPU_RC_NEAREST | |
85 | # endif | |
86 | # ifdef _FPU_RC_ZERO | |
87 | | _FPU_RC_ZERO | |
88 | # endif | |
89 | # ifdef _FPU_RC_UP | |
90 | | _FPU_RC_UP | |
91 | # endif | |
92 | ); | |
93 | ||
94 | _FPU_GETCW (fc); | |
95 | switch (fc & mask) | |
96 | { | |
97 | # ifdef _FPU_RC_DOWN | |
98 | case _FPU_RC_DOWN: | |
99 | return FE_DOWNWARD; | |
100 | # endif | |
101 | ||
102 | # ifdef _FPU_RC_NEAREST | |
103 | case _FPU_RC_NEAREST: | |
104 | return FE_TONEAREST; | |
105 | # endif | |
106 | ||
107 | # ifdef _FPU_RC_ZERO | |
108 | case _FPU_RC_ZERO: | |
109 | return FE_TOWARDZERO; | |
110 | # endif | |
111 | ||
112 | # ifdef _FPU_RC_UP | |
113 | case _FPU_RC_UP: | |
114 | return FE_UPWARD; | |
115 | # endif | |
116 | ||
117 | default: | |
118 | abort (); | |
119 | } | |
120 | #else | |
121 | return FE_TONEAREST; | |
122 | #endif | |
123 | } | |
124 | ||
125 | #endif /* get-rounding-mode.h */ |