All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: peter.maydell@linearo.org
Cc: agraf@suse.de, qemu-devel@nongnu.org, qemu-ppc@nongnu.org,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	David Gibson <david@gibson.dropbear.id.au>
Subject: [Qemu-devel] [PULL 30/66] ppc: Rework NIP updates vs. exception generation
Date: Tue,  6 Sep 2016 13:40:17 +1000	[thread overview]
Message-ID: <1473133253-17598-31-git-send-email-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <1473133253-17598-1-git-send-email-david@gibson.dropbear.id.au>

From: Benjamin Herrenschmidt <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>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 linux-user/main.c        |  12 ++--
 target-ppc/excp_helper.c | 146 ++++++++++++++++++-----------------------------
 target-ppc/translate.c   |  60 +++++++++++--------
 3 files changed, 95 insertions(+), 123 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index f2f4d2f..d112834 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 dc5ebb1..afcdd3e 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);
@@ -1643,7 +1666,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) */
 
@@ -2912,12 +2935,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;
     }
@@ -3055,16 +3072,12 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
                                   int reg, int size)
 {
     TCGv t0 = tcg_temp_new();
-    uint32_t save_exception = ctx->exception;
 
     tcg_gen_st_tl(EA, cpu_env, offsetof(CPUPPCState, reserve_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,
@@ -3203,7 +3216,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)
@@ -3306,10 +3319,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);
@@ -3578,7 +3588,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);
@@ -3590,7 +3600,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);
@@ -3602,7 +3612,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);
@@ -3614,7 +3624,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);
@@ -7054,7 +7064,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

  parent reply	other threads:[~2016-09-06  3:39 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-06  3:39 [Qemu-devel] [PULL 00/66] ppc-for-2.8 queue 20160906 David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 01/66] xics_kvm: drop extra checking of kernel_xics_fd David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 02/66] hw/ppc: include fdt helper routine in a common file David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 03/66] target-ppc: Introduce Power9 family David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 04/66] target-ppc: Introduce POWER ISA 3.0 flag David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 05/66] target-ppc: adding addpcis instruction David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 06/66] target-ppc: add cmprb instruction David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 07/66] target-ppc: add modulo word operations David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 08/66] target-ppc: add modulo dword operations David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 09/66] target-ppc: add cnttzd[.] instruction David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 10/66] target-ppc: add cnttzw[.] instruction David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 11/66] target-ppc: add cmpeqb instruction David Gibson
2016-09-06  3:39 ` [Qemu-devel] [PULL 12/66] target-ppc: add setb instruction David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 13/66] target-ppc: add maddld instruction David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 14/66] target-ppc: add maddhd and maddhdu instruction David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 15/66] target-ppc: introduce opc4 for Expanded Opcode David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 16/66] ppc: Provide basic raise_exception_* functions David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 17/66] ppc: Move classic fp ops out of translate.c David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 18/66] ppc: Move embedded spe " David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 19/66] ppc: Move DFP " David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 20/66] ppc: Move VMX " David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 21/66] ppc: Move VSX " David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 22/66] ppc: Rename fload_invalid_op_excp to float_invalid_op_excp David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 23/66] ppc: Make float_invalid_op_excp() pass the return address David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 24/66] ppc: Make float_check_status() " David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 25/66] ppc: Don't update the NIP in floating point generated code David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 26/66] ppc: FP exceptions are always precise David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 27/66] ppc: Don't update NIP in lswi/lswx/stswi/stswx David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 28/66] ppc: Don't update NIP in lmw/stmw/icbi David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 29/66] ppc: Make tlb_fill() use new exception helper David Gibson
2016-09-06  3:40 ` David Gibson [this message]
2016-09-06  3:40 ` [Qemu-devel] [PULL 31/66] ppc: Fix source NIP on SLB related interrupts David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 32/66] ppc: Don't update NIP in DCR access routines David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 33/66] ppc: Don't update NIP in facility unavailable interrupts David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 34/66] ppc: Don't update NIP BookE 2.06 tlbwe David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 35/66] ppc: Don't update NIP on conditional trap instructions David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 36/66] ppc: Don't update NIP if not taking alignment exceptions David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 37/66] ppc: Don't update NIP in dcbz and lscbx David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 38/66] ppc: Make alignment exceptions suck less David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 39/66] ppc: Handle unconditional (always/never) traps at translation time David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 40/66] ppc: Speed up dcbz David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 41/66] ppc: Fix CFAR updates David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 42/66] ppc: Don't set access_type on all load/stores on hash64 David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 43/66] ppc: Use a helper to generate "LE unsupported" alignment interrupts David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 44/66] ppc: load/store multiple and string insns don't do LE David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 45/66] ppc: Speed up load/store multiple David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 46/66] target-ppc: implement branch-less divw[o][.] David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 47/66] target-ppc: implement branch-less divd[o][.] David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 48/66] target-ppc: add dtstsfi[q] instructions David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 49/66] target-ppc: add vabsdu[b, h, w] instructions David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 50/66] target-ppc: add vcmpnez[b, h, w][.] instructions David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 51/66] target-ppc: add vslv instruction David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 52/66] target-ppc: add vsrv instruction David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 53/66] target-ppc: add extswsli[.] instruction David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 54/66] ppc: Rename #include'd .c files to .inc.c David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 55/66] hw/ppc: use error_report instead of fprintf David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 56/66] hw/ppc: add a ppc_create_page_sizes_prop() helper routine David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 57/66] ppc: Fix macio ESCC legacy mapping David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 58/66] ppc: Fix catching some segfaults in user mode David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 59/66] ppc: Stop dumping state on all exceptions in linux-user David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 60/66] ppc: Don't generate dead code on unconditional branches David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 61/66] ppc: Improve flags for helpers loading/writing the time facilities David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 62/66] ppc: Improve the exception helpers flags David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 63/66] ppc: Improve a few more helper flags David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 64/66] spapr: implement H_CHANGE_LOGICAL_LAN_MAC h_call David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 65/66] tests: Resort check-qtest entries in Makefile.include David Gibson
2016-09-06  3:40 ` [Qemu-devel] [PULL 66/66] tests: Check serial output of firmware boot of some machines David Gibson
2016-09-06  5:14 ` [Qemu-devel] [PULL 00/66] ppc-for-2.8 queue 20160906 no-reply
2016-09-06 14:04 ` Peter Maydell
2016-09-06 19:35   ` Thomas Huth
2016-09-06 20:23     ` Paolo Bonzini
2016-09-06 20:55       ` Thomas Huth
2016-09-06 21:26         ` Thomas Huth
2016-09-07  1:13           ` David Gibson
2016-09-06 21:09   ` Thomas Huth
2016-09-06 21:52     ` Benjamin Herrenschmidt
2016-09-07  2:26       ` Benjamin Herrenschmidt
2016-09-06  3:42 David Gibson
2016-09-06  3:42 ` [Qemu-devel] [PULL 30/66] ppc: Rework NIP updates vs. exception generation 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=1473133253-17598-31-git-send-email-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=agraf@suse.de \
    --cc=benh@kernel.crashing.org \
    --cc=peter.maydell@linearo.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.