diff options
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r-- | target-mips/translate.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c index 0d5a054021..31a56b6a44 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -17780,6 +17780,121 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free_i32(tdf); } +static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16))) + uint8_t source = (ctx->opcode >> 11) & 0x1f; + uint8_t dest = (ctx->opcode >> 6) & 0x1f; + TCGv telm = tcg_temp_new(); + TCGv_i32 tsr = tcg_const_i32(source); + TCGv_i32 tdt = tcg_const_i32(dest); + + switch (MASK_MSA_ELM_DF3E(ctx->opcode)) { + case OPC_CTCMSA: + gen_load_gpr(telm, source); + gen_helper_msa_ctcmsa(cpu_env, telm, tdt); + break; + case OPC_CFCMSA: + gen_helper_msa_cfcmsa(telm, cpu_env, tsr); + gen_store_gpr(telm, dest); + break; + case OPC_MOVE_V: + gen_helper_msa_move_v(cpu_env, tdt, tsr); + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception(ctx, EXCP_RI); + break; + } + + tcg_temp_free(telm); + tcg_temp_free_i32(tdt); + tcg_temp_free_i32(tsr); +} + +static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df, + uint32_t n) +{ +#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) + uint8_t ws = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 tws = tcg_const_i32(ws); + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 tn = tcg_const_i32(n); + TCGv_i32 tdf = tcg_const_i32(df); + + switch (MASK_MSA_ELM(ctx->opcode)) { + case OPC_SLDI_df: + gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_SPLATI_df: + gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_INSVE_df: + gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_COPY_S_df: + case OPC_COPY_U_df: + case OPC_INSERT_df: +#if !defined(TARGET_MIPS64) + /* Double format valid only for MIPS64 */ + if (df == DF_DOUBLE) { + generate_exception(ctx, EXCP_RI); + break; + } +#endif + switch (MASK_MSA_ELM(ctx->opcode)) { + case OPC_COPY_S_df: + gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_COPY_U_df: + gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_INSERT_df: + gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn); + break; + } + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception(ctx, EXCP_RI); + } + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(tn); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx) +{ + uint8_t dfn = (ctx->opcode >> 16) & 0x3f; + uint32_t df = 0, n = 0; + + if ((dfn & 0x30) == 0x00) { + n = dfn & 0x0f; + df = DF_BYTE; + } else if ((dfn & 0x38) == 0x20) { + n = dfn & 0x07; + df = DF_HALF; + } else if ((dfn & 0x3c) == 0x30) { + n = dfn & 0x03; + df = DF_WORD; + } else if ((dfn & 0x3e) == 0x38) { + n = dfn & 0x01; + df = DF_DOUBLE; + } else if (dfn == 0x3E) { + /* CTCMSA, CFCMSA, MOVE.V */ + gen_msa_elm_3e(env, ctx); + return; + } else { + generate_exception(ctx, EXCP_RI); + return; + } + + gen_msa_elm_df(env, ctx, df, n); +} + static void gen_msa(CPUMIPSState *env, DisasContext *ctx) { uint32_t opcode = ctx->opcode; @@ -17811,6 +17926,9 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx) case OPC_MSA_3R_15: gen_msa_3r(env, ctx); break; + case OPC_MSA_ELM: + gen_msa_elm(env, ctx); + break; default: MIPS_INVAL("MSA instruction"); generate_exception(ctx, EXCP_RI); |