Mercurial > vec
changeset 26:6c91cd9a2f2d
include/vec/vec: fix vec_avg implementation
now it's exactly the same as AltiVec's
author | Paper <paper@tflc.us> |
---|---|
date | Mon, 25 Nov 2024 04:43:22 +0000 |
parents | 92156fe32755 |
children | d00b95f95dd1 |
files | include/vec/vec.h |
diffstat | 1 files changed, 7 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/include/vec/vec.h Sun Nov 24 11:15:59 2024 +0000 +++ b/include/vec/vec.h Mon Nov 25 04:43:22 2024 +0000 @@ -239,19 +239,14 @@ inline vec_intmax vec_avg(vec_intmax x, vec_intmax y) { - if ((x < 0) == (y < 0)) { // same sign - // this gets the equivalent of: - // vec_int32 r = ((vec_int64)x + (vec_int64)y) / 2; - vec_intmax r = (x / 2) + (y / 2) + (((x % 2) + (y % 2)) / 2); - - // FIXME emulate AltiVec quirks + vec_intmax x_d_quot = (x / 2); + vec_intmax x_d_rem = (x % 2); + vec_intmax y_d_quot = (y / 2); + vec_intmax y_d_rem = (y % 2); + vec_intmax rem_d_quot = ((x_d_rem + y_d_rem) / 2); + vec_intmax rem_d_rem = ((x_d_rem + y_d_rem) % 2); - return r; - } else { - vec_intmax r = (x + y) / 2; - // FIXME emulate AltiVec quirks - return r; - } + return (x_d_quot + y_d_quot) + (rem_d_quot) + (rem_d_rem == 1); } inline vec_uintmax vec_uavg(vec_uintmax x, vec_uintmax y)