Commit 9a819377d80f99a4293fd753dd1e90e6cbd618d2
1 parent
b12363e1
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
Showing
3 changed files
with
41 additions
and
31 deletions
target-ppc/helper.h
... | ... | @@ -63,8 +63,8 @@ DEF_HELPER_1(fpscr_setbit, void, i32) |
63 | 63 | DEF_HELPER_1(float64_to_float32, i32, i64) |
64 | 64 | DEF_HELPER_1(float32_to_float64, i64, i32) |
65 | 65 | |
66 | -DEF_HELPER_2(fcmpo, i32, i64, i64) | |
67 | -DEF_HELPER_2(fcmpu, i32, i64, i64) | |
66 | +DEF_HELPER_3(fcmpo, void, i64, i64, i32) | |
67 | +DEF_HELPER_3(fcmpu, void, i64, i64, i32) | |
68 | 68 | |
69 | 69 | DEF_HELPER_1(fctiw, i64, i64) |
70 | 70 | DEF_HELPER_1(fctiwz, i64, i64) | ... | ... |
target-ppc/op_helper.c
... | ... | @@ -1620,32 +1620,36 @@ uint64_t helper_fsel (uint64_t arg1, uint64_t arg2, uint64_t arg3) |
1620 | 1620 | return arg3; |
1621 | 1621 | } |
1622 | 1622 | |
1623 | -uint32_t helper_fcmpu (uint64_t arg1, uint64_t arg2) | |
1623 | +void helper_fcmpu (uint64_t arg1, uint64_t arg2, uint32_t crfD) | |
1624 | 1624 | { |
1625 | 1625 | CPU_DoubleU farg1, farg2; |
1626 | 1626 | uint32_t ret = 0; |
1627 | 1627 | farg1.ll = arg1; |
1628 | 1628 | farg2.ll = arg2; |
1629 | 1629 | |
1630 | - if (unlikely(float64_is_signaling_nan(farg1.d) || | |
1631 | - float64_is_signaling_nan(farg2.d))) { | |
1632 | - /* sNaN comparison */ | |
1633 | - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); | |
1630 | + if (unlikely(float64_is_nan(farg1.d) || | |
1631 | + float64_is_nan(farg2.d))) { | |
1632 | + ret = 0x01UL; | |
1633 | + } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) { | |
1634 | + ret = 0x08UL; | |
1635 | + } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) { | |
1636 | + ret = 0x04UL; | |
1634 | 1637 | } else { |
1635 | - if (float64_lt(farg1.d, farg2.d, &env->fp_status)) { | |
1636 | - ret = 0x08UL; | |
1637 | - } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) { | |
1638 | - ret = 0x04UL; | |
1639 | - } else { | |
1640 | - ret = 0x02UL; | |
1641 | - } | |
1638 | + ret = 0x02UL; | |
1642 | 1639 | } |
1640 | + | |
1643 | 1641 | env->fpscr &= ~(0x0F << FPSCR_FPRF); |
1644 | 1642 | env->fpscr |= ret << FPSCR_FPRF; |
1645 | - return ret; | |
1643 | + env->crf[crfD] = ret; | |
1644 | + if (unlikely(ret == 0x01UL | |
1645 | + && (float64_is_signaling_nan(farg1.d) || | |
1646 | + float64_is_signaling_nan(farg2.d)))) { | |
1647 | + /* sNaN comparison */ | |
1648 | + fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); | |
1649 | + } | |
1646 | 1650 | } |
1647 | 1651 | |
1648 | -uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2) | |
1652 | +void helper_fcmpo (uint64_t arg1, uint64_t arg2, uint32_t crfD) | |
1649 | 1653 | { |
1650 | 1654 | CPU_DoubleU farg1, farg2; |
1651 | 1655 | uint32_t ret = 0; |
... | ... | @@ -1654,6 +1658,19 @@ uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2) |
1654 | 1658 | |
1655 | 1659 | if (unlikely(float64_is_nan(farg1.d) || |
1656 | 1660 | float64_is_nan(farg2.d))) { |
1661 | + ret = 0x01UL; | |
1662 | + } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) { | |
1663 | + ret = 0x08UL; | |
1664 | + } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) { | |
1665 | + ret = 0x04UL; | |
1666 | + } else { | |
1667 | + ret = 0x02UL; | |
1668 | + } | |
1669 | + | |
1670 | + env->fpscr &= ~(0x0F << FPSCR_FPRF); | |
1671 | + env->fpscr |= ret << FPSCR_FPRF; | |
1672 | + env->crf[crfD] = ret; | |
1673 | + if (unlikely (ret == 0x01UL)) { | |
1657 | 1674 | if (float64_is_signaling_nan(farg1.d) || |
1658 | 1675 | float64_is_signaling_nan(farg2.d)) { |
1659 | 1676 | /* sNaN comparison */ |
... | ... | @@ -1663,18 +1680,7 @@ uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2) |
1663 | 1680 | /* qNaN comparison */ |
1664 | 1681 | fload_invalid_op_excp(POWERPC_EXCP_FP_VXVC); |
1665 | 1682 | } |
1666 | - } else { | |
1667 | - if (float64_lt(farg1.d, farg2.d, &env->fp_status)) { | |
1668 | - ret = 0x08UL; | |
1669 | - } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) { | |
1670 | - ret = 0x04UL; | |
1671 | - } else { | |
1672 | - ret = 0x02UL; | |
1673 | - } | |
1674 | 1683 | } |
1675 | - env->fpscr &= ~(0x0F << FPSCR_FPRF); | |
1676 | - env->fpscr |= ret << FPSCR_FPRF; | |
1677 | - return ret; | |
1678 | 1684 | } |
1679 | 1685 | |
1680 | 1686 | #if !defined (CONFIG_USER_ONLY) | ... | ... |
target-ppc/translate.c
... | ... | @@ -2249,26 +2249,30 @@ GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT); |
2249 | 2249 | /* fcmpo */ |
2250 | 2250 | GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) |
2251 | 2251 | { |
2252 | + TCGv crf; | |
2252 | 2253 | if (unlikely(!ctx->fpu_enabled)) { |
2253 | 2254 | gen_exception(ctx, POWERPC_EXCP_FPU); |
2254 | 2255 | return; |
2255 | 2256 | } |
2256 | 2257 | gen_reset_fpstatus(); |
2257 | - gen_helper_fcmpo(cpu_crf[crfD(ctx->opcode)], | |
2258 | - cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); | |
2258 | + crf = tcg_const_i32(crfD(ctx->opcode)); | |
2259 | + gen_helper_fcmpo(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf); | |
2260 | + tcg_temp_free(crf); | |
2259 | 2261 | gen_helper_float_check_status(); |
2260 | 2262 | } |
2261 | 2263 | |
2262 | 2264 | /* fcmpu */ |
2263 | 2265 | GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) |
2264 | 2266 | { |
2267 | + TCGv crf; | |
2265 | 2268 | if (unlikely(!ctx->fpu_enabled)) { |
2266 | 2269 | gen_exception(ctx, POWERPC_EXCP_FPU); |
2267 | 2270 | return; |
2268 | 2271 | } |
2269 | 2272 | gen_reset_fpstatus(); |
2270 | - gen_helper_fcmpu(cpu_crf[crfD(ctx->opcode)], | |
2271 | - cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); | |
2273 | + crf = tcg_const_i32(crfD(ctx->opcode)); | |
2274 | + gen_helper_fcmpu(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf); | |
2275 | + tcg_temp_free(crf); | |
2272 | 2276 | gen_helper_float_check_status(); |
2273 | 2277 | } |
2274 | 2278 | ... | ... |