diff --git a/code/duffle/gte.atom.c b/code/duffle/gte.atom.c index fb75e02..209b0a0 100644 --- a/code/duffle/gte.atom.c +++ b/code/duffle/gte.atom.c @@ -225,20 +225,22 @@ MipsAtom_Proc_(normalize_v3s4, aa, { /* Stage 3: compute srav amount (r_lzcr) + align |v|² to bit 24. * IMPORTANT: the sllv/srav below writes the aligned |v|² to r_mac1_scratch (NOT r_lzcr), - * so r_lzcr retains the shift count all the way to the start of stage 4. */ + * so r_lzcr retains the shift count all the way to the start of stage 4. + */ and_i( r_shift, r_shift, -2), + or_u(r_mac1_scratch, r_lzcr, 0), /* FIX B: save sum before clobbering r_lzcr with shift count */ li_s( r_lzcr, 31), sub_s( r_lzcr, r_lzcr, r_shift), shift_aright(r_lzcr, r_lzcr, 1), /* r_branch_tmp = LZCR - 24 (overwrites r_branch_tmp; src.z no longer needed after SQR) */ add_si( r_branch_tmp, r_shift, -24), - branch_lt_zero(r_branch_tmp, atom_offset(srav_path, aligned_done)), nop, - jump_rel(atom_offset(aligned_done, srav_path)), - shift_lleft_var(r_mac1_scratch, r_lzcr, r_branch_tmp), /* sllv path: aligned = r_lzcr sll (LZCR-24) — dst=r_mac1_scratch to PRESERVE r_lzcr=shift count */ + branch_lt_zero(r_branch_tmp, atom_offset(aligned_done, srav_path)), nop, /* FIX A: bltz → srav_path (LZCR<24 path) */ + jump_rel(atom_offset(srav_path, aligned_done)), /* FIX A: b → aligned_done (LZCR>=24 path) */ + shift_lleft_var(r_mac1_scratch, r_mac1_scratch, r_branch_tmp), /* FIX B: src=sum (r_mac1_scratch), dst=same */ atom_label(srav_path) li_s( r_branch_tmp, 24), sub_s( r_branch_tmp, r_branch_tmp, r_shift), - shift_aright_var(r_mac1_scratch, r_lzcr, r_branch_tmp), /* srav path: aligned = r_lzcr sra (24-LZCR) — dst=r_mac1_scratch to PRESERVE r_lzcr=shift count */ + shift_aright_var(r_mac1_scratch, r_mac1_scratch, r_branch_tmp), /* FIX B: src=sum (r_mac1_scratch), dst=same */ atom_label(aligned_done) /* Save the shift count to r_shift before the next 5 instructions overwrite r_lzcr * (the sqrtbl lookup loads 1/|v| into r_lzcr, which becomes IR0 in stage 4). */ @@ -251,11 +253,14 @@ MipsAtom_Proc_(normalize_v3s4, aa, { add_u(r_branch_tmp, r_branch_tmp, r_mac1_scratch), load_half(r_lzcr, r_branch_tmp, 0), nop, /* r_lzcr = sqrtbl[aligned-64] = 1/|v| (IR0 in stage 4) */ + /* FIX bug C: r_branch_tmp held the sqrtbl base+index, NOT src.z. Reload src.z from scratch now that r_branch_tmp is free. */ + load_word(r_branch_tmp, r_src_ptr, O_(V3_S4,z)), nop, /* r_branch_tmp = src.z (for IR3 in stage 4) */ + /* Stage 4: GPF + srav finalize (r_shift = shift count, r_lzcr = 1/|v|). */ gte_mv_to_data_r(r_lzcr, C2_IR0), gte_mv_to_data_r(r_tmp, C2_IR1), /* IR1 = src.x (preserved in r_tmp — r_mac2_scratch was clobbered to MAC2 in stage 1.5) */ gte_mv_to_data_r(r_recip_est, C2_IR2), - gte_mv_to_data_r(r_branch_tmp, C2_IR3), + gte_mv_to_data_r(r_branch_tmp, C2_IR3), /* IR3 = src.z (reloaded) */ nop2, gte_cmdw_gpf, gte_mv_from_data_r(r_mac2_scratch, C2_MAC1), gte_mv_from_data_r(r_recip_est, C2_MAC2), diff --git a/code/duffle/lottes_tape.h b/code/duffle/lottes_tape.h index 34faa24..4e0fbfd 100644 --- a/code/duffle/lottes_tape.h +++ b/code/duffle/lottes_tape.h @@ -238,8 +238,6 @@ typedef Struct_(FMipsAtom512) { U4 data[512]; U4 used; }; // FArena Related typedef Relative_(FArena) Struct_(AtomBuilder) { U4 start; U4 capacity; U4 used; }; -// Whatever the builder is writting to should most likely coresspond -// to something that can fit within instruction cache? // Usual way to resolve an atom after the bulder is done. #define atom_from_atombuilder(ab) C_(MipsAtom*, (ab).start) @@ -255,9 +253,6 @@ FI_ void atombuilder_push(AtomBuilder_R ab, Slice_MipsCode code) { // When done authoring, utilize this to cap-off the atom (if not utilizing a MipsAtom_Proc). FI_ void atombuilder_end(AtomBuilder_R ab) { atombuilder_push(ab, slice_from_array(MipsCode, ac_yield)); } -// tb_emit_builder(tb, ab) — emit the builder's atom into the tape and advance tb->used. -// Thin wrapper around tb_emit(tb, mipsatom_from_builder(ab[0])). -// Equivalent to tb_emit(tb, code_) for runtime-built atoms. FI_ void tb_emit_atombuilder(TapeBuilder_R tb, AtomBuilder_R ab) { tb_emit(tb, atom_from_atombuilder(ab[0])); } #pragma endregion Mips Atom Builder diff --git a/code/duffle/word_count.metadata.h b/code/duffle/word_count.metadata.h index cd75d30..a454402 100644 --- a/code/duffle/word_count.metadata.h +++ b/code/duffle/word_count.metadata.h @@ -15,6 +15,8 @@ #define WORD_COUNT(name, count) enum { words_##name = (count) }; WORD_COUNT(nop, 1) +WORD_COUNT(atom_label, 0) +WORD_COUNT(atom_offset, 0) WORD_COUNT(load_upper_i, 1) WORD_COUNT(jump_reg, 1) WORD_COUNT(jump_link, 1) diff --git a/code/hello_camera/hello_camera.c b/code/hello_camera/hello_camera.c index e0aa325..a2b98a0 100644 --- a/code/hello_camera/hello_camera.c +++ b/code/hello_camera/hello_camera.c @@ -276,8 +276,7 @@ I_ void resolve_look_at( tb_data(tb, u4_(smem.scratchpad)); /* Binds_ResolveLookAtScratch.scratch_base */ } - /* Atoms 1-5: - Context carrier R_ResolveScratch (R_T4) is preserved across atoms. */ + /* Atoms 1-5: disabled (atom 1 verification below) */ tb_emit(tb, smem.resolve_look_at_atom_addrs[1]); { } // tb_emit(tb, smem.resolve_look_at_atom_addrs[2]); { } // tb_emit(tb, smem.resolve_look_at_atom_addrs[3]); { } @@ -356,12 +355,12 @@ void update(PrimitiveArena* pa, U4* ordering_buf) ResolveLookAtScratch_V scratch = C_scratch(ResolveLookAtScratch_V); - // Atom 0: Works - forward = scratch->fwd; - - // Atom 1: + // Atom 0: Works (tape emits fwd to scratch+0; C-side reads it back) + forward = scratch->fwd; + + // C-side normalize fallback (atom 1 disabled) // normalize_v3s4(& forward, & uz); - uz = scratch->uz; + uz = scratch->uz; /* tape-side: enable after verifying atom 1 fix */ cross_v3s4(& uz, & v3s4(0, -fp_one, 0), & right); normalize_v3s4(& right, & ux); cross_v3s4(& uz, & ux, & up); normalize_v3s4(& up, & uy); @@ -526,3 +525,4 @@ int main(void) return 0; } GCC_OPTIMIZATION_ENABLE + diff --git a/scripts/pcsx_debug_helper.zip b/scripts/pcsx_debug_helper.zip index 10826c8..0a52961 100644 Binary files a/scripts/pcsx_debug_helper.zip and b/scripts/pcsx_debug_helper.zip differ