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 | 365 | # must use static linking to avoid leaving stuff in virtual address space |
| 366 | 366 | VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o loader.o isa_mmio.o |
| 367 | 367 | VL_OBJS+=cutils.o |
| 368 | +VL_OBJS+=host-utils.o | |
| 368 | 369 | VL_OBJS+=block.o block-raw.o |
| 369 | 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 | 371 | VL_OBJS+=irq.o | ... | ... |
exec-all.h
| ... | ... | @@ -78,6 +78,9 @@ void optimize_flags_init(void); |
| 78 | 78 | extern FILE *logfile; |
| 79 | 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 | 84 | int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); |
| 82 | 85 | int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); |
| 83 | 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 | 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 | 3623 | /* return TRUE if overflow */ |
| 3668 | 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 | 3687 | { |
| 3732 | 3688 | uint64_t r0, r1; |
| 3733 | 3689 | |
| 3734 | - mul64(&r0, &r1, EAX, T0); | |
| 3690 | + mulu64(&r1, &r0, EAX, T0); | |
| 3735 | 3691 | EAX = r0; |
| 3736 | 3692 | EDX = r1; |
| 3737 | 3693 | CC_DST = r0; |
| ... | ... | @@ -3742,7 +3698,7 @@ void helper_imulq_EAX_T0(void) |
| 3742 | 3698 | { |
| 3743 | 3699 | uint64_t r0, r1; |
| 3744 | 3700 | |
| 3745 | - imul64(&r0, &r1, EAX, T0); | |
| 3701 | + muls64(&r1, &r0, EAX, T0); | |
| 3746 | 3702 | EAX = r0; |
| 3747 | 3703 | EDX = r1; |
| 3748 | 3704 | CC_DST = r0; |
| ... | ... | @@ -3753,7 +3709,7 @@ void helper_imulq_T0_T1(void) |
| 3753 | 3709 | { |
| 3754 | 3710 | uint64_t r0, r1; |
| 3755 | 3711 | |
| 3756 | - imul64(&r0, &r1, T0, T1); | |
| 3712 | + muls64(&r1, &r0, T0, T1); | |
| 3757 | 3713 | T0 = r0; |
| 3758 | 3714 | CC_DST = r0; |
| 3759 | 3715 | CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); | ... | ... |
target-mips/exec.h
target-mips/op.c
| ... | ... | @@ -874,13 +874,13 @@ void op_msubu (void) |
| 874 | 874 | #ifdef TARGET_MIPS64 |
| 875 | 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 | 878 | RETURN(); |
| 879 | 879 | } |
| 880 | 880 | |
| 881 | 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 | 884 | RETURN(); |
| 885 | 885 | } |
| 886 | 886 | #endif | ... | ... |
target-mips/op_helper.c
| ... | ... | @@ -228,20 +228,6 @@ void do_div (void) |
| 228 | 228 | #endif |
| 229 | 229 | |
| 230 | 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 | 231 | void do_ddiv (void) |
| 246 | 232 | { |
| 247 | 233 | if (T1 != 0) { | ... | ... |