diff mbox

[2/9] target-mips: Prepare loads/stores for EVA

Message ID d45c604ed17bce936767871b91e07a94960d2b54.1473159543.git-series.james.hogan@imgtec.com (mailing list archive)
State New, archived
Headers show

Commit Message

James Hogan Sept. 6, 2016, 11:03 a.m. UTC
EVA load and store instructions access the user mode address map, so
they need to use mem_idx of MIPS_HFLAG_UM. Update the various utility
functions to allow mem_idx to be more easily overridden from the
decoding logic.

Specifically we add a mem_idx argument to the op_ld/st_* helpers used
for atomics, and a mem_idx local variable to gen_ld(), gen_st(), and
gen_st_cond().

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Leon Alrae <leon.alrae@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/translate.c | 77 ++++++++++++++++++++++--------------------
 1 file changed, 42 insertions(+), 35 deletions(-)

Comments

Yongbok Kim Oct. 7, 2016, 3:32 p.m. UTC | #1
On 06/09/2016 12:03, James Hogan wrote:
> EVA load and store instructions access the user mode address map, so
> they need to use mem_idx of MIPS_HFLAG_UM. Update the various utility
> functions to allow mem_idx to be more easily overridden from the
> decoding logic.
> 
> Specifically we add a mem_idx argument to the op_ld/st_* helpers used
> for atomics, and a mem_idx local variable to gen_ld(), gen_st(), and
> gen_st_cond().
> 
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Leon Alrae <leon.alrae@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  target-mips/translate.c | 77 ++++++++++++++++++++++--------------------
>  1 file changed, 42 insertions(+), 35 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index e224c2f09af4..df2befbd5294 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -2028,7 +2028,8 @@ FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
>  /* load/store instructions. */
>  #ifdef CONFIG_USER_ONLY
>  #define OP_LD_ATOMIC(insn,fname)                                           \
> -static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
> +static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
> +                                DisasContext *ctx)                         \
>  {                                                                          \
>      TCGv t0 = tcg_temp_new();                                              \
>      tcg_gen_mov_tl(t0, arg1);                                              \
> @@ -2039,9 +2040,10 @@ static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
>  }
>  #else
>  #define OP_LD_ATOMIC(insn,fname)                                           \
> -static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
> +static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
> +                                DisasContext *ctx)                         \
>  {                                                                          \
> -    gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx);                        \
> +    gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
>  }
>  #endif
>  OP_LD_ATOMIC(ll,ld32s);
> @@ -2052,7 +2054,8 @@ OP_LD_ATOMIC(lld,ld64);
>  
>  #ifdef CONFIG_USER_ONLY
>  #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
> -static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
> +static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
> +                                DisasContext *ctx)                           \
>  {                                                                            \
>      TCGv t0 = tcg_temp_new();                                                \
>      TCGLabel *l1 = gen_new_label();                                          \
> @@ -2076,10 +2079,11 @@ static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx)
>  }
>  #else
>  #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
> -static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
> +static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
> +                                DisasContext *ctx)                           \
>  {                                                                            \
>      TCGv t0 = tcg_temp_new();                                                \
> -    gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx);                     \
> +    gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
>      gen_store_gpr(t0, rt);                                                   \
>      tcg_temp_free(t0);                                                       \
>  }
> @@ -2122,6 +2126,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
>                     int rt, int base, int16_t offset)
>  {
>      TCGv t0, t1, t2;
> +    int mem_idx = ctx->mem_idx;
>  
>      if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
>          /* Loongson CPU uses a load to zero register for prefetch.
> @@ -2136,32 +2141,32 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
>      switch (opc) {
>  #if defined(TARGET_MIPS64)
>      case OPC_LWU:
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
>                             ctx->default_tcg_memop_mask);
>          gen_store_gpr(t0, rt);
>          break;
>      case OPC_LD:
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
>                             ctx->default_tcg_memop_mask);
>          gen_store_gpr(t0, rt);
>          break;
>      case OPC_LLD:
>      case R6_OPC_LLD:
> -        op_ld_lld(t0, t0, ctx);
> +        op_ld_lld(t0, t0, mem_idx, ctx);
>          gen_store_gpr(t0, rt);
>          break;
>      case OPC_LDL:
>          t1 = tcg_temp_new();
>          /* Do a byte access to possibly trigger a page
>             fault with the unaligned address.  */
> -        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
> +        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
>          tcg_gen_andi_tl(t1, t0, 7);
>  #ifndef TARGET_WORDS_BIGENDIAN
>          tcg_gen_xori_tl(t1, t1, 7);
>  #endif
>          tcg_gen_shli_tl(t1, t1, 3);
>          tcg_gen_andi_tl(t0, t0, ~7);
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
>          tcg_gen_shl_tl(t0, t0, t1);
>          t2 = tcg_const_tl(-1);
>          tcg_gen_shl_tl(t2, t2, t1);
> @@ -2176,14 +2181,14 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
>          t1 = tcg_temp_new();
>          /* Do a byte access to possibly trigger a page
>             fault with the unaligned address.  */
> -        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
> +        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
>          tcg_gen_andi_tl(t1, t0, 7);
>  #ifdef TARGET_WORDS_BIGENDIAN
>          tcg_gen_xori_tl(t1, t1, 7);
>  #endif
>          tcg_gen_shli_tl(t1, t1, 3);
>          tcg_gen_andi_tl(t0, t0, ~7);
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
>          tcg_gen_shr_tl(t0, t0, t1);
>          tcg_gen_xori_tl(t1, t1, 63);
>          t2 = tcg_const_tl(0xfffffffffffffffeull);
> @@ -2199,7 +2204,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
>          t1 = tcg_const_tl(pc_relative_pc(ctx));
>          gen_op_addr_add(ctx, t0, t0, t1);
>          tcg_temp_free(t1);
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
>          gen_store_gpr(t0, rt);
>          break;
>  #endif
> @@ -2207,44 +2212,44 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
>          t1 = tcg_const_tl(pc_relative_pc(ctx));
>          gen_op_addr_add(ctx, t0, t0, t1);
>          tcg_temp_free(t1);
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
>          gen_store_gpr(t0, rt);
>          break;
>      case OPC_LW:
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
>                             ctx->default_tcg_memop_mask);
>          gen_store_gpr(t0, rt);
>          break;
>      case OPC_LH:
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
>                             ctx->default_tcg_memop_mask);
>          gen_store_gpr(t0, rt);
>          break;
>      case OPC_LHU:
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
>                             ctx->default_tcg_memop_mask);
>          gen_store_gpr(t0, rt);
>          break;
>      case OPC_LB:
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
>          gen_store_gpr(t0, rt);
>          break;
>      case OPC_LBU:
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
>          gen_store_gpr(t0, rt);
>          break;
>      case OPC_LWL:
>          t1 = tcg_temp_new();
>          /* Do a byte access to possibly trigger a page
>             fault with the unaligned address.  */
> -        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
> +        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
>          tcg_gen_andi_tl(t1, t0, 3);
>  #ifndef TARGET_WORDS_BIGENDIAN
>          tcg_gen_xori_tl(t1, t1, 3);
>  #endif
>          tcg_gen_shli_tl(t1, t1, 3);
>          tcg_gen_andi_tl(t0, t0, ~3);
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
>          tcg_gen_shl_tl(t0, t0, t1);
>          t2 = tcg_const_tl(-1);
>          tcg_gen_shl_tl(t2, t2, t1);
> @@ -2260,14 +2265,14 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
>          t1 = tcg_temp_new();
>          /* Do a byte access to possibly trigger a page
>             fault with the unaligned address.  */
> -        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
> +        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
>          tcg_gen_andi_tl(t1, t0, 3);
>  #ifdef TARGET_WORDS_BIGENDIAN
>          tcg_gen_xori_tl(t1, t1, 3);
>  #endif
>          tcg_gen_shli_tl(t1, t1, 3);
>          tcg_gen_andi_tl(t0, t0, ~3);
> -        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
> +        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
>          tcg_gen_shr_tl(t0, t0, t1);
>          tcg_gen_xori_tl(t1, t1, 31);
>          t2 = tcg_const_tl(0xfffffffeull);
> @@ -2282,7 +2287,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
>          break;
>      case OPC_LL:
>      case R6_OPC_LL:
> -        op_ld_ll(t0, t0, ctx);
> +        op_ld_ll(t0, t0, mem_idx, ctx);
>          gen_store_gpr(t0, rt);
>          break;
>      }
> @@ -2295,38 +2300,39 @@ static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
>  {
>      TCGv t0 = tcg_temp_new();
>      TCGv t1 = tcg_temp_new();
> +    int mem_idx = ctx->mem_idx;
>  
>      gen_base_offset_addr(ctx, t0, base, offset);
>      gen_load_gpr(t1, rt);
>      switch (opc) {
>  #if defined(TARGET_MIPS64)
>      case OPC_SD:
> -        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
> +        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
>                             ctx->default_tcg_memop_mask);
>          break;
>      case OPC_SDL:
> -        gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
> +        gen_helper_0e2i(sdl, t1, t0, mem_idx);
>          break;
>      case OPC_SDR:
> -        gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
> +        gen_helper_0e2i(sdr, t1, t0, mem_idx);
>          break;
>  #endif
>      case OPC_SW:
> -        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
> +        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
>                             ctx->default_tcg_memop_mask);
>          break;
>      case OPC_SH:
> -        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
> +        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
>                             ctx->default_tcg_memop_mask);
>          break;
>      case OPC_SB:
> -        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
> +        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
>          break;
>      case OPC_SWL:
> -        gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
> +        gen_helper_0e2i(swl, t1, t0, mem_idx);
>          break;
>      case OPC_SWR:
> -        gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
> +        gen_helper_0e2i(swr, t1, t0, mem_idx);
>          break;
>      }
>      tcg_temp_free(t0);
> @@ -2339,6 +2345,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
>                           int base, int16_t offset)
>  {
>      TCGv t0, t1;
> +    int mem_idx = ctx->mem_idx;
>  
>  #ifdef CONFIG_USER_ONLY
>      t0 = tcg_temp_local_new();
> @@ -2353,12 +2360,12 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
>  #if defined(TARGET_MIPS64)
>      case OPC_SCD:
>      case R6_OPC_SCD:
> -        op_st_scd(t1, t0, rt, ctx);
> +        op_st_scd(t1, t0, rt, mem_idx, ctx);
>          break;
>  #endif
>      case OPC_SC:
>      case R6_OPC_SC:
> -        op_st_sc(t1, t0, rt, ctx);
> +        op_st_sc(t1, t0, rt, mem_idx, ctx);
>          break;
>      }
>      tcg_temp_free(t1);
> 

Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>

Regards,
Yongbok
diff mbox

Patch

diff --git a/target-mips/translate.c b/target-mips/translate.c
index e224c2f09af4..df2befbd5294 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2028,7 +2028,8 @@  FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
 /* load/store instructions. */
 #ifdef CONFIG_USER_ONLY
 #define OP_LD_ATOMIC(insn,fname)                                           \
-static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
+static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
+                                DisasContext *ctx)                         \
 {                                                                          \
     TCGv t0 = tcg_temp_new();                                              \
     tcg_gen_mov_tl(t0, arg1);                                              \
@@ -2039,9 +2040,10 @@  static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
 }
 #else
 #define OP_LD_ATOMIC(insn,fname)                                           \
-static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
+static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
+                                DisasContext *ctx)                         \
 {                                                                          \
-    gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx);                        \
+    gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
 }
 #endif
 OP_LD_ATOMIC(ll,ld32s);
@@ -2052,7 +2054,8 @@  OP_LD_ATOMIC(lld,ld64);
 
 #ifdef CONFIG_USER_ONLY
 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
-static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
+static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
+                                DisasContext *ctx)                           \
 {                                                                            \
     TCGv t0 = tcg_temp_new();                                                \
     TCGLabel *l1 = gen_new_label();                                          \
@@ -2076,10 +2079,11 @@  static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx)
 }
 #else
 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
-static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
+static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
+                                DisasContext *ctx)                           \
 {                                                                            \
     TCGv t0 = tcg_temp_new();                                                \
-    gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx);                     \
+    gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
     gen_store_gpr(t0, rt);                                                   \
     tcg_temp_free(t0);                                                       \
 }
@@ -2122,6 +2126,7 @@  static void gen_ld(DisasContext *ctx, uint32_t opc,
                    int rt, int base, int16_t offset)
 {
     TCGv t0, t1, t2;
+    int mem_idx = ctx->mem_idx;
 
     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
         /* Loongson CPU uses a load to zero register for prefetch.
@@ -2136,32 +2141,32 @@  static void gen_ld(DisasContext *ctx, uint32_t opc,
     switch (opc) {
 #if defined(TARGET_MIPS64)
     case OPC_LWU:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LD:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LLD:
     case R6_OPC_LLD:
-        op_ld_lld(t0, t0, ctx);
+        op_ld_lld(t0, t0, mem_idx, ctx);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LDL:
         t1 = tcg_temp_new();
         /* Do a byte access to possibly trigger a page
            fault with the unaligned address.  */
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 7);
 #ifndef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 7);
 #endif
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~7);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
         tcg_gen_shl_tl(t0, t0, t1);
         t2 = tcg_const_tl(-1);
         tcg_gen_shl_tl(t2, t2, t1);
@@ -2176,14 +2181,14 @@  static void gen_ld(DisasContext *ctx, uint32_t opc,
         t1 = tcg_temp_new();
         /* Do a byte access to possibly trigger a page
            fault with the unaligned address.  */
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 7);
 #ifdef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 7);
 #endif
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~7);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
         tcg_gen_shr_tl(t0, t0, t1);
         tcg_gen_xori_tl(t1, t1, 63);
         t2 = tcg_const_tl(0xfffffffffffffffeull);
@@ -2199,7 +2204,7 @@  static void gen_ld(DisasContext *ctx, uint32_t opc,
         t1 = tcg_const_tl(pc_relative_pc(ctx));
         gen_op_addr_add(ctx, t0, t0, t1);
         tcg_temp_free(t1);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
         gen_store_gpr(t0, rt);
         break;
 #endif
@@ -2207,44 +2212,44 @@  static void gen_ld(DisasContext *ctx, uint32_t opc,
         t1 = tcg_const_tl(pc_relative_pc(ctx));
         gen_op_addr_add(ctx, t0, t0, t1);
         tcg_temp_free(t1);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LW:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LH:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LHU:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LB:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LBU:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LWL:
         t1 = tcg_temp_new();
         /* Do a byte access to possibly trigger a page
            fault with the unaligned address.  */
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 3);
 #ifndef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 3);
 #endif
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~3);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
         tcg_gen_shl_tl(t0, t0, t1);
         t2 = tcg_const_tl(-1);
         tcg_gen_shl_tl(t2, t2, t1);
@@ -2260,14 +2265,14 @@  static void gen_ld(DisasContext *ctx, uint32_t opc,
         t1 = tcg_temp_new();
         /* Do a byte access to possibly trigger a page
            fault with the unaligned address.  */
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 3);
 #ifdef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 3);
 #endif
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~3);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
         tcg_gen_shr_tl(t0, t0, t1);
         tcg_gen_xori_tl(t1, t1, 31);
         t2 = tcg_const_tl(0xfffffffeull);
@@ -2282,7 +2287,7 @@  static void gen_ld(DisasContext *ctx, uint32_t opc,
         break;
     case OPC_LL:
     case R6_OPC_LL:
-        op_ld_ll(t0, t0, ctx);
+        op_ld_ll(t0, t0, mem_idx, ctx);
         gen_store_gpr(t0, rt);
         break;
     }
@@ -2295,38 +2300,39 @@  static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
 {
     TCGv t0 = tcg_temp_new();
     TCGv t1 = tcg_temp_new();
+    int mem_idx = ctx->mem_idx;
 
     gen_base_offset_addr(ctx, t0, base, offset);
     gen_load_gpr(t1, rt);
     switch (opc) {
 #if defined(TARGET_MIPS64)
     case OPC_SD:
-        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
+        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
                            ctx->default_tcg_memop_mask);
         break;
     case OPC_SDL:
-        gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
+        gen_helper_0e2i(sdl, t1, t0, mem_idx);
         break;
     case OPC_SDR:
-        gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
+        gen_helper_0e2i(sdr, t1, t0, mem_idx);
         break;
 #endif
     case OPC_SW:
-        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
+        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
                            ctx->default_tcg_memop_mask);
         break;
     case OPC_SH:
-        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
+        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
                            ctx->default_tcg_memop_mask);
         break;
     case OPC_SB:
-        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
+        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
         break;
     case OPC_SWL:
-        gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
+        gen_helper_0e2i(swl, t1, t0, mem_idx);
         break;
     case OPC_SWR:
-        gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
+        gen_helper_0e2i(swr, t1, t0, mem_idx);
         break;
     }
     tcg_temp_free(t0);
@@ -2339,6 +2345,7 @@  static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
                          int base, int16_t offset)
 {
     TCGv t0, t1;
+    int mem_idx = ctx->mem_idx;
 
 #ifdef CONFIG_USER_ONLY
     t0 = tcg_temp_local_new();
@@ -2353,12 +2360,12 @@  static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
 #if defined(TARGET_MIPS64)
     case OPC_SCD:
     case R6_OPC_SCD:
-        op_st_scd(t1, t0, rt, ctx);
+        op_st_scd(t1, t0, rt, mem_idx, ctx);
         break;
 #endif
     case OPC_SC:
     case R6_OPC_SC:
-        op_st_sc(t1, t0, rt, ctx);
+        op_st_sc(t1, t0, rt, mem_idx, ctx);
         break;
     }
     tcg_temp_free(t1);