Update.
authorUlrich Drepper <drepper@redhat.com>
Sun, 3 Dec 2000 10:00:46 +0000 (10:00 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 3 Dec 2000 10:00:46 +0000 (10:00 +0000)
2000-12-03  Ulrich Drepper  <drepper@redhat.com>

* math/test-misc.c (main): Add tests for frexp.
Reported by Fred J. Tydeman <tydeman@tybor.com>.
* sysdeps/i386/fpu/s_frexpl.S: Don't overflow during the computation.

ChangeLog
math/test-misc.c
sysdeps/i386/fpu/s_frexpl.S

index b85c7d1..ed1ddaf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2000-12-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * math/test-misc.c (main): Add tests for frexp.
+       Reported by Fred J. Tydeman <tydeman@tybor.com>.
+       * sysdeps/i386/fpu/s_frexpl.S: Don't overflow during the computation.
+
 2000-12-02  H.J. Lu  <hjl@gnu.org>
 
        * locale/lc-time.c (_nl_init_era_entries): Pass L'\0' instead of
index 515277f..c0b8d0f 100644 (file)
@@ -39,6 +39,43 @@ main (void)
        result = 1;
       }
   }
+
+# if __GNUC__ >= 3 || __GNUC_MINOR__ >= 96
+  {
+    long double x = LDBL_MAX / ldexpl (1.0L, LDBL_MANT_DIG + 1);
+    long double m;
+    int i;
+
+#  if LDBL_MANT_DIG == 64
+    m = 0xf.fffffffffffffffp-4L;
+#  else
+#   error "Please adjust"
+#  endif
+
+    for (i = 0; i < LDBL_MANT_DIG + 1; ++i, x *= 2.0L)
+      {
+       long double r;
+       int e;
+
+       printf ("2^%d: ", LDBL_MAX_EXP - (LDBL_MANT_DIG + 1) + i);
+
+       r = frexpl (x, &e);
+       if (r != m)
+         {
+           printf ("mantissa incorrect: %.20La\n", r);
+           result = 1;
+           continue;
+         }
+       if (e != LDBL_MAX_EXP - (LDBL_MANT_DIG + 1) + i)
+         {
+           printf ("exponent wrong %d (%.20Lg)\n", e, x);
+           result = 1;
+           continue;
+         }
+       puts ("ok");
+      }
+  }
+# endif
 #endif
 
   {
index cb943f7..2645d22 100644 (file)
        ASM_TYPE_DIRECTIVE(two64,@object)
 two64: .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x43
        ASM_SIZE_DIRECTIVE(two64)
+       /* The following is LDBL_MAX / ldexp (1.0, 64), the largest
+          number we can handle the normal way.  */
+       ASM_TYPE_DIRECTIVE(largest,@object)
+largest:
+       .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbe, 0x7f, 0, 0
+       ASM_SIZE_DIRECTIVE(largest)
 
 #ifdef PIC
 #define MO(op) op##@GOTOFF(%edx)
@@ -63,12 +69,16 @@ ENTRY (BP_SYM (__frexpl))
        cmpl    $0, %eax
        je      2f
 
+       cmpl    $0x7fbe, %eax
+       ja      4f
+
        fldt    VAL0(%esp)
 #ifdef PIC
        call    3f
 3:     popl    %edx
        addl    $_GLOBAL_OFFSET_TABLE_+[.-3b], %edx
 #endif
+
        fmull   MO(two64)       /* It's not necessary to use a 80bit factor */
        movl    $-64, %ecx
        fstpt   VAL0(%esp)
@@ -92,5 +102,15 @@ ENTRY (BP_SYM (__frexpl))
 
        LEAVE
        ret
+
+4:     movl    VAL2(%esp), %ecx
+       movl    %ecx, %edx
+       andl    $0x7fff, %ecx
+
+       andl    $0x8000, %edx
+       subl    $16382, %ecx
+       orl     $0x3ffe, %edx
+       movl    %edx, VAL2(%esp)
+       jmp     1b
 END (BP_SYM (__frexpl))
 weak_alias (BP_SYM (__frexpl), BP_SYM (frexpl))