Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,11 @@ add_test(x87pc ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}

set_tests_properties(x87pc PROPERTIES ENVIRONMENT "BOX64_DYNAREC_X87DOUBLE=2")

add_test(Boundary ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test33 -D TEST_OUTPUT=tmpfile33.txt
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref33.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )

else()

add_test(bootSyscall ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
Expand Down
8 changes: 4 additions & 4 deletions src/emu/x64primop.c
Original file line number Diff line number Diff line change
Expand Up @@ -1379,7 +1379,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;
}
Expand All @@ -1406,7 +1406,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;
}
Expand Down Expand Up @@ -1434,7 +1434,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;
}
Expand All @@ -1461,7 +1461,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;
}
Expand Down
1 change: 1 addition & 0 deletions tests/ref33.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
All tests Passed!
Binary file added tests/test33
Binary file not shown.
244 changes: 244 additions & 0 deletions tests/test33.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
// gcc test33.c -o test33 -O2

#include <stdint.h>
#include <limits.h>
#include <stdio.h>


/* Generic modulo test functions (for testing int8/int16/int32/int64) */
#define DEFINE_TEST_FUNCTIONS(TYPE, NAME, MIN_MACRO) \
__attribute__((noinline, noclone)) TYPE \
f1_##NAME (TYPE x, TYPE y) { \
return x % y; \
} \
__attribute__((noinline, noclone)) TYPE \
f2_##NAME (TYPE x, TYPE y) { \
return x % -y; \
} \
__attribute__((noinline, noclone)) TYPE \
f3_##NAME (TYPE x, TYPE y) { \
TYPE z = -y; \
return x % z; \
} \
static int test_##NAME##_direct(void) { \
volatile TYPE v1 = 1; \
volatile TYPE v2 = -1; \
volatile TYPE v3 = -1; \
\
/* Basic test: MIN % 1 */ \
if ((MIN_MACRO % (TYPE)1) != 0) \
return 1; \
\
/* Test via variable: MIN % variable 1 */ \
if ((MIN_MACRO % v1) != 0) \
return 1; \
\
/* Conditional branch test */ \
if (v2 == -1) { \
if ((MIN_MACRO % (TYPE)1) != 0) \
return 1; \
} else if ((MIN_MACRO % -v2) != 0) { \
return 1; \
} \
\
/* Test MIN % -(-1) */ \
if ((MIN_MACRO % -v3) != 0) \
return 1; \
\
return 0; \
} \
static int test_##NAME##_functions(void) { \
/* Test function call forms */ \
if (f1_##NAME(MIN_MACRO, 1) != 0) \
return 1; \
if (f2_##NAME(MIN_MACRO, -1) != 0) \
return 1; \
if (f3_##NAME(MIN_MACRO, -1) != 0) \
return 1; \
return 0; \
}

/* Define test functions for various integer types */
/* Use macro definitions from standard library */
DEFINE_TEST_FUNCTIONS(int8_t, int8, INT8_MIN)
DEFINE_TEST_FUNCTIONS(int16_t, int16, INT16_MIN)
DEFINE_TEST_FUNCTIONS(int32_t, int32, INT32_MIN)
DEFINE_TEST_FUNCTIONS(int64_t, int64, INT64_MIN)

/* Test regular int type (compatible with original test) */
__attribute__((noinline, noclone)) int
f1_int (int x, int y) {
return x % y;
}

__attribute__((noinline, noclone)) int
f2_int (int x, int y) {
return x % -y;
}

__attribute__((noinline, noclone)) int
f3_int (int x, int y) {
int z = -y;
return x % z;
}

static int test_int_direct(void) {
volatile int v1 = 1;
volatile int v2 = -1;
volatile int v3 = -1;

/* Use INT_MIN instead of -__INT_MAX__ - 1 */
if ((INT_MIN % 1) != 0)
return 1;
if ((INT_MIN % v1) != 0)
return 1;
if (v2 == -1) {
if ((INT_MIN % 1) != 0)
return 1;
} else if ((INT_MIN % -v2) != 0) {
return 1;
}
if ((INT_MIN % -v3) != 0)
return 1;

return 0;
}

static int test_int_functions(void) {
if (f1_int(INT_MIN, 1) != 0)
return 1;
if (f2_int(INT_MIN, -1) != 0)
return 1;
if (f3_int(INT_MIN, -1) != 0)
return 1;
return 0;
}

__attribute__((noinline, noclone)) long
f1_long (long x, long y) {
return x % y;
}

__attribute__((noinline, noclone)) long
f2_long (long x, long y) {
return x % -y;
}

__attribute__((noinline, noclone)) long
f3_long (long x, long y) {
long z = -y;
return x % z;
}

static int test_long_direct(void) {
volatile long v1 = 1L;
volatile long v2 = -1L;
volatile long v3 = -1L;

if ((LONG_MIN % 1L) != 0)
return 1;
if ((LONG_MIN % v1) != 0)
return 1;
if (v2 == -1L) {
if ((LONG_MIN % 1L) != 0)
return 1;
} else if ((LONG_MIN % -v2) != 0) {
return 1;
}
if ((LONG_MIN % -v3) != 0)
return 1;

return 0;
}

static int test_long_functions(void) {
if (f1_long(LONG_MIN, 1L) != 0)
return 1;
if (f2_long(LONG_MIN, -1L) != 0)
return 1;
if (f3_long(LONG_MIN, -1L) != 0)
return 1;
return 0;
}

/* Test long long type */
__attribute__((noinline, noclone)) long long
f1_longlong (long long x, long long y) {
return x % y;
}

__attribute__((noinline, noclone)) long long
f2_longlong (long long x, long long y) {
return x % -y;
}

__attribute__((noinline, noclone)) long long
f3_longlong (long long x, long long y) {
long long z = -y;
return x % z;
}

static int test_longlong_direct(void) {
volatile long long v1 = 1LL;
volatile long long v2 = -1LL;
volatile long long v3 = -1LL;

if ((LLONG_MIN % 1LL) != 0)
return 1;
if ((LLONG_MIN % v1) != 0)
return 1;
if (v2 == -1LL) {
if ((LLONG_MIN % 1LL) != 0)
return 1;
} else if ((LLONG_MIN % -v2) != 0) {
return 1;
}
if ((LLONG_MIN % -v3) != 0)
return 1;

return 0;
}

static int test_longlong_functions(void) {
if (f1_longlong(LLONG_MIN, 1LL) != 0)
return 1;
if (f2_longlong(LLONG_MIN, -1LL) != 0)
return 1;
if (f3_longlong(LLONG_MIN, -1LL) != 0)
return 1;
return 0;
}

int main(void) {
/* test int8_t */
if (test_int8_direct()) __builtin_abort();
if (test_int8_functions()) __builtin_abort();

/* Test int16_t */
if (test_int16_direct()) __builtin_abort();
if (test_int16_functions()) __builtin_abort();

/* Test int32_t */
if (test_int32_direct()) __builtin_abort();
if (test_int32_functions()) __builtin_abort();

/* Test int64_t */
if (test_int64_direct()) __builtin_abort();
if (test_int64_functions()) __builtin_abort();

/* Test regular int type */
if (test_int_direct()) __builtin_abort();
if (test_int_functions()) __builtin_abort();

/* Test long type */
if (test_long_direct()) __builtin_abort();
if (test_long_functions()) __builtin_abort();

/* Test long long type */
if (test_longlong_direct()) __builtin_abort();
if (test_longlong_functions()) __builtin_abort();

/* All tests passed */
printf("All tests Passed!\n");
return 0;
}
Loading