Back to index

glibc  2.9
test-powerpc-snan.c
Go to the documentation of this file.
00001 /* Test Signalling NaN in isnan, isinf etc functions.
00002    Copyright (C) 2008 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Andreas Jaeger <aj@suse.de>, 2005.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #define _GNU_SOURCE
00022 #define __USE_GNU
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <sys/time.h>
00026 #include <string.h>
00027 #include <math.h>
00028 #include <float.h>
00029 #include <fenv.h>
00030 #include <signal.h>
00031 #include <setjmp.h>
00032 #include <errno.h>
00033 
00034 int dest_offset;
00035 char *dest_address;
00036 double value = 123.456;
00037 double zero = 0.0;
00038 
00039 float SNANf;
00040 double SNAN;
00041 long double SNANl;
00042 
00043 static sigjmp_buf sigfpe_buf;
00044 
00045 void
00046 init_signaling_nan()
00047 {
00048     union {
00049        double _ld16;
00050        double _d8;
00051        unsigned int _ui4[4];
00052        float _f4;
00053     } nan_temp;
00054     
00055     nan_temp._ui4[0] = 0x7fa00000;
00056     SNANf = nan_temp._f4;
00057 
00058     nan_temp._ui4[0] = 0x7ff40000;
00059     nan_temp._ui4[1] = 0x00000000;
00060     SNAN = nan_temp._d8;
00061 
00062     nan_temp._ui4[0] = 0x7ff40000;
00063     nan_temp._ui4[1] = 0x00000000;
00064     nan_temp._ui4[2] = 0x00000000;
00065     nan_temp._ui4[3] = 0x00000000;
00066     SNANl = nan_temp._ld16;
00067 }
00068 
00069 static float
00070 snan_float (void)
00071 {
00072   return SNANf;
00073 }
00074 
00075 static double
00076 snan_double (void)
00077 {
00078   return SNAN;
00079 }
00080 
00081 typedef long double ldouble;
00082 
00083 static ldouble
00084 snan_ldouble (void)
00085 {
00086   return SNANl;
00087 }
00088 
00089 
00090 void
00091 myFPsighandler(int signal,
00092              siginfo_t *info,
00093              void *context)
00094 {
00095   siglongjmp(sigfpe_buf, 0);
00096 }
00097 
00098 int
00099 set_sigaction_FP(void)
00100 {
00101     struct sigaction sa;
00102     /* register RT signal handler via sigaction */
00103     sa.sa_flags = SA_SIGINFO;
00104     sa.sa_sigaction = &myFPsighandler;
00105     sigemptyset(&sa.sa_mask);
00106     sigaction(SIGFPE, &sa, NULL);
00107 
00108     return 0;
00109 }
00110 
00111 int
00112 remove_sigaction_FP(void)
00113 {
00114     struct sigaction sa;
00115     /* restore default RT signal handler via sigaction */
00116     sa.sa_flags = SA_SIGINFO;
00117     sa.sa_handler = SIG_DFL;
00118     sigemptyset(&sa.sa_mask);
00119     sigaction(SIGFPE, &sa, NULL);
00120 
00121     return 0;
00122 }
00123 
00124 static int errors = 0;
00125 
00126 static void
00127 check (const char *testname, int result)
00128 {
00129   if (!result) {
00130     printf ("Failure: %s\n", testname);
00131     errors++;
00132   }
00133 }
00134 
00135 #define TEST_FUNC(NAME, FLOAT) \
00136 static void                                                          \
00137 NAME (void)                                                          \
00138 {                                                                    \
00139   /* Variables are declared volatile to forbid some compiler                \
00140      optimizations.  */                                                     \
00141   volatile FLOAT Inf_var, NaN_var, zero_var, one_var, SNaN_var;                    \
00142   fenv_t saved_fenv;                                                 \
00143                                                                      \
00144   zero_var = 0.0;                                                    \
00145   one_var = 1.0;                                                     \
00146   NaN_var = zero_var / zero_var;                                     \
00147   SNaN_var = snan_##FLOAT ();                                               \
00148   Inf_var = one_var / zero_var;                                             \
00149                                                                      \
00150   (void) &zero_var;                                                  \
00151   (void) &one_var;                                                   \
00152   (void) &NaN_var;                                                   \
00153   (void) &SNaN_var;                                                  \
00154   (void) &Inf_var;                                                   \
00155                                                                      \
00156   set_sigaction_FP ();                                                      \
00157   fegetenv(&saved_fenv);                                             \
00158                                                                      \
00159   feclearexcept(FE_ALL_EXCEPT);                                             \
00160   feenableexcept (FE_ALL_EXCEPT);                                    \
00161   if (sigsetjmp(sigfpe_buf, 0))                                             \
00162     {                                                                \
00163       printf (#FLOAT " isnan(NaN) raised SIGFPE\n");                        \
00164       errors++;                                                             \
00165     } else {                                                         \
00166       check (#FLOAT " isnan (NaN)", isnan (NaN_var));                       \
00167     }                                                                \
00168                                                                      \
00169   feclearexcept(FE_ALL_EXCEPT);                                             \
00170   feenableexcept (FE_ALL_EXCEPT);                                    \
00171   if (sigsetjmp(sigfpe_buf, 0))                                             \
00172     {                                                                \
00173       printf (#FLOAT " isnan(-NaN) raised SIGFPE\n");                       \
00174       errors++;                                                             \
00175     } else {                                                         \
00176       check (#FLOAT " isnan (-NaN)", isnan (-NaN_var));                     \
00177     }                                                                \
00178                                                                      \
00179   feclearexcept(FE_ALL_EXCEPT);                                             \
00180   feenableexcept (FE_ALL_EXCEPT);                                    \
00181   if (sigsetjmp(sigfpe_buf, 0))                                             \
00182     {                                                                \
00183       printf (#FLOAT " isnan(SNaN) raised SIGFPE\n");                       \
00184       errors++;                                                             \
00185     } else {                                                         \
00186       check (#FLOAT " isnan (SNaN)", isnan (SNaN_var));                     \
00187     }                                                                \
00188                                                                      \
00189   feclearexcept(FE_ALL_EXCEPT);                                             \
00190   feenableexcept (FE_ALL_EXCEPT);                                    \
00191   if (sigsetjmp(sigfpe_buf, 0))                                             \
00192     {                                                                \
00193       printf (#FLOAT " isnan(-SNaN) raised SIGFPE\n");                      \
00194       errors++;                                                             \
00195     } else {                                                         \
00196       check (#FLOAT " isnan (-SNaN)", isnan (-SNaN_var));                   \
00197     }                                                                \
00198                                                                      \
00199   feclearexcept(FE_ALL_EXCEPT);                                             \
00200   feenableexcept (FE_ALL_EXCEPT);                                    \
00201   if (sigsetjmp(sigfpe_buf, 0))                                             \
00202     {                                                                \
00203       printf (#FLOAT " isinf(NaN) raised SIGFPE\n");                        \
00204       errors++;                                                             \
00205     } else {                                                         \
00206       check (#FLOAT " isinf (NaN)", !isinf (NaN_var));                      \
00207     }                                                                \
00208                                                                      \
00209   feclearexcept(FE_ALL_EXCEPT);                                             \
00210   feenableexcept (FE_ALL_EXCEPT);                                    \
00211   if (sigsetjmp(sigfpe_buf, 0))                                             \
00212     {                                                                \
00213       printf (#FLOAT " isinf(-NaN) raised SIGFPE\n");                       \
00214       errors++;                                                             \
00215     } else {                                                         \
00216       check (#FLOAT " isinf (-NaN)", !isinf (-NaN_var));                    \
00217     }                                                                \
00218                                                                      \
00219   feclearexcept(FE_ALL_EXCEPT);                                             \
00220   feenableexcept (FE_ALL_EXCEPT);                                    \
00221   if (sigsetjmp(sigfpe_buf, 0))                                             \
00222     {                                                                \
00223       printf (#FLOAT " isinf(SNaN) raised SIGFPE\n");                       \
00224       errors++;                                                             \
00225     } else {                                                         \
00226       check (#FLOAT " isinf (SNaN)", !isinf (SNaN_var));                    \
00227     }                                                                \
00228                                                                      \
00229   feclearexcept(FE_ALL_EXCEPT);                                             \
00230   feenableexcept (FE_ALL_EXCEPT);                                    \
00231   if (sigsetjmp(sigfpe_buf, 0))                                             \
00232     {                                                                \
00233       printf (#FLOAT " isinf(-SNaN) raised SIGFPE\n");                      \
00234       errors++;                                                             \
00235     } else {                                                         \
00236       check (#FLOAT " isinf (-SNaN)", !isinf (-SNaN_var));                  \
00237     }                                                                \
00238                                                                      \
00239   feclearexcept(FE_ALL_EXCEPT);                                             \
00240   feenableexcept (FE_ALL_EXCEPT);                                    \
00241   if (sigsetjmp(sigfpe_buf, 0))                                             \
00242     {                                                                \
00243       printf (#FLOAT " isfinite(NaN) raised SIGFPE\n");                     \
00244       errors++;                                                             \
00245     } else {                                                         \
00246       check (#FLOAT " isfinite (NaN)", !isfinite (NaN_var));                \
00247     }                                                                \
00248                                                                      \
00249   feclearexcept(FE_ALL_EXCEPT);                                             \
00250   feenableexcept (FE_ALL_EXCEPT);                                    \
00251   if (sigsetjmp(sigfpe_buf, 0))                                             \
00252     {                                                                \
00253       printf (#FLOAT " isfinite(-NaN) raised SIGFPE\n");                    \
00254       errors++;                                                             \
00255     } else {                                                         \
00256       check (#FLOAT " isfinite (-NaN)", !isfinite (-NaN_var));              \
00257     }                                                                \
00258                                                                      \
00259   feclearexcept(FE_ALL_EXCEPT);                                             \
00260   feenableexcept (FE_ALL_EXCEPT);                                    \
00261   if (sigsetjmp(sigfpe_buf, 0))                                             \
00262     {                                                                \
00263       printf (#FLOAT " isfinite(SNaN) raised SIGFPE\n");                    \
00264       errors++;                                                             \
00265     } else {                                                         \
00266       check (#FLOAT " isfinite (SNaN)", !isfinite (SNaN_var));              \
00267     }                                                                \
00268                                                                      \
00269   feclearexcept(FE_ALL_EXCEPT);                                             \
00270   feenableexcept (FE_ALL_EXCEPT);                                    \
00271   if (sigsetjmp(sigfpe_buf, 0))                                             \
00272     {                                                                \
00273       printf (#FLOAT " isfinite(-SNaN) raised SIGFPE\n");                   \
00274       errors++;                                                             \
00275     } else {                                                         \
00276       check (#FLOAT " isfinite (-SNaN)", !isfinite (-SNaN_var));            \
00277     }                                                                \
00278                                                                      \
00279   feclearexcept(FE_ALL_EXCEPT);                                             \
00280   feenableexcept (FE_ALL_EXCEPT);                                    \
00281   if (sigsetjmp(sigfpe_buf, 0))                                             \
00282     {                                                                \
00283       printf (#FLOAT " isnormal(NaN) raised SIGFPE\n");                     \
00284       errors++;                                                             \
00285     } else {                                                         \
00286       check (#FLOAT " isnormal (NaN)", !isnormal (NaN_var));                \
00287     }                                                                \
00288                                                                      \
00289   feclearexcept(FE_ALL_EXCEPT);                                             \
00290   feenableexcept (FE_ALL_EXCEPT);                                    \
00291   if (sigsetjmp(sigfpe_buf, 0))                                             \
00292     {                                                                \
00293       printf (#FLOAT " isnormal(-NaN) raised SIGFPE\n");                    \
00294       errors++;                                                             \
00295     } else {                                                         \
00296       check (#FLOAT " isnormal (-NaN)", !isnormal (-NaN_var));              \
00297     }                                                                \
00298                                                                      \
00299   feclearexcept(FE_ALL_EXCEPT);                                             \
00300   feenableexcept (FE_ALL_EXCEPT);                                    \
00301   if (sigsetjmp(sigfpe_buf, 0))                                             \
00302     {                                                                \
00303       printf (#FLOAT " isnormal(SNaN) isnormal SIGFPE\n");                  \
00304       errors++;                                                             \
00305     } else {                                                         \
00306       check (#FLOAT " isnormal (SNaN)", !isnormal (SNaN_var));              \
00307     }                                                                \
00308                                                                      \
00309   feclearexcept(FE_ALL_EXCEPT);                                             \
00310   feenableexcept (FE_ALL_EXCEPT);                                    \
00311   if (sigsetjmp(sigfpe_buf, 0))                                             \
00312     {                                                                \
00313       printf (#FLOAT " isnormal(-SNaN) raised SIGFPE\n");                   \
00314       errors++;                                                             \
00315     } else {                                                         \
00316       check (#FLOAT " isnormal (-SNaN)", !isnormal (-SNaN_var));            \
00317     }                                                                \
00318                                                                      \
00319   feclearexcept(FE_ALL_EXCEPT);                                             \
00320   feenableexcept (FE_ALL_EXCEPT);                                    \
00321   if (sigsetjmp(sigfpe_buf, 0))                                             \
00322     {                                                                \
00323       printf (#FLOAT " fpclassify(NaN) raised SIGFPE\n");                   \
00324       errors++;                                                             \
00325     } else {                                                         \
00326       check (#FLOAT " fpclassify (NaN)", (fpclassify (NaN_var)==FP_NAN));     \
00327     }                                                                \
00328                                                                      \
00329   feclearexcept(FE_ALL_EXCEPT);                                             \
00330   feenableexcept (FE_ALL_EXCEPT);                                    \
00331   if (sigsetjmp(sigfpe_buf, 0))                                             \
00332     {                                                                \
00333       printf (#FLOAT " fpclassify(-NaN) raised SIGFPE\n");                  \
00334       errors++;                                                             \
00335     } else {                                                         \
00336       check (#FLOAT " fpclassify (-NaN)", (fpclassify (-NaN_var)==FP_NAN));   \
00337     }                                                                \
00338                                                                      \
00339   feclearexcept(FE_ALL_EXCEPT);                                             \
00340   feenableexcept (FE_ALL_EXCEPT);                                    \
00341   if (sigsetjmp(sigfpe_buf, 0))                                             \
00342     {                                                                \
00343       printf (#FLOAT " fpclassify(SNaN) isnormal SIGFPE\n");                \
00344       errors++;                                                             \
00345     } else {                                                         \
00346       check (#FLOAT " fpclassify (SNaN)", (fpclassify (SNaN_var)==FP_NAN));   \
00347     }                                                                \
00348                                                                      \
00349   feclearexcept(FE_ALL_EXCEPT);                                             \
00350   feenableexcept (FE_ALL_EXCEPT);                                    \
00351   if (sigsetjmp(sigfpe_buf, 0))                                             \
00352     {                                                                \
00353       printf (#FLOAT " fpclassify(-SNaN) raised SIGFPE\n");                 \
00354       errors++;                                                             \
00355     } else {                                                         \
00356       check (#FLOAT " fpclassify (-SNaN)", (fpclassify (-SNaN_var)==FP_NAN)); \
00357     }                                                                \
00358                                                                      \
00359   fesetenv(&saved_fenv); /* restore saved fenv */                           \
00360   remove_sigaction_FP();                                             \
00361 }
00362 
00363 TEST_FUNC (float_test, float)
00364 TEST_FUNC (double_test, double)
00365 #ifndef NO_LONG_DOUBLE
00366 TEST_FUNC (ldouble_test, ldouble)
00367 #endif
00368 
00369 static int
00370 do_test (void)
00371 {
00372   init_signaling_nan();
00373 
00374   float_test();
00375   double_test();
00376 #ifndef NO_LONG_DOUBLE
00377   ldouble_test();
00378 #endif
00379 
00380   return errors != 0;
00381 }
00382 
00383 #define TEST_FUNCTION do_test ()
00384 #include "../test-skeleton.c"
00385