-
-
Notifications
You must be signed in to change notification settings - Fork 391
Description
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; }