mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 16:53:55 -06:00
target-mips: add MSA I5 format instruction
add MSA I5 format instructions Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
This commit is contained in:
parent
4c7895465e
commit
80e7159184
3 changed files with 232 additions and 0 deletions
|
@ -113,3 +113,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, int32_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,
|
||||
int32_t s10)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
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)s10;
|
||||
}
|
||||
break;
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
pwd->w[i] = (int32_t)s10;
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
pwd->d[i] = (int64_t)s10;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue