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 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;
... ...