target/arm: Implement MVE VSHRN, VRSHRN
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN. do_urshr() is borrowed from sve_helper.c. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
This commit is contained in:
parent
a78b25fa71
commit
162e265500
|
@ -404,3 +404,13 @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
|
|
||||||
|
DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
|
|
||||||
|
DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
|
||||||
|
|
|
@ -380,3 +380,14 @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
|
||||||
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
|
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
|
||||||
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
|
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
|
||||||
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
|
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
|
||||||
|
|
||||||
|
# Narrowing shifts (which only support b and h sizes)
|
||||||
|
VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
|
||||||
|
VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
|
||||||
|
VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
|
||||||
|
VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
|
||||||
|
|
||||||
|
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
|
||||||
|
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
|
||||||
|
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
|
||||||
|
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
|
||||||
|
|
|
@ -1324,3 +1324,43 @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
|
||||||
|
|
||||||
DO_VSHLL_ALL(vshllb, false)
|
DO_VSHLL_ALL(vshllb, false)
|
||||||
DO_VSHLL_ALL(vshllt, true)
|
DO_VSHLL_ALL(vshllt, true)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Narrowing right shifts, taking a double sized input, shifting it
|
||||||
|
* and putting the result in either the top or bottom half of the output.
|
||||||
|
* ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
|
||||||
|
*/
|
||||||
|
#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
|
||||||
|
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
|
||||||
|
void *vm, uint32_t shift) \
|
||||||
|
{ \
|
||||||
|
LTYPE *m = vm; \
|
||||||
|
TYPE *d = vd; \
|
||||||
|
uint16_t mask = mve_element_mask(env); \
|
||||||
|
unsigned le; \
|
||||||
|
for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
|
||||||
|
TYPE r = FN(m[H##LESIZE(le)], shift); \
|
||||||
|
mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
|
||||||
|
} \
|
||||||
|
mve_advance_vpt(env); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DO_VSHRN_ALL(OP, FN) \
|
||||||
|
DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
|
||||||
|
DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
|
||||||
|
DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
|
||||||
|
DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
|
||||||
|
|
||||||
|
static inline uint64_t do_urshr(uint64_t x, unsigned sh)
|
||||||
|
{
|
||||||
|
if (likely(sh < 64)) {
|
||||||
|
return (x >> sh) + ((x >> (sh - 1)) & 1);
|
||||||
|
} else if (sh == 64) {
|
||||||
|
return x >> 63;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DO_VSHRN_ALL(vshrn, DO_SHR)
|
||||||
|
DO_VSHRN_ALL(vrshrn, do_urshr)
|
||||||
|
|
|
@ -911,3 +911,18 @@ DO_VSHLL(VSHLL_BS, vshllbs)
|
||||||
DO_VSHLL(VSHLL_BU, vshllbu)
|
DO_VSHLL(VSHLL_BU, vshllbu)
|
||||||
DO_VSHLL(VSHLL_TS, vshllts)
|
DO_VSHLL(VSHLL_TS, vshllts)
|
||||||
DO_VSHLL(VSHLL_TU, vshlltu)
|
DO_VSHLL(VSHLL_TU, vshlltu)
|
||||||
|
|
||||||
|
#define DO_2SHIFT_N(INSN, FN) \
|
||||||
|
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
|
||||||
|
{ \
|
||||||
|
static MVEGenTwoOpShiftFn * const fns[] = { \
|
||||||
|
gen_helper_mve_##FN##b, \
|
||||||
|
gen_helper_mve_##FN##h, \
|
||||||
|
}; \
|
||||||
|
return do_2shift(s, a, fns[a->size], false); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DO_2SHIFT_N(VSHRNB, vshrnb)
|
||||||
|
DO_2SHIFT_N(VSHRNT, vshrnt)
|
||||||
|
DO_2SHIFT_N(VRSHRNB, vrshrnb)
|
||||||
|
DO_2SHIFT_N(VRSHRNT, vrshrnt)
|
||||||
|
|
Loading…
Reference in a new issue