[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/20] target-mips: add MSA I8 format instructions
From: |
Yongbok Kim |
Subject: |
[Qemu-devel] [PATCH 10/20] target-mips: add MSA I8 format instructions |
Date: |
Mon, 14 Jul 2014 10:55:53 +0100 |
add MSA I8 format instructions
Signed-off-by: Yongbok Kim <address@hidden>
---
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);
--
1.7.4
- [Qemu-devel] [PATCH 00/20] target-mips: add MSA module, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 01/20] target-mips: add MSA defines and data structure, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 05/20] target-mips: stop translation after ctc1, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 04/20] target-mips: add 8, 16, 32, 64 bits load and store, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 08/20] target-mips: add msa_helper.c, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 07/20] target-mips: add msa_reset(), global msa register, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 03/20] target-mips: move common funcs to cpu.h, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 09/20] target-mips: add MSA branch instructions, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 02/20] target-mips: add MSA exceptions, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 06/20] target-mips: add MSA opcode enum, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 10/20] target-mips: add MSA I8 format instructions,
Yongbok Kim <=
- [Qemu-devel] [PATCH 11/20] target-mips: add MSA I5 format instructions, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 12/20] target-mips: add MSA BIT format instructions, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 14/20] target-mips: add MSA ELM format instructions, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 16/20] target-mips: add MSA VEC/2R format instructions, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 18/20] target-mips: add MSA MI10 format instructions, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 15/20] target-mips: add MSA 3RF format instructions, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 20/20] target-mips: add MSA support to mips32r5-generic, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 13/20] target-mips: add MSA 3R format instructions, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 19/20] disas/mips.c: disassemble MSA instructions, Yongbok Kim, 2014/07/14
- [Qemu-devel] [PATCH 17/20] target-mips: add MSA 2RF format instructions, Yongbok Kim, 2014/07/14