aboutsummaryrefslogtreecommitdiff
path: root/target/arm/mve_helper.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-08-13 17:11:47 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-08-25 10:48:48 +0100
commita5e59e8dcbbf7b1205370b3f4519749df5d0b726 (patch)
tree70f5e99872ee7748b4070ccd7b1faa789f424514 /target/arm/mve_helper.c
parented5a59d61f1619f4015a7a02f72e3590528008b4 (diff)
downloadqemu-a5e59e8dcbbf7b1205370b3f4519749df5d0b726.zip
qemu-a5e59e8dcbbf7b1205370b3f4519749df5d0b726.tar.gz
qemu-a5e59e8dcbbf7b1205370b3f4519749df5d0b726.tar.bz2
target/arm: Fix mask handling for MVE narrowing operations
In the MVE helpers for the narrowing operations (DO_VSHRN and DO_VSHRN_SAT) we were using the wrong bits of the predicate mask for the 'top' versions of the insn. This is because the loop works over the double-sized input elements and shifts the predicate mask by that many bits each time, but when we write out the half-sized output we must look at the mask bits for whichever half of the element we are writing to. Correct this by shifting the whole mask right by ESIZE bits for the 'top' insns. This allows us also to simplify the saturation bit checking (where we had noticed that we needed to look at a different mask bit for the 'top' 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.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
index 82151b0..847ef51 100644
--- a/target/arm/mve_helper.c
+++ b/target/arm/mve_helper.c
@@ -1358,6 +1358,7 @@ DO_VSHLL_ALL(vshllt, true)
TYPE *d = vd; \
uint16_t mask = mve_element_mask(env); \
unsigned le; \
+ mask >>= ESIZE * TOP; \
for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
TYPE r = FN(m[H##LESIZE(le)], shift); \
mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
@@ -1419,11 +1420,12 @@ static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
uint16_t mask = mve_element_mask(env); \
bool qc = false; \
unsigned le; \
+ mask >>= ESIZE * TOP; \
for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
bool sat = false; \
TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
- qc |= sat && (mask & 1 << (TOP * ESIZE)); \
+ qc |= sat & mask & 1; \
} \
if (qc) { \
env->vfp.qc[0] = qc; \