diff --git a/libs/gamecode/opcodes.py b/libs/gamecode/opcodes.py index c8316eb16..40d84c341 100644 --- a/libs/gamecode/opcodes.py +++ b/libs/gamecode/opcodes.py @@ -4,6 +4,7 @@ bitmap_txt = """ 0 0010 mmss push 0 0011 mmss pop 0 1ccc ttss compare +0 0000 00nn 0 1011 nnnn 0 1111 nnnn @@ -34,11 +35,26 @@ bitmap_txt = """ import copy +address_mode = "ABCD" +address_types = [ + "ev_void, ev_invalid", + "ev_entity, ev_field", + "ev_ptr, ev_short", + "ev_ptr, ev_int", +] +#store, pop and lea +store_fmt = [ + "%ga", + "%Ga.%Gb(%Ea)", + "*(%Ga + %sb)", + "*(%Ga + %Gb)", +] +# load and push load_fmt = [ - "%Ga.%Gb(%Ea), %gc", "*%Ga, %gc", - "*(%Ga + %sb), %gc", - "*(%Ga + %Gb), %gc", + "%Ga.%Gb(%Ea)", + "*(%Ga + %sb)", + "*(%Ga + %Gb)", ] branch_fmt = [ "branch %sa (%Oa)", @@ -175,29 +191,26 @@ lea_formats = { "opcode": "OP_LEA_{op_mode[mm]}", "mnemonic": "lea", "opname": "lea", - "format": "{lea_fmt[mm]}", + "format": "{lea_fmt[mm]}, %gc", "widths": "0, 0, 1", - "types": "ev_ptr, ev_ptr, ev_ptr", + "types": "{lea_types[mm]}, ev_ptr", "args": { - "op_mode": "AECD", - "lea_fmt": [ - "%ga, %gc", - "%Ga.%Gb(%Ea), %gc", - "*(%Ga + %sb), %gc", - "*(%Ga + %Gb), %gc", - ], + "op_mode": address_mode, + "lea_fmt": store_fmt, + "lea_types": address_types, }, } load_formats = { "opcode": "OP_LOAD_{op_mode[mm]}_{ss+1}", "mnemonic": "load", "opname": "load", - "format": "{load_fmt[mm]}", + "format": "{load_fmt[mm]}, %gc", "widths": "0, 0, {ss+1}", - "types": "ev_void, ev_void, ev_void", + "types": "{load_types[mm]}, ev_void", "args": { - "op_mode": "EBCD", + "op_mode": address_mode, "load_fmt": load_fmt, + "load_types": address_types, }, } mathops_formats = { @@ -242,15 +255,11 @@ push_formats = { "opname": "push", "format": "{push_fmt[mm]}", "widths": "{ss+1}, 0, 0", - "types": "ev_void, ev_void, ev_invalid", + "types": "{push_types[mm]}, ev_invalid", "args": { - "op_mode": "ABCD", - "push_fmt": [ - "%Ga", - "*%Ga", - "*(%Ga + %sb)", - "*(%Ga + %Gb)", - ], + "op_mode": address_mode, + "push_fmt": load_fmt, + "push_types": address_types, }, } pushregs_formats = { @@ -267,15 +276,11 @@ pop_formats = { "opname": "pop", "format": "{pop_fmt[mm]}", "widths": "{ss+1}, 0, 0", - "types": "ev_void, ev_void, ev_invalid", + "types": "{pop_types[mm]}, ev_invalid", "args": { - "op_mode": "ABCD", - "pop_fmt": [ - "%ga", - "*%Ga", - "*(%Ga + %sb)", - "*(%Ga + %Gb)", - ], + "op_mode": address_mode, + "pop_fmt": store_fmt, + "pop_types": address_types, }, } popregs_formats = { @@ -342,24 +347,14 @@ store_formats = { "opcode": "OP_STORE_{op_mode[mm]}_{ss+1}", "mnemonic": "{store_op[mm]}", "opname": "{store_op[mm]}", - "format": "{store_fmt[mm]}", + "format": "%Gc, {store_fmt[mm]}", "widths": "{ss+1}, 0, {ss+1}", - "types": "{store_types[mm]}", + "types": "{store_types[mm]}, ev_void", "args": { - "op_mode": "ABCD", - "store_fmt": [ - "%Gc, %ga", - "%Gc, *%Ga", - "%Gc, *(%Ga + %sb)", - "%Gc, *(%Ga + %Gb)", - ], + "op_mode": address_mode, + "store_fmt": store_fmt, "store_op": ["assign", "store", "store", "store"], - "store_types": [ - "ev_void, ev_invalid, ev_void", - "ev_ptr, ev_invalid, ev_void", - "ev_ptr, ev_short, ev_void", - "ev_ptr, ev_int, ev_void", - ], + "store_types": address_types, }, } string_formats = { diff --git a/libs/gamecode/pr_exec.c b/libs/gamecode/pr_exec.c index 7ca7d6ad9..1e7f9634c 100644 --- a/libs/gamecode/pr_exec.c +++ b/libs/gamecode/pr_exec.c @@ -1759,8 +1759,9 @@ pr_address_mode (progs_t *pr, const dstatement_t *st, int mm_ind) mm_offs = op_a - pr->pr_globals; break; case 1: - // simple pointer dereference: *a - mm_offs = OPA(ptr); + // entity.field (equivalent to OP_LOAD_t_v6p) + pr_ptr_t edict_area = pr->pr_edict_area - pr->pr_globals; + mm_offs = edict_area + OPA(entity) + OPB(field); break; case 2: // constant indexed pointer: *a + b (supports -ve offset) @@ -1770,11 +1771,6 @@ pr_address_mode (progs_t *pr, const dstatement_t *st, int mm_ind) // variable indexed pointer: *a + *b (supports -ve offset) mm_offs = OPA(ptr) + OPB(int); break; - case 4: - // entity.field (equivalent to OP_LOAD_t_v6p) - pr_ptr_t edict_area = pr->pr_edict_area - pr->pr_globals; - mm_offs = edict_area + OPA(entity) + OPB(field); - break; } return pr->pr_globals + mm_offs; } @@ -2767,44 +2763,28 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) pr_opcode_e st_op = st->op & OP_MASK; switch (st_op) { // 0 0000 - case OP_LOAD_E_1: - mm = pr_address_mode (pr, st, 4); - OPC(int) = MM(int); - break; case OP_LOAD_B_1: case OP_LOAD_C_1: case OP_LOAD_D_1: - mm = pr_address_mode (pr, st, (st_op - OP_LOAD_E_1) >> 2); + mm = pr_address_mode (pr, st, (st_op - OP_LOAD_B_1 + 4) >> 2); OPC(int) = MM(int); break; - case OP_LOAD_E_2: - mm = pr_address_mode (pr, st, 4); - OPC(ivec2) = MM(ivec2); - break; case OP_LOAD_B_2: case OP_LOAD_C_2: case OP_LOAD_D_2: - mm = pr_address_mode (pr, st, (st_op - OP_LOAD_E_2) >> 2); + mm = pr_address_mode (pr, st, (st_op - OP_LOAD_B_2 + 4) >> 2); OPC(ivec2) = MM(ivec2); break; - case OP_LOAD_E_3: - mm = pr_address_mode (pr, st, 4); - VectorCopy (&MM(int), &OPC(int)); - break; case OP_LOAD_B_3: case OP_LOAD_C_3: case OP_LOAD_D_3: - mm = pr_address_mode (pr, st, (st_op - OP_LOAD_E_3) >> 2); + mm = pr_address_mode (pr, st, (st_op - OP_LOAD_B_3 + 4) >> 2); VectorCopy (&MM(int), &OPC(int)); break; - case OP_LOAD_E_4: - mm = pr_address_mode (pr, st, 4); - OPC(ivec4) = MM(ivec4); - break; case OP_LOAD_B_4: case OP_LOAD_C_4: case OP_LOAD_D_4: - mm = pr_address_mode (pr, st, (st_op - OP_LOAD_E_4) >> 2); + mm = pr_address_mode (pr, st, (st_op - OP_LOAD_B_4 + 4) >> 2); OPC(ivec4) = MM(ivec4); break; // 0 0001 @@ -3389,15 +3369,12 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) break; // 1 1111 case OP_LEA_A: + case OP_LEA_B: case OP_LEA_C: case OP_LEA_D: mm = pr_address_mode (pr, st, (st_op - OP_LEA_A)); op_c->pointer_var = mm - pr->pr_globals; break; - case OP_LEA_E: - mm = pr_address_mode (pr, st, 4); - op_c->pointer_var = mm - pr->pr_globals; - break; case OP_QV4MUL_F: OPC(vec4) = qvmulf (OPA(vec4), OPB(vec4)); break; diff --git a/libs/gamecode/test/test-lea.c b/libs/gamecode/test/test-lea.c index 1a4f159f7..33e148c16 100644 --- a/libs/gamecode/test/test-lea.c +++ b/libs/gamecode/test/test-lea.c @@ -22,7 +22,7 @@ static dstatement_t lea_statements[] = { {OP(0, 0, 0, OP_LEA_A), 7, 9, 12}, {OP(0, 0, 0, OP_LEA_C), 2, 6, 13}, {OP(0, 0, 0, OP_LEA_D), 2, 6, 14}, - {OP(0, 0, 0, OP_LEA_E), 4, 2, 15}, + {OP(0, 0, 0, OP_LEA_B), 4, 2, 15}, }; test_t tests[] = { diff --git a/libs/gamecode/test/test-load.c b/libs/gamecode/test/test-load.c index e283ced38..986a58163 100644 --- a/libs/gamecode/test/test-load.c +++ b/libs/gamecode/test/test-load.c @@ -30,20 +30,12 @@ static pr_int_t test_globals_expect[] = { 1, 2, 3, 4, }; -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}, + {OP(0, 0, 0, OP_LOAD_B_4), 7, 9, 12}, + {OP(0, 0, 0, OP_LOAD_B_3), 7, 8, 16}, + {OP(0, 0, 0, OP_LOAD_B_1), 7, 7, 19}, + {OP(0, 0, 0, OP_LOAD_B_2), 7, 6, 20}, + {OP(0, 0, 0, OP_LOAD_B_2), 7, 5, 22}, }; static dstatement_t load_C_statements[] = { @@ -63,17 +55,6 @@ static dstatement_t load_D_statements[] = { }; 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), @@ -81,6 +62,9 @@ test_t tests[] = { .statements = load_B_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 C", diff --git a/libs/gamecode/test/test-stack.c b/libs/gamecode/test/test-stack.c index 183e33694..eba5a06d8 100644 --- a/libs/gamecode/test/test-stack.c +++ b/libs/gamecode/test/test-stack.c @@ -81,11 +81,11 @@ static dstatement_t stack_AB_statements[] = { {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}, + {OP(0, 0, 0, OP_POP_B_2), 7, 5, 0}, + {OP(0, 0, 0, OP_POP_B_2), 7, 6, 0}, + {OP(0, 0, 0, OP_POP_B_1), 7, 7, 0}, + {OP(0, 0, 0, OP_POP_B_3), 7, 8, 0}, + {OP(0, 0, 0, OP_POP_B_4), 7, 9, 0}, }; static dstatement_t stack_AC_statements[] = { @@ -117,11 +117,11 @@ static dstatement_t stack_AD_statements[] = { }; 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_PUSH_B_2), 7, 5, 0}, + {OP(0, 0, 0, OP_PUSH_B_2), 7, 6, 0}, + {OP(0, 0, 0, OP_PUSH_B_1), 7, 7, 0}, + {OP(0, 0, 0, OP_PUSH_B_3), 7, 8, 0}, + {OP(0, 0, 0, OP_PUSH_B_4), 7, 9, 0}, {OP(0, 0, 0, OP_POP_A_4), 12, 0, 0}, {OP(0, 0, 0, OP_POP_A_3), 16, 0, 0}, @@ -176,6 +176,9 @@ test_t tests[] = { .statements = stack_AB_statements, .init_globals = test_globals_init1, .expect_globals = test_globals_expect1, + // 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 = "stack push A pop C", @@ -203,6 +206,9 @@ test_t tests[] = { .statements = stack_BA_statements, .init_globals = test_globals_init2, .expect_globals = test_globals_expect2, + // 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 = "stack push C pop A", diff --git a/libs/gamecode/test/test-store.c b/libs/gamecode/test/test-store.c index dc580f028..5ed5147b8 100644 --- a/libs/gamecode/test/test-store.c +++ b/libs/gamecode/test/test-store.c @@ -39,11 +39,11 @@ static dstatement_t store_A_statements[] = { }; static dstatement_t store_B_statements[] = { - {OP(0, 0, 0, OP_STORE_B_4), 4, 0, 12}, - {OP(0, 0, 0, OP_STORE_B_3), 3, 0, 16}, - {OP(0, 0, 0, OP_STORE_B_1), 2, 0, 19}, - {OP(0, 0, 0, OP_STORE_B_2), 1, 0, 20}, - {OP(0, 0, 0, OP_STORE_B_2), 0, 0, 22}, + {OP(0, 0, 0, OP_STORE_B_4), 7, 9, 12}, + {OP(0, 0, 0, OP_STORE_B_3), 7, 8, 16}, + {OP(0, 0, 0, OP_STORE_B_1), 7, 7, 19}, + {OP(0, 0, 0, OP_STORE_B_2), 7, 6, 20}, + {OP(0, 0, 0, OP_STORE_B_2), 7, 5, 22}, }; static dstatement_t store_C_statements[] = { @@ -78,6 +78,9 @@ test_t tests[] = { .statements = store_B_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 = "store C",