about summary refs log tree commit diff
path: root/sysdeps/hppa/fpu/fesetenv.c
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@systemhalted.org>2006-04-21 00:27:20 +0000
committerCarlos O'Donell <carlos@systemhalted.org>2006-04-21 00:27:20 +0000
commit48dcf1c597b5e90d40020319758467fe6d35b15f (patch)
tree07bce7355055acd26f0ae44d36d1671cfd8df12f /sysdeps/hppa/fpu/fesetenv.c
parentcb1636152429f05766214ca1a70cc867500f8553 (diff)
downloadglibc-48dcf1c597b5e90d40020319758467fe6d35b15f.tar.gz
glibc-48dcf1c597b5e90d40020319758467fe6d35b15f.tar.xz
glibc-48dcf1c597b5e90d40020319758467fe6d35b15f.zip
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.
Diffstat (limited to 'sysdeps/hppa/fpu/fesetenv.c')
-rw-r--r--sysdeps/hppa/fpu/fesetenv.c38
1 files changed, 18 insertions, 20 deletions
diff --git a/sysdeps/hppa/fpu/fesetenv.c b/sysdeps/hppa/fpu/fesetenv.c
index 526773214b..b5753efabd 100644
--- a/sysdeps/hppa/fpu/fesetenv.c
+++ b/sysdeps/hppa/fpu/fesetenv.c
@@ -25,40 +25,38 @@
 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;