target-mips: add MSA MI10 format instructions
add MSA MI10 format instructions update LSA and DLSA for MSA add 16, 64 bit load and store Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
This commit is contained in:
		
							parent
							
								
									3bdeb68866
								
							
						
					
					
						commit
						f7685877f5
					
				| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -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…
	
		Reference in New Issue