mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-21 11:11:37 +00:00
[gamecode] Add tests for load instructions
This needed the test struct declaration to be moved out to a head file so it can be shared with other tests.
This commit is contained in:
parent
28df32eb0d
commit
c86f1f671b
5 changed files with 151 additions and 32 deletions
|
@ -1,16 +1,22 @@
|
||||||
libs_gamecode_tests = \
|
libs_gamecode_tests = \
|
||||||
|
libs/gamecode/test/test-load \
|
||||||
libs/gamecode/test/test-store
|
libs/gamecode/test/test-store
|
||||||
|
|
||||||
TESTS += $(libs_gamecode_tests)
|
TESTS += $(libs_gamecode_tests)
|
||||||
|
|
||||||
check_PROGRAMS += $(libs_gamecode_tests)
|
check_PROGRAMS += $(libs_gamecode_tests)
|
||||||
|
|
||||||
EXTRA_DIST += main.c
|
EXTRA_DIST += head.c main.c
|
||||||
|
|
||||||
test_gamecode_libs= \
|
test_gamecode_libs= \
|
||||||
libs/gamecode/libQFgamecode.la \
|
libs/gamecode/libQFgamecode.la \
|
||||||
libs/util/libQFutil.la
|
libs/util/libQFutil.la
|
||||||
|
|
||||||
|
libs_gamecode_test_test_load_SOURCES= \
|
||||||
|
libs/gamecode/test/test-load.c
|
||||||
|
libs_gamecode_test_test_load_LDADD= $(test_gamecode_libs)
|
||||||
|
libs_gamecode_test_test_load_DEPENDENCIES= $(test_gamecode_libs)
|
||||||
|
|
||||||
libs_gamecode_test_test_store_SOURCES= \
|
libs_gamecode_test_test_store_SOURCES= \
|
||||||
libs/gamecode/test/test-store.c
|
libs/gamecode/test/test-store.c
|
||||||
libs_gamecode_test_test_store_LDADD= $(test_gamecode_libs)
|
libs_gamecode_test_test_store_LDADD= $(test_gamecode_libs)
|
||||||
|
|
31
libs/gamecode/test/head.c
Normal file
31
libs/gamecode/test/head.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "QF/progs.h"
|
||||||
|
|
||||||
|
static int verbose = 0;
|
||||||
|
|
||||||
|
// both calculates the number of globals in the test, and ensures that both
|
||||||
|
// init and expect are the same size (will product a "void value not ignored"
|
||||||
|
// error if the sizes differ)
|
||||||
|
#define num_globals(init, expect) \
|
||||||
|
__builtin_choose_expr ( \
|
||||||
|
sizeof (init) == sizeof (expect), sizeof (init) / sizeof (init[0]), \
|
||||||
|
(void) 0\
|
||||||
|
)
|
||||||
|
|
||||||
|
// calculate the numver of statements in the test
|
||||||
|
#define num_statements(statements) \
|
||||||
|
(sizeof (statements) / sizeof (statements[0]))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *desc;
|
||||||
|
pr_uint_t edict_area;
|
||||||
|
pr_uint_t extra_globals;
|
||||||
|
pr_uint_t num_globals;
|
||||||
|
pr_uint_t num_statements;
|
||||||
|
dstatement_t *statements;
|
||||||
|
pr_int_t *init_globals;
|
||||||
|
pr_int_t *expect_globals;
|
||||||
|
} test_t;
|
|
@ -68,6 +68,7 @@ setup_test (test_t *test)
|
||||||
test_pr.pr_trace = 1;
|
test_pr.pr_trace = 1;
|
||||||
test_pr.pr_trace_depth = -1;
|
test_pr.pr_trace_depth = -1;
|
||||||
test_pr.function_table = test_functions;
|
test_pr.function_table = test_functions;
|
||||||
|
|
||||||
test_pr.globals_size = test->num_globals;
|
test_pr.globals_size = test->num_globals;
|
||||||
pr_uint_t num_globals = test->num_globals + test->extra_globals;
|
pr_uint_t num_globals = test->num_globals + test->extra_globals;
|
||||||
test_pr.pr_globals = malloc (num_globals * sizeof (pr_type_t));
|
test_pr.pr_globals = malloc (num_globals * sizeof (pr_type_t));
|
||||||
|
@ -75,6 +76,10 @@ setup_test (test_t *test)
|
||||||
test->num_globals * sizeof (pr_type_t));
|
test->num_globals * sizeof (pr_type_t));
|
||||||
memset (test_pr.pr_globals + test->num_globals, 0,
|
memset (test_pr.pr_globals + test->num_globals, 0,
|
||||||
test->extra_globals * sizeof (pr_type_t));
|
test->extra_globals * sizeof (pr_type_t));
|
||||||
|
if (test->edict_area) {
|
||||||
|
test_pr.pr_edict_area = test_pr.pr_globals + test->edict_area;
|
||||||
|
}
|
||||||
|
|
||||||
test_pr.pr_statements
|
test_pr.pr_statements
|
||||||
= malloc ((test->num_statements + 1) * sizeof (dstatement_t));
|
= malloc ((test->num_statements + 1) * sizeof (dstatement_t));
|
||||||
memcpy (test_pr.pr_statements, test->statements,
|
memcpy (test_pr.pr_statements, test->statements,
|
||||||
|
@ -101,7 +106,7 @@ run_test (test_t *test)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
printf ("test #%zd: %s: OK\n", test - tests, test->desc);
|
printf ("test #%zd: %s: OK\n", test - tests, test->desc);
|
||||||
} else {
|
} else {
|
||||||
printf ("test #%zd: %s: bytes differ\n", test - tests, test->desc);
|
printf ("test #%zd: %s: words differ\n", test - tests, test->desc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf ("test #%zd: %s: critical failure\n", test - tests, test->desc);
|
printf ("test #%zd: %s: critical failure\n", test - tests, test->desc);
|
||||||
|
|
106
libs/gamecode/test/test-load.c
Normal file
106
libs/gamecode/test/test-load.c
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#include "head.c"
|
||||||
|
|
||||||
|
static pr_int_t test_globals_init[] = {
|
||||||
|
// pointers
|
||||||
|
24, 26, 28, 29,
|
||||||
|
32, -4, -2, 0,
|
||||||
|
1, 4, 0xdeadbeef, 0xfeedf00d,
|
||||||
|
// destination data
|
||||||
|
0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
// source data
|
||||||
|
11, 12, 9, 10,
|
||||||
|
8, 5, 6, 7,
|
||||||
|
1, 2, 3, 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
static pr_int_t test_globals_expect[] = {
|
||||||
|
// pointers
|
||||||
|
24, 26, 28, 29,
|
||||||
|
32, -4, -2, 0,
|
||||||
|
1, 4, 0xdeadbeef, 0xfeedf00d,
|
||||||
|
// destination data
|
||||||
|
1, 2, 3, 4,
|
||||||
|
5, 6, 7, 8,
|
||||||
|
9, 10, 11, 12,
|
||||||
|
// source data
|
||||||
|
11, 12, 9, 10,
|
||||||
|
8, 5, 6, 7,
|
||||||
|
1, 2, 3, 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BASE(b, base) (((base) & 3) << OP_##b##_SHIFT)
|
||||||
|
#define OP(a, b, c, op) ((op) | BASE(A, a) | BASE(B, b) | BASE(C, c))
|
||||||
|
|
||||||
|
static dstatement_t load_E_statements[] = {
|
||||||
|
{OP(0, 0, 0, OP_LOAD_E_4), 7, 9, 12},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_E_3), 7, 8, 16},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_E_1), 7, 7, 19},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_E_2), 7, 6, 20},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_E_2), 7, 5, 22},
|
||||||
|
};
|
||||||
|
|
||||||
|
static dstatement_t load_B_statements[] = {
|
||||||
|
{OP(0, 0, 0, OP_LOAD_B_4), 4, 0, 12},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_B_3), 3, 0, 16},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_B_1), 2, 0, 19},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_B_2), 1, 0, 20},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_B_2), 0, 0, 22},
|
||||||
|
};
|
||||||
|
|
||||||
|
static dstatement_t load_C_statements[] = {
|
||||||
|
{OP(0, 0, 0, OP_LOAD_C_4), 2, 4, 12},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_C_3), 2, 1, 16},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_C_1), 2, 0, 19},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_C_2), 2, -2, 20},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_C_2), 2, -4, 22},
|
||||||
|
};
|
||||||
|
|
||||||
|
static dstatement_t load_D_statements[] = {
|
||||||
|
{OP(0, 0, 0, OP_LOAD_D_4), 2, 9, 12},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_D_3), 2, 8, 16},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_D_1), 2, 7, 19},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_D_2), 2, 6, 20},
|
||||||
|
{OP(0, 0, 0, OP_LOAD_D_2), 2, 5, 22},
|
||||||
|
};
|
||||||
|
|
||||||
|
test_t tests[] = {
|
||||||
|
{
|
||||||
|
.desc = "load E",
|
||||||
|
.num_globals = num_globals (test_globals_init, test_globals_expect),
|
||||||
|
.num_statements = num_statements (load_E_statements),
|
||||||
|
.statements = load_E_statements,
|
||||||
|
.init_globals = test_globals_init,
|
||||||
|
.expect_globals = test_globals_expect,
|
||||||
|
// FIXME negative field offsets are not official but work because all
|
||||||
|
// offset calculations are done in 32-bit and thus wrap anyway
|
||||||
|
.edict_area = 28,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.desc = "load B",
|
||||||
|
.num_globals = num_globals (test_globals_init, test_globals_expect),
|
||||||
|
.num_statements = num_statements (load_B_statements),
|
||||||
|
.statements = load_B_statements,
|
||||||
|
.init_globals = test_globals_init,
|
||||||
|
.expect_globals = test_globals_expect,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.desc = "load C",
|
||||||
|
.num_globals = num_globals (test_globals_init, test_globals_expect),
|
||||||
|
.num_statements = num_statements (load_C_statements),
|
||||||
|
.statements = load_C_statements,
|
||||||
|
.init_globals = test_globals_init,
|
||||||
|
.expect_globals = test_globals_expect,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.desc = "load D",
|
||||||
|
.num_globals = num_globals (test_globals_init, test_globals_expect),
|
||||||
|
.num_statements = num_statements (load_D_statements),
|
||||||
|
.statements = load_D_statements,
|
||||||
|
.init_globals = test_globals_init,
|
||||||
|
.expect_globals = test_globals_expect,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "main.c"
|
|
@ -1,33 +1,4 @@
|
||||||
#ifdef HAVE_CONFIG_H
|
#include "head.c"
|
||||||
# include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "QF/progs.h"
|
|
||||||
|
|
||||||
static int verbose = 0;
|
|
||||||
|
|
||||||
// both calculates the number of globals in the test, and ensures that both
|
|
||||||
// init and expect are the same size (will product a "void value not ignored"
|
|
||||||
// error if the sizes differ)
|
|
||||||
#define num_globals(init, expect) \
|
|
||||||
__builtin_choose_expr ( \
|
|
||||||
sizeof (init) == sizeof (expect), sizeof (init) / sizeof (init[0]), \
|
|
||||||
(void) 0\
|
|
||||||
)
|
|
||||||
|
|
||||||
// calculate the numver of statements in the test
|
|
||||||
#define num_statements(statements) \
|
|
||||||
(sizeof (statements) / sizeof (statements[0]))
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *desc;
|
|
||||||
pr_uint_t extra_globals;
|
|
||||||
pr_uint_t num_globals;
|
|
||||||
pr_uint_t num_statements;
|
|
||||||
dstatement_t *statements;
|
|
||||||
pr_int_t *init_globals;
|
|
||||||
pr_int_t *expect_globals;
|
|
||||||
} test_t;
|
|
||||||
|
|
||||||
static pr_int_t test_globals_init[] = {
|
static pr_int_t test_globals_init[] = {
|
||||||
// pointers
|
// pointers
|
||||||
|
|
Loading…
Reference in a new issue