From ffbb6122b9f485edaf31cc0d44713b8ead88cc78 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 3 Jan 2022 16:29:42 +0900 Subject: [PATCH] [gamecode] Add tests for push and pop --- libs/gamecode/test/Makemodule.am | 6 + libs/gamecode/test/head.c | 6 +- libs/gamecode/test/main.c | 28 +++- libs/gamecode/test/test-load.c | 3 - libs/gamecode/test/test-stack.c | 227 +++++++++++++++++++++++++++++++ libs/gamecode/test/test-store.c | 3 - 6 files changed, 262 insertions(+), 11 deletions(-) create mode 100644 libs/gamecode/test/test-stack.c diff --git a/libs/gamecode/test/Makemodule.am b/libs/gamecode/test/Makemodule.am index e8a21ee58..b06e1c9fa 100644 --- a/libs/gamecode/test/Makemodule.am +++ b/libs/gamecode/test/Makemodule.am @@ -1,5 +1,6 @@ libs_gamecode_tests = \ libs/gamecode/test/test-load \ + libs/gamecode/test/test-stack \ libs/gamecode/test/test-store TESTS += $(libs_gamecode_tests) @@ -17,6 +18,11 @@ libs_gamecode_test_test_load_SOURCES= \ libs_gamecode_test_test_load_LDADD= $(test_gamecode_libs) libs_gamecode_test_test_load_DEPENDENCIES= $(test_gamecode_libs) +libs_gamecode_test_test_stack_SOURCES= \ + libs/gamecode/test/test-stack.c +libs_gamecode_test_test_stack_LDADD= $(test_gamecode_libs) +libs_gamecode_test_test_stack_DEPENDENCIES= $(test_gamecode_libs) + libs_gamecode_test_test_store_SOURCES= \ libs/gamecode/test/test-store.c libs_gamecode_test_test_store_LDADD= $(test_gamecode_libs) diff --git a/libs/gamecode/test/head.c b/libs/gamecode/test/head.c index c4e099c78..c7db8fb26 100644 --- a/libs/gamecode/test/head.c +++ b/libs/gamecode/test/head.c @@ -19,9 +19,13 @@ static int verbose = 0; #define num_statements(statements) \ (sizeof (statements) / sizeof (statements[0])) +#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)) + typedef struct { const char *desc; - pr_uint_t edict_area; + pointer_t edict_area; + pointer_t stack_size; pr_uint_t extra_globals; pr_uint_t num_globals; pr_uint_t num_statements; diff --git a/libs/gamecode/test/main.c b/libs/gamecode/test/main.c index 184db9cf4..4e231b5e0 100644 --- a/libs/gamecode/test/main.c +++ b/libs/gamecode/test/main.c @@ -27,6 +27,8 @@ static jmp_buf jump_buffer; static void test_debug_handler (prdebug_t event, void *param, void *data) { + progs_t *pr = data; + switch (event) { case prd_breakpoint: if (verbose > 0) { @@ -42,8 +44,16 @@ test_debug_handler (prdebug_t event, void *param, void *data) case prd_trace: dstatement_t *st = test_pr.pr_statements + test_pr.pr_xstatement; if (verbose > 0) { - printf ("debug: trace %05x %04x %04x %04x %04x\n", - test_pr.pr_xstatement, st->op, st->a, st->b, st->c); + printf ("debug: trace %05x %04x %04x %04x %04x%s\n", + test_pr.pr_xstatement, st->op, st->a, st->b, st->c, + pr->globals.stack ? va (0, " %05x", *pr->globals.stack) + : ""); + } + if (pr->globals.stack) { + if (*pr->globals.stack & 3) { + printf ("stack not aligned: %d\n", *pr->globals.stack); + longjmp (jump_buffer, 3); + } } break; case prd_runerror: @@ -65,17 +75,26 @@ setup_test (test_t *test) memset (&test_pr, 0, sizeof (test_pr)); test_pr.progs = &test_progs; test_pr.debug_handler = test_debug_handler; + test_pr.debug_data = &test_pr; test_pr.pr_trace = 1; test_pr.pr_trace_depth = -1; test_pr.function_table = test_functions; - 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; + num_globals += test->extra_globals + test->stack_size; + + test_pr.globals_size = num_globals; test_pr.pr_globals = malloc (num_globals * sizeof (pr_type_t)); memcpy (test_pr.pr_globals, test->init_globals, test->num_globals * sizeof (pr_type_t)); memset (test_pr.pr_globals + test->num_globals, 0, test->extra_globals * sizeof (pr_type_t)); + if (test->stack_size) { + pointer_t stack = num_globals - test->stack_size; + test_pr.stack_bottom = stack + 4; + test_pr.globals.stack = (pointer_t *) (test_pr.pr_globals + stack); + *test_pr.globals.stack = num_globals; + } if (test->edict_area) { test_pr.pr_edict_area = test_pr.pr_globals + test->edict_area; } @@ -128,6 +147,7 @@ main (int argc, char **argv) Cmd_Init (); Cvar_Init (); PR_Init_Cvars (); + pr_boundscheck->int_val = 1; while ((c = getopt (argc, argv, "qvt:")) != EOF) { switch (c) { diff --git a/libs/gamecode/test/test-load.c b/libs/gamecode/test/test-load.c index 212aaa49b..e283ced38 100644 --- a/libs/gamecode/test/test-load.c +++ b/libs/gamecode/test/test-load.c @@ -30,9 +30,6 @@ static pr_int_t test_globals_expect[] = { 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}, diff --git a/libs/gamecode/test/test-stack.c b/libs/gamecode/test/test-stack.c new file mode 100644 index 000000000..183e33694 --- /dev/null +++ b/libs/gamecode/test/test-stack.c @@ -0,0 +1,227 @@ +#include "head.c" + +static pr_int_t test_globals_init1[] = { + // pointers + 24, 26, 28, 29, + 32, -4, -2, 0, + 1, 4, 0xdeadbeef, 0xfeedf00d, + // source data + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + // destination data + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, +}; + +static pr_int_t test_globals_expect1[] = { + // pointers + 24, 26, 28, 29, + 32, -4, -2, 0, + 1, 4, 0xdeadbeef, 0xfeedf00d, + // source data + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + // destination data + 11, 12, 9, 10, + 8, 5, 6, 7, + 1, 2, 3, 4, +}; + +static pr_int_t test_globals_init2[] = { + // 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_expect2[] = { + // 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, +}; + +static dstatement_t stack_AA_statements[] = { + {OP(0, 0, 0, OP_PUSH_A_4), 12, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_3), 16, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_1), 19, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_2), 20, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_2), 22, 0, 0}, + + {OP(0, 0, 0, OP_POP_A_2), 24, 0, 0}, + {OP(0, 0, 0, OP_POP_A_2), 26, 0, 0}, + {OP(0, 0, 0, OP_POP_A_1), 28, 0, 0}, + {OP(0, 0, 0, OP_POP_A_3), 29, 0, 0}, + {OP(0, 0, 0, OP_POP_A_4), 32, 0, 0}, +}; + +static dstatement_t stack_AB_statements[] = { + {OP(0, 0, 0, OP_PUSH_A_4), 12, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_3), 16, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_1), 19, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_2), 20, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_2), 22, 0, 0}, + + {OP(0, 0, 0, OP_POP_B_2), 0, 0, 0}, + {OP(0, 0, 0, OP_POP_B_2), 1, 0, 0}, + {OP(0, 0, 0, OP_POP_B_1), 2, 0, 0}, + {OP(0, 0, 0, OP_POP_B_3), 3, 0, 0}, + {OP(0, 0, 0, OP_POP_B_4), 4, 0, 0}, +}; + +static dstatement_t stack_AC_statements[] = { + {OP(0, 0, 0, OP_PUSH_A_4), 12, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_3), 16, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_1), 19, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_2), 20, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_2), 22, 0, 0}, + + {OP(0, 0, 0, OP_POP_C_2), 2, -4, 0}, + {OP(0, 0, 0, OP_POP_C_2), 2, -2, 0}, + {OP(0, 0, 0, OP_POP_C_1), 2, 0, 0}, + {OP(0, 0, 0, OP_POP_C_3), 2, 1, 0}, + {OP(0, 0, 0, OP_POP_C_4), 2, 4, 0}, +}; + +static dstatement_t stack_AD_statements[] = { + {OP(0, 0, 0, OP_PUSH_A_4), 12, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_3), 16, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_1), 19, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_2), 20, 0, 0}, + {OP(0, 0, 0, OP_PUSH_A_2), 22, 0, 0}, + + {OP(0, 0, 0, OP_POP_D_2), 2, 5, 0}, + {OP(0, 0, 0, OP_POP_D_2), 2, 6, 0}, + {OP(0, 0, 0, OP_POP_D_1), 2, 7, 0}, + {OP(0, 0, 0, OP_POP_D_3), 2, 8, 0}, + {OP(0, 0, 0, OP_POP_D_4), 2, 9, 0}, +}; + +static dstatement_t stack_BA_statements[] = { + {OP(0, 0, 0, OP_PUSH_B_2), 0, 0, 0}, + {OP(0, 0, 0, OP_PUSH_B_2), 1, 0, 0}, + {OP(0, 0, 0, OP_PUSH_B_1), 2, 0, 0}, + {OP(0, 0, 0, OP_PUSH_B_3), 3, 0, 0}, + {OP(0, 0, 0, OP_PUSH_B_4), 4, 0, 0}, + + {OP(0, 0, 0, OP_POP_A_4), 12, 0, 0}, + {OP(0, 0, 0, OP_POP_A_3), 16, 0, 0}, + {OP(0, 0, 0, OP_POP_A_1), 19, 0, 0}, + {OP(0, 0, 0, OP_POP_A_2), 20, 0, 0}, + {OP(0, 0, 0, OP_POP_A_2), 22, 0, 0}, +}; + +static dstatement_t stack_CA_statements[] = { + {OP(0, 0, 0, OP_PUSH_C_2), 2, -4, 0}, + {OP(0, 0, 0, OP_PUSH_C_2), 2, -2, 0}, + {OP(0, 0, 0, OP_PUSH_C_1), 2, 0, 0}, + {OP(0, 0, 0, OP_PUSH_C_3), 2, 1, 0}, + {OP(0, 0, 0, OP_PUSH_C_4), 2, 4, 0}, + + {OP(0, 0, 0, OP_POP_A_4), 12, 0, 0}, + {OP(0, 0, 0, OP_POP_A_3), 16, 0, 0}, + {OP(0, 0, 0, OP_POP_A_1), 19, 0, 0}, + {OP(0, 0, 0, OP_POP_A_2), 20, 0, 0}, + {OP(0, 0, 0, OP_POP_A_2), 22, 0, 0}, +}; + +static dstatement_t stack_DA_statements[] = { + {OP(0, 0, 0, OP_PUSH_D_2), 2, 5, 0}, + {OP(0, 0, 0, OP_PUSH_D_2), 2, 6, 0}, + {OP(0, 0, 0, OP_PUSH_D_1), 2, 7, 0}, + {OP(0, 0, 0, OP_PUSH_D_3), 2, 8, 0}, + {OP(0, 0, 0, OP_PUSH_D_4), 2, 9, 0}, + + {OP(0, 0, 0, OP_POP_A_4), 12, 0, 0}, + {OP(0, 0, 0, OP_POP_A_3), 16, 0, 0}, + {OP(0, 0, 0, OP_POP_A_1), 19, 0, 0}, + {OP(0, 0, 0, OP_POP_A_2), 20, 0, 0}, + {OP(0, 0, 0, OP_POP_A_2), 22, 0, 0}, +}; + +test_t tests[] = { + { + .desc = "stack push A pop A", + .stack_size = 32, + .num_globals = num_globals (test_globals_init1, test_globals_expect1), + .num_statements = num_statements (stack_AA_statements), + .statements = stack_AA_statements, + .init_globals = test_globals_init1, + .expect_globals = test_globals_expect1, + }, + { + .desc = "stack push A pop B", + .stack_size = 32, + .num_globals = num_globals (test_globals_init1, test_globals_expect1), + .num_statements = num_statements (stack_AB_statements), + .statements = stack_AB_statements, + .init_globals = test_globals_init1, + .expect_globals = test_globals_expect1, + }, + { + .desc = "stack push A pop C", + .stack_size = 32, + .num_globals = num_globals (test_globals_init1, test_globals_expect1), + .num_statements = num_statements (stack_AC_statements), + .statements = stack_AC_statements, + .init_globals = test_globals_init1, + .expect_globals = test_globals_expect1, + }, + { + .desc = "stack push A pop D", + .stack_size = 32, + .num_globals = num_globals (test_globals_init1, test_globals_expect1), + .num_statements = num_statements (stack_AD_statements), + .statements = stack_AD_statements, + .init_globals = test_globals_init1, + .expect_globals = test_globals_expect1, + }, + { + .desc = "stack push B pop A", + .stack_size = 32, + .num_globals = num_globals (test_globals_init2, test_globals_expect2), + .num_statements = num_statements (stack_BA_statements), + .statements = stack_BA_statements, + .init_globals = test_globals_init2, + .expect_globals = test_globals_expect2, + }, + { + .desc = "stack push C pop A", + .stack_size = 32, + .num_globals = num_globals (test_globals_init2, test_globals_expect2), + .num_statements = num_statements (stack_CA_statements), + .statements = stack_CA_statements, + .init_globals = test_globals_init2, + .expect_globals = test_globals_expect2, + }, + { + .desc = "stack push D pop A", + .stack_size = 32, + .num_globals = num_globals (test_globals_init2, test_globals_expect2), + .num_statements = num_statements (stack_DA_statements), + .statements = stack_DA_statements, + .init_globals = test_globals_init2, + .expect_globals = test_globals_expect2, + }, +}; + +#include "main.c" diff --git a/libs/gamecode/test/test-store.c b/libs/gamecode/test/test-store.c index dee244485..dc580f028 100644 --- a/libs/gamecode/test/test-store.c +++ b/libs/gamecode/test/test-store.c @@ -30,9 +30,6 @@ static pr_int_t test_globals_expect[] = { 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 store_A_statements[] = { {OP(0, 0, 0, OP_STORE_A_4), 32, 0, 12}, {OP(0, 0, 0, OP_STORE_A_3), 29, 0, 16},