[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [PATCH 16/32] ppc: Rework NIP updates vs. exception gener
From: |
David Gibson |
Subject: |
Re: [Qemu-ppc] [PATCH 16/32] ppc: Rework NIP updates vs. exception generation |
Date: |
Wed, 27 Jul 2016 12:19:39 +1000 |
User-agent: |
Mutt/1.6.2 (2016-07-01) |
On Wed, Jul 27, 2016 at 08:21:10AM +1000, Benjamin Herrenschmidt wrote:
> We make env->nip almost always point to the faulting instruction,
> thus avoiding a mess of "store_current" vs "store_next" in the
> exception handling. The syscall exception knows to move the PC by
> 4 and that's really about it.
>
> This actually fixes a number of cases where the translator was
> setting env->nip to ctx->nip - 4 (ie. the *current* instruction)
> but the program check exception handler would branch to
> "store_current" which applies another -4 offset.
>
> Signed-off-by: Benjamin Herrenschmidt <address@hidden>
I'm having a fair bit of trouble wrapping my head around this. Still
comments on a couple of small matters.
> ---
> linux-user/main.c | 12 ++--
> target-ppc/excp_helper.c | 148
> ++++++++++++++++++-----------------------------
> target-ppc/translate.c | 59 +++++++++++--------
> 3 files changed, 96 insertions(+), 123 deletions(-)
>
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 462e820..1d149dc 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -1814,7 +1814,7 @@ void cpu_loop(CPUPPCState *env)
> env->error_code);
> break;
> }
> - info._sifields._sigfault._addr = env->nip - 4;
> + info._sifields._sigfault._addr = env->nip;
> queue_signal(env, info.si_signo, &info);
> break;
> case POWERPC_EXCP_FPU: /* Floating-point unavailable exception
> */
> @@ -1822,7 +1822,7 @@ void cpu_loop(CPUPPCState *env)
> info.si_signo = TARGET_SIGILL;
> info.si_errno = 0;
> info.si_code = TARGET_ILL_COPROC;
> - info._sifields._sigfault._addr = env->nip - 4;
> + info._sifields._sigfault._addr = env->nip;
> queue_signal(env, info.si_signo, &info);
> break;
> case POWERPC_EXCP_SYSCALL: /* System call exception
> */
> @@ -1834,7 +1834,7 @@ void cpu_loop(CPUPPCState *env)
> info.si_signo = TARGET_SIGILL;
> info.si_errno = 0;
> info.si_code = TARGET_ILL_COPROC;
> - info._sifields._sigfault._addr = env->nip - 4;
> + info._sifields._sigfault._addr = env->nip;
> queue_signal(env, info.si_signo, &info);
> break;
> case POWERPC_EXCP_DECR: /* Decrementer exception
> */
> @@ -1862,7 +1862,7 @@ void cpu_loop(CPUPPCState *env)
> info.si_signo = TARGET_SIGILL;
> info.si_errno = 0;
> info.si_code = TARGET_ILL_COPROC;
> - info._sifields._sigfault._addr = env->nip - 4;
> + info._sifields._sigfault._addr = env->nip;
> queue_signal(env, info.si_signo, &info);
> break;
> case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ
> */
> @@ -1926,7 +1926,7 @@ void cpu_loop(CPUPPCState *env)
> info.si_signo = TARGET_SIGILL;
> info.si_errno = 0;
> info.si_code = TARGET_ILL_COPROC;
> - info._sifields._sigfault._addr = env->nip - 4;
> + info._sifields._sigfault._addr = env->nip;
> queue_signal(env, info.si_signo, &info);
> break;
> case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ
> */
> @@ -2001,9 +2001,9 @@ void cpu_loop(CPUPPCState *env)
> env->gpr[5], env->gpr[6], env->gpr[7],
> env->gpr[8], 0, 0);
> if (ret == -TARGET_ERESTARTSYS) {
> - env->nip -= 4;
> break;
> }
> + env->nip += 4;
> if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) {
> /* Returning from a successful sigreturn syscall.
> Avoid corrupting register state. */
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index 563c7bc..570d188 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -198,7 +198,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
> default:
> goto excp_invalid;
> }
> - goto store_next;
> + break;
> case POWERPC_EXCP_MCHECK: /* Machine check exception
> */
> if (msr_me == 0) {
> /* Machine check exception is not enabled.
> @@ -209,7 +209,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
> if (qemu_log_separate()) {
> qemu_log("Machine check while not allowed. "
> "Entering checkstop state\n");
> - }
> + }
Looks like an accidental whitespace change.
> cs->halted = 1;
> cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
> }
> @@ -235,16 +235,16 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
> default:
> break;
> }
> - goto store_next;
> + break;
> case POWERPC_EXCP_DSI: /* Data storage exception
> */
> LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
> "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
> - goto store_next;
> + break;
> case POWERPC_EXCP_ISI: /* Instruction storage exception
> */
> LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
> "\n", msr, env->nip);
> msr |= env->error_code;
> - goto store_next;
> + break;
> case POWERPC_EXCP_EXTERNAL: /* External input
> */
> cs = CPU(cpu);
>
> @@ -258,13 +258,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
> /* IACK the IRQ on delivery */
> env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
> }
> - goto store_next;
> + break;
> case POWERPC_EXCP_ALIGN: /* Alignment exception
> */
> /* XXX: this is false */
> /* Get rS/rD and rA from faulting opcode */
> - env->spr[SPR_DSISR] |= (cpu_ldl_code(env, (env->nip - 4))
> + /* Broken for LE mode */
> + env->spr[SPR_DSISR] |= (cpu_ldl_code(env, env->nip)
> & 0x03FF0000) >> 16;
> - goto store_next;
> + break;
> case POWERPC_EXCP_PROGRAM: /* Program exception
> */
> switch (env->error_code & ~0xF) {
> case POWERPC_EXCP_FP:
> @@ -280,15 +281,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
> * precise in the MSR.
> */
> msr |= 0x00100000;
> - goto store_next;
> + break;
> case POWERPC_EXCP_INVAL:
> LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
> msr |= 0x00080000;
> env->spr[SPR_BOOKE_ESR] = ESR_PIL;
> - /* Some invalids will have the PC in the right place already */
> - if (env->error_code & POWERPC_EXCP_INVAL_LSWX) {
> - goto store_next;
> - }
> break;
> case POWERPC_EXCP_PRIV:
> msr |= 0x00040000;
> @@ -304,23 +301,16 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
> env->error_code);
> break;
> }
> - goto store_current;
> - case POWERPC_EXCP_HV_EMU:
> - srr0 = SPR_HSRR0;
> - srr1 = SPR_HSRR1;
> - new_msr |= (target_ulong)MSR_HVB;
> - new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> - /* Some invalids will have the PC in the right place already */
> - if (env->error_code == (POWERPC_EXCP_INVAL|POWERPC_EXCP_INVAL_LSWX))
> {
> - goto store_next;
> - }
> - goto store_current;
> - case POWERPC_EXCP_FPU: /* Floating-point unavailable exception
> */
> - goto store_current;
> + break;
> case POWERPC_EXCP_SYSCALL: /* System call exception
> */
> dump_syscall(env);
> lev = env->error_code;
>
> + /* We need to correct the NIP which in this case is supposed
> + * to point to the next instruction
> + */
> + env->nip += 4;
> +
> /* "PAPR mode" built-in hypercall emulation */
> if ((lev == 1) && cpu_ppc_hypercall) {
> cpu_ppc_hypercall(cpu);
> @@ -329,15 +319,15 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
> if (lev == 1) {
> new_msr |= (target_ulong)MSR_HVB;
> }
> - goto store_next;
> + break;
> + case POWERPC_EXCP_FPU: /* Floating-point unavailable exception
> */
> case POWERPC_EXCP_APU: /* Auxiliary processor unavailable
> */
> - goto store_current;
> case POWERPC_EXCP_DECR: /* Decrementer exception
> */
> - goto store_next;
> + break;
> case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt
> */
> /* FIT on 4xx */
> LOG_EXCP("FIT exception\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_WDT: /* Watchdog timer interrupt
> */
> LOG_EXCP("WDT exception\n");
> switch (excp_model) {
> @@ -348,11 +338,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
> default:
> break;
> }
> - goto store_next;
> + break;
> case POWERPC_EXCP_DTLB: /* Data TLB error
> */
> - goto store_next;
> case POWERPC_EXCP_ITLB: /* Instruction TLB error
> */
> - goto store_next;
> + break;
> case POWERPC_EXCP_DEBUG: /* Debug interrupt
> */
> switch (excp_model) {
> case POWERPC_EXCP_BOOKE:
> @@ -367,33 +356,33 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
> }
> /* XXX: TODO */
> cpu_abort(cs, "Debug exception is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable
> */
> env->spr[SPR_BOOKE_ESR] = ESR_SPV;
> - goto store_current;
> + break;
> case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt
> */
> /* XXX: TODO */
> cpu_abort(cs, "Embedded floating point data exception "
> "is not implemented yet !\n");
> env->spr[SPR_BOOKE_ESR] = ESR_SPV;
> - goto store_next;
> + break;
> case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt
> */
> /* XXX: TODO */
> cpu_abort(cs, "Embedded floating point round exception "
> "is not implemented yet !\n");
> env->spr[SPR_BOOKE_ESR] = ESR_SPV;
> - goto store_next;
> + break;
> case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt
> */
> /* XXX: TODO */
> cpu_abort(cs,
> "Performance counter exception is not implemented yet
> !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt
> */
> - goto store_next;
> + break;
> case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt
> */
> srr0 = SPR_BOOKE_CSRR0;
> srr1 = SPR_BOOKE_CSRR1;
> - goto store_next;
> + break;
> case POWERPC_EXCP_RESET: /* System reset exception
> */
> if (msr_pow) {
> /* indicate that we resumed from power save mode */
> @@ -404,65 +393,42 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
>
> new_msr |= (target_ulong)MSR_HVB;
> ail = 0;
> - goto store_next;
> + break;
> case POWERPC_EXCP_DSEG: /* Data segment exception
> */
> - goto store_next;
> case POWERPC_EXCP_ISEG: /* Instruction segment exception
> */
> - goto store_next;
> - case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception
> */
> - srr0 = SPR_HSRR0;
> - srr1 = SPR_HSRR1;
> - new_msr |= (target_ulong)MSR_HVB;
> - new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> - goto store_next;
> case POWERPC_EXCP_TRACE: /* Trace exception
> */
> - goto store_next;
> + break;
> + case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception
> */
> case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception
> */
> - srr0 = SPR_HSRR0;
> - srr1 = SPR_HSRR1;
> - new_msr |= (target_ulong)MSR_HVB;
> - new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> - goto store_next;
> case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception
> */
> - srr0 = SPR_HSRR0;
> - srr1 = SPR_HSRR1;
> - new_msr |= (target_ulong)MSR_HVB;
> - new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> - goto store_next;
> case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception
> */
> - srr0 = SPR_HSRR0;
> - srr1 = SPR_HSRR1;
> - new_msr |= (target_ulong)MSR_HVB;
> - new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> - goto store_next;
> case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception
> */
> + case POWERPC_EXCP_HV_EMU:
> srr0 = SPR_HSRR0;
> srr1 = SPR_HSRR1;
> new_msr |= (target_ulong)MSR_HVB;
> new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> - goto store_next;
> + break;
> case POWERPC_EXCP_VPU: /* Vector unavailable exception
> */
> - goto store_current;
> case POWERPC_EXCP_VSXU: /* VSX unavailable exception
> */
> - goto store_current;
> case POWERPC_EXCP_FU: /* Facility unavailable exception
> */
> - goto store_current;
> + break;
> case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt
> */
> LOG_EXCP("PIT exception\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_IO: /* IO error exception
> */
> /* XXX: TODO */
> cpu_abort(cs, "601 IO error exception is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_RUNM: /* Run mode exception
> */
> /* XXX: TODO */
> cpu_abort(cs, "601 run mode exception is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_EMUL: /* Emulation trap exception
> */
> /* XXX: TODO */
> cpu_abort(cs, "602 emulation trap exception "
> "is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error
> */
> switch (excp_model) {
> case POWERPC_EXCP_602:
> @@ -577,71 +543,67 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
> excp_model, int excp)
> cpu_abort(cs, "Invalid data store TLB miss exception\n");
> break;
> }
> - goto store_next;
> + break;
> case POWERPC_EXCP_FPA: /* Floating-point assist exception
> */
> /* XXX: TODO */
> cpu_abort(cs, "Floating point assist exception "
> "is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_DABR: /* Data address breakpoint
> */
> /* XXX: TODO */
> cpu_abort(cs, "DABR exception is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_IABR: /* Instruction address breakpoint
> */
> /* XXX: TODO */
> cpu_abort(cs, "IABR exception is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_SMI: /* System management interrupt
> */
> /* XXX: TODO */
> cpu_abort(cs, "SMI exception is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_THERM: /* Thermal interrupt
> */
> /* XXX: TODO */
> cpu_abort(cs, "Thermal management exception "
> "is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt
> */
> /* XXX: TODO */
> cpu_abort(cs,
> "Performance counter exception is not implemented yet
> !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_VPUA: /* Vector assist exception
> */
> /* XXX: TODO */
> cpu_abort(cs, "VPU assist exception is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_SOFTP: /* Soft patch exception
> */
> /* XXX: TODO */
> cpu_abort(cs,
> "970 soft-patch exception is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_MAINT: /* Maintenance exception
> */
> /* XXX: TODO */
> cpu_abort(cs,
> "970 maintenance exception is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint
> */
> /* XXX: TODO */
> cpu_abort(cs, "Maskable external exception "
> "is not implemented yet !\n");
> - goto store_next;
> + break;
> case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint
> */
> /* XXX: TODO */
> cpu_abort(cs, "Non maskable external exception "
> "is not implemented yet !\n");
> - goto store_next;
> + break;
> default:
> excp_invalid:
> cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
> break;
> - store_current:
> - /* save current instruction location */
> - env->spr[srr0] = env->nip - 4;
> - break;
> - store_next:
> - /* save next instruction location */
> - env->spr[srr0] = env->nip;
> - break;
> }
> +
> + /* Save PC */
> + env->spr[srr0] = env->nip;
> +
> /* Save MSR */
> env->spr[srr1] = msr;
>
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index c4f8916..84bcb09 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -276,8 +276,12 @@ void gen_update_current_nip(void *opaque)
> static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t
> error)
> {
> TCGv_i32 t0, t1;
> +
> + /* These are all synchronous exceptions, we set the PC back to
> + * the faulting instruction
> + */
> if (ctx->exception == POWERPC_EXCP_NONE) {
> - gen_update_nip(ctx, ctx->nip);
> + gen_update_nip(ctx, ctx->nip - 4);
> }
> t0 = tcg_const_i32(excp);
> t1 = tcg_const_i32(error);
> @@ -290,8 +294,12 @@ 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;
> +
> + /* These are all synchronous exceptions, we set the PC back to
> + * the faulting instruction
> + */
> if (ctx->exception == POWERPC_EXCP_NONE) {
> - gen_update_nip(ctx, ctx->nip);
> + gen_update_nip(ctx, ctx->nip - 4);
> }
> t0 = tcg_const_i32(excp);
> gen_helper_raise_exception(cpu_env, t0);
> @@ -299,13 +307,28 @@ static void gen_exception(DisasContext *ctx, uint32_t
> excp)
> ctx->exception = (excp);
> }
>
> +static void gen_exception_nip(DisasContext *ctx, uint32_t excp,
> + target_ulong nip)
> +{
> + TCGv_i32 t0;
> +
> + gen_update_nip(ctx, nip);
> + t0 = tcg_const_i32(excp);
> + gen_helper_raise_exception(cpu_env, t0);
> + tcg_temp_free_i32(t0);
> + ctx->exception = (excp);
> +}
> +
> static void gen_debug_exception(DisasContext *ctx)
> {
> TCGv_i32 t0;
>
> + /* These are all synchronous exceptions, we set the PC back to
> + * the faulting instruction
> + */
> if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
> (ctx->exception != POWERPC_EXCP_SYNC)) {
> - gen_update_nip(ctx, ctx->nip);
> + gen_update_nip(ctx, ctx->nip - 4);
> }
> t0 = tcg_const_i32(EXCP_DEBUG);
> gen_helper_raise_exception(cpu_env, t0);
> @@ -1437,7 +1460,7 @@ static void gen_pause(DisasContext *ctx)
> tcg_temp_free_i32(t0);
>
> /* Stop translation, this gives other CPUs a chance to run */
> - gen_exception_err(ctx, EXCP_HLT, 1);
> + gen_exception_nip(ctx, EXCP_HLT, ctx->nip);
> }
> #endif /* defined(TARGET_PPC64) */
>
> @@ -2697,12 +2720,6 @@ static void gen_lswi(DisasContext *ctx)
> nb = 32;
> nr = (nb + 3) / 4;
> if (unlikely(lsw_reg_in_range(start, nr, ra))) {
> - /* The handler expects the PC to point to *this* instruction,
> - * so setting ctx->exception here prevents it from being
> - * improperly updated again by gen_inval_exception
> - */
> - gen_update_nip(ctx, ctx->nip - 4);
> - ctx->exception = POWERPC_EXCP_HV_EMU;
> gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
> return;
> }
> @@ -2845,10 +2862,7 @@ static void gen_conditional_store(DisasContext *ctx,
> TCGv EA,
> tcg_gen_movi_tl(t0, (size << 5) | reg);
> tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, reserve_info));
> tcg_temp_free(t0);
> - gen_update_nip(ctx, ctx->nip-4);
> - ctx->exception = POWERPC_EXCP_BRANCH;
> - gen_exception(ctx, POWERPC_EXCP_STCX);
> - ctx->exception = save_exception;
> + gen_exception_err(ctx, POWERPC_EXCP_STCX, 0);
> }
> #else
> static void gen_conditional_store(DisasContext *ctx, TCGv EA,
> @@ -2987,7 +3001,7 @@ static void gen_wait(DisasContext *ctx)
> -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
> tcg_temp_free_i32(t0);
> /* Stop translation, as the CPU is supposed to sleep from now */
> - gen_exception_err(ctx, EXCP_HLT, 1);
> + gen_exception_nip(ctx, EXCP_HLT, ctx->nip);
> }
>
> #if defined(TARGET_PPC64)
> @@ -3090,10 +3104,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int
> n, target_ulong dest)
> (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
> (ctx->exception == POWERPC_EXCP_BRANCH ||
> ctx->exception == POWERPC_EXCP_TRACE)) {
> - target_ulong tmp = ctx->nip;
> - ctx->nip = dest;
> - gen_exception(ctx, POWERPC_EXCP_TRACE);
> - ctx->nip = tmp;
> + gen_exception_nip(ctx, POWERPC_EXCP_TRACE, dest);
> }
> if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
> gen_debug_exception(ctx);
> @@ -3362,7 +3373,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_update_nip(ctx, ctx->nip - 4);
twi etc will generally resume from the next instruction if they trap,
yes? In which case I'm a bit confused by the nip - 4. But possibly I
just haven't correctly followed all the nip update logic changed by
this patch.
> gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)],
> cpu_gpr[rB(ctx->opcode)],
> t0);
> tcg_temp_free_i32(t0);
> @@ -3374,7 +3385,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_update_nip(ctx, ctx->nip - 4);
> gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
> tcg_temp_free(t0);
> tcg_temp_free_i32(t1);
> @@ -3386,7 +3397,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_update_nip(ctx, ctx->nip - 4);
> gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)],
> cpu_gpr[rB(ctx->opcode)],
> t0);
> tcg_temp_free_i32(t0);
> @@ -3398,7 +3409,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_update_nip(ctx, ctx->nip - 4);
> gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
> tcg_temp_free(t0);
> tcg_temp_free_i32(t1);
> @@ -6757,7 +6768,7 @@ void gen_intermediate_code(CPUPPCState *env, struct
> TranslationBlock *tb)
> ctx.exception != POWERPC_SYSCALL &&
> ctx.exception != POWERPC_EXCP_TRAP &&
> ctx.exception != POWERPC_EXCP_BRANCH)) {
> - gen_exception(ctxp, POWERPC_EXCP_TRACE);
> + gen_exception_nip(ctxp, POWERPC_EXCP_TRACE, ctx.nip);
> } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
> (cs->singlestep_enabled) ||
> singlestep ||
--
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
signature.asc
Description: PGP signature
- [Qemu-ppc] [PATCH 08/32] ppc: Rename fload_invalid_op_excp to float_invalid_op_excp, (continued)
- [Qemu-ppc] [PATCH 08/32] ppc: Rename fload_invalid_op_excp to float_invalid_op_excp, Benjamin Herrenschmidt, 2016/07/26
- [Qemu-ppc] [PATCH 03/32] ppc: Move classic fp ops out of translate.c, Benjamin Herrenschmidt, 2016/07/26
- [Qemu-ppc] [PATCH 04/32] ppc: Move embedded spe ops out of translate.c, Benjamin Herrenschmidt, 2016/07/26
- [Qemu-ppc] [PATCH 06/32] ppc: Move VMX ops out of translate.c, Benjamin Herrenschmidt, 2016/07/26
- [Qemu-ppc] [PATCH 07/32] ppc: Move VSX ops out of translate.c, Benjamin Herrenschmidt, 2016/07/26
- [Qemu-ppc] [PATCH 18/32] ppc: Don't update NIP in DCR access routines, Benjamin Herrenschmidt, 2016/07/26
- [Qemu-ppc] [PATCH 19/32] ppc: Don't update NIP in facility unavailable interrupts, Benjamin Herrenschmidt, 2016/07/26
- [Qemu-ppc] [PATCH 16/32] ppc: Rework NIP updates vs. exception generation, Benjamin Herrenschmidt, 2016/07/26
- Re: [Qemu-ppc] [PATCH 16/32] ppc: Rework NIP updates vs. exception generation,
David Gibson <=
- [Qemu-ppc] [PATCH 20/32] ppc: Don't update NIP BookE 2.06 tlbwe, Benjamin Herrenschmidt, 2016/07/26
- [Qemu-ppc] [PATCH 21/32] ppc: Don't update NIP on conditional trap instructions, Benjamin Herrenschmidt, 2016/07/26
- [Qemu-ppc] [PATCH 24/32] ppc: Make alignment exceptions suck less, Benjamin Herrenschmidt, 2016/07/26
- [Qemu-ppc] [PATCH 27/32] ppc: Fix CFAR updates, Benjamin Herrenschmidt, 2016/07/26