* [Qemu-devel] [PATCH v2] target-mips: add SIGRIE instruction
2015-10-29 15:18 [Qemu-devel] [PATCH v2] target-mips: fix updating XContext on mmu exception Yongbok Kim
@ 2015-10-29 15:18 ` Yongbok Kim
2015-10-29 15:18 ` [Qemu-devel] [PATCH v2] target-mips: add PC, XNP reg numbers to RDHWR Yongbok Kim
1 sibling, 0 replies; 3+ messages in thread
From: Yongbok Kim @ 2015-10-29 15:18 UTC (permalink / raw)
To: qemu-devel; +Cc: leon.alrae, aurelien
Add SIGRIE (Signal Reserved Instruction Exception) for both MIPS and
microMIPS.
The instruction allows to use the 16-bit code field for software use.
This instruction is introduced by and required as of Release 6.
Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
target-mips/translate.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 4cb77de..df24d6b 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -323,6 +323,7 @@ enum {
OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
+ OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
@@ -12014,7 +12015,8 @@ enum {
LSA = 0x0f,
ALIGN = 0x1f,
EXT = 0x2c,
- POOL32AXF = 0x3c
+ POOL32AXF = 0x3c,
+ SIGRIE = 0x3f
};
/* POOL32AXF encoding of minor opcode field extension */
@@ -13633,6 +13635,10 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
case BREAK32:
generate_exception_end(ctx, EXCP_BREAK);
break;
+ case SIGRIE:
+ check_insn(ctx, ISA_MIPS32R6);
+ generate_exception_end(ctx, EXCP_RI);
+ break;
default:
pool32a_invalid:
MIPS_INVAL("pool32a");
@@ -18951,6 +18957,10 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_trap(ctx, op1, rs, -1, imm);
break;
+ case OPC_SIGRIE:
+ check_insn(ctx, ISA_MIPS32R6);
+ generate_exception_end(ctx, EXCP_RI);
+ break;
case OPC_SYNCI:
check_insn(ctx, ISA_MIPS32R2);
/* Break the TB to be able to sync copied instructions
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [Qemu-devel] [PATCH v2] target-mips: add PC, XNP reg numbers to RDHWR
2015-10-29 15:18 [Qemu-devel] [PATCH v2] target-mips: fix updating XContext on mmu exception Yongbok Kim
2015-10-29 15:18 ` [Qemu-devel] [PATCH v2] target-mips: add SIGRIE instruction Yongbok Kim
@ 2015-10-29 15:18 ` Yongbok Kim
1 sibling, 0 replies; 3+ messages in thread
From: Yongbok Kim @ 2015-10-29 15:18 UTC (permalink / raw)
To: qemu-devel; +Cc: leon.alrae, aurelien
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>
---
target-mips/cpu.h | 1 +
target-mips/helper.h | 2 +
target-mips/op_helper.c | 64 +++++++++++++++++++++++++---------------------
target-mips/translate.c | 28 ++++++++++++++++++--
4 files changed, 63 insertions(+), 32 deletions(-)
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index c68681d..fa919c1 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -469,6 +469,7 @@ struct CPUMIPSState {
#define CP0C5_CV 29
#define CP0C5_EVA 28
#define CP0C5_MSAEn 27
+#define CP0C5_XNP 13
#define CP0C5_UFE 9
#define CP0C5_FRE 8
#define CP0C5_SBRI 6
diff --git a/target-mips/helper.h b/target-mips/helper.h
index d8cc766..95b9149 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -358,6 +358,8 @@ DEF_HELPER_1(rdhwr_cpunum, tl, env)
DEF_HELPER_1(rdhwr_synci_step, tl, env)
DEF_HELPER_1(rdhwr_cc, tl, env)
DEF_HELPER_1(rdhwr_ccres, tl, env)
+DEF_HELPER_1(rdhwr_performance, tl, env)
+DEF_HELPER_1(rdhwr_xnp, tl, env)
DEF_HELPER_2(pmon, void, env, int)
DEF_HELPER_1(wait, void, env)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 6739fff..ff03465 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1357,6 +1357,13 @@ void helper_mtc0_hwrena(CPUMIPSState *env, target_ulong arg1)
{
uint32_t mask = 0x0000000F;
+ if ((env->CP0_Config1 & (1 << CP0C1_PC)) &&
+ (env->insn_flags & ISA_MIPS32R6)) {
+ mask |= (1 << 4);
+ }
+ if (env->insn_flags & ISA_MIPS32R6) {
+ mask |= (1 << 5);
+ }
if (env->CP0_Config3 & (1 << CP0C3_ULRI)) {
mask |= (1 << 29);
@@ -2185,53 +2192,52 @@ void helper_deret(CPUMIPSState *env)
}
#endif /* !CONFIG_USER_ONLY */
-target_ulong helper_rdhwr_cpunum(CPUMIPSState *env)
+static inline void check_hwrena(CPUMIPSState *env, int reg)
{
- if ((env->hflags & MIPS_HFLAG_CP0) ||
- (env->CP0_HWREna & (1 << 0)))
- return env->CP0_EBase & 0x3ff;
- else
- do_raise_exception(env, EXCP_RI, GETPC());
+ if ((env->hflags & MIPS_HFLAG_CP0) || (env->CP0_HWREna & (1 << reg))) {
+ return;
+ }
+ do_raise_exception(env, EXCP_RI, GETPC());
+}
- return 0;
+target_ulong helper_rdhwr_cpunum(CPUMIPSState *env)
+{
+ check_hwrena(env, 0);
+ return env->CP0_EBase & 0x3ff;
}
target_ulong helper_rdhwr_synci_step(CPUMIPSState *env)
{
- if ((env->hflags & MIPS_HFLAG_CP0) ||
- (env->CP0_HWREna & (1 << 1)))
- return env->SYNCI_Step;
- else
- do_raise_exception(env, EXCP_RI, GETPC());
-
- return 0;
+ check_hwrena(env, 1);
+ return env->SYNCI_Step;
}
target_ulong helper_rdhwr_cc(CPUMIPSState *env)
{
- if ((env->hflags & MIPS_HFLAG_CP0) ||
- (env->CP0_HWREna & (1 << 2))) {
+ check_hwrena(env, 2);
#ifdef CONFIG_USER_ONLY
- return env->CP0_Count;
+ return env->CP0_Count;
#else
- return (int32_t)cpu_mips_get_count(env);
+ return (int32_t)cpu_mips_get_count(env);
#endif
- } else {
- do_raise_exception(env, EXCP_RI, GETPC());
- }
-
- return 0;
}
target_ulong helper_rdhwr_ccres(CPUMIPSState *env)
{
- if ((env->hflags & MIPS_HFLAG_CP0) ||
- (env->CP0_HWREna & (1 << 3)))
- return env->CCRes;
- else
- do_raise_exception(env, EXCP_RI, GETPC());
+ check_hwrena(env, 3);
+ return env->CCRes;
+}
- return 0;
+target_ulong helper_rdhwr_performance(CPUMIPSState *env)
+{
+ check_hwrena(env, 4);
+ return env->CP0_Performance0;
+}
+
+target_ulong helper_rdhwr_xnp(CPUMIPSState *env)
+{
+ check_hwrena(env, 5);
+ return (env->CP0_Config5 >> CP0C5_XNP) & 1;
}
void helper_pmon(CPUMIPSState *env, int function)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index df24d6b..9046c30 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -10334,7 +10334,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;
@@ -10362,6 +10362,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,
@@ -11980,6 +11996,7 @@ enum {
ROTR = 0x3,
SELEQZ = 0x5,
SELNEZ = 0x6,
+ R6_RDHWR = 0x7,
SLLV = 0x0,
SRLV = 0x1,
@@ -12934,7 +12951,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);
@@ -13489,6 +13507,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;
}
@@ -17739,7 +17761,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);
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread