commit 59ca12838278bed97ce5cc311f90ddfec7953047 Author: Paolo Bonzini Date: Sat Feb 13 21:13:12 2010 +0100 make sparc workaround less ugly Not-quite-signed-off-by: Paolo Bonzini diff --git a/cpu-exec.c b/cpu-exec.c index badd5d7..01b7143 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -39,9 +39,14 @@ #endif #if defined(__sparc__) && !defined(CONFIG_SOLARIS) -// Work around ugly bugs in glibc that mangle global register contents -#undef env +/* glibc will mangle global register contents. To work around this, + * we avoid using the global register in this file, and place back + * cpu_single_env in AREG0 before giving control to target-* routines. + */ +#define export_env() asm ("mov %0, %%" AREG0 : : "r" (cpu_single_env) : AREG0); #define env cpu_single_env +#else +#define export_env() #endif int tb_invalidated_flag; @@ -257,11 +262,7 @@ int cpu_exec(CPUState *env1) /* prepare setjmp context for exception handling */ for(;;) { if (setjmp(env->jmp_env) == 0) { -#if defined(__sparc__) && !defined(CONFIG_SOLARIS) -#undef env - env = cpu_single_env; -#define env cpu_single_env -#endif + export_env(); /* if an exception is pending, we execute it here */ if (env->exception_index >= 0) { if (env->exception_index >= EXCP_INTERRUPT) { @@ -387,11 +388,7 @@ int cpu_exec(CPUState *env1) env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); intno = cpu_get_pic_interrupt(env); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno); -#if defined(__sparc__) && !defined(CONFIG_SOLARIS) -#undef env - env = cpu_single_env; -#define env cpu_single_env -#endif + export_env(); do_interrupt(intno, 0, 0, 0, 1); /* ensure that no TB jump will be modified as the program flow was changed */ @@ -603,12 +600,8 @@ int cpu_exec(CPUState *env1) if (!unlikely (env->exit_request)) { env->current_tb = tb; tc_ptr = tb->tc_ptr; - /* execute the generated code */ -#if defined(__sparc__) && !defined(CONFIG_SOLARIS) -#undef env - env = cpu_single_env; -#define env cpu_single_env -#endif + /* execute the generated code */ + export_env(); next_tb = tcg_qemu_tb_exec(tc_ptr); env->current_tb = NULL; if ((next_tb & 3) == 2) {