Fix underflow reporting and tie up loose ends in sparc soft-fp.
authorDavid S. Miller <davem@davemloft.net>
Mon, 28 May 2012 04:02:14 +0000 (21:02 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 May 2012 04:11:42 +0000 (21:11 -0700)
* sysdeps/sparc/sparc32/soft-fp/q_util.c (___Q_numbers): Delete.
(___Q_zero): New.
(__Q_simulate_exceptions): Return void.  Change to simulate
exceptions by writing into the %fsr.
* sysdeps/sparc/sparc64/soft-fp/qp_util.c
(__Qp_handle_exceptions): Likewise.
(numbers): Delete.
* sysdeps/sparc/sparc64/soft-fp/Versions: Remove entry for
__Qp_handle_exceptions.
* sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist: Remove
__Qp_handle_exceptions.
* sysdeps/sparc/sparc32/soft-fp/sfp-machine.h (_FP_DECL_EX): Mark
as unused and give dummy FP_RND_NEAREST initializer.
(FP_INHIBIT_RESULTS): Define.
(___Q_simulate_exceptions): Update declaration.
(FP_HANDLE_EXCEPTIONS): Use ___Q_zero and tidy inline asm
formatting.
* sysdeps/sparc/sparc64/soft-fp/sfp-machine.h (_FP_DECL_EX): Mark
as unused and give dummy FP_RND_NEAREST initializer.
(__Qp_handle_exceptions): Update declaration.
(FP_HANDLE_EXCEPTIONS, QP_NO_EXCEPTIONS): Tidy inline asm
formatting.

ChangeLog
sysdeps/sparc/sparc32/soft-fp/q_util.c
sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
sysdeps/sparc/sparc64/soft-fp/Versions
sysdeps/sparc/sparc64/soft-fp/qp_util.c
sysdeps/sparc/sparc64/soft-fp/sfp-machine.h
sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist

index 9a5cd02..8f64826 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2012-05-27  David S. Miller  <davem@davemloft.net>
+
+       * sysdeps/sparc/sparc32/soft-fp/q_util.c (___Q_numbers): Delete.
+       (___Q_zero): New.
+       (__Q_simulate_exceptions): Return void.  Change to simulate
+       exceptions by writing into the %fsr.
+       * sysdeps/sparc/sparc64/soft-fp/qp_util.c
+       (__Qp_handle_exceptions): Likewise.
+       (numbers): Delete.
+       * sysdeps/sparc/sparc64/soft-fp/Versions: Remove entry for
+       __Qp_handle_exceptions.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist: Remove
+       __Qp_handle_exceptions.
+       * sysdeps/sparc/sparc32/soft-fp/sfp-machine.h (_FP_DECL_EX): Mark
+       as unused and give dummy FP_RND_NEAREST initializer.
+       (FP_INHIBIT_RESULTS): Define.
+       (___Q_simulate_exceptions): Update declaration.
+       (FP_HANDLE_EXCEPTIONS): Use ___Q_zero and tidy inline asm
+       formatting.
+       * sysdeps/sparc/sparc64/soft-fp/sfp-machine.h (_FP_DECL_EX): Mark
+       as unused and give dummy FP_RND_NEAREST initializer.
+       (__Qp_handle_exceptions): Update declaration.
+       (FP_HANDLE_EXCEPTIONS, QP_NO_EXCEPTIONS): Tidy inline asm
+       formatting.
+
 2012-05-27  Thomas Schwinge  <thomas@codesourcery.com>
 
        * sysdeps/sh/sh4/fpu/fclrexcpt.c (feclearexcept): Use fpu_control_t for
index 22f70ba..c4efc10 100644 (file)
@@ -1,7 +1,7 @@
 /* Software floating-point emulation.
    Helper routine for _Q_* routines.
    Simulate exceptions using double arithmetics.
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek (jj@ultra.linux.cz).
 
 
 #include "soft-fp.h"
 
-unsigned long long ___Q_numbers [] = {
-0x0000000000000000ULL, /* Zero */
-0x0010100000000000ULL, /* Very tiny number */
-0x0010000000000000ULL, /* Minimum normalized number */
-0x7fef000000000000ULL, /* A huge double number */
-};
+unsigned long long ___Q_zero = 0x0000000000000000ULL;
 
-double ___Q_simulate_exceptions(int exceptions)
+void ___Q_simulate_exceptions(int exceptions)
 {
-  double d, *p = (double *)___Q_numbers;
-  if (exceptions & FP_EX_INVALID)
-    d = p[0]/p[0];
-  if (exceptions & FP_EX_OVERFLOW)
-    {
-      d = p[3] + p[3];
-      exceptions &= ~FP_EX_INEXACT;
-    }
-  if (exceptions & FP_EX_UNDERFLOW)
-    {
-      if (exceptions & FP_EX_INEXACT)
-        {
-         d = p[2] * p[2];
-         exceptions &= ~FP_EX_INEXACT;
-       }
-      else
-       d = p[1] - p[2];
-    }
-  if (exceptions & FP_EX_DIVZERO)
-    d = 1.0/p[0];
-  if (exceptions & FP_EX_INEXACT)
-    d = p[3] - p[2];
-  return d;
+  fpu_control_t fcw;
+  int tem, ou;
+
+  _FPU_GETCW(fcw);
+
+  tem = (fcw >> 23) & 0x1f;
+
+  ou = exceptions & (FP_EX_OVERFLOW | FP_EX_UNDERFLOW);
+  if (ou & tem)
+    exceptions &= ~FP_EX_INVALID;
+
+  fcw &= ~0x1f;
+  fcw |= (exceptions | (exceptions << 5));
+
+  _FPU_SETCW(fcw);
 }
index 8cdc7c2..4314082 100644 (file)
 #define FP_EX_DIVZERO          (1 << 1)
 #define FP_EX_INEXACT          (1 << 0)
 
-#define _FP_DECL_EX    fpu_control_t _fcw
+#define _FP_DECL_EX \
+  fpu_control_t _fcw __attribute__ ((unused)) = (FP_RND_NEAREST << 30)
 
 #define FP_INIT_ROUNDMODE                                      \
 do {                                                           \
   _FPU_GETCW(_fcw);                                            \
 } while (0)
 
+#define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex)
+
 /* Simulate exceptions using double arithmetics. */
-extern double ___Q_simulate_exceptions(int exc);
+extern void ___Q_simulate_exceptions(int exc);
 
 #define FP_HANDLE_EXCEPTIONS                                   \
 do {                                                           \
@@ -201,11 +204,10 @@ do {                                                              \
       /* This is the common case, so we do it inline.          \
        * We need to clear cexc bits if any.                    \
        */                                                      \
-      extern unsigned long long ___Q_numbers[];                        \
-      __asm__ __volatile__("\
-       ldd [%0], %%f30\n\
-       faddd %%f30, %%f30, %%f30\
-       " : : "r" (___Q_numbers) : "f30");                      \
+      extern unsigned long long ___Q_zero;                     \
+      __asm__ __volatile__("ldd [%0], %%f30\n\t"               \
+                          "faddd %%f30, %%f30, %%f30"          \
+                          : : "r" (&___Q_zero) : "f30");       \
     }                                                          \
   else                                                         \
     ___Q_simulate_exceptions (_fex);                           \
index 4404827..9e89c3c 100644 (file)
@@ -3,6 +3,6 @@ libc {
     _Qp_add; _Qp_cmp; _Qp_cmpe; _Qp_div; _Qp_dtoq; _Qp_feq; _Qp_fge; _Qp_fgt;
     _Qp_fle; _Qp_flt; _Qp_fne; _Qp_itoq; _Qp_mul; _Qp_neg; _Qp_qtod; _Qp_qtoi;
     _Qp_qtos; _Qp_qtoui; _Qp_qtoux; _Qp_qtox; _Qp_sqrt; _Qp_stoq; _Qp_sub;
-    _Qp_uitoq; _Qp_uxtoq; _Qp_xtoq; __Qp_handle_exceptions;
+    _Qp_uitoq; _Qp_uxtoq; _Qp_xtoq;
   }
 }
index fd3043b..358d0e4 100644 (file)
@@ -1,7 +1,7 @@
 /* Software floating-point emulation.
    Helper routine for _Qp_* routines.
    Simulate exceptions using double arithmetics.
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek (jj@ultra.linux.cz).
 
 
 #include "soft-fp.h"
 
-static unsigned long numbers [] = {
-0x7fef000000000000UL, /* A huge double number */
-0x0010100000000000UL, /* Very tiny number */
-0x0010000000000000UL, /* Minimum normalized number */
-0x0000000000000000UL, /* Zero */
-};
-
-double __Qp_handle_exceptions(int exceptions)
+void __Qp_handle_exceptions(int exceptions)
 {
-  double d, *p = (double *)numbers;
-  if (exceptions & FP_EX_INVALID)
-    d = p[3]/p[3];
-  if (exceptions & FP_EX_OVERFLOW)
-    {
-      d = p[0] + p[0];
-      exceptions &= ~FP_EX_INEXACT;
-    }
-  if (exceptions & FP_EX_UNDERFLOW)
-    {
-      if (exceptions & FP_EX_INEXACT)
-        {
-         d = p[2] * p[2];
-         exceptions &= ~FP_EX_INEXACT;
-       }
-      else
-       d = p[1] - p[2];
-    }
-  if (exceptions & FP_EX_DIVZERO)
-    d = 1.0/p[3];
-  if (exceptions & FP_EX_INEXACT)
-    d = p[0] - p[2];
-  return d;
+  fpu_control_t fcw;
+  int tem, ou;
+
+  _FPU_GETCW(fcw);
+
+  tem = (fcw >> 23) & 0x1f;
+
+  ou = exceptions & (FP_EX_OVERFLOW | FP_EX_UNDERFLOW);
+  if (ou & tem)
+    exceptions &= ~FP_EX_INVALID;
+
+  fcw &= ~0x1f;
+  fcw |= (exceptions | (exceptions << 5));
+
+  _FPU_SETCW(fcw);
 }
index 7ec804d..36f92d6 100644 (file)
@@ -92,7 +92,8 @@ do {                                                          \
 #define FP_EX_DIVZERO          (1 << 1)
 #define FP_EX_INEXACT          (1 << 0)
 
-#define _FP_DECL_EX    fpu_control_t _fcw
+#define _FP_DECL_EX \
+  fpu_control_t _fcw __attribute__ ((unused)) = (FP_RND_NEAREST << 30)
 
 #define FP_INIT_ROUNDMODE                                      \
 do {                                                           \
@@ -102,7 +103,7 @@ do {                                                                \
 #define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex)
 
 /* Simulate exceptions using double arithmetics. */
-extern double __Qp_handle_exceptions(int exc);
+extern void __Qp_handle_exceptions(int exc);
 
 #define FP_HANDLE_EXCEPTIONS                                   \
 do {                                                           \
@@ -111,10 +112,9 @@ do {                                                               \
       /* This is the common case, so we do it inline.          \
        * We need to clear cexc bits if any.                    \
        */                                                      \
-      __asm__ __volatile__("\n"                                        \
-"              fzero %%f62\n"                                          \
-"              faddd %%f62, %%f62, %%f62\n"                            \
-"              " : : : "f62");                                         \
+      __asm__ __volatile__("fzero %%f62\n\t"                   \
+                          "faddd %%f62, %%f62, %%f62"          \
+                          : : : "f62");                        \
     }                                                          \
   else                                                         \
     {                                                          \
@@ -136,8 +136,8 @@ do {                                                                \
 } while (0)
 
 #define QP_NO_EXCEPTIONS                                       \
-  __asm ("fzero %%f62\n"                                       \
-"        faddd %%f62, %%f62, %%f62" : : : "f62")
+  __asm ("fzero %%f62\n\t"                                     \
+        "faddd %%f62, %%f62, %%f62" : : : "f62")
                               
 #define QP_CLOBBER "memory", "f52", "f54", "f56", "f58", "f60", "f62"
 #define QP_CLOBBER_CC QP_CLOBBER , "cc"
index 2914d1c..8571fa8 100644 (file)
@@ -248,7 +248,6 @@ GLIBC_2.2
  _Qp_uitoq F
  _Qp_uxtoq F
  _Qp_xtoq F
- __Qp_handle_exceptions F
  __adjtimex F
  __after_morecore_hook D 0x8
  __align_cpy_1 F