qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [patch] Missing rounding modes.
@ 2005-03-10  1:35 Paul Brook
  0 siblings, 0 replies; only message in thread
From: Paul Brook @ 2005-03-10  1:35 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 284 bytes --]

Some hosts (eg. arm-linux) don't support all the IEEE/C99 floating point 
rounding modes.

The attached patch adds appropriate ifdefs to the arm, ppc and sparc targets. 
Emulation obviously won't be perfect on these systems, but it will at least 
work to a first approximation.

Paul

[-- Attachment #2: patch.qemu_fpround --]
[-- Type: text/x-diff, Size: 4324 bytes --]

Index: target-arm/op_helper.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/op_helper.c,v
retrieving revision 1.1
diff -c -p -r1.1 op_helper.c
*** target-arm/op_helper.c	22 Feb 2005 19:27:29 -0000	1.1
--- target-arm/op_helper.c	10 Mar 2005 01:27:20 -0000
*************** int vfp_host_exceptbits_to_host(int targ
*** 177,183 ****
  
  void do_vfp_set_fpscr(void)
  {
-     int i;
      uint32_t changed;
  
      changed = env->vfp.fpscr;
--- 177,182 ----
*************** void do_vfp_set_fpscr(void)
*** 187,208 ****
  
      changed ^= T0;
      if (changed & (3 << 22)) {
!         i = (T0 >> 22) & 3;
!         switch (i) {
          case 0:
!             i = FE_TONEAREST;
              break;
          case 1:
!             i = FE_UPWARD;
              break;
          case 2:
!             i = FE_DOWNWARD;
              break;
          case 3:
!             i = FE_TOWARDZERO;
              break;
          }
-         fesetround (i);
      }
  
      /* Clear host exception flags.  */
--- 186,217 ----
  
      changed ^= T0;
      if (changed & (3 << 22)) {
!         switch ((T0 >> 22) & 3) {
          case 0:
!             /* Best approximation (round to nearest) */
! #ifdef FE_TONEAREST
!             fesetround(FE_TONEAREST);
! #endif
              break;
          case 1:
!             /* Smaller magnitude (round toward zero) */
! #ifdef FE_TOWARDZERO
!             fesetround(FE_TOWARDZERO);
! #endif
              break;
          case 2:
!             /* Round toward +infinite */
! #ifdef FE_UPWARD
!             fesetround(FE_UPWARD);
! #endif
              break;
          case 3:
!             /* Round toward -infinite */
! #ifdef FE_DOWNWARD
!             fesetround(FE_DOWNWARD);
! #endif
              break;
          }
      }
  
      /* Clear host exception flags.  */
*************** void do_vfp_set_fpscr(void)
*** 210,215 ****
--- 219,225 ----
  
  #ifdef feenableexcept
      if (changed & 0x1f00) {
+         int i;
          i = vfp_exceptbits_to_host((T0 >> 8) & 0x1f);
          feenableexcept (i);
          fedisableexcept (FE_ALL_EXCEPT & ~i);
Index: target-ppc/op_helper.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-ppc/op_helper.c,v
retrieving revision 1.11
diff -c -p -r1.11 op_helper.c
*** target-ppc/op_helper.c	15 Feb 2005 23:06:19 -0000	1.11
--- target-ppc/op_helper.c	10 Mar 2005 01:27:22 -0000
*************** void do_store_fpscr (uint32_t mask)
*** 227,245 ****
--- 227,253 ----
      switch (env->fpscr[0] & 0x3) {
      case 0:
          /* Best approximation (round to nearest) */
+ #ifdef FE_TONEAREST
          fesetround(FE_TONEAREST);
+ #endif
          break;
      case 1:
          /* Smaller magnitude (round toward zero) */
+ #ifdef FE_TOWARDZERO
          fesetround(FE_TOWARDZERO);
+ #endif
          break;
      case 2:
          /* Round toward +infinite */
+ #ifdef FE_UPWARD
          fesetround(FE_UPWARD);
+ #endif
          break;
      case 3:
          /* Round toward -infinite */
+ #ifdef FE_DOWNWARD
          fesetround(FE_DOWNWARD);
+ #endif
          break;
      }
  }
*************** void do_fctiwz (void)
*** 269,275 ****
--- 277,285 ----
      } *p = (void *)&FT1;
      int cround = fegetround();
  
+ #ifdef FE_TOWARDZERO
      fesetround(FE_TOWARDZERO);
+ #endif
      if (FT0 > (double)0x7FFFFFFF)
          p->i = 0x7FFFFFFFULL << 32;
      else if (FT0 < -(double)0x80000000)
Index: target-sparc/op_helper.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.9
diff -c -p -r1.9 op_helper.c
*** target-sparc/op_helper.c	22 Feb 2005 19:14:33 -0000	1.9
--- target-sparc/op_helper.c	10 Mar 2005 01:27:23 -0000
*************** void helper_ldfsr(void)
*** 252,267 ****
--- 252,275 ----
  {
      switch (env->fsr & FSR_RD_MASK) {
      case FSR_RD_NEAREST:
+ #ifdef FE_TONEAREST
  	fesetround(FE_TONEAREST);
+ #endif
  	break;
      case FSR_RD_ZERO:
+ #ifdef FE_TOWARDZERO
  	fesetround(FE_TOWARDZERO);
+ #endif
  	break;
      case FSR_RD_POS:
+ #ifdef FE_UPWARD
  	fesetround(FE_UPWARD);
+ #endif
  	break;
      case FSR_RD_NEG:
+ #ifdef FE_DOWNWARD
  	fesetround(FE_DOWNWARD);
+ #endif
  	break;
      }
  }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-03-10  2:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-10  1:35 [Qemu-devel] [patch] Missing rounding modes Paul Brook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).