Commit e4533c7a8cdcc79ccdf695f0aaa2e23a5b926ed0

Authored by bellard
1 parent 1e5ffbed

main cpu loop is target independent


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@238 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 95 additions and 24 deletions
exec-i386.c renamed to cpu-exec.c
@@ -17,18 +17,33 @@ @@ -17,18 +17,33 @@
17 * License along with this library; if not, write to the Free Software 17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
  20 +#include "config.h"
  21 +#ifdef TARGET_I386
20 #include "exec-i386.h" 22 #include "exec-i386.h"
  23 +#endif
  24 +#ifdef TARGET_ARM
  25 +#include "exec-arm.h"
  26 +#endif
  27 +
21 #include "disas.h" 28 #include "disas.h"
22 29
23 //#define DEBUG_EXEC 30 //#define DEBUG_EXEC
24 //#define DEBUG_SIGNAL 31 //#define DEBUG_SIGNAL
25 32
  33 +#if defined(TARGET_ARM)
  34 +/* XXX: unify with i386 target */
  35 +void cpu_loop_exit(void)
  36 +{
  37 + longjmp(env->jmp_env, 1);
  38 +}
  39 +#endif
  40 +
26 /* main execution loop */ 41 /* main execution loop */
27 42
28 -int cpu_x86_exec(CPUX86State *env1) 43 +int cpu_exec(CPUState *env1)
29 { 44 {
30 - int saved_T0, saved_T1, saved_A0;  
31 - CPUX86State *saved_env; 45 + int saved_T0, saved_T1, saved_T2;
  46 + CPUState *saved_env;
32 #ifdef reg_EAX 47 #ifdef reg_EAX
33 int saved_EAX; 48 int saved_EAX;
34 #endif 49 #endif
@@ -65,9 +80,15 @@ int cpu_x86_exec(CPUX86State *env1) @@ -65,9 +80,15 @@ int cpu_x86_exec(CPUX86State *env1)
65 /* first we save global registers */ 80 /* first we save global registers */
66 saved_T0 = T0; 81 saved_T0 = T0;
67 saved_T1 = T1; 82 saved_T1 = T1;
68 - saved_A0 = A0; 83 + saved_T2 = T2;
69 saved_env = env; 84 saved_env = env;
70 env = env1; 85 env = env1;
  86 +#ifdef __sparc__
  87 + /* we also save i7 because longjmp may not restore it */
  88 + asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
  89 +#endif
  90 +
  91 +#if defined(TARGET_I386)
71 #ifdef reg_EAX 92 #ifdef reg_EAX
72 saved_EAX = EAX; 93 saved_EAX = EAX;
73 EAX = env->regs[R_EAX]; 94 EAX = env->regs[R_EAX];
@@ -100,16 +121,24 @@ int cpu_x86_exec(CPUX86State *env1) @@ -100,16 +121,24 @@ int cpu_x86_exec(CPUX86State *env1)
100 saved_EDI = EDI; 121 saved_EDI = EDI;
101 EDI = env->regs[R_EDI]; 122 EDI = env->regs[R_EDI];
102 #endif 123 #endif
103 -#ifdef __sparc__  
104 - /* we also save i7 because longjmp may not restore it */  
105 - asm volatile ("mov %%i7, %0" : "=r" (saved_i7));  
106 -#endif  
107 124
108 /* put eflags in CPU temporary format */ 125 /* put eflags in CPU temporary format */
109 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); 126 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
110 DF = 1 - (2 * ((env->eflags >> 10) & 1)); 127 DF = 1 - (2 * ((env->eflags >> 10) & 1));
111 CC_OP = CC_OP_EFLAGS; 128 CC_OP = CC_OP_EFLAGS;
112 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); 129 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
  130 +#elif defined(TARGET_ARM)
  131 + {
  132 + unsigned int psr;
  133 + psr = env->cpsr;
  134 + env->CF = (psr >> 29) & 1;
  135 + env->NZF = (psr & 0xc0000000) ^ 0x40000000;
  136 + env->VF = (psr << 3) & 0x80000000;
  137 + env->cpsr = psr & ~0xf0000000;
  138 + }
  139 +#else
  140 +#error unsupported target CPU
  141 +#endif
113 env->interrupt_request = 0; 142 env->interrupt_request = 0;
114 143
115 /* prepare setjmp context for exception handling */ 144 /* prepare setjmp context for exception handling */
@@ -126,7 +155,7 @@ int cpu_x86_exec(CPUX86State *env1) @@ -126,7 +155,7 @@ int cpu_x86_exec(CPUX86State *env1)
126 } 155 }
127 #ifdef DEBUG_EXEC 156 #ifdef DEBUG_EXEC
128 if (loglevel) { 157 if (loglevel) {
129 - /* XXX: save all volatile state in cpu state */ 158 +#if defined(TARGET_I386)
130 /* restore flags in standard format */ 159 /* restore flags in standard format */
131 env->regs[R_EAX] = EAX; 160 env->regs[R_EAX] = EAX;
132 env->regs[R_EBX] = EBX; 161 env->regs[R_EBX] = EBX;
@@ -139,10 +168,16 @@ int cpu_x86_exec(CPUX86State *env1) @@ -139,10 +168,16 @@ int cpu_x86_exec(CPUX86State *env1)
139 env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); 168 env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
140 cpu_x86_dump_state(env, logfile, 0); 169 cpu_x86_dump_state(env, logfile, 0);
141 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); 170 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
  171 +#elif defined(TARGET_ARM)
  172 + cpu_arm_dump_state(env, logfile, 0);
  173 +#else
  174 +#error unsupported target CPU
  175 +#endif
142 } 176 }
143 #endif 177 #endif
144 /* we compute the CPU state. We assume it will not 178 /* we compute the CPU state. We assume it will not
145 change during the whole generated block. */ 179 change during the whole generated block. */
  180 +#if defined(TARGET_I386)
146 flags = env->seg_cache[R_CS].seg_32bit << GEN_FLAG_CODE32_SHIFT; 181 flags = env->seg_cache[R_CS].seg_32bit << GEN_FLAG_CODE32_SHIFT;
147 flags |= env->seg_cache[R_SS].seg_32bit << GEN_FLAG_SS32_SHIFT; 182 flags |= env->seg_cache[R_SS].seg_32bit << GEN_FLAG_SS32_SHIFT;
148 flags |= (((unsigned long)env->seg_cache[R_DS].base | 183 flags |= (((unsigned long)env->seg_cache[R_DS].base |
@@ -159,6 +194,13 @@ int cpu_x86_exec(CPUX86State *env1) @@ -159,6 +194,13 @@ int cpu_x86_exec(CPUX86State *env1)
159 flags |= (env->eflags & (IOPL_MASK | TF_MASK)); 194 flags |= (env->eflags & (IOPL_MASK | TF_MASK));
160 cs_base = env->seg_cache[R_CS].base; 195 cs_base = env->seg_cache[R_CS].base;
161 pc = cs_base + env->eip; 196 pc = cs_base + env->eip;
  197 +#elif defined(TARGET_ARM)
  198 + flags = 0;
  199 + cs_base = 0;
  200 + pc = (uint8_t *)env->regs[15];
  201 +#else
  202 +#error unsupported CPU
  203 +#endif
162 tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, 204 tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base,
163 flags); 205 flags);
164 if (!tb) { 206 if (!tb) {
@@ -178,7 +220,9 @@ int cpu_x86_exec(CPUX86State *env1) @@ -178,7 +220,9 @@ int cpu_x86_exec(CPUX86State *env1)
178 tb->tc_ptr = tc_ptr; 220 tb->tc_ptr = tc_ptr;
179 tb->cs_base = (unsigned long)cs_base; 221 tb->cs_base = (unsigned long)cs_base;
180 tb->flags = flags; 222 tb->flags = flags;
181 - ret = cpu_x86_gen_code(tb, CODE_GEN_MAX_SIZE, &code_gen_size); 223 + ret = cpu_gen_code(tb, CODE_GEN_MAX_SIZE, &code_gen_size);
  224 +#if defined(TARGET_I386)
  225 + /* XXX: suppress that, this is incorrect */
182 /* if invalid instruction, signal it */ 226 /* if invalid instruction, signal it */
183 if (ret != 0) { 227 if (ret != 0) {
184 /* NOTE: the tb is allocated but not linked, so we 228 /* NOTE: the tb is allocated but not linked, so we
@@ -186,6 +230,7 @@ int cpu_x86_exec(CPUX86State *env1) @@ -186,6 +230,7 @@ int cpu_x86_exec(CPUX86State *env1)
186 spin_unlock(&tb_lock); 230 spin_unlock(&tb_lock);
187 raise_exception(EXCP06_ILLOP); 231 raise_exception(EXCP06_ILLOP);
188 } 232 }
  233 +#endif
189 *ptb = tb; 234 *ptb = tb;
190 tb->hash_next = NULL; 235 tb->hash_next = NULL;
191 tb_link(tb); 236 tb_link(tb);
@@ -202,8 +247,12 @@ int cpu_x86_exec(CPUX86State *env1) @@ -202,8 +247,12 @@ int cpu_x86_exec(CPUX86State *env1)
202 #ifdef __sparc__ 247 #ifdef __sparc__
203 T0 = tmp_T0; 248 T0 = tmp_T0;
204 #endif 249 #endif
205 - /* see if we can patch the calling TB */  
206 - if (T0 != 0 && !(env->eflags & TF_MASK)) { 250 + /* see if we can patch the calling TB. XXX: remove TF test */
  251 + if (T0 != 0
  252 +#if defined(TARGET_I386)
  253 + && !(env->eflags & TF_MASK)
  254 +#endif
  255 + ) {
207 spin_lock(&tb_lock); 256 spin_lock(&tb_lock);
208 tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); 257 tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb);
209 spin_unlock(&tb_lock); 258 spin_unlock(&tb_lock);
@@ -232,6 +281,7 @@ int cpu_x86_exec(CPUX86State *env1) @@ -232,6 +281,7 @@ int cpu_x86_exec(CPUX86State *env1)
232 } 281 }
233 ret = env->exception_index; 282 ret = env->exception_index;
234 283
  284 +#if defined(TARGET_I386)
235 /* restore flags in standard format */ 285 /* restore flags in standard format */
236 env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); 286 env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
237 287
@@ -260,22 +310,34 @@ int cpu_x86_exec(CPUX86State *env1) @@ -260,22 +310,34 @@ int cpu_x86_exec(CPUX86State *env1)
260 #ifdef reg_EDI 310 #ifdef reg_EDI
261 EDI = saved_EDI; 311 EDI = saved_EDI;
262 #endif 312 #endif
  313 +#elif defined(TARGET_ARM)
  314 + {
  315 + int ZF;
  316 + ZF = (env->NZF == 0);
  317 + env->cpsr = env->cpsr | (env->NZF & 0x80000000) | (ZF << 30) |
  318 + (env->CF << 29) | ((env->VF & 0x80000000) >> 3);
  319 + }
  320 +#else
  321 +#error unsupported target CPU
  322 +#endif
263 #ifdef __sparc__ 323 #ifdef __sparc__
264 asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); 324 asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
265 #endif 325 #endif
266 T0 = saved_T0; 326 T0 = saved_T0;
267 T1 = saved_T1; 327 T1 = saved_T1;
268 - A0 = saved_A0; 328 + T2 = saved_T2;
269 env = saved_env; 329 env = saved_env;
270 return ret; 330 return ret;
271 } 331 }
272 332
273 -void cpu_x86_interrupt(CPUX86State *s) 333 +void cpu_interrupt(CPUState *s)
274 { 334 {
275 s->interrupt_request = 1; 335 s->interrupt_request = 1;
276 } 336 }
277 337
278 338
  339 +#if defined(TARGET_I386)
  340 +
279 void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) 341 void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
280 { 342 {
281 CPUX86State *saved_env; 343 CPUX86State *saved_env;
@@ -322,6 +384,8 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32) @@ -322,6 +384,8 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32)
322 env = saved_env; 384 env = saved_env;
323 } 385 }
324 386
  387 +#endif /* TARGET_I386 */
  388 +
325 #undef EAX 389 #undef EAX
326 #undef ECX 390 #undef ECX
327 #undef EDX 391 #undef EDX
@@ -357,15 +421,22 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -357,15 +421,22 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
357 if (tb) { 421 if (tb) {
358 /* the PC is inside the translated code. It means that we have 422 /* the PC is inside the translated code. It means that we have
359 a virtual CPU fault */ 423 a virtual CPU fault */
360 - ret = cpu_x86_search_pc(tb, &found_pc, pc); 424 + ret = cpu_search_pc(tb, &found_pc, pc);
361 if (ret < 0) 425 if (ret < 0)
362 return 0; 426 return 0;
  427 +#if defined(TARGET_I386)
363 env->eip = found_pc - tb->cs_base; 428 env->eip = found_pc - tb->cs_base;
364 env->cr2 = address; 429 env->cr2 = address;
365 /* we restore the process signal mask as the sigreturn should 430 /* we restore the process signal mask as the sigreturn should
366 do it (XXX: use sigsetjmp) */ 431 do it (XXX: use sigsetjmp) */
367 sigprocmask(SIG_SETMASK, old_set, NULL); 432 sigprocmask(SIG_SETMASK, old_set, NULL);
368 raise_exception_err(EXCP0E_PAGE, 4 | (is_write << 1)); 433 raise_exception_err(EXCP0E_PAGE, 4 | (is_write << 1));
  434 +#elif defined(TARGET_ARM)
  435 + env->regs[15] = found_pc;
  436 + /* XXX: do more */
  437 +#else
  438 +#error unsupported target CPU
  439 +#endif
369 /* never comes here */ 440 /* never comes here */
370 return 1; 441 return 1;
371 } else { 442 } else {
@@ -375,8 +446,8 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -375,8 +446,8 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
375 446
376 #if defined(__i386__) 447 #if defined(__i386__)
377 448
378 -int cpu_x86_signal_handler(int host_signum, struct siginfo *info,  
379 - void *puc) 449 +int cpu_signal_handler(int host_signum, struct siginfo *info,
  450 + void *puc)
380 { 451 {
381 struct ucontext *uc = puc; 452 struct ucontext *uc = puc;
382 unsigned long pc; 453 unsigned long pc;
@@ -396,8 +467,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, @@ -396,8 +467,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
396 467
397 #elif defined(__powerpc) 468 #elif defined(__powerpc)
398 469
399 -int cpu_x86_signal_handler(int host_signum, struct siginfo *info,  
400 - void *puc) 470 +int cpu_signal_handler(int host_signum, struct siginfo *info,
  471 + void *puc)
401 { 472 {
402 struct ucontext *uc = puc; 473 struct ucontext *uc = puc;
403 struct pt_regs *regs = uc->uc_mcontext.regs; 474 struct pt_regs *regs = uc->uc_mcontext.regs;
@@ -420,7 +491,7 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, @@ -420,7 +491,7 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
420 491
421 #elif defined(__alpha__) 492 #elif defined(__alpha__)
422 493
423 -int cpu_x86_signal_handler(int host_signum, struct siginfo *info, 494 +int cpu_signal_handler(int host_signum, struct siginfo *info,
424 void *puc) 495 void *puc)
425 { 496 {
426 struct ucontext *uc = puc; 497 struct ucontext *uc = puc;
@@ -449,8 +520,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, @@ -449,8 +520,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
449 } 520 }
450 #elif defined(__sparc__) 521 #elif defined(__sparc__)
451 522
452 -int cpu_x86_signal_handler(int host_signum, struct siginfo *info,  
453 - void *puc) 523 +int cpu_signal_handler(int host_signum, struct siginfo *info,
  524 + void *puc)
454 { 525 {
455 uint32_t *regs = (uint32_t *)(info + 1); 526 uint32_t *regs = (uint32_t *)(info + 1);
456 void *sigmask = (regs + 20); 527 void *sigmask = (regs + 20);
@@ -482,8 +553,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, @@ -482,8 +553,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
482 553
483 #elif defined(__arm__) 554 #elif defined(__arm__)
484 555
485 -int cpu_x86_signal_handler(int host_signum, struct siginfo *info,  
486 - void *puc) 556 +int cpu_signal_handler(int host_signum, struct siginfo *info,
  557 + void *puc)
487 { 558 {
488 struct ucontext *uc = puc; 559 struct ucontext *uc = puc;
489 unsigned long pc; 560 unsigned long pc;