The saturation arithmetic logic in helper_macl is not correct.
I tested and verified this behavior on a SH7091, the general pattern
is a code sequence such as:
sets
mov.l _mach,r2
lds r2,mach
mov.l _macl,r2
lds r2,macl
mova _n,r0
mov r0,r1
mova _m,r0
mac.l @r0+,@r1+
_mach: .long 0x00007fff
_macl: .long 0x12345678
_m: .long 0x7fffffff
_n: .long 0x7fffffff
Test case 0: (no int64_t overflow)
given; prior to saturation mac.l:
mach = 0x00007fff macl = 0x12345678
@r0 = 0x7fffffff @r1 = 0x7fffffff
expected saturation mac.l result:
mach = 0x00007fff macl = 0xffffffff
qemu saturation mac.l result (prior to this commit):
mach = 0x00007ffe macl = 0x12345678
Test case 1: (no int64_t overflow)
given; prior to saturation mac.l:
mach = 0xffff8000 macl = 0x00000000
@r0 = 0xffffffff @r1 = 0x00000001
expected saturation mac.l result:
mach = 0xffff8000 macl = 0x00000000
qemu saturation mac.l result (prior to this commit):
mach = 0xffff7fff macl = 0xffffffff
Test case 2: (int64_t addition overflow)
given; prior to saturation mac.l:
mach = 0x80000000 macl = 0x00000000
@r0 = 0xffffffff @r1 = 0x00000001
expected saturation mac.l result:
mach = 0xffff8000 macl = 0x00000000
qemu saturation mac.l result (prior to this commit):
mach = 0xffff7fff macl = 0xffffffff
Test case 3: (int64_t addition overflow)
given; prior to saturation mac.l:
mach = 0x7fffffff macl = 0x00000000
@r0 = 0x7fffffff @r1 = 0x7fffffff
expected saturation mac.l result:
mach = 0x00007fff macl = 0xffffffff
qemu saturation mac.l result (prior to this commit):
mach = 0xfffffffe macl = 0x00000001
All of the above also matches the description of MAC.L as documented
in cd00147165-sh-4-32-bit-cpu-core-architecture-stmicroelectronics.pdf
---
target/sh4/op_helper.c | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)