From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1D9DKV-0003gH-MS for qemu-devel@nongnu.org; Wed, 09 Mar 2005 21:23:15 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1D9DKU-0003fs-NP for qemu-devel@nongnu.org; Wed, 09 Mar 2005 21:23:15 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1D9DJL-0003Cu-V6 for qemu-devel@nongnu.org; Wed, 09 Mar 2005 21:22:04 -0500 Received: from [65.74.133.9] (helo=mail.codesourcery.com) by monty-python.gnu.org with esmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.34) id 1D9CaO-0004pp-E6 for qemu-devel@nongnu.org; Wed, 09 Mar 2005 20:35:36 -0500 From: Paul Brook Date: Thu, 10 Mar 2005 01:35:31 +0000 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_kR6LClVzGx8YC9l" Message-Id: <200503100135.32859.paul@codesourcery.com> Subject: [Qemu-devel] [patch] Missing rounding modes. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --Boundary-00=_kR6LClVzGx8YC9l Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline 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 --Boundary-00=_kR6LClVzGx8YC9l Content-Type: text/x-diff; charset="us-ascii"; name="patch.qemu_fpround" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="patch.qemu_fpround" 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; } } --Boundary-00=_kR6LClVzGx8YC9l--