[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 02/22] target-mips: signal RI Exception on instru
From: |
Leon Alrae |
Subject: |
[Qemu-devel] [PATCH v2 02/22] target-mips: signal RI Exception on instructions removed in R6 |
Date: |
Wed, 11 Jun 2014 16:19:32 +0100 |
Signal Reserved Instruction Exception on instructions that do not exist in R6.
In this commit the following groups of preR6 instructions are marked as deleted:
- Floating Point Paired Single
- Floating Point Compare
- conditional moves / branches on FPU conditions
- branch likelies
- unaligned loads / stores
- traps
- legacy accumulator instructions
- COP1X
- MIPS-3D
Signed-off-by: Leon Alrae <address@hidden>
Reviewed-by: Aurelien Jarno <address@hidden>
---
target-mips/translate.c | 64 +++++++++++++++++++++++++++++++++++++++++------
1 files changed, 56 insertions(+), 8 deletions(-)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 76deb7b..dbb3746 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1430,6 +1430,16 @@ static inline void check_insn(DisasContext *ctx, int
flags)
}
}
+/* This code generates a "reserved instruction" exception if the
+ CPU has corresponding flag set which indicates that the instruction
+ has been removed. */
+static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
+{
+ if (unlikely(ctx->insn_flags & flags)) {
+ generate_exception(ctx, EXCP_RI);
+ }
+}
+
/* This code generates a "reserved instruction" exception if 64-bit
instructions are not enabled. */
static inline void check_mips_64(DisasContext *ctx)
@@ -7667,10 +7677,12 @@ static void gen_farith (DisasContext *ctx, enum fopcode
op1,
opn = "floor.w.s";
break;
case OPC_MOVCF_S:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
opn = "movcf.s";
break;
case OPC_MOVZ_S:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
{
int l1 = gen_new_label();
TCGv_i32 fp0;
@@ -7687,6 +7699,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode
op1,
opn = "movz.s";
break;
case OPC_MOVN_S:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
{
int l1 = gen_new_label();
TCGv_i32 fp0;
@@ -7820,6 +7833,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode
op1,
opn = "cvt.l.s";
break;
case OPC_CVT_PS_S:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
check_cp1_64bitmode(ctx);
{
TCGv_i64 fp64 = tcg_temp_new_i64();
@@ -7852,6 +7866,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode
op1,
case OPC_CMP_NGE_S:
case OPC_CMP_LE_S:
case OPC_CMP_NGT_S:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
if (ctx->opcode & (1 << 6)) {
gen_cmpabs_s(ctx, func-48, ft, fs, cc);
opn = condnames_abs[func-48];
@@ -8076,10 +8091,12 @@ static void gen_farith (DisasContext *ctx, enum fopcode
op1,
opn = "floor.w.d";
break;
case OPC_MOVCF_D:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
opn = "movcf.d";
break;
case OPC_MOVZ_D:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
{
int l1 = gen_new_label();
TCGv_i64 fp0;
@@ -8096,6 +8113,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode
op1,
opn = "movz.d";
break;
case OPC_MOVN_D:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
{
int l1 = gen_new_label();
TCGv_i64 fp0;
@@ -8205,6 +8223,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode
op1,
case OPC_CMP_NGE_D:
case OPC_CMP_LE_D:
case OPC_CMP_NGT_D:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
if (ctx->opcode & (1 << 6)) {
gen_cmpabs_d(ctx, func-48, ft, fs, cc);
opn = condnames_abs[func-48];
@@ -8305,6 +8324,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode
op1,
opn = "cvt.d.l";
break;
case OPC_CVT_PS_PW:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
check_cp1_64bitmode(ctx);
{
TCGv_i64 fp0 = tcg_temp_new_i64();
@@ -14455,6 +14475,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext
*ctx)
break;
case OPC_MOVN: /* Conditional move */
case OPC_MOVZ:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
INSN_LOONGSON2E | INSN_LOONGSON2F);
gen_cond_move(ctx, op1, rd, rs, rt);
@@ -14515,10 +14536,12 @@ static void decode_opc (CPUMIPSState *env,
DisasContext *ctx)
break;
case OPC_MFHI: /* Move from HI/LO */
case OPC_MFLO:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_HILO(ctx, op1, rs & 3, rd);
break;
case OPC_MTHI:
case OPC_MTLO: /* Move to HI/LO */
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_HILO(ctx, op1, rd & 3, rs);
break;
case OPC_PMON: /* Pmon entry point, also R4010 selsl */
@@ -14551,6 +14574,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext
*ctx)
break;
case OPC_MOVCI:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
check_cp1_enabled(ctx);
@@ -14653,10 +14677,12 @@ static void decode_opc (CPUMIPSState *env,
DisasContext *ctx)
switch (op1) {
case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
case OPC_MSUB ... OPC_MSUBU:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
check_insn(ctx, ISA_MIPS32);
gen_muldiv(ctx, op1, rd & 3, rs, rt);
break;
case OPC_MUL:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_arith(ctx, op1, rd, rs, rt);
break;
case OPC_CLO:
@@ -15271,12 +15297,20 @@ static void decode_opc (CPUMIPSState *env,
DisasContext *ctx)
case OPC_REGIMM:
op1 = MASK_REGIMM(ctx->opcode);
switch (op1) {
- case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
- case OPC_BLTZAL ... OPC_BGEZALL:
+ case OPC_BLTZL: /* REGIMM branches */
+ case OPC_BGEZL:
+ case OPC_BLTZALL:
+ case OPC_BGEZALL:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
+ case OPC_BLTZ:
+ case OPC_BGEZ:
+ case OPC_BLTZAL:
+ case OPC_BGEZAL:
gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
break;
case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
case OPC_TNEI:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_trap(ctx, op1, rs, -1, imm);
break;
case OPC_SYNCI:
@@ -15401,16 +15435,24 @@ static void decode_opc (CPUMIPSState *env,
DisasContext *ctx)
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
gen_compute_branch(ctx, op, 4, rs, rt, offset);
break;
- case OPC_BEQ ... OPC_BGTZ: /* Branch */
- case OPC_BEQL ... OPC_BGTZL:
+ case OPC_BEQL ... OPC_BGTZL: /* Branch */
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
+ case OPC_BEQ ... OPC_BGTZ:
gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
break;
- case OPC_LB ... OPC_LWR: /* Load and stores */
+ case OPC_LWL: /* Load and stores */
+ case OPC_LWR:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
+ case OPC_LB ... OPC_LH:
+ case OPC_LW ... OPC_LHU:
case OPC_LL:
gen_ld(ctx, op, rt, rs, imm);
break;
- case OPC_SB ... OPC_SW:
+ case OPC_SWL:
case OPC_SWR:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
+ case OPC_SB ... OPC_SH:
+ case OPC_SW:
gen_st(ctx, op, rt, rs, imm);
break;
case OPC_SC:
@@ -15457,18 +15499,21 @@ static void decode_opc (CPUMIPSState *env,
DisasContext *ctx)
#endif
case OPC_BC1ANY2:
case OPC_BC1ANY4:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
check_cop1x(ctx);
check_insn(ctx, ASE_MIPS3D);
/* fall through */
case OPC_BC1:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
(rt >> 2) & 0x7, imm << 2);
break;
+ case OPC_PS_FMT:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
case OPC_S_FMT:
case OPC_D_FMT:
case OPC_W_FMT:
case OPC_L_FMT:
- case OPC_PS_FMT:
gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
(imm >> 8) & 0x7);
break;
@@ -15497,6 +15542,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext
*ctx)
break;
case OPC_CP3:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
check_cp1_enabled(ctx);
op1 = MASK_CP3(ctx->opcode);
@@ -15539,8 +15585,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext
*ctx)
#if defined(TARGET_MIPS64)
/* MIPS64 opcodes */
- case OPC_LWU:
case OPC_LDL ... OPC_LDR:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
+ case OPC_LWU:
case OPC_LLD:
case OPC_LD:
check_insn(ctx, ISA_MIPS3);
@@ -15548,6 +15595,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext
*ctx)
gen_ld(ctx, op, rt, rs, imm);
break;
case OPC_SDL ... OPC_SDR:
+ check_insn_opc_removed(ctx, ISA_MIPS32R6);
case OPC_SD:
check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
--
1.7.5.4
- [Qemu-devel] [PATCH v2 00/22] target-mips: add MIPS64R6 Instruction Set support, Leon Alrae, 2014/06/11
- [Qemu-devel] [PATCH v2 01/22] target-mips: define ISA_MIPS64R6, Leon Alrae, 2014/06/11
- [Qemu-devel] [PATCH v2 02/22] target-mips: signal RI Exception on instructions removed in R6,
Leon Alrae <=
- [Qemu-devel] [PATCH v2 03/22] target-mips: add SELEQZ and SELNEZ instructions, Leon Alrae, 2014/06/11
- [Qemu-devel] [PATCH v2 04/22] target-mips: move LL and SC instructions, Leon Alrae, 2014/06/11
- [Qemu-devel] [PATCH v2 06/22] target-mips: split decode_opc_special* into *_r6 and *_legacy, Leon Alrae, 2014/06/11
- [Qemu-devel] [PATCH v2 07/22] target-mips: signal RI Exception on DSP and Loongson instructions, Leon Alrae, 2014/06/11
- [Qemu-devel] [PATCH v2 08/22] target-mips: move PREF, CACHE, LLD and SCD instructions, Leon Alrae, 2014/06/11
- [Qemu-devel] [PATCH v2 10/22] target-mips: move CLO, DCLO, CLZ, DCLZ, SDBBP and free special2 in R6, Leon Alrae, 2014/06/11
- [Qemu-devel] [PATCH v2 05/22] target-mips: extract decode_opc_special* from decode_opc, Leon Alrae, 2014/06/11
- [Qemu-devel] [PATCH v2 11/22] target-mips: Status.UX/SX/KX enable 32-bit address wrapping, Leon Alrae, 2014/06/11