mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-08-25 02:20:33 +00:00
reviewed: resolve_look_at__populate_proc
This commit is contained in:
+24
-2
@@ -58,10 +58,21 @@ WORD_COUNT(mac_yield_load, 1)
|
|||||||
, nop
|
, nop
|
||||||
WORD_COUNT(mac_yield_tail, 3)
|
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 */
|
/* atom_dbg_skip */
|
||||||
#define mac_load_v2s2(rs_x, rs_y, r_base, offset) \
|
#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_x, r_base, offset + O_(V3_S2,x)) \
|
||||||
, load_half( rs_y, r_base, offset + O_(V3_S2,y))
|
, load_half(rs_y, r_base, offset + O_(V3_S2,y))
|
||||||
WORD_COUNT(mac_load_v2s2, 2)
|
WORD_COUNT(mac_load_v2s2, 2)
|
||||||
|
|
||||||
/* atom_dbg_skip */
|
/* 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)
|
mac_load_word_v3(transfer.x, transfer.y, transfer.z, base, offset)
|
||||||
WORD_COUNT(mac_load_p3s4, 3)
|
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 */
|
/* atom_dbg_skip */
|
||||||
#define mac_store_word_v3(tx, ty, tz, base, offset) \
|
#define mac_store_word_v3(tx, ty, tz, base, offset) \
|
||||||
store_word(tx, base, offset + OA_(U4,[0])) \
|
store_word(tx, base, offset + OA_(U4,[0])) \
|
||||||
|
|||||||
+22
-3
@@ -7,14 +7,25 @@
|
|||||||
|
|
||||||
ATOM_FILE_DEBUGGER_LINE_MARKER(math_atom_c);
|
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_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
|
typedef Struct_(Reg_P3_S4) { Reg x, y, z; }; // Register allocation of a P3_S4
|
||||||
|
|
||||||
#pragma region MACs (Mips Atom Component)
|
#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, {
|
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_x, r_base, offset + O_(V3_S2,x)),
|
||||||
load_half( rs_y, r_base, offset + O_(V3_S2,y)),
|
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, {
|
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_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_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(tx, base, offset + OA_(U4,[0])),
|
||||||
store_word(ty, base, offset + OA_(U4,[1])),
|
store_word(ty, base, offset + OA_(U4,[1])),
|
||||||
store_word(tz, base, offset + OA_(U4,[2])),
|
store_word(tz, base, offset + OA_(U4,[2])),
|
||||||
|
|||||||
@@ -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. */
|
/* Load a (uz).x/y/z into r.a. */
|
||||||
mac_load_v3s4(r.a, r.uz, 0), LdSlot_ nop,
|
mac_load_v3s4(r.a, r.uz, 0), LdSlot_ nop,
|
||||||
|
|
||||||
/* Load b (ux).x/y/z into r.b. */
|
/* 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 */
|
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) {
|
typedef Struct_(Binds_ResolveLookAtPopAndTrans) {
|
||||||
U4 look_at; /* U4 (MT3_S2S4* — destination matrix address) */
|
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;
|
||||||
* GPR codes (assigned by resolve_look_at_init):
|
Reg look_at;
|
||||||
* r_look_at : MT3_S2S4* (popped from tape; output matrix destination)
|
Reg_(V3_S4) row; /* one matrix row, reused */
|
||||||
* r_pux : pointer to ux (offset O_(ResolveLookAtScratch,ux))
|
Reg ux;
|
||||||
* r_puy : pointer to uy (offset O_(ResolveLookAtScratch,uy))
|
Reg uy;
|
||||||
* r_puz : pointer to uz (offset O_(ResolveLookAtScratch,uz))
|
Reg uz;
|
||||||
* r_peye : pointer to eye (offset O_(ResolveLookAtScratch,eye))
|
};
|
||||||
* r_tmp0/1/2 : atom-local scratch (load + MVMVA + store temps)
|
/* Atom 6a: write look_at->m[][] from ux/uy/uz as S2. Zero t[].
|
||||||
*
|
* MT3_S2S4 { A3x3_S2 m; A3_S4 t; }
|
||||||
* 4 pointer regs (r_pux/r_puy/r_puz/r_peye) are DEDICATED — they hold the scratch addresses for the entire body.
|
* m[][] is S2 packed (9 × 2 = 18 bytes at offset 0)
|
||||||
* 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)
|
* t[0/1/2] is S4 (3 × 4 = 12 bytes at offset 18)
|
||||||
*
|
*
|
||||||
* Translation column: GTE MVMVA with the world rotation matrix pre-set
|
* ux/uy/uz stay dedicated address regs for the whole body.
|
||||||
* (helper emits set_gte_world before the bundle, per the bundle design).
|
* row is the S4 load / S2 store transfer, reused per matrix row.
|
||||||
* MVMVA computes R * pos (with cv=0/mx=0/sf=0/v=0); MAC1/2/3 = R * (-eye).
|
* Eye is not read here — atom 6b reads it.
|
||||||
* Pool cost: r_look_at (1) + r_scratch (R_T4 carrier) + 4 ptr regs + 3 tmp regs = 9 GPRs.
|
|
||||||
*/
|
*/
|
||||||
internal MipsAtom* resolve_look_at__populate_proc(AtomArena_R aa
|
internal MipsAtom* resolve_look_at__populate_proc(AtomArena_R aa,
|
||||||
, U4 r_look_at
|
RegUse_resolve_look_at__populate_proc r
|
||||||
, U4 r_scratch
|
|
||||||
, U4 r_pux, U4 r_puy, U4 r_puz
|
|
||||||
, U4 r_tmp0, U4 r_tmp1, U4 r_tmp2
|
|
||||||
) MipsAtom_Proc_(aa, {
|
) 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)),
|
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.ux, r.scratch, O_(ResolveLookAtScratch,ux)), /* r.ux = &ux */
|
||||||
add_si(r_pux, r_scratch, O_(ResolveLookAtScratch,ux)), /* r_pux = &ux */
|
add_si(r.uy, r.scratch, O_(ResolveLookAtScratch,uy)), /* r.uy = &uy */
|
||||||
add_si(r_puy, r_scratch, O_(ResolveLookAtScratch,uy)), /* r_puy = &uy */
|
add_si(r.uz, r.scratch, O_(ResolveLookAtScratch,uz)), /* r.uz = &uz */
|
||||||
add_si(r_puz, r_scratch, O_(ResolveLookAtScratch,uz)), /* r_puz = &uz */
|
|
||||||
nop,
|
|
||||||
|
|
||||||
/* ── m[0] = (S2)ux ── */
|
mac_load_v3s4(r.row, r.ux, 0), LdSlot_ mac_store_v3s2(r.row, r.look_at, O_(MT3_S2S4,m[0])),
|
||||||
load_word(r_tmp0, r_pux, O_(V3_S4,x)),
|
mac_load_v3s4(r.row, r.uy, 0), LdSlot_ mac_store_v3s2(r.row, r.look_at, O_(MT3_S2S4,m[1])),
|
||||||
load_word(r_tmp1, r_pux, O_(V3_S4,y)),
|
mac_load_v3s4(r.row, r.uz, 0), LdSlot_ mac_store_v3s2(r.row, r.look_at, O_(MT3_S2S4,m[2])),
|
||||||
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])),
|
|
||||||
|
|
||||||
/* Zero t[0..2] — atom 6c writes the final values here. */
|
/* Zero t[0..2] — atom 6c writes the final values here. */
|
||||||
store_word(R_0, r_look_at, O_(MT3_S2S4,t[0])),
|
mac_store_v3s4(v3s4_R_0(), r.look_at, O_(MT3_S2S4,t)),
|
||||||
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_yield()
|
mac_yield()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -247,18 +247,16 @@ internal void resolve_look_at_init(void) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/* === ATOM 6a: populate (m[][] from ux/uy/uz, t[]=0) === */
|
/* === ATOM 6a: populate (m[][] from ux/uy/uz, t[]=0) === */
|
||||||
U4 r_look_at_6a = R_T0; /* tape pop → look_at* */
|
regfile_reset_to_mask(& rf, pin_mask);
|
||||||
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;
|
|
||||||
smem.resolve_look_at_atom_addrs[6] = resolve_look_at__populate_proc(& ab,
|
smem.resolve_look_at_atom_addrs[6] = resolve_look_at__populate_proc(& ab,
|
||||||
r_look_at_6a, r_scratch_6a,
|
RegUse_(resolve_look_at__populate_proc){
|
||||||
r_pux_6a, r_puy_6a, r_puz_6a,
|
.scratch = R_ResolveScratch,
|
||||||
r_tmp0_6a, r_tmp1_6a, r_tmp2_6a);
|
.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) ===
|
/* === 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
|
* This is a BAKED atom from gte.atom.c. Its body hardcodes R_T3 as
|
||||||
|
|||||||
Reference in New Issue
Block a user