From patchwork Wed Jun 8 05:13:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 9163297 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 91892604DB for ; Wed, 8 Jun 2016 05:14:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B3EF2824F for ; Wed, 8 Jun 2016 05:14:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F9A228305; Wed, 8 Jun 2016 05:14:53 +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 799E82836C for ; Wed, 8 Jun 2016 05:14:50 +0000 (UTC) Received: from localhost ([::1]:54510 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bAVpJ-0005ZW-Iy for patchwork-qemu-devel@patchwork.kernel.org; Wed, 08 Jun 2016 01:14:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51730) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bAVol-0005Uq-Ea for qemu-devel@nongnu.org; Wed, 08 Jun 2016 01:14:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bAVof-0000MK-20 for qemu-devel@nongnu.org; Wed, 08 Jun 2016 01:14:14 -0400 Received: from mail.ispras.ru ([83.149.199.45]:60315) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bAVoe-0000LO-62 for qemu-devel@nongnu.org; Wed, 08 Jun 2016 01:14:08 -0400 Received: from [10.10.150.28] (unknown [85.142.117.224]) by mail.ispras.ru (Postfix) with ESMTPSA id 9B7C0540074; Wed, 8 Jun 2016 08:13:56 +0300 (MSK) To: qemu-devel@nongnu.org From: Pavel Dovgalyuk Date: Wed, 08 Jun 2016 08:13:58 +0300 Message-ID: <20160608051358.1688.33874.stgit@PASHA-ISP> In-Reply-To: <20160608051352.1688.7877.stgit@PASHA-ISP> References: <20160608051352.1688.7877.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 1/3] 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: pbonzini@redhat.com, jasowang@redhat.com, agraf@suse.de, 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 | 84 +----------------- 10 files changed, 169 insertions(+), 214 deletions(-) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 98a24a5..4d7319a 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -2391,4 +2391,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 /* !defined (__CPU_PPC_H__) */ diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index a37009e..ec006fa 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -887,8 +887,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)); @@ -897,15 +897,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; @@ -914,7 +931,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); } } @@ -1015,8 +1033,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); } } @@ -1029,8 +1048,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 b67ebca..a02bc63 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) || float64_is_signaling_nan(farg2.d))) { /* sNaN addition */ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); } farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status); } @@ -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) || float64_is_signaling_nan(farg2.d))) { /* sNaN subtraction */ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); } farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status); } @@ -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) || float64_is_signaling_nan(farg2.d))) { /* sNaN multiplication */ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); } farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status); } @@ -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) || float64_is_signaling_nan(farg2.d))) { /* sNaN division */ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1, GETPC()); } farg1.d = float64_div(farg1.d, farg2.d, &env->fp_status); } @@ -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)) { \ - 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))) { /* 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) || 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; @@ -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) || 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; @@ -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) || 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; @@ -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) || 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; @@ -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))) { /* 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))) { /* 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))) { /* 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))) { /* 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))) { /* 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) || 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()); } } @@ -1135,10 +1141,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()); } } } @@ -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) || \ 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());\ } \ } \ \ @@ -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) || \ 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());\ } \ } \ \ @@ -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) || \ 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());\ } \ } \ \ @@ -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))) { \ - 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)) { \ - 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)) { \ - 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) || \ tp##_is_signaling_nan(b->fld) || \ tp##_is_signaling_nan(c->fld)) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf, GETPC());\ tstat.float_exception_flags &= ~float_flag_invalid; \ } \ if ((tp##_is_infinity(xa.fld) && tp##_is_zero(b->fld)) || \ (tp##_is_zero(xa.fld) && tp##_is_infinity(b->fld))) { \ xt_out.fld = float64_to_##tp(fload_invalid_op_excp(env, \ - POWERPC_EXCP_FP_VXIMZ, sfprf), &env->fp_status); \ + POWERPC_EXCP_FP_VXIMZ, sfprf, GETPC()), &env->fp_status); \ tstat.float_exception_flags &= ~float_flag_invalid; \ } \ if ((tstat.float_exception_flags & float_flag_invalid) && \ ((tp##_is_infinity(xa.fld) || \ tp##_is_infinity(b->fld)) && \ tp##_is_infinity(c->fld))) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf, GETPC());\ } \ } \ \ @@ -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)) || \ float64_is_signaling_nan(xb.VsrD(0))) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC());\ } \ if (ordered) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0, GETPC());\ } \ cc = 1; \ } else { \ @@ -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) || \ tp##_is_signaling_nan(xb.fld))) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC()); \ } \ } \ \ putVSR(xT(opcode), &xt, env); \ - helper_float_check_status(env); \ + do_float_check_status(env, GETPC()); \ } VSX_MAX_MIN(xsmaxdp, maxnum, 1, float64, VsrD(0)) @@ -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) || \ tp##_is_signaling_nan(xb.fld)) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC());\ } \ if (svxvc) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0, GETPC());\ } \ xt.fld = 0; \ all_true = 0; \ @@ -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) @@ -2501,7 +2507,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ for (i = 0; i < nels; i++) { \ xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \ if (unlikely(stp##_is_signaling_nan(xb.sfld))) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC()); \ xt.tfld = ttp##_snan_to_qnan(xt.tfld); \ } \ if (sfprf) { \ @@ -2511,7 +2517,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) @@ -2556,21 +2562,21 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ for (i = 0; i < nels; i++) { \ if (unlikely(stp##_is_any_nan(xb.sfld))) { \ if (stp##_is_signaling_nan(xb.sfld)) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC());\ } \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0, GETPC()); \ xt.tfld = rnan; \ } else { \ xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, \ &env->fp_status); \ if (env->fp_status.float_exception_flags & float_flag_invalid) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0, GETPC());\ } \ } \ } \ \ putVSR(xT(opcode), &xt, env); \ - helper_float_check_status(env); \ + do_float_check_status(env, GETPC()); \ } VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, VsrD(0), VsrD(0), \ @@ -2621,7 +2627,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) @@ -2665,7 +2671,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ \ for (i = 0; i < nels; i++) { \ if (unlikely(tp##_is_signaling_nan(xb.fld))) { \ - fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0, GETPC());\ xt.fld = tp##_snan_to_qnan(xb.fld); \ } else { \ xt.fld = tp##_round_to_int(xb.fld, &env->fp_status); \ @@ -2684,7 +2690,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ } \ \ putVSR(xT(opcode), &xt, env); \ - helper_float_check_status(env); \ + do_float_check_status(env, GETPC()); \ } VSX_ROUND(xsrdpi, 1, float64, VsrD(0), float_round_nearest_even, 1) @@ -2712,6 +2718,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 0526322..3d318fe 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 e4de86b..7ebc412 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 7d41b01..ded5941 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 ea6e99a..58465d8 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -224,8 +224,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()); } } @@ -235,8 +235,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; } @@ -247,8 +247,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 1499af72..62c82bc 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -2608,9 +2608,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 */ @@ -2618,9 +2618,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) { @@ -2902,10 +2902,6 @@ void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx); } if (unlikely(ret != 0)) { - if (likely(retaddr)) { - /* now we have a real cpu fault */ - cpu_restore_state(cs, retaddr); - } - helper_raise_exception_err(env, cs->exception_index, env->error_code); + raise_exception_err(env, cs->exception_index, env->error_code, retaddr); } } diff --git a/target-ppc/timebase_helper.c b/target-ppc/timebase_helper.c index 66de313..77b91f3 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" /*****************************************************************************/ @@ -133,15 +134,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; } @@ -150,14 +151,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 fe10bf8..6c3f268 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -291,7 +291,7 @@ static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t } t0 = tcg_const_i32(excp); t1 = tcg_const_i32(error); - gen_helper_raise_exception_err(cpu_env, t0, t1); + gen_helper_raise_exception_end(cpu_env, t0, t1); tcg_temp_free_i32(t0); tcg_temp_free_i32(t1); ctx->exception = (excp); @@ -299,14 +299,7 @@ static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t static inline void gen_exception(DisasContext *ctx, uint32_t excp) { - TCGv_i32 t0; - if (ctx->exception == POWERPC_EXCP_NONE) { - gen_update_nip(ctx, ctx->nip); - } - t0 = tcg_const_i32(excp); - gen_helper_raise_exception(cpu_env, t0); - tcg_temp_free_i32(t0); - ctx->exception = (excp); + gen_exception_err(ctx, excp, 0); } static inline void gen_debug_exception(DisasContext *ctx) @@ -2070,8 +2063,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)], \ @@ -2099,8 +2090,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)], \ @@ -2127,8 +2116,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)], \ @@ -2155,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##name(cpu_fpr[rD(ctx->opcode)], cpu_env, \ cpu_fpr[rB(ctx->opcode)]); \ @@ -2175,8 +2160,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)]); \ @@ -2211,8 +2194,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)]); @@ -2237,8 +2218,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)]); @@ -2254,8 +2233,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)]); @@ -2345,8 +2322,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)], @@ -2363,8 +2338,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)], @@ -2534,8 +2507,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); @@ -2560,8 +2531,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); @@ -2591,8 +2560,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); @@ -2627,8 +2594,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); @@ -2711,8 +2676,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); @@ -3160,8 +3123,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); @@ -3176,8 +3137,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); @@ -3211,8 +3170,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); @@ -3229,8 +3186,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)); @@ -3250,8 +3205,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) @@ -3270,8 +3223,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(); @@ -4139,7 +4090,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); @@ -4151,7 +4102,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); @@ -4163,7 +4114,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); @@ -4175,7 +4126,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); @@ -4580,8 +4531,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); @@ -4624,8 +4573,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); @@ -5120,8 +5067,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); @@ -6175,8 +6120,6 @@ static void gen_mfdcr(DisasContext *ctx) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); return; } - /* NIP cannot be restored if the memory exception comes from an helper */ - gen_update_nip(ctx, ctx->nip - 4); dcrn = tcg_const_tl(SPR(ctx->opcode)); gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn); tcg_temp_free(dcrn); @@ -6194,8 +6137,6 @@ static void gen_mtdcr(DisasContext *ctx) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); return; } - /* NIP cannot be restored if the memory exception comes from an helper */ - gen_update_nip(ctx, ctx->nip - 4); dcrn = tcg_const_tl(SPR(ctx->opcode)); gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]); tcg_temp_free(dcrn); @@ -6213,8 +6154,6 @@ static void gen_mfdcrx(DisasContext *ctx) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); return; } - /* NIP cannot be restored if the memory exception comes from an helper */ - gen_update_nip(ctx, ctx->nip - 4); gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)]); /* Note: Rc update flag set leads to undefined state of Rc0 */ @@ -6232,8 +6171,6 @@ static void gen_mtdcrx(DisasContext *ctx) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); return; } - /* NIP cannot be restored if the memory exception comes from an helper */ - gen_update_nip(ctx, ctx->nip - 4); gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); /* Note: Rc update flag set leads to undefined state of Rc0 */ @@ -6243,8 +6180,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 */ @@ -6253,8 +6188,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 */ @@ -7963,8 +7896,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); \ @@ -7977,9 +7908,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))); \