diff options
author | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-11-04 02:24:58 +0000 |
---|---|---|
committer | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-11-04 02:24:58 +0000 |
commit | 7a51ad822f533472cab908d2622578d51eb97dc6 (patch) | |
tree | 92e7d1dda1536cd9260d203ac93714e3adedd24b | |
parent | 077fc2061e254422c44b2de16c526476398113ae (diff) |
For consistency, move muls64 / mulu64 prototypes to host-utils.h
Make x86_64 optimized versions inline.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3523 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | exec-all.h | 3 | ||||
-rw-r--r-- | host-utils.c | 15 | ||||
-rw-r--r-- | host-utils.h | 53 | ||||
-rw-r--r-- | target-alpha/op.c | 1 | ||||
-rw-r--r-- | target-i386/helper.c | 1 |
5 files changed, 31 insertions, 42 deletions
diff --git a/exec-all.h b/exec-all.h index 861688bd5c..0ced25ca13 100644 --- a/exec-all.h +++ b/exec-all.h @@ -91,9 +91,6 @@ void optimize_flags_init(void); 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); - int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); diff --git a/host-utils.c b/host-utils.c index a3c838f4dc..7cd0843f94 100644 --- a/host-utils.c +++ b/host-utils.c @@ -28,6 +28,7 @@ //#define DEBUG_MULDIV /* Long integer helpers */ +#if !defined(__x86_64__) static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) { *plow += a; @@ -69,17 +70,10 @@ static void mul64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) *phigh += v; } - /* Unsigned 64x64 -> 128 multiplication */ 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)); -#else mul64(plow, phigh, a, b); -#endif #if defined(DEBUG_MULDIV) printf("mulu64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n", a, b, *phigh, *plow); @@ -89,11 +83,6 @@ void mulu64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) /* 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; sa = (a < 0); @@ -106,9 +95,9 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t 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 } +#endif /* !defined(__x86_64__) */ diff --git a/host-utils.h b/host-utils.h index fe306f6e48..234a062182 100644 --- a/host-utils.h +++ b/host-utils.h @@ -23,6 +23,28 @@ * THE SOFTWARE. */ +#if defined(__x86_64__) +#define __HAVE_FAST_MULU64__ +static always_inline void mulu64 (uint64_t *plow, uint64_t *phigh, + uint64_t a, uint64_t b) +{ + __asm__ ("mul %0\n\t" + : "=d" (*phigh), "=a" (*plow) + : "a" (a), "0" (b)); +} +#define __HAVE_FAST_MULS64__ +static always_inline void muls64 (uint64_t *plow, uint64_t *phigh, + int64_t a, int64_t b) +{ + __asm__ ("imul %0\n\t" + : "=d" (*phigh), "=a" (*plow) + : "a" (a), "0" (b)); +} +#else +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); +#endif + /* Note that some of those functions may end up calling libgcc functions, depending on the host machine. It is up to the target emulation to cope with that. */ @@ -68,34 +90,13 @@ static always_inline int clz64(uint64_t val) { int cnt = 0; - if (!(val & 0xFFFFFFFF00000000ULL)) { + if (!(val >> 32)) { cnt += 32; - val <<= 32; - } - if (!(val & 0xFFFF000000000000ULL)) { - cnt += 16; - val <<= 16; - } - if (!(val & 0xFF00000000000000ULL)) { - cnt += 8; - val <<= 8; - } - if (!(val & 0xF000000000000000ULL)) { - cnt += 4; - val <<= 4; - } - if (!(val & 0xC000000000000000ULL)) { - cnt += 2; - val <<= 2; - } - if (!(val & 0x8000000000000000ULL)) { - cnt++; - val <<= 1; - } - if (!(val & 0x8000000000000000ULL)) { - cnt++; + } else { + val >>= 32; } - return cnt; + + return cnt + clz32(val); } static always_inline int clo64(uint64_t val) diff --git a/target-alpha/op.c b/target-alpha/op.c index 2a52be4f49..da93e7cdfb 100644 --- a/target-alpha/op.c +++ b/target-alpha/op.c @@ -22,6 +22,7 @@ #include "config.h" #include "exec.h" +#include "host-utils.h" #include "op_helper.h" diff --git a/target-i386/helper.c b/target-i386/helper.c index bb927f673d..0a75e8c335 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "exec.h" +#include "host-utils.h" //#define DEBUG_PCALL |