Re: [Qemu-devel] [PATCH v4 3/5] target-mips: improve exceptions handling

2015-07-01 Thread Aurelien Jarno
On 2015-06-29 10:23, Pavel Dovgalyuk wrote:
> This patch improves exception handling in MIPS.
> Instructions generate several types of exceptions.
> When exception is generated, it breaks the execution of the current 
> translation
> block. Implementation of the exceptions handling does not correctly
> restore icount for the instruction which caused the exception. In most cases
> icount will be decreased by the value equal to the size of TB.
> This patch passes pointer to the translation block internals to the exception
> handler. It allows correct restoring of the icount value.
> 
> v3 changes:
> This patch stops translation when instruction which always generates exception
> is translated. This improves the performance of the patched version compared
> to original one.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  target-mips/cpu.h|   23 +++
>  target-mips/helper.h |1 
>  target-mips/msa_helper.c |  158 +++-
>  target-mips/op_helper.c  |  179 ++
>  target-mips/translate.c  |  372 
> ++
>  5 files changed, 368 insertions(+), 365 deletions(-)

[ snip ]

> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
> index 73a8e45..b562384 100644
> --- a/target-mips/op_helper.c
> +++ b/target-mips/op_helper.c

[ snip ]

> @@ -72,21 +54,21 @@ void helper_raise_exception(CPUMIPSState *env, uint32_t 
> exception)
>  #if defined(CONFIG_USER_ONLY)
>  #define HELPER_LD(name, insn, type) \
>  static inline type do_##name(CPUMIPSState *env, target_ulong addr,  \
> - int mem_idx)   \
> + int mem_idx, uintptr_t retaddr)\
>  {   \
> -return (type) cpu_##insn##_data(env, addr); \
> +return (type) cpu_##insn##_data_ra(env, addr, retaddr); \
>  }

You changed this, but as already said, your first patch doesn't providee
the cpu_##insn##_data_ra function. Also you forgot to update the caller of
this function, so it doesn't compile.

>  #else
>  #define HELPER_LD(name, insn, type) \
>  static inline type do_##name(CPUMIPSState *env, target_ulong addr,  \
> - int mem_idx)   \
> + int mem_idx, uintptr_t retaddr)\
>  {   \
>  switch (mem_idx)\
>  {   \
> -case 0: return (type) cpu_##insn##_kernel(env, addr); break;\
> -case 1: return (type) cpu_##insn##_super(env, addr); break; \
> +case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr);   \
> +case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr);\
>  default:\
> -case 2: return (type) cpu_##insn##_user(env, addr); break;  \
> +case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr); \
>  }   \
>  }
>  #endif
> @@ -106,14 +88,14 @@ static inline void do_##name(CPUMIPSState *env, 
> target_ulong addr,  \
>  #else
>  #define HELPER_ST(name, insn, type) \
>  static inline void do_##name(CPUMIPSState *env, target_ulong addr,  \
> - type val, int mem_idx) \
> + type val, int mem_idx, uintptr_t retaddr)  \
>  {   \
>  switch (mem_idx)\
>  {   \
> -case 0: cpu_##insn##_kernel(env, addr, val); break; \
> -case 1: cpu_##insn##_super(env, addr, val); break;  \
> +case 0: cpu_##insn##_kernel_ra(env, addr, val, retaddr); break; \
> +case 1: cpu_##insn##_super_ra(env, addr, val, retaddr); break;  \
>  default:\
> -case 2: cpu_##insn##_user(env, addr, val); break;   \
> +case 2: cpu_##insn##_user_ra(env, addr, val, retaddr); break;   \
>  }   \
>  }
>  #endif

[ snip ]

> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index fd063a2..85d374c 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -1677,15 +1677,21 @@ generate_exception_err (DisasContext *ctx, int excp, 
> int err)
>  gen_helper_raise_exception_err(cpu_env, texcp, terr);
>  tcg_temp_free_i

[Qemu-devel] [PATCH v4 3/5] target-mips: improve exceptions handling

2015-06-29 Thread Pavel Dovgalyuk
This patch improves exception handling in MIPS.
Instructions generate several types of exceptions.
When exception is generated, it breaks the execution of the current translation
block. Implementation of the exceptions handling does not correctly
restore icount for the instruction which caused the exception. In most cases
icount will be decreased by the value equal to the size of TB.
This patch passes pointer to the translation block internals to the exception
handler. It allows correct restoring of the icount value.

v3 changes:
This patch stops translation when instruction which always generates exception
is translated. This improves the performance of the patched version compared
to original one.

Signed-off-by: Pavel Dovgalyuk 
---
 target-mips/cpu.h|   23 +++
 target-mips/helper.h |1 
 target-mips/msa_helper.c |  158 +++-
 target-mips/op_helper.c  |  179 ++
 target-mips/translate.c  |  372 ++
 5 files changed, 368 insertions(+), 365 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index f9d2b4c..44d6e29 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -1015,4 +1015,27 @@ static inline void cpu_mips_store_cause(CPUMIPSState 
*env, target_ulong val)
 }
 #endif
 
+static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env,
+uint32_t exception,
+int error_code,
+uintptr_t pc)
+{
+CPUState *cs = CPU(mips_env_get_cpu(env));
+
+if (exception < EXCP_SC) {
+qemu_log("%s: %d %d\n", __func__, exception, error_code);
+}
+cs->exception_index = exception;
+env->error_code = error_code;
+
+cpu_loop_exit_restore(cs, pc);
+}
+
+static inline void QEMU_NORETURN do_raise_exception(CPUMIPSState *env,
+uint32_t exception,
+uintptr_t pc)
+{
+do_raise_exception_err(env, exception, 0, pc);
+}
+
 #endif /* !defined (__MIPS_CPU_H__) */
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 3bd0b02..50c699e 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -1,5 +1,6 @@
 DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int)
 DEF_HELPER_2(raise_exception, noreturn, env, i32)
+DEF_HELPER_1(raise_exception_debug, noreturn, env)
 
 #ifdef TARGET_MIPS64
 DEF_HELPER_4(sdl, void, env, tl, tl, int)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index 26ffdc7..b907b02 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -1352,7 +1352,7 @@ void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong 
elm, uint32_t cd)
 /* check exception */
 if ((GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)
 & GET_FP_CAUSE(env->active_tc.msacsr)) {
-helper_raise_exception(env, EXCP_MSAFPE);
+do_raise_exception(env, EXCP_MSAFPE, GETPC());
 }
 break;
 }
@@ -1505,14 +1505,14 @@ static inline void clear_msacsr_cause(CPUMIPSState *env)
 SET_FP_CAUSE(env->active_tc.msacsr, 0);
 }
 
-static inline void check_msacsr_cause(CPUMIPSState *env)
+static inline void check_msacsr_cause(CPUMIPSState *env, uintptr_t retaddr)
 {
 if ((GET_FP_CAUSE(env->active_tc.msacsr) &
 (GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)) == 0) {
 UPDATE_FP_FLAGS(env->active_tc.msacsr,
 GET_FP_CAUSE(env->active_tc.msacsr));
 } else {
-helper_raise_exception(env, EXCP_MSAFPE);
+do_raise_exception(env, EXCP_MSAFPE, retaddr);
 }
 }
 
@@ -1851,7 +1851,8 @@ static inline int32 float64_to_q32(float64 a, 
float_status *status)
 } while (0)
 
 static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-  wr_t *pwt, uint32_t df, int quiet)
+  wr_t *pwt, uint32_t df, int quiet,
+  uintptr_t retaddr)
 {
 wr_t wx, *pwx = &wx;
 uint32_t i;
@@ -1873,13 +1874,14 @@ static inline void compare_af(CPUMIPSState *env, wr_t 
*pwd, wr_t *pws,
 assert(0);
 }
 
-check_msacsr_cause(env);
+check_msacsr_cause(env, retaddr);
 
 msa_move_v(pwd, pwx);
 }
 
 static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-  wr_t *pwt, uint32_t df, int quiet)
+  wr_t *pwt, uint32_t df, int quiet,
+  uintptr_t retaddr)
 {
 wr_t wx, *pwx = &wx;
 uint32_t i;
@@ -1903,13 +1905,14 @@ static inline void compare_un(CPUMIPSState *env, wr_t 
*pwd, wr_t *pws,
 assert(0);
 }
 
-check_msacsr_cause(env);
+check_msacsr_cause(env, retaddr);
 
 msa_move_v(pwd, pwx);
 }
 
 static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t