From e133de8c89a3245a2164bc2da0b8779c60bd6d96 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 15 Jan 2022 16:27:46 +0900 Subject: [PATCH] [gamecode] Drop B addressing for lea When creating the tests for lea, I noticed that B was yet another simple assign, so I decided it was best to drop it and move E into its place (freeing up another instruction). --- libs/gamecode/opcodes.py | 16 ++---- libs/gamecode/pr_exec.c | 92 ++++++++++++++--------------------- libs/gamecode/test/test-lea.c | 11 ++--- 3 files changed, 44 insertions(+), 75 deletions(-) diff --git a/libs/gamecode/opcodes.py b/libs/gamecode/opcodes.py index 0596636c7..3c8e85cd0 100644 --- a/libs/gamecode/opcodes.py +++ b/libs/gamecode/opcodes.py @@ -25,7 +25,7 @@ bitmap_txt = """ 1 1010 d1xx 1 1011 00mm lea 1 1011 01ss any -1 1011 0100 lea_e +1 1011 0100 1 1011 10ss all 1 1011 1000 pushregs 1 1011 11ss none @@ -176,24 +176,15 @@ lea_formats = { "widths": "0, 0, 1", "types": "ev_pointer, ev_pointer, ev_pointer", "args": { - "op_mode": "ABCD", + "op_mode": "AECD", "lea_fmt": [ "%ga, %gc", - "*%Ga, %gc", + "%Ga.%Gb(%Ea), %gc", "*(%Ga + %sb), %gc", "*(%Ga + %Gb), %gc", ], }, } -lea_e_formats = { - "opcode": "OP_LEA_E", - "mnemonic": "lea", - "opname": "lea", - "format": "{load_fmt[0]}", - "format": "%Ga.%Gb(%Ea), %gc", - "types": "ev_entity, ev_field, ev_pointer", - "widths": "0, 0, 1", -} load_formats = { "opcode": "OP_LOAD_{op_mode[mm]}_{ss+1}", "mnemonic": "load", @@ -461,7 +452,6 @@ group_map = { "compare2": compare2_formats, "convert": convert_formats, "lea": lea_formats, - "lea_e": lea_e_formats, "load": load_formats, "mathops": mathops_formats, "memset": memset_formats, diff --git a/libs/gamecode/pr_exec.c b/libs/gamecode/pr_exec.c index abe934815..f8d31a6ec 100644 --- a/libs/gamecode/pr_exec.c +++ b/libs/gamecode/pr_exec.c @@ -1735,41 +1735,10 @@ exit_program: #define STK(type) (*((pr_##type##_t *) (stk))) static pr_type_t * -pr_entity_mode (progs_t *pr, const dstatement_t *st, int shift) +pr_address_mode (progs_t *pr, const dstatement_t *st, int mm_ind) { pr_type_t *op_a = pr->pr_globals + st->a + PR_BASE (pr, st, A); pr_type_t *op_b = pr->pr_globals + st->b + PR_BASE (pr, st, B); - int mm_ind = (st->op >> shift) & 3; - pointer_t edict_area = pr->pr_edict_area - pr->pr_globals; - pointer_t mm_offs = 0; - - switch (mm_ind) { - case 0: - // entity.field (equivalent to OP_LOAD_t_v6p) - mm_offs = edict_area + OPA(uint) + OPB(uint); - break; - case 1: - // simple pointer dereference: *a - mm_offs = OPA(uint); - break; - case 2: - // constant indexed pointer: *a + b (supports -ve offset) - mm_offs = OPA(uint) + (short) st->b; - break; - case 3: - // variable indexed pointer: *a + *b (supports -ve offset) - mm_offs = OPA(uint) + OPB(int); - break; - } - return pr->pr_globals + mm_offs; -} - -static pr_type_t * -pr_address_mode (progs_t *pr, const dstatement_t *st, int shift) -{ - pr_type_t *op_a = pr->pr_globals + st->a + PR_BASE (pr, st, A); - pr_type_t *op_b = pr->pr_globals + st->b + PR_BASE (pr, st, B); - int mm_ind = (st->op >> shift) & 3; pointer_t mm_offs = 0; switch (mm_ind) { @@ -1789,6 +1758,11 @@ pr_address_mode (progs_t *pr, const dstatement_t *st, int shift) // variable indexed pointer: *a + *b (supports -ve offset) mm_offs = OPA(uint) + OPB(int); break; + case 4: + // entity.field (equivalent to OP_LOAD_t_v6p) + pointer_t edict_area = pr->pr_edict_area - pr->pr_globals; + mm_offs = edict_area + OPA(uint) + OPB(uint); + break; } return pr->pr_globals + mm_offs; } @@ -2758,31 +2732,43 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) 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_entity_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_LOAD_E_1) >> 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_entity_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_LOAD_E_2) >> 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_entity_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_LOAD_E_3) >> 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_entity_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_LOAD_E_4) >> 2); OPC(ivec4) = MM(ivec4); break; // 0 0001 @@ -2790,28 +2776,28 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) case OP_STORE_B_1: case OP_STORE_C_1: case OP_STORE_D_1: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_STORE_A_1) >> 2); MM(int) = OPC(int); break; case OP_STORE_A_2: case OP_STORE_B_2: case OP_STORE_C_2: case OP_STORE_D_2: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_STORE_A_2) >> 2); MM(ivec2) = OPC(ivec2); break; case OP_STORE_A_3: case OP_STORE_B_3: case OP_STORE_C_3: case OP_STORE_D_3: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_STORE_A_3) >> 2); VectorCopy (&OPC(int), &MM(int)); break; case OP_STORE_A_4: case OP_STORE_B_4: case OP_STORE_C_4: case OP_STORE_D_4: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_STORE_A_4) >> 2); MM(ivec4) = OPC(ivec4); break; // 0 0010 @@ -2819,7 +2805,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) case OP_PUSH_B_1: case OP_PUSH_C_1: case OP_PUSH_D_1: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_PUSH_A_1) >> 2); stk = pr_stack_push (pr); STK(int) = MM(int); break; @@ -2827,7 +2813,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) case OP_PUSH_B_2: case OP_PUSH_C_2: case OP_PUSH_D_2: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_PUSH_A_2) >> 2); stk = pr_stack_push (pr); STK(ivec2) = MM(ivec2); break; @@ -2835,7 +2821,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) case OP_PUSH_B_3: case OP_PUSH_C_3: case OP_PUSH_D_3: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_PUSH_A_3) >> 2); stk = pr_stack_push (pr); VectorCopy (&MM(int), &STK(int)); break; @@ -2843,7 +2829,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) case OP_PUSH_B_4: case OP_PUSH_C_4: case OP_PUSH_D_4: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_PUSH_A_4) >> 2); stk = pr_stack_push (pr); STK(ivec4) = MM(ivec4); break; @@ -2852,7 +2838,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) case OP_POP_B_1: case OP_POP_C_1: case OP_POP_D_1: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_POP_A_1) >> 2); stk = pr_stack_pop (pr); MM(int) = STK(int); break; @@ -2860,7 +2846,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) case OP_POP_B_2: case OP_POP_C_2: case OP_POP_D_2: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_POP_A_2) >> 2); stk = pr_stack_pop (pr); MM(ivec2) = STK(ivec2); break; @@ -2868,7 +2854,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) case OP_POP_B_3: case OP_POP_C_3: case OP_POP_D_3: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_POP_A_3) >> 2); stk = pr_stack_pop (pr); VectorCopy (&STK(int), &MM(int)); break; @@ -2876,7 +2862,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) case OP_POP_B_4: case OP_POP_C_4: case OP_POP_D_4: - mm = pr_address_mode (pr, st, 2); + mm = pr_address_mode (pr, st, (st_op - OP_POP_A_4) >> 2); stk = pr_stack_pop (pr); MM(ivec4) = STK(ivec4); break; @@ -3342,19 +3328,13 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) // spare // 1 1011 case OP_LEA_A: - case OP_LEA_B: case OP_LEA_C: case OP_LEA_D: - mm = pr_address_mode (pr, st, 0); + mm = pr_address_mode (pr, st, (st_op - OP_LEA_A)); op_c->pointer_var = mm - pr->pr_globals; break; case OP_LEA_E: - // ensures OP_LEA_E is compatible with OP_LOAD_E_n and thus - // with pr_entity_mode - mm = __builtin_choose_expr ( - (OP_LEA_E & 3) == 0, - pr_entity_mode (pr, st, 0), - (void) 0); + mm = pr_address_mode (pr, st, 4); op_c->pointer_var = mm - pr->pr_globals; break; case OP_ANY_2: diff --git a/libs/gamecode/test/test-lea.c b/libs/gamecode/test/test-lea.c index 36de277ff..1a4f159f7 100644 --- a/libs/gamecode/test/test-lea.c +++ b/libs/gamecode/test/test-lea.c @@ -6,7 +6,7 @@ static pr_int_t lea_globals_init[] = { 32, -4, -2, 0, 1, 4, 0xdeadbeef, 0xfeedf00d, - 0, 0, 0, 0, 0, + 0, 0, 0, 0, }; static pr_int_t lea_globals_expect[] = { @@ -15,15 +15,14 @@ static pr_int_t lea_globals_expect[] = { 32, -4, -2, 0, 1, 4, 0xdeadbeef, 0xfeedf00d, - 7, 29, 34, 26, 88, + 7, 34, 26, 88, }; static dstatement_t lea_statements[] = { {OP(0, 0, 0, OP_LEA_A), 7, 9, 12}, - {OP(0, 0, 0, OP_LEA_B), 3, 8, 13}, - {OP(0, 0, 0, OP_LEA_C), 2, 6, 14}, - {OP(0, 0, 0, OP_LEA_D), 2, 6, 15}, - {OP(0, 0, 0, OP_LEA_E), 4, 2, 16}, + {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}, }; test_t tests[] = {