Message ID | 20160915080959.3124.63067.stgit@PASHA-ISP (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Sep 15, 2016 at 11:09:59AM +0300, Pavel Dovgalyuk wrote: > From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> > > 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. > > Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> I'm not really confident reviewing changes in this area. I've CCed Ben Herrenshmidt, who did some work on the exception handling recently. Ben, if you get a chance can you please review this change. > --- > target-ppc/cpu.h | 3 + > target-ppc/excp_helper.c | 38 ++++++-- > target-ppc/fpu_helper.c | 192 ++++++++++++++++++++++-------------------- > 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 | 21 ++--- > target-ppc/translate.c | 76 +---------------- > 10 files changed, 169 insertions(+), 206 deletions(-) > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index 786ab5c..95baae3 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -2434,4 +2434,7 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu); > PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id); > > void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len); > +void raise_exception_err(CPUPPCState *env, uint32_t exception, > + uint32_t error_code, uintptr_t pc); > + > #endif /* PPC_CPU_H */ > diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c > index d6e1678..3da1c32 100644 > --- a/target-ppc/excp_helper.c > +++ b/target-ppc/excp_helper.c > @@ -898,8 +898,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)); > > @@ -908,15 +908,32 @@ 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); I'm struggling to see how raising an exception with a return address of 0 could ever be useful... > } > > void helper_raise_exception(CPUPPCState *env, uint32_t exception) > { > - helper_raise_exception_err(env, exception, 0); > + raise_exception_err(env, exception, 0, GETPC()); > } > > #if !defined(CONFIG_USER_ONLY) > +static void raise_exception(CPUPPCState *env, uint32_t exception, uintptr_t pc) > +{ > + raise_exception_err(env, exception, 0, pc); > +} > + > void helper_store_msr(CPUPPCState *env, target_ulong val) > { > CPUState *cs; > @@ -925,7 +942,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); > } > } > > @@ -1041,8 +1059,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); > } > } > > @@ -1055,8 +1074,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 d9795d0..6eaa3f4 100644 > --- a/target-ppc/fpu_helper.c > +++ b/target-ppc/fpu_helper.c > @@ -19,6 +19,7 @@ > #include "qemu/osdep.h" > #include "cpu.h" > #include "exec/helper-proto.h" > +#include "exec/exec-all.h" > > #define float64_snan_to_qnan(x) ((x) | 0x0008000000000000ULL) > #define float32_snan_to_qnan(x) ((x) | 0x00400000) > @@ -117,7 +118,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; > @@ -200,14 +201,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)); > @@ -217,8 +218,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); > } > } > } > @@ -491,13 +492,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) { > @@ -510,12 +511,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); > @@ -532,12 +538,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, &env->fp_status) || > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > /* 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); > } > @@ -556,12 +562,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, &env->fp_status) || > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > /* 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); > } > @@ -580,12 +586,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, &env->fp_status) || > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > /* 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); > } > @@ -604,15 +610,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, &env->fp_status) || > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > /* 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); > } > @@ -631,16 +637,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, &env->fp_status)) { \ > - 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; \ > } > @@ -665,7 +671,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; \ > } > > @@ -675,7 +681,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; > > @@ -683,7 +689,7 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg, > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > /* 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) & > @@ -698,28 +704,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. */ > @@ -735,13 +741,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, &env->fp_status) || > float64_is_signaling_nan(farg2.d, &env->fp_status) || > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > /* 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; > @@ -753,7 +759,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); > @@ -778,13 +784,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, &env->fp_status) || > float64_is_signaling_nan(farg2.d, &env->fp_status) || > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > /* 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; > @@ -796,7 +802,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); > @@ -819,13 +825,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, &env->fp_status) || > float64_is_signaling_nan(farg2.d, &env->fp_status) || > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > /* 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; > @@ -837,7 +843,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); > @@ -864,13 +870,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, &env->fp_status) || > float64_is_signaling_nan(farg2.d, &env->fp_status) || > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > /* 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; > @@ -882,7 +888,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); > @@ -905,7 +911,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg) > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > /* 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); > @@ -923,12 +929,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, &env->fp_status))) { > /* 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); > } > @@ -944,7 +950,7 @@ uint64_t helper_fre(CPUPPCState *env, uint64_t arg) > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > /* 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; > @@ -960,7 +966,7 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg) > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > /* 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); > @@ -979,12 +985,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, &env->fp_status))) { > /* 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); > @@ -1103,7 +1109,7 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2, > && (float64_is_signaling_nan(farg1.d, &env->fp_status) || > float64_is_signaling_nan(farg2.d, &env->fp_status)))) { > /* sNaN comparison */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); > } > } > > @@ -1135,10 +1141,10 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2, > float64_is_signaling_nan(farg2.d, &env->fp_status)) { > /* 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()); > } > } > } > @@ -1838,10 +1844,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, &tstat) || \ > tp##_is_signaling_nan(xb.fld, &tstat)) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > } \ > } \ > \ > @@ -1854,7 +1860,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) > @@ -1893,10 +1899,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, &tstat) || \ > tp##_is_signaling_nan(xb.fld, &tstat)) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > } \ > } \ > \ > @@ -1910,7 +1916,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) > @@ -1944,13 +1950,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, &tstat) || \ > tp##_is_signaling_nan(xb.fld, &tstat)) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > } \ > } \ > \ > @@ -1964,7 +1970,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) > @@ -1991,7 +1997,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ > \ > for (i = 0; i < nels; i++) { \ > if (unlikely(tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \ > - 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); \ > \ > @@ -2005,7 +2011,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) > @@ -2038,9 +2044,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, &tstat)) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > } \ > } \ > \ > @@ -2054,7 +2060,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) > @@ -2088,9 +2094,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, &tstat)) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > } \ > } \ > \ > @@ -2104,7 +2110,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) > @@ -2277,20 +2283,20 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ > if (tp##_is_signaling_nan(xa.fld, &tstat) || \ > tp##_is_signaling_nan(b->fld, &tstat) || \ > tp##_is_signaling_nan(c->fld, &tstat)) { \ > - 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());\ > } \ > } \ > \ > @@ -2303,7 +2309,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 > @@ -2360,10 +2366,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ > float64_is_any_nan(xb.VsrD(0)))) { \ > if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \ > float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \ > - 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 { \ > @@ -2381,7 +2387,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) > @@ -2408,12 +2414,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, &env->fp_status) || \ > tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \ > - 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)) > @@ -2448,10 +2454,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ > tp##_is_any_nan(xb.fld))) { \ > if (tp##_is_signaling_nan(xa.fld, &env->fp_status) || \ > tp##_is_signaling_nan(xb.fld, &env->fp_status)) { \ > - 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; \ > @@ -2470,7 +2476,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) > @@ -2502,7 +2508,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ > xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \ > if (unlikely(stp##_is_signaling_nan(xb.sfld, \ > &env->fp_status))) { \ > - 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) { \ > @@ -2512,7 +2518,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) > @@ -2557,21 +2563,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, &env->fp_status)) { \ > - 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), \ > @@ -2622,7 +2628,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) > @@ -2667,7 +2673,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ > for (i = 0; i < nels; i++) { \ > if (unlikely(tp##_is_signaling_nan(xb.fld, \ > &env->fp_status))) { \ > - 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); \ > @@ -2686,7 +2692,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_ties_away, 1) > @@ -2714,6 +2720,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 1f5cfd0..34560f9 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 e4ed377..5cee620 100644 > --- a/target-ppc/mem_helper.c > +++ b/target-ppc/mem_helper.c > @@ -107,9 +107,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg, > if (unlikely((ra != 0 && lsw_reg_in_range(reg, num_used_regs, ra)) || > lsw_reg_in_range(reg, num_used_regs, rb))) { > env->nip += 4; /* Compensate the "nip - 4" from gen_lswx() */ > - 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 cb5ebf5..6661650 100644 > --- a/target-ppc/misc_helper.c > +++ b/target-ppc/misc_helper.c > @@ -39,7 +39,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); > > @@ -47,7 +47,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 > > @@ -59,7 +59,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 > } > > @@ -71,7 +71,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 5de1358..a1b27b0 100644 > --- a/target-ppc/mmu-hash64.c > +++ b/target-ppc/mmu-hash64.c > @@ -241,8 +241,8 @@ void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs) > PowerPCCPU *cpu = ppc_env_get_cpu(env); > > if (ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs) < 0) { > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL); > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL, GETPC()); > } > } > > @@ -252,8 +252,8 @@ target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb) > target_ulong rt = 0; > > if (ppc_load_slb_esid(cpu, 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; > } > @@ -276,8 +276,8 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb) > target_ulong rt = 0; > > if (ppc_load_slb_vsid(cpu, 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 3eb3cd7..7cd9c2c 100644 > --- a/target-ppc/mmu_helper.c > +++ b/target-ppc/mmu_helper.c > @@ -2598,9 +2598,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 */ > @@ -2608,9 +2608,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) { > @@ -2892,10 +2892,6 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type, > ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, 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 a07faa4..af328ca 100644 > --- a/target-ppc/timebase_helper.c > +++ b/target-ppc/timebase_helper.c > @@ -19,6 +19,7 @@ > #include "qemu/osdep.h" > #include "cpu.h" > #include "exec/helper-proto.h" > +#include "exec/exec-all.h" > #include "qemu/log.h" > > /*****************************************************************************/ > @@ -143,15 +144,15 @@ target_ulong helper_load_dcr(CPUPPCState *env, target_ulong dcrn) > > if (unlikely(env->dcr_env == NULL)) { > qemu_log_mask(LOG_GUEST_ERROR, "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_mask(LOG_GUEST_ERROR, "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; > } > @@ -160,14 +161,14 @@ void helper_store_dcr(CPUPPCState *env, target_ulong dcrn, target_ulong val) > { > if (unlikely(env->dcr_env == NULL)) { > qemu_log_mask(LOG_GUEST_ERROR, "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_mask(LOG_GUEST_ERROR, "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 92030b6..0e16578 100644 > --- a/target-ppc/translate.c > +++ b/target-ppc/translate.c > @@ -292,7 +292,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error) > } > 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); > @@ -300,14 +300,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error) > > static 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 void gen_debug_exception(DisasContext *ctx) > @@ -2149,8 +2142,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)], \ > @@ -2178,8 +2169,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)], \ > @@ -2206,8 +2195,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)], \ > @@ -2234,8 +2221,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)]); \ > @@ -2254,8 +2239,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)]); \ > @@ -2290,8 +2273,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)]); > @@ -2316,8 +2297,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)]); > @@ -2333,8 +2312,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)]); > @@ -2424,8 +2401,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)], > @@ -2442,8 +2417,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)], > @@ -2613,8 +2586,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); > @@ -2639,8 +2610,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); > @@ -2670,8 +2639,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); > @@ -2706,8 +2673,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); > @@ -2790,8 +2755,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); > @@ -3261,8 +3224,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); > @@ -3277,8 +3238,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); > @@ -3312,8 +3271,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); > @@ -3330,8 +3287,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)); > @@ -3351,8 +3306,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) > @@ -3371,8 +3324,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(); > @@ -4306,7 +4257,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); > @@ -4318,7 +4269,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); > @@ -4330,7 +4281,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); > @@ -4342,7 +4293,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); > @@ -4768,8 +4719,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); > > @@ -4812,8 +4761,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); > @@ -5299,8 +5246,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); > @@ -6386,8 +6331,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 */ > @@ -6396,8 +6339,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 */ > @@ -8027,8 +7968,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); \ > @@ -8041,9 +7980,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))); \ >
> From: David Gibson [mailto:david@gibson.dropbear.id.au] > On Thu, Sep 15, 2016 at 11:09:59AM +0300, Pavel Dovgalyuk wrote: > > From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> > > > > 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. > > > > Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> > > I'm not really confident reviewing changes in this area. > > I've CCed Ben Herrenshmidt, who did some work on the exception > handling recently. Thanks. It seems that most of these changes were already upstreamed from some other patch. That's why I removed this one from the updated series. > > > --- > > target-ppc/cpu.h | 3 + > > target-ppc/excp_helper.c | 38 ++++++-- > > target-ppc/fpu_helper.c | 192 ++++++++++++++++++++++-------------------- > > 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 | 21 ++--- > > target-ppc/translate.c | 76 +---------------- > > 10 files changed, 169 insertions(+), 206 deletions(-) > > > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > > index 786ab5c..95baae3 100644 > > --- a/target-ppc/cpu.h > > +++ b/target-ppc/cpu.h > > @@ -2434,4 +2434,7 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu); > > PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id); > > > > void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len); > > +void raise_exception_err(CPUPPCState *env, uint32_t exception, > > + uint32_t error_code, uintptr_t pc); > > + > > #endif /* PPC_CPU_H */ > > diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c > > index d6e1678..3da1c32 100644 > > --- a/target-ppc/excp_helper.c > > +++ b/target-ppc/excp_helper.c > > @@ -898,8 +898,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)); > > > > @@ -908,15 +908,32 @@ 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); > > I'm struggling to see how raising an exception with a return address > of 0 could ever be useful... > > > } > > > > void helper_raise_exception(CPUPPCState *env, uint32_t exception) > > { > > - helper_raise_exception_err(env, exception, 0); > > + raise_exception_err(env, exception, 0, GETPC()); > > } > > > > #if !defined(CONFIG_USER_ONLY) > > +static void raise_exception(CPUPPCState *env, uint32_t exception, uintptr_t pc) > > +{ > > + raise_exception_err(env, exception, 0, pc); > > +} > > + > > void helper_store_msr(CPUPPCState *env, target_ulong val) > > { > > CPUState *cs; > > @@ -925,7 +942,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); > > } > > } > > > > @@ -1041,8 +1059,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); > > } > > } > > > > @@ -1055,8 +1074,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 d9795d0..6eaa3f4 100644 > > --- a/target-ppc/fpu_helper.c > > +++ b/target-ppc/fpu_helper.c > > @@ -19,6 +19,7 @@ > > #include "qemu/osdep.h" > > #include "cpu.h" > > #include "exec/helper-proto.h" > > +#include "exec/exec-all.h" > > > > #define float64_snan_to_qnan(x) ((x) | 0x0008000000000000ULL) > > #define float32_snan_to_qnan(x) ((x) | 0x00400000) > > @@ -117,7 +118,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; > > @@ -200,14 +201,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)); > > @@ -217,8 +218,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); > > } > > } > > } > > @@ -491,13 +492,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) { > > @@ -510,12 +511,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); > > @@ -532,12 +538,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, &env->fp_status) || > > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > > /* 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); > > } > > @@ -556,12 +562,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, &env->fp_status) || > > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > > /* 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); > > } > > @@ -580,12 +586,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, &env->fp_status) || > > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > > /* 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); > > } > > @@ -604,15 +610,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, &env->fp_status) || > > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > > /* 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); > > } > > @@ -631,16 +637,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, &env->fp_status)) { \ > > - 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; \ > > } > > @@ -665,7 +671,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; \ > > } > > > > @@ -675,7 +681,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; > > > > @@ -683,7 +689,7 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg, > > > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > > /* 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) & > > @@ -698,28 +704,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. */ > > @@ -735,13 +741,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, &env->fp_status) || > > float64_is_signaling_nan(farg2.d, &env->fp_status) || > > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > > /* 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; > > @@ -753,7 +759,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); > > @@ -778,13 +784,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, &env->fp_status) || > > float64_is_signaling_nan(farg2.d, &env->fp_status) || > > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > > /* 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; > > @@ -796,7 +802,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); > > @@ -819,13 +825,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, &env->fp_status) || > > float64_is_signaling_nan(farg2.d, &env->fp_status) || > > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > > /* 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; > > @@ -837,7 +843,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); > > @@ -864,13 +870,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, &env->fp_status) || > > float64_is_signaling_nan(farg2.d, &env->fp_status) || > > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > > /* 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; > > @@ -882,7 +888,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); > > @@ -905,7 +911,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg) > > > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > > /* 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); > > @@ -923,12 +929,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, &env->fp_status))) { > > /* 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); > > } > > @@ -944,7 +950,7 @@ uint64_t helper_fre(CPUPPCState *env, uint64_t arg) > > > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > > /* 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; > > @@ -960,7 +966,7 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg) > > > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > > /* 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); > > @@ -979,12 +985,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, &env->fp_status))) { > > /* 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); > > @@ -1103,7 +1109,7 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2, > > && (float64_is_signaling_nan(farg1.d, &env->fp_status) || > > float64_is_signaling_nan(farg2.d, &env->fp_status)))) { > > /* sNaN comparison */ > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); > > } > > } > > > > @@ -1135,10 +1141,10 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2, > > float64_is_signaling_nan(farg2.d, &env->fp_status)) { > > /* 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()); > > } > > } > > } > > @@ -1838,10 +1844,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, &tstat) || \ > > tp##_is_signaling_nan(xb.fld, &tstat)) { \ > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > } \ > > } \ > > \ > > @@ -1854,7 +1860,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) > > @@ -1893,10 +1899,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, &tstat) || \ > > tp##_is_signaling_nan(xb.fld, &tstat)) { \ > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > } \ > > } \ > > \ > > @@ -1910,7 +1916,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) > > @@ -1944,13 +1950,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, &tstat) || \ > > tp##_is_signaling_nan(xb.fld, &tstat)) { \ > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > } \ > > } \ > > \ > > @@ -1964,7 +1970,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) > > @@ -1991,7 +1997,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) > \ > > \ > > for (i = 0; i < nels; i++) { \ > > if (unlikely(tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \ > > - 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); \ > > \ > > @@ -2005,7 +2011,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) > > @@ -2038,9 +2044,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, &tstat)) { \ > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > } \ > > } \ > > \ > > @@ -2054,7 +2060,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) > > @@ -2088,9 +2094,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, &tstat)) { \ > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > } \ > > } \ > > \ > > @@ -2104,7 +2110,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) > > @@ -2277,20 +2283,20 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) > \ > > if (tp##_is_signaling_nan(xa.fld, &tstat) || \ > > tp##_is_signaling_nan(b->fld, &tstat) || \ > > tp##_is_signaling_nan(c->fld, &tstat)) { \ > > - 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());\ > > } \ > > } \ > > \ > > @@ -2303,7 +2309,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 > > @@ -2360,10 +2366,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) > \ > > float64_is_any_nan(xb.VsrD(0)))) { \ > > if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \ > > float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \ > > - 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 { \ > > @@ -2381,7 +2387,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) > > @@ -2408,12 +2414,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, &env->fp_status) || \ > > tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \ > > - 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)) > > @@ -2448,10 +2454,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) > \ > > tp##_is_any_nan(xb.fld))) { \ > > if (tp##_is_signaling_nan(xa.fld, &env->fp_status) || \ > > tp##_is_signaling_nan(xb.fld, &env->fp_status)) { \ > > - 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; \ > > @@ -2470,7 +2476,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) > > @@ -2502,7 +2508,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ > > xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \ > > if (unlikely(stp##_is_signaling_nan(xb.sfld, \ > > &env->fp_status))) { \ > > - 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) { \ > > @@ -2512,7 +2518,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) > > @@ -2557,21 +2563,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, &env->fp_status)) { \ > > - 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), \ > > @@ -2622,7 +2628,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) > > @@ -2667,7 +2673,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) > \ > > for (i = 0; i < nels; i++) { \ > > if (unlikely(tp##_is_signaling_nan(xb.fld, \ > > &env->fp_status))) { \ > > - 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); \ > > @@ -2686,7 +2692,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_ties_away, 1) > > @@ -2714,6 +2720,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 1f5cfd0..34560f9 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 e4ed377..5cee620 100644 > > --- a/target-ppc/mem_helper.c > > +++ b/target-ppc/mem_helper.c > > @@ -107,9 +107,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg, > > if (unlikely((ra != 0 && lsw_reg_in_range(reg, num_used_regs, ra)) || > > lsw_reg_in_range(reg, num_used_regs, rb))) { > > env->nip += 4; /* Compensate the "nip - 4" from gen_lswx() */ > > - 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 cb5ebf5..6661650 100644 > > --- a/target-ppc/misc_helper.c > > +++ b/target-ppc/misc_helper.c > > @@ -39,7 +39,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); > > > > @@ -47,7 +47,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 > > > > @@ -59,7 +59,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 > > } > > > > @@ -71,7 +71,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 5de1358..a1b27b0 100644 > > --- a/target-ppc/mmu-hash64.c > > +++ b/target-ppc/mmu-hash64.c > > @@ -241,8 +241,8 @@ void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong > rs) > > PowerPCCPU *cpu = ppc_env_get_cpu(env); > > > > if (ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs) < 0) { > > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > > - POWERPC_EXCP_INVAL); > > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > > + POWERPC_EXCP_INVAL, GETPC()); > > } > > } > > > > @@ -252,8 +252,8 @@ target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb) > > target_ulong rt = 0; > > > > if (ppc_load_slb_esid(cpu, 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; > > } > > @@ -276,8 +276,8 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb) > > target_ulong rt = 0; > > > > if (ppc_load_slb_vsid(cpu, 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 3eb3cd7..7cd9c2c 100644 > > --- a/target-ppc/mmu_helper.c > > +++ b/target-ppc/mmu_helper.c > > @@ -2598,9 +2598,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 */ > > @@ -2608,9 +2608,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) { > > @@ -2892,10 +2892,6 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType > access_type, > > ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, 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 a07faa4..af328ca 100644 > > --- a/target-ppc/timebase_helper.c > > +++ b/target-ppc/timebase_helper.c > > @@ -19,6 +19,7 @@ > > #include "qemu/osdep.h" > > #include "cpu.h" > > #include "exec/helper-proto.h" > > +#include "exec/exec-all.h" > > #include "qemu/log.h" > > > > /*****************************************************************************/ > > @@ -143,15 +144,15 @@ target_ulong helper_load_dcr(CPUPPCState *env, target_ulong dcrn) > > > > if (unlikely(env->dcr_env == NULL)) { > > qemu_log_mask(LOG_GUEST_ERROR, "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_mask(LOG_GUEST_ERROR, "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; > > } > > @@ -160,14 +161,14 @@ void helper_store_dcr(CPUPPCState *env, target_ulong dcrn, > target_ulong val) > > { > > if (unlikely(env->dcr_env == NULL)) { > > qemu_log_mask(LOG_GUEST_ERROR, "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_mask(LOG_GUEST_ERROR, "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 92030b6..0e16578 100644 > > --- a/target-ppc/translate.c > > +++ b/target-ppc/translate.c > > @@ -292,7 +292,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t > error) > > } > > 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); > > @@ -300,14 +300,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, > uint32_t error) > > > > static 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 void gen_debug_exception(DisasContext *ctx) > > @@ -2149,8 +2142,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)], \ > > @@ -2178,8 +2169,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)], \ > > @@ -2206,8 +2195,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)], \ > > @@ -2234,8 +2221,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)]); \ > > @@ -2254,8 +2239,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)]); \ > > @@ -2290,8 +2273,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)]); > > @@ -2316,8 +2297,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)]); > > @@ -2333,8 +2312,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)]); > > @@ -2424,8 +2401,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)], > > @@ -2442,8 +2417,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)], > > @@ -2613,8 +2586,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); > > @@ -2639,8 +2610,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); > > @@ -2670,8 +2639,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); > > @@ -2706,8 +2673,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); > > @@ -2790,8 +2755,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); > > @@ -3261,8 +3224,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); > > @@ -3277,8 +3238,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); > > @@ -3312,8 +3271,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); > > @@ -3330,8 +3287,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)); > > @@ -3351,8 +3306,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) > > @@ -3371,8 +3324,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(); > > @@ -4306,7 +4257,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); > > @@ -4318,7 +4269,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); > > @@ -4330,7 +4281,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); > > @@ -4342,7 +4293,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); > > @@ -4768,8 +4719,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); > > > > @@ -4812,8 +4761,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); > > @@ -5299,8 +5246,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); > > @@ -6386,8 +6331,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 */ > > @@ -6396,8 +6339,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 */ > > @@ -8027,8 +7968,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); \ > > @@ -8041,9 +7980,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))); \ > > > > -- > David Gibson | I'll have my music baroque, and my code > david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ > | _way_ _around_! > http://www.ozlabs.org/~dgibson
On Tue, 2016-09-20 at 11:42 +0300, Pavel Dovgalyuk wrote: > > > > From: David Gibson [mailto:david@gibson.dropbear.id.au] > > On Thu, Sep 15, 2016 at 11:09:59AM +0300, Pavel Dovgalyuk wrote: > > > > > > From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> > > > > > > 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. > > > > > > Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> > > > > I'm not really confident reviewing changes in this area. > > > > I've CCd Ben Herrenshmidt, who did some work on the exception > > handling recently.  Hrm.. Isn't this something that gets fixed by rth's patch to properly fix GET_RA ? Ie. it should be legit to pass "0" for the PC if we have updated nip manually ... I'm not sure I get what you are doing here. > Thanks. > It seems that most of these changes were already upstreamed from some > other patch. > That's why I removed this one from the updated series. > > > > > > > > > > > --- > > >  target-ppc/cpu.h             |    3 + > > >  target-ppc/excp_helper.c     |   38 ++++++-- > > >  target-ppc/fpu_helper.c      |  192 ++++++++++++++++++++++---- > > > ---------------- > > >  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 |   21 ++--- > > >  target-ppc/translate.c       |   76 +---------------- > > >  10 files changed, 169 insertions(+), 206 deletions(-) > > > > > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > > > index 786ab5c..95baae3 100644 > > > --- a/target-ppc/cpu.h > > > +++ b/target-ppc/cpu.h > > > @@ -2434,4 +2434,7 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu); > > >  PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id); > > > > > >  void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t > > > *mem_buf, int len); > > > +void raise_exception_err(CPUPPCState *env, uint32_t exception, > > > +                         uint32_t error_code, uintptr_t pc); > > > + > > >  #endif /* PPC_CPU_H */ > > > diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c > > > index d6e1678..3da1c32 100644 > > > --- a/target-ppc/excp_helper.c > > > +++ b/target-ppc/excp_helper.c > > > @@ -898,8 +898,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)); > > > > > > @@ -908,15 +908,32 @@ 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); > > > > I'm struggling to see how raising an exception with a return > > address > > of 0 could ever be useful... > > > > > > > >  } > > > > > >  void helper_raise_exception(CPUPPCState *env, uint32_t > > > exception) > > >  { > > > -    helper_raise_exception_err(env, exception, 0); > > > +    raise_exception_err(env, exception, 0, GETPC()); > > >  } > > > > > >  #if !defined(CONFIG_USER_ONLY) > > > +static void raise_exception(CPUPPCState *env, uint32_t > > > exception, uintptr_t pc) > > > +{ > > > +    raise_exception_err(env, exception, 0, pc); > > > +} > > > + > > >  void helper_store_msr(CPUPPCState *env, target_ulong val) > > >  { > > >      CPUState *cs; > > > @@ -925,7 +942,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); > > >      } > > >  } > > > > > > @@ -1041,8 +1059,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); > > >      } > > >  } > > > > > > @@ -1055,8 +1074,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 d9795d0..6eaa3f4 100644 > > > --- a/target-ppc/fpu_helper.c > > > +++ b/target-ppc/fpu_helper.c > > > @@ -19,6 +19,7 @@ > > >  #include "qemu/osdep.h" > > >  #include "cpu.h" > > >  #include "exec/helper-proto.h" > > > +#include "exec/exec-all.h" > > > > > >  #define float64_snan_to_qnan(x) ((x) | 0x0008000000000000ULL) > > >  #define float32_snan_to_qnan(x) ((x) | 0x00400000) > > > @@ -117,7 +118,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; > > > @@ -200,14 +201,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)); > > > @@ -217,8 +218,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); > > >          } > > >      } > > >  } > > > @@ -491,13 +492,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) { > > > @@ -510,12 +511,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); > > > @@ -532,12 +538,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, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg2.d, &env- > > > >fp_status))) { > > >              /* 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); > > >      } > > > @@ -556,12 +562,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, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg2.d, &env- > > > >fp_status))) { > > >              /* 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); > > >      } > > > @@ -580,12 +586,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, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg2.d, &env- > > > >fp_status))) { > > >              /* 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); > > >      } > > > @@ -604,15 +610,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, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg2.d, &env- > > > >fp_status))) { > > >              /* 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); > > >      } > > > @@ -631,16 +637,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, &env->fp_status)) > > > {      \ > > > -                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;                                                    \ > > >  } > > > @@ -665,7 +671,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;                                        \ > > >  } > > > > > > @@ -675,7 +681,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; > > > > > > @@ -683,7 +689,7 @@ static inline uint64_t do_fri(CPUPPCState > > > *env, uint64_t arg, > > > > > >      if (unlikely(float64_is_signaling_nan(farg.d, &env- > > > >fp_status))) { > > >          /* 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) > > > & > > > @@ -698,28 +704,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. */ > > > @@ -735,13 +741,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, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg2.d, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg3.d, &env- > > > >fp_status))) { > > >              /* 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; > > > @@ -753,7 +759,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); > > > @@ -778,13 +784,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, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg2.d, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg3.d, &env- > > > >fp_status))) { > > >              /* 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; > > > @@ -796,7 +802,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); > > > @@ -819,13 +825,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, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg2.d, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg3.d, &env- > > > >fp_status))) { > > >              /* 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; > > > @@ -837,7 +843,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); > > > @@ -864,13 +870,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, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg2.d, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg3.d, &env- > > > >fp_status))) { > > >              /* 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; > > > @@ -882,7 +888,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); > > > @@ -905,7 +911,7 @@ uint64_t helper_frsp(CPUPPCState *env, > > > uint64_t arg) > > > > > >      if (unlikely(float64_is_signaling_nan(farg.d, &env- > > > >fp_status))) { > > >          /* 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); > > > @@ -923,12 +929,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, &env- > > > >fp_status))) { > > >              /* 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); > > >      } > > > @@ -944,7 +950,7 @@ uint64_t helper_fre(CPUPPCState *env, > > > uint64_t arg) > > > > > >      if (unlikely(float64_is_signaling_nan(farg.d, &env- > > > >fp_status))) { > > >          /* 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; > > > @@ -960,7 +966,7 @@ uint64_t helper_fres(CPUPPCState *env, > > > uint64_t arg) > > > > > >      if (unlikely(float64_is_signaling_nan(farg.d, &env- > > > >fp_status))) { > > >          /* 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); > > > @@ -979,12 +985,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, &env- > > > >fp_status))) { > > >              /* 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); > > > @@ -1103,7 +1109,7 @@ void helper_fcmpu(CPUPPCState *env, > > > uint64_t arg1, uint64_t arg2, > > >                   && (float64_is_signaling_nan(farg1.d, &env- > > > >fp_status) || > > >                       float64_is_signaling_nan(farg2.d, &env- > > > >fp_status)))) { > > >          /* sNaN comparison */ > > > -        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > > > +        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, > > > GETPC()); > > >      } > > >  } > > > > > > @@ -1135,10 +1141,10 @@ void helper_fcmpo(CPUPPCState *env, > > > uint64_t arg1, uint64_t arg2, > > >              float64_is_signaling_nan(farg2.d, &env->fp_status)) > > > { > > >              /* 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()); > > >          } > > >      } > > >  } > > > @@ -1838,10 +1844,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, &tstat) > > > ||              \ > > >                         tp##_is_signaling_nan(xb.fld, &tstat)) > > > {              \ > > > -                fload_invalid_op_excp(env, > > > POWERPC_EXCP_FP_VXSNAN, sfprf);   \ > > > +                fload_invalid_op_excp(env, > > > POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > >              }                                                   > > >              \ > > >          }                                                       > > >              \ > > >                                                                  > > >              \ > > > @@ -1854,7 +1860,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) > > > @@ -1893,10 +1899,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, &tstat) > > > ||              \ > > >                         tp##_is_signaling_nan(xb.fld, &tstat)) > > > {              \ > > > -                fload_invalid_op_excp(env, > > > POWERPC_EXCP_FP_VXSNAN, sfprf);   \ > > > +                fload_invalid_op_excp(env, > > > POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > >              }                                                   > > >              \ > > >          }                                                       > > >              \ > > >                                                                  > > >              \ > > > @@ -1910,7 +1916,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) > > > @@ -1944,13 +1950,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, &tstat) > > > ||               \ > > >                  tp##_is_signaling_nan(xb.fld, &tstat)) > > > {                      \ > > > -                fload_invalid_op_excp(env, > > > POWERPC_EXCP_FP_VXSNAN, sfprf);    \ > > > +                fload_invalid_op_excp(env, > > > POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > >              }                                                   > > >               \ > > >          }                                                       > > >               \ > > >                                                                  > > >               \ > > > @@ -1964,7 +1970,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) > > > @@ -1991,7 +1997,7 @@ void helper_##op(CPUPPCState *env, uint32_t > > > opcode) > > \ > > > > > >                                                                  > > >               \ > > >      for (i = 0; i < nels; i++) > > > {                                              \ > > >          if (unlikely(tp##_is_signaling_nan(xb.fld, &env- > > > >fp_status))) {       \ > > > -                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);                 \ > > >                                                                  > > >               \ > > > @@ -2005,7 +2011,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) > > > @@ -2038,9 +2044,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, &tstat)) > > > {              \ > > > -                fload_invalid_op_excp(env, > > > POWERPC_EXCP_FP_VXSNAN, sfprf);   \ > > > +                fload_invalid_op_excp(env, > > > POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > >              }                                                   > > >              \ > > >          }                                                       > > >              \ > > >                                                                  > > >              \ > > > @@ -2054,7 +2060,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) > > > @@ -2088,9 +2094,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, &tstat)) > > > {              \ > > > -                fload_invalid_op_excp(env, > > > POWERPC_EXCP_FP_VXSNAN, sfprf);   \ > > > +                fload_invalid_op_excp(env, > > > POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > >              }                                                   > > >              \ > > >          }                                                       > > >              \ > > >                                                                  > > >              \ > > > @@ -2104,7 +2110,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) > > > @@ -2277,20 +2283,20 @@ void helper_##op(CPUPPCState *env, > > > uint32_t opcode) > > \ > > > > > >              if (tp##_is_signaling_nan(xa.fld, &tstat) > > > ||                      \ > > >                  tp##_is_signaling_nan(b->fld, &tstat) > > > ||                      \ > > >                  tp##_is_signaling_nan(c->fld, &tstat)) > > > {                      \ > > > -                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());\ > > >              }                                                   > > >               \ > > >          }                                                       > > >               \ > > >                                                                  > > >               \ > > > @@ -2303,7 +2309,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 > > > @@ -2360,10 +2366,10 @@ void helper_##op(CPUPPCState *env, > > > uint32_t opcode) > > \ > > > > > >                   float64_is_any_nan(xb.VsrD(0)))) > > > {                      \ > > >          if (float64_is_signaling_nan(xa.VsrD(0), &env- > > > >fp_status) ||     \ > > >              float64_is_signaling_nan(xb.VsrD(0), &env- > > > >fp_status)) {     \ > > > -            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 > > > {                                                             \ > > > @@ -2381,7 +2387,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) > > > @@ -2408,12 +2414,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, &env- > > > >fp_status) ||        \ > > >                       tp##_is_signaling_nan(xb.fld, &env- > > > >fp_status))) {       \ > > > -            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)) > > > @@ -2448,10 +2454,10 @@ void helper_##op(CPUPPCState *env, > > > uint32_t opcode) > > \ > > > > > >                       tp##_is_any_nan(xb.fld))) > > > {                          \ > > >              if (tp##_is_signaling_nan(xa.fld, &env->fp_status) > > > ||         \ > > >                  tp##_is_signaling_nan(xb.fld, &env->fp_status)) > > > {         \ > > > -                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;                                                 \ > > > @@ -2470,7 +2476,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) > > > @@ -2502,7 +2508,7 @@ void helper_##op(CPUPPCState *env, uint32_t > > > opcode)                \ > > >          xt.tfld = stp##_to_##ttp(xb.sfld, &env- > > > >fp_status);        \ > > >          if > > > (unlikely(stp##_is_signaling_nan(xb.sfld,               \ > > >                                              &env->fp_status))) > > > {   \ > > > -            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) > > > {                                               \ > > > @@ -2512,7 +2518,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) > > > @@ -2557,21 +2563,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, &env- > > > >fp_status)) {          \ > > > -                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), \ > > > @@ -2622,7 +2628,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) > > > @@ -2667,7 +2673,7 @@ void helper_##op(CPUPPCState *env, uint32_t > > > opcode) > > \ > > > > > >      for (i = 0; i < nels; i++) > > > {                                       \ > > >          if > > > (unlikely(tp##_is_signaling_nan(xb.fld,                     \ > > >                                             &env->fp_status))) > > > {        \ > > > -            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);       \ > > > @@ -2686,7 +2692,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_ties_away, 1) > > > @@ -2714,6 +2720,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 1f5cfd0..34560f9 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 e4ed377..5cee620 100644 > > > --- a/target-ppc/mem_helper.c > > > +++ b/target-ppc/mem_helper.c > > > @@ -107,9 +107,9 @@ void helper_lswx(CPUPPCState *env, > > > target_ulong addr, uint32_t reg, > > >          if (unlikely((ra != 0 && lsw_reg_in_range(reg, > > > num_used_regs, ra)) || > > >                       lsw_reg_in_range(reg, num_used_regs, rb))) > > > { > > >              env->nip += 4;     /* Compensate the "nip - 4" from > > > gen_lswx() */ > > > -            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 cb5ebf5..6661650 100644 > > > --- a/target-ppc/misc_helper.c > > > +++ b/target-ppc/misc_helper.c > > > @@ -39,7 +39,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); > > > > > > @@ -47,7 +47,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 > > > > > > @@ -59,7 +59,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 > > >  } > > > > > > @@ -71,7 +71,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 5de1358..a1b27b0 100644 > > > --- a/target-ppc/mmu-hash64.c > > > +++ b/target-ppc/mmu-hash64.c > > > @@ -241,8 +241,8 @@ void helper_store_slb(CPUPPCState *env, > > > target_ulong rb, target_ulong > > rs) > > > > > >      PowerPCCPU *cpu = ppc_env_get_cpu(env); > > > > > >      if (ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs) < 0) > > > { > > > -        helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > > > -                                   POWERPC_EXCP_INVAL); > > > +        raise_exception_err(env, POWERPC_EXCP_PROGRAM, > > > +                            POWERPC_EXCP_INVAL, GETPC()); > > >      } > > >  } > > > > > > @@ -252,8 +252,8 @@ target_ulong helper_load_slb_esid(CPUPPCState > > > *env, target_ulong rb) > > >      target_ulong rt = 0; > > > > > >      if (ppc_load_slb_esid(cpu, 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; > > >  } > > > @@ -276,8 +276,8 @@ target_ulong helper_load_slb_vsid(CPUPPCState > > > *env, target_ulong rb) > > >      target_ulong rt = 0; > > > > > >      if (ppc_load_slb_vsid(cpu, 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 3eb3cd7..7cd9c2c 100644 > > > --- a/target-ppc/mmu_helper.c > > > +++ b/target-ppc/mmu_helper.c > > > @@ -2598,9 +2598,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 */ > > > @@ -2608,9 +2608,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) { > > > @@ -2892,10 +2892,6 @@ void tlb_fill(CPUState *cs, target_ulong > > > addr, MMUAccessType > > access_type, > > > > > >          ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, > > > 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 a07faa4..af328ca 100644 > > > --- a/target-ppc/timebase_helper.c > > > +++ b/target-ppc/timebase_helper.c > > > @@ -19,6 +19,7 @@ > > >  #include "qemu/osdep.h" > > >  #include "cpu.h" > > >  #include "exec/helper-proto.h" > > > +#include "exec/exec-all.h" > > >  #include "qemu/log.h" > > > > > >  /*************************************************************** > > > **************/ > > > @@ -143,15 +144,15 @@ target_ulong helper_load_dcr(CPUPPCState > > > *env, target_ulong dcrn) > > > > > >      if (unlikely(env->dcr_env == NULL)) { > > >          qemu_log_mask(LOG_GUEST_ERROR, "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_mask(LOG_GUEST_ERROR, "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; > > >  } > > > @@ -160,14 +161,14 @@ void helper_store_dcr(CPUPPCState *env, > > > target_ulong dcrn, > > target_ulong val) > > > > > >  { > > >      if (unlikely(env->dcr_env == NULL)) { > > >          qemu_log_mask(LOG_GUEST_ERROR, "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_mask(LOG_GUEST_ERROR, "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 92030b6..0e16578 100644 > > > --- a/target-ppc/translate.c > > > +++ b/target-ppc/translate.c > > > @@ -292,7 +292,7 @@ static void gen_exception_err(DisasContext > > > *ctx, uint32_t excp, uint32_t > > error) > > > > > >      } > > >      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); > > > @@ -300,14 +300,7 @@ static void gen_exception_err(DisasContext > > > *ctx, uint32_t excp, > > uint32_t error) > > > > > > > > >  static 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 void gen_debug_exception(DisasContext *ctx) > > > @@ -2149,8 +2142,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)],                                \ > > > @@ -2178,8 +2169,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)],                                \ > > > @@ -2206,8 +2195,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)],                                \ > > > @@ -2234,8 +2221,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)]);                             \ > > > @@ -2254,8 +2239,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)]);                             \ > > > @@ -2290,8 +2273,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)]); > > > @@ -2316,8 +2297,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)]); > > > @@ -2333,8 +2312,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)]); > > > @@ -2424,8 +2401,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)], > > > @@ -2442,8 +2417,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)], > > > @@ -2613,8 +2586,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); > > > @@ -2639,8 +2610,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); > > > @@ -2670,8 +2639,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); > > > @@ -2706,8 +2673,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); > > > @@ -2790,8 +2755,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); > > > @@ -3261,8 +3224,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); > > > @@ -3277,8 +3238,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); > > > @@ -3312,8 +3271,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); > > > @@ -3330,8 +3287,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)); > > > @@ -3351,8 +3306,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) > > > @@ -3371,8 +3324,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(); > > > @@ -4306,7 +4257,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); > > > @@ -4318,7 +4269,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); > > > @@ -4330,7 +4281,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); > > > @@ -4342,7 +4293,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); > > > @@ -4768,8 +4719,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); > > > > > > @@ -4812,8 +4761,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); > > > @@ -5299,8 +5246,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); > > > @@ -6386,8 +6331,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 > > > */ > > > @@ -6396,8 +6339,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 > > > */ > > > @@ -8027,8 +7968,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);                                     > > >               \ > > > @@ -8041,9 +7980,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)));             \ > > > > > > > -- > > David Gibson | I'll have my music baroque, > > and my code > > david AT gibson.dropbear.id.au | minimalist, thank you.  NOT > > _the_ _other_ > > | _way_ _around_! > > http://www.ozlabs.org/~dgibson
On Tue, Sep 20, 2016 at 11:42:38AM +0300, Pavel Dovgalyuk wrote: > > From: David Gibson [mailto:david@gibson.dropbear.id.au] > > On Thu, Sep 15, 2016 at 11:09:59AM +0300, Pavel Dovgalyuk wrote: > > > From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> > > > > > > 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. > > > > > > Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> > > > > I'm not really confident reviewing changes in this area. > > > > I've CCed Ben Herrenshmidt, who did some work on the exception > > handling recently. > > Thanks. > It seems that most of these changes were already upstreamed from some other patch. > That's why I removed this one from the updated series. Oh, ok. I'm not following the icount or replay stuff, so I didn't notice - I just saw I'd been CCed on a patch touching ppc stuff. > > > > > > --- > > > target-ppc/cpu.h | 3 + > > > target-ppc/excp_helper.c | 38 ++++++-- > > > target-ppc/fpu_helper.c | 192 ++++++++++++++++++++++-------------------- > > > 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 | 21 ++--- > > > target-ppc/translate.c | 76 +---------------- > > > 10 files changed, 169 insertions(+), 206 deletions(-) > > > > > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > > > index 786ab5c..95baae3 100644 > > > --- a/target-ppc/cpu.h > > > +++ b/target-ppc/cpu.h > > > @@ -2434,4 +2434,7 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu); > > > PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id); > > > > > > void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len); > > > +void raise_exception_err(CPUPPCState *env, uint32_t exception, > > > + uint32_t error_code, uintptr_t pc); > > > + > > > #endif /* PPC_CPU_H */ > > > diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c > > > index d6e1678..3da1c32 100644 > > > --- a/target-ppc/excp_helper.c > > > +++ b/target-ppc/excp_helper.c > > > @@ -898,8 +898,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)); > > > > > > @@ -908,15 +908,32 @@ 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); > > > > I'm struggling to see how raising an exception with a return address > > of 0 could ever be useful... > > > > > } > > > > > > void helper_raise_exception(CPUPPCState *env, uint32_t exception) > > > { > > > - helper_raise_exception_err(env, exception, 0); > > > + raise_exception_err(env, exception, 0, GETPC()); > > > } > > > > > > #if !defined(CONFIG_USER_ONLY) > > > +static void raise_exception(CPUPPCState *env, uint32_t exception, uintptr_t pc) > > > +{ > > > + raise_exception_err(env, exception, 0, pc); > > > +} > > > + > > > void helper_store_msr(CPUPPCState *env, target_ulong val) > > > { > > > CPUState *cs; > > > @@ -925,7 +942,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); > > > } > > > } > > > > > > @@ -1041,8 +1059,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); > > > } > > > } > > > > > > @@ -1055,8 +1074,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 d9795d0..6eaa3f4 100644 > > > --- a/target-ppc/fpu_helper.c > > > +++ b/target-ppc/fpu_helper.c > > > @@ -19,6 +19,7 @@ > > > #include "qemu/osdep.h" > > > #include "cpu.h" > > > #include "exec/helper-proto.h" > > > +#include "exec/exec-all.h" > > > > > > #define float64_snan_to_qnan(x) ((x) | 0x0008000000000000ULL) > > > #define float32_snan_to_qnan(x) ((x) | 0x00400000) > > > @@ -117,7 +118,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; > > > @@ -200,14 +201,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)); > > > @@ -217,8 +218,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); > > > } > > > } > > > } > > > @@ -491,13 +492,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) { > > > @@ -510,12 +511,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); > > > @@ -532,12 +538,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, &env->fp_status) || > > > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > > > /* 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); > > > } > > > @@ -556,12 +562,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, &env->fp_status) || > > > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > > > /* 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); > > > } > > > @@ -580,12 +586,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, &env->fp_status) || > > > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > > > /* 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); > > > } > > > @@ -604,15 +610,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, &env->fp_status) || > > > float64_is_signaling_nan(farg2.d, &env->fp_status))) { > > > /* 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); > > > } > > > @@ -631,16 +637,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, &env->fp_status)) { \ > > > - 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; \ > > > } > > > @@ -665,7 +671,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; \ > > > } > > > > > > @@ -675,7 +681,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; > > > > > > @@ -683,7 +689,7 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg, > > > > > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > > > /* 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) & > > > @@ -698,28 +704,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. */ > > > @@ -735,13 +741,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, &env->fp_status) || > > > float64_is_signaling_nan(farg2.d, &env->fp_status) || > > > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > > > /* 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; > > > @@ -753,7 +759,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); > > > @@ -778,13 +784,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, &env->fp_status) || > > > float64_is_signaling_nan(farg2.d, &env->fp_status) || > > > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > > > /* 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; > > > @@ -796,7 +802,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); > > > @@ -819,13 +825,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, &env->fp_status) || > > > float64_is_signaling_nan(farg2.d, &env->fp_status) || > > > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > > > /* 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; > > > @@ -837,7 +843,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); > > > @@ -864,13 +870,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, &env->fp_status) || > > > float64_is_signaling_nan(farg2.d, &env->fp_status) || > > > float64_is_signaling_nan(farg3.d, &env->fp_status))) { > > > /* 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; > > > @@ -882,7 +888,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); > > > @@ -905,7 +911,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg) > > > > > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > > > /* 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); > > > @@ -923,12 +929,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, &env->fp_status))) { > > > /* 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); > > > } > > > @@ -944,7 +950,7 @@ uint64_t helper_fre(CPUPPCState *env, uint64_t arg) > > > > > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > > > /* 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; > > > @@ -960,7 +966,7 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg) > > > > > > if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { > > > /* 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); > > > @@ -979,12 +985,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, &env->fp_status))) { > > > /* 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); > > > @@ -1103,7 +1109,7 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2, > > > && (float64_is_signaling_nan(farg1.d, &env->fp_status) || > > > float64_is_signaling_nan(farg2.d, &env->fp_status)))) { > > > /* sNaN comparison */ > > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); > > > } > > > } > > > > > > @@ -1135,10 +1141,10 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2, > > > float64_is_signaling_nan(farg2.d, &env->fp_status)) { > > > /* 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()); > > > } > > > } > > > } > > > @@ -1838,10 +1844,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, &tstat) || \ > > > tp##_is_signaling_nan(xb.fld, &tstat)) { \ > > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > > } \ > > > } \ > > > \ > > > @@ -1854,7 +1860,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) > > > @@ -1893,10 +1899,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, &tstat) || \ > > > tp##_is_signaling_nan(xb.fld, &tstat)) { \ > > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > > } \ > > > } \ > > > \ > > > @@ -1910,7 +1916,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) > > > @@ -1944,13 +1950,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, &tstat) || \ > > > tp##_is_signaling_nan(xb.fld, &tstat)) { \ > > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > > } \ > > > } \ > > > \ > > > @@ -1964,7 +1970,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) > > > @@ -1991,7 +1997,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) > > \ > > > \ > > > for (i = 0; i < nels; i++) { \ > > > if (unlikely(tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \ > > > - 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); \ > > > \ > > > @@ -2005,7 +2011,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) > > > @@ -2038,9 +2044,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, &tstat)) { \ > > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > > } \ > > > } \ > > > \ > > > @@ -2054,7 +2060,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) > > > @@ -2088,9 +2094,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, &tstat)) { \ > > > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ > > > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ > > > } \ > > > } \ > > > \ > > > @@ -2104,7 +2110,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) > > > @@ -2277,20 +2283,20 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) > > \ > > > if (tp##_is_signaling_nan(xa.fld, &tstat) || \ > > > tp##_is_signaling_nan(b->fld, &tstat) || \ > > > tp##_is_signaling_nan(c->fld, &tstat)) { \ > > > - 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());\ > > > } \ > > > } \ > > > \ > > > @@ -2303,7 +2309,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 > > > @@ -2360,10 +2366,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) > > \ > > > float64_is_any_nan(xb.VsrD(0)))) { \ > > > if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \ > > > float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \ > > > - 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 { \ > > > @@ -2381,7 +2387,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) > > > @@ -2408,12 +2414,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, &env->fp_status) || \ > > > tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \ > > > - 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)) > > > @@ -2448,10 +2454,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) > > \ > > > tp##_is_any_nan(xb.fld))) { \ > > > if (tp##_is_signaling_nan(xa.fld, &env->fp_status) || \ > > > tp##_is_signaling_nan(xb.fld, &env->fp_status)) { \ > > > - 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; \ > > > @@ -2470,7 +2476,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) > > > @@ -2502,7 +2508,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ > > > xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \ > > > if (unlikely(stp##_is_signaling_nan(xb.sfld, \ > > > &env->fp_status))) { \ > > > - 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) { \ > > > @@ -2512,7 +2518,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) > > > @@ -2557,21 +2563,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, &env->fp_status)) { \ > > > - 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), \ > > > @@ -2622,7 +2628,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) > > > @@ -2667,7 +2673,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) > > \ > > > for (i = 0; i < nels; i++) { \ > > > if (unlikely(tp##_is_signaling_nan(xb.fld, \ > > > &env->fp_status))) { \ > > > - 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); \ > > > @@ -2686,7 +2692,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_ties_away, 1) > > > @@ -2714,6 +2720,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 1f5cfd0..34560f9 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 e4ed377..5cee620 100644 > > > --- a/target-ppc/mem_helper.c > > > +++ b/target-ppc/mem_helper.c > > > @@ -107,9 +107,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg, > > > if (unlikely((ra != 0 && lsw_reg_in_range(reg, num_used_regs, ra)) || > > > lsw_reg_in_range(reg, num_used_regs, rb))) { > > > env->nip += 4; /* Compensate the "nip - 4" from gen_lswx() */ > > > - 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 cb5ebf5..6661650 100644 > > > --- a/target-ppc/misc_helper.c > > > +++ b/target-ppc/misc_helper.c > > > @@ -39,7 +39,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); > > > > > > @@ -47,7 +47,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 > > > > > > @@ -59,7 +59,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 > > > } > > > > > > @@ -71,7 +71,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 5de1358..a1b27b0 100644 > > > --- a/target-ppc/mmu-hash64.c > > > +++ b/target-ppc/mmu-hash64.c > > > @@ -241,8 +241,8 @@ void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong > > rs) > > > PowerPCCPU *cpu = ppc_env_get_cpu(env); > > > > > > if (ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs) < 0) { > > > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > > > - POWERPC_EXCP_INVAL); > > > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > > > + POWERPC_EXCP_INVAL, GETPC()); > > > } > > > } > > > > > > @@ -252,8 +252,8 @@ target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb) > > > target_ulong rt = 0; > > > > > > if (ppc_load_slb_esid(cpu, 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; > > > } > > > @@ -276,8 +276,8 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb) > > > target_ulong rt = 0; > > > > > > if (ppc_load_slb_vsid(cpu, 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 3eb3cd7..7cd9c2c 100644 > > > --- a/target-ppc/mmu_helper.c > > > +++ b/target-ppc/mmu_helper.c > > > @@ -2598,9 +2598,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 */ > > > @@ -2608,9 +2608,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) { > > > @@ -2892,10 +2892,6 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType > > access_type, > > > ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, 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 a07faa4..af328ca 100644 > > > --- a/target-ppc/timebase_helper.c > > > +++ b/target-ppc/timebase_helper.c > > > @@ -19,6 +19,7 @@ > > > #include "qemu/osdep.h" > > > #include "cpu.h" > > > #include "exec/helper-proto.h" > > > +#include "exec/exec-all.h" > > > #include "qemu/log.h" > > > > > > /*****************************************************************************/ > > > @@ -143,15 +144,15 @@ target_ulong helper_load_dcr(CPUPPCState *env, target_ulong dcrn) > > > > > > if (unlikely(env->dcr_env == NULL)) { > > > qemu_log_mask(LOG_GUEST_ERROR, "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_mask(LOG_GUEST_ERROR, "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; > > > } > > > @@ -160,14 +161,14 @@ void helper_store_dcr(CPUPPCState *env, target_ulong dcrn, > > target_ulong val) > > > { > > > if (unlikely(env->dcr_env == NULL)) { > > > qemu_log_mask(LOG_GUEST_ERROR, "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_mask(LOG_GUEST_ERROR, "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 92030b6..0e16578 100644 > > > --- a/target-ppc/translate.c > > > +++ b/target-ppc/translate.c > > > @@ -292,7 +292,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t > > error) > > > } > > > 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); > > > @@ -300,14 +300,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, > > uint32_t error) > > > > > > static 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 void gen_debug_exception(DisasContext *ctx) > > > @@ -2149,8 +2142,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)], \ > > > @@ -2178,8 +2169,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)], \ > > > @@ -2206,8 +2195,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)], \ > > > @@ -2234,8 +2221,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)]); \ > > > @@ -2254,8 +2239,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)]); \ > > > @@ -2290,8 +2273,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)]); > > > @@ -2316,8 +2297,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)]); > > > @@ -2333,8 +2312,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)]); > > > @@ -2424,8 +2401,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)], > > > @@ -2442,8 +2417,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)], > > > @@ -2613,8 +2586,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); > > > @@ -2639,8 +2610,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); > > > @@ -2670,8 +2639,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); > > > @@ -2706,8 +2673,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); > > > @@ -2790,8 +2755,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); > > > @@ -3261,8 +3224,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); > > > @@ -3277,8 +3238,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); > > > @@ -3312,8 +3271,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); > > > @@ -3330,8 +3287,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)); > > > @@ -3351,8 +3306,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) > > > @@ -3371,8 +3324,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(); > > > @@ -4306,7 +4257,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); > > > @@ -4318,7 +4269,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); > > > @@ -4330,7 +4281,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); > > > @@ -4342,7 +4293,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); > > > @@ -4768,8 +4719,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); > > > > > > @@ -4812,8 +4761,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); > > > @@ -5299,8 +5246,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); > > > @@ -6386,8 +6331,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 */ > > > @@ -6396,8 +6339,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 */ > > > @@ -8027,8 +7968,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); \ > > > @@ -8041,9 +7980,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))); \ > > > > > >
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 786ab5c..95baae3 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -2434,4 +2434,7 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu); PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id); void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len); +void raise_exception_err(CPUPPCState *env, uint32_t exception, + uint32_t error_code, uintptr_t pc); + #endif /* PPC_CPU_H */ diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index d6e1678..3da1c32 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -898,8 +898,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)); @@ -908,15 +908,32 @@ 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()); } #if !defined(CONFIG_USER_ONLY) +static void raise_exception(CPUPPCState *env, uint32_t exception, uintptr_t pc) +{ + raise_exception_err(env, exception, 0, pc); +} + void helper_store_msr(CPUPPCState *env, target_ulong val) { CPUState *cs; @@ -925,7 +942,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); } } @@ -1041,8 +1059,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); } } @@ -1055,8 +1074,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 d9795d0..6eaa3f4 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" +#include "exec/exec-all.h" #define float64_snan_to_qnan(x) ((x) | 0x0008000000000000ULL) #define float32_snan_to_qnan(x) ((x) | 0x00400000) @@ -117,7 +118,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; @@ -200,14 +201,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)); @@ -217,8 +218,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); } } } @@ -491,13 +492,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) { @@ -510,12 +511,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); @@ -532,12 +538,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, &env->fp_status) || float64_is_signaling_nan(farg2.d, &env->fp_status))) { /* 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); } @@ -556,12 +562,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, &env->fp_status) || float64_is_signaling_nan(farg2.d, &env->fp_status))) { /* 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); } @@ -580,12 +586,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, &env->fp_status) || float64_is_signaling_nan(farg2.d, &env->fp_status))) { /* 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); } @@ -604,15 +610,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, &env->fp_status) || float64_is_signaling_nan(farg2.d, &env->fp_status))) { /* 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); } @@ -631,16 +637,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, &env->fp_status)) { \ - 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; \ } @@ -665,7 +671,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; \ } @@ -675,7 +681,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; @@ -683,7 +689,7 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg, if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { /* 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) & @@ -698,28 +704,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. */ @@ -735,13 +741,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, &env->fp_status) || float64_is_signaling_nan(farg2.d, &env->fp_status) || float64_is_signaling_nan(farg3.d, &env->fp_status))) { /* 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; @@ -753,7 +759,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); @@ -778,13 +784,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, &env->fp_status) || float64_is_signaling_nan(farg2.d, &env->fp_status) || float64_is_signaling_nan(farg3.d, &env->fp_status))) { /* 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; @@ -796,7 +802,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); @@ -819,13 +825,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, &env->fp_status) || float64_is_signaling_nan(farg2.d, &env->fp_status) || float64_is_signaling_nan(farg3.d, &env->fp_status))) { /* 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; @@ -837,7 +843,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); @@ -864,13 +870,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, &env->fp_status) || float64_is_signaling_nan(farg2.d, &env->fp_status) || float64_is_signaling_nan(farg3.d, &env->fp_status))) { /* 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; @@ -882,7 +888,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); @@ -905,7 +911,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg) if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { /* 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); @@ -923,12 +929,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, &env->fp_status))) { /* 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); } @@ -944,7 +950,7 @@ uint64_t helper_fre(CPUPPCState *env, uint64_t arg) if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { /* 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; @@ -960,7 +966,7 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg) if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { /* 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); @@ -979,12 +985,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, &env->fp_status))) { /* 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); @@ -1103,7 +1109,7 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2, && (float64_is_signaling_nan(farg1.d, &env->fp_status) || float64_is_signaling_nan(farg2.d, &env->fp_status)))) { /* sNaN comparison */ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); } } @@ -1135,10 +1141,10 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2, float64_is_signaling_nan(farg2.d, &env->fp_status)) { /* 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()); } } } @@ -1838,10 +1844,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, &tstat) || \ tp##_is_signaling_nan(xb.fld, &tstat)) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ } \ } \ \ @@ -1854,7 +1860,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) @@ -1893,10 +1899,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, &tstat) || \ tp##_is_signaling_nan(xb.fld, &tstat)) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ } \ } \ \ @@ -1910,7 +1916,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) @@ -1944,13 +1950,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, &tstat) || \ tp##_is_signaling_nan(xb.fld, &tstat)) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ } \ } \ \ @@ -1964,7 +1970,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) @@ -1991,7 +1997,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ \ for (i = 0; i < nels; i++) { \ if (unlikely(tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \ - 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); \ \ @@ -2005,7 +2011,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) @@ -2038,9 +2044,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, &tstat)) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ } \ } \ \ @@ -2054,7 +2060,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) @@ -2088,9 +2094,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, &tstat)) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ } \ } \ \ @@ -2104,7 +2110,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) @@ -2277,20 +2283,20 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ if (tp##_is_signaling_nan(xa.fld, &tstat) || \ tp##_is_signaling_nan(b->fld, &tstat) || \ tp##_is_signaling_nan(c->fld, &tstat)) { \ - 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());\ } \ } \ \ @@ -2303,7 +2309,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 @@ -2360,10 +2366,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ float64_is_any_nan(xb.VsrD(0)))) { \ if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \ float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \ - 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 { \ @@ -2381,7 +2387,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) @@ -2408,12 +2414,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, &env->fp_status) || \ tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \ - 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)) @@ -2448,10 +2454,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ tp##_is_any_nan(xb.fld))) { \ if (tp##_is_signaling_nan(xa.fld, &env->fp_status) || \ tp##_is_signaling_nan(xb.fld, &env->fp_status)) { \ - 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; \ @@ -2470,7 +2476,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) @@ -2502,7 +2508,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \ if (unlikely(stp##_is_signaling_nan(xb.sfld, \ &env->fp_status))) { \ - 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) { \ @@ -2512,7 +2518,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) @@ -2557,21 +2563,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, &env->fp_status)) { \ - 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), \ @@ -2622,7 +2628,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) @@ -2667,7 +2673,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ for (i = 0; i < nels; i++) { \ if (unlikely(tp##_is_signaling_nan(xb.fld, \ &env->fp_status))) { \ - 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); \ @@ -2686,7 +2692,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_ties_away, 1) @@ -2714,6 +2720,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 1f5cfd0..34560f9 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 e4ed377..5cee620 100644 --- a/target-ppc/mem_helper.c +++ b/target-ppc/mem_helper.c @@ -107,9 +107,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg, if (unlikely((ra != 0 && lsw_reg_in_range(reg, num_used_regs, ra)) || lsw_reg_in_range(reg, num_used_regs, rb))) { env->nip += 4; /* Compensate the "nip - 4" from gen_lswx() */ - 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 cb5ebf5..6661650 100644 --- a/target-ppc/misc_helper.c +++ b/target-ppc/misc_helper.c @@ -39,7 +39,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); @@ -47,7 +47,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 @@ -59,7 +59,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 } @@ -71,7 +71,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 5de1358..a1b27b0 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -241,8 +241,8 @@ void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs) PowerPCCPU *cpu = ppc_env_get_cpu(env); if (ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs) < 0) { - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, - POWERPC_EXCP_INVAL); + raise_exception_err(env, POWERPC_EXCP_PROGRAM, + POWERPC_EXCP_INVAL, GETPC()); } } @@ -252,8 +252,8 @@ target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb) target_ulong rt = 0; if (ppc_load_slb_esid(cpu, 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; } @@ -276,8 +276,8 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb) target_ulong rt = 0; if (ppc_load_slb_vsid(cpu, 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 3eb3cd7..7cd9c2c 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -2598,9 +2598,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 */ @@ -2608,9 +2608,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) { @@ -2892,10 +2892,6 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type, ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, 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 a07faa4..af328ca 100644 --- a/target-ppc/timebase_helper.c +++ b/target-ppc/timebase_helper.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" +#include "exec/exec-all.h" #include "qemu/log.h" /*****************************************************************************/ @@ -143,15 +144,15 @@ target_ulong helper_load_dcr(CPUPPCState *env, target_ulong dcrn) if (unlikely(env->dcr_env == NULL)) { qemu_log_mask(LOG_GUEST_ERROR, "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_mask(LOG_GUEST_ERROR, "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; } @@ -160,14 +161,14 @@ void helper_store_dcr(CPUPPCState *env, target_ulong dcrn, target_ulong val) { if (unlikely(env->dcr_env == NULL)) { qemu_log_mask(LOG_GUEST_ERROR, "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_mask(LOG_GUEST_ERROR, "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 92030b6..0e16578 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -292,7 +292,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error) } 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); @@ -300,14 +300,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error) static 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 void gen_debug_exception(DisasContext *ctx) @@ -2149,8 +2142,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)], \ @@ -2178,8 +2169,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)], \ @@ -2206,8 +2195,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)], \ @@ -2234,8 +2221,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)]); \ @@ -2254,8 +2239,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)]); \ @@ -2290,8 +2273,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)]); @@ -2316,8 +2297,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)]); @@ -2333,8 +2312,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)]); @@ -2424,8 +2401,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)], @@ -2442,8 +2417,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)], @@ -2613,8 +2586,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); @@ -2639,8 +2610,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); @@ -2670,8 +2639,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); @@ -2706,8 +2673,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); @@ -2790,8 +2755,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); @@ -3261,8 +3224,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); @@ -3277,8 +3238,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); @@ -3312,8 +3271,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); @@ -3330,8 +3287,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)); @@ -3351,8 +3306,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) @@ -3371,8 +3324,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(); @@ -4306,7 +4257,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); @@ -4318,7 +4269,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); @@ -4330,7 +4281,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); @@ -4342,7 +4293,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); @@ -4768,8 +4719,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); @@ -4812,8 +4761,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); @@ -5299,8 +5246,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); @@ -6386,8 +6331,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 */ @@ -6396,8 +6339,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 */ @@ -8027,8 +7968,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); \ @@ -8041,9 +7980,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))); \