From a704341fc67291e009b3a7fdaa8ef1f58408a9d4 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 27 Jul 2026 23:35:03 -0400 Subject: [PATCH] Testing out the metaprogram with some optimization, need to remove some hardcoding later.. --- .vscode/launch.json | 1 - code/duffle/gen/duffle.macs.h | 12 +++--- code/duffle/lottes_tape.h | 6 +-- code/gte_hello/gen/gte_hello.offsets.h | 8 ++-- code/gte_hello/hello_gte_tape.c | 30 +++++++-------- scripts/duffle.lua | 52 +++++++++++++------------- 6 files changed, 55 insertions(+), 54 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index ac29223..cb8ea26 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -138,7 +138,6 @@ "monitor reset shellhalt", "load build/hello_gte.dwarf-injected.elf", "source scripts/gdb/gdb_tape_atoms.gdb", - "source build/gen/hello_gte.gdbinit", "tbreak main", "continue" ] diff --git a/code/duffle/gen/duffle.macs.h b/code/duffle/gen/duffle.macs.h index 337ce4c..218ed79 100644 --- a/code/duffle/gen/duffle.macs.h +++ b/code/duffle/gen/duffle.macs.h @@ -98,11 +98,11 @@ WORD_COUNT(mac_format_f3_color, 3) /* atom_dbg_skip */ /* Words: 3; Stores the 3 transformed (V2_S2 screen) vertices to the F3. * PIPELINE: post-RTPT (SXY0=v0.screen, SXY1=v1.screen, SXY2=v2.screen). */ -#define mac_gte_store_f3_post_rtpt(...) \ +#define mac_gte_store_f3(...) \ gte_sw(C2_SXY0, R_PrimCursor, O_(Poly_F3,p0)) \ , gte_sw(C2_SXY1, R_PrimCursor, O_(Poly_F3,p1)) \ , gte_sw(C2_SXY2, R_PrimCursor, O_(Poly_F3,p2)) -WORD_COUNT(mac_gte_store_f3_post_rtpt, 3) +WORD_COUNT(mac_gte_store_f3, 3) #define mac_format_g4_color(r0, g0, b0, r1, g1, b1, r2, g2, b2, r3, g3, b3) \ mac_pack_color_word(O_(Poly_G4,c0), gp0_cmd_poly_g4, r0,g0,b0) \ @@ -117,18 +117,18 @@ WORD_COUNT(mac_format_g4_color, 12) * PIPELINE: post-RTPT, pre-RTPS (SXY0=v0.screen, SXY1=v1.screen, SXY2=v2.screen). * MUST be called BEFORE V3-RTPS, otherwise SXY0/1/2 get overwritten with v3 * (RTPS writes only to SXY2, but to keep the three registers aligned with v0/v1/v2 you must store before RTPS). */ -#define mac_gte_store_g4_p012_post_rtpt_pre_rtps(...) \ +#define mac_gte_store_g4_p012(...) \ gte_sw(C2_SXY0, R_PrimCursor, O_(Poly_G4,p0)) \ , gte_sw(C2_SXY1, R_PrimCursor, O_(Poly_G4,p1)) \ , gte_sw(C2_SXY2, R_PrimCursor, O_(Poly_G4,p2)) -WORD_COUNT(mac_gte_store_g4_p012_post_rtpt_pre_rtps, 3) +WORD_COUNT(mac_gte_store_g4_p012, 3) /* atom_dbg_skip */ /* Words: 1; Stores the V3 screen coord to the G4's p3 slot. * PIPELINE: post-RTPS (SXY2 holds v3.screen because RTPS writes its single-vertex result to SXY2; * SXY0 still holds v0.screen from the earlier RTPT. */ -#define mac_gte_store_g4_p3_post_rtps(...) \ +#define mac_gte_store_g4_p3(...) \ gte_sw(C2_SXY2, R_PrimCursor, O_(Poly_G4,p3)) -WORD_COUNT(mac_gte_store_g4_p3_post_rtps, 1) +WORD_COUNT(mac_gte_store_g4_p3, 1) diff --git a/code/duffle/lottes_tape.h b/code/duffle/lottes_tape.h index 569f2df..6bf5825 100644 --- a/code/duffle/lottes_tape.h +++ b/code/duffle/lottes_tape.h @@ -170,7 +170,7 @@ atom_dbg_skip MipsAtomComp_Proc_(ac_format_f3_color, { mac_pack_color_word(O_(Po /* Words: 3; Stores the 3 transformed (V2_S2 screen) vertices to the F3. * PIPELINE: post-RTPT (SXY0=v0.screen, SXY1=v1.screen, SXY2=v2.screen). */ -atom_dbg_skip MipsAtomComp_(ac_gte_store_f3_post_rtpt) { +atom_dbg_skip MipsAtomComp_(ac_gte_store_f3) { gte_sw(C2_SXY0, R_PrimCursor, O_(Poly_F3,p0)), gte_sw(C2_SXY1, R_PrimCursor, O_(Poly_F3,p1)), gte_sw(C2_SXY2, R_PrimCursor, O_(Poly_F3,p2)), @@ -195,7 +195,7 @@ MipsAtomComp_Proc_(ac_format_g4_color, { * PIPELINE: post-RTPT, pre-RTPS (SXY0=v0.screen, SXY1=v1.screen, SXY2=v2.screen). * MUST be called BEFORE V3-RTPS, otherwise SXY0/1/2 get overwritten with v3 * (RTPS writes only to SXY2, but to keep the three registers aligned with v0/v1/v2 you must store before RTPS). */ -atom_dbg_skip MipsAtomComp_(ac_gte_store_g4_p012_post_rtpt_pre_rtps) { +atom_dbg_skip MipsAtomComp_(ac_gte_store_g4_p012) { gte_sw(C2_SXY0, R_PrimCursor, O_(Poly_G4,p0)), gte_sw(C2_SXY1, R_PrimCursor, O_(Poly_G4,p1)), gte_sw(C2_SXY2, R_PrimCursor, O_(Poly_G4,p2)), @@ -205,7 +205,7 @@ atom_dbg_skip MipsAtomComp_(ac_gte_store_g4_p012_post_rtpt_pre_rtps) { * PIPELINE: post-RTPS (SXY2 holds v3.screen because RTPS writes its single-vertex result to SXY2; * SXY0 still holds v0.screen from the earlier RTPT. */ -atom_dbg_skip MipsAtomComp_(ac_gte_store_g4_p3_post_rtps) { gte_sw(C2_SXY2, R_PrimCursor, O_(Poly_G4,p3)) }; +atom_dbg_skip MipsAtomComp_(ac_gte_store_g4_p3) { gte_sw(C2_SXY2, R_PrimCursor, O_(Poly_G4,p3)) }; #pragma endregion Macro Atom Components diff --git a/code/gte_hello/gen/gte_hello.offsets.h b/code/gte_hello/gen/gte_hello.offsets.h index ce2aa87..cf46d71 100644 --- a/code/gte_hello/gen/gte_hello.offsets.h +++ b/code/gte_hello/gen/gte_hello.offsets.h @@ -5,10 +5,10 @@ #pragma region hello_gte_tape -// --- atom: cube_g4_face (79 words) --- +// --- atom: cube_g4_face (77 words) --- -#define _atom_offset_cull_cube_g4_face_exit 44 -#define _atom_offset_bounds_chk_cube_g4_face_exit 12 +#define _atom_offset_cull_cube_g4_face_exit 42 +#define _atom_offset_bounds_chk_cube_g4_face_exit 24 enum { atom_offset_cull_cube_g4_face_exit = _atom_offset_cull_cube_g4_face_exit, @@ -18,7 +18,7 @@ enum { // --- atom: floor_f3_face (58 words) --- #define _atom_offset_culling_floor_f3_face_exit 25 -#define _atom_offset_bounds_chk_floor_f3_face_exit 13 +#define _atom_offset_bounds_chk_floor_f3_face_exit 16 enum { atom_offset_culling_floor_f3_face_exit = _atom_offset_culling_floor_f3_face_exit, diff --git a/code/gte_hello/hello_gte_tape.c b/code/gte_hello/hello_gte_tape.c index 5851084..a8c3f2f 100644 --- a/code/gte_hello/hello_gte_tape.c +++ b/code/gte_hello/hello_gte_tape.c @@ -51,22 +51,18 @@ MipsAtom_(cube_g4_face) atom_info(atom_phase(cube_g4), gte_cmdw_nclip, gte_mv_from_data_r(R_T0, C2_MAC0), - nop, branch_le_zero(R_T0, atom_offset(cull, cube_g4_face_exit)), nop, + nop, + branch_le_zero(R_T0, atom_offset(cull, cube_g4_face_exit)), nop, store_word(R_0, R_PrimCursor, O_(Poly_G4, tag)), - mac_format_g4_color( - /* c0 magenta */ 0xFF, 0x00, 0xFF, - /* c1 yellow */ 0xFF, 0xFF, 0x00, - /* c2 cyan */ 0x00, 0xFF, 0xFF, - /* c3 green */ 0x00, 0xFF, 0x00), - mac_gte_store_g4_p012_post_rtpt_pre_rtps(), shift_lleft(R_AT, R_T3, v3s2_byteoff), add_u(R_AT, R_AT, R_VertBase), load_word(R_V0, R_AT, O_(V3_S2, x)), load_word(R_V1, R_AT, O_(V3_S2, z)), gte_mv_to_data_r(R_V0, C2_VXY0), gte_mv_to_data_r(R_V1, C2_VZ0), - nop2, gte_cmdw_rotate_translate_perspective_single, - mac_gte_store_g4_p3_post_rtps(), + mac_gte_store_g4_p012(), + gte_cmdw_rotate_translate_perspective_single, + mac_gte_store_g4_p3(), gte_cmdw_avg_sort_z4, gte_mv_from_data_r(R_T1, C2_OTZ), @@ -74,6 +70,11 @@ MipsAtom_(cube_g4_face) atom_info(atom_phase(cube_g4), add_ui( R_AT, R_0, OrderingTbl_Len), set_lt_u( R_AT, R_T1, R_AT), branch_equal(R_AT, R_0, atom_offset(bounds_chk, cube_g4_face_exit)), nop, + mac_format_g4_color( + /* c0 magenta */ 0xFF, 0x00, 0xFF, + /* c1 yellow */ 0xFF, 0xFF, 0x00, + /* c2 cyan */ 0x00, 0xFF, 0xFF, + /* c3 green */ 0x00, 0xFF, 0x00), mac_insert_ot_tag_g4(), atom_label(cube_g4_face_exit) @@ -102,11 +103,11 @@ MipsAtom_(rbind_floor_f3_face) atom_info(atom_bind(Binds_FloorTri), atom_phase(f mac_yield() }; -atom_dbg_skip +// atom_dbg_skip internal MipsAtom_(floor_f3_face) atom_info(atom_phase(floor_f3) , atom_reads( R_PrimCursor, R_FaceCursor, R_VertBase, R_OtBase) - , atom_writes(R_PrimCursor, R_FaceCursr) + , atom_writes(R_PrimCursor, R_FaceCursor) ) { mac_load_tri_indices( R_T0, R_T1, R_T2), mac_gte_load_tri_verts(R_T0, R_T1, R_T2), @@ -117,8 +118,7 @@ MipsAtom_(floor_f3_face) atom_info(atom_phase(floor_f3) gte_mv_from_data_r(R_T0, C2_MAC0), nop, branch_le_zero(R_T0, atom_offset(culling, floor_f3_face_exit)), nop, // required gte -> cpu load-delay slot. /* Format Primitive */ - mac_format_f3_color(0xFF, 0xFF, 0xFF), // RGB-form (R=FF, G=FF, B=FF = white) - mac_gte_store_f3_post_rtpt(), + mac_gte_store_f3(), /* Calculate Depth */ gte_avg_sort_z3, @@ -127,8 +127,8 @@ MipsAtom_(floor_f3_face) atom_info(atom_phase(floor_f3) add_ui( R_AT, R_0, OrderingTbl_Len), set_lt_u( R_AT, R_T1, R_AT), branch_equal(R_AT, R_0, atom_offset(bounds_chk, floor_f3_face_exit)), nop, - /* Insert into Ordering Table Linked List */ - mac_insert_ot_tag_f3(), + mac_format_f3_color(0xFF, 0xFF, 0xFF), // RGB-form (R=FF, G=FF, B=FF = white) + mac_insert_ot_tag_f3(), /* Insert into Ordering Table Linked List */ add_ui_self(R_PrimCursor, S_(Poly_F3)), /* Advance Prim Cursor (5 words) */ // Note(Ed): No bounds checking, should be checked before atom runs. diff --git a/scripts/duffle.lua b/scripts/duffle.lua index 23a4c61..3ac84cb 100644 --- a/scripts/duffle.lua +++ b/scripts/duffle.lua @@ -1180,8 +1180,7 @@ M.GTE_COMMAND_INPUTS = { -- * "mac_result" : generic MAC output (nclip, op, mvmva) -- -- Consumers: --- * passes/static_analysis.lua::analyze_hardware_relations (the walker reads this after a GTE command to update --- `forward_state.post_command_roles` for `gte_role_mismatch`). +-- * passes/static_analysis.lua::analyze_hardware_relations (the walker reads this after a GTE command to update `forward_state.post_command_roles` for `gte_role_mismatch`). -- * passes/static_analysis.lua::check_gte_role_mismatch (per-atom CHECK_RULES reader; renders role mismatches). -- This table is consumed by the hardware-relation analyzer and the gte_role_mismatch check. M.GTE_COMMAND_OUTPUTS = { @@ -1294,8 +1293,7 @@ M.GTE_COMMAND_LATCH_WINDOWS = { } -- GTE component result contracts were removed: the `_post_` naming convention was a soft convention --- (the user did not want it formalized via static-analysis enforcement). A proper `atom_info` directive for --- ordering semantics is a future TODO. +-- (the user did not want it formalized via static-analysis enforcement). A proper `atom_info` directive for ordering semantics is a future TODO. -- Operand-class table for the COP2->GPR load-delay check. -- @@ -1424,20 +1422,21 @@ M.GP0_CMD_BY_SHAPE = { ["g4"] = 0x38, ["gt4"] = 0x3C, } +-- TODO(Ed): REMOVE THIS HARDCODE, THIS SHOULD BE RESOLVED AUTOMATICALLY -- Per-macro prim-buffer contribution: how many 32-bit words each macro writes to the primitive being built in main RAM. -- (This counts RAM-side prim-buffer words, not .text instruction words.) -- The sum across `mac_format_X_color` + `mac_gte_store_X_post_*` + `mac_insert_ot_tag_X` calls in an atom body must equal -- `GP0_CMD_SIZE[GP0_CMD_BY_SHAPE[shape]]`. M.GP0_MACRO_CONTRIB = { - ["mac_format_f3_color"] = 1, - ["mac_format_g3_color"] = 3, - ["mac_format_g4_color"] = 4, - ["mac_gte_store_f3_post_rtpt"] = 3, - ["mac_gte_store_g3_post_rtpt"] = 3, - ["mac_gte_store_g4_p012_post_rtpt_pre_rtps"] = 3, - ["mac_gte_store_g4_p3_post_rtps"] = 1, - ["mac_insert_ot_tag_f3"] = 1, - ["mac_insert_ot_tag_g4"] = 1, + ["mac_format_f3_color"] = 1, + ["mac_format_g3_color"] = 3, + ["mac_format_g4_color"] = 4, + ["mac_gte_store_f3"] = 3, + ["mac_gte_store_g3"] = 3, + ["mac_gte_store_g4_p012"] = 3, + ["mac_gte_store_g4_p3"] = 1, + ["mac_insert_ot_tag_f3"] = 1, + ["mac_insert_ot_tag_g4"] = 1, } -- Per-macro cycle cost (best-case, no stalls). Used by the static-analysis pass to emit per-atom cycle budgets. @@ -1560,20 +1559,23 @@ M.INSTRUCTION_LATENCY = { ["gte_load_v1"] = 2, ["gte_load_v2"] = 2, ["gte_load_v0v1v2"] = 6, + + -- TODO(Ed): REMOVE THIS HARDCODE, THIS SHOULD BE RESOLVED AUTOMATICALLY -- mac_* helpers (cycle cost = sum of the expanded instructions) -- mac_yield transfers control; cycle budget is 0 (the next atom absorbs the cost). - ["mac_yield"] = 0, - ["mac_pack_color_word"] = 3, -- lui + ori + sw - ["mac_format_f3_color"] = 3, -- = mac_pack_color_word - ["mac_format_g4_color"] = 12, -- 4 x mac_pack_color_word - ["mac_load_tri_indices"] = 3, -- 3 x lhu - ["mac_gte_load_tri_verts"] = 18, -- 3 x {sll, addu, lw, lw, mtc2, mtc2} - ["mac_gte_store_f3_post_rtpt"] = 3, - ["mac_gte_store_g3_post_rtpt"] = 3, - ["mac_gte_store_g4_p012_post_rtpt_pre_rtps"] = 3, - ["mac_gte_store_g4_p3_post_rtps"] = 1, - ["mac_insert_ot_tag_f3"] = 11, -- 11 .word slots in the macro body - ["mac_insert_ot_tag_g4"] = 11, + ["mac_yield"] = 0, + ["mac_pack_color_word"] = 3, -- lui + ori + sw + ["mac_format_f3_color"] = 3, -- = mac_pack_color_word + ["mac_format_g4_color"] = 12, -- 4 x mac_pack_color_word + ["mac_load_tri_indices"] = 3, -- 3 x lhu + ["mac_gte_load_tri_verts"] = 18, -- 3 x {sll, addu, lw, lw, mtc2, mtc2} + ["mac_gte_store_f3"] = 3, + ["mac_gte_store_g3"] = 3, + ["mac_gte_store_g4_p012"] = 3, + ["mac_gte_store_g4_p3"] = 1, + ["mac_insert_ot_tag_f3"] = 11, -- 11 .word slots in the macro body + ["mac_insert_ot_tag_g4"] = 11, + -- Annotation markers (emit no code; pure metaprogram hints) ["atom_label"] = 0, ["atom_offset"] = 0,