[gamecode] Support offset for lea on globals

Allows using `array + offset` addressing. Both constant and variable
offsets are supported.
This commit is contained in:
Bill Currie 2023-05-14 12:32:35 +09:00
parent 61d656881b
commit 717cbaff87
3 changed files with 41 additions and 5 deletions

View file

@ -11,7 +11,7 @@ bitmap_txt = """
0 1011 otss udivops
0 1111 s0mm load64
0 1111 s1mm store64
0 1111 n000
0 1111 m000 lea2
1 0ooo ttss mathops
1 011r tuss shiftops
@ -46,20 +46,24 @@ address_types = [
"ev_entity, ev_field",
"ev_ptr, ev_short",
"ev_ptr, ev_int",
"ev_void, ev_short",
"ev_void, ev_int",
]
address_widths = [
[ "1, 0", "1, 1", "1, 0", "1, 1", ],
[ "2, 0", "1, 1", "1, 0", "1, 1", ],
[ "3, 0", "1, 1", "1, 0", "1, 1", ],
[ "4, 0", "1, 1", "1, 0", "1, 1", ],
[ "-1, 0", "1, 1", "1, 0", "1, 1", ],
[ "-1, 0", "1, 1", "1, 0", "1, 1", "-1, 0", "-1, 1"],
]
#store, pop and lea
#store, pop, lea
store_fmt = [
"%ga",
"%Ga.%Gb(%Ea)",
"*(%Ga + %sb)",
"*(%Ga + %Gb)",
"%ga + %sb",
"%ga + %Gb",
]
# load and push
load_fmt = [
@ -267,6 +271,20 @@ lea_formats = {
"lea_widths": address_widths[4],
},
}
lea2_formats = {
"opcode": "OP_LEA_{op_mode[m]}",
"mnemonic": "lea",
"opname": "lea",
"format": "{lea_fmt[m+4]}, %gc",
"widths": "{lea_widths[m+4]}, 1",
"types": "{lea_types[m+4]}, ev_ptr",
"args": {
"op_mode": "EF",
"lea_fmt": store_fmt,
"lea_types": address_types,
"lea_widths": address_widths[4],
},
}
load_formats = {
"opcode": "OP_LOAD_{op_mode[mm]}_{ss+1}",
"mnemonic": "load",
@ -579,6 +597,7 @@ group_map = {
"hops": hops_formats,
"jump": jump_formats,
"lea": lea_formats,
"lea2": lea2_formats,
"load": load_formats,
"load64": load64_formats,
"mathops": mathops_formats,

View file

@ -1812,6 +1812,14 @@ 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:
// global access with constant offset (supports -ve offset)
mm_offs = op_a - pr->pr_globals + (short) st->b;
break;
case 5:
// global access with variable offset (supports -ve offset)
mm_offs = op_a - pr->pr_globals + OPB(int);
break;
}
return pr->pr_globals + mm_offs;
}
@ -2346,6 +2354,10 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
// 0 1110
OP_cmp(LE, <=);
// 0 1111
case OP_LEA_E:
mm = pr_address_mode (pr, st, 4);
OPC(ptr) = mm - pr->pr_globals;
break;
case OP_LOAD64_B_3:
case OP_LOAD64_C_3:
case OP_LOAD64_D_3:
@ -2359,6 +2371,10 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
mm = pr_address_mode (pr, st, (st_op - OP_STORE64_A_3));
VectorCopy (&OPC(long), &MM(long));
break;
case OP_LEA_F:
mm = pr_address_mode (pr, st, 5);
OPC(ptr) = mm - pr->pr_globals;
break;
case OP_LOAD64_B_4:
case OP_LOAD64_C_4:
case OP_LOAD64_D_4:
@ -2372,7 +2388,6 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
mm = pr_address_mode (pr, st, (st_op - OP_STORE64_A_4));
MM(lvec4) = OPC(lvec4);
break;
// spare
#define OP_op(OP, op) \
OP_op_T (OP, I, int, ivec2, ivec4, op); \

View file

@ -13,7 +13,7 @@ static pr_int_t lea_globals_expect[] = {
// pointers
24, 26, 28, 29,
32, -4, -2, 0,
1, 4, 0xdeadbeef, 0xfeedf00d,
1, 4, 6, 32,
7, 34, 26, 88,
};
@ -23,6 +23,8 @@ static dstatement_t lea_statements[] = {
{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_B), 4, 2, 15},
{OP(0, 0, 0, OP_LEA_E), 4, 2, 10},
{OP(0, 0, 0, OP_LEA_F), 4, 2, 11},
};
test_t tests[] = {