Signed-off-by: Andreas Färber <afaer...@suse.de> --- cpu-exec.c | 4 ++-- cpus.c | 13 ++++++------- include/exec/cpu-defs.h | 20 -------------------- include/exec/gen-icount.h | 6 ++++-- include/qom/cpu.h | 19 +++++++++++++++++++ qom/cpu.c | 1 + translate-all.c | 15 ++++++++------- 7 files changed, 40 insertions(+), 38 deletions(-)
diff --git a/cpu-exec.c b/cpu-exec.c index 4a03d83..9d98f21 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -649,7 +649,7 @@ int cpu_exec(CPUArchState *env) /* Instruction counter expired. */ int insns_left; tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); - insns_left = env->icount_decr.u32; + insns_left = cpu->icount_decr.u32; if (cpu->icount_extra && insns_left >= 0) { /* Refill decrementer and continue execution. */ cpu->icount_extra += insns_left; @@ -659,7 +659,7 @@ int cpu_exec(CPUArchState *env) insns_left = cpu->icount_extra; } cpu->icount_extra -= insns_left; - env->icount_decr.u16.low = insns_left; + cpu->icount_decr.u16.low = insns_left; } else { if (insns_left > 0) { /* Execute remaining instructions. */ diff --git a/cpus.c b/cpus.c index e9c17ae..1104d61 100644 --- a/cpus.c +++ b/cpus.c @@ -139,11 +139,10 @@ static int64_t cpu_get_icount_locked(void) icount = qemu_icount; if (cpu) { - CPUArchState *env = cpu->env_ptr; if (!cpu_can_do_io(cpu)) { fprintf(stderr, "Bad clock read\n"); } - icount -= (env->icount_decr.u16.low + cpu->icount_extra); + icount -= (cpu->icount_decr.u16.low + cpu->icount_extra); } return qemu_icount_bias + (icount << icount_time_shift); } @@ -1249,8 +1248,8 @@ static int tcg_cpu_exec(CPUArchState *env) int64_t count; int64_t deadline; int decr; - qemu_icount -= (env->icount_decr.u16.low + cpu->icount_extra); - env->icount_decr.u16.low = 0; + qemu_icount -= (cpu->icount_decr.u16.low + cpu->icount_extra); + cpu->icount_decr.u16.low = 0; cpu->icount_extra = 0; deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); @@ -1267,7 +1266,7 @@ static int tcg_cpu_exec(CPUArchState *env) qemu_icount += count; decr = (count > 0xffff) ? 0xffff : count; count -= decr; - env->icount_decr.u16.low = decr; + cpu->icount_decr.u16.low = decr; cpu->icount_extra = count; } ret = cpu_exec(env); @@ -1277,8 +1276,8 @@ static int tcg_cpu_exec(CPUArchState *env) if (use_icount) { /* Fold pending instructions back into the instruction counter, and clear the interrupt flag. */ - qemu_icount -= (env->icount_decr.u16.low + cpu->icount_extra); - env->icount_decr.u32 = 0; + qemu_icount -= (cpu->icount_decr.u16.low + cpu->icount_extra); + cpu->icount_decr.u32 = 0; cpu->icount_extra = 0; } return ret; diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 8f9871c..d036e8e 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -118,18 +118,6 @@ QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS)); #endif -#ifdef HOST_WORDS_BIGENDIAN -typedef struct icount_decr_u16 { - uint16_t high; - uint16_t low; -} icount_decr_u16; -#else -typedef struct icount_decr_u16 { - uint16_t low; - uint16_t high; -} icount_decr_u16; -#endif - typedef struct CPUBreakpoint { target_ulong pc; int flags; /* BP_* */ @@ -149,14 +137,6 @@ typedef struct CPUWatchpoint { CPU_COMMON_TLB \ struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \ \ - /* Number of cycles left, with interrupt flag in high bit. \ - This allows a single read-compare-cbranch-write sequence to test \ - for both decrementer underflow and exceptions. */ \ - union { \ - uint32_t u32; \ - icount_decr_u16 u16; \ - } icount_decr; \ - \ /* from this point: preserved by CPU reset */ \ /* ice debug support */ \ QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \ diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h index f0dace3..da53395 100644 --- a/include/exec/gen-icount.h +++ b/include/exec/gen-icount.h @@ -26,13 +26,15 @@ static inline void gen_tb_start(void) icount_label = gen_new_label(); count = tcg_temp_local_new_i32(); - tcg_gen_ld_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u32)); + tcg_gen_ld_i32(count, cpu_env, + -ENV_OFFSET + offsetof(CPUState, icount_decr.u32)); /* This is a horrid hack to allow fixing up the value later. */ icount_arg = tcg_ctx.gen_opparam_ptr + 1; tcg_gen_subi_i32(count, count, 0xdeadbeef); tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label); - tcg_gen_st16_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u16.low)); + tcg_gen_st16_i32(count, cpu_env, + -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low)); tcg_temp_free_i32(count); } diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 012a7e6..3156b16 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -138,6 +138,18 @@ typedef struct CPUClass { const char *gdb_core_xml_file; } CPUClass; +#ifdef HOST_WORDS_BIGENDIAN +typedef struct icount_decr_u16 { + uint16_t high; + uint16_t low; +} icount_decr_u16; +#else +typedef struct icount_decr_u16 { + uint16_t low; + uint16_t high; +} icount_decr_u16; +#endif + struct KVMState; struct kvm_run; @@ -158,6 +170,9 @@ struct kvm_run; * CPU and return to its top level loop. * @singlestep_enabled: Flags for single-stepping. * @icount_extra: Instructions until next timer event. + * @icount_decr: Number of cycles left, with interrupt flag in high bit. + * This allows a single read-compare-cbranch-write sequence to test + * for both decrementer underflow and exceptions. * @can_do_io: Nonzero if memory-mapped IO is safe. * @env_ptr: Pointer to subclass-specific CPUArchState field. * @current_tb: Currently executing TB. @@ -223,6 +238,10 @@ struct CPUState { /* TODO Move common fields from CPUArchState here. */ int cpu_index; /* used by alpha TCG */ uint32_t halted; /* used by alpha, cris, ppc TCG */ + union { + uint32_t u32; + icount_decr_u16 u16; + } icount_decr; uint32_t can_do_io; }; diff --git a/qom/cpu.c b/qom/cpu.c index a4f6a78..a4c5073 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -242,6 +242,7 @@ static void cpu_common_reset(CPUState *cpu) cpu->mem_io_pc = 0; cpu->mem_io_vaddr = 0; cpu->icount_extra = 0; + cpu->icount_decr.u32 = 0; cpu->can_do_io = 0; } diff --git a/translate-all.c b/translate-all.c index a1af5ef..6bb3933 100644 --- a/translate-all.c +++ b/translate-all.c @@ -217,7 +217,7 @@ static int cpu_restore_state_from_tb(TranslationBlock *tb, CPUArchState *env, if (use_icount) { /* Reset the cycle counter to the start of the block. */ - env->icount_decr.u16.low += tb->icount; + cpu->icount_decr.u16.low += tb->icount; /* Clear the IO flag. */ cpu->can_do_io = 0; } @@ -242,7 +242,7 @@ static int cpu_restore_state_from_tb(TranslationBlock *tb, CPUArchState *env, while (s->gen_opc_instr_start[j] == 0) { j--; } - env->icount_decr.u16.low -= s->gen_opc_icount[j]; + cpu->icount_decr.u16.low -= s->gen_opc_icount[j]; restore_state_to_opc(env, tb, j); @@ -1409,7 +1409,7 @@ static void tcg_handle_interrupt(CPUState *cpu, int mask) } if (use_icount) { - env->icount_decr.u16.high = 0xffff; + cpu->icount_decr.u16.high = 0xffff; if (!cpu_can_do_io(cpu) && (mask & ~old_mask) != 0) { cpu_abort(env, "Raised interrupt while not in I/O function"); @@ -1425,6 +1425,7 @@ CPUInterruptHandler cpu_interrupt_handler = tcg_handle_interrupt; must be at the end of the TB */ void cpu_io_recompile(CPUArchState *env, uintptr_t retaddr) { + CPUState *cpu = ENV_GET_CPU(env); TranslationBlock *tb; uint32_t n, cflags; target_ulong pc, cs_base; @@ -1435,11 +1436,11 @@ void cpu_io_recompile(CPUArchState *env, uintptr_t retaddr) cpu_abort(env, "cpu_io_recompile: could not find TB for pc=%p", (void *)retaddr); } - n = env->icount_decr.u16.low + tb->icount; + n = cpu->icount_decr.u16.low + tb->icount; cpu_restore_state_from_tb(tb, env, retaddr); /* Calculate how many instructions had been executed before the fault occurred. */ - n = n - env->icount_decr.u16.low; + n = n - cpu->icount_decr.u16.low; /* Generate a new TB ending on the I/O insn. */ n++; /* On MIPS and SH, delay slot instructions can only be restarted if @@ -1449,14 +1450,14 @@ void cpu_io_recompile(CPUArchState *env, uintptr_t retaddr) #if defined(TARGET_MIPS) if ((env->hflags & MIPS_HFLAG_BMASK) != 0 && n > 1) { env->active_tc.PC -= 4; - env->icount_decr.u16.low++; + cpu->icount_decr.u16.low++; env->hflags &= ~MIPS_HFLAG_BMASK; } #elif defined(TARGET_SH4) if ((env->flags & ((DELAY_SLOT | DELAY_SLOT_CONDITIONAL))) != 0 && n > 1) { env->pc -= 2; - env->icount_decr.u16.low++; + cpu->icount_decr.u16.low++; env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL); } #endif -- 1.8.4.5