target/arm: Implement SVE2 MATCH, NMATCH
Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Stephen Long <steplong@quicinc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210525010358.152808-34-richard.henderson@linaro.org Message-Id: <20200415145915.2859-1-steplong@quicinc.com> [rth: Expanded comment for do_match2] Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
911cdc6d79
commit
e0ae6ec383
@ -2509,6 +2509,16 @@ DEF_HELPER_FLAGS_3(sve2_uqrshrnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(sve2_uqrshrnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(sve2_uqrshrnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(sve2_match_ppzz_b, TCG_CALL_NO_RWG,
|
||||
i32, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_match_ppzz_h, TCG_CALL_NO_RWG,
|
||||
i32, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(sve2_nmatch_ppzz_b, TCG_CALL_NO_RWG,
|
||||
i32, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_nmatch_ppzz_h, TCG_CALL_NO_RWG,
|
||||
i32, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_s, TCG_CALL_NO_RWG,
|
||||
|
@ -1320,6 +1320,11 @@ UQSHRNT 01000101 .. 1 ..... 00 1101 ..... ..... @rd_rn_tszimm_shr
|
||||
UQRSHRNB 01000101 .. 1 ..... 00 1110 ..... ..... @rd_rn_tszimm_shr
|
||||
UQRSHRNT 01000101 .. 1 ..... 00 1111 ..... ..... @rd_rn_tszimm_shr
|
||||
|
||||
### SVE2 Character Match
|
||||
|
||||
MATCH 01000101 .. 1 ..... 100 ... ..... 0 .... @pd_pg_rn_rm
|
||||
NMATCH 01000101 .. 1 ..... 100 ... ..... 1 .... @pd_pg_rn_rm
|
||||
|
||||
## SVE2 floating-point pairwise operations
|
||||
|
||||
FADDP 01100100 .. 010 00 0 100 ... ..... ..... @rdn_pg_rm
|
||||
|
@ -6847,3 +6847,67 @@ void HELPER(sve2_nbsl)(void *vd, void *vn, void *vm, void *vk, uint32_t desc)
|
||||
d[i] = ~((n[i] & k[i]) | (m[i] & ~k[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if m0 or m1 contains the low uint8_t/uint16_t in n.
|
||||
* See hasless(v,1) from
|
||||
* https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
|
||||
*/
|
||||
static inline bool do_match2(uint64_t n, uint64_t m0, uint64_t m1, int esz)
|
||||
{
|
||||
int bits = 8 << esz;
|
||||
uint64_t ones = dup_const(esz, 1);
|
||||
uint64_t signs = ones << (bits - 1);
|
||||
uint64_t cmp0, cmp1;
|
||||
|
||||
cmp1 = dup_const(esz, n);
|
||||
cmp0 = cmp1 ^ m0;
|
||||
cmp1 = cmp1 ^ m1;
|
||||
cmp0 = (cmp0 - ones) & ~cmp0;
|
||||
cmp1 = (cmp1 - ones) & ~cmp1;
|
||||
return (cmp0 | cmp1) & signs;
|
||||
}
|
||||
|
||||
static inline uint32_t do_match(void *vd, void *vn, void *vm, void *vg,
|
||||
uint32_t desc, int esz, bool nmatch)
|
||||
{
|
||||
uint16_t esz_mask = pred_esz_masks[esz];
|
||||
intptr_t opr_sz = simd_oprsz(desc);
|
||||
uint32_t flags = PREDTEST_INIT;
|
||||
intptr_t i, j, k;
|
||||
|
||||
for (i = 0; i < opr_sz; i += 16) {
|
||||
uint64_t m0 = *(uint64_t *)(vm + i);
|
||||
uint64_t m1 = *(uint64_t *)(vm + i + 8);
|
||||
uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)) & esz_mask;
|
||||
uint16_t out = 0;
|
||||
|
||||
for (j = 0; j < 16; j += 8) {
|
||||
uint64_t n = *(uint64_t *)(vn + i + j);
|
||||
|
||||
for (k = 0; k < 8; k += 1 << esz) {
|
||||
if (pg & (1 << (j + k))) {
|
||||
bool o = do_match2(n >> (k * 8), m0, m1, esz);
|
||||
out |= (o ^ nmatch) << (j + k);
|
||||
}
|
||||
}
|
||||
}
|
||||
*(uint16_t *)(vd + H1_2(i >> 3)) = out;
|
||||
flags = iter_predtest_fwd(out, pg, flags);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
#define DO_PPZZ_MATCH(NAME, ESZ, INV) \
|
||||
uint32_t HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
|
||||
{ \
|
||||
return do_match(vd, vn, vm, vg, desc, ESZ, INV); \
|
||||
}
|
||||
|
||||
DO_PPZZ_MATCH(sve2_match_ppzz_b, MO_8, false)
|
||||
DO_PPZZ_MATCH(sve2_match_ppzz_h, MO_16, false)
|
||||
|
||||
DO_PPZZ_MATCH(sve2_nmatch_ppzz_b, MO_8, true)
|
||||
DO_PPZZ_MATCH(sve2_nmatch_ppzz_h, MO_16, true)
|
||||
|
||||
#undef DO_PPZZ_MATCH
|
||||
|
@ -7462,6 +7462,28 @@ static bool trans_UQRSHRNT(DisasContext *s, arg_rri_esz *a)
|
||||
return do_sve2_shr_narrow(s, a, ops);
|
||||
}
|
||||
|
||||
static bool do_sve2_ppzz_flags(DisasContext *s, arg_rprr_esz *a,
|
||||
gen_helper_gvec_flags_4 *fn)
|
||||
{
|
||||
if (!dc_isar_feature(aa64_sve2, s)) {
|
||||
return false;
|
||||
}
|
||||
return do_ppzz_flags(s, a, fn);
|
||||
}
|
||||
|
||||
#define DO_SVE2_PPZZ_MATCH(NAME, name) \
|
||||
static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a) \
|
||||
{ \
|
||||
static gen_helper_gvec_flags_4 * const fns[4] = { \
|
||||
gen_helper_sve2_##name##_ppzz_b, gen_helper_sve2_##name##_ppzz_h, \
|
||||
NULL, NULL \
|
||||
}; \
|
||||
return do_sve2_ppzz_flags(s, a, fns[a->esz]); \
|
||||
}
|
||||
|
||||
DO_SVE2_PPZZ_MATCH(MATCH, match)
|
||||
DO_SVE2_PPZZ_MATCH(NMATCH, nmatch)
|
||||
|
||||
static bool do_sve2_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
|
||||
gen_helper_gvec_4_ptr *fn)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user