aboutsummaryrefslogtreecommitdiff
path: root/target/openrisc/sys_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/openrisc/sys_helper.c')
-rw-r--r--target/openrisc/sys_helper.c44
1 files changed, 16 insertions, 28 deletions
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index 9841a5bb27..0968901426 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -29,11 +29,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
target_ulong ra, target_ulong rb, target_ulong offset)
{
#ifndef CONFIG_USER_ONLY
- int spr = (ra | offset);
- int idx;
-
OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
CPUState *cs = CPU(cpu);
+ int spr = (ra | offset);
+ int idx;
switch (spr) {
case TO_SPR(0, 0): /* VR */
@@ -41,7 +40,14 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
break;
case TO_SPR(0, 16): /* NPC */
- env->npc = rb;
+ cpu_restore_state(cs, GETPC());
+ /* ??? Mirror or1ksim in not trashing delayed branch state
+ when "jumping" to the current instruction. */
+ if (env->pc != rb) {
+ env->pc = rb;
+ env->flags = 0;
+ cpu_loop_exit(cs);
+ }
break;
case TO_SPR(0, 17): /* SR */
@@ -170,7 +176,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
cpu_openrisc_timer_update(cpu);
break;
default:
-
break;
}
#endif
@@ -180,11 +185,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
target_ulong rd, target_ulong ra, uint32_t offset)
{
#ifndef CONFIG_USER_ONLY
+ OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+ CPUState *cs = CPU(cpu);
int spr = (ra | offset);
int idx;
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
switch (spr) {
case TO_SPR(0, 0): /* VR */
return env->vr & SPR_VR;
@@ -201,13 +206,15 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
case TO_SPR(0, 4): /* IMMUCFGR */
return env->immucfgr;
- case TO_SPR(0, 16): /* NPC */
- return env->npc;
+ case TO_SPR(0, 16): /* NPC (equals PC) */
+ cpu_restore_state(cs, GETPC());
+ return env->pc;
case TO_SPR(0, 17): /* SR */
return cpu_get_sr(env);
case TO_SPR(0, 18): /* PPC */
+ cpu_restore_state(cs, GETPC());
return env->ppc;
case TO_SPR(0, 32): /* EPCR */
@@ -276,25 +283,6 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
}
#endif
-/*If we later need to add tracepoints (or debug printfs) for the return
-value, it may be useful to structure the code like this:
-
-target_ulong ret = 0;
-
-switch() {
-case x:
- ret = y;
- break;
-case z:
- ret = 42;
- break;
-...
-}
-
-later something like trace_spr_read(ret);
-
-return ret;*/
-
/* for rd is passed in, if rd unchanged, just keep it back. */
return rd;
}