qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v3 2/3] target-mips: improve exceptions handling


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH v3 2/3] target-mips: improve exceptions handling
Date: Wed, 24 Jun 2015 01:32:41 +0200
User-agent: Mutt/1.5.23 (2014-03-12)

On 2015-06-18 16:28, Pavel Dovgalyuk wrote:
> This patch improves exception handling in MIPS.
> Instructions generate several types of exceptions.
> When exception is generated, it breaks the execution of the current 
> translation
> block. Implementation of the exceptions handling does not correctly
> restore icount for the instruction which caused the exception. In most cases
> icount will be decreased by the value equal to the size of TB.
> This patch passes pointer to the translation block internals to the exception
> handler. It allows correct restoring of the icount value.
> 
> v3 changes:
> This patch stops translation when instruction which always generates exception
> is translated. This improves the performance of the patched version compared
> to original one.
> 
> Signed-off-by: Pavel Dovgalyuk <address@hidden>
> ---
>  target-mips/cpu.h        |   28 +++
>  target-mips/helper.h     |    1 
>  target-mips/msa_helper.c |    5 -
>  target-mips/op_helper.c  |  183 ++++++++++------------
>  target-mips/translate.c  |  379 
> ++++++++++++++++++++++------------------------
>  5 files changed, 302 insertions(+), 294 deletions(-)
> 
> diff --git a/target-mips/cpu.h b/target-mips/cpu.h
> index f9d2b4c..70ba39a 100644
> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -1015,4 +1015,32 @@ static inline void cpu_mips_store_cause(CPUMIPSState 
> *env, target_ulong val)
>  }
>  #endif
>  
> +static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env,
> +                                                        uint32_t exception,
> +                                                        int error_code,
> +                                                        uintptr_t pc)
> +{
> +    CPUState *cs = CPU(mips_env_get_cpu(env));
> +
> +    if (exception < EXCP_SC) {
> +        qemu_log("%s: %d %d\n", __func__, exception, error_code);
> +    }
> +    cs->exception_index = exception;
> +    env->error_code = error_code;
> +
> +    if (pc) {
> +        /* now we have a real cpu fault */
> +        cpu_restore_state(cs, pc);
> +    }
> +
> +    cpu_loop_exit(cs);

What about creating a cpu_loop_exit_restore(cs, pc) (maybe with a better
name?) in the common code, if we now have to repeat this pattern for
every target?

> +}
> +
> +static inline void QEMU_NORETURN do_raise_exception(CPUMIPSState *env,
> +                                                    uint32_t exception,
> +                                                    uintptr_t pc)
> +{
> +    do_raise_exception_err(env, exception, 0, pc);
> +}
> +
>  #endif /* !defined (__MIPS_CPU_H__) */
> diff --git a/target-mips/helper.h b/target-mips/helper.h
> index 3bd0b02..50c699e 100644
> --- a/target-mips/helper.h
> +++ b/target-mips/helper.h
> @@ -1,5 +1,6 @@
>  DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int)
>  DEF_HELPER_2(raise_exception, noreturn, env, i32)
> +DEF_HELPER_1(raise_exception_debug, noreturn, env)
>  
>  #ifdef TARGET_MIPS64
>  DEF_HELPER_4(sdl, void, env, tl, tl, int)
> diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
> index 26ffdc7..f7bc710 100644
> --- a/target-mips/msa_helper.c
> +++ b/target-mips/msa_helper.c
> @@ -1352,7 +1352,7 @@ void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong 
> elm, uint32_t cd)
>          /* check exception */
>          if ((GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)
>              & GET_FP_CAUSE(env->active_tc.msacsr)) {
> -            helper_raise_exception(env, EXCP_MSAFPE);
> +            do_raise_exception(env, EXCP_MSAFPE, GETPC());
>          }
>          break;
>      }
> @@ -1512,7 +1512,8 @@ static inline void check_msacsr_cause(CPUMIPSState *env)
>          UPDATE_FP_FLAGS(env->active_tc.msacsr,
>                  GET_FP_CAUSE(env->active_tc.msacsr));
>      } else {
> -        helper_raise_exception(env, EXCP_MSAFPE);
> +        /* Will work only when check_msacsr_cause is actually inlined */
> +        do_raise_exception(env, EXCP_MSAFPE, GETPC());

Then that might not work. Instead of adding this comment, please change
the function to always_inline, or (probably better) change it to take
the return address in argument.

>      }
>  }
>  
> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
> index 73a8e45..077ea94 100644
> --- a/target-mips/op_helper.c
> +++ b/target-mips/op_helper.c
> @@ -30,41 +30,23 @@ static inline void cpu_mips_tlb_flush (CPUMIPSState *env, 
> int flush_global);
>  
> /*****************************************************************************/
>  /* Exceptions processing helpers */
>  
> -static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env,
> -                                                        uint32_t exception,
> -                                                        int error_code,
> -                                                        uintptr_t pc)
> +void helper_raise_exception_err(CPUMIPSState *env, uint32_t exception,
> +                                int error_code)
>  {
> -    CPUState *cs = CPU(mips_env_get_cpu(env));
> -
> -    if (exception < EXCP_SC) {
> -        qemu_log("%s: %d %d\n", __func__, exception, error_code);
> -    }
> -    cs->exception_index = exception;
> -    env->error_code = error_code;
> -
> -    if (pc) {
> -        /* now we have a real cpu fault */
> -        cpu_restore_state(cs, pc);
> -    }
> -
> -    cpu_loop_exit(cs);
> +    do_raise_exception_err(env, exception, error_code, 0);
>  }
>  
> -static inline void QEMU_NORETURN do_raise_exception(CPUMIPSState *env,
> -                                                    uint32_t exception,
> -                                                    uintptr_t pc)
> +void helper_raise_exception(CPUMIPSState *env, uint32_t exception)
>  {
> -    do_raise_exception_err(env, exception, 0, pc);
> +    do_raise_exception(env, exception, GETPC());
>  }
>  
> -void helper_raise_exception_err(CPUMIPSState *env, uint32_t exception,
> -                                int error_code)
> +void helper_raise_exception_debug(CPUMIPSState *env)
>  {
> -    do_raise_exception_err(env, exception, error_code, 0);
> +    do_raise_exception(env, EXCP_DEBUG, 0);
>  }
>  
> -void helper_raise_exception(CPUMIPSState *env, uint32_t exception)
> +static void raise_exception(CPUMIPSState *env, uint32_t exception)
>  {
>      do_raise_exception(env, exception, 0);
>  }
> @@ -72,21 +54,21 @@ void helper_raise_exception(CPUMIPSState *env, uint32_t 
> exception)
>  #if defined(CONFIG_USER_ONLY)
>  #define HELPER_LD(name, insn, type)                                     \
>  static inline type do_##name(CPUMIPSState *env, target_ulong addr,      \
> -                             int mem_idx)                               \
> +                             int mem_idx, uintptr_t retaddr)            \
>  {                                                                       \
> -    return (type) cpu_##insn##_data(env, addr);                         \
> +    return (type) cpu_##insn##_data_ra(env, addr, retaddr);             \
>  }
>  #else
>  #define HELPER_LD(name, insn, type)                                     \
>  static inline type do_##name(CPUMIPSState *env, target_ulong addr,      \
> -                             int mem_idx)                               \
> +                             int mem_idx, uintptr_t retaddr)            \
>  {                                                                       \
>      switch (mem_idx)                                                    \
>      {                                                                   \
> -    case 0: return (type) cpu_##insn##_kernel(env, addr); break;        \
> -    case 1: return (type) cpu_##insn##_super(env, addr); break;         \
> +    case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr);   \
> +    case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr);    \
>      default:                                                            \
> -    case 2: return (type) cpu_##insn##_user(env, addr); break;          \
> +    case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr);     \
>      }                                                                   \
>  }
>  #endif
> @@ -106,14 +88,14 @@ static inline void do_##name(CPUMIPSState *env, 
> target_ulong addr,      \
>  #else
>  #define HELPER_ST(name, insn, type)                                     \
>  static inline void do_##name(CPUMIPSState *env, target_ulong addr,      \
> -                             type val, int mem_idx)                     \
> +                             type val, int mem_idx, uintptr_t retaddr)  \
>  {                                                                       \
>      switch (mem_idx)                                                    \
>      {                                                                   \
> -    case 0: cpu_##insn##_kernel(env, addr, val); break;                 \
> -    case 1: cpu_##insn##_super(env, addr, val); break;                  \
> +    case 0: cpu_##insn##_kernel_ra(env, addr, val, retaddr); break;     \
> +    case 1: cpu_##insn##_super_ra(env, addr, val, retaddr); break;      \
>      default:                                                            \
> -    case 2: cpu_##insn##_user(env, addr, val); break;                   \
> +    case 2: cpu_##insn##_user_ra(env, addr, val, retaddr); break;       \
>      }                                                                   \
>  }
>  #endif
> @@ -291,14 +273,19 @@ target_ulong helper_bitswap(target_ulong rt)
>  
>  static inline hwaddr do_translate_address(CPUMIPSState *env,
>                                                        target_ulong address,
> -                                                      int rw)
> +                                                      int rw, uintptr_t 
> retaddr)
>  {
>      hwaddr lladdr;
> +    CPUState *cs = CPU(mips_env_get_cpu(env));
>  
>      lladdr = cpu_mips_translate_address(env, address, rw);
>  
>      if (lladdr == -1LL) {
> -        cpu_loop_exit(CPU(mips_env_get_cpu(env)));
> +        if (retaddr) {
> +            /* now we have a real cpu fault */
> +            cpu_restore_state(cs, retaddr);
> +        }
> +        cpu_loop_exit(cs);

That's where a common cpu_loop_exit_restore might help to reduce code
duplication.

>      } else {
>          return lladdr;
>      }
> @@ -309,10 +296,10 @@ target_ulong helper_##name(CPUMIPSState *env, 
> target_ulong arg, int mem_idx)  \
>  {                                                                            
>  \
>      if (arg & almask) {                                                      
>  \
>          env->CP0_BadVAddr = arg;                                             
>  \
> -        helper_raise_exception(env, EXCP_AdEL);                              
>  \
> +        do_raise_exception(env, EXCP_AdEL, GETPC());                         
>  \
>      }                                                                        
>  \
> -    env->lladdr = do_translate_address(env, arg, 0);                         
>  \
> -    env->llval = do_##insn(env, arg, mem_idx);                               
>  \
> +    env->lladdr = do_translate_address(env, arg, 0, GETPC());                
>  \
> +    env->llval = do_##insn(env, arg, mem_idx, GETPC());                      
>  \
>      return env->llval;                                                       
>  \
>  }
>  HELPER_LD_ATOMIC(ll, lw, 0x3)
> @@ -329,12 +316,12 @@ target_ulong helper_##name(CPUMIPSState *env, 
> target_ulong arg1,              \
>                                                                               
>  \
>      if (arg2 & almask) {                                                     
>  \
>          env->CP0_BadVAddr = arg2;                                            
>  \
> -        helper_raise_exception(env, EXCP_AdES);                              
>  \
> +        do_raise_exception(env, EXCP_AdES, GETPC());                         
>  \
>      }                                                                        
>  \
> -    if (do_translate_address(env, arg2, 1) == env->lladdr) {                 
>  \
> -        tmp = do_##ld_insn(env, arg2, mem_idx);                              
>  \
> +    if (do_translate_address(env, arg2, 1, GETPC()) == env->lladdr) {        
>  \
> +        tmp = do_##ld_insn(env, arg2, mem_idx, GETPC());                     
>  \
>          if (tmp == env->llval) {                                             
>  \
> -            do_##st_insn(env, arg2, arg1, mem_idx);                          
>  \
> +            do_##st_insn(env, arg2, arg1, mem_idx, GETPC());                 
>  \
>              return 1;                                                        
>  \
>          }                                                                    
>  \
>      }                                                                        
>  \
> @@ -358,31 +345,31 @@ HELPER_ST_ATOMIC(scd, ld, sd, 0x7)
>  void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
>                  int mem_idx)
>  {
> -    do_sb(env, arg2, (uint8_t)(arg1 >> 24), mem_idx);
> +    do_sb(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC());
>  
>      if (GET_LMASK(arg2) <= 2)
> -        do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK(arg2) <= 1)
> -        do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK(arg2) == 0)
> -        do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)arg1, mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)arg1, mem_idx, GETPC());
>  }
>  
>  void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
>                  int mem_idx)
>  {
> -    do_sb(env, arg2, (uint8_t)arg1, mem_idx);
> +    do_sb(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
>  
>      if (GET_LMASK(arg2) >= 1)
> -        do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK(arg2) >= 2)
> -        do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK(arg2) == 3)
> -        do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx, 
> GETPC());
>  }
>  
>  #if defined(TARGET_MIPS64)
> @@ -398,55 +385,55 @@ void helper_swr(CPUMIPSState *env, target_ulong arg1, 
> target_ulong arg2,
>  void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
>                  int mem_idx)
>  {
> -    do_sb(env, arg2, (uint8_t)(arg1 >> 56), mem_idx);
> +    do_sb(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC());
>  
>      if (GET_LMASK64(arg2) <= 6)
> -        do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) <= 5)
> -        do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) <= 4)
> -        do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) <= 3)
> -        do_sb(env, GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) <= 2)
> -        do_sb(env, GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) <= 1)
> -        do_sb(env, GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) <= 0)
> -        do_sb(env, GET_OFFSET(arg2, 7), (uint8_t)arg1, mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, 7), (uint8_t)arg1, mem_idx, GETPC());
>  }
>  
>  void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
>                  int mem_idx)
>  {
> -    do_sb(env, arg2, (uint8_t)arg1, mem_idx);
> +    do_sb(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
>  
>      if (GET_LMASK64(arg2) >= 1)
> -        do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) >= 2)
> -        do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) >= 3)
> -        do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) >= 4)
> -        do_sb(env, GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) >= 5)
> -        do_sb(env, GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) >= 6)
> -        do_sb(env, GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48), mem_idx, 
> GETPC());
>  
>      if (GET_LMASK64(arg2) == 7)
> -        do_sb(env, GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56), mem_idx);
> +        do_sb(env, GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56), mem_idx, 
> GETPC());
>  }
>  #endif /* TARGET_MIPS64 */
>  
> @@ -463,13 +450,13 @@ void helper_lwm(CPUMIPSState *env, target_ulong addr, 
> target_ulong reglist,
>  
>          for (i = 0; i < base_reglist; i++) {
>              env->active_tc.gpr[multiple_regs[i]] =
> -                (target_long)do_lw(env, addr, mem_idx);
> +                (target_long)do_lw(env, addr, mem_idx, GETPC());
>              addr += 4;
>          }
>      }
>  
>      if (do_r31) {
> -        env->active_tc.gpr[31] = (target_long)do_lw(env, addr, mem_idx);
> +        env->active_tc.gpr[31] = (target_long)do_lw(env, addr, mem_idx, 
> GETPC());
>      }
>  }
>  
> @@ -483,13 +470,13 @@ void helper_swm(CPUMIPSState *env, target_ulong addr, 
> target_ulong reglist,
>          target_ulong i;
>  
>          for (i = 0; i < base_reglist; i++) {
> -            do_sw(env, addr, env->active_tc.gpr[multiple_regs[i]], mem_idx);
> +            do_sw(env, addr, env->active_tc.gpr[multiple_regs[i]], mem_idx, 
> GETPC());
>              addr += 4;
>          }
>      }
>  
>      if (do_r31) {
> -        do_sw(env, addr, env->active_tc.gpr[31], mem_idx);
> +        do_sw(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
>      }
>  }
>  
> @@ -504,7 +491,7 @@ void helper_ldm(CPUMIPSState *env, target_ulong addr, 
> target_ulong reglist,
>          target_ulong i;
>  
>          for (i = 0; i < base_reglist; i++) {
> -            env->active_tc.gpr[multiple_regs[i]] = do_ld(env, addr, mem_idx);
> +            env->active_tc.gpr[multiple_regs[i]] = do_ld(env, addr, mem_idx, 
> GETPC());
>              addr += 8;
>          }
>      }
> @@ -524,13 +511,13 @@ void helper_sdm(CPUMIPSState *env, target_ulong addr, 
> target_ulong reglist,
>          target_ulong i;
>  
>          for (i = 0; i < base_reglist; i++) {
> -            do_sd(env, addr, env->active_tc.gpr[multiple_regs[i]], mem_idx);
> +            do_sd(env, addr, env->active_tc.gpr[multiple_regs[i]], mem_idx, 
> GETPC());
>              addr += 8;
>          }
>      }
>  
>      if (do_r31) {
> -        do_sd(env, addr, env->active_tc.gpr[31], mem_idx);
> +        do_sd(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
>      }
>  }
>  #endif
> @@ -1787,13 +1774,13 @@ target_ulong helper_yield(CPUMIPSState *env, 
> target_ulong arg)
>                  env->active_tc.CP0_TCStatus & (1 << CP0TCSt_DT)) {
>                  env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
>                  env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
> -                helper_raise_exception(env, EXCP_THREAD);
> +                do_raise_exception(env, EXCP_THREAD, GETPC());
>              }
>          }
>      } else if (arg1 == 0) {
>          if (0 /* TODO: TC underflow */) {
>              env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
> -            helper_raise_exception(env, EXCP_THREAD);
> +            do_raise_exception(env, EXCP_THREAD, GETPC());
>          } else {
>              // TODO: Deallocate TC
>          }
> @@ -1801,7 +1788,7 @@ target_ulong helper_yield(CPUMIPSState *env, 
> target_ulong arg)
>          /* Yield qualifier inputs not implemented. */
>          env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
>          env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
> -        helper_raise_exception(env, EXCP_THREAD);
> +        do_raise_exception(env, EXCP_THREAD, GETPC());
>      }
>      return env->CP0_YQMask;
>  }
> @@ -2131,7 +2118,7 @@ target_ulong helper_rdhwr_cpunum(CPUMIPSState *env)
>          (env->CP0_HWREna & (1 << 0)))
>          return env->CP0_EBase & 0x3ff;
>      else
> -        helper_raise_exception(env, EXCP_RI);
> +        do_raise_exception(env, EXCP_RI, GETPC());
>  
>      return 0;
>  }
> @@ -2142,7 +2129,7 @@ target_ulong helper_rdhwr_synci_step(CPUMIPSState *env)
>          (env->CP0_HWREna & (1 << 1)))
>          return env->SYNCI_Step;
>      else
> -        helper_raise_exception(env, EXCP_RI);
> +        do_raise_exception(env, EXCP_RI, GETPC());
>  
>      return 0;
>  }
> @@ -2153,7 +2140,7 @@ target_ulong helper_rdhwr_cc(CPUMIPSState *env)
>          (env->CP0_HWREna & (1 << 2)))
>          return env->CP0_Count;
>      else
> -        helper_raise_exception(env, EXCP_RI);
> +        do_raise_exception(env, EXCP_RI, GETPC());
>  
>      return 0;
>  }
> @@ -2164,7 +2151,7 @@ target_ulong helper_rdhwr_ccres(CPUMIPSState *env)
>          (env->CP0_HWREna & (1 << 3)))
>          return env->CCRes;
>      else
> -        helper_raise_exception(env, EXCP_RI);
> +        do_raise_exception(env, EXCP_RI, GETPC());
>  
>      return 0;
>  }
> @@ -2201,7 +2188,9 @@ void helper_wait(CPUMIPSState *env)
>  
>      cs->halted = 1;
>      cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE);
> -    helper_raise_exception(env, EXCP_HLT);
> +    /* Last instruction in the block, PC was updated before
> +       - no need to recover PC and icount */
> +    raise_exception(env, EXCP_HLT);
>  }
>  
>  #if !defined(CONFIG_USER_ONLY)
> @@ -2262,9 +2251,9 @@ void mips_cpu_unassigned_access(CPUState *cs, hwaddr 
> addr,
>      }
>  
>      if (is_exec) {
> -        helper_raise_exception(env, EXCP_IBE);
> +        raise_exception(env, EXCP_IBE);
>      } else {
> -        helper_raise_exception(env, EXCP_DBE);
> +        raise_exception(env, EXCP_DBE);
>      }
>  }
>  #endif /* !CONFIG_USER_ONLY */
> @@ -2299,7 +2288,7 @@ target_ulong helper_cfc1(CPUMIPSState *env, uint32_t 
> reg)
>                  arg1 = (int32_t)
>                         ((env->CP0_Status & (1  << CP0St_FR)) >> CP0St_FR);
>              } else {
> -                helper_raise_exception(env, EXCP_RI);
> +                do_raise_exception(env, EXCP_RI, GETPC());
>              }
>          }
>          break;
> @@ -2332,7 +2321,7 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, 
> uint32_t fs, uint32_t rt)
>              env->CP0_Status &= ~(1 << CP0St_FR);
>              compute_hflags(env);
>          } else {
> -            helper_raise_exception(env, EXCP_RI);
> +            do_raise_exception(env, EXCP_RI, GETPC());
>          }
>          break;
>      case 4:
> @@ -2344,7 +2333,7 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, 
> uint32_t fs, uint32_t rt)
>              env->CP0_Status |= (1 << CP0St_FR);
>              compute_hflags(env);
>          } else {
> -            helper_raise_exception(env, EXCP_RI);
> +            do_raise_exception(env, EXCP_RI, GETPC());
>          }
>          break;
>      case 25:
> @@ -3569,25 +3558,25 @@ void helper_msa_ld_df(CPUMIPSState *env, uint32_t df, 
> uint32_t wd, uint32_t rs,
>      case DF_BYTE:
>          for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
>              pwd->b[i] = do_lbu(env, addr + (i << DF_BYTE),
> -                                env->hflags & MIPS_HFLAG_KSU);
> +                                env->hflags & MIPS_HFLAG_KSU, GETPC());
>          }
>          break;
>      case DF_HALF:
>          for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
>              pwd->h[i] = do_lhu(env, addr + (i << DF_HALF),
> -                                env->hflags & MIPS_HFLAG_KSU);
> +                                env->hflags & MIPS_HFLAG_KSU, GETPC());
>          }
>          break;
>      case DF_WORD:
>          for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
>              pwd->w[i] = do_lw(env, addr + (i << DF_WORD),
> -                                env->hflags & MIPS_HFLAG_KSU);
> +                                env->hflags & MIPS_HFLAG_KSU, GETPC());
>          }
>          break;
>      case DF_DOUBLE:
>          for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
>              pwd->d[i] = do_ld(env, addr + (i << DF_DOUBLE),
> -                                env->hflags & MIPS_HFLAG_KSU);
> +                                env->hflags & MIPS_HFLAG_KSU, GETPC());
>          }
>          break;
>      }
> @@ -3604,25 +3593,25 @@ void helper_msa_st_df(CPUMIPSState *env, uint32_t df, 
> uint32_t wd, uint32_t rs,
>      case DF_BYTE:
>          for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
>              do_sb(env, addr + (i << DF_BYTE), pwd->b[i],
> -                    env->hflags & MIPS_HFLAG_KSU);
> +                    env->hflags & MIPS_HFLAG_KSU, GETPC());
>          }
>          break;
>      case DF_HALF:
>          for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
>              do_sh(env, addr + (i << DF_HALF), pwd->h[i],
> -                    env->hflags & MIPS_HFLAG_KSU);
> +                    env->hflags & MIPS_HFLAG_KSU, GETPC());
>          }
>          break;
>      case DF_WORD:
>          for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
>              do_sw(env, addr + (i << DF_WORD), pwd->w[i],
> -                    env->hflags & MIPS_HFLAG_KSU);
> +                    env->hflags & MIPS_HFLAG_KSU, GETPC());
>          }
>          break;
>      case DF_DOUBLE:
>          for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
>              do_sd(env, addr + (i << DF_DOUBLE), pwd->d[i],
> -                    env->hflags & MIPS_HFLAG_KSU);
> +                    env->hflags & MIPS_HFLAG_KSU, GETPC());
>          }
>          break;
>      }
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index fd063a2..f87d5ac 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -1677,15 +1677,21 @@ generate_exception_err (DisasContext *ctx, int excp, 
> int err)
>      gen_helper_raise_exception_err(cpu_env, texcp, terr);
>      tcg_temp_free_i32(terr);
>      tcg_temp_free_i32(texcp);
> +    ctx->bstate = BS_STOP;
>  }
>  
>  static inline void
>  generate_exception (DisasContext *ctx, int excp)
>  {
> -    save_cpu_state(ctx, 1);
>      gen_helper_0e0i(raise_exception, excp);
>  }
>  
> +static inline void
> +generate_exception_end(DisasContext *ctx, int excp)
> +{
> +    generate_exception_err(ctx, excp, 0);
> +}
> +

This sets error_code to 0, which is different than leaving it unchanged.
This might be ok, but have you checked there is no side effect?

>  /* Addresses computation */
>  static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, 
> TCGv arg1)
>  {
> @@ -1731,7 +1737,7 @@ static inline void check_cp1_enabled(DisasContext *ctx)
>  static inline void check_cop1x(DisasContext *ctx)
>  {
>      if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);

I don't think it is correct. Before triggering such an exception, we
were saving the CPU state, and not going through retranslation. With
this change, we don't save the CPU state, but we don't go through
retranslation either.

The rule is to either go through retranslation, or to save the CPU state
before a possible exception.

>  }
>  
>  /* Verify that the processor is running with 64-bit floating-point
> @@ -1740,7 +1746,7 @@ static inline void check_cop1x(DisasContext *ctx)
>  static inline void check_cp1_64bitmode(DisasContext *ctx)
>  {
>      if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>  }
>  
>  /*
> @@ -1757,7 +1763,7 @@ static inline void check_cp1_64bitmode(DisasContext 
> *ctx)
>  static inline void check_cp1_registers(DisasContext *ctx, int regs)
>  {
>      if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>  }
>  
>  /* Verify that the processor is running with DSP instructions enabled.
> @@ -1768,9 +1774,9 @@ static inline void check_dsp(DisasContext *ctx)
>  {
>      if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
>          if (ctx->insn_flags & ASE_DSP) {
> -            generate_exception(ctx, EXCP_DSPDIS);
> +            generate_exception_end(ctx, EXCP_DSPDIS);
>          } else {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          }
>      }
>  }
> @@ -1779,9 +1785,9 @@ static inline void check_dspr2(DisasContext *ctx)
>  {
>      if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
>          if (ctx->insn_flags & ASE_DSP) {
> -            generate_exception(ctx, EXCP_DSPDIS);
> +            generate_exception_end(ctx, EXCP_DSPDIS);
>          } else {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          }
>      }
>  }
> @@ -1791,7 +1797,7 @@ static inline void check_dspr2(DisasContext *ctx)
>  static inline void check_insn(DisasContext *ctx, int flags)
>  {
>      if (unlikely(!(ctx->insn_flags & flags))) {
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>      }
>  }
>  
> @@ -1801,7 +1807,7 @@ static inline void check_insn(DisasContext *ctx, int 
> flags)
>  static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
>  {
>      if (unlikely(ctx->insn_flags & flags)) {
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>      }
>  }
>  
> @@ -1811,7 +1817,7 @@ static inline void check_insn_opc_removed(DisasContext 
> *ctx, int flags)
>  static inline void check_mips_64(DisasContext *ctx)
>  {
>      if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>  }
>  #endif
>  
> @@ -2092,7 +2098,6 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
>          break;
>      case OPC_LLD:
>      case R6_OPC_LLD:
> -        save_cpu_state(ctx, 1);
>          op_ld_lld(t0, t0, ctx);
>          gen_store_gpr(t0, rt);
>          opn = "lld";
> @@ -2227,7 +2232,6 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
>          break;
>      case OPC_LL:
>      case R6_OPC_LL:
> -        save_cpu_state(ctx, 1);
>          op_ld_ll(t0, t0, ctx);
>          gen_store_gpr(t0, rt);
>          opn = "ll";
> @@ -2255,12 +2259,10 @@ static void gen_st (DisasContext *ctx, uint32_t opc, 
> int rt,
>          opn = "sd";
>          break;
>      case OPC_SDL:
> -        save_cpu_state(ctx, 1);
>          gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
>          opn = "sdl";
>          break;
>      case OPC_SDR:
> -        save_cpu_state(ctx, 1);
>          gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
>          opn = "sdr";
>          break;
> @@ -2278,12 +2280,10 @@ static void gen_st (DisasContext *ctx, uint32_t opc, 
> int rt,
>          opn = "sb";
>          break;
>      case OPC_SWL:
> -        save_cpu_state(ctx, 1);
>          gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
>          opn = "swl";
>          break;
>      case OPC_SWR:
> -        save_cpu_state(ctx, 1);
>          gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
>          opn = "swr";
>          break;
> @@ -2315,14 +2315,12 @@ static void gen_st_cond (DisasContext *ctx, uint32_t 
> opc, int rt,
>  #if defined(TARGET_MIPS64)
>      case OPC_SCD:
>      case R6_OPC_SCD:
> -        save_cpu_state(ctx, 1);
>          op_st_scd(t1, t0, rt, ctx);
>          opn = "scd";
>          break;
>  #endif
>      case OPC_SC:
>      case R6_OPC_SC:
> -        save_cpu_state(ctx, 1);
>          op_st_sc(t1, t0, rt, ctx);
>          opn = "sc";
>          break;
> @@ -2382,7 +2380,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t 
> opc, int ft,
>          break;
>      default:
>          MIPS_INVAL(opn);
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>      (void)opn; /* avoid a compiler warning */
> @@ -3211,7 +3209,7 @@ static inline void gen_pcrel(DisasContext *ctx, int rs, 
> int16_t imm)
>  #endif
>          default:
>              MIPS_INVAL("OPC_PCREL");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -3440,7 +3438,7 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, 
> int rd, int rs, int rt)
>  #endif
>      default:
>          MIPS_INVAL(opn);
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>      (void)opn; /* avoid a compiler warning */
> @@ -3659,7 +3657,7 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
>          break;
>      default:
>          MIPS_INVAL(opn);
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>      (void)opn; /* avoid a compiler warning */
> @@ -3738,7 +3736,7 @@ static void gen_mul_vr54xx (DisasContext *ctx, uint32_t 
> opc,
>          break;
>      default:
>          MIPS_INVAL("mul vr54xx");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>      gen_store_gpr(t0, rd);
> @@ -4263,7 +4261,7 @@ static void gen_loongson_multimedia(DisasContext *ctx, 
> int rd, int rs, int rt)
>             FD field is the CC field?  */
>      default:
>          MIPS_INVAL(opn);
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>  
> @@ -4326,7 +4324,7 @@ static void gen_trap (DisasContext *ctx, uint32_t opc,
>          case OPC_TGEU:  /* rs >= rs unsigned */
>          case OPC_TGEIU: /* r0 >= 0  unsigned */
>              /* Always trap */
> -            generate_exception(ctx, EXCP_TRAP);
> +            generate_exception_end(ctx, EXCP_TRAP);
>              break;
>          case OPC_TLT:   /* rs < rs           */
>          case OPC_TLTI:  /* r0 < 0            */
> @@ -4386,7 +4384,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int 
> n, target_ulong dest)
>          gen_save_pc(dest);
>          if (ctx->singlestep_enabled) {
>              save_cpu_state(ctx, 0);
> -            gen_helper_0e0i(raise_exception, EXCP_DEBUG);
> +            gen_helper_raise_exception_debug(cpu_env);
>          }
>          tcg_gen_exit_tb(0);
>      }
> @@ -4409,7 +4407,7 @@ static void gen_compute_branch (DisasContext *ctx, 
> uint32_t opc,
>          LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
>                    TARGET_FMT_lx "\n", ctx->pc);
>  #endif
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>  
> @@ -4469,14 +4467,14 @@ static void gen_compute_branch (DisasContext *ctx, 
> uint32_t opc,
>              /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
>                 others are reserved. */
>              MIPS_INVAL("jump hint");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              goto out;
>          }
>          gen_load_gpr(btarget, rs);
>          break;
>      default:
>          MIPS_INVAL("branch/jump");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>      if (bcond_compute == 0) {
> @@ -4549,7 +4547,7 @@ static void gen_compute_branch (DisasContext *ctx, 
> uint32_t opc,
>              break;
>          default:
>              MIPS_INVAL("branch/jump");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              goto out;
>          }
>      } else {
> @@ -4642,7 +4640,7 @@ static void gen_compute_branch (DisasContext *ctx, 
> uint32_t opc,
>              break;
>          default:
>              MIPS_INVAL("conditional branch/jump");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              goto out;
>          }
>      }
> @@ -4733,7 +4731,7 @@ static void gen_bitops (DisasContext *ctx, uint32_t 
> opc, int rt,
>      default:
>  fail:
>          MIPS_INVAL("bitops");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          tcg_temp_free(t0);
>          tcg_temp_free(t1);
>          return;
> @@ -4806,7 +4804,7 @@ static void gen_bshfl (DisasContext *ctx, uint32_t op2, 
> int rt, int rd)
>  #endif
>      default:
>          MIPS_INVAL("bsfhl");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          tcg_temp_free(t0);
>          return;
>      }
> @@ -7587,7 +7585,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext 
> *ctx, int rt, int rd,
>  die:
>      tcg_temp_free(t0);
>      LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
> -    generate_exception(ctx, EXCP_RI);
> +    generate_exception_end(ctx, EXCP_RI);
>  }
>  
>  static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
> @@ -7768,7 +7766,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext 
> *ctx, int rd, int rt,
>          break;
>      case 3:
>          /* XXX: For now we support only a single FPU context. */
> -        save_cpu_state(ctx, 1);
> +        save_cpu_state(ctx, 0);

Since you changed helper_ctc1 to use retranslation, there is no need to
save the CPU context. 

>          {
>              TCGv_i32 fs_tmp = tcg_const_i32(rd);
>  
> @@ -7792,7 +7790,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext 
> *ctx, int rd, int rt,
>  die:
>      tcg_temp_free(t0);
>      LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
> -    generate_exception(ctx, EXCP_RI);
> +    generate_exception_end(ctx, EXCP_RI);
>  }
>  
>  static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int 
> rt, int rd)
> @@ -7920,7 +7918,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext 
> *ctx, uint32_t opc, int rt,
>          }
>          if (!(ctx->hflags & MIPS_HFLAG_DM)) {
>              MIPS_INVAL(opn);
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          } else {
>              gen_helper_deret(cpu_env);
>              ctx->bstate = BS_EXCP;
> @@ -7944,7 +7942,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext 
> *ctx, uint32_t opc, int rt,
>      default:
>   die:
>          MIPS_INVAL(opn);
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>      (void)opn; /* avoid a compiler warning */
> @@ -7962,7 +7960,7 @@ static void gen_compute_branch1(DisasContext *ctx, 
> uint32_t op,
>  
>      if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & 
> MIPS_HFLAG_BMASK)) {
>          MIPS_DEBUG("CTI in delay / forbidden slot");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>  
> @@ -8060,7 +8058,7 @@ static void gen_compute_branch1(DisasContext *ctx, 
> uint32_t op,
>          break;
>      default:
>          MIPS_INVAL(opn);
> -        generate_exception (ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>      (void)opn; /* avoid a compiler warning */
> @@ -8085,7 +8083,7 @@ static void gen_compute_branch1_r6(DisasContext *ctx, 
> uint32_t op,
>          LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
>                    "\n", ctx->pc);
>  #endif
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>  
> @@ -8107,7 +8105,7 @@ static void gen_compute_branch1_r6(DisasContext *ctx, 
> uint32_t op,
>          break;
>      default:
>          MIPS_INVAL(opn);
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>  
> @@ -8371,7 +8369,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, 
> int rt, int fs)
>          break;
>      case OPC_CTC1:
>          gen_load_gpr(t0, rt);
> -        save_cpu_state(ctx, 1);
> +        save_cpu_state(ctx, 0);
>          {
>              TCGv_i32 fs_tmp = tcg_const_i32(fs);
>  
> @@ -8418,7 +8416,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, 
> int rt, int fs)
>          break;
>      default:
>          MIPS_INVAL(opn);
> -        generate_exception (ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>      (void)opn; /* avoid a compiler warning */
> @@ -8551,7 +8549,7 @@ static void gen_sel_s(DisasContext *ctx, enum fopcode 
> op1, int fd, int ft,
>          break;
>      default:
>          MIPS_INVAL("gen_sel_s");
> -        generate_exception (ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -8588,7 +8586,7 @@ static void gen_sel_d(DisasContext *ctx, enum fopcode 
> op1, int fd, int ft,
>          break;
>      default:
>          MIPS_INVAL("gen_sel_d");
> -        generate_exception (ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -10088,7 +10086,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          break;
>      default:
>          MIPS_INVAL(opn);
> -        generate_exception (ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>      (void)opn; /* avoid a compiler warning */
> @@ -10466,7 +10464,7 @@ static void gen_flt3_arith (DisasContext *ctx, 
> uint32_t opc,
>          break;
>      default:
>          MIPS_INVAL(opn);
> -        generate_exception (ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>      (void)opn; /* avoid a compiler warning */
> @@ -10487,22 +10485,22 @@ static void gen_rdhwr(DisasContext *ctx, int rt, 
> int rd)
>  
>      switch (rd) {
>      case 0:
> -        save_cpu_state(ctx, 1);
> +        save_cpu_state(ctx, 0);
>          gen_helper_rdhwr_cpunum(t0, cpu_env);

Same here, if helper_rdhwr_cpunum uses retranslation, there is no need
to save the cpu state.

>          gen_store_gpr(t0, rt);
>          break;
>      case 1:
> -        save_cpu_state(ctx, 1);
> +        save_cpu_state(ctx, 0);

ditto

>          gen_helper_rdhwr_synci_step(t0, cpu_env);
>          gen_store_gpr(t0, rt);
>          break;
>      case 2:
> -        save_cpu_state(ctx, 1);
> +        save_cpu_state(ctx, 0);
>          gen_helper_rdhwr_cc(t0, cpu_env);
>          gen_store_gpr(t0, rt);
>          break;
>      case 3:
> -        save_cpu_state(ctx, 1);
> +        save_cpu_state(ctx, 0);
>          gen_helper_rdhwr_ccres(t0, cpu_env);
>          gen_store_gpr(t0, rt);
>          break;
> @@ -10519,13 +10517,13 @@ static void gen_rdhwr(DisasContext *ctx, int rt, 
> int rd)
>                            offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
>              gen_store_gpr(t0, rt);
>          } else {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          }
>          break;
>  #endif
>      default:            /* Invalid */
>          MIPS_INVAL("rdhwr");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>      tcg_temp_free(t0);
> @@ -10602,7 +10600,7 @@ static void gen_branch(DisasContext *ctx, int 
> insn_bytes)
>              }
>              if (ctx->singlestep_enabled) {
>                  save_cpu_state(ctx, 0);
> -                gen_helper_0e0i(raise_exception, EXCP_DEBUG);
> +                gen_helper_raise_exception_debug(cpu_env);
>              }
>              tcg_gen_exit_tb(0);
>              break;
> @@ -10771,7 +10769,7 @@ static void gen_mips16_save (DisasContext *ctx,
>          args = 4;
>          break;
>      default:
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>  
> @@ -10867,7 +10865,7 @@ static void gen_mips16_save (DisasContext *ctx,
>          astatic = 4;
>          break;
>      default:
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>  
> @@ -10973,7 +10971,7 @@ static void gen_mips16_restore (DisasContext *ctx,
>          astatic = 4;
>          break;
>      default:
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>  
> @@ -11004,7 +11002,7 @@ static void gen_addiupc (DisasContext *ctx, int rx, 
> int imm,
>      TCGv t0;
>  
>      if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>  
> @@ -11053,7 +11051,7 @@ static void decode_i64_mips16 (DisasContext *ctx,
>          check_insn(ctx, ISA_MIPS3);
>          check_mips_64(ctx);
>          if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          } else {
>              offset = extended ? offset : offset << 3;
>              gen_ld(ctx, OPC_LDPC, ry, 0, offset);
> @@ -11128,7 +11126,7 @@ static int decode_extended_mips16_opc (CPUMIPSState 
> *env, DisasContext *ctx)
>              check_mips_64(ctx);
>              gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
>  #else
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>  #endif
>              break;
>          case 0x2:
> @@ -11156,7 +11154,7 @@ static int decode_extended_mips16_opc (CPUMIPSState 
> *env, DisasContext *ctx)
>              check_mips_64(ctx);
>              gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
>  #else
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>  #endif
>          } else {
>              gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
> @@ -11208,7 +11206,7 @@ static int decode_extended_mips16_opc (CPUMIPSState 
> *env, DisasContext *ctx)
>              }
>              break;
>          default:
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -11271,7 +11269,7 @@ static int decode_extended_mips16_opc (CPUMIPSState 
> *env, DisasContext *ctx)
>          break;
>  #endif
>      default:
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -11343,7 +11341,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>              check_mips_64(ctx);
>              gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
>  #else
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>  #endif
>              break;
>          case 0x2:
> @@ -11371,7 +11369,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>                  check_mips_64(ctx);
>                  gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
>  #else
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>  #endif
>              } else {
>                  gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
> @@ -11455,7 +11453,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>                  gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
>                  break;
>              default:
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  break;
>              }
>          }
> @@ -11545,7 +11543,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>                  break;
>  #endif
>              default:
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  goto done;
>              }
>  
> @@ -11582,9 +11580,9 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>               */
>              check_insn(ctx, ISA_MIPS32);
>              if (!(ctx->hflags & MIPS_HFLAG_DM)) {
> -                generate_exception(ctx, EXCP_DBp);
> +                generate_exception_end(ctx, EXCP_DBp);
>              } else {
> -                generate_exception(ctx, EXCP_DBp);
> +                generate_exception_end(ctx, EXCP_DBp);
>              }
>              break;
>          case RR_SLT:
> @@ -11594,7 +11592,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>              gen_slt(ctx, OPC_SLTU, 24, rx, ry);
>              break;
>          case RR_BREAK:
> -            generate_exception(ctx, EXCP_BREAK);
> +            generate_exception_end(ctx, EXCP_BREAK);
>              break;
>          case RR_SLLV:
>              gen_shift(ctx, OPC_SLLV, ry, rx, ry);
> @@ -11661,7 +11659,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>                  break;
>  #endif
>              default:
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  break;
>              }
>              break;
> @@ -11725,7 +11723,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>              break;
>  #endif
>          default:
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -11740,7 +11738,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>  #endif
>      default:
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -12299,7 +12297,7 @@ static void gen_ldst_multiple (DisasContext *ctx, 
> uint32_t opc, int reglist,
>      TCGv_i32 t2;
>  
>      if (ctx->hflags & MIPS_HFLAG_BMASK) {
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>  
> @@ -12429,7 +12427,7 @@ static void gen_pool16c_insn(DisasContext *ctx)
>          gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
>          break;
>      case BREAK16:
> -        generate_exception(ctx, EXCP_BREAK);
> +        generate_exception_end(ctx, EXCP_BREAK);
>          break;
>      case SDBBP16:
>          /* XXX: not clear which exception should be raised
> @@ -12437,9 +12435,9 @@ static void gen_pool16c_insn(DisasContext *ctx)
>           */
>          check_insn(ctx, ISA_MIPS32);
>          if (!(ctx->hflags & MIPS_HFLAG_DM)) {
> -            generate_exception(ctx, EXCP_DBp);
> +            generate_exception_end(ctx, EXCP_DBp);
>          } else {
> -            generate_exception(ctx, EXCP_DBp);
> +            generate_exception_end(ctx, EXCP_DBp);
>          }
>          break;
>      case JRADDIUSP + 0:
> @@ -12453,7 +12451,7 @@ static void gen_pool16c_insn(DisasContext *ctx)
>          }
>          break;
>      default:
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -12485,7 +12483,7 @@ static void gen_ldst_pair (DisasContext *ctx, 
> uint32_t opc, int rd,
>      TCGv t0, t1;
>  
>      if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>  
> @@ -12497,7 +12495,7 @@ static void gen_ldst_pair (DisasContext *ctx, 
> uint32_t opc, int rd,
>      switch (opc) {
>      case LWP:
>          if (rd == base) {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              return;
>          }
>          tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
> @@ -12520,7 +12518,7 @@ static void gen_ldst_pair (DisasContext *ctx, 
> uint32_t opc, int rd,
>  #ifdef TARGET_MIPS64
>      case LDP:
>          if (rd == base) {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              return;
>          }
>          tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
> @@ -12800,15 +12798,14 @@ static void gen_pool32axf (CPUMIPSState *env, 
> DisasContext *ctx, int rt, int rs)
>              /* NOP */
>              break;
>          case SYSCALL:
> -            generate_exception(ctx, EXCP_SYSCALL);
> -            ctx->bstate = BS_STOP;
> +            generate_exception_end(ctx, EXCP_SYSCALL);
>              break;
>          case SDBBP:
>              check_insn(ctx, ISA_MIPS32);
>              if (!(ctx->hflags & MIPS_HFLAG_DM)) {
> -                generate_exception(ctx, EXCP_DBp);
> +                generate_exception_end(ctx, EXCP_DBp);
>              } else {
> -                generate_exception(ctx, EXCP_DBp);
> +                generate_exception_end(ctx, EXCP_DBp);
>              }
>              break;
>          default:
> @@ -12854,7 +12851,7 @@ static void gen_pool32axf (CPUMIPSState *env, 
> DisasContext *ctx, int rt, int rs)
>      default:
>      pool32axf_invalid:
>          MIPS_INVAL("pool32axf");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -13120,7 +13117,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, 
> int rs)
>          break;
>      default:
>          MIPS_INVAL("pool32fxf");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -13263,12 +13260,12 @@ static void decode_micromips32_opc (CPUMIPSState 
> *env, DisasContext *ctx,
>              gen_pool32axf(env, ctx, rt, rs);
>              break;
>          case 0x07:
> -            generate_exception(ctx, EXCP_BREAK);
> +            generate_exception_end(ctx, EXCP_BREAK);
>              break;
>          default:
>          pool32a_invalid:
>                  MIPS_INVAL("pool32a");
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  break;
>          }
>          break;
> @@ -13308,7 +13305,7 @@ static void decode_micromips32_opc (CPUMIPSState 
> *env, DisasContext *ctx,
>              break;
>          default:
>              MIPS_INVAL("pool32b");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -13594,7 +13591,7 @@ static void decode_micromips32_opc (CPUMIPSState 
> *env, DisasContext *ctx,
>              default:
>              pool32f_invalid:
>                  MIPS_INVAL("pool32f");
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  break;
>              }
>          } else {
> @@ -13706,7 +13703,7 @@ static void decode_micromips32_opc (CPUMIPSState 
> *env, DisasContext *ctx,
>              /* Fall through */
>          default:
>              MIPS_INVAL("pool32i");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -13781,7 +13778,7 @@ static void decode_micromips32_opc (CPUMIPSState 
> *env, DisasContext *ctx,
>              break;
>          default:
>              MIPS_INVAL("pool32c");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -13908,7 +13905,7 @@ static void decode_micromips32_opc (CPUMIPSState 
> *env, DisasContext *ctx,
>          gen_st(ctx, mips32_op, rt, rs, imm);
>          break;
>      default:
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -13920,8 +13917,7 @@ static int decode_micromips_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>      /* make sure instructions are on a halfword boundary */
>      if (ctx->pc & 0x1) {
>          env->CP0_BadVAddr = ctx->pc;
> -        generate_exception(ctx, EXCP_AdEL);
> -        ctx->bstate = BS_STOP;
> +        generate_exception_end(ctx, EXCP_AdEL);
>          return 2;
>      }
>  
> @@ -13940,9 +13936,7 @@ static int decode_micromips_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>          case 7:
>          /* LB32, LH32, LWC132, LDC132, LW32 */
>              if (ctx->hflags & MIPS_HFLAG_BDS16) {
> -                generate_exception(ctx, EXCP_RI);
> -                /* Just stop translation; the user is confused.  */
> -                ctx->bstate = BS_STOP;
> +                generate_exception_end(ctx, EXCP_RI);
>                  return 2;
>              }
>              break;
> @@ -13953,9 +13947,7 @@ static int decode_micromips_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>          case 3:
>          /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
>              if (ctx->hflags & MIPS_HFLAG_BDS32) {
> -                generate_exception(ctx, EXCP_RI);
> -                /* Just stop translation; the user is confused.  */
> -                ctx->bstate = BS_STOP;
> +                generate_exception_end(ctx, EXCP_RI);
>                  return 2;
>              }
>              break;
> @@ -14016,7 +14008,7 @@ static int decode_micromips_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      case POOL16F:
>          if (ctx->opcode & 1) {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          } else {
>              /* MOVEP */
>              int enc_dest = uMIPS_RD(ctx->opcode);
> @@ -14166,7 +14158,7 @@ static int decode_micromips_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>      case RES_31:
>      case RES_38:
>      case RES_39:
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      default:
>          decode_micromips32_opc (env, ctx, op);
> @@ -14804,7 +14796,7 @@ static void gen_mipsdsp_shift(DisasContext *ctx, 
> uint32_t opc,
>                  break;
>              default:            /* Invalid */
>                  MIPS_INVAL("MASK SHLL.QB");
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  break;
>              }
>              break;
> @@ -14919,7 +14911,7 @@ static void gen_mipsdsp_shift(DisasContext *ctx, 
> uint32_t opc,
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK SHLL.OB");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -15628,7 +15620,7 @@ static void gen_mipsdsp_append(CPUMIPSState *env, 
> DisasContext *ctx,
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK APPEND");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -15662,7 +15654,7 @@ static void gen_mipsdsp_append(CPUMIPSState *env, 
> DisasContext *ctx,
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK DAPPEND");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -15918,7 +15910,7 @@ static void gen_compute_compact_branch(DisasContext 
> *ctx, uint32_t opc,
>          LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
>                    "\n", ctx->pc);
>  #endif
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>  
> @@ -15980,7 +15972,7 @@ static void gen_compute_compact_branch(DisasContext 
> *ctx, uint32_t opc,
>          break;
>      default:
>          MIPS_INVAL("Compact branch/jump");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          goto out;
>      }
>  
> @@ -16001,7 +15993,7 @@ static void gen_compute_compact_branch(DisasContext 
> *ctx, uint32_t opc,
>              break;
>          default:
>              MIPS_INVAL("Compact branch/jump");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              goto out;
>          }
>  
> @@ -16124,7 +16116,7 @@ static void gen_compute_compact_branch(DisasContext 
> *ctx, uint32_t opc,
>              break;
>          default:
>              MIPS_INVAL("Compact conditional branch/jump");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              goto out;
>          }
>  
> @@ -16182,7 +16174,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, 
> DisasContext *ctx)
>              break;
>          default:
>              MIPS_INVAL("special_r6 muldiv");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16197,14 +16189,14 @@ static void decode_opc_special_r6(CPUMIPSState 
> *env, DisasContext *ctx)
>                 We need additionally to check other fields */
>              gen_cl(ctx, op1, rd, rs);
>          } else {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          }
>          break;
>      case R6_OPC_SDBBP:
>          if (ctx->hflags & MIPS_HFLAG_SBRI) {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          } else {
> -            generate_exception(ctx, EXCP_DBp);
> +            generate_exception_end(ctx, EXCP_DBp);
>          }
>          break;
>  #if defined(TARGET_MIPS64)
> @@ -16230,7 +16222,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, 
> DisasContext *ctx)
>              check_mips_64(ctx);
>              gen_cl(ctx, op1, rd, rs);
>          } else {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          }
>          break;
>      case OPC_DMULT ... OPC_DDIVU:
> @@ -16249,14 +16241,14 @@ static void decode_opc_special_r6(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:
>              MIPS_INVAL("special_r6 muldiv");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
>  #endif
>      default:            /* Invalid */
>          MIPS_INVAL("special_r6");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -16324,16 +16316,16 @@ static void decode_opc_special_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>      case OPC_SPIM:
>  #ifdef MIPS_STRICT_STANDARD
>          MIPS_INVAL("SPIM");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>  #else
>          /* Implemented as RI exception for now. */
>          MIPS_INVAL("spim (unofficial)");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>  #endif
>          break;
>      default:            /* Invalid */
>          MIPS_INVAL("special_legacy");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -16356,7 +16348,7 @@ static void decode_opc_special(CPUMIPSState *env, 
> DisasContext *ctx)
>              if ((ctx->insn_flags & ISA_MIPS32R6) &&
>                  (ctx->hflags & MIPS_HFLAG_BMASK)) {
>                  MIPS_DEBUG("CTI in delay / forbidden slot");
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  break;
>              }
>          }
> @@ -16376,7 +16368,7 @@ static void decode_opc_special(CPUMIPSState *env, 
> DisasContext *ctx)
>              gen_shift_imm(ctx, op1, rd, rt, sa);
>              break;
>          default:
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16399,7 +16391,7 @@ static void decode_opc_special(CPUMIPSState *env, 
> DisasContext *ctx)
>              gen_shift(ctx, op1, rd, rs, rt);
>              break;
>          default:
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16429,18 +16421,17 @@ static void decode_opc_special(CPUMIPSState *env, 
> DisasContext *ctx)
>              /* Pmon entry point, also R4010 selsl */
>  #ifdef MIPS_STRICT_STANDARD
>              MIPS_INVAL("PMON / selsl");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>  #else
>              gen_helper_0e0i(pmon, sa);
>  #endif
>          }
>          break;
>      case OPC_SYSCALL:
> -        generate_exception(ctx, EXCP_SYSCALL);
> -        ctx->bstate = BS_STOP;
> +        generate_exception_end(ctx, EXCP_SYSCALL);
>          break;
>      case OPC_BREAK:
> -        generate_exception(ctx, EXCP_BREAK);
> +        generate_exception_end(ctx, EXCP_BREAK);
>          break;
>      case OPC_SYNC:
>          check_insn(ctx, ISA_MIPS2);
> @@ -16471,7 +16462,7 @@ static void decode_opc_special(CPUMIPSState *env, 
> DisasContext *ctx)
>              gen_shift_imm(ctx, op1, rd, rt, sa);
>              break;
>          default:
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16489,7 +16480,7 @@ static void decode_opc_special(CPUMIPSState *env, 
> DisasContext *ctx)
>              gen_shift_imm(ctx, op1, rd, rt, sa);
>              break;
>          default:
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16518,7 +16509,7 @@ static void decode_opc_special(CPUMIPSState *env, 
> DisasContext *ctx)
>              gen_shift(ctx, op1, rd, rs, rt);
>              break;
>          default:
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16579,9 +16570,9 @@ static void decode_opc_special2_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>           */
>          check_insn(ctx, ISA_MIPS32);
>          if (!(ctx->hflags & MIPS_HFLAG_DM)) {
> -            generate_exception(ctx, EXCP_DBp);
> +            generate_exception_end(ctx, EXCP_DBp);
>          } else {
> -            generate_exception(ctx, EXCP_DBp);
> +            generate_exception_end(ctx, EXCP_DBp);
>          }
>          /* Treat as NOP. */
>          break;
> @@ -16604,7 +16595,7 @@ static void decode_opc_special2_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>  #endif
>      default:            /* Invalid */
>          MIPS_INVAL("special2_legacy");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -16626,7 +16617,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, 
> DisasContext *ctx)
>      case R6_OPC_PREF:
>          if (rt >= 24) {
>              /* hint codes 24-31 are reserved and signal RI */
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          }
>          /* Treat as NOP. */
>          break;
> @@ -16718,7 +16709,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, 
> DisasContext *ctx)
>  #endif
>      default:            /* Invalid */
>          MIPS_INVAL("special3_r6");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -16764,13 +16755,13 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>                  break;
>              default:
>                  MIPS_INVAL("MASK ADDUH.QB");
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  break;
>              }
>          } else if (ctx->insn_flags & INSN_LOONGSON2E) {
>              gen_loongson_integer(ctx, op1, rd, rs, rt);
>          } else {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          }
>          break;
>      case OPC_LX_DSP:
> @@ -16786,7 +16777,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK LX");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16817,7 +16808,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:
>              MIPS_INVAL("MASK ABSQ_S.PH");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16854,7 +16845,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK ADDU.QB");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>  
>          }
> @@ -16894,7 +16885,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK CMPU.EQ.QB");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16930,7 +16921,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK DPAW.PH");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16961,7 +16952,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              }
>          default:            /* Invalid */
>              MIPS_INVAL("MASK INSV");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -16996,7 +16987,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK EXTR.W");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -17039,7 +17030,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK ABSQ_S.QH");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -17078,7 +17069,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK ADDU.OB");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -17123,7 +17114,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK CMPU_EQ.OB");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -17160,7 +17151,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK EXTR.W");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -17199,7 +17190,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK DPAQ.W.QH");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -17230,7 +17221,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>          }
>          default:            /* Invalid */
>              MIPS_INVAL("MASK DINSV");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -17240,7 +17231,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
> *env, DisasContext *ctx)
>  #endif
>      default:            /* Invalid */
>          MIPS_INVAL("special3_legacy");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -17321,7 +17312,6 @@ static void decode_opc_special3(CPUMIPSState *env, 
> DisasContext *ctx)
>          {
>              TCGv t0 = tcg_temp_new();
>  
> -            save_cpu_state(ctx, 1);
>              gen_load_gpr(t0, rs);
>              gen_helper_yield(t0, cpu_env, t0);
>              gen_store_gpr(t0, rd);
> @@ -17342,16 +17332,16 @@ static inline int check_msa_access(DisasContext 
> *ctx)
>  {
>      if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
>                   !(ctx->hflags & MIPS_HFLAG_F64))) {
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return 0;
>      }
>  
>      if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
>          if (ctx->insn_flags & ASE_MSA) {
> -            generate_exception(ctx, EXCP_MSADIS);
> +            generate_exception_end(ctx, EXCP_MSADIS);
>              return 0;
>          } else {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              return 0;
>          }
>      }
> @@ -17409,7 +17399,7 @@ static void gen_msa_branch(CPUMIPSState *env, 
> DisasContext *ctx, uint32_t op1)
>  
>      if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
>          MIPS_DEBUG("CTI in delay / forbidden slot");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>      switch (op1) {
> @@ -17484,7 +17474,7 @@ static void gen_msa_i8(CPUMIPSState *env, 
> DisasContext *ctx)
>          {
>              uint8_t df = (ctx->opcode >> 24) & 0x3;
>              if (df == DF_DOUBLE) {
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>              } else {
>                  TCGv_i32 tdf = tcg_const_i32(df);
>                  gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
> @@ -17494,7 +17484,7 @@ static void gen_msa_i8(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -17566,7 +17556,7 @@ static void gen_msa_i5(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -17602,7 +17592,7 @@ static void gen_msa_bit(CPUMIPSState *env, 
> DisasContext *ctx)
>          m = dfm & 0x7;
>          df = DF_BYTE;
>      } else {
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>  
> @@ -17650,7 +17640,7 @@ static void gen_msa_bit(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -17845,7 +17835,8 @@ static void gen_msa_3r(CPUMIPSState *env, 
> DisasContext *ctx)
>      case OPC_HSUB_S_df:
>      case OPC_HSUB_U_df:
>          if (df == DF_BYTE) {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
> +            break;
>          }
>          switch (MASK_MSA_3R(ctx->opcode)) {
>          case OPC_DOTP_S_df:
> @@ -17882,7 +17873,7 @@ static void gen_msa_3r(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>      tcg_temp_free_i32(twd);
> @@ -17914,7 +17905,7 @@ static void gen_msa_elm_3e(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -17951,7 +17942,7 @@ static void gen_msa_elm_df(CPUMIPSState *env, 
> DisasContext *ctx, uint32_t df,
>  #if !defined(TARGET_MIPS64)
>          /* Double format valid only for MIPS64 */
>          if (df == DF_DOUBLE) {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>  #endif
> @@ -17969,7 +17960,7 @@ static void gen_msa_elm_df(CPUMIPSState *env, 
> DisasContext *ctx, uint32_t df,
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>      }
>      tcg_temp_free_i32(twd);
>      tcg_temp_free_i32(tws);
> @@ -17999,7 +17990,7 @@ static void gen_msa_elm(CPUMIPSState *env, 
> DisasContext *ctx)
>          gen_msa_elm_3e(env, ctx);
>          return;
>      } else {
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          return;
>      }
>  
> @@ -18154,7 +18145,7 @@ static void gen_msa_3rf(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -18182,7 +18173,7 @@ static void gen_msa_2r(CPUMIPSState *env, 
> DisasContext *ctx)
>  #if !defined(TARGET_MIPS64)
>          /* Double format valid only for MIPS64 */
>          if (df == DF_DOUBLE) {
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>  #endif
> @@ -18199,7 +18190,7 @@ static void gen_msa_2r(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -18314,7 +18305,7 @@ static void gen_msa_vec_v(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -18343,7 +18334,7 @@ static void gen_msa_vec(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -18414,14 +18405,14 @@ static void gen_msa(CPUMIPSState *env, DisasContext 
> *ctx)
>              case OPC_LD_H:
>              case OPC_LD_W:
>              case OPC_LD_D:
> -                save_cpu_state(ctx, 1);
> +                save_cpu_state(ctx, 0);

Ditto

>                  gen_helper_msa_ld_df(cpu_env, tdf, twd, trs, ts10);
>                  break;
>              case OPC_ST_B:
>              case OPC_ST_H:
>              case OPC_ST_W:
>              case OPC_ST_D:
> -                save_cpu_state(ctx, 1);
> +                save_cpu_state(ctx, 0);
>                  gen_helper_msa_st_df(cpu_env, tdf, twd, trs, ts10);
>                  break;
>              }
> @@ -18434,7 +18425,7 @@ static void gen_msa(CPUMIPSState *env, DisasContext 
> *ctx)
>          break;
>      default:
>          MIPS_INVAL("MSA instruction");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  
> @@ -18451,7 +18442,6 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>      if (ctx->pc & 0x3) {
>          env->CP0_BadVAddr = ctx->pc;
>          generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
> -        ctx->bstate = BS_STOP;
>          return;
>      }
>  
> @@ -18507,7 +18497,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>                      /* OPC_NAL, OPC_BAL */
>                      gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
>                  } else {
> -                    generate_exception(ctx, EXCP_RI);
> +                    generate_exception_end(ctx, EXCP_RI);
>                  }
>              } else {
>                  gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
> @@ -18552,7 +18542,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>  #endif
>          default:            /* Invalid */
>              MIPS_INVAL("regimm");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -18625,7 +18615,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>                      break;
>                  default:            /* Invalid */
>                      MIPS_INVAL("mfmc0");
> -                    generate_exception(ctx, EXCP_RI);
> +                    generate_exception_end(ctx, EXCP_RI);
>                      break;
>                  }
>                  tcg_temp_free(t0);
> @@ -18642,7 +18632,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>              break;
>          default:
>              MIPS_INVAL("cp0");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -18677,7 +18667,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>      case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
>          if (ctx->insn_flags & ISA_MIPS32R6) {
>              if (rt == 0) {
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  break;
>              }
>              /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
> @@ -18690,7 +18680,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>      case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
>          if (ctx->insn_flags & ISA_MIPS32R6) {
>              if (rt == 0) {
> -                generate_exception(ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  break;
>              }
>              /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
> @@ -18921,7 +18911,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>              break;
>          default:
>              MIPS_INVAL("cp1");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
>          break;
> @@ -19003,7 +18993,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>                  break;
>              default:
>                  MIPS_INVAL("cp3");
> -                generate_exception (ctx, EXCP_RI);
> +                generate_exception_end(ctx, EXCP_RI);
>                  break;
>              }
>          } else {
> @@ -19059,7 +19049,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>              gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
>          } else {
>              MIPS_INVAL("major opcode");
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>          }
>          break;
>  #endif
> @@ -19076,7 +19066,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>              }
>              MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
>  #else
> -            generate_exception(ctx, EXCP_RI);
> +            generate_exception_end(ctx, EXCP_RI);
>              MIPS_INVAL("major opcode");
>  #endif
>          } else {
> @@ -19096,7 +19086,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      default:            /* Invalid */
>          MIPS_INVAL("major opcode");
> -        generate_exception(ctx, EXCP_RI);
> +        generate_exception_end(ctx, EXCP_RI);
>          break;
>      }
>  }
> @@ -19155,7 +19145,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, 
> TranslationBlock *tb,
>                  if (bp->pc == ctx.pc) {
>                      save_cpu_state(&ctx, 1);
>                      ctx.bstate = BS_BRANCH;
> -                    gen_helper_0e0i(raise_exception, EXCP_DEBUG);
> +                    gen_helper_raise_exception_debug(cpu_env);
>                      /* Include the breakpoint location or the tb won't
>                       * be flushed when it must be.  */
>                      ctx.pc += 4;
> @@ -19192,8 +19182,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, 
> TranslationBlock *tb,
>              ctx.opcode = cpu_lduw_code(env, ctx.pc);
>              insn_bytes = decode_mips16_opc(env, &ctx);
>          } else {
> -            generate_exception(&ctx, EXCP_RI);
> -            ctx.bstate = BS_STOP;
> +            generate_exception_end(&ctx, EXCP_RI);
>              break;
>          }
>  
> @@ -19239,7 +19228,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, 
> TranslationBlock *tb,
>      }
>      if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
>          save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
> -        gen_helper_0e0i(raise_exception, EXCP_DEBUG);
> +        gen_helper_raise_exception_debug(cpu_env);
>      } else {
>          switch (ctx.bstate) {
>          case BS_STOP:
> 
> 

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
address@hidden                 http://www.aurel32.net



reply via email to

[Prev in Thread] Current Thread [Next in Thread]