]> sourceware.org Git - glibc.git/commitdiff
hppa: Fix feupdateenv and fesetexceptflag (Bug 18111).
authorCarlos O'Donell <carlos@systemhalted.org>
Wed, 11 Mar 2015 06:42:27 +0000 (02:42 -0400)
committerCarlos O'Donell <carlos@systemhalted.org>
Wed, 11 Mar 2015 06:48:59 +0000 (02:48 -0400)
The function feupdateenv has been fixed to correctly handle FE_DFL_ENV
and FE_NOMASK_ENV.

The fesetexceptflag function has been fixed to correctly handle setting
the new flags instead of just OR-ing the existing flags.

This fixes the test-fenv-return and test-fenvinline failures on hppa.

ChangeLog
NEWS
sysdeps/hppa/fpu/feupdateenv.c
sysdeps/hppa/fpu/fpu_control.h
sysdeps/hppa/fpu/fsetexcptflg.c

index 26b6928f8359afe10d412c6099380c1947475f90..2413d2493a3422ec64251ac563d7d77a69c470d7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2015-03-11  Carlos O'Donell  <carlos@redhat.com>
+
+       [BZ #18111]
+       * sysdeps/hppa/fpu/fpu_control.h (_FPU_HPPA_SHIFT_FLAGS): Define.
+       (_FPU_SETCW): Initialize cw from fpsr before storing.
+       * sysdeps/hppa/fpu/fsetexcptflg.c: Include fpu_control.h
+       (fesetexceptflag): Rewrite using fpu_control.h.
+       * sysdeps/hppa/fpu/feupdateenv.c: Handle FE_DFL_ENV, and FE_NOMASK_ENV.
+
 2015-03-11  John David Anglin  <danglin@gcc.gnu.org>
 
        [BZ #18110]
diff --git a/NEWS b/NEWS
index 56405a14667e4d094791ce6d0cdcffe788598715..7f2238083462d8f3f314e7068cb86933b55ae68f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,7 @@ Version 2.22
   17792, 17836, 17912, 17916, 17932, 17944, 17949, 17964, 17965, 17967,
   17969, 17978, 17987, 17991, 17996, 17998, 17999, 18019, 18020, 18029,
   18030, 18032, 18036, 18038, 18039, 18042, 18043, 18046, 18047, 18104,
-  18110.
+  18110, 18111.
 
 * Character encoding and ctype tables were updated to Unicode 7.0.0, using
   new generator scripts contributed by Pravin Satpute and Mike FABIAN (Red
index 931f7e629232f72d6b46a03a32e78c3cb9a757bd..345559edab63450828f37dfa4ae65fb05b3c2299 100644 (file)
@@ -29,9 +29,22 @@ __feupdateenv (const fenv_t *envp)
   __asm__ ("fstd %%fr0,0(%1)   \n\t"
            "fldd 0(%1),%%fr0   \n\t"
           : "=m" (s.l) : "r" (&s.l));
-  memcpy(&temp, envp, sizeof(fenv_t));
-  /* Currently raised exceptions not cleared */
-  temp.__status_word |= s.sw[0] & (FE_ALL_EXCEPT << 27);
+
+  /* Given environment with exception flags not cleared.  */
+  if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV))
+    {
+      memcpy(&temp, envp, sizeof(fenv_t));
+      temp.__status_word |= s.sw[0] & (FE_ALL_EXCEPT << 27);
+    }
+
+  /* Default environment with exception flags not cleared.  */
+  if (envp == FE_DFL_ENV)
+    temp.__status_word = s.sw[0] & (FE_ALL_EXCEPT << 27);
+
+  /* All traps enabled and current exception flags not cleared.  */
+  if (envp == FE_NOMASK_ENV)
+    temp.__status_word = (s.sw[0] & (FE_ALL_EXCEPT << 27)) | FE_ALL_EXCEPT;
+
   /* Install new environment.  */
   __fesetenv (&temp);
   /* Success.  */
index ba9692fe63cc11ac2da64a1084f2b72d44efb178..2087928496c5bb126d18b98ffdb98c28f8ac0c02 100644 (file)
@@ -19,7 +19,7 @@
 #ifndef _FPU_CONTROL_H
 #define _FPU_CONTROL_H
 
-/* Masking of interrupts */
+/* Masking of interrupts */
 #define _FPU_MASK_PM   0x00000001      /* Inexact (I) */
 #define _FPU_MASK_UM   0x00000002      /* Underflow (U) */
 #define _FPU_MASK_OM   0x00000004      /* Overflow (O) */
@@ -30,6 +30,8 @@
 #define _FPU_HPPA_MASK_RM      0x00000600      /* Rounding mode mask */
 /* Masking of interrupt enable bits.  */
 #define _FPU_HPPA_MASK_INT     0x0000001f      /* Interrupt mask */
+/* Shift by 27 to install flag bits.  */
+#define _FPU_HPPA_SHIFT_FLAGS  27
 
 /* There are no reserved bits in the PA fpsr (though some are undefined).  */
 #define _FPU_RESERVED  0x00000000
@@ -55,6 +57,9 @@ typedef unsigned int fpu_control_t;
 #define _FPU_SETCW(cw) \
 ({                                                                             \
   union { __extension__ unsigned long long __fpreg; unsigned int __halfreg[2]; } __fullfp;     \
+  /* Get the current status word and set the control word.  */                 \
+  __asm__ ("fstd %%fr0,0(%1)\n\t"                                              \
+          : "=m" (__fullfp.__fpreg) : "r" (&__fullfp.__fpreg) : "%r0");        \
   __fullfp.__halfreg[0] = cw;                                                  \
   __asm__ ("fldd 0(%1),%%fr0\n\t"                                              \
           : : "m" (__fullfp.__fpreg), "r" (&__fullfp.__fpreg) : "%r0" );       \
index 2c34a1e28793fdfcbccefdf65c0dbb540bdc9b75..c31de8bbe47eae884b1e49d8a1c59ad6b281e52e 100644 (file)
    <http://www.gnu.org/licenses/>.  */
 
 #include <fenv.h>
-#include <math.h>
+#include <fpu_control.h>
 
 int
 fesetexceptflag (const fexcept_t *flagp, int excepts)
 {
-  union { unsigned long long l; unsigned int sw[2]; } s;
+  fpu_control_t fpsr;
+  fpu_control_t fpsr_new;
 
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
-  /* Install new raised trap bits */
-  s.sw[0] |= (*flagp & excepts & FE_ALL_EXCEPT) << 27;
+  _FPU_GETCW (fpsr);
+  excepts &= FE_ALL_EXCEPT;
+
+  /* Install new raised flags.  */
+  fpsr_new = fpsr & ~(excepts << _FPU_HPPA_SHIFT_FLAGS);
+  fpsr_new |= (*flagp & excepts) << _FPU_HPPA_SHIFT_FLAGS;
+
   /* Store the new status word.  */
-  __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
+  if (fpsr != fpsr_new)
+    _FPU_SETCW (fpsr_new);
 
   /* Success.  */
   return 0;
This page took 0.133007 seconds and 5 git commands to generate.