From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LBwjE-00041f-Hn for qemu-devel@nongnu.org; Sun, 14 Dec 2008 14:34:12 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LBwjE-00041B-08 for qemu-devel@nongnu.org; Sun, 14 Dec 2008 14:34:12 -0500 Received: from [199.232.76.173] (port=49996 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LBwjD-00040v-PZ for qemu-devel@nongnu.org; Sun, 14 Dec 2008 14:34:11 -0500 Received: from savannah.gnu.org ([199.232.41.3]:51923 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LBwjD-0001EJ-72 for qemu-devel@nongnu.org; Sun, 14 Dec 2008 14:34:11 -0500 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1LBwjC-0006O9-Jp for qemu-devel@nongnu.org; Sun, 14 Dec 2008 19:34:10 +0000 Received: from aurel32 by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1LBwjC-0006O5-5O for qemu-devel@nongnu.org; Sun, 14 Dec 2008 19:34:10 +0000 MIME-Version: 1.0 Errors-To: aurel32 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Aurelien Jarno Message-Id: Date: Sun, 14 Dec 2008 19:34:10 +0000 Subject: [Qemu-devel] [6034] target-ppc: fix fcmp{o,u} instructions 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 Revision: 6034 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6034 Author: aurel32 Date: 2008-12-14 19:34:09 +0000 (Sun, 14 Dec 2008) Log Message: ----------- 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 Signed-off-by: Aurelien Jarno Modified Paths: -------------- trunk/target-ppc/helper.h trunk/target-ppc/op_helper.c trunk/target-ppc/translate.c Modified: trunk/target-ppc/helper.h =================================================================== --- trunk/target-ppc/helper.h 2008-12-14 18:59:08 UTC (rev 6033) +++ trunk/target-ppc/helper.h 2008-12-14 19:34:09 UTC (rev 6034) @@ -63,8 +63,8 @@ DEF_HELPER_1(float64_to_float32, i32, i64) DEF_HELPER_1(float32_to_float64, i64, i32) -DEF_HELPER_2(fcmpo, i32, i64, i64) -DEF_HELPER_2(fcmpu, i32, i64, i64) +DEF_HELPER_3(fcmpo, void, i64, i64, i32) +DEF_HELPER_3(fcmpu, void, i64, i64, i32) DEF_HELPER_1(fctiw, i64, i64) DEF_HELPER_1(fctiwz, i64, i64) Modified: trunk/target-ppc/op_helper.c =================================================================== --- trunk/target-ppc/op_helper.c 2008-12-14 18:59:08 UTC (rev 6033) +++ trunk/target-ppc/op_helper.c 2008-12-14 19:34:09 UTC (rev 6034) @@ -1620,32 +1620,36 @@ 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 @@ 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 @@ /* 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) Modified: trunk/target-ppc/translate.c =================================================================== --- trunk/target-ppc/translate.c 2008-12-14 18:59:08 UTC (rev 6033) +++ trunk/target-ppc/translate.c 2008-12-14 19:34:09 UTC (rev 6034) @@ -2249,26 +2249,30 @@ /* fcmpo */ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) { + TCGv crf; if (unlikely(!ctx->fpu_enabled)) { gen_exception(ctx, POWERPC_EXCP_FPU); return; } gen_reset_fpstatus(); - gen_helper_fcmpo(cpu_crf[crfD(ctx->opcode)], - cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); + crf = tcg_const_i32(crfD(ctx->opcode)); + gen_helper_fcmpo(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf); + tcg_temp_free(crf); gen_helper_float_check_status(); } /* fcmpu */ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) { + TCGv crf; if (unlikely(!ctx->fpu_enabled)) { gen_exception(ctx, POWERPC_EXCP_FPU); return; } gen_reset_fpstatus(); - gen_helper_fcmpu(cpu_crf[crfD(ctx->opcode)], - cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); + crf = tcg_const_i32(crfD(ctx->opcode)); + gen_helper_fcmpu(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf); + tcg_temp_free(crf); gen_helper_float_check_status(); }