]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
2006-04-20 Carlos O'Donell <carlos@systemhalted.org>
authorCarlos O'Donell <carlos@systemhalted.org>
Fri, 21 Apr 2006 00:27:20 +0000 (00:27 +0000)
committerCarlos O'Donell <carlos@systemhalted.org>
Fri, 21 Apr 2006 00:27:20 +0000 (00:27 +0000)
* sysdeps/hppa/fpu/fclrexcpt.c (feclearexcept): Use union to
align parameters. Specify memory clobbers.
* sysdeps/hppa/fpu/fedisblxcpt.c (fedisableexcept): Likewise.
* sysdeps/hppa/fpu/feenablxcpt.c (feenableexcept): Likewise.
* sysdeps/hppa/fpu/fegetenv.c (fegetenv): Do not save exception
register. Use memcpy to align buffer.
* sysdeps/hppa/fpu/fegetexcept.c (fegetexcept): Store and reload
fr0. Use union to align parameters.
* sysdeps/hppa/fpu/fegetround.c (fegetround): Likewise.
* sysdeps/hppa/fpu/feholdexcpt.c (feholdexcept): Do not save
exception registers. Define libm_hidden_def.
* sysdeps/hppa/fpu/fesetenv.c (fesetenv): Do not save exception
registers.
* sysdeps/hppa/fpu/fesetround.c (fesetround): Use union to
align parameters, speficy memory clobbers. Define libm_hidde_def
* sysdeps/hppa/fpu/feupdateenv.c (feupdateenv): Use union to align
parameters. Use memcpy to align buffer.
* sysdeps/hppa/fpu/fgetexcptflg.c (fegetexceptflag): Likewise.
* sysdeps/hppa/fpu/fsetexcptflg.c (fesetexceptflag): Likewise.
* sysdeps/hppa/fpu/ftestexcept.c (fetestexcept): Likewise.
* sysdeps/hppa/fpu/libm-test-ulps: Update.
* sysdeps/hppa/fpu/bits/fenv.h: Add ABI comments.

16 files changed:
ChangeLog.hppa
sysdeps/hppa/fpu/bits/fenv.h
sysdeps/hppa/fpu/fclrexcpt.c
sysdeps/hppa/fpu/fedisblxcpt.c
sysdeps/hppa/fpu/feenablxcpt.c
sysdeps/hppa/fpu/fegetenv.c
sysdeps/hppa/fpu/fegetexcept.c
sysdeps/hppa/fpu/fegetround.c
sysdeps/hppa/fpu/feholdexcpt.c
sysdeps/hppa/fpu/fesetenv.c
sysdeps/hppa/fpu/fesetround.c
sysdeps/hppa/fpu/feupdateenv.c
sysdeps/hppa/fpu/fgetexcptflg.c
sysdeps/hppa/fpu/fsetexcptflg.c
sysdeps/hppa/fpu/ftestexcept.c
sysdeps/hppa/fpu/libm-test-ulps

index 401a2a20684e77bd72c134f84b5b6524a16252a2..e937d9bbe2460424ebadcd1d9c3934ed804d45ed 100644 (file)
@@ -1,3 +1,28 @@
+2006-04-20  Carlos O'Donell  <carlos@systemhalted.org>
+
+       * sysdeps/hppa/fpu/fclrexcpt.c (feclearexcept): Use union to
+       align parameters. Specify memory clobbers.
+       * sysdeps/hppa/fpu/fedisblxcpt.c (fedisableexcept): Likewise.
+       * sysdeps/hppa/fpu/feenablxcpt.c (feenableexcept): Likewise.
+       * sysdeps/hppa/fpu/fegetenv.c (fegetenv): Do not save exception
+       register. Use memcpy to align buffer.
+       * sysdeps/hppa/fpu/fegetexcept.c (fegetexcept): Store and reload
+       fr0. Use union to align parameters.
+       * sysdeps/hppa/fpu/fegetround.c (fegetround): Likewise.
+       * sysdeps/hppa/fpu/feholdexcpt.c (feholdexcept): Do not save
+       exception registers. Define libm_hidden_def.
+       * sysdeps/hppa/fpu/fesetenv.c (fesetenv): Do not save exception
+       registers.
+       * sysdeps/hppa/fpu/fesetround.c (fesetround): Use union to
+       align parameters, speficy memory clobbers. Define libm_hidde_def
+       * sysdeps/hppa/fpu/feupdateenv.c (feupdateenv): Use union to align
+       parameters. Use memcpy to align buffer.
+       * sysdeps/hppa/fpu/fgetexcptflg.c (fegetexceptflag): Likewise.
+       * sysdeps/hppa/fpu/fsetexcptflg.c (fesetexceptflag): Likewise.
+       * sysdeps/hppa/fpu/ftestexcept.c (fetestexcept): Likewise.
+       * sysdeps/hppa/fpu/libm-test-ulps: Update.
+       * sysdeps/hppa/fpu/bits/fenv.h: Add ABI comments.
+
 2006-04-19  Carlos O'Donell  <carlos@systemhalted.org>
 
        * sysdeps/unix/sysv/linux/hppa/bits/mman.h [__USE_GNU]: 
index c5f8c43459ac13c7c315e65cf9ba2c8735c87946..6d83b141f83661fcf1b160c759dc5e27ef8b23f3 100644 (file)
@@ -62,7 +62,12 @@ typedef unsigned int fexcept_t;
 
 /* Type representing floating-point environment.  This structure
    corresponds to the layout of the status and exception words in the
-   register file. */
+   register file. The exception registers are never saved/stored by
+   userspace. This structure is also not correctly aligned ever, in
+   an ABI error we left out __aligned(8) and subsequently all of our
+   fenv functions must accept unaligned input, align the input, and
+   then use assembly to store fr0. This is a performance hit, but 
+   means the ABI is stable. */
 typedef struct
 {
   unsigned int __status_word;
index a7c698206e5dbb384fac4972e7ed55dba321c801..d74a449ebb57f6807c788f7c7561a9eaa1139f12 100644 (file)
 int
 feclearexcept (int excepts)
 {
-  unsigned int sw[2];
+  union { unsigned long long l; unsigned int sw[2]; } s;
 
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
-
+  __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
   /* Clear all the relevant bits. */
-  sw[0] &= ~((excepts & FE_ALL_EXCEPT) << 27);
-  __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw));
+  s.sw[0] &= ~((excepts & FE_ALL_EXCEPT) << 27);
+  __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
 
   /* Success.  */
   return 0;
index aac6bbfa2a54d28eec1878f93151bc6c389016f3..8d2e66403454de397eed254b666d659bee89a278 100644 (file)
 int
 fedisableexcept (int excepts)
 {
-  unsigned int sw[2], old_exc;
+  union { unsigned long long l; unsigned int sw[2]; } s; 
+  unsigned int old_exc;
 
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
+  __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
 
-  old_exc = sw[0] & FE_ALL_EXCEPT;
+  old_exc = s.sw[0] & FE_ALL_EXCEPT;
 
-  sw[0] &= ~(excepts & FE_ALL_EXCEPT);
-  __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw));
+  s.sw[0] &= ~(excepts & FE_ALL_EXCEPT);
+  __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
 
   return old_exc;
 }
index 9ce3ca82cc5ec245f378eddede78e216dece686e..4b17a603783864d5ea117fda8d40a6bdd087e0ae 100644 (file)
 int
 feenableexcept (int excepts)
 {
-  unsigned int sw[2], old_exc;
+  union { unsigned long long l; unsigned int sw[2]; } s;
+  unsigned int old_exc;
 
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
+  __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
 
-  old_exc = sw[0] & FE_ALL_EXCEPT;
+  old_exc = s.sw[0] & FE_ALL_EXCEPT;
 
-  sw[0] |= (excepts & FE_ALL_EXCEPT);
-  __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw));
+  s.sw[0] |= (excepts & FE_ALL_EXCEPT);
+  __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
 
   return old_exc;
 }
index b87317b78957f5e2b207ce4d07eabfdd86ec4485..fcf5d2dcfe23111fae1808381e7d5db8977c38dd 100644 (file)
    02111-1307 USA.  */
 
 #include <fenv.h>
+#include <string.h>
 
 int
 fegetenv (fenv_t *envp)
 {
+  unsigned long long buf[4], *bufptr = buf;
+  
   __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" (*envp), "+r" (envp));
+          "fstd,ma %%fr0,8(%1) \n\t"
+          "fldd -8(%1),%%fr0   \n\t"
+          : "=m" (buf), "+r" (bufptr) : : "%r0");
+  memcpy(envp, buf, sizeof (*envp));
   return 0;
 }
index efd1d7df0599b8979fc0e011685276536dcd4969..d249dc6b9fdd5f3ca30e54c9afb9845b6f62da17 100644 (file)
 int
 fegetexcept (void)
 {
-  unsigned int sw[2];
+  union { unsigned long long l; unsigned int sw[2] } s;
 
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
+  __asm__ ("fstd %%fr0,0(%1)   \n\t" 
+           "fldd 0(%1),%%fr0   \n\t"
+          : "=m" (s.l) : "r" (&s.l) : "%r0");
 
-  return sw[0] & FE_ALL_EXCEPT;
+  return (s.sw[0] & FE_ALL_EXCEPT);
 }
index aefedbc0713136da9810e2677fc5f7564a25ada2..1e606c9ecdb1ea85ffb69b693836d880a328d3de 100644 (file)
 int
 fegetround (void)
 {
-  unsigned int sw[2];
+  union { unsigned long long l; unsigned int sw[2] } s;
 
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
+  __asm__ ("fstd %%fr0,0(%1)   \n\t" 
+          "fldd 0(%1),%%fr0    \n\t" 
+           : "=m" (s.l) : "r" (&s.l));
 
-  return sw[0] & FE_DOWNWARD;
+  return (s.sw[0] & FE_DOWNWARD);
 }
index 5aec0151f835f1912efb4459a5b0357d77d41a9c..ac6eb580554e04ced590257fd92fbe839401ea77 100644 (file)
 int
 feholdexcept (fenv_t *envp)
 {
-  fenv_t clear;
-  fenv_t * _regs = envp;
+  union { unsigned long long buf[4]; fenv_t env; } clear;
+  unsigned long long *bufptr;
 
   /* Store the environment.  */
+  bufptr = clear.buf;
   __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);
-  memset (clear.__exception, 0, sizeof (clear.__exception));
+          : "=m" (clear), "+r" (bufptr) : : "%r0");
+  memcpy (envp, &clear.env, sizeof (fenv_t));
 
+  /* Clear exception queues */
+  memset (clear.env.__exception, 0, sizeof (clear.env.__exception));
   /* And set all exceptions to non-stop.  */
-  clear.__status_word &= ~FE_ALL_EXCEPT;
+  clear.env.__status_word &= ~FE_ALL_EXCEPT;
+  /* Now clear all flags  */
+  clear.env.__status_word &= ~(FE_ALL_EXCEPT << 27);
 
-  /* Load the new environment. */
-  _regs = &clear;
+  /* Load the new environment. Note: fr0 must load last to enable T-bit 
+     Thus we start bufptr at the end and work backwards */
+  bufptr = (unsigned int)(clear.buf) + sizeof(unsigned int)*4;
   __asm__ (
-          "fldd,ma 8(%0),%%fr0\n"
-          "fldd,ma 8(%0),%%fr1\n"
-          "fldd,ma 8(%0),%%fr2\n"
-          "fldd 0(%0),%%fr3\n"
-          : : "r" (_regs));
+          "fldd,mb -8(%0),%%fr0\n"
+          : : "r" (bufptr), "m" (clear) : "%r0");
 
   return 0;
 }
+
+libm_hidden_def (feholdexcept)
+
index 526773214b73bfd75500c6c7ef13231028770156..b5753efabd40dc4fd54da11ae5d3bf2ff71c990e 100644 (file)
 int
 fesetenv (const fenv_t *envp)
 {
-  fenv_t temp;
-  fenv_t * _regs = &temp;
+  union { unsigned long long buf[4]; fenv_t env; } temp;
+  unsigned long long *bufptr;
 
   /* 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.  */
+  bufptr = temp.buf;
   __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));
+          : "=m" (temp), "+r" (bufptr) : : "%r0");
 
-  temp.__status_word &= ~(FE_ALL_EXCEPT
-                         | (FE_ALL_EXCEPT << 27)
-                         | FE_DOWNWARD);
+  temp.env.__status_word &= ~(FE_ALL_EXCEPT
+                           | (FE_ALL_EXCEPT << 27)
+                           | FE_DOWNWARD);
   if (envp == FE_DFL_ENV)
     ;
   else if (envp == FE_NOMASK_ENV)
-    temp.__status_word |= FE_ALL_EXCEPT;
+    temp.env.__status_word |= FE_ALL_EXCEPT;
   else
-    temp.__status_word |= (envp->__status_word
-                          & (FE_ALL_EXCEPT
-                             | FE_DOWNWARD
-                             | (FE_ALL_EXCEPT << 27)));
+    temp.env.__status_word |= (envp->__status_word
+                              & (FE_ALL_EXCEPT
+                                 | FE_DOWNWARD
+                                 | (FE_ALL_EXCEPT << 27)));
 
-  /* Load the new environment. */
+  /* Load the new environment. We use bufptr again since the 
+     initial asm has modified the value of the register and here
+     we take advantage of that to load in reverse order so fr0
+     is loaded last and T-Bit is enabled. */
   __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));
+          "fldd,mb -8(%1),%%fr0\n"
+          : "=m" (temp), "+r" (bufptr) : : "%r0" );
 
   /* Success.  */
   return 0;
index 3687624c2b5120cb3e9e25719547a9d62222e402..9f30c2495f68c025b3e89a64cfcdb92b6a3178d6 100644 (file)
 int
 fesetround (int round)
 {
-  unsigned int sw[2];
+  union { unsigned long long l; unsigned int sw[2]; } s;
 
   if (round & ~FE_DOWNWARD)
-    /* ROUND is not a valid rounding mode.  */
+    /* round is not a valid rounding mode. */
     return 1;
-
+  
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
-  sw[0] &= ~FE_DOWNWARD;
-  sw[0] |= round;
-  __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw));
+  __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
+  s.sw[0] &= ~FE_DOWNWARD;
+  s.sw[0] |= round & FE_DOWNWARD;
+  __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
 
   return 0;
 }
+
+libm_hidden_def (fesetround)
index 7d50282e0569d516fb526a833ad40d61f341b80d..17140060ad6bea698d58d5ae6095a93e44afae09 100644 (file)
    02111-1307 USA.  */
 
 #include <fenv.h>
+#include <string.h>
 
 int
 feupdateenv (const fenv_t *envp)
 {
-  unsigned int sw[2];
-
-  /* Get the current exception status. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
+  union { unsigned long long l; unsigned int sw[2]; } s;
+  fenv_t temp;
+  /* Get the current exception status */
+  __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);
   /* Install new environment.  */
-  fesetenv (envp);
-  /* Raise the saved exceptions */
-  feraiseexcept(sw[0] & FE_ALL_EXCEPT);
-
+  fesetenv (&temp);
   /* Success.  */
   return 0;
 }
index 27766ecf58767bb5865c6c43092452abe655d35e..d5bcfe31d6bfbbc8e88c7979d2f29f4124855a7b 100644 (file)
 int
 fegetexceptflag (fexcept_t *flagp, int excepts)
 {
-  unsigned int sw[2];
+  union { unsigned long long l; unsigned int sw[2]; } s;
 
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
+  __asm__ ("fstd %%fr0,0(%1)   \n\t" 
+           "fldd 0(%1),%%fr0   \n\t" 
+          : "=m" (s.l) : "r" (&s.l) : "%r0");
 
-  *flagp = (sw[0] >> 27) & excepts & FE_ALL_EXCEPT;
+  *flagp = (s.sw[0] >> 27) & excepts & FE_ALL_EXCEPT;
 
   /* Success.  */
   return 0;
index af35f5ae351d19aa254c76b9bf52cd6a8af83f44..4ec3a92dcca89a5aa4af36c4e0307c6c296a2eed 100644 (file)
 int
 fesetexceptflag (const fexcept_t *flagp, int excepts)
 {
-  unsigned int sw[2];
+  union { unsigned long long l; unsigned int sw[2]; } s;
 
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
-
-  /* Install new enable trap bits  */
-  sw[0] |= (*flagp & excepts & FE_ALL_EXCEPT) << 27;
-
+  __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;
   /* Store the new status word.  */
-  __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw));
+  __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
 
   /* Success.  */
   return 0;
index d08d4d6eb902583727aa960c1b02e1604564de5f..ac6d4b2e350c4769654a90714c4ec70e5cc0e953 100644 (file)
 int
 fetestexcept (int excepts)
 {
-  unsigned int sw[2];
+  union { unsigned long long l; unsigned int sw[2] } s;
 
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
+  __asm__ ("fstd %%fr0,0(%1)   \n\t" 
+           "fldd 0(%1),%%fr0   \n\t" 
+          : "=m" (s.l) : "r" (&s.l));
 
-  return (sw[0] >> 27) & excepts & FE_ALL_EXCEPT;
+  return (s.sw[0] >> 27) & excepts & FE_ALL_EXCEPT;
 }
index b5144966764007be6522fcc09a4e23101b0dd78f..c4ffefaa86bf3136bb3cc5c39edce15185b45111 100644 (file)
@@ -1,6 +1,9 @@
 # Begin of automatic generation
 
 # atan2
+Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994380":
+float: 6
+ifloat: 6
 Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
 float: 3
 ifloat: 3
@@ -258,9 +261,6 @@ float: 1
 ifloat: 1
 
 # ctan
-Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
-double: 1
-idouble: 1
 Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
 double: 1
 idouble: 1
@@ -479,6 +479,11 @@ Test "log1p (-0.25) == -0.287682072451780927439219005993827432":
 float: 1
 ifloat: 1
 
+# lround
+Test "lround (1071930.0008) == 1071930":
+double: -214511494
+idouble: -214511494
+
 # sincos
 Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
 double: 1
@@ -640,8 +645,8 @@ idouble: 1
 
 # Maximal error of functions:
 Function: "atan2":
-float: 3
-ifloat: 3
+float: 6
+ifloat: 6
 
 Function: "atanh":
 float: 1
@@ -777,10 +782,6 @@ Function: Real part of "csqrt":
 float: 1
 ifloat: 1
 
-Function: Real part of "ctan":
-double: 1
-idouble: 1
-
 Function: Imaginary part of "ctan":
 double: 1
 idouble: 1