Micro-optimize back-to-back store-load sequences.
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 26 Nov 2007 09:01:34 +0000 (09:01 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 26 Nov 2007 09:01:34 +0000 (09:01 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3743 c046a42c-6fe2-441c-8c8c-71466251a162

target-mips/translate.c

index 55e6290..c909463 100644 (file)
@@ -543,6 +543,8 @@ typedef struct DisasContext {
     uint32_t hflags, saved_hflags;
     int bstate;
     target_ulong btarget;
+    void *last_T0_store;
+    int last_T0_gpr;
 } DisasContext;
 
 enum {
@@ -572,12 +574,33 @@ do {                                                                          \
                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
 } while (0)
 
-#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
+#define GEN_LOAD_REG_T0(Rn)                                                   \
 do {                                                                          \
     if (Rn == 0) {                                                            \
-        glue(gen_op_reset_, Tn)();                                            \
+        gen_op_reset_T0();                                                    \
+    } else {                                                                  \
+        if (ctx->glue(last_T0, _store) != gen_opc_ptr                         \
+            || ctx->glue(last_T0, _gpr) != Rn) {                              \
+                gen_op_load_gpr_T0(Rn);                                       \
+        }                                                                     \
+    }                                                                         \
+} while (0)
+
+#define GEN_LOAD_REG_T1(Rn)                                                   \
+do {                                                                          \
+    if (Rn == 0) {                                                            \
+        gen_op_reset_T1();                                                    \
+    } else {                                                                  \
+        gen_op_load_gpr_T1(Rn);                                               \
+    }                                                                         \
+} while (0)
+
+#define GEN_LOAD_REG_T2(Rn)                                                   \
+do {                                                                          \
+    if (Rn == 0) {                                                            \
+        gen_op_reset_T2();                                                    \
     } else {                                                                  \
-        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
+        gen_op_load_gpr_T2(Rn);                                               \
     }                                                                         \
 } while (0)
 
@@ -612,13 +635,21 @@ do {                                                                          \
 } while (0)
 #endif
 
-#define GEN_STORE_TN_REG(Rn, Tn)                                              \
+#define GEN_STORE_T0_REG(Rn)                                                  \
 do {                                                                          \
     if (Rn != 0) {                                                            \
-        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
+        glue(gen_op_store_T0,_gpr)(Rn);                                       \
+        ctx->glue(last_T0,_store) = gen_opc_ptr;                              \
+        ctx->glue(last_T0,_gpr) = Rn;                                         \
     }                                                                         \
 } while (0)
 
+#define GEN_STORE_T1_REG(Rn)                                                  \
+do {                                                                          \
+    if (Rn != 0)                                                              \
+        glue(gen_op_store_T1,_gpr)(Rn);                                       \
+} while (0)
+
 #define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
 do {                                                                          \
     if (Rn != 0) {                                                            \
@@ -855,126 +886,126 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
 #if defined(TARGET_MIPS64)
     case OPC_LWU:
         op_ldst(lwu);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "lwu";
         break;
     case OPC_LD:
         op_ldst(ld);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "ld";
         break;
     case OPC_LLD:
         op_ldst(lld);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "lld";
         break;
     case OPC_SD:
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(sd);
         opn = "sd";
         break;
     case OPC_SCD:
         save_cpu_state(ctx, 1);
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(scd);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "scd";
         break;
     case OPC_LDL:
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(ldl);
-        GEN_STORE_TN_REG(rt, T1);
+        GEN_STORE_T1_REG(rt);
         opn = "ldl";
         break;
     case OPC_SDL:
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(sdl);
         opn = "sdl";
         break;
     case OPC_LDR:
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(ldr);
-        GEN_STORE_TN_REG(rt, T1);
+        GEN_STORE_T1_REG(rt);
         opn = "ldr";
         break;
     case OPC_SDR:
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(sdr);
         opn = "sdr";
         break;
 #endif
     case OPC_LW:
         op_ldst(lw);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "lw";
         break;
     case OPC_SW:
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(sw);
         opn = "sw";
         break;
     case OPC_LH:
         op_ldst(lh);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "lh";
         break;
     case OPC_SH:
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(sh);
         opn = "sh";
         break;
     case OPC_LHU:
         op_ldst(lhu);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "lhu";
         break;
     case OPC_LB:
         op_ldst(lb);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "lb";
         break;
     case OPC_SB:
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(sb);
         opn = "sb";
         break;
     case OPC_LBU:
         op_ldst(lbu);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "lbu";
         break;
     case OPC_LWL:
-       GEN_LOAD_REG_TN(T1, rt);
+       GEN_LOAD_REG_T1(rt);
         op_ldst(lwl);
-        GEN_STORE_TN_REG(rt, T1);
+        GEN_STORE_T1_REG(rt);
         opn = "lwl";
         break;
     case OPC_SWL:
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(swl);
         opn = "swr";
         break;
     case OPC_LWR:
-       GEN_LOAD_REG_TN(T1, rt);
+       GEN_LOAD_REG_T1(rt);
         op_ldst(lwr);
-        GEN_STORE_TN_REG(rt, T1);
+        GEN_STORE_T1_REG(rt);
         opn = "lwr";
         break;
     case OPC_SWR:
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(swr);
         opn = "swr";
         break;
     case OPC_LL:
         op_ldst(ll);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "ll";
         break;
     case OPC_SC:
         save_cpu_state(ctx, 1);
-        GEN_LOAD_REG_TN(T1, rt);
+        GEN_LOAD_REG_T1(rt);
         op_ldst(sc);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "sc";
         break;
     default:
@@ -1059,7 +1090,7 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
     case OPC_ANDI:
     case OPC_ORI:
     case OPC_XORI:
-        GEN_LOAD_REG_TN(T0, rs);
+        GEN_LOAD_REG_T0(rs);
         GEN_LOAD_IMM_TN(T1, uimm);
         break;
     case OPC_LUI:
@@ -1077,7 +1108,7 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
     case OPC_DSRL32:
 #endif
         uimm &= 0x1f;
-        GEN_LOAD_REG_TN(T0, rs);
+        GEN_LOAD_REG_T0(rs);
         GEN_LOAD_IMM_TN(T1, uimm);
         break;
     }
@@ -1222,7 +1253,7 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
         generate_exception(ctx, EXCP_RI);
         return;
     }
-    GEN_STORE_TN_REG(rt, T0);
+    GEN_STORE_T0_REG(rt);
     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
 }
 
@@ -1239,14 +1270,14 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
         MIPS_DEBUG("NOP");
         return;
     }
-    GEN_LOAD_REG_TN(T0, rs);
+    GEN_LOAD_REG_T0(rs);
     /* Specialcase the conventional move operation. */
     if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
                     || opc == OPC_SUBU || opc == OPC_DSUBU)) {
-        GEN_STORE_TN_REG(rd, T0);
+        GEN_STORE_T0_REG(rd);
         return;
     }
-    GEN_LOAD_REG_TN(T1, rt);
+    GEN_LOAD_REG_T1(rt);
     switch (opc) {
     case OPC_ADD:
         save_cpu_state(ctx, 1);
@@ -1389,7 +1420,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
         generate_exception(ctx, EXCP_RI);
         return;
     }
-    GEN_STORE_TN_REG(rd, T0);
+    GEN_STORE_T0_REG(rd);
  print:
     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
 }
@@ -1407,21 +1438,21 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
     switch (opc) {
     case OPC_MFHI:
         gen_op_load_HI(0);
-        GEN_STORE_TN_REG(reg, T0);
+        GEN_STORE_T0_REG(reg);
         opn = "mfhi";
         break;
     case OPC_MFLO:
         gen_op_load_LO(0);
-        GEN_STORE_TN_REG(reg, T0);
+        GEN_STORE_T0_REG(reg);
         opn = "mflo";
         break;
     case OPC_MTHI:
-        GEN_LOAD_REG_TN(T0, reg);
+        GEN_LOAD_REG_T0(reg);
         gen_op_store_HI(0);
         opn = "mthi";
         break;
     case OPC_MTLO:
-        GEN_LOAD_REG_TN(T0, reg);
+        GEN_LOAD_REG_T0(reg);
         gen_op_store_LO(0);
         opn = "mtlo";
         break;
@@ -1438,8 +1469,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
 {
     const char *opn = "mul/div";
 
-    GEN_LOAD_REG_TN(T0, rs);
-    GEN_LOAD_REG_TN(T1, rt);
+    GEN_LOAD_REG_T0(rs);
+    GEN_LOAD_REG_T1(rt);
     switch (opc) {
     case OPC_DIV:
         gen_op_div();
@@ -1508,7 +1539,7 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
         MIPS_DEBUG("NOP");
         return;
     }
-    GEN_LOAD_REG_TN(T0, rs);
+    GEN_LOAD_REG_T0(rs);
     switch (opc) {
     case OPC_CLO:
         gen_op_clo();
@@ -1554,8 +1585,8 @@ static void gen_trap (DisasContext *ctx, uint32_t opc,
     case OPC_TNE:
         /* Compare two registers */
         if (rs != rt) {
-            GEN_LOAD_REG_TN(T0, rs);
-            GEN_LOAD_REG_TN(T1, rt);
+            GEN_LOAD_REG_T0(rs);
+            GEN_LOAD_REG_T1(rt);
             cond = 1;
         }
         break;
@@ -1567,7 +1598,7 @@ static void gen_trap (DisasContext *ctx, uint32_t opc,
     case OPC_TNEI:
         /* Compare register to immediate */
         if (rs != 0 || imm != 0) {
-            GEN_LOAD_REG_TN(T0, rs);
+            GEN_LOAD_REG_T0(rs);
             GEN_LOAD_IMM_TN(T1, (int32_t)imm);
             cond = 1;
         }
@@ -1680,8 +1711,8 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
     case OPC_BNEL:
         /* Compare two registers */
         if (rs != rt) {
-            GEN_LOAD_REG_TN(T0, rs);
-            GEN_LOAD_REG_TN(T1, rt);
+            GEN_LOAD_REG_T0(rs);
+            GEN_LOAD_REG_T1(rt);
             bcond = 1;
         }
         btarget = ctx->pc + 4 + offset;
@@ -1720,7 +1751,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
             generate_exception(ctx, EXCP_RI);
             return;
         }
-        GEN_LOAD_REG_TN(T2, rs);
+        GEN_LOAD_REG_T2(rs);
         break;
     default:
         MIPS_INVAL("branch/jump");
@@ -1896,7 +1927,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
                        int rs, int lsb, int msb)
 {
-    GEN_LOAD_REG_TN(T1, rs);
+    GEN_LOAD_REG_T1(rs);
     switch (opc) {
     case OPC_EXT:
         if (lsb + msb > 31)
@@ -1923,26 +1954,26 @@ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
     case OPC_INS:
         if (lsb > msb)
             goto fail;
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         gen_op_ins(lsb, msb - lsb + 1);
         break;
 #if defined(TARGET_MIPS64)
     case OPC_DINSM:
         if (lsb > msb)
             goto fail;
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         gen_op_dins(lsb, msb - lsb + 1 + 32);
         break;
     case OPC_DINSU:
         if (lsb > msb)
             goto fail;
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         gen_op_dins(lsb + 32, msb - lsb + 1);
         break;
     case OPC_DINS:
         if (lsb > msb)
             goto fail;
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         gen_op_dins(lsb, msb - lsb + 1);
         break;
 #endif
@@ -1952,7 +1983,7 @@ fail:
         generate_exception(ctx, EXCP_RI);
         return;
     }
-    GEN_STORE_TN_REG(rt, T0);
+    GEN_STORE_T0_REG(rt);
 }
 
 /* CP0 (MMU and control) */
@@ -4611,7 +4642,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
         opn = "mfc0";
         break;
     case OPC_MTC0:
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         save_cpu_state(ctx, 1);
         gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
         opn = "mtc0";
@@ -4629,7 +4660,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
         break;
     case OPC_DMTC0:
         check_insn(env, ctx, ISA_MIPS3);
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         save_cpu_state(ctx, 1);
         gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
         opn = "dmtc0";
@@ -4648,7 +4679,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
         break;
     case OPC_MTTR:
         check_insn(env, ctx, ASE_MT);
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
         opn = "mttr";
@@ -4789,33 +4820,33 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
     case OPC_MFC1:
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_mfc1();
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "mfc1";
         break;
     case OPC_MTC1:
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         gen_op_mtc1();
         GEN_STORE_FTN_FREG(fs, WT0);
         opn = "mtc1";
         break;
     case OPC_CFC1:
         gen_op_cfc1(fs);
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "cfc1";
         break;
     case OPC_CTC1:
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         gen_op_ctc1(fs);
         opn = "ctc1";
         break;
     case OPC_DMFC1:
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_dmfc1();
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "dmfc1";
         break;
     case OPC_DMTC1:
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         gen_op_dmtc1();
         GEN_STORE_FTN_FREG(fs, DT0);
         opn = "dmtc1";
@@ -4823,11 +4854,11 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
     case OPC_MFHC1:
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_mfhc1();
-        GEN_STORE_TN_REG(rt, T0);
+        GEN_STORE_T0_REG(rt);
         opn = "mfhc1";
         break;
     case OPC_MTHC1:
-        GEN_LOAD_REG_TN(T0, rt);
+        GEN_LOAD_REG_T0(rt);
         gen_op_mthc1();
         GEN_STORE_FTN_FREG(fs, WTH0);
         opn = "mthc1";
@@ -4844,8 +4875,8 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
 {
     uint32_t ccbit;
 
-    GEN_LOAD_REG_TN(T0, rd);
-    GEN_LOAD_REG_TN(T1, rs);
+    GEN_LOAD_REG_T0(rd);
+    GEN_LOAD_REG_T1(rs);
     if (cc) {
         ccbit = 1 << (24 + cc);
     } else
@@ -4854,7 +4885,7 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
         gen_op_movf(ccbit);
     else
         gen_op_movt(ccbit);
-    GEN_STORE_TN_REG(rd, T0);
+    GEN_STORE_T0_REG(rd);
 }
 
 #define GEN_MOVCF(fmt)                                                \
@@ -5029,7 +5060,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1,
         opn = "floor.w.s";
         break;
     case FOP(17, 16):
-        GEN_LOAD_REG_TN(T0, ft);
+        GEN_LOAD_REG_T0(ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
         gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
@@ -5037,7 +5068,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1,
         opn = "movcf.s";
         break;
     case FOP(18, 16):
-        GEN_LOAD_REG_TN(T0, ft);
+        GEN_LOAD_REG_T0(ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
         gen_op_float_movz_s();
@@ -5045,7 +5076,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1,
         opn = "movz.s";
         break;
     case FOP(19, 16):
-        GEN_LOAD_REG_TN(T0, ft);
+        GEN_LOAD_REG_T0(ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
         gen_op_float_movn_s();
@@ -5270,7 +5301,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1,
         opn = "floor.w.d";
         break;
     case FOP(17, 17):
-        GEN_LOAD_REG_TN(T0, ft);
+        GEN_LOAD_REG_T0(ft);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT2, fd);
         gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
@@ -5278,7 +5309,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1,
         opn = "movcf.d";
         break;
     case FOP(18, 17):
-        GEN_LOAD_REG_TN(T0, ft);
+        GEN_LOAD_REG_T0(ft);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT2, fd);
         gen_op_float_movz_d();
@@ -5286,7 +5317,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1,
         opn = "movz.d";
         break;
     case FOP(19, 17):
-        GEN_LOAD_REG_TN(T0, ft);
+        GEN_LOAD_REG_T0(ft);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT2, fd);
         gen_op_float_movn_d();
@@ -5484,7 +5515,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1,
         break;
     case FOP(17, 22):
         check_cp1_64bitmode(ctx);
-        GEN_LOAD_REG_TN(T0, ft);
+        GEN_LOAD_REG_T0(ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
@@ -5496,7 +5527,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1,
         break;
     case FOP(18, 22):
         check_cp1_64bitmode(ctx);
-        GEN_LOAD_REG_TN(T0, ft);
+        GEN_LOAD_REG_T0(ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
@@ -5508,7 +5539,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1,
         break;
     case FOP(19, 22):
         check_cp1_64bitmode(ctx);
-        GEN_LOAD_REG_TN(T0, ft);
+        GEN_LOAD_REG_T0(ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
@@ -5695,12 +5726,12 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
         if (index == 0)
             gen_op_reset_T0();
         else
-            GEN_LOAD_REG_TN(T0, index);
+            GEN_LOAD_REG_T0(index);
     } else if (index == 0) {
-        GEN_LOAD_REG_TN(T0, base);
+        GEN_LOAD_REG_T0(base);
     } else {
-        GEN_LOAD_REG_TN(T0, base);
-        GEN_LOAD_REG_TN(T1, index);
+        GEN_LOAD_REG_T0(base);
+        GEN_LOAD_REG_T1(index);
         gen_op_addr_add();
     }
     /* Don't do NOP if destination is zero: we must perform the actual
@@ -5757,7 +5788,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
     check_cp1_64bitmode(ctx);
     switch (opc) {
     case OPC_ALNV_PS:
-        GEN_LOAD_REG_TN(T0, fr);
+        GEN_LOAD_REG_T0(fr);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         gen_op_float_alnv_ps();
@@ -6081,15 +6112,15 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
              op2 = MASK_BSHFL(ctx->opcode);
              switch (op2) {
              case OPC_WSBH:
-                 GEN_LOAD_REG_TN(T1, rt);
+                 GEN_LOAD_REG_T1(rt);
                  gen_op_wsbh();
                  break;
              case OPC_SEB:
-                 GEN_LOAD_REG_TN(T1, rt);
+                 GEN_LOAD_REG_T1(rt);
                  gen_op_seb();
                  break;
              case OPC_SEH:
-                 GEN_LOAD_REG_TN(T1, rt);
+                 GEN_LOAD_REG_T1(rt);
                  gen_op_seh();
                  break;
              default:            /* Invalid */
@@ -6097,7 +6128,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
                  generate_exception(ctx, EXCP_RI);
                  break;
             }
-            GEN_STORE_TN_REG(rd, T0);
+            GEN_STORE_T0_REG(rd);
             break;
         case OPC_RDHWR:
             check_insn(env, ctx, ISA_MIPS32R2);
@@ -6128,19 +6159,19 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
                 generate_exception(ctx, EXCP_RI);
                 break;
             }
-            GEN_STORE_TN_REG(rt, T0);
+            GEN_STORE_T0_REG(rt);
             break;
         case OPC_FORK:
             check_insn(env, ctx, ASE_MT);
-            GEN_LOAD_REG_TN(T0, rt);
-            GEN_LOAD_REG_TN(T1, rs);
+            GEN_LOAD_REG_T0(rt);
+            GEN_LOAD_REG_T1(rs);
             gen_op_fork();
             break;
         case OPC_YIELD:
             check_insn(env, ctx, ASE_MT);
-            GEN_LOAD_REG_TN(T0, rs);
+            GEN_LOAD_REG_T0(rs);
             gen_op_yield();
-            GEN_STORE_TN_REG(rd, T0);
+            GEN_STORE_T0_REG(rd);
             break;
 #if defined(TARGET_MIPS64)
         case OPC_DEXTM ... OPC_DEXT:
@@ -6155,11 +6186,11 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
             op2 = MASK_DBSHFL(ctx->opcode);
             switch (op2) {
             case OPC_DSBH:
-                GEN_LOAD_REG_TN(T1, rt);
+                GEN_LOAD_REG_T1(rt);
                 gen_op_dsbh();
                 break;
             case OPC_DSHD:
-                GEN_LOAD_REG_TN(T1, rt);
+                GEN_LOAD_REG_T1(rt);
                 gen_op_dshd();
                 break;
             default:            /* Invalid */
@@ -6167,7 +6198,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
                 generate_exception(ctx, EXCP_RI);
                 break;
             }
-            GEN_STORE_TN_REG(rd, T0);
+            GEN_STORE_T0_REG(rd);
             break;
 #endif
         default:            /* Invalid */
@@ -6252,16 +6283,16 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
                 generate_exception(ctx, EXCP_RI);
                 break;
             }
-            GEN_STORE_TN_REG(rt, T0);
+            GEN_STORE_T0_REG(rt);
             break;
         case OPC_RDPGPR:
             check_insn(env, ctx, ISA_MIPS32R2);
             GEN_LOAD_SRSREG_TN(T0, rt);
-            GEN_STORE_TN_REG(rd, T0);
+            GEN_STORE_T0_REG(rd);
             break;
         case OPC_WRPGPR:
             check_insn(env, ctx, ISA_MIPS32R2);
-            GEN_LOAD_REG_TN(T0, rt);
+            GEN_LOAD_REG_T0(rt);
             GEN_STORE_TN_SRSREG(rd, T0);
             break;
         default:
@@ -6589,6 +6620,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
        }
     }
 done_generating:
+    ctx.last_T0_store = NULL;
     *gen_opc_ptr = INDEX_op_end;
     if (search_pc) {
         j = gen_opc_ptr - gen_opc_buf;