From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1K0D1X-0005Pr-Rj for qemu-devel@nongnu.org; Sun, 25 May 2008 06:00:19 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1K0D1V-0005P2-1Z for qemu-devel@nongnu.org; Sun, 25 May 2008 06:00:18 -0400 Received: from [199.232.76.173] (port=59340 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K0D1T-0005Oa-EO for qemu-devel@nongnu.org; Sun, 25 May 2008 06:00:15 -0400 Received: from ug-out-1314.google.com ([66.249.92.171]:45880) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1K0D1S-0002GA-MJ for qemu-devel@nongnu.org; Sun, 25 May 2008 06:00:14 -0400 Received: by ug-out-1314.google.com with SMTP id j40so178482ugd.4 for ; Sun, 25 May 2008 03:00:13 -0700 (PDT) From: Richard Sandiford Date: Sun, 25 May 2008 11:00:10 +0100 Message-ID: <87k5hi66vp.fsf@firetop.home> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Subject: [Qemu-devel] [PATCH] Fix modulus result from MIPS DDIV & avoid overflowing division 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 The MIPS DDIV code assigns the division result to cpu_T[0] before the remainder code has read the dividend. Fixed by using the same sort of construct as DDIVU, which doesn't have this problem. Also, the code checks for overflowing division cases, but it doesn't avoid doing the division itself; it only avoids doing the remainder. We don't really need to do anything, because the dividend is also the quotient. Richard Index: qemu/target-mips/translate.c =================================================================== --- qemu.orig/target-mips/translate.c 2008-05-25 09:57:00.000000000 +0100 +++ qemu/target-mips/translate.c 2008-05-25 09:57:08.000000000 +0100 @@ -2047,20 +2047,25 @@ static void gen_muldiv (DisasContext *ct tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); { int l2 = gen_new_label(); - int l3 = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 1ULL << 63, l2); tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1ULL, l2); - tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_movi_tl(cpu_T[1], 0); - tcg_gen_br(l3); + { + tcg_gen_movi_tl(cpu_T[1], 0); + gen_store_LO(cpu_T[0], 0); + gen_store_HI(cpu_T[1], 0); + tcg_gen_br(l1); + } gen_set_label(l2); - tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_rem_i64(cpu_T[1], cpu_T[0], cpu_T[1]); - gen_set_label(l3); - - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]); + tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]); + gen_store_LO(r_tmp1, 0); + gen_store_HI(r_tmp2, 0); + } } gen_set_label(l1); }