Loading target-mips/helper.h +3 −0 Original line number Diff line number Diff line Loading @@ -929,3 +929,6 @@ DEF_HELPER_4(msa_ftint_s_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_ftint_u_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_ffint_s_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_ffint_u_df, void, env, i32, i32, i32) DEF_HELPER_5(msa_ld_df, void, env, i32, i32, i32, s32) DEF_HELPER_5(msa_st_df, void, env, i32, i32, i32, s32) target-mips/op_helper.c +80 −4 Original line number Diff line number Diff line Loading @@ -90,10 +90,10 @@ static inline type do_##name(CPUMIPSState *env, target_ulong addr, \ } \ } #endif HELPER_LD(lbu, ldub, uint8_t) HELPER_LD(lhu, lduw, uint16_t) HELPER_LD(lw, ldl, int32_t) #ifdef TARGET_MIPS64 HELPER_LD(ld, ldq, int64_t) #endif #undef HELPER_LD #if defined(CONFIG_USER_ONLY) Loading @@ -118,10 +118,9 @@ static inline void do_##name(CPUMIPSState *env, target_ulong addr, \ } #endif HELPER_ST(sb, stb, uint8_t) HELPER_ST(sh, stw, uint16_t) HELPER_ST(sw, stl, uint32_t) #ifdef TARGET_MIPS64 HELPER_ST(sd, stq, uint64_t) #endif #undef HELPER_ST target_ulong helper_clo (target_ulong arg1) Loading Loading @@ -3626,3 +3625,80 @@ FOP_CONDN_S(sune, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status))) FOP_CONDN_S(sne, (float32_lt(fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status))) /* MSA */ /* Data format min and max values */ #define DF_BITS(df) (1 << ((df) + 3)) /* Element-by-element access macros */ #define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df)) void helper_msa_ld_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs, int32_t s10) { wr_t *pwd = &(env->active_fpu.fpr[wd].wr); target_ulong addr = env->active_tc.gpr[rs] + (s10 << df); int i; switch (df) { case DF_BYTE: for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { pwd->b[i] = do_lbu(env, addr + (i << DF_BYTE), env->hflags & MIPS_HFLAG_KSU); } break; case DF_HALF: for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { pwd->h[i] = do_lhu(env, addr + (i << DF_HALF), env->hflags & MIPS_HFLAG_KSU); } break; case DF_WORD: for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { pwd->w[i] = do_lw(env, addr + (i << DF_WORD), env->hflags & MIPS_HFLAG_KSU); } break; case DF_DOUBLE: for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { pwd->d[i] = do_ld(env, addr + (i << DF_DOUBLE), env->hflags & MIPS_HFLAG_KSU); } break; } } void helper_msa_st_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs, int32_t s10) { wr_t *pwd = &(env->active_fpu.fpr[wd].wr); target_ulong addr = env->active_tc.gpr[rs] + (s10 << df); int i; switch (df) { case DF_BYTE: for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { do_sb(env, addr + (i << DF_BYTE), pwd->b[i], env->hflags & MIPS_HFLAG_KSU); } break; case DF_HALF: for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { do_sh(env, addr + (i << DF_HALF), pwd->h[i], env->hflags & MIPS_HFLAG_KSU); } break; case DF_WORD: for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { do_sw(env, addr + (i << DF_WORD), pwd->w[i], env->hflags & MIPS_HFLAG_KSU); } break; case DF_DOUBLE: for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { do_sd(env, addr + (i << DF_DOUBLE), pwd->d[i], env->hflags & MIPS_HFLAG_KSU); } break; } } target-mips/translate.c +48 −1 Original line number Diff line number Diff line Loading @@ -16319,7 +16319,8 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_trap(ctx, op1, rs, rt, -1); break; case OPC_LSA: /* OPC_PMON */ if (ctx->insn_flags & ISA_MIPS32R6) { if ((ctx->insn_flags & ISA_MIPS32R6) || (env->CP0_Config3 & (1 << CP0C3_MSAP))) { decode_opc_special_r6(env, ctx); } else { /* Pmon entry point, also R4010 selsl */ Loading Loading @@ -16417,6 +16418,12 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) break; } break; case OPC_DLSA: if ((ctx->insn_flags & ISA_MIPS32R6) || (env->CP0_Config3 & (1 << CP0C3_MSAP))) { decode_opc_special_r6(env, ctx); } break; #endif default: if (ctx->insn_flags & ISA_MIPS32R6) { Loading Loading @@ -18279,6 +18286,46 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx) case OPC_MSA_VEC: gen_msa_vec(env, ctx); break; case OPC_LD_B: case OPC_LD_H: case OPC_LD_W: case OPC_LD_D: case OPC_ST_B: case OPC_ST_H: case OPC_ST_W: case OPC_ST_D: { int32_t s10 = sextract32(ctx->opcode, 16, 10); uint8_t rs = (ctx->opcode >> 11) & 0x1f; uint8_t wd = (ctx->opcode >> 6) & 0x1f; uint8_t df = (ctx->opcode >> 0) & 0x3; TCGv_i32 tdf = tcg_const_i32(df); TCGv_i32 twd = tcg_const_i32(wd); TCGv_i32 trs = tcg_const_i32(rs); TCGv_i32 ts10 = tcg_const_i32(s10); switch (MASK_MSA_MINOR(opcode)) { case OPC_LD_B: case OPC_LD_H: case OPC_LD_W: case OPC_LD_D: gen_helper_msa_ld_df(cpu_env, tdf, twd, trs, ts10); break; case OPC_ST_B: case OPC_ST_H: case OPC_ST_W: case OPC_ST_D: gen_helper_msa_st_df(cpu_env, tdf, twd, trs, ts10); break; } tcg_temp_free_i32(twd); tcg_temp_free_i32(tdf); tcg_temp_free_i32(trs); tcg_temp_free_i32(ts10); } break; default: MIPS_INVAL("MSA instruction"); generate_exception(ctx, EXCP_RI); Loading
target-mips/helper.h +3 −0 Original line number Diff line number Diff line Loading @@ -929,3 +929,6 @@ DEF_HELPER_4(msa_ftint_s_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_ftint_u_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_ffint_s_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_ffint_u_df, void, env, i32, i32, i32) DEF_HELPER_5(msa_ld_df, void, env, i32, i32, i32, s32) DEF_HELPER_5(msa_st_df, void, env, i32, i32, i32, s32)
target-mips/op_helper.c +80 −4 Original line number Diff line number Diff line Loading @@ -90,10 +90,10 @@ static inline type do_##name(CPUMIPSState *env, target_ulong addr, \ } \ } #endif HELPER_LD(lbu, ldub, uint8_t) HELPER_LD(lhu, lduw, uint16_t) HELPER_LD(lw, ldl, int32_t) #ifdef TARGET_MIPS64 HELPER_LD(ld, ldq, int64_t) #endif #undef HELPER_LD #if defined(CONFIG_USER_ONLY) Loading @@ -118,10 +118,9 @@ static inline void do_##name(CPUMIPSState *env, target_ulong addr, \ } #endif HELPER_ST(sb, stb, uint8_t) HELPER_ST(sh, stw, uint16_t) HELPER_ST(sw, stl, uint32_t) #ifdef TARGET_MIPS64 HELPER_ST(sd, stq, uint64_t) #endif #undef HELPER_ST target_ulong helper_clo (target_ulong arg1) Loading Loading @@ -3626,3 +3625,80 @@ FOP_CONDN_S(sune, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status))) FOP_CONDN_S(sne, (float32_lt(fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status))) /* MSA */ /* Data format min and max values */ #define DF_BITS(df) (1 << ((df) + 3)) /* Element-by-element access macros */ #define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df)) void helper_msa_ld_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs, int32_t s10) { wr_t *pwd = &(env->active_fpu.fpr[wd].wr); target_ulong addr = env->active_tc.gpr[rs] + (s10 << df); int i; switch (df) { case DF_BYTE: for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { pwd->b[i] = do_lbu(env, addr + (i << DF_BYTE), env->hflags & MIPS_HFLAG_KSU); } break; case DF_HALF: for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { pwd->h[i] = do_lhu(env, addr + (i << DF_HALF), env->hflags & MIPS_HFLAG_KSU); } break; case DF_WORD: for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { pwd->w[i] = do_lw(env, addr + (i << DF_WORD), env->hflags & MIPS_HFLAG_KSU); } break; case DF_DOUBLE: for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { pwd->d[i] = do_ld(env, addr + (i << DF_DOUBLE), env->hflags & MIPS_HFLAG_KSU); } break; } } void helper_msa_st_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs, int32_t s10) { wr_t *pwd = &(env->active_fpu.fpr[wd].wr); target_ulong addr = env->active_tc.gpr[rs] + (s10 << df); int i; switch (df) { case DF_BYTE: for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { do_sb(env, addr + (i << DF_BYTE), pwd->b[i], env->hflags & MIPS_HFLAG_KSU); } break; case DF_HALF: for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { do_sh(env, addr + (i << DF_HALF), pwd->h[i], env->hflags & MIPS_HFLAG_KSU); } break; case DF_WORD: for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { do_sw(env, addr + (i << DF_WORD), pwd->w[i], env->hflags & MIPS_HFLAG_KSU); } break; case DF_DOUBLE: for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { do_sd(env, addr + (i << DF_DOUBLE), pwd->d[i], env->hflags & MIPS_HFLAG_KSU); } break; } }
target-mips/translate.c +48 −1 Original line number Diff line number Diff line Loading @@ -16319,7 +16319,8 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_trap(ctx, op1, rs, rt, -1); break; case OPC_LSA: /* OPC_PMON */ if (ctx->insn_flags & ISA_MIPS32R6) { if ((ctx->insn_flags & ISA_MIPS32R6) || (env->CP0_Config3 & (1 << CP0C3_MSAP))) { decode_opc_special_r6(env, ctx); } else { /* Pmon entry point, also R4010 selsl */ Loading Loading @@ -16417,6 +16418,12 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) break; } break; case OPC_DLSA: if ((ctx->insn_flags & ISA_MIPS32R6) || (env->CP0_Config3 & (1 << CP0C3_MSAP))) { decode_opc_special_r6(env, ctx); } break; #endif default: if (ctx->insn_flags & ISA_MIPS32R6) { Loading Loading @@ -18279,6 +18286,46 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx) case OPC_MSA_VEC: gen_msa_vec(env, ctx); break; case OPC_LD_B: case OPC_LD_H: case OPC_LD_W: case OPC_LD_D: case OPC_ST_B: case OPC_ST_H: case OPC_ST_W: case OPC_ST_D: { int32_t s10 = sextract32(ctx->opcode, 16, 10); uint8_t rs = (ctx->opcode >> 11) & 0x1f; uint8_t wd = (ctx->opcode >> 6) & 0x1f; uint8_t df = (ctx->opcode >> 0) & 0x3; TCGv_i32 tdf = tcg_const_i32(df); TCGv_i32 twd = tcg_const_i32(wd); TCGv_i32 trs = tcg_const_i32(rs); TCGv_i32 ts10 = tcg_const_i32(s10); switch (MASK_MSA_MINOR(opcode)) { case OPC_LD_B: case OPC_LD_H: case OPC_LD_W: case OPC_LD_D: gen_helper_msa_ld_df(cpu_env, tdf, twd, trs, ts10); break; case OPC_ST_B: case OPC_ST_H: case OPC_ST_W: case OPC_ST_D: gen_helper_msa_st_df(cpu_env, tdf, twd, trs, ts10); break; } tcg_temp_free_i32(twd); tcg_temp_free_i32(tdf); tcg_temp_free_i32(trs); tcg_temp_free_i32(ts10); } break; default: MIPS_INVAL("MSA instruction"); generate_exception(ctx, EXCP_RI);