target/sh4: Fix mac.l with saturation enabled

The saturation arithmetic logic in helper_macl is not correct.
I tested and verified this behavior on a SH7091.

Signed-off-by: Zack Buhman <zack@buhman.org>
Message-Id: <20240404162641.27528-2-zack@buhman.org>
[rth: Reformat helper_macl, add a test case.]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
This commit is contained in:
Zack Buhman 2024-04-05 15:17:39 -10:00 committed by Richard Henderson
parent 7d95db5e78
commit c97e8977dc
4 changed files with 86 additions and 11 deletions

View file

@ -158,20 +158,23 @@ void helper_ocbi(CPUSH4State *env, uint32_t address)
}
}
void helper_macl(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
void helper_macl(CPUSH4State *env, int32_t arg0, int32_t arg1)
{
const int64_t min = -(1ll << 47);
const int64_t max = (1ll << 47) - 1;
int64_t mul = (int64_t)arg0 * arg1;
int64_t mac = env->mac;
int64_t res;
res = ((uint64_t) env->mach << 32) | env->macl;
res += (int64_t) (int32_t) arg0 *(int64_t) (int32_t) arg1;
env->mach = (res >> 32) & 0xffffffff;
env->macl = res & 0xffffffff;
if (env->sr & (1u << SR_S)) {
if (res < 0)
env->mach |= 0xffff0000;
else
env->mach &= 0x00007fff;
if (!(env->sr & (1u << SR_S))) {
res = mac + mul;
} else if (sadd64_overflow(mac, mul, &res)) {
res = mac < 0 ? min : max;
} else {
res = MIN(MAX(res, min), max);
}
env->mac = res;
}
void helper_macw(CPUSH4State *env, uint32_t arg0, uint32_t arg1)