From patchwork Thu Sep 15 08:09:59 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 9332935 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C3686607FD for ; Thu, 15 Sep 2016 08:11:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A9D2429106 for ; Thu, 15 Sep 2016 08:11:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9D67B2912D; Thu, 15 Sep 2016 08:11:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C25C629114 for ; Thu, 15 Sep 2016 08:11:04 +0000 (UTC) Received: from localhost ([::1]:60806 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bkRl9-0007em-T5 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 15 Sep 2016 04:11:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42015) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bkRkU-0007aF-Qh for qemu-devel@nongnu.org; Thu, 15 Sep 2016 04:10:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bkRkP-0002Se-4a for qemu-devel@nongnu.org; Thu, 15 Sep 2016 04:10:22 -0400 Received: from mail.ispras.ru ([83.149.199.45]:35662) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bkRkO-0002Mu-6h for qemu-devel@nongnu.org; Thu, 15 Sep 2016 04:10:17 -0400 Received: from [10.10.150.35] (unknown [85.142.117.224]) by mail.ispras.ru (Postfix) with ESMTPSA id 94B97540071; Thu, 15 Sep 2016 11:10:04 +0300 (MSK) To: qemu-devel@nongnu.org From: Pavel Dovgalyuk Date: Thu, 15 Sep 2016 11:09:59 +0300 Message-ID: <20160915080959.3124.63067.stgit@PASHA-ISP> In-Reply-To: <20160915080952.3124.19133.stgit@PASHA-ISP> References: <20160915080952.3124.19133.stgit@PASHA-ISP> User-Agent: StGit/0.16 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v2 01/11] target-ppc: exceptions handling in icount mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, quintela@redhat.com, jasowang@redhat.com, mst@redhat.com, agraf@suse.de, pbonzini@redhat.com, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Pavel Dovgalyuk 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 --- 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); } 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))); \