powerpc: Use latest optimizations for internal function calls
[glibc.git] / math / test-fenvinline.c
blob8fdfb38d13dbeb515fd0240275fbaa07e6208de4
1 /* Test for fenv inline implementations.
2 Copyright (C) 2015-2017 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
19 #ifndef _GNU_SOURCE
20 # define _GNU_SOURCE
21 #endif
23 /* To make sure the fenv inline function are used. */
24 #undef __NO_MATH_INLINES
26 #include <fenv.h>
27 #include <stdio.h>
28 #include <math-tests.h>
31 Since not all architectures might define all exceptions, we define
32 a private set and map accordingly.
34 #define NO_EXC 0
35 #define INEXACT_EXC 0x1
36 #define DIVBYZERO_EXC 0x2
37 #define UNDERFLOW_EXC 0x04
38 #define OVERFLOW_EXC 0x08
39 #define INVALID_EXC 0x10
40 #define ALL_EXC \
41 (INEXACT_EXC | DIVBYZERO_EXC | UNDERFLOW_EXC | OVERFLOW_EXC | \
42 INVALID_EXC)
43 static int count_errors;
45 #if FE_ALL_EXCEPT
46 static void
47 test_single_exception_fp_int (int exception,
48 int exc_flag,
49 int fe_flag,
50 const char *flag_name)
52 if (exception & exc_flag)
54 if (fetestexcept (fe_flag))
55 printf (" Pass: Exception \"%s\" is set\n", flag_name);
56 else
58 printf (" Fail: Exception \"%s\" is not set\n", flag_name);
59 ++count_errors;
62 else
64 if (fetestexcept (fe_flag))
66 printf (" Fail: Exception \"%s\" is set\n", flag_name);
67 ++count_errors;
69 else
70 printf (" Pass: Exception \"%s\" is not set\n", flag_name);
73 /* Test whether a given exception was raised. */
74 static void
75 test_single_exception_fp_double (int exception,
76 int exc_flag,
77 double fe_flag,
78 const char *flag_name)
80 if (exception & exc_flag)
82 if (fetestexcept (fe_flag))
83 printf (" Pass: Exception \"%s\" is set\n", flag_name);
84 else
86 printf (" Fail: Exception \"%s\" is not set\n", flag_name);
87 ++count_errors;
90 else
92 if (fetestexcept (fe_flag))
94 printf (" Fail: Exception \"%s\" is set\n", flag_name);
95 ++count_errors;
97 else
98 printf (" Pass: Exception \"%s\" is not set\n", flag_name);
101 #endif
103 static void
104 test_exceptions (const char *test_name, int exception)
106 printf ("Test: %s\n", test_name);
107 #ifdef FE_DIVBYZERO
108 test_single_exception_fp_double (exception, DIVBYZERO_EXC, FE_DIVBYZERO,
109 "DIVBYZERO");
110 #endif
111 #ifdef FE_INVALID
112 test_single_exception_fp_double (exception, INVALID_EXC, FE_INVALID,
113 "INVALID");
114 #endif
115 #ifdef FE_INEXACT
116 test_single_exception_fp_double (exception, INEXACT_EXC, FE_INEXACT,
117 "INEXACT");
118 #endif
119 #ifdef FE_UNDERFLOW
120 test_single_exception_fp_double (exception, UNDERFLOW_EXC, FE_UNDERFLOW,
121 "UNDERFLOW");
122 #endif
123 #ifdef FE_OVERFLOW
124 test_single_exception_fp_double (exception, OVERFLOW_EXC, FE_OVERFLOW,
125 "OVERFLOW");
126 #endif
129 static void
130 test_exceptionflag (void)
132 printf ("Test: fegetexceptionflag (FE_ALL_EXCEPT)\n");
133 #if FE_ALL_EXCEPT
134 fexcept_t excepts;
136 feclearexcept (FE_ALL_EXCEPT);
138 feraiseexcept (FE_INVALID);
139 fegetexceptflag (&excepts, FE_ALL_EXCEPT);
141 feclearexcept (FE_ALL_EXCEPT);
142 feraiseexcept (FE_OVERFLOW | FE_INEXACT);
144 fesetexceptflag (&excepts, FE_ALL_EXCEPT);
146 test_single_exception_fp_int (INVALID_EXC, INVALID_EXC, FE_INVALID,
147 "INVALID (int)");
148 test_single_exception_fp_int (INVALID_EXC, OVERFLOW_EXC, FE_OVERFLOW,
149 "OVERFLOW (int)");
150 test_single_exception_fp_int (INVALID_EXC, INEXACT_EXC, FE_INEXACT,
151 "INEXACT (int)");
153 /* Same test, but using double as argument */
154 feclearexcept (FE_ALL_EXCEPT);
156 feraiseexcept (FE_INVALID);
157 fegetexceptflag (&excepts, (double)FE_ALL_EXCEPT);
159 feclearexcept (FE_ALL_EXCEPT);
160 feraiseexcept (FE_OVERFLOW | FE_INEXACT);
162 fesetexceptflag (&excepts, (double)FE_ALL_EXCEPT);
164 test_single_exception_fp_double (INVALID_EXC, INVALID_EXC, FE_INVALID,
165 "INVALID (double)");
166 test_single_exception_fp_double (INVALID_EXC, OVERFLOW_EXC, FE_OVERFLOW,
167 "OVERFLOW (double)");
168 test_single_exception_fp_double (INVALID_EXC, INEXACT_EXC, FE_INEXACT,
169 "INEXACT (double)");
170 #endif
173 static void
174 test_fesetround (void)
176 #if defined FE_TONEAREST && defined FE_TOWARDZERO
177 int res1;
178 int res2;
180 printf ("Tests for fesetround\n");
182 /* The fesetround should not itself cause the test to fail, however it
183 should either succeed for both 'int' and 'double' argument, or fail
184 for both. */
185 res1 = fesetround ((int) FE_TOWARDZERO);
186 res2 = fesetround ((double) FE_TOWARDZERO);
187 if (res1 != res2)
189 printf ("fesetround (FE_TOWARDZERO) failed: %d, %d\n", res1, res2);
190 ++count_errors;
193 res1 = fesetround ((int) FE_TONEAREST);
194 res2 = fesetround ((double) FE_TONEAREST);
195 if (res1 != res2)
197 printf ("fesetround (FE_TONEAREST) failed: %d, %d\n", res1, res2);
198 ++count_errors;
200 #endif
203 #if FE_ALL_EXCEPT
204 /* Tests for feenableexcept/fedisableexcept. */
205 static void
206 feenable_test (const char *flag_name, fexcept_t fe_exc)
208 int fe_exci = fe_exc;
209 double fe_excd = fe_exc;
210 int excepts;
212 /* First disable all exceptions. */
213 if (fedisableexcept (FE_ALL_EXCEPT) == -1)
215 printf ("Test: fedisableexcept (FE_ALL_EXCEPT) failed\n");
216 ++count_errors;
217 /* If this fails, the other tests don't make sense. */
218 return;
221 /* Test for inline macros using integer argument. */
222 excepts = feenableexcept (fe_exci);
223 if (!EXCEPTION_ENABLE_SUPPORTED (fe_exci) && excepts == -1)
225 printf ("Test: not testing feenableexcept, it isn't implemented.\n");
226 return;
228 if (excepts == -1)
230 printf ("Test: feenableexcept (%s) failed\n", flag_name);
231 ++count_errors;
232 return;
234 if (excepts != 0)
236 printf ("Test: feenableexcept (%s) failed, return should be 0, is %x\n",
237 flag_name, excepts);
238 ++count_errors;
241 /* And now disable the exception again. */
242 excepts = fedisableexcept (fe_exc);
243 if (excepts == -1)
245 printf ("Test: fedisableexcept (%s) failed\n", flag_name);
246 ++count_errors;
247 return;
249 if (excepts != fe_exc)
251 printf ("Test: fedisableexcept (%s) failed, return should be 0x%x, is 0x%x\n",
252 flag_name, (unsigned int)fe_exc, excepts);
253 ++count_errors;
256 /* Test for inline macros using double argument. */
257 excepts = feenableexcept (fe_excd);
258 if (!EXCEPTION_ENABLE_SUPPORTED (fe_excd) && excepts == -1)
260 printf ("Test: not testing feenableexcept, it isn't implemented.\n");
261 return;
263 if (excepts == -1)
265 printf ("Test: feenableexcept (%s) failed\n", flag_name);
266 ++count_errors;
267 return;
269 if (excepts != 0)
271 printf ("Test: feenableexcept (%s) failed, return should be 0, is %x\n",
272 flag_name, excepts);
273 ++count_errors;
276 /* And now disable the exception again. */
277 excepts = fedisableexcept (fe_exc);
278 if (excepts == -1)
280 printf ("Test: fedisableexcept (%s) failed\n", flag_name);
281 ++count_errors;
282 return;
284 if (excepts != fe_exc)
286 printf ("Test: fedisableexcept (%s) failed, return should be 0x%x, is 0x%x\n",
287 flag_name, (unsigned int)fe_exc, excepts);
288 ++count_errors;
291 #endif
293 static void
294 test_feenabledisable (void)
296 printf ("Tests for feenableexcepts/fedisableexcept\n");
298 /* We might have some exceptions still set. */
299 feclearexcept (FE_ALL_EXCEPT);
301 #ifdef FE_DIVBYZERO
302 feenable_test ("FE_DIVBYZERO", FE_DIVBYZERO);
303 #endif
304 #ifdef FE_INVALID
305 feenable_test ("FE_INVALID", FE_INVALID);
306 #endif
307 #ifdef FE_INEXACT
308 feenable_test ("FE_INEXACT", FE_INEXACT);
309 #endif
310 #ifdef FE_UNDERFLOW
311 feenable_test ("FE_UNDERFLOW", FE_UNDERFLOW);
312 #endif
313 #ifdef FE_OVERFLOW
314 feenable_test ("FE_OVERFLOW", FE_OVERFLOW);
315 #endif
316 fesetenv (FE_DFL_ENV);
319 static int
320 do_test (void)
322 /* clear all exceptions and test if all are cleared */
323 feclearexcept (FE_ALL_EXCEPT);
324 test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions",
325 NO_EXC);
327 /* raise all exceptions and test if all are raised */
328 feraiseexcept (FE_ALL_EXCEPT);
329 if (EXCEPTION_TESTS (float))
330 test_exceptions ("feraiseexcept (FE_ALL_EXCEPT) raises all exceptions",
331 ALL_EXC);
333 /* Same test, but using double as argument */
334 feclearexcept ((double)FE_ALL_EXCEPT);
335 test_exceptions ("feclearexcept ((double)FE_ALL_EXCEPT) clears all exceptions",
336 NO_EXC);
338 feraiseexcept ((double)FE_ALL_EXCEPT);
339 if (EXCEPTION_TESTS (float))
340 test_exceptions ("feraiseexcept ((double)FE_ALL_EXCEPT) raises all exceptions",
341 ALL_EXC);
343 if (EXCEPTION_TESTS (float))
344 test_exceptionflag ();
346 test_fesetround ();
348 test_feenabledisable ();
350 return count_errors;
353 #define TEST_FUNCTION do_test ()
354 #include "../test-skeleton.c"