diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-14 19:34:09 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-14 19:34:09 +0000 |
commit | 9a819377d80f99a4293fd753dd1e90e6cbd618d2 (patch) | |
tree | 1631d578390caebcb09e69bd26c801ca816dfd51 /target-ppc/op_helper.c | |
parent | b12363e1b7d7454daa21c861290f49de42c2ea71 (diff) |
target-ppc: fix fcmp{o,u} instructions
The instructions are specified to update the condition register even if
an error is to be signaled because of NaN input.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6034 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-ppc/op_helper.c')
-rw-r--r-- | target-ppc/op_helper.c | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index a46c00c9d7..a26b1ddb28 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -1620,32 +1620,36 @@ uint64_t helper_fsel (uint64_t arg1, uint64_t arg2, uint64_t arg3) return arg3; } -uint32_t helper_fcmpu (uint64_t arg1, uint64_t arg2) +void helper_fcmpu (uint64_t arg1, uint64_t arg2, uint32_t crfD) { CPU_DoubleU farg1, farg2; uint32_t ret = 0; farg1.ll = arg1; farg2.ll = arg2; - if (unlikely(float64_is_signaling_nan(farg1.d) || - float64_is_signaling_nan(farg2.d))) { - /* sNaN comparison */ - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); + if (unlikely(float64_is_nan(farg1.d) || + float64_is_nan(farg2.d))) { + ret = 0x01UL; + } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) { + ret = 0x08UL; + } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) { + ret = 0x04UL; } else { - if (float64_lt(farg1.d, farg2.d, &env->fp_status)) { - ret = 0x08UL; - } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) { - ret = 0x04UL; - } else { - ret = 0x02UL; - } + ret = 0x02UL; } + env->fpscr &= ~(0x0F << FPSCR_FPRF); env->fpscr |= ret << FPSCR_FPRF; - return ret; + env->crf[crfD] = ret; + if (unlikely(ret == 0x01UL + && (float64_is_signaling_nan(farg1.d) || + float64_is_signaling_nan(farg2.d)))) { + /* sNaN comparison */ + fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); + } } -uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2) +void helper_fcmpo (uint64_t arg1, uint64_t arg2, uint32_t crfD) { CPU_DoubleU farg1, farg2; uint32_t ret = 0; @@ -1654,6 +1658,19 @@ uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2) if (unlikely(float64_is_nan(farg1.d) || float64_is_nan(farg2.d))) { + ret = 0x01UL; + } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) { + ret = 0x08UL; + } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) { + ret = 0x04UL; + } else { + ret = 0x02UL; + } + + env->fpscr &= ~(0x0F << FPSCR_FPRF); + env->fpscr |= ret << FPSCR_FPRF; + env->crf[crfD] = ret; + if (unlikely (ret == 0x01UL)) { if (float64_is_signaling_nan(farg1.d) || float64_is_signaling_nan(farg2.d)) { /* sNaN comparison */ @@ -1663,18 +1680,7 @@ uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2) /* qNaN comparison */ fload_invalid_op_excp(POWERPC_EXCP_FP_VXVC); } - } else { - if (float64_lt(farg1.d, farg2.d, &env->fp_status)) { - ret = 0x08UL; - } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) { - ret = 0x04UL; - } else { - ret = 0x02UL; - } } - env->fpscr &= ~(0x0F << FPSCR_FPRF); - env->fpscr |= ret << FPSCR_FPRF; - return ret; } #if !defined (CONFIG_USER_ONLY) |