qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] Modified OpenRisc fpu exception


From: Feng Gao
Subject: [Qemu-devel] [PATCH] Modified OpenRisc fpu exception
Date: Fri, 30 Nov 2012 15:17:42 +0800

Add OpenRisc fpu excepiton.
When an exception raised, CPU can save right PC.

Signed-off-by: Feng Gao <address@hidden>
---
 target-openrisc/exception.c        |   31 +++++++++++++++++++++--
 target-openrisc/exception.h        |    8 ++++--
 target-openrisc/exception_helper.c |    2 +-
 target-openrisc/fpu_helper.c       |   48 +++++++++++++++++++-----------------
 target-openrisc/int_helper.c       |    2 +-
 target-openrisc/mmu_helper.c       |   17 +++----------
 6 files changed, 66 insertions(+), 42 deletions(-)

diff --git a/target-openrisc/exception.c b/target-openrisc/exception.c
index 58e53c6..39966a7 100644
--- a/target-openrisc/exception.c
+++ b/target-openrisc/exception.c
@@ -20,8 +20,35 @@
 #include "cpu.h"
 #include "exception.h"
 
-void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp)
+void QEMU_NORETURN do_raise_exception_err(OpenRISCCPU *cpu,
+                                          uint32_t exception,
+                                          uintptr_t pc)
 {
-    cpu->env.exception_index = excp;
+    TranslationBlock *tb;
+
+    /* openrisc cpu has fifteen exceptions */
+    if (exception < 0xe)
+        qemu_log("%s: %d\n", __func__, exception);
+
+    cpu->env.exception_index = exception;
+
+    if (pc) {
+        /* now we have a real cpu fault */
+        tb = tb_find_pc(pc);
+        if (tb) {
+            /* the PC is inside the translated code. It means that we have
+               a virtual CPU fault */
+            cpu_restore_state(tb, &cpu->env, pc);
+        }
+    }
+
     cpu_loop_exit(&cpu->env);
 }
+
+void QEMU_NORETURN do_raise_exception(OpenRISCCPU *cpu,
+                                      uint32_t exception,
+                                      uintptr_t pc)
+{
+    do_raise_exception_err(cpu, exception, pc);
+}
+
diff --git a/target-openrisc/exception.h b/target-openrisc/exception.h
index 4b64430..4d1928e 100644
--- a/target-openrisc/exception.h
+++ b/target-openrisc/exception.h
@@ -23,6 +23,10 @@
 #include "cpu.h"
 #include "qemu-common.h"
 
-void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp);
-
+void QEMU_NORETURN do_raise_exception_err(OpenRISCCPU *cpu,
+                                          uint32_t exception,
+                                          uintptr_t pc);
+void QEMU_NORETURN do_raise_exception(OpenRISCCPU *cpu,
+                                      uint32_t exception,
+                                      uintptr_t pc);
 #endif /* QEMU_OPENRISC_EXCP_H */
diff --git a/target-openrisc/exception_helper.c 
b/target-openrisc/exception_helper.c
index dab4148..15b9c1f 100644
--- a/target-openrisc/exception_helper.c
+++ b/target-openrisc/exception_helper.c
@@ -25,5 +25,5 @@ void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));
 
-    raise_exception(cpu, excp);
+    do_raise_exception(cpu, excp, 0);
 }
diff --git a/target-openrisc/fpu_helper.c b/target-openrisc/fpu_helper.c
index b184d5e..c2890d5 100644
--- a/target-openrisc/fpu_helper.c
+++ b/target-openrisc/fpu_helper.c
@@ -51,17 +51,21 @@ static inline uint32_t ieee_ex_to_openrisc(OpenRISCCPU 
*cpu, int fexcp)
     return ret;
 }
 
-static inline void update_fpcsr(OpenRISCCPU *cpu)
+static inline void update_fpcsr(OpenRISCCPU *cpu, uintptr_t pc)
 {
     int tmp = ieee_ex_to_openrisc(cpu,
                               get_float_exception_flags(&cpu->env.fp_status));
 
     SET_FP_CAUSE(cpu->env.fpcsr, tmp);
-    if ((GET_FP_ENABLE(cpu->env.fpcsr) & tmp) &&
-        (cpu->env.fpcsr & FPCSR_FPEE)) {
-        helper_exception(&cpu->env, EXCP_FPE);
-    } else {
-        UPDATE_FP_FLAGS(cpu->env.fpcsr, tmp);
+    if (tmp) {
+        set_float_exception_flags(0, &cpu->env.fp_status);
+
+        if ((GET_FP_ENABLE(cpu->env.fpcsr) & tmp) &&
+            (cpu->env.fpcsr & FPCSR_FPEE)) {
+            do_raise_exception(cpu, EXCP_FPE, pc);
+        } else {
+            UPDATE_FP_FLAGS(cpu->env.fpcsr, tmp);
+        }
     }
 }
 
@@ -72,7 +76,7 @@ uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
 
     set_float_exception_flags(0, &cpu->env.fp_status);
     itofd = int32_to_float64(val, &cpu->env.fp_status);
-    update_fpcsr(cpu);
+    update_fpcsr(cpu, GETPC());
 
     return itofd;
 }
@@ -84,7 +88,7 @@ uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)
 
     set_float_exception_flags(0, &cpu->env.fp_status);
     itofs = int32_to_float32(val, &cpu->env.fp_status);
-    update_fpcsr(cpu);
+    update_fpcsr(cpu, GETPC());
 
     return itofs;
 }
@@ -96,7 +100,7 @@ uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val)
 
     set_float_exception_flags(0, &cpu->env.fp_status);
     ftoid = float32_to_int64(val, &cpu->env.fp_status);
-    update_fpcsr(cpu);
+    update_fpcsr(cpu, GETPC());
 
     return ftoid;
 }
@@ -108,7 +112,7 @@ uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val)
 
     set_float_exception_flags(0, &cpu->env.fp_status);
     ftois = float32_to_int32(val, &cpu->env.fp_status);
-    update_fpcsr(cpu);
+    update_fpcsr(cpu, GETPC());
 
     return ftois;
 }
@@ -123,7 +127,7 @@ uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, 
              \
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));                    \
     set_float_exception_flags(0, &cpu->env.fp_status);                    \
     result = float64_ ## name(fdt0, fdt1, &cpu->env.fp_status);           \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     return result;                                                        \
 }                                                                         \
                                                                           \
@@ -134,7 +138,7 @@ uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, 
              \
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));                    \
     set_float_exception_flags(0, &cpu->env.fp_status);                    \
     result = float32_ ## name(fdt0, fdt1, &cpu->env.fp_status);           \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     return result;                                                        \
 }                                                                         \
 
@@ -163,7 +167,7 @@ uint64_t helper_float_ ## name1 ## name2 ## 
_d(CPUOpenRISCState *env,     \
     result = float64_ ## name2(result, temp, &cpu->env.fp_status);        \
     val1 = result >> 32;                                                  \
     val2 = (uint32_t) (result & 0xffffffff);                              \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     cpu->env.fpmaddlo = val2;                                             \
     cpu->env.fpmaddhi = val1;                                             \
     return 0;                                                             \
@@ -183,7 +187,7 @@ uint32_t helper_float_ ## name1 ## name2 ## 
_s(CPUOpenRISCState *env,     \
     result = float64_ ## name2(result, temp, &cpu->env.fp_status);        \
     val1 = result >> 32;                                                  \
     val2 = (uint32_t) (result & 0xffffffff);                              \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     cpu->env.fpmaddlo = val2;                                             \
     cpu->env.fpmaddhi = val1;                                             \
     return 0;                                                             \
@@ -201,7 +205,7 @@ uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, 
              \
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));                    \
     set_float_exception_flags(0, &cpu->env.fp_status);                    \
     res = float64_ ## name(fdt0, fdt1, &cpu->env.fp_status);              \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     return res;                                                           \
 }                                                                         \
                                                                           \
@@ -212,7 +216,7 @@ uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, 
              \
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));                    \
     set_float_exception_flags(0, &cpu->env.fp_status);                    \
     res = float32_ ## name(fdt0, fdt1, &cpu->env.fp_status);              \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     return res;                                                           \
 }
 
@@ -230,7 +234,7 @@ uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, 
              \
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));                    \
     set_float_exception_flags(0, &cpu->env.fp_status);                    \
     res = !float64_eq_quiet(fdt0, fdt1, &cpu->env.fp_status);             \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     return res;                                                           \
 }                                                                         \
                                                                           \
@@ -241,7 +245,7 @@ uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, 
              \
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));                    \
     set_float_exception_flags(0, &cpu->env.fp_status);                    \
     res = !float32_eq_quiet(fdt0, fdt1, &cpu->env.fp_status);             \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     return res;                                                           \
 }
 
@@ -256,7 +260,7 @@ uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, 
              \
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));                    \
     set_float_exception_flags(0, &cpu->env.fp_status);                    \
     res = !float64_le(fdt0, fdt1, &cpu->env.fp_status);                   \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     return res;                                                           \
 }                                                                         \
                                                                           \
@@ -267,7 +271,7 @@ uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, 
              \
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));                    \
     set_float_exception_flags(0, &cpu->env.fp_status);                    \
     res = !float32_le(fdt0, fdt1, &cpu->env.fp_status);                   \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     return res;                                                           \
 }
 FLOAT_CMPGT(gt)
@@ -281,7 +285,7 @@ uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, 
              \
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));                    \
     set_float_exception_flags(0, &cpu->env.fp_status);                    \
     res = !float64_lt(fdt0, fdt1, &cpu->env.fp_status);                   \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     return res;                                                           \
 }                                                                         \
                                                                           \
@@ -292,7 +296,7 @@ uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, 
              \
     OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));                    \
     set_float_exception_flags(0, &cpu->env.fp_status);                    \
     res = !float32_lt(fdt0, fdt1, &cpu->env.fp_status);                   \
-    update_fpcsr(cpu);                                                    \
+    update_fpcsr(cpu, GETPC());                                           \
     return res;                                                           \
 }
 
diff --git a/target-openrisc/int_helper.c b/target-openrisc/int_helper.c
index 2fdfd27..46ec978 100644
--- a/target-openrisc/int_helper.c
+++ b/target-openrisc/int_helper.c
@@ -72,7 +72,7 @@ uint32_t HELPER(mul32)(CPUOpenRISCState *env,
 
     cpu->env.sr |= (SR_OV | SR_CY);
     if (cpu->env.sr & SR_OVE) {
-        raise_exception(cpu, EXCP_RANGE);
+        do_raise_exception(cpu, EXCP_RANGE, GETPC());
     }
 
     return result;
diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c
index 59ed371..8b687c0 100644
--- a/target-openrisc/mmu_helper.c
+++ b/target-openrisc/mmu_helper.c
@@ -19,6 +19,7 @@
  */
 
 #include "cpu.h"
+#include "exception.h"
 
 #ifndef CONFIG_USER_ONLY
 #include "softmmu_exec.h"
@@ -39,25 +40,13 @@
 void tlb_fill(CPUOpenRISCState *env, target_ulong addr, int is_write,
               int mmu_idx, uintptr_t retaddr)
 {
-    TranslationBlock *tb;
-    unsigned long pc;
     int ret;
 
+    OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));
     ret = cpu_openrisc_handle_mmu_fault(env, addr, is_write, mmu_idx);
 
     if (ret) {
-        if (retaddr) {
-            /* now we have a real cpu fault.  */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
-            if (tb) {
-                /* the PC is inside the translated code. It means that we
-                   have a virtual CPU fault.  */
-                cpu_restore_state(tb, env, pc);
-            }
-        }
-        /* Raise Exception.  */
-        cpu_loop_exit(env);
+        do_raise_exception_err(cpu, env->exception_index, retaddr); 
     }
 }
 #endif
-- 
1.7.10.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]