public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] fenv fixes for x86_64/i386/ia64
@ 2007-03-22 14:49 Jakub Jelinek
  2007-03-22 21:46 ` Steven Munroe
  0 siblings, 1 reply; 11+ messages in thread
From: Jakub Jelinek @ 2007-03-22 14:49 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Glibc hackers

Hi!

feholdexcept is supposed to clear the sticky exception bits:
"The feholdexcept function saves the current floating-point environment in the object
pointed to by envp, clears the floating-point status flags, and then installs a non-stop
(continue on floating-point exceptions) mode, if available, for all floating-point
exceptions."
and
"A floating-point status flag is a system variable whose value is set
(but never cleared) when a floating-point exception is raised, which occurs as a side effect
of exceptional floating-point arithmetic to provide auxiliary information."

Several feholdexcept implementations didn't handle this right.
Also, e.g. feupdateenv was a stub on x86_64 eventhough it is IMHO easily
implementable and other arches had bugs in it too (e.g. ia64 would rise
wrong exceptions and always return a failure).
I added a new testcase for feholdexcept/feupdateenv (hopefully I haven't
misinterpreted the standard) and I believe other arches (ppc*, s390*, ...)
will need some care too.

2007-03-22  Jakub Jelinek  <jakub@redhat.com>

	[BZ #3427]
	* sysdeps/x86_64/fpu/feholdexcpt.c (feholdexcept): Clear all
	exceptions both in SW and MXCSR.
	* sysdeps/x86_64/fpu/feupdateenv.c: New file.
	* sysdeps/x86_64/fpu/feenablxcpt.c (feenableexcept): Remove dead code.
	* sysdeps/x86_64/fpu/fedisblxcpt.c (fedisableexcept): Likewise.
	* sysdeps/i386/fpu/feholdexcpt.c (feholdexcept): Clear all exceptions
	in MXCSR if SSE is available.
	* sysdeps/i386/fpu/feupdateenv.c: Include unistd.h, dl-procinfo.h
	and ldsodefs.h.
	(__feupdateenv): Query exceptions also from MXCSR if SSE is available.
	Fix comment typo.
	* sysdeps/ia64/fpu/feholdexcpt.c (feholdexcept): Clear all exceptions.
	Return 0 rather than 1.
	* sysdeps/ia64/fpu/feupdateenv.c (feupdateenv): Fix comment typo.
	Remove incorrect part of a comment.  Fix argument to feraiseexcept.
	* math/test-fenv.c (feholdexcept_tests): New function.
	(main): Call it.

2007-01-05  Richard B. Kreckel  <kreckel@ginac.de>

	[BZ #3427]
	* sysdeps/i386/fpu/feholdexcpt.c (feholdexcept): Clear all exceptions
	in SW.

--- libc/math/test-fenv.c.jj	2003-05-22 04:08:50.000000000 +0200
+++ libc/math/test-fenv.c	2007-03-22 14:41:33.000000000 +0100
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997, 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2000, 2001, 2003, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de> and
    Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -636,6 +637,102 @@ feenv_tests (void)
 }
 
 
+static void
+feholdexcept_tests (void)
+{
+  fenv_t saved, saved2;
+  int res;
+
+  feclearexcept (FE_ALL_EXCEPT);
+  fedisableexcept (FE_ALL_EXCEPT);
+#ifdef FE_DIVBYZERO
+  feraiseexcept (FE_DIVBYZERO);
+#endif
+  test_exceptions ("feholdexcept_tests FE_DIVBYZERO test",
+		   DIVBYZERO_EXC, 0);
+  res = feholdexcept (&saved);
+  if (res != 0)
+    {
+      printf ("feholdexcept failed: %d\n", res);
+      ++count_errors;
+    }
+#if defined FE_TONEAREST && defined FE_TOWARDZERO
+  res = fesetround (FE_TOWARDZERO);
+  if (res != 0)
+    {
+      printf ("fesetround failed: %d\n", res);
+      ++count_errors;
+    }
+#endif
+  test_exceptions ("feholdexcept_tests 0 test", NO_EXC, 0);
+  feraiseexcept (FE_INVALID);
+  test_exceptions ("feholdexcept_tests FE_INVALID test",
+		   INVALID_EXC, 0);
+  res = feupdateenv (&saved);
+  if (res != 0)
+    {
+      printf ("feupdateenv failed: %d\n", res);
+      ++count_errors;
+    }
+#if defined FE_TONEAREST && defined FE_TOWARDZERO
+  res = fegetround ();
+  if (res != FE_TONEAREST)
+    {
+      printf ("feupdateenv didn't restore rounding mode: %d\n", res);
+      ++count_errors;
+    }
+#endif
+  test_exceptions ("feholdexcept_tests FE_DIVBYZERO|FE_INVALID test",
+		   DIVBYZERO_EXC | INVALID_EXC, 0);
+  feclearexcept (FE_ALL_EXCEPT);
+  feraiseexcept (FE_INVALID);
+#if defined FE_TONEAREST && defined FE_UPWARD
+  res = fesetround (FE_UPWARD);
+  if (res != 0)
+    {
+      printf ("fesetround failed: %d\n", res);
+      ++count_errors;
+    }
+#endif
+  res = feholdexcept (&saved2);
+  if (res != 0)
+    {
+      printf ("feholdexcept failed: %d\n", res);
+      ++count_errors;
+    }
+#if defined FE_TONEAREST && defined FE_UPWARD
+  res = fesetround (FE_TONEAREST);
+  if (res != 0)
+    {
+      printf ("fesetround failed: %d\n", res);
+      ++count_errors;
+    }
+#endif
+  test_exceptions ("feholdexcept_tests 0 2nd test", NO_EXC, 0);
+  feraiseexcept (FE_INEXACT);
+  test_exceptions ("feholdexcept_tests FE_INEXACT test",
+		   INEXACT_EXC, 0);
+  res = feupdateenv (&saved2);
+  if (res != 0)
+    {
+      printf ("feupdateenv failed: %d\n", res);
+      ++count_errors;
+    }
+#if defined FE_TONEAREST && defined FE_UPWARD
+  res = fegetround ();
+  if (res != FE_UPWARD)
+    {
+      printf ("feupdateenv didn't restore rounding mode: %d\n", res);
+      ++count_errors;
+    }
+  fesetround (FE_TONEAREST);
+#endif
+  test_exceptions ("feholdexcept_tests FE_INEXACT|FE_INVALID test",
+		   INVALID_EXC | INEXACT_EXC, 0);
+  feclearexcept (FE_ALL_EXCEPT);
+}
+
+
 /* IEC 559 and ISO C99 define a default startup environment */
 static void
 initial_tests (void)
@@ -654,6 +751,7 @@ main (void)
   initial_tests ();
   fe_tests ();
   feenv_tests ();
+  feholdexcept_tests ();
 
   if (count_errors)
     {
--- libc/sysdeps/ia64/fpu/feholdexcpt.c.jj	2005-07-08 20:52:46.000000000 +0200
+++ libc/sysdeps/ia64/fpu/feholdexcpt.c	2007-03-22 13:28:45.000000000 +0100
@@ -1,5 +1,5 @@
 /* Store current floating-point environment and clear exceptions.
-   Copyright (C) 1997, 1999, 2000, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2000, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999
 
@@ -23,12 +23,20 @@
 int
 feholdexcept (fenv_t *envp)
 {
+  fenv_t fpsr;
   /* Save the current state.  */
-  fegetenv (envp);
+  __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
+  *envp = fpsr;
 
-  /* set the trap disable bit */
-  __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (*envp | FE_ALL_EXCEPT));
+  /* Set the trap disable bits.  */
+  fpsr |= FE_ALL_EXCEPT;
 
-  return 1;
+  /* And clear the exception bits.  */
+  fpsr &= ~(fenv_t) (FE_ALL_EXCEPT << 13);
+
+  __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (fpsr));
+
+  /* Success.  */
+  return 0;
 }
 libm_hidden_def (feholdexcept)
--- libc/sysdeps/ia64/fpu/feupdateenv.c.jj	2001-07-06 06:55:54.000000000 +0200
+++ libc/sysdeps/ia64/fpu/feupdateenv.c	2007-03-22 13:27:28.000000000 +0100
@@ -1,5 +1,5 @@
 /* Install given floating-point environment and raise exceptions.
-   Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997, 2000, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
 
@@ -32,10 +32,8 @@ feupdateenv (const fenv_t *envp)
   /* Install new environment.  */
   fesetenv (envp);
 
-  /* Raise the safed exception.  Incidently for us the implementation
-     defined format of the values in objects of type fexcept_t is the
-     same as the ones specified using the FE_* constants.  */
-  feraiseexcept ((int) fpsr & FE_ALL_EXCEPT);
+  /* Raise the saved exceptions.  */
+  feraiseexcept ((int) (fpsr >> 13) & FE_ALL_EXCEPT);
 
   /* Success.  */
   return 0;
--- libc/sysdeps/i386/fpu/feholdexcpt.c.jj	2005-07-08 20:52:47.000000000 +0200
+++ libc/sysdeps/i386/fpu/feholdexcpt.c	2007-03-22 14:56:35.000000000 +0100
@@ -1,5 +1,6 @@
 /* Store current floating-point environment and clear exceptions.
-   Copyright (C) 1997, 1999, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2003, 2004, 2005, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -26,14 +27,19 @@
 int
 feholdexcept (fenv_t *envp)
 {
-  unsigned short int work;
+  fenv_t temp;
 
   /* Store the environment.  */
-  __asm__ ("fnstenv %0" : "=m" (*envp));
+  __asm__ ("fnstenv %0" : "=m" (temp));
+  *envp = temp;
 
   /* Now set all exceptions to non-stop.  */
-  work = envp->__control_word | 0x3f;
-  __asm__ ("fldcw %0" : : "m" (*&work));
+  temp.__control_word |= 0x3f;
+
+  /* And clear all exceptions.  */
+  temp.__status_word &= ~0x3f;
+
+  __asm__ ("fldenv %0" : : "m" (temp));
 
   /* If the CPU supports SSE we set the MXCSR as well.  */
   if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
@@ -43,8 +49,8 @@ feholdexcept (fenv_t *envp)
       /* Get the current control word.  */
       __asm__ ("stmxcsr %0" : "=m" (*&xwork));
 
-      /* Set all exceptions to non-stop.  */
-      xwork |= 0x1f80;
+      /* Set all exceptions to non-stop and clear them.  */
+      xwork = (xwork | 0x1f80) & ~0x3f;
 
       __asm__ ("ldmxcsr %0" : : "m" (*&xwork));
     }
--- libc/sysdeps/i386/fpu/feupdateenv.c.jj	2001-07-06 06:55:53.000000000 +0200
+++ libc/sysdeps/i386/fpu/feupdateenv.c	2007-03-22 14:47:22.000000000 +0100
@@ -1,5 +1,5 @@
 /* Install given floating-point environment and raise exceptions.
-   Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+   Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,20 +20,29 @@
 
 #include <fenv.h>
 #include <bp-sym.h>
+#include <unistd.h>
+#include <dl-procinfo.h>
+#include <ldsodefs.h>
 
 int
 __feupdateenv (const fenv_t *envp)
 {
   fexcept_t temp;
+  unsigned int xtemp = 0;
 
   /* Save current exceptions.  */
   __asm__ ("fnstsw %0" : "=m" (*&temp));
-  temp &= FE_ALL_EXCEPT;
+
+  /* If the CPU supports SSE we test the MXCSR as well.  */
+  if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+    __asm__ ("stmxcsr %0" : "=m" (*&xtemp));
+
+  temp = (temp | xtemp) & FE_ALL_EXCEPT;
 
   /* Install new environment.  */
   fesetenv (envp);
 
-  /* Raise the safed exception.  Incidently for us the implementation
+  /* Raise the saved exception.  Incidently for us the implementation
      defined format of the values in objects of type fexcept_t is the
      same as the ones specified using the FE_* constants.  */
   feraiseexcept ((int) temp);
--- libc/sysdeps/x86_64/fpu/feholdexcpt.c.jj	2005-07-08 20:52:45.000000000 +0200
+++ libc/sysdeps/x86_64/fpu/feholdexcpt.c	2007-03-22 11:46:47.000000000 +0100
@@ -1,5 +1,5 @@
 /* Store current floating-point environment and clear exceptions.
-   Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -22,19 +22,24 @@
 int
 feholdexcept (fenv_t *envp)
 {
-  unsigned short int work;
   unsigned int mxcsr;
+  fenv_t temp;
 
   /* Store the environment.  */
   __asm__ ("fnstenv %0\n"
-	   "stmxcsr %1" : "=m" (*envp), "=m" (envp->__mxcsr));
+	   "stmxcsr %1" : "=m" (temp), "=m" (temp.__mxcsr));
+  *envp = temp;
 
   /* Now set all exceptions to non-stop, first the x87 FPU.  */
-  work = envp->__control_word | 0x3f;
-  __asm__ ("fldcw %0" : : "m" (*&work));
+  temp.__control_word |= 0x3f;
+
+  /* And clear all exceptions.  */
+  temp.__status_word &= ~0x3f;
+
+  __asm__ ("fldenv %0" : : "m" (temp));
 
   /* Set the SSE MXCSR register.  */
-  mxcsr = envp->__mxcsr | 0x1f80;
+  mxcsr = (envp->__mxcsr | 0x1f80) & ~0x3f;
   __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
 
   return 0;
--- libc/sysdeps/x86_64/fpu/feupdateenv.c.jj	2007-03-22 12:11:41.000000000 +0100
+++ libc/sysdeps/x86_64/fpu/feupdateenv.c	2007-03-22 12:19:23.000000000 +0100
@@ -0,0 +1,51 @@
+/* Install given floating-point environment and raise exceptions.
+   Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+  fexcept_t temp;
+  unsigned int xtemp;
+
+  /* Save current exceptions.  */
+  __asm__ ("fnstsw %0\n\tstmxcsr %1" : "=m" (*&temp), "=m" (xtemp));
+  temp = (temp | xtemp) & FE_ALL_EXCEPT;
+
+  /* Install new environment.  */
+  fesetenv (envp);
+
+  /* Raise the saved exception.  Incidently for us the implementation
+     defined format of the values in objects of type fexcept_t is the
+     same as the ones specified using the FE_* constants.  */
+  feraiseexcept ((int) temp);
+
+  /* Success.  */
+  return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feupdateenv, __old_feupdateenv)
+compat_symbol (libm, __old_feupdateenv, feupdateenv, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __feupdateenv, feupdateenv, GLIBC_2_2);
--- libc/sysdeps/x86_64/fpu/feenablxcpt.c.jj	2001-09-19 12:23:17.000000000 +0200
+++ libc/sysdeps/x86_64/fpu/feenablxcpt.c	2007-03-22 11:24:28.000000000 +0100
@@ -1,5 +1,5 @@
 /* Enable floating-point exceptions.
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 2001.
 
@@ -24,7 +24,7 @@ int
 feenableexcept (int excepts)
 {
   unsigned short int new_exc, old_exc;
-  unsigned int new, old;
+  unsigned int new;
 
   excepts &= FE_ALL_EXCEPT;
 
@@ -40,8 +40,6 @@ feenableexcept (int excepts)
   __asm__ ("stmxcsr %0" : "=m" (*&new));
 
   /* The SSE exception masks are shifted by 7 bits.  */
-  old = (~new) & (FE_ALL_EXCEPT << 7);
-
   new &= ~(excepts << 7);
   __asm__ ("ldmxcsr %0" : : "m" (*&new));
 
--- libc/sysdeps/x86_64/fpu/fedisblxcpt.c.jj	2001-09-19 12:23:17.000000000 +0200
+++ libc/sysdeps/x86_64/fpu/fedisblxcpt.c	2007-03-22 11:26:35.000000000 +0100
@@ -1,5 +1,5 @@
 /* Disable floating-point exceptions.
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 2001.
 
@@ -24,7 +24,7 @@ int
 fedisableexcept (int excepts)
 {
   unsigned short int new_exc, old_exc;
-  unsigned int new, old;
+  unsigned int new;
 
   excepts &= FE_ALL_EXCEPT;
 
@@ -40,8 +40,6 @@ fedisableexcept (int excepts)
   __asm__ ("stmxcsr %0" : "=m" (*&new));
 
   /* The SSE exception masks are shifted by 7 bits.  */
-  old = (~new) & (FE_ALL_EXCEPT << 7);
-
   new |= excepts << 7;
   __asm__ ("ldmxcsr %0" : : "m" (*&new));
 

	Jakub

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] fenv fixes for x86_64/i386/ia64
  2007-03-22 14:49 [PATCH] fenv fixes for x86_64/i386/ia64 Jakub Jelinek
@ 2007-03-22 21:46 ` Steven Munroe
  2007-03-27 15:53   ` [PATCH] PPC fenv fixes Steven Munroe
  0 siblings, 1 reply; 11+ messages in thread
From: Steven Munroe @ 2007-03-22 21:46 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Ulrich Drepper, Glibc hackers, Peter Eberlein

Jakub Jelinek wrote:
> Hi!
>
> feholdexcept is supposed to clear the sticky exception bits:
> "The feholdexcept function saves the current floating-point environment in the object
> pointed to by envp, clears the floating-point status flags, and then installs a non-stop
> (continue on floating-point exceptions) mode, if available, for all floating-point
> exceptions."
> and
> "A floating-point status flag is a system variable whose value is set
> (but never cleared) when a floating-point exception is raised, which occurs as a side effect
> of exceptional floating-point arithmetic to provide auxiliary information."
>
> Several feholdexcept implementations didn't handle this right.
> Also, e.g. feupdateenv was a stub on x86_64 eventhough it is IMHO easily
> implementable and other arches had bugs in it too (e.g. ia64 would rise
> wrong exceptions and always return a failure).
> I added a new testcase for feholdexcept/feupdateenv (hopefully I haven't
> misinterpreted the standard) and I believe other arches (ppc*, s390*, ...)
> will need some care too.
>   

powerpc32 and powerpc64 both show two failures with the new test-fenv:

Test: feholdexcept_tests FE_DIVBYZERO|FE_INVALID test
  Fail: Exception "DIVBYZERO" is not set
  Pass: Exception "INVALID" is set
  Pass: Exception "INEXACT" is not set
  Pass: Exception "UNDERFLOW" is not set
  Pass: Exception "OVERFLOW" is not set

and

Test: feholdexcept_tests FE_INEXACT|FE_INVALID test
  Pass: Exception "DIVBYZERO" is not set
  Fail: Exception "INVALID" is not set
  Pass: Exception "INEXACT" is set
  Pass: Exception "UNDERFLOW" is not set
  Pass: Exception "OVERFLOW" is not set

We will look into this.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] PPC fenv fixes.
  2007-03-22 21:46 ` Steven Munroe
@ 2007-03-27 15:53   ` Steven Munroe
       [not found]     ` <20070327160708.GA355@devserv.devel.redhat.com>
  0 siblings, 1 reply; 11+ messages in thread
From: Steven Munroe @ 2007-03-27 15:53 UTC (permalink / raw)
  To: Glibc hackers; +Cc: Jakub Jelinek, Ulrich Drepper, Peter Eberlein

[-- Attachment #1: Type: text/plain, Size: 1949 bytes --]

Steven Munroe wrote:
> Jakub Jelinek wrote:
>   
>> Hi!
>>
>> feholdexcept is supposed to clear the sticky exception bits:
>> "The feholdexcept function saves the current floating-point environment in the object
>> pointed to by envp, clears the floating-point status flags, and then installs a non-stop
>> (continue on floating-point exceptions) mode, if available, for all floating-point
>> exceptions."
>> and
>> "A floating-point status flag is a system variable whose value is set
>> (but never cleared) when a floating-point exception is raised, which occurs as a side effect
>> of exceptional floating-point arithmetic to provide auxiliary information."
>>
>> Several feholdexcept implementations didn't handle this right.
>> Also, e.g. feupdateenv was a stub on x86_64 eventhough it is IMHO easily
>> implementable and other arches had bugs in it too (e.g. ia64 would rise
>> wrong exceptions and always return a failure).
>> I added a new testcase for feholdexcept/feupdateenv (hopefully I haven't
>> misinterpreted the standard) and I believe other arches (ppc*, s390*, ...)
>> will need some care too.
>>   
>>     
>
> powerpc32 and powerpc64 both show two failures with the new test-fenv:
>
> Test: feholdexcept_tests FE_DIVBYZERO|FE_INVALID test
>   Fail: Exception "DIVBYZERO" is not set
>   Pass: Exception "INVALID" is set
>   Pass: Exception "INEXACT" is not set
>   Pass: Exception "UNDERFLOW" is not set
>   Pass: Exception "OVERFLOW" is not set
>
> and
>
> Test: feholdexcept_tests FE_INEXACT|FE_INVALID test
>   Pass: Exception "DIVBYZERO" is not set
>   Fail: Exception "INVALID" is not set
>   Pass: Exception "INEXACT" is set
>   Pass: Exception "UNDERFLOW" is not set
>   Pass: Exception "OVERFLOW" is not set
>
> We will look into this.
>   
feupdateenv was not merging pending and current exceptions correctly and
caused 2 failures with the new feholdexcept tests. The attached patch
fixes feupdateenv for ppc32/ppc64.



[-- Attachment #2: ppc-feupdateenv-20070327.txt --]
[-- Type: text/plain, Size: 1283 bytes --]

2007-03-26  Steven Munroe  <sjmunroe@us.ibm.com>

	* sysdeps/powerpc/fpu/feupdateenv.c: Change mask to merge exceptions
	from env.


diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/feupdateenv.c libc25/sysdeps/powerpc/fpu/feupdateenv.c
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/feupdateenv.c	2001-07-05 23:56:02.000000000 -0500
+++ libc25/sysdeps/powerpc/fpu/feupdateenv.c	2007-03-27 09:13:54.875363776 -0500
@@ -1,5 +1,5 @@
 /* Install given floating-point environment and raise exceptions.
-   Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+   Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -30,8 +30,10 @@
   new.fenv = *envp;
   old.fenv = fegetenv_register ();
 
-  /* Copy the set exceptions from `old' to `new'.  */
-  new.l[1] = (new.l[1] & 0xE00000FF) | (old.l[1] & 0x1FFFFF00);
+  /* Restore rounding mode and exception enable from *envp and merge
+     exceptions.  Leave fraction rounded/inexact and FP result/CC bits
+     unchanged.  */
+  new.l[1] = (old.l[1] & 0x1FFFFF00) | (new.l[1] & 0x1FF80FFF);
 
   /* Atomically enable and raise (if appropriate) exceptions set in `new'. */
   fesetenv_register (new.fenv);

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] PPC fenv fixes.
       [not found]     ` <20070327160708.GA355@devserv.devel.redhat.com>
@ 2007-03-27 18:07       ` Steven Munroe
  2007-03-28 15:29         ` Steven Munroe
  2007-04-02 16:43       ` [PATCH] [PORTS] PPC fenv fixes for soft-fp Steven Munroe
  1 sibling, 1 reply; 11+ messages in thread
From: Steven Munroe @ 2007-03-27 18:07 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Glibc hackers, Ulrich Drepper, Peter Eberlein

Jakub Jelinek wrote:
> On Tue, Mar 27, 2007 at 11:09:28AM -0500, Steven Munroe wrote:
>   
>> 2007-03-26  Steven Munroe  <sjmunroe@us.ibm.com>
>>
>> 	* sysdeps/powerpc/fpu/feupdateenv.c: Change mask to merge exceptions
>> 	from env.
>>     
>
> Will that actually raise SIGFPE signals when exceptions are enabled?
> From my reading of POSIX that's what should happen with the
> `old' exceptions (and other arches are calling feraiseexcept that will do
> that).  I didn't add a testcase for it because I'm not 100% sure about that.
>
>   
hmmm not unless the SIGFPE is eanbled by the MSR FE bits. So we will
need to call __fe_nomask_env() in feupdateenv similar to what we do in
feenableexcept(). Probably should add the __fe_mask_env() call for when
the application remasks FP exceptions. This allows the hardware to run
faster when we are taking the default action.

I will rework the patch.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] PPC fenv fixes.
  2007-03-27 18:07       ` Steven Munroe
@ 2007-03-28 15:29         ` Steven Munroe
  2007-04-05  2:27           ` Richard Henderson
  0 siblings, 1 reply; 11+ messages in thread
From: Steven Munroe @ 2007-03-28 15:29 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Glibc hackers, Ulrich Drepper, Peter Eberlein

[-- Attachment #1: Type: text/plain, Size: 1575 bytes --]

Steven Munroe wrote:
> Jakub Jelinek wrote:
>   
>> On Tue, Mar 27, 2007 at 11:09:28AM -0500, Steven Munroe wrote:
>>     
>>> 2007-03-26  Steven Munroe  <sjmunroe@us.ibm.com>
>>>
>>> 	* sysdeps/powerpc/fpu/feupdateenv.c: Change mask to merge exceptions
>>> 	from env.
>>>       
>> Will that actually raise SIGFPE signals when exceptions are enabled?
>> From my reading of POSIX that's what should happen with the
>> `old' exceptions (and other arches are calling feraiseexcept that will do
>> that).  I didn't add a testcase for it because I'm not 100% sure about that.
>>   
>>     
> hmmm not unless the SIGFPE is eanbled by the MSR FE bits. So we will
> need to call __fe_nomask_env() in feupdateenv similar to what we do in
> feenableexcept(). Probably should add the __fe_mask_env() call for when
> the application remasks FP exceptions. This allows the hardware to run
> faster when we are taking the default action.
>
> I will rework the patch.
>   
Merges my patch with one from Peter Bergner to use the prctl system to
eanble/disable FP exception when ever the FPSCR exeptions bits:
  FPSCR_VE,        /* invalid operation exception enable */
  FPSCR_OE,        /* overflow exception enable */
  FPSCR_UE,        /* underflow exception enable */
  FPSCR_ZE,        /* zero divide exception enable */
  FPSCR_XE,        /* inexact exception enable */

Change from all disabled to any enabled or any eanbled to all disabled.
This check was already in feenableexcept(). This patch adds the
appropriate eanble/disable calls to fedisableexcept() and __feupdateenv().



[-- Attachment #2: ppc-fenv-20070320.txt --]
[-- Type: text/plain, Size: 10722 bytes --]

2007-03-26  Steven Munroe  <sjmunroe@us.ibm.com>
            Peter Bergner  <bergner@us.ibm.com>

	* sysdeps/powerpc/Versions (GLIBC_2.4): Add __fe_mask_env.
	* sysdeps/powerpc/bits/fenv.h: Declare __fe_nomask_env extern.
	Define FE_MASK_ENV.
	* sysdeps/powerpc/fpu/fe_mask.c: New file.
	* sysdeps/powerpc/fpu/fedisblxcpt.c (fedisableexcept):
	Call __fe_mask_env if all FP exceptions disabled.
	* sysdeps/powerpc/fpu/feupdateenv.c (__feupdateenv): Change mask to
	merge exceptions from env.  Use FE_NOMASK_ENV or FE_MASK_ENV when
	transitioning from all exceptions disabled to any exception enabled
	or visa versa.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_mask.c: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_mask.c: New file.

diff -urN libc25-cvstip-20070320/sysdeps/powerpc/Versions libc25/sysdeps/powerpc/Versions
--- libc25-cvstip-20070320/sysdeps/powerpc/Versions	2004-02-13 21:25:10.000000000 -0600
+++ libc25/sysdeps/powerpc/Versions	2007-03-27 17:00:20.662310456 -0500
@@ -3,6 +3,10 @@
     # symbols used in macros from sysdeps/powerpc/bits/fenv.h
     __fe_dfl_env; __fe_enabled_env; __fe_nonieee_env; __fe_nomask_env;
   }
+  GLIBC_2.4 {
+    # symbols used in macros from sysdeps/powerpc/bits/fenv.h
+    __fe_mask_env;
+  }
 }
 
 libc {
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/bits/fenv.h libc25/sysdeps/powerpc/bits/fenv.h
--- libc25-cvstip-20070320/sysdeps/powerpc/bits/fenv.h	2002-10-17 17:38:37.000000000 -0500
+++ libc25/sysdeps/powerpc/bits/fenv.h	2007-03-27 13:59:43.475316488 -0500
@@ -142,4 +142,8 @@
    performance penalty (but have no other visible effect).  */
 extern const fenv_t *__fe_nomask_env (void);
 # define FE_NOMASK_ENV	(__fe_nomask_env ())
+
+/* Floating-point environment with all exceptions disabled.  */
+extern const fenv_t *__fe_mask_env (void);
+# define FE_MASK_ENV	(__fe_mask_env ())
 #endif
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/Makefile libc25/sysdeps/powerpc/fpu/Makefile
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/Makefile	2004-05-25 23:33:09.000000000 -0500
+++ libc25/sysdeps/powerpc/fpu/Makefile	2007-03-27 14:49:12.307388232 -0500
@@ -1,5 +1,5 @@
 ifeq ($(subdir),math)
-libm-support += fenv_const fe_nomask t_sqrt
+libm-support += fenv_const fe_nomask fe_mask t_sqrt
 
 # libm needs ld.so to access dl_hwcap
 $(objpfx)libm.so: $(elfobjdir)/ld.so
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/fe_mask.c libc25/sysdeps/powerpc/fpu/fe_mask.c
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/fe_mask.c	Wed Dec 31 18:00:00 1969
+++ libc25/sysdeps/powerpc/fpu/fe_mask.c	Tue Mar 27 13:59:43 2007
@@ -0,0 +1,32 @@
+/* Procedure definition for FE_MASK_ENV.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <errno.h>
+
+/* This is presently a stub, until it's decided how the kernels should
+   support this.  */
+
+const fenv_t *
+__fe_mask_env(void)
+{
+  __set_errno (ENOSYS);
+  return FE_DFL_ENV;
+}
+stub_warning (__fe_mask_env)
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/fedisblxcpt.c libc25/sysdeps/powerpc/fpu/fedisblxcpt.c
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/fedisblxcpt.c	2001-07-05 23:56:02.000000000 -0500
+++ libc25/sysdeps/powerpc/fpu/fedisblxcpt.c	2007-03-27 13:59:43.494313600 -0500
@@ -24,7 +24,7 @@
 fedisableexcept (int excepts)
 {
   fenv_union_t fe;
-  int result;
+  int result, new;
 
   result = fegetexcept ();
 
@@ -44,7 +44,11 @@
     fe.l[1] &= ~(1 << (31 - FPSCR_VE));
   fesetenv_register (fe.fenv);
 
-  if ((fegetexcept () & excepts) != 0)
+  new = fegetexcept ();
+  if (new == 0 && result != 0)
+    (void)__fe_mask_env ();
+
+  if ((new & excepts) != 0)
     result = -1;
   return result;
 }
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/feupdateenv.c libc25/sysdeps/powerpc/fpu/feupdateenv.c
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/feupdateenv.c	2001-07-05 23:56:02.000000000 -0500
+++ libc25/sysdeps/powerpc/fpu/feupdateenv.c	2007-03-27 16:50:49.810423368 -0500
@@ -1,5 +1,5 @@
 /* Install given floating-point environment and raise exceptions.
-   Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+   Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -30,8 +30,24 @@
   new.fenv = *envp;
   old.fenv = fegetenv_register ();
 
-  /* Copy the set exceptions from `old' to `new'.  */
-  new.l[1] = (new.l[1] & 0xE00000FF) | (old.l[1] & 0x1FFFFF00);
+  /* Restore rounding mode and exception enable from *envp and merge
+     exceptions.  Leave fraction rounded/inexact and FP result/CC bits
+     unchanged.  */
+  new.l[1] = (old.l[1] & 0x1FFFFF00) | (new.l[1] & 0x1FF80FFF);
+  
+  /* If the old env has no eabled exceptions and the new env has any enabled
+     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put
+     the hardware into "precise mode" and may cause the FPU to run slower on
+     some hardware.  */
+  if ((old.l[1] & 0x000000F8) == 0 && (new.l[1] & 0x000000F8) != 0)
+    FE_NOMASK_ENV;
+  
+  /* If the old env had any eabled exceptions and the new env has no enabled
+     exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+     FPU to run faster because it always takes the default action and can not 
+     generate SIGFPE. */
+  if ((old.l[1] & 0x000000F8) != 0 && (new.l[1] & 0x000000F8) == 0)
+    FE_MASK_ENV;
 
   /* Atomically enable and raise (if appropriate) exceptions set in `new'. */
   fesetenv_register (new.fenv);
diff -urN libc25-cvstip-20070320/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_mask.c libc25/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_mask.c
--- libc25-cvstip-20070320/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_mask.c	Wed Dec 31 18:00:00 1969
+++ libc25/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_mask.c	Tue Mar 27 13:59:43 2007
@@ -0,0 +1,68 @@
+/* Procedure definition for FE_MASK_ENV for Linux/ppc.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sysdep.h>
+#include <sys/prctl.h>
+#include <kernel-features.h>
+
+#if __ASSUME_NEW_PRCTL_SYSCALL == 0
+/* This is rather fiddly under Linux.  We don't have direct access,
+   and there is no system call, but we can change the bits
+   in a signal handler's context...  */
+
+static struct sigaction oact;
+
+static void
+fe_mask_handler (int signum, struct sigcontext *sc)
+{
+  sc->regs->msr &= ~0x900ul;  /* FE0 | FE1 */
+  sigaction (SIGUSR1, &oact, NULL);
+}
+#endif
+
+const fenv_t *
+__fe_mask_env (void)
+{
+#if __ASSUME_NEW_PRCTL_SYSCALL == 0
+# if defined PR_SET_FPEXC && defined PR_FP_EXC_DISABLED
+  int result = INLINE_SYSCALL (prctl, 2, PR_SET_FPEXC, PR_FP_EXC_DISABLED);
+
+  if (result == -1 && errno == EINVAL)
+# endif
+    {
+      struct sigaction act;
+
+      act.sa_handler = (sighandler_t) fe_mask_handler;
+      sigemptyset (&act.sa_mask);
+      act.sa_flags = 0;
+
+      sigaction (SIGUSR1, &act, &oact);
+      raise (SIGUSR1);
+    }
+#else
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, PR_FP_EXC_DISABLED);
+#endif
+
+  return FE_DFL_ENV;
+}
diff -urN libc25-cvstip-20070320/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_mask.c libc25/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_mask.c
--- libc25-cvstip-20070320/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_mask.c	Wed Dec 31 18:00:00 1969
+++ libc25/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_mask.c	Tue Mar 27 13:59:43 2007
@@ -0,0 +1,43 @@
+/* Procedure definition for FE_MASK_ENV for Linux/ppc64.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <errno.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <sys/prctl.h>
+#include <kernel-features.h>
+
+const fenv_t *
+__fe_mask_env (void)
+{
+#if defined PR_SET_FPEXC && defined PR_FP_EXC_DISABLED
+  int result;
+  INTERNAL_SYSCALL_DECL (err);
+  result = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, PR_FP_EXC_DISABLED);
+# ifndef __ASSUME_NEW_PRCTL_SYSCALL
+  if (INTERNAL_SYSCALL_ERROR_P (result, err)
+      && INTERNAL_SYSCALL_ERRNO (result, err) == EINVAL)
+    __set_errno (ENOSYS);
+# endif
+#else
+  __set_errno (ENOSYS);
+#endif
+  return FE_DFL_ENV;
+}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] [PORTS] PPC fenv fixes for soft-fp
       [not found]     ` <20070327160708.GA355@devserv.devel.redhat.com>
  2007-03-27 18:07       ` Steven Munroe
@ 2007-04-02 16:43       ` Steven Munroe
  1 sibling, 0 replies; 11+ messages in thread
From: Steven Munroe @ 2007-04-02 16:43 UTC (permalink / raw)
  To: Jakub Jelinek, libc-ports; +Cc: Glibc hackers, Ulrich Drepper, Peter Eberlein

[-- Attachment #1: Type: text/plain, Size: 762 bytes --]

This change exposes a few bugs in the soft-fp implementations for PPC.
The current feholdexcept implementation has where it uses fesetenv to
resort the current env:

/* Get the current state. */
fegetenv (envp);

u.fenv = *envp;
/* Clear everything except the rounding mode. */
u.l[0] &= 0x3;

/* ?? Should we clear the disabled exceptions as well ?? */

/* Put the new state in effect. */
fesetenv (envp);

Which is incorrect. It should disable exceptions and pass the updated
env to fesetenv:

/* Disable exceptions */
u.l[1] = FE_ALL_EXCEPT;

/* Put the new state in effect. */
fesetenv (&u.fenv);

Finally the powerpc/nofpu version is missing the libm_hidden_def which
results in a link error in make check.

The attached patch fixes all of these problems.


[-- Attachment #2: ports-feholdexcept-20070320.txt --]
[-- Type: text/plain, Size: 1196 bytes --]

2007-04-02  Steven Munroe  <sjmunroe@us.ibm.com>

	* sysdeps/powerpc/nofpu/feholdexcpt.c (feholdexcept): Disable
	exceptions.  Use the updated env in fesetenv().
	Add libm_hidden_def.

diff -urN libc25-cvstip-20070320/ports/sysdeps/powerpc/nofpu/feholdexcpt.c libc25/ports/sysdeps/powerpc/nofpu/feholdexcpt.c
--- libc25-cvstip-20070320/ports/sysdeps/powerpc/nofpu/feholdexcpt.c	2002-10-19 15:06:29.000000000 -0500
+++ libc25/ports/sysdeps/powerpc/nofpu/feholdexcpt.c	2007-04-02 10:57:50.350540888 -0500
@@ -1,6 +1,6 @@
 /* Store current floating-point environment and clear exceptions
    (soft-float edition).
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002.
    This file is part of the GNU C Library.
 
@@ -33,11 +33,12 @@
   u.fenv = *envp;
   /* Clear everything except the rounding mode.  */
   u.l[0] &= 0x3;
-
-  /* ?? Should we clear the disabled exceptions as well ?? */
+  /* Disable exceptions */
+  u.l[1] = FE_ALL_EXCEPT;
 
   /* Put the new state in effect.  */
-  fesetenv (envp);
+  fesetenv (&u.fenv);
 
   return 0;
 }
+libm_hidden_def (feholdexcept)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] PPC fenv fixes.
  2007-03-28 15:29         ` Steven Munroe
@ 2007-04-05  2:27           ` Richard Henderson
  2007-04-05 22:00             ` [PATCH] PPC fenv fixes. 3rd update Steven Munroe
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Henderson @ 2007-04-05  2:27 UTC (permalink / raw)
  To: Steven Munroe
  Cc: Jakub Jelinek, Glibc hackers, Ulrich Drepper, Peter Eberlein

On Wed, Mar 28, 2007 at 10:44:56AM -0500, Steven Munroe wrote:
>     performance penalty (but have no other visible effect).  */
>  extern const fenv_t *__fe_nomask_env (void);
>  # define FE_NOMASK_ENV	(__fe_nomask_env ())
> +
> +/* Floating-point environment with all exceptions disabled.  */
> +extern const fenv_t *__fe_mask_env (void);
> +# define FE_MASK_ENV	(__fe_mask_env ())

This is incorrect.  The mere evaluation of FE_NOMASK_ENV/FE_MASK_ENV
should have no effect at all.  This stuff should be delayed until
the environment is actually installed.

You should be using magic numbers, like in the i386 port.


r~

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] PPC fenv fixes. 3rd update
  2007-04-05  2:27           ` Richard Henderson
@ 2007-04-05 22:00             ` Steven Munroe
  2007-04-14 17:32               ` Jakub Jelinek
  0 siblings, 1 reply; 11+ messages in thread
From: Steven Munroe @ 2007-04-05 22:00 UTC (permalink / raw)
  To: Steven Munroe, Jakub Jelinek, Glibc hackers, Ulrich Drepper,
	Peter Eberlein

[-- Attachment #1: Type: text/plain, Size: 1073 bytes --]

Richard Henderson wrote:
> On Wed, Mar 28, 2007 at 10:44:56AM -0500, Steven Munroe wrote:
>   
>>     performance penalty (but have no other visible effect).  */
>>  extern const fenv_t *__fe_nomask_env (void);
>>  # define FE_NOMASK_ENV	(__fe_nomask_env ())
>> +
>> +/* Floating-point environment with all exceptions disabled.  */
>> +extern const fenv_t *__fe_mask_env (void);
>> +# define FE_MASK_ENV	(__fe_mask_env ())
>>     
>
> This is incorrect.  The mere evaluation of FE_NOMASK_ENV/FE_MASK_ENV
> should have no effect at all.  This stuff should be delayed until
> the environment is actually installed.
>
> You should be using magic numbers, like in the i386 port.
>
>   
Upated the patch to define FE_NOMASK_ENV as FE_ENABLED_ENV and
FE_MASK_ENV as FE_DFL_ENV. On PPC we can't use magic numbers because
fesetenv takes (fenc_t *envp).

This change delays any change to the env until the application calls
fedisblxcpt(), feholdexcpt(), feholdexcept(), fesetenv(), or
feupdateenv(). Those functions will call __fe_mask_env() or
__fe_nomask_env() as appropriate.




[-- Attachment #2: ppc-fenv-20070405.txt --]
[-- Type: text/plain, Size: 14809 bytes --]

2007-04-05  Steven Munroe  <sjmunroe@us.ibm.com>
            Peter Bergner  <bergner@us.ibm.com>

	* sysdeps/powerpc/Versions (GLIBC_2.4): Add __fe_mask_env.
	* sysdeps/powerpc/bits/fenv.h: Declare __fe_mask_env extern.
	Define FE_NOMASK_ENV as FE_EANBLED_ENV.  Define FE_MASK_ENV. 
	* sysdeps/powerpc/fpu/fe_mask.c: New file.
	* sysdeps/powerpc/fpu/fedisblxcpt.c (fedisableexcept):
	Call __fe_mask_env if all FP exceptions disabled.
	* sysdeps/powerpc/fpu/feholdexcpt.c (feholdexcept):
	Call __fe_mask_env if FP exceptions previously enabled.
	* sysdeps/powerpc/fpu/fesetenv.c (fesetenv): Change mask to merge
	exceptions from env.  Use __fe_nomask_env or __fe_mask_env when
	transitioning from all exceptions disabled to any exception enabled
	or visa versa.
	* sysdeps/powerpc/fpu/feupdateenv.c (__feupdateenv): Change mask to
	merge exceptions from env.  Call __fe_nomask_env or __fe_mask_env
	when transitioning from all exceptions disabled to any exception
	enabled or visa versa.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_mask.c: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_mask.c: New file.

diff -urN libc25-cvstip-20070320/sysdeps/powerpc/Versions libc25/sysdeps/powerpc/Versions
--- libc25-cvstip-20070320/sysdeps/powerpc/Versions	2004-02-13 21:25:10.000000000 -0600
+++ libc25/sysdeps/powerpc/Versions	2007-03-27 17:00:20.000000000 -0500
@@ -3,6 +3,10 @@
     # symbols used in macros from sysdeps/powerpc/bits/fenv.h
     __fe_dfl_env; __fe_enabled_env; __fe_nonieee_env; __fe_nomask_env;
   }
+  GLIBC_2.4 {
+    # symbols used in macros from sysdeps/powerpc/bits/fenv.h
+    __fe_mask_env;
+  }
 }
 
 libc {
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/bits/fenv.h libc25/sysdeps/powerpc/bits/fenv.h
--- libc25-cvstip-20070320/sysdeps/powerpc/bits/fenv.h	2002-10-17 17:38:37.000000000 -0500
+++ libc25/sysdeps/powerpc/bits/fenv.h	2007-04-05 15:38:33.561591360 -0500
@@ -137,9 +137,19 @@
 # define FE_NONIEEE_ENV	(&__fe_nonieee_env)
 
 /* Floating-point environment with all exceptions enabled.  Note that
-   just evaluating this value will set the processor into 'FPU
-   exceptions imprecise recoverable' mode, which may cause a significant
-   performance penalty (but have no other visible effect).  */
+   just evaluating this value does not change the processor exception mode.
+   Passing this mask to fesetenv will result in a prctl syscall to change
+   the MSR FE0/FE1 bits to "Precise Mode".  On some processors this will
+   result in slower floating point execution.  This will last until an fenv
+   or exception mask is installed that disables all FP exceptions.  */
 extern const fenv_t *__fe_nomask_env (void);
-# define FE_NOMASK_ENV	(__fe_nomask_env ())
+# define FE_NOMASK_ENV	FE_ENABLED_ENV
+
+/* Floating-point environment with all exceptions disabled.  Note that
+   just evaluating this value does not change the processor exception mode.
+   Passing this mask to fesetenv will result in a prctl syscall to change
+   the MSR FE0/FE1 bits to "Ignore Exceptions Mode".  On most processors
+   this allows the fastest possible floating point execution.  */
+extern const fenv_t *__fe_mask_env (void);
+# define FE_MASK_ENV	FE_DFL_ENV
 #endif
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/Makefile libc25/sysdeps/powerpc/fpu/Makefile
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/Makefile	2004-05-25 23:33:09.000000000 -0500
+++ libc25/sysdeps/powerpc/fpu/Makefile	2007-03-27 14:49:12.000000000 -0500
@@ -1,5 +1,5 @@
 ifeq ($(subdir),math)
-libm-support += fenv_const fe_nomask t_sqrt
+libm-support += fenv_const fe_nomask fe_mask t_sqrt
 
 # libm needs ld.so to access dl_hwcap
 $(objpfx)libm.so: $(elfobjdir)/ld.so
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/fe_mask.c libc25/sysdeps/powerpc/fpu/fe_mask.c
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/fe_mask.c	Wed Dec 31 18:00:00 1969
+++ libc25/sysdeps/powerpc/fpu/fe_mask.c	Tue Mar 27 13:59:43 2007
@@ -0,0 +1,32 @@
+/* Procedure definition for FE_MASK_ENV.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <errno.h>
+
+/* This is presently a stub, until it's decided how the kernels should
+   support this.  */
+
+const fenv_t *
+__fe_mask_env(void)
+{
+  __set_errno (ENOSYS);
+  return FE_DFL_ENV;
+}
+stub_warning (__fe_mask_env)
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/fedisblxcpt.c libc25/sysdeps/powerpc/fpu/fedisblxcpt.c
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/fedisblxcpt.c	2001-07-05 23:56:02.000000000 -0500
+++ libc25/sysdeps/powerpc/fpu/fedisblxcpt.c	2007-03-27 13:59:43.000000000 -0500
@@ -24,7 +24,7 @@
 fedisableexcept (int excepts)
 {
   fenv_union_t fe;
-  int result;
+  int result, new;
 
   result = fegetexcept ();
 
@@ -44,7 +44,11 @@
     fe.l[1] &= ~(1 << (31 - FPSCR_VE));
   fesetenv_register (fe.fenv);
 
-  if ((fegetexcept () & excepts) != 0)
+  new = fegetexcept ();
+  if (new == 0 && result != 0)
+    (void)__fe_mask_env ();
+
+  if ((new & excepts) != 0)
     result = -1;
   return result;
 }
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/feholdexcpt.c libc25/sysdeps/powerpc/fpu/feholdexcpt.c
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/feholdexcpt.c	2005-07-08 13:52:46.000000000 -0500
+++ libc25/sysdeps/powerpc/fpu/feholdexcpt.c	2007-04-05 11:00:01.820520480 -0500
@@ -22,17 +22,24 @@
 int
 feholdexcept (fenv_t *envp)
 {
-  fenv_union_t u;
+  fenv_union_t old, new;
 
-  /* Get the current state.  */
-  u.fenv = *envp = fegetenv_register ();
+  /* Save the currently set exceptions.  */
+  old.fenv = *envp = fegetenv_register ();
 
-  /* Clear everything except for the rounding mode and non-IEEE arithmetic
+  /* Clear everything except for the rounding modes and non-IEEE arithmetic
      flag.  */
-  u.l[1] = u.l[1] & 7;
+  new.l[1] = old.l[1] & 7;
+  new.l[0] = old.l[0];
+  
+  /* If the old env had any eabled exceptions, then mask SIGFPE in the
+     MSR FE0/FE1 bits.  This may allow the FPU to run faster because it
+     always takes the default action and can not generate SIGFPE. */
+  if ((old.l[1] & 0x000000F8) != 0)
+    __fe_mask_env;
 
   /* Put the new state in effect.  */
-  fesetenv_register (u.fenv);
+  fesetenv_register (new.fenv);
 
   return 0;
 }
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/fesetenv.c libc25/sysdeps/powerpc/fpu/fesetenv.c
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/fesetenv.c	2002-09-09 20:26:37.000000000 -0500
+++ libc25/sysdeps/powerpc/fpu/fesetenv.c	2007-04-05 16:06:01.299497056 -0500
@@ -1,5 +1,5 @@
 /* Install given floating-point environment.
-   Copyright (C) 1997,99,2000,01,02 Free Software Foundation, Inc.
+   Copyright (C) 1997,99,2000,01,02,07 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -23,6 +23,26 @@
 int
 __fesetenv (const fenv_t *envp)
 {
+  fenv_union_t old, new;
+
+  /* get the currently set exceptions.  */
+  new.fenv = *envp;
+  old.fenv = fegetenv_register ();
+  
+  /* If the old env has no eabled exceptions and the new env has any enabled
+     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put
+     the hardware into "precise mode" and may cause the FPU to run slower on
+     some hardware.  */
+  if ((old.l[1] & 0x000000F8) == 0 && (new.l[1] & 0x000000F8) != 0)
+    __fe_nomask_env;
+  
+  /* If the old env had any eabled exceptions and the new env has no enabled
+     exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+     FPU to run faster because it always takes the default action and can not 
+     generate SIGFPE. */
+  if ((old.l[1] & 0x000000F8) != 0 && (new.l[1] & 0x000000F8) == 0)
+    __fe_mask_env;
+    
   fesetenv_register (*envp);
 
   /* Success.  */
diff -urN libc25-cvstip-20070320/sysdeps/powerpc/fpu/feupdateenv.c libc25/sysdeps/powerpc/fpu/feupdateenv.c
--- libc25-cvstip-20070320/sysdeps/powerpc/fpu/feupdateenv.c	2001-07-05 23:56:02.000000000 -0500
+++ libc25/sysdeps/powerpc/fpu/feupdateenv.c	2007-04-05 10:31:18.373530120 -0500
@@ -1,5 +1,5 @@
 /* Install given floating-point environment and raise exceptions.
-   Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+   Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -30,8 +30,24 @@
   new.fenv = *envp;
   old.fenv = fegetenv_register ();
 
-  /* Copy the set exceptions from `old' to `new'.  */
-  new.l[1] = (new.l[1] & 0xE00000FF) | (old.l[1] & 0x1FFFFF00);
+  /* Restore rounding mode and exception enable from *envp and merge
+     exceptions.  Leave fraction rounded/inexact and FP result/CC bits
+     unchanged.  */
+  new.l[1] = (old.l[1] & 0x1FFFFF00) | (new.l[1] & 0x1FF80FFF);
+  
+  /* If the old env has no eabled exceptions and the new env has any enabled
+     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put
+     the hardware into "precise mode" and may cause the FPU to run slower on
+     some hardware.  */
+  if ((old.l[1] & 0x000000F8) == 0 && (new.l[1] & 0x000000F8) != 0)
+    __fe_nomask_env;
+  
+  /* If the old env had any eabled exceptions and the new env has no enabled
+     exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+     FPU to run faster because it always takes the default action and can not 
+     generate SIGFPE. */
+  if ((old.l[1] & 0x000000F8) != 0 && (new.l[1] & 0x000000F8) == 0)
+    __fe_mask_env;
 
   /* Atomically enable and raise (if appropriate) exceptions set in `new'. */
   fesetenv_register (new.fenv);
diff -urN libc25-cvstip-20070320/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_mask.c libc25/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_mask.c
--- libc25-cvstip-20070320/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_mask.c	Wed Dec 31 18:00:00 1969
+++ libc25/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_mask.c	Tue Mar 27 13:59:43 2007
@@ -0,0 +1,68 @@
+/* Procedure definition for FE_MASK_ENV for Linux/ppc.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sysdep.h>
+#include <sys/prctl.h>
+#include <kernel-features.h>
+
+#if __ASSUME_NEW_PRCTL_SYSCALL == 0
+/* This is rather fiddly under Linux.  We don't have direct access,
+   and there is no system call, but we can change the bits
+   in a signal handler's context...  */
+
+static struct sigaction oact;
+
+static void
+fe_mask_handler (int signum, struct sigcontext *sc)
+{
+  sc->regs->msr &= ~0x900ul;  /* FE0 | FE1 */
+  sigaction (SIGUSR1, &oact, NULL);
+}
+#endif
+
+const fenv_t *
+__fe_mask_env (void)
+{
+#if __ASSUME_NEW_PRCTL_SYSCALL == 0
+# if defined PR_SET_FPEXC && defined PR_FP_EXC_DISABLED
+  int result = INLINE_SYSCALL (prctl, 2, PR_SET_FPEXC, PR_FP_EXC_DISABLED);
+
+  if (result == -1 && errno == EINVAL)
+# endif
+    {
+      struct sigaction act;
+
+      act.sa_handler = (sighandler_t) fe_mask_handler;
+      sigemptyset (&act.sa_mask);
+      act.sa_flags = 0;
+
+      sigaction (SIGUSR1, &act, &oact);
+      raise (SIGUSR1);
+    }
+#else
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, PR_FP_EXC_DISABLED);
+#endif
+
+  return FE_DFL_ENV;
+}
diff -urN libc25-cvstip-20070320/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_mask.c libc25/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_mask.c
--- libc25-cvstip-20070320/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_mask.c	Wed Dec 31 18:00:00 1969
+++ libc25/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_mask.c	Tue Mar 27 13:59:43 2007
@@ -0,0 +1,43 @@
+/* Procedure definition for FE_MASK_ENV for Linux/ppc64.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <errno.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <sys/prctl.h>
+#include <kernel-features.h>
+
+const fenv_t *
+__fe_mask_env (void)
+{
+#if defined PR_SET_FPEXC && defined PR_FP_EXC_DISABLED
+  int result;
+  INTERNAL_SYSCALL_DECL (err);
+  result = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, PR_FP_EXC_DISABLED);
+# ifndef __ASSUME_NEW_PRCTL_SYSCALL
+  if (INTERNAL_SYSCALL_ERROR_P (result, err)
+      && INTERNAL_SYSCALL_ERRNO (result, err) == EINVAL)
+    __set_errno (ENOSYS);
+# endif
+#else
+  __set_errno (ENOSYS);
+#endif
+  return FE_DFL_ENV;
+}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] PPC fenv fixes. 3rd update
  2007-04-05 22:00             ` [PATCH] PPC fenv fixes. 3rd update Steven Munroe
@ 2007-04-14 17:32               ` Jakub Jelinek
  2007-04-17  0:09                 ` Richard Henderson
  0 siblings, 1 reply; 11+ messages in thread
From: Jakub Jelinek @ 2007-04-14 17:32 UTC (permalink / raw)
  To: Steven Munroe; +Cc: Glibc hackers, Ulrich Drepper, Peter Eberlein

On Thu, Apr 05, 2007 at 05:16:24PM -0500, Steven Munroe wrote:
> > You should be using magic numbers, like in the i386 port.
> >
> >   
> Upated the patch to define FE_NOMASK_ENV as FE_ENABLED_ENV and
> FE_MASK_ENV as FE_DFL_ENV. On PPC we can't use magic numbers because
> fesetenv takes (fenc_t *envp).

Hm, why can't you use the magic numbers?  fesetenv takes (fenv_t *envp)
on all arches, yet all but ppc manage to handle magic numbers.

> +  GLIBC_2.4 {
> +    # symbols used in macros from sysdeps/powerpc/bits/fenv.h
> +    __fe_mask_env;
> +  }

Current glibc development uses GLIBC_2.6.  But I don't think you
want to export this at all.

> +  /* If the old env has no eabled exceptions and the new env has any enabled
> +     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put
> +     the hardware into "precise mode" and may cause the FPU to run slower on
> +     some hardware.  */
> +  if ((old.l[1] & 0x000000F8) == 0 && (new.l[1] & 0x000000F8) != 0)
> +    __fe_nomask_env;

I thought __fe_nomask_env is a function, so __fe_nomask_env just evaluates
to the address of that function and is being thrown away immediately, i.e.
a nop.

> +  /* If the old env had any eabled exceptions and the new env has no enabled
> +     exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
> +     FPU to run faster because it always takes the default action and can not 
> +     generate SIGFPE. */
> +  if ((old.l[1] & 0x000000F8) != 0 && (new.l[1] & 0x000000F8) == 0)
> +    __fe_mask_env;

Here too and in several other places as well.

	Jakub

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] PPC fenv fixes. 3rd update
  2007-04-14 17:32               ` Jakub Jelinek
@ 2007-04-17  0:09                 ` Richard Henderson
       [not found]                   ` <20070417002157.GI355@devserv.devel.redhat.com>
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Henderson @ 2007-04-17  0:09 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: Steven Munroe, Glibc hackers, Ulrich Drepper, Peter Eberlein

On Sat, Apr 14, 2007 at 07:38:39PM +0200, Jakub Jelinek wrote:
> Hm, why can't you use the magic numbers?  fesetenv takes (fenv_t *envp)
> on all arches, yet all but ppc manage to handle magic numbers.

Assuming a userland has all bits available for user mapping,
there may be no easy space to reserve.  In which case I'd export
some dummy variables from libc, and compare vs their addresses.


r~

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] PPC fenv fixes. 3rd update
       [not found]                   ` <20070417002157.GI355@devserv.devel.redhat.com>
@ 2007-04-30 21:45                     ` Steven Munroe
  0 siblings, 0 replies; 11+ messages in thread
From: Steven Munroe @ 2007-04-30 21:45 UTC (permalink / raw)
  To: Jakub Jelinek, Glibc hackers, Richard Henderson
  Cc: Ulrich Drepper, Peter Eberlein

Jakub Jelinek wrote:
> On Mon, Apr 16, 2007 at 05:07:25PM -0700, Richard Henderson wrote:
>   
>> On Sat, Apr 14, 2007 at 07:38:39PM +0200, Jakub Jelinek wrote:
>>     
>>> Hm, why can't you use the magic numbers?  fesetenv takes (fenv_t *envp)
>>> on all arches, yet all but ppc manage to handle magic numbers.
>>>       
>> Assuming a userland has all bits available for user mapping,
>> there may be no easy space to reserve.  In which case I'd export
>> some dummy variables from libc, and compare vs their addresses.
>>     
>
> Even then, as fenv_t is 64-bit on ppc (double), values
> (const fenv_t *)-7 through (const fenv_t *)-1 can be safely used
> as magic numbers - a valid fenv_t object can't cross the end of
> the address space.
>
>   
Sorry for the delayed responce, I was on vacation.

Actually the problem is the FPSCR is floating point register and can
only be transfer to/from a FPR. That is why fenv_t is defined as double
*. Also with Power6 the FPSCR contains DFP rounding bits in the high
32-bits of the double.

So passing a magic number that is not a double or a pointer to double
would require an extra GPR store just to reload it as an FPR for
transfer to the FPSCR. This would only complicate things.

Also FE_ENABLED_ENV and FE_DFL_ENV are #defines to the addresses of
existing static doubles which already contain the appropriate magic
numbers. So why shouldn't I use them?

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2007-04-30 21:45 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-22 14:49 [PATCH] fenv fixes for x86_64/i386/ia64 Jakub Jelinek
2007-03-22 21:46 ` Steven Munroe
2007-03-27 15:53   ` [PATCH] PPC fenv fixes Steven Munroe
     [not found]     ` <20070327160708.GA355@devserv.devel.redhat.com>
2007-03-27 18:07       ` Steven Munroe
2007-03-28 15:29         ` Steven Munroe
2007-04-05  2:27           ` Richard Henderson
2007-04-05 22:00             ` [PATCH] PPC fenv fixes. 3rd update Steven Munroe
2007-04-14 17:32               ` Jakub Jelinek
2007-04-17  0:09                 ` Richard Henderson
     [not found]                   ` <20070417002157.GI355@devserv.devel.redhat.com>
2007-04-30 21:45                     ` Steven Munroe
2007-04-02 16:43       ` [PATCH] [PORTS] PPC fenv fixes for soft-fp Steven Munroe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).