This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Simulate sparc fpu exceptions using real FP ops again insoft-fp.


Tested and committed to master.

I'll unify these two routines somehow in the future as they have
identical code yet have different names.

	* sysdeps/sparc/sparc32/soft-fp/q_util.c
	(___Q_simulate_exceptions): Use real FP ops rather than writing
	into the %fsr.
	* sysdeps/sparc/sparc32/soft-fp/q_util.c (__Qp_handle_exceptions):
	Likewise.
---
 ChangeLog                               |    8 +++++
 sysdeps/sparc/sparc32/soft-fp/q_util.c  |   49 +++++++++++++++++++++----------
 sysdeps/sparc/sparc64/soft-fp/qp_util.c |   49 +++++++++++++++++++++----------
 3 files changed, 76 insertions(+), 30 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f7090ec..067a91a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2012-05-30  David S. Miller  <davem@davemloft.net>
+
+	* sysdeps/sparc/sparc32/soft-fp/q_util.c
+	(___Q_simulate_exceptions): Use real FP ops rather than writing
+	into the %fsr.
+	* sysdeps/sparc/sparc32/soft-fp/q_util.c (__Qp_handle_exceptions):
+	Likewise.
+
 2012-05-30  H.J. Lu  <hongjiu.lu@intel.com>
 
 	[BZ #14117]
diff --git a/sysdeps/sparc/sparc32/soft-fp/q_util.c b/sysdeps/sparc/sparc32/soft-fp/q_util.c
index c4efc10..47e34c7 100644
--- a/sysdeps/sparc/sparc32/soft-fp/q_util.c
+++ b/sysdeps/sparc/sparc32/soft-fp/q_util.c
@@ -19,25 +19,44 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <float.h>
+#include <math.h>
+#include <assert.h>
 #include "soft-fp.h"
 
 unsigned long long ___Q_zero = 0x0000000000000000ULL;
 
 void ___Q_simulate_exceptions(int exceptions)
 {
-  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);
+  if (exceptions & FP_EX_INVALID)
+    {
+      float f = 0.0;
+      __asm__ __volatile__ ("fdivs %0, %0, %0" : "+f" (f));
+    }
+  if (exceptions & FP_EX_DIVZERO)
+    {
+      float f = 1.0, g = 0.0;
+      __asm__ __volatile__ ("fdivs %0, %1, %0"
+			    : "+f" (f)
+			    : "f" (g));
+    }
+  if (exceptions & FP_EX_OVERFLOW)
+    {
+      float f = FLT_MAX;
+      __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f));
+      exceptions &= ~FP_EX_INEXACT;
+    }
+  if (exceptions & FP_EX_UNDERFLOW)
+    {
+      float f = FLT_MIN;
+      __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f));
+      exceptions &= ~FP_EX_INEXACT;
+    }
+  if (exceptions & FP_EX_INEXACT)
+    {
+      double d = 1.0, e = M_PI;
+      __asm__ __volatile__ ("fdivd %0, %1, %0"
+			    : "+f" (d)
+			    : "f" (e));
+    }
 }
diff --git a/sysdeps/sparc/sparc64/soft-fp/qp_util.c b/sysdeps/sparc/sparc64/soft-fp/qp_util.c
index 358d0e4..4a1280b 100644
--- a/sysdeps/sparc/sparc64/soft-fp/qp_util.c
+++ b/sysdeps/sparc/sparc64/soft-fp/qp_util.c
@@ -19,23 +19,42 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <float.h>
+#include <math.h>
+#include <assert.h>
 #include "soft-fp.h"
 
 void __Qp_handle_exceptions(int exceptions)
 {
-  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);
+  if (exceptions & FP_EX_INVALID)
+    {
+      float f = 0.0;
+      __asm__ __volatile__ ("fdivs %0, %0, %0" : "+f" (f));
+    }
+  if (exceptions & FP_EX_DIVZERO)
+    {
+      float f = 1.0, g = 0.0;
+      __asm__ __volatile__ ("fdivs %0, %1, %0"
+			    : "+f" (f)
+			    : "f" (g));
+    }
+  if (exceptions & FP_EX_OVERFLOW)
+    {
+      float f = FLT_MAX;
+      __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f));
+      exceptions &= ~FP_EX_INEXACT;
+    }
+  if (exceptions & FP_EX_UNDERFLOW)
+    {
+      float f = FLT_MIN;
+      __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f));
+      exceptions &= ~FP_EX_INEXACT;
+    }
+  if (exceptions & FP_EX_INEXACT)
+    {
+      double d = 1.0, e = M_PI;
+      __asm__ __volatile__ ("fdivd %0, %1, %0"
+			    : "+f" (d)
+			    : "f" (e));
+    }
 }
-- 
1.7.10


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]