qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCHv1 07/14] target/mips: convert to DisasContextBas


From: Philippe Mathieu-Daudé
Subject: Re: [Qemu-devel] [PATCHv1 07/14] target/mips: convert to DisasContextBase
Date: Wed, 7 Mar 2018 20:21:34 -0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0

On 03/01/2018 07:53 PM, Emilio G. Cota wrote:
> Cc: Aurelien Jarno <address@hidden>
> Cc: Yongbok Kim <address@hidden>
> Signed-off-by: Emilio G. Cota <address@hidden>

Reviewed-by: Philippe Mathieu-Daudé <address@hidden>

> ---
>  target/mips/translate.c | 346 
> ++++++++++++++++++++++++------------------------
>  1 file changed, 175 insertions(+), 171 deletions(-)
> 
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index a133205..aefd729 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -1430,17 +1430,15 @@ static TCGv_i64 msa_wr_d[64];
>      } while(0)
>  
>  typedef struct DisasContext {
> -    struct TranslationBlock *tb;
> -    target_ulong pc, saved_pc;
> +    DisasContextBase base;
> +    target_ulong saved_pc;
>      uint32_t opcode;
> -    int singlestep_enabled;
>      int insn_flags;
>      int32_t CP0_Config1;
>      /* Routine used to access memory */
>      int mem_idx;
>      TCGMemOp default_tcg_memop_mask;
>      uint32_t hflags, saved_hflags;
> -    DisasJumpType is_jmp;
>      target_ulong btarget;
>      bool ulri;
>      int kscrexist;
> @@ -1517,8 +1515,9 @@ static const char * const msaregnames[] = {
>          if (MIPS_DEBUG_DISAS) {                                              
>  \
>              qemu_log_mask(CPU_LOG_TB_IN_ASM,                                 
>  \
>                            TARGET_FMT_lx ": %08x Invalid %s %03x %03x 
> %03x\n", \
> -                          ctx->pc, ctx->opcode, op, ctx->opcode >> 26,       
>  \
> -                          ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); 
>  \
> +                          ctx->base.pc_next, ctx->opcode, op,                
>  \
> +                          ctx->opcode >> 26, ctx->opcode & 0x3F,             
>  \
> +                          ((ctx->opcode >> 16) & 0x1F));                     
>  \
>          }                                                                    
>  \
>      } while (0)
>  
> @@ -1594,9 +1593,9 @@ static inline void gen_save_pc(target_ulong pc)
>  static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
>  {
>      LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
> -    if (do_save_pc && ctx->pc != ctx->saved_pc) {
> -        gen_save_pc(ctx->pc);
> -        ctx->saved_pc = ctx->pc;
> +    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
> +        gen_save_pc(ctx->base.pc_next);
> +        ctx->saved_pc = ctx->base.pc_next;
>      }
>      if (ctx->hflags != ctx->saved_hflags) {
>          tcg_gen_movi_i32(hflags, ctx->hflags);
> @@ -1635,7 +1634,7 @@ static inline void 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->is_jmp = DISAS_EXCP;
> +    ctx->base.is_jmp = DISAS_EXCP;
>  }
>  
>  static inline void generate_exception(DisasContext *ctx, int excp)
> @@ -2126,7 +2125,7 @@ static void gen_base_offset_addr (DisasContext *ctx, 
> TCGv addr,
>  
>  static target_ulong pc_relative_pc (DisasContext *ctx)
>  {
> -    target_ulong pc = ctx->pc;
> +    target_ulong pc = ctx->base.pc_next;
>  
>      if (ctx->hflags & MIPS_HFLAG_BMASK) {
>          int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
> @@ -4275,12 +4274,12 @@ static void gen_trap (DisasContext *ctx, uint32_t opc,
>  
>  static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
>  {
> -    if (unlikely(ctx->singlestep_enabled)) {
> +    if (unlikely(ctx->base.singlestep_enabled)) {
>          return false;
>      }
>  
>  #ifndef CONFIG_USER_ONLY
> -    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
> +    return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & 
> TARGET_PAGE_MASK);
>  #else
>      return true;
>  #endif
> @@ -4291,10 +4290,10 @@ static inline void gen_goto_tb(DisasContext *ctx, int 
> n, target_ulong dest)
>      if (use_goto_tb(ctx, dest)) {
>          tcg_gen_goto_tb(n);
>          gen_save_pc(dest);
> -        tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
> +        tcg_gen_exit_tb((uintptr_t)ctx->base.tb + n);
>      } else {
>          gen_save_pc(dest);
> -        if (ctx->singlestep_enabled) {
> +        if (ctx->base.singlestep_enabled) {
>              save_cpu_state(ctx, 0);
>              gen_helper_raise_exception_debug(cpu_env);
>          }
> @@ -4317,7 +4316,7 @@ static void gen_compute_branch (DisasContext *ctx, 
> uint32_t opc,
>      if (ctx->hflags & MIPS_HFLAG_BMASK) {
>  #ifdef MIPS_DEBUG_DISAS
>          LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
> -                  TARGET_FMT_lx "\n", ctx->pc);
> +                  TARGET_FMT_lx "\n", ctx->base.pc_next);
>  #endif
>          generate_exception_end(ctx, EXCP_RI);
>          goto out;
> @@ -4335,7 +4334,7 @@ static void gen_compute_branch (DisasContext *ctx, 
> uint32_t opc,
>              gen_load_gpr(t1, rt);
>              bcond_compute = 1;
>          }
> -        btgt = ctx->pc + insn_bytes + offset;
> +        btgt = ctx->base.pc_next + insn_bytes + offset;
>          break;
>      case OPC_BGEZ:
>      case OPC_BGEZAL:
> @@ -4354,7 +4353,7 @@ static void gen_compute_branch (DisasContext *ctx, 
> uint32_t opc,
>              gen_load_gpr(t0, rs);
>              bcond_compute = 1;
>          }
> -        btgt = ctx->pc + insn_bytes + offset;
> +        btgt = ctx->base.pc_next + insn_bytes + offset;
>          break;
>      case OPC_BPOSGE32:
>  #if defined(TARGET_MIPS64)
> @@ -4364,13 +4363,14 @@ static void gen_compute_branch (DisasContext *ctx, 
> uint32_t opc,
>          tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
>  #endif
>          bcond_compute = 1;
> -        btgt = ctx->pc + insn_bytes + offset;
> +        btgt = ctx->base.pc_next + insn_bytes + offset;
>          break;
>      case OPC_J:
>      case OPC_JAL:
>      case OPC_JALX:
>          /* Jump to immediate */
> -        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | 
> (uint32_t)offset;
> +        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
> +            (uint32_t)offset;
>          break;
>      case OPC_JR:
>      case OPC_JALR:
> @@ -4416,19 +4416,19 @@ static void gen_compute_branch (DisasContext *ctx, 
> uint32_t opc,
>              /* Handle as an unconditional branch to get correct delay
>                 slot checking.  */
>              blink = 31;
> -            btgt = ctx->pc + insn_bytes + delayslot_size;
> +            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
>              ctx->hflags |= MIPS_HFLAG_B;
>              break;
>          case OPC_BLTZALL: /* 0 < 0 likely */
> -            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
> +            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
>              /* Skip the instruction in the delay slot */
> -            ctx->pc += 4;
> +            ctx->base.pc_next += 4;
>              goto out;
>          case OPC_BNEL:    /* rx != rx likely */
>          case OPC_BGTZL:   /* 0 > 0 likely */
>          case OPC_BLTZL:   /* 0 < 0 likely */
>              /* Skip the instruction in the delay slot */
> -            ctx->pc += 4;
> +            ctx->base.pc_next += 4;
>              goto out;
>          case OPC_J:
>              ctx->hflags |= MIPS_HFLAG_B;
> @@ -4540,7 +4540,8 @@ static void gen_compute_branch (DisasContext *ctx, 
> uint32_t opc,
>          int post_delay = insn_bytes + delayslot_size;
>          int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
>  
> -        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
> +        tcg_gen_movi_tl(cpu_gpr[blink],
> +                        ctx->base.pc_next + post_delay + lowbit);
>      }
>  
>   out:
> @@ -5322,18 +5323,18 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>          switch (sel) {
>          case 0:
>              /* Mark as an IO operation because we read the time.  */
> -            if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
> +            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
>                  gen_io_start();
>           }
>              gen_helper_mfc0_count(arg, cpu_env);
> -            if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
> +            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
>                  gen_io_end();
>              }
>              /* Break the TB to be able to take timer interrupts immediately
>                 after reading count. DISAS_STOP isn't sufficient, we need to
>                 ensure we break completely out of translated code.  */
> -            gen_save_pc(ctx->pc + 4);
> -            ctx->is_jmp = DISAS_EXCP;
> +            gen_save_pc(ctx->base.pc_next + 4);
> +            ctx->base.is_jmp = DISAS_EXCP;
>              rn = "Count";
>              break;
>          /* 6,7 are implementation dependent */
> @@ -5729,7 +5730,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>      if (sel != 0)
>          check_insn(ctx, ISA_MIPS32);
>  
> -    if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
>          gen_io_start();
>      }
>  
> @@ -5901,7 +5902,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>              check_insn(ctx, ISA_MIPS32R2);
>              gen_helper_mtc0_pagegrain(cpu_env, arg);
>              rn = "PageGrain";
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          case 2:
>              CP0_CHECK(ctx->sc);
> @@ -5962,7 +5963,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>          case 0:
>              check_insn(ctx, ISA_MIPS32R2);
>              gen_helper_mtc0_hwrena(cpu_env, arg);
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "HWREna";
>              break;
>          default:
> @@ -6025,29 +6026,29 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>              save_cpu_state(ctx, 1);
>              gen_helper_mtc0_status(cpu_env, arg);
>              /* DISAS_STOP isn't good enough here, hflags may have changed. */
> -            gen_save_pc(ctx->pc + 4);
> -            ctx->is_jmp = DISAS_EXCP;
> +            gen_save_pc(ctx->base.pc_next + 4);
> +            ctx->base.is_jmp = DISAS_EXCP;
>              rn = "Status";
>              break;
>          case 1:
>              check_insn(ctx, ISA_MIPS32R2);
>              gen_helper_mtc0_intctl(cpu_env, arg);
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "IntCtl";
>              break;
>          case 2:
>              check_insn(ctx, ISA_MIPS32R2);
>              gen_helper_mtc0_srsctl(cpu_env, arg);
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "SRSCtl";
>              break;
>          case 3:
>              check_insn(ctx, ISA_MIPS32R2);
>              gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "SRSMap";
>              break;
>          default:
> @@ -6062,8 +6063,8 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>              /* Stop translation as we may have triggered an interrupt.
>               * DISAS_STOP isn't sufficient, we need to ensure we break out of
>               * translated code to check for pending interrupts.  */
> -            gen_save_pc(ctx->pc + 4);
> -            ctx->is_jmp = DISAS_EXCP;
> +            gen_save_pc(ctx->base.pc_next + 4);
> +            ctx->base.is_jmp = DISAS_EXCP;
>              rn = "Cause";
>              break;
>          default:
> @@ -6101,7 +6102,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>              gen_helper_mtc0_config0(cpu_env, arg);
>              rn = "Config";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          case 1:
>              /* ignored, read only */
> @@ -6111,24 +6112,24 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>              gen_helper_mtc0_config2(cpu_env, arg);
>              rn = "Config2";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          case 3:
>              gen_helper_mtc0_config3(cpu_env, arg);
>              rn = "Config3";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          case 4:
>              gen_helper_mtc0_config4(cpu_env, arg);
>              rn = "Config4";
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          case 5:
>              gen_helper_mtc0_config5(cpu_env, arg);
>              rn = "Config5";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          /* 6,7 are implementation dependent */
>          case 6:
> @@ -6218,34 +6219,34 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>          case 0:
>              gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
>              /* DISAS_STOP isn't good enough here, hflags may have changed. */
> -            gen_save_pc(ctx->pc + 4);
> -            ctx->is_jmp = DISAS_EXCP;
> +            gen_save_pc(ctx->base.pc_next + 4);
> +            ctx->base.is_jmp = DISAS_EXCP;
>              rn = "Debug";
>              break;
>          case 1:
>  //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support 
> */
>              rn = "TraceControl";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              goto cp0_unimplemented;
>          case 2:
>  //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace 
> support */
>              rn = "TraceControl2";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              goto cp0_unimplemented;
>          case 3:
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>  //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace 
> support */
>              rn = "UserTraceData";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              goto cp0_unimplemented;
>          case 4:
>  //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "TraceBPC";
>              goto cp0_unimplemented;
>          default:
> @@ -6305,7 +6306,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>          switch (sel) {
>          case 0:
>              gen_helper_mtc0_errctl(cpu_env, arg);
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "ErrCtl";
>              break;
>          default:
> @@ -6396,12 +6397,12 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>      trace_mips_translate_c0("mtc0", rn, reg, sel);
>  
>      /* For simplicity assume that all writes can cause interrupts.  */
> -    if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
>          gen_io_end();
>          /* DISAS_STOP isn't sufficient, we need to ensure we break out of
>           * translated code to check for pending interrupts.  */
> -        gen_save_pc(ctx->pc + 4);
> -        ctx->is_jmp = DISAS_EXCP;
> +        gen_save_pc(ctx->base.pc_next + 4);
> +        ctx->base.is_jmp = DISAS_EXCP;
>      }
>      return;
>  
> @@ -6674,18 +6675,18 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, 
> int reg, int sel)
>          switch (sel) {
>          case 0:
>              /* Mark as an IO operation because we read the time.  */
> -            if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
> +            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
>                  gen_io_start();
>              }
>              gen_helper_mfc0_count(arg, cpu_env);
> -            if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
> +            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
>                  gen_io_end();
>              }
>              /* Break the TB to be able to take timer interrupts immediately
>                 after reading count. DISAS_STOP isn't sufficient, we need to
>                 ensure we break completely out of translated code.  */
> -            gen_save_pc(ctx->pc + 4);
> -            ctx->is_jmp = DISAS_EXCP;
> +            gen_save_pc(ctx->base.pc_next + 4);
> +            ctx->base.is_jmp = DISAS_EXCP;
>              rn = "Count";
>              break;
>          /* 6,7 are implementation dependent */
> @@ -7067,7 +7068,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>      if (sel != 0)
>          check_insn(ctx, ISA_MIPS64);
>  
> -    if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
>          gen_io_start();
>      }
>  
> @@ -7297,7 +7298,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>          case 0:
>              check_insn(ctx, ISA_MIPS32R2);
>              gen_helper_mtc0_hwrena(cpu_env, arg);
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "HWREna";
>              break;
>          default:
> @@ -7333,7 +7334,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>              goto cp0_unimplemented;
>          }
>          /* Stop translation as we may have switched the execution mode */
> -        ctx->is_jmp = DISAS_STOP;
> +        ctx->base.is_jmp = DISAS_STOP;
>          break;
>      case 10:
>          switch (sel) {
> @@ -7356,7 +7357,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>              goto cp0_unimplemented;
>          }
>          /* Stop translation as we may have switched the execution mode */
> -        ctx->is_jmp = DISAS_STOP;
> +        ctx->base.is_jmp = DISAS_STOP;
>          break;
>      case 12:
>          switch (sel) {
> @@ -7364,29 +7365,29 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, 
> int reg, int sel)
>              save_cpu_state(ctx, 1);
>              gen_helper_mtc0_status(cpu_env, arg);
>              /* DISAS_STOP isn't good enough here, hflags may have changed. */
> -            gen_save_pc(ctx->pc + 4);
> -            ctx->is_jmp = DISAS_EXCP;
> +            gen_save_pc(ctx->base.pc_next + 4);
> +            ctx->base.is_jmp = DISAS_EXCP;
>              rn = "Status";
>              break;
>          case 1:
>              check_insn(ctx, ISA_MIPS32R2);
>              gen_helper_mtc0_intctl(cpu_env, arg);
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "IntCtl";
>              break;
>          case 2:
>              check_insn(ctx, ISA_MIPS32R2);
>              gen_helper_mtc0_srsctl(cpu_env, arg);
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "SRSCtl";
>              break;
>          case 3:
>              check_insn(ctx, ISA_MIPS32R2);
>              gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "SRSMap";
>              break;
>          default:
> @@ -7401,8 +7402,8 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>              /* Stop translation as we may have triggered an intetrupt.
>               * DISAS_STOP isn't sufficient, we need to ensure we break out of
>               * translated code to check for pending interrupts.  */
> -            gen_save_pc(ctx->pc + 4);
> -            ctx->is_jmp = DISAS_EXCP;
> +            gen_save_pc(ctx->base.pc_next + 4);
> +            ctx->base.is_jmp = DISAS_EXCP;
>              rn = "Cause";
>              break;
>          default:
> @@ -7440,7 +7441,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>              gen_helper_mtc0_config0(cpu_env, arg);
>              rn = "Config";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          case 1:
>              /* ignored, read only */
> @@ -7450,13 +7451,13 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, 
> int reg, int sel)
>              gen_helper_mtc0_config2(cpu_env, arg);
>              rn = "Config2";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          case 3:
>              gen_helper_mtc0_config3(cpu_env, arg);
>              rn = "Config3";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          case 4:
>              /* currently ignored */
> @@ -7466,7 +7467,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>              gen_helper_mtc0_config5(cpu_env, arg);
>              rn = "Config5";
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          /* 6,7 are implementation dependent */
>          default:
> @@ -7546,32 +7547,32 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, 
> int reg, int sel)
>          case 0:
>              gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
>              /* DISAS_STOP isn't good enough here, hflags may have changed. */
> -            gen_save_pc(ctx->pc + 4);
> -            ctx->is_jmp = DISAS_EXCP;
> +            gen_save_pc(ctx->base.pc_next + 4);
> +            ctx->base.is_jmp = DISAS_EXCP;
>              rn = "Debug";
>              break;
>          case 1:
>  //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support 
> */
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "TraceControl";
>              goto cp0_unimplemented;
>          case 2:
>  //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace 
> support */
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "TraceControl2";
>              goto cp0_unimplemented;
>          case 3:
>  //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace 
> support */
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "UserTraceData";
>              goto cp0_unimplemented;
>          case 4:
>  //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
>              /* Stop translation as we may have switched the execution mode */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "TraceBPC";
>              goto cp0_unimplemented;
>          default:
> @@ -7631,7 +7632,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>          switch (sel) {
>          case 0:
>              gen_helper_mtc0_errctl(cpu_env, arg);
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              rn = "ErrCtl";
>              break;
>          default:
> @@ -7722,12 +7723,12 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, 
> int reg, int sel)
>      trace_mips_translate_c0("dmtc0", rn, reg, sel);
>  
>      /* For simplicity assume that all writes can cause interrupts.  */
> -    if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
>          gen_io_end();
>          /* DISAS_STOP isn't sufficient, we need to ensure we break out of
>           * translated code to check for pending interrupts.  */
> -        gen_save_pc(ctx->pc + 4);
> -        ctx->is_jmp = DISAS_EXCP;
> +        gen_save_pc(ctx->base.pc_next + 4);
> +        ctx->base.is_jmp = DISAS_EXCP;
>      }
>      return;
>  
> @@ -8138,7 +8139,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext 
> *ctx, int rd, int rt,
>              tcg_temp_free_i32(fs_tmp);
>          }
>          /* Stop translation as we may have changed hflags */
> -        ctx->is_jmp = DISAS_STOP;
> +        ctx->base.is_jmp = DISAS_STOP;
>          break;
>      /* COP2: Not implemented. */
>      case 4:
> @@ -8297,7 +8298,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext 
> *ctx, uint32_t opc, int rt,
>                  check_insn(ctx, ISA_MIPS2);
>                  gen_helper_eret(cpu_env);
>              }
> -            ctx->is_jmp = DISAS_EXCP;
> +            ctx->base.is_jmp = DISAS_EXCP;
>          }
>          break;
>      case OPC_DERET:
> @@ -8312,7 +8313,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext 
> *ctx, uint32_t opc, int rt,
>              generate_exception_end(ctx, EXCP_RI);
>          } else {
>              gen_helper_deret(cpu_env);
> -            ctx->is_jmp = DISAS_EXCP;
> +            ctx->base.is_jmp = DISAS_EXCP;
>          }
>          break;
>      case OPC_WAIT:
> @@ -8323,11 +8324,11 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext 
> *ctx, uint32_t opc, int rt,
>              goto die;
>          }
>          /* If we get an exception, we want to restart at next instruction */
> -        ctx->pc += 4;
> +        ctx->base.pc_next += 4;
>          save_cpu_state(ctx, 1);
> -        ctx->pc -= 4;
> +        ctx->base.pc_next -= 4;
>          gen_helper_wait(cpu_env);
> -        ctx->is_jmp = DISAS_EXCP;
> +        ctx->base.is_jmp = DISAS_EXCP;
>          break;
>      default:
>   die:
> @@ -8354,7 +8355,7 @@ static void gen_compute_branch1(DisasContext *ctx, 
> uint32_t op,
>      if (cc != 0)
>          check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
>  
> -    btarget = ctx->pc + 4 + offset;
> +    btarget = ctx->base.pc_next + 4 + offset;
>  
>      switch (op) {
>      case OPC_BC1F:
> @@ -8457,7 +8458,7 @@ static void gen_compute_branch1_r6(DisasContext *ctx, 
> uint32_t op,
>      if (ctx->hflags & MIPS_HFLAG_BMASK) {
>  #ifdef MIPS_DEBUG_DISAS
>          LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
> -                  "\n", ctx->pc);
> +                  "\n", ctx->base.pc_next);
>  #endif
>          generate_exception_end(ctx, EXCP_RI);
>          goto out;
> @@ -8466,7 +8467,7 @@ static void gen_compute_branch1_r6(DisasContext *ctx, 
> uint32_t op,
>      gen_load_fpr64(ctx, t0, ft);
>      tcg_gen_andi_i64(t0, t0, 1);
>  
> -    btarget = addr_add(ctx, ctx->pc + 4, offset);
> +    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
>  
>      switch (op) {
>      case OPC_BC1EQZ:
> @@ -8752,7 +8753,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, 
> int rt, int fs)
>              tcg_temp_free_i32(fs_tmp);
>          }
>          /* Stop translation as we may have changed hflags */
> -        ctx->is_jmp = DISAS_STOP;
> +        ctx->base.is_jmp = DISAS_STOP;
>          break;
>  #if defined(TARGET_MIPS64)
>      case OPC_DMFC1:
> @@ -10751,19 +10752,19 @@ static void gen_rdhwr(DisasContext *ctx, int rt, 
> int rd, int sel)
>          gen_store_gpr(t0, rt);
>          break;
>      case 2:
> -        if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
> +        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
>              gen_io_start();
>          }
>          gen_helper_rdhwr_cc(t0, cpu_env);
> -        if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
> +        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
>              gen_io_end();
>          }
>          gen_store_gpr(t0, rt);
>          /* Break the TB to be able to take timer interrupts immediately
>             after reading count. DISAS_STOP isn't sufficient, we need to 
> ensure
>             we break completely out of translated code.  */
> -        gen_save_pc(ctx->pc + 4);
> -        ctx->is_jmp = DISAS_EXCP;
> +        gen_save_pc(ctx->base.pc_next + 4);
> +        ctx->base.is_jmp = DISAS_EXCP;
>          break;
>      case 3:
>          gen_helper_rdhwr_ccres(t0, cpu_env);
> @@ -10813,7 +10814,7 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int 
> rd, int sel)
>  static inline void clear_branch_hflags(DisasContext *ctx)
>  {
>      ctx->hflags &= ~MIPS_HFLAG_BMASK;
> -    if (ctx->is_jmp == DISAS_NEXT) {
> +    if (ctx->base.is_jmp == DISAS_NEXT) {
>          save_cpu_state(ctx, 0);
>      } else {
>          /* it is not safe to save ctx->hflags as hflags may be changed
> @@ -10828,11 +10829,11 @@ static void gen_branch(DisasContext *ctx, int 
> insn_bytes)
>          int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
>          /* Branches completion */
>          clear_branch_hflags(ctx);
> -        ctx->is_jmp = DISAS_NORETURN;
> +        ctx->base.is_jmp = DISAS_NORETURN;
>          /* FIXME: Need to clear can_do_io.  */
>          switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
>          case MIPS_HFLAG_FBNSLOT:
> -            gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
> +            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
>              break;
>          case MIPS_HFLAG_B:
>              /* unconditional branch */
> @@ -10851,7 +10852,7 @@ static void gen_branch(DisasContext *ctx, int 
> insn_bytes)
>                  TCGLabel *l1 = gen_new_label();
>  
>                  tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
> -                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
> +                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
>                  gen_set_label(l1);
>                  gen_goto_tb(ctx, 0, ctx->btarget);
>              }
> @@ -10874,7 +10875,7 @@ static void gen_branch(DisasContext *ctx, int 
> insn_bytes)
>              } else {
>                  tcg_gen_mov_tl(cpu_PC, btarget);
>              }
> -            if (ctx->singlestep_enabled) {
> +            if (ctx->base.singlestep_enabled) {
>                  save_cpu_state(ctx, 0);
>                  gen_helper_raise_exception_debug(cpu_env);
>              }
> @@ -10899,7 +10900,7 @@ static void gen_compute_compact_branch(DisasContext 
> *ctx, uint32_t opc,
>      if (ctx->hflags & MIPS_HFLAG_BMASK) {
>  #ifdef MIPS_DEBUG_DISAS
>          LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
> -                  "\n", ctx->pc);
> +                  "\n", ctx->base.pc_next);
>  #endif
>          generate_exception_end(ctx, EXCP_RI);
>          goto out;
> @@ -10913,10 +10914,10 @@ static void gen_compute_compact_branch(DisasContext 
> *ctx, uint32_t opc,
>          gen_load_gpr(t0, rs);
>          gen_load_gpr(t1, rt);
>          bcond_compute = 1;
> -        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
> +        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
>          if (rs <= rt && rs == 0) {
>              /* OPC_BEQZALC, OPC_BNEZALC */
> -            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
> +            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
>          }
>          break;
>      case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
> @@ -10924,23 +10925,23 @@ static void gen_compute_compact_branch(DisasContext 
> *ctx, uint32_t opc,
>          gen_load_gpr(t0, rs);
>          gen_load_gpr(t1, rt);
>          bcond_compute = 1;
> -        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
> +        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
>          break;
>      case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
>      case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
>          if (rs == 0 || rs == rt) {
>              /* OPC_BLEZALC, OPC_BGEZALC */
>              /* OPC_BGTZALC, OPC_BLTZALC */
> -            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
> +            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
>          }
>          gen_load_gpr(t0, rs);
>          gen_load_gpr(t1, rt);
>          bcond_compute = 1;
> -        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
> +        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
>          break;
>      case OPC_BC:
>      case OPC_BALC:
> -        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
> +        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
>          break;
>      case OPC_BEQZC:
>      case OPC_BNEZC:
> @@ -10948,7 +10949,7 @@ static void gen_compute_compact_branch(DisasContext 
> *ctx, uint32_t opc,
>              /* OPC_BEQZC, OPC_BNEZC */
>              gen_load_gpr(t0, rs);
>              bcond_compute = 1;
> -            ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
> +            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
>          } else {
>              /* OPC_JIC, OPC_JIALC */
>              TCGv tbase = tcg_temp_new();
> @@ -10971,13 +10972,13 @@ static void gen_compute_compact_branch(DisasContext 
> *ctx, uint32_t opc,
>          /* Uncoditional compact branch */
>          switch (opc) {
>          case OPC_JIALC:
> -            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
> +            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
>              /* Fallthrough */
>          case OPC_JIC:
>              ctx->hflags |= MIPS_HFLAG_BR;
>              break;
>          case OPC_BALC:
> -            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
> +            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
>              /* Fallthrough */
>          case OPC_BC:
>              ctx->hflags |= MIPS_HFLAG_B;
> @@ -11602,7 +11603,7 @@ static void decode_i64_mips16 (DisasContext *ctx,
>  
>  static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
>  {
> -    int extend = cpu_lduw_code(env, ctx->pc + 2);
> +    int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
>      int op, rx, ry, funct, sa;
>      int16_t imm, offset;
>  
> @@ -11842,7 +11843,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>          /* No delay slot, so just process as a normal instruction */
>          break;
>      case M16_OPC_JAL:
> -        offset = cpu_lduw_code(env, ctx->pc + 2);
> +        offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
>          offset = (((ctx->opcode & 0x1f) << 21)
>                    | ((ctx->opcode >> 5) & 0x1f) << 16
>                    | offset) << 2;
> @@ -13570,7 +13571,7 @@ static void gen_pool32axf (CPUMIPSState *env, 
> DisasContext *ctx, int rt, int rs)
>                  gen_helper_di(t0, cpu_env);
>                  gen_store_gpr(t0, rs);
>                  /* Stop translation as we may have switched the execution 
> mode */
> -                ctx->is_jmp = DISAS_STOP;
> +                ctx->base.is_jmp = DISAS_STOP;
>                  tcg_temp_free(t0);
>              }
>              break;
> @@ -13584,8 +13585,8 @@ static void gen_pool32axf (CPUMIPSState *env, 
> DisasContext *ctx, int rt, int rs)
>                  gen_store_gpr(t0, rs);
>                  /* DISAS_STOP isn't sufficient, we need to ensure we break 
> out
>                     of translated code to check for pending interrupts.  */
> -                gen_save_pc(ctx->pc + 4);
> -                ctx->is_jmp = DISAS_EXCP;
> +                gen_save_pc(ctx->base.pc_next + 4);
> +                ctx->base.is_jmp = DISAS_EXCP;
>                  tcg_temp_free(t0);
>              }
>              break;
> @@ -13940,7 +13941,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>      uint32_t op, minor, minor2, mips32_op;
>      uint32_t cond, fmt, cc;
>  
> -    insn = cpu_lduw_code(env, ctx->pc + 2);
> +    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
>      ctx->opcode = (ctx->opcode << 16) | insn;
>  
>      rt = (ctx->opcode >> 21) & 0x1f;
> @@ -14741,7 +14742,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>                  /* SYNCI */
>                  /* Break the TB to be able to sync copied instructions
>                     immediately */
> -                ctx->is_jmp = DISAS_STOP;
> +                ctx->base.is_jmp = DISAS_STOP;
>              } else {
>                  /* TNEI */
>                  mips32_op = OPC_TNEI;
> @@ -14772,7 +14773,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>              check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              /* Break the TB to be able to sync copied instructions
>                 immediately */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          case BC2F:
>          case BC2T:
> @@ -15135,16 +15136,16 @@ static void decode_micromips32_opc(CPUMIPSState 
> *env, DisasContext *ctx)
>              /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
>              switch ((ctx->opcode >> 16) & 0x1f) {
>              case ADDIUPC_00 ... ADDIUPC_07:
> -                gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
> +                gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
>                  break;
>              case AUIPC:
> -                gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
> +                gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
>                  break;
>              case ALUIPC:
> -                gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
> +                gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
>                  break;
>              case LWPC_08 ... LWPC_0F:
> -                gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
> +                gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
>                  break;
>              default:
>                  generate_exception(ctx, EXCP_RI);
> @@ -15276,8 +15277,8 @@ static int decode_micromips_opc (CPUMIPSState *env, 
> DisasContext *ctx)
>      uint32_t op;
>  
>      /* make sure instructions are on a halfword boundary */
> -    if (ctx->pc & 0x1) {
> -        env->CP0_BadVAddr = ctx->pc;
> +    if (ctx->base.pc_next & 0x1) {
> +        env->CP0_BadVAddr = ctx->base.pc_next;
>          generate_exception_end(ctx, EXCP_AdEL);
>          return 2;
>      }
> @@ -18503,7 +18504,7 @@ static void gen_msa_branch(CPUMIPSState *env, 
> DisasContext *ctx, uint32_t op1)
>          break;
>      }
>  
> -    ctx->btarget = ctx->pc + (s16 << 2) + 4;
> +    ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
>  
>      ctx->hflags |= MIPS_HFLAG_BC;
>      ctx->hflags |= MIPS_HFLAG_BDS32;
> @@ -19524,8 +19525,8 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>      int16_t imm;
>  
>      /* make sure instructions are on a word boundary */
> -    if (ctx->pc & 0x3) {
> -        env->CP0_BadVAddr = ctx->pc;
> +    if (ctx->base.pc_next & 0x3) {
> +        env->CP0_BadVAddr = ctx->base.pc_next;
>          generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
>          return;
>      }
> @@ -19536,7 +19537,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>  
>          tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
>          tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
> -        gen_goto_tb(ctx, 1, ctx->pc + 4);
> +        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
>          gen_set_label(l1);
>      }
>  
> @@ -19597,7 +19598,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>              check_insn(ctx, ISA_MIPS32R2);
>              /* Break the TB to be able to sync copied instructions
>                 immediately */
> -            ctx->is_jmp = DISAS_STOP;
> +            ctx->base.is_jmp = DISAS_STOP;
>              break;
>          case OPC_BPOSGE32:    /* MIPS DSP branch */
>  #if defined(TARGET_MIPS64)
> @@ -19700,7 +19701,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>                      gen_store_gpr(t0, rt);
>                      /* Stop translation as we may have switched
>                         the execution mode.  */
> -                    ctx->is_jmp = DISAS_STOP;
> +                    ctx->base.is_jmp = DISAS_STOP;
>                      break;
>                  case OPC_EI:
>                      check_insn(ctx, ISA_MIPS32R2);
> @@ -19709,8 +19710,8 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>                      gen_store_gpr(t0, rt);
>                      /* DISAS_STOP isn't sufficient, we need to ensure we 
> break
>                         out of translated code to check for pending 
> interrupts */
> -                    gen_save_pc(ctx->pc + 4);
> -                    ctx->is_jmp = DISAS_EXCP;
> +                    gen_save_pc(ctx->base.pc_next + 4);
> +                    ctx->base.is_jmp = DISAS_EXCP;
>                      break;
>                  default:            /* Invalid */
>                      MIPS_INVAL("mfmc0");
> @@ -20184,7 +20185,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>          break;
>      case OPC_PCREL:
>          check_insn(ctx, ISA_MIPS32R6);
> -        gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
> +        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
>          break;
>      default:            /* Invalid */
>          MIPS_INVAL("major opcode");
> @@ -20197,22 +20198,22 @@ void gen_intermediate_code(CPUState *cs, struct 
> TranslationBlock *tb)
>  {
>      CPUMIPSState *env = cs->env_ptr;
>      DisasContext ctx;
> -    target_ulong pc_start;
>      target_ulong next_page_start;
> -    int num_insns;
>      int max_insns;
>      int insn_bytes;
>      int is_slot;
>  
> -    pc_start = tb->pc;
> -    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
> -    ctx.pc = pc_start;
> +    ctx.base.tb = tb;
> +    ctx.base.pc_first = tb->pc;
> +    ctx.base.pc_next = tb->pc;
> +    ctx.base.is_jmp = DISAS_NEXT;
> +    ctx.base.singlestep_enabled = cs->singlestep_enabled;
> +    ctx.base.num_insns = 0;
> +
> +    next_page_start = (ctx.base.pc_first & TARGET_PAGE_MASK) + 
> TARGET_PAGE_SIZE;
>      ctx.saved_pc = -1;
> -    ctx.singlestep_enabled = cs->singlestep_enabled;
>      ctx.insn_flags = env->insn_flags;
>      ctx.CP0_Config1 = env->CP0_Config1;
> -    ctx.tb = tb;
> -    ctx.is_jmp = DISAS_NEXT;
>      ctx.btarget = 0;
>      ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
>      ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
> @@ -20226,7 +20227,7 @@ void gen_intermediate_code(CPUState *cs, struct 
> TranslationBlock *tb)
>      ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
>      ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
>      /* Restore delay slot state from the tb context.  */
> -    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
> +    ctx.hflags = (uint32_t)ctx.base.tb->flags; /* FIXME: maybe use 64 bits? 
> */
>      ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
>      ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
>               (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
> @@ -20242,7 +20243,6 @@ void gen_intermediate_code(CPUState *cs, struct 
> TranslationBlock *tb)
>  #endif
>      ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
>                                   MO_UNALN : MO_ALIGN;
> -    num_insns = 0;
>      max_insns = tb_cflags(tb) & CF_COUNT_MASK;
>      if (max_insns == 0) {
>          max_insns = CF_COUNT_MASK;
> @@ -20253,36 +20253,37 @@ void gen_intermediate_code(CPUState *cs, struct 
> TranslationBlock *tb)
>  
>      LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
>      gen_tb_start(tb);
> -    while (ctx.is_jmp == DISAS_NEXT) {
> -        tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, 
> ctx.btarget);
> -        num_insns++;
> +    while (ctx.base.is_jmp == DISAS_NEXT) {
> +        tcg_gen_insn_start(ctx.base.pc_next, ctx.hflags & MIPS_HFLAG_BMASK,
> +                           ctx.btarget);
> +        ctx.base.num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cs, ctx.base.pc_next, BP_ANY))) {
>              save_cpu_state(&ctx, 1);
> -            ctx.is_jmp = DISAS_NORETURN;
> +            ctx.base.is_jmp = DISAS_NORETURN;
>              gen_helper_raise_exception_debug(cpu_env);
>              /* The address covered by the breakpoint must be included in
>                 [tb->pc, tb->pc + tb->size) in order to for it to be
>                 properly cleared -- thus we increment the PC here so that
>                 the logic setting tb->size below does the right thing.  */
> -            ctx.pc += 4;
> +            ctx.base.pc_next += 4;
>              goto done_generating;
>          }
>  
> -        if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
> +        if (ctx.base.num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) 
> {
>              gen_io_start();
>          }
>  
>          is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
>          if (!(ctx.hflags & MIPS_HFLAG_M16)) {
> -            ctx.opcode = cpu_ldl_code(env, ctx.pc);
> +            ctx.opcode = cpu_ldl_code(env, ctx.base.pc_next);
>              insn_bytes = 4;
>              decode_opc(env, &ctx);
>          } else if (ctx.insn_flags & ASE_MICROMIPS) {
> -            ctx.opcode = cpu_lduw_code(env, ctx.pc);
> +            ctx.opcode = cpu_lduw_code(env, ctx.base.pc_next);
>              insn_bytes = decode_micromips_opc(env, &ctx);
>          } else if (ctx.insn_flags & ASE_MIPS16) {
> -            ctx.opcode = cpu_lduw_code(env, ctx.pc);
> +            ctx.opcode = cpu_lduw_code(env, ctx.base.pc_next);
>              insn_bytes = decode_mips16_opc(env, &ctx);
>          } else {
>              generate_exception_end(&ctx, EXCP_RI);
> @@ -20306,17 +20307,18 @@ void gen_intermediate_code(CPUState *cs, struct 
> TranslationBlock *tb)
>          if (is_slot) {
>              gen_branch(&ctx, insn_bytes);
>          }
> -        ctx.pc += insn_bytes;
> +        ctx.base.pc_next += insn_bytes;
>  
>          /* Execute a branch and its delay slot as a single instruction.
>             This is what GDB expects and is consistent with what the
>             hardware does (e.g. if a delay slot instruction faults, the
>             reported PC is the PC of the branch).  */
> -        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
> +        if (ctx.base.singlestep_enabled &&
> +            (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
>              break;
>          }
>  
> -        if (ctx.pc >= next_page_start) {
> +        if (ctx.base.pc_next >= next_page_start) {
>              break;
>          }
>  
> @@ -20324,8 +20326,9 @@ void gen_intermediate_code(CPUState *cs, struct 
> TranslationBlock *tb)
>              break;
>          }
>  
> -        if (num_insns >= max_insns)
> +        if (ctx.base.num_insns >= max_insns) {
>              break;
> +        }
>  
>          if (singlestep)
>              break;
> @@ -20333,17 +20336,17 @@ void gen_intermediate_code(CPUState *cs, struct 
> TranslationBlock *tb)
>      if (tb_cflags(tb) & CF_LAST_IO) {
>          gen_io_end();
>      }
> -    if (cs->singlestep_enabled && ctx.is_jmp != DISAS_NORETURN) {
> -        save_cpu_state(&ctx, ctx.is_jmp != DISAS_EXCP);
> +    if (ctx.base.singlestep_enabled && ctx.base.is_jmp != DISAS_NORETURN) {
> +        save_cpu_state(&ctx, ctx.base.is_jmp != DISAS_EXCP);
>          gen_helper_raise_exception_debug(cpu_env);
>      } else {
> -        switch (ctx.is_jmp) {
> +        switch (ctx.base.is_jmp) {
>          case DISAS_STOP:
> -            gen_goto_tb(&ctx, 0, ctx.pc);
> +            gen_goto_tb(&ctx, 0, ctx.base.pc_next);
>              break;
>          case DISAS_NEXT:
>              save_cpu_state(&ctx, 0);
> -            gen_goto_tb(&ctx, 0, ctx.pc);
> +            gen_goto_tb(&ctx, 0, ctx.base.pc_next);
>              break;
>          case DISAS_EXCP:
>              tcg_gen_exit_tb(0);
> @@ -20354,18 +20357,19 @@ void gen_intermediate_code(CPUState *cs, struct 
> TranslationBlock *tb)
>          }
>      }
>  done_generating:
> -    gen_tb_end(tb, num_insns);
> +    gen_tb_end(tb, ctx.base.num_insns);
>  
> -    tb->size = ctx.pc - pc_start;
> -    tb->icount = num_insns;
> +    tb->size = ctx.base.pc_next - ctx.base.pc_first;
> +    tb->icount = ctx.base.num_insns;
>  
>  #ifdef DEBUG_DISAS
>      LOG_DISAS("\n");
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
> -        && qemu_log_in_addr_range(pc_start)) {
> +        && qemu_log_in_addr_range(ctx.base.pc_first)) {
>          qemu_log_lock();
> -        qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, ctx.pc - pc_start);
> +        qemu_log("IN: %s\n", lookup_symbol(ctx.base.pc_first));
> +        log_target_disas(cs, ctx.base.pc_first,
> +                         ctx.base.pc_next - ctx.base.pc_first);
>          qemu_log("\n");
>          qemu_log_unlock();
>      }
> 



reply via email to

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