From patchwork Mon Jul 14 09:55:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yongbok Kim X-Patchwork-Id: 369553 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 2C6FD14007D for ; Mon, 14 Jul 2014 19:59:21 +1000 (EST) Received: from localhost ([::1]:55527 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X6d2U-0007tZ-50 for incoming@patchwork.ozlabs.org; Mon, 14 Jul 2014 05:59:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40341) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X6czd-0003EV-Om for qemu-devel@nongnu.org; Mon, 14 Jul 2014 05:56:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X6czY-0003dr-8D for qemu-devel@nongnu.org; Mon, 14 Jul 2014 05:56:21 -0400 Received: from mailapp01.imgtec.com ([195.59.15.196]:52013) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X6czX-0003dR-Vv for qemu-devel@nongnu.org; Mon, 14 Jul 2014 05:56:16 -0400 Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id E3C5837CE0B00; Mon, 14 Jul 2014 10:56:11 +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; Mon, 14 Jul 2014 10:56:13 +0100 From: Yongbok Kim To: Date: Mon, 14 Jul 2014 10:55:53 +0100 Message-ID: <1405331763-57126-11-git-send-email-yongbok.kim@imgtec.com> X-Mailer: git-send-email 1.7.4 In-Reply-To: <1405331763-57126-1-git-send-email-yongbok.kim@imgtec.com> References: <1405331763-57126-1-git-send-email-yongbok.kim@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 Subject: [Qemu-devel] [PATCH 10/20] target-mips: add MSA I8 format instructions 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 add MSA I8 format instructions Signed-off-by: Yongbok Kim Reviewed-by: James Hogan --- target-mips/helper.h | 11 ++++ target-mips/msa_helper.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++ target-mips/translate.c | 94 ++++++++++++++++++++++++++++++- 3 files changed, 243 insertions(+), 2 deletions(-) diff --git a/target-mips/helper.h b/target-mips/helper.h index 74ef094..174bc62 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -689,3 +689,14 @@ DEF_HELPER_FLAGS_3(dmthlip, 0, void, tl, tl, env) #endif DEF_HELPER_FLAGS_3(wrdsp, 0, void, tl, tl, env) DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env) + +/* MIPS SIMD Architecture */ + +DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bmnzi_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bmzi_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bseli_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) +DEF_HELPER_5(msa_shf_df, void, env, i32, i32, i32, i32) +DEF_HELPER_4(msa_xori_b, void, env, i32, i32, i32) diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c index 5afc9ae..2355809 100644 --- a/target-mips/msa_helper.c +++ b/target-mips/msa_helper.c @@ -194,3 +194,143 @@ static inline void msa_store_wr_elem(CPUMIPSState *env, uint64_t val, assert(0); } } + +void helper_msa_andi_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, + uint32_t i8) +{ + void *pwd = &(env->active_fpu.fpr[wd]); + void *pws = &(env->active_fpu.fpr[ws]); + ALL_B_ELEMENTS(i, MSA_WRLEN) { + B(pwd, i) = B(pws, i) & i8; + } DONE_ALL_ELEMENTS; + if (env->active_msa.msair & MSAIR_WRP_BIT) { + env->active_msa.msamodify |= (1 << wd); + } +} + +void helper_msa_ori_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, + uint32_t i8) +{ + void *pwd = &(env->active_fpu.fpr[wd]); + void *pws = &(env->active_fpu.fpr[ws]); + ALL_B_ELEMENTS(i, MSA_WRLEN) { + B(pwd, i) = B(pws, i) | i8; + } DONE_ALL_ELEMENTS; + if (env->active_msa.msair & MSAIR_WRP_BIT) { + env->active_msa.msamodify |= (1 << wd); + } +} + +void helper_msa_nori_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, + uint32_t i8) +{ + void *pwd = &(env->active_fpu.fpr[wd]); + void *pws = &(env->active_fpu.fpr[ws]); + ALL_B_ELEMENTS(i, MSA_WRLEN) { + B(pwd, i) = ~(B(pws, i) | i8); + } DONE_ALL_ELEMENTS; + if (env->active_msa.msair & MSAIR_WRP_BIT) { + env->active_msa.msamodify |= (1 << wd); + } +} + +void helper_msa_xori_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, + uint32_t i8) +{ + void *pwd = &(env->active_fpu.fpr[wd]); + void *pws = &(env->active_fpu.fpr[ws]); + ALL_B_ELEMENTS(i, MSA_WRLEN) { + B(pwd, i) = B(pws, i) ^ i8; + } DONE_ALL_ELEMENTS; + if (env->active_msa.msair & MSAIR_WRP_BIT) { + env->active_msa.msamodify |= (1 << wd); + } +} + +#define BIT_MOVE_IF_NOT_ZERO(dest, arg1, arg2, df) \ + dest = UNSIGNED(((dest & (~arg2)) | (arg1 & arg2)), df) + +void helper_msa_bmnzi_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, + uint32_t i8) +{ + void *pwd = &(env->active_fpu.fpr[wd]); + void *pws = &(env->active_fpu.fpr[ws]); + ALL_B_ELEMENTS(i, MSA_WRLEN) { + BIT_MOVE_IF_NOT_ZERO(B(pwd, i), B(pws, i), i8, DF_BYTE); + } DONE_ALL_ELEMENTS; + if (env->active_msa.msair & MSAIR_WRP_BIT) { + env->active_msa.msamodify |= (1 << wd); + } +} + +#define BIT_MOVE_IF_ZERO(dest, arg1, arg2, df) \ + dest = UNSIGNED((dest & arg2) | (arg1 & (~arg2)), df) + +void helper_msa_bmzi_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, + uint32_t i8) +{ + void *pwd = &(env->active_fpu.fpr[wd]); + void *pws = &(env->active_fpu.fpr[ws]); + ALL_B_ELEMENTS(i, MSA_WRLEN) { + BIT_MOVE_IF_ZERO(B(pwd, i), B(pws, i), i8, DF_BYTE); + } DONE_ALL_ELEMENTS; + if (env->active_msa.msair & MSAIR_WRP_BIT) { + env->active_msa.msamodify |= (1 << wd); + } +} + +#define BIT_SELECT(dest, arg1, arg2, df) \ + dest = UNSIGNED((arg1 & (~dest)) | (arg2 & dest), df) + +void helper_msa_bseli_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, + uint32_t i8) +{ + void *pwd = &(env->active_fpu.fpr[wd]); + void *pws = &(env->active_fpu.fpr[ws]); + ALL_B_ELEMENTS(i, MSA_WRLEN) { + BIT_SELECT(B(pwd, i), B(pws, i), i8, DF_BYTE); + } DONE_ALL_ELEMENTS; + if (env->active_msa.msair & MSAIR_WRP_BIT) { + env->active_msa.msamodify |= (1 << wd); + } +} + +#define SHF_POS(i, imm) ((i & 0xfc) + ((imm >> (2 * (i & 0x03))) & 0x03)) + +static inline void msa_shf_df(CPUMIPSState *env, uint32_t df, void *pwd, + void *pws, uint32_t imm) +{ + wr_t wx, *pwx = &wx; + switch (df) { + case DF_BYTE: + ALL_B_ELEMENTS(i, MSA_WRLEN) { + B(pwx, i) = B(pws, SHF_POS(i, imm)); + } DONE_ALL_ELEMENTS; + break; + case DF_HALF: + ALL_H_ELEMENTS(i, MSA_WRLEN) { + H(pwx, i) = H(pws, SHF_POS(i, imm)); + } DONE_ALL_ELEMENTS; + break; + case DF_WORD: + ALL_W_ELEMENTS(i, MSA_WRLEN) { + W(pwx, i) = W(pws, SHF_POS(i, imm)); + } DONE_ALL_ELEMENTS; + break; + default: + /* shouldn't get here */ + assert(0); + } + msa_move_v(pwd, pwx); +} + +void helper_msa_shf_df(CPUMIPSState *env, uint32_t df, uint32_t wd, + uint32_t ws, uint32_t imm) +{ + void *pwd = &(env->active_fpu.fpr[wd]); + void *pws = &(env->active_fpu.fpr[ws]); + msa_shf_df(env, df, pwd, pws, imm); + if (env->active_msa.msair & MSAIR_WRP_BIT) { + env->active_msa.msamodify |= (1 << wd); + } +} diff --git a/target-mips/translate.c b/target-mips/translate.c index 0bfbcfe..c241299 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -14777,6 +14777,95 @@ static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1) ctx->hflags |= MIPS_HFLAG_BC; } + +static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24))) + + uint32_t opcode = ctx->opcode; + + uint8_t i8 = (opcode >> 16) & 0xff /* i8 [23:16] */; + uint8_t ws = (opcode >> 11) & 0x1f /* ws [15:11] */; + uint8_t wd = (opcode >> 6) & 0x1f /* wd [10:6] */; + + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 tws = tcg_const_i32(ws); + TCGv_i32 ti8 = tcg_const_i32(i8); + + switch (MASK_MSA_I8(opcode)) { + case OPC_MSA_ANDI_B: + check_msa_access(env, ctx, -1, ws, wd); + gen_helper_msa_andi_b(cpu_env, twd, tws, ti8); + break; + case OPC_MSA_ORI_B: + check_msa_access(env, ctx, -1, ws, wd); + gen_helper_msa_ori_b(cpu_env, twd, tws, ti8); + break; + case OPC_MSA_NORI_B: + check_msa_access(env, ctx, -1, ws, wd); + gen_helper_msa_nori_b(cpu_env, twd, tws, ti8); + break; + case OPC_MSA_XORI_B: + check_msa_access(env, ctx, -1, ws, wd); + gen_helper_msa_xori_b(cpu_env, twd, tws, ti8); + break; + case OPC_MSA_BMNZI_B: + check_msa_access(env, ctx, -1, ws, wd); + gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8); + break; + case OPC_MSA_BMZI_B: + check_msa_access(env, ctx, -1, ws, wd); + gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8); + break; + case OPC_MSA_BSELI_B: + check_msa_access(env, ctx, -1, ws, wd); + gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8); + break; + case OPC_MSA_SHF_B: + case OPC_MSA_SHF_H: + case OPC_MSA_SHF_W: + { + uint8_t df = (opcode >> 24) & 0x3; + if (df == 3) { + generate_exception(ctx, EXCP_RI); + } else { + TCGv_i32 tdf = tcg_const_i32(df); + check_msa_access(env, ctx, -1, ws, wd); + gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8); + tcg_temp_free_i32(tdf); + } + } + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception(ctx, EXCP_RI); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(ti8); +} + +static void gen_msa(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode = ctx->opcode; + check_insn(ctx, ASE_MSA); + + switch (MASK_MSA_MINOR(opcode)) { + case OPC_MSA_I8_00: + case OPC_MSA_I8_01: + case OPC_MSA_I8_02: + gen_msa_i8(env, ctx); + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception(ctx, EXCP_RI); + break; + } + +} + static void decode_opc (CPUMIPSState *env, DisasContext *ctx) { int32_t offset; @@ -15967,9 +16056,10 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); break; - case OPC_MDMX: - check_insn(ctx, ASE_MDMX); + case OPC_MSA: /* OPC_MDMX */ /* MDMX: Not implemented. */ + gen_msa(env, ctx); + break; default: /* Invalid */ MIPS_INVAL("major opcode"); generate_exception(ctx, EXCP_RI);