Replace FSF snail mail address with URLs.
[glibc.git] / sysdeps / powerpc / fpu / test-powerpc-snan.c
blobb90f0264b2b2bfb93e6c06eca94ae1eef068bb89
1 /* Test Signalling NaN in isnan, isinf etc functions.
2 Copyright (C) 2008 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Andreas Jaeger <aj@suse.de>, 2005.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
20 #define _GNU_SOURCE
21 #define __USE_GNU
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <sys/time.h>
25 #include <string.h>
26 #include <math.h>
27 #include <float.h>
28 #include <fenv.h>
29 #include <signal.h>
30 #include <setjmp.h>
31 #include <errno.h>
33 int dest_offset;
34 char *dest_address;
35 double value = 123.456;
36 double zero = 0.0;
38 float SNANf;
39 double SNAN;
40 long double SNANl;
42 static sigjmp_buf sigfpe_buf;
44 void
45 init_signaling_nan()
47 union {
48 double _ld16;
49 double _d8;
50 unsigned int _ui4[4];
51 float _f4;
52 } nan_temp;
54 nan_temp._ui4[0] = 0x7fa00000;
55 SNANf = nan_temp._f4;
57 nan_temp._ui4[0] = 0x7ff40000;
58 nan_temp._ui4[1] = 0x00000000;
59 SNAN = nan_temp._d8;
61 nan_temp._ui4[0] = 0x7ff40000;
62 nan_temp._ui4[1] = 0x00000000;
63 nan_temp._ui4[2] = 0x00000000;
64 nan_temp._ui4[3] = 0x00000000;
65 SNANl = nan_temp._ld16;
68 static float
69 snan_float (void)
71 return SNANf;
74 static double
75 snan_double (void)
77 return SNAN;
80 typedef long double ldouble;
82 static ldouble
83 snan_ldouble (void)
85 return SNANl;
89 void
90 myFPsighandler(int signal,
91 siginfo_t *info,
92 void *context)
94 siglongjmp(sigfpe_buf, 0);
97 int
98 set_sigaction_FP(void)
100 struct sigaction sa;
101 /* register RT signal handler via sigaction */
102 sa.sa_flags = SA_SIGINFO;
103 sa.sa_sigaction = &myFPsighandler;
104 sigemptyset(&sa.sa_mask);
105 sigaction(SIGFPE, &sa, NULL);
107 return 0;
111 remove_sigaction_FP(void)
113 struct sigaction sa;
114 /* restore default RT signal handler via sigaction */
115 sa.sa_flags = SA_SIGINFO;
116 sa.sa_handler = SIG_DFL;
117 sigemptyset(&sa.sa_mask);
118 sigaction(SIGFPE, &sa, NULL);
120 return 0;
123 static int errors = 0;
125 static void
126 check (const char *testname, int result)
128 if (!result) {
129 printf ("Failure: %s\n", testname);
130 errors++;
134 #define TEST_FUNC(NAME, FLOAT) \
135 static void \
136 NAME (void) \
138 /* Variables are declared volatile to forbid some compiler \
139 optimizations. */ \
140 volatile FLOAT Inf_var, NaN_var, zero_var, one_var, SNaN_var; \
141 fenv_t saved_fenv; \
143 zero_var = 0.0; \
144 one_var = 1.0; \
145 NaN_var = zero_var / zero_var; \
146 SNaN_var = snan_##FLOAT (); \
147 Inf_var = one_var / zero_var; \
149 (void) &zero_var; \
150 (void) &one_var; \
151 (void) &NaN_var; \
152 (void) &SNaN_var; \
153 (void) &Inf_var; \
155 set_sigaction_FP (); \
156 fegetenv(&saved_fenv); \
158 feclearexcept(FE_ALL_EXCEPT); \
159 feenableexcept (FE_ALL_EXCEPT); \
160 if (sigsetjmp(sigfpe_buf, 0)) \
162 printf (#FLOAT " isnan(NaN) raised SIGFPE\n"); \
163 errors++; \
164 } else { \
165 check (#FLOAT " isnan (NaN)", isnan (NaN_var)); \
168 feclearexcept(FE_ALL_EXCEPT); \
169 feenableexcept (FE_ALL_EXCEPT); \
170 if (sigsetjmp(sigfpe_buf, 0)) \
172 printf (#FLOAT " isnan(-NaN) raised SIGFPE\n"); \
173 errors++; \
174 } else { \
175 check (#FLOAT " isnan (-NaN)", isnan (-NaN_var)); \
178 feclearexcept(FE_ALL_EXCEPT); \
179 feenableexcept (FE_ALL_EXCEPT); \
180 if (sigsetjmp(sigfpe_buf, 0)) \
182 printf (#FLOAT " isnan(SNaN) raised SIGFPE\n"); \
183 errors++; \
184 } else { \
185 check (#FLOAT " isnan (SNaN)", isnan (SNaN_var)); \
188 feclearexcept(FE_ALL_EXCEPT); \
189 feenableexcept (FE_ALL_EXCEPT); \
190 if (sigsetjmp(sigfpe_buf, 0)) \
192 printf (#FLOAT " isnan(-SNaN) raised SIGFPE\n"); \
193 errors++; \
194 } else { \
195 check (#FLOAT " isnan (-SNaN)", isnan (-SNaN_var)); \
198 feclearexcept(FE_ALL_EXCEPT); \
199 feenableexcept (FE_ALL_EXCEPT); \
200 if (sigsetjmp(sigfpe_buf, 0)) \
202 printf (#FLOAT " isinf(NaN) raised SIGFPE\n"); \
203 errors++; \
204 } else { \
205 check (#FLOAT " isinf (NaN)", !isinf (NaN_var)); \
208 feclearexcept(FE_ALL_EXCEPT); \
209 feenableexcept (FE_ALL_EXCEPT); \
210 if (sigsetjmp(sigfpe_buf, 0)) \
212 printf (#FLOAT " isinf(-NaN) raised SIGFPE\n"); \
213 errors++; \
214 } else { \
215 check (#FLOAT " isinf (-NaN)", !isinf (-NaN_var)); \
218 feclearexcept(FE_ALL_EXCEPT); \
219 feenableexcept (FE_ALL_EXCEPT); \
220 if (sigsetjmp(sigfpe_buf, 0)) \
222 printf (#FLOAT " isinf(SNaN) raised SIGFPE\n"); \
223 errors++; \
224 } else { \
225 check (#FLOAT " isinf (SNaN)", !isinf (SNaN_var)); \
228 feclearexcept(FE_ALL_EXCEPT); \
229 feenableexcept (FE_ALL_EXCEPT); \
230 if (sigsetjmp(sigfpe_buf, 0)) \
232 printf (#FLOAT " isinf(-SNaN) raised SIGFPE\n"); \
233 errors++; \
234 } else { \
235 check (#FLOAT " isinf (-SNaN)", !isinf (-SNaN_var)); \
238 feclearexcept(FE_ALL_EXCEPT); \
239 feenableexcept (FE_ALL_EXCEPT); \
240 if (sigsetjmp(sigfpe_buf, 0)) \
242 printf (#FLOAT " isfinite(NaN) raised SIGFPE\n"); \
243 errors++; \
244 } else { \
245 check (#FLOAT " isfinite (NaN)", !isfinite (NaN_var)); \
248 feclearexcept(FE_ALL_EXCEPT); \
249 feenableexcept (FE_ALL_EXCEPT); \
250 if (sigsetjmp(sigfpe_buf, 0)) \
252 printf (#FLOAT " isfinite(-NaN) raised SIGFPE\n"); \
253 errors++; \
254 } else { \
255 check (#FLOAT " isfinite (-NaN)", !isfinite (-NaN_var)); \
258 feclearexcept(FE_ALL_EXCEPT); \
259 feenableexcept (FE_ALL_EXCEPT); \
260 if (sigsetjmp(sigfpe_buf, 0)) \
262 printf (#FLOAT " isfinite(SNaN) raised SIGFPE\n"); \
263 errors++; \
264 } else { \
265 check (#FLOAT " isfinite (SNaN)", !isfinite (SNaN_var)); \
268 feclearexcept(FE_ALL_EXCEPT); \
269 feenableexcept (FE_ALL_EXCEPT); \
270 if (sigsetjmp(sigfpe_buf, 0)) \
272 printf (#FLOAT " isfinite(-SNaN) raised SIGFPE\n"); \
273 errors++; \
274 } else { \
275 check (#FLOAT " isfinite (-SNaN)", !isfinite (-SNaN_var)); \
278 feclearexcept(FE_ALL_EXCEPT); \
279 feenableexcept (FE_ALL_EXCEPT); \
280 if (sigsetjmp(sigfpe_buf, 0)) \
282 printf (#FLOAT " isnormal(NaN) raised SIGFPE\n"); \
283 errors++; \
284 } else { \
285 check (#FLOAT " isnormal (NaN)", !isnormal (NaN_var)); \
288 feclearexcept(FE_ALL_EXCEPT); \
289 feenableexcept (FE_ALL_EXCEPT); \
290 if (sigsetjmp(sigfpe_buf, 0)) \
292 printf (#FLOAT " isnormal(-NaN) raised SIGFPE\n"); \
293 errors++; \
294 } else { \
295 check (#FLOAT " isnormal (-NaN)", !isnormal (-NaN_var)); \
298 feclearexcept(FE_ALL_EXCEPT); \
299 feenableexcept (FE_ALL_EXCEPT); \
300 if (sigsetjmp(sigfpe_buf, 0)) \
302 printf (#FLOAT " isnormal(SNaN) isnormal SIGFPE\n"); \
303 errors++; \
304 } else { \
305 check (#FLOAT " isnormal (SNaN)", !isnormal (SNaN_var)); \
308 feclearexcept(FE_ALL_EXCEPT); \
309 feenableexcept (FE_ALL_EXCEPT); \
310 if (sigsetjmp(sigfpe_buf, 0)) \
312 printf (#FLOAT " isnormal(-SNaN) raised SIGFPE\n"); \
313 errors++; \
314 } else { \
315 check (#FLOAT " isnormal (-SNaN)", !isnormal (-SNaN_var)); \
318 feclearexcept(FE_ALL_EXCEPT); \
319 feenableexcept (FE_ALL_EXCEPT); \
320 if (sigsetjmp(sigfpe_buf, 0)) \
322 printf (#FLOAT " fpclassify(NaN) raised SIGFPE\n"); \
323 errors++; \
324 } else { \
325 check (#FLOAT " fpclassify (NaN)", (fpclassify (NaN_var)==FP_NAN)); \
328 feclearexcept(FE_ALL_EXCEPT); \
329 feenableexcept (FE_ALL_EXCEPT); \
330 if (sigsetjmp(sigfpe_buf, 0)) \
332 printf (#FLOAT " fpclassify(-NaN) raised SIGFPE\n"); \
333 errors++; \
334 } else { \
335 check (#FLOAT " fpclassify (-NaN)", (fpclassify (-NaN_var)==FP_NAN)); \
338 feclearexcept(FE_ALL_EXCEPT); \
339 feenableexcept (FE_ALL_EXCEPT); \
340 if (sigsetjmp(sigfpe_buf, 0)) \
342 printf (#FLOAT " fpclassify(SNaN) isnormal SIGFPE\n"); \
343 errors++; \
344 } else { \
345 check (#FLOAT " fpclassify (SNaN)", (fpclassify (SNaN_var)==FP_NAN)); \
348 feclearexcept(FE_ALL_EXCEPT); \
349 feenableexcept (FE_ALL_EXCEPT); \
350 if (sigsetjmp(sigfpe_buf, 0)) \
352 printf (#FLOAT " fpclassify(-SNaN) raised SIGFPE\n"); \
353 errors++; \
354 } else { \
355 check (#FLOAT " fpclassify (-SNaN)", (fpclassify (-SNaN_var)==FP_NAN)); \
358 fesetenv(&saved_fenv); /* restore saved fenv */ \
359 remove_sigaction_FP(); \
362 TEST_FUNC (float_test, float)
363 TEST_FUNC (double_test, double)
364 #ifndef NO_LONG_DOUBLE
365 TEST_FUNC (ldouble_test, ldouble)
366 #endif
368 static int
369 do_test (void)
371 init_signaling_nan();
373 float_test();
374 double_test();
375 #ifndef NO_LONG_DOUBLE
376 ldouble_test();
377 #endif
379 return errors != 0;
382 #define TEST_FUNCTION do_test ()
383 #include "../test-skeleton.c"