summaryrefslogtreecommitdiff
blob: b5aa0fd368738743411a3d51540765b12708c679 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
2005-10-28  Gwenole Beauchesne  <gbeauchesne@mandriva.com>

	* Various additional hacks for GCC4.

Index: qemu-0.8.1/cpu-all.h
===================================================================
--- qemu-0.8.1.orig/cpu-all.h
+++ qemu-0.8.1/cpu-all.h
@@ -339,7 +339,13 @@ static inline void stl_le_p(void *ptr, i
 
 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 */
Index: qemu-0.8.1/softmmu_header.h
===================================================================
--- qemu-0.8.1.orig/softmmu_header.h
+++ qemu-0.8.1/softmmu_header.h
@@ -108,7 +108,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
 void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user);
 
 #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
-    (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
+    (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU) && (__GNUC__ < 4)
 
 #define CPU_TLB_ENTRY_BITS 4
 
@@ -150,7 +150,7 @@ static inline RES_TYPE glue(glue(ld, USU
                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
                   "i" (CPU_MEM_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
-                  : "%eax", "%ecx", "%edx", "memory", "cc");
+                  : "%eax", "%edx", "memory", "cc");
     return res;
 }
 
@@ -197,13 +197,14 @@ static inline int glue(glue(lds, SUFFIX)
                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
                   "i" (CPU_MEM_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"
@@ -240,16 +241,14 @@ static inline void glue(glue(st, SUFFIX)
                   "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_MEM_INDEX][0].addr_write)),
                   "i" (CPU_MEM_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
-                  : "%eax", "%ecx", "%edx", "memory", "cc");
+                  : "%eax", "%edx", "memory", "cc");
 }
 
 #else
Index: qemu-0.8.1/target-i386/helper.c
===================================================================
--- qemu-0.8.1.orig/target-i386/helper.c
+++ qemu-0.8.1/target-i386/helper.c
@@ -3145,8 +3145,15 @@ void helper_fxrstor(target_ulong ptr, in
         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;
         }
     }
Index: qemu-0.8.1/target-i386/ops_sse.h
===================================================================
--- qemu-0.8.1.orig/target-i386/ops_sse.h
+++ qemu-0.8.1/target-i386/ops_sse.h
@@ -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)
 {
@@ -570,7 +576,7 @@ void OPPROTO glue(op_pshufw, SUFFIX) (vo
     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)