aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2011-07-14 17:30:43 +0000
committerBlue Swirl <blauwirbel@gmail.com>2011-07-14 17:30:43 +0000
commitf838e2c535e47dc8e99ae7ec711407b849700cc9 (patch)
tree75c5d26c91fa55ca92c997bc654ea0c1d5747081
parentd8e586ffccd73c9c7758166241564c63109fc8d3 (diff)
Sparc: fix FPU and AM enable checks for translation
Translation used incorrectly CPUState fields directly to check for FPU enable state and 32 bit address masking on Sparc64. Fix by using TB flags instead. Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
-rw-r--r--target-sparc/cpu.h49
-rw-r--r--target-sparc/translate.c9
2 files changed, 35 insertions, 23 deletions
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 4edae78ca3..22ee2743d7 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -606,17 +606,6 @@ static inline int cpu_pil_allowed(CPUState *env1, int pil)
#endif
}
-static inline int cpu_fpu_enabled(CPUState *env1)
-{
-#if defined(CONFIG_USER_ONLY)
- return 1;
-#elif !defined(TARGET_SPARC64)
- return env1->psref;
-#else
- return ((env1->pstate & PS_PEF) != 0) && ((env1->fprs & FPRS_FEF) != 0);
-#endif
-}
-
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
@@ -639,6 +628,9 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit);
trap_state* cpu_tsptr(CPUState* env);
#endif
+#define TB_FLAG_FPU_ENABLED (1 << 4)
+#define TB_FLAG_AM_ENABLED (1 << 5)
+
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
@@ -646,16 +638,41 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
*cs_base = env->npc;
#ifdef TARGET_SPARC64
// AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
- *flags = ((env->pstate & PS_AM) << 2) /* 5 */
- | (((env->pstate & PS_PEF) >> 1) /* 3 */
- | ((env->fprs & FPRS_FEF) << 2)) /* 4 */
- | (env->pstate & PS_PRIV) /* 2 */
+ *flags = (env->pstate & PS_PRIV) /* 2 */
| ((env->lsu & (DMMU_E | IMMU_E)) >> 2) /* 1, 0 */
| ((env->tl & 0xff) << 8)
| (env->dmmu.mmu_primary_context << 16); /* 16... */
+ if (env->pstate & PS_AM) {
+ *flags |= TB_FLAG_AM_ENABLED;
+ }
+ if ((env->def->features & CPU_FEATURE_FLOAT) && (env->pstate & PS_PEF)
+ && (env->fprs & FPRS_FEF)) {
+ *flags |= TB_FLAG_FPU_ENABLED;
+ }
#else
// FPU enable . Supervisor
- *flags = (env->psref << 4) | env->psrs;
+ *flags = env->psrs;
+ if ((env->def->features & CPU_FEATURE_FLOAT) && env->psref) {
+ *flags |= TB_FLAG_FPU_ENABLED;
+ }
+#endif
+}
+
+static inline bool tb_fpu_enabled(int tb_flags)
+{
+#if defined(CONFIG_USER_ONLY)
+ return true;
+#else
+ return tb_flags & TB_FLAG_FPU_ENABLED;
+#endif
+}
+
+static inline bool tb_am_enabled(int tb_flags)
+{
+#ifndef TARGET_SPARC64
+ return false;
+#else
+ return tb_flags & TB_FLAG_AM_ENABLED;
#endif
}
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 5f92dbb819..27c2cf98e8 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4879,13 +4879,8 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
dc->cc_op = CC_OP_DYNAMIC;
dc->mem_idx = cpu_mmu_index(env);
dc->def = env->def;
- if ((dc->def->features & CPU_FEATURE_FLOAT))
- dc->fpu_enabled = cpu_fpu_enabled(env);
- else
- dc->fpu_enabled = 0;
-#ifdef TARGET_SPARC64
- dc->address_mask_32bit = env->pstate & PS_AM;
-#endif
+ dc->fpu_enabled = tb_fpu_enabled(tb->flags);
+ dc->address_mask_32bit = tb_am_enabled(tb->flags);
dc->singlestep = (env->singlestep_enabled || singlestep);
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;