chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / sysdeps / powerpc / fpu / test-powerpc-snan.c
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.
5
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.
10
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.
15
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.  */
20
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>
33
34 int dest_offset;
35 char *dest_address;
36 double  value = 123.456;
37 double  zero = 0.0;
38
39 float SNANf;
40 double SNAN;
41 long double SNANl;
42
43 static sigjmp_buf sigfpe_buf;
44
45 void
46 init_signaling_nan()
47 {
48     union {
49         double _ld16;
50         double _d8;
51         unsigned int _ui4[4];
52         float _f4;
53     } nan_temp;
54     
55     nan_temp._ui4[0] = 0x7fa00000;
56     SNANf = nan_temp._f4;
57
58     nan_temp._ui4[0] = 0x7ff40000;
59     nan_temp._ui4[1] = 0x00000000;
60     SNAN = nan_temp._d8;
61
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;
67 }
68
69 static float
70 snan_float (void)
71 {
72   return SNANf;
73 }
74
75 static double
76 snan_double (void)
77 {
78   return SNAN;
79 }
80
81 typedef long double ldouble;
82
83 static ldouble
84 snan_ldouble (void)
85 {
86   return SNANl;
87 }
88
89
90 void
91 myFPsighandler(int signal,
92              siginfo_t *info,
93              void *context)
94 {
95   siglongjmp(sigfpe_buf, 0);
96 }
97
98 int
99 set_sigaction_FP(void)
100 {
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);
107
108     return 0;
109 }
110
111 int
112 remove_sigaction_FP(void)
113 {
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);
120
121     return 0;
122 }
123
124 static int errors = 0;
125
126 static void
127 check (const char *testname, int result)
128 {
129   if (!result) {
130     printf ("Failure: %s\n", testname);
131     errors++;
132   }
133 }
134
135 #define TEST_FUNC(NAME, FLOAT) \
136 static void                                                                   \
137 NAME (void)                                                                   \
138 {                                                                             \
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;                                                          \
143                                                                               \
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;                                               \
149                                                                               \
150   (void) &zero_var;                                                           \
151   (void) &one_var;                                                            \
152   (void) &NaN_var;                                                            \
153   (void) &SNaN_var;                                                           \
154   (void) &Inf_var;                                                            \
155                                                                               \
156   set_sigaction_FP ();                                                        \
157   fegetenv(&saved_fenv);                                                      \
158                                                                               \
159   feclearexcept(FE_ALL_EXCEPT);                                               \
160   feenableexcept (FE_ALL_EXCEPT);                                             \
161   if (sigsetjmp(sigfpe_buf, 0))                                               \
162     {                                                                         \
163       printf (#FLOAT " isnan(NaN) raised SIGFPE\n");                          \
164       errors++;                                                               \
165     } else {                                                                  \
166       check (#FLOAT " isnan (NaN)", isnan (NaN_var));                         \
167     }                                                                         \
168                                                                               \
169   feclearexcept(FE_ALL_EXCEPT);                                               \
170   feenableexcept (FE_ALL_EXCEPT);                                             \
171   if (sigsetjmp(sigfpe_buf, 0))                                               \
172     {                                                                         \
173       printf (#FLOAT " isnan(-NaN) raised SIGFPE\n");                         \
174       errors++;                                                               \
175     } else {                                                                  \
176       check (#FLOAT " isnan (-NaN)", isnan (-NaN_var));                       \
177     }                                                                         \
178                                                                               \
179   feclearexcept(FE_ALL_EXCEPT);                                               \
180   feenableexcept (FE_ALL_EXCEPT);                                             \
181   if (sigsetjmp(sigfpe_buf, 0))                                               \
182     {                                                                         \
183       printf (#FLOAT " isnan(SNaN) raised SIGFPE\n");                         \
184       errors++;                                                               \
185     } else {                                                                  \
186       check (#FLOAT " isnan (SNaN)", isnan (SNaN_var));                       \
187     }                                                                         \
188                                                                               \
189   feclearexcept(FE_ALL_EXCEPT);                                               \
190   feenableexcept (FE_ALL_EXCEPT);                                             \
191   if (sigsetjmp(sigfpe_buf, 0))                                               \
192     {                                                                         \
193       printf (#FLOAT " isnan(-SNaN) raised SIGFPE\n");                        \
194       errors++;                                                               \
195     } else {                                                                  \
196       check (#FLOAT " isnan (-SNaN)", isnan (-SNaN_var));                     \
197     }                                                                         \
198                                                                               \
199   feclearexcept(FE_ALL_EXCEPT);                                               \
200   feenableexcept (FE_ALL_EXCEPT);                                             \
201   if (sigsetjmp(sigfpe_buf, 0))                                               \
202     {                                                                         \
203       printf (#FLOAT " isinf(NaN) raised SIGFPE\n");                          \
204       errors++;                                                               \
205     } else {                                                                  \
206       check (#FLOAT " isinf (NaN)", !isinf (NaN_var));                        \
207     }                                                                         \
208                                                                               \
209   feclearexcept(FE_ALL_EXCEPT);                                               \
210   feenableexcept (FE_ALL_EXCEPT);                                             \
211   if (sigsetjmp(sigfpe_buf, 0))                                               \
212     {                                                                         \
213       printf (#FLOAT " isinf(-NaN) raised SIGFPE\n");                         \
214       errors++;                                                               \
215     } else {                                                                  \
216       check (#FLOAT " isinf (-NaN)", !isinf (-NaN_var));                      \
217     }                                                                         \
218                                                                               \
219   feclearexcept(FE_ALL_EXCEPT);                                               \
220   feenableexcept (FE_ALL_EXCEPT);                                             \
221   if (sigsetjmp(sigfpe_buf, 0))                                               \
222     {                                                                         \
223       printf (#FLOAT " isinf(SNaN) raised SIGFPE\n");                         \
224       errors++;                                                               \
225     } else {                                                                  \
226       check (#FLOAT " isinf (SNaN)", !isinf (SNaN_var));                      \
227     }                                                                         \
228                                                                               \
229   feclearexcept(FE_ALL_EXCEPT);                                               \
230   feenableexcept (FE_ALL_EXCEPT);                                             \
231   if (sigsetjmp(sigfpe_buf, 0))                                               \
232     {                                                                         \
233       printf (#FLOAT " isinf(-SNaN) raised SIGFPE\n");                        \
234       errors++;                                                               \
235     } else {                                                                  \
236       check (#FLOAT " isinf (-SNaN)", !isinf (-SNaN_var));                    \
237     }                                                                         \
238                                                                               \
239   feclearexcept(FE_ALL_EXCEPT);                                               \
240   feenableexcept (FE_ALL_EXCEPT);                                             \
241   if (sigsetjmp(sigfpe_buf, 0))                                               \
242     {                                                                         \
243       printf (#FLOAT " isfinite(NaN) raised SIGFPE\n");                       \
244       errors++;                                                               \
245     } else {                                                                  \
246       check (#FLOAT " isfinite (NaN)", !isfinite (NaN_var));                  \
247     }                                                                         \
248                                                                               \
249   feclearexcept(FE_ALL_EXCEPT);                                               \
250   feenableexcept (FE_ALL_EXCEPT);                                             \
251   if (sigsetjmp(sigfpe_buf, 0))                                               \
252     {                                                                         \
253       printf (#FLOAT " isfinite(-NaN) raised SIGFPE\n");                      \
254       errors++;                                                               \
255     } else {                                                                  \
256       check (#FLOAT " isfinite (-NaN)", !isfinite (-NaN_var));                \
257     }                                                                         \
258                                                                               \
259   feclearexcept(FE_ALL_EXCEPT);                                               \
260   feenableexcept (FE_ALL_EXCEPT);                                             \
261   if (sigsetjmp(sigfpe_buf, 0))                                               \
262     {                                                                         \
263       printf (#FLOAT " isfinite(SNaN) raised SIGFPE\n");                      \
264       errors++;                                                               \
265     } else {                                                                  \
266       check (#FLOAT " isfinite (SNaN)", !isfinite (SNaN_var));                \
267     }                                                                         \
268                                                                               \
269   feclearexcept(FE_ALL_EXCEPT);                                               \
270   feenableexcept (FE_ALL_EXCEPT);                                             \
271   if (sigsetjmp(sigfpe_buf, 0))                                               \
272     {                                                                         \
273       printf (#FLOAT " isfinite(-SNaN) raised SIGFPE\n");                     \
274       errors++;                                                               \
275     } else {                                                                  \
276       check (#FLOAT " isfinite (-SNaN)", !isfinite (-SNaN_var));              \
277     }                                                                         \
278                                                                               \
279   feclearexcept(FE_ALL_EXCEPT);                                               \
280   feenableexcept (FE_ALL_EXCEPT);                                             \
281   if (sigsetjmp(sigfpe_buf, 0))                                               \
282     {                                                                         \
283       printf (#FLOAT " isnormal(NaN) raised SIGFPE\n");                       \
284       errors++;                                                               \
285     } else {                                                                  \
286       check (#FLOAT " isnormal (NaN)", !isnormal (NaN_var));                  \
287     }                                                                         \
288                                                                               \
289   feclearexcept(FE_ALL_EXCEPT);                                               \
290   feenableexcept (FE_ALL_EXCEPT);                                             \
291   if (sigsetjmp(sigfpe_buf, 0))                                               \
292     {                                                                         \
293       printf (#FLOAT " isnormal(-NaN) raised SIGFPE\n");                      \
294       errors++;                                                               \
295     } else {                                                                  \
296       check (#FLOAT " isnormal (-NaN)", !isnormal (-NaN_var));                \
297     }                                                                         \
298                                                                               \
299   feclearexcept(FE_ALL_EXCEPT);                                               \
300   feenableexcept (FE_ALL_EXCEPT);                                             \
301   if (sigsetjmp(sigfpe_buf, 0))                                               \
302     {                                                                         \
303       printf (#FLOAT " isnormal(SNaN) isnormal SIGFPE\n");                    \
304       errors++;                                                               \
305     } else {                                                                  \
306       check (#FLOAT " isnormal (SNaN)", !isnormal (SNaN_var));                \
307     }                                                                         \
308                                                                               \
309   feclearexcept(FE_ALL_EXCEPT);                                               \
310   feenableexcept (FE_ALL_EXCEPT);                                             \
311   if (sigsetjmp(sigfpe_buf, 0))                                               \
312     {                                                                         \
313       printf (#FLOAT " isnormal(-SNaN) raised SIGFPE\n");                     \
314       errors++;                                                               \
315     } else {                                                                  \
316       check (#FLOAT " isnormal (-SNaN)", !isnormal (-SNaN_var));              \
317     }                                                                         \
318                                                                               \
319   feclearexcept(FE_ALL_EXCEPT);                                               \
320   feenableexcept (FE_ALL_EXCEPT);                                             \
321   if (sigsetjmp(sigfpe_buf, 0))                                               \
322     {                                                                         \
323       printf (#FLOAT " fpclassify(NaN) raised SIGFPE\n");                     \
324       errors++;                                                               \
325     } else {                                                                  \
326       check (#FLOAT " fpclassify (NaN)", (fpclassify (NaN_var)==FP_NAN));     \
327     }                                                                         \
328                                                                               \
329   feclearexcept(FE_ALL_EXCEPT);                                               \
330   feenableexcept (FE_ALL_EXCEPT);                                             \
331   if (sigsetjmp(sigfpe_buf, 0))                                               \
332     {                                                                         \
333       printf (#FLOAT " fpclassify(-NaN) raised SIGFPE\n");                    \
334       errors++;                                                               \
335     } else {                                                                  \
336       check (#FLOAT " fpclassify (-NaN)", (fpclassify (-NaN_var)==FP_NAN));   \
337     }                                                                         \
338                                                                               \
339   feclearexcept(FE_ALL_EXCEPT);                                               \
340   feenableexcept (FE_ALL_EXCEPT);                                             \
341   if (sigsetjmp(sigfpe_buf, 0))                                               \
342     {                                                                         \
343       printf (#FLOAT " fpclassify(SNaN) isnormal SIGFPE\n");                  \
344       errors++;                                                               \
345     } else {                                                                  \
346       check (#FLOAT " fpclassify (SNaN)", (fpclassify (SNaN_var)==FP_NAN));   \
347     }                                                                         \
348                                                                               \
349   feclearexcept(FE_ALL_EXCEPT);                                               \
350   feenableexcept (FE_ALL_EXCEPT);                                             \
351   if (sigsetjmp(sigfpe_buf, 0))                                               \
352     {                                                                         \
353       printf (#FLOAT " fpclassify(-SNaN) raised SIGFPE\n");                   \
354       errors++;                                                               \
355     } else {                                                                  \
356       check (#FLOAT " fpclassify (-SNaN)", (fpclassify (-SNaN_var)==FP_NAN)); \
357     }                                                                         \
358                                                                               \
359   fesetenv(&saved_fenv); /* restore saved fenv */                             \
360   remove_sigaction_FP();                                                      \
361 }
362
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
368
369 static int
370 do_test (void)
371 {
372   init_signaling_nan();
373
374   float_test();
375   double_test();
376 #ifndef NO_LONG_DOUBLE
377   ldouble_test();
378 #endif
379
380   return errors != 0;
381 }
382
383 #define TEST_FUNCTION do_test ()
384 #include "../test-skeleton.c"
385