Commit 61382a500a9e54ef96ca28e0f221151f569cbb6e

Authored by bellard
1 parent 3a51dee6

full softmmu support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@410 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
@@ -20,18 +20,19 @@ @@ -20,18 +20,19 @@
20 #ifndef CPU_ALL_H 20 #ifndef CPU_ALL_H
21 #define CPU_ALL_H 21 #define CPU_ALL_H
22 22
23 -/* all CPU memory access use these macros */  
24 -static inline int ldub(void *ptr) 23 +/* CPU memory access without any memory or io remapping */
  24 +
  25 +static inline int ldub_raw(void *ptr)
25 { 26 {
26 return *(uint8_t *)ptr; 27 return *(uint8_t *)ptr;
27 } 28 }
28 29
29 -static inline int ldsb(void *ptr) 30 +static inline int ldsb_raw(void *ptr)
30 { 31 {
31 return *(int8_t *)ptr; 32 return *(int8_t *)ptr;
32 } 33 }
33 34
34 -static inline void stb(void *ptr, int v) 35 +static inline void stb_raw(void *ptr, int v)
35 { 36 {
36 *(uint8_t *)ptr = v; 37 *(uint8_t *)ptr = v;
37 } 38 }
@@ -42,7 +43,7 @@ static inline void stb(void *ptr, int v) @@ -42,7 +43,7 @@ static inline void stb(void *ptr, int v)
42 #if defined(WORDS_BIGENDIAN) || defined(__arm__) 43 #if defined(WORDS_BIGENDIAN) || defined(__arm__)
43 44
44 /* conservative code for little endian unaligned accesses */ 45 /* conservative code for little endian unaligned accesses */
45 -static inline int lduw(void *ptr) 46 +static inline int lduw_raw(void *ptr)
46 { 47 {
47 #ifdef __powerpc__ 48 #ifdef __powerpc__
48 int val; 49 int val;
@@ -54,7 +55,7 @@ static inline int lduw(void *ptr) @@ -54,7 +55,7 @@ static inline int lduw(void *ptr)
54 #endif 55 #endif
55 } 56 }
56 57
57 -static inline int ldsw(void *ptr) 58 +static inline int ldsw_raw(void *ptr)
58 { 59 {
59 #ifdef __powerpc__ 60 #ifdef __powerpc__
60 int val; 61 int val;
@@ -66,7 +67,7 @@ static inline int ldsw(void *ptr) @@ -66,7 +67,7 @@ static inline int ldsw(void *ptr)
66 #endif 67 #endif
67 } 68 }
68 69
69 -static inline int ldl(void *ptr) 70 +static inline int ldl_raw(void *ptr)
70 { 71 {
71 #ifdef __powerpc__ 72 #ifdef __powerpc__
72 int val; 73 int val;
@@ -78,16 +79,16 @@ static inline int ldl(void *ptr) @@ -78,16 +79,16 @@ static inline int ldl(void *ptr)
78 #endif 79 #endif
79 } 80 }
80 81
81 -static inline uint64_t ldq(void *ptr) 82 +static inline uint64_t ldq_raw(void *ptr)
82 { 83 {
83 uint8_t *p = ptr; 84 uint8_t *p = ptr;
84 uint32_t v1, v2; 85 uint32_t v1, v2;
85 - v1 = ldl(p);  
86 - v2 = ldl(p + 4); 86 + v1 = ldl_raw(p);
  87 + v2 = ldl_raw(p + 4);
87 return v1 | ((uint64_t)v2 << 32); 88 return v1 | ((uint64_t)v2 << 32);
88 } 89 }
89 90
90 -static inline void stw(void *ptr, int v) 91 +static inline void stw_raw(void *ptr, int v)
91 { 92 {
92 #ifdef __powerpc__ 93 #ifdef __powerpc__
93 __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); 94 __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
@@ -98,7 +99,7 @@ static inline void stw(void *ptr, int v) @@ -98,7 +99,7 @@ static inline void stw(void *ptr, int v)
98 #endif 99 #endif
99 } 100 }
100 101
101 -static inline void stl(void *ptr, int v) 102 +static inline void stl_raw(void *ptr, int v)
102 { 103 {
103 #ifdef __powerpc__ 104 #ifdef __powerpc__
104 __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); 105 __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
@@ -111,104 +112,104 @@ static inline void stl(void *ptr, int v) @@ -111,104 +112,104 @@ static inline void stl(void *ptr, int v)
111 #endif 112 #endif
112 } 113 }
113 114
114 -static inline void stq(void *ptr, uint64_t v) 115 +static inline void stq_raw(void *ptr, uint64_t v)
115 { 116 {
116 uint8_t *p = ptr; 117 uint8_t *p = ptr;
117 - stl(p, (uint32_t)v);  
118 - stl(p + 4, v >> 32); 118 + stl_raw(p, (uint32_t)v);
  119 + stl_raw(p + 4, v >> 32);
119 } 120 }
120 121
121 /* float access */ 122 /* float access */
122 123
123 -static inline float ldfl(void *ptr) 124 +static inline float ldfl_raw(void *ptr)
124 { 125 {
125 union { 126 union {
126 float f; 127 float f;
127 uint32_t i; 128 uint32_t i;
128 } u; 129 } u;
129 - u.i = ldl(ptr); 130 + u.i = ldl_raw(ptr);
130 return u.f; 131 return u.f;
131 } 132 }
132 133
133 -static inline void stfl(void *ptr, float v) 134 +static inline void stfl_raw(void *ptr, float v)
134 { 135 {
135 union { 136 union {
136 float f; 137 float f;
137 uint32_t i; 138 uint32_t i;
138 } u; 139 } u;
139 u.f = v; 140 u.f = v;
140 - stl(ptr, u.i); 141 + stl_raw(ptr, u.i);
141 } 142 }
142 143
143 144
144 #if defined(__arm__) && !defined(WORDS_BIGENDIAN) 145 #if defined(__arm__) && !defined(WORDS_BIGENDIAN)
145 146
146 /* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ 147 /* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
147 -static inline double ldfq(void *ptr) 148 +static inline double ldfq_raw(void *ptr)
148 { 149 {
149 union { 150 union {
150 double d; 151 double d;
151 uint32_t tab[2]; 152 uint32_t tab[2];
152 } u; 153 } u;
153 - u.tab[1] = ldl(ptr);  
154 - u.tab[0] = ldl(ptr + 4); 154 + u.tab[1] = ldl_raw(ptr);
  155 + u.tab[0] = ldl_raw(ptr + 4);
155 return u.d; 156 return u.d;
156 } 157 }
157 158
158 -static inline void stfq(void *ptr, double v) 159 +static inline void stfq_raw(void *ptr, double v)
159 { 160 {
160 union { 161 union {
161 double d; 162 double d;
162 uint32_t tab[2]; 163 uint32_t tab[2];
163 } u; 164 } u;
164 u.d = v; 165 u.d = v;
165 - stl(ptr, u.tab[1]);  
166 - stl(ptr + 4, u.tab[0]); 166 + stl_raw(ptr, u.tab[1]);
  167 + stl_raw(ptr + 4, u.tab[0]);
167 } 168 }
168 169
169 #else 170 #else
170 -static inline double ldfq(void *ptr) 171 +static inline double ldfq_raw(void *ptr)
171 { 172 {
172 union { 173 union {
173 double d; 174 double d;
174 uint64_t i; 175 uint64_t i;
175 } u; 176 } u;
176 - u.i = ldq(ptr); 177 + u.i = ldq_raw(ptr);
177 return u.d; 178 return u.d;
178 } 179 }
179 180
180 -static inline void stfq(void *ptr, double v) 181 +static inline void stfq_raw(void *ptr, double v)
181 { 182 {
182 union { 183 union {
183 double d; 184 double d;
184 uint64_t i; 185 uint64_t i;
185 } u; 186 } u;
186 u.d = v; 187 u.d = v;
187 - stq(ptr, u.i); 188 + stq_raw(ptr, u.i);
188 } 189 }
189 #endif 190 #endif
190 191
191 #elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN) 192 #elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)
192 193
193 -static inline int lduw(void *ptr) 194 +static inline int lduw_raw(void *ptr)
194 { 195 {
195 uint8_t *b = (uint8_t *) ptr; 196 uint8_t *b = (uint8_t *) ptr;
196 return (b[0]<<8|b[1]); 197 return (b[0]<<8|b[1]);
197 } 198 }
198 199
199 -static inline int ldsw(void *ptr) 200 +static inline int ldsw_raw(void *ptr)
200 { 201 {
201 int8_t *b = (int8_t *) ptr; 202 int8_t *b = (int8_t *) ptr;
202 return (b[0]<<8|b[1]); 203 return (b[0]<<8|b[1]);
203 } 204 }
204 205
205 -static inline int ldl(void *ptr) 206 +static inline int ldl_raw(void *ptr)
206 { 207 {
207 uint8_t *b = (uint8_t *) ptr; 208 uint8_t *b = (uint8_t *) ptr;
208 return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]); 209 return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]);
209 } 210 }
210 211
211 -static inline uint64_t ldq(void *ptr) 212 +static inline uint64_t ldq_raw(void *ptr)
212 { 213 {
213 uint32_t a,b; 214 uint32_t a,b;
214 a = ldl (ptr); 215 a = ldl (ptr);
@@ -216,14 +217,14 @@ static inline uint64_t ldq(void *ptr) @@ -216,14 +217,14 @@ static inline uint64_t ldq(void *ptr)
216 return (((uint64_t)a<<32)|b); 217 return (((uint64_t)a<<32)|b);
217 } 218 }
218 219
219 -static inline void stw(void *ptr, int v) 220 +static inline void stw_raw(void *ptr, int v)
220 { 221 {
221 uint8_t *d = (uint8_t *) ptr; 222 uint8_t *d = (uint8_t *) ptr;
222 d[0] = v >> 8; 223 d[0] = v >> 8;
223 d[1] = v; 224 d[1] = v;
224 } 225 }
225 226
226 -static inline void stl(void *ptr, int v) 227 +static inline void stl_raw(void *ptr, int v)
227 { 228 {
228 uint8_t *d = (uint8_t *) ptr; 229 uint8_t *d = (uint8_t *) ptr;
229 d[0] = v >> 24; 230 d[0] = v >> 24;
@@ -232,7 +233,7 @@ static inline void stl(void *ptr, int v) @@ -232,7 +233,7 @@ static inline void stl(void *ptr, int v)
232 d[3] = v; 233 d[3] = v;
233 } 234 }
234 235
235 -static inline void stq(void *ptr, uint64_t v) 236 +static inline void stq_raw(void *ptr, uint64_t v)
236 { 237 {
237 stl (ptr, v); 238 stl (ptr, v);
238 stl (ptr+4, v >> 32); 239 stl (ptr+4, v >> 32);
@@ -240,64 +241,102 @@ static inline void stq(void *ptr, uint64_t v) @@ -240,64 +241,102 @@ static inline void stq(void *ptr, uint64_t v)
240 241
241 #else 242 #else
242 243
243 -static inline int lduw(void *ptr) 244 +static inline int lduw_raw(void *ptr)
244 { 245 {
245 return *(uint16_t *)ptr; 246 return *(uint16_t *)ptr;
246 } 247 }
247 248
248 -static inline int ldsw(void *ptr) 249 +static inline int ldsw_raw(void *ptr)
249 { 250 {
250 return *(int16_t *)ptr; 251 return *(int16_t *)ptr;
251 } 252 }
252 253
253 -static inline int ldl(void *ptr) 254 +static inline int ldl_raw(void *ptr)
254 { 255 {
255 return *(uint32_t *)ptr; 256 return *(uint32_t *)ptr;
256 } 257 }
257 258
258 -static inline uint64_t ldq(void *ptr) 259 +static inline uint64_t ldq_raw(void *ptr)
259 { 260 {
260 return *(uint64_t *)ptr; 261 return *(uint64_t *)ptr;
261 } 262 }
262 263
263 -static inline void stw(void *ptr, int v) 264 +static inline void stw_raw(void *ptr, int v)
264 { 265 {
265 *(uint16_t *)ptr = v; 266 *(uint16_t *)ptr = v;
266 } 267 }
267 268
268 -static inline void stl(void *ptr, int v) 269 +static inline void stl_raw(void *ptr, int v)
269 { 270 {
270 *(uint32_t *)ptr = v; 271 *(uint32_t *)ptr = v;
271 } 272 }
272 273
273 -static inline void stq(void *ptr, uint64_t v) 274 +static inline void stq_raw(void *ptr, uint64_t v)
274 { 275 {
275 *(uint64_t *)ptr = v; 276 *(uint64_t *)ptr = v;
276 } 277 }
277 278
278 /* float access */ 279 /* float access */
279 280
280 -static inline float ldfl(void *ptr) 281 +static inline float ldfl_raw(void *ptr)
281 { 282 {
282 return *(float *)ptr; 283 return *(float *)ptr;
283 } 284 }
284 285
285 -static inline double ldfq(void *ptr) 286 +static inline double ldfq_raw(void *ptr)
286 { 287 {
287 return *(double *)ptr; 288 return *(double *)ptr;
288 } 289 }
289 290
290 -static inline void stfl(void *ptr, float v) 291 +static inline void stfl_raw(void *ptr, float v)
291 { 292 {
292 *(float *)ptr = v; 293 *(float *)ptr = v;
293 } 294 }
294 295
295 -static inline void stfq(void *ptr, double v) 296 +static inline void stfq_raw(void *ptr, double v)
296 { 297 {
297 *(double *)ptr = v; 298 *(double *)ptr = v;
298 } 299 }
299 #endif 300 #endif
300 301
  302 +/* MMU memory access macros */
  303 +
  304 +#if defined(CONFIG_USER_ONLY)
  305 +
  306 +/* if user mode, no other memory access functions */
  307 +#define ldub(p) ldub_raw(p)
  308 +#define ldsb(p) ldsb_raw(p)
  309 +#define lduw(p) lduw_raw(p)
  310 +#define ldsw(p) ldsw_raw(p)
  311 +#define ldl(p) ldl_raw(p)
  312 +#define ldq(p) ldq_raw(p)
  313 +#define ldfl(p) ldfl_raw(p)
  314 +#define ldfq(p) ldfq_raw(p)
  315 +#define stb(p, v) stb_raw(p, v)
  316 +#define stw(p, v) stw_raw(p, v)
  317 +#define stl(p, v) stl_raw(p, v)
  318 +#define stq(p, v) stq_raw(p, v)
  319 +#define stfl(p, v) stfl_raw(p, v)
  320 +#define stfq(p, v) stfq_raw(p, v)
  321 +
  322 +#define ldub_code(p) ldub_raw(p)
  323 +#define ldsb_code(p) ldsb_raw(p)
  324 +#define lduw_code(p) lduw_raw(p)
  325 +#define ldsw_code(p) ldsw_raw(p)
  326 +#define ldl_code(p) ldl_raw(p)
  327 +
  328 +#define ldub_kernel(p) ldub_raw(p)
  329 +#define ldsb_kernel(p) ldsb_raw(p)
  330 +#define lduw_kernel(p) lduw_raw(p)
  331 +#define ldsw_kernel(p) ldsw_raw(p)
  332 +#define ldl_kernel(p) ldl_raw(p)
  333 +#define stb_kernel(p, v) stb_raw(p, v)
  334 +#define stw_kernel(p, v) stw_raw(p, v)
  335 +#define stl_kernel(p, v) stl_raw(p, v)
  336 +#define stq_kernel(p, v) stq_raw(p, v)
  337 +
  338 +#endif /* defined(CONFIG_USER_ONLY) */
  339 +
301 /* page related stuff */ 340 /* page related stuff */
302 341
303 #define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS) 342 #define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
@@ -444,16 +444,20 @@ static inline void tb_alloc_page(TranslationBlock *tb, unsigned int page_index) @@ -444,16 +444,20 @@ static inline void tb_alloc_page(TranslationBlock *tb, unsigned int page_index)
444 prot = 0; 444 prot = 0;
445 for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE) 445 for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE)
446 prot |= page_get_flags(addr); 446 prot |= page_get_flags(addr);
  447 +#if !defined(CONFIG_SOFTMMU)
447 mprotect((void *)host_start, host_page_size, 448 mprotect((void *)host_start, host_page_size,
448 (prot & PAGE_BITS) & ~PAGE_WRITE); 449 (prot & PAGE_BITS) & ~PAGE_WRITE);
  450 +#endif
  451 +#if !defined(CONFIG_USER_ONLY)
  452 + /* suppress soft TLB */
  453 + /* XXX: must flush on all processor with same address space */
  454 + tlb_flush_page_write(cpu_single_env, host_start);
  455 +#endif
449 #ifdef DEBUG_TB_INVALIDATE 456 #ifdef DEBUG_TB_INVALIDATE
450 printf("protecting code page: 0x%08lx\n", 457 printf("protecting code page: 0x%08lx\n",
451 host_start); 458 host_start);
452 #endif 459 #endif
453 p->flags &= ~PAGE_WRITE; 460 p->flags &= ~PAGE_WRITE;
454 -#ifdef DEBUG_TB_CHECK  
455 - tb_page_check();  
456 -#endif  
457 } 461 }
458 } 462 }
459 463
@@ -483,6 +487,9 @@ void tb_link(TranslationBlock *tb) @@ -483,6 +487,9 @@ void tb_link(TranslationBlock *tb)
483 if (page_index2 != page_index1) { 487 if (page_index2 != page_index1) {
484 tb_alloc_page(tb, page_index2); 488 tb_alloc_page(tb, page_index2);
485 } 489 }
  490 +#ifdef DEBUG_TB_CHECK
  491 + tb_page_check();
  492 +#endif
486 tb->jmp_first = (TranslationBlock *)((long)tb | 2); 493 tb->jmp_first = (TranslationBlock *)((long)tb | 2);
487 tb->jmp_next[0] = NULL; 494 tb->jmp_next[0] = NULL;
488 tb->jmp_next[1] = NULL; 495 tb->jmp_next[1] = NULL;
@@ -517,20 +524,23 @@ int page_unprotect(unsigned long address) @@ -517,20 +524,23 @@ int page_unprotect(unsigned long address)
517 /* if the page was really writable, then we change its 524 /* if the page was really writable, then we change its
518 protection back to writable */ 525 protection back to writable */
519 if (prot & PAGE_WRITE_ORG) { 526 if (prot & PAGE_WRITE_ORG) {
520 - mprotect((void *)host_start, host_page_size,  
521 - (prot & PAGE_BITS) | PAGE_WRITE);  
522 pindex = (address - host_start) >> TARGET_PAGE_BITS; 527 pindex = (address - host_start) >> TARGET_PAGE_BITS;
523 - p1[pindex].flags |= PAGE_WRITE;  
524 - /* and since the content will be modified, we must invalidate  
525 - the corresponding translated code. */  
526 - tb_invalidate_page(address); 528 + if (!(p1[pindex].flags & PAGE_WRITE)) {
  529 +#if !defined(CONFIG_SOFTMMU)
  530 + mprotect((void *)host_start, host_page_size,
  531 + (prot & PAGE_BITS) | PAGE_WRITE);
  532 +#endif
  533 + p1[pindex].flags |= PAGE_WRITE;
  534 + /* and since the content will be modified, we must invalidate
  535 + the corresponding translated code. */
  536 + tb_invalidate_page(address);
527 #ifdef DEBUG_TB_CHECK 537 #ifdef DEBUG_TB_CHECK
528 - tb_invalidate_check(address); 538 + tb_invalidate_check(address);
529 #endif 539 #endif
530 - return 1;  
531 - } else {  
532 - return 0; 540 + return 1;
  541 + }
533 } 542 }
  543 + return 0;
534 } 544 }
535 545
536 /* call this function when system calls directly modify a memory area */ 546 /* call this function when system calls directly modify a memory area */
@@ -734,13 +744,17 @@ void cpu_abort(CPUState *env, const char *fmt, ...) @@ -734,13 +744,17 @@ void cpu_abort(CPUState *env, const char *fmt, ...)
734 /* unmap all maped pages and flush all associated code */ 744 /* unmap all maped pages and flush all associated code */
735 void page_unmap(void) 745 void page_unmap(void)
736 { 746 {
737 - PageDesc *p, *pmap;  
738 - unsigned long addr;  
739 - int i, j, ret, j1; 747 + PageDesc *pmap;
  748 + int i;
740 749
741 for(i = 0; i < L1_SIZE; i++) { 750 for(i = 0; i < L1_SIZE; i++) {
742 pmap = l1_map[i]; 751 pmap = l1_map[i];
743 if (pmap) { 752 if (pmap) {
  753 +#if !defined(CONFIG_SOFTMMU)
  754 + PageDesc *p;
  755 + unsigned long addr;
  756 + int j, ret, j1;
  757 +
744 p = pmap; 758 p = pmap;
745 for(j = 0;j < L2_SIZE;) { 759 for(j = 0;j < L2_SIZE;) {
746 if (p->flags & PAGE_VALID) { 760 if (p->flags & PAGE_VALID) {
@@ -763,6 +777,7 @@ void page_unmap(void) @@ -763,6 +777,7 @@ void page_unmap(void)
763 j++; 777 j++;
764 } 778 }
765 } 779 }
  780 +#endif
766 free(pmap); 781 free(pmap);
767 l1_map[i] = NULL; 782 l1_map[i] = NULL;
768 } 783 }
@@ -773,7 +788,7 @@ void page_unmap(void) @@ -773,7 +788,7 @@ void page_unmap(void)
773 788
774 void tlb_flush(CPUState *env) 789 void tlb_flush(CPUState *env)
775 { 790 {
776 -#if defined(TARGET_I386) 791 +#if !defined(CONFIG_USER_ONLY)
777 int i; 792 int i;
778 for(i = 0; i < CPU_TLB_SIZE; i++) { 793 for(i = 0; i < CPU_TLB_SIZE; i++) {
779 env->tlb_read[0][i].address = -1; 794 env->tlb_read[0][i].address = -1;
@@ -784,16 +799,38 @@ void tlb_flush(CPUState *env) @@ -784,16 +799,38 @@ void tlb_flush(CPUState *env)
784 #endif 799 #endif
785 } 800 }
786 801
  802 +static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, uint32_t addr)
  803 +{
  804 + if (addr == (tlb_entry->address &
  805 + (TARGET_PAGE_MASK | TLB_INVALID_MASK)))
  806 + tlb_entry->address = -1;
  807 +}
  808 +
787 void tlb_flush_page(CPUState *env, uint32_t addr) 809 void tlb_flush_page(CPUState *env, uint32_t addr)
788 { 810 {
789 -#if defined(TARGET_I386) 811 +#if !defined(CONFIG_USER_ONLY)
  812 + int i;
  813 +
  814 + addr &= TARGET_PAGE_MASK;
  815 + i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  816 + tlb_flush_entry(&env->tlb_read[0][i], addr);
  817 + tlb_flush_entry(&env->tlb_write[0][i], addr);
  818 + tlb_flush_entry(&env->tlb_read[1][i], addr);
  819 + tlb_flush_entry(&env->tlb_write[1][i], addr);
  820 +#endif
  821 +}
  822 +
  823 +/* make all write to page 'addr' trigger a TLB exception to detect
  824 + self modifying code */
  825 +void tlb_flush_page_write(CPUState *env, uint32_t addr)
  826 +{
  827 +#if !defined(CONFIG_USER_ONLY)
790 int i; 828 int i;
791 829
  830 + addr &= TARGET_PAGE_MASK;
792 i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 831 i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
793 - env->tlb_read[0][i].address = -1;  
794 - env->tlb_write[0][i].address = -1;  
795 - env->tlb_read[1][i].address = -1;  
796 - env->tlb_write[1][i].address = -1; 832 + tlb_flush_entry(&env->tlb_write[0][i], addr);
  833 + tlb_flush_entry(&env->tlb_write[1][i], addr);
797 #endif 834 #endif
798 } 835 }
799 836
@@ -900,3 +937,25 @@ int cpu_register_io_memory(int io_index, @@ -900,3 +937,25 @@ int cpu_register_io_memory(int io_index,
900 } 937 }
901 return io_index << IO_MEM_SHIFT; 938 return io_index << IO_MEM_SHIFT;
902 } 939 }
  940 +
  941 +#if !defined(CONFIG_USER_ONLY)
  942 +
  943 +#define MMUSUFFIX _cmmu
  944 +#define GETPC() NULL
  945 +#define env cpu_single_env
  946 +
  947 +#define SHIFT 0
  948 +#include "softmmu_template.h"
  949 +
  950 +#define SHIFT 1
  951 +#include "softmmu_template.h"
  952 +
  953 +#define SHIFT 2
  954 +#include "softmmu_template.h"
  955 +
  956 +#define SHIFT 3
  957 +#include "softmmu_template.h"
  958 +
  959 +#undef env
  960 +
  961 +#endif
hw/vga_template.h
@@ -354,7 +354,7 @@ static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d, @@ -354,7 +354,7 @@ static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d,
354 354
355 w = width; 355 w = width;
356 do { 356 do {
357 - v = lduw((void *)s); 357 + v = lduw_raw((void *)s);
358 r = (v >> 7) & 0xf8; 358 r = (v >> 7) & 0xf8;
359 g = (v >> 2) & 0xf8; 359 g = (v >> 2) & 0xf8;
360 b = (v << 3) & 0xf8; 360 b = (v << 3) & 0xf8;
@@ -379,7 +379,7 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, @@ -379,7 +379,7 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d,
379 379
380 w = width; 380 w = width;
381 do { 381 do {
382 - v = lduw((void *)s); 382 + v = lduw_raw((void *)s);
383 r = (v >> 8) & 0xf8; 383 r = (v >> 8) & 0xf8;
384 g = (v >> 3) & 0xfc; 384 g = (v >> 3) & 0xfc;
385 b = (v << 3) & 0xf8; 385 b = (v << 3) & 0xf8;
softmmu_header.h
@@ -19,26 +19,48 @@ @@ -19,26 +19,48 @@
19 */ 19 */
20 #if DATA_SIZE == 8 20 #if DATA_SIZE == 8
21 #define SUFFIX q 21 #define SUFFIX q
  22 +#define USUFFIX q
22 #define DATA_TYPE uint64_t 23 #define DATA_TYPE uint64_t
23 #elif DATA_SIZE == 4 24 #elif DATA_SIZE == 4
24 #define SUFFIX l 25 #define SUFFIX l
  26 +#define USUFFIX l
25 #define DATA_TYPE uint32_t 27 #define DATA_TYPE uint32_t
26 #elif DATA_SIZE == 2 28 #elif DATA_SIZE == 2
27 #define SUFFIX w 29 #define SUFFIX w
  30 +#define USUFFIX uw
28 #define DATA_TYPE uint16_t 31 #define DATA_TYPE uint16_t
29 #define DATA_STYPE int16_t 32 #define DATA_STYPE int16_t
30 #elif DATA_SIZE == 1 33 #elif DATA_SIZE == 1
31 #define SUFFIX b 34 #define SUFFIX b
  35 +#define USUFFIX ub
32 #define DATA_TYPE uint8_t 36 #define DATA_TYPE uint8_t
33 #define DATA_STYPE int8_t 37 #define DATA_STYPE int8_t
34 #else 38 #else
35 #error unsupported data size 39 #error unsupported data size
36 #endif 40 #endif
37 41
38 -#if MEMUSER == 0  
39 -#define MEMSUFFIX _kernel 42 +#if ACCESS_TYPE == 0
  43 +
  44 +#define CPU_MEM_INDEX 0
  45 +#define MMUSUFFIX _mmu
  46 +
  47 +#elif ACCESS_TYPE == 1
  48 +
  49 +#define CPU_MEM_INDEX 1
  50 +#define MMUSUFFIX _mmu
  51 +
  52 +#elif ACCESS_TYPE == 2
  53 +
  54 +#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
  55 +#define MMUSUFFIX _mmu
  56 +
  57 +#elif ACCESS_TYPE == 3
  58 +
  59 +#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
  60 +#define MMUSUFFIX _cmmu
  61 +
40 #else 62 #else
41 -#define MEMSUFFIX _user 63 +#error invalid ACCESS_TYPE
42 #endif 64 #endif
43 65
44 #if DATA_SIZE == 8 66 #if DATA_SIZE == 8
@@ -48,24 +70,26 @@ @@ -48,24 +70,26 @@
48 #endif 70 #endif
49 71
50 72
51 -#if MEMUSER == 0  
52 -DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr);  
53 -void REGPARM(2) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE v);  
54 -#endif 73 +DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
  74 + int is_user);
  75 +void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr, DATA_TYPE v, int is_user);
55 76
56 -static inline int glue(glue(ldu, SUFFIX), MEMSUFFIX)(void *ptr) 77 +static inline int glue(glue(ld, USUFFIX), MEMSUFFIX)(void *ptr)
57 { 78 {
58 int index; 79 int index;
59 RES_TYPE res; 80 RES_TYPE res;
60 unsigned long addr, physaddr; 81 unsigned long addr, physaddr;
  82 + int is_user;
  83 +
61 addr = (unsigned long)ptr; 84 addr = (unsigned long)ptr;
62 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 85 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
63 - if (__builtin_expect(env->tlb_read[MEMUSER][index].address != 86 + is_user = CPU_MEM_INDEX;
  87 + if (__builtin_expect(env->tlb_read[is_user][index].address !=
64 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { 88 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
65 - res = glue(glue(__ld, SUFFIX), _mmu)(addr); 89 + res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
66 } else { 90 } else {
67 - physaddr = addr + env->tlb_read[MEMUSER][index].addend;  
68 - res = glue(glue(ldu, SUFFIX), _raw)((uint8_t *)physaddr); 91 + physaddr = addr + env->tlb_read[is_user][index].addend;
  92 + res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
69 } 93 }
70 return res; 94 return res;
71 } 95 }
@@ -75,13 +99,16 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr) @@ -75,13 +99,16 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr)
75 { 99 {
76 int res, index; 100 int res, index;
77 unsigned long addr, physaddr; 101 unsigned long addr, physaddr;
  102 + int is_user;
  103 +
78 addr = (unsigned long)ptr; 104 addr = (unsigned long)ptr;
79 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 105 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
80 - if (__builtin_expect(env->tlb_read[MEMUSER][index].address != 106 + is_user = CPU_MEM_INDEX;
  107 + if (__builtin_expect(env->tlb_read[is_user][index].address !=
81 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { 108 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
82 - res = (DATA_STYPE)glue(glue(__ld, SUFFIX), _mmu)(addr); 109 + res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
83 } else { 110 } else {
84 - physaddr = addr + env->tlb_read[MEMUSER][index].addend; 111 + physaddr = addr + env->tlb_read[is_user][index].addend;
85 res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr); 112 res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
86 } 113 }
87 return res; 114 return res;
@@ -92,13 +119,16 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v) @@ -92,13 +119,16 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v)
92 { 119 {
93 int index; 120 int index;
94 unsigned long addr, physaddr; 121 unsigned long addr, physaddr;
  122 + int is_user;
  123 +
95 addr = (unsigned long)ptr; 124 addr = (unsigned long)ptr;
96 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 125 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
97 - if (__builtin_expect(env->tlb_write[MEMUSER][index].address != 126 + is_user = CPU_MEM_INDEX;
  127 + if (__builtin_expect(env->tlb_write[is_user][index].address !=
98 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { 128 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
99 - glue(glue(__st, SUFFIX), _mmu)(addr, v); 129 + glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
100 } else { 130 } else {
101 - physaddr = addr + env->tlb_write[MEMUSER][index].addend; 131 + physaddr = addr + env->tlb_write[is_user][index].addend;
102 glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v); 132 glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
103 } 133 }
104 } 134 }
@@ -107,5 +137,7 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v) @@ -107,5 +137,7 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v)
107 #undef DATA_TYPE 137 #undef DATA_TYPE
108 #undef DATA_STYPE 138 #undef DATA_STYPE
109 #undef SUFFIX 139 #undef SUFFIX
  140 +#undef USUFFIX
110 #undef DATA_SIZE 141 #undef DATA_SIZE
111 -#undef MEMSUFFIX 142 +#undef CPU_MEM_INDEX
  143 +#undef MMUSUFFIX
softmmu_template.h
@@ -21,23 +21,31 @@ @@ -21,23 +21,31 @@
21 21
22 #if DATA_SIZE == 8 22 #if DATA_SIZE == 8
23 #define SUFFIX q 23 #define SUFFIX q
  24 +#define USUFFIX q
24 #define DATA_TYPE uint64_t 25 #define DATA_TYPE uint64_t
25 #elif DATA_SIZE == 4 26 #elif DATA_SIZE == 4
26 #define SUFFIX l 27 #define SUFFIX l
  28 +#define USUFFIX l
27 #define DATA_TYPE uint32_t 29 #define DATA_TYPE uint32_t
28 #elif DATA_SIZE == 2 30 #elif DATA_SIZE == 2
29 #define SUFFIX w 31 #define SUFFIX w
  32 +#define USUFFIX uw
30 #define DATA_TYPE uint16_t 33 #define DATA_TYPE uint16_t
31 #elif DATA_SIZE == 1 34 #elif DATA_SIZE == 1
32 #define SUFFIX b 35 #define SUFFIX b
  36 +#define USUFFIX ub
33 #define DATA_TYPE uint8_t 37 #define DATA_TYPE uint8_t
34 #else 38 #else
35 #error unsupported data size 39 #error unsupported data size
36 #endif 40 #endif
37 41
38 -static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr);  
39 -static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val,  
40 - void *retaddr); 42 +static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
  43 + int is_user,
  44 + void *retaddr);
  45 +static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr,
  46 + DATA_TYPE val,
  47 + int is_user,
  48 + void *retaddr);
41 49
42 static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr, 50 static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr,
43 unsigned long tlb_addr) 51 unsigned long tlb_addr)
@@ -81,16 +89,16 @@ static inline void glue(io_write, SUFFIX)(unsigned long physaddr, @@ -81,16 +89,16 @@ static inline void glue(io_write, SUFFIX)(unsigned long physaddr,
81 } 89 }
82 90
83 /* handle all cases except unaligned access which span two pages */ 91 /* handle all cases except unaligned access which span two pages */
84 -DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr) 92 +DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
  93 + int is_user)
85 { 94 {
86 DATA_TYPE res; 95 DATA_TYPE res;
87 - int is_user, index; 96 + int index;
88 unsigned long physaddr, tlb_addr; 97 unsigned long physaddr, tlb_addr;
89 void *retaddr; 98 void *retaddr;
90 99
91 /* test if there is match for unaligned or IO access */ 100 /* test if there is match for unaligned or IO access */
92 /* XXX: could done more in memory macro in a non portable way */ 101 /* XXX: could done more in memory macro in a non portable way */
93 - is_user = ((env->hflags & HF_CPL_MASK) == 3);  
94 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 102 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
95 redo: 103 redo:
96 tlb_addr = env->tlb_read[is_user][index].address; 104 tlb_addr = env->tlb_read[is_user][index].address;
@@ -104,29 +112,31 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr) @@ -104,29 +112,31 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr)
104 } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { 112 } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
105 /* slow unaligned access (it spans two pages or IO) */ 113 /* slow unaligned access (it spans two pages or IO) */
106 do_unaligned_access: 114 do_unaligned_access:
107 - retaddr = __builtin_return_address(0);  
108 - res = glue(slow_ld, SUFFIX)(addr, retaddr); 115 + retaddr = GETPC();
  116 + res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
  117 + is_user, retaddr);
109 } else { 118 } else {
110 /* unaligned access in the same page */ 119 /* unaligned access in the same page */
111 - res = glue(glue(ldu, SUFFIX), _raw)((uint8_t *)physaddr); 120 + res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
112 } 121 }
113 } else { 122 } else {
114 /* the page is not in the TLB : fill it */ 123 /* the page is not in the TLB : fill it */
115 - retaddr = __builtin_return_address(0);  
116 - tlb_fill(addr, 0, retaddr); 124 + retaddr = GETPC();
  125 + tlb_fill(addr, 0, is_user, retaddr);
117 goto redo; 126 goto redo;
118 } 127 }
119 return res; 128 return res;
120 } 129 }
121 130
122 /* handle all unaligned cases */ 131 /* handle all unaligned cases */
123 -static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr) 132 +static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
  133 + int is_user,
  134 + void *retaddr)
124 { 135 {
125 DATA_TYPE res, res1, res2; 136 DATA_TYPE res, res1, res2;
126 - int is_user, index, shift; 137 + int index, shift;
127 unsigned long physaddr, tlb_addr, addr1, addr2; 138 unsigned long physaddr, tlb_addr, addr1, addr2;
128 139
129 - is_user = ((env->hflags & HF_CPL_MASK) == 3);  
130 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 140 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
131 redo: 141 redo:
132 tlb_addr = env->tlb_read[is_user][index].address; 142 tlb_addr = env->tlb_read[is_user][index].address;
@@ -142,8 +152,10 @@ static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr) @@ -142,8 +152,10 @@ static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr)
142 /* slow unaligned access (it spans two pages) */ 152 /* slow unaligned access (it spans two pages) */
143 addr1 = addr & ~(DATA_SIZE - 1); 153 addr1 = addr & ~(DATA_SIZE - 1);
144 addr2 = addr1 + DATA_SIZE; 154 addr2 = addr1 + DATA_SIZE;
145 - res1 = glue(slow_ld, SUFFIX)(addr1, retaddr);  
146 - res2 = glue(slow_ld, SUFFIX)(addr2, retaddr); 155 + res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
  156 + is_user, retaddr);
  157 + res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
  158 + is_user, retaddr);
147 shift = (addr & (DATA_SIZE - 1)) * 8; 159 shift = (addr & (DATA_SIZE - 1)) * 8;
148 #ifdef TARGET_WORDS_BIGENDIAN 160 #ifdef TARGET_WORDS_BIGENDIAN
149 res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); 161 res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
@@ -152,24 +164,25 @@ static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr) @@ -152,24 +164,25 @@ static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr)
152 #endif 164 #endif
153 } else { 165 } else {
154 /* unaligned/aligned access in the same page */ 166 /* unaligned/aligned access in the same page */
155 - res = glue(glue(ldu, SUFFIX), _raw)((uint8_t *)physaddr); 167 + res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
156 } 168 }
157 } else { 169 } else {
158 /* the page is not in the TLB : fill it */ 170 /* the page is not in the TLB : fill it */
159 - tlb_fill(addr, 0, retaddr); 171 + tlb_fill(addr, 0, is_user, retaddr);
160 goto redo; 172 goto redo;
161 } 173 }
162 return res; 174 return res;
163 } 175 }
164 176
165 177
166 -void REGPARM(2) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE val) 178 +void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr,
  179 + DATA_TYPE val,
  180 + int is_user)
167 { 181 {
168 unsigned long physaddr, tlb_addr; 182 unsigned long physaddr, tlb_addr;
169 void *retaddr; 183 void *retaddr;
170 - int is_user, index; 184 + int index;
171 185
172 - is_user = ((env->hflags & HF_CPL_MASK) == 3);  
173 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 186 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
174 redo: 187 redo:
175 tlb_addr = env->tlb_write[is_user][index].address; 188 tlb_addr = env->tlb_write[is_user][index].address;
@@ -182,28 +195,30 @@ void REGPARM(2) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE val @@ -182,28 +195,30 @@ void REGPARM(2) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE val
182 glue(io_write, SUFFIX)(physaddr, val, tlb_addr); 195 glue(io_write, SUFFIX)(physaddr, val, tlb_addr);
183 } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { 196 } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
184 do_unaligned_access: 197 do_unaligned_access:
185 - retaddr = __builtin_return_address(0);  
186 - glue(slow_st, SUFFIX)(addr, val, retaddr); 198 + retaddr = GETPC();
  199 + glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
  200 + is_user, retaddr);
187 } else { 201 } else {
188 /* aligned/unaligned access in the same page */ 202 /* aligned/unaligned access in the same page */
189 glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val); 203 glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val);
190 } 204 }
191 } else { 205 } else {
192 /* the page is not in the TLB : fill it */ 206 /* the page is not in the TLB : fill it */
193 - retaddr = __builtin_return_address(0);  
194 - tlb_fill(addr, 1, retaddr); 207 + retaddr = GETPC();
  208 + tlb_fill(addr, 1, is_user, retaddr);
195 goto redo; 209 goto redo;
196 } 210 }
197 } 211 }
198 212
199 /* handles all unaligned cases */ 213 /* handles all unaligned cases */
200 -static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val,  
201 - void *retaddr) 214 +static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr,
  215 + DATA_TYPE val,
  216 + int is_user,
  217 + void *retaddr)
202 { 218 {
203 unsigned long physaddr, tlb_addr; 219 unsigned long physaddr, tlb_addr;
204 - int is_user, index, i; 220 + int index, i;
205 221
206 - is_user = ((env->hflags & HF_CPL_MASK) == 3);  
207 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 222 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
208 redo: 223 redo:
209 tlb_addr = env->tlb_write[is_user][index].address; 224 tlb_addr = env->tlb_write[is_user][index].address;
@@ -219,9 +234,11 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, @@ -219,9 +234,11 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val,
219 /* XXX: not efficient, but simple */ 234 /* XXX: not efficient, but simple */
220 for(i = 0;i < DATA_SIZE; i++) { 235 for(i = 0;i < DATA_SIZE; i++) {
221 #ifdef TARGET_WORDS_BIGENDIAN 236 #ifdef TARGET_WORDS_BIGENDIAN
222 - slow_stb(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)), retaddr); 237 + glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
  238 + is_user, retaddr);
223 #else 239 #else
224 - slow_stb(addr + i, val >> (i * 8), retaddr); 240 + glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
  241 + is_user, retaddr);
225 #endif 242 #endif
226 } 243 }
227 } else { 244 } else {
@@ -230,7 +247,7 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, @@ -230,7 +247,7 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val,
230 } 247 }
231 } else { 248 } else {
232 /* the page is not in the TLB : fill it */ 249 /* the page is not in the TLB : fill it */
233 - tlb_fill(addr, 1, retaddr); 250 + tlb_fill(addr, 1, is_user, retaddr);
234 goto redo; 251 goto redo;
235 } 252 }
236 } 253 }
@@ -238,4 +255,5 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, @@ -238,4 +255,5 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val,
238 #undef SHIFT 255 #undef SHIFT
239 #undef DATA_TYPE 256 #undef DATA_TYPE
240 #undef SUFFIX 257 #undef SUFFIX
  258 +#undef USUFFIX
241 #undef DATA_SIZE 259 #undef DATA_SIZE
target-i386/exec.h
@@ -137,8 +137,10 @@ void helper_invlpg(unsigned int addr); @@ -137,8 +137,10 @@ void helper_invlpg(unsigned int addr);
137 void cpu_x86_update_cr0(CPUX86State *env); 137 void cpu_x86_update_cr0(CPUX86State *env);
138 void cpu_x86_update_cr3(CPUX86State *env); 138 void cpu_x86_update_cr3(CPUX86State *env);
139 void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr); 139 void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
140 -int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write);  
141 -void tlb_fill(unsigned long addr, int is_write, void *retaddr); 140 +int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr,
  141 + int is_write, int is_user, int is_softmmu);
  142 +void tlb_fill(unsigned long addr, int is_write, int is_user,
  143 + void *retaddr);
142 void __hidden cpu_lock(void); 144 void __hidden cpu_lock(void);
143 void __hidden cpu_unlock(void); 145 void __hidden cpu_unlock(void);
144 void do_interrupt(int intno, int is_int, int error_code, 146 void do_interrupt(int intno, int is_int, int error_code,
@@ -366,26 +368,30 @@ static inline void load_eflags(int eflags, int update_mask) @@ -366,26 +368,30 @@ static inline void load_eflags(int eflags, int update_mask)
366 (eflags & update_mask); 368 (eflags & update_mask);
367 } 369 }
368 370
369 -/* memory access macros */ 371 +/* XXX: move that to a generic header */
  372 +#if !defined(CONFIG_USER_ONLY)
370 373
371 -#define ldul ldl  
372 -#define lduq ldq  
373 #define ldul_user ldl_user 374 #define ldul_user ldl_user
374 #define ldul_kernel ldl_kernel 375 #define ldul_kernel ldl_kernel
375 376
376 -#define ldub_raw ldub  
377 -#define ldsb_raw ldsb  
378 -#define lduw_raw lduw  
379 -#define ldsw_raw ldsw  
380 -#define ldl_raw ldl  
381 -#define ldq_raw ldq 377 +#define ACCESS_TYPE 0
  378 +#define MEMSUFFIX _kernel
  379 +#define DATA_SIZE 1
  380 +#include "softmmu_header.h"
  381 +
  382 +#define DATA_SIZE 2
  383 +#include "softmmu_header.h"
382 384
383 -#define stb_raw stb  
384 -#define stw_raw stw  
385 -#define stl_raw stl  
386 -#define stq_raw stq 385 +#define DATA_SIZE 4
  386 +#include "softmmu_header.h"
  387 +
  388 +#define DATA_SIZE 8
  389 +#include "softmmu_header.h"
  390 +#undef ACCESS_TYPE
  391 +#undef MEMSUFFIX
387 392
388 -#define MEMUSER 0 393 +#define ACCESS_TYPE 1
  394 +#define MEMSUFFIX _user
389 #define DATA_SIZE 1 395 #define DATA_SIZE 1
390 #include "softmmu_header.h" 396 #include "softmmu_header.h"
391 397
@@ -397,9 +403,12 @@ static inline void load_eflags(int eflags, int update_mask) @@ -397,9 +403,12 @@ static inline void load_eflags(int eflags, int update_mask)
397 403
398 #define DATA_SIZE 8 404 #define DATA_SIZE 8
399 #include "softmmu_header.h" 405 #include "softmmu_header.h"
  406 +#undef ACCESS_TYPE
  407 +#undef MEMSUFFIX
400 408
401 -#undef MEMUSER  
402 -#define MEMUSER 1 409 +/* these access are slower, they must be as rare as possible */
  410 +#define ACCESS_TYPE 2
  411 +#define MEMSUFFIX _data
403 #define DATA_SIZE 1 412 #define DATA_SIZE 1
404 #include "softmmu_header.h" 413 #include "softmmu_header.h"
405 414
@@ -411,6 +420,59 @@ static inline void load_eflags(int eflags, int update_mask) @@ -411,6 +420,59 @@ static inline void load_eflags(int eflags, int update_mask)
411 420
412 #define DATA_SIZE 8 421 #define DATA_SIZE 8
413 #include "softmmu_header.h" 422 #include "softmmu_header.h"
  423 +#undef ACCESS_TYPE
  424 +#undef MEMSUFFIX
  425 +
  426 +#define ldub(p) ldub_data(p)
  427 +#define ldsb(p) ldsb_data(p)
  428 +#define lduw(p) lduw_data(p)
  429 +#define ldsw(p) ldsw_data(p)
  430 +#define ldl(p) ldl_data(p)
  431 +#define ldq(p) ldq_data(p)
  432 +
  433 +#define stb(p, v) stb_data(p, v)
  434 +#define stw(p, v) stw_data(p, v)
  435 +#define stl(p, v) stl_data(p, v)
  436 +#define stq(p, v) stq_data(p, v)
  437 +
  438 +static inline double ldfq(void *ptr)
  439 +{
  440 + union {
  441 + double d;
  442 + uint64_t i;
  443 + } u;
  444 + u.i = ldq(ptr);
  445 + return u.d;
  446 +}
  447 +
  448 +static inline void stfq(void *ptr, double v)
  449 +{
  450 + union {
  451 + double d;
  452 + uint64_t i;
  453 + } u;
  454 + u.d = v;
  455 + stq(ptr, u.i);
  456 +}
414 457
415 -#undef MEMUSER 458 +static inline float ldfl(void *ptr)
  459 +{
  460 + union {
  461 + float f;
  462 + uint32_t i;
  463 + } u;
  464 + u.i = ldl(ptr);
  465 + return u.f;
  466 +}
  467 +
  468 +static inline void stfl(void *ptr, float v)
  469 +{
  470 + union {
  471 + float f;
  472 + uint32_t i;
  473 + } u;
  474 + u.f = v;
  475 + stl(ptr, u.i);
  476 +}
416 477
  478 +#endif /* !defined(CONFIG_USER_ONLY) */
target-i386/helper.c
@@ -153,11 +153,11 @@ static inline void get_ss_esp_from_tss(uint32_t *ss_ptr, @@ -153,11 +153,11 @@ static inline void get_ss_esp_from_tss(uint32_t *ss_ptr,
153 if (index + (4 << shift) - 1 > env->tr.limit) 153 if (index + (4 << shift) - 1 > env->tr.limit)
154 raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc); 154 raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);
155 if (shift == 0) { 155 if (shift == 0) {
156 - *esp_ptr = lduw(env->tr.base + index);  
157 - *ss_ptr = lduw(env->tr.base + index + 2); 156 + *esp_ptr = lduw_kernel(env->tr.base + index);
  157 + *ss_ptr = lduw_kernel(env->tr.base + index + 2);
158 } else { 158 } else {
159 - *esp_ptr = ldl(env->tr.base + index);  
160 - *ss_ptr = lduw(env->tr.base + index + 4); 159 + *esp_ptr = ldl_kernel(env->tr.base + index);
  160 + *ss_ptr = lduw_kernel(env->tr.base + index + 4);
161 } 161 }
162 } 162 }
163 163
@@ -177,8 +177,8 @@ static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr, @@ -177,8 +177,8 @@ static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
177 if ((index + 7) > dt->limit) 177 if ((index + 7) > dt->limit)
178 return -1; 178 return -1;
179 ptr = dt->base + index; 179 ptr = dt->base + index;
180 - *e1_ptr = ldl(ptr);  
181 - *e2_ptr = ldl(ptr + 4); 180 + *e1_ptr = ldl_kernel(ptr);
  181 + *e2_ptr = ldl_kernel(ptr + 4);
182 return 0; 182 return 0;
183 } 183 }
184 184
@@ -226,8 +226,8 @@ static void do_interrupt_protected(int intno, int is_int, int error_code, @@ -226,8 +226,8 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
226 if (intno * 8 + 7 > dt->limit) 226 if (intno * 8 + 7 > dt->limit)
227 raise_exception_err(EXCP0D_GPF, intno * 8 + 2); 227 raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
228 ptr = dt->base + intno * 8; 228 ptr = dt->base + intno * 8;
229 - e1 = ldl(ptr);  
230 - e2 = ldl(ptr + 4); 229 + e1 = ldl_kernel(ptr);
  230 + e2 = ldl_kernel(ptr + 4);
231 /* check gate type */ 231 /* check gate type */
232 type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; 232 type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
233 switch(type) { 233 switch(type) {
@@ -344,47 +344,47 @@ static void do_interrupt_protected(int intno, int is_int, int error_code, @@ -344,47 +344,47 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
344 int old_eflags; 344 int old_eflags;
345 if (env->eflags & VM_MASK) { 345 if (env->eflags & VM_MASK) {
346 ssp -= 4; 346 ssp -= 4;
347 - stl(ssp, env->segs[R_GS].selector); 347 + stl_kernel(ssp, env->segs[R_GS].selector);
348 ssp -= 4; 348 ssp -= 4;
349 - stl(ssp, env->segs[R_FS].selector); 349 + stl_kernel(ssp, env->segs[R_FS].selector);
350 ssp -= 4; 350 ssp -= 4;
351 - stl(ssp, env->segs[R_DS].selector); 351 + stl_kernel(ssp, env->segs[R_DS].selector);
352 ssp -= 4; 352 ssp -= 4;
353 - stl(ssp, env->segs[R_ES].selector); 353 + stl_kernel(ssp, env->segs[R_ES].selector);
354 } 354 }
355 if (new_stack) { 355 if (new_stack) {
356 ssp -= 4; 356 ssp -= 4;
357 - stl(ssp, old_ss); 357 + stl_kernel(ssp, old_ss);
358 ssp -= 4; 358 ssp -= 4;
359 - stl(ssp, old_esp); 359 + stl_kernel(ssp, old_esp);
360 } 360 }
361 ssp -= 4; 361 ssp -= 4;
362 old_eflags = compute_eflags(); 362 old_eflags = compute_eflags();
363 - stl(ssp, old_eflags); 363 + stl_kernel(ssp, old_eflags);
364 ssp -= 4; 364 ssp -= 4;
365 - stl(ssp, old_cs); 365 + stl_kernel(ssp, old_cs);
366 ssp -= 4; 366 ssp -= 4;
367 - stl(ssp, old_eip); 367 + stl_kernel(ssp, old_eip);
368 if (has_error_code) { 368 if (has_error_code) {
369 ssp -= 4; 369 ssp -= 4;
370 - stl(ssp, error_code); 370 + stl_kernel(ssp, error_code);
371 } 371 }
372 } else { 372 } else {
373 if (new_stack) { 373 if (new_stack) {
374 ssp -= 2; 374 ssp -= 2;
375 - stw(ssp, old_ss); 375 + stw_kernel(ssp, old_ss);
376 ssp -= 2; 376 ssp -= 2;
377 - stw(ssp, old_esp); 377 + stw_kernel(ssp, old_esp);
378 } 378 }
379 ssp -= 2; 379 ssp -= 2;
380 - stw(ssp, compute_eflags()); 380 + stw_kernel(ssp, compute_eflags());
381 ssp -= 2; 381 ssp -= 2;
382 - stw(ssp, old_cs); 382 + stw_kernel(ssp, old_cs);
383 ssp -= 2; 383 ssp -= 2;
384 - stw(ssp, old_eip); 384 + stw_kernel(ssp, old_eip);
385 if (has_error_code) { 385 if (has_error_code) {
386 ssp -= 2; 386 ssp -= 2;
387 - stw(ssp, error_code); 387 + stw_kernel(ssp, error_code);
388 } 388 }
389 } 389 }
390 390
@@ -410,8 +410,8 @@ static void do_interrupt_real(int intno, int is_int, int error_code, @@ -410,8 +410,8 @@ static void do_interrupt_real(int intno, int is_int, int error_code,
410 if (intno * 4 + 3 > dt->limit) 410 if (intno * 4 + 3 > dt->limit)
411 raise_exception_err(EXCP0D_GPF, intno * 8 + 2); 411 raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
412 ptr = dt->base + intno * 4; 412 ptr = dt->base + intno * 4;
413 - offset = lduw(ptr);  
414 - selector = lduw(ptr + 2); 413 + offset = lduw_kernel(ptr);
  414 + selector = lduw_kernel(ptr + 2);
415 esp = ESP; 415 esp = ESP;
416 ssp = env->segs[R_SS].base; 416 ssp = env->segs[R_SS].base;
417 if (is_int) 417 if (is_int)
@@ -420,11 +420,11 @@ static void do_interrupt_real(int intno, int is_int, int error_code, @@ -420,11 +420,11 @@ static void do_interrupt_real(int intno, int is_int, int error_code,
420 old_eip = env->eip; 420 old_eip = env->eip;
421 old_cs = env->segs[R_CS].selector; 421 old_cs = env->segs[R_CS].selector;
422 esp -= 2; 422 esp -= 2;
423 - stw(ssp + (esp & 0xffff), compute_eflags()); 423 + stw_kernel(ssp + (esp & 0xffff), compute_eflags());
424 esp -= 2; 424 esp -= 2;
425 - stw(ssp + (esp & 0xffff), old_cs); 425 + stw_kernel(ssp + (esp & 0xffff), old_cs);
426 esp -= 2; 426 esp -= 2;
427 - stw(ssp + (esp & 0xffff), old_eip); 427 + stw_kernel(ssp + (esp & 0xffff), old_eip);
428 428
429 /* update processor state */ 429 /* update processor state */
430 ESP = (ESP & ~0xffff) | (esp & 0xffff); 430 ESP = (ESP & ~0xffff) | (esp & 0xffff);
@@ -445,7 +445,7 @@ void do_interrupt_user(int intno, int is_int, int error_code, @@ -445,7 +445,7 @@ void do_interrupt_user(int intno, int is_int, int error_code,
445 445
446 dt = &env->idt; 446 dt = &env->idt;
447 ptr = dt->base + (intno * 8); 447 ptr = dt->base + (intno * 8);
448 - e2 = ldl(ptr + 4); 448 + e2 = ldl_kernel(ptr + 4);
449 449
450 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 450 dpl = (e2 >> DESC_DPL_SHIFT) & 3;
451 cpl = env->hflags & HF_CPL_MASK; 451 cpl = env->hflags & HF_CPL_MASK;
@@ -651,8 +651,8 @@ void helper_lldt_T0(void) @@ -651,8 +651,8 @@ void helper_lldt_T0(void)
651 if ((index + 7) > dt->limit) 651 if ((index + 7) > dt->limit)
652 raise_exception_err(EXCP0D_GPF, selector & 0xfffc); 652 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
653 ptr = dt->base + index; 653 ptr = dt->base + index;
654 - e1 = ldl(ptr);  
655 - e2 = ldl(ptr + 4); 654 + e1 = ldl_kernel(ptr);
  655 + e2 = ldl_kernel(ptr + 4);
656 if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) 656 if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2)
657 raise_exception_err(EXCP0D_GPF, selector & 0xfffc); 657 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
658 if (!(e2 & DESC_P_MASK)) 658 if (!(e2 & DESC_P_MASK))
@@ -684,8 +684,8 @@ void helper_ltr_T0(void) @@ -684,8 +684,8 @@ void helper_ltr_T0(void)
684 if ((index + 7) > dt->limit) 684 if ((index + 7) > dt->limit)
685 raise_exception_err(EXCP0D_GPF, selector & 0xfffc); 685 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
686 ptr = dt->base + index; 686 ptr = dt->base + index;
687 - e1 = ldl(ptr);  
688 - e2 = ldl(ptr + 4); 687 + e1 = ldl_kernel(ptr);
  688 + e2 = ldl_kernel(ptr + 4);
689 type = (e2 >> DESC_TYPE_SHIFT) & 0xf; 689 type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
690 if ((e2 & DESC_S_MASK) || 690 if ((e2 & DESC_S_MASK) ||
691 (type != 2 && type != 9)) 691 (type != 2 && type != 9))
@@ -694,7 +694,7 @@ void helper_ltr_T0(void) @@ -694,7 +694,7 @@ void helper_ltr_T0(void)
694 raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); 694 raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
695 load_seg_cache_raw_dt(&env->tr, e1, e2); 695 load_seg_cache_raw_dt(&env->tr, e1, e2);
696 e2 |= 0x00000200; /* set the busy bit */ 696 e2 |= 0x00000200; /* set the busy bit */
697 - stl(ptr + 4, e2); 697 + stl_kernel(ptr + 4, e2);
698 } 698 }
699 env->tr.selector = selector; 699 env->tr.selector = selector;
700 } 700 }
@@ -813,14 +813,14 @@ void helper_lcall_real_T0_T1(int shift, int next_eip) @@ -813,14 +813,14 @@ void helper_lcall_real_T0_T1(int shift, int next_eip)
813 ssp = env->segs[R_SS].base; 813 ssp = env->segs[R_SS].base;
814 if (shift) { 814 if (shift) {
815 esp -= 4; 815 esp -= 4;
816 - stl(ssp + (esp & esp_mask), env->segs[R_CS].selector); 816 + stl_kernel(ssp + (esp & esp_mask), env->segs[R_CS].selector);
817 esp -= 4; 817 esp -= 4;
818 - stl(ssp + (esp & esp_mask), next_eip); 818 + stl_kernel(ssp + (esp & esp_mask), next_eip);
819 } else { 819 } else {
820 esp -= 2; 820 esp -= 2;
821 - stw(ssp + (esp & esp_mask), env->segs[R_CS].selector); 821 + stw_kernel(ssp + (esp & esp_mask), env->segs[R_CS].selector);
822 esp -= 2; 822 esp -= 2;
823 - stw(ssp + (esp & esp_mask), next_eip); 823 + stw_kernel(ssp + (esp & esp_mask), next_eip);
824 } 824 }
825 825
826 if (!(env->segs[R_SS].flags & DESC_B_MASK)) 826 if (!(env->segs[R_SS].flags & DESC_B_MASK))
@@ -873,14 +873,14 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) @@ -873,14 +873,14 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
873 ssp = env->segs[R_SS].base + sp; 873 ssp = env->segs[R_SS].base + sp;
874 if (shift) { 874 if (shift) {
875 ssp -= 4; 875 ssp -= 4;
876 - stl(ssp, env->segs[R_CS].selector); 876 + stl_kernel(ssp, env->segs[R_CS].selector);
877 ssp -= 4; 877 ssp -= 4;
878 - stl(ssp, next_eip); 878 + stl_kernel(ssp, next_eip);
879 } else { 879 } else {
880 ssp -= 2; 880 ssp -= 2;
881 - stw(ssp, env->segs[R_CS].selector); 881 + stw_kernel(ssp, env->segs[R_CS].selector);
882 ssp -= 2; 882 ssp -= 2;
883 - stw(ssp, next_eip); 883 + stw_kernel(ssp, next_eip);
884 } 884 }
885 sp -= (4 << shift); 885 sp -= (4 << shift);
886 886
@@ -975,23 +975,23 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) @@ -975,23 +975,23 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
975 ssp = env->segs[R_SS].base + sp; 975 ssp = env->segs[R_SS].base + sp;
976 if (shift) { 976 if (shift) {
977 ssp -= 4; 977 ssp -= 4;
978 - stl(ssp, old_ss); 978 + stl_kernel(ssp, old_ss);
979 ssp -= 4; 979 ssp -= 4;
980 - stl(ssp, old_esp); 980 + stl_kernel(ssp, old_esp);
981 ssp -= 4 * param_count; 981 ssp -= 4 * param_count;
982 for(i = 0; i < param_count; i++) { 982 for(i = 0; i < param_count; i++) {
983 - val = ldl(old_ssp + i * 4);  
984 - stl(ssp + i * 4, val); 983 + val = ldl_kernel(old_ssp + i * 4);
  984 + stl_kernel(ssp + i * 4, val);
985 } 985 }
986 } else { 986 } else {
987 ssp -= 2; 987 ssp -= 2;
988 - stw(ssp, old_ss); 988 + stw_kernel(ssp, old_ss);
989 ssp -= 2; 989 ssp -= 2;
990 - stw(ssp, old_esp); 990 + stw_kernel(ssp, old_esp);
991 ssp -= 2 * param_count; 991 ssp -= 2 * param_count;
992 for(i = 0; i < param_count; i++) { 992 for(i = 0; i < param_count; i++) {
993 - val = lduw(old_ssp + i * 2);  
994 - stw(ssp + i * 2, val); 993 + val = lduw_kernel(old_ssp + i * 2);
  994 + stw_kernel(ssp + i * 2, val);
995 } 995 }
996 } 996 }
997 } else { 997 } else {
@@ -1004,14 +1004,14 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) @@ -1004,14 +1004,14 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1004 1004
1005 if (shift) { 1005 if (shift) {
1006 ssp -= 4; 1006 ssp -= 4;
1007 - stl(ssp, env->segs[R_CS].selector); 1007 + stl_kernel(ssp, env->segs[R_CS].selector);
1008 ssp -= 4; 1008 ssp -= 4;
1009 - stl(ssp, next_eip); 1009 + stl_kernel(ssp, next_eip);
1010 } else { 1010 } else {
1011 ssp -= 2; 1011 ssp -= 2;
1012 - stw(ssp, env->segs[R_CS].selector); 1012 + stw_kernel(ssp, env->segs[R_CS].selector);
1013 ssp -= 2; 1013 ssp -= 2;
1014 - stw(ssp, next_eip); 1014 + stw_kernel(ssp, next_eip);
1015 } 1015 }
1016 1016
1017 sp -= push_size; 1017 sp -= push_size;
@@ -1042,14 +1042,14 @@ void helper_iret_real(int shift) @@ -1042,14 +1042,14 @@ void helper_iret_real(int shift)
1042 ssp = env->segs[R_SS].base + sp; 1042 ssp = env->segs[R_SS].base + sp;
1043 if (shift == 1) { 1043 if (shift == 1) {
1044 /* 32 bits */ 1044 /* 32 bits */
1045 - new_eflags = ldl(ssp + 8);  
1046 - new_cs = ldl(ssp + 4) & 0xffff;  
1047 - new_eip = ldl(ssp) & 0xffff; 1045 + new_eflags = ldl_kernel(ssp + 8);
  1046 + new_cs = ldl_kernel(ssp + 4) & 0xffff;
  1047 + new_eip = ldl_kernel(ssp) & 0xffff;
1048 } else { 1048 } else {
1049 /* 16 bits */ 1049 /* 16 bits */
1050 - new_eflags = lduw(ssp + 4);  
1051 - new_cs = lduw(ssp + 2);  
1052 - new_eip = lduw(ssp); 1050 + new_eflags = lduw_kernel(ssp + 4);
  1051 + new_cs = lduw_kernel(ssp + 2);
  1052 + new_eip = lduw_kernel(ssp);
1053 } 1053 }
1054 new_esp = sp + (6 << shift); 1054 new_esp = sp + (6 << shift);
1055 ESP = (ESP & 0xffff0000) | 1055 ESP = (ESP & 0xffff0000) |
@@ -1078,17 +1078,17 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) @@ -1078,17 +1078,17 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
1078 if (shift == 1) { 1078 if (shift == 1) {
1079 /* 32 bits */ 1079 /* 32 bits */
1080 if (is_iret) 1080 if (is_iret)
1081 - new_eflags = ldl(ssp + 8);  
1082 - new_cs = ldl(ssp + 4) & 0xffff;  
1083 - new_eip = ldl(ssp); 1081 + new_eflags = ldl_kernel(ssp + 8);
  1082 + new_cs = ldl_kernel(ssp + 4) & 0xffff;
  1083 + new_eip = ldl_kernel(ssp);
1084 if (is_iret && (new_eflags & VM_MASK)) 1084 if (is_iret && (new_eflags & VM_MASK))
1085 goto return_to_vm86; 1085 goto return_to_vm86;
1086 } else { 1086 } else {
1087 /* 16 bits */ 1087 /* 16 bits */
1088 if (is_iret) 1088 if (is_iret)
1089 - new_eflags = lduw(ssp + 4);  
1090 - new_cs = lduw(ssp + 2);  
1091 - new_eip = lduw(ssp); 1089 + new_eflags = lduw_kernel(ssp + 4);
  1090 + new_cs = lduw_kernel(ssp + 2);
  1091 + new_eip = lduw_kernel(ssp);
1092 } 1092 }
1093 if ((new_cs & 0xfffc) == 0) 1093 if ((new_cs & 0xfffc) == 0)
1094 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); 1094 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
@@ -1124,12 +1124,12 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) @@ -1124,12 +1124,12 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
1124 ssp += (4 << shift) + ((2 * is_iret) << shift) + addend; 1124 ssp += (4 << shift) + ((2 * is_iret) << shift) + addend;
1125 if (shift == 1) { 1125 if (shift == 1) {
1126 /* 32 bits */ 1126 /* 32 bits */
1127 - new_esp = ldl(ssp);  
1128 - new_ss = ldl(ssp + 4) & 0xffff; 1127 + new_esp = ldl_kernel(ssp);
  1128 + new_ss = ldl_kernel(ssp + 4) & 0xffff;
1129 } else { 1129 } else {
1130 /* 16 bits */ 1130 /* 16 bits */
1131 - new_esp = lduw(ssp);  
1132 - new_ss = lduw(ssp + 2); 1131 + new_esp = lduw_kernel(ssp);
  1132 + new_ss = lduw_kernel(ssp + 2);
1133 } 1133 }
1134 1134
1135 if ((new_ss & 3) != rpl) 1135 if ((new_ss & 3) != rpl)
@@ -1175,12 +1175,12 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) @@ -1175,12 +1175,12 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
1175 return; 1175 return;
1176 1176
1177 return_to_vm86: 1177 return_to_vm86:
1178 - new_esp = ldl(ssp + 12);  
1179 - new_ss = ldl(ssp + 16);  
1180 - new_es = ldl(ssp + 20);  
1181 - new_ds = ldl(ssp + 24);  
1182 - new_fs = ldl(ssp + 28);  
1183 - new_gs = ldl(ssp + 32); 1178 + new_esp = ldl_kernel(ssp + 12);
  1179 + new_ss = ldl_kernel(ssp + 16);
  1180 + new_es = ldl_kernel(ssp + 20);
  1181 + new_ds = ldl_kernel(ssp + 24);
  1182 + new_fs = ldl_kernel(ssp + 28);
  1183 + new_gs = ldl_kernel(ssp + 32);
1184 1184
1185 /* modify processor state */ 1185 /* modify processor state */
1186 load_eflags(new_eflags, FL_UPDATE_CPL0_MASK | VM_MASK | VIF_MASK | VIP_MASK); 1186 load_eflags(new_eflags, FL_UPDATE_CPL0_MASK | VM_MASK | VIF_MASK | VIP_MASK);
@@ -1770,6 +1770,11 @@ void helper_frstor(uint8_t *ptr, int data32) @@ -1770,6 +1770,11 @@ void helper_frstor(uint8_t *ptr, int data32)
1770 } 1770 }
1771 } 1771 }
1772 1772
  1773 +#if !defined(CONFIG_USER_ONLY)
  1774 +
  1775 +#define MMUSUFFIX _mmu
  1776 +#define GETPC() (__builtin_return_address(0))
  1777 +
1773 #define SHIFT 0 1778 #define SHIFT 0
1774 #include "softmmu_template.h" 1779 #include "softmmu_template.h"
1775 1780
@@ -1782,22 +1787,41 @@ void helper_frstor(uint8_t *ptr, int data32) @@ -1782,22 +1787,41 @@ void helper_frstor(uint8_t *ptr, int data32)
1782 #define SHIFT 3 1787 #define SHIFT 3
1783 #include "softmmu_template.h" 1788 #include "softmmu_template.h"
1784 1789
1785 -/* try to fill the TLB and return an exception if error */  
1786 -void tlb_fill(unsigned long addr, int is_write, void *retaddr) 1790 +#endif
  1791 +
  1792 +/* try to fill the TLB and return an exception if error. If retaddr is
  1793 + NULL, it means that the function was called in C code (i.e. not
  1794 + from generated code or from helper.c) */
  1795 +/* XXX: fix it to restore all registers */
  1796 +void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr)
1787 { 1797 {
1788 TranslationBlock *tb; 1798 TranslationBlock *tb;
1789 int ret; 1799 int ret;
1790 unsigned long pc; 1800 unsigned long pc;
1791 - ret = cpu_x86_handle_mmu_fault(env, addr, is_write); 1801 + CPUX86State *saved_env;
  1802 +
  1803 + /* XXX: hack to restore env in all cases, even if not called from
  1804 + generated code */
  1805 + saved_env = env;
  1806 + env = cpu_single_env;
  1807 + if (is_write && page_unprotect(addr)) {
  1808 + /* nothing more to do: the page was write protected because
  1809 + there was code in it. page_unprotect() flushed the code. */
  1810 + }
  1811 +
  1812 + ret = cpu_x86_handle_mmu_fault(env, addr, is_write, is_user, 1);
1792 if (ret) { 1813 if (ret) {
1793 - /* now we have a real cpu fault */  
1794 - pc = (unsigned long)retaddr;  
1795 - tb = tb_find_pc(pc);  
1796 - if (tb) {  
1797 - /* the PC is inside the translated code. It means that we have  
1798 - a virtual CPU fault */  
1799 - cpu_restore_state(tb, env, pc); 1814 + if (retaddr) {
  1815 + /* now we have a real cpu fault */
  1816 + pc = (unsigned long)retaddr;
  1817 + tb = tb_find_pc(pc);
  1818 + if (tb) {
  1819 + /* the PC is inside the translated code. It means that we have
  1820 + a virtual CPU fault */
  1821 + cpu_restore_state(tb, env, pc);
  1822 + }
1800 } 1823 }
1801 raise_exception_err(EXCP0E_PAGE, env->error_code); 1824 raise_exception_err(EXCP0E_PAGE, env->error_code);
1802 } 1825 }
  1826 + env = saved_env;
1803 } 1827 }
target-i386/helper2.c
@@ -210,7 +210,9 @@ void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr) @@ -210,7 +210,9 @@ void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr)
210 flags = page_get_flags(addr); 210 flags = page_get_flags(addr);
211 if (flags & PAGE_VALID) { 211 if (flags & PAGE_VALID) {
212 virt_addr = addr & ~0xfff; 212 virt_addr = addr & ~0xfff;
  213 +#if !defined(CONFIG_SOFTMMU)
213 munmap((void *)virt_addr, 4096); 214 munmap((void *)virt_addr, 4096);
  215 +#endif
214 page_set_flags(virt_addr, virt_addr + 4096, 0); 216 page_set_flags(virt_addr, virt_addr + 4096, 0);
215 } 217 }
216 } 218 }
@@ -221,16 +223,14 @@ void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr) @@ -221,16 +223,14 @@ void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr)
221 1 = generate PF fault 223 1 = generate PF fault
222 2 = soft MMU activation required for this block 224 2 = soft MMU activation required for this block
223 */ 225 */
224 -int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) 226 +int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr,
  227 + int is_write, int is_user, int is_softmmu)
225 { 228 {
226 uint8_t *pde_ptr, *pte_ptr; 229 uint8_t *pde_ptr, *pte_ptr;
227 uint32_t pde, pte, virt_addr; 230 uint32_t pde, pte, virt_addr;
228 - int cpl, error_code, is_dirty, is_user, prot, page_size, ret; 231 + int error_code, is_dirty, prot, page_size, ret;
229 unsigned long pd; 232 unsigned long pd;
230 233
231 - cpl = env->hflags & HF_CPL_MASK;  
232 - is_user = (cpl == 3);  
233 -  
234 #ifdef DEBUG_MMU 234 #ifdef DEBUG_MMU
235 printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n", 235 printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n",
236 addr, is_write, is_user, env->eip); 236 addr, is_write, is_user, env->eip);
@@ -252,7 +252,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) @@ -252,7 +252,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write)
252 252
253 /* page directory entry */ 253 /* page directory entry */
254 pde_ptr = phys_ram_base + ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)); 254 pde_ptr = phys_ram_base + ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3));
255 - pde = ldl(pde_ptr); 255 + pde = ldl_raw(pde_ptr);
256 if (!(pde & PG_PRESENT_MASK)) { 256 if (!(pde & PG_PRESENT_MASK)) {
257 error_code = 0; 257 error_code = 0;
258 goto do_fault; 258 goto do_fault;
@@ -274,7 +274,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) @@ -274,7 +274,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write)
274 pde |= PG_ACCESSED_MASK; 274 pde |= PG_ACCESSED_MASK;
275 if (is_dirty) 275 if (is_dirty)
276 pde |= PG_DIRTY_MASK; 276 pde |= PG_DIRTY_MASK;
277 - stl(pde_ptr, pde); 277 + stl_raw(pde_ptr, pde);
278 } 278 }
279 279
280 pte = pde & ~0x003ff000; /* align to 4MB */ 280 pte = pde & ~0x003ff000; /* align to 4MB */
@@ -283,12 +283,12 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) @@ -283,12 +283,12 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write)
283 } else { 283 } else {
284 if (!(pde & PG_ACCESSED_MASK)) { 284 if (!(pde & PG_ACCESSED_MASK)) {
285 pde |= PG_ACCESSED_MASK; 285 pde |= PG_ACCESSED_MASK;
286 - stl(pde_ptr, pde); 286 + stl_raw(pde_ptr, pde);
287 } 287 }
288 288
289 /* page directory entry */ 289 /* page directory entry */
290 pte_ptr = phys_ram_base + ((pde & ~0xfff) + ((addr >> 10) & 0xffc)); 290 pte_ptr = phys_ram_base + ((pde & ~0xfff) + ((addr >> 10) & 0xffc));
291 - pte = ldl(pte_ptr); 291 + pte = ldl_raw(pte_ptr);
292 if (!(pte & PG_PRESENT_MASK)) { 292 if (!(pte & PG_PRESENT_MASK)) {
293 error_code = 0; 293 error_code = 0;
294 goto do_fault; 294 goto do_fault;
@@ -308,7 +308,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) @@ -308,7 +308,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write)
308 pte |= PG_ACCESSED_MASK; 308 pte |= PG_ACCESSED_MASK;
309 if (is_dirty) 309 if (is_dirty)
310 pte |= PG_DIRTY_MASK; 310 pte |= PG_DIRTY_MASK;
311 - stl(pte_ptr, pte); 311 + stl_raw(pte_ptr, pte);
312 } 312 }
313 page_size = 4096; 313 page_size = 4096;
314 virt_addr = addr & ~0xfff; 314 virt_addr = addr & ~0xfff;
@@ -325,7 +325,10 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) @@ -325,7 +325,10 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write)
325 } 325 }
326 326
327 do_mapping: 327 do_mapping:
328 - if (env->hflags & HF_SOFTMMU_MASK) { 328 +#if !defined(CONFIG_SOFTMMU)
  329 + if (is_softmmu)
  330 +#endif
  331 + {
329 unsigned long paddr, vaddr, address, addend, page_offset; 332 unsigned long paddr, vaddr, address, addend, page_offset;
330 int index; 333 int index;
331 334
@@ -352,32 +355,39 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) @@ -352,32 +355,39 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write)
352 env->tlb_write[is_user][index].address = address; 355 env->tlb_write[is_user][index].address = address;
353 env->tlb_write[is_user][index].addend = addend; 356 env->tlb_write[is_user][index].addend = addend;
354 } 357 }
  358 + page_set_flags(vaddr, vaddr + TARGET_PAGE_SIZE,
  359 + PAGE_VALID | PAGE_EXEC | prot);
  360 + ret = 0;
355 } 361 }
356 - ret = 0;  
357 - /* XXX: incorrect for 4MB pages */  
358 - pd = physpage_find(pte & ~0xfff);  
359 - if ((pd & 0xfff) != 0) {  
360 - /* IO access: no mapping is done as it will be handled by the  
361 - soft MMU */  
362 - if (!(env->hflags & HF_SOFTMMU_MASK))  
363 - ret = 2;  
364 - } else {  
365 - void *map_addr;  
366 - map_addr = mmap((void *)virt_addr, page_size, prot,  
367 - MAP_SHARED | MAP_FIXED, phys_ram_fd, pd);  
368 - if (map_addr == MAP_FAILED) {  
369 - fprintf(stderr,  
370 - "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",  
371 - pte & ~0xfff, virt_addr);  
372 - exit(1);  
373 - } 362 +#if !defined(CONFIG_SOFTMMU)
  363 + else {
  364 + ret = 0;
  365 + /* XXX: incorrect for 4MB pages */
  366 + pd = physpage_find(pte & ~0xfff);
  367 + if ((pd & 0xfff) != 0) {
  368 + /* IO access: no mapping is done as it will be handled by the
  369 + soft MMU */
  370 + if (!(env->hflags & HF_SOFTMMU_MASK))
  371 + ret = 2;
  372 + } else {
  373 + void *map_addr;
  374 + map_addr = mmap((void *)virt_addr, page_size, prot,
  375 + MAP_SHARED | MAP_FIXED, phys_ram_fd, pd);
  376 + if (map_addr == MAP_FAILED) {
  377 + fprintf(stderr,
  378 + "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",
  379 + pte & ~0xfff, virt_addr);
  380 + exit(1);
  381 + }
374 #ifdef DEBUG_MMU 382 #ifdef DEBUG_MMU
375 - printf("mmaping 0x%08x to virt 0x%08x pse=%d\n",  
376 - pte & ~0xfff, virt_addr, (page_size != 4096)); 383 + printf("mmaping 0x%08x to virt 0x%08x pse=%d\n",
  384 + pte & ~0xfff, virt_addr, (page_size != 4096));
377 #endif 385 #endif
378 - page_set_flags(virt_addr, virt_addr + page_size,  
379 - PAGE_VALID | PAGE_EXEC | prot); 386 + page_set_flags(virt_addr, virt_addr + page_size,
  387 + PAGE_VALID | PAGE_EXEC | prot);
  388 + }
380 } 389 }
  390 +#endif
381 return ret; 391 return ret;
382 do_fault_protect: 392 do_fault_protect:
383 error_code = PG_ERROR_P_MASK; 393 error_code = PG_ERROR_P_MASK;
target-i386/op.c
@@ -376,14 +376,16 @@ void OPPROTO op_andl_A0_ffff(void) @@ -376,14 +376,16 @@ void OPPROTO op_andl_A0_ffff(void)
376 376
377 /* memory access */ 377 /* memory access */
378 378
379 -#define MEMSUFFIX 379 +#define MEMSUFFIX _raw
380 #include "ops_mem.h" 380 #include "ops_mem.h"
381 381
  382 +#if !defined(CONFIG_USER_ONLY)
382 #define MEMSUFFIX _user 383 #define MEMSUFFIX _user
383 #include "ops_mem.h" 384 #include "ops_mem.h"
384 385
385 #define MEMSUFFIX _kernel 386 #define MEMSUFFIX _kernel
386 #include "ops_mem.h" 387 #include "ops_mem.h"
  388 +#endif
387 389
388 /* used for bit operations */ 390 /* used for bit operations */
389 391
target-i386/translate.c
@@ -570,10 +570,10 @@ static GenOpFunc *gen_op_bsx_T0_cc[2][2] = { @@ -570,10 +570,10 @@ static GenOpFunc *gen_op_bsx_T0_cc[2][2] = {
570 }; 570 };
571 571
572 static GenOpFunc *gen_op_lds_T0_A0[3 * 3] = { 572 static GenOpFunc *gen_op_lds_T0_A0[3 * 3] = {
573 - gen_op_ldsb_T0_A0,  
574 - gen_op_ldsw_T0_A0, 573 + gen_op_ldsb_raw_T0_A0,
  574 + gen_op_ldsw_raw_T0_A0,
575 NULL, 575 NULL,
576 - 576 +#ifndef CONFIG_USER_ONLY
577 gen_op_ldsb_kernel_T0_A0, 577 gen_op_ldsb_kernel_T0_A0,
578 gen_op_ldsw_kernel_T0_A0, 578 gen_op_ldsw_kernel_T0_A0,
579 NULL, 579 NULL,
@@ -581,13 +581,15 @@ static GenOpFunc *gen_op_lds_T0_A0[3 * 3] = { @@ -581,13 +581,15 @@ static GenOpFunc *gen_op_lds_T0_A0[3 * 3] = {
581 gen_op_ldsb_user_T0_A0, 581 gen_op_ldsb_user_T0_A0,
582 gen_op_ldsw_user_T0_A0, 582 gen_op_ldsw_user_T0_A0,
583 NULL, 583 NULL,
  584 +#endif
584 }; 585 };
585 586
586 static GenOpFunc *gen_op_ldu_T0_A0[3 * 3] = { 587 static GenOpFunc *gen_op_ldu_T0_A0[3 * 3] = {
587 - gen_op_ldub_T0_A0,  
588 - gen_op_lduw_T0_A0, 588 + gen_op_ldub_raw_T0_A0,
  589 + gen_op_lduw_raw_T0_A0,
589 NULL, 590 NULL,
590 591
  592 +#ifndef CONFIG_USER_ONLY
591 gen_op_ldub_kernel_T0_A0, 593 gen_op_ldub_kernel_T0_A0,
592 gen_op_lduw_kernel_T0_A0, 594 gen_op_lduw_kernel_T0_A0,
593 NULL, 595 NULL,
@@ -595,14 +597,16 @@ static GenOpFunc *gen_op_ldu_T0_A0[3 * 3] = { @@ -595,14 +597,16 @@ static GenOpFunc *gen_op_ldu_T0_A0[3 * 3] = {
595 gen_op_ldub_user_T0_A0, 597 gen_op_ldub_user_T0_A0,
596 gen_op_lduw_user_T0_A0, 598 gen_op_lduw_user_T0_A0,
597 NULL, 599 NULL,
  600 +#endif
598 }; 601 };
599 602
600 /* sign does not matter, except for lidt/lgdt call (TODO: fix it) */ 603 /* sign does not matter, except for lidt/lgdt call (TODO: fix it) */
601 static GenOpFunc *gen_op_ld_T0_A0[3 * 3] = { 604 static GenOpFunc *gen_op_ld_T0_A0[3 * 3] = {
602 - gen_op_ldub_T0_A0,  
603 - gen_op_lduw_T0_A0,  
604 - gen_op_ldl_T0_A0, 605 + gen_op_ldub_raw_T0_A0,
  606 + gen_op_lduw_raw_T0_A0,
  607 + gen_op_ldl_raw_T0_A0,
605 608
  609 +#ifndef CONFIG_USER_ONLY
606 gen_op_ldub_kernel_T0_A0, 610 gen_op_ldub_kernel_T0_A0,
607 gen_op_lduw_kernel_T0_A0, 611 gen_op_lduw_kernel_T0_A0,
608 gen_op_ldl_kernel_T0_A0, 612 gen_op_ldl_kernel_T0_A0,
@@ -610,13 +614,15 @@ static GenOpFunc *gen_op_ld_T0_A0[3 * 3] = { @@ -610,13 +614,15 @@ static GenOpFunc *gen_op_ld_T0_A0[3 * 3] = {
610 gen_op_ldub_user_T0_A0, 614 gen_op_ldub_user_T0_A0,
611 gen_op_lduw_user_T0_A0, 615 gen_op_lduw_user_T0_A0,
612 gen_op_ldl_user_T0_A0, 616 gen_op_ldl_user_T0_A0,
  617 +#endif
613 }; 618 };
614 619
615 static GenOpFunc *gen_op_ld_T1_A0[3 * 3] = { 620 static GenOpFunc *gen_op_ld_T1_A0[3 * 3] = {
616 - gen_op_ldub_T1_A0,  
617 - gen_op_lduw_T1_A0,  
618 - gen_op_ldl_T1_A0, 621 + gen_op_ldub_raw_T1_A0,
  622 + gen_op_lduw_raw_T1_A0,
  623 + gen_op_ldl_raw_T1_A0,
619 624
  625 +#ifndef CONFIG_USER_ONLY
620 gen_op_ldub_kernel_T1_A0, 626 gen_op_ldub_kernel_T1_A0,
621 gen_op_lduw_kernel_T1_A0, 627 gen_op_lduw_kernel_T1_A0,
622 gen_op_ldl_kernel_T1_A0, 628 gen_op_ldl_kernel_T1_A0,
@@ -624,13 +630,15 @@ static GenOpFunc *gen_op_ld_T1_A0[3 * 3] = { @@ -624,13 +630,15 @@ static GenOpFunc *gen_op_ld_T1_A0[3 * 3] = {
624 gen_op_ldub_user_T1_A0, 630 gen_op_ldub_user_T1_A0,
625 gen_op_lduw_user_T1_A0, 631 gen_op_lduw_user_T1_A0,
626 gen_op_ldl_user_T1_A0, 632 gen_op_ldl_user_T1_A0,
  633 +#endif
627 }; 634 };
628 635
629 static GenOpFunc *gen_op_st_T0_A0[3 * 3] = { 636 static GenOpFunc *gen_op_st_T0_A0[3 * 3] = {
630 - gen_op_stb_T0_A0,  
631 - gen_op_stw_T0_A0,  
632 - gen_op_stl_T0_A0, 637 + gen_op_stb_raw_T0_A0,
  638 + gen_op_stw_raw_T0_A0,
  639 + gen_op_stl_raw_T0_A0,
633 640
  641 +#ifndef CONFIG_USER_ONLY
634 gen_op_stb_kernel_T0_A0, 642 gen_op_stb_kernel_T0_A0,
635 gen_op_stw_kernel_T0_A0, 643 gen_op_stw_kernel_T0_A0,
636 gen_op_stl_kernel_T0_A0, 644 gen_op_stl_kernel_T0_A0,
@@ -638,6 +646,7 @@ static GenOpFunc *gen_op_st_T0_A0[3 * 3] = { @@ -638,6 +646,7 @@ static GenOpFunc *gen_op_st_T0_A0[3 * 3] = {
638 gen_op_stb_user_T0_A0, 646 gen_op_stb_user_T0_A0,
639 gen_op_stw_user_T0_A0, 647 gen_op_stw_user_T0_A0,
640 gen_op_stl_user_T0_A0, 648 gen_op_stl_user_T0_A0,
  649 +#endif
641 }; 650 };
642 651
643 static inline void gen_string_movl_A0_ESI(DisasContext *s) 652 static inline void gen_string_movl_A0_ESI(DisasContext *s)
@@ -1176,7 +1185,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ @@ -1176,7 +1185,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
1176 1185
1177 if (base == 4) { 1186 if (base == 4) {
1178 havesib = 1; 1187 havesib = 1;
1179 - code = ldub(s->pc++); 1188 + code = ldub_code(s->pc++);
1180 scale = (code >> 6) & 3; 1189 scale = (code >> 6) & 3;
1181 index = (code >> 3) & 7; 1190 index = (code >> 3) & 7;
1182 base = code & 7; 1191 base = code & 7;
@@ -1186,18 +1195,18 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ @@ -1186,18 +1195,18 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
1186 case 0: 1195 case 0:
1187 if (base == 5) { 1196 if (base == 5) {
1188 base = -1; 1197 base = -1;
1189 - disp = ldl(s->pc); 1198 + disp = ldl_code(s->pc);
1190 s->pc += 4; 1199 s->pc += 4;
1191 } else { 1200 } else {
1192 disp = 0; 1201 disp = 0;
1193 } 1202 }
1194 break; 1203 break;
1195 case 1: 1204 case 1:
1196 - disp = (int8_t)ldub(s->pc++); 1205 + disp = (int8_t)ldub_code(s->pc++);
1197 break; 1206 break;
1198 default: 1207 default:
1199 case 2: 1208 case 2:
1200 - disp = ldl(s->pc); 1209 + disp = ldl_code(s->pc);
1201 s->pc += 4; 1210 s->pc += 4;
1202 break; 1211 break;
1203 } 1212 }
@@ -1229,7 +1238,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ @@ -1229,7 +1238,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
1229 switch (mod) { 1238 switch (mod) {
1230 case 0: 1239 case 0:
1231 if (rm == 6) { 1240 if (rm == 6) {
1232 - disp = lduw(s->pc); 1241 + disp = lduw_code(s->pc);
1233 s->pc += 2; 1242 s->pc += 2;
1234 gen_op_movl_A0_im(disp); 1243 gen_op_movl_A0_im(disp);
1235 rm = 0; /* avoid SS override */ 1244 rm = 0; /* avoid SS override */
@@ -1239,11 +1248,11 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ @@ -1239,11 +1248,11 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
1239 } 1248 }
1240 break; 1249 break;
1241 case 1: 1250 case 1:
1242 - disp = (int8_t)ldub(s->pc++); 1251 + disp = (int8_t)ldub_code(s->pc++);
1243 break; 1252 break;
1244 default: 1253 default:
1245 case 2: 1254 case 2:
1246 - disp = lduw(s->pc); 1255 + disp = lduw_code(s->pc);
1247 s->pc += 2; 1256 s->pc += 2;
1248 break; 1257 break;
1249 } 1258 }
@@ -1337,16 +1346,16 @@ static inline uint32_t insn_get(DisasContext *s, int ot) @@ -1337,16 +1346,16 @@ static inline uint32_t insn_get(DisasContext *s, int ot)
1337 1346
1338 switch(ot) { 1347 switch(ot) {
1339 case OT_BYTE: 1348 case OT_BYTE:
1340 - ret = ldub(s->pc); 1349 + ret = ldub_code(s->pc);
1341 s->pc++; 1350 s->pc++;
1342 break; 1351 break;
1343 case OT_WORD: 1352 case OT_WORD:
1344 - ret = lduw(s->pc); 1353 + ret = lduw_code(s->pc);
1345 s->pc += 2; 1354 s->pc += 2;
1346 break; 1355 break;
1347 default: 1356 default:
1348 case OT_LONG: 1357 case OT_LONG:
1349 - ret = ldl(s->pc); 1358 + ret = ldl_code(s->pc);
1350 s->pc += 4; 1359 s->pc += 4;
1351 break; 1360 break;
1352 } 1361 }
@@ -1756,7 +1765,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1756,7 +1765,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1756 dflag = s->code32; 1765 dflag = s->code32;
1757 s->override = -1; 1766 s->override = -1;
1758 next_byte: 1767 next_byte:
1759 - b = ldub(s->pc); 1768 + b = ldub_code(s->pc);
1760 s->pc++; 1769 s->pc++;
1761 /* check prefixes */ 1770 /* check prefixes */
1762 switch (b) { 1771 switch (b) {
@@ -1814,7 +1823,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1814,7 +1823,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1814 case 0x0f: 1823 case 0x0f:
1815 /**************************/ 1824 /**************************/
1816 /* extended op code */ 1825 /* extended op code */
1817 - b = ldub(s->pc++) | 0x100; 1826 + b = ldub_code(s->pc++) | 0x100;
1818 goto reswitch; 1827 goto reswitch;
1819 1828
1820 /**************************/ 1829 /**************************/
@@ -1839,7 +1848,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1839,7 +1848,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1839 1848
1840 switch(f) { 1849 switch(f) {
1841 case 0: /* OP Ev, Gv */ 1850 case 0: /* OP Ev, Gv */
1842 - modrm = ldub(s->pc++); 1851 + modrm = ldub_code(s->pc++);
1843 reg = ((modrm >> 3) & 7); 1852 reg = ((modrm >> 3) & 7);
1844 mod = (modrm >> 6) & 3; 1853 mod = (modrm >> 6) & 3;
1845 rm = modrm & 7; 1854 rm = modrm & 7;
@@ -1861,7 +1870,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1861,7 +1870,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1861 gen_op(s, op, ot, opreg); 1870 gen_op(s, op, ot, opreg);
1862 break; 1871 break;
1863 case 1: /* OP Gv, Ev */ 1872 case 1: /* OP Gv, Ev */
1864 - modrm = ldub(s->pc++); 1873 + modrm = ldub_code(s->pc++);
1865 mod = (modrm >> 6) & 3; 1874 mod = (modrm >> 6) & 3;
1866 reg = ((modrm >> 3) & 7); 1875 reg = ((modrm >> 3) & 7);
1867 rm = modrm & 7; 1876 rm = modrm & 7;
@@ -1895,7 +1904,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1895,7 +1904,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1895 else 1904 else
1896 ot = dflag ? OT_LONG : OT_WORD; 1905 ot = dflag ? OT_LONG : OT_WORD;
1897 1906
1898 - modrm = ldub(s->pc++); 1907 + modrm = ldub_code(s->pc++);
1899 mod = (modrm >> 6) & 3; 1908 mod = (modrm >> 6) & 3;
1900 rm = modrm & 7; 1909 rm = modrm & 7;
1901 op = (modrm >> 3) & 7; 1910 op = (modrm >> 3) & 7;
@@ -1939,7 +1948,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1939,7 +1948,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
1939 else 1948 else
1940 ot = dflag ? OT_LONG : OT_WORD; 1949 ot = dflag ? OT_LONG : OT_WORD;
1941 1950
1942 - modrm = ldub(s->pc++); 1951 + modrm = ldub_code(s->pc++);
1943 mod = (modrm >> 6) & 3; 1952 mod = (modrm >> 6) & 3;
1944 rm = modrm & 7; 1953 rm = modrm & 7;
1945 op = (modrm >> 3) & 7; 1954 op = (modrm >> 3) & 7;
@@ -2045,7 +2054,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2045,7 +2054,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2045 else 2054 else
2046 ot = dflag ? OT_LONG : OT_WORD; 2055 ot = dflag ? OT_LONG : OT_WORD;
2047 2056
2048 - modrm = ldub(s->pc++); 2057 + modrm = ldub_code(s->pc++);
2049 mod = (modrm >> 6) & 3; 2058 mod = (modrm >> 6) & 3;
2050 rm = modrm & 7; 2059 rm = modrm & 7;
2051 op = (modrm >> 3) & 7; 2060 op = (modrm >> 3) & 7;
@@ -2085,10 +2094,10 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2085,10 +2094,10 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2085 gen_push_T0(s); 2094 gen_push_T0(s);
2086 gen_eob(s); 2095 gen_eob(s);
2087 break; 2096 break;
2088 - case 3: /*< lcall Ev */ 2097 + case 3: /* lcall Ev */
2089 gen_op_ld_T1_A0[ot + s->mem_index](); 2098 gen_op_ld_T1_A0[ot + s->mem_index]();
2090 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); 2099 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
2091 - gen_op_ld_T0_A0[OT_WORD + s->mem_index](); 2100 + gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
2092 do_lcall: 2101 do_lcall:
2093 if (s->pe && !s->vm86) { 2102 if (s->pe && !s->vm86) {
2094 if (s->cc_op != CC_OP_DYNAMIC) 2103 if (s->cc_op != CC_OP_DYNAMIC)
@@ -2109,7 +2118,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2109,7 +2118,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2109 case 5: /* ljmp Ev */ 2118 case 5: /* ljmp Ev */
2110 gen_op_ld_T1_A0[ot + s->mem_index](); 2119 gen_op_ld_T1_A0[ot + s->mem_index]();
2111 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); 2120 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
2112 - gen_op_lduw_T0_A0(); 2121 + gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
2113 do_ljmp: 2122 do_ljmp:
2114 if (s->pe && !s->vm86) { 2123 if (s->pe && !s->vm86) {
2115 if (s->cc_op != CC_OP_DYNAMIC) 2124 if (s->cc_op != CC_OP_DYNAMIC)
@@ -2138,7 +2147,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2138,7 +2147,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2138 else 2147 else
2139 ot = dflag ? OT_LONG : OT_WORD; 2148 ot = dflag ? OT_LONG : OT_WORD;
2140 2149
2141 - modrm = ldub(s->pc++); 2150 + modrm = ldub_code(s->pc++);
2142 mod = (modrm >> 6) & 3; 2151 mod = (modrm >> 6) & 3;
2143 rm = modrm & 7; 2152 rm = modrm & 7;
2144 reg = (modrm >> 3) & 7; 2153 reg = (modrm >> 3) & 7;
@@ -2179,7 +2188,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2179,7 +2188,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2179 case 0x69: /* imul Gv, Ev, I */ 2188 case 0x69: /* imul Gv, Ev, I */
2180 case 0x6b: 2189 case 0x6b:
2181 ot = dflag ? OT_LONG : OT_WORD; 2190 ot = dflag ? OT_LONG : OT_WORD;
2182 - modrm = ldub(s->pc++); 2191 + modrm = ldub_code(s->pc++);
2183 reg = ((modrm >> 3) & 7) + OR_EAX; 2192 reg = ((modrm >> 3) & 7) + OR_EAX;
2184 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); 2193 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2185 if (b == 0x69) { 2194 if (b == 0x69) {
@@ -2206,7 +2215,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2206,7 +2215,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2206 ot = OT_BYTE; 2215 ot = OT_BYTE;
2207 else 2216 else
2208 ot = dflag ? OT_LONG : OT_WORD; 2217 ot = dflag ? OT_LONG : OT_WORD;
2209 - modrm = ldub(s->pc++); 2218 + modrm = ldub_code(s->pc++);
2210 reg = (modrm >> 3) & 7; 2219 reg = (modrm >> 3) & 7;
2211 mod = (modrm >> 6) & 3; 2220 mod = (modrm >> 6) & 3;
2212 if (mod == 3) { 2221 if (mod == 3) {
@@ -2233,7 +2242,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2233,7 +2242,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2233 ot = OT_BYTE; 2242 ot = OT_BYTE;
2234 else 2243 else
2235 ot = dflag ? OT_LONG : OT_WORD; 2244 ot = dflag ? OT_LONG : OT_WORD;
2236 - modrm = ldub(s->pc++); 2245 + modrm = ldub_code(s->pc++);
2237 reg = (modrm >> 3) & 7; 2246 reg = (modrm >> 3) & 7;
2238 mod = (modrm >> 6) & 3; 2247 mod = (modrm >> 6) & 3;
2239 gen_op_mov_TN_reg[ot][1][reg](); 2248 gen_op_mov_TN_reg[ot][1][reg]();
@@ -2250,7 +2259,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2250,7 +2259,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2250 s->cc_op = CC_OP_SUBB + ot; 2259 s->cc_op = CC_OP_SUBB + ot;
2251 break; 2260 break;
2252 case 0x1c7: /* cmpxchg8b */ 2261 case 0x1c7: /* cmpxchg8b */
2253 - modrm = ldub(s->pc++); 2262 + modrm = ldub_code(s->pc++);
2254 mod = (modrm >> 6) & 3; 2263 mod = (modrm >> 6) & 3;
2255 if (mod == 3) 2264 if (mod == 3)
2256 goto illegal_op; 2265 goto illegal_op;
@@ -2291,7 +2300,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2291,7 +2300,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2291 break; 2300 break;
2292 case 0x8f: /* pop Ev */ 2301 case 0x8f: /* pop Ev */
2293 ot = dflag ? OT_LONG : OT_WORD; 2302 ot = dflag ? OT_LONG : OT_WORD;
2294 - modrm = ldub(s->pc++); 2303 + modrm = ldub_code(s->pc++);
2295 gen_pop_T0(s); 2304 gen_pop_T0(s);
2296 s->popl_esp_hack = 2 << dflag; 2305 s->popl_esp_hack = 2 << dflag;
2297 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); 2306 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
@@ -2301,9 +2310,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2301,9 +2310,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2301 case 0xc8: /* enter */ 2310 case 0xc8: /* enter */
2302 { 2311 {
2303 int level; 2312 int level;
2304 - val = lduw(s->pc); 2313 + val = lduw_code(s->pc);
2305 s->pc += 2; 2314 s->pc += 2;
2306 - level = ldub(s->pc++); 2315 + level = ldub_code(s->pc++);
2307 gen_enter(s, val, level); 2316 gen_enter(s, val, level);
2308 } 2317 }
2309 break; 2318 break;
@@ -2369,7 +2378,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2369,7 +2378,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2369 ot = OT_BYTE; 2378 ot = OT_BYTE;
2370 else 2379 else
2371 ot = dflag ? OT_LONG : OT_WORD; 2380 ot = dflag ? OT_LONG : OT_WORD;
2372 - modrm = ldub(s->pc++); 2381 + modrm = ldub_code(s->pc++);
2373 reg = (modrm >> 3) & 7; 2382 reg = (modrm >> 3) & 7;
2374 2383
2375 /* generate a generic store */ 2384 /* generate a generic store */
@@ -2381,7 +2390,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2381,7 +2390,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2381 ot = OT_BYTE; 2390 ot = OT_BYTE;
2382 else 2391 else
2383 ot = dflag ? OT_LONG : OT_WORD; 2392 ot = dflag ? OT_LONG : OT_WORD;
2384 - modrm = ldub(s->pc++); 2393 + modrm = ldub_code(s->pc++);
2385 mod = (modrm >> 6) & 3; 2394 mod = (modrm >> 6) & 3;
2386 if (mod != 3) 2395 if (mod != 3)
2387 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 2396 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
@@ -2398,14 +2407,14 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2398,14 +2407,14 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2398 ot = OT_BYTE; 2407 ot = OT_BYTE;
2399 else 2408 else
2400 ot = dflag ? OT_LONG : OT_WORD; 2409 ot = dflag ? OT_LONG : OT_WORD;
2401 - modrm = ldub(s->pc++); 2410 + modrm = ldub_code(s->pc++);
2402 reg = (modrm >> 3) & 7; 2411 reg = (modrm >> 3) & 7;
2403 2412
2404 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); 2413 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2405 gen_op_mov_reg_T0[ot][reg](); 2414 gen_op_mov_reg_T0[ot][reg]();
2406 break; 2415 break;
2407 case 0x8e: /* mov seg, Gv */ 2416 case 0x8e: /* mov seg, Gv */
2408 - modrm = ldub(s->pc++); 2417 + modrm = ldub_code(s->pc++);
2409 reg = (modrm >> 3) & 7; 2418 reg = (modrm >> 3) & 7;
2410 if (reg >= 6 || reg == R_CS) 2419 if (reg >= 6 || reg == R_CS)
2411 goto illegal_op; 2420 goto illegal_op;
@@ -2422,7 +2431,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2422,7 +2431,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2422 } 2431 }
2423 break; 2432 break;
2424 case 0x8c: /* mov Gv, seg */ 2433 case 0x8c: /* mov Gv, seg */
2425 - modrm = ldub(s->pc++); 2434 + modrm = ldub_code(s->pc++);
2426 reg = (modrm >> 3) & 7; 2435 reg = (modrm >> 3) & 7;
2427 mod = (modrm >> 6) & 3; 2436 mod = (modrm >> 6) & 3;
2428 if (reg >= 6) 2437 if (reg >= 6)
@@ -2444,7 +2453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2444,7 +2453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2444 d_ot = dflag + OT_WORD; 2453 d_ot = dflag + OT_WORD;
2445 /* ot is the size of source */ 2454 /* ot is the size of source */
2446 ot = (b & 1) + OT_BYTE; 2455 ot = (b & 1) + OT_BYTE;
2447 - modrm = ldub(s->pc++); 2456 + modrm = ldub_code(s->pc++);
2448 reg = ((modrm >> 3) & 7) + OR_EAX; 2457 reg = ((modrm >> 3) & 7) + OR_EAX;
2449 mod = (modrm >> 6) & 3; 2458 mod = (modrm >> 6) & 3;
2450 rm = modrm & 7; 2459 rm = modrm & 7;
@@ -2481,7 +2490,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2481,7 +2490,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2481 2490
2482 case 0x8d: /* lea */ 2491 case 0x8d: /* lea */
2483 ot = dflag ? OT_LONG : OT_WORD; 2492 ot = dflag ? OT_LONG : OT_WORD;
2484 - modrm = ldub(s->pc++); 2493 + modrm = ldub_code(s->pc++);
2485 reg = (modrm >> 3) & 7; 2494 reg = (modrm >> 3) & 7;
2486 /* we must ensure that no segment is added */ 2495 /* we must ensure that no segment is added */
2487 s->override = -1; 2496 s->override = -1;
@@ -2574,7 +2583,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2574,7 +2583,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2574 ot = OT_BYTE; 2583 ot = OT_BYTE;
2575 else 2584 else
2576 ot = dflag ? OT_LONG : OT_WORD; 2585 ot = dflag ? OT_LONG : OT_WORD;
2577 - modrm = ldub(s->pc++); 2586 + modrm = ldub_code(s->pc++);
2578 reg = (modrm >> 3) & 7; 2587 reg = (modrm >> 3) & 7;
2579 mod = (modrm >> 6) & 3; 2588 mod = (modrm >> 6) & 3;
2580 if (mod == 3) { 2589 if (mod == 3) {
@@ -2613,7 +2622,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2613,7 +2622,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2613 op = R_GS; 2622 op = R_GS;
2614 do_lxx: 2623 do_lxx:
2615 ot = dflag ? OT_LONG : OT_WORD; 2624 ot = dflag ? OT_LONG : OT_WORD;
2616 - modrm = ldub(s->pc++); 2625 + modrm = ldub_code(s->pc++);
2617 reg = (modrm >> 3) & 7; 2626 reg = (modrm >> 3) & 7;
2618 mod = (modrm >> 6) & 3; 2627 mod = (modrm >> 6) & 3;
2619 if (mod == 3) 2628 if (mod == 3)
@@ -2622,7 +2631,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2622,7 +2631,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2622 gen_op_ld_T1_A0[ot + s->mem_index](); 2631 gen_op_ld_T1_A0[ot + s->mem_index]();
2623 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); 2632 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
2624 /* load the segment first to handle exceptions properly */ 2633 /* load the segment first to handle exceptions properly */
2625 - gen_op_lduw_T0_A0(); 2634 + gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
2626 gen_movl_seg_T0(s, op, pc_start - s->cs_base); 2635 gen_movl_seg_T0(s, op, pc_start - s->cs_base);
2627 /* then put the data */ 2636 /* then put the data */
2628 gen_op_mov_reg_T1[ot][reg](); 2637 gen_op_mov_reg_T1[ot][reg]();
@@ -2645,7 +2654,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2645,7 +2654,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2645 else 2654 else
2646 ot = dflag ? OT_LONG : OT_WORD; 2655 ot = dflag ? OT_LONG : OT_WORD;
2647 2656
2648 - modrm = ldub(s->pc++); 2657 + modrm = ldub_code(s->pc++);
2649 mod = (modrm >> 6) & 3; 2658 mod = (modrm >> 6) & 3;
2650 rm = modrm & 7; 2659 rm = modrm & 7;
2651 op = (modrm >> 3) & 7; 2660 op = (modrm >> 3) & 7;
@@ -2662,7 +2671,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2662,7 +2671,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2662 gen_shift(s, op, ot, opreg, OR_ECX); 2671 gen_shift(s, op, ot, opreg, OR_ECX);
2663 } else { 2672 } else {
2664 if (shift == 2) { 2673 if (shift == 2) {
2665 - shift = ldub(s->pc++); 2674 + shift = ldub_code(s->pc++);
2666 } 2675 }
2667 gen_shifti(s, op, ot, opreg, shift); 2676 gen_shifti(s, op, ot, opreg, shift);
2668 } 2677 }
@@ -2696,7 +2705,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2696,7 +2705,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2696 shift = 0; 2705 shift = 0;
2697 do_shiftd: 2706 do_shiftd:
2698 ot = dflag ? OT_LONG : OT_WORD; 2707 ot = dflag ? OT_LONG : OT_WORD;
2699 - modrm = ldub(s->pc++); 2708 + modrm = ldub_code(s->pc++);
2700 mod = (modrm >> 6) & 3; 2709 mod = (modrm >> 6) & 3;
2701 rm = modrm & 7; 2710 rm = modrm & 7;
2702 reg = (modrm >> 3) & 7; 2711 reg = (modrm >> 3) & 7;
@@ -2710,7 +2719,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2710,7 +2719,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2710 gen_op_mov_TN_reg[ot][1][reg](); 2719 gen_op_mov_TN_reg[ot][1][reg]();
2711 2720
2712 if (shift) { 2721 if (shift) {
2713 - val = ldub(s->pc++); 2722 + val = ldub_code(s->pc++);
2714 val &= 0x1f; 2723 val &= 0x1f;
2715 if (val) { 2724 if (val) {
2716 if (mod == 3) 2725 if (mod == 3)
@@ -2739,7 +2748,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2739,7 +2748,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2739 /************************/ 2748 /************************/
2740 /* floats */ 2749 /* floats */
2741 case 0xd8 ... 0xdf: 2750 case 0xd8 ... 0xdf:
2742 - modrm = ldub(s->pc++); 2751 + modrm = ldub_code(s->pc++);
2743 mod = (modrm >> 6) & 3; 2752 mod = (modrm >> 6) & 3;
2744 rm = modrm & 7; 2753 rm = modrm & 7;
2745 op = ((b & 7) << 3) | ((modrm >> 3) & 7); 2754 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
@@ -3256,7 +3265,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3256,7 +3265,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3256 ot = OT_BYTE; 3265 ot = OT_BYTE;
3257 else 3266 else
3258 ot = dflag ? OT_LONG : OT_WORD; 3267 ot = dflag ? OT_LONG : OT_WORD;
3259 - val = ldub(s->pc++); 3268 + val = ldub_code(s->pc++);
3260 gen_op_movl_T0_im(val); 3269 gen_op_movl_T0_im(val);
3261 gen_op_in[ot](); 3270 gen_op_in[ot]();
3262 gen_op_mov_reg_T1[ot][R_EAX](); 3271 gen_op_mov_reg_T1[ot][R_EAX]();
@@ -3271,7 +3280,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3271,7 +3280,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3271 ot = OT_BYTE; 3280 ot = OT_BYTE;
3272 else 3281 else
3273 ot = dflag ? OT_LONG : OT_WORD; 3282 ot = dflag ? OT_LONG : OT_WORD;
3274 - val = ldub(s->pc++); 3283 + val = ldub_code(s->pc++);
3275 gen_op_movl_T0_im(val); 3284 gen_op_movl_T0_im(val);
3276 gen_op_mov_TN_reg[ot][1][R_EAX](); 3285 gen_op_mov_TN_reg[ot][1][R_EAX]();
3277 gen_op_out[ot](); 3286 gen_op_out[ot]();
@@ -3309,7 +3318,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3309,7 +3318,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3309 /************************/ 3318 /************************/
3310 /* control */ 3319 /* control */
3311 case 0xc2: /* ret im */ 3320 case 0xc2: /* ret im */
3312 - val = ldsw(s->pc); 3321 + val = ldsw_code(s->pc);
3313 s->pc += 2; 3322 s->pc += 2;
3314 gen_pop_T0(s); 3323 gen_pop_T0(s);
3315 gen_stack_update(s, val + (2 << s->dflag)); 3324 gen_stack_update(s, val + (2 << s->dflag));
@@ -3327,7 +3336,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3327,7 +3336,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3327 gen_eob(s); 3336 gen_eob(s);
3328 break; 3337 break;
3329 case 0xca: /* lret im */ 3338 case 0xca: /* lret im */
3330 - val = ldsw(s->pc); 3339 + val = ldsw_code(s->pc);
3331 s->pc += 2; 3340 s->pc += 2;
3332 do_lret: 3341 do_lret:
3333 if (s->pe && !s->vm86) { 3342 if (s->pe && !s->vm86) {
@@ -3443,13 +3452,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3443,13 +3452,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3443 break; 3452 break;
3444 3453
3445 case 0x190 ... 0x19f: /* setcc Gv */ 3454 case 0x190 ... 0x19f: /* setcc Gv */
3446 - modrm = ldub(s->pc++); 3455 + modrm = ldub_code(s->pc++);
3447 gen_setcc(s, b); 3456 gen_setcc(s, b);
3448 gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1); 3457 gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
3449 break; 3458 break;
3450 case 0x140 ... 0x14f: /* cmov Gv, Ev */ 3459 case 0x140 ... 0x14f: /* cmov Gv, Ev */
3451 ot = dflag ? OT_LONG : OT_WORD; 3460 ot = dflag ? OT_LONG : OT_WORD;
3452 - modrm = ldub(s->pc++); 3461 + modrm = ldub_code(s->pc++);
3453 reg = (modrm >> 3) & 7; 3462 reg = (modrm >> 3) & 7;
3454 mod = (modrm >> 6) & 3; 3463 mod = (modrm >> 6) & 3;
3455 gen_setcc(s, b); 3464 gen_setcc(s, b);
@@ -3542,7 +3551,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3542,7 +3551,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3542 /* bit operations */ 3551 /* bit operations */
3543 case 0x1ba: /* bt/bts/btr/btc Gv, im */ 3552 case 0x1ba: /* bt/bts/btr/btc Gv, im */
3544 ot = dflag ? OT_LONG : OT_WORD; 3553 ot = dflag ? OT_LONG : OT_WORD;
3545 - modrm = ldub(s->pc++); 3554 + modrm = ldub_code(s->pc++);
3546 op = (modrm >> 3) & 7; 3555 op = (modrm >> 3) & 7;
3547 mod = (modrm >> 6) & 3; 3556 mod = (modrm >> 6) & 3;
3548 rm = modrm & 7; 3557 rm = modrm & 7;
@@ -3553,7 +3562,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3553,7 +3562,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3553 gen_op_mov_TN_reg[ot][0][rm](); 3562 gen_op_mov_TN_reg[ot][0][rm]();
3554 } 3563 }
3555 /* load shift */ 3564 /* load shift */
3556 - val = ldub(s->pc++); 3565 + val = ldub_code(s->pc++);
3557 gen_op_movl_T1_im(val); 3566 gen_op_movl_T1_im(val);
3558 if (op < 4) 3567 if (op < 4)
3559 goto illegal_op; 3568 goto illegal_op;
@@ -3581,7 +3590,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3581,7 +3590,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3581 op = 3; 3590 op = 3;
3582 do_btx: 3591 do_btx:
3583 ot = dflag ? OT_LONG : OT_WORD; 3592 ot = dflag ? OT_LONG : OT_WORD;
3584 - modrm = ldub(s->pc++); 3593 + modrm = ldub_code(s->pc++);
3585 reg = (modrm >> 3) & 7; 3594 reg = (modrm >> 3) & 7;
3586 mod = (modrm >> 6) & 3; 3595 mod = (modrm >> 6) & 3;
3587 rm = modrm & 7; 3596 rm = modrm & 7;
@@ -3610,7 +3619,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3610,7 +3619,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3610 case 0x1bc: /* bsf */ 3619 case 0x1bc: /* bsf */
3611 case 0x1bd: /* bsr */ 3620 case 0x1bd: /* bsr */
3612 ot = dflag ? OT_LONG : OT_WORD; 3621 ot = dflag ? OT_LONG : OT_WORD;
3613 - modrm = ldub(s->pc++); 3622 + modrm = ldub_code(s->pc++);
3614 reg = (modrm >> 3) & 7; 3623 reg = (modrm >> 3) & 7;
3615 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); 3624 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3616 gen_op_bsx_T0_cc[ot - OT_WORD][b & 1](); 3625 gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
@@ -3646,12 +3655,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3646,12 +3655,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3646 s->cc_op = CC_OP_EFLAGS; 3655 s->cc_op = CC_OP_EFLAGS;
3647 break; 3656 break;
3648 case 0xd4: /* aam */ 3657 case 0xd4: /* aam */
3649 - val = ldub(s->pc++); 3658 + val = ldub_code(s->pc++);
3650 gen_op_aam(val); 3659 gen_op_aam(val);
3651 s->cc_op = CC_OP_LOGICB; 3660 s->cc_op = CC_OP_LOGICB;
3652 break; 3661 break;
3653 case 0xd5: /* aad */ 3662 case 0xd5: /* aad */
3654 - val = ldub(s->pc++); 3663 + val = ldub_code(s->pc++);
3655 gen_op_aad(val); 3664 gen_op_aad(val);
3656 s->cc_op = CC_OP_LOGICB; 3665 s->cc_op = CC_OP_LOGICB;
3657 break; 3666 break;
@@ -3665,7 +3674,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3665,7 +3674,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3665 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base); 3674 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
3666 break; 3675 break;
3667 case 0xcd: /* int N */ 3676 case 0xcd: /* int N */
3668 - val = ldub(s->pc++); 3677 + val = ldub_code(s->pc++);
3669 /* XXX: add error code for vm86 GPF */ 3678 /* XXX: add error code for vm86 GPF */
3670 if (!s->vm86) 3679 if (!s->vm86)
3671 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base); 3680 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
@@ -3718,7 +3727,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3718,7 +3727,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3718 break; 3727 break;
3719 case 0x62: /* bound */ 3728 case 0x62: /* bound */
3720 ot = dflag ? OT_LONG : OT_WORD; 3729 ot = dflag ? OT_LONG : OT_WORD;
3721 - modrm = ldub(s->pc++); 3730 + modrm = ldub_code(s->pc++);
3722 reg = (modrm >> 3) & 7; 3731 reg = (modrm >> 3) & 7;
3723 mod = (modrm >> 6) & 3; 3732 mod = (modrm >> 6) & 3;
3724 if (mod == 3) 3733 if (mod == 3)
@@ -3785,7 +3794,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3785,7 +3794,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3785 } 3794 }
3786 break; 3795 break;
3787 case 0x100: 3796 case 0x100:
3788 - modrm = ldub(s->pc++); 3797 + modrm = ldub_code(s->pc++);
3789 mod = (modrm >> 6) & 3; 3798 mod = (modrm >> 6) & 3;
3790 op = (modrm >> 3) & 7; 3799 op = (modrm >> 3) & 7;
3791 switch(op) { 3800 switch(op) {
@@ -3828,7 +3837,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3828,7 +3837,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3828 } 3837 }
3829 break; 3838 break;
3830 case 0x101: 3839 case 0x101:
3831 - modrm = ldub(s->pc++); 3840 + modrm = ldub_code(s->pc++);
3832 mod = (modrm >> 6) & 3; 3841 mod = (modrm >> 6) & 3;
3833 op = (modrm >> 3) & 7; 3842 op = (modrm >> 3) & 7;
3834 switch(op) { 3843 switch(op) {
@@ -3904,7 +3913,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3904,7 +3913,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3904 if (!s->pe || s->vm86) 3913 if (!s->pe || s->vm86)
3905 goto illegal_op; 3914 goto illegal_op;
3906 ot = dflag ? OT_LONG : OT_WORD; 3915 ot = dflag ? OT_LONG : OT_WORD;
3907 - modrm = ldub(s->pc++); 3916 + modrm = ldub_code(s->pc++);
3908 reg = (modrm >> 3) & 7; 3917 reg = (modrm >> 3) & 7;
3909 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); 3918 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3910 gen_op_mov_TN_reg[ot][1][reg](); 3919 gen_op_mov_TN_reg[ot][1][reg]();
@@ -3918,7 +3927,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3918,7 +3927,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3918 gen_op_mov_reg_T1[ot][reg](); 3927 gen_op_mov_reg_T1[ot][reg]();
3919 break; 3928 break;
3920 case 0x118: 3929 case 0x118:
3921 - modrm = ldub(s->pc++); 3930 + modrm = ldub_code(s->pc++);
3922 mod = (modrm >> 6) & 3; 3931 mod = (modrm >> 6) & 3;
3923 op = (modrm >> 3) & 7; 3932 op = (modrm >> 3) & 7;
3924 switch(op) { 3933 switch(op) {
@@ -3940,7 +3949,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3940,7 +3949,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3940 if (s->cpl != 0) { 3949 if (s->cpl != 0) {
3941 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 3950 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3942 } else { 3951 } else {
3943 - modrm = ldub(s->pc++); 3952 + modrm = ldub_code(s->pc++);
3944 if ((modrm & 0xc0) != 0xc0) 3953 if ((modrm & 0xc0) != 0xc0)
3945 goto illegal_op; 3954 goto illegal_op;
3946 rm = modrm & 7; 3955 rm = modrm & 7;
@@ -3970,7 +3979,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3970,7 +3979,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3970 if (s->cpl != 0) { 3979 if (s->cpl != 0) {
3971 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 3980 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3972 } else { 3981 } else {
3973 - modrm = ldub(s->pc++); 3982 + modrm = ldub_code(s->pc++);
3974 if ((modrm & 0xc0) != 0xc0) 3983 if ((modrm & 0xc0) != 0xc0)
3975 goto illegal_op; 3984 goto illegal_op;
3976 rm = modrm & 7; 3985 rm = modrm & 7;