2.9
[glibc/nacl-glibc.git] / sysdeps / powerpc / fpu / test-powerpc-snan.c
blob93b212abcb2884a98117d6057d78627c69d6cfbf
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, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #define _GNU_SOURCE
22 #define __USE_GNU
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <sys/time.h>
26 #include <string.h>
27 #include <math.h>
28 #include <float.h>
29 #include <fenv.h>
30 #include <signal.h>
31 #include <setjmp.h>
32 #include <errno.h>
34 int dest_offset;
35 char *dest_address;
36 double value = 123.456;
37 double zero = 0.0;
39 float SNANf;
40 double SNAN;
41 long double SNANl;
43 static sigjmp_buf sigfpe_buf;
45 void
46 init_signaling_nan()
48 union {
49 double _ld16;
50 double _d8;
51 unsigned int _ui4[4];
52 float _f4;
53 } nan_temp;
55 nan_temp._ui4[0] = 0x7fa00000;
56 SNANf = nan_temp._f4;
58 nan_temp._ui4[0] = 0x7ff40000;
59 nan_temp._ui4[1] = 0x00000000;
60 SNAN = nan_temp._d8;
62 nan_temp._ui4[0] = 0x7ff40000;
63 nan_temp._ui4[1] = 0x00000000;
64 nan_temp._ui4[2] = 0x00000000;
65 nan_temp._ui4[3] = 0x00000000;
66 SNANl = nan_temp._ld16;
69 static float
70 snan_float (void)
72 return SNANf;
75 static double
76 snan_double (void)
78 return SNAN;
81 typedef long double ldouble;
83 static ldouble
84 snan_ldouble (void)
86 return SNANl;
90 void
91 myFPsighandler(int signal,
92 siginfo_t *info,
93 void *context)
95 siglongjmp(sigfpe_buf, 0);
98 int
99 set_sigaction_FP(void)
101 struct sigaction sa;
102 /* register RT signal handler via sigaction */
103 sa.sa_flags = SA_SIGINFO;
104 sa.sa_sigaction = &myFPsighandler;
105 sigemptyset(&sa.sa_mask);
106 sigaction(SIGFPE, &sa, NULL);
108 return 0;
112 remove_sigaction_FP(void)
114 struct sigaction sa;
115 /* restore default RT signal handler via sigaction */
116 sa.sa_flags = SA_SIGINFO;
117 sa.sa_handler = SIG_DFL;
118 sigemptyset(&sa.sa_mask);
119 sigaction(SIGFPE, &sa, NULL);
121 return 0;
124 static int errors = 0;
126 static void
127 check (const char *testname, int result)
129 if (!result) {
130 printf ("Failure: %s\n", testname);
131 errors++;
135 #define TEST_FUNC(NAME, FLOAT) \
136 static void \
137 NAME (void) \
139 /* Variables are declared volatile to forbid some compiler \
140 optimizations. */ \
141 volatile FLOAT Inf_var, NaN_var, zero_var, one_var, SNaN_var; \
142 fenv_t saved_fenv; \
144 zero_var = 0.0; \
145 one_var = 1.0; \
146 NaN_var = zero_var / zero_var; \
147 SNaN_var = snan_##FLOAT (); \
148 Inf_var = one_var / zero_var; \
150 (void) &zero_var; \
151 (void) &one_var; \
152 (void) &NaN_var; \
153 (void) &SNaN_var; \
154 (void) &Inf_var; \
156 set_sigaction_FP (); \
157 fegetenv(&saved_fenv); \
159 feclearexcept(FE_ALL_EXCEPT); \
160 feenableexcept (FE_ALL_EXCEPT); \
161 if (sigsetjmp(sigfpe_buf, 0)) \
163 printf (#FLOAT " isnan(NaN) raised SIGFPE\n"); \
164 errors++; \
165 } else { \
166 check (#FLOAT " isnan (NaN)", isnan (NaN_var)); \
169 feclearexcept(FE_ALL_EXCEPT); \
170 feenableexcept (FE_ALL_EXCEPT); \
171 if (sigsetjmp(sigfpe_buf, 0)) \
173 printf (#FLOAT " isnan(-NaN) raised SIGFPE\n"); \
174 errors++; \
175 } else { \
176 check (#FLOAT " isnan (-NaN)", isnan (-NaN_var)); \
179 feclearexcept(FE_ALL_EXCEPT); \
180 feenableexcept (FE_ALL_EXCEPT); \
181 if (sigsetjmp(sigfpe_buf, 0)) \
183 printf (#FLOAT " isnan(SNaN) raised SIGFPE\n"); \
184 errors++; \
185 } else { \
186 check (#FLOAT " isnan (SNaN)", isnan (SNaN_var)); \
189 feclearexcept(FE_ALL_EXCEPT); \
190 feenableexcept (FE_ALL_EXCEPT); \
191 if (sigsetjmp(sigfpe_buf, 0)) \
193 printf (#FLOAT " isnan(-SNaN) raised SIGFPE\n"); \
194 errors++; \
195 } else { \
196 check (#FLOAT " isnan (-SNaN)", isnan (-SNaN_var)); \
199 feclearexcept(FE_ALL_EXCEPT); \
200 feenableexcept (FE_ALL_EXCEPT); \
201 if (sigsetjmp(sigfpe_buf, 0)) \
203 printf (#FLOAT " isinf(NaN) raised SIGFPE\n"); \
204 errors++; \
205 } else { \
206 check (#FLOAT " isinf (NaN)", !isinf (NaN_var)); \
209 feclearexcept(FE_ALL_EXCEPT); \
210 feenableexcept (FE_ALL_EXCEPT); \
211 if (sigsetjmp(sigfpe_buf, 0)) \
213 printf (#FLOAT " isinf(-NaN) raised SIGFPE\n"); \
214 errors++; \
215 } else { \
216 check (#FLOAT " isinf (-NaN)", !isinf (-NaN_var)); \
219 feclearexcept(FE_ALL_EXCEPT); \
220 feenableexcept (FE_ALL_EXCEPT); \
221 if (sigsetjmp(sigfpe_buf, 0)) \
223 printf (#FLOAT " isinf(SNaN) raised SIGFPE\n"); \
224 errors++; \
225 } else { \
226 check (#FLOAT " isinf (SNaN)", !isinf (SNaN_var)); \
229 feclearexcept(FE_ALL_EXCEPT); \
230 feenableexcept (FE_ALL_EXCEPT); \
231 if (sigsetjmp(sigfpe_buf, 0)) \
233 printf (#FLOAT " isinf(-SNaN) raised SIGFPE\n"); \
234 errors++; \
235 } else { \
236 check (#FLOAT " isinf (-SNaN)", !isinf (-SNaN_var)); \
239 feclearexcept(FE_ALL_EXCEPT); \
240 feenableexcept (FE_ALL_EXCEPT); \
241 if (sigsetjmp(sigfpe_buf, 0)) \
243 printf (#FLOAT " isfinite(NaN) raised SIGFPE\n"); \
244 errors++; \
245 } else { \
246 check (#FLOAT " isfinite (NaN)", !isfinite (NaN_var)); \
249 feclearexcept(FE_ALL_EXCEPT); \
250 feenableexcept (FE_ALL_EXCEPT); \
251 if (sigsetjmp(sigfpe_buf, 0)) \
253 printf (#FLOAT " isfinite(-NaN) raised SIGFPE\n"); \
254 errors++; \
255 } else { \
256 check (#FLOAT " isfinite (-NaN)", !isfinite (-NaN_var)); \
259 feclearexcept(FE_ALL_EXCEPT); \
260 feenableexcept (FE_ALL_EXCEPT); \
261 if (sigsetjmp(sigfpe_buf, 0)) \
263 printf (#FLOAT " isfinite(SNaN) raised SIGFPE\n"); \
264 errors++; \
265 } else { \
266 check (#FLOAT " isfinite (SNaN)", !isfinite (SNaN_var)); \
269 feclearexcept(FE_ALL_EXCEPT); \
270 feenableexcept (FE_ALL_EXCEPT); \
271 if (sigsetjmp(sigfpe_buf, 0)) \
273 printf (#FLOAT " isfinite(-SNaN) raised SIGFPE\n"); \
274 errors++; \
275 } else { \
276 check (#FLOAT " isfinite (-SNaN)", !isfinite (-SNaN_var)); \
279 feclearexcept(FE_ALL_EXCEPT); \
280 feenableexcept (FE_ALL_EXCEPT); \
281 if (sigsetjmp(sigfpe_buf, 0)) \
283 printf (#FLOAT " isnormal(NaN) raised SIGFPE\n"); \
284 errors++; \
285 } else { \
286 check (#FLOAT " isnormal (NaN)", !isnormal (NaN_var)); \
289 feclearexcept(FE_ALL_EXCEPT); \
290 feenableexcept (FE_ALL_EXCEPT); \
291 if (sigsetjmp(sigfpe_buf, 0)) \
293 printf (#FLOAT " isnormal(-NaN) raised SIGFPE\n"); \
294 errors++; \
295 } else { \
296 check (#FLOAT " isnormal (-NaN)", !isnormal (-NaN_var)); \
299 feclearexcept(FE_ALL_EXCEPT); \
300 feenableexcept (FE_ALL_EXCEPT); \
301 if (sigsetjmp(sigfpe_buf, 0)) \
303 printf (#FLOAT " isnormal(SNaN) isnormal SIGFPE\n"); \
304 errors++; \
305 } else { \
306 check (#FLOAT " isnormal (SNaN)", !isnormal (SNaN_var)); \
309 feclearexcept(FE_ALL_EXCEPT); \
310 feenableexcept (FE_ALL_EXCEPT); \
311 if (sigsetjmp(sigfpe_buf, 0)) \
313 printf (#FLOAT " isnormal(-SNaN) raised SIGFPE\n"); \
314 errors++; \
315 } else { \
316 check (#FLOAT " isnormal (-SNaN)", !isnormal (-SNaN_var)); \
319 feclearexcept(FE_ALL_EXCEPT); \
320 feenableexcept (FE_ALL_EXCEPT); \
321 if (sigsetjmp(sigfpe_buf, 0)) \
323 printf (#FLOAT " fpclassify(NaN) raised SIGFPE\n"); \
324 errors++; \
325 } else { \
326 check (#FLOAT " fpclassify (NaN)", (fpclassify (NaN_var)==FP_NAN)); \
329 feclearexcept(FE_ALL_EXCEPT); \
330 feenableexcept (FE_ALL_EXCEPT); \
331 if (sigsetjmp(sigfpe_buf, 0)) \
333 printf (#FLOAT " fpclassify(-NaN) raised SIGFPE\n"); \
334 errors++; \
335 } else { \
336 check (#FLOAT " fpclassify (-NaN)", (fpclassify (-NaN_var)==FP_NAN)); \
339 feclearexcept(FE_ALL_EXCEPT); \
340 feenableexcept (FE_ALL_EXCEPT); \
341 if (sigsetjmp(sigfpe_buf, 0)) \
343 printf (#FLOAT " fpclassify(SNaN) isnormal SIGFPE\n"); \
344 errors++; \
345 } else { \
346 check (#FLOAT " fpclassify (SNaN)", (fpclassify (SNaN_var)==FP_NAN)); \
349 feclearexcept(FE_ALL_EXCEPT); \
350 feenableexcept (FE_ALL_EXCEPT); \
351 if (sigsetjmp(sigfpe_buf, 0)) \
353 printf (#FLOAT " fpclassify(-SNaN) raised SIGFPE\n"); \
354 errors++; \
355 } else { \
356 check (#FLOAT " fpclassify (-SNaN)", (fpclassify (-SNaN_var)==FP_NAN)); \
359 fesetenv(&saved_fenv); /* restore saved fenv */ \
360 remove_sigaction_FP(); \
363 TEST_FUNC (float_test, float)
364 TEST_FUNC (double_test, double)
365 #ifndef NO_LONG_DOUBLE
366 TEST_FUNC (ldouble_test, ldouble)
367 #endif
369 static int
370 do_test (void)
372 init_signaling_nan();
374 float_test();
375 double_test();
376 #ifndef NO_LONG_DOUBLE
377 ldouble_test();
378 #endif
380 return errors != 0;
383 #define TEST_FUNCTION do_test ()
384 #include "../test-skeleton.c"