icount/replay additions
v2 cover icount/replay additions
This set of patches includes several fixes for replay and adds network record/replay for network devices. It also makes possible saving/restoring vmstate in replay mode.
Record and replay for network interactions is performed with the network filter. Each backend must have its own instance of the replay filter as follows:
-netdev user,id=net1 -device rtl8139,netdev=net1
-object filter-replay,id=replay,netdev=net1
This patches add overlay option for blkreplay block driver. Using persistent overlay file allows saving and reloading VM snapshots in replay mode. Replay mechanism automatically creates one snapshot named 'replay_init' to allow rewinding execution while replaying.
Overlay file may be specified as follows:
-drive file=disk.qcow,if=none,id=img-direct
-drive driver=blkreplay,if=none,image=img-direct,overlay=overlay.qcow2,id=img-blkreplay -device ide-hd,drive=img-blkreplay
This set of patches includes fixes and additions for icount and record/replay implementation:
- Fixing icount processing on exceptions in PPC
- Enabling VM start/stop in replay mode
- Adding network interaction record/replay
- Adding overlay option for blkreplay filter
- Fixes of the vmstate for several virtual devices
---
Pavel Dovgalyuk (11):
target-ppc: exceptions handling in icount mode record/replay: add network support
block: set snapshot option for block devices in blkreplay module
block: don't make snapshots for filters
replay: save/load initial state
replay: move internal data to the structure
replay: vmstate for replay module
replay: allow replay stopping and restarting
kvmvapic: fix state change handler
pcspk: adding vmstate for save/restore
integratorcp: adding vmstate for save/restore
block/blkreplay.c | 132 +++++++++++++++++++++++++++-- block/snapshot.c | 3 + cpus.c | 1 docs/replay.txt | 22 +++++ hw/arm/integratorcp.c | 62 ++++++++++++++ hw/audio/pcspk.c | 17 +++- hw/i386/kvmvapic.c | 1 include/sysemu/replay.h | 26 ++++++ net/Makefile.objs | 1 net/filter-replay.c | 90 ++++++++++++++++++++ replay/Makefile.objs | 2 replay/replay-events.c | 21 ++++- replay/replay-internal.c | 19 ++-- replay/replay-internal.h | 26 +++++- replay/replay-net.c | 110 ++++++++++++++++++++++++ replay/replay-snapshot.c | 72 ++++++++++++++++ replay/replay-time.c | 2 replay/replay.c | 17 ++-- stubs/replay.c | 5 + 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 +---------------- vl.c | 9 ++ 30 files changed, 768 insertions(+), 245 deletions(-) create mode 100644 net/filter-replay.c create mode 100644 replay/replay-net.c create mode 100644 replay/replay-snapshot.c
Signature · 1 line
Pavel Dovgalyuk
PATCH v2 1/11 target-ppc: exceptions handling in icount mode
From: Pavel Dovgalyuk <[email protected]>
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.
--- 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(-)
target-ppc/cpu.h +3 -0
@@ -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 */
target-ppc/excp_helper.c +29 -9
@@ -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
target-ppc/fpu_helper.c +99 -93
652 lines not on this page · raw message
target-ppc/helper.h +1 -0
@@ -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 )
target-ppc/mem_helper.c +3 -3
@@ -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); }
target-ppc/misc_helper.c +4 -4
@@ -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 }
target-ppc/mmu-hash64.c +6 -6
@@ -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; }
target-ppc/mmu_helper.c +7 -11
@@ -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); } }
target-ppc/timebase_helper.c +11 -10
@@ -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 ()); } }
target-ppc/translate.c +6 -70
280 lines not on this page · raw message
Re: [Qemu-devel] [PATCH v2 01/11] target-ppc: exceptions handling in icount mode
Quoted 11 lines · Pavel Dovgalyuk
From: Pavel Dovgalyuk <[email protected]>
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.
Quoted 1 line
Signed-off-by Pavel Dovgalyuk <[email protected]>
I'm not really confident reviewing changes in this area.
I've CCed Ben Herrenshmidt, who did some work on the exception handling recently. Ben, if you get a chance can you please review this change.
Quoted 48 lines
--- 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(-)target-ppc/cpu.h +3
-0@@ -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 */ target-ppc/excp_helper.c +5
-3@@ -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); +} +
target-ppc/excp_helper.c void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, · line 923
Quoted 10 lines
target-ppc/excp_helper.c +10
-0+void helper_raise_exception_err (CPUPPCState *env,uint32_t exception, +uint32_t error_code) +{ +raise_exception_err (env, exception, error_code,GETPC ()); +} + +void helper_raise_exception_end (CPUPPCState *env,uint32_t exception, +uint32_t error_code) +{ +raise_exception_err (env, exception, error_code,0 );
I'm struggling to see how raising an exception with a return address of 0 could ever be useful...
Quoted 1,281 lines
target-ppc/excp_helper.c +14
-6}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 target-ppc/fpu_helper.c +99
-93@@ -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; }target-ppc/helper.h +1
-0@@ -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 )target-ppc/mem_helper.c +3
-3@@ -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); }target-ppc/misc_helper.c +4
-4@@ -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 }target-ppc/mmu-hash64.c +6
-6@@ -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; }target-ppc/mmu_helper.c +7
-11@@ -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); } }target-ppc/timebase_helper.c +11
-10@@ -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 ()); } }target-ppc/translate.c +6
-70@@ -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))); \
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Re: [Qemu-devel] [PATCH v2 01/11] target-ppc: exceptions handling in icount mode
Quoted 13 lines
From: David Gibson [mailto:[email protected]]
Quoted 11 lines · Pavel Dovgalyuk
From: Pavel Dovgalyuk <[email protected]>
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.
Quoted 6 lines
Quoted 1 line
Signed-off-by Pavel Dovgalyuk <[email protected]>I'm not really confident reviewing changes in this area.
I've CCed Ben Herrenshmidt, who did some work on the exception handling recently.
Thanks.
It seems that most of these changes were already upstreamed from some other patch. That's why I removed this one from the updated series.
Quoted 1,386 lines
Quoted 49 lines
--- 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(-)target-ppc/cpu.h +3
-0@@ -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 */ target-ppc/excp_helper.c +5
-3@@ -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); +} +target-ppc/excp_helper.c void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, · line 923
Quoted 10 lines
target-ppc/excp_helper.c +10
-0+void helper_raise_exception_err (CPUPPCState *env,uint32_t exception, +uint32_t error_code) +{ +raise_exception_err (env, exception, error_code,GETPC ()); +} + +void helper_raise_exception_end (CPUPPCState *env,uint32_t exception, +uint32_t error_code) +{ +raise_exception_err (env, exception, error_code,0 );I'm struggling to see how raising an exception with a return address of 0 could ever be useful...
target-ppc/fpu_helper.c uint64_t helper_##op(CPUPPCState *env, uint64_t arg)
Quoted 202 lines
target-ppc/excp_helper.c +14
-6}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 target-ppc/fpu_helper.c +25
-19@@ -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)\
target-ppc/fpu_helper.c void helper_##name(CPUPPCState *env, uint32_t opcode)
Quoted 261 lines
target-ppc/fpu_helper.c +34
-34\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)\
target-ppc/fpu_helper.c void helper_##name(CPUPPCState *env, uint32_t opcode)
Quoted 13 lines
target-ppc/fpu_helper.c +2
-2\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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ } \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 13 lines
target-ppc/fpu_helper.c +2
-2if (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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 17 lines
target-ppc/fpu_helper.c +3
-3\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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1\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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 12 lines
target-ppc/fpu_helper.c +2
-2\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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 12 lines
target-ppc/fpu_helper.c +2
-2\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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 24 lines
target-ppc/fpu_helper.c +3
-3if (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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ } \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 13 lines
target-ppc/fpu_helper.c +2
-2float64_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)\
target-ppc/fpu_helper.c void helper_##name(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1env->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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 15 lines
target-ppc/fpu_helper.c +2
-2xt.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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 13 lines
target-ppc/fpu_helper.c +2
-2tp##_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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 27 lines
target-ppc/fpu_helper.c +3
-3if ((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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 26 lines
target-ppc/fpu_helper.c +4
-4for (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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1for (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)\
target-ppc/mmu-hash64.c void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong
Quoted 88 lines
target-ppc/fpu_helper.c +2
-2} \ \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; }target-ppc/helper.h +1
-0@@ -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 )target-ppc/mem_helper.c +3
-3@@ -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); }target-ppc/misc_helper.c +4
-4@@ -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 }target-ppc/mmu-hash64.c +0
-0@@ -241,8 +241,8 @@ void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulongrs)
target-ppc/mmu_helper.c void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType
Quoted 63 lines
target-ppc/mmu-hash64.c +6
-6PowerPCCPU *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; }target-ppc/mmu_helper.c +6
-6@@ -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,target-ppc/timebase_helper.c void helper_store_dcr(CPUPPCState *env, target_ulong dcrn,
Quoted 45 lines
target-ppc/mmu_helper.c +1
-5ret =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); } }target-ppc/timebase_helper.c +6
-5@@ -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_ulongval)target-ppc/translate.c static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t
Quoted 24 lines
target-ppc/timebase_helper.c +5
-5{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 ()); } }target-ppc/translate.c +0
-0@@ -292,7 +292,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_terror)
target-ppc/translate.c static void gen_exception_err(DisasContext *ctx, uint32_t excp,
Quoted 9 lines
target-ppc/translate.c +1
-1} 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_terror)target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 16 lines
target-ppc/translate.c +1
-8static 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)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 9 lines
target-ppc/translate.c +0
-2gen_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)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 9 lines
target-ppc/translate.c +0
-2gen_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)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 9 lines
target-ppc/translate.c +0
-2gen_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)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 9 lines
target-ppc/translate.c +0
-2gen_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)\
target-ppc/translate.c static inline void gen_check_align(DisasContext *ctx, TCGv EA, int
Quoted 90 lines
target-ppc/translate.c +0
-20gen_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, intmask)
target-ppc/translate.c static void gen_##name(DisasContext * ctx)
Quoted 144 lines
target-ppc/translate.c +4
-28TCGLabel *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)\
Quoted 10 lines
target-ppc/translate.c +0
-2gen_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); \target-ppc/translate.c static void gen_##name(DisasContext * ctx) \ · line 7985
Quoted 9 lines
target-ppc/translate.c +0
-3@@ -8041,9 +7980,6 @@ static void gen_##name(DisasContext * ctx) \gen_exception (ctx,POWERPC_EXCP_VSXU ); \return ; \ } \ -/* NIP cannot be restored if the exception comes */ \ -/* from a helper. */ \ -gen_update_nip (ctx, ctx->nip -4 ); \ \ gen_helper_##name(cpu_vsrh(xT(ctx->opcode)), cpu_env, \ cpu_vsrh(xB(ctx->opcode))); \--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_| _way_ _around_!
Re: [Qemu-devel] [PATCH v2 01/11] target-ppc: exceptions handling in icount mode
Quoted 19 lines · Pavel Dovgalyuk
Quoted 19 lines
From: David Gibson [mailto:[email protected]]
Quoted 16 lines · Pavel Dovgalyuk
From: Pavel Dovgalyuk <[email protected]>
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.
Quoted 6 lines
Quoted 6 lines
Quoted 1 line
Signed-off-by Pavel Dovgalyuk <[email protected]>I'm not really confident reviewing changes in this area.
I've CCd Ben Herrenshmidt, who did some work on the exception handling recently.
Hrm.. Isn't this something that gets fixed by rth's patch to properly fix GET_RA ?
Ie. it should be legit to pass "0" for the PC if we have updated nip manually ... I'm not sure I get what you are doing here.
Quoted 2,009 lines
Thanks.
It seems that most of these changes were already upstreamed from some other patch.
That's why I removed this one from the updated series.Quoted 2,004 lines
Quoted 59 lines
---
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(-)target-ppc/cpu.h +0
-0@@ -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);target-ppc/cpu.h +3
-0+void raise_exception_err (CPUPPCState *env,uint32_t exception, + uint32_t error_code, uintptr_t pc); +#endif /*
PPC_CPU_H*/target-ppc/excp_helper.c +2
-2@@ -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));target-ppc/excp_helper.c +4
-1@@ -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,target-ppc/excp_helper.c void helper_raise_exception_err(CPUPPCState · line 926
Quoted 10 lines
target-ppc/excp_helper.c +9
-0+ uint32_t error_code) +{ + raise_exception_err(env, exception, error_code, GETPC()); +} + +void helper_raise_exception_end (CPUPPCState *env,uint32_t exception, + uint32_t error_code) +{ + raise_exception_err(env, exception, error_code, 0);I'm struggling to see how raising an exception with a return address
of 0 could ever be useful...Quoted 271 lines
target-ppc/excp_helper.c +0
-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 voidraise_exception(CPUPPCState *env, uint32_t exception, uintptr_t pc)target-ppc/excp_helper.c +4
-0+{ + raise_exception_err(env, exception, 0, pc); +} +void
helper_store_msr(CPUPPCState *env, target_ulong val){
CPUState *cs;target-ppc/excp_helper.c +2
-1@@ -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);
}
}target-ppc/excp_helper.c +0
-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);
}
}
#endiftarget-ppc/fpu_helper.c +2
-1@@ -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;target-ppc/fpu_helper.c +3
-3@@ -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_tretaddr)
{
env->fpscr |= 1 <<FPSCR_ZX;
env->fpscr &= ~((1 <<FPSCR_FR) | (1 <<FPSCR_FI));target-ppc/fpu_helper.c +0
-2@@ -217,8 +218,8 @@ static inline voidfloat_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);
}
}
}target-ppc/fpu_helper.c +2
-2@@ -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) {target-ppc/fpu_helper.c +0
-0@@ -510,12 +511,17 @@ void helper_float_check_status(CPUPPCState *env) (env->error_code & POWERPC_EXCP_FP)) { /* Differred floating-point exception after target FPRupdate */
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); }
}
}target-ppc/fpu_helper.c +5
-0+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);target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg2.d, &env-
Quoted 1 line
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-Quoted 1 line
fp_status);}
target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg2.d, &env-
Quoted 1 line
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-Quoted 1 line
fp_status);}
target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg2.d, &env-
Quoted 1 line
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-Quoted 1 line
fp_status);}
target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg2.d, &env-
Quoted 1 line
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-Quoted 1 line
fp_status);}
target-ppc/fpu_helper.c uint64_t helper_##op(CPUPPCState *env, · line 637
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -631,16 +637,16 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg)\
Quoted 386 lines
\
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; \
}target-ppc/fpu_helper.c +2
-2@@ -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-
Quoted 1 line
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)&target-ppc/fpu_helper.c +0
-0@@ -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){
- returndo_fri(env, arg, float_round_ties_away); + returndo_fri(env, arg, float_round_ties_away, GETPC()); }uint64_t
helper_friz(CPUPPCState *env, uint64_t arg){
- returndo_fri(env, arg, float_round_to_zero); + returndo_fri(env, arg, float_round_to_zero, GETPC()); }uint64_t
helper_frip(CPUPPCState *env, uint64_t arg){
- returndo_fri(env, arg, float_round_up); + returndo_fri(env, arg, float_round_up, GETPC()); }uint64_t
helper_frim(CPUPPCState *env, uint64_t arg){
- returndo_fri(env, arg, float_round_down); + returndo_fri(env, arg, float_round_down, GETPC()); }/* fmadd - fmadd. */
target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg2.d, &env-
Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg3.d, &env-
Quoted 1 line
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 */
float128ft0_128,ft1_128;target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status);ft0_128 = float128_add(ft0_128,
ft1_128, &env-Quoted 1 line
fp_status);target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg2.d, &env-
Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg3.d, &env-
Quoted 1 line
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 */
float128ft0_128,ft1_128;target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status);ft0_128 = float128_sub(ft0_128,
ft1_128, &env-Quoted 1 line
fp_status);target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg2.d, &env-
Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg3.d, &env-
Quoted 1 line
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 */
float128ft0_128,ft1_128;target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status);ft0_128 = float128_add(ft0_128,
ft1_128, &env-Quoted 1 line
fp_status);target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg2.d, &env-
Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg3.d, &env-
Quoted 1 line
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 */
float128ft0_128,ft1_128;target-ppc/fpu_helper.c +0
-0@@ -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-Quoted 1 line
fp_status);ft0_128 = float128_sub(ft0_128,
ft1_128, &env-Quoted 1 line
fp_status);target-ppc/fpu_helper.c +0
-0@@ -905,7 +911,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)if (unlikely(float64_is_signaling_nan(farg.d, &env-
Quoted 1 line
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);target-ppc/fpu_helper.c +0
-0@@ -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-
Quoted 1 line
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); }target-ppc/fpu_helper.c +0
-0@@ -944,7 +950,7 @@ uint64_t helper_fre(CPUPPCState *env, uint64_t arg)if (unlikely(float64_is_signaling_nan(farg.d, &env-
Quoted 1 line
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;target-ppc/fpu_helper.c +0
-0@@ -960,7 +966,7 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg)if (unlikely(float64_is_signaling_nan(farg.d, &env-
Quoted 1 line
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);target-ppc/fpu_helper.c +0
-0@@ -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-
Quoted 1 line
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-Quoted 1 line
fp_status);target-ppc/fpu_helper.c +0
-0@@ -1103,7 +1109,7 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,&& (float64_is_signaling_nan(farg1.d, &env-
Quoted 1 line
fp_status) ||float64_is_signaling_nan(farg2.d, &env-
Quoted 1 line
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());
}
}target-ppc/fpu_helper.c +0
-0@@ -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());
}
}
}target-ppc/fpu_helper.c void helper_##name(CPUPPCState *env, · line 1844
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -1838,10 +1844,10 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)\
Quoted 26 lines
\
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());\
}
\
}
\
\target-ppc/fpu_helper.c void helper_##name(CPUPPCState *env, · line 1860
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -1854,7 +1860,7 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)\
Quoted 15 lines
target-ppc/fpu_helper.c +0
-1} \ } \ 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)
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, · line 1899
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -1893,10 +1899,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 26 lines
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());\
}
\
}
\
\target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 1916
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -1910,7 +1916,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 15 lines
target-ppc/fpu_helper.c +0
-0} \
\
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)
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, · line 1950
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -1944,13 +1950,13 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 34 lines
\
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());\
}
\
}
\
\target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 1970
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -1964,7 +1970,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 15 lines
target-ppc/fpu_helper.c +0
-0} \
\
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)
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 1997
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -1991,7 +1997,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 18 lines
\
for (i = 0; i < nels; i++)
{ \
if (unlikely(tp##_is_signaling_nan(xb.fld, &env-Quoted 1 line
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-Quoted 1 line
fp_status); \
\target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2011
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2005,7 +2011,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 15 lines
target-ppc/fpu_helper.c +0
-0} \
\
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)
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2044
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2038,9 +2044,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 24 lines
\
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());\
}
\
}
\
\target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2060
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2054,7 +2060,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 15 lines
target-ppc/fpu_helper.c +0
-0} \
\
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)
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2094
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2088,9 +2094,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 24 lines
\
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());\
}
\
}
\
\target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2110
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2104,7 +2110,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 15 lines
target-ppc/fpu_helper.c +0
-0} \
\
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)
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, · line 2283
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2277,20 +2283,20 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 48 lines
target-ppc/fpu_helper.c +1
-1if (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-Quoted 1 line
fld)) || \
(tp##_is_zero(xa.fld) && tp##_is_infinity(b-
Quoted 1 line
fld))) { \
xt_out.fld = float64_to_##tp(fload_invalid_op_excp(env, \
- POWERPC_EXCP_FP_VXIMZ, sfprf), &env-Quoted 1 line
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());\
}
\
}
\
\target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2309
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2303,7 +2309,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 15 lines
target-ppc/fpu_helper.c +0
-1} \ } \ putVSR(xT(opcode), &xt_out, env); \ - helper_float_check_status(env);\
+ do_float_check_status(env,
GETPC()); \
}#define
MADD_FLGS0target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, · line 2366
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2360,10 +2366,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 26 lines
target-ppc/fpu_helper.c +0
-0float64_is_any_nan(xb.VsrD(0)))) { \if (float64_is_signaling_nan(xa.VsrD(0), &env-
Quoted 1 line
fp_status) || \float64_is_signaling_nan(xb.VsrD(0), &env-
Quoted 1 line
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
{ \target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2387
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2381,7 +2387,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 15 lines
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)
target-ppc/fpu_helper.c void helper_##name(CPUPPCState *env, · line 2414
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2408,12 +2414,12 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)\
Quoted 27 lines
xt.fld = tp##_##op(xa.fld, xb.fld, &env-
Quoted 1 line
fp_status); \
if (unlikely(tp##_is_signaling_nan(xa.fld, &env-
Quoted 1 line
fp_status) || \tp##_is_signaling_nan(xb.fld, &env-
Quoted 1 line
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))
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, · line 2454
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2448,10 +2454,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 26 lines
target-ppc/fpu_helper.c +1
-1tp##_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; \target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2476
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2470,7 +2476,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 49 lines
target-ppc/fpu_helper.c +0
-0if ((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)
target-ppc/fpu_helper.c +0
-0@@ -2502,7 +2508,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \xt.tfld = stp##_to_##ttp(xb.sfld, &env-
Quoted 1 line
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)
{ \target-ppc/fpu_helper.c +0
-0@@ -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)
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, · line 2563
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2557,21 +2563,21 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 50 lines
target-ppc/fpu_helper.c +0
-0for (i = 0; i < nels; i++) { \ if (unlikely(stp##_is_any_nan(xb.sfld))) { \if (stp##_is_signaling_nan(xb.sfld, &env-
Quoted 1 line
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-Quoted 1 line
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), \
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2628
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2622,7 +2628,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 16 lines
target-ppc/fpu_helper.c +0
-0} \
\
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)
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2673
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2667,7 +2673,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 18 lines
target-ppc/fpu_helper.c +0
-0for (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-Quoted 1 line
fp_status); \
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t · line 2692
Quoted 1 line
target-ppc/fpu_helper.c +0
-0@@ -2686,7 +2692,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)\
Quoted 107 lines
target-ppc/fpu_helper.c +0
-0} \
\
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)target-ppc/fpu_helper.c +1
-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;}
target-ppc/helper.h +1
-0@@ -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)target-ppc/mem_helper.c +0
-0@@ -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" fromgen_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);
}target-ppc/misc_helper.c +1
-1@@ -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);
target-ppc/misc_helper.c +3
-3@@ -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 }target-ppc/mmu-hash64.c +0
-0@@ -241,8 +241,8 @@ void helper_store_slb(CPUPPCState *env,Quoted 1 line
target_ulongrb,target_ulongrs)
Quoted 70 lines
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()); }
}target-ppc/mmu-hash64.c +2
-2@@ -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;}
target-ppc/mmu-hash64.c +2
-2@@ -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;}
target-ppc/mmu_helper.c +3
-3@@ -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 */
target-ppc/mmu_helper.c +0
-0@@ -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) {target-ppc/mmu_helper.c +0
-0@@ -2892,10 +2892,6 @@ void tlb_fill(CPUState *cs, target_ulongQuoted 1 line
addr, MMUAccessType
access_type,Quoted 56 lines
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-Quoted 1 line
error_code, retaddr);}
}target- renamed from target-ppc/timebase_helper.c +0
-0
ppc/timebase_helper.c
index a07faa4..af328ca 100644target-ppc/timebase_helper.c +1
-0@@ -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" /*****************************************************************************/
target-ppc/timebase_helper.c +3
-3@@ -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;
}target-ppc/timebase_helper.c void helper_store_dcr(CPUPPCState *env, · line 161
Quoted 1 line
target-ppc/timebase_helper.c +0
-0@@ -160,14 +161,14 @@ void helper_store_dcr(CPUPPCState *env, target_ulong dcrn,
target_ulongval)Quoted 29 lines
target-ppc/timebase_helper.c +3
-3{ 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());
}
}target-ppc/translate.c +0
-0target-ppc/translate.c static void gen_exception_err(DisasContext · line 292
Quoted 1 line
target-ppc/translate.c +0
-0@@ -292,7 +292,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_terror)
target-ppc/translate.c static void gen_exception_err(DisasContext · line 300
Quoted 11 lines
target-ppc/translate.c +1
-1} 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);
target-ppc/translate.c +0
-0@@ -300,14 +300,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp,
uint32_terror)target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 17 lines
target-ppc/translate.c +1
-8static 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)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 18 lines
target-ppc/translate.c +0
-1gen_exception(ctx, POWERPC_EXCP_FPU); \ return; \ } \ - /* NIP cannot be restored if the memory exception comes froman 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-Quoted 1 line
opcode)], \
target-ppc/translate.c +0
-0@@ -2178,8 +2169,6 @@ static void gen_f##name(DisasContext *ctx)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 18 lines
target-ppc/translate.c +0
-1gen_exception(ctx, POWERPC_EXCP_FPU); \ return; \ } \ - /* NIP cannot be restored if the memory exception comes froman 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-Quoted 1 line
opcode)], \
target-ppc/translate.c +0
-0@@ -2206,8 +2195,6 @@ static void gen_f##name(DisasContext *ctx)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 18 lines
target-ppc/translate.c +0
-1gen_exception(ctx, POWERPC_EXCP_FPU); \ return; \ } \ - /* NIP cannot be restored if the memory exception comes froman 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-Quoted 1 line
opcode)], \
target-ppc/translate.c +0
-0@@ -2234,8 +2221,6 @@ static void gen_f##name(DisasContext *ctx)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 18 lines
target-ppc/translate.c +0
-1gen_exception(ctx, POWERPC_EXCP_FPU); \ return; \ } \ - /* NIP cannot be restored if the memory exception comes froman 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-Quoted 1 line
opcode)]); \
target-ppc/translate.c +0
-0@@ -2254,8 +2239,6 @@ static void gen_f##name(DisasContext *ctx)\
Quoted 112 lines
target-ppc/translate.c +0
-1gen_exception(ctx, POWERPC_EXCP_FPU); \ return; \ } \ - /* NIP cannot be restored if the memory exception comes froman 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-Quoted 1 line
opcode)]); \
target-ppc/translate.c +0
-1@@ -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 froman 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)]);target-ppc/translate.c +0
-1@@ -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 froman 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)]);target-ppc/translate.c +0
-1@@ -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 froman 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)]);target-ppc/translate.c +0
-1@@ -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 froman 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)],target-ppc/translate.c +0
-1@@ -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 froman 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)],target-ppc/translate.c +0
-1@@ -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 comesfrom 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);target-ppc/translate.c +0
-0@@ -2639,8 +2610,6 @@ static void gen_mtfsb1(DisasContext *ctx) /* XXX: we pretend we can only do IEEE floating-pointcomputations */
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);target-ppc/translate.c +0
-1@@ -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 froman helper */
- gen_update_nip(ctx,ctx->nip- 4);gen_reset_fpstatus();
if (l) {
t0 =tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff : 0xff);target-ppc/translate.c +0
-1@@ -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 froman 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);target-ppc/translate.c +0
-0@@ -2790,8 +2755,6 @@ static inline voidQuoted 1 line
gen_check_align(DisasContext *ctx, TCGv EA, int
mask)
target-ppc/translate.c static void gen_##name(DisasContext * ctx)
Quoted 165 lines
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);target-ppc/translate.c +0
-1@@ -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 froman 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);target-ppc/translate.c +0
-1@@ -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 froman 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);target-ppc/translate.c +0
-1@@ -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 froman helper */
- gen_update_nip(ctx,ctx->nip- 4);
t0 =tcg_temp_new();
gen_addr_register(ctx, t0);
t1 =tcg_const_i32(nb);target-ppc/translate.c +0
-1@@ -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 froman 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));target-ppc/translate.c +0
-1@@ -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 froman helper */
- gen_update_nip(ctx,ctx->nip- 4);
t0 =tcg_temp_new();
gen_addr_register(ctx, t0);
if (nb == 0)target-ppc/translate.c +0
-1@@ -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 froman helper */
- gen_update_nip(ctx,ctx->nip- 4);
t0 =tcg_temp_new();
gen_addr_reg_index(ctx, t0);
t1 =tcg_temp_new_i32();target-ppc/translate.c +1
-1@@ -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);target-ppc/translate.c +1
-1@@ -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);
target-ppc/translate.c +1
-1@@ -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);target-ppc/translate.c +1
-1@@ -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);
target-ppc/translate.c +0
-1@@ -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 froman helper */
- gen_update_nip(ctx,ctx->nip- 4);
tcgv_addr =tcg_temp_new();
tcgv_is_dcbzl =tcg_const_i32(is_dcbzl);target-ppc/translate.c +0
-1@@ -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 froman helper */
- gen_update_nip(ctx,ctx->nip- 4);
t0 =tcg_temp_new();
gen_addr_reg_index(ctx, t0);
gen_helper_icbi(cpu_env, t0);target-ppc/translate.c +0
-1@@ -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 froman 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);target-ppc/translate.c +0
-1@@ -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 froman 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 */target-ppc/translate.c +0
-1@@ -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 froman 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 */target-ppc/translate.c +0
-0@@ -8027,8 +7968,6 @@ static void gen_##name(DisasContext * ctx)\
Quoted 27 lines
target-ppc/translate.c +0
-1gen_exception(ctx, POWERPC_EXCP_VSXU); \ return; \ } \ - /* NIP cannot be restored if the memory exception comes froman helper */ \
- gen_update_nip(ctx,ctx->nip-
4); \
opc = tcg_const_i32(ctx-Quoted 1 line
opcode); \
gen_helper_##name(cpu_env,
opc); \
tcg_temp_free_i32(opc);
\target-ppc/translate.c +0
-3@@ -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, \Quoted 2 lines
cpu_vsrh(xB(ctx->opcode))); \
--
David Gibson | I'll have my music baroque,
and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT
_the_ _other_| _way_ _around_!
Re: [Qemu-devel] [PATCH v2 01/11] target-ppc: exceptions handling in icount mode
In reply to Pavel DovgalyukQuoted 15 lines · Pavel Dovgalyuk
Quoted 15 lines
From: David Gibson [mailto:[email protected]]
Quoted 12 lines · Pavel Dovgalyuk
From: Pavel Dovgalyuk <[email protected]>
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 <[email protected]>
Quoted 8 lines
Quoted 4 lines
I'm not really confident reviewing changes in this area.
I've CCed Ben Herrenshmidt, who did some work on the exception handling recently.
Thanks.
It seems that most of these changes were already upstreamed from some other patch. That's why I removed this one from the updated series.
Oh, ok. I'm not following the icount or replay stuff, so I didn't notice - I just saw I'd been CCed on a patch touching ppc stuff.
Quoted 1,383 lines
Quoted 1,382 lines
Quoted 50 lines
--- 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(-)target-ppc/cpu.h +3
-0@@ -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 */ target-ppc/excp_helper.c +5
-3@@ -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); +} +target-ppc/excp_helper.c void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, · line 923
Quoted 10 lines
target-ppc/excp_helper.c +10
-0+void helper_raise_exception_err (CPUPPCState *env,uint32_t exception, +uint32_t error_code) +{ +raise_exception_err (env, exception, error_code,GETPC ()); +} + +void helper_raise_exception_end (CPUPPCState *env,uint32_t exception, +uint32_t error_code) +{ +raise_exception_err (env, exception, error_code,0 );I'm struggling to see how raising an exception with a return address of 0 could ever be useful...
target-ppc/fpu_helper.c uint64_t helper_##op(CPUPPCState *env, uint64_t arg)
Quoted 202 lines
target-ppc/excp_helper.c +14
-6}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 target-ppc/fpu_helper.c +25
-19@@ -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)\
target-ppc/fpu_helper.c void helper_##name(CPUPPCState *env, uint32_t opcode)
Quoted 261 lines
target-ppc/fpu_helper.c +34
-34\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)\
target-ppc/fpu_helper.c void helper_##name(CPUPPCState *env, uint32_t opcode)
Quoted 13 lines
target-ppc/fpu_helper.c +2
-2\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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ } \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 13 lines
target-ppc/fpu_helper.c +2
-2if (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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 17 lines
target-ppc/fpu_helper.c +3
-3\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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1\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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 12 lines
target-ppc/fpu_helper.c +2
-2\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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 12 lines
target-ppc/fpu_helper.c +2
-2\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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 24 lines
target-ppc/fpu_helper.c +3
-3if (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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ } \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 13 lines
target-ppc/fpu_helper.c +2
-2float64_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)\
target-ppc/fpu_helper.c void helper_##name(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1env->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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 15 lines
target-ppc/fpu_helper.c +2
-2xt.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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 13 lines
target-ppc/fpu_helper.c +2
-2tp##_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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 27 lines
target-ppc/fpu_helper.c +3
-3if ((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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 26 lines
target-ppc/fpu_helper.c +4
-4for (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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1} \ \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)\
target-ppc/fpu_helper.c void helper_##op(CPUPPCState *env, uint32_t opcode)
Quoted 9 lines
target-ppc/fpu_helper.c +1
-1for (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)\
target-ppc/mmu-hash64.c void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong
Quoted 88 lines
target-ppc/fpu_helper.c +2
-2} \ \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; }target-ppc/helper.h +1
-0@@ -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 )target-ppc/mem_helper.c +3
-3@@ -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); }target-ppc/misc_helper.c +4
-4@@ -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 }target-ppc/mmu-hash64.c +0
-0@@ -241,8 +241,8 @@ void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulongrs)
target-ppc/mmu_helper.c void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType
Quoted 63 lines
target-ppc/mmu-hash64.c +6
-6PowerPCCPU *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; }target-ppc/mmu_helper.c +6
-6@@ -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,target-ppc/timebase_helper.c void helper_store_dcr(CPUPPCState *env, target_ulong dcrn,
Quoted 45 lines
target-ppc/mmu_helper.c +1
-5ret =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); } }target-ppc/timebase_helper.c +6
-5@@ -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_ulongval)target-ppc/translate.c static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t
Quoted 24 lines
target-ppc/timebase_helper.c +5
-5{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 ()); } }target-ppc/translate.c +0
-0@@ -292,7 +292,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_terror)
target-ppc/translate.c static void gen_exception_err(DisasContext *ctx, uint32_t excp,
Quoted 9 lines
target-ppc/translate.c +1
-1} 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_terror)target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 16 lines
target-ppc/translate.c +1
-8static 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)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 9 lines
target-ppc/translate.c +0
-2gen_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)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 9 lines
target-ppc/translate.c +0
-2gen_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)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 9 lines
target-ppc/translate.c +0
-2gen_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)\
target-ppc/translate.c static void gen_f##name(DisasContext *ctx)
Quoted 9 lines
target-ppc/translate.c +0
-2gen_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)\
target-ppc/translate.c static inline void gen_check_align(DisasContext *ctx, TCGv EA, int
Quoted 90 lines
target-ppc/translate.c +0
-20gen_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, intmask)
target-ppc/translate.c static void gen_##name(DisasContext * ctx)
Quoted 144 lines
target-ppc/translate.c +4
-28TCGLabel *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)\
Quoted 19 lines
target-ppc/translate.c +0
-5gen_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))); \
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH v2 2/11 record/replay: add network support
In reply to Pavel DovgalyukThis patch adds support of recording and replaying network packets in irount rr mode.
Record and replay for network interactions is performed with the network filter. Each backend must have its own instance of the replay filter as follows:
-netdev user,id=net1 -device rtl8139,netdev=net1
-object filter-replay,id=replay,netdev=net1
Replay network filter is used to record and replay network packets. While recording the virtual machine this filter puts all packets coming from the outer world into the log. In replay mode packets from the log are injected into the network device. All interactions with network backend in replay mode are disabled.
--- docs/replay.txt | 14 ++++++ include/sysemu/replay.h | 12 +++++ net/Makefile.objs | 1 net/filter-replay.c | 90 ++++++++++++++++++++++++++++++++++++++ replay/Makefile.objs | 1 replay/replay-events.c | 11 +++++ replay/replay-internal.h | 10 ++++ replay/replay-net.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++ replay/replay.c | 2 - vl.c | 3 + 10 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 net/filter-replay.c create mode 100644 replay/replay-net.c
docs/replay.txt +14 -0
@@ -195,3 +195,17 @@ Queue is flushed at checkpoints and information about processed requests is recorded to the log. In replay phase the queue is matched with events read from the log. Therefore block devices requests are processed deterministically. + +Network devices +--------------- + +Record and replay for network interactions is performed with the network filter. +Each backend must have its own instance of the replay filter as follows: + -netdev user,id=net1 -device rtl8139,netdev=net1 + -object filter-replay,id=replay,netdev=net1 + +Replay network filter is used to record and replay network packets. While +recording the virtual machine this filter puts all packets coming from +the outer world into the log. In replay mode packets from the log are +injected into the network device. All interactions with network backend +in replay mode are disabled.
include/sysemu/replay.h +12 -0
@@ -39,6 +39,8 @@ enum ReplayCheckpoint { };typedef enum ReplayCheckpoint ReplayCheckpoint ; +typedef struct ReplayNetState ReplayNetState ; +extern ReplayMode replay_mode;/* Replay process control functions */
@@ -133,4 +135,14 @@ void replay_char_read_all_save_error(int res);/*! Writes character read_all execution result into the replay log. */ void replay_char_read_all_save_buf (uint8_t *buf,int offset); +/* Network */ + +/*! Registers replay network filter attached to some backend. */ +ReplayNetState *replay_register_net (NetFilterState *nfs); +/*! Unregisters replay network filter. */ +void replay_unregister_net (ReplayNetState *rns); +/*! Called to write network packet to the replay log. */ +void replay_net_packet_event (ReplayNetState *rns,unsigned flags, +const struct iovec *iov,int iovcnt); +#endif
net/Makefile.objs +1 -0
@@ -16,3 +16,4 @@ common-obj-$(CONFIG_NETMAP) += netmap.o common-obj-y += filter.o common-obj-y += filter-buffer.o common-obj-y += filter-mirror.o +common-obj-y += filter-replay.o
net/filter-replay.c new file +90 -0
90 lines not on this page · raw message
replay/Makefile.objs +1 -0
@@ -4,3 +4,4 @@ common-obj-y += replay-events.o common-obj-y += replay-time.o common-obj-y += replay-input.o common-obj-y += replay-char.o +common-obj-y += replay-net.o
replay/replay-events.c +11 -0
@@ -54,6 +54,9 @@ static void replay_run_event(Event *event)case REPLAY_ASYNC_EVENT_BLOCK :aio_bh_call (event->opaque);break ; +case REPLAY_ASYNC_EVENT_NET : +replay_event_net_run (event->opaque); +break ;default :error_report ("Replay: invalid async event ID (%d) in the queue" , event->event_kind);
@@ -189,6 +192,9 @@ static void replay_save_event(Event *event, int checkpoint)case REPLAY_ASYNC_EVENT_BLOCK :replay_put_qword (event->id);break ; +case REPLAY_ASYNC_EVENT_NET : +replay_event_net_save (event->opaque); +break ;default :error_report ("Unknown ID %" PRId64" of replay event" , event->id);exit (1 );
@@ -252,6 +258,11 @@ static Event *replay_read_event(int checkpoint) read_id =replay_get_qword (); }break ; +case REPLAY_ASYNC_EVENT_NET : + event =g_malloc0 (sizeof (Event)); + event->event_kind = read_event_kind; + event->opaque =replay_event_net_load (); +return event;default :error_report ("Unknown ID %d of replay event" , read_event_kind);exit (1 );
replay/replay-internal.h +10 -0
@@ -50,6 +50,7 @@ enum ReplayAsyncEventKind {REPLAY_ASYNC_EVENT_INPUT_SYNC ,REPLAY_ASYNC_EVENT_CHAR_READ ,REPLAY_ASYNC_EVENT_BLOCK , +REPLAY_ASYNC_EVENT_NET , REPLAY_ASYNC_COUNT };
@@ -155,4 +156,13 @@ void replay_event_char_read_save(void *opaque);/*! Reads char event read from the file. */ void *replay_event_char_read_load (void ); +/* Network devices */ + +/*! Called to run network event. */ +void replay_event_net_run (void *opaque); +/*! Writes network event to the file. */ +void replay_event_net_save (void *opaque); +/*! Reads network from the file. */ +void *replay_event_net_load (void ); +#endif
replay/replay-net.c new file +110 -0
110 lines not on this page · raw message
replay/replay.c +1 -1
@@ -21,7 +21,7 @@/* Current version of the replay mechanism. Increase it when file format changes. */ -#define REPLAY_VERSION 0xe02004 +#define REPLAY_VERSION 0xe02005/* Size of replay log header */ #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t))
vl.c +2 -1
@@ -2806,7 +2806,8 @@ static bool object_create_initial(const char *type)if (g_str_equal (type,"filter-buffer" ) ||g_str_equal (type,"filter-dump" ) ||g_str_equal (type,"filter-mirror" ) || -g_str_equal (type,"filter-redirector" )) { +g_str_equal (type,"filter-redirector" ) || +g_str_equal (type,"filter-replay" )) {return false; }