[BOX64]: ERROR on idiv8 idiv16 idiv32 idiv64
Hi ptitSeb, I found an issue in the idiv8/idiv16/idiv32/idiv64 function in the file src/emu/x64primop.c in box64. testcase on pass -DARM_DYNAREC=ON, failed when -DARM_DYNAREC=OFF
[testcase] build on x86-ubuntu22.04 gcc $c -O2 -o $c.out
#define INT64_MIN (-LONG_LONG_MAX - 1)
int main () { volatile long long l1 = 1; volatile long long l2 = -1; volatile long long l3 = -1;
if ((INT64_MIN % 1LL) != 0) __builtin_abort (); if ((INT64_MIN % l1) != 0) __builtin_abort (); if (l2 == -1) { if ((INT64_MIN % 1LL) != 0) __builtin_abort (); } else if ((INT64_MIN % -l2) != 0) __builtin_abort (); if ((INT64_MIN % -l3) != 0) __builtin_abort ();
return 0; }
--- a/src/emu/x64primop.c +++ b/src/emu/x64primop.c @@ -1378,7 +1378,7 @@ void idiv8(x64emu_t *emu, uint8_t s) div_t p = div(dvd, (int8_t)s); quot = p.quot; mod = p.rem;
-
if (abs(quot) > 0x7f) {
-
if ((int8_t)quot != quot) { INTR_RAISE_DIV0(emu); return; }
@@ -1405,7 +1405,7 @@ void idiv16(x64emu_t *emu, uint16_t s) div_t p = div(dvd, (int16_t)s); quot = p.quot; mod = p.rem;
-
if (abs(quot) > 0x7fff) {
-
if ((int16_t)quot != quot) { INTR_RAISE_DIV0(emu); return; }
@@ -1433,7 +1433,7 @@ void idiv32(x64emu_t *emu, uint32_t s) ldiv_t p = ldiv(dvd, (int32_t)s); quot = p.quot; mod = p.rem;
-
if (llabs(quot) > 0x7fffffff) {
-
if ((int32_t)quot != quot) { INTR_RAISE_DIV0(emu); return; }
@@ -1460,7 +1460,7 @@ void idiv64(x64emu_t *emu, uint64_t s) } quot = dvd/(int64_t)s; mod = dvd%(int64_t)s;
-
if ((quot > 0x7fffffffffffffffLL) || (quot < -0x7fffffffffffffffLL)) {
-
if ((int64_t)quot != quot) { INTR_RAISE_DIV0(emu); return; }
Indeed. Thanks for the test & analysis. Don't you want to create a PR with the fixes?
Yes, sure. I will prepare a pull request with the fixes and the test cases.