mirror of https://github.com/xemu-project/xemu.git
target-mips: add MSA 3R format instructions
add MSA 3R format instructions Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
This commit is contained in:
parent
d4cf28dec2
commit
28f99f08cf
|
@ -784,3 +784,67 @@ DEF_HELPER_5(msa_sat_s_df, void, env, i32, i32, i32, i32)
|
|||
DEF_HELPER_5(msa_sat_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_srari_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_srlri_df, void, env, i32, i32, i32, i32)
|
||||
|
||||
DEF_HELPER_5(msa_sll_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_sra_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_srl_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_bclr_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_bset_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_bneg_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_binsl_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_binsr_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_addv_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_subv_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_max_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_max_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_min_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_min_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_max_a_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_min_a_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_ceq_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_clt_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_clt_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_cle_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_cle_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_add_a_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_adds_a_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_adds_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_adds_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_ave_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_ave_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_aver_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_aver_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_subs_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_subs_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_subsus_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_subsuu_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_asub_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_asub_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_mulv_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_maddv_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_msubv_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_div_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_div_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_mod_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_mod_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_dotp_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_dotp_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_dpadd_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_dpadd_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_dpsub_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_dpsub_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_sld_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_splat_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_pckev_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_pckod_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_ilvl_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_ilvr_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_ilvev_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_ilvod_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_srar_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_srlr_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_hadd_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_hadd_u_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_hsub_s_df, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32)
|
||||
|
|
|
@ -451,3 +451,660 @@ void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, \
|
|||
MSA_TEROP_IMMU_DF(binsli, binsl)
|
||||
MSA_TEROP_IMMU_DF(binsri, binsr)
|
||||
#undef MSA_TEROP_IMMU_DF
|
||||
|
||||
static inline int64_t msa_max_a_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
|
||||
uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
|
||||
return abs_arg1 > abs_arg2 ? arg1 : arg2;
|
||||
}
|
||||
|
||||
static inline int64_t msa_min_a_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
|
||||
uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
|
||||
return abs_arg1 < abs_arg2 ? arg1 : arg2;
|
||||
}
|
||||
|
||||
static inline int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
|
||||
uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
|
||||
return abs_arg1 + abs_arg2;
|
||||
}
|
||||
|
||||
static inline int64_t msa_adds_a_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
uint64_t max_int = (uint64_t)DF_MAX_INT(df);
|
||||
uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
|
||||
uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
|
||||
if (abs_arg1 > max_int || abs_arg2 > max_int) {
|
||||
return (int64_t)max_int;
|
||||
} else {
|
||||
return (abs_arg1 < max_int - abs_arg2) ? abs_arg1 + abs_arg2 : max_int;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int64_t msa_adds_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
int64_t max_int = DF_MAX_INT(df);
|
||||
int64_t min_int = DF_MIN_INT(df);
|
||||
if (arg1 < 0) {
|
||||
return (min_int - arg1 < arg2) ? arg1 + arg2 : min_int;
|
||||
} else {
|
||||
return (arg2 < max_int - arg1) ? arg1 + arg2 : max_int;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
|
||||
{
|
||||
uint64_t max_uint = DF_MAX_UINT(df);
|
||||
uint64_t u_arg1 = UNSIGNED(arg1, df);
|
||||
uint64_t u_arg2 = UNSIGNED(arg2, df);
|
||||
return (u_arg1 < max_uint - u_arg2) ? u_arg1 + u_arg2 : max_uint;
|
||||
}
|
||||
|
||||
static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
/* signed shift */
|
||||
return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1);
|
||||
}
|
||||
|
||||
static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
|
||||
{
|
||||
uint64_t u_arg1 = UNSIGNED(arg1, df);
|
||||
uint64_t u_arg2 = UNSIGNED(arg2, df);
|
||||
/* unsigned shift */
|
||||
return (u_arg1 >> 1) + (u_arg2 >> 1) + (u_arg1 & u_arg2 & 1);
|
||||
}
|
||||
|
||||
static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
/* signed shift */
|
||||
return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1);
|
||||
}
|
||||
|
||||
static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
|
||||
{
|
||||
uint64_t u_arg1 = UNSIGNED(arg1, df);
|
||||
uint64_t u_arg2 = UNSIGNED(arg2, df);
|
||||
/* unsigned shift */
|
||||
return (u_arg1 >> 1) + (u_arg2 >> 1) + ((u_arg1 | u_arg2) & 1);
|
||||
}
|
||||
|
||||
static inline int64_t msa_subs_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
int64_t max_int = DF_MAX_INT(df);
|
||||
int64_t min_int = DF_MIN_INT(df);
|
||||
if (arg2 > 0) {
|
||||
return (min_int + arg2 < arg1) ? arg1 - arg2 : min_int;
|
||||
} else {
|
||||
return (arg1 < max_int + arg2) ? arg1 - arg2 : max_int;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int64_t msa_subs_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) ? u_arg1 - u_arg2 : 0;
|
||||
}
|
||||
|
||||
static inline int64_t msa_subsus_u_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
uint64_t u_arg1 = UNSIGNED(arg1, df);
|
||||
uint64_t max_uint = DF_MAX_UINT(df);
|
||||
if (arg2 >= 0) {
|
||||
uint64_t u_arg2 = (uint64_t)arg2;
|
||||
return (u_arg1 > u_arg2) ?
|
||||
(int64_t)(u_arg1 - u_arg2) :
|
||||
0;
|
||||
} else {
|
||||
uint64_t u_arg2 = (uint64_t)(-arg2);
|
||||
return (u_arg1 < max_uint - u_arg2) ?
|
||||
(int64_t)(u_arg1 + u_arg2) :
|
||||
(int64_t)max_uint;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int64_t msa_subsuu_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
uint64_t u_arg1 = UNSIGNED(arg1, df);
|
||||
uint64_t u_arg2 = UNSIGNED(arg2, df);
|
||||
int64_t max_int = DF_MAX_INT(df);
|
||||
int64_t min_int = DF_MIN_INT(df);
|
||||
if (u_arg1 > u_arg2) {
|
||||
return u_arg1 - u_arg2 < (uint64_t)max_int ?
|
||||
(int64_t)(u_arg1 - u_arg2) :
|
||||
max_int;
|
||||
} else {
|
||||
return u_arg2 - u_arg1 < (uint64_t)(-min_int) ?
|
||||
(int64_t)(u_arg1 - u_arg2) :
|
||||
min_int;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int64_t msa_asub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
/* signed compare */
|
||||
return (arg1 < arg2) ?
|
||||
(uint64_t)(arg2 - arg1) : (uint64_t)(arg1 - arg2);
|
||||
}
|
||||
|
||||
static inline uint64_t msa_asub_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
|
||||
{
|
||||
uint64_t u_arg1 = UNSIGNED(arg1, df);
|
||||
uint64_t u_arg2 = UNSIGNED(arg2, df);
|
||||
/* unsigned compare */
|
||||
return (u_arg1 < u_arg2) ?
|
||||
(uint64_t)(u_arg2 - u_arg1) : (uint64_t)(u_arg1 - u_arg2);
|
||||
}
|
||||
|
||||
static inline int64_t msa_mulv_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
return arg1 * arg2;
|
||||
}
|
||||
|
||||
static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
|
||||
return DF_MIN_INT(df);
|
||||
}
|
||||
return arg2 ? arg1 / arg2 : 0;
|
||||
}
|
||||
|
||||
static inline int64_t msa_div_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_arg2 ? u_arg1 / u_arg2 : 0;
|
||||
}
|
||||
|
||||
static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
|
||||
return 0;
|
||||
}
|
||||
return arg2 ? arg1 % arg2 : 0;
|
||||
}
|
||||
|
||||
static inline int64_t msa_mod_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_arg2 ? u_arg1 % u_arg2 : 0;
|
||||
}
|
||||
|
||||
#define SIGNED_EVEN(a, df) \
|
||||
((((int64_t)(a)) << (64 - DF_BITS(df)/2)) >> (64 - DF_BITS(df)/2))
|
||||
|
||||
#define UNSIGNED_EVEN(a, df) \
|
||||
((((uint64_t)(a)) << (64 - DF_BITS(df)/2)) >> (64 - DF_BITS(df)/2))
|
||||
|
||||
#define SIGNED_ODD(a, df) \
|
||||
((((int64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df)/2))
|
||||
|
||||
#define UNSIGNED_ODD(a, df) \
|
||||
((((uint64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df)/2))
|
||||
|
||||
#define SIGNED_EXTRACT(e, o, a, df) \
|
||||
do { \
|
||||
e = SIGNED_EVEN(a, df); \
|
||||
o = SIGNED_ODD(a, df); \
|
||||
} while (0);
|
||||
|
||||
#define UNSIGNED_EXTRACT(e, o, a, df) \
|
||||
do { \
|
||||
e = UNSIGNED_EVEN(a, df); \
|
||||
o = UNSIGNED_ODD(a, df); \
|
||||
} while (0);
|
||||
|
||||
static inline int64_t msa_dotp_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
int64_t even_arg1;
|
||||
int64_t even_arg2;
|
||||
int64_t odd_arg1;
|
||||
int64_t odd_arg2;
|
||||
SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
|
||||
SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
|
||||
return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
|
||||
}
|
||||
|
||||
static inline int64_t msa_dotp_u_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
int64_t even_arg1;
|
||||
int64_t even_arg2;
|
||||
int64_t odd_arg1;
|
||||
int64_t odd_arg2;
|
||||
UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
|
||||
UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
|
||||
return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
|
||||
}
|
||||
|
||||
#define CONCATENATE_AND_SLIDE(s, k) \
|
||||
do { \
|
||||
for (i = 0; i < s; i++) { \
|
||||
v[i] = pws->b[s * k + i]; \
|
||||
v[i + s] = pwd->b[s * k + i]; \
|
||||
} \
|
||||
for (i = 0; i < s; i++) { \
|
||||
pwd->b[s * k + i] = v[i + n]; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline void msa_sld_df(uint32_t df, wr_t *pwd,
|
||||
wr_t *pws, target_ulong rt)
|
||||
{
|
||||
uint32_t n = rt % DF_ELEMENTS(df);
|
||||
uint8_t v[64];
|
||||
uint32_t i, k;
|
||||
|
||||
switch (df) {
|
||||
case DF_BYTE:
|
||||
CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_BYTE), 0);
|
||||
break;
|
||||
case DF_HALF:
|
||||
for (k = 0; k < 2; k++) {
|
||||
CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_HALF), k);
|
||||
}
|
||||
break;
|
||||
case DF_WORD:
|
||||
for (k = 0; k < 4; k++) {
|
||||
CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_WORD), k);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (k = 0; k < 8; k++) {
|
||||
CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_DOUBLE), k);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
return SIGNED_ODD(arg1, df) + SIGNED_EVEN(arg2, df);
|
||||
}
|
||||
|
||||
static inline int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
return UNSIGNED_ODD(arg1, df) + UNSIGNED_EVEN(arg2, df);
|
||||
}
|
||||
|
||||
static inline int64_t msa_hsub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
return SIGNED_ODD(arg1, df) - SIGNED_EVEN(arg2, df);
|
||||
}
|
||||
|
||||
static inline int64_t msa_hsub_u_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||
{
|
||||
return UNSIGNED_ODD(arg1, df) - UNSIGNED_EVEN(arg2, df);
|
||||
}
|
||||
|
||||
#define MSA_BINOP_DF(func) \
|
||||
void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, \
|
||||
uint32_t wd, uint32_t ws, uint32_t wt) \
|
||||
{ \
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
|
||||
wr_t *pwt = &(env->active_fpu.fpr[wt].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], pwt->b[i]); \
|
||||
} \
|
||||
break; \
|
||||
case DF_HALF: \
|
||||
for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { \
|
||||
pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], pwt->h[i]); \
|
||||
} \
|
||||
break; \
|
||||
case DF_WORD: \
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { \
|
||||
pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], pwt->w[i]); \
|
||||
} \
|
||||
break; \
|
||||
case DF_DOUBLE: \
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \
|
||||
pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], pwt->d[i]); \
|
||||
} \
|
||||
break; \
|
||||
default: \
|
||||
assert(0); \
|
||||
} \
|
||||
}
|
||||
|
||||
MSA_BINOP_DF(sll)
|
||||
MSA_BINOP_DF(sra)
|
||||
MSA_BINOP_DF(srl)
|
||||
MSA_BINOP_DF(bclr)
|
||||
MSA_BINOP_DF(bset)
|
||||
MSA_BINOP_DF(bneg)
|
||||
MSA_BINOP_DF(addv)
|
||||
MSA_BINOP_DF(subv)
|
||||
MSA_BINOP_DF(max_s)
|
||||
MSA_BINOP_DF(max_u)
|
||||
MSA_BINOP_DF(min_s)
|
||||
MSA_BINOP_DF(min_u)
|
||||
MSA_BINOP_DF(max_a)
|
||||
MSA_BINOP_DF(min_a)
|
||||
MSA_BINOP_DF(ceq)
|
||||
MSA_BINOP_DF(clt_s)
|
||||
MSA_BINOP_DF(clt_u)
|
||||
MSA_BINOP_DF(cle_s)
|
||||
MSA_BINOP_DF(cle_u)
|
||||
MSA_BINOP_DF(add_a)
|
||||
MSA_BINOP_DF(adds_a)
|
||||
MSA_BINOP_DF(adds_s)
|
||||
MSA_BINOP_DF(adds_u)
|
||||
MSA_BINOP_DF(ave_s)
|
||||
MSA_BINOP_DF(ave_u)
|
||||
MSA_BINOP_DF(aver_s)
|
||||
MSA_BINOP_DF(aver_u)
|
||||
MSA_BINOP_DF(subs_s)
|
||||
MSA_BINOP_DF(subs_u)
|
||||
MSA_BINOP_DF(subsus_u)
|
||||
MSA_BINOP_DF(subsuu_s)
|
||||
MSA_BINOP_DF(asub_s)
|
||||
MSA_BINOP_DF(asub_u)
|
||||
MSA_BINOP_DF(mulv)
|
||||
MSA_BINOP_DF(div_s)
|
||||
MSA_BINOP_DF(div_u)
|
||||
MSA_BINOP_DF(mod_s)
|
||||
MSA_BINOP_DF(mod_u)
|
||||
MSA_BINOP_DF(dotp_s)
|
||||
MSA_BINOP_DF(dotp_u)
|
||||
MSA_BINOP_DF(srar)
|
||||
MSA_BINOP_DF(srlr)
|
||||
MSA_BINOP_DF(hadd_s)
|
||||
MSA_BINOP_DF(hadd_u)
|
||||
MSA_BINOP_DF(hsub_s)
|
||||
MSA_BINOP_DF(hsub_u)
|
||||
#undef MSA_BINOP_DF
|
||||
|
||||
void helper_msa_sld_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws, uint32_t rt)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
|
||||
msa_sld_df(df, pwd, pws, env->active_tc.gpr[rt]);
|
||||
}
|
||||
|
||||
static inline int64_t msa_maddv_df(uint32_t df, int64_t dest, int64_t arg1,
|
||||
int64_t arg2)
|
||||
{
|
||||
return dest + arg1 * arg2;
|
||||
}
|
||||
|
||||
static inline int64_t msa_msubv_df(uint32_t df, int64_t dest, int64_t arg1,
|
||||
int64_t arg2)
|
||||
{
|
||||
return dest - arg1 * arg2;
|
||||
}
|
||||
|
||||
static inline int64_t msa_dpadd_s_df(uint32_t df, int64_t dest, int64_t arg1,
|
||||
int64_t arg2)
|
||||
{
|
||||
int64_t even_arg1;
|
||||
int64_t even_arg2;
|
||||
int64_t odd_arg1;
|
||||
int64_t odd_arg2;
|
||||
SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
|
||||
SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
|
||||
return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
|
||||
}
|
||||
|
||||
static inline int64_t msa_dpadd_u_df(uint32_t df, int64_t dest, int64_t arg1,
|
||||
int64_t arg2)
|
||||
{
|
||||
int64_t even_arg1;
|
||||
int64_t even_arg2;
|
||||
int64_t odd_arg1;
|
||||
int64_t odd_arg2;
|
||||
UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
|
||||
UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
|
||||
return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
|
||||
}
|
||||
|
||||
static inline int64_t msa_dpsub_s_df(uint32_t df, int64_t dest, int64_t arg1,
|
||||
int64_t arg2)
|
||||
{
|
||||
int64_t even_arg1;
|
||||
int64_t even_arg2;
|
||||
int64_t odd_arg1;
|
||||
int64_t odd_arg2;
|
||||
SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
|
||||
SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
|
||||
return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
|
||||
}
|
||||
|
||||
static inline int64_t msa_dpsub_u_df(uint32_t df, int64_t dest, int64_t arg1,
|
||||
int64_t arg2)
|
||||
{
|
||||
int64_t even_arg1;
|
||||
int64_t even_arg2;
|
||||
int64_t odd_arg1;
|
||||
int64_t odd_arg2;
|
||||
UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
|
||||
UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
|
||||
return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
|
||||
}
|
||||
|
||||
#define MSA_TEROP_DF(func) \
|
||||
void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd, \
|
||||
uint32_t ws, uint32_t wt) \
|
||||
{ \
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
|
||||
wr_t *pwt = &(env->active_fpu.fpr[wt].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, pwd->b[i], pws->b[i], \
|
||||
pwt->b[i]); \
|
||||
} \
|
||||
break; \
|
||||
case DF_HALF: \
|
||||
for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { \
|
||||
pwd->h[i] = msa_ ## func ## _df(df, pwd->h[i], pws->h[i], \
|
||||
pwt->h[i]); \
|
||||
} \
|
||||
break; \
|
||||
case DF_WORD: \
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { \
|
||||
pwd->w[i] = msa_ ## func ## _df(df, pwd->w[i], pws->w[i], \
|
||||
pwt->w[i]); \
|
||||
} \
|
||||
break; \
|
||||
case DF_DOUBLE: \
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \
|
||||
pwd->d[i] = msa_ ## func ## _df(df, pwd->d[i], pws->d[i], \
|
||||
pwt->d[i]); \
|
||||
} \
|
||||
break; \
|
||||
default: \
|
||||
assert(0); \
|
||||
} \
|
||||
}
|
||||
|
||||
MSA_TEROP_DF(maddv)
|
||||
MSA_TEROP_DF(msubv)
|
||||
MSA_TEROP_DF(dpadd_s)
|
||||
MSA_TEROP_DF(dpadd_u)
|
||||
MSA_TEROP_DF(dpsub_s)
|
||||
MSA_TEROP_DF(dpsub_u)
|
||||
MSA_TEROP_DF(binsl)
|
||||
MSA_TEROP_DF(binsr)
|
||||
#undef MSA_TEROP_DF
|
||||
|
||||
static inline void msa_splat_df(uint32_t df, wr_t *pwd,
|
||||
wr_t *pws, target_ulong rt)
|
||||
{
|
||||
uint32_t n = rt % DF_ELEMENTS(df);
|
||||
uint32_t i;
|
||||
|
||||
switch (df) {
|
||||
case DF_BYTE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
|
||||
pwd->b[i] = pws->b[n];
|
||||
}
|
||||
break;
|
||||
case DF_HALF:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
|
||||
pwd->h[i] = pws->h[n];
|
||||
}
|
||||
break;
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
pwd->w[i] = pws->w[n];
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
pwd->d[i] = pws->d[n];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void helper_msa_splat_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws, uint32_t rt)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
|
||||
msa_splat_df(df, pwd, pws, env->active_tc.gpr[rt]);
|
||||
}
|
||||
|
||||
#define MSA_DO_B MSA_DO(b)
|
||||
#define MSA_DO_H MSA_DO(h)
|
||||
#define MSA_DO_W MSA_DO(w)
|
||||
#define MSA_DO_D MSA_DO(d)
|
||||
|
||||
#define MSA_LOOP_B MSA_LOOP(B)
|
||||
#define MSA_LOOP_H MSA_LOOP(H)
|
||||
#define MSA_LOOP_W MSA_LOOP(W)
|
||||
#define MSA_LOOP_D MSA_LOOP(D)
|
||||
|
||||
#define MSA_LOOP_COND_B MSA_LOOP_COND(DF_BYTE)
|
||||
#define MSA_LOOP_COND_H MSA_LOOP_COND(DF_HALF)
|
||||
#define MSA_LOOP_COND_W MSA_LOOP_COND(DF_WORD)
|
||||
#define MSA_LOOP_COND_D MSA_LOOP_COND(DF_DOUBLE)
|
||||
|
||||
#define MSA_LOOP(DF) \
|
||||
for (i = 0; i < (MSA_LOOP_COND_ ## DF) ; i++) { \
|
||||
MSA_DO_ ## DF \
|
||||
}
|
||||
|
||||
#define MSA_FN_DF(FUNC) \
|
||||
void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
|
||||
uint32_t ws, uint32_t wt) \
|
||||
{ \
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
|
||||
wr_t *pwt = &(env->active_fpu.fpr[wt].wr); \
|
||||
wr_t wx, *pwx = &wx; \
|
||||
uint32_t i; \
|
||||
switch (df) { \
|
||||
case DF_BYTE: \
|
||||
MSA_LOOP_B \
|
||||
break; \
|
||||
case DF_HALF: \
|
||||
MSA_LOOP_H \
|
||||
break; \
|
||||
case DF_WORD: \
|
||||
MSA_LOOP_W \
|
||||
break; \
|
||||
case DF_DOUBLE: \
|
||||
MSA_LOOP_D \
|
||||
break; \
|
||||
default: \
|
||||
assert(0); \
|
||||
} \
|
||||
msa_move_v(pwd, pwx); \
|
||||
}
|
||||
|
||||
#define MSA_LOOP_COND(DF) \
|
||||
(DF_ELEMENTS(DF) / 2)
|
||||
|
||||
#define Rb(pwr, i) (pwr->b[i])
|
||||
#define Lb(pwr, i) (pwr->b[i + DF_ELEMENTS(DF_BYTE)/2])
|
||||
#define Rh(pwr, i) (pwr->h[i])
|
||||
#define Lh(pwr, i) (pwr->h[i + DF_ELEMENTS(DF_HALF)/2])
|
||||
#define Rw(pwr, i) (pwr->w[i])
|
||||
#define Lw(pwr, i) (pwr->w[i + DF_ELEMENTS(DF_WORD)/2])
|
||||
#define Rd(pwr, i) (pwr->d[i])
|
||||
#define Ld(pwr, i) (pwr->d[i + DF_ELEMENTS(DF_DOUBLE)/2])
|
||||
|
||||
#define MSA_DO(DF) \
|
||||
do { \
|
||||
R##DF(pwx, i) = pwt->DF[2*i]; \
|
||||
L##DF(pwx, i) = pws->DF[2*i]; \
|
||||
} while (0);
|
||||
MSA_FN_DF(pckev_df)
|
||||
#undef MSA_DO
|
||||
|
||||
#define MSA_DO(DF) \
|
||||
do { \
|
||||
R##DF(pwx, i) = pwt->DF[2*i+1]; \
|
||||
L##DF(pwx, i) = pws->DF[2*i+1]; \
|
||||
} while (0);
|
||||
MSA_FN_DF(pckod_df)
|
||||
#undef MSA_DO
|
||||
|
||||
#define MSA_DO(DF) \
|
||||
do { \
|
||||
pwx->DF[2*i] = L##DF(pwt, i); \
|
||||
pwx->DF[2*i+1] = L##DF(pws, i); \
|
||||
} while (0);
|
||||
MSA_FN_DF(ilvl_df)
|
||||
#undef MSA_DO
|
||||
|
||||
#define MSA_DO(DF) \
|
||||
do { \
|
||||
pwx->DF[2*i] = R##DF(pwt, i); \
|
||||
pwx->DF[2*i+1] = R##DF(pws, i); \
|
||||
} while (0);
|
||||
MSA_FN_DF(ilvr_df)
|
||||
#undef MSA_DO
|
||||
|
||||
#define MSA_DO(DF) \
|
||||
do { \
|
||||
pwx->DF[2*i] = pwt->DF[2*i]; \
|
||||
pwx->DF[2*i+1] = pws->DF[2*i]; \
|
||||
} while (0);
|
||||
MSA_FN_DF(ilvev_df)
|
||||
#undef MSA_DO
|
||||
|
||||
#define MSA_DO(DF) \
|
||||
do { \
|
||||
pwx->DF[2*i] = pwt->DF[2*i+1]; \
|
||||
pwx->DF[2*i+1] = pws->DF[2*i+1]; \
|
||||
} while (0);
|
||||
MSA_FN_DF(ilvod_df)
|
||||
#undef MSA_DO
|
||||
#undef MSA_LOOP_COND
|
||||
|
||||
#define MSA_LOOP_COND(DF) \
|
||||
(DF_ELEMENTS(DF))
|
||||
|
||||
#define MSA_DO(DF) \
|
||||
do { \
|
||||
uint32_t n = DF_ELEMENTS(df); \
|
||||
uint32_t k = (pwd->DF[i] & 0x3f) % (2 * n); \
|
||||
pwx->DF[i] = \
|
||||
(pwd->DF[i] & 0xc0) ? 0 : k < n ? pwt->DF[k] : pws->DF[k - n]; \
|
||||
} while (0);
|
||||
MSA_FN_DF(vshf_df)
|
||||
#undef MSA_DO
|
||||
#undef MSA_LOOP_COND
|
||||
#undef MSA_FN_DF
|
||||
|
|
|
@ -17549,6 +17549,237 @@ static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
|
|||
tcg_temp_free_i32(tws);
|
||||
}
|
||||
|
||||
static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
|
||||
{
|
||||
#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
|
||||
uint8_t df = (ctx->opcode >> 21) & 0x3;
|
||||
uint8_t wt = (ctx->opcode >> 16) & 0x1f;
|
||||
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
|
||||
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
|
||||
|
||||
TCGv_i32 tdf = tcg_const_i32(df);
|
||||
TCGv_i32 twd = tcg_const_i32(wd);
|
||||
TCGv_i32 tws = tcg_const_i32(ws);
|
||||
TCGv_i32 twt = tcg_const_i32(wt);
|
||||
|
||||
switch (MASK_MSA_3R(ctx->opcode)) {
|
||||
case OPC_SLL_df:
|
||||
gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ADDV_df:
|
||||
gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_CEQ_df:
|
||||
gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ADD_A_df:
|
||||
gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SUBS_S_df:
|
||||
gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MULV_df:
|
||||
gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SLD_df:
|
||||
gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_VSHF_df:
|
||||
gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SRA_df:
|
||||
gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SUBV_df:
|
||||
gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ADDS_A_df:
|
||||
gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SUBS_U_df:
|
||||
gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MADDV_df:
|
||||
gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SPLAT_df:
|
||||
gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SRAR_df:
|
||||
gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SRL_df:
|
||||
gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MAX_S_df:
|
||||
gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_CLT_S_df:
|
||||
gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ADDS_S_df:
|
||||
gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SUBSUS_U_df:
|
||||
gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MSUBV_df:
|
||||
gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_PCKEV_df:
|
||||
gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SRLR_df:
|
||||
gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_BCLR_df:
|
||||
gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MAX_U_df:
|
||||
gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_CLT_U_df:
|
||||
gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ADDS_U_df:
|
||||
gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_SUBSUU_S_df:
|
||||
gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_PCKOD_df:
|
||||
gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_BSET_df:
|
||||
gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MIN_S_df:
|
||||
gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_CLE_S_df:
|
||||
gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_AVE_S_df:
|
||||
gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ASUB_S_df:
|
||||
gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_DIV_S_df:
|
||||
gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ILVL_df:
|
||||
gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_BNEG_df:
|
||||
gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MIN_U_df:
|
||||
gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_CLE_U_df:
|
||||
gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_AVE_U_df:
|
||||
gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ASUB_U_df:
|
||||
gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_DIV_U_df:
|
||||
gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ILVR_df:
|
||||
gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_BINSL_df:
|
||||
gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MAX_A_df:
|
||||
gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_AVER_S_df:
|
||||
gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MOD_S_df:
|
||||
gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ILVEV_df:
|
||||
gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_BINSR_df:
|
||||
gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MIN_A_df:
|
||||
gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_AVER_U_df:
|
||||
gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_MOD_U_df:
|
||||
gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_ILVOD_df:
|
||||
gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
|
||||
case OPC_DOTP_S_df:
|
||||
case OPC_DOTP_U_df:
|
||||
case OPC_DPADD_S_df:
|
||||
case OPC_DPADD_U_df:
|
||||
case OPC_DPSUB_S_df:
|
||||
case OPC_HADD_S_df:
|
||||
case OPC_DPSUB_U_df:
|
||||
case OPC_HADD_U_df:
|
||||
case OPC_HSUB_S_df:
|
||||
case OPC_HSUB_U_df:
|
||||
if (df == DF_BYTE) {
|
||||
generate_exception(ctx, EXCP_RI);
|
||||
}
|
||||
switch (MASK_MSA_3R(ctx->opcode)) {
|
||||
case OPC_DOTP_S_df:
|
||||
gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_DOTP_U_df:
|
||||
gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_DPADD_S_df:
|
||||
gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_DPADD_U_df:
|
||||
gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_DPSUB_S_df:
|
||||
gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_HADD_S_df:
|
||||
gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_DPSUB_U_df:
|
||||
gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_HADD_U_df:
|
||||
gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_HSUB_S_df:
|
||||
gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
case OPC_HSUB_U_df:
|
||||
gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MIPS_INVAL("MSA instruction");
|
||||
generate_exception(ctx, EXCP_RI);
|
||||
break;
|
||||
}
|
||||
tcg_temp_free_i32(twd);
|
||||
tcg_temp_free_i32(tws);
|
||||
tcg_temp_free_i32(twt);
|
||||
tcg_temp_free_i32(tdf);
|
||||
}
|
||||
|
||||
static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
|
||||
{
|
||||
uint32_t opcode = ctx->opcode;
|
||||
|
@ -17569,6 +17800,17 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
|
|||
case OPC_MSA_BIT_0A:
|
||||
gen_msa_bit(env, ctx);
|
||||
break;
|
||||
case OPC_MSA_3R_0D:
|
||||
case OPC_MSA_3R_0E:
|
||||
case OPC_MSA_3R_0F:
|
||||
case OPC_MSA_3R_10:
|
||||
case OPC_MSA_3R_11:
|
||||
case OPC_MSA_3R_12:
|
||||
case OPC_MSA_3R_13:
|
||||
case OPC_MSA_3R_14:
|
||||
case OPC_MSA_3R_15:
|
||||
gen_msa_3r(env, ctx);
|
||||
break;
|
||||
default:
|
||||
MIPS_INVAL("MSA instruction");
|
||||
generate_exception(ctx, EXCP_RI);
|
||||
|
|
Loading…
Reference in New Issue