target/arm: Implement MVE VMAXA, VMINA

Implement the MVE VMAXA and VMINA insns, which take the absolute
value of the signed elements in the input vector and then accumulate
the unsigned max or min into the destination vector.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Peter Maydell 2021-08-13 17:11:55 +01:00
parent 398e7cd3cd
commit d5c571ea6d
4 changed files with 40 additions and 0 deletions

View file

@ -2237,3 +2237,29 @@ DO_1OP_SAT(vqabsw, 4, int32_t, DO_VQABS_W)
DO_1OP_SAT(vqnegb, 1, int8_t, DO_VQNEG_B)
DO_1OP_SAT(vqnegh, 2, int16_t, DO_VQNEG_H)
DO_1OP_SAT(vqnegw, 4, int32_t, DO_VQNEG_W)
/*
* VMAXA, VMINA: vd is unsigned; vm is signed, and we take its
* absolute value; we then do an unsigned comparison.
*/
#define DO_VMAXMINA(OP, ESIZE, STYPE, UTYPE, FN) \
void HELPER(mve_##OP)(CPUARMState *env, void *vd, void *vm) \
{ \
UTYPE *d = vd; \
STYPE *m = vm; \
uint16_t mask = mve_element_mask(env); \
unsigned e; \
for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
UTYPE r = DO_ABS(m[H##ESIZE(e)]); \
r = FN(d[H##ESIZE(e)], r); \
mergemask(&d[H##ESIZE(e)], r, mask); \
} \
mve_advance_vpt(env); \
}
DO_VMAXMINA(vmaxab, 1, int8_t, uint8_t, DO_MAX)
DO_VMAXMINA(vmaxah, 2, int16_t, uint16_t, DO_MAX)
DO_VMAXMINA(vmaxaw, 4, int32_t, uint32_t, DO_MAX)
DO_VMAXMINA(vminab, 1, int8_t, uint8_t, DO_MIN)
DO_VMAXMINA(vminah, 2, int16_t, uint16_t, DO_MIN)
DO_VMAXMINA(vminaw, 4, int32_t, uint32_t, DO_MIN)