mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
target/arm: Implement MVE incrementing/decrementing dup insns
Implement the MVE incrementing/decrementing dup insns VIDUP, VDDUP, VIWDUP and VDWDUP. These fill the elements of a vector with successively incrementing values, starting at the offset specified in a general purpose register. The final value of the offset is written back to this register. The wrapping variants take a second general purpose register which specifies the point where the count should wrap back to 0. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
c1bd78cb06
commit
395b92d50e
4 changed files with 220 additions and 0 deletions
|
@ -1695,3 +1695,66 @@ uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
|
|||
{
|
||||
return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
|
||||
}
|
||||
|
||||
#define DO_VIDUP(OP, ESIZE, TYPE, FN) \
|
||||
uint32_t HELPER(mve_##OP)(CPUARMState *env, void *vd, \
|
||||
uint32_t offset, uint32_t imm) \
|
||||
{ \
|
||||
TYPE *d = vd; \
|
||||
uint16_t mask = mve_element_mask(env); \
|
||||
unsigned e; \
|
||||
for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
|
||||
mergemask(&d[H##ESIZE(e)], offset, mask); \
|
||||
offset = FN(offset, imm); \
|
||||
} \
|
||||
mve_advance_vpt(env); \
|
||||
return offset; \
|
||||
}
|
||||
|
||||
#define DO_VIWDUP(OP, ESIZE, TYPE, FN) \
|
||||
uint32_t HELPER(mve_##OP)(CPUARMState *env, void *vd, \
|
||||
uint32_t offset, uint32_t wrap, \
|
||||
uint32_t imm) \
|
||||
{ \
|
||||
TYPE *d = vd; \
|
||||
uint16_t mask = mve_element_mask(env); \
|
||||
unsigned e; \
|
||||
for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
|
||||
mergemask(&d[H##ESIZE(e)], offset, mask); \
|
||||
offset = FN(offset, wrap, imm); \
|
||||
} \
|
||||
mve_advance_vpt(env); \
|
||||
return offset; \
|
||||
}
|
||||
|
||||
#define DO_VIDUP_ALL(OP, FN) \
|
||||
DO_VIDUP(OP##b, 1, int8_t, FN) \
|
||||
DO_VIDUP(OP##h, 2, int16_t, FN) \
|
||||
DO_VIDUP(OP##w, 4, int32_t, FN)
|
||||
|
||||
#define DO_VIWDUP_ALL(OP, FN) \
|
||||
DO_VIWDUP(OP##b, 1, int8_t, FN) \
|
||||
DO_VIWDUP(OP##h, 2, int16_t, FN) \
|
||||
DO_VIWDUP(OP##w, 4, int32_t, FN)
|
||||
|
||||
static uint32_t do_add_wrap(uint32_t offset, uint32_t wrap, uint32_t imm)
|
||||
{
|
||||
offset += imm;
|
||||
if (offset == wrap) {
|
||||
offset = 0;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static uint32_t do_sub_wrap(uint32_t offset, uint32_t wrap, uint32_t imm)
|
||||
{
|
||||
if (offset == 0) {
|
||||
offset = wrap;
|
||||
}
|
||||
offset -= imm;
|
||||
return offset;
|
||||
}
|
||||
|
||||
DO_VIDUP_ALL(vidup, DO_ADD)
|
||||
DO_VIWDUP_ALL(viwdup, do_add_wrap)
|
||||
DO_VIWDUP_ALL(vdwdup, do_sub_wrap)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue