[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCHv2 15/31] ppc: Rework NIP updates vs. exception generat
From: |
Benjamin Herrenschmidt |
Subject: |
[Qemu-ppc] [PATCHv2 15/31] ppc: Rework NIP updates vs. exception generation |
Date: |
Wed, 27 Jul 2016 16:56:33 +1000 |
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>
---
linux-user/main.c | 12 ++--
target-ppc/excp_helper.c | 146 ++++++++++++++++++-----------------------------
target-ppc/translate.c | 59 +++++++++++--------
3 files changed, 95 insertions(+), 122 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 eb00473..d31eece 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.
@@ -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 5e88ee2..622c375 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);
@@ -1642,7 +1665,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) */
@@ -2911,12 +2934,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;
}
@@ -3059,10 +3076,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,
@@ -3201,7 +3215,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)
@@ -3304,10 +3318,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);
@@ -3576,7 +3587,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);
@@ -3588,7 +3599,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);
@@ -3600,7 +3611,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);
@@ -3612,7 +3623,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);
@@ -7052,7 +7063,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
- [Qemu-ppc] [PATCHv2 05/31] ppc: Move VMX ops out of translate.c, (continued)
- [Qemu-ppc] [PATCHv2 12/31] ppc: Don't update NIP in lswi/lswx/stswi/stswx, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 13/31] ppc: Don't update NIP in lmw/stmw/icbi, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 03/31] ppc: Move embedded spe ops out of translate.c, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 14/31] ppc: Make tlb_fill() use new exception helper, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 16/31] ppc: Fix source NIP on SLB related interrupts, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 15/31] ppc: Rework NIP updates vs. exception generation,
Benjamin Herrenschmidt <=
- [Qemu-ppc] [PATCHv2 17/31] ppc: Don't update NIP in DCR access routines, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 21/31] ppc: Don't update NIP if not taking alignment exceptions, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 22/31] ppc: Don't update NIP in dcbz and lscbx, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 19/31] ppc: Don't update NIP BookE 2.06 tlbwe, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 18/31] ppc: Don't update NIP in facility unavailable interrupts, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 20/31] ppc: Don't update NIP on conditional trap instructions, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 23/31] ppc: Make alignment exceptions suck less, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 24/31] ppc: Handle unconditional (always/never) traps at translation time, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 25/31] ppc: Speed up dcbz, Benjamin Herrenschmidt, 2016/07/27
- [Qemu-ppc] [PATCHv2 26/31] ppc: Fix CFAR updates, Benjamin Herrenschmidt, 2016/07/27