* [Qemu-devel] [PATCH_v3] add target-openrisc floating point exception
[not found] <Feng Gao>
@ 2012-12-06 23:53 ` Feng, Gao
0 siblings, 0 replies; 2+ messages in thread
From: Feng, Gao @ 2012-12-06 23:53 UTC (permalink / raw)
To: qemu-devel; +Cc: Feng Gao
From: Feng Gao <gf91597@gmail.com>
This patch complete target-openrisc floating point exception.
When float exception, the right PC can be saved, so exception handler
could do proper processing, and back to the right address letting the
program continue.
The patch I have tested it ok.
---
target-openrisc/exception.c | 23 +++++++++++++++--
target-openrisc/exception.h | 5 ++--
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, 55 insertions(+), 42 deletions(-)
diff --git a/target-openrisc/exception.c b/target-openrisc/exception.c
index 58e53c6..0377c43 100644
--- a/target-openrisc/exception.c
+++ b/target-openrisc/exception.c
@@ -20,8 +20,27 @@
#include "cpu.h"
#include "exception.h"
-void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp)
+void QEMU_NORETURN do_raise_exception(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);
}
diff --git a/target-openrisc/exception.h b/target-openrisc/exception.h
index 4b64430..b3cb687 100644
--- a/target-openrisc/exception.h
+++ b/target-openrisc/exception.h
@@ -23,6 +23,7 @@
#include "cpu.h"
#include "qemu-common.h"
-void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp);
-
+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..d7507db 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(cpu, env->exception_index, retaddr);
}
}
#endif
--
1.7.10.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [Qemu-devel] [PATCH_v3] add target-openrisc floating point exception
@ 2012-12-10 14:16 陳韋任 (Wei-Ren Chen)
0 siblings, 0 replies; 2+ messages in thread
From: 陳韋任 (Wei-Ren Chen) @ 2012-12-10 14:16 UTC (permalink / raw)
To: Feng Gao; +Cc: qemu-devel
Hi Feng,
One question,
> @@ -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);
> }
Shouldn't above helper function be called from the code cache?
The 3rd argument of do_raise_exception means if the exception comes
from code cache or not, iiuc. Is it correct to put zero here?
Regards,
chenwj
--
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-12-10 14:16 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <Feng Gao>
2012-12-06 23:53 ` [Qemu-devel] [PATCH_v3] add target-openrisc floating point exception Feng, Gao
2012-12-10 14:16 陳韋任 (Wei-Ren Chen)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).