diff options
Diffstat (limited to 'sysdeps/hppa/fpu')
-rw-r--r-- | sysdeps/hppa/fpu/fclrexcpt.c | 2 | ||||
-rw-r--r-- | sysdeps/hppa/fpu/fegetenv.c | 10 | ||||
-rw-r--r-- | sysdeps/hppa/fpu/feholdexcpt.c | 34 | ||||
-rw-r--r-- | sysdeps/hppa/fpu/fesetenv.c | 31 | ||||
-rw-r--r-- | sysdeps/hppa/fpu/feupdateenv.c | 8 | ||||
-rw-r--r-- | sysdeps/hppa/fpu/fraiseexcpt.c | 63 | ||||
-rw-r--r-- | sysdeps/hppa/fpu/fsetexcptflg.c | 3 |
7 files changed, 75 insertions, 76 deletions
diff --git a/sysdeps/hppa/fpu/fclrexcpt.c b/sysdeps/hppa/fpu/fclrexcpt.c index 8ad67b9698..a7c698206e 100644 --- a/sysdeps/hppa/fpu/fclrexcpt.c +++ b/sysdeps/hppa/fpu/fclrexcpt.c @@ -29,7 +29,7 @@ feclearexcept (int excepts) __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); /* Clear all the relevant bits. */ - sw[0] &= ~(excepts & FE_ALL_EXCEPT) << 27; + sw[0] &= ~((excepts & FE_ALL_EXCEPT) << 27); __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw)); /* Success. */ diff --git a/sysdeps/hppa/fpu/fegetenv.c b/sysdeps/hppa/fpu/fegetenv.c index 1ed18daa2c..b87317b789 100644 --- a/sysdeps/hppa/fpu/fegetenv.c +++ b/sysdeps/hppa/fpu/fegetenv.c @@ -24,10 +24,10 @@ int fegetenv (fenv_t *envp) { __asm__ ( - "fstd %%fr0,0(%2)\n" - "fstd,ma %%fr1,8(%2)\n" - "fstd,ma %%fr2,8(%2)\n" - "fstd %%fr3,0(%2)\n" - : "=m" (*envp), "=r" (envp) : "1" (envp)); + "fstd,ma %%fr0,8(%1)\n" + "fstd,ma %%fr1,8(%1)\n" + "fstd,ma %%fr2,8(%1)\n" + "fstd %%fr3,0(%1)\n" + : "=m" (*envp), "+r" (envp)); return 0; } diff --git a/sysdeps/hppa/fpu/feholdexcpt.c b/sysdeps/hppa/fpu/feholdexcpt.c index 27133365bc..db9fb409ae 100644 --- a/sysdeps/hppa/fpu/feholdexcpt.c +++ b/sysdeps/hppa/fpu/feholdexcpt.c @@ -25,18 +25,16 @@ int feholdexcept (fenv_t *envp) { fenv_t clear; + fenv_t * _regs = envp; /* Store the environment. */ - { - fenv_t * _regs = envp; - __asm__ ( - "fstd %%fr0,0(%2)\n" - "fstd,ma %%fr1,8(%2)\n" - "fstd,ma %%fr2,8(%2)\n" - "fstd %%fr3,0(%2)\n" - : "=m" (*_regs), "=r" (_regs) : "1" (_regs)); - memcpy (&clear, envp, sizeof (clear)); - } + __asm__ ( + "fstd,ma %%fr0,8(%1)\n" + "fstd,ma %%fr1,8(%1)\n" + "fstd,ma %%fr2,8(%1)\n" + "fstd %%fr3,0(%1)\n" + : "=m" (*_regs), "+r" (_regs)); + memcpy (&clear, envp, sizeof (clear)); /* Now clear all exceptions. */ clear.__status_word &= ~(FE_ALL_EXCEPT << 27); @@ -46,15 +44,13 @@ feholdexcept (fenv_t *envp) clear.__status_word &= ~FE_ALL_EXCEPT; /* Load the new environment. */ - { - fenv_t * _regs = &clear + 1; - __asm__ ( - "fldd,mb -8(%2),%%fr3\n" - "fldd,mb -8(%2),%%fr2\n" - "fldd,mb -8(%2),%%fr1\n" - "fldd -8(%2),%%fr0\n" - : "=m" (*_regs), "=r" (_regs) : "1" (_regs)); - } + _regs = &clear; + __asm__ ( + "fldd,ma -8(%1),%%fr3\n" + "fldd,ma -8(%1),%%fr2\n" + "fldd,ma -8(%1),%%fr1\n" + "fldd 0(%1),%%fr0\n" + : "=m" (*_regs), "+r" (_regs)); return 0; } diff --git a/sysdeps/hppa/fpu/fesetenv.c b/sysdeps/hppa/fpu/fesetenv.c index 2c7986987b..526773214b 100644 --- a/sysdeps/hppa/fpu/fesetenv.c +++ b/sysdeps/hppa/fpu/fesetenv.c @@ -26,20 +26,18 @@ int fesetenv (const fenv_t *envp) { fenv_t temp; + fenv_t * _regs = &temp; /* Install the environment specified by ENVP. But there are a few values which we do not want to come from the saved environment. Therefore, we get the current environment and replace the values we want to use from the environment specified by the parameter. */ - { - fenv_t * _regs = &temp; - __asm__ ( - "fstd %%fr0,0(%2)\n" - "fstd,ma %%fr1,8(%2)\n" - "fstd,ma %%fr2,8(%2)\n" - "fstd %%fr3,0(%2)\n" - : "=m" (*_regs), "=r" (_regs) : "1" (_regs)); - } + __asm__ ( + "fstd,ma %%fr0,8(%1)\n" + "fstd,ma %%fr1,8(%1)\n" + "fstd,ma %%fr2,8(%1)\n" + "fstd %%fr3,0(%1)\n" + : "=m" (*_regs), "+r" (_regs)); temp.__status_word &= ~(FE_ALL_EXCEPT | (FE_ALL_EXCEPT << 27) @@ -55,15 +53,12 @@ fesetenv (const fenv_t *envp) | (FE_ALL_EXCEPT << 27))); /* Load the new environment. */ - { - fenv_t * _regs = &temp + 1; - __asm__ ( - "fldd,mb -8(%2),%%fr3\n" - "fldd,mb -8(%2),%%fr2\n" - "fldd,mb -8(%2),%%fr1\n" - "fldd -8(%2),%%fr0\n" - : "=m" (*_regs), "=r" (_regs) : "1" (_regs)); - } + __asm__ ( + "fldd,ma -8(%1),%%fr3\n" + "fldd,ma -8(%1),%%fr2\n" + "fldd,ma -8(%1),%%fr1\n" + "fldd 0(%1),%%fr0\n" + : "=m" (*_regs), "+r" (_regs)); /* Success. */ return 0; diff --git a/sysdeps/hppa/fpu/feupdateenv.c b/sysdeps/hppa/fpu/feupdateenv.c index c61b7b298a..8980dfd69c 100644 --- a/sysdeps/hppa/fpu/feupdateenv.c +++ b/sysdeps/hppa/fpu/feupdateenv.c @@ -27,14 +27,12 @@ feupdateenv (const fenv_t *envp) /* Get the current exception status. */ __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); - sw[0] &= (FE_ALL_EXCEPT << 27); - + sw[0] &= FE_ALL_EXCEPT; + envp->__status_word = envp->__status_word | sw[0]; + /* Install new environment. */ fesetenv (envp); - /* Raise the saved exception. */ - feraiseexcept (sw[0] >> 27); - /* Success. */ return 0; } diff --git a/sysdeps/hppa/fpu/fraiseexcpt.c b/sysdeps/hppa/fpu/fraiseexcpt.c index a13668f954..b064dc1527 100644 --- a/sysdeps/hppa/fpu/fraiseexcpt.c +++ b/sysdeps/hppa/fpu/fraiseexcpt.c @@ -22,6 +22,9 @@ #include <float.h> #include <math.h> +/* Please see section 10, + page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */ + int feraiseexcept (int excepts) { @@ -33,56 +36,64 @@ feraiseexcept (int excepts) /* We do these bits in assembly to be certain GCC doesn't optimize away something important, and so we can force delayed traps to - occur. */ - - /* FIXME: These all need verification! */ + occur. */ - /* First: invalid exception. */ + /* We use "fldd 0(%%sr0,%%sp),%0" to flush the delayed exception */ + + /* First: Invalid exception. */ if (excepts & FE_INVALID) { /* One example of a invalid operation is 0 * Infinity. */ double d = HUGE_VAL; - __asm__ __volatile__ ("fmpy,dbl %1,%%fr0,%0\n\t" - /* FIXME: is this a proper trap barrier? */ - "fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d)); + __asm__ __volatile__ ( + " fcpy,dbl %%fr0,%%fr22\n" + " fmpy,dbl %0,%%fr22,%0\n" + " fldd 0(%%sr0,%%sp),%0" + : "+f" (d) : : "%fr22" ); } - /* Next: division by zero. */ + /* Second: Division by zero. */ if (excepts & FE_DIVBYZERO) { double d = 1.0; - __asm__ __volatile__ ("fdiv,dbl %1,%%fr0,%0\n\t" - "fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d)); + __asm__ __volatile__ ( + " fcpy,dbl %%fr0,%%fr22\n" + " fdiv,dbl %0,%%fr22,%0\n" + " fldd 0(%%sr0,%%sp),%0" + : "+f" (d) : : "%fr22" ); } - /* Next: overflow. */ - /* FIXME: Compare with IA-64 - do we have the same problem? */ + /* Third: Overflow. */ if (excepts & FE_OVERFLOW) { double d = DBL_MAX; - - __asm__ __volatile__ ("fmpy,dbl %1,%1,%0\n\t" - "fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d)); + __asm__ __volatile__ ( + " fadd,dbl %0,%0,%0\n" + " fldd 0(%%sr0,%%sp),%0" + : "+f" (d) ); } - /* Next: underflow. */ + /* Fourth: Underflow. */ if (excepts & FE_UNDERFLOW) { double d = DBL_MIN; - double e = 69.69; - - __asm__ __volatile__ ("fdiv,dbl %1,%2,%0\n\t" - "fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d), "f" (e)); + double e = 3.0; + __asm__ __volatile__ ( + " fdiv,dbl %0,%1,%0\n" + " fldd 0(%%sr0,%%sp),%0" + : "+f" (d) : "f" (e) ); } - /* Last: inexact. */ + /* Fifth: Inexact */ if (excepts & FE_INEXACT) { - double d = 1.0; - double e = M_PI; - - __asm__ __volatile__ ("fdiv,dbl %1,%2,%0\n\t" - "fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d), "f" (e)); + double d = M_PI; + double e = 69.69; + __asm__ __volatile__ ( + " fdiv,dbl %0,%1,%%fr22\n" + " fcnvfxt,dbl,sgl %%fr22,%%fr22L\n" + " fldd 0(%%sr0,%%sp),%%fr22" + : : "f" (d), "f" (e) : "%fr22" ); } /* Success. */ diff --git a/sysdeps/hppa/fpu/fsetexcptflg.c b/sysdeps/hppa/fpu/fsetexcptflg.c index 343ddad943..af35f5ae35 100644 --- a/sysdeps/hppa/fpu/fsetexcptflg.c +++ b/sysdeps/hppa/fpu/fsetexcptflg.c @@ -29,8 +29,7 @@ fesetexceptflag (const fexcept_t *flagp, int excepts) /* Get the current status word. */ __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); - /* Install the new exception flags bits. */ - sw[0] &= ~(excepts & (FE_ALL_EXCEPT >> 27)); + /* Install new enable trap bits */ sw[0] |= (*flagp & excepts & FE_ALL_EXCEPT) << 27; /* Store the new status word. */ |