From patchwork Wed Oct 15 09:53:58 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leon Alrae X-Patchwork-Id: 399884 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 C2560140081 for ; Wed, 15 Oct 2014 21:00:47 +1100 (EST) Received: from localhost ([::1]:43392 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XeLNu-0001h5-0e for incoming@patchwork.ozlabs.org; Wed, 15 Oct 2014 06:00:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41828) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XeLIJ-0000Ty-C0 for qemu-devel@nongnu.org; Wed, 15 Oct 2014 05:55:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XeLIE-0000U9-OR for qemu-devel@nongnu.org; Wed, 15 Oct 2014 05:54:59 -0400 Received: from mailapp01.imgtec.com ([195.59.15.196]:24285) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XeLIE-0000Tx-Gi for qemu-devel@nongnu.org; Wed, 15 Oct 2014 05:54:54 -0400 Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id 130C464E156AB for ; Wed, 15 Oct 2014 10:54:49 +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; Wed, 15 Oct 2014 10:54:50 +0100 From: Leon Alrae To: Date: Wed, 15 Oct 2014 10:53:58 +0100 Message-ID: <1413366860-7833-7-git-send-email-leon.alrae@imgtec.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1413366860-7833-1-git-send-email-leon.alrae@imgtec.com> References: <1413366860-7833-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 Subject: [Qemu-devel] [PULL 06/28] target-mips: split decode_opc_special* into *_r6 and *_legacy 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 For better code readability and to avoid 'if' statements for all R6 and preR6 instructions whose opcodes are the same - decode_opc_special* functions are split into functions with _r6 and _legacy suffixes. *_r6 functions will contain instructions which were introduced in R6. *_legacy functions will contain instructions which were removed in R6. Signed-off-by: Leon Alrae Reviewed-by: Aurelien Jarno --- target-mips/translate.c | 228 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 160 insertions(+), 68 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 5b8f762..0c64aeb 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -14482,6 +14482,70 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, /* End MIPSDSP functions. */ +static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) +{ + int rs, rt, rd; + uint32_t op1; + + rs = (ctx->opcode >> 21) & 0x1f; + rt = (ctx->opcode >> 16) & 0x1f; + rd = (ctx->opcode >> 11) & 0x1f; + + op1 = MASK_SPECIAL(ctx->opcode); + switch (op1) { + case OPC_SELEQZ: + case OPC_SELNEZ: + gen_cond_move(ctx, op1, rd, rs, rt); + break; + default: /* Invalid */ + MIPS_INVAL("special_r6"); + generate_exception(ctx, EXCP_RI); + break; + } +} + +static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) +{ + int rs, rt, rd; + uint32_t op1; + + rs = (ctx->opcode >> 21) & 0x1f; + rt = (ctx->opcode >> 16) & 0x1f; + rd = (ctx->opcode >> 11) & 0x1f; + + op1 = MASK_SPECIAL(ctx->opcode); + switch (op1) { + case OPC_MOVN: /* Conditional move */ + case OPC_MOVZ: + check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | + INSN_LOONGSON2E | INSN_LOONGSON2F); + gen_cond_move(ctx, op1, rd, rs, rt); + break; + case OPC_MFHI: /* Move from HI/LO */ + case OPC_MFLO: + gen_HILO(ctx, op1, rs & 3, rd); + break; + case OPC_MTHI: + case OPC_MTLO: /* Move to HI/LO */ + gen_HILO(ctx, op1, rd & 3, rs); + break; + case OPC_MOVCI: + check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); + if (env->CP0_Config1 & (1 << CP0C1_FP)) { + check_cp1_enabled(ctx); + gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, + (ctx->opcode >> 16) & 1); + } else { + generate_exception_err(ctx, EXCP_CpU, 1); + } + break; + default: /* Invalid */ + MIPS_INVAL("special_legacy"); + generate_exception(ctx, EXCP_RI); + break; + } +} + static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) { int rs, rt, rd, sa; @@ -14514,18 +14578,6 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) break; } 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); - break; - case OPC_SELEQZ: - case OPC_SELNEZ: - check_insn(ctx, ISA_MIPS32R6); - gen_cond_move(ctx, op1, rd, rs, rt); - break; case OPC_ADD ... OPC_SUBU: gen_arith(ctx, op1, rd, rs, rt); break; @@ -14580,16 +14632,6 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) case OPC_TNE: gen_trap(ctx, op1, rs, rt, -1); 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 */ #ifdef MIPS_STRICT_STANDARD MIPS_INVAL("PMON / selsl"); @@ -14619,18 +14661,6 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) /* Treat as NOP. */ 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); - gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, - (ctx->opcode >> 16) & 1); - } else { - generate_exception_err(ctx, EXCP_CpU, 1); - } - break; - #if defined(TARGET_MIPS64) /* MIPS64 specific opcodes */ case OPC_DSLL: @@ -14712,14 +14742,29 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_muldiv(ctx, op1, 0, rs, rt); break; #endif + default: + if (ctx->insn_flags & ISA_MIPS32R6) { + decode_opc_special_r6(env, ctx); + } else { + decode_opc_special_legacy(env, 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("special"); + MIPS_INVAL("special2_r6"); generate_exception(ctx, EXCP_RI); break; } } -static void decode_opc_special2(CPUMIPSState *env, DisasContext *ctx) +static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) { int rs, rt, rd; uint32_t op1; @@ -14732,14 +14777,30 @@ static void decode_opc_special2(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; + default: /* Invalid */ + MIPS_INVAL("special2_legacy"); + generate_exception(ctx, EXCP_RI); + break; + } +} + +static void decode_opc_special2(CPUMIPSState *env, DisasContext *ctx) +{ + int rs, rt, rd; + uint32_t op1; + + rs = (ctx->opcode >> 21) & 0x1f; + rt = (ctx->opcode >> 16) & 0x1f; + rd = (ctx->opcode >> 11) & 0x1f; + + op1 = MASK_SPECIAL2(ctx->opcode); + switch (op1) { case OPC_CLO: case OPC_CLZ: check_insn(ctx, ISA_MIPS32); @@ -14783,30 +14844,78 @@ static void decode_opc_special2(CPUMIPSState *env, DisasContext *ctx) 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); + } + } +} + +static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) +{ + int rs, rt; + uint32_t op1; + int16_t imm; + + rs = (ctx->opcode >> 21) & 0x1f; + rt = (ctx->opcode >> 16) & 0x1f; + imm = (int16_t)ctx->opcode >> 7; + + op1 = MASK_SPECIAL3(ctx->opcode); + switch (op1) { + case R6_OPC_SC: + gen_st_cond(ctx, op1, rt, rs, imm); + break; + case R6_OPC_LL: + gen_ld(ctx, op1, rt, rs, imm); + break; default: /* Invalid */ - MIPS_INVAL("special2"); + MIPS_INVAL("special3_r6"); generate_exception(ctx, EXCP_RI); break; } } + +static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t op1; +#if defined(TARGET_MIPS64) + int rd = (ctx->opcode >> 11) & 0x1f; + int rs = (ctx->opcode >> 21) & 0x1f; + int rt = (ctx->opcode >> 16) & 0x1f; +#endif + + op1 = MASK_SPECIAL3(ctx->opcode); + switch (op1) { +#if defined(TARGET_MIPS64) + case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E: + case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E: + case OPC_DMOD_G_2E ... OPC_DMODU_G_2E: + check_insn(ctx, INSN_LOONGSON2E); + gen_loongson_integer(ctx, op1, rd, rs, rt); + break; +#endif + default: /* Invalid */ + MIPS_INVAL("special3_legacy"); + generate_exception(ctx, EXCP_RI); + break; + } +} + static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) { int rs, rt, rd, sa; uint32_t op1, op2; - int16_t imm; rs = (ctx->opcode >> 21) & 0x1f; rt = (ctx->opcode >> 16) & 0x1f; rd = (ctx->opcode >> 11) & 0x1f; sa = (ctx->opcode >> 6) & 0x1f; - imm = (int16_t)ctx->opcode; op1 = MASK_SPECIAL3(ctx->opcode); switch (op1) { - case R6_OPC_LL: - check_insn(ctx, ISA_MIPS32R6); - gen_ld(ctx, op1, rt, rs, imm >> 7); - break; case OPC_EXT: case OPC_INS: check_insn(ctx, ISA_MIPS32R2); @@ -15111,19 +15220,6 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) break; } break; - case R6_OPC_SC: /* OPC_DMOD_G_2E */ - if (ctx->insn_flags & ISA_MIPS32R6) { - gen_st_cond(ctx, op1, rt, rs, imm >> 7); - } else { -#if defined(TARGET_MIPS64) - check_insn(ctx, INSN_LOONGSON2E); - gen_loongson_integer(ctx, op1, rd, rs, rt); -#else - /* Invalid in MIPS32 */ - generate_exception(ctx, EXCP_RI); -#endif - } - break; #if defined(TARGET_MIPS64) case OPC_DEXTM ... OPC_DEXT: case OPC_DINSM ... OPC_DINS: @@ -15137,12 +15233,6 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) op2 = MASK_DBSHFL(ctx->opcode); gen_bshfl(ctx, op2, rt, rd); break; - case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E: - case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E: - case OPC_DMODU_G_2E: - check_insn(ctx, INSN_LOONGSON2E); - gen_loongson_integer(ctx, op1, rd, rs, rt); - break; case OPC_ABSQ_S_QH_DSP: op2 = MASK_ABSQ_S_QH(ctx->opcode); switch (op2) { @@ -15374,10 +15464,12 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) gen_mipsdsp_shift(ctx, op1, rd, rs, rt); break; #endif - default: /* Invalid */ - MIPS_INVAL("special3"); - generate_exception(ctx, EXCP_RI); - break; + default: + if (ctx->insn_flags & ISA_MIPS32R6) { + decode_opc_special3_r6(env, ctx); + } else { + decode_opc_special3_legacy(env, ctx); + } } }