target-mips: break out [ls][wd]c1 and rdhwr insn generation

Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Acked-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Nathan Froyd 2010-05-24 09:19:35 -07:00 committed by Aurelien Jarno
parent d44cff2204
commit 26ebe46848

View File

@ -1220,6 +1220,17 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
tcg_temp_free(t0); tcg_temp_free(t0);
} }
static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
uint32_t op, int rt, int rs, int16_t imm)
{
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
check_cp1_enabled(ctx);
gen_flt_ldst(ctx, op, rt, rs, imm);
} else {
generate_exception_err(ctx, EXCP_CpU, 1);
}
}
/* Arithmetic with immediate operand */ /* Arithmetic with immediate operand */
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
int rt, int rs, int16_t imm) int rt, int rs, int16_t imm)
@ -7528,6 +7539,52 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
fregnames[fs], fregnames[ft]); fregnames[fs], fregnames[ft]);
} }
static void
gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
{
TCGv t0;
check_insn(env, ctx, ISA_MIPS32R2);
t0 = tcg_temp_new();
switch (rd) {
case 0:
save_cpu_state(ctx, 1);
gen_helper_rdhwr_cpunum(t0);
gen_store_gpr(t0, rt);
break;
case 1:
save_cpu_state(ctx, 1);
gen_helper_rdhwr_synci_step(t0);
gen_store_gpr(t0, rt);
break;
case 2:
save_cpu_state(ctx, 1);
gen_helper_rdhwr_cc(t0);
gen_store_gpr(t0, rt);
break;
case 3:
save_cpu_state(ctx, 1);
gen_helper_rdhwr_ccres(t0);
gen_store_gpr(t0, rt);
break;
case 29:
#if defined(CONFIG_USER_ONLY)
tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
gen_store_gpr(t0, rt);
break;
#else
/* XXX: Some CPUs implement this in hardware.
Not supported yet. */
#endif
default: /* Invalid */
MIPS_INVAL("rdhwr");
generate_exception(ctx, EXCP_RI);
break;
}
tcg_temp_free(t0);
}
static void handle_delay_slot (CPUState *env, DisasContext *ctx, static void handle_delay_slot (CPUState *env, DisasContext *ctx,
int insn_bytes) int insn_bytes)
{ {
@ -8999,47 +9056,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
gen_bshfl(ctx, op2, rt, rd); gen_bshfl(ctx, op2, rt, rd);
break; break;
case OPC_RDHWR: case OPC_RDHWR:
check_insn(env, ctx, ISA_MIPS32R2); gen_rdhwr(env, ctx, rt, rd);
{
TCGv t0 = tcg_temp_new();
switch (rd) {
case 0:
save_cpu_state(ctx, 1);
gen_helper_rdhwr_cpunum(t0);
gen_store_gpr(t0, rt);
break;
case 1:
save_cpu_state(ctx, 1);
gen_helper_rdhwr_synci_step(t0);
gen_store_gpr(t0, rt);
break;
case 2:
save_cpu_state(ctx, 1);
gen_helper_rdhwr_cc(t0);
gen_store_gpr(t0, rt);
break;
case 3:
save_cpu_state(ctx, 1);
gen_helper_rdhwr_ccres(t0);
gen_store_gpr(t0, rt);
break;
case 29:
#if defined(CONFIG_USER_ONLY)
tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
gen_store_gpr(t0, rt);
break;
#else
/* XXX: Some CPUs implement this in hardware.
Not supported yet. */
#endif
default: /* Invalid */
MIPS_INVAL("rdhwr");
generate_exception(ctx, EXCP_RI);
break;
}
tcg_temp_free(t0);
}
break; break;
case OPC_FORK: case OPC_FORK:
check_insn(env, ctx, ASE_MT); check_insn(env, ctx, ASE_MT);
@ -9242,12 +9259,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
case OPC_LDC1: case OPC_LDC1:
case OPC_SWC1: case OPC_SWC1:
case OPC_SDC1: case OPC_SDC1:
if (env->CP0_Config1 & (1 << CP0C1_FP)) { gen_cop1_ldst(env, ctx, op, rt, rs, imm);
check_cp1_enabled(ctx);
gen_flt_ldst(ctx, op, rt, rs, imm);
} else {
generate_exception_err(ctx, EXCP_CpU, 1);
}
break; break;
case OPC_CP1: case OPC_CP1: