提交 ae2dbf7f 编写于 作者: T ths

Micro-optimize back-to-back store-load sequences.


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