summaryrefslogtreecommitdiffstats
path: root/llvm/include/llvm-state.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/llvm-state.h')
-rw-r--r--llvm/include/llvm-state.h194
1 files changed, 194 insertions, 0 deletions
diff --git a/llvm/include/llvm-state.h b/llvm/include/llvm-state.h
new file mode 100644
index 0000000..e573073
--- /dev/null
+++ b/llvm/include/llvm-state.h
@@ -0,0 +1,194 @@
+/*
+ * (C) 2010 by Computer System Laboratory, IIS, Academia Sinica, Taiwan.
+ * See COPYRIGHT in top-level directory.
+ *
+ * This file implements the basic optimization schemes including indirect
+ * branch target cache (IBTC), indirect branch chain (IB chain), and trace
+ * profiling and prediction routines.
+ */
+
+#ifndef __LLVM_STATE_H
+#define __LLVM_STATE_H
+
+#define COPY_STATE(_dst, _src, _e) do { _dst->_e = _src->_e; } while(0)
+
+/*
+ * The following data structure and routine are used to save/restore the states
+ * of CPUArchState. Only the states that could affect decoding the guest binary by
+ * the TCG front-end are saved/restored. Such states are saved when translating
+ * the block at the first time because the states could change later and are
+ * restored to the saved values when the block is decoded again during the
+ * trace formation.
+ */
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+typedef struct i386_env {
+ int singlestep_enabled;
+ uint32_t hflags;
+ target_ulong eflags;
+} cpustate;
+#elif defined(TARGET_ARM)
+typedef struct arm_env {
+ int singlestep_enabled;
+ uint32_t pstate;
+ uint32_t aarch64;
+ struct {
+ uint32_t c15_cpar;
+ uint64_t scr_el3;
+ } cp15;
+ uint32_t uncached_cpsr;
+ uint64_t features;
+} cpustate;
+#elif defined(TARGET_PPC) || defined(TARGET_PPC64)
+typedef struct ppc_env {
+ int singlestep_enabled;
+ target_ulong msr;
+ int mmu_idx;
+ uint32_t flags;
+ uint64_t insns_flags;
+ uint64_t insns_flags2;
+ target_ulong hflags;
+} cpustate;
+#elif defined(TARGET_SH4)
+typedef struct sh4_env {
+ int singlestep_enabled;
+ uint32_t sr; /* status register */
+ uint32_t fpscr; /* floating point status/control register */
+ uint32_t features;
+} cpustate;
+#elif defined(TARGET_M68K)
+typedef struct m68k_env {
+ int singlestep_enabled;
+ uint32_t sr; /* status register */
+ uint32_t fpcr; /* floating point status/control register */
+} cpustate;
+#elif defined(TARGET_MIPS)
+typedef struct mips_env {
+ int singlestep_enabled;
+ target_ulong btarget;
+} cpustate;
+#else
+typedef struct dummy_env {
+ int dummy;
+} cpustate;
+#endif
+
+static inline void tcg_save_state(CPUArchState *env, TranslationBlock *tb)
+{
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct i386_env *s = new struct i386_env;
+ COPY_STATE(s, cpu, singlestep_enabled);
+ COPY_STATE(s, env, hflags);
+ COPY_STATE(s, env, eflags);
+#elif defined(TARGET_ARM)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct arm_env *s = new struct arm_env;
+ COPY_STATE(s, cpu, singlestep_enabled);
+ COPY_STATE(s, env, cp15.c15_cpar);
+ COPY_STATE(s, env, cp15.scr_el3);
+ COPY_STATE(s, env, uncached_cpsr);
+ COPY_STATE(s, env, features);
+ COPY_STATE(s, env, pstate);
+ COPY_STATE(s, env, aarch64);
+#elif defined(TARGET_PPC) || defined(TARGET_PPC64)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct ppc_env *s = new struct ppc_env;
+ COPY_STATE(s, cpu, singlestep_enabled);
+ COPY_STATE(s, env, msr);
+ COPY_STATE(s, env, mmu_idx);
+ COPY_STATE(s, env, flags);
+ COPY_STATE(s, env, insns_flags);
+ COPY_STATE(s, env, insns_flags2);
+ COPY_STATE(s, env, hflags);
+#elif defined(TARGET_SH4)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct sh4_env *s = new struct sh4_env;
+ COPY_STATE(s, cpu, singlestep_enabled);
+ COPY_STATE(s, env, sr);
+ COPY_STATE(s, env, fpscr);
+ COPY_STATE(s, env, features);
+#elif defined(TARGET_M68K)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct m68k_env *s = new struct m68k_env;
+ COPY_STATE(s, cpu, singlestep_enabled);
+ COPY_STATE(s, env, sr);
+ COPY_STATE(s, env, fpcr);
+#elif defined(TARGET_MIPS)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct mips_env *s = new struct mips_env;
+ COPY_STATE(s, cpu, singlestep_enabled);
+ COPY_STATE(s, env, btarget);
+#else
+ void *s = nullptr;
+#endif
+
+ tb->state = (void *)s;
+}
+
+/*
+ * tcg_restore_state()
+ * Reset states to those when the block is first translated.
+ */
+static inline void tcg_copy_state(CPUArchState *env, TranslationBlock *tb)
+{
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct i386_env *i386e = (struct i386_env *)tb->state;
+ COPY_STATE(cpu, i386e, singlestep_enabled);
+ COPY_STATE(env, i386e, hflags);
+ COPY_STATE(env, i386e, eflags);
+#elif defined(TARGET_ARM)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct arm_env *arme = (struct arm_env *)tb->state;
+ COPY_STATE(cpu, arme, singlestep_enabled);
+ COPY_STATE(env, arme, cp15.c15_cpar);
+ COPY_STATE(env, arme, cp15.scr_el3);
+ COPY_STATE(env, arme, uncached_cpsr);
+ COPY_STATE(env, arme, features);
+ COPY_STATE(env, arme, pstate);
+ COPY_STATE(env, arme, aarch64);
+#elif defined(TARGET_PPC) || defined(TARGET_PPC64)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct ppc_env *ppce = (struct ppc_env *)tb->state;
+ COPY_STATE(cpu, ppce, singlestep_enabled);
+ COPY_STATE(env, ppce, msr);
+ COPY_STATE(env, ppce, mmu_idx);
+ COPY_STATE(env, ppce, flags);
+ COPY_STATE(env, ppce, insns_flags);
+ COPY_STATE(env, ppce, insns_flags2);
+ COPY_STATE(env, ppce, hflags);
+#elif defined(TARGET_SH4)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct sh4_env *sh4e = (struct sh4_env *)tb->state;
+ COPY_STATE(cpu, sh4e, singlestep_enabled);
+ COPY_STATE(env, sh4e, sr);
+ COPY_STATE(env, sh4e, fpscr);
+ COPY_STATE(env, sh4e, features);
+#elif defined(TARGET_M68K)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct m68k_env *m68ke = (struct m68k_env *)tb->state;
+ COPY_STATE(cpu, m68ke, singlestep_enabled);
+ COPY_STATE(env, m68ke, sr);
+ COPY_STATE(env, m68ke, fpcr);
+#elif defined(TARGET_MIPS)
+ CPUState *cpu = ENV_GET_CPU(env);
+ struct mips_env *mipse = (struct mips_env *)tb->state;
+ COPY_STATE(cpu, mipse, singlestep_enabled);
+ COPY_STATE(env, mipse, btarget);
+#endif
+}
+
+static inline void delete_state(TranslationBlock *tb)
+{
+ delete (cpustate *)tb->state;
+ tb->state = nullptr;
+}
+
+#undef COPY_STATE
+#endif /* __LLVM_STATE_H */
+
+
+/*
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
+
OpenPOWER on IntegriCloud