summary refs log tree commit diff stats
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.c62
1 files changed, 31 insertions, 31 deletions
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index daea902856..60c3193656 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->dflag = 0;
+            cpu_loop_exit(cs);
+        }
         break;
 
     case TO_SPR(0, 17): /* SR */
@@ -49,8 +55,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
             (rb & (SR_IME | SR_DME | SR_SM))) {
             tlb_flush(cs);
         }
-        env->sr = rb;
-        env->sr |= SR_FO;      /* FO is const equal to 1 */
+        cpu_set_sr(env, rb);
         if (env->sr & SR_DME) {
             env->tlb->cpu_openrisc_map_address_data =
                 &cpu_openrisc_get_phys_data;
@@ -121,6 +126,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
     case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
+    case TO_SPR(5, 1):  /* MACLO */
+        env->mac = deposit64(env->mac, 0, 32, rb);
+        break;
+    case TO_SPR(5, 2):  /* MACHI */
+        env->mac = deposit64(env->mac, 32, 32, rb);
+        break;
     case TO_SPR(9, 0):  /* PICMR */
         env->picmr |= rb;
         break;
@@ -165,7 +176,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
         cpu_openrisc_timer_update(cpu);
         break;
     default:
-
         break;
     }
 #endif
@@ -175,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;
@@ -196,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 env->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 */
@@ -246,6 +258,13 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
 
+    case TO_SPR(5, 1):  /* MACLO */
+        return (uint32_t)env->mac;
+        break;
+    case TO_SPR(5, 2):  /* MACHI */
+        return env->mac >> 32;
+        break;
+
     case TO_SPR(9, 0):  /* PICMR */
         return env->picmr;
 
@@ -264,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;
 }