From: Thiemo Seufer <ths@networkno.de>
To: "J. Mayer" <l_indien@magic.fr>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] qemu host-utils.c
Date: Wed, 24 Oct 2007 18:37:26 +0100 [thread overview]
Message-ID: <20071024173726.GC6666@networkno.de> (raw)
In-Reply-To: <1193222136.16781.229.camel@rapid>
J. Mayer wrote:
>
> On Wed, 2007-10-24 at 12:20 +0200, Fabrice Bellard wrote:
> > I strongly suggest to reuse my code which was in target-i386/helper.c
> > revision 1.80 which was far easier to validate. Moreover, integer
> > divisions from target-i386/helper.c should be put in the same file.
>
> I fully agree with this. I still use the same code in the PowerPC
> op_helper.c file because I never conviced myself that the host_utils
> version was bug-free. I would likely switch to the common version if I
> could be sure it cannot lead to any regression.
Like this? Questions/Comments I have:
- Is the BSD-style copyright still ok for this version?
- The x86-64 assembler is untested for this version, could you check
it works for you?
- SPARC and Alpha look like they will break on 32bit hosts, they should
do multiplications the same way as the other 64bit targets.
Thiemo
Index: qemu-cvs/host-utils.c
===================================================================
--- qemu-cvs.orig/host-utils.c
+++ qemu-cvs/host-utils.c
@@ -1,6 +1,8 @@
/*
* Utility compute operations used by translated code.
*
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2003-2007 Jocelyn Mayer
* Copyright (c) 2007 Aurelien Jarno
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,54 +26,90 @@
#include "vl.h"
-/* Signed 64x64 -> 128 multiplication */
+#define DEBUG_MULDEV
-void muls64(int64_t *phigh, int64_t *plow, int64_t a, int64_t b)
+/* Long integer helpers */
+static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
{
-#if defined(__x86_64__)
- __asm__ ("imul %0\n\t"
- : "=d" (*phigh), "=a" (*plow)
- : "a" (a), "0" (b)
- );
-#else
- int64_t ph;
- uint64_t pm1, pm2, pl;
+ *plow += a;
+ /* carry test */
+ if (*plow < a)
+ (*phigh)++;
+ *phigh += b;
+}
+
+static void neg128 (uint64_t *plow, uint64_t *phigh)
+{
+ *plow = ~*plow;
+ *phigh = ~*phigh;
+ add128(plow, phigh, 1, 0);
+}
- pl = (uint64_t)((uint32_t)a) * (uint64_t)((uint32_t)b);
- pm1 = (a >> 32) * (uint32_t)b;
- pm2 = (uint32_t)a * (b >> 32);
- ph = (a >> 32) * (b >> 32);
-
- ph += (int64_t)pm1 >> 32;
- ph += (int64_t)pm2 >> 32;
- pm1 = (uint64_t)((uint32_t)pm1) + (uint64_t)((uint32_t)pm2) + (pl >> 32);
+static void mul64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
+{
+ uint32_t a0, a1, b0, b1;
+ uint64_t v;
- *phigh = ph + ((int64_t)pm1 >> 32);
- *plow = (pm1 << 32) + (uint32_t)pl;
-#endif
+ a0 = a;
+ a1 = a >> 32;
+
+ b0 = b;
+ b1 = b >> 32;
+
+ v = (uint64_t)a0 * (uint64_t)b0;
+ *plow = v;
+ *phigh = 0;
+
+ v = (uint64_t)a0 * (uint64_t)b1;
+ add128(plow, phigh, v << 32, v >> 32);
+
+ v = (uint64_t)a1 * (uint64_t)b0;
+ add128(plow, phigh, v << 32, v >> 32);
+
+ v = (uint64_t)a1 * (uint64_t)b1;
+ *phigh += v;
}
+
/* Unsigned 64x64 -> 128 multiplication */
-void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b)
+void mulu64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
{
#if defined(__x86_64__)
__asm__ ("mul %0\n\t"
: "=d" (*phigh), "=a" (*plow)
- : "a" (a), "0" (b)
- );
+ : "a" (a), "0" (b));
#else
- uint64_t ph, pm1, pm2, pl;
+ mul64(plow, phigh, a, b);
+#endif
+#if defined(DEBUG_MULDIV)
+ printf("mulu64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
+ a, b, *phigh, *plow);
+#endif
+}
- pl = (uint64_t)((uint32_t)a) * (uint64_t)((uint32_t)b);
- pm1 = (a >> 32) * (uint32_t)b;
- pm2 = (uint32_t)a * (b >> 32);
- ph = (a >> 32) * (b >> 32);
-
- ph += pm1 >> 32;
- ph += pm2 >> 32;
- pm1 = (uint64_t)((uint32_t)pm1) + (uint64_t)((uint32_t)pm2) + (pl >> 32);
+/* Signed 64x64 -> 128 multiplication */
+void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
+{
+#if defined(__x86_64__)
+ __asm__ ("imul %0\n\t"
+ : "=d" (*phigh), "=a" (*plow)
+ : "a" (a), "0" (b));
+#else
+ int sa, sb;
- *phigh = ph + (pm1 >> 32);
- *plow = (pm1 << 32) + (uint32_t)pl;
+ sa = (a < 0);
+ if (sa)
+ a = -a;
+ sb = (b < 0);
+ if (sb)
+ b = -b;
+ mul64(plow, phigh, a, b);
+ if (sa ^ sb) {
+ neg128(plow, phigh);
+ }
+#endif
+#if defined(DEBUG_MULDIV)
+ printf("muls64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
+ a, b, *phigh, *plow);
#endif
}
Index: qemu-cvs/target-ppc/op_helper.c
===================================================================
--- qemu-cvs.orig/target-ppc/op_helper.c
+++ qemu-cvs/target-ppc/op_helper.c
@@ -217,75 +217,14 @@
/*****************************************************************************/
/* Fixed point operations helpers */
#if defined(TARGET_PPC64)
-static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
-{
- *plow += a;
- /* carry test */
- if (*plow < a)
- (*phigh)++;
- *phigh += b;
-}
-
-static void neg128 (uint64_t *plow, uint64_t *phigh)
-{
- *plow = ~*plow;
- *phigh = ~*phigh;
- add128(plow, phigh, 1, 0);
-}
-
-static void mul64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
-{
- uint32_t a0, a1, b0, b1;
- uint64_t v;
-
- a0 = a;
- a1 = a >> 32;
-
- b0 = b;
- b1 = b >> 32;
-
- v = (uint64_t)a0 * (uint64_t)b0;
- *plow = v;
- *phigh = 0;
-
- v = (uint64_t)a0 * (uint64_t)b1;
- add128(plow, phigh, v << 32, v >> 32);
-
- v = (uint64_t)a1 * (uint64_t)b0;
- add128(plow, phigh, v << 32, v >> 32);
-
- v = (uint64_t)a1 * (uint64_t)b1;
- *phigh += v;
-#if defined(DEBUG_MULDIV)
- printf("mul: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
- a, b, *phigh, *plow);
-#endif
-}
-
void do_mul64 (uint64_t *plow, uint64_t *phigh)
{
- mul64(plow, phigh, T0, T1);
-}
-
-static void imul64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
-{
- int sa, sb;
-
- sa = (a < 0);
- if (sa)
- a = -a;
- sb = (b < 0);
- if (sb)
- b = -b;
- mul64(plow, phigh, a, b);
- if (sa ^ sb) {
- neg128(plow, phigh);
- }
+ mulu64(plow, phigh, T0, T1);
}
void do_imul64 (uint64_t *plow, uint64_t *phigh)
{
- imul64(plow, phigh, T0, T1);
+ muls64(plow, phigh, T0, T1);
}
#endif
Index: qemu-cvs/exec-all.h
===================================================================
--- qemu-cvs.orig/exec-all.h
+++ qemu-cvs/exec-all.h
@@ -91,8 +91,8 @@
extern FILE *logfile;
extern int loglevel;
-void muls64(int64_t *phigh, int64_t *plow, int64_t a, int64_t b);
-void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
+void muls64(int64_t *plow, int64_t *phigh, int64_t a, int64_t b);
+void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
Index: qemu-cvs/target-i386/helper.c
===================================================================
--- qemu-cvs.orig/target-i386/helper.c
+++ qemu-cvs/target-i386/helper.c
@@ -3735,7 +3735,7 @@
{
uint64_t r0, r1;
- muls64(&r1, &r0, EAX, T0);
+ muls64(&r0, &r1, EAX, T0);
EAX = r0;
EDX = r1;
CC_DST = r0;
@@ -3746,7 +3746,7 @@
{
uint64_t r0, r1;
- muls64(&r1, &r0, T0, T1);
+ muls64(&r0, &r1, T0, T1);
T0 = r0;
CC_DST = r0;
CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
Index: qemu-cvs/target-mips/op.c
===================================================================
--- qemu-cvs.orig/target-mips/op.c
+++ qemu-cvs/target-mips/op.c
@@ -876,13 +876,13 @@
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
void op_dmult (void)
{
- CALL_FROM_TB4(muls64, &(env->HI[0][env->current_tc]), &(env->LO[0][env->current_tc]), T0, T1);
+ CALL_FROM_TB4(muls64, &(env->LO[0][env->current_tc]), &(env->HI[0][env->current_tc]), T0, T1);
RETURN();
}
void op_dmultu (void)
{
- CALL_FROM_TB4(mulu64, &(env->HI[0][env->current_tc]), &(env->LO[0][env->current_tc]), T0, T1);
+ CALL_FROM_TB4(mulu64, &(env->LO[0][env->current_tc]), &(env->HI[0][env->current_tc]), T0, T1);
RETURN();
}
#endif
next prev parent reply other threads:[~2007-10-24 17:37 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-23 23:22 [Qemu-devel] qemu host-utils.c Thiemo Seufer
2007-10-24 10:20 ` Fabrice Bellard
2007-10-24 10:35 ` J. Mayer
2007-10-24 17:37 ` Thiemo Seufer [this message]
2007-10-24 18:46 ` Jocelyn Mayer
2007-10-24 19:26 ` Fabrice Bellard
2007-10-24 22:26 ` J. Mayer
2007-10-25 23:00 ` Thiemo Seufer
2007-10-27 6:45 ` Blue Swirl
2007-10-27 11:11 ` Thiemo Seufer
-- strict thread matches above, loose matches on Subject: below --
2007-10-25 23:00 Thiemo Seufer
2007-11-05 13:01 Jocelyn Mayer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20071024173726.GC6666@networkno.de \
--to=ths@networkno.de \
--cc=l_indien@magic.fr \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.