[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] target-or32: Improve float exception
From: |
Feng Gao |
Subject: |
[Qemu-devel] [PATCH] target-or32: Improve float exception |
Date: |
Thu, 22 Nov 2012 10:10:04 +0800 |
From: gaofeng <address@hidden(none)>
When float exception raise, can save right pc.
Signed-off-by: Feng Gao <address@hidden>
---
target-openrisc/exception.c | 35 ++++++++++++++++++++++++++++--
target-openrisc/exception.h | 8 ++++++-
target-openrisc/fpu_helper.c | 48 +++++++++++++++++++++++-------------------
target-openrisc/mmu_helper.c | 17 +++------------
4 files changed, 69 insertions(+), 39 deletions(-)
diff --git a/target-openrisc/exception.c b/target-openrisc/exception.c
index 58e53c6..f37e32c 100644
--- a/target-openrisc/exception.c
+++ b/target-openrisc/exception.c
@@ -20,8 +20,39 @@
#include "cpu.h"
#include "exception.h"
-void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp)
+void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t exception)
{
- cpu->env.exception_index = excp;
+ do_raise_exception_err(cpu, exception, 0);
+}
+
+void QEMU_NORETURN do_raise_exception_err(OpenRISCCPU *cpu,
+ uint32_t exception,
+ uintptr_t pc)
+{
+ TranslationBlock *tb;
+#if 1
+ if (exception < 0x100)
+ qemu_log("%s: %d\n", __func__, exception);
+#endif
+ 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..1f0cd90 100644
--- a/target-openrisc/exception.h
+++ b/target-openrisc/exception.h
@@ -23,6 +23,12 @@
#include "cpu.h"
#include "qemu-common.h"
-void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp);
+void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t exception);
+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/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/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
- [Qemu-devel] [PATCH] target-or32: Improve float exception,
Feng Gao <=