Commit 69d357286d0ab5a852e827dad1dc4b05917aaaa8
1 parent
100ce988
More generic 64 bit multiplication support, by Aurelien Jarno.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2821 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
7 changed files
with
84 additions
and
65 deletions
Makefile.target
@@ -365,6 +365,7 @@ endif | @@ -365,6 +365,7 @@ endif | ||
365 | # must use static linking to avoid leaving stuff in virtual address space | 365 | # must use static linking to avoid leaving stuff in virtual address space |
366 | VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o loader.o isa_mmio.o | 366 | VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o loader.o isa_mmio.o |
367 | VL_OBJS+=cutils.o | 367 | VL_OBJS+=cutils.o |
368 | +VL_OBJS+=host-utils.o | ||
368 | VL_OBJS+=block.o block-raw.o | 369 | VL_OBJS+=block.o block-raw.o |
369 | VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o | 370 | VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o |
370 | VL_OBJS+=irq.o | 371 | VL_OBJS+=irq.o |
exec-all.h
@@ -78,6 +78,9 @@ void optimize_flags_init(void); | @@ -78,6 +78,9 @@ void optimize_flags_init(void); | ||
78 | extern FILE *logfile; | 78 | extern FILE *logfile; |
79 | extern int loglevel; | 79 | extern int loglevel; |
80 | 80 | ||
81 | +void muls64(int64_t *phigh, int64_t *plow, int64_t a, int64_t b); | ||
82 | +void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b); | ||
83 | + | ||
81 | int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); | 84 | int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); |
82 | int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); | 85 | int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); |
83 | void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); | 86 | void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); |
host-utils.c
0 → 100644
1 | +/* | ||
2 | + * Utility compute operations used by translated code. | ||
3 | + * | ||
4 | + * Copyright (c) 2007 Aurelien Jarno | ||
5 | + * | ||
6 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
7 | + * of this software and associated documentation files (the "Software"), to deal | ||
8 | + * in the Software without restriction, including without limitation the rights | ||
9 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
10 | + * copies of the Software, and to permit persons to whom the Software is | ||
11 | + * furnished to do so, subject to the following conditions: | ||
12 | + * | ||
13 | + * The above copyright notice and this permission notice shall be included in | ||
14 | + * all copies or substantial portions of the Software. | ||
15 | + * | ||
16 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
20 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
21 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
22 | + * THE SOFTWARE. | ||
23 | + */ | ||
24 | + | ||
25 | +#include "vl.h" | ||
26 | + | ||
27 | +/* Signed 64x64 -> 128 multiplication */ | ||
28 | + | ||
29 | +void muls64(int64_t *phigh, int64_t *plow, int64_t a, int64_t b) | ||
30 | +{ | ||
31 | +#if defined(__x86_64__) | ||
32 | + __asm__ ("imul %0\n\t" | ||
33 | + : "=d" (*phigh), "=a" (*plow) | ||
34 | + : "a" (a), "0" (b) | ||
35 | + ); | ||
36 | +#else | ||
37 | + int64_t ph; | ||
38 | + uint64_t pm1, pm2, pl; | ||
39 | + | ||
40 | + pl = (uint64_t)((uint32_t)a) * (uint64_t)((uint32_t)b); | ||
41 | + pm1 = (a >> 32) * (uint32_t)b; | ||
42 | + pm2 = (uint32_t)a * (b >> 32); | ||
43 | + ph = (a >> 32) * (b >> 32); | ||
44 | + | ||
45 | + ph += (int64_t)pm1 >> 32; | ||
46 | + pm1 = (uint64_t)((uint32_t)pm1) + pm2 + (pl >> 32); | ||
47 | + | ||
48 | + *phigh = ph + ((int64_t)pm1 >> 32); | ||
49 | + *plow = (pm1 << 32) + (uint32_t)pl; | ||
50 | +#endif | ||
51 | +} | ||
52 | + | ||
53 | +/* Unsigned 64x64 -> 128 multiplication */ | ||
54 | +void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b) | ||
55 | +{ | ||
56 | +#if defined(__x86_64__) | ||
57 | + __asm__ ("mul %0\n\t" | ||
58 | + : "=d" (*phigh), "=a" (*plow) | ||
59 | + : "a" (a), "0" (b) | ||
60 | + ); | ||
61 | +#else | ||
62 | + uint64_t ph, pm1, pm2, pl; | ||
63 | + | ||
64 | + pl = (uint64_t)((uint32_t)a) * (uint64_t)((uint32_t)b); | ||
65 | + pm1 = (a >> 32) * (uint32_t)b; | ||
66 | + pm2 = (uint32_t)a * (b >> 32); | ||
67 | + ph = (a >> 32) * (b >> 32); | ||
68 | + | ||
69 | + ph += pm1 >> 32; | ||
70 | + pm1 = (uint64_t)((uint32_t)pm1) + pm2 + (pl >> 32); | ||
71 | + | ||
72 | + *phigh = ph + (pm1 >> 32); | ||
73 | + *plow = (pm1 << 32) + (uint32_t)pl; | ||
74 | +#endif | ||
75 | +} |
target-i386/helper.c
@@ -3620,50 +3620,6 @@ static void neg128(uint64_t *plow, uint64_t *phigh) | @@ -3620,50 +3620,6 @@ static void neg128(uint64_t *plow, uint64_t *phigh) | ||
3620 | add128(plow, phigh, 1, 0); | 3620 | add128(plow, phigh, 1, 0); |
3621 | } | 3621 | } |
3622 | 3622 | ||
3623 | -static void mul64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) | ||
3624 | -{ | ||
3625 | - uint32_t a0, a1, b0, b1; | ||
3626 | - uint64_t v; | ||
3627 | - | ||
3628 | - a0 = a; | ||
3629 | - a1 = a >> 32; | ||
3630 | - | ||
3631 | - b0 = b; | ||
3632 | - b1 = b >> 32; | ||
3633 | - | ||
3634 | - v = (uint64_t)a0 * (uint64_t)b0; | ||
3635 | - *plow = v; | ||
3636 | - *phigh = 0; | ||
3637 | - | ||
3638 | - v = (uint64_t)a0 * (uint64_t)b1; | ||
3639 | - add128(plow, phigh, v << 32, v >> 32); | ||
3640 | - | ||
3641 | - v = (uint64_t)a1 * (uint64_t)b0; | ||
3642 | - add128(plow, phigh, v << 32, v >> 32); | ||
3643 | - | ||
3644 | - v = (uint64_t)a1 * (uint64_t)b1; | ||
3645 | - *phigh += v; | ||
3646 | -#ifdef DEBUG_MULDIV | ||
3647 | - printf("mul: 0x%016" PRIx64 " * 0x%016" PRIx64 " = 0x%016" PRIx64 "%016" PRIx64 "\n", | ||
3648 | - a, b, *phigh, *plow); | ||
3649 | -#endif | ||
3650 | -} | ||
3651 | - | ||
3652 | -static void imul64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b) | ||
3653 | -{ | ||
3654 | - int sa, sb; | ||
3655 | - sa = (a < 0); | ||
3656 | - if (sa) | ||
3657 | - a = -a; | ||
3658 | - sb = (b < 0); | ||
3659 | - if (sb) | ||
3660 | - b = -b; | ||
3661 | - mul64(plow, phigh, a, b); | ||
3662 | - if (sa ^ sb) { | ||
3663 | - neg128(plow, phigh); | ||
3664 | - } | ||
3665 | -} | ||
3666 | - | ||
3667 | /* return TRUE if overflow */ | 3623 | /* return TRUE if overflow */ |
3668 | static int div64(uint64_t *plow, uint64_t *phigh, uint64_t b) | 3624 | static int div64(uint64_t *plow, uint64_t *phigh, uint64_t b) |
3669 | { | 3625 | { |
@@ -3731,7 +3687,7 @@ void helper_mulq_EAX_T0(void) | @@ -3731,7 +3687,7 @@ void helper_mulq_EAX_T0(void) | ||
3731 | { | 3687 | { |
3732 | uint64_t r0, r1; | 3688 | uint64_t r0, r1; |
3733 | 3689 | ||
3734 | - mul64(&r0, &r1, EAX, T0); | 3690 | + mulu64(&r1, &r0, EAX, T0); |
3735 | EAX = r0; | 3691 | EAX = r0; |
3736 | EDX = r1; | 3692 | EDX = r1; |
3737 | CC_DST = r0; | 3693 | CC_DST = r0; |
@@ -3742,7 +3698,7 @@ void helper_imulq_EAX_T0(void) | @@ -3742,7 +3698,7 @@ void helper_imulq_EAX_T0(void) | ||
3742 | { | 3698 | { |
3743 | uint64_t r0, r1; | 3699 | uint64_t r0, r1; |
3744 | 3700 | ||
3745 | - imul64(&r0, &r1, EAX, T0); | 3701 | + muls64(&r1, &r0, EAX, T0); |
3746 | EAX = r0; | 3702 | EAX = r0; |
3747 | EDX = r1; | 3703 | EDX = r1; |
3748 | CC_DST = r0; | 3704 | CC_DST = r0; |
@@ -3753,7 +3709,7 @@ void helper_imulq_T0_T1(void) | @@ -3753,7 +3709,7 @@ void helper_imulq_T0_T1(void) | ||
3753 | { | 3709 | { |
3754 | uint64_t r0, r1; | 3710 | uint64_t r0, r1; |
3755 | 3711 | ||
3756 | - imul64(&r0, &r1, T0, T1); | 3712 | + muls64(&r1, &r0, T0, T1); |
3757 | T0 = r0; | 3713 | T0 = r0; |
3758 | CC_DST = r0; | 3714 | CC_DST = r0; |
3759 | CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); | 3715 | CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); |
target-mips/exec.h
@@ -97,8 +97,6 @@ void do_ddiv (void); | @@ -97,8 +97,6 @@ void do_ddiv (void); | ||
97 | #if TARGET_LONG_BITS > HOST_LONG_BITS | 97 | #if TARGET_LONG_BITS > HOST_LONG_BITS |
98 | void do_ddivu (void); | 98 | void do_ddivu (void); |
99 | #endif | 99 | #endif |
100 | -void do_dmult (void); | ||
101 | -void do_dmultu (void); | ||
102 | #endif | 100 | #endif |
103 | void do_mfc0_random(void); | 101 | void do_mfc0_random(void); |
104 | void do_mfc0_count(void); | 102 | void do_mfc0_count(void); |
target-mips/op.c
@@ -874,13 +874,13 @@ void op_msubu (void) | @@ -874,13 +874,13 @@ void op_msubu (void) | ||
874 | #ifdef TARGET_MIPS64 | 874 | #ifdef TARGET_MIPS64 |
875 | void op_dmult (void) | 875 | void op_dmult (void) |
876 | { | 876 | { |
877 | - CALL_FROM_TB0(do_dmult); | 877 | + CALL_FROM_TB4(muls64, &(env->HI), &(env->LO), T0, T1); |
878 | RETURN(); | 878 | RETURN(); |
879 | } | 879 | } |
880 | 880 | ||
881 | void op_dmultu (void) | 881 | void op_dmultu (void) |
882 | { | 882 | { |
883 | - CALL_FROM_TB0(do_dmultu); | 883 | + CALL_FROM_TB4(mulu64, &(env->HI), &(env->LO), T0, T1); |
884 | RETURN(); | 884 | RETURN(); |
885 | } | 885 | } |
886 | #endif | 886 | #endif |
target-mips/op_helper.c
@@ -228,20 +228,6 @@ void do_div (void) | @@ -228,20 +228,6 @@ void do_div (void) | ||
228 | #endif | 228 | #endif |
229 | 229 | ||
230 | #ifdef TARGET_MIPS64 | 230 | #ifdef TARGET_MIPS64 |
231 | -void do_dmult (void) | ||
232 | -{ | ||
233 | - env->LO = (int64_t)T0 * (int64_t)T1; | ||
234 | - /* XXX */ | ||
235 | - env->HI = (env->LO | (1ULL << 63)) ? ~0ULL : 0ULL; | ||
236 | -} | ||
237 | - | ||
238 | -void do_dmultu (void) | ||
239 | -{ | ||
240 | - env->LO = T0 * T1; | ||
241 | - /* XXX */ | ||
242 | - env->HI = 0; | ||
243 | -} | ||
244 | - | ||
245 | void do_ddiv (void) | 231 | void do_ddiv (void) |
246 | { | 232 | { |
247 | if (T1 != 0) { | 233 | if (T1 != 0) { |