hppa: Fix feupdateenv and fesetexceptflag (Bug 18111).
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.
This commit is contained in:
parent
fae1aa8d22
commit
e4363cfb57
|
@ -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>
|
2015-03-11 John David Anglin <danglin@gcc.gnu.org>
|
||||||
|
|
||||||
[BZ #18110]
|
[BZ #18110]
|
||||||
|
|
2
NEWS
2
NEWS
|
@ -14,7 +14,7 @@ Version 2.22
|
||||||
17792, 17836, 17912, 17916, 17932, 17944, 17949, 17964, 17965, 17967,
|
17792, 17836, 17912, 17916, 17932, 17944, 17949, 17964, 17965, 17967,
|
||||||
17969, 17978, 17987, 17991, 17996, 17998, 17999, 18019, 18020, 18029,
|
17969, 17978, 17987, 17991, 17996, 17998, 17999, 18019, 18020, 18029,
|
||||||
18030, 18032, 18036, 18038, 18039, 18042, 18043, 18046, 18047, 18104,
|
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
|
* Character encoding and ctype tables were updated to Unicode 7.0.0, using
|
||||||
new generator scripts contributed by Pravin Satpute and Mike FABIAN (Red
|
new generator scripts contributed by Pravin Satpute and Mike FABIAN (Red
|
||||||
|
|
|
@ -29,9 +29,22 @@ __feupdateenv (const fenv_t *envp)
|
||||||
__asm__ ("fstd %%fr0,0(%1) \n\t"
|
__asm__ ("fstd %%fr0,0(%1) \n\t"
|
||||||
"fldd 0(%1),%%fr0 \n\t"
|
"fldd 0(%1),%%fr0 \n\t"
|
||||||
: "=m" (s.l) : "r" (&s.l));
|
: "=m" (s.l) : "r" (&s.l));
|
||||||
|
|
||||||
|
/* Given environment with exception flags not cleared. */
|
||||||
|
if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV))
|
||||||
|
{
|
||||||
memcpy(&temp, envp, sizeof(fenv_t));
|
memcpy(&temp, envp, sizeof(fenv_t));
|
||||||
/* Currently raised exceptions not cleared */
|
|
||||||
temp.__status_word |= s.sw[0] & (FE_ALL_EXCEPT << 27);
|
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. */
|
/* Install new environment. */
|
||||||
__fesetenv (&temp);
|
__fesetenv (&temp);
|
||||||
/* Success. */
|
/* Success. */
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#ifndef _FPU_CONTROL_H
|
#ifndef _FPU_CONTROL_H
|
||||||
#define _FPU_CONTROL_H
|
#define _FPU_CONTROL_H
|
||||||
|
|
||||||
/* Masking of interrupts */
|
/* Masking of interrupts. */
|
||||||
#define _FPU_MASK_PM 0x00000001 /* Inexact (I) */
|
#define _FPU_MASK_PM 0x00000001 /* Inexact (I) */
|
||||||
#define _FPU_MASK_UM 0x00000002 /* Underflow (U) */
|
#define _FPU_MASK_UM 0x00000002 /* Underflow (U) */
|
||||||
#define _FPU_MASK_OM 0x00000004 /* Overflow (O) */
|
#define _FPU_MASK_OM 0x00000004 /* Overflow (O) */
|
||||||
|
@ -30,6 +30,8 @@
|
||||||
#define _FPU_HPPA_MASK_RM 0x00000600 /* Rounding mode mask */
|
#define _FPU_HPPA_MASK_RM 0x00000600 /* Rounding mode mask */
|
||||||
/* Masking of interrupt enable bits. */
|
/* Masking of interrupt enable bits. */
|
||||||
#define _FPU_HPPA_MASK_INT 0x0000001f /* Interrupt mask */
|
#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). */
|
/* There are no reserved bits in the PA fpsr (though some are undefined). */
|
||||||
#define _FPU_RESERVED 0x00000000
|
#define _FPU_RESERVED 0x00000000
|
||||||
|
@ -55,6 +57,9 @@ typedef unsigned int fpu_control_t;
|
||||||
#define _FPU_SETCW(cw) \
|
#define _FPU_SETCW(cw) \
|
||||||
({ \
|
({ \
|
||||||
union { __extension__ unsigned long long __fpreg; unsigned int __halfreg[2]; } __fullfp; \
|
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; \
|
__fullfp.__halfreg[0] = cw; \
|
||||||
__asm__ ("fldd 0(%1),%%fr0\n\t" \
|
__asm__ ("fldd 0(%1),%%fr0\n\t" \
|
||||||
: : "m" (__fullfp.__fpreg), "r" (&__fullfp.__fpreg) : "%r0" ); \
|
: : "m" (__fullfp.__fpreg), "r" (&__fullfp.__fpreg) : "%r0" ); \
|
||||||
|
|
|
@ -18,19 +18,25 @@
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include <fenv.h>
|
#include <fenv.h>
|
||||||
#include <math.h>
|
#include <fpu_control.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
fesetexceptflag (const fexcept_t *flagp, int excepts)
|
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. */
|
/* Get the current status word. */
|
||||||
__asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
|
_FPU_GETCW (fpsr);
|
||||||
/* Install new raised trap bits */
|
excepts &= FE_ALL_EXCEPT;
|
||||||
s.sw[0] |= (*flagp & excepts & FE_ALL_EXCEPT) << 27;
|
|
||||||
|
/* 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. */
|
/* 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. */
|
/* Success. */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue