From 3301826f5cb22fe0b2706e6953aecc5158d85baf Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 15 Aug 2026 21:34:55 -0400 Subject: [PATCH] reviewed: resolve_look_at__populate_proc --- code/duffle/gen/macs.h | 26 +++++++- code/duffle/math.atom.h | 25 +++++++- code/hello_camera/hello_camera.atom.c | 88 ++++++++------------------- code/hello_camera/hello_camera.c | 20 +++--- 4 files changed, 80 insertions(+), 79 deletions(-) diff --git a/code/duffle/gen/macs.h b/code/duffle/gen/macs.h index e36c41a..c2bbc0e 100644 --- a/code/duffle/gen/macs.h +++ b/code/duffle/gen/macs.h @@ -58,10 +58,21 @@ WORD_COUNT(mac_yield_load, 1) , nop WORD_COUNT(mac_yield_tail, 3) +/* atom_dbg_skip */ +#define mac_load_half_v3(tx, ty, tz, base, offset) \ + load_half(tx, base, offset + OA_(U2,[0])) \ +, load_half(ty, base, offset + OA_(U2,[1])) \ +, load_half(tz, base, offset + OA_(U2,[2])) +WORD_COUNT(mac_load_half_v3, 3) + +#define mac_load_v3s2(transfer, base, offset) \ + mac_load_half_v3(transfer.x, transfer.y, transfer.z, base, offset) +WORD_COUNT(mac_load_v3s2, 3) + /* atom_dbg_skip */ #define mac_load_v2s2(rs_x, rs_y, r_base, offset) \ - load_half( rs_x, r_base, offset + O_(V3_S2,x)) \ -, load_half( rs_y, r_base, offset + O_(V3_S2,y)) + load_half(rs_x, r_base, offset + O_(V3_S2,x)) \ +, load_half(rs_y, r_base, offset + O_(V3_S2,y)) WORD_COUNT(mac_load_v2s2, 2) /* atom_dbg_skip */ @@ -85,6 +96,17 @@ WORD_COUNT(mac_load_v3s4, 3) mac_load_word_v3(transfer.x, transfer.y, transfer.z, base, offset) WORD_COUNT(mac_load_p3s4, 3) +/* atom_dbg_skip */ +#define mac_store_half_v3(tx, ty, tz, base, offset) \ + store_half(tx, base, offset + OA_(U2,[0])) \ +, store_half(ty, base, offset + OA_(U2,[1])) \ +, store_half(tz, base, offset + OA_(U2,[2])) +WORD_COUNT(mac_store_half_v3, 3) + +#define mac_store_v3s2(transfer, base, offset) \ + mac_store_half_v3(transfer.x, transfer.y, transfer.z, base, offset) +WORD_COUNT(mac_store_v3s2, 3) + /* atom_dbg_skip */ #define mac_store_word_v3(tx, ty, tz, base, offset) \ store_word(tx, base, offset + OA_(U4,[0])) \ diff --git a/code/duffle/math.atom.h b/code/duffle/math.atom.h index 369d79d..95d4d7c 100644 --- a/code/duffle/math.atom.h +++ b/code/duffle/math.atom.h @@ -7,14 +7,25 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(math_atom_c); +#define v3s4_R_0() ((Reg_(V3_S4)){R_0,R_0,R_0}) + +typedef Struct_(Reg_V3_S2) { Reg x, y, z; }; typedef Struct_(Reg_V3_S4) { Reg x, y, z; }; // Register allocation of a V3_S4 typedef Struct_(Reg_P3_S4) { Reg x, y, z; }; // Register allocation of a P3_S4 #pragma region MACs (Mips Atom Component) +FI_ Slice_MipsCode ac_load_half_v3(AtomBuilder_R ab, Reg tx, Reg ty, Reg tz, Reg base, U2 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, { + load_half(tx, base, offset + OA_(U2,[0])), + load_half(ty, base, offset + OA_(U2,[1])), + load_half(tz, base, offset + OA_(U2,[2])), +}) + +FI_ Slice_MipsCode ac_load_v3s2(AtomBuilder_R ab, Reg_(V3_S2) transfer, Reg base, U2 offset) MipsAtomComp_ProcMap_(ab, mac_load_half_v3(transfer.x, transfer.y, transfer.z, base, offset)) + FI_ Slice_MipsCode ac_load_v2s2(AtomBuilder_R ab, U4 rs_x, U4 rs_y, U4 r_base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, { - load_half( rs_x, r_base, offset + O_(V3_S2,x)), - load_half( rs_y, r_base, offset + O_(V3_S2,y)), + load_half(rs_x, r_base, offset + O_(V3_S2,x)), + load_half(rs_y, r_base, offset + O_(V3_S2,y)), }) FI_ Slice_MipsCode ac_store_v2s2(AtomBuilder_R ab, U4 rt_x, U4 rt_y, U4 base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, { @@ -31,7 +42,15 @@ FI_ Slice_MipsCode ac_load_word_v3(AtomBuilder_R ab, Reg tx, Reg ty, Reg tz, Reg FI_ Slice_MipsCode ac_load_v3s4(AtomBuilder_R ab, Reg_(V3_S4) transfer, Reg base, U2 offset) MipsAtomComp_ProcMap_(ab, mac_load_word_v3(transfer.x, transfer.y, transfer.z, base, offset)) FI_ Slice_MipsCode ac_load_p3s4(AtomBuilder_R ab, Reg_(P3_S4) transfer, Reg base, U2 offset) MipsAtomComp_ProcMap_(ab, mac_load_word_v3(transfer.x, transfer.y, transfer.z, base, offset)) -FI_ Slice_MipsCode ac_store_word_v3(AtomBuilder_R ab, U4 tx, U4 ty, U4 tz, U4 base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, { +FI_ Slice_MipsCode ac_store_half_v3(AtomBuilder_R ab, Reg tx, Reg ty, Reg tz, Reg base, U2 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, { + store_half(tx, base, offset + OA_(U2,[0])), + store_half(ty, base, offset + OA_(U2,[1])), + store_half(tz, base, offset + OA_(U2,[2])), +}) + +FI_ Slice_MipsCode ac_store_v3s2(AtomBuilder_R ab, Reg_(V3_S2) transfer, Reg base, U2 offset) MipsAtomComp_ProcMap_(ab, mac_store_half_v3(transfer.x, transfer.y, transfer.z, base, offset)) + +FI_ Slice_MipsCode ac_store_word_v3(AtomBuilder_R ab, Reg tx, Reg ty, Reg tz, Reg base, U2 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, { store_word(tx, base, offset + OA_(U4,[0])), store_word(ty, base, offset + OA_(U4,[1])), store_word(tz, base, offset + OA_(U4,[2])), diff --git a/code/hello_camera/hello_camera.atom.c b/code/hello_camera/hello_camera.atom.c index 8d23d1c..23e2a83 100644 --- a/code/hello_camera/hello_camera.atom.c +++ b/code/hello_camera/hello_camera.atom.c @@ -273,7 +273,6 @@ internal MipsAtom* resolve_look_at__cross_uz_ux_to_up_proc(AtomArena_R aa, /* Load a (uz).x/y/z into r.a. */ mac_load_v3s4(r.a, r.uz, 0), LdSlot_ nop, - /* Load b (ux).x/y/z into r.b. */ mac_load_v3s4(r.b, r.ux, 0), LdSlot_ /* taken by gte_mv_from_ctrl_r */ @@ -321,76 +320,39 @@ internal MipsAtom* resolve_look_at__cross_uz_ux_to_up_proc(AtomArena_R aa, typedef Struct_(Binds_ResolveLookAtPopAndTrans) { U4 look_at; /* U4 (MT3_S2S4* — destination matrix address) */ }; -/* Atom 6 in the bundle: write look_at->m[][] from ux/uy/uz, then compute the translation column t[] = R * (-eye). +typedef Struct_(RegUse_resolve_look_at__populate_proc) { + Reg const scratch; + Reg look_at; + Reg_(V3_S4) row; /* one matrix row, reused */ + Reg ux; + Reg uy; + Reg uz; +}; +/* Atom 6a: write look_at->m[][] from ux/uy/uz as S2. Zero t[]. + * MT3_S2S4 { A3x3_S2 m; A3_S4 t; } + * m[][] is S2 packed (9 × 2 = 18 bytes at offset 0) + * t[0/1/2] is S4 (3 × 4 = 12 bytes at offset 18) * - * GPR codes (assigned by resolve_look_at_init): - * r_look_at : MT3_S2S4* (popped from tape; output matrix destination) - * r_pux : pointer to ux (offset O_(ResolveLookAtScratch,ux)) - * r_puy : pointer to uy (offset O_(ResolveLookAtScratch,uy)) - * r_puz : pointer to uz (offset O_(ResolveLookAtScratch,uz)) - * r_peye : pointer to eye (offset O_(ResolveLookAtScratch,eye)) - * r_tmp0/1/2 : atom-local scratch (load + MVMVA + store temps) - * - * 4 pointer regs (r_pux/r_puy/r_puz/r_peye) are DEDICATED — they hold the scratch addresses for the entire body. - * They are computed in-body via `add_si(r_px, r_scratch, O_(ResolveLookAtScratch, field))` so no tape-data pointer is needed. - * - * Struct layout (per duffle/math.h): - * MT3_S2S4 { A3x3_S2 m; A3_S4 t; } → m[][] is S2 packed (9 × 2 = 18 bytes at offset 0) - * t[0/1/2] is S4 (3 × 4 = 12 bytes at offset 18) - * - * Translation column: GTE MVMVA with the world rotation matrix pre-set - * (helper emits set_gte_world before the bundle, per the bundle design). - * MVMVA computes R * pos (with cv=0/mx=0/sf=0/v=0); MAC1/2/3 = R * (-eye). - * Pool cost: r_look_at (1) + r_scratch (R_T4 carrier) + 4 ptr regs + 3 tmp regs = 9 GPRs. + * ux/uy/uz stay dedicated address regs for the whole body. + * row is the S4 load / S2 store transfer, reused per matrix row. + * Eye is not read here — atom 6b reads it. */ -internal MipsAtom* resolve_look_at__populate_proc(AtomArena_R aa - , U4 r_look_at - , U4 r_scratch - , U4 r_pux, U4 r_puy, U4 r_puz - , U4 r_tmp0, U4 r_tmp1, U4 r_tmp2 +internal MipsAtom* resolve_look_at__populate_proc(AtomArena_R aa, + RegUse_resolve_look_at__populate_proc r ) MipsAtom_Proc_(aa, { - /* Pop look_at* (the matrix output) — advance R_TapePtr by 4 bytes. */ - load_word(r_look_at, R_TapePtr, O_(Binds_ResolveLookAtPopAndTrans,look_at)), + load_word(r.look_at, R_TapePtr, O_(Binds_ResolveLookAtPopAndTrans,look_at)), add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtPopAndTrans)), - /* Compute the 3 scratch pointers in their dedicated GPRs (eye isn't needed by 6a — 6b reads it). */ - add_si(r_pux, r_scratch, O_(ResolveLookAtScratch,ux)), /* r_pux = &ux */ - add_si(r_puy, r_scratch, O_(ResolveLookAtScratch,uy)), /* r_puy = &uy */ - add_si(r_puz, r_scratch, O_(ResolveLookAtScratch,uz)), /* r_puz = &uz */ - nop, + add_si(r.ux, r.scratch, O_(ResolveLookAtScratch,ux)), /* r.ux = &ux */ + add_si(r.uy, r.scratch, O_(ResolveLookAtScratch,uy)), /* r.uy = &uy */ + add_si(r.uz, r.scratch, O_(ResolveLookAtScratch,uz)), /* r.uz = &uz */ - /* ── m[0] = (S2)ux ── */ - load_word(r_tmp0, r_pux, O_(V3_S4,x)), - load_word(r_tmp1, r_pux, O_(V3_S4,y)), - load_word(r_tmp2, r_pux, O_(V3_S4,z)), - nop, - store_half(r_tmp0, r_look_at, O_(MT3_S2S4,m[0][0])), - store_half(r_tmp1, r_look_at, O_(MT3_S2S4,m[0][1])), - store_half(r_tmp2, r_look_at, O_(MT3_S2S4,m[0][2])), - - /* ── m[1] = (S2)uy ── */ - load_word(r_tmp0, r_puy, O_(V3_S4,x)), - load_word(r_tmp1, r_puy, O_(V3_S4,y)), - load_word(r_tmp2, r_puy, O_(V3_S4,z)), - nop, - store_half(r_tmp0, r_look_at, O_(MT3_S2S4,m[1][0])), - store_half(r_tmp1, r_look_at, O_(MT3_S2S4,m[1][1])), - store_half(r_tmp2, r_look_at, O_(MT3_S2S4,m[1][2])), - - /* ── m[2] = (S2)uz ── */ - load_word(r_tmp0, r_puz, O_(V3_S4,x)), - load_word(r_tmp1, r_puz, O_(V3_S4,y)), - load_word(r_tmp2, r_puz, O_(V3_S4,z)), - nop, - store_half(r_tmp0, r_look_at, O_(MT3_S2S4,m[2][0])), - store_half(r_tmp1, r_look_at, O_(MT3_S2S4,m[2][1])), - store_half(r_tmp2, r_look_at, O_(MT3_S2S4,m[2][2])), + mac_load_v3s4(r.row, r.ux, 0), LdSlot_ mac_store_v3s2(r.row, r.look_at, O_(MT3_S2S4,m[0])), + mac_load_v3s4(r.row, r.uy, 0), LdSlot_ mac_store_v3s2(r.row, r.look_at, O_(MT3_S2S4,m[1])), + mac_load_v3s4(r.row, r.uz, 0), LdSlot_ mac_store_v3s2(r.row, r.look_at, O_(MT3_S2S4,m[2])), /* Zero t[0..2] — atom 6c writes the final values here. */ - store_word(R_0, r_look_at, O_(MT3_S2S4,t[0])), - store_word(R_0, r_look_at, O_(MT3_S2S4,t[1])), - store_word(R_0, r_look_at, O_(MT3_S2S4,t[2])), - + mac_store_v3s4(v3s4_R_0(), r.look_at, O_(MT3_S2S4,t)), mac_yield() }) diff --git a/code/hello_camera/hello_camera.c b/code/hello_camera/hello_camera.c index d3a8470..913938b 100644 --- a/code/hello_camera/hello_camera.c +++ b/code/hello_camera/hello_camera.c @@ -247,18 +247,16 @@ internal void resolve_look_at_init(void) { }); /* === ATOM 6a: populate (m[][] from ux/uy/uz, t[]=0) === */ - U4 r_look_at_6a = R_T0; /* tape pop → look_at* */ - U4 r_scratch_6a = R_ResolveScratch; - U4 r_pux_6a = R_T1; - U4 r_puy_6a = R_T3; - U4 r_puz_6a = R_T5; - U4 r_tmp0_6a = R_T2; - U4 r_tmp1_6a = R_T6; - U4 r_tmp2_6a = R_V0; + regfile_reset_to_mask(& rf, pin_mask); smem.resolve_look_at_atom_addrs[6] = resolve_look_at__populate_proc(& ab, - r_look_at_6a, r_scratch_6a, - r_pux_6a, r_puy_6a, r_puz_6a, - r_tmp0_6a, r_tmp1_6a, r_tmp2_6a); + RegUse_(resolve_look_at__populate_proc){ + .scratch = R_ResolveScratch, + .look_at = ralloc(), /* T0 */ + .row = ralloc_v3(), /* T1 T2 T3 */ + .ux = ralloc(), /* T5 = ux */ + .uy = ralloc(), /* T6 = uy */ + .uz = ralloc(), /* T7 = uz */ + }); /* === ATOM 6a.5: set_gte_mt3s2s4 (BAKED — ctc2 RT matrix) === * This is a BAKED atom from gte.atom.c. Its body hardcodes R_T3 as