From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: qemu-ppc@nongnu.org
Cc: qemu-devel@nongnu.org, david@gibson.dropbear.id.au,
Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: [Qemu-devel] [PATCH 16/32] ppc: Rework NIP updates vs. exception generation
Date: Wed, 27 Jul 2016 08:21:10 +1000 [thread overview]
Message-ID: <1469571686-7284-16-git-send-email-benh@kernel.crashing.org> (raw)
In-Reply-To: <1469571686-7284-1-git-send-email-benh@kernel.crashing.org>
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 <benh@kernel.crashing.org>
---
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");
- }
+ }
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);
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 ||
--
2.7.4
next prev parent reply other threads:[~2016-07-26 22:23 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-26 22:20 [Qemu-devel] [PATCH 01/32] ppc: Fix fault PC reporting for lve*/stve* VMX instructions Benjamin Herrenschmidt
2016-07-26 22:20 ` [Qemu-devel] [PATCH 02/32] ppc: Provide basic raise_exception_* functions Benjamin Herrenschmidt
2016-07-27 1:50 ` David Gibson
2016-07-27 3:46 ` Benjamin Herrenschmidt
2016-07-26 22:20 ` [Qemu-devel] [PATCH 03/32] ppc: Move classic fp ops out of translate.c Benjamin Herrenschmidt
2016-07-28 16:02 ` Richard Henderson
2016-07-28 21:56 ` Benjamin Herrenschmidt
2016-07-26 22:20 ` [Qemu-devel] [PATCH 04/32] ppc: Move embedded spe " Benjamin Herrenschmidt
2016-07-26 22:20 ` [Qemu-devel] [PATCH 05/32] ppc: Move DFP " Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 06/32] ppc: Move VMX " Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 07/32] ppc: Move VSX " Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 08/32] ppc: Rename fload_invalid_op_excp to float_invalid_op_excp Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 09/32] ppc: Make float_invalid_op_excp() pass the return address Benjamin Herrenschmidt
2016-07-28 16:06 ` Richard Henderson
2016-07-28 21:57 ` Benjamin Herrenschmidt
2016-07-28 22:10 ` Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 10/32] ppc: Make float_check_status() " Benjamin Herrenschmidt
2016-07-27 1:57 ` David Gibson
2016-07-27 3:47 ` Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 11/32] ppc: Don't update the NIP in floating point generated code Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 12/32] ppc: FP exceptions are always precise Benjamin Herrenschmidt
2016-07-27 2:00 ` David Gibson
2016-07-27 3:50 ` Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 13/32] ppc: Don't update NIP in lswi/lswx/stswi/stswx Benjamin Herrenschmidt
2016-07-27 2:04 ` David Gibson
2016-07-27 3:51 ` Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 14/32] ppc: Don't update NIP in lmw/stmw/icbi Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 15/32] ppc: Make tlb_fill() use new exception helper Benjamin Herrenschmidt
2016-07-26 22:21 ` Benjamin Herrenschmidt [this message]
2016-07-27 2:19 ` [Qemu-devel] [PATCH 16/32] ppc: Rework NIP updates vs. exception generation David Gibson
2016-07-27 3:54 ` Benjamin Herrenschmidt
2016-07-27 4:35 ` Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 17/32] ppc: Fix source NIP on SLB related interrupts Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 18/32] ppc: Don't update NIP in DCR access routines Benjamin Herrenschmidt
2016-07-27 2:21 ` David Gibson
2016-07-27 3:55 ` Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 19/32] ppc: Don't update NIP in facility unavailable interrupts Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 20/32] ppc: Don't update NIP BookE 2.06 tlbwe Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 21/32] ppc: Don't update NIP on conditional trap instructions Benjamin Herrenschmidt
2016-07-27 2:26 ` David Gibson
2016-07-27 3:56 ` Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 22/32] ppc: Don't update NIP if not taking alignment exceptions Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 23/32] ppc: Don't update NIP in dcbz and lscbx Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 24/32] ppc: Make alignment exceptions suck less Benjamin Herrenschmidt
2016-07-27 2:30 ` David Gibson
2016-07-27 3:59 ` Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 25/32] ppc: Handle unconditional (always/never) traps at translation time Benjamin Herrenschmidt
2016-07-27 2:33 ` David Gibson
2016-07-27 4:00 ` Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 26/32] ppc: Speed up dcbz Benjamin Herrenschmidt
2016-07-27 2:36 ` David Gibson
2016-07-27 4:02 ` Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 27/32] ppc: Fix CFAR updates Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 28/32] ppc: Avoid double translation for lvx/lvxl/stvx/stvxl Benjamin Herrenschmidt
2016-07-29 0:49 ` Richard Henderson
2016-07-29 2:13 ` Benjamin Herrenschmidt
2016-07-29 3:34 ` David Gibson
2016-07-29 4:40 ` Benjamin Herrenschmidt
2016-07-29 4:58 ` Benjamin Herrenschmidt
2016-07-29 5:42 ` David Gibson
2016-07-29 9:00 ` Benjamin Herrenschmidt
2016-07-29 12:43 ` Richard Henderson
2016-07-26 22:21 ` [Qemu-devel] [PATCH 29/32] ppc: Don't set access_type on all load/stores on hash64 Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 30/32] ppc: Use a helper to generate "LE unsupported" alignment interrupts Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 31/32] ppc: load/store multiple and string insns don't do LE Benjamin Herrenschmidt
2016-07-26 22:21 ` [Qemu-devel] [PATCH 32/32] ppc: Speed up load/store multiple Benjamin Herrenschmidt
2016-07-27 2:47 ` David Gibson
2016-07-27 4:04 ` Benjamin Herrenschmidt
2016-07-27 1:06 ` [Qemu-devel] [PATCH 01/32] ppc: Fix fault PC reporting for lve*/stve* VMX instructions David Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1469571686-7284-16-git-send-email-benh@kernel.crashing.org \
--to=benh@kernel.crashing.org \
--cc=david@gibson.dropbear.id.au \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).