diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-08-13 17:11:56 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-08-25 10:48:50 +0100 |
commit | 0f31e37c7f0b9577c6ce46304158ccd7c935006b (patch) | |
tree | fbcb2f0f86862ee0c3a48a32e2bd3a1cfcd7add6 /target/arm/mve_helper.c | |
parent | fea3958fa11c75b4f3f335ac0ce4cfc5cf0af7de (diff) | |
download | qemu-0f31e37c7f0b9577c6ce46304158ccd7c935006b.zip qemu-0f31e37c7f0b9577c6ce46304158ccd7c935006b.tar.gz qemu-0f31e37c7f0b9577c6ce46304158ccd7c935006b.tar.bz2 |
target/arm: Implement MVE VCTP
Implement the MVE VCTP insn, which sets the VPR.P0 predicate bits so
as to predicate any element at index Rn or greater is predicated. As
with VPNOT, this insn itself is predicable and subject to beatwise
execution.
The calculation of the mask is the same as is used to determine
ltpmask in mve_element_mask(), but we precalculate masklen in
generated code to avoid having to have 4 helpers specialized by size.
We put the decode line in with the low-overhead-loop insns in
t32.decode because it's logically part of that collection of insn
patterns, even though it is an MVE only insn.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/arm/mve_helper.c')
-rw-r--r-- | target/arm/mve_helper.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c index c22a00c..1752555 100644 --- a/target/arm/mve_helper.c +++ b/target/arm/mve_helper.c @@ -2218,6 +2218,26 @@ void HELPER(mve_vpnot)(CPUARMState *env) mve_advance_vpt(env); } +/* + * VCTP: P0 unexecuted bits unchanged, predicated bits zeroed, + * otherwise set according to value of Rn. The calculation of + * newmask here works in the same way as the calculation of the + * ltpmask in mve_element_mask(), but we have pre-calculated + * the masklen in the generated code. + */ +void HELPER(mve_vctp)(CPUARMState *env, uint32_t masklen) +{ + uint16_t mask = mve_element_mask(env); + uint16_t eci_mask = mve_eci_mask(env); + uint16_t newmask; + + assert(masklen <= 16); + newmask = masklen ? MAKE_64BIT_MASK(0, masklen) : 0; + newmask &= mask; + env->v7m.vpr = (env->v7m.vpr & ~(uint32_t)eci_mask) | (newmask & eci_mask); + mve_advance_vpt(env); +} + #define DO_1OP_SAT(OP, ESIZE, TYPE, FN) \ void HELPER(mve_##OP)(CPUARMState *env, void *vd, void *vm) \ { \ |