target/arm: Fix MVE 48-bit SQRSHRL for small right shifts
We got an edge case wrong in the 48-bit SQRSHRL implementation: if the shift is to the right, although it always makes the result smaller than the input value it might not be within the 48-bit range the result is supposed to be if the input had some bits in [63..48] set and the shift didn't bring all of those within the [47..0] range. Handle this similarly to the way we already do for this case in do_uqrshl48_d(): extend the calculated result from 48 bits, and return that if not saturating or if it doesn't change the result; otherwise fall through to return a saturated value. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
95351aa76c
commit
fdcf2269c4
@ -1563,6 +1563,8 @@ uint64_t HELPER(mve_uqrshll)(CPUARMState *env, uint64_t n, uint32_t shift)
|
||||
static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
|
||||
bool round, uint32_t *sat)
|
||||
{
|
||||
int64_t val, extval;
|
||||
|
||||
if (shift <= -48) {
|
||||
/* Rounding the sign bit always produces 0. */
|
||||
if (round) {
|
||||
@ -1572,9 +1574,14 @@ static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
|
||||
} else if (shift < 0) {
|
||||
if (round) {
|
||||
src >>= -shift - 1;
|
||||
return (src >> 1) + (src & 1);
|
||||
val = (src >> 1) + (src & 1);
|
||||
} else {
|
||||
val = src >> -shift;
|
||||
}
|
||||
extval = sextract64(val, 0, 48);
|
||||
if (!sat || val == extval) {
|
||||
return extval;
|
||||
}
|
||||
return src >> -shift;
|
||||
} else if (shift < 48) {
|
||||
int64_t extval = sextract64(src << shift, 0, 48);
|
||||
if (!sat || src == (extval >> shift)) {
|
||||
|
Loading…
Reference in New Issue
Block a user