mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
target/arm: Implement MVE integer vector comparisons
Implement the MVE integer vector comparison instructions. These are "VCMP (vector)" encodings T1, T2 and T3, and "VPT (vector)" encodings T1, T2 and T3. These insns compare corresponding elements in each vector, and update the VPR.P0 predicate bits with the results of the comparison. VPT also sets the VPR.MASK01 and VPR.MASK23 fields -- it is effectively "VCMP then VPST". Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
552517861c
commit
eff5d9a9bd
4 changed files with 152 additions and 1 deletions
|
@ -1758,3 +1758,59 @@ static uint32_t do_sub_wrap(uint32_t offset, uint32_t wrap, uint32_t imm)
|
|||
DO_VIDUP_ALL(vidup, DO_ADD)
|
||||
DO_VIWDUP_ALL(viwdup, do_add_wrap)
|
||||
DO_VIWDUP_ALL(vdwdup, do_sub_wrap)
|
||||
|
||||
/*
|
||||
* Vector comparison.
|
||||
* P0 bits for non-executed beats (where eci_mask is 0) are unchanged.
|
||||
* P0 bits for predicated lanes in executed beats (where mask is 0) are 0.
|
||||
* P0 bits otherwise are updated with the results of the comparisons.
|
||||
* We must also keep unchanged the MASK fields at the top of v7m.vpr.
|
||||
*/
|
||||
#define DO_VCMP(OP, ESIZE, TYPE, FN) \
|
||||
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, void *vm) \
|
||||
{ \
|
||||
TYPE *n = vn, *m = vm; \
|
||||
uint16_t mask = mve_element_mask(env); \
|
||||
uint16_t eci_mask = mve_eci_mask(env); \
|
||||
uint16_t beatpred = 0; \
|
||||
uint16_t emask = MAKE_64BIT_MASK(0, ESIZE); \
|
||||
unsigned e; \
|
||||
for (e = 0; e < 16 / ESIZE; e++) { \
|
||||
bool r = FN(n[H##ESIZE(e)], m[H##ESIZE(e)]); \
|
||||
/* Comparison sets 0/1 bits for each byte in the element */ \
|
||||
beatpred |= r * emask; \
|
||||
emask <<= ESIZE; \
|
||||
} \
|
||||
beatpred &= mask; \
|
||||
env->v7m.vpr = (env->v7m.vpr & ~(uint32_t)eci_mask) | \
|
||||
(beatpred & eci_mask); \
|
||||
mve_advance_vpt(env); \
|
||||
}
|
||||
|
||||
#define DO_VCMP_S(OP, FN) \
|
||||
DO_VCMP(OP##b, 1, int8_t, FN) \
|
||||
DO_VCMP(OP##h, 2, int16_t, FN) \
|
||||
DO_VCMP(OP##w, 4, int32_t, FN)
|
||||
|
||||
#define DO_VCMP_U(OP, FN) \
|
||||
DO_VCMP(OP##b, 1, uint8_t, FN) \
|
||||
DO_VCMP(OP##h, 2, uint16_t, FN) \
|
||||
DO_VCMP(OP##w, 4, uint32_t, FN)
|
||||
|
||||
#define DO_EQ(N, M) ((N) == (M))
|
||||
#define DO_NE(N, M) ((N) != (M))
|
||||
#define DO_EQ(N, M) ((N) == (M))
|
||||
#define DO_EQ(N, M) ((N) == (M))
|
||||
#define DO_GE(N, M) ((N) >= (M))
|
||||
#define DO_LT(N, M) ((N) < (M))
|
||||
#define DO_GT(N, M) ((N) > (M))
|
||||
#define DO_LE(N, M) ((N) <= (M))
|
||||
|
||||
DO_VCMP_U(vcmpeq, DO_EQ)
|
||||
DO_VCMP_U(vcmpne, DO_NE)
|
||||
DO_VCMP_U(vcmpcs, DO_GE)
|
||||
DO_VCMP_U(vcmphi, DO_GT)
|
||||
DO_VCMP_S(vcmpge, DO_GE)
|
||||
DO_VCMP_S(vcmplt, DO_LT)
|
||||
DO_VCMP_S(vcmpgt, DO_GT)
|
||||
DO_VCMP_S(vcmple, DO_LE)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue