From patchwork Wed Jun 11 15:19:40 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leon Alrae X-Patchwork-Id: 358748 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 9D7F2140085 for ; Thu, 12 Jun 2014 01:25:21 +1000 (EST) Received: from localhost ([::1]:47266 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WukOt-0007w0-96 for incoming@patchwork.ozlabs.org; Wed, 11 Jun 2014 11:25:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55343) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WukKm-0001NZ-2B for qemu-devel@nongnu.org; Wed, 11 Jun 2014 11:21:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WukKh-00045r-Gu for qemu-devel@nongnu.org; Wed, 11 Jun 2014 11:21:03 -0400 Received: from mailapp01.imgtec.com ([195.59.15.196]:30058) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WukKh-00045S-95 for qemu-devel@nongnu.org; Wed, 11 Jun 2014 11:20:59 -0400 Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id B1BD7ADC909CA; Wed, 11 Jun 2014 16:20:54 +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.181.6; Wed, 11 Jun 2014 16:20:56 +0100 From: Leon Alrae To: Date: Wed, 11 Jun 2014 16:19:40 +0100 Message-ID: <1402499992-64851-11-git-send-email-leon.alrae@imgtec.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1402499992-64851-1-git-send-email-leon.alrae@imgtec.com> References: <1402499992-64851-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 v2 10/22] target-mips: move CLO, DCLO, CLZ, DCLZ, SDBBP and free special2 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 Also consider OPC_SPIM instruction as deleted in R6 because it is overlaping with MIPS32R6 SDBBP. Signed-off-by: Leon Alrae Reviewed-by: Aurelien Jarno --- v2: * check_insn_opc_removed() moved to decode_opc_special2_legacy() --- disas/mips.c | 5 ++ target-mips/translate.c | 121 ++++++++++++++++++++++++----------------------- 2 files changed, 67 insertions(+), 59 deletions(-) diff --git a/disas/mips.c b/disas/mips.c index db8d9ee..8cb9032 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -1217,6 +1217,11 @@ const struct mips_opcode mips_builtin_opcodes[] = them first. The assemblers uses a hash table based on the instruction name anyhow. */ /* name, args, match, mask, pinfo, membership */ +{"clz", "U,s", 0x00000050, 0xfc0007ff, WR_d|RD_s, 0, I32R6}, +{"clo", "U,s", 0x00000051, 0xfc0007ff, WR_d|RD_s, 0, I32R6}, +{"dclz", "U,s", 0x00000052, 0xfc0007ff, WR_d|RD_s, 0, I64R6}, +{"dclo", "U,s", 0x00000053, 0xfc0007ff, WR_d|RD_s, 0, I64R6}, +{"sdbbp", "B", 0x0000000e, 0xfc00003f, TRAP, 0, I32R6}, {"mul", "d,s,t", 0x00000098, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {"muh", "d,s,t", 0x000000d8, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {"mulu", "d,s,t", 0x00000099, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, diff --git a/target-mips/translate.c b/target-mips/translate.c index 68834a7..8472fae 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -233,6 +233,12 @@ enum { R6_OPC_DMOD = OPC_DDIV | (3 << 6), R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), R6_OPC_DMODU = OPC_DDIVU | (3 << 6), + + R6_OPC_CLZ = 0x10 | OPC_SPECIAL, + R6_OPC_CLO = 0x11 | OPC_SPECIAL, + R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, + R6_OPC_DCLO = 0x13 | OPC_SPECIAL, + R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, }; /* Multiplication variants of the vr54xx. */ @@ -3259,19 +3265,23 @@ static void gen_cl (DisasContext *ctx, uint32_t opc, gen_load_gpr(t0, rs); switch (opc) { case OPC_CLO: + case R6_OPC_CLO: gen_helper_clo(cpu_gpr[rd], t0); opn = "clo"; break; case OPC_CLZ: + case R6_OPC_CLZ: gen_helper_clz(cpu_gpr[rd], t0); opn = "clz"; break; #if defined(TARGET_MIPS64) case OPC_DCLO: + case R6_OPC_DCLO: gen_helper_dclo(cpu_gpr[rd], t0); opn = "dclo"; break; case OPC_DCLZ: + case R6_OPC_DCLZ: gen_helper_dclz(cpu_gpr[rd], t0); opn = "dclz"; break; @@ -14696,12 +14706,13 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) { - int rs, rt, rd; + int rs, rt, rd, sa; uint32_t op1, op2; rs = (ctx->opcode >> 21) & 0x1f; rt = (ctx->opcode >> 16) & 0x1f; rd = (ctx->opcode >> 11) & 0x1f; + sa = (ctx->opcode >> 6) & 0x1f; op1 = MASK_SPECIAL(ctx->opcode); switch (op1) { @@ -14728,7 +14739,31 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) case OPC_SELNEZ: gen_cond_move(ctx, op1, rd, rs, rt); break; + case R6_OPC_CLO: + case R6_OPC_CLZ: + if (rt == 0 && sa == 1) { + /* Major opcode and function field is shared with preR6 MFHI/MTHI. + We need additionally to check other fields */ + gen_cl(ctx, op1, rd, rs); + } else { + generate_exception(ctx, EXCP_RI); + } + break; + case R6_OPC_SDBBP: + generate_exception(ctx, EXCP_DBp); + break; #if defined(TARGET_MIPS64) + case R6_OPC_DCLO: + case R6_OPC_DCLZ: + if (rt == 0 && sa == 1) { + /* Major opcode and function field is shared with preR6 MFHI/MTHI. + We need additionally to check other fields */ + check_mips_64(ctx); + gen_cl(ctx, op1, rd, rs); + } else { + generate_exception(ctx, EXCP_RI); + } + break; case OPC_DMULT ... OPC_DDIVU: op2 = MASK_R6_MULDIV(ctx->opcode); switch (op2) { @@ -14814,6 +14849,16 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) gen_muldiv(ctx, op1, 0, rs, rt); break; #endif + case OPC_SPIM: +#ifdef MIPS_STRICT_STANDARD + MIPS_INVAL("SPIM"); + generate_exception(ctx, EXCP_RI); +#else + /* Implemented as RI exception for now. */ + MIPS_INVAL("spim (unofficial)"); + generate_exception(ctx, EXCP_RI); +#endif + break; default: /* Invalid */ MIPS_INVAL("special_legacy"); generate_exception(ctx, EXCP_RI); @@ -14908,16 +14953,6 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) case OPC_BREAK: generate_exception(ctx, EXCP_BREAK); break; - case OPC_SPIM: -#ifdef MIPS_STRICT_STANDARD - MIPS_INVAL("SPIM"); - generate_exception(ctx, EXCP_RI); -#else - /* Implemented as RI exception for now. */ - MIPS_INVAL("spim (unofficial)"); - generate_exception(ctx, EXCP_RI); -#endif - break; case OPC_SYNC: /* Treat as NOP. */ break; @@ -15007,24 +15042,13 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) } } -static void decode_opc_special2_r6(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t op1; - - op1 = MASK_SPECIAL2(ctx->opcode); - switch (op1) { - default: /* Invalid */ - MIPS_INVAL("special2_r6"); - generate_exception(ctx, EXCP_RI); - break; - } -} - static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) { int rs, rt, rd; uint32_t op1; + check_insn_opc_removed(ctx, ISA_MIPS32R6); + rs = (ctx->opcode >> 21) & 0x1f; rt = (ctx->opcode >> 16) & 0x1f; rd = (ctx->opcode >> 11) & 0x1f; @@ -15048,34 +15072,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) check_insn(ctx, INSN_LOONGSON2F); gen_loongson_integer(ctx, op1, rd, rs, rt); break; -#if defined(TARGET_MIPS64) - case OPC_DMULT_G_2F: - case OPC_DMULTU_G_2F: - case OPC_DDIV_G_2F: - case OPC_DDIVU_G_2F: - case OPC_DMOD_G_2F: - case OPC_DMODU_G_2F: - check_insn(ctx, INSN_LOONGSON2F); - gen_loongson_integer(ctx, op1, rd, rs, rt); - break; -#endif - default: /* Invalid */ - MIPS_INVAL("special2_legacy"); - generate_exception(ctx, EXCP_RI); - break; - } -} - -static void decode_opc_special2(CPUMIPSState *env, DisasContext *ctx) -{ - int rs, rd; - uint32_t op1; - - rs = (ctx->opcode >> 21) & 0x1f; - rd = (ctx->opcode >> 11) & 0x1f; - - op1 = MASK_SPECIAL2(ctx->opcode); - switch (op1) { case OPC_CLO: case OPC_CLZ: check_insn(ctx, ISA_MIPS32); @@ -15100,13 +15096,20 @@ static void decode_opc_special2(CPUMIPSState *env, DisasContext *ctx) check_mips_64(ctx); gen_cl(ctx, op1, rd, rs); break; + case OPC_DMULT_G_2F: + case OPC_DMULTU_G_2F: + case OPC_DDIV_G_2F: + case OPC_DDIVU_G_2F: + case OPC_DMOD_G_2F: + case OPC_DMODU_G_2F: + check_insn(ctx, INSN_LOONGSON2F); + gen_loongson_integer(ctx, op1, rd, rs, rt); + break; #endif - default: - if (ctx->insn_flags & ISA_MIPS32R6) { - decode_opc_special2_r6(env, ctx); - } else { - decode_opc_special2_legacy(env, ctx); - } + default: /* Invalid */ + MIPS_INVAL("special2_legacy"); + generate_exception(ctx, EXCP_RI); + break; } } @@ -15785,7 +15788,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) decode_opc_special(env, ctx); break; case OPC_SPECIAL2: - decode_opc_special2(env, ctx); + decode_opc_special2_legacy(env, ctx); break; case OPC_SPECIAL3: decode_opc_special3(env, ctx);