mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 14:20:59 +00:00
[gamecode] Change address mode B to entity.field
It turned out that address mode B was redundant as C with 0 offset (immediate) was the same (except for the underlying C code of course, but adding st->b is very cheap). This allowed B to be used for entity.field for all transfer operations. Thus instructions 0-3 are now free as load E became load B, and other than the specifics of format codes for statement printing, transfers+lea are unified.
This commit is contained in:
parent
6ae9daf4b7
commit
e20aed5c5a
6 changed files with 82 additions and 117 deletions
|
@ -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 = {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue