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)
} \
}
#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)
}
#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)
|| 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;
+ }
+}
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 */
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) {
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);