[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 11/20] target-mips: add MSA I5 format instruction
From: |
Yongbok Kim |
Subject: |
[Qemu-devel] [PATCH v2 11/20] target-mips: add MSA I5 format instruction |
Date: |
Wed, 29 Oct 2014 01:41:59 +0000 |
add MSA I5 format instructions
Signed-off-by: Yongbok Kim <address@hidden>
---
target-mips/helper.h | 13 ++++
target-mips/msa_helper.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++
target-mips/translate.c | 79 +++++++++++++++++++++++++
3 files changed, 234 insertions(+), 0 deletions(-)
diff --git a/target-mips/helper.h b/target-mips/helper.h
index ec1c0e5..585eaa9 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -758,3 +758,16 @@ 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)
+
+DEF_HELPER_5(msa_addvi_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_ceqi_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_clei_s_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_clei_u_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_clti_s_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_clti_u_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_4(msa_ldi_df, void, env, i32, i32, i32)
+DEF_HELPER_5(msa_maxi_s_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_maxi_u_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_mini_s_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_mini_u_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_subvi_df, void, env, i32, i32, i32, s64)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index 46ffaa5..ffdde07 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -114,3 +114,145 @@ void helper_msa_shf_df(CPUMIPSState *env, uint32_t df,
uint32_t wd,
msa_move_v(pwd, pwx);
}
+static inline int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ return arg1 + arg2;
+}
+
+static inline int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ return arg1 - arg2;
+}
+
+static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ return arg1 == arg2 ? -1 : 0;
+}
+
+static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ return arg1 <= arg2 ? -1 : 0;
+}
+
+static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ uint64_t u_arg1 = UNSIGNED(arg1, df);
+ uint64_t u_arg2 = UNSIGNED(arg2, df);
+ return u_arg1 <= u_arg2 ? -1 : 0;
+}
+
+static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ return arg1 < arg2 ? -1 : 0;
+}
+
+static inline int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ uint64_t u_arg1 = UNSIGNED(arg1, df);
+ uint64_t u_arg2 = UNSIGNED(arg2, df);
+ return u_arg1 < u_arg2 ? -1 : 0;
+}
+
+static inline int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ return arg1 > arg2 ? arg1 : arg2;
+}
+
+static inline int64_t msa_max_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ uint64_t u_arg1 = UNSIGNED(arg1, df);
+ uint64_t u_arg2 = UNSIGNED(arg2, df);
+ return u_arg1 > u_arg2 ? arg1 : arg2;
+}
+
+static inline int64_t msa_min_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ return arg1 < arg2 ? arg1 : arg2;
+}
+
+static inline int64_t msa_min_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+{
+ uint64_t u_arg1 = UNSIGNED(arg1, df);
+ uint64_t u_arg2 = UNSIGNED(arg2, df);
+ return u_arg1 < u_arg2 ? arg1 : arg2;
+}
+
+#define MSA_BINOP_IMM_DF(helper, func) \
+void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, \
+ uint32_t wd, uint32_t ws, int64_t u5) \
+{ \
+ wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
+ wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
+ uint32_t i; \
+ \
+ switch (df) { \
+ case DF_BYTE: \
+ for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { \
+ pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5); \
+ } \
+ break; \
+ case DF_HALF: \
+ for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { \
+ pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5); \
+ } \
+ break; \
+ case DF_WORD: \
+ for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { \
+ pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5); \
+ } \
+ break; \
+ case DF_DOUBLE: \
+ for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \
+ pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5); \
+ } \
+ break; \
+ default: \
+ assert(0); \
+ } \
+}
+
+MSA_BINOP_IMM_DF(addvi, addv)
+MSA_BINOP_IMM_DF(subvi, subv)
+MSA_BINOP_IMM_DF(ceqi, ceq)
+MSA_BINOP_IMM_DF(clei_s, cle_s)
+MSA_BINOP_IMM_DF(clei_u, cle_u)
+MSA_BINOP_IMM_DF(clti_s, clt_s)
+MSA_BINOP_IMM_DF(clti_u, clt_u)
+MSA_BINOP_IMM_DF(maxi_s, max_s)
+MSA_BINOP_IMM_DF(maxi_u, max_u)
+MSA_BINOP_IMM_DF(mini_s, min_s)
+MSA_BINOP_IMM_DF(mini_u, min_u)
+#undef MSA_BINOP_IMM_DF
+
+void helper_msa_ldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+ uint32_t s10)
+{
+ wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+ int64_t s64 = ((int64_t)s10 << 54) >> 54;
+ uint32_t i;
+
+ switch (df) {
+ case DF_BYTE:
+ for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
+ pwd->b[i] = (int8_t)s10;
+ }
+ break;
+ case DF_HALF:
+ for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
+ pwd->h[i] = (int16_t)s64;
+ }
+ break;
+ case DF_WORD:
+ for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
+ pwd->w[i] = (int32_t)s64;
+ }
+ break;
+ case DF_DOUBLE:
+ for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
+ pwd->d[i] = s64;
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
diff --git a/target-mips/translate.c b/target-mips/translate.c
index b2934d7..62dd0b9 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -17395,6 +17395,81 @@ static void gen_msa_i8(CPUMIPSState *env, DisasContext
*ctx)
tcg_temp_free_i32(ti8);
}
+static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
+{
+#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
+ uint32_t opcode = ctx->opcode;
+
+ uint8_t df = (ctx->opcode >> 21) & 0x3;
+ int64_t s5 = (ctx->opcode >> 16) & 0x1f;
+ s5 = (s5 << 59) >> 59; /* sign extend s5 to 64 bits*/
+ uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
+ uint8_t ws = (ctx->opcode >> 11) & 0x1f;
+ uint8_t wd = (ctx->opcode >> 6) & 0x1f;
+
+ TCGv_i32 tdf = tcg_const_i32(df);
+ TCGv_i32 twd = tcg_const_i32(wd);
+ TCGv_i32 tws = tcg_const_i32(ws);
+ TCGv_i64 tu5 = tcg_const_i64(u5);
+ TCGv_i64 ts5 = tcg_const_i64(s5);
+
+ switch (MASK_MSA_I5(opcode)) {
+ case OPC_ADDVI_df:
+ gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, tu5);
+ break;
+ case OPC_SUBVI_df:
+ gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, tu5);
+ break;
+ case OPC_MAXI_S_df:
+ gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, ts5);
+ break;
+ case OPC_MAXI_U_df:
+ gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, tu5);
+ break;
+ case OPC_MINI_S_df:
+ gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, ts5);
+ break;
+ case OPC_MINI_U_df:
+ gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, tu5);
+ break;
+ case OPC_CEQI_df:
+ gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, ts5);
+ break;
+ case OPC_CLTI_S_df:
+ gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, ts5);
+ break;
+ case OPC_CLTI_U_df:
+ gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, tu5);
+ break;
+ case OPC_CLEI_S_df:
+ gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, ts5);
+ break;
+ case OPC_CLEI_U_df:
+ gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, tu5);
+ break;
+ case OPC_LDI_df:
+ {
+ int64_t s10 = (ctx->opcode >> 11) & 0x3ff;
+ s10 = (s10 << 54) >> 54; /* sign extend s10 to 64 bits*/
+
+ TCGv_i32 ts10 = tcg_const_i32(s10);
+ gen_helper_msa_ldi_df(cpu_env, tdf, twd, ts10);
+ tcg_temp_free_i32(ts10);
+ }
+ break;
+ default:
+ MIPS_INVAL("MSA instruction");
+ generate_exception(ctx, EXCP_RI);
+ break;
+ }
+
+ tcg_temp_free_i32(tdf);
+ tcg_temp_free_i32(twd);
+ tcg_temp_free_i32(tws);
+ tcg_temp_free_i64(tu5);
+ tcg_temp_free_i64(ts5);
+}
+
static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
{
uint32_t opcode = ctx->opcode;
@@ -17407,6 +17482,10 @@ static void gen_msa(CPUMIPSState *env, DisasContext
*ctx)
case OPC_MSA_I8_02:
gen_msa_i8(env, ctx);
break;
+ case OPC_MSA_I5_06:
+ case OPC_MSA_I5_07:
+ gen_msa_i5(env, ctx);
+ break;
default:
MIPS_INVAL("MSA instruction");
generate_exception(ctx, EXCP_RI);
--
1.7.4
- [Qemu-devel] [PATCH v2 06/20] target-mips: add MSA opcode enum, (continued)
- [Qemu-devel] [PATCH v2 06/20] target-mips: add MSA opcode enum, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 07/20] target-mips: add msa_reset(), global msa register, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 08/20] target-mips: add msa_helper.c, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 09/20] target-mips: add MSA branch instructions, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 10/20] target-mips: add MSA I8 format instructions, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 11/20] target-mips: add MSA I5 format instruction,
Yongbok Kim <=
- [Qemu-devel] [PATCH v2 12/20] target-mips: add MSA BIT format instructions, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 14/20] target-mips: add MSA ELM format instructions, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 13/20] target-mips: add MSA 3R format instructions, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 16/20] target-mips: add MSA VEC/2R format instructions, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 17/20] target-mips: add MSA 2RF format instructions, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 18/20] target-mips: add MSA MI10 format instructions, Yongbok Kim, 2014/10/28
- [Qemu-devel] [PATCH v2 15/20] target-mips: add MSA 3RF format instructions, Yongbok Kim, 2014/10/28