From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53067) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZC5Ow-0003j9-5S for qemu-devel@nongnu.org; Mon, 06 Jul 2015 08:21:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZC5Op-0006VY-VE for qemu-devel@nongnu.org; Mon, 06 Jul 2015 08:21:34 -0400 Received: from hall.aurel32.net ([2001:bc8:30d7:100::1]:48264) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZC5Op-0006VO-9T for qemu-devel@nongnu.org; Mon, 06 Jul 2015 08:21:27 -0400 Date: Mon, 6 Jul 2015 14:21:23 +0200 From: Aurelien Jarno Message-ID: <20150706122123.GA11638@aurel32.net> References: <20150706082535.11980.88013.stgit@PASHA-ISP> <20150706082639.11980.59873.stgit@PASHA-ISP> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable In-Reply-To: <20150706082639.11980.59873.stgit@PASHA-ISP> Subject: Re: [Qemu-devel] [PATCH v5 11/11] target-ppc: exceptions handling in icount mode List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Pavel Dovgalyuk Cc: pbonzini@redhat.com, rth7680@gmail.com, leon.alrae@imgtec.com, qemu-devel@nongnu.org, agraf@suse.de On 2015-07-06 11:26, Pavel Dovgalyuk wrote: > This patch fixes exception handling in PowerPC. > Instructions generate several types of exceptions. > When exception is generated, it breaks the execution of the current trans= lation > block. Implementation of the exceptions handling does not correctly > restore icount for the instruction which caused the exception. In most ca= ses > icount will be decreased by the value equal to the size of TB. > This patch passes pointer to the translation block internals to the excep= tion > handler. It allows correct restoring of the icount value. With this patch, the ppc*-linux-user targets do not build: | CC ppc-linux-user/target-ppc/excp_helper.o | /home/aurel32/git/qemu/target-ppc/excp_helper.c:879:13: error: =E2=80=98r= aise_exception=E2=80=99 defined but not used [-Werror=3Dunused-function] |=C2=A0 static void raise_exception(CPUPPCState *env, uint32_t exception, u= intptr_t pc) | ^ |=C2=A0cc1: all warnings being treated as errors | /home/aurel32/git/qemu/rules.mak:57: recipe for target 'target-ppc/excp_h= elper.o' failed |=C2=A0make[1]: *** [target-ppc/excp_helper.o] Error 1 |=C2=A0Makefile:178: recipe for target 'subdir-ppc-linux-user' failed |=C2=A0make: *** [subdir-ppc-linux-user] Error 2 > Signed-off-by: Pavel Dovgalyuk > --- > target-ppc/cpu.h | 3 + > target-ppc/excp_helper.c | 38 ++++++-- > target-ppc/fpu_helper.c | 191 ++++++++++++++++++++++--------------= ------ > target-ppc/helper.h | 1=20 > target-ppc/mem_helper.c | 6 + > target-ppc/misc_helper.c | 8 +- > target-ppc/mmu-hash64.c | 12 +-- > target-ppc/mmu_helper.c | 18 ++-- > target-ppc/timebase_helper.c | 20 ++-- > target-ppc/translate.c | 84 +----------------- > 10 files changed, 167 insertions(+), 214 deletions(-) >=20 > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index c05c503..27aaff8 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -2328,4 +2328,7 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu); > */ > PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id); > =20 > +void raise_exception_err(CPUPPCState *env, uint32_t exception, > + uint32_t error_code, uintptr_t pc); > + > #endif /* !defined (__CPU_PPC_H__) */ > diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c > index b803475..5402e0d 100644 > --- a/target-ppc/excp_helper.c > +++ b/target-ppc/excp_helper.c > @@ -846,8 +846,8 @@ static void cpu_dump_rfi(target_ulong RA, target_ulon= g msr) > /***********************************************************************= ******/ > /* Exceptions processing helpers */ > =20 > -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 =3D CPU(ppc_env_get_cpu(env)); > =20 > @@ -856,12 +856,29 @@ void helper_raise_exception_err(CPUPPCState *env, u= int32_t exception, > #endif > cs->exception_index =3D exception; > env->error_code =3D 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); > } > =20 > void helper_raise_exception(CPUPPCState *env, uint32_t exception) > { > - helper_raise_exception_err(env, exception, 0); > + raise_exception_err(env, exception, 0, GETPC()); > +} > + > +static void raise_exception(CPUPPCState *env, uint32_t exception, uintpt= r_t pc) > +{ > + raise_exception_err(env, exception, 0, pc); > } > =20 > #if !defined(CONFIG_USER_ONLY) > @@ -873,7 +890,8 @@ void helper_store_msr(CPUPPCState *env, target_ulong = val) > if (val !=3D 0) { > cs =3D CPU(ppc_env_get_cpu(env)); > cs->interrupt_request |=3D CPU_INTERRUPT_EXITTB; > - helper_raise_exception(env, val); > + /* nip is updated by generated code */ > + raise_exception(env, val, 0); > } > } > =20 > @@ -971,8 +989,9 @@ void helper_tw(CPUPPCState *env, target_ulong arg1, t= arget_ulong arg2, > ((int32_t)arg1 =3D=3D (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); > } > } > =20 > @@ -985,8 +1004,9 @@ void helper_td(CPUPPCState *env, target_ulong arg1, = target_ulong arg2, > ((int64_t)arg1 =3D=3D (int64_t)arg2 && (flags & 0x04))= || > ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) || > ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01)))))= { > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_TRAP); > + /* nip is updated in TB */ > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_TRAP, 0); > } > } > #endif > diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c > index 6cceffc..088ad06 100644 > --- a/target-ppc/fpu_helper.c > +++ b/target-ppc/fpu_helper.c > @@ -116,7 +116,7 @@ void helper_compute_fprf(CPUPPCState *env, uint64_t a= rg) > =20 > /* 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 ret= addr) > { > CPUState *cs =3D CPU(ppc_env_get_cpu(env)); > uint64_t ret =3D 0; > @@ -199,14 +199,14 @@ static inline uint64_t fload_invalid_op_excp(CPUPPC= State *env, int op, > /* Update the floating-point enabled exception summary */ > env->fpscr |=3D 1 << FPSCR_FEX; > if (msr_fe0 !=3D 0 || msr_fe1 !=3D 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; > } > =20 > -static inline void float_zero_divide_excp(CPUPPCState *env) > +static inline void float_zero_divide_excp(CPUPPCState *env, uintptr_t re= taddr) > { > env->fpscr |=3D 1 << FPSCR_ZX; > env->fpscr &=3D ~((1 << FPSCR_FR) | (1 << FPSCR_FI)); > @@ -216,8 +216,8 @@ static inline void float_zero_divide_excp(CPUPPCState= *env) > /* Update the floating-point enabled exception summary */ > env->fpscr |=3D 1 << FPSCR_FEX; > if (msr_fe0 !=3D 0 || msr_fe1 !=3D 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, re= taddr); > } > } > } > @@ -490,13 +490,13 @@ void store_fpscr(CPUPPCState *env, uint64_t arg, ui= nt32_t mask) > helper_store_fpscr(env, arg, mask); > } > =20 > -void helper_float_check_status(CPUPPCState *env) > +static void do_float_check_status(CPUPPCState *env, uintptr_t retaddr) > { > CPUState *cs =3D CPU(ppc_env_get_cpu(env)); > int status =3D get_float_exception_flags(&env->fp_status); > =20 > if (status & float_flag_divbyzero) { > - float_zero_divide_excp(env); > + float_zero_divide_excp(env, retaddr); > } else if (status & float_flag_overflow) { > float_overflow_excp(env); > } else if (status & float_flag_underflow) { > @@ -509,12 +509,17 @@ void helper_float_check_status(CPUPPCState *env) > (env->error_code & POWERPC_EXCP_FP)) { > /* Differred floating-point exception after target FPR update */ > if (msr_fe0 !=3D 0 || msr_fe1 !=3D 0) { > - helper_raise_exception_err(env, cs->exception_index, > - env->error_code); > + raise_exception_err(env, cs->exception_index, > + env->error_code, retaddr); > } > } > } > =20 > +void helper_float_check_status(CPUPPCState *env) > +{ > + do_float_check_status(env, GETPC()); > +} > + > void helper_reset_fpstatus(CPUPPCState *env) > { > set_float_exception_flags(0, &env->fp_status); > @@ -531,12 +536,12 @@ uint64_t helper_fadd(CPUPPCState *env, uint64_t arg= 1, uint64_t arg2) > if (unlikely(float64_is_infinity(farg1.d) && float64_is_infinity(far= g2.d) && > float64_is_neg(farg1.d) !=3D float64_is_neg(farg2.d))) { > /* Magnitude subtraction of infinities */ > - farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1= ); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1= , GETPC()); > } else { > if (unlikely(float64_is_signaling_nan(farg1.d) || > float64_is_signaling_nan(farg2.d))) { > /* sNaN addition */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC(= )); > } > farg1.d =3D float64_add(farg1.d, farg2.d, &env->fp_status); > } > @@ -555,12 +560,12 @@ uint64_t helper_fsub(CPUPPCState *env, uint64_t arg= 1, uint64_t arg2) > if (unlikely(float64_is_infinity(farg1.d) && float64_is_infinity(far= g2.d) && > float64_is_neg(farg1.d) =3D=3D float64_is_neg(farg2.d))= ) { > /* Magnitude subtraction of infinities */ > - farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1= ); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1= , GETPC()); > } else { > if (unlikely(float64_is_signaling_nan(farg1.d) || > float64_is_signaling_nan(farg2.d))) { > /* sNaN subtraction */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC(= )); > } > farg1.d =3D float64_sub(farg1.d, farg2.d, &env->fp_status); > } > @@ -579,12 +584,12 @@ uint64_t helper_fmul(CPUPPCState *env, uint64_t arg= 1, 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 =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1= ); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1= , GETPC()); > } else { > if (unlikely(float64_is_signaling_nan(farg1.d) || > float64_is_signaling_nan(farg2.d))) { > /* sNaN multiplication */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC(= )); > } > farg1.d =3D float64_mul(farg1.d, farg2.d, &env->fp_status); > } > @@ -603,15 +608,15 @@ uint64_t helper_fdiv(CPUPPCState *env, uint64_t arg= 1, uint64_t arg2) > if (unlikely(float64_is_infinity(farg1.d) && > float64_is_infinity(farg2.d))) { > /* Division of infinity by infinity */ > - farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1= ); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1= , GETPC()); > } else if (unlikely(float64_is_zero(farg1.d) && float64_is_zero(farg= 2.d))) { > /* Division of zero by zero */ > - farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1= ); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1= , GETPC()); > } else { > if (unlikely(float64_is_signaling_nan(farg1.d) || > float64_is_signaling_nan(farg2.d))) { > /* sNaN division */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC(= )); > } > farg1.d =3D float64_div(farg1.d, farg2.d, &env->fp_status); > } > @@ -630,16 +635,16 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg= ) \ > \ > if (unlikely(env->fp_status.float_exception_flags)) { \ > if (float64_is_any_nan(arg)) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1, GETPC()= );\ > if (float64_is_signaling_nan(arg)) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GE= TPC());\ > } \ > farg.ll =3D nanval; = \ > } else if (env->fp_status.float_exception_flags & \ > float_flag_invalid) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1, GETPC()= );\ > } \ > - helper_float_check_status(env); \ > + do_float_check_status(env, GETPC()); \ > } \ > return farg.ll; \ > } > @@ -664,7 +669,7 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg) = \ > } else { \ > farg.d =3D cvtr(arg, &env->fp_status); \ > } \ > - helper_float_check_status(env); \ > + do_float_check_status(env, GETPC()); \ > return farg.ll; \ > } > =20 > @@ -674,7 +679,7 @@ FPU_FCFI(fcfidu, uint64_to_float64, 0) > FPU_FCFI(fcfidus, uint64_to_float32, 1) > =20 > static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg, > - int rounding_mode) > + int rounding_mode, uint64_t retaddr) > { > CPU_DoubleU farg; > =20 > @@ -682,7 +687,7 @@ static inline uint64_t do_fri(CPUPPCState *env, uint6= 4_t arg, > =20 > if (unlikely(float64_is_signaling_nan(farg.d))) { > /* sNaN round */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, retaddr); > farg.ll =3D arg | 0x0008000000000000ULL; > } else { > int inexact =3D get_float_exception_flags(&env->fp_status) & > @@ -697,28 +702,28 @@ static inline uint64_t do_fri(CPUPPCState *env, uin= t64_t arg, > env->fp_status.float_exception_flags &=3D ~float_flag_inexac= t; > } > } > - helper_float_check_status(env); > + do_float_check_status(env, GETPC()); > return farg.ll; > } > =20 > 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()); > } > =20 > 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()); > } > =20 > 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()); > } > =20 > 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()); > } > =20 > /* fmadd - fmadd. */ > @@ -734,13 +739,13 @@ uint64_t helper_fmadd(CPUPPCState *env, uint64_t ar= g1, 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 =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1= ); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1= , GETPC()); > } else { > if (unlikely(float64_is_signaling_nan(farg1.d) || > float64_is_signaling_nan(farg2.d) || > float64_is_signaling_nan(farg3.d))) { > /* sNaN operation */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC(= )); > } > /* This is the way the PowerPC specification defines it */ > float128 ft0_128, ft1_128; > @@ -752,7 +757,7 @@ uint64_t helper_fmadd(CPUPPCState *env, uint64_t arg1= , uint64_t arg2, > float64_is_infinity(farg3.d) && > float128_is_neg(ft0_128) !=3D float64_is_neg(farg3.= d))) { > /* Magnitude subtraction of infinities */ > - farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIS= I, 1); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIS= I, 1, GETPC()); > } else { > ft1_128 =3D float64_to_float128(farg3.d, &env->fp_status); > ft0_128 =3D float128_add(ft0_128, ft1_128, &env->fp_status); > @@ -777,13 +782,13 @@ uint64_t helper_fmsub(CPUPPCState *env, uint64_t ar= g1, uint64_t arg2, > (float64_is_zero(farg1.d) && > float64_is_infinity(farg2.d)))) { > /* Multiplication of zero by infinity */ > - farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1= ); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1= , GETPC()); > } else { > if (unlikely(float64_is_signaling_nan(farg1.d) || > float64_is_signaling_nan(farg2.d) || > float64_is_signaling_nan(farg3.d))) { > /* sNaN operation */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC(= )); > } > /* This is the way the PowerPC specification defines it */ > float128 ft0_128, ft1_128; > @@ -795,7 +800,7 @@ uint64_t helper_fmsub(CPUPPCState *env, uint64_t arg1= , uint64_t arg2, > float64_is_infinity(farg3.d) && > float128_is_neg(ft0_128) =3D=3D float64_is_neg(farg= 3.d))) { > /* Magnitude subtraction of infinities */ > - farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIS= I, 1); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIS= I, 1, GETPC()); > } else { > ft1_128 =3D float64_to_float128(farg3.d, &env->fp_status); > ft0_128 =3D float128_sub(ft0_128, ft1_128, &env->fp_status); > @@ -818,13 +823,13 @@ uint64_t helper_fnmadd(CPUPPCState *env, uint64_t a= rg1, 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 =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1= ); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1= , GETPC()); > } else { > if (unlikely(float64_is_signaling_nan(farg1.d) || > float64_is_signaling_nan(farg2.d) || > float64_is_signaling_nan(farg3.d))) { > /* sNaN operation */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC(= )); > } > /* This is the way the PowerPC specification defines it */ > float128 ft0_128, ft1_128; > @@ -836,7 +841,7 @@ uint64_t helper_fnmadd(CPUPPCState *env, uint64_t arg= 1, uint64_t arg2, > float64_is_infinity(farg3.d) && > float128_is_neg(ft0_128) !=3D float64_is_neg(farg3.= d))) { > /* Magnitude subtraction of infinities */ > - farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIS= I, 1); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIS= I, 1, GETPC()); > } else { > ft1_128 =3D float64_to_float128(farg3.d, &env->fp_status); > ft0_128 =3D float128_add(ft0_128, ft1_128, &env->fp_status); > @@ -863,13 +868,13 @@ uint64_t helper_fnmsub(CPUPPCState *env, uint64_t a= rg1, uint64_t arg2, > (float64_is_zero(farg1.d) && > float64_is_infinity(farg2.d)))) { > /* Multiplication of zero by infinity */ > - farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1= ); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1= , GETPC()); > } else { > if (unlikely(float64_is_signaling_nan(farg1.d) || > float64_is_signaling_nan(farg2.d) || > float64_is_signaling_nan(farg3.d))) { > /* sNaN operation */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC(= )); > } > /* This is the way the PowerPC specification defines it */ > float128 ft0_128, ft1_128; > @@ -881,7 +886,7 @@ uint64_t helper_fnmsub(CPUPPCState *env, uint64_t arg= 1, uint64_t arg2, > float64_is_infinity(farg3.d) && > float128_is_neg(ft0_128) =3D=3D float64_is_neg(farg= 3.d))) { > /* Magnitude subtraction of infinities */ > - farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIS= I, 1); > + farg1.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIS= I, 1, GETPC()); > } else { > ft1_128 =3D float64_to_float128(farg3.d, &env->fp_status); > ft0_128 =3D float128_sub(ft0_128, ft1_128, &env->fp_status); > @@ -904,7 +909,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg) > =20 > if (unlikely(float64_is_signaling_nan(farg.d))) { > /* sNaN square root */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); > } > f32 =3D float64_to_float32(farg.d, &env->fp_status); > farg.d =3D float32_to_float64(f32, &env->fp_status); > @@ -922,12 +927,12 @@ uint64_t helper_fsqrt(CPUPPCState *env, uint64_t ar= g) > if (unlikely(float64_is_any_nan(farg.d))) { > if (unlikely(float64_is_signaling_nan(farg.d))) { > /* sNaN reciprocal square root */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC(= )); > farg.ll =3D 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 =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1= ); > + farg.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1= , GETPC()); > } else { > farg.d =3D float64_sqrt(farg.d, &env->fp_status); > } > @@ -943,7 +948,7 @@ uint64_t helper_fre(CPUPPCState *env, uint64_t arg) > =20 > if (unlikely(float64_is_signaling_nan(farg.d))) { > /* sNaN reciprocal */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); > } > farg.d =3D float64_div(float64_one, farg.d, &env->fp_status); > return farg.d; > @@ -959,7 +964,7 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg) > =20 > if (unlikely(float64_is_signaling_nan(farg.d))) { > /* sNaN reciprocal */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); > } > farg.d =3D float64_div(float64_one, farg.d, &env->fp_status); > f32 =3D float64_to_float32(farg.d, &env->fp_status); > @@ -978,12 +983,12 @@ uint64_t helper_frsqrte(CPUPPCState *env, uint64_t = arg) > if (unlikely(float64_is_any_nan(farg.d))) { > if (unlikely(float64_is_signaling_nan(farg.d))) { > /* sNaN reciprocal square root */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC(= )); > farg.ll =3D 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 =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1= ); > + farg.ll =3D fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1= , GETPC()); > } else { > farg.d =3D float64_sqrt(farg.d, &env->fp_status); > farg.d =3D float64_div(float64_one, farg.d, &env->fp_status); > @@ -1102,7 +1107,7 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, = uint64_t arg2, > && (float64_is_signaling_nan(farg1.d) || > float64_is_signaling_nan(farg2.d)))) { > /* sNaN comparison */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); > } > } > =20 > @@ -1134,10 +1139,10 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1= , uint64_t arg2, > float64_is_signaling_nan(farg2.d)) { > /* sNaN comparison */ > fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | > - POWERPC_EXCP_FP_VXVC, 1); > + POWERPC_EXCP_FP_VXVC, 1, GETPC()); > } else { > /* qNaN comparison */ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 1); > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 1, GETPC()); > } > } > } > @@ -1837,10 +1842,10 @@ void helper_##name(CPUPPCState *env, uint32_t opc= ode) \ > = \ > if (unlikely(tstat.float_exception_flags & float_flag_invalid)) = { \ > if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf)= ; \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf,= GETPC());\ > } else if (tp##_is_signaling_nan(xa.fld) || = \ > tp##_is_signaling_nan(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= ); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= , GETPC());\ > } = \ > } = \ > = \ > @@ -1853,7 +1858,7 @@ void helper_##name(CPUPPCState *env, uint32_t opcod= e) \ > } = \ > } = \ > putVSR(xT(opcode), &xt, env); = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > VSX_ADD_SUB(xsadddp, add, 1, float64, VsrD(0), 1, 0) > @@ -1892,10 +1897,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcod= e) \ > if (unlikely(tstat.float_exception_flags & float_flag_invalid)) = { \ > if ((tp##_is_infinity(xa.fld) && tp##_is_zero(xb.fld)) || = \ > (tp##_is_infinity(xb.fld) && tp##_is_zero(xa.fld))) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, sfprf)= ; \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, sfprf,= GETPC());\ > } else if (tp##_is_signaling_nan(xa.fld) || = \ > tp##_is_signaling_nan(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= ); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= , GETPC());\ > } = \ > } = \ > = \ > @@ -1909,7 +1914,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > } = \ > = \ > putVSR(xT(opcode), &xt, env); = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > VSX_MUL(xsmuldp, 1, float64, VsrD(0), 1, 0) > @@ -1943,13 +1948,13 @@ void helper_##op(CPUPPCState *env, uint32_t opcod= e) \ > = \ > if (unlikely(tstat.float_exception_flags & float_flag_invalid)) = { \ > if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, sfprf)= ; \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, sfprf,= GETPC());\ > } else if (tp##_is_zero(xa.fld) && = \ > tp##_is_zero(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf)= ; \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf,= GETPC());\ > } else if (tp##_is_signaling_nan(xa.fld) || = \ > tp##_is_signaling_nan(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= ); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= , GETPC());\ > } = \ > } = \ > = \ > @@ -1963,7 +1968,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > } = \ > = \ > putVSR(xT(opcode), &xt, env); = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > VSX_DIV(xsdivdp, 1, float64, VsrD(0), 1, 0) > @@ -1990,7 +1995,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > = \ > for (i =3D 0; i < nels; i++) { = \ > if (unlikely(tp##_is_signaling_nan(xb.fld))) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= ); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= , GETPC());\ > } = \ > xt.fld =3D tp##_div(tp##_one, xb.fld, &env->fp_status); = \ > = \ > @@ -2004,7 +2009,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > } = \ > = \ > putVSR(xT(opcode), &xt, env); = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > VSX_RE(xsredp, 1, float64, VsrD(0), 1, 0) > @@ -2037,9 +2042,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > = \ > if (unlikely(tstat.float_exception_flags & float_flag_invalid)) = { \ > if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf= ); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf= , GETPC());\ > } else if (tp##_is_signaling_nan(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= ); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= , GETPC());\ > } = \ > } = \ > = \ > @@ -2053,7 +2058,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > } = \ > = \ > putVSR(xT(opcode), &xt, env); = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > VSX_SQRT(xssqrtdp, 1, float64, VsrD(0), 1, 0) > @@ -2087,9 +2092,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > = \ > if (unlikely(tstat.float_exception_flags & float_flag_invalid)) = { \ > if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf= ); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf= , GETPC());\ > } else if (tp##_is_signaling_nan(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= ); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= , GETPC());\ > } = \ > } = \ > = \ > @@ -2103,7 +2108,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > } = \ > = \ > putVSR(xT(opcode), &xt, env); = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > VSX_RSQRTE(xsrsqrtedp, 1, float64, VsrD(0), 1, 0) > @@ -2276,20 +2281,20 @@ void helper_##op(CPUPPCState *env, uint32_t opcod= e) \ > if (tp##_is_signaling_nan(xa.fld) || = \ > tp##_is_signaling_nan(b->fld) || = \ > tp##_is_signaling_nan(c->fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= ); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf= , GETPC());\ > tstat.float_exception_flags &=3D ~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 =3D float64_to_##tp(fload_invalid_op_excp(env= , \ > - POWERPC_EXCP_FP_VXIMZ, sfprf), &env->fp_status); = \ > + POWERPC_EXCP_FP_VXIMZ, sfprf, GETPC()), &env->fp_sta= tus); \ > tstat.float_exception_flags &=3D ~float_flag_invalid; = \ > } = \ > if ((tstat.float_exception_flags & float_flag_invalid) && = \ > ((tp##_is_infinity(xa.fld) || = \ > tp##_is_infinity(b->fld)) && = \ > tp##_is_infinity(c->fld))) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf)= ; \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf,= GETPC());\ > } = \ > } = \ > = \ > @@ -2302,7 +2307,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > } = \ > } = \ > putVSR(xT(opcode), &xt_out, env); = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > #define MADD_FLGS 0 > @@ -2359,10 +2364,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcod= e) \ > float64_is_any_nan(xb.VsrD(0)))) { = \ > if (float64_is_signaling_nan(xa.VsrD(0)) || = \ > float64_is_signaling_nan(xb.VsrD(0))) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); = \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC(= ));\ > } = \ > if (ordered) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); = \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0, GETPC())= ;\ > } = \ > cc =3D 1; = \ > } else { = \ > @@ -2380,7 +2385,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > env->fpscr |=3D cc << FPSCR_FPRF; = \ > env->crf[BF(opcode)] =3D cc; = \ > = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > VSX_SCALAR_CMP(xscmpodp, 1) > @@ -2407,12 +2412,12 @@ void helper_##name(CPUPPCState *env, uint32_t opc= ode) \ > xt.fld =3D tp##_##op(xa.fld, xb.fld, &env->fp_status); = \ > if (unlikely(tp##_is_signaling_nan(xa.fld) || = \ > tp##_is_signaling_nan(xb.fld))) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); = \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC(= )); \ > } = \ > } = \ > = \ > putVSR(xT(opcode), &xt, env); = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > VSX_MAX_MIN(xsmaxdp, maxnum, 1, float64, VsrD(0)) > @@ -2447,10 +2452,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcod= e) \ > tp##_is_any_nan(xb.fld))) { = \ > if (tp##_is_signaling_nan(xa.fld) || = \ > tp##_is_signaling_nan(xb.fld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); = \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GE= TPC());\ > } = \ > if (svxvc) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); = \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0, GETP= C());\ > } = \ > xt.fld =3D 0; = \ > all_true =3D 0; = \ > @@ -2469,7 +2474,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > if ((opcode >> (31-21)) & 1) { = \ > env->crf[6] =3D (all_true ? 0x8 : 0) | (all_false ? 0x2 : 0); = \ > } = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > VSX_CMP(xvcmpeqdp, 2, float64, VsrD(i), eq, 0) > @@ -2500,7 +2505,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > for (i =3D 0; i < nels; i++) { \ > xt.tfld =3D stp##_to_##ttp(xb.sfld, &env->fp_status); \ > if (unlikely(stp##_is_signaling_nan(xb.sfld))) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC(= )); \ > xt.tfld =3D ttp##_snan_to_qnan(xt.tfld); \ > } \ > if (sfprf) { \ > @@ -2510,7 +2515,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > } \ > \ > putVSR(xT(opcode), &xt, env); \ > - helper_float_check_status(env); \ > + do_float_check_status(env, GETPC()); \ > } > =20 > VSX_CVT_FP_TO_FP(xscvdpsp, 1, float64, float32, VsrD(0), VsrW(0), 1) > @@ -2555,21 +2560,21 @@ void helper_##op(CPUPPCState *env, uint32_t opcod= e) \ > for (i =3D 0; i < nels; i++) { = \ > if (unlikely(stp##_is_any_nan(xb.sfld))) { = \ > if (stp##_is_signaling_nan(xb.sfld)) { = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); = \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GE= TPC());\ > } = \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); = \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0, GETPC()= ); \ > xt.tfld =3D rnan; = \ > } else { = \ > xt.tfld =3D stp##_to_##ttp##_round_to_zero(xb.sfld, = \ > &env->fp_status); = \ > if (env->fp_status.float_exception_flags & float_flag_invali= d) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); = \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0, GET= PC());\ > } = \ > } = \ > } = \ > = \ > putVSR(xT(opcode), &xt, env); = \ > - helper_float_check_status(env); = \ > + do_float_check_status(env, GETPC()); = \ > } > =20 > VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, VsrD(0), VsrD(0), \ > @@ -2620,7 +2625,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > } \ > \ > putVSR(xT(opcode), &xt, env); \ > - helper_float_check_status(env); \ > + do_float_check_status(env, GETPC()); \ > } > =20 > VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, VsrD(0), VsrD(0), 1, 0) > @@ -2664,7 +2669,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > \ > for (i =3D 0; i < nels; i++) { = \ > if (unlikely(tp##_is_signaling_nan(xb.fld))) { \ > - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ > + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC(= ));\ > xt.fld =3D tp##_snan_to_qnan(xb.fld); = \ > } else { \ > xt.fld =3D tp##_round_to_int(xb.fld, &env->fp_status); = \ > @@ -2683,7 +2688,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)= \ > } \ > \ > putVSR(xT(opcode), &xt, env); \ > - helper_float_check_status(env); \ > + do_float_check_status(env, GETPC()); \ > } > =20 > VSX_ROUND(xsrdpi, 1, float64, VsrD(0), float_round_nearest_even, 1) > @@ -2711,6 +2716,6 @@ uint64_t helper_xsrsp(CPUPPCState *env, uint64_t xb) > uint64_t xt =3D helper_frsp(env, xb); > =20 > helper_compute_fprf(env, xt); > - helper_float_check_status(env); > + do_float_check_status(env, GETPC()); > return xt; > } > diff --git a/target-ppc/helper.h b/target-ppc/helper.h > index 869be15..fee2dd1 100644 > --- a/target-ppc/helper.h > +++ b/target-ppc/helper.h > @@ -1,4 +1,5 @@ > DEF_HELPER_3(raise_exception_err, void, env, i32, i32) > +DEF_HELPER_3(raise_exception_end, void, env, i32, i32) > DEF_HELPER_2(raise_exception, void, env, i32) > DEF_HELPER_4(tw, void, env, tl, tl, i32) > #if defined(TARGET_PPC64) > diff --git a/target-ppc/mem_helper.c b/target-ppc/mem_helper.c > index 6d37dae..1c67562 100644 > --- a/target-ppc/mem_helper.c > +++ b/target-ppc/mem_helper.c > @@ -102,9 +102,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr,= uint32_t reg, > if (likely(xer_bc !=3D 0)) { > if (unlikely((ra !=3D 0 && reg < ra && (reg + xer_bc) > ra) || > (reg < rb && (reg + xer_bc) > rb))) { > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL | > - POWERPC_EXCP_INVAL_LSWX); > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL | > + POWERPC_EXCP_INVAL_LSWX, GETPC()); > } else { > helper_lsw(env, addr, xer_bc, reg); > } > diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c > index 6b12ca8..1596187 100644 > --- a/target-ppc/misc_helper.c > +++ b/target-ppc/misc_helper.c > @@ -37,7 +37,7 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t s= prn) > =20 > #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= ); > =20 > @@ -45,7 +45,7 @@ static void raise_fu_exception(CPUPPCState *env, uint32= _t bit, > cause &=3D FSCR_IC_MASK; > env->spr[SPR_FSCR] |=3D (target_ulong)cause << FSCR_IC_POS; > =20 > - helper_raise_exception_err(env, POWERPC_EXCP_FU, 0); > + raise_exception_err(env, POWERPC_EXCP_FU, 0, retaddr); > } > #endif > =20 > @@ -57,7 +57,7 @@ void helper_fscr_facility_check(CPUPPCState *env, uint3= 2_t bit, > /* Facility is enabled, continue */ > return; > } > - raise_fu_exception(env, bit, sprn, cause); > + raise_fu_exception(env, bit, sprn, cause, GETPC()); > #endif > } > =20 > @@ -69,7 +69,7 @@ void helper_msr_facility_check(CPUPPCState *env, uint32= _t bit, > /* Facility is enabled, continue */ > return; > } > - raise_fu_exception(env, bit, sprn, cause); > + raise_fu_exception(env, bit, sprn, cause, GETPC()); > #endif > } > =20 > diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c > index 7df6ede..7f22706 100644 > --- a/target-ppc/mmu-hash64.c > +++ b/target-ppc/mmu-hash64.c > @@ -197,8 +197,8 @@ static int ppc_load_slb_vsid(CPUPPCState *env, target= _ulong rb, > void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs) > { > if (ppc_store_slb(env, rb, rs) < 0) { > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL); > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL, GETPC()); > } > } > =20 > @@ -207,8 +207,8 @@ target_ulong helper_load_slb_esid(CPUPPCState *env, t= arget_ulong rb) > target_ulong rt =3D 0; > =20 > if (ppc_load_slb_esid(env, rb, &rt) < 0) { > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL); > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL, GETPC()); > } > return rt; > } > @@ -218,8 +218,8 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, t= arget_ulong rb) > target_ulong rt =3D 0; > =20 > if (ppc_load_slb_vsid(env, rb, &rt) < 0) { > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL); > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL, GETPC()); > } > return rt; > } > diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c > index 527c6ad..acd266f 100644 > --- a/target-ppc/mmu_helper.c > +++ b/target-ppc/mmu_helper.c > @@ -2635,9 +2635,9 @@ void helper_booke206_tlbwe(CPUPPCState *env) > tlb =3D booke206_cur_tlb(env); > =20 > 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()); > } > =20 > /* check that we support the targeted size */ > @@ -2645,9 +2645,9 @@ void helper_booke206_tlbwe(CPUPPCState *env) > size_ps =3D booke206_tlbnps(env, tlbn); > if ((env->spr[SPR_BOOKE_MAS1] & MAS1_VALID) && (tlbncfg & TLBnCFG_AV= AIL) && > !(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()); > } > =20 > if (msr_gs) { > @@ -2924,10 +2924,6 @@ void tlb_fill(CPUState *cs, target_ulong addr, int= is_write, int mmu_idx, > ret =3D cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx); > } > if (unlikely(ret !=3D 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, r= etaddr); > } > } > diff --git a/target-ppc/timebase_helper.c b/target-ppc/timebase_helper.c > index 865dcbe..229523c 100644 > --- a/target-ppc/timebase_helper.c > +++ b/target-ppc/timebase_helper.c > @@ -131,14 +131,14 @@ target_ulong helper_load_dcr(CPUPPCState *env, targ= et_ulong dcrn) > =20 > if (unlikely(env->dcr_env =3D=3D NULL)) { > qemu_log("No DCR environment\n"); > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL | > - POWERPC_EXCP_INVAL_INVAL); > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL | > + POWERPC_EXCP_INVAL_INVAL, GETPC()); > } else if (unlikely(ppc_dcr_read(env->dcr_env, > (uint32_t)dcrn, &val) !=3D 0)) { > qemu_log("DCR read error %d %03x\n", (uint32_t)dcrn, (uint32_t)d= crn); > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL | POWERPC_EXCP_PRI= V_REG); > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG, = GETPC()); > } > return val; > } > @@ -147,13 +147,13 @@ void helper_store_dcr(CPUPPCState *env, target_ulon= g dcrn, target_ulong val) > { > if (unlikely(env->dcr_env =3D=3D NULL)) { > qemu_log("No DCR environment\n"); > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL | > - POWERPC_EXCP_INVAL_INVAL); > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL | > + POWERPC_EXCP_INVAL_INVAL, GETPC()); > } else if (unlikely(ppc_dcr_write(env->dcr_env, (uint32_t)dcrn, > (uint32_t)val) !=3D 0)) { > qemu_log("DCR write error %d %03x\n", (uint32_t)dcrn, (uint32_t)= dcrn); > - helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL | POWERPC_EXCP_PRI= V_REG); > + raise_exception_err(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG, = GETPC()); > } > } > diff --git a/target-ppc/translate.c b/target-ppc/translate.c > index 84c5cea..fd5b503 100644 > --- a/target-ppc/translate.c > +++ b/target-ppc/translate.c > @@ -288,7 +288,7 @@ static inline void gen_exception_err(DisasContext *ct= x, uint32_t excp, uint32_t > } > t0 =3D tcg_const_i32(excp); > t1 =3D 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 =3D (excp); > @@ -296,14 +296,7 @@ static inline void gen_exception_err(DisasContext *c= tx, uint32_t excp, uint32_t > =20 > static inline void gen_exception(DisasContext *ctx, uint32_t excp) > { > - TCGv_i32 t0; > - if (ctx->exception =3D=3D POWERPC_EXCP_NONE) { > - gen_update_nip(ctx, ctx->nip); > - } > - t0 =3D tcg_const_i32(excp); > - gen_helper_raise_exception(cpu_env, t0); > - tcg_temp_free_i32(t0); > - ctx->exception =3D (excp); > + gen_exception_err(ctx, excp, 0); > } > =20 > static inline void gen_debug_exception(DisasContext *ctx) > @@ -2090,8 +2083,6 @@ static void gen_f##name(DisasContext *ctx) = \ > gen_exception(ctx, POWERPC_EXCP_FPU); = \ > return; = \ > } = \ > - /* NIP cannot be restored if the memory exception comes from an help= er */ \ > - gen_update_nip(ctx, ctx->nip - 4); = \ > gen_reset_fpstatus(); = \ > gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env, = \ > cpu_fpr[rA(ctx->opcode)], = \ > @@ -2119,8 +2110,6 @@ static void gen_f##name(DisasContext *ctx) = \ > gen_exception(ctx, POWERPC_EXCP_FPU); = \ > return; = \ > } = \ > - /* NIP cannot be restored if the memory exception comes from an help= er */ \ > - gen_update_nip(ctx, ctx->nip - 4); = \ > gen_reset_fpstatus(); = \ > gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env, = \ > cpu_fpr[rA(ctx->opcode)], = \ > @@ -2147,8 +2136,6 @@ static void gen_f##name(DisasContext *ctx) = \ > gen_exception(ctx, POWERPC_EXCP_FPU); = \ > return; = \ > } = \ > - /* NIP cannot be restored if the memory exception comes from an help= er */ \ > - gen_update_nip(ctx, ctx->nip - 4); = \ > gen_reset_fpstatus(); = \ > gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env, = \ > cpu_fpr[rA(ctx->opcode)], = \ > @@ -2175,8 +2162,6 @@ static void gen_f##name(DisasContext *ctx) = \ > gen_exception(ctx, POWERPC_EXCP_FPU); = \ > return; = \ > } = \ > - /* NIP cannot be restored if the memory exception comes from an help= er */ \ > - gen_update_nip(ctx, ctx->nip - 4); = \ > gen_reset_fpstatus(); = \ > gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env, = \ > cpu_fpr[rB(ctx->opcode)]); = \ > @@ -2195,8 +2180,6 @@ static void gen_f##name(DisasContext *ctx) = \ > gen_exception(ctx, POWERPC_EXCP_FPU); = \ > return; = \ > } = \ > - /* NIP cannot be restored if the memory exception comes from an help= er */ \ > - gen_update_nip(ctx, ctx->nip - 4); = \ > gen_reset_fpstatus(); = \ > gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env, = \ > cpu_fpr[rB(ctx->opcode)]); = \ > @@ -2231,8 +2214,6 @@ static void gen_frsqrtes(DisasContext *ctx) > gen_exception(ctx, POWERPC_EXCP_FPU); > return; > } > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_reset_fpstatus(); > gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_env, > cpu_fpr[rB(ctx->opcode)]); > @@ -2257,8 +2238,6 @@ static void gen_fsqrt(DisasContext *ctx) > gen_exception(ctx, POWERPC_EXCP_FPU); > return; > } > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_reset_fpstatus(); > gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env, > cpu_fpr[rB(ctx->opcode)]); > @@ -2274,8 +2253,6 @@ static void gen_fsqrts(DisasContext *ctx) > gen_exception(ctx, POWERPC_EXCP_FPU); > return; > } > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_reset_fpstatus(); > gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env, > cpu_fpr[rB(ctx->opcode)]); > @@ -2365,8 +2342,6 @@ static void gen_fcmpo(DisasContext *ctx) > gen_exception(ctx, POWERPC_EXCP_FPU); > return; > } > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_reset_fpstatus(); > crf =3D tcg_const_i32(crfD(ctx->opcode)); > gen_helper_fcmpo(cpu_env, cpu_fpr[rA(ctx->opcode)], > @@ -2383,8 +2358,6 @@ static void gen_fcmpu(DisasContext *ctx) > gen_exception(ctx, POWERPC_EXCP_FPU); > return; > } > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_reset_fpstatus(); > crf =3D tcg_const_i32(crfD(ctx->opcode)); > gen_helper_fcmpu(cpu_env, cpu_fpr[rA(ctx->opcode)], > @@ -2541,8 +2514,6 @@ static void gen_mtfsb0(DisasContext *ctx) > gen_reset_fpstatus(); > if (likely(crb !=3D FPSCR_FEX && crb !=3D 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 =3D tcg_const_i32(crb); > gen_helper_fpscr_clrbit(cpu_env, t0); > tcg_temp_free_i32(t0); > @@ -2567,8 +2538,6 @@ static void gen_mtfsb1(DisasContext *ctx) > /* XXX: we pretend we can only do IEEE floating-point computations */ > if (likely(crb !=3D FPSCR_FEX && crb !=3D FPSCR_VX && crb !=3D 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 =3D tcg_const_i32(crb); > gen_helper_fpscr_setbit(cpu_env, t0); > tcg_temp_free_i32(t0); > @@ -2598,8 +2567,6 @@ static void gen_mtfsf(DisasContext *ctx) > gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); > return; > } > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_reset_fpstatus(); > if (l) { > t0 =3D tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff = : 0xff); > @@ -2634,8 +2601,6 @@ static void gen_mtfsfi(DisasContext *ctx) > return; > } > sh =3D (8 * w) + 7 - bf; > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_reset_fpstatus(); > t0 =3D tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh)); > t1 =3D tcg_const_i32(1 << sh); > @@ -2718,8 +2683,6 @@ static inline void gen_check_align(DisasContext *ct= x, TCGv EA, int mask) > TCGLabel *l1 =3D gen_new_label(); > TCGv t0 =3D tcg_temp_new(); > TCGv_i32 t1, t2; > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - 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 =3D tcg_const_i32(POWERPC_EXCP_ALIGN); > @@ -3167,8 +3130,6 @@ static void gen_lmw(DisasContext *ctx) > TCGv t0; > TCGv_i32 t1; > gen_set_access_type(ctx, ACCESS_INT); > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > t0 =3D tcg_temp_new(); > t1 =3D tcg_const_i32(rD(ctx->opcode)); > gen_addr_imm_index(ctx, t0, 0); > @@ -3183,8 +3144,6 @@ static void gen_stmw(DisasContext *ctx) > TCGv t0; > TCGv_i32 t1; > gen_set_access_type(ctx, ACCESS_INT); > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > t0 =3D tcg_temp_new(); > t1 =3D tcg_const_i32(rS(ctx->opcode)); > gen_addr_imm_index(ctx, t0, 0); > @@ -3220,8 +3179,6 @@ static void gen_lswi(DisasContext *ctx) > return; > } > gen_set_access_type(ctx, ACCESS_INT); > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > t0 =3D tcg_temp_new(); > gen_addr_register(ctx, t0); > t1 =3D tcg_const_i32(nb); > @@ -3238,8 +3195,6 @@ static void gen_lswx(DisasContext *ctx) > TCGv t0; > TCGv_i32 t1, t2, t3; > gen_set_access_type(ctx, ACCESS_INT); > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > t0 =3D tcg_temp_new(); > gen_addr_reg_index(ctx, t0); > t1 =3D tcg_const_i32(rD(ctx->opcode)); > @@ -3259,8 +3214,6 @@ static void gen_stswi(DisasContext *ctx) > TCGv_i32 t1, t2; > int nb =3D NB(ctx->opcode); > gen_set_access_type(ctx, ACCESS_INT); > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > t0 =3D tcg_temp_new(); > gen_addr_register(ctx, t0); > if (nb =3D=3D 0) > @@ -3279,8 +3232,6 @@ static void gen_stswx(DisasContext *ctx) > TCGv t0; > TCGv_i32 t1, t2; > gen_set_access_type(ctx, ACCESS_INT); > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > t0 =3D tcg_temp_new(); > gen_addr_reg_index(ctx, t0); > t1 =3D tcg_temp_new_i32(); > @@ -4106,7 +4057,7 @@ static void gen_tw(DisasContext *ctx) > { > TCGv_i32 t0 =3D 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->opc= ode)], > t0); > tcg_temp_free_i32(t0); > @@ -4118,7 +4069,7 @@ static void gen_twi(DisasContext *ctx) > TCGv t0 =3D tcg_const_tl(SIMM(ctx->opcode)); > TCGv_i32 t1 =3D tcg_const_i32(TO(ctx->opcode)); > /* Update the nip since this might generate a trap exception */ > - gen_update_nip(ctx, ctx->nip); > + gen_stop_exception(ctx); > gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1); > tcg_temp_free(t0); > tcg_temp_free_i32(t1); > @@ -4130,7 +4081,7 @@ static void gen_td(DisasContext *ctx) > { > TCGv_i32 t0 =3D 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->opc= ode)], > t0); > tcg_temp_free_i32(t0); > @@ -4142,7 +4093,7 @@ static void gen_tdi(DisasContext *ctx) > TCGv t0 =3D tcg_const_tl(SIMM(ctx->opcode)); > TCGv_i32 t1 =3D tcg_const_i32(TO(ctx->opcode)); > /* Update the nip since this might generate a trap exception */ > - gen_update_nip(ctx, ctx->nip); > + gen_stop_exception(ctx); > gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1); > tcg_temp_free(t0); > tcg_temp_free_i32(t1); > @@ -4533,8 +4484,6 @@ static void gen_dcbz(DisasContext *ctx) > int is_dcbzl =3D ctx->opcode & 0x00200000 ? 1 : 0; > =20 > gen_set_access_type(ctx, ACCESS_CACHE); > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > tcgv_addr =3D tcg_temp_new(); > tcgv_is_dcbzl =3D tcg_const_i32(is_dcbzl); > =20 > @@ -4577,8 +4526,6 @@ static void gen_icbi(DisasContext *ctx) > { > TCGv t0; > gen_set_access_type(ctx, ACCESS_CACHE); > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > t0 =3D tcg_temp_new(); > gen_addr_reg_index(ctx, t0); > gen_helper_icbi(cpu_env, t0); > @@ -5072,8 +5019,6 @@ static void gen_lscbx(DisasContext *ctx) > TCGv_i32 t3 =3D tcg_const_i32(rB(ctx->opcode)); > =20 > gen_addr_reg_index(ctx, t0); > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3); > tcg_temp_free_i32(t1); > tcg_temp_free_i32(t2); > @@ -6127,8 +6072,6 @@ static void gen_mfdcr(DisasContext *ctx) > gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); > return; > } > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > dcrn =3D tcg_const_tl(SPR(ctx->opcode)); > gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn); > tcg_temp_free(dcrn); > @@ -6146,8 +6089,6 @@ static void gen_mtdcr(DisasContext *ctx) > gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); > return; > } > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > dcrn =3D tcg_const_tl(SPR(ctx->opcode)); > gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]); > tcg_temp_free(dcrn); > @@ -6165,8 +6106,6 @@ static void gen_mfdcrx(DisasContext *ctx) > gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); > return; > } > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, > cpu_gpr[rA(ctx->opcode)]); > /* Note: Rc update flag set leads to undefined state of Rc0 */ > @@ -6184,8 +6123,6 @@ static void gen_mtdcrx(DisasContext *ctx) > gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); > return; > } > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)], > cpu_gpr[rS(ctx->opcode)]); > /* Note: Rc update flag set leads to undefined state of Rc0 */ > @@ -6195,8 +6132,6 @@ static void gen_mtdcrx(DisasContext *ctx) > /* mfdcrux (PPC 460) : user-mode access to DCR */ > static void gen_mfdcrux(DisasContext *ctx) > { > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, > cpu_gpr[rA(ctx->opcode)]); > /* Note: Rc update flag set leads to undefined state of Rc0 */ > @@ -6205,8 +6140,6 @@ static void gen_mfdcrux(DisasContext *ctx) > /* mtdcrux (PPC 460) : user-mode access to DCR */ > static void gen_mtdcrux(DisasContext *ctx) > { > - /* NIP cannot be restored if the memory exception comes from an help= er */ > - gen_update_nip(ctx, ctx->nip - 4); > gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)], > cpu_gpr[rS(ctx->opcode)]); > /* Note: Rc update flag set leads to undefined state of Rc0 */ > @@ -7915,8 +7848,6 @@ static void gen_##name(DisasContext * ctx) = \ > gen_exception(ctx, POWERPC_EXCP_VSXU); = \ > return; = \ > } = \ > - /* NIP cannot be restored if the memory exception comes from an help= er */ \ > - gen_update_nip(ctx, ctx->nip - 4); = \ > opc =3D tcg_const_i32(ctx->opcode); = \ > gen_helper_##name(cpu_env, opc); = \ > tcg_temp_free_i32(opc); = \ > @@ -7929,9 +7860,6 @@ static void gen_##name(DisasContext * ctx) = \ > gen_exception(ctx, POWERPC_EXCP_VSXU); \ > return; \ > } \ > - /* NIP cannot be restored if the exception comes */ \ > - /* from a helper. */ \ > - gen_update_nip(ctx, ctx->nip - 4); \ > \ > gen_helper_##name(cpu_vsrh(xT(ctx->opcode)), cpu_env, \ > cpu_vsrh(xB(ctx->opcode))); \ >=20 >=20 --=20 Aurelien Jarno GPG: 4096R/1DDD8C9B aurelien@aurel32.net http://www.aurel32.net