[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v5 11/11] target-ppc: exceptions handling in ico
From: |
Aurelien Jarno |
Subject: |
Re: [Qemu-devel] [PATCH v5 11/11] target-ppc: exceptions handling in icount mode |
Date: |
Mon, 6 Jul 2015 14:21:23 +0200 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
On 2015-07-06 11:26, Pavel Dovgalyuk wrote:
> This patch fixes exception handling in PowerPC.
> 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.
With this patch, the ppc*-linux-user targets do not build:
| CC ppc-linux-user/target-ppc/excp_helper.o
| /home/aurel32/git/qemu/target-ppc/excp_helper.c:879:13: error:
‘raise_exception’ defined but not used [-Werror=unused-function]
| static void raise_exception(CPUPPCState *env, uint32_t exception, uintptr_t
pc)
| ^
| cc1: all warnings being treated as errors
| /home/aurel32/git/qemu/rules.mak:57: recipe for target
'target-ppc/excp_helper.o' failed
| make[1]: *** [target-ppc/excp_helper.o] Error 1
| Makefile:178: recipe for target 'subdir-ppc-linux-user' failed
| make: *** [subdir-ppc-linux-user] Error 2
> Signed-off-by: Pavel Dovgalyuk <address@hidden>
> ---
> target-ppc/cpu.h | 3 +
> target-ppc/excp_helper.c | 38 ++++++--
> target-ppc/fpu_helper.c | 191
> ++++++++++++++++++++++--------------------
> target-ppc/helper.h | 1
> target-ppc/mem_helper.c | 6 +
> target-ppc/misc_helper.c | 8 +-
> target-ppc/mmu-hash64.c | 12 +--
> target-ppc/mmu_helper.c | 18 ++--
> target-ppc/timebase_helper.c | 20 ++--
> target-ppc/translate.c | 84 +-----------------
> 10 files changed, 167 insertions(+), 214 deletions(-)
>
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index c05c503..27aaff8 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -2328,4 +2328,7 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu);
> */
> PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id);
>
> +void raise_exception_err(CPUPPCState *env, uint32_t exception,
> + uint32_t error_code, uintptr_t pc);
> +
> #endif /* !defined (__CPU_PPC_H__) */
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index b803475..5402e0d 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -846,8 +846,8 @@ static void cpu_dump_rfi(target_ulong RA, target_ulong
> msr)
>
> /*****************************************************************************/
> /* Exceptions processing helpers */
>
> -void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
> - uint32_t error_code)
> +void raise_exception_err(CPUPPCState *env, uint32_t exception,
> + uint32_t error_code, uintptr_t pc)
> {
> CPUState *cs = CPU(ppc_env_get_cpu(env));
>
> @@ -856,12 +856,29 @@ void helper_raise_exception_err(CPUPPCState *env,
> uint32_t exception,
> #endif
> cs->exception_index = exception;
> env->error_code = error_code;
> - cpu_loop_exit(cs);
> + cpu_loop_exit_restore(cs, pc);
> +}
> +
> +void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
> + uint32_t error_code)
> +{
> + raise_exception_err(env, exception, error_code, GETPC());
> +}
> +
> +void helper_raise_exception_end(CPUPPCState *env, uint32_t exception,
> + uint32_t error_code)
> +{
> + raise_exception_err(env, exception, error_code, 0);
> }
>
> void helper_raise_exception(CPUPPCState *env, uint32_t exception)
> {
> - helper_raise_exception_err(env, exception, 0);
> + raise_exception_err(env, exception, 0, GETPC());
> +}
> +
> +static void raise_exception(CPUPPCState *env, uint32_t exception, uintptr_t
> pc)
> +{
> + raise_exception_err(env, exception, 0, pc);
> }
>
> #if !defined(CONFIG_USER_ONLY)
> @@ -873,7 +890,8 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
> if (val != 0) {
> cs = CPU(ppc_env_get_cpu(env));
> cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
> - helper_raise_exception(env, val);
> + /* nip is updated by generated code */
> + raise_exception(env, val, 0);
> }
> }
>
> @@ -971,8 +989,9 @@ void helper_tw(CPUPPCState *env, target_ulong arg1,
> target_ulong arg2,
> ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
> ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
> ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_TRAP);
> + /* nip is updated in TB */
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_TRAP, 0);
> }
> }
>
> @@ -985,8 +1004,9 @@ void helper_td(CPUPPCState *env, target_ulong arg1,
> target_ulong arg2,
> ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
> ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
> ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_TRAP);
> + /* nip is updated in TB */
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_TRAP, 0);
> }
> }
> #endif
> diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
> index 6cceffc..088ad06 100644
> --- a/target-ppc/fpu_helper.c
> +++ b/target-ppc/fpu_helper.c
> @@ -116,7 +116,7 @@ void helper_compute_fprf(CPUPPCState *env, uint64_t arg)
>
> /* Floating-point invalid operations exception */
> static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op,
> - int set_fpcc)
> + int set_fpcc, uintptr_t retaddr)
> {
> CPUState *cs = CPU(ppc_env_get_cpu(env));
> uint64_t ret = 0;
> @@ -199,14 +199,14 @@ static inline uint64_t
> fload_invalid_op_excp(CPUPPCState *env, int op,
> /* Update the floating-point enabled exception summary */
> env->fpscr |= 1 << FPSCR_FEX;
> if (msr_fe0 != 0 || msr_fe1 != 0) {
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_FP | op);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_FP | op, retaddr);
> }
> }
> return ret;
> }
>
> -static inline void float_zero_divide_excp(CPUPPCState *env)
> +static inline void float_zero_divide_excp(CPUPPCState *env, uintptr_t
> retaddr)
> {
> env->fpscr |= 1 << FPSCR_ZX;
> env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
> @@ -216,8 +216,8 @@ static inline void float_zero_divide_excp(CPUPPCState
> *env)
> /* Update the floating-point enabled exception summary */
> env->fpscr |= 1 << FPSCR_FEX;
> if (msr_fe0 != 0 || msr_fe1 != 0) {
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX,
> retaddr);
> }
> }
> }
> @@ -490,13 +490,13 @@ void store_fpscr(CPUPPCState *env, uint64_t arg,
> uint32_t mask)
> helper_store_fpscr(env, arg, mask);
> }
>
> -void helper_float_check_status(CPUPPCState *env)
> +static void do_float_check_status(CPUPPCState *env, uintptr_t retaddr)
> {
> CPUState *cs = CPU(ppc_env_get_cpu(env));
> int status = get_float_exception_flags(&env->fp_status);
>
> if (status & float_flag_divbyzero) {
> - float_zero_divide_excp(env);
> + float_zero_divide_excp(env, retaddr);
> } else if (status & float_flag_overflow) {
> float_overflow_excp(env);
> } else if (status & float_flag_underflow) {
> @@ -509,12 +509,17 @@ void helper_float_check_status(CPUPPCState *env)
> (env->error_code & POWERPC_EXCP_FP)) {
> /* Differred floating-point exception after target FPR update */
> if (msr_fe0 != 0 || msr_fe1 != 0) {
> - helper_raise_exception_err(env, cs->exception_index,
> - env->error_code);
> + raise_exception_err(env, cs->exception_index,
> + env->error_code, retaddr);
> }
> }
> }
>
> +void helper_float_check_status(CPUPPCState *env)
> +{
> + do_float_check_status(env, GETPC());
> +}
> +
> void helper_reset_fpstatus(CPUPPCState *env)
> {
> set_float_exception_flags(0, &env->fp_status);
> @@ -531,12 +536,12 @@ uint64_t helper_fadd(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2)
> if (unlikely(float64_is_infinity(farg1.d) &&
> float64_is_infinity(farg2.d) &&
> float64_is_neg(farg1.d) != float64_is_neg(farg2.d))) {
> /* Magnitude subtraction of infinities */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1,
> GETPC());
> } else {
> if (unlikely(float64_is_signaling_nan(farg1.d) ||
> float64_is_signaling_nan(farg2.d))) {
> /* sNaN addition */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status);
> }
> @@ -555,12 +560,12 @@ uint64_t helper_fsub(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2)
> if (unlikely(float64_is_infinity(farg1.d) &&
> float64_is_infinity(farg2.d) &&
> float64_is_neg(farg1.d) == float64_is_neg(farg2.d))) {
> /* Magnitude subtraction of infinities */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1,
> GETPC());
> } else {
> if (unlikely(float64_is_signaling_nan(farg1.d) ||
> float64_is_signaling_nan(farg2.d))) {
> /* sNaN subtraction */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status);
> }
> @@ -579,12 +584,12 @@ uint64_t helper_fmul(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2)
> if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d))
> ||
> (float64_is_zero(farg1.d) &&
> float64_is_infinity(farg2.d)))) {
> /* Multiplication of zero by infinity */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1,
> GETPC());
> } else {
> if (unlikely(float64_is_signaling_nan(farg1.d) ||
> float64_is_signaling_nan(farg2.d))) {
> /* sNaN multiplication */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
> }
> @@ -603,15 +608,15 @@ uint64_t helper_fdiv(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2)
> if (unlikely(float64_is_infinity(farg1.d) &&
> float64_is_infinity(farg2.d))) {
> /* Division of infinity by infinity */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1,
> GETPC());
> } else if (unlikely(float64_is_zero(farg1.d) &&
> float64_is_zero(farg2.d))) {
> /* Division of zero by zero */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1,
> GETPC());
> } else {
> if (unlikely(float64_is_signaling_nan(farg1.d) ||
> float64_is_signaling_nan(farg2.d))) {
> /* sNaN division */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> farg1.d = float64_div(farg1.d, farg2.d, &env->fp_status);
> }
> @@ -630,16 +635,16 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg)
> \
> \
> if (unlikely(env->fp_status.float_exception_flags)) { \
> if (float64_is_any_nan(arg)) { \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1, GETPC());\
> if (float64_is_signaling_nan(arg)) { \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1,
> GETPC());\
> } \
> farg.ll = nanval; \
> } else if (env->fp_status.float_exception_flags & \
> float_flag_invalid) { \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1, GETPC());\
> } \
> - helper_float_check_status(env); \
> + do_float_check_status(env, GETPC()); \
> } \
> return farg.ll; \
> }
> @@ -664,7 +669,7 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg)
> \
> } else { \
> farg.d = cvtr(arg, &env->fp_status); \
> } \
> - helper_float_check_status(env); \
> + do_float_check_status(env, GETPC()); \
> return farg.ll; \
> }
>
> @@ -674,7 +679,7 @@ FPU_FCFI(fcfidu, uint64_to_float64, 0)
> FPU_FCFI(fcfidus, uint64_to_float32, 1)
>
> static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg,
> - int rounding_mode)
> + int rounding_mode, uint64_t retaddr)
> {
> CPU_DoubleU farg;
>
> @@ -682,7 +687,7 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t
> arg,
>
> if (unlikely(float64_is_signaling_nan(farg.d))) {
> /* sNaN round */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, retaddr);
> farg.ll = arg | 0x0008000000000000ULL;
> } else {
> int inexact = get_float_exception_flags(&env->fp_status) &
> @@ -697,28 +702,28 @@ static inline uint64_t do_fri(CPUPPCState *env,
> uint64_t arg,
> env->fp_status.float_exception_flags &= ~float_flag_inexact;
> }
> }
> - helper_float_check_status(env);
> + do_float_check_status(env, GETPC());
> return farg.ll;
> }
>
> uint64_t helper_frin(CPUPPCState *env, uint64_t arg)
> {
> - return do_fri(env, arg, float_round_ties_away);
> + return do_fri(env, arg, float_round_ties_away, GETPC());
> }
>
> uint64_t helper_friz(CPUPPCState *env, uint64_t arg)
> {
> - return do_fri(env, arg, float_round_to_zero);
> + return do_fri(env, arg, float_round_to_zero, GETPC());
> }
>
> uint64_t helper_frip(CPUPPCState *env, uint64_t arg)
> {
> - return do_fri(env, arg, float_round_up);
> + return do_fri(env, arg, float_round_up, GETPC());
> }
>
> uint64_t helper_frim(CPUPPCState *env, uint64_t arg)
> {
> - return do_fri(env, arg, float_round_down);
> + return do_fri(env, arg, float_round_down, GETPC());
> }
>
> /* fmadd - fmadd. */
> @@ -734,13 +739,13 @@ uint64_t helper_fmadd(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2,
> if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d))
> ||
> (float64_is_zero(farg1.d) &&
> float64_is_infinity(farg2.d)))) {
> /* Multiplication of zero by infinity */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1,
> GETPC());
> } else {
> if (unlikely(float64_is_signaling_nan(farg1.d) ||
> float64_is_signaling_nan(farg2.d) ||
> float64_is_signaling_nan(farg3.d))) {
> /* sNaN operation */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> /* This is the way the PowerPC specification defines it */
> float128 ft0_128, ft1_128;
> @@ -752,7 +757,7 @@ uint64_t helper_fmadd(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2,
> float64_is_infinity(farg3.d) &&
> float128_is_neg(ft0_128) != float64_is_neg(farg3.d))) {
> /* Magnitude subtraction of infinities */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1,
> GETPC());
> } else {
> ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
> ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
> @@ -777,13 +782,13 @@ uint64_t helper_fmsub(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2,
> (float64_is_zero(farg1.d) &&
> float64_is_infinity(farg2.d)))) {
> /* Multiplication of zero by infinity */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1,
> GETPC());
> } else {
> if (unlikely(float64_is_signaling_nan(farg1.d) ||
> float64_is_signaling_nan(farg2.d) ||
> float64_is_signaling_nan(farg3.d))) {
> /* sNaN operation */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> /* This is the way the PowerPC specification defines it */
> float128 ft0_128, ft1_128;
> @@ -795,7 +800,7 @@ uint64_t helper_fmsub(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2,
> float64_is_infinity(farg3.d) &&
> float128_is_neg(ft0_128) == float64_is_neg(farg3.d))) {
> /* Magnitude subtraction of infinities */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1,
> GETPC());
> } else {
> ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
> ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
> @@ -818,13 +823,13 @@ uint64_t helper_fnmadd(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2,
> if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d))
> ||
> (float64_is_zero(farg1.d) &&
> float64_is_infinity(farg2.d)))) {
> /* Multiplication of zero by infinity */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1,
> GETPC());
> } else {
> if (unlikely(float64_is_signaling_nan(farg1.d) ||
> float64_is_signaling_nan(farg2.d) ||
> float64_is_signaling_nan(farg3.d))) {
> /* sNaN operation */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> /* This is the way the PowerPC specification defines it */
> float128 ft0_128, ft1_128;
> @@ -836,7 +841,7 @@ uint64_t helper_fnmadd(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2,
> float64_is_infinity(farg3.d) &&
> float128_is_neg(ft0_128) != float64_is_neg(farg3.d))) {
> /* Magnitude subtraction of infinities */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1,
> GETPC());
> } else {
> ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
> ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
> @@ -863,13 +868,13 @@ uint64_t helper_fnmsub(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2,
> (float64_is_zero(farg1.d) &&
> float64_is_infinity(farg2.d)))) {
> /* Multiplication of zero by infinity */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1,
> GETPC());
> } else {
> if (unlikely(float64_is_signaling_nan(farg1.d) ||
> float64_is_signaling_nan(farg2.d) ||
> float64_is_signaling_nan(farg3.d))) {
> /* sNaN operation */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> /* This is the way the PowerPC specification defines it */
> float128 ft0_128, ft1_128;
> @@ -881,7 +886,7 @@ uint64_t helper_fnmsub(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2,
> float64_is_infinity(farg3.d) &&
> float128_is_neg(ft0_128) == float64_is_neg(farg3.d))) {
> /* Magnitude subtraction of infinities */
> - farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
> + farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1,
> GETPC());
> } else {
> ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
> ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
> @@ -904,7 +909,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
>
> if (unlikely(float64_is_signaling_nan(farg.d))) {
> /* sNaN square root */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> f32 = float64_to_float32(farg.d, &env->fp_status);
> farg.d = float32_to_float64(f32, &env->fp_status);
> @@ -922,12 +927,12 @@ uint64_t helper_fsqrt(CPUPPCState *env, uint64_t arg)
> if (unlikely(float64_is_any_nan(farg.d))) {
> if (unlikely(float64_is_signaling_nan(farg.d))) {
> /* sNaN reciprocal square root */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> farg.ll = float64_snan_to_qnan(farg.ll);
> }
> } else if (unlikely(float64_is_neg(farg.d) && !float64_is_zero(farg.d)))
> {
> /* Square root of a negative nonzero number */
> - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1);
> + farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1,
> GETPC());
> } else {
> farg.d = float64_sqrt(farg.d, &env->fp_status);
> }
> @@ -943,7 +948,7 @@ uint64_t helper_fre(CPUPPCState *env, uint64_t arg)
>
> if (unlikely(float64_is_signaling_nan(farg.d))) {
> /* sNaN reciprocal */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> farg.d = float64_div(float64_one, farg.d, &env->fp_status);
> return farg.d;
> @@ -959,7 +964,7 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg)
>
> if (unlikely(float64_is_signaling_nan(farg.d))) {
> /* sNaN reciprocal */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> farg.d = float64_div(float64_one, farg.d, &env->fp_status);
> f32 = float64_to_float32(farg.d, &env->fp_status);
> @@ -978,12 +983,12 @@ uint64_t helper_frsqrte(CPUPPCState *env, uint64_t arg)
> if (unlikely(float64_is_any_nan(farg.d))) {
> if (unlikely(float64_is_signaling_nan(farg.d))) {
> /* sNaN reciprocal square root */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> farg.ll = float64_snan_to_qnan(farg.ll);
> }
> } else if (unlikely(float64_is_neg(farg.d) && !float64_is_zero(farg.d)))
> {
> /* Reciprocal square root of a negative nonzero number */
> - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1);
> + farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1,
> GETPC());
> } else {
> farg.d = float64_sqrt(farg.d, &env->fp_status);
> farg.d = float64_div(float64_one, farg.d, &env->fp_status);
> @@ -1102,7 +1107,7 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2,
> && (float64_is_signaling_nan(farg1.d) ||
> float64_is_signaling_nan(farg2.d)))) {
> /* sNaN comparison */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC());
> }
> }
>
> @@ -1134,10 +1139,10 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1,
> uint64_t arg2,
> float64_is_signaling_nan(farg2.d)) {
> /* sNaN comparison */
> fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
> - POWERPC_EXCP_FP_VXVC, 1);
> + POWERPC_EXCP_FP_VXVC, 1, GETPC());
> } else {
> /* qNaN comparison */
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 1);
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 1, GETPC());
> }
> }
> }
> @@ -1837,10 +1842,10 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)
> \
>
> \
> if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
> \
> if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf,
> GETPC());\
> } else if (tp##_is_signaling_nan(xa.fld) ||
> \
> tp##_is_signaling_nan(xb.fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf,
> GETPC());\
> }
> \
> }
> \
>
> \
> @@ -1853,7 +1858,7 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)
> \
> }
> \
> }
> \
> putVSR(xT(opcode), &xt, env);
> \
> - helper_float_check_status(env);
> \
> + do_float_check_status(env, GETPC());
> \
> }
>
> VSX_ADD_SUB(xsadddp, add, 1, float64, VsrD(0), 1, 0)
> @@ -1892,10 +1897,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
> \
> if ((tp##_is_infinity(xa.fld) && tp##_is_zero(xb.fld)) ||
> \
> (tp##_is_infinity(xb.fld) && tp##_is_zero(xa.fld))) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, sfprf,
> GETPC());\
> } else if (tp##_is_signaling_nan(xa.fld) ||
> \
> tp##_is_signaling_nan(xb.fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf,
> GETPC());\
> }
> \
> }
> \
>
> \
> @@ -1909,7 +1914,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> }
> \
>
> \
> putVSR(xT(opcode), &xt, env);
> \
> - helper_float_check_status(env);
> \
> + do_float_check_status(env, GETPC());
> \
> }
>
> VSX_MUL(xsmuldp, 1, float64, VsrD(0), 1, 0)
> @@ -1943,13 +1948,13 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
>
> \
> if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
> \
> if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, sfprf,
> GETPC());\
> } else if (tp##_is_zero(xa.fld) &&
> \
> tp##_is_zero(xb.fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf,
> GETPC());\
> } else if (tp##_is_signaling_nan(xa.fld) ||
> \
> tp##_is_signaling_nan(xb.fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf,
> GETPC());\
> }
> \
> }
> \
>
> \
> @@ -1963,7 +1968,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> }
> \
>
> \
> putVSR(xT(opcode), &xt, env);
> \
> - helper_float_check_status(env);
> \
> + do_float_check_status(env, GETPC());
> \
> }
>
> VSX_DIV(xsdivdp, 1, float64, VsrD(0), 1, 0)
> @@ -1990,7 +1995,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
>
> \
> for (i = 0; i < nels; i++) {
> \
> if (unlikely(tp##_is_signaling_nan(xb.fld))) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf,
> GETPC());\
> }
> \
> xt.fld = tp##_div(tp##_one, xb.fld, &env->fp_status);
> \
>
> \
> @@ -2004,7 +2009,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> }
> \
>
> \
> putVSR(xT(opcode), &xt, env);
> \
> - helper_float_check_status(env);
> \
> + do_float_check_status(env, GETPC());
> \
> }
>
> VSX_RE(xsredp, 1, float64, VsrD(0), 1, 0)
> @@ -2037,9 +2042,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
>
> \
> if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
> \
> if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf,
> GETPC());\
> } else if (tp##_is_signaling_nan(xb.fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf,
> GETPC());\
> }
> \
> }
> \
>
> \
> @@ -2053,7 +2058,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> }
> \
>
> \
> putVSR(xT(opcode), &xt, env);
> \
> - helper_float_check_status(env);
> \
> + do_float_check_status(env, GETPC());
> \
> }
>
> VSX_SQRT(xssqrtdp, 1, float64, VsrD(0), 1, 0)
> @@ -2087,9 +2092,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
>
> \
> if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
> \
> if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf,
> GETPC());\
> } else if (tp##_is_signaling_nan(xb.fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf,
> GETPC());\
> }
> \
> }
> \
>
> \
> @@ -2103,7 +2108,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> }
> \
>
> \
> putVSR(xT(opcode), &xt, env);
> \
> - helper_float_check_status(env);
> \
> + do_float_check_status(env, GETPC());
> \
> }
>
> VSX_RSQRTE(xsrsqrtedp, 1, float64, VsrD(0), 1, 0)
> @@ -2276,20 +2281,20 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> if (tp##_is_signaling_nan(xa.fld) ||
> \
> tp##_is_signaling_nan(b->fld) ||
> \
> tp##_is_signaling_nan(c->fld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf,
> GETPC());\
> tstat.float_exception_flags &= ~float_flag_invalid;
> \
> }
> \
> if ((tp##_is_infinity(xa.fld) && tp##_is_zero(b->fld)) ||
> \
> (tp##_is_zero(xa.fld) && tp##_is_infinity(b->fld))) {
> \
> xt_out.fld = float64_to_##tp(fload_invalid_op_excp(env,
> \
> - POWERPC_EXCP_FP_VXIMZ, sfprf), &env->fp_status);
> \
> + POWERPC_EXCP_FP_VXIMZ, sfprf, GETPC()),
> &env->fp_status); \
> tstat.float_exception_flags &= ~float_flag_invalid;
> \
> }
> \
> if ((tstat.float_exception_flags & float_flag_invalid) &&
> \
> ((tp##_is_infinity(xa.fld) ||
> \
> tp##_is_infinity(b->fld)) &&
> \
> tp##_is_infinity(c->fld))) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf,
> GETPC());\
> }
> \
> }
> \
>
> \
> @@ -2302,7 +2307,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> }
> \
> }
> \
> putVSR(xT(opcode), &xt_out, env);
> \
> - helper_float_check_status(env);
> \
> + do_float_check_status(env, GETPC());
> \
> }
>
> #define MADD_FLGS 0
> @@ -2359,10 +2364,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> float64_is_any_nan(xb.VsrD(0)))) { \
> if (float64_is_signaling_nan(xa.VsrD(0)) || \
> float64_is_signaling_nan(xb.VsrD(0))) { \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC());\
> } \
> if (ordered) { \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0, GETPC());\
> } \
> cc = 1; \
> } else { \
> @@ -2380,7 +2385,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> env->fpscr |= cc << FPSCR_FPRF; \
> env->crf[BF(opcode)] = cc; \
> \
> - helper_float_check_status(env); \
> + do_float_check_status(env, GETPC()); \
> }
>
> VSX_SCALAR_CMP(xscmpodp, 1)
> @@ -2407,12 +2412,12 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)
> \
> xt.fld = tp##_##op(xa.fld, xb.fld, &env->fp_status);
> \
> if (unlikely(tp##_is_signaling_nan(xa.fld) ||
> \
> tp##_is_signaling_nan(xb.fld))) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC());
> \
> }
> \
> }
> \
>
> \
> putVSR(xT(opcode), &xt, env);
> \
> - helper_float_check_status(env);
> \
> + do_float_check_status(env, GETPC());
> \
> }
>
> VSX_MAX_MIN(xsmaxdp, maxnum, 1, float64, VsrD(0))
> @@ -2447,10 +2452,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> tp##_is_any_nan(xb.fld))) { \
> if (tp##_is_signaling_nan(xa.fld) || \
> tp##_is_signaling_nan(xb.fld)) { \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0,
> GETPC());\
> } \
> if (svxvc) { \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0,
> GETPC());\
> } \
> xt.fld = 0; \
> all_true = 0; \
> @@ -2469,7 +2474,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> if ((opcode >> (31-21)) & 1) { \
> env->crf[6] = (all_true ? 0x8 : 0) | (all_false ? 0x2 : 0); \
> } \
> - helper_float_check_status(env); \
> + do_float_check_status(env, GETPC()); \
> }
>
> VSX_CMP(xvcmpeqdp, 2, float64, VsrD(i), eq, 0)
> @@ -2500,7 +2505,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> for (i = 0; i < nels; i++) { \
> xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
> if (unlikely(stp##_is_signaling_nan(xb.sfld))) { \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC()); \
> xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
> } \
> if (sfprf) { \
> @@ -2510,7 +2515,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> } \
> \
> putVSR(xT(opcode), &xt, env); \
> - helper_float_check_status(env); \
> + do_float_check_status(env, GETPC()); \
> }
>
> VSX_CVT_FP_TO_FP(xscvdpsp, 1, float64, float32, VsrD(0), VsrW(0), 1)
> @@ -2555,21 +2560,21 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> for (i = 0; i < nels; i++) {
> \
> if (unlikely(stp##_is_any_nan(xb.sfld))) {
> \
> if (stp##_is_signaling_nan(xb.sfld)) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0,
> GETPC());\
> }
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0, GETPC());
> \
> xt.tfld = rnan;
> \
> } else {
> \
> xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld,
> \
> &env->fp_status);
> \
> if (env->fp_status.float_exception_flags & float_flag_invalid) {
> \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0);
> \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0,
> GETPC());\
> }
> \
> }
> \
> }
> \
>
> \
> putVSR(xT(opcode), &xt, env);
> \
> - helper_float_check_status(env);
> \
> + do_float_check_status(env, GETPC());
> \
> }
>
> VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, VsrD(0), VsrD(0), \
> @@ -2620,7 +2625,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> } \
> \
> putVSR(xT(opcode), &xt, env); \
> - helper_float_check_status(env); \
> + do_float_check_status(env, GETPC()); \
> }
>
> VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, VsrD(0), VsrD(0), 1, 0)
> @@ -2664,7 +2669,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> \
> for (i = 0; i < nels; i++) { \
> if (unlikely(tp##_is_signaling_nan(xb.fld))) { \
> - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
> + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC());\
> xt.fld = tp##_snan_to_qnan(xb.fld); \
> } else { \
> xt.fld = tp##_round_to_int(xb.fld, &env->fp_status); \
> @@ -2683,7 +2688,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)
> \
> } \
> \
> putVSR(xT(opcode), &xt, env); \
> - helper_float_check_status(env); \
> + do_float_check_status(env, GETPC()); \
> }
>
> VSX_ROUND(xsrdpi, 1, float64, VsrD(0), float_round_nearest_even, 1)
> @@ -2711,6 +2716,6 @@ uint64_t helper_xsrsp(CPUPPCState *env, uint64_t xb)
> uint64_t xt = helper_frsp(env, xb);
>
> helper_compute_fprf(env, xt);
> - helper_float_check_status(env);
> + do_float_check_status(env, GETPC());
> return xt;
> }
> diff --git a/target-ppc/helper.h b/target-ppc/helper.h
> index 869be15..fee2dd1 100644
> --- a/target-ppc/helper.h
> +++ b/target-ppc/helper.h
> @@ -1,4 +1,5 @@
> DEF_HELPER_3(raise_exception_err, void, env, i32, i32)
> +DEF_HELPER_3(raise_exception_end, void, env, i32, i32)
> DEF_HELPER_2(raise_exception, void, env, i32)
> DEF_HELPER_4(tw, void, env, tl, tl, i32)
> #if defined(TARGET_PPC64)
> diff --git a/target-ppc/mem_helper.c b/target-ppc/mem_helper.c
> index 6d37dae..1c67562 100644
> --- a/target-ppc/mem_helper.c
> +++ b/target-ppc/mem_helper.c
> @@ -102,9 +102,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr,
> uint32_t reg,
> if (likely(xer_bc != 0)) {
> if (unlikely((ra != 0 && reg < ra && (reg + xer_bc) > ra) ||
> (reg < rb && (reg + xer_bc) > rb))) {
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_INVAL |
> - POWERPC_EXCP_INVAL_LSWX);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_INVAL |
> + POWERPC_EXCP_INVAL_LSWX, GETPC());
> } else {
> helper_lsw(env, addr, xer_bc, reg);
> }
> diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c
> index 6b12ca8..1596187 100644
> --- a/target-ppc/misc_helper.c
> +++ b/target-ppc/misc_helper.c
> @@ -37,7 +37,7 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn)
>
> #ifdef TARGET_PPC64
> static void raise_fu_exception(CPUPPCState *env, uint32_t bit,
> - uint32_t sprn, uint32_t cause)
> + uint32_t sprn, uint32_t cause, uintptr_t
> retaddr)
> {
> qemu_log("Facility SPR %d is unavailable (SPR FSCR:%d)\n", sprn, bit);
>
> @@ -45,7 +45,7 @@ static void raise_fu_exception(CPUPPCState *env, uint32_t
> bit,
> cause &= FSCR_IC_MASK;
> env->spr[SPR_FSCR] |= (target_ulong)cause << FSCR_IC_POS;
>
> - helper_raise_exception_err(env, POWERPC_EXCP_FU, 0);
> + raise_exception_err(env, POWERPC_EXCP_FU, 0, retaddr);
> }
> #endif
>
> @@ -57,7 +57,7 @@ void helper_fscr_facility_check(CPUPPCState *env, uint32_t
> bit,
> /* Facility is enabled, continue */
> return;
> }
> - raise_fu_exception(env, bit, sprn, cause);
> + raise_fu_exception(env, bit, sprn, cause, GETPC());
> #endif
> }
>
> @@ -69,7 +69,7 @@ void helper_msr_facility_check(CPUPPCState *env, uint32_t
> bit,
> /* Facility is enabled, continue */
> return;
> }
> - raise_fu_exception(env, bit, sprn, cause);
> + raise_fu_exception(env, bit, sprn, cause, GETPC());
> #endif
> }
>
> diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
> index 7df6ede..7f22706 100644
> --- a/target-ppc/mmu-hash64.c
> +++ b/target-ppc/mmu-hash64.c
> @@ -197,8 +197,8 @@ static int ppc_load_slb_vsid(CPUPPCState *env,
> target_ulong rb,
> void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs)
> {
> if (ppc_store_slb(env, rb, rs) < 0) {
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_INVAL);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_INVAL, GETPC());
> }
> }
>
> @@ -207,8 +207,8 @@ target_ulong helper_load_slb_esid(CPUPPCState *env,
> target_ulong rb)
> target_ulong rt = 0;
>
> if (ppc_load_slb_esid(env, rb, &rt) < 0) {
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_INVAL);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_INVAL, GETPC());
> }
> return rt;
> }
> @@ -218,8 +218,8 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env,
> target_ulong rb)
> target_ulong rt = 0;
>
> if (ppc_load_slb_vsid(env, rb, &rt) < 0) {
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_INVAL);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_INVAL, GETPC());
> }
> return rt;
> }
> diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
> index 527c6ad..acd266f 100644
> --- a/target-ppc/mmu_helper.c
> +++ b/target-ppc/mmu_helper.c
> @@ -2635,9 +2635,9 @@ void helper_booke206_tlbwe(CPUPPCState *env)
> tlb = booke206_cur_tlb(env);
>
> if (!tlb) {
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_INVAL |
> - POWERPC_EXCP_INVAL_INVAL);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_INVAL |
> + POWERPC_EXCP_INVAL_INVAL, GETPC());
> }
>
> /* check that we support the targeted size */
> @@ -2645,9 +2645,9 @@ void helper_booke206_tlbwe(CPUPPCState *env)
> size_ps = booke206_tlbnps(env, tlbn);
> if ((env->spr[SPR_BOOKE_MAS1] & MAS1_VALID) && (tlbncfg & TLBnCFG_AVAIL)
> &&
> !(size_ps & (1 << size_tlb))) {
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_INVAL |
> - POWERPC_EXCP_INVAL_INVAL);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_INVAL |
> + POWERPC_EXCP_INVAL_INVAL, GETPC());
> }
>
> if (msr_gs) {
> @@ -2924,10 +2924,6 @@ void tlb_fill(CPUState *cs, target_ulong addr, int
> is_write, int mmu_idx,
> ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx);
> }
> if (unlikely(ret != 0)) {
> - if (likely(retaddr)) {
> - /* now we have a real cpu fault */
> - cpu_restore_state(cs, retaddr);
> - }
> - helper_raise_exception_err(env, cs->exception_index,
> env->error_code);
> + raise_exception_err(env, cs->exception_index, env->error_code,
> retaddr);
> }
> }
> diff --git a/target-ppc/timebase_helper.c b/target-ppc/timebase_helper.c
> index 865dcbe..229523c 100644
> --- a/target-ppc/timebase_helper.c
> +++ b/target-ppc/timebase_helper.c
> @@ -131,14 +131,14 @@ target_ulong helper_load_dcr(CPUPPCState *env,
> target_ulong dcrn)
>
> if (unlikely(env->dcr_env == NULL)) {
> qemu_log("No DCR environment\n");
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_INVAL |
> - POWERPC_EXCP_INVAL_INVAL);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_INVAL |
> + POWERPC_EXCP_INVAL_INVAL, GETPC());
> } else if (unlikely(ppc_dcr_read(env->dcr_env,
> (uint32_t)dcrn, &val) != 0)) {
> qemu_log("DCR read error %d %03x\n", (uint32_t)dcrn, (uint32_t)dcrn);
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_INVAL |
> POWERPC_EXCP_PRIV_REG);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG,
> GETPC());
> }
> return val;
> }
> @@ -147,13 +147,13 @@ void helper_store_dcr(CPUPPCState *env, target_ulong
> dcrn, target_ulong val)
> {
> if (unlikely(env->dcr_env == NULL)) {
> qemu_log("No DCR environment\n");
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_INVAL |
> - POWERPC_EXCP_INVAL_INVAL);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_INVAL |
> + POWERPC_EXCP_INVAL_INVAL, GETPC());
> } else if (unlikely(ppc_dcr_write(env->dcr_env, (uint32_t)dcrn,
> (uint32_t)val) != 0)) {
> qemu_log("DCR write error %d %03x\n", (uint32_t)dcrn,
> (uint32_t)dcrn);
> - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> - POWERPC_EXCP_INVAL |
> POWERPC_EXCP_PRIV_REG);
> + raise_exception_err(env, POWERPC_EXCP_PROGRAM,
> + POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG,
> GETPC());
> }
> }
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 84c5cea..fd5b503 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -288,7 +288,7 @@ static inline void gen_exception_err(DisasContext *ctx,
> uint32_t excp, uint32_t
> }
> t0 = tcg_const_i32(excp);
> t1 = tcg_const_i32(error);
> - gen_helper_raise_exception_err(cpu_env, t0, t1);
> + gen_helper_raise_exception_end(cpu_env, t0, t1);
> tcg_temp_free_i32(t0);
> tcg_temp_free_i32(t1);
> ctx->exception = (excp);
> @@ -296,14 +296,7 @@ static inline void gen_exception_err(DisasContext *ctx,
> uint32_t excp, uint32_t
>
> static inline void gen_exception(DisasContext *ctx, uint32_t excp)
> {
> - TCGv_i32 t0;
> - if (ctx->exception == POWERPC_EXCP_NONE) {
> - gen_update_nip(ctx, ctx->nip);
> - }
> - t0 = tcg_const_i32(excp);
> - gen_helper_raise_exception(cpu_env, t0);
> - tcg_temp_free_i32(t0);
> - ctx->exception = (excp);
> + gen_exception_err(ctx, excp, 0);
> }
>
> static inline void gen_debug_exception(DisasContext *ctx)
> @@ -2090,8 +2083,6 @@ static void gen_f##name(DisasContext *ctx)
> \
> gen_exception(ctx, POWERPC_EXCP_FPU);
> \
> return;
> \
> }
> \
> - /* NIP cannot be restored if the memory exception comes from an helper
> */ \
> - gen_update_nip(ctx, ctx->nip - 4);
> \
> gen_reset_fpstatus();
> \
> gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,
> \
> cpu_fpr[rA(ctx->opcode)],
> \
> @@ -2119,8 +2110,6 @@ static void gen_f##name(DisasContext *ctx)
> \
> gen_exception(ctx, POWERPC_EXCP_FPU);
> \
> return;
> \
> }
> \
> - /* NIP cannot be restored if the memory exception comes from an helper
> */ \
> - gen_update_nip(ctx, ctx->nip - 4);
> \
> gen_reset_fpstatus();
> \
> gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,
> \
> cpu_fpr[rA(ctx->opcode)],
> \
> @@ -2147,8 +2136,6 @@ static void gen_f##name(DisasContext *ctx)
> \
> gen_exception(ctx, POWERPC_EXCP_FPU);
> \
> return;
> \
> }
> \
> - /* NIP cannot be restored if the memory exception comes from an helper
> */ \
> - gen_update_nip(ctx, ctx->nip - 4);
> \
> gen_reset_fpstatus();
> \
> gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,
> \
> cpu_fpr[rA(ctx->opcode)],
> \
> @@ -2175,8 +2162,6 @@ static void gen_f##name(DisasContext *ctx)
> \
> gen_exception(ctx, POWERPC_EXCP_FPU);
> \
> return;
> \
> }
> \
> - /* NIP cannot be restored if the memory exception comes from an helper
> */ \
> - gen_update_nip(ctx, ctx->nip - 4);
> \
> gen_reset_fpstatus();
> \
> gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env,
> \
> cpu_fpr[rB(ctx->opcode)]);
> \
> @@ -2195,8 +2180,6 @@ static void gen_f##name(DisasContext *ctx)
> \
> gen_exception(ctx, POWERPC_EXCP_FPU);
> \
> return;
> \
> }
> \
> - /* NIP cannot be restored if the memory exception comes from an helper
> */ \
> - gen_update_nip(ctx, ctx->nip - 4);
> \
> gen_reset_fpstatus();
> \
> gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env,
> \
> cpu_fpr[rB(ctx->opcode)]);
> \
> @@ -2231,8 +2214,6 @@ static void gen_frsqrtes(DisasContext *ctx)
> gen_exception(ctx, POWERPC_EXCP_FPU);
> return;
> }
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_reset_fpstatus();
> gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_env,
> cpu_fpr[rB(ctx->opcode)]);
> @@ -2257,8 +2238,6 @@ static void gen_fsqrt(DisasContext *ctx)
> gen_exception(ctx, POWERPC_EXCP_FPU);
> return;
> }
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_reset_fpstatus();
> gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
> cpu_fpr[rB(ctx->opcode)]);
> @@ -2274,8 +2253,6 @@ static void gen_fsqrts(DisasContext *ctx)
> gen_exception(ctx, POWERPC_EXCP_FPU);
> return;
> }
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_reset_fpstatus();
> gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
> cpu_fpr[rB(ctx->opcode)]);
> @@ -2365,8 +2342,6 @@ static void gen_fcmpo(DisasContext *ctx)
> gen_exception(ctx, POWERPC_EXCP_FPU);
> return;
> }
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_reset_fpstatus();
> crf = tcg_const_i32(crfD(ctx->opcode));
> gen_helper_fcmpo(cpu_env, cpu_fpr[rA(ctx->opcode)],
> @@ -2383,8 +2358,6 @@ static void gen_fcmpu(DisasContext *ctx)
> gen_exception(ctx, POWERPC_EXCP_FPU);
> return;
> }
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_reset_fpstatus();
> crf = tcg_const_i32(crfD(ctx->opcode));
> gen_helper_fcmpu(cpu_env, cpu_fpr[rA(ctx->opcode)],
> @@ -2541,8 +2514,6 @@ static void gen_mtfsb0(DisasContext *ctx)
> gen_reset_fpstatus();
> if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
> TCGv_i32 t0;
> - /* NIP cannot be restored if the memory exception comes from an
> helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> t0 = tcg_const_i32(crb);
> gen_helper_fpscr_clrbit(cpu_env, t0);
> tcg_temp_free_i32(t0);
> @@ -2567,8 +2538,6 @@ static void gen_mtfsb1(DisasContext *ctx)
> /* XXX: we pretend we can only do IEEE floating-point computations */
> if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
> TCGv_i32 t0;
> - /* NIP cannot be restored if the memory exception comes from an
> helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> t0 = tcg_const_i32(crb);
> gen_helper_fpscr_setbit(cpu_env, t0);
> tcg_temp_free_i32(t0);
> @@ -2598,8 +2567,6 @@ static void gen_mtfsf(DisasContext *ctx)
> gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
> return;
> }
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_reset_fpstatus();
> if (l) {
> t0 = tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff :
> 0xff);
> @@ -2634,8 +2601,6 @@ static void gen_mtfsfi(DisasContext *ctx)
> return;
> }
> sh = (8 * w) + 7 - bf;
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_reset_fpstatus();
> t0 = tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh));
> t1 = tcg_const_i32(1 << sh);
> @@ -2718,8 +2683,6 @@ static inline void gen_check_align(DisasContext *ctx,
> TCGv EA, int mask)
> TCGLabel *l1 = gen_new_label();
> TCGv t0 = tcg_temp_new();
> TCGv_i32 t1, t2;
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> tcg_gen_andi_tl(t0, EA, mask);
> tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
> t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
> @@ -3167,8 +3130,6 @@ static void gen_lmw(DisasContext *ctx)
> TCGv t0;
> TCGv_i32 t1;
> gen_set_access_type(ctx, ACCESS_INT);
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> t0 = tcg_temp_new();
> t1 = tcg_const_i32(rD(ctx->opcode));
> gen_addr_imm_index(ctx, t0, 0);
> @@ -3183,8 +3144,6 @@ static void gen_stmw(DisasContext *ctx)
> TCGv t0;
> TCGv_i32 t1;
> gen_set_access_type(ctx, ACCESS_INT);
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> t0 = tcg_temp_new();
> t1 = tcg_const_i32(rS(ctx->opcode));
> gen_addr_imm_index(ctx, t0, 0);
> @@ -3220,8 +3179,6 @@ static void gen_lswi(DisasContext *ctx)
> return;
> }
> gen_set_access_type(ctx, ACCESS_INT);
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> t0 = tcg_temp_new();
> gen_addr_register(ctx, t0);
> t1 = tcg_const_i32(nb);
> @@ -3238,8 +3195,6 @@ static void gen_lswx(DisasContext *ctx)
> TCGv t0;
> TCGv_i32 t1, t2, t3;
> gen_set_access_type(ctx, ACCESS_INT);
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> t0 = tcg_temp_new();
> gen_addr_reg_index(ctx, t0);
> t1 = tcg_const_i32(rD(ctx->opcode));
> @@ -3259,8 +3214,6 @@ static void gen_stswi(DisasContext *ctx)
> TCGv_i32 t1, t2;
> int nb = NB(ctx->opcode);
> gen_set_access_type(ctx, ACCESS_INT);
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> t0 = tcg_temp_new();
> gen_addr_register(ctx, t0);
> if (nb == 0)
> @@ -3279,8 +3232,6 @@ static void gen_stswx(DisasContext *ctx)
> TCGv t0;
> TCGv_i32 t1, t2;
> gen_set_access_type(ctx, ACCESS_INT);
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> t0 = tcg_temp_new();
> gen_addr_reg_index(ctx, t0);
> t1 = tcg_temp_new_i32();
> @@ -4106,7 +4057,7 @@ static void gen_tw(DisasContext *ctx)
> {
> TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
> /* Update the nip since this might generate a trap exception */
> - gen_update_nip(ctx, ctx->nip);
> + gen_stop_exception(ctx);
> gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)],
> cpu_gpr[rB(ctx->opcode)],
> t0);
> tcg_temp_free_i32(t0);
> @@ -4118,7 +4069,7 @@ static void gen_twi(DisasContext *ctx)
> TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
> TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
> /* Update the nip since this might generate a trap exception */
> - gen_update_nip(ctx, ctx->nip);
> + gen_stop_exception(ctx);
> gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
> tcg_temp_free(t0);
> tcg_temp_free_i32(t1);
> @@ -4130,7 +4081,7 @@ static void gen_td(DisasContext *ctx)
> {
> TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
> /* Update the nip since this might generate a trap exception */
> - gen_update_nip(ctx, ctx->nip);
> + gen_stop_exception(ctx);
> gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)],
> cpu_gpr[rB(ctx->opcode)],
> t0);
> tcg_temp_free_i32(t0);
> @@ -4142,7 +4093,7 @@ static void gen_tdi(DisasContext *ctx)
> TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
> TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
> /* Update the nip since this might generate a trap exception */
> - gen_update_nip(ctx, ctx->nip);
> + gen_stop_exception(ctx);
> gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
> tcg_temp_free(t0);
> tcg_temp_free_i32(t1);
> @@ -4533,8 +4484,6 @@ static void gen_dcbz(DisasContext *ctx)
> int is_dcbzl = ctx->opcode & 0x00200000 ? 1 : 0;
>
> gen_set_access_type(ctx, ACCESS_CACHE);
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> tcgv_addr = tcg_temp_new();
> tcgv_is_dcbzl = tcg_const_i32(is_dcbzl);
>
> @@ -4577,8 +4526,6 @@ static void gen_icbi(DisasContext *ctx)
> {
> TCGv t0;
> gen_set_access_type(ctx, ACCESS_CACHE);
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> t0 = tcg_temp_new();
> gen_addr_reg_index(ctx, t0);
> gen_helper_icbi(cpu_env, t0);
> @@ -5072,8 +5019,6 @@ static void gen_lscbx(DisasContext *ctx)
> TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
>
> gen_addr_reg_index(ctx, t0);
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3);
> tcg_temp_free_i32(t1);
> tcg_temp_free_i32(t2);
> @@ -6127,8 +6072,6 @@ static void gen_mfdcr(DisasContext *ctx)
> gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> return;
> }
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> dcrn = tcg_const_tl(SPR(ctx->opcode));
> gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
> tcg_temp_free(dcrn);
> @@ -6146,8 +6089,6 @@ static void gen_mtdcr(DisasContext *ctx)
> gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> return;
> }
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> dcrn = tcg_const_tl(SPR(ctx->opcode));
> gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
> tcg_temp_free(dcrn);
> @@ -6165,8 +6106,6 @@ static void gen_mfdcrx(DisasContext *ctx)
> gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> return;
> }
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
> cpu_gpr[rA(ctx->opcode)]);
> /* Note: Rc update flag set leads to undefined state of Rc0 */
> @@ -6184,8 +6123,6 @@ static void gen_mtdcrx(DisasContext *ctx)
> gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> return;
> }
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
> cpu_gpr[rS(ctx->opcode)]);
> /* Note: Rc update flag set leads to undefined state of Rc0 */
> @@ -6195,8 +6132,6 @@ static void gen_mtdcrx(DisasContext *ctx)
> /* mfdcrux (PPC 460) : user-mode access to DCR */
> static void gen_mfdcrux(DisasContext *ctx)
> {
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
> cpu_gpr[rA(ctx->opcode)]);
> /* Note: Rc update flag set leads to undefined state of Rc0 */
> @@ -6205,8 +6140,6 @@ static void gen_mfdcrux(DisasContext *ctx)
> /* mtdcrux (PPC 460) : user-mode access to DCR */
> static void gen_mtdcrux(DisasContext *ctx)
> {
> - /* NIP cannot be restored if the memory exception comes from an helper */
> - gen_update_nip(ctx, ctx->nip - 4);
> gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
> cpu_gpr[rS(ctx->opcode)]);
> /* Note: Rc update flag set leads to undefined state of Rc0 */
> @@ -7915,8 +7848,6 @@ static void gen_##name(DisasContext * ctx)
> \
> gen_exception(ctx, POWERPC_EXCP_VSXU);
> \
> return;
> \
> }
> \
> - /* NIP cannot be restored if the memory exception comes from an helper
> */ \
> - gen_update_nip(ctx, ctx->nip - 4);
> \
> opc = tcg_const_i32(ctx->opcode);
> \
> gen_helper_##name(cpu_env, opc);
> \
> tcg_temp_free_i32(opc);
> \
> @@ -7929,9 +7860,6 @@ static void gen_##name(DisasContext * ctx)
> \
> gen_exception(ctx, POWERPC_EXCP_VSXU); \
> return; \
> } \
> - /* NIP cannot be restored if the exception comes */ \
> - /* from a helper. */ \
> - gen_update_nip(ctx, ctx->nip - 4); \
> \
> gen_helper_##name(cpu_vsrh(xT(ctx->opcode)), cpu_env, \
> cpu_vsrh(xB(ctx->opcode))); \
>
>
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
address@hidden http://www.aurel32.net
- Re: [Qemu-devel] [PATCH v5 07/11] target-i386: exception handling for memory helpers, (continued)