From 49dcd5ef4092a08753e785ec08345cb59fddd7a5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 15 Jan 2022 18:44:11 +0900 Subject: [PATCH] [gamecode] Add tests for the with instruction(s) While mode 4 was tested a lot, none of the rest were. Also added a full reset instruction. --- libs/gamecode/pr_exec.c | 30 +-- libs/gamecode/test/Makemodule.am | 16 +- libs/gamecode/test/test-with.c | 307 +++++++++++++++++++++++++++++++ 3 files changed, 337 insertions(+), 16 deletions(-) create mode 100644 libs/gamecode/test/test-with.c diff --git a/libs/gamecode/pr_exec.c b/libs/gamecode/pr_exec.c index b3a4afae9..69d9c0f6f 100644 --- a/libs/gamecode/pr_exec.c +++ b/libs/gamecode/pr_exec.c @@ -1893,49 +1893,57 @@ pr_with (progs_t *pr, const dstatement_t *st) pointer_t edict_area = pr->pr_edict_area - pr->pr_globals; pr_type_t *op_b = pr->pr_globals + PR_BASE (pr, st, B) + st->b; pr_type_t *stk; + pr_uint_t *base = &pr->pr_bases[st->c & 3]; switch (st->a) { // fixed offset case 0: // hard-0 base - pr->pr_bases[st->c & 3] = st->b; + *base = st->b; return; case 1: - // relative to current base - pr->pr_bases[st->c & 3] = PR_BASE (pr, st, B) + st->b; + // relative to current base (-ve offset) + *base = PR_BASE (pr, st, B) + (pr_short_t) st->b; return; case 2: // relative to stack (-ve offset) - pr->pr_bases[st->c & 3] = *pr->globals.stack + (pr_short_t) st->b; + *base = *pr->globals.stack + (pr_short_t) st->b; return; case 3: - // relative to edict_area (+ve only) - pr->pr_bases[st->c & 3] = edict_area + st->b; + // relative to edict_area (only +ve) + *base = edict_area + st->b; return; case 4: // hard-0 base - pr->pr_bases[st->c & 3] = pr->pr_globals[st->b].pointer_var; + *base = pr->pr_globals[st->b].pointer_var; return; case 5: - pr->pr_bases[st->c & 3] = OPB(pointer); + *base = OPB(pointer); return; case 6: // relative to stack (-ve offset) - pr->pr_bases[st->c & 3] = *pr->globals.stack + OPB(int); + *base = *pr->globals.stack + OPB(int); return; case 7: - // relative to edict_area (+ve only) - pr->pr_bases[st->c & 3] = edict_area + OPB(uint); + // relative to edict_area (only +ve) + *base = edict_area + OPB(uint); return; + case 8: + // pushregs stk = pr_stack_push (pr); STK(uivec4) = pr->pr_bases; return; case 9: + // popregs stk = pr_stack_pop (pr); pr->pr_bases = STK(uivec4); return; + case 10: + // reset + pr->pr_bases = (pr_uivec4_t) {}; + return; } PR_RunError (pr, "Invalid with index: %u", st->a); } diff --git a/libs/gamecode/test/Makemodule.am b/libs/gamecode/test/Makemodule.am index 364ebfea6..8fc813622 100644 --- a/libs/gamecode/test/Makemodule.am +++ b/libs/gamecode/test/Makemodule.am @@ -20,7 +20,8 @@ libs_gamecode_tests = \ libs/gamecode/test/test-store \ libs/gamecode/test/test-string \ libs/gamecode/test/test-unsigned \ - libs/gamecode/test/test-vector + libs/gamecode/test/test-vector \ + libs/gamecode/test/test-with TESTS += $(libs_gamecode_tests) @@ -132,12 +133,17 @@ libs_gamecode_test_test_string_SOURCES= \ libs_gamecode_test_test_string_LDADD= $(test_gamecode_libs) libs_gamecode_test_test_string_DEPENDENCIES= $(test_gamecode_libs) +libs_gamecode_test_test_unsigned_SOURCES= \ + libs/gamecode/test/test-unsigned.c +libs_gamecode_test_test_unsigned_LDADD= $(test_gamecode_libs) +libs_gamecode_test_test_unsigned_DEPENDENCIES= $(test_gamecode_libs) + libs_gamecode_test_test_vector_SOURCES= \ libs/gamecode/test/test-vector.c libs_gamecode_test_test_vector_LDADD= $(test_gamecode_libs) libs_gamecode_test_test_vector_DEPENDENCIES= $(test_gamecode_libs) -libs_gamecode_test_test_unsigned_SOURCES= \ - libs/gamecode/test/test-unsigned.c -libs_gamecode_test_test_unsigned_LDADD= $(test_gamecode_libs) -libs_gamecode_test_test_unsigned_DEPENDENCIES= $(test_gamecode_libs) +libs_gamecode_test_test_with_SOURCES= \ + libs/gamecode/test/test-with.c +libs_gamecode_test_test_with_LDADD= $(test_gamecode_libs) +libs_gamecode_test_test_with_DEPENDENCIES= $(test_gamecode_libs) diff --git a/libs/gamecode/test/test-with.c b/libs/gamecode/test/test-with.c new file mode 100644 index 000000000..f86637360 --- /dev/null +++ b/libs/gamecode/test/test-with.c @@ -0,0 +1,307 @@ +#include "head.c" + +#include "QF/mathlib.h" + +#define DB 0xdeadbeef + +static pr_ivec4_t pushregs_init[] = { + { DB, DB, DB, DB}, +}; + +static pr_ivec4_t pushregs_expect[] = { + { 0, 0, 0, 0}, // initial base regs should all be 0 +}; + +static dstatement_t pushregs_statements[] = { + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(0, 0, 0, OP_POP_A_4), 0, 0, 0 }, +}; + +static pr_ivec4_t popregs_init[] = { + { 4, 5, 6, 7}, + { DB, DB, DB, DB}, +}; + +static pr_ivec4_t popregs_expect[] = { + { 4, 5, 6, 7}, + { 7, 6, 5, 4}, +}; + +static dstatement_t popregs_statements[] = { + { OP(0, 0, 0, OP_PUSH_A_4), 0, 0, 0 }, + { OP(0, 0, 0, OP_WITH), 9, 0, 0 }, // popregs + { OP(3, 0, 0, OP_LEA_A), 0, 0, 0 }, + { OP(2, 0, 1, OP_LEA_A), 0, 0, 0 }, + { OP(1, 0, 2, OP_LEA_A), 0, 0, 0 }, + { OP(0, 0, 3, OP_LEA_A), 0, 0, 0 }, +}; + +static pr_ivec4_t with_0_init[] = { + { 4, 5, 6, 7}, + { DB, DB, DB, DB}, + { DB, DB, DB, DB}, + { DB, DB, DB, DB}, +}; + +static pr_ivec4_t with_0_expect[] = { + { 4, 5, 6, 7}, + { 0, 1, 6, 7}, + { 4, 5, 0, 1}, + { 0, 0, 0, 0}, +}; + +static dstatement_t with_0_statements[] = { + { OP(0, 0, 0, OP_PUSH_A_4), 0, 0, 0 }, + { OP(0, 0, 0, OP_WITH), 9, 0, 0 }, // popregs + { OP(0, 0, 0, OP_WITH), 0, 0, 0 }, // set reg 0 to 0 + { OP(0, 0, 0, OP_WITH), 0, 1, 1 }, // set reg 1 to 1 + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 }, + { OP(0, 0, 0, OP_PUSH_A_4), 0, 0, 0 }, + { OP(0, 0, 0, OP_WITH), 9, 0, 0 }, // popregs + { OP(0, 0, 0, OP_WITH), 0, 0, 2 }, // set reg 2 to 0 + { OP(0, 0, 0, OP_WITH), 0, 1, 3 }, // set reg 3 to 1 + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(2, 0, 0, OP_POP_A_4), 8, 0, 0 }, + { OP(0, 0, 0, OP_WITH), 10, 0, 0 }, // reset + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(2, 0, 0, OP_POP_A_4), 12, 0, 0 }, +}; + +static pr_ivec4_t with_1_init[] = { + { 4, 5, 6, 7}, + { DB, DB, DB, DB}, +}; + +static pr_ivec4_t with_1_expect[] = { + { 4, 5, 6, 7}, + { 0, 4, 6, 2}, +}; + +static dstatement_t with_1_statements[] = { + { OP(0, 0, 0, OP_WITH), 0, 4, 1 }, + { OP(0, 1, 0, OP_WITH), 1, 2, 2 }, + { OP(0, 1, 0, OP_WITH), 1, -2, 3 }, + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 }, +}; + +static pr_ivec4_t with_2_init[] = { + { 4, 5, 6, 7}, + { DB, DB, DB, DB}, + { DB, DB, DB, DB}, + { DB, DB, DB, DB}, +}; + +static pr_ivec4_t with_2_expect[] = { + { 4, 5, 6, 7}, + { 0, 44, 48, 40}, + { DB, DB, DB, DB}, + { DB, DB, DB, DB}, +}; + +static dstatement_t with_2_statements[] = { + { OP(0, 0, 0, OP_PUSH_A_4), 0, 0, 0 }, // so something is on the stack + { OP(0, 0, 0, OP_WITH), 2, 0, 1 }, + { OP(0, 1, 0, OP_WITH), 2, 4, 2 }, + { OP(0, 1, 0, OP_WITH), 2, -4, 3 }, + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 }, +}; + +static pr_ivec4_t with_3_init[] = { + { 4, 5, 6, 7}, + { DB, DB, DB, DB}, +}; + +static pr_ivec4_t with_3_expect[] = { + { 4, 5, 6, 7}, + { 0, 64, 68, 65596}, // edict-area relative is only +ve +}; + +static dstatement_t with_3_statements[] = { + { OP(0, 0, 0, OP_WITH), 3, 0, 1 }, + { OP(0, 1, 0, OP_WITH), 3, 4, 2 }, + { OP(0, 1, 0, OP_WITH), 3, -4, 3 }, + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 }, +}; + +static pr_ivec4_t with_4_init[] = { + { 4, 5, 6, 7}, + { DB, DB, DB, DB}, +}; + +static pr_ivec4_t with_4_expect[] = { + { 4, 5, 6, 7}, + { 0, 4, 5, 6}, +}; + +static dstatement_t with_4_statements[] = { + { OP(0, 0, 0, OP_WITH), 4, 0, 1 }, + { OP(0, 1, 0, OP_WITH), 4, 1, 2 }, + { OP(0, 1, 0, OP_WITH), 4, 2, 3 }, + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 }, +}; + +static pr_ivec4_t with_5_init[] = { + { 4, 5, 6, 7}, + { DB, DB, DB, DB}, +}; + +static pr_ivec4_t with_5_expect[] = { + { 4, 5, 6, 7}, + { 0, 2, 6, 7}, +}; + +static dstatement_t with_5_statements[] = { + { OP(0, 0, 0, OP_WITH), 0, 2, 1 }, + { OP(0, 1, 0, OP_WITH), 5, 0, 2 }, + { OP(0, 1, 0, OP_WITH), 5, 1, 3 }, + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 }, +}; + +static pr_ivec4_t with_6_init[] = { + { 4, 5, 6, -4}, + { DB, DB, DB, DB}, + { DB, DB, DB, DB}, + { DB, DB, DB, DB}, +}; + +static pr_ivec4_t with_6_expect[] = { + { 4, 5, 6, -4}, + { 0, 44, 48, 40}, + { DB, DB, DB, DB}, + { DB, DB, DB, DB}, +}; + +static dstatement_t with_6_statements[] = { + { OP(0, 0, 0, OP_PUSH_A_4), 0, 0, 0 }, // so something is on the stack + { OP(0, 0, 0, OP_WITH), 2, 0, 1 }, + { OP(0, 1, 0, OP_WITH), 6, 0, 2 }, + { OP(0, 1, 0, OP_WITH), 6, 3, 3 }, + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 }, +}; + +static pr_ivec4_t with_7_init[] = { + { 4, 5, 6, -4}, + { DB, DB, DB, DB}, +}; + +static pr_ivec4_t with_7_expect[] = { + { 4, 5, 6, -4}, + { 0, 2, 70, 60}, // edict-area relative is only +ve, but 32-bit wrap +}; + +static dstatement_t with_7_statements[] = { + { OP(0, 0, 0, OP_WITH), 0, 2, 1 }, + { OP(0, 1, 0, OP_WITH), 7, 0, 2 }, + { OP(0, 1, 0, OP_WITH), 7, 1, 3 }, + { OP(0, 0, 0, OP_WITH), 8, 0, 0 }, // pushregs + { OP(0, 0, 0, OP_POP_A_4), 4, 0, 0 }, +}; + +test_t tests[] = { + { + .desc = "pushregs", + .num_globals = num_globals(pushregs_init,pushregs_expect), + .num_statements = num_statements (pushregs_statements), + .statements = pushregs_statements, + .init_globals = (pr_int_t *) pushregs_init, + .expect_globals = (pr_int_t *) pushregs_expect, + .stack_size = 32, + }, + { + .desc = "popregs", + .num_globals = num_globals(popregs_init,popregs_expect), + .num_statements = num_statements (popregs_statements), + .statements = popregs_statements, + .init_globals = (pr_int_t *) popregs_init, + .expect_globals = (pr_int_t *) popregs_expect, + .stack_size = 32, + }, + { + .desc = "with 0", + .num_globals = num_globals(with_0_init,with_0_expect), + .num_statements = num_statements (with_0_statements), + .statements = with_0_statements, + .init_globals = (pr_int_t *) with_0_init, + .expect_globals = (pr_int_t *) with_0_expect, + .stack_size = 32, + }, + { + .desc = "with 1", + .num_globals = num_globals(with_1_init,with_1_expect), + .num_statements = num_statements (with_1_statements), + .statements = with_1_statements, + .init_globals = (pr_int_t *) with_1_init, + .expect_globals = (pr_int_t *) with_1_expect, + .stack_size = 32, + .edict_area = 64, + }, + { + .desc = "with 2", + .num_globals = num_globals(with_2_init,with_2_expect), + .num_statements = num_statements (with_2_statements), + .statements = with_2_statements, + .init_globals = (pr_int_t *) with_2_init, + .expect_globals = (pr_int_t *) with_2_expect, + .stack_size = 32, + .edict_area = 64, + }, + { + .desc = "with 3", + .num_globals = num_globals(with_3_init,with_3_expect), + .num_statements = num_statements (with_3_statements), + .statements = with_3_statements, + .init_globals = (pr_int_t *) with_3_init, + .expect_globals = (pr_int_t *) with_3_expect, + .stack_size = 32, + .edict_area = 64, + }, + { + .desc = "with 4", + .num_globals = num_globals(with_4_init,with_4_expect), + .num_statements = num_statements (with_4_statements), + .statements = with_4_statements, + .init_globals = (pr_int_t *) with_4_init, + .expect_globals = (pr_int_t *) with_4_expect, + .stack_size = 32, + .edict_area = 64, + }, + { + .desc = "with 5", + .num_globals = num_globals(with_5_init,with_5_expect), + .num_statements = num_statements (with_5_statements), + .statements = with_5_statements, + .init_globals = (pr_int_t *) with_5_init, + .expect_globals = (pr_int_t *) with_5_expect, + .stack_size = 32, + .edict_area = 64, + }, + { + .desc = "with 6", + .num_globals = num_globals(with_6_init,with_6_expect), + .num_statements = num_statements (with_6_statements), + .statements = with_6_statements, + .init_globals = (pr_int_t *) with_6_init, + .expect_globals = (pr_int_t *) with_6_expect, + .stack_size = 32, + .edict_area = 64, + }, + { + .desc = "with 7", + .num_globals = num_globals(with_7_init,with_7_expect), + .num_statements = num_statements (with_7_statements), + .statements = with_7_statements, + .init_globals = (pr_int_t *) with_7_init, + .expect_globals = (pr_int_t *) with_7_expect, + .stack_size = 32, + .edict_area = 64, + }, +}; + +#include "main.c"