mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
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:
parent
7d95db5e78
commit
c97e8977dc
4 changed files with 86 additions and 11 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue