aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/hppa/fpu
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-12-18 04:02:31 +0000
committerUlrich Drepper <drepper@redhat.com>2003-12-18 04:02:31 +0000
commit592f26a3ed6e74aad8ff65eec9c139a6bc4aa89e (patch)
tree3eabb471cd2153b059302d3dedc628241fbb9071 /sysdeps/hppa/fpu
parent4ae4facccf1286dae59ccc4758b64a76ab985aff (diff)
downloadglibc-592f26a3ed6e74aad8ff65eec9c139a6bc4aa89e.tar
glibc-592f26a3ed6e74aad8ff65eec9c139a6bc4aa89e.tar.gz
glibc-592f26a3ed6e74aad8ff65eec9c139a6bc4aa89e.tar.bz2
glibc-592f26a3ed6e74aad8ff65eec9c139a6bc4aa89e.zip
Update.
2003-12-17 Carlos O'Donell <carlos@baldric.uwo.ca> * sysdeps/hppa/fpu/fclrexcpt.c (feclearexcept): Right shift FE_ALL_EXCEPT before complimenting. * sysdeps/hppa/fpu/fegetenv.c (fegetenv): Use asm 'ma,' completer, and gcc '+r' constraint. * sysdeps/hppa/fpu/feholdexcpt.c (feholdexcept): Likewise. * sysdeps/hppa/fpu/fesetenv.c (fesetenv): Likewise. * sysdeps/hppa/fpu/feupdateenv.c (feupdateenv): Read raised exception bits, OR with envp, pass to fesetenv. * sysdeps/hppa/fpu/fraiseexcpt.c (feraiseexcept): Add delayed exception flushing, FE_UNDERFLOW is DBL_MIN/3.0, FE_INEXACT is triggered by M_PI/69.69 converted to single precision. * sysdeps/hppa/fpu/fsetexcptflg.c (fesetexceptflag): Set enable bits not raised exception bits. * sysdeps/hppa/Makefile: Add dl-symaddr and dl-fptr to the correct build strings. * sysdeps/hppa/dl-fptr.h: New file. * sysdeps/hppa/dl-fptr.c: Removed. * sysdeps/hppa/dl-symaddr.c (_dl_symbol_address): Use _dl_make_ftpr, remove const qualifier for map. (_dl_function_address): Removed. * sysdeps/hppa/dl-lookupcfg.h: DL_LOOKUP_ADDRESS must clear PLABEL32 bits, define DL_AUTO_FUNCTION_ADDRESS and DL_STATIC_FUNCTION_ADDRESS, DL_DT_INIT_ADDRESS and DL_DT_FINI_ADDRESS use the previous two macros. * misc/mntent_r.c: Change encoding to match recently changed decoder.
Diffstat (limited to 'sysdeps/hppa/fpu')
-rw-r--r--sysdeps/hppa/fpu/fclrexcpt.c2
-rw-r--r--sysdeps/hppa/fpu/fegetenv.c10
-rw-r--r--sysdeps/hppa/fpu/feholdexcpt.c34
-rw-r--r--sysdeps/hppa/fpu/fesetenv.c31
-rw-r--r--sysdeps/hppa/fpu/feupdateenv.c8
-rw-r--r--sysdeps/hppa/fpu/fraiseexcpt.c63
-rw-r--r--sysdeps/hppa/fpu/fsetexcptflg.c3
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. */