Added jump_rel (can't use abs jump with asm dsl). Fixes + improvements to ps1 asm meta passes.

This commit is contained in:
ed
2026-08-04 16:01:01 -04:00
parent 54a5bb9a31
commit 7289e7c89c
8 changed files with 610 additions and 208 deletions
+20 -2
View File
@@ -362,10 +362,28 @@ enum { _BitOffsets = 0
/* call_reg rs — jump-and-link to register-held address; link in $ra. */
#define call_reg(rs) jump_link((rs), R_RA)
/* j target — absolute jump within the current 256MB region. */
/* j target — absolute jump within the current 256MB region.
* WARNING: `jump(off)` CANNOT BE USED for within-atom jumps in the current pipeline.
* The MIPS j opcode encodes `(target_addr >> 2)` in its 26-bit immediate field; an ABSOLUTE byte address, not a relative word offset.
* The metaprogram computes `off` as a relative word offset (`target_word_idx - branch_word_idx - 1`), which the assembler/linker does NOT resolve.
*
* `jump(off)` is only safe when the BUILD PIPELINE owns the absolute position of the emitted code — i.e. when: s
* - the build emits a symbol-relative `.word` expression that the linker resolvess via `R_MIPS_26`, OR
* - the code is hand-assembled with explicit absolute targets, OR a custom post-build patcher resolves the 26-bit field.
*/
#define jump(off) enc_i(op_j, R_0, R_0, (off))
/* call_addr off — jump-and-link to immediate address. */
/* jump_rel off — unconditional relative jump (the within-atom-safe `jump`).
* MIPS I R3000A has no "branch always" opcode. The idiom for an unconditional relative jump is `beq $0, $0, off`.
*/
#define jump_rel(off) branch_equal(R_0, R_0, (off))
/* call_addr off — jump-and-link to immediate address.
*
* Same WARNING as `jump(off)` above: the jal opcode also encodes an absolute 26-bit target.
* For within-atom calls, the current pipeline has no equivalent always-taken call-and-link idiom.
* Workaround: `branch_link` (always-taken branch + explicit `la $ra, next_word_addr; jr $ra`), or just use `call_reg($tmp)` after loading the target into a register.
*/
#define call_addr(off) enc_i(op_jal, R_0, R_0, (off))
/* --- Store family (mirrors the load family) --- */
-16
View File
@@ -478,22 +478,6 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
// C-side state (pa->used) has already been updated by the tape!
// smem.floor.rot.y += 5;
}
// --- TAPE DIAGNOSTICS ---
if (0)
{
LP_ U4 mem_temp_tape[512]; FArena tape_arena; farena_init(& tape_arena, slice_ut_arr(mem_temp_tape));
TapeBuilder tb = tb_make_old(& tape_arena); tb_scope(& tb) {
// Skip set_gte_world atom for diagnostics to isolate the triangle loop
for (U4 i = 0; i < Floor_num_faces; i++) {
// tb_emit(& tb, code_diag_yield);
// tb_emit(& tb, code_diag_color);
// tb_emit(& tb, code_diag_gte);
}
}
B1* prim_cursor = (B1*)r_(pa->buf)[smem.active_buf_id] + pa->used;
tape_run(tb_slice(tb));
pa->used = (U4)prim_cursor - (U4)r_(pa->buf)[smem.active_buf_id];
}
}
GCC_OPTIMIZATION_ENABLE
+7 -22
View File
@@ -459,9 +459,7 @@ atom_label(disconnected) /* === Disconnected body. */
load_upper_i(R_T4, 0x8080), or_i_self(R_T4, 0x8080),
store_word( R_T4, R_PadState, O_(PadState,left_x)),
store_byte( R_RawId, R_PadState, O_(PadState,id)),
branch_equal(R_0, R_0, atom_offset(disconnected, snap_end)), nop,
// TODO(Ed): Lua metaprogram: Support jump instruction here..
// jump(atom_offset(disconnected, snap_end)), nop,
jump_rel(atom_offset(disconnected, snap_end)), nop,
atom_label(skip_disconnected)
/* === Case 2: Pending (status == 0 && id == 0)
@@ -479,9 +477,7 @@ atom_label(pending) /* === Pending body */
load_upper_i(R_T4, 0x8080), or_i_self(R_T4, 0x8080),
store_word( R_T4, R_PadState, O_(PadState,left_x)),
store_byte( R_RawId, R_PadState, O_(PadState,id)),
branch_equal(R_0, R_0, atom_offset(pending, snap_end)), nop,
// TODO(Ed): Lua metaprogram: Support jump instruction here..
// jump(atom_offset(pending, snap_end)), nop,
jump_rel(atom_offset(pending, snap_end)), nop,
atom_label(id_dispatch) /* === Case 3-6: ID dispatch */
add_ui(R_T4, R_0, 0x41), branch_ne(R_RawId, R_T4, atom_offset(id_dispatch, try_analog_stick)),
@@ -503,9 +499,7 @@ atom_label(id_dispatch) /* === Case 3-6: ID dispatch */
add_ui( R_T4, R_0, 0x41),
store_byte( R_T4, R_PadState, O_(PadState,id)),
branch_equal(R_0, R_0, atom_offset(id_dispatch, snap_end)), nop,
// TODO(Ed): Lua metaprogram: Support jump instruction here..
// jump(atom_offset(id_dispatch, snap_end)), nop,
jump_rel(atom_offset(id_dispatch, snap_end)), nop,
atom_label(try_analog_stick) /* === Case 4: AnalogStick (id == 0x53)*/
add_ui(R_T4, R_0, 0x53), branch_ne(R_RawId, R_T4, atom_offset(try_analog_stick, try_analog_pad)),
@@ -526,9 +520,7 @@ atom_label(analog_stick) /* === AnalogStick body
store_half( R_T4, R_PadState, O_(PadState,right_x)),
add_ui( R_T5, R_0, 0x53), /* R_T5 = id value (clobbers left_xy, already stored) */
store_byte( R_T5, R_PadState, O_(PadState,id)),
branch_equal(R_0, R_0, atom_offset(analog_stick, snap_end)), nop,
// TODO(Ed): Lua metaprogram: Support jump instruction here..
// jump(atom_offset(analog_stick, snap_end)), nop,
jump_rel(atom_offset(analog_stick, snap_end)), nop,
atom_label(try_analog_pad) /* === Case 5-6: AnalogPad (id & 0xF0 == 0x70) */
and_i( R_T4, R_RawId, 0xF0),
@@ -550,9 +542,7 @@ atom_label(analog_pad) /* === AnalogPad body
store_half( R_T4, R_PadState, O_(PadState,right_x)),
store_byte( R_RawId, R_PadState, O_(PadState,id)),
branch_equal(R_0, R_0, atom_offset(analog_pad, snap_end)), nop,
// TODO(Ed): Lua metaprogram: Support jump instruction here..
// jump(atom_offset(analog_pad, snap_end)), nop,
jump_rel(atom_offset(analog_pad, snap_end)), nop,
atom_label(try_unsupported) /* === Case 7: Unsupported — fall through from the AnalogPad range-check miss. */
add_ui( R_T4, R_0, PadStatus_Unsupported),
@@ -650,10 +640,7 @@ atom_label(dead_check_upper)
/* R_T4 = (0x90 < left_x) ? 1 : 0 → (left_x > 0x90) ? 1 : 0 */
set_lt_u(R_T4, R_T4, R_T3), branch_ne(R_T4, R_0, atom_offset(dead_zone_high_check, dead_high_active)),
add_ui( R_T4, R_0, 0x80), /* BD-slot: pre-load 0x80 for dead_high_active */
branch_equal(R_0, R_0, atom_offset(dead_zone_skip, exit_stick)), nop,
/* Fall-through = left_x in [0x70, 0x90] (dead zone); skip analog entirely. */
// TODO(Ed): Lua metaprogram: Support jump instruction here..
// jump(atom_offset(dead_zone_skip, exit_stick)), nop,
jump_rel(atom_offset(dead_zone_skip, exit_stick)), nop,
atom_label(dead_low_active)
/* R_T3 = left_x (from line 632 lbu; not clobbered between dead_zone_low_check branch + its BD-slot `add_ui R_T4, 0x80`).
@@ -675,9 +662,7 @@ atom_label(dead_low_active)
add_u( R_T0, R_T0, R_T4),
store_half( R_T0, R_FloorRot, O_(V3_S2,y)),
branch_equal(R_0, R_0, atom_offset(end_low, exit_stick)), nop,
// TODO(Ed): Lua metaprogram: Support jump instruction here..
// jump(atom_offset(end_low, exit_stick)), nop,
jump_rel(atom_offset(end_low, exit_stick)), nop,
atom_label(dead_high_active)
/* R_T3 = left_x (from line 641 lbu in dead_check_upper; not clobbered between dead_zone_high_check branch + its BD-slot `add_ui R_T4, 0x80`).