Commit e4533c7a8cdcc79ccdf695f0aaa2e23a5b926ed0
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 | 17 | * License along with this library; if not, write to the Free Software |
18 | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | 19 | */ |
20 | +#include "config.h" | |
21 | +#ifdef TARGET_I386 | |
20 | 22 | #include "exec-i386.h" |
23 | +#endif | |
24 | +#ifdef TARGET_ARM | |
25 | +#include "exec-arm.h" | |
26 | +#endif | |
27 | + | |
21 | 28 | #include "disas.h" |
22 | 29 | |
23 | 30 | //#define DEBUG_EXEC |
24 | 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 | 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 | 47 | #ifdef reg_EAX |
33 | 48 | int saved_EAX; |
34 | 49 | #endif |
... | ... | @@ -65,9 +80,15 @@ int cpu_x86_exec(CPUX86State *env1) |
65 | 80 | /* first we save global registers */ |
66 | 81 | saved_T0 = T0; |
67 | 82 | saved_T1 = T1; |
68 | - saved_A0 = A0; | |
83 | + saved_T2 = T2; | |
69 | 84 | saved_env = env; |
70 | 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 | 92 | #ifdef reg_EAX |
72 | 93 | saved_EAX = EAX; |
73 | 94 | EAX = env->regs[R_EAX]; |
... | ... | @@ -100,16 +121,24 @@ int cpu_x86_exec(CPUX86State *env1) |
100 | 121 | saved_EDI = EDI; |
101 | 122 | EDI = env->regs[R_EDI]; |
102 | 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 | 125 | /* put eflags in CPU temporary format */ |
109 | 126 | CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); |
110 | 127 | DF = 1 - (2 * ((env->eflags >> 10) & 1)); |
111 | 128 | CC_OP = CC_OP_EFLAGS; |
112 | 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 | 142 | env->interrupt_request = 0; |
114 | 143 | |
115 | 144 | /* prepare setjmp context for exception handling */ |
... | ... | @@ -126,7 +155,7 @@ int cpu_x86_exec(CPUX86State *env1) |
126 | 155 | } |
127 | 156 | #ifdef DEBUG_EXEC |
128 | 157 | if (loglevel) { |
129 | - /* XXX: save all volatile state in cpu state */ | |
158 | +#if defined(TARGET_I386) | |
130 | 159 | /* restore flags in standard format */ |
131 | 160 | env->regs[R_EAX] = EAX; |
132 | 161 | env->regs[R_EBX] = EBX; |
... | ... | @@ -139,10 +168,16 @@ int cpu_x86_exec(CPUX86State *env1) |
139 | 168 | env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); |
140 | 169 | cpu_x86_dump_state(env, logfile, 0); |
141 | 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 | 177 | #endif |
144 | 178 | /* we compute the CPU state. We assume it will not |
145 | 179 | change during the whole generated block. */ |
180 | +#if defined(TARGET_I386) | |
146 | 181 | flags = env->seg_cache[R_CS].seg_32bit << GEN_FLAG_CODE32_SHIFT; |
147 | 182 | flags |= env->seg_cache[R_SS].seg_32bit << GEN_FLAG_SS32_SHIFT; |
148 | 183 | flags |= (((unsigned long)env->seg_cache[R_DS].base | |
... | ... | @@ -159,6 +194,13 @@ int cpu_x86_exec(CPUX86State *env1) |
159 | 194 | flags |= (env->eflags & (IOPL_MASK | TF_MASK)); |
160 | 195 | cs_base = env->seg_cache[R_CS].base; |
161 | 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 | 204 | tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, |
163 | 205 | flags); |
164 | 206 | if (!tb) { |
... | ... | @@ -178,7 +220,9 @@ int cpu_x86_exec(CPUX86State *env1) |
178 | 220 | tb->tc_ptr = tc_ptr; |
179 | 221 | tb->cs_base = (unsigned long)cs_base; |
180 | 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 | 226 | /* if invalid instruction, signal it */ |
183 | 227 | if (ret != 0) { |
184 | 228 | /* NOTE: the tb is allocated but not linked, so we |
... | ... | @@ -186,6 +230,7 @@ int cpu_x86_exec(CPUX86State *env1) |
186 | 230 | spin_unlock(&tb_lock); |
187 | 231 | raise_exception(EXCP06_ILLOP); |
188 | 232 | } |
233 | +#endif | |
189 | 234 | *ptb = tb; |
190 | 235 | tb->hash_next = NULL; |
191 | 236 | tb_link(tb); |
... | ... | @@ -202,8 +247,12 @@ int cpu_x86_exec(CPUX86State *env1) |
202 | 247 | #ifdef __sparc__ |
203 | 248 | T0 = tmp_T0; |
204 | 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 | 256 | spin_lock(&tb_lock); |
208 | 257 | tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); |
209 | 258 | spin_unlock(&tb_lock); |
... | ... | @@ -232,6 +281,7 @@ int cpu_x86_exec(CPUX86State *env1) |
232 | 281 | } |
233 | 282 | ret = env->exception_index; |
234 | 283 | |
284 | +#if defined(TARGET_I386) | |
235 | 285 | /* restore flags in standard format */ |
236 | 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 | 310 | #ifdef reg_EDI |
261 | 311 | EDI = saved_EDI; |
262 | 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 | 323 | #ifdef __sparc__ |
264 | 324 | asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); |
265 | 325 | #endif |
266 | 326 | T0 = saved_T0; |
267 | 327 | T1 = saved_T1; |
268 | - A0 = saved_A0; | |
328 | + T2 = saved_T2; | |
269 | 329 | env = saved_env; |
270 | 330 | return ret; |
271 | 331 | } |
272 | 332 | |
273 | -void cpu_x86_interrupt(CPUX86State *s) | |
333 | +void cpu_interrupt(CPUState *s) | |
274 | 334 | { |
275 | 335 | s->interrupt_request = 1; |
276 | 336 | } |
277 | 337 | |
278 | 338 | |
339 | +#if defined(TARGET_I386) | |
340 | + | |
279 | 341 | void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) |
280 | 342 | { |
281 | 343 | CPUX86State *saved_env; |
... | ... | @@ -322,6 +384,8 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32) |
322 | 384 | env = saved_env; |
323 | 385 | } |
324 | 386 | |
387 | +#endif /* TARGET_I386 */ | |
388 | + | |
325 | 389 | #undef EAX |
326 | 390 | #undef ECX |
327 | 391 | #undef EDX |
... | ... | @@ -357,15 +421,22 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, |
357 | 421 | if (tb) { |
358 | 422 | /* the PC is inside the translated code. It means that we have |
359 | 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 | 425 | if (ret < 0) |
362 | 426 | return 0; |
427 | +#if defined(TARGET_I386) | |
363 | 428 | env->eip = found_pc - tb->cs_base; |
364 | 429 | env->cr2 = address; |
365 | 430 | /* we restore the process signal mask as the sigreturn should |
366 | 431 | do it (XXX: use sigsetjmp) */ |
367 | 432 | sigprocmask(SIG_SETMASK, old_set, NULL); |
368 | 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 | 440 | /* never comes here */ |
370 | 441 | return 1; |
371 | 442 | } else { |
... | ... | @@ -375,8 +446,8 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, |
375 | 446 | |
376 | 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 | 452 | struct ucontext *uc = puc; |
382 | 453 | unsigned long pc; |
... | ... | @@ -396,8 +467,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
396 | 467 | |
397 | 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 | 473 | struct ucontext *uc = puc; |
403 | 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 | 491 | |
421 | 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 | 495 | void *puc) |
425 | 496 | { |
426 | 497 | struct ucontext *uc = puc; |
... | ... | @@ -449,8 +520,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
449 | 520 | } |
450 | 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 | 526 | uint32_t *regs = (uint32_t *)(info + 1); |
456 | 527 | void *sigmask = (regs + 20); |
... | ... | @@ -482,8 +553,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
482 | 553 | |
483 | 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 | 559 | struct ucontext *uc = puc; |
489 | 560 | unsigned long pc; | ... | ... |