mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 12:09:58 +00:00
target-mips: add MSA 2RF format instructions
add MSA 2RF 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
cbe50b9a8e
commit
3bdeb68866
@ -912,3 +912,20 @@ DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_pcnt_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_nloc_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_nlzc_df, void, env, i32, i32, i32)
|
||||
|
||||
DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_fsqrt_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_frsqrt_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_frcp_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_frint_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_flog2_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_fexupl_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_fexupr_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_ffql_df, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msa_ffqr_df, void, env, i32, i32, i32)
|
||||
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)
|
||||
|
@ -1498,6 +1498,7 @@ void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, \
|
||||
MSA_UNOP_DF(nlzc)
|
||||
MSA_UNOP_DF(nloc)
|
||||
MSA_UNOP_DF(pcnt)
|
||||
#undef MSA_UNOP_DF
|
||||
|
||||
#define FLOAT_ONE32 make_float32(0x3f8 << 20)
|
||||
#define FLOAT_ONE64 make_float64(0x3ffULL << 52)
|
||||
@ -2904,3 +2905,532 @@ void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
|
||||
uint32_t wd, uint32_t ws)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
if (df == DF_WORD) {
|
||||
pwd->w[0] = helper_float_class_s(pws->w[0]);
|
||||
pwd->w[1] = helper_float_class_s(pws->w[1]);
|
||||
pwd->w[2] = helper_float_class_s(pws->w[2]);
|
||||
pwd->w[3] = helper_float_class_s(pws->w[3]);
|
||||
} else {
|
||||
pwd->d[0] = helper_float_class_d(pws->d[0]);
|
||||
pwd->d[1] = helper_float_class_d(pws->d[1]);
|
||||
}
|
||||
}
|
||||
|
||||
#define MSA_FLOAT_UNOP0(DEST, OP, ARG, BITS) \
|
||||
do { \
|
||||
int c; \
|
||||
\
|
||||
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
|
||||
DEST = float ## BITS ## _ ## OP(ARG, &env->active_tc.msa_fp_status);\
|
||||
c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0); \
|
||||
\
|
||||
if (get_enabled_exceptions(env, c)) { \
|
||||
DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c; \
|
||||
} else if (float ## BITS ## _is_any_nan(ARG)) { \
|
||||
DEST = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
void helper_msa_ftrunc_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_UNOP0(pwx->w[i], to_int32_round_to_zero, pws->w[i], 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP0(pwx->d[i], to_int64_round_to_zero, pws->d[i], 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_ftrunc_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_UNOP0(pwx->w[i], to_uint32_round_to_zero, pws->w[i], 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP0(pwx->d[i], to_uint64_round_to_zero, pws->d[i], 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->w[i], sqrt, pws->w[i], 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->d[i], sqrt, pws->d[i], 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
#define MSA_FLOAT_RECIPROCAL(DEST, ARG, BITS) \
|
||||
do { \
|
||||
int c; \
|
||||
\
|
||||
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
|
||||
DEST = float ## BITS ## _ ## div(FLOAT_ONE ## BITS, ARG, \
|
||||
&env->active_tc.msa_fp_status); \
|
||||
c = update_msacsr(env, float ## BITS ## _is_infinity(ARG) || \
|
||||
float ## BITS ## _is_quiet_nan(DEST) ? \
|
||||
0 : RECIPROCAL_INEXACT, \
|
||||
IS_DENORMAL(DEST, BITS)); \
|
||||
\
|
||||
if (get_enabled_exceptions(env, c)) { \
|
||||
DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
void helper_msa_frsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_RECIPROCAL(pwx->w[i], float32_sqrt(pws->w[i],
|
||||
&env->active_tc.msa_fp_status), 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_RECIPROCAL(pwx->d[i], float64_sqrt(pws->d[i],
|
||||
&env->active_tc.msa_fp_status), 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_frcp_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_RECIPROCAL(pwx->w[i], pws->w[i], 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_RECIPROCAL(pwx->d[i], pws->d[i], 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->w[i], round_to_int, pws->w[i], 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->d[i], round_to_int, pws->d[i], 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
#define MSA_FLOAT_LOGB(DEST, ARG, BITS) \
|
||||
do { \
|
||||
int c; \
|
||||
\
|
||||
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
|
||||
set_float_rounding_mode(float_round_down, \
|
||||
&env->active_tc.msa_fp_status); \
|
||||
DEST = float ## BITS ## _ ## log2(ARG, \
|
||||
&env->active_tc.msa_fp_status); \
|
||||
DEST = float ## BITS ## _ ## round_to_int(DEST, \
|
||||
&env->active_tc.msa_fp_status); \
|
||||
set_float_rounding_mode(ieee_rm[(env->active_tc.msacsr & \
|
||||
MSACSR_RM_MASK) >> MSACSR_RM], \
|
||||
&env->active_tc.msa_fp_status); \
|
||||
\
|
||||
set_float_exception_flags( \
|
||||
get_float_exception_flags(&env->active_tc.msa_fp_status) \
|
||||
& (~float_flag_inexact), \
|
||||
&env->active_tc.msa_fp_status); \
|
||||
\
|
||||
c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
|
||||
\
|
||||
if (get_enabled_exceptions(env, c)) { \
|
||||
DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
void helper_msa_flog2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_LOGB(pwx->w[i], pws->w[i], 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_LOGB(pwx->d[i], pws->d[i], 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
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_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
/* Half precision floats come in two formats: standard
|
||||
IEEE and "ARM" format. The latter gains extra exponent
|
||||
range by omitting the NaN/Inf encodings. */
|
||||
flag ieee = 1;
|
||||
|
||||
MSA_FLOAT_BINOP(pwx->w[i], from_float16, Lh(pws, i), ieee, 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->d[i], from_float32, Lw(pws, i), 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
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_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
/* Half precision floats come in two formats: standard
|
||||
IEEE and "ARM" format. The latter gains extra exponent
|
||||
range by omitting the NaN/Inf encodings. */
|
||||
flag ieee = 1;
|
||||
|
||||
MSA_FLOAT_BINOP(pwx->w[i], from_float16, Rh(pws, i), ieee, 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->d[i], from_float32, Rw(pws, i), 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_ffql_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
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_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->w[i], from_q16, Lh(pws, i), 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->d[i], from_q32, Lw(pws, i), 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_ffqr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
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_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->w[i], from_q16, Rh(pws, i), 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->d[i], from_q32, Rw(pws, i), 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_ftint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_UNOP0(pwx->w[i], to_int32, pws->w[i], 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP0(pwx->d[i], to_int64, pws->d[i], 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_ftint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_UNOP0(pwx->w[i], to_uint32, pws->w[i], 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP0(pwx->d[i], to_uint64, pws->d[i], 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
#define float32_from_int32 int32_to_float32
|
||||
#define float32_from_uint32 uint32_to_float32
|
||||
|
||||
#define float64_from_int64 int64_to_float64
|
||||
#define float64_from_uint64 uint64_to_float64
|
||||
|
||||
void helper_msa_ffint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->w[i], from_int32, pws->w[i], 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->d[i], from_int64, pws->d[i], 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
||||
void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||
uint32_t ws)
|
||||
{
|
||||
wr_t wx, *pwx = &wx;
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
|
||||
uint32_t i;
|
||||
|
||||
clear_msacsr_cause(env);
|
||||
|
||||
switch (df) {
|
||||
case DF_WORD:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->w[i], from_uint32, pws->w[i], 32);
|
||||
}
|
||||
break;
|
||||
case DF_DOUBLE:
|
||||
for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
|
||||
MSA_FLOAT_UNOP(pwx->d[i], from_uint64, pws->d[i], 64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
check_msacsr_cause(env);
|
||||
|
||||
msa_move_v(pwd, pwx);
|
||||
}
|
||||
|
@ -18098,6 +18098,77 @@ static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
|
||||
tcg_temp_free_i32(tdf);
|
||||
}
|
||||
|
||||
static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
|
||||
{
|
||||
#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
|
||||
(op & (0xf << 17)))
|
||||
uint8_t wt = (ctx->opcode >> 16) & 0x1f;
|
||||
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
|
||||
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
|
||||
uint8_t df = (ctx->opcode >> 16) & 0x1;
|
||||
TCGv_i32 twd = tcg_const_i32(wd);
|
||||
TCGv_i32 tws = tcg_const_i32(ws);
|
||||
TCGv_i32 twt = tcg_const_i32(wt);
|
||||
/* adjust df value for floating-point instruction */
|
||||
TCGv_i32 tdf = tcg_const_i32(df + 2);
|
||||
|
||||
switch (MASK_MSA_2RF(ctx->opcode)) {
|
||||
case OPC_FCLASS_df:
|
||||
gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FTRUNC_S_df:
|
||||
gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FTRUNC_U_df:
|
||||
gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FSQRT_df:
|
||||
gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FRSQRT_df:
|
||||
gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FRCP_df:
|
||||
gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FRINT_df:
|
||||
gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FLOG2_df:
|
||||
gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FEXUPL_df:
|
||||
gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FEXUPR_df:
|
||||
gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FFQL_df:
|
||||
gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FFQR_df:
|
||||
gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FTINT_S_df:
|
||||
gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FTINT_U_df:
|
||||
gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FFINT_S_df:
|
||||
gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
|
||||
break;
|
||||
case OPC_FFINT_U_df:
|
||||
gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
|
||||
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_vec_v(CPUMIPSState *env, DisasContext *ctx)
|
||||
{
|
||||
#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
|
||||
@ -18156,6 +18227,9 @@ static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
|
||||
case OPC_MSA_2R:
|
||||
gen_msa_2r(env, ctx);
|
||||
break;
|
||||
case OPC_MSA_2RF:
|
||||
gen_msa_2rf(env, ctx);
|
||||
break;
|
||||
default:
|
||||
MIPS_INVAL("MSA instruction");
|
||||
generate_exception(ctx, EXCP_RI);
|
||||
|
Loading…
Reference in New Issue
Block a user