]>
Commit | Line | Data |
---|---|---|
ec94343f | 1 | /* Test femode_t functions. |
2b778ceb | 2 | Copyright (C) 2016-2021 Free Software Foundation, Inc. |
ec94343f 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 | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
ec94343f JM |
18 | |
19 | #include <fenv.h> | |
20 | #include <stdio.h> | |
21 | #include <math-tests.h> | |
22 | ||
23 | static int | |
24 | test_mmee (int mode1, int mode2, int exc1, int exc2) | |
25 | { | |
26 | int result = 0; | |
27 | printf ("testing %x %x %x %x\n", (unsigned int) mode1, (unsigned int) mode2, | |
28 | (unsigned int) exc1, (unsigned int) exc2); | |
29 | ||
30 | feclearexcept (FE_ALL_EXCEPT); | |
31 | int ret = fesetround (mode1); | |
32 | if (ret != 0) | |
33 | { | |
34 | if (ROUNDING_TESTS (float, mode1)) | |
35 | { | |
36 | puts ("first fesetround failed unexpectedly"); | |
37 | result = 1; | |
38 | } | |
39 | else | |
40 | puts ("first fesetround failed, cannot test"); | |
41 | return result; | |
42 | } | |
43 | ret = fesetexcept (exc1); | |
44 | if (ret != 0) | |
45 | { | |
46 | if (EXCEPTION_TESTS (float) || exc1 == 0) | |
47 | { | |
48 | puts ("first fesetexcept failed unexpectedly"); | |
49 | result = 1; | |
50 | } | |
51 | else | |
52 | puts ("first fesetexcept failed, cannot test"); | |
53 | return result; | |
54 | } | |
55 | femode_t saved; | |
56 | ret = fegetmode (&saved); | |
57 | if (ret != 0) | |
58 | { | |
59 | puts ("fegetmode failed"); | |
60 | result = 1; | |
61 | return result; | |
62 | } | |
63 | feclearexcept (FE_ALL_EXCEPT); | |
64 | ret = fesetround (mode2); | |
65 | if (ret != 0) | |
66 | { | |
67 | if (ROUNDING_TESTS (float, mode2)) | |
68 | { | |
69 | puts ("second fesetround failed unexpectedly"); | |
70 | result = 1; | |
71 | } | |
72 | else | |
73 | puts ("second fesetround failed, cannot test"); | |
74 | return result; | |
75 | } | |
76 | ret = fesetexcept (exc2); | |
77 | if (ret != 0) | |
78 | { | |
79 | if (EXCEPTION_TESTS (float) || exc2 == 0) | |
80 | { | |
81 | puts ("second fesetexcept failed unexpectedly"); | |
82 | result = 1; | |
83 | } | |
84 | else | |
85 | puts ("second fesetexcept failed, cannot test"); | |
86 | return result; | |
87 | } | |
88 | ret = fesetmode (&saved); | |
89 | if (ret != 0) | |
90 | { | |
91 | puts ("fesetmode failed"); | |
92 | result = 1; | |
93 | return result; | |
94 | } | |
95 | /* Verify that the rounding mode was restored but the exception | |
96 | flags remain unchanged. */ | |
97 | ret = fegetround (); | |
98 | if (ret != mode1) | |
99 | { | |
100 | printf ("restored rounding mode %x not %x\n", (unsigned int) ret, | |
101 | (unsigned int) mode1); | |
102 | result = 1; | |
103 | } | |
104 | ret = fetestexcept (FE_ALL_EXCEPT); | |
105 | if (ret != exc2) | |
106 | { | |
107 | printf ("exceptions %x not %x\n", (unsigned int) ret, | |
108 | (unsigned int) exc2); | |
109 | result = 1; | |
110 | } | |
111 | /* Likewise, with default modes. */ | |
112 | ret = fesetmode (FE_DFL_MODE); | |
113 | if (ret != 0) | |
114 | { | |
115 | puts ("fesetmode (FE_DFL_MODE) failed"); | |
116 | result = 1; | |
117 | return result; | |
118 | } | |
119 | ret = fegetround (); | |
120 | if (ret != FE_TONEAREST) | |
121 | { | |
122 | printf ("FE_DFL_MODE rounding mode %x not %x\n", (unsigned int) ret, | |
123 | (unsigned int) FE_TONEAREST); | |
124 | result = 1; | |
125 | } | |
126 | ret = fetestexcept (FE_ALL_EXCEPT); | |
127 | if (ret != exc2) | |
128 | { | |
129 | printf ("FE_DFL_MODE exceptions %x not %x\n", (unsigned int) ret, | |
130 | (unsigned int) exc2); | |
131 | result = 1; | |
132 | } | |
133 | return result; | |
134 | } | |
135 | ||
136 | static int | |
137 | test_mme (int mode1, int mode2, int exc1) | |
138 | { | |
139 | int result = 0; | |
140 | ||
141 | result |= test_mmee (mode1, mode2, exc1, 0); | |
142 | result |= test_mmee (mode1, mode2, exc1, FE_ALL_EXCEPT); | |
143 | #ifdef FE_DIVBYZERO | |
144 | result |= test_mmee (mode1, mode2, exc1, FE_DIVBYZERO); | |
145 | #endif | |
146 | #ifdef FE_INEXACT | |
147 | result |= test_mmee (mode1, mode2, exc1, FE_INEXACT); | |
148 | #endif | |
149 | #ifdef FE_INVALID | |
150 | result |= test_mmee (mode1, mode2, exc1, FE_INVALID); | |
151 | #endif | |
152 | #ifdef FE_OVERFLOW | |
153 | result |= test_mmee (mode1, mode2, exc1, FE_OVERFLOW); | |
154 | #endif | |
155 | #ifdef FE_UNDERFLOW | |
156 | result |= test_mmee (mode1, mode2, exc1, FE_UNDERFLOW); | |
157 | #endif | |
158 | ||
159 | return result; | |
160 | } | |
161 | ||
162 | static int | |
163 | test_mm (int mode1, int mode2) | |
164 | { | |
165 | int result = 0; | |
166 | ||
167 | result |= test_mme (mode1, mode2, 0); | |
168 | result |= test_mme (mode1, mode2, FE_ALL_EXCEPT); | |
169 | #ifdef FE_DIVBYZERO | |
170 | result |= test_mme (mode1, mode2, FE_DIVBYZERO); | |
171 | #endif | |
172 | #ifdef FE_INEXACT | |
173 | result |= test_mme (mode1, mode2, FE_INEXACT); | |
174 | #endif | |
175 | #ifdef FE_INVALID | |
176 | result |= test_mme (mode1, mode2, FE_INVALID); | |
177 | #endif | |
178 | #ifdef FE_OVERFLOW | |
179 | result |= test_mme (mode1, mode2, FE_OVERFLOW); | |
180 | #endif | |
181 | #ifdef FE_UNDERFLOW | |
182 | result |= test_mme (mode1, mode2, FE_UNDERFLOW); | |
183 | #endif | |
184 | ||
185 | return result; | |
186 | } | |
187 | ||
188 | static int | |
189 | test_m (int mode1) | |
190 | { | |
191 | int result = 0; | |
192 | ||
193 | #ifdef FE_DOWNWARD | |
194 | result |= test_mm (mode1, FE_DOWNWARD); | |
195 | #endif | |
196 | #ifdef FE_TONEAREST | |
197 | result |= test_mm (mode1, FE_TONEAREST); | |
198 | #endif | |
199 | #ifdef FE_TOWARDZERO | |
200 | result |= test_mm (mode1, FE_TOWARDZERO); | |
201 | #endif | |
202 | #ifdef FE_UPWARD | |
203 | result |= test_mm (mode1, FE_UPWARD); | |
204 | #endif | |
205 | ||
206 | return result; | |
207 | } | |
208 | ||
209 | static int | |
210 | do_test (void) | |
211 | { | |
212 | int result = 0; | |
213 | ||
214 | #ifdef FE_DOWNWARD | |
215 | result |= test_m (FE_DOWNWARD); | |
216 | #endif | |
217 | #ifdef FE_TONEAREST | |
218 | result |= test_m (FE_TONEAREST); | |
219 | #endif | |
220 | #ifdef FE_TOWARDZERO | |
221 | result |= test_m (FE_TOWARDZERO); | |
222 | #endif | |
223 | #ifdef FE_UPWARD | |
224 | result |= test_m (FE_UPWARD); | |
225 | #endif | |
226 | ||
227 | return result; | |
228 | } | |
229 | ||
230 | #define TEST_FUNCTION do_test () | |
231 | #include "../test-skeleton.c" |