patches/mpfr/2.4.2/100-sin_cos_underflow.patch
author Michael Hope <michael.hope@linaro.org>
Wed Oct 19 15:27:32 2011 +1300 (2011-10-19)
changeset 2739 f320e22f2cba
permissions -rw-r--r--
arch: add softfp support

Some architectures support a mixed hard/soft floating point, where
the compiler emits hardware floating point instructions, but passes
the operands in core (aka integer) registers.

For example, ARM supports this mode (to come in the next changeset).

Add support for softfp cross compilers to the GCC and GLIBC
configuration. Needed for Ubuntu and other distros that are softfp.

Signed-off-by: Michael Hope <michael.hope@linaro.org>
[yann.morin.1998@anciens.enib.fr: split the original patch]
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
     1 diff -Naurd mpfr-2.4.2-a/PATCHES mpfr-2.4.2-b/PATCHES
     2 --- mpfr-2.4.2-a/PATCHES	2009-12-07 13:37:12.000000000 +0000
     3 +++ mpfr-2.4.2-b/PATCHES	2009-12-07 13:37:12.000000000 +0000
     4 @@ -0,0 +1 @@
     5 +sin_cos_underflow
     6 diff -Naurd mpfr-2.4.2-a/VERSION mpfr-2.4.2-b/VERSION
     7 --- mpfr-2.4.2-a/VERSION	2009-11-30 02:43:08.000000000 +0000
     8 +++ mpfr-2.4.2-b/VERSION	2009-12-07 13:37:12.000000000 +0000
     9 @@ -1 +1 @@
    10 -2.4.2
    11 +2.4.2-p1
    12 diff -Naurd mpfr-2.4.2-a/mpfr.h mpfr-2.4.2-b/mpfr.h
    13 --- mpfr-2.4.2-a/mpfr.h	2009-11-30 02:43:08.000000000 +0000
    14 +++ mpfr-2.4.2-b/mpfr.h	2009-12-07 13:37:12.000000000 +0000
    15 @@ -27,7 +27,7 @@
    16  #define MPFR_VERSION_MAJOR 2
    17  #define MPFR_VERSION_MINOR 4
    18  #define MPFR_VERSION_PATCHLEVEL 2
    19 -#define MPFR_VERSION_STRING "2.4.2"
    20 +#define MPFR_VERSION_STRING "2.4.2-p1"
    21  
    22  /* Macros dealing with MPFR VERSION */
    23  #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
    24 diff -Naurd mpfr-2.4.2-a/sin_cos.c mpfr-2.4.2-b/sin_cos.c
    25 --- mpfr-2.4.2-a/sin_cos.c	2009-11-30 02:43:09.000000000 +0000
    26 +++ mpfr-2.4.2-b/sin_cos.c	2009-12-07 13:37:12.000000000 +0000
    27 @@ -82,17 +82,19 @@
    28        if (y != x)
    29          /* y and x differ, thus we can safely try to compute y first */
    30          {
    31 -          MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * expx, 2, 0, rnd_mode,
    32 -                                            { inexy = _inexact;
    33 -                                              goto small_input; });
    34 +          MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
    35 +            y, x, -2 * expx, 2, 0, rnd_mode,
    36 +            { inexy = _inexact;
    37 +              goto small_input; });
    38            if (0)
    39              {
    40              small_input:
    41                /* we can go here only if we can round sin(x) */
    42 -              MPFR_FAST_COMPUTE_IF_SMALL_INPUT (z, __gmpfr_one, -2 * expx,
    43 -                                                1, 0, rnd_mode,
    44 -                                                { inexz = _inexact;
    45 -                                                  goto end; });
    46 +              MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
    47 +                z, __gmpfr_one, -2 * expx, 1, 0, rnd_mode,
    48 +                { inexz = _inexact;
    49 +                  MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
    50 +                  goto end; });
    51              }
    52  
    53            /* if we go here, one of the two MPFR_FAST_COMPUTE_IF_SMALL_INPUT
    54 @@ -101,18 +103,19 @@
    55        else /* y and x are the same variable: try to compute z first, which
    56                necessarily differs */
    57          {
    58 -          MPFR_FAST_COMPUTE_IF_SMALL_INPUT (z, __gmpfr_one, -2 * expx,
    59 -                                            1, 0, rnd_mode,
    60 -                                            { inexz = _inexact;
    61 -                                              goto small_input2; });
    62 +          MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
    63 +            z, __gmpfr_one, -2 * expx, 1, 0, rnd_mode,
    64 +            { inexz = _inexact;
    65 +              goto small_input2; });
    66            if (0)
    67              {
    68              small_input2:
    69                /* we can go here only if we can round cos(x) */
    70 -              MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * expx, 2, 0,
    71 -                                                rnd_mode,
    72 -                                                { inexy = _inexact;
    73 -                                                  goto end; });
    74 +              MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
    75 +                y, x, -2 * expx, 2, 0, rnd_mode,
    76 +                { inexy = _inexact;
    77 +                  MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
    78 +                  goto end; });
    79              }
    80          }
    81        m += 2 * (-expx);
    82 @@ -207,7 +210,6 @@
    83    mpfr_clear (xr);
    84  
    85   end:
    86 -  /* FIXME: update the underflow flag if need be. */
    87    MPFR_SAVE_EXPO_FREE (expo);
    88    mpfr_check_range (y, inexy, rnd_mode);
    89    mpfr_check_range (z, inexz, rnd_mode);
    90 diff -Naurd mpfr-2.4.2-a/tests/tsin_cos.c mpfr-2.4.2-b/tests/tsin_cos.c
    91 --- mpfr-2.4.2-a/tests/tsin_cos.c	2009-11-30 02:43:08.000000000 +0000
    92 +++ mpfr-2.4.2-b/tests/tsin_cos.c	2009-12-07 13:37:12.000000000 +0000
    93 @@ -382,23 +382,56 @@
    94  consistency (void)
    95  {
    96    mpfr_t x, s1, s2, c1, c2;
    97 +  mp_exp_t emin, emax;
    98    mp_rnd_t rnd;
    99 +  unsigned int flags_sin, flags_cos, flags, flags_before, flags_ref;
   100 +  int inex_sin, inex_cos, inex, inex_ref;
   101    int i;
   102  
   103 +  emin = mpfr_get_emin ();
   104 +  emax = mpfr_get_emax ();
   105 +
   106    for (i = 0; i <= 10000; i++)
   107      {
   108        mpfr_init2 (x, MPFR_PREC_MIN + (randlimb () % 8));
   109        mpfr_inits2 (MPFR_PREC_MIN + (randlimb () % 8), s1, s2, c1, c2,
   110                     (mpfr_ptr) 0);
   111 -      tests_default_random (x, 256, -5, 50);
   112 -      rnd = RND_RAND ();
   113 -      mpfr_sin (s1, x, rnd);
   114 -      mpfr_cos (c1, x, rnd);
   115 -      mpfr_sin_cos (s2, c2, x, rnd);
   116 -      if (!(mpfr_equal_p (s1, s2) && mpfr_equal_p (c1, c2)))
   117 +      if (i < 8 * GMP_RND_MAX)
   118          {
   119 -          printf ("mpfr_sin_cos and mpfr_sin/mpfr_cos disagree on %s,\nx = ",
   120 -                  mpfr_print_rnd_mode (rnd));
   121 +          int j = i / GMP_RND_MAX;
   122 +          if (j & 1)
   123 +            mpfr_set_emin (MPFR_EMIN_MIN);
   124 +          mpfr_set_si (x, (j & 2) ? 1 : -1, GMP_RNDN);
   125 +          mpfr_set_exp (x, mpfr_get_emin ());
   126 +          rnd = (mpfr_rnd_t) (i % GMP_RND_MAX);
   127 +          flags_before = 0;
   128 +          if (j & 4)
   129 +            mpfr_set_emax (-17);
   130 +        }
   131 +      else
   132 +        {
   133 +          tests_default_random (x, 256, -5, 50);
   134 +          rnd = RND_RAND ();
   135 +          flags_before = (randlimb () & 1) ?
   136 +            (unsigned int) (MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE) :
   137 +            (unsigned int) 0;
   138 +        }
   139 +      __gmpfr_flags = flags_before;
   140 +      inex_sin = mpfr_sin (s1, x, rnd);
   141 +      flags_sin = __gmpfr_flags;
   142 +      __gmpfr_flags = flags_before;
   143 +      inex_cos = mpfr_cos (c1, x, rnd);
   144 +      flags_cos = __gmpfr_flags;
   145 +      __gmpfr_flags = flags_before;
   146 +      inex = !!mpfr_sin_cos (s2, c2, x, rnd);
   147 +      flags = __gmpfr_flags;
   148 +      inex_ref = inex_sin || inex_cos;
   149 +      flags_ref = flags_sin | flags_cos;
   150 +      if (!(mpfr_equal_p (s1, s2) && mpfr_equal_p (c1, c2)) ||
   151 +          inex != inex_ref || flags != flags_ref)
   152 +        {
   153 +          printf ("mpfr_sin_cos and mpfr_sin/mpfr_cos disagree on %s,"
   154 +                  " i = %d\nx = ", mpfr_print_rnd_mode (rnd), i);
   155            mpfr_dump (x);
   156            printf ("s1 = ");
   157            mpfr_dump (s1);
   158 @@ -408,9 +441,16 @@
   159            mpfr_dump (c1);
   160            printf ("c2 = ");
   161            mpfr_dump (c2);
   162 +          printf ("inex_sin = %d, inex_cos = %d, inex = %d (expected %d)\n",
   163 +                  inex_sin, inex_cos, inex, inex_ref);
   164 +          printf ("flags_sin = 0x%x, flags_cos = 0x%x, "
   165 +                  "flags = 0x%x (expected 0x%x)\n",
   166 +                  flags_sin, flags_cos, flags, flags_ref);
   167            exit (1);
   168          }
   169        mpfr_clears (x, s1, s2, c1, c2, (mpfr_ptr) 0);
   170 +      mpfr_set_emin (emin);
   171 +      mpfr_set_emax (emax);
   172      }
   173  }
   174  
   175 diff -Naurd mpfr-2.4.2-a/version.c mpfr-2.4.2-b/version.c
   176 --- mpfr-2.4.2-a/version.c	2009-11-30 02:43:08.000000000 +0000
   177 +++ mpfr-2.4.2-b/version.c	2009-12-07 13:37:12.000000000 +0000
   178 @@ -25,5 +25,5 @@
   179  const char *
   180  mpfr_get_version (void)
   181  {
   182 -  return "2.4.2";
   183 +  return "2.4.2-p1";
   184  }