aboutsummaryrefslogtreecommitdiff
path: root/target-alpha/helper.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2014-09-16 12:16:38 -0700
committerRichard Henderson <rth@twiddle.net>2015-08-18 11:08:48 -0700
commit591243846f7d0dc59f482a89e241a6ce02d25fae (patch)
tree1590c103a70c076198d0e38b1b993f70b584c36f /target-alpha/helper.c
parent074a9925e1cfd659d5376dcaccd1436d3840e611 (diff)
target-alpha: Use separate TCGv temporaries for the shadow registers
This avoids having to manually swap them around when swapping to and from PALmode. We simply encode the shadow registers into the translation. The VMStateDescription version changes, because the meaning of "shadow" changes in the save file when in PALmode. It would be possible to fix this, but I don't think it's worth the effort. Reviewed-by: Aurelien Jarno <aurelien@aurel32.net> Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-alpha/helper.c')
-rw-r--r--target-alpha/helper.c63
1 files changed, 26 insertions, 37 deletions
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 46b8ef9141..5a85335838 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -79,6 +79,30 @@ void helper_store_fpcr(CPUAlphaState *env, uint64_t val)
cpu_alpha_store_fpcr(env, val);
}
+static uint64_t *cpu_alpha_addr_gr(CPUAlphaState *env, unsigned reg)
+{
+#ifndef CONFIG_USER_ONLY
+ if (env->pal_mode) {
+ if (reg >= 8 && reg <= 14) {
+ return &env->shadow[reg - 8];
+ } else if (reg == 25) {
+ return &env->shadow[7];
+ }
+ }
+#endif
+ return &env->ir[reg];
+}
+
+uint64_t cpu_alpha_load_gr(CPUAlphaState *env, unsigned reg)
+{
+ return *cpu_alpha_addr_gr(env, reg);
+}
+
+void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val)
+{
+ *cpu_alpha_addr_gr(env, reg) = val;
+}
+
#if defined(CONFIG_USER_ONLY)
int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
int rw, int mmu_idx)
@@ -90,38 +114,6 @@ int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
return 1;
}
#else
-void swap_shadow_regs(CPUAlphaState *env)
-{
- uint64_t i0, i1, i2, i3, i4, i5, i6, i7;
-
- i0 = env->ir[8];
- i1 = env->ir[9];
- i2 = env->ir[10];
- i3 = env->ir[11];
- i4 = env->ir[12];
- i5 = env->ir[13];
- i6 = env->ir[14];
- i7 = env->ir[25];
-
- env->ir[8] = env->shadow[0];
- env->ir[9] = env->shadow[1];
- env->ir[10] = env->shadow[2];
- env->ir[11] = env->shadow[3];
- env->ir[12] = env->shadow[4];
- env->ir[13] = env->shadow[5];
- env->ir[14] = env->shadow[6];
- env->ir[25] = env->shadow[7];
-
- env->shadow[0] = i0;
- env->shadow[1] = i1;
- env->shadow[2] = i2;
- env->shadow[3] = i3;
- env->shadow[4] = i4;
- env->shadow[5] = i5;
- env->shadow[6] = i6;
- env->shadow[7] = i7;
-}
-
/* Returns the OSF/1 entMM failure indication, or -1 on success. */
static int get_physical_address(CPUAlphaState *env, target_ulong addr,
int prot_need, int mmu_idx,
@@ -375,10 +367,7 @@ void alpha_cpu_do_interrupt(CPUState *cs)
env->pc = env->palbr + i;
/* Switch to PALmode. */
- if (!env->pal_mode) {
- env->pal_mode = 1;
- swap_shadow_regs(env);
- }
+ env->pal_mode = 1;
#endif /* !USER_ONLY */
}
@@ -443,7 +432,7 @@ void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
env->pc, env->ps);
for (i = 0; i < 31; i++) {
cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i,
- linux_reg_names[i], env->ir[i]);
+ linux_reg_names[i], cpu_alpha_load_gr(env, i));
if ((i % 3) == 2)
cpu_fprintf(f, "\n");
}