diff -Naur qemu-0.9.1.orig/cpu-all.h qemu-0.9.1/cpu-all.h --- qemu-0.9.1.orig/cpu-all.h 2008-01-07 04:38:42.000000000 +0900 +++ qemu-0.9.1/cpu-all.h 2009-02-16 12:34:44.339592070 +0900 @@ -369,7 +369,13 @@ static inline void stq_le_p(void *ptr, uint64_t v) { +#if defined(__i386__) && __GNUC__ >= 4 + const union { uint64_t v; uint32_t p[2]; } x = { .v = v }; + ((uint32_t *)ptr)[0] = x.p[0]; + ((uint32_t *)ptr)[1] = x.p[1]; +#else *(uint64_t *)ptr = v; +#endif } /* float access */ diff -Naur qemu-0.9.1.orig/softmmu_header.h qemu-0.9.1/softmmu_header.h --- qemu-0.9.1.orig/softmmu_header.h 2008-01-07 04:38:42.000000000 +0900 +++ qemu-0.9.1/softmmu_header.h 2009-02-16 12:50:41.547536127 +0900 @@ -75,7 +75,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int mmu_idx); #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \ - (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU) + (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU) && (__GNUC__ < 4) #define CPU_TLB_ENTRY_BITS 4 @@ -117,7 +117,7 @@ "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)), "i" (CPU_MMU_INDEX), "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) - : "%eax", "%ecx", "%edx", "memory", "cc"); + : "%eax", "%edx", "memory", "cc"); return res; } @@ -164,13 +164,14 @@ "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)), "i" (CPU_MMU_INDEX), "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) - : "%eax", "%ecx", "%edx", "memory", "cc"); + : "%eax", "%edx", "memory", "cc"); return res; } #endif -static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v) +static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE val) { + RES_TYPE v = val; asm volatile ("movl %0, %%edx\n" "movl %0, %%eax\n" "shrl %3, %%edx\n" @@ -207,16 +208,14 @@ "2:\n" : : "r" (ptr), -/* NOTE: 'q' would be needed as constraint, but we could not use it - with T1 ! */ - "r" (v), + "q" (v), "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)), "i" (CPU_MMU_INDEX), "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX)) - : "%eax", "%ecx", "%edx", "memory", "cc"); + : "%eax", "%edx", "memory", "cc"); } #else diff -Naur qemu-0.9.1.orig/target-i386/helper.c qemu-0.9.1/target-i386/helper.c --- qemu-0.9.1.orig/target-i386/helper.c 2008-01-07 04:38:45.000000000 +0900 +++ qemu-0.9.1/target-i386/helper.c 2009-02-16 12:58:17.427561802 +0900 @@ -3607,8 +3607,15 @@ nb_xmm_regs = 8 << data64; addr = ptr + 0xa0; for(i = 0; i < nb_xmm_regs; i++) { +#if defined(__i386__) && __GNUC__ >= 4 + env->xmm_regs[i].XMM_L(0) = ldl(addr); + env->xmm_regs[i].XMM_L(1) = ldl(addr + 4); + env->xmm_regs[i].XMM_L(2) = ldl(addr + 8); + env->xmm_regs[i].XMM_L(3) = ldl(addr + 12); +#else env->xmm_regs[i].XMM_Q(0) = ldq(addr); env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8); +#endif addr += 16; } } diff -Naur qemu-0.9.1.orig/target-i386/ops_sse.h qemu-0.9.1/target-i386/ops_sse.h --- qemu-0.9.1.orig/target-i386/ops_sse.h 2008-01-07 04:38:45.000000000 +0900 +++ qemu-0.9.1/target-i386/ops_sse.h 2009-02-16 13:03:21.587712348 +0900 @@ -34,6 +34,12 @@ #define Q(n) XMM_Q(n) #define SUFFIX _xmm #endif +#if defined(__i386__) && __GNUC__ >= 4 +#define RegCopy(d, s) __builtin_memcpy(&(d), &(s), sizeof(d)) +#endif +#ifndef RegCopy +#define RegCopy(d, s) d = s +#endif void OPPROTO glue(op_psrlw, SUFFIX)(void) { @@ -589,7 +595,7 @@ r.W(1) = s->W((order >> 2) & 3); r.W(2) = s->W((order >> 4) & 3); r.W(3) = s->W((order >> 6) & 3); - *d = r; + RegCopy(*d, r); } #else void OPPROTO op_shufps(void)