From patchwork Fri Jun 27 15:21:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leon Alrae X-Patchwork-Id: 365040 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F9531400DC for ; Sat, 28 Jun 2014 01:23:55 +1000 (EST) Received: from localhost ([::1]:50938 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0Y0H-00013D-Gf for incoming@patchwork.ozlabs.org; Fri, 27 Jun 2014 11:23:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44142) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0Xza-000890-9u for qemu-devel@nongnu.org; Fri, 27 Jun 2014 11:23:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X0XzU-00057G-3M for qemu-devel@nongnu.org; Fri, 27 Jun 2014 11:23:10 -0400 Received: from mailapp01.imgtec.com ([195.59.15.196]:10387) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0XzT-00056a-Q8 for qemu-devel@nongnu.org; Fri, 27 Jun 2014 11:23:04 -0400 Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id 073AD3D161D26; Fri, 27 Jun 2014 16:22:58 +0100 (IST) Received: from localhost.localdomain (192.168.14.85) by KLMAIL01.kl.imgtec.org (192.168.5.35) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 27 Jun 2014 16:23:00 +0100 From: Leon Alrae To: Date: Fri, 27 Jun 2014 16:21:51 +0100 Message-ID: <1403882530-47821-3-git-send-email-leon.alrae@imgtec.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1403882530-47821-1-git-send-email-leon.alrae@imgtec.com> References: <1403882530-47821-1-git-send-email-leon.alrae@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [192.168.14.85] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.59.15.196 Cc: yongbok.kim@imgtec.com, cristian.cuna@imgtec.com, leon.alrae@imgtec.com, aurelien@aurel32.net, rth@twiddle.net Subject: [Qemu-devel] [PATCH v3 02/21] target-mips: signal RI Exception on instructions removed in R6 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 Reviewed-by: Aurelien Jarno --- 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 2f91959..931a580 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1432,6 +1432,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) @@ -7708,10 +7718,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; @@ -7728,6 +7740,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; @@ -7861,6 +7874,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(); @@ -7893,6 +7907,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]; @@ -8117,10 +8132,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; @@ -8137,6 +8154,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; @@ -8246,6 +8264,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]; @@ -8346,6 +8365,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(); @@ -14504,6 +14524,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); @@ -14564,10 +14585,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 */ @@ -14600,6 +14623,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 (ctx->CP0_Config1 & (1 << CP0C1_FP)) { check_cp1_enabled(ctx); @@ -14702,10 +14726,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: @@ -15320,12 +15346,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: @@ -15450,16 +15484,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: @@ -15506,18 +15548,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; @@ -15546,6 +15591,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) break; case OPC_CP3: + check_insn_opc_removed(ctx, ISA_MIPS32R6); if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { check_cp1_enabled(ctx); op1 = MASK_CP3(ctx->opcode); @@ -15588,8 +15634,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); @@ -15597,6 +15644,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);