[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 02/21] target-mips: signal RI Exception on instr
From: |
Aurelien Jarno |
Subject: |
Re: [Qemu-devel] [PATCH 02/21] target-mips: signal RI Exception on instructions removed in R6 |
Date: |
Fri, 30 May 2014 18:43:48 +0200 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Fri, May 30, 2014 at 03:47:40PM +0100, Leon Alrae wrote:
> 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>
> ---
> 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 05f82d2..2ac8023 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);
Reviewed-by: Aurelien Jarno <address@hidden>
Just a comment, not related to QEMU: while it looks at a first glance to
build a binary that runs on both pre-R6 and R6 by not using the removed
instructions, I do wonder how the transition would be done for unaligned
load/stores. On pre-R6, unaligned load/stores are not supported so
LDR/LDL must be used, while on R6 LDR/LDL are not supported, so
unaligned load/stores should be used instead...
--
Aurelien Jarno GPG: 1024D/F1BCDB73
address@hidden http://www.aurel32.net
- [Qemu-devel] [PATCH 00/21] target-mips: add MIPS64R6 Instruction Set support, Leon Alrae, 2014/05/30
- [Qemu-devel] [PATCH 01/21] target-mips: introduce MIPS64R6 ISA and a new generic CPU, Leon Alrae, 2014/05/30
- [Qemu-devel] [PATCH 02/21] target-mips: signal RI Exception on instructions removed in R6, Leon Alrae, 2014/05/30
- Re: [Qemu-devel] [PATCH 02/21] target-mips: signal RI Exception on instructions removed in R6,
Aurelien Jarno <=
- [Qemu-devel] [PATCH 04/21] target-mips: move LL and SC instructions, Leon Alrae, 2014/05/30
- [Qemu-devel] [PATCH 03/21] target-mips: add SELEQZ and SELNEZ instructions, Leon Alrae, 2014/05/30
- [Qemu-devel] [PATCH 05/21] target-mips: extract decode_opc_special* from decode_opc, Leon Alrae, 2014/05/30
- [Qemu-devel] [PATCH 08/21] target-mips: move PREF, CACHE, LLD and SCD instructions, Leon Alrae, 2014/05/30
- [Qemu-devel] [PATCH 06/21] target-mips: split decode_opc_special* into *_r6 and *_legacy, Leon Alrae, 2014/05/30