From: Feng@gaofeng-K43SM.localdomain, Gao@gaofeng-K43SM.localdomain
To: qemu-devel@nongnu.org
Cc: Feng Gao <gf91597@gmail.com>
Subject: [Qemu-devel] [PATCH_v3] add target-openrisc floating point exception
Date: Fri, 7 Dec 2012 07:53:31 +0800 [thread overview]
Message-ID: <1354838011-5937-1-git-send-email-gf91597@gmail.com> (raw)
In-Reply-To: <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
next parent reply other threads:[~2012-12-07 0:42 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <Feng Gao>
2012-12-06 23:53 ` Feng, Gao [this message]
2012-12-10 14:16 [Qemu-devel] [PATCH_v3] add target-openrisc floating point exception 陳韋任 (Wei-Ren Chen)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1354838011-5937-1-git-send-email-gf91597@gmail.com \
--to=feng@gaofeng-k43sm.localdomain \
--cc=Gao@gaofeng-K43SM.localdomain \
--cc=gf91597@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).