]> git.proxmox.com Git - mirror_qemu.git/commitdiff
target/openrisc: Implement move to/from FPCSR
authorRichard Henderson <richard.henderson@linaro.org>
Mon, 26 Aug 2019 22:10:10 +0000 (15:10 -0700)
committerRichard Henderson <richard.henderson@linaro.org>
Wed, 4 Sep 2019 19:58:55 +0000 (12:58 -0700)
Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
target/openrisc/cpu.c
target/openrisc/cpu.h
target/openrisc/fpu_helper.c
target/openrisc/machine.c
target/openrisc/sys_helper.c

index b931605e622ba6faa8e56a277534214bf4b3c584..f96a69e2789731645408d2c189bfb788e7666cd9 100644 (file)
@@ -55,6 +55,7 @@ static void openrisc_cpu_reset(CPUState *s)
     cpu->env.sr = SR_FO | SR_SM;
     cpu->env.lock_addr = -1;
     s->exception_index = -1;
+    cpu_set_fpcsr(&cpu->env, 0);
 
 #ifndef CONFIG_USER_ONLY
     cpu->env.picmr = 0x00000000;
index 71c59598281ef7be3429cb73aa5d78acd50b14d3..0ad02eab7946b8ecdfb39ba9a88c603a87fa9a20 100644 (file)
@@ -413,6 +413,8 @@ static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val)
     env->sr = (val & ~(SR_F | SR_CY | SR_OV)) | SR_FO;
 }
 
+void cpu_set_fpcsr(CPUOpenRISCState *env, uint32_t val);
+
 #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
 
 #endif /* OPENRISC_CPU_H */
index 7bcef9dc53326f454a4986885ed748dbf523db12..59e1413279148917dff5bd50f1345992000cfcda 100644 (file)
@@ -61,6 +61,19 @@ void HELPER(update_fpcsr)(CPUOpenRISCState *env)
     }
 }
 
+void cpu_set_fpcsr(CPUOpenRISCState *env, uint32_t val)
+{
+    static const int rm_to_sf[] = {
+        float_round_nearest_even,
+        float_round_to_zero,
+        float_round_up,
+        float_round_down
+    };
+
+    env->fpcsr = val & 0x7ff;
+    set_float_rounding_mode(rm_to_sf[extract32(val, 1, 2)], &env->fp_status);
+}
+
 uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
 {
     return int64_to_float64(val, &env->fp_status);
index 0a96404dc66a8855a5ef9c93b3e4b1aec7156f37..b92985d99be86f51bca8d2030df4d80f4cab22b9 100644 (file)
@@ -121,10 +121,21 @@ static const VMStateDescription vmstate_env = {
     }
 };
 
+static int cpu_post_load(void *opaque, int version_id)
+{
+    OpenRISCCPU *cpu = opaque;
+    CPUOpenRISCState *env = &cpu->env;
+
+    /* Update env->fp_status to match env->fpcsr.  */
+    cpu_set_fpcsr(env, env->fpcsr);
+    return 0;
+}
+
 const VMStateDescription vmstate_openrisc_cpu = {
     .name = "cpu",
     .version_id = 1,
     .minimum_version_id = 1,
+    .post_load = cpu_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_CPU(),
         VMSTATE_STRUCT(env, OpenRISCCPU, 1, vmstate_env, CPUOpenRISCState),
index cf8e637b08763fd61c0ad6d027feaf02933c3f22..d9fe6c594893399fc0d22bc1d30d6d2a3d18b991 100644 (file)
@@ -37,8 +37,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
     CPUState *cs = env_cpu(env);
     target_ulong mr;
     int idx;
+#endif
 
     switch (spr) {
+#ifndef CONFIG_USER_ONLY
     case TO_SPR(0, 11): /* EVBAR */
         env->evbar = rb;
         break;
@@ -179,10 +181,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
         }
         cpu_openrisc_timer_update(cpu);
         break;
-    default:
+#endif
+
+    case TO_SPR(0, 20): /* FPCSR */
+        cpu_set_fpcsr(env, rb);
         break;
     }
-#endif
 }
 
 target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
@@ -193,8 +197,10 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
     OpenRISCCPU *cpu = env_archcpu(env);
     CPUState *cs = env_cpu(env);
     int idx;
+#endif
 
     switch (spr) {
+#ifndef CONFIG_USER_ONLY
     case TO_SPR(0, 0): /* VR */
         return env->vr;
 
@@ -303,11 +309,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
     case TO_SPR(10, 1): /* TTCR */
         cpu_openrisc_count_update(cpu);
         return cpu_openrisc_count_get(cpu);
+#endif
 
-    default:
-        break;
+    case TO_SPR(0, 20): /* FPCSR */
+        return env->fpcsr;
     }
-#endif
 
     /* for rd is passed in, if rd unchanged, just keep it back.  */
     return rd;