about summary refs log tree commit diff
path: root/sysdeps/sparc/sparc32
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-05-27 21:02:14 -0700
committerDavid S. Miller <davem@davemloft.net>2012-05-27 21:11:42 -0700
commitd66ef399f5a9e1656fe8e435a8fa655cf271b676 (patch)
treefa8fa1a3d009ccbac649f4587ede51c4e2d0b871 /sysdeps/sparc/sparc32
parent04fb54b50745587b5bfb7baff66ac9f69ac92db9 (diff)
downloadglibc-d66ef399f5a9e1656fe8e435a8fa655cf271b676.tar.gz
glibc-d66ef399f5a9e1656fe8e435a8fa655cf271b676.tar.xz
glibc-d66ef399f5a9e1656fe8e435a8fa655cf271b676.zip
Fix underflow reporting and tie up loose ends in sparc soft-fp.
	* 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.
Diffstat (limited to 'sysdeps/sparc/sparc32')
-rw-r--r--sysdeps/sparc/sparc32/soft-fp/q_util.c49
-rw-r--r--sysdeps/sparc/sparc32/soft-fp/sfp-machine.h16
2 files changed, 27 insertions, 38 deletions
diff --git a/sysdeps/sparc/sparc32/soft-fp/q_util.c b/sysdeps/sparc/sparc32/soft-fp/q_util.c
index 22f70ba467..c4efc10bf8 100644
--- a/sysdeps/sparc/sparc32/soft-fp/q_util.c
+++ b/sysdeps/sparc/sparc32/soft-fp/q_util.c
@@ -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).
 
@@ -21,36 +21,23 @@
 
 #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);
 }
diff --git a/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h b/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
index 8cdc7c2677..4314082f70 100644
--- a/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
+++ b/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
@@ -184,15 +184,18 @@
 #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);			        \