Add another fma test.
[platform/upstream/glibc.git] / math / test-snan.c
1 /* Test signaling NaNs in issignaling, isnan, isinf, and similar functions.
2    Copyright (C) 2008-2013 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, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #define _GNU_SOURCE 1
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/time.h>
24 #include <string.h>
25 #include <math.h>
26 #include <float.h>
27 #include <fenv.h>
28 #include <signal.h>
29 #include <setjmp.h>
30 #include <errno.h>
31
32 #include <math-tests.h>
33
34
35 int dest_offset;
36 char *dest_address;
37 double  value = 123.456;
38 double  zero = 0.0;
39
40 static sigjmp_buf sigfpe_buf;
41
42 typedef long double ldouble;
43
44
45 void
46 myFPsighandler(int signal,
47              siginfo_t *info,
48              void *context)
49 {
50   siglongjmp(sigfpe_buf, 0);
51 }
52
53 int
54 set_sigaction_FP(void)
55 {
56     struct sigaction sa;
57     /* register RT signal handler via sigaction */
58     sa.sa_flags = SA_SIGINFO;
59     sa.sa_sigaction = &myFPsighandler;
60     sigemptyset(&sa.sa_mask);
61     sigaction(SIGFPE, &sa, NULL);
62
63     return 0;
64 }
65
66 int
67 remove_sigaction_FP(void)
68 {
69     struct sigaction sa;
70     /* restore default RT signal handler via sigaction */
71     sa.sa_flags = SA_SIGINFO;
72     sa.sa_handler = SIG_DFL;
73     sigemptyset(&sa.sa_mask);
74     sigaction(SIGFPE, &sa, NULL);
75
76     return 0;
77 }
78
79 static int errors = 0;
80
81 static void
82 check (const char *testname, int result)
83 {
84   if (!result) {
85     printf ("Failure: %s\n", testname);
86     errors++;
87   }
88 }
89
90 #define TEST_FUNC(NAME, FLOAT, SUFFIX)                                        \
91 static void                                                                   \
92 NAME (void)                                                                   \
93 {                                                                             \
94   /* Variables are declared volatile to forbid some compiler                  \
95      optimizations.  */                                                       \
96   volatile FLOAT Inf_var, qNaN_var, zero_var, one_var;                        \
97   /* A sNaN is only guaranteed to be representable in variables with */       \
98   /* static (or thread-local) storage duration.  */                           \
99   static volatile FLOAT sNaN_var = __builtin_nans ## SUFFIX ("");             \
100   static volatile FLOAT minus_sNaN_var = -__builtin_nans ## SUFFIX ("");      \
101   fenv_t saved_fenv;                                                          \
102                                                                               \
103   zero_var = 0.0;                                                             \
104   one_var = 1.0;                                                              \
105   qNaN_var = __builtin_nan ## SUFFIX ("");                                    \
106   Inf_var = one_var / zero_var;                                               \
107                                                                               \
108   (void) &zero_var;                                                           \
109   (void) &one_var;                                                            \
110   (void) &qNaN_var;                                                           \
111   (void) &sNaN_var;                                                           \
112   (void) &minus_sNaN_var;                                                     \
113   (void) &Inf_var;                                                            \
114                                                                               \
115   set_sigaction_FP ();                                                        \
116   fegetenv(&saved_fenv);                                                      \
117                                                                               \
118   feclearexcept(FE_ALL_EXCEPT);                                               \
119   feenableexcept (FE_ALL_EXCEPT);                                             \
120   if (sigsetjmp(sigfpe_buf, 0))                                               \
121     {                                                                         \
122       printf (#FLOAT " issignaling (qNaN) raised SIGFPE\n");                  \
123       errors++;                                                               \
124     } else {                                                                  \
125       check (#FLOAT " issignaling (qNaN)", !issignaling (qNaN_var));          \
126     }                                                                         \
127                                                                               \
128   feclearexcept(FE_ALL_EXCEPT);                                               \
129   feenableexcept (FE_ALL_EXCEPT);                                             \
130   if (sigsetjmp(sigfpe_buf, 0))                                               \
131     {                                                                         \
132       printf (#FLOAT " issignaling (-qNaN) raised SIGFPE\n");                 \
133       errors++;                                                               \
134     } else {                                                                  \
135       check (#FLOAT " issignaling (-qNaN)", !issignaling (-qNaN_var));        \
136     }                                                                         \
137                                                                               \
138   feclearexcept(FE_ALL_EXCEPT);                                               \
139   feenableexcept (FE_ALL_EXCEPT);                                             \
140   if (sigsetjmp(sigfpe_buf, 0))                                               \
141     {                                                                         \
142       printf (#FLOAT " issignaling (sNaN) raised SIGFPE\n");                  \
143       errors++;                                                               \
144     } else {                                                                  \
145       check (#FLOAT " issignaling (sNaN)",                                    \
146              SNAN_TESTS (FLOAT) ? issignaling (sNaN_var) : 1);                \
147     }                                                                         \
148                                                                               \
149   feclearexcept(FE_ALL_EXCEPT);                                               \
150   feenableexcept (FE_ALL_EXCEPT);                                             \
151   if (sigsetjmp(sigfpe_buf, 0))                                               \
152     {                                                                         \
153       printf (#FLOAT " issignaling (-sNaN) raised SIGFPE\n");                 \
154       errors++;                                                               \
155     } else {                                                                  \
156       check (#FLOAT " issignaling (-sNaN)",                                   \
157              SNAN_TESTS (FLOAT) ? issignaling (minus_sNaN_var) : 1);          \
158     }                                                                         \
159                                                                               \
160   feclearexcept(FE_ALL_EXCEPT);                                               \
161   feenableexcept (FE_ALL_EXCEPT);                                             \
162   if (sigsetjmp(sigfpe_buf, 0))                                               \
163     {                                                                         \
164       printf (#FLOAT " isnan (qNaN) raised SIGFPE\n");                        \
165       errors++;                                                               \
166     } else {                                                                  \
167       check (#FLOAT " isnan (qNaN)", isnan (qNaN_var));                       \
168     }                                                                         \
169                                                                               \
170   feclearexcept(FE_ALL_EXCEPT);                                               \
171   feenableexcept (FE_ALL_EXCEPT);                                             \
172   if (sigsetjmp(sigfpe_buf, 0))                                               \
173     {                                                                         \
174       printf (#FLOAT " isnan (-qNaN) raised SIGFPE\n");                       \
175       errors++;                                                               \
176     } else {                                                                  \
177       check (#FLOAT " isnan (-qNaN)", isnan (-qNaN_var));                     \
178     }                                                                         \
179                                                                               \
180   feclearexcept(FE_ALL_EXCEPT);                                               \
181   feenableexcept (FE_ALL_EXCEPT);                                             \
182   if (sigsetjmp(sigfpe_buf, 0))                                               \
183     {                                                                         \
184       printf (#FLOAT " isnan (sNaN) raised SIGFPE\n");                        \
185       errors++;                                                               \
186     } else {                                                                  \
187       check (#FLOAT " isnan (sNaN)",                                          \
188              SNAN_TESTS (FLOAT) ? isnan (sNaN_var) : 1);                      \
189     }                                                                         \
190                                                                               \
191   feclearexcept(FE_ALL_EXCEPT);                                               \
192   feenableexcept (FE_ALL_EXCEPT);                                             \
193   if (sigsetjmp(sigfpe_buf, 0))                                               \
194     {                                                                         \
195       printf (#FLOAT " isnan (-sNaN) raised SIGFPE\n");                       \
196       errors++;                                                               \
197     } else {                                                                  \
198       check (#FLOAT " isnan (-sNaN)",                                         \
199              SNAN_TESTS (FLOAT) ? isnan (minus_sNaN_var) : 1);                \
200     }                                                                         \
201                                                                               \
202   feclearexcept(FE_ALL_EXCEPT);                                               \
203   feenableexcept (FE_ALL_EXCEPT);                                             \
204   if (sigsetjmp(sigfpe_buf, 0))                                               \
205     {                                                                         \
206       printf (#FLOAT " isinf (qNaN) raised SIGFPE\n");                        \
207       errors++;                                                               \
208     } else {                                                                  \
209       check (#FLOAT " isinf (qNaN)", !isinf (qNaN_var));                      \
210     }                                                                         \
211                                                                               \
212   feclearexcept(FE_ALL_EXCEPT);                                               \
213   feenableexcept (FE_ALL_EXCEPT);                                             \
214   if (sigsetjmp(sigfpe_buf, 0))                                               \
215     {                                                                         \
216       printf (#FLOAT " isinf (-qNaN) raised SIGFPE\n");                       \
217       errors++;                                                               \
218     } else {                                                                  \
219       check (#FLOAT " isinf (-qNaN)", !isinf (-qNaN_var));                    \
220     }                                                                         \
221                                                                               \
222   feclearexcept(FE_ALL_EXCEPT);                                               \
223   feenableexcept (FE_ALL_EXCEPT);                                             \
224   if (sigsetjmp(sigfpe_buf, 0))                                               \
225     {                                                                         \
226       printf (#FLOAT " isinf (sNaN) raised SIGFPE\n");                        \
227       errors++;                                                               \
228     } else {                                                                  \
229       check (#FLOAT " isinf (sNaN)",                                          \
230              SNAN_TESTS (FLOAT) ? !isinf (sNaN_var) : 1);                     \
231     }                                                                         \
232                                                                               \
233   feclearexcept(FE_ALL_EXCEPT);                                               \
234   feenableexcept (FE_ALL_EXCEPT);                                             \
235   if (sigsetjmp(sigfpe_buf, 0))                                               \
236     {                                                                         \
237       printf (#FLOAT " isinf (-sNaN) raised SIGFPE\n");                       \
238       errors++;                                                               \
239     } else {                                                                  \
240       check (#FLOAT " isinf (-sNaN)",                                         \
241              SNAN_TESTS (FLOAT) ? !isinf (minus_sNaN_var) : 1);               \
242     }                                                                         \
243                                                                               \
244   feclearexcept(FE_ALL_EXCEPT);                                               \
245   feenableexcept (FE_ALL_EXCEPT);                                             \
246   if (sigsetjmp(sigfpe_buf, 0))                                               \
247     {                                                                         \
248       printf (#FLOAT " isfinite (qNaN) raised SIGFPE\n");                     \
249       errors++;                                                               \
250     } else {                                                                  \
251       check (#FLOAT " isfinite (qNaN)", !isfinite (qNaN_var));                \
252     }                                                                         \
253                                                                               \
254   feclearexcept(FE_ALL_EXCEPT);                                               \
255   feenableexcept (FE_ALL_EXCEPT);                                             \
256   if (sigsetjmp(sigfpe_buf, 0))                                               \
257     {                                                                         \
258       printf (#FLOAT " isfinite (-qNaN) raised SIGFPE\n");                    \
259       errors++;                                                               \
260     } else {                                                                  \
261       check (#FLOAT " isfinite (-qNaN)", !isfinite (-qNaN_var));              \
262     }                                                                         \
263                                                                               \
264   feclearexcept(FE_ALL_EXCEPT);                                               \
265   feenableexcept (FE_ALL_EXCEPT);                                             \
266   if (sigsetjmp(sigfpe_buf, 0))                                               \
267     {                                                                         \
268       printf (#FLOAT " isfinite (sNaN) raised SIGFPE\n");                     \
269       errors++;                                                               \
270     } else {                                                                  \
271       check (#FLOAT " isfinite (sNaN)",                                       \
272              SNAN_TESTS (FLOAT) ? !isfinite (sNaN_var) : 1);                  \
273     }                                                                         \
274                                                                               \
275   feclearexcept(FE_ALL_EXCEPT);                                               \
276   feenableexcept (FE_ALL_EXCEPT);                                             \
277   if (sigsetjmp(sigfpe_buf, 0))                                               \
278     {                                                                         \
279       printf (#FLOAT " isfinite (-sNaN) raised SIGFPE\n");                    \
280       errors++;                                                               \
281     } else {                                                                  \
282       check (#FLOAT " isfinite (-sNaN)",                                      \
283              SNAN_TESTS (FLOAT) ? !isfinite (minus_sNaN_var) : 1);            \
284     }                                                                         \
285                                                                               \
286   feclearexcept(FE_ALL_EXCEPT);                                               \
287   feenableexcept (FE_ALL_EXCEPT);                                             \
288   if (sigsetjmp(sigfpe_buf, 0))                                               \
289     {                                                                         \
290       printf (#FLOAT " isnormal (qNaN) raised SIGFPE\n");                     \
291       errors++;                                                               \
292     } else {                                                                  \
293       check (#FLOAT " isnormal (qNaN)", !isnormal (qNaN_var));                \
294     }                                                                         \
295                                                                               \
296   feclearexcept(FE_ALL_EXCEPT);                                               \
297   feenableexcept (FE_ALL_EXCEPT);                                             \
298   if (sigsetjmp(sigfpe_buf, 0))                                               \
299     {                                                                         \
300       printf (#FLOAT " isnormal (-qNaN) raised SIGFPE\n");                    \
301       errors++;                                                               \
302     } else {                                                                  \
303       check (#FLOAT " isnormal (-qNaN)", !isnormal (-qNaN_var));              \
304     }                                                                         \
305                                                                               \
306   feclearexcept(FE_ALL_EXCEPT);                                               \
307   feenableexcept (FE_ALL_EXCEPT);                                             \
308   if (sigsetjmp(sigfpe_buf, 0))                                               \
309     {                                                                         \
310       printf (#FLOAT " isnormal (sNaN) isnormal SIGFPE\n");                   \
311       errors++;                                                               \
312     } else {                                                                  \
313       check (#FLOAT " isnormal (sNaN)",                                       \
314              SNAN_TESTS (FLOAT) ? !isnormal (sNaN_var) : 1);                  \
315     }                                                                         \
316                                                                               \
317   feclearexcept(FE_ALL_EXCEPT);                                               \
318   feenableexcept (FE_ALL_EXCEPT);                                             \
319   if (sigsetjmp(sigfpe_buf, 0))                                               \
320     {                                                                         \
321       printf (#FLOAT " isnormal (-sNaN) raised SIGFPE\n");                    \
322       errors++;                                                               \
323     } else {                                                                  \
324       check (#FLOAT " isnormal (-sNaN)",                                      \
325              SNAN_TESTS (FLOAT) ? !isnormal (minus_sNaN_var) : 1);            \
326     }                                                                         \
327                                                                               \
328   feclearexcept(FE_ALL_EXCEPT);                                               \
329   feenableexcept (FE_ALL_EXCEPT);                                             \
330   if (sigsetjmp(sigfpe_buf, 0))                                               \
331     {                                                                         \
332       printf (#FLOAT " fpclassify (qNaN) raised SIGFPE\n");                   \
333       errors++;                                                               \
334     } else {                                                                  \
335       check (#FLOAT " fpclassify (qNaN)", (fpclassify (qNaN_var)==FP_NAN));   \
336     }                                                                         \
337                                                                               \
338   feclearexcept(FE_ALL_EXCEPT);                                               \
339   feenableexcept (FE_ALL_EXCEPT);                                             \
340   if (sigsetjmp(sigfpe_buf, 0))                                               \
341     {                                                                         \
342       printf (#FLOAT " fpclassify (-qNaN) raised SIGFPE\n");                  \
343       errors++;                                                               \
344     } else {                                                                  \
345       check (#FLOAT " fpclassify (-qNaN)", (fpclassify (-qNaN_var)==FP_NAN)); \
346     }                                                                         \
347                                                                               \
348   feclearexcept(FE_ALL_EXCEPT);                                               \
349   feenableexcept (FE_ALL_EXCEPT);                                             \
350   if (sigsetjmp(sigfpe_buf, 0))                                               \
351     {                                                                         \
352       printf (#FLOAT " fpclassify (sNaN) isnormal SIGFPE\n");                 \
353       errors++;                                                               \
354     } else {                                                                  \
355       check (#FLOAT " fpclassify (sNaN)",                                     \
356              SNAN_TESTS (FLOAT) ? fpclassify (sNaN_var) == FP_NAN : 1);       \
357     }                                                                         \
358                                                                               \
359   feclearexcept(FE_ALL_EXCEPT);                                               \
360   feenableexcept (FE_ALL_EXCEPT);                                             \
361   if (sigsetjmp(sigfpe_buf, 0))                                               \
362     {                                                                         \
363       printf (#FLOAT " fpclassify (-sNaN) raised SIGFPE\n");                  \
364       errors++;                                                               \
365     } else {                                                                  \
366       check (#FLOAT " fpclassify (-sNaN)",                                    \
367              SNAN_TESTS (FLOAT) ? fpclassify (minus_sNaN_var) == FP_NAN : 1); \
368     }                                                                         \
369                                                                               \
370   fesetenv(&saved_fenv); /* restore saved fenv */                             \
371   remove_sigaction_FP();                                                      \
372 }
373
374 TEST_FUNC (float_test, float, f)
375 TEST_FUNC (double_test, double, )
376 #ifndef NO_LONG_DOUBLE
377 TEST_FUNC (ldouble_test, ldouble, l)
378 #endif
379
380 static int
381 do_test (void)
382 {
383   float_test();
384   double_test();
385 #ifndef NO_LONG_DOUBLE
386   ldouble_test();
387 #endif
388
389   return errors != 0;
390 }
391
392 #define TEST_FUNCTION do_test ()
393 #include "../test-skeleton.c"