target/arm: Implement SVE2 integer pairwise arithmetic
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210525010358.152808-9-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a47dc220e9
commit
8597dc8b86
@ -326,6 +326,51 @@ DEF_HELPER_FLAGS_5(sve_sel_zpzz_s, TCG_CALL_NO_RWG,
|
||||
DEF_HELPER_FLAGS_5(sve_sel_zpzz_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(sve2_addp_zpzz_b, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_addp_zpzz_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_addp_zpzz_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_addp_zpzz_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(sve2_smaxp_zpzz_b, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_smaxp_zpzz_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_smaxp_zpzz_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_smaxp_zpzz_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(sve2_umaxp_zpzz_b, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_umaxp_zpzz_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_umaxp_zpzz_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_umaxp_zpzz_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(sve2_sminp_zpzz_b, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_sminp_zpzz_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_sminp_zpzz_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_sminp_zpzz_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(sve2_uminp_zpzz_b, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_uminp_zpzz_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_uminp_zpzz_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_uminp_zpzz_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(sve_asr_zpzw_b, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve_asr_zpzw_h, TCG_CALL_NO_RWG,
|
||||
|
@ -1140,3 +1140,11 @@ SRHADD 01000100 .. 010 100 100 ... ..... ..... @rdn_pg_rm
|
||||
URHADD 01000100 .. 010 101 100 ... ..... ..... @rdn_pg_rm
|
||||
SHSUB 01000100 .. 010 110 100 ... ..... ..... @rdm_pg_rn # SHSUBR
|
||||
UHSUB 01000100 .. 010 111 100 ... ..... ..... @rdm_pg_rn # UHSUBR
|
||||
|
||||
### SVE2 integer pairwise arithmetic
|
||||
|
||||
ADDP 01000100 .. 010 001 101 ... ..... ..... @rdn_pg_rm
|
||||
SMAXP 01000100 .. 010 100 101 ... ..... ..... @rdn_pg_rm
|
||||
UMAXP 01000100 .. 010 101 101 ... ..... ..... @rdn_pg_rm
|
||||
SMINP 01000100 .. 010 110 101 ... ..... ..... @rdn_pg_rm
|
||||
UMINP 01000100 .. 010 111 101 ... ..... ..... @rdn_pg_rm
|
||||
|
@ -690,6 +690,82 @@ DO_ZPZZ_D(sve2_uhsub_zpzz_d, uint64_t, DO_HSUB_D)
|
||||
#undef DO_ZPZZ
|
||||
#undef DO_ZPZZ_D
|
||||
|
||||
/*
|
||||
* Three operand expander, operating on element pairs.
|
||||
* If the slot I is even, the elements from from VN {I, I+1}.
|
||||
* If the slot I is odd, the elements from from VM {I-1, I}.
|
||||
* Load all of the input elements in each pair before overwriting output.
|
||||
*/
|
||||
#define DO_ZPZZ_PAIR(NAME, TYPE, H, OP) \
|
||||
void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
|
||||
{ \
|
||||
intptr_t i, opr_sz = simd_oprsz(desc); \
|
||||
for (i = 0; i < opr_sz; ) { \
|
||||
uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
|
||||
do { \
|
||||
TYPE n0 = *(TYPE *)(vn + H(i)); \
|
||||
TYPE m0 = *(TYPE *)(vm + H(i)); \
|
||||
TYPE n1 = *(TYPE *)(vn + H(i + sizeof(TYPE))); \
|
||||
TYPE m1 = *(TYPE *)(vm + H(i + sizeof(TYPE))); \
|
||||
if (pg & 1) { \
|
||||
*(TYPE *)(vd + H(i)) = OP(n0, n1); \
|
||||
} \
|
||||
i += sizeof(TYPE), pg >>= sizeof(TYPE); \
|
||||
if (pg & 1) { \
|
||||
*(TYPE *)(vd + H(i)) = OP(m0, m1); \
|
||||
} \
|
||||
i += sizeof(TYPE), pg >>= sizeof(TYPE); \
|
||||
} while (i & 15); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Similarly, specialized for 64-bit operands. */
|
||||
#define DO_ZPZZ_PAIR_D(NAME, TYPE, OP) \
|
||||
void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
|
||||
{ \
|
||||
intptr_t i, opr_sz = simd_oprsz(desc) / 8; \
|
||||
TYPE *d = vd, *n = vn, *m = vm; \
|
||||
uint8_t *pg = vg; \
|
||||
for (i = 0; i < opr_sz; i += 2) { \
|
||||
TYPE n0 = n[i], n1 = n[i + 1]; \
|
||||
TYPE m0 = m[i], m1 = m[i + 1]; \
|
||||
if (pg[H1(i)] & 1) { \
|
||||
d[i] = OP(n0, n1); \
|
||||
} \
|
||||
if (pg[H1(i + 1)] & 1) { \
|
||||
d[i + 1] = OP(m0, m1); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
DO_ZPZZ_PAIR(sve2_addp_zpzz_b, uint8_t, H1, DO_ADD)
|
||||
DO_ZPZZ_PAIR(sve2_addp_zpzz_h, uint16_t, H1_2, DO_ADD)
|
||||
DO_ZPZZ_PAIR(sve2_addp_zpzz_s, uint32_t, H1_4, DO_ADD)
|
||||
DO_ZPZZ_PAIR_D(sve2_addp_zpzz_d, uint64_t, DO_ADD)
|
||||
|
||||
DO_ZPZZ_PAIR(sve2_umaxp_zpzz_b, uint8_t, H1, DO_MAX)
|
||||
DO_ZPZZ_PAIR(sve2_umaxp_zpzz_h, uint16_t, H1_2, DO_MAX)
|
||||
DO_ZPZZ_PAIR(sve2_umaxp_zpzz_s, uint32_t, H1_4, DO_MAX)
|
||||
DO_ZPZZ_PAIR_D(sve2_umaxp_zpzz_d, uint64_t, DO_MAX)
|
||||
|
||||
DO_ZPZZ_PAIR(sve2_uminp_zpzz_b, uint8_t, H1, DO_MIN)
|
||||
DO_ZPZZ_PAIR(sve2_uminp_zpzz_h, uint16_t, H1_2, DO_MIN)
|
||||
DO_ZPZZ_PAIR(sve2_uminp_zpzz_s, uint32_t, H1_4, DO_MIN)
|
||||
DO_ZPZZ_PAIR_D(sve2_uminp_zpzz_d, uint64_t, DO_MIN)
|
||||
|
||||
DO_ZPZZ_PAIR(sve2_smaxp_zpzz_b, int8_t, H1, DO_MAX)
|
||||
DO_ZPZZ_PAIR(sve2_smaxp_zpzz_h, int16_t, H1_2, DO_MAX)
|
||||
DO_ZPZZ_PAIR(sve2_smaxp_zpzz_s, int32_t, H1_4, DO_MAX)
|
||||
DO_ZPZZ_PAIR_D(sve2_smaxp_zpzz_d, int64_t, DO_MAX)
|
||||
|
||||
DO_ZPZZ_PAIR(sve2_sminp_zpzz_b, int8_t, H1, DO_MIN)
|
||||
DO_ZPZZ_PAIR(sve2_sminp_zpzz_h, int16_t, H1_2, DO_MIN)
|
||||
DO_ZPZZ_PAIR(sve2_sminp_zpzz_s, int32_t, H1_4, DO_MIN)
|
||||
DO_ZPZZ_PAIR_D(sve2_sminp_zpzz_d, int64_t, DO_MIN)
|
||||
|
||||
#undef DO_ZPZZ_PAIR
|
||||
#undef DO_ZPZZ_PAIR_D
|
||||
|
||||
/* Three-operand expander, controlled by a predicate, in which the
|
||||
* third operand is "wide". That is, for D = N op M, the same 64-bit
|
||||
* value of M is used with all of the narrower values of N.
|
||||
|
@ -5957,3 +5957,9 @@ DO_SVE2_ZPZZ(SHSUB, shsub)
|
||||
DO_SVE2_ZPZZ(UHADD, uhadd)
|
||||
DO_SVE2_ZPZZ(URHADD, urhadd)
|
||||
DO_SVE2_ZPZZ(UHSUB, uhsub)
|
||||
|
||||
DO_SVE2_ZPZZ(ADDP, addp)
|
||||
DO_SVE2_ZPZZ(SMAXP, smaxp)
|
||||
DO_SVE2_ZPZZ(UMAXP, umaxp)
|
||||
DO_SVE2_ZPZZ(SMINP, sminp)
|
||||
DO_SVE2_ZPZZ(UMINP, uminp)
|
||||
|
Loading…
Reference in New Issue
Block a user