summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exec-all.h1
-rw-r--r--target-sparc/helper.c2
-rw-r--r--target-sparc/translate.c2
-rw-r--r--translate-all.c21
4 files changed, 22 insertions, 4 deletions
diff --git a/exec-all.h b/exec-all.h
index 3065858f3a..1ecb41c55e 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -61,6 +61,7 @@ extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
extern target_ulong gen_opc_npc[OPC_BUF_SIZE];
extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
+extern target_ulong gen_opc_jump_pc[2];
typedef void (GenOpFunc)(void);
typedef void (GenOpFunc1)(long);
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index e6891ccbb1..82a3a4ec90 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -94,7 +94,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
if (tb) {
/* the PC is inside the translated code. It means that we have
a virtual CPU fault */
- cpu_restore_state(tb, env, pc, NULL);
+ cpu_restore_state(tb, env, pc, (void *)T2);
}
}
cpu_loop_exit();
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 9f5c2f5c3d..543ed927b6 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1582,6 +1582,8 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
page_dump(logfile);
}
#endif
+ gen_opc_jump_pc[0] = dc->jump_pc[0];
+ gen_opc_jump_pc[1] = dc->jump_pc[1];
} else {
tb->size = last_pc + 4 - pc_start;
}
diff --git a/translate-all.c b/translate-all.c
index fd7cc668cf..e4f7c9c19e 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -52,6 +52,7 @@ uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
#elif defined(TARGET_SPARC)
target_ulong gen_opc_npc[OPC_BUF_SIZE];
+target_ulong gen_opc_jump_pc[2];
#endif
int code_copy_enabled = 1;
@@ -244,9 +245,23 @@ int cpu_restore_state(TranslationBlock *tb,
#elif defined(TARGET_ARM)
env->regs[15] = gen_opc_pc[j];
#elif defined(TARGET_SPARC)
- /* XXX: restore npc too */
- env->pc = gen_opc_pc[j];
- env->npc = gen_opc_npc[j];
+ {
+ target_ulong npc;
+ env->pc = gen_opc_pc[j];
+ npc = gen_opc_npc[j];
+ if (npc == 1) {
+ /* dynamic NPC: already stored */
+ } else if (npc == 2) {
+ target_ulong t2 = (target_ulong)puc;
+ /* jump PC: use T2 and the jump targets of the translation */
+ if (t2)
+ env->npc = gen_opc_jump_pc[0];
+ else
+ env->npc = gen_opc_jump_pc[1];
+ } else {
+ env->npc = npc;
+ }
+ }
#elif defined(TARGET_PPC)
{
int type;