Micro-optimize back-to-back store-load sequences.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3743 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
2382dc6b9b
commit
ae2dbf7fb0
@ -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 { \
|
||||
glue(gen_op_load_gpr_, Tn)(Rn); \
|
||||
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 { \
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user