aboutsummaryrefslogtreecommitdiff
path: root/target-mips/translate.c
diff options
context:
space:
mode:
authorYongbok Kim <yongbok.kim@imgtec.com>2015-10-29 15:18:39 +0000
committerLeon Alrae <leon.alrae@imgtec.com>2015-10-30 14:35:52 +0000
commitb00c72180c36510bf9b124e190bd520e3b7e1358 (patch)
treef5a64bd037c0b5577e406da3a7d17f1fc1f5080d /target-mips/translate.c
parentca2f6bbbce32b7e1ba4fdaf54165ab0dee47a3a5 (diff)
target-mips: add PC, XNP reg numbers to RDHWR
Add Performance Counter (4) and XNP (5) register numbers to RDHWR. Add check_hwrena() to simplify access control checkings. Add RDHWR support to microMIPS R6. Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 3105c7f175..bacac2b4fb 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -10333,7 +10333,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
}
}
-static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
+static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
{
TCGv t0;
@@ -10361,6 +10361,22 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
gen_helper_rdhwr_ccres(t0, cpu_env);
gen_store_gpr(t0, rt);
break;
+ case 4:
+ check_insn(ctx, ISA_MIPS32R6);
+ if (sel != 0) {
+ /* Performance counter registers are not implemented other than
+ * control register 0.
+ */
+ generate_exception(ctx, EXCP_RI);
+ }
+ gen_helper_rdhwr_performance(t0, cpu_env);
+ gen_store_gpr(t0, rt);
+ break;
+ case 5:
+ check_insn(ctx, ISA_MIPS32R6);
+ gen_helper_rdhwr_xnp(t0, cpu_env);
+ gen_store_gpr(t0, rt);
+ break;
case 29:
#if defined(CONFIG_USER_ONLY)
tcg_gen_ld_tl(t0, cpu_env,
@@ -11979,6 +11995,7 @@ enum {
ROTR = 0x3,
SELEQZ = 0x5,
SELNEZ = 0x6,
+ R6_RDHWR = 0x7,
SLLV = 0x0,
SRLV = 0x1,
@@ -12932,7 +12949,8 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
gen_cl(ctx, mips32_op, rt, rs);
break;
case RDHWR:
- gen_rdhwr(ctx, rt, rs);
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
+ gen_rdhwr(ctx, rt, rs, 0);
break;
case WSBH:
gen_bshfl(ctx, OPC_WSBH, rs, rt);
@@ -13487,6 +13505,10 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
check_insn(ctx, ISA_MIPS32R6);
gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
break;
+ case R6_RDHWR:
+ check_insn(ctx, ISA_MIPS32R6);
+ gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
+ break;
default:
goto pool32a_invalid;
}
@@ -17733,7 +17755,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
break;
#endif
case OPC_RDHWR:
- gen_rdhwr(ctx, rt, rd);
+ gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
break;
case OPC_FORK:
check_insn(ctx, ASE_MT);