From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Ho45D-0001mE-N1 for qemu-devel@nongnu.org; Tue, 15 May 2007 16:57:23 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Ho45C-0001m2-8k for qemu-devel@nongnu.org; Tue, 15 May 2007 16:57:22 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ho45C-0001lz-4E for qemu-devel@nongnu.org; Tue, 15 May 2007 16:57:22 -0400 Received: from farad.aurel32.net ([82.232.2.251] helo=mail.aurel32.net) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Ho3xH-0003RS-78 for qemu-devel@nongnu.org; Tue, 15 May 2007 16:49:11 -0400 Received: from amd64.aurel32.net ([2001:618:400:fc13:216:3eff:fe00:1009]) by mail.aurel32.net with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.63) (envelope-from ) id 1Ho3xB-0008Pk-SI for qemu-devel@nongnu.org; Tue, 15 May 2007 22:49:05 +0200 Received: from aurel32 by amd64.aurel32.net with local (Exim 4.67) (envelope-from ) id 1Ho3xB-00054s-Ex for qemu-devel@nongnu.org; Tue, 15 May 2007 22:49:05 +0200 Date: Tue, 15 May 2007 22:49:05 +0200 From: Aurelien Jarno Message-ID: <20070515204903.GA19494@amd64.aurel32.net> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-15 Content-Disposition: inline Subject: [Qemu-devel] [PATCH, MIPS64] dmult & dmultu emulation 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 Hi, The patch below fixes the emulation of dmult and dmultu by doing a real 64x64 -> 128 multiplication. On x86_64, it uses the mul/imul instruction, an equivalent C code (but much slower) is provided for other architectures. Cheers, Aurelien Index: target-mips/op_helper.c =================================================================== RCS file: /sources/qemu/qemu/target-mips/op_helper.c,v retrieving revision 1.45 diff -u -d -p -r1.45 op_helper.c --- target-mips/op_helper.c 13 May 2007 19:22:13 -0000 1.45 +++ target-mips/op_helper.c 15 May 2007 20:40:12 -0000 @@ -230,16 +230,49 @@ void do_div (void) #ifdef TARGET_MIPS64 void do_dmult (void) { - env->LO = (int64_t)T0 * (int64_t)T1; - /* XXX */ - env->HI = (env->LO | (1ULL << 63)) ? ~0ULL : 0ULL; +#if defined(__x86_64__) + __asm__ ("imul %0\n\t" + : "=d" (env->HI), "=a" (env->LO) + : "a" (T0), "0" (T1) + ); +#else + int64_t ph; + uint64_t pm1, pm2, pl; + + pl = (uint64_t)((uint32_t)T0) * (uint64_t)((uint32_t)T1); + pm1 = ((int64_t)T0 >> 32) * (uint32_t)T1; + pm2 = (uint32_t)T0 * ((int64_t)T1 >> 32); + ph = ((int64_t)T0 >> 32) * ((int64_t)T1 >> 32); + + ph += ((int64_t)pm1) >> 32; + pm1 = (uint64_t)((uint32_t)pm1) + pm2 + (pl >> 32); + + env->HI = ph + ((int64_t)pm1) >> 32; + env->LO = (pm1 << 32) + (uint32_t)pl; +#endif } void do_dmultu (void) { - env->LO = T0 * T1; - /* XXX */ - env->HI = 0; +#if defined(__x86_64__) + __asm__ ("mul %0\n\t" + : "=d" (env->HI), "=a" (env->LO) + : "a" (T0), "0" (T1) + ); +#else + uint64_t ph, pm1, pm2, pl; + + pl = (uint64_t)((uint32_t)T0) * (uint64_t)((uint32_t)T1); + pm1 = (T0 >> 32) * (uint32_t)T1; + pm2 = (uint32_t)T0 * (T1 >> 32); + ph = (T0 >> 32) * (T1 >> 32); + + ph += pm1 >> 32; + pm1 = (uint64_t)((uint32_t)pm1) + pm2 + (pl >> 32); + + env->HI = ph + (pm1 >> 32); + env->LO = (pm1 << 32) + (uint32_t)pl; +#endif } void do_ddiv (void) -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' aurel32@debian.org | aurelien@aurel32.net `- people.debian.org/~aurel32 | www.aurel32.net