From e4533c7a8cdcc79ccdf695f0aaa2e23a5b926ed0 Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 15 Jun 2003 19:51:39 +0000 Subject: [PATCH] main cpu loop is target independent git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@238 c046a42c-6fe2-441c-8c8c-71466251a162 --- exec-i386.c => cpu-exec.c | 119 ++++++++++++++++++++++++++++++-------- 1 file changed, 95 insertions(+), 24 deletions(-) rename exec-i386.c => cpu-exec.c (84%) diff --git a/exec-i386.c b/cpu-exec.c similarity index 84% rename from exec-i386.c rename to cpu-exec.c index c285eb4507..8d9ffa678d 100644 --- a/exec-i386.c +++ b/cpu-exec.c @@ -17,18 +17,33 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "config.h" +#ifdef TARGET_I386 #include "exec-i386.h" +#endif +#ifdef TARGET_ARM +#include "exec-arm.h" +#endif + #include "disas.h" //#define DEBUG_EXEC //#define DEBUG_SIGNAL +#if defined(TARGET_ARM) +/* XXX: unify with i386 target */ +void cpu_loop_exit(void) +{ + longjmp(env->jmp_env, 1); +} +#endif + /* main execution loop */ -int cpu_x86_exec(CPUX86State *env1) +int cpu_exec(CPUState *env1) { - int saved_T0, saved_T1, saved_A0; - CPUX86State *saved_env; + int saved_T0, saved_T1, saved_T2; + CPUState *saved_env; #ifdef reg_EAX int saved_EAX; #endif @@ -65,9 +80,15 @@ int cpu_x86_exec(CPUX86State *env1) /* first we save global registers */ saved_T0 = T0; saved_T1 = T1; - saved_A0 = A0; + saved_T2 = T2; saved_env = env; env = env1; +#ifdef __sparc__ + /* we also save i7 because longjmp may not restore it */ + asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); +#endif + +#if defined(TARGET_I386) #ifdef reg_EAX saved_EAX = EAX; EAX = env->regs[R_EAX]; @@ -100,16 +121,24 @@ int cpu_x86_exec(CPUX86State *env1) saved_EDI = EDI; EDI = env->regs[R_EDI]; #endif -#ifdef __sparc__ - /* we also save i7 because longjmp may not restore it */ - asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); -#endif /* put eflags in CPU temporary format */ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); DF = 1 - (2 * ((env->eflags >> 10) & 1)); CC_OP = CC_OP_EFLAGS; env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); +#elif defined(TARGET_ARM) + { + unsigned int psr; + psr = env->cpsr; + env->CF = (psr >> 29) & 1; + env->NZF = (psr & 0xc0000000) ^ 0x40000000; + env->VF = (psr << 3) & 0x80000000; + env->cpsr = psr & ~0xf0000000; + } +#else +#error unsupported target CPU +#endif env->interrupt_request = 0; /* prepare setjmp context for exception handling */ @@ -126,7 +155,7 @@ int cpu_x86_exec(CPUX86State *env1) } #ifdef DEBUG_EXEC if (loglevel) { - /* XXX: save all volatile state in cpu state */ +#if defined(TARGET_I386) /* restore flags in standard format */ env->regs[R_EAX] = EAX; env->regs[R_EBX] = EBX; @@ -139,10 +168,16 @@ int cpu_x86_exec(CPUX86State *env1) env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); cpu_x86_dump_state(env, logfile, 0); env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); +#elif defined(TARGET_ARM) + cpu_arm_dump_state(env, logfile, 0); +#else +#error unsupported target CPU +#endif } #endif /* we compute the CPU state. We assume it will not change during the whole generated block. */ +#if defined(TARGET_I386) flags = env->seg_cache[R_CS].seg_32bit << GEN_FLAG_CODE32_SHIFT; flags |= env->seg_cache[R_SS].seg_32bit << GEN_FLAG_SS32_SHIFT; flags |= (((unsigned long)env->seg_cache[R_DS].base | @@ -159,6 +194,13 @@ int cpu_x86_exec(CPUX86State *env1) flags |= (env->eflags & (IOPL_MASK | TF_MASK)); cs_base = env->seg_cache[R_CS].base; pc = cs_base + env->eip; +#elif defined(TARGET_ARM) + flags = 0; + cs_base = 0; + pc = (uint8_t *)env->regs[15]; +#else +#error unsupported CPU +#endif tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, flags); if (!tb) { @@ -178,7 +220,9 @@ int cpu_x86_exec(CPUX86State *env1) tb->tc_ptr = tc_ptr; tb->cs_base = (unsigned long)cs_base; tb->flags = flags; - ret = cpu_x86_gen_code(tb, CODE_GEN_MAX_SIZE, &code_gen_size); + ret = cpu_gen_code(tb, CODE_GEN_MAX_SIZE, &code_gen_size); +#if defined(TARGET_I386) + /* XXX: suppress that, this is incorrect */ /* if invalid instruction, signal it */ if (ret != 0) { /* NOTE: the tb is allocated but not linked, so we @@ -186,6 +230,7 @@ int cpu_x86_exec(CPUX86State *env1) spin_unlock(&tb_lock); raise_exception(EXCP06_ILLOP); } +#endif *ptb = tb; tb->hash_next = NULL; tb_link(tb); @@ -202,8 +247,12 @@ int cpu_x86_exec(CPUX86State *env1) #ifdef __sparc__ T0 = tmp_T0; #endif - /* see if we can patch the calling TB */ - if (T0 != 0 && !(env->eflags & TF_MASK)) { + /* see if we can patch the calling TB. XXX: remove TF test */ + if (T0 != 0 +#if defined(TARGET_I386) + && !(env->eflags & TF_MASK) +#endif + ) { spin_lock(&tb_lock); tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); spin_unlock(&tb_lock); @@ -232,6 +281,7 @@ int cpu_x86_exec(CPUX86State *env1) } ret = env->exception_index; +#if defined(TARGET_I386) /* restore flags in standard format */ env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); @@ -260,22 +310,34 @@ int cpu_x86_exec(CPUX86State *env1) #ifdef reg_EDI EDI = saved_EDI; #endif +#elif defined(TARGET_ARM) + { + int ZF; + ZF = (env->NZF == 0); + env->cpsr = env->cpsr | (env->NZF & 0x80000000) | (ZF << 30) | + (env->CF << 29) | ((env->VF & 0x80000000) >> 3); + } +#else +#error unsupported target CPU +#endif #ifdef __sparc__ asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); #endif T0 = saved_T0; T1 = saved_T1; - A0 = saved_A0; + T2 = saved_T2; env = saved_env; return ret; } -void cpu_x86_interrupt(CPUX86State *s) +void cpu_interrupt(CPUState *s) { s->interrupt_request = 1; } +#if defined(TARGET_I386) + void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) { CPUX86State *saved_env; @@ -322,6 +384,8 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32) env = saved_env; } +#endif /* TARGET_I386 */ + #undef EAX #undef ECX #undef EDX @@ -357,15 +421,22 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - ret = cpu_x86_search_pc(tb, &found_pc, pc); + ret = cpu_search_pc(tb, &found_pc, pc); if (ret < 0) return 0; +#if defined(TARGET_I386) env->eip = found_pc - tb->cs_base; env->cr2 = address; /* we restore the process signal mask as the sigreturn should do it (XXX: use sigsetjmp) */ sigprocmask(SIG_SETMASK, old_set, NULL); raise_exception_err(EXCP0E_PAGE, 4 | (is_write << 1)); +#elif defined(TARGET_ARM) + env->regs[15] = found_pc; + /* XXX: do more */ +#else +#error unsupported target CPU +#endif /* never comes here */ return 1; } else { @@ -375,8 +446,8 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, #if defined(__i386__) -int cpu_x86_signal_handler(int host_signum, struct siginfo *info, - void *puc) +int cpu_signal_handler(int host_signum, struct siginfo *info, + void *puc) { struct ucontext *uc = puc; unsigned long pc; @@ -396,8 +467,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, #elif defined(__powerpc) -int cpu_x86_signal_handler(int host_signum, struct siginfo *info, - void *puc) +int cpu_signal_handler(int host_signum, struct siginfo *info, + void *puc) { struct ucontext *uc = puc; struct pt_regs *regs = uc->uc_mcontext.regs; @@ -420,7 +491,7 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, #elif defined(__alpha__) -int cpu_x86_signal_handler(int host_signum, struct siginfo *info, +int cpu_signal_handler(int host_signum, struct siginfo *info, void *puc) { struct ucontext *uc = puc; @@ -449,8 +520,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, } #elif defined(__sparc__) -int cpu_x86_signal_handler(int host_signum, struct siginfo *info, - void *puc) +int cpu_signal_handler(int host_signum, struct siginfo *info, + void *puc) { uint32_t *regs = (uint32_t *)(info + 1); void *sigmask = (regs + 20); @@ -482,8 +553,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, #elif defined(__arm__) -int cpu_x86_signal_handler(int host_signum, struct siginfo *info, - void *puc) +int cpu_signal_handler(int host_signum, struct siginfo *info, + void *puc) { struct ucontext *uc = puc; unsigned long pc;