mirror of https://github.com/xemu-project/xemu.git
target/arm: Implement MVE VCVT between floating and fixed point
Implement the MVE VCVT insns which convert between floating and fixed point. As with the Neon equivalents, these use essentially the same constant encoding as right-shift-by-immediate. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
c2d8f6bb28
commit
2a4b939cf8
|
@ -863,3 +863,12 @@ DEF_HELPER_FLAGS_4(mve_vfma_scalars, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
|||
|
||||
DEF_HELPER_FLAGS_4(mve_vfmas_scalarh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(mve_vfmas_scalars, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(mve_vcvt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(mve_vcvt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(mve_vcvt_hs, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(mve_vcvt_hu, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(mve_vcvt_sf, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(mve_vcvt_uf, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(mve_vcvt_fs, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(mve_vcvt_fu, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||
|
|
|
@ -779,3 +779,22 @@ VCMLA0 1111 110 00 . 1 . ... 0 ... 0 1000 . 1 . 0 ... 0 @2op_fp_size_
|
|||
VCMLA90 1111 110 01 . 1 . ... 0 ... 0 1000 . 1 . 0 ... 0 @2op_fp_size_rev
|
||||
VCMLA180 1111 110 10 . 1 . ... 0 ... 0 1000 . 1 . 0 ... 0 @2op_fp_size_rev
|
||||
VCMLA270 1111 110 11 . 1 . ... 0 ... 0 1000 . 1 . 0 ... 0 @2op_fp_size_rev
|
||||
|
||||
# floating-point <-> fixed-point conversions. Naming convention:
|
||||
# VCVT_<from><to>, S = signed int, U = unsigned int, H = halfprec, F = singleprec
|
||||
@vcvt .... .... .. 1 ..... .... .. 1 . .... .... &2shift \
|
||||
qd=%qd qm=%qm shift=%rshift_i5 size=2
|
||||
@vcvt_f16 .... .... .. 11 .... .... .. 0 . .... .... &2shift \
|
||||
qd=%qd qm=%qm shift=%rshift_i4 size=1
|
||||
|
||||
VCVT_SH_fixed 1110 1111 1 . ...... ... 0 11 . 0 01 . 1 ... 0 @vcvt_f16
|
||||
VCVT_UH_fixed 1111 1111 1 . ...... ... 0 11 . 0 01 . 1 ... 0 @vcvt_f16
|
||||
|
||||
VCVT_HS_fixed 1110 1111 1 . ...... ... 0 11 . 1 01 . 1 ... 0 @vcvt_f16
|
||||
VCVT_HU_fixed 1111 1111 1 . ...... ... 0 11 . 1 01 . 1 ... 0 @vcvt_f16
|
||||
|
||||
VCVT_SF_fixed 1110 1111 1 . ...... ... 0 11 . 0 01 . 1 ... 0 @vcvt
|
||||
VCVT_UF_fixed 1111 1111 1 . ...... ... 0 11 . 0 01 . 1 ... 0 @vcvt
|
||||
|
||||
VCVT_FS_fixed 1110 1111 1 . ...... ... 0 11 . 1 01 . 1 ... 0 @vcvt
|
||||
VCVT_FU_fixed 1111 1111 1 . ...... ... 0 11 . 1 01 . 1 ... 0 @vcvt
|
||||
|
|
|
@ -3258,3 +3258,39 @@ DO_VCMP_FP_BOTH(vfcmpgts, vfcmpgt_scalars, 4, float32, DO_GT32)
|
|||
|
||||
DO_VCMP_FP_BOTH(vfcmpleh, vfcmple_scalarh, 2, float16, !DO_GT16)
|
||||
DO_VCMP_FP_BOTH(vfcmples, vfcmple_scalars, 4, float32, !DO_GT32)
|
||||
|
||||
#define DO_VCVT_FIXED(OP, ESIZE, TYPE, FN) \
|
||||
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, void *vm, \
|
||||
uint32_t shift) \
|
||||
{ \
|
||||
TYPE *d = vd, *m = vm; \
|
||||
TYPE r; \
|
||||
uint16_t mask = mve_element_mask(env); \
|
||||
unsigned e; \
|
||||
float_status *fpst; \
|
||||
float_status scratch_fpst; \
|
||||
for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
|
||||
if ((mask & MAKE_64BIT_MASK(0, ESIZE)) == 0) { \
|
||||
continue; \
|
||||
} \
|
||||
fpst = (ESIZE == 2) ? &env->vfp.standard_fp_status_f16 : \
|
||||
&env->vfp.standard_fp_status; \
|
||||
if (!(mask & 1)) { \
|
||||
/* We need the result but without updating flags */ \
|
||||
scratch_fpst = *fpst; \
|
||||
fpst = &scratch_fpst; \
|
||||
} \
|
||||
r = FN(m[H##ESIZE(e)], shift, fpst); \
|
||||
mergemask(&d[H##ESIZE(e)], r, mask); \
|
||||
} \
|
||||
mve_advance_vpt(env); \
|
||||
}
|
||||
|
||||
DO_VCVT_FIXED(vcvt_sh, 2, int16_t, helper_vfp_shtoh)
|
||||
DO_VCVT_FIXED(vcvt_uh, 2, uint16_t, helper_vfp_uhtoh)
|
||||
DO_VCVT_FIXED(vcvt_hs, 2, int16_t, helper_vfp_toshh_round_to_zero)
|
||||
DO_VCVT_FIXED(vcvt_hu, 2, uint16_t, helper_vfp_touhh_round_to_zero)
|
||||
DO_VCVT_FIXED(vcvt_sf, 4, int32_t, helper_vfp_sltos)
|
||||
DO_VCVT_FIXED(vcvt_uf, 4, uint32_t, helper_vfp_ultos)
|
||||
DO_VCVT_FIXED(vcvt_fs, 4, int32_t, helper_vfp_tosls_round_to_zero)
|
||||
DO_VCVT_FIXED(vcvt_fu, 4, uint32_t, helper_vfp_touls_round_to_zero)
|
||||
|
|
|
@ -1439,6 +1439,24 @@ DO_2SHIFT(VRSHRI_U, vrshli_u, true)
|
|||
DO_2SHIFT(VSRI, vsri, false)
|
||||
DO_2SHIFT(VSLI, vsli, false)
|
||||
|
||||
#define DO_2SHIFT_FP(INSN, FN) \
|
||||
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
|
||||
{ \
|
||||
if (!dc_isar_feature(aa32_mve_fp, s)) { \
|
||||
return false; \
|
||||
} \
|
||||
return do_2shift(s, a, gen_helper_mve_##FN, false); \
|
||||
}
|
||||
|
||||
DO_2SHIFT_FP(VCVT_SH_fixed, vcvt_sh)
|
||||
DO_2SHIFT_FP(VCVT_UH_fixed, vcvt_uh)
|
||||
DO_2SHIFT_FP(VCVT_HS_fixed, vcvt_hs)
|
||||
DO_2SHIFT_FP(VCVT_HU_fixed, vcvt_hu)
|
||||
DO_2SHIFT_FP(VCVT_SF_fixed, vcvt_sf)
|
||||
DO_2SHIFT_FP(VCVT_UF_fixed, vcvt_uf)
|
||||
DO_2SHIFT_FP(VCVT_FS_fixed, vcvt_fs)
|
||||
DO_2SHIFT_FP(VCVT_FU_fixed, vcvt_fu)
|
||||
|
||||
static bool do_2shift_scalar(DisasContext *s, arg_shl_scalar *a,
|
||||
MVEGenTwoOpShiftFn *fn)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue