diff options
-rw-r--r-- | Makefile.target | 2 | ||||
-rw-r--r-- | cpu-exec.c | 74 | ||||
-rw-r--r-- | tcg/arm/tcg-target.c | 17 | ||||
-rw-r--r-- | tcg/hppa/tcg-target.c | 6 | ||||
-rw-r--r-- | tcg/i386/tcg-target.c | 8 | ||||
-rw-r--r-- | tcg/ia64/tcg-target.c | 5 | ||||
-rw-r--r-- | tcg/mips/tcg-target.c | 8 | ||||
-rw-r--r-- | tcg/ppc/tcg-target.c | 6 | ||||
-rw-r--r-- | tcg/ppc64/tcg-target.c | 6 | ||||
-rw-r--r-- | tcg/s390/tcg-target.c | 5 | ||||
-rw-r--r-- | tcg/sparc/tcg-target.c | 4 | ||||
-rw-r--r-- | tcg/tcg.h | 7 |
12 files changed, 61 insertions, 87 deletions
diff --git a/Makefile.target b/Makefile.target index d3971a6d8..38afdb8e9 100644 --- a/Makefile.target +++ b/Makefile.target @@ -94,7 +94,7 @@ tcg/tcg.o: cpu.h # HELPER_CFLAGS is used for all the code compiled with static register # variables -%_helper.o cpu-exec.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS) +%_helper.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS) # Note: this is a workaround. The real fix is to avoid compiling # cpu_signal_handler() in user-exec.c. diff --git a/cpu-exec.c b/cpu-exec.c index 49de9e0ad..20e3ec41d 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -17,17 +17,11 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "config.h" -#include "exec.h" +#include "cpu.h" #include "disas.h" #include "tcg.h" #include "qemu-barrier.h" -#if defined(__sparc__) && !defined(CONFIG_SOLARIS) -// Work around ugly bugs in glibc that mangle global register contents -#undef env -#define env cpu_single_env -#endif - int tb_invalidated_flag; //#define CONFIG_DEBUG_EXEC @@ -37,20 +31,18 @@ bool qemu_cpu_has_work(CPUState *env) return cpu_has_work(env); } -void cpu_loop_exit(CPUState *env1) +void cpu_loop_exit(CPUState *env) { - env1->current_tb = NULL; - longjmp(env1->jmp_env, 1); + env->current_tb = NULL; + longjmp(env->jmp_env, 1); } /* exit the current TB from a signal handler. The host registers are restored in a state compatible with the CPU emulator */ #if defined(CONFIG_SOFTMMU) -void cpu_resume_from_signal(CPUState *env1, void *puc) +void cpu_resume_from_signal(CPUState *env, void *puc) { - env = env1; - /* XXX: restore cpu registers saved in host registers */ env->exception_index = -1; @@ -60,7 +52,8 @@ void cpu_resume_from_signal(CPUState *env1, void *puc) /* Execute the code without caching the generated code. An interpreter could be used if available. */ -static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb) +static void cpu_exec_nocache(CPUState *env, int max_cycles, + TranslationBlock *orig_tb) { unsigned long next_tb; TranslationBlock *tb; @@ -74,7 +67,7 @@ static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb) max_cycles); env->current_tb = tb; /* execute the generated code */ - next_tb = tcg_qemu_tb_exec(tb->tc_ptr); + next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr); env->current_tb = NULL; if ((next_tb & 3) == 2) { @@ -86,7 +79,8 @@ static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb) tb_free(tb); } -static TranslationBlock *tb_find_slow(target_ulong pc, +static TranslationBlock *tb_find_slow(CPUState *env, + target_ulong pc, target_ulong cs_base, uint64_t flags) { @@ -140,7 +134,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc, return tb; } -static inline TranslationBlock *tb_find_fast(void) +static inline TranslationBlock *tb_find_fast(CPUState *env) { TranslationBlock *tb; target_ulong cs_base, pc; @@ -153,7 +147,7 @@ static inline TranslationBlock *tb_find_fast(void) tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base || tb->flags != flags)) { - tb = tb_find_slow(pc, cs_base, flags); + tb = tb_find_slow(env, pc, cs_base, flags); } return tb; } @@ -186,31 +180,22 @@ static void cpu_handle_debug_exception(CPUState *env) volatile sig_atomic_t exit_request; -int cpu_exec(CPUState *env1) +int cpu_exec(CPUState *env) { - volatile host_reg_t saved_env_reg; int ret, interrupt_request; TranslationBlock *tb; uint8_t *tc_ptr; unsigned long next_tb; - if (env1->halted) { - if (!cpu_has_work(env1)) { + if (env->halted) { + if (!cpu_has_work(env)) { return EXCP_HALTED; } - env1->halted = 0; + env->halted = 0; } - cpu_single_env = env1; - - /* the access to env below is actually saving the global register's - value, so that files not including target-xyz/exec.h are free to - use it. */ - QEMU_BUILD_BUG_ON (sizeof (saved_env_reg) != sizeof (env)); - saved_env_reg = (host_reg_t) env; - barrier(); - env = env1; + cpu_single_env = env; if (unlikely(exit_request)) { env->exit_request = 1; @@ -246,11 +231,6 @@ 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 /* if an exception is pending, we execute it here */ if (env->exception_index >= 0) { if (env->exception_index >= EXCP_INTERRUPT) { @@ -336,11 +316,6 @@ 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 do_interrupt_x86_hardirq(env, intno, 1); /* ensure that no TB jump will be modified as the program flow was changed */ @@ -547,7 +522,7 @@ int cpu_exec(CPUState *env1) } #endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */ spin_lock(&tb_lock); - tb = tb_find_fast(); + tb = tb_find_fast(env); /* Note: we do it here to avoid a gcc bug on Mac OS X when doing it in tb_find_slow */ if (tb_invalidated_flag) { @@ -579,12 +554,7 @@ int cpu_exec(CPUState *env1) if (likely(!env->exit_request)) { 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 - next_tb = tcg_qemu_tb_exec(tc_ptr); + next_tb = tcg_qemu_tb_exec(env, tc_ptr); if ((next_tb & 3) == 2) { /* Instruction counter expired. */ int insns_left; @@ -605,7 +575,7 @@ int cpu_exec(CPUState *env1) } else { if (insns_left > 0) { /* Execute remaining instructions. */ - cpu_exec_nocache(insns_left, tb); + cpu_exec_nocache(env, insns_left, tb); } env->exception_index = EXCP_INTERRUPT; next_tb = 0; @@ -647,10 +617,6 @@ int cpu_exec(CPUState *env1) #error unsupported target CPU #endif - /* restore global registers */ - barrier(); - env = (void *) saved_env_reg; - /* fail safe : never use cpu_single_env outside cpu_exec() */ cpu_single_env = NULL; return ret; diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index fb858d863..457ad7edf 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -1846,15 +1846,18 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type, static void tcg_target_qemu_prologue(TCGContext *s) { - /* There is no need to save r7, it is used to store the address - of the env structure and is not modified by GCC. */ + /* Calling convention requires us to save r4-r11 and lr; + * save also r12 to maintain stack 8-alignment. + */ + + /* stmdb sp!, { r4 - r12, lr } */ + tcg_out32(s, (COND_AL << 28) | 0x092d5ff0); - /* stmdb sp!, { r4 - r6, r8 - r11, lr } */ - tcg_out32(s, (COND_AL << 28) | 0x092d4f70); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); - tcg_out_bx(s, COND_AL, TCG_REG_R0); + tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]); tb_ret_addr = s->code_ptr; - /* ldmia sp!, { r4 - r6, r8 - r11, pc } */ - tcg_out32(s, (COND_AL << 28) | 0x08bd8f70); + /* ldmia sp!, { r4 - r12, pc } */ + tcg_out32(s, (COND_AL << 28) | 0x08bd9ff0); } diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c index 7f4653e34..7248520ca 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c @@ -1596,7 +1596,7 @@ static int tcg_target_callee_save_regs[] = { TCG_REG_R14, TCG_REG_R15, TCG_REG_R16, - /* R17 is the global env, so no need to save. */ + TCG_REG_R17, /* R17 is the global env. */ TCG_REG_R18 }; @@ -1635,8 +1635,10 @@ static void tcg_target_qemu_prologue(TCGContext *s) } #endif + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + /* Jump to TB, and adjust R18 to be the return address. */ - tcg_out32(s, INSN_BLE_SR4 | INSN_R2(TCG_REG_R26)); + tcg_out32(s, INSN_BLE_SR4 | INSN_R2(tcg_target_call_iarg_regs[1])); tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R18, TCG_REG_R31); /* Restore callee saved registers. */ diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index bb19a950b..72b3a48f1 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1901,10 +1901,10 @@ static int tcg_target_callee_save_regs[] = { TCG_REG_RBX, TCG_REG_R12, TCG_REG_R13, - /* TCG_REG_R14, */ /* Currently used for the global env. */ + TCG_REG_R14, /* Currently used for the global env. */ TCG_REG_R15, #else - /* TCG_REG_EBP, */ /* Currently used for the global env. */ + TCG_REG_EBP, /* Currently used for the global env. */ TCG_REG_EBX, TCG_REG_ESI, TCG_REG_EDI, @@ -1933,8 +1933,10 @@ static void tcg_target_qemu_prologue(TCGContext *s) stack_addend = frame_size - push_size; tcg_out_addi(s, TCG_REG_ESP, -stack_addend); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + /* jmp *tb. */ - tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[0]); + tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]); /* TB epilogue */ tb_ret_addr = s->code_ptr; diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index 8dac7f72f..246b2c0a4 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -2292,7 +2292,7 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_opc_m34(TCG_REG_P0, OPC_ALLOC_M34, TCG_REG_R33, 32, 24, 0), tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21, - TCG_REG_B6, TCG_REG_R32, 0), + TCG_REG_B6, TCG_REG_R33, 0), tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22, TCG_REG_R32, TCG_REG_B0)); @@ -2308,7 +2308,8 @@ static void tcg_target_qemu_prologue(TCGContext *s) } tcg_out_bundle(s, miB, - tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0), + tcg_opc_m48(TCG_REG_P0, OPC_MOV_I21, + TCG_REG_AREG0, TCG_REG_R32, 0), tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4, TCG_REG_R12, -frame_size, TCG_REG_R12), tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6)); diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index e04b0dc32..cb2ab8ba6 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -1452,9 +1452,7 @@ static const TCGTargetOpDef mips_op_defs[] = { }; static int tcg_target_callee_save_regs[] = { -#if 0 /* used for the global env (TCG_AREG0), so no need to save */ - TCG_REG_S0, -#endif + TCG_REG_S0, /* used for the global env (TCG_AREG0) */ TCG_REG_S1, TCG_REG_S2, TCG_REG_S3, @@ -1486,8 +1484,8 @@ static void tcg_target_qemu_prologue(TCGContext *s) } /* Call generated code */ - tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_A0, 0); - tcg_out_nop(s); + tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1]), 0); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); tb_ret_addr = s->code_ptr; /* TB epilogue */ diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 7970268e5..266e699e4 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -160,8 +160,7 @@ static const int tcg_target_callee_save_regs[] = { TCG_REG_R24, TCG_REG_R25, TCG_REG_R26, - /* TCG_REG_R27, */ /* currently used for the global env, so no - need to save */ + TCG_REG_R27, /* currently used for the global env */ TCG_REG_R28, TCG_REG_R29, TCG_REG_R30, @@ -939,7 +938,8 @@ static void tcg_target_qemu_prologue (TCGContext *s) } #endif - tcg_out32 (s, MTSPR | RS (3) | CTR); + tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR); tcg_out32 (s, BCCTR | BO_ALWAYS); tb_ret_addr = s->code_ptr; diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index ebbee343f..2e3cd2b81 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -151,8 +151,7 @@ static const int tcg_target_callee_save_regs[] = { TCG_REG_R24, TCG_REG_R25, TCG_REG_R26, - /* TCG_REG_R27, */ /* currently used for the global env, so no - need to save */ + TCG_REG_R27, /* currently used for the global env */ TCG_REG_R28, TCG_REG_R29, TCG_REG_R30, @@ -905,7 +904,8 @@ static void tcg_target_qemu_prologue (TCGContext *s) } #endif - tcg_out32 (s, MTSPR | RS (3) | CTR); + tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR); tcg_out32 (s, BCCTR | BO_ALWAYS); /* Epilogue */ diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index 450fcabd7..8d8498ca2 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -2306,8 +2306,9 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG); } - /* br %r2 (go to TB) */ - tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R2); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + /* br %r3 (go to TB) */ + tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]); tb_ret_addr = s->code_ptr; diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 5f1353adf..ecf7ace79 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -695,9 +695,9 @@ static void tcg_target_qemu_prologue(TCGContext *s) { tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) | INSN_IMM13(-TCG_TARGET_STACK_MINFRAME)); - tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I0) | + tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) | INSN_RS2(TCG_REG_G0)); - tcg_out_nop(s); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0); } #if defined(CONFIG_SOFTMMU) @@ -515,8 +515,9 @@ TCGv_i64 tcg_const_local_i64(int64_t val); extern uint8_t code_gen_prologue[]; #if defined(_ARCH_PPC) && !defined(_ARCH_PPC64) -#define tcg_qemu_tb_exec(tb_ptr) \ - ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr) +#define tcg_qemu_tb_exec(env, tb_ptr) \ + ((long REGPARM __attribute__ ((longcall)) (*)(void *, void *))code_gen_prologue)(env, tb_ptr) #else -#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr) +#define tcg_qemu_tb_exec(env, tb_ptr) \ + ((long REGPARM (*)(void *, void *))code_gen_prologue)(env, tb_ptr) #endif |