Patchwork [RFC,qom-cpu,08/41] cpu: Move icount_decr field from CPU_COMMON to CPUState

login
register
mail settings
Submitter Andreas Färber
Date Sept. 4, 2013, 9:04 a.m.
Message ID <1378285521-3230-9-git-send-email-afaerber@suse.de>
Download mbox | patch
Permalink /patch/272497/
State New
Headers show

Comments

Andreas Färber - Sept. 4, 2013, 9:04 a.m.
Signed-off-by: Andreas Färber <afaerber@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(-)

Patch

diff --git a/cpu-exec.c b/cpu-exec.c
index 8a135ca..b164662 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -643,7 +643,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;
@@ -653,7 +653,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 318e13f..fd1fe1c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -127,11 +127,10 @@  int64_t cpu_get_icount(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);
 }
@@ -1160,8 +1159,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);
 
@@ -1178,7 +1177,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);
@@ -1188,8 +1187,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 9f0c0f2..b301ac2 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -117,18 +117,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_* */
@@ -148,14 +136,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 fdf7ae5..e2ab371 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -141,6 +141,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;
 
@@ -161,6 +173,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 fe0d2e7..192a9f1 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -201,6 +201,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 69dea6e..bbf911e 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -213,7 +213,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;
     }
@@ -238,7 +238,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);
 
@@ -1422,7 +1422,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");
@@ -1438,6 +1438,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;
@@ -1448,11 +1449,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
@@ -1462,14 +1463,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