2 Commits
Author SHA1 Message Date
ed 1faf3539d8 use tb_bind_ macro fro draw cube and tri, better type convention on binds. 2026-09-03 17:36:36 -04:00
ed 6b3fbab387 Adjusting type convention for raw memory. (Reviewing for articles)
Feel like opting for u1-4.. (b1-4 not meaning byte anymore, not sure why I bothered, just bools/bits)
2026-09-03 17:14:34 -04:00
8 changed files with 143 additions and 155 deletions
+12
View File
@@ -121,6 +121,11 @@ typedef unsigned char TSet_(B1);
typedef __UINT16_TYPE__ TSet_(B2); typedef __UINT16_TYPE__ TSet_(B2);
typedef __UINT32_TYPE__ TSet_(B4); typedef __UINT32_TYPE__ TSet_(B4);
#define b1_(value) C_(B1, value)
#define b2_(value) C_(B2, value)
#define b4_(value) C_(B4, value)
#define u1_(value) C_(U1, value) #define u1_(value) C_(U1, value)
#define u2_(value) C_(U2, value) #define u2_(value) C_(U2, value)
#define u4_(value) C_(U4, value) #define u4_(value) C_(U4, value)
@@ -128,6 +133,13 @@ typedef __UINT32_TYPE__ TSet_(B4);
#define s2_(value) C_(S2, value) #define s2_(value) C_(S2, value)
#define s4_(value) C_(S4, value) #define s4_(value) C_(S4, value)
#define b1_r(value) C_(B1*R_, value)
#define b2_r(value) C_(B2*R_, value)
#define b4_r(value) C_(B4*R_, value)
#define b1_v(value) C_(B1 V_*, value)
#define b2_v(value) C_(B2 V_*, value)
#define b4_v(value) C_(B4 V_*, value)
#define u1_r(value) C_(U1 *R_, value) #define u1_r(value) C_(U1 *R_, value)
#define u2_r(value) C_(U2 *R_, value) #define u2_r(value) C_(U2 *R_, value)
#define u4_r(value) C_(U4 *R_, value) #define u4_r(value) C_(U4 *R_, value)
+1 -1
View File
@@ -8,7 +8,7 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(gp_atom_c);
#pragma region MACs (Mips Atom Components) #pragma region MACs (Mips Atom Components)
FI_ Slice_MipsCode ac_gcmd_push(AtomBuilder_R ab, U4 cmd, U4 reg_transfer, U4 reg_base, U2 port) FI_ Slice_MipsCode ac_gcmd_push(AtomBuilder_R ab, U2 cmd, Reg reg_transfer, Reg reg_base, U2 port)
atom_dbg_skip MipsAtomComp_Proc_(ab, { atom_dbg_skip MipsAtomComp_Proc_(ab, {
mac_load_word_imm(reg_transfer, cmd), mac_load_word_imm(reg_transfer, cmd),
store_word( reg_transfer, reg_base, port), store_word( reg_transfer, reg_base, port),
+19 -19
View File
@@ -386,7 +386,7 @@ enum {
* ============================================================================ */ * ============================================================================ */
/* ---------- RGB8 (3-byte packed color) ---------- */ /* ---------- RGB8 (3-byte packed color) ---------- */
typedef Struct_(RGB8) { B1 r; B1 g; B1 b; }; typedef Struct_(RGB8) { U1 r; U1 g; U1 b; };
#define rgb8(r,g,b) ((RGB8){r,g,b}) #define rgb8(r,g,b) ((RGB8){r,g,b})
/* ---------- PolyTag (the OT-link header; 1 word) ---------- */ /* ---------- PolyTag (the OT-link header; 1 word) ---------- */
@@ -416,7 +416,7 @@ typedef Struct_(PolyTag) {
typedef Struct_(Poly_F3) { typedef Struct_(Poly_F3) {
U4 tag; U4 tag;
RGB8 color; RGB8 color;
B1 code; U1 code;
union { union {
struct { V2_S2 p0; V2_S2 p1; V2_S2 p2; }; struct { V2_S2 p0; V2_S2 p1; V2_S2 p2; };
A3_V2_S2 points; A3_V2_S2 points;
@@ -427,7 +427,7 @@ typedef Struct_(Poly_F3) {
typedef Struct_(Poly_F4) { typedef Struct_(Poly_F4) {
U4 tag; U4 tag;
RGB8 color; RGB8 color;
B1 code; U1 code;
union { union {
struct { V2_S2 p0; V2_S2 p1; V2_S2 p2; V2_S2 p3; }; struct { V2_S2 p0; V2_S2 p1; V2_S2 p2; V2_S2 p3; };
A4_V2_S2 points; A4_V2_S2 points;
@@ -436,18 +436,18 @@ typedef Struct_(Poly_F4) {
/* ---------- Poly_G3 (Gouraud Triangle; 7 words) ---------- */ /* ---------- Poly_G3 (Gouraud Triangle; 7 words) ---------- */
typedef Struct_(Poly_G3) { typedef Struct_(Poly_G3) {
U4 tag; RGB8 c0; B1 code; U4 tag; RGB8 c0; U1 code;
V2_S2 p0; RGB8 c1; B1 pad1; V2_S2 p0; RGB8 c1; U1 pad1;
V2_S2 p1; RGB8 c2; B1 pad2; V2_S2 p1; RGB8 c2; U1 pad2;
V2_S2 p2; V2_S2 p2;
}; };
/* ---------- Poly_G4 (Gouraud Quad; 9 words) ---------- */ /* ---------- Poly_G4 (Gouraud Quad; 9 words) ---------- */
typedef Struct_(Poly_G4) { typedef Struct_(Poly_G4) {
U4 tag; RGB8 c0; B1 code; U4 tag; RGB8 c0; U1 code;
V2_S2 p0; RGB8 c1; B1 pad1; V2_S2 p0; RGB8 c1; U1 pad1;
V2_S2 p1; RGB8 c2; B1 pad2; V2_S2 p1; RGB8 c2; U1 pad2;
V2_S2 p2; RGB8 c3; B1 pad3; V2_S2 p2; RGB8 c3; U1 pad3;
V2_S2 p3; V2_S2 p3;
}; };
@@ -456,7 +456,7 @@ typedef Struct_(Poly_G4) {
typedef Struct_(Poly_FT3) { typedef Struct_(Poly_FT3) {
U4 tag; U4 tag;
RGB8 color; RGB8 color;
B1 code; U1 code;
U4 tpage; U4 tpage;
U4 clut; U4 clut;
V2_S2 p0; U1 u0; U1 v0; V2_S2 p0; U1 u0; U1 v0;
@@ -468,7 +468,7 @@ typedef Struct_(Poly_FT3) {
typedef Struct_(Poly_FT4) { typedef Struct_(Poly_FT4) {
U4 tag; U4 tag;
RGB8 color; RGB8 color;
B1 code; U1 code;
U4 tpage; U4 tpage;
U4 clut; U4 clut;
V2_S2 p0; U1 u0; U1 v0; V2_S2 p0; U1 u0; U1 v0;
@@ -479,9 +479,9 @@ typedef Struct_(Poly_FT4) {
/* ---------- Poly_GT3 (Gouraud Textured Triangle) ---------- */ /* ---------- Poly_GT3 (Gouraud Textured Triangle) ---------- */
typedef Struct_(Poly_GT3) { typedef Struct_(Poly_GT3) {
U4 tag; RGB8 c0; B1 code; U4 tag; RGB8 c0; U1 code;
V2_S2 p0; RGB8 c1; B1 pad1; V2_S2 p0; RGB8 c1; U1 pad1;
V2_S2 p1; RGB8 c2; B1 pad2; V2_S2 p1; RGB8 c2; U1 pad2;
V2_S2 p2; V2_S2 p2;
U4 tpage; U4 tpage;
U4 clut; U4 clut;
@@ -492,10 +492,10 @@ typedef Struct_(Poly_GT3) {
/* ---------- Poly_GT4 (Gouraud Textured Quad) ---------- */ /* ---------- Poly_GT4 (Gouraud Textured Quad) ---------- */
typedef Struct_(Poly_GT4) { typedef Struct_(Poly_GT4) {
U4 tag; RGB8 c0; B1 code; U4 tag; RGB8 c0; U1 code;
V2_S2 p0; RGB8 c1; B1 pad1; V2_S2 p0; RGB8 c1; U1 pad1;
V2_S2 p1; RGB8 c2; B1 pad2; V2_S2 p1; RGB8 c2; U1 pad2;
V2_S2 p2; RGB8 c3; B1 pad3; V2_S2 p2; RGB8 c3; U1 pad3;
V2_S2 p3; V2_S2 p3;
U4 tpage; U4 tpage;
U4 clut; U4 clut;
+14 -14
View File
@@ -23,10 +23,10 @@ FI_ void mem_bump(U4 cap, U4*R_ used, U4 amount) {
used[0] += amount; used[0] += amount;
} }
FI_ U4 mem_copy (U4 dest, U4 src, U4 len) { return (U4)(__builtin_memcpy ((void*)dest, (void const*)src, len)); } FI_ U4 mem_copy (U1_R dest, U1_R src, U4 len) { return (U4)(__builtin_memcpy ((void*)dest, (void const*)src, len)); }
FI_ U4 mem_copy_overlapping(U4 dest, U4 src, U4 len) { return (U4)(__builtin_memmove((void*)dest, (void const*)src, len)); } FI_ U4 mem_copy_overlapping(U1* dest, U1* src, U4 len) { return (U4)(__builtin_memmove((void*)dest, (void const*)src, len)); }
FI_ U4 mem_fill (U4 dest, U4 value, U4 len) { return (U4)(__builtin_memset ((void*)dest, (int) value, len)); } FI_ U4 mem_fill (U1_R dest, U4 value, U4 len) { return (U4)(__builtin_memset ((void*)dest, (int) value, len)); }
FI_ B4 mem_zero (U4 dest, U4 len) { if(dest == 0){return false;} mem_fill(dest, 0, len); return true; } FI_ B4 mem_zero (U1_R dest, U4 len) { if(dest == 0){return false;} mem_fill(dest, 0, len); return true; }
#pragma region DAG #pragma region DAG
@@ -58,31 +58,30 @@ typedef Struct_(Str8) { UTF8* ptr; U4 len; };
typedef Struct_(Slice_Str8) { Str8* ptr; U4 len; }; typedef Struct_(Slice_Str8) { Str8* ptr; U4 len; };
#define slit(string_literal) (Str8){ (UTF8*) string_literal, S_(string_literal) - 1 } #define slit(string_literal) (Str8){ (UTF8*) string_literal, S_(string_literal) - 1 }
typedef Struct_(Slice) { B1* ptr; U4 len; }; typedef Struct_(Slice) { U1* ptr; U4 len; };
FI_ Slice slice_ut_(U4 ptr, U4 len) { return (Slice){(B1*)ptr, len}; } FI_ Slice slice_ut_(U1* ptr, U4 len) { return (Slice){ptr, len}; }
#define Slice_(type) Struct_(tmpl(Slice,type)) { type* ptr; U4 len; } #define Slice_(type) Struct_(tmpl(Slice,type)) { type* ptr; U4 len; }
typedef Slice_(B1);
#define slice_assert(s) do { assert((s).ptr != 0); assert((s).len > 0); } while(0) #define slice_assert(s) do { assert((s).ptr != 0); assert((s).len > 0); } while(0)
#define slice_end(slice) ((slice).ptr + S_slice(slice) / S_(B1)) #define slice_end(slice) ((slice).ptr + S_slice(slice))
#define S_slice(s) ((s).len * S_((s).ptr[0])) #define S_slice(s) ((s).len * S_((s).ptr[0]))
#define slice_ut(ptr,len) slice_ut_(u4_(ptr), u4_(len)) #define slice_ut(ptr,len) slice_ut_(C_(U1*,ptr), u4_(len))
#define slice_ut_arr(a) slice_ut_(u4_(a), S_(a)) #define slice_ut_arr(a) slice_ut_(C_(U1*,a), S_(a))
#define slice_to_ut(s) slice_ut_(u4_((s).ptr), S_slice(s)) #define slice_to_ut(s) slice_ut_(C_(U1*,(s).ptr), S_slice(s))
#define slice_iter(container, iter) (T_((container).ptr) iter = (container).ptr; iter != slice_end(container); ++ iter) #define slice_iter(container, iter) (T_((container).ptr) iter = (container).ptr; iter != slice_end(container); ++ iter)
#define slice_arg_from_array(type, ...) & (tmpl(Slice,type)) { .ptr = Array_decl(type,__VA_ARGS__), .len = Array_len( Array_decl(type,__VA_ARGS__)) } #define slice_arg_from_array(type, ...) & (tmpl(Slice,type)) { .ptr = Array_decl(type,__VA_ARGS__), .len = Array_len( Array_decl(type,__VA_ARGS__)) }
#define slice_from_array(type, array) (tmpl(Slice,type)) { .ptr = array, .len = Array_len(array) } #define slice_from_array(type, array) (tmpl(Slice,type)) { .ptr = array, .len = Array_len(array) }
FI_ void slice_zero_(Slice s) { slice_assert(s); mem_zero(u4_(s.ptr), s.len); } FI_ void slice_zero_(Slice s) { slice_assert(s); mem_zero(s.ptr, s.len); }
#define slice_zero(s) slice_zero_(slice_to_ut(s)) #define slice_zero(s) slice_zero_(slice_to_ut(s))
FI_ void slice_copy_(Slice dest, Slice src) { FI_ void slice_copy_(Slice dest, Slice src) {
assert(S_slice(dest) >= S_slice(src)); assert(S_slice(dest) >= S_slice(src));
slice_assert(dest); slice_assert(dest);
slice_assert(src); slice_assert(src);
mem_copy(u4_(dest.ptr), u4_(src.ptr), S_slice(src)); mem_copy(dest.ptr, src.ptr, S_slice(src));
} }
#define slice_copy(dest, src) do { \ #define slice_copy(dest, src) do { \
static_assert(T_same(dest, src)); \ static_assert(T_same(dest, src)); \
@@ -95,6 +94,7 @@ FI_ Slice slice_bump(U4_R used, U4 start, U4 len, U4 amount) {
return slice_ut(ptr, amount); return slice_ut(ptr, amount);
} }
typedef Slice_(B1);
typedef Slice_(U1); typedef Slice_(U1);
typedef Slice_(U4); typedef Slice_(U4);
@@ -117,7 +117,7 @@ I_ Slice farena_push(FArena_R arena, U4 amount, Opt_farena o) {
U4 to_commit = align_pow2(desired, o.alignment ? o.alignment : MEM_ALIGNMENT_DEFAULT); U4 to_commit = align_pow2(desired, o.alignment ? o.alignment : MEM_ALIGNMENT_DEFAULT);
U4 ptr = arena->start + arena->used; U4 ptr = arena->start + arena->used;
mem_bump(arena->capacity, & arena->used, to_commit); mem_bump(arena->capacity, & arena->used, to_commit);
return (Slice){ (B1*)ptr, to_commit }; return (Slice){ (U1*)ptr, to_commit };
} }
FI_ void farena_reset (FArena_R arena) { arena->used = 0; } FI_ void farena_reset (FArena_R arena) { arena->used = 0; }
FI_ void farena_rewind(FArena_R arena, U4 save_point) { FI_ void farena_rewind(FArena_R arena, U4 save_point) {
+18 -31
View File
@@ -121,7 +121,7 @@ typedef U2 Reg; // Register parameter used with atom or atom component procedure
typedef U4 const MipsCode; // Underlying type to mips asm words. typedef U4 const MipsCode; // Underlying type to mips asm words.
typedef Slice_(MipsCode); typedef Slice_(MipsCode);
typedef U4 const MipsAtom; // Underlying type to a mips atom defnition typedef U4 const MipsAtom; // Underlying type to a mips atom definition
typedef Slice_(MipsAtom); typedef Slice_(MipsAtom);
// Sometimes a user will define a bundle of atoms that represent a procedure of work as: // Sometimes a user will define a bundle of atoms that represent a procedure of work as:
@@ -176,7 +176,7 @@ typedef Slice_(MipsAtom);
The constant is in `.rodata` so the linker may eliminate it. */ The constant is in `.rodata` so the linker may eliminate it. */
#define ATOM_FILE_DEBUGGER_LINE_MARKER(file_name) internal U4 const tmpl(atom_file_debugger_line_marker,file_name) = 0 #define ATOM_FILE_DEBUGGER_LINE_MARKER(file_name) internal U4 const tmpl(atom_file_debugger_line_marker,file_name) = 0
typedef Slice_MipsAtom Tape; typedef Struct_(Tape) { union { MipsAtom* ptr; U4* inlaid_data; }; U4 len; };
typedef Struct_(TapeHostFrame) { typedef Struct_(TapeHostFrame) {
U4 s0; U4 s0;
@@ -249,12 +249,8 @@ FI_ void tb_emit(TapeBuilder* tb, MipsAtom* atom) { u4_r(tb->ptr)[tb->used] = u4
FI_ void tb_data(TapeBuilder* tb, U4 data) { u4_r(tb->ptr)[tb->used] = u4_(data); ++ tb->used; } FI_ void tb_data(TapeBuilder* tb, U4 data) { u4_r(tb->ptr)[tb->used] = u4_(data); ++ tb->used; }
#define tb_emit_(atom) tb_emit(& tb, atom) #define tb_emit_(atom) tb_emit(& tb, atom)
FI_ void tb_bind(TapeBuilder* tb, Slice data) { mem_copy(tb->ptr + tb->used * S_(MipsCode), u4_(data.ptr), data.len); tb->used += data.len / S_(MipsCode); } FI_ void tb_bind(TapeBuilder* tb, Slice data) { mem_copy(b1_r(tb->ptr + tb->used * S_(MipsCode)), data.ptr, data.len); tb->used += data.len / S_(MipsCode); }
#define tb_bind_(tb,type,...) tb_bind(tb, (Slice){ (B1*)(& (type){__VA_ARGS__}), S_(type) }); static_assert(S_(type) % S_(MipsCode) == 0) #define tb_bind_(tb,type,...) tb_bind(tb, (Slice){ (U1*)(& (type){__VA_ARGS__}), S_(type) }); static_assert(S_(type) % S_(MipsCode) == 0)
// NOTE(Ed): Wip still ideating convention. Possibly will never use a composite.
#define tb_emit_wbind_(tb,atom,...) tb_emit(tb,atom); tb_bind_(tb,tmpl(Binds,atom),__VA_ARGS__)
#define tb_emit_wbind2_(tb,atom,type,...) tb_emit(tb,atom); tb_bind_(tb,type,__VA_ARGS__)
FI_ Tape tb_end (TapeBuilder* tb) { tb_emit(tb,tape_exit); return (Tape){ C_(U4*,tb->ptr), tb->used }; } FI_ Tape tb_end (TapeBuilder* tb) { tb_emit(tb,tape_exit); return (Tape){ C_(U4*,tb->ptr), tb->used }; }
FI_ Tape tb_slice(TapeBuilder tb) { return (Tape){ C_(U4*,tb.ptr), tb.used }; } FI_ Tape tb_slice(TapeBuilder tb) { return (Tape){ C_(U4*,tb.ptr), tb.used }; }
@@ -262,6 +258,12 @@ FI_ Tape tb_slice(TapeBuilder tb) { return (Tape){ C_(U4
FI_ void tb_scope_run_end(TapeBuilder* tb) { tb_emit(tb,tape_exit); tape_run(tb_slice(tb[0])); } FI_ void tb_scope_run_end(TapeBuilder* tb) { tb_emit(tb,tape_exit); tape_run(tb_slice(tb[0])); }
#define tb_scope_run(tb) for(U4 tbs_once=0;tbs_once==0;++tbs_once,tb_scope_run_end(tb)) #define tb_scope_run(tb) for(U4 tbs_once=0;tbs_once==0;++tbs_once,tb_scope_run_end(tb))
// NOTE(Ed): Wip still ideating convention. Possibly will never use a composite.
#define tb_emit_wbind_(tb,atom,...) tb_emit(tb,atom); tb_bind_(tb,tmpl(Binds,atom),__VA_ARGS__)
#define tb_emit_wbind2_(tb,atom,type,...) tb_emit(tb,atom); tb_bind_(tb,type,__VA_ARGS__)
#pragma endregion Tape Drive #pragma endregion Tape Drive
#pragma region Macro Mips Atom Components #pragma region Macro Mips Atom Components
@@ -299,7 +301,7 @@ typedef Relative_(FArena) Struct_(AtomBuilder) { U4 start; U4 capacity; U4 used;
FI_ void atombuilder_push(AtomBuilder_R ab, Slice_MipsCode code) { FI_ void atombuilder_push(AtomBuilder_R ab, Slice_MipsCode code) {
assert(ab->capacity - ab->used - code.len); assert(ab->capacity - ab->used - code.len);
U4 dest = ab->start + ab->used * S_(MipsCode); U4 size = S_slice(code); U4 dest = ab->start + ab->used * S_(MipsCode); U4 size = S_slice(code);
mem_copy(dest, u4_(code.ptr), size); ab->used += size; mem_copy(b1_r(dest), b1_r(code.ptr), size); ab->used += size;
} }
#define atombuilder_push_mac(ab, mac) atombuilder_push(ab, slice_arg_from_array(Slice_MipsCode, mac)) #define atombuilder_push_mac(ab, mac) atombuilder_push(ab, slice_arg_from_array(Slice_MipsCode, mac))
@@ -323,7 +325,7 @@ FI_ AtomArena atomarena_make(Slice mem) { AtomArena a; atomarena_init(& a, mem);
FI_ MipsAtom* atomarena_push(AtomArena_R aa, Slice_MipsCode code) { FI_ MipsAtom* atomarena_push(AtomArena_R aa, Slice_MipsCode code) {
assert(aa->capacity - aa->used - code.len); assert(aa->capacity - aa->used - code.len);
U4 dest = atomarena_unused_start(aa[0]); U4 size = S_slice(code); U4 dest = atomarena_unused_start(aa[0]); U4 size = S_slice(code);
mem_copy(dest, u4_(code.ptr), size); aa->used += size; mem_copy(b1_r(dest), b1_r(code.ptr), size); aa->used += size;
return C_(MipsAtom*, dest); return C_(MipsAtom*, dest);
} }
FI_ void atomarena_reset(AtomArena_R aa) { aa->used = 0; } FI_ void atomarena_reset(AtomArena_R aa) { aa->used = 0; }
@@ -354,24 +356,16 @@ internal Reg const regfile_alloc_order[] = {
R_T8, R_T9, R_T8, R_T9,
}; };
typedef Struct_(RegFile) { typedef Struct_(RegFile) { A2_U2 GPR; };
A2_U2 GPR;
A2_U2 GTE;
};
#define regfile(pin_mask) {.GPR={u4_lo(pin_mask), u4_hi(pin_mask)} } #define regfile(pin_mask) {.GPR={u4_lo(pin_mask), u4_hi(pin_mask)} }
FI_ void regfile_init(RegFile_R rf) { FI_ void regfile_init(RegFile_R rf) {
/* pack the 32-bit ABI mask into the two U2s */ /* pack the 32-bit ABI mask into the two U2s */
rf->GPR[0] = u4_lo(regfile_abi_mask); rf->GPR[0] = u4_lo(regfile_abi_mask);
rf->GPR[1] = u4_hi(regfile_abi_mask); rf->GPR[1] = u4_hi(regfile_abi_mask);
rf->GTE[0] = rf->GTE[1] = 0;
} }
FI_ RegFile regfile_make(void) { RegFile rf; regfile_init(& rf); return rf; } FI_ RegFile regfile_make(void) { RegFile rf; regfile_init(& rf); return rf; }
typedef Struct_(RegFile_RInfo) { typedef Struct_(RegFile_RInfo) { U2_R section; U2 mask; B2 occupied; };
U2_R section;
U2 mask;
B2 occupied;
};
FI_ RegFile_RInfo regfile_rinfo(A2_U2 file, Reg r_id) { FI_ RegFile_RInfo regfile_rinfo(A2_U2 file, Reg r_id) {
U2 s_id = r_id >> 4; U2 s_id = r_id >> 4;
U2_R section = & file[s_id]; U2_R section = & file[s_id];
@@ -381,15 +375,11 @@ FI_ RegFile_RInfo regfile_rinfo(A2_U2 file, Reg r_id) {
} }
FI_ Reg regfile__alloc_helper(A2_U2 file, Reg r_id) { FI_ Reg regfile__alloc_helper(A2_U2 file, Reg r_id) {
Reg result = 0; RegFile_RInfo info = regfile_rinfo(file, r_id); Reg result = 0; RegFile_RInfo info = regfile_rinfo(file, r_id);
if (info.occupied == false) { if (info.occupied == false) { info.section[0] |= info.mask; result = r_id; }
info.section[0] |= info.mask;
result = r_id;
}
return result; return result;
} }
I_ Reg regfile_alloc(RegFile_R rf) { I_ Reg regfile_alloc(RegFile_R rf) {
Reg allocated = 0; Reg allocated = 0; for index_iter(U4, r_id, R_V0, <, R_T9) {
for index_iter(U4, r_id, R_V0, <, R_T9) {
allocated = regfile__alloc_helper(rf->GPR, r_id); allocated = regfile__alloc_helper(rf->GPR, r_id);
Jmp_nZero_(allocated,resolved); Jmp_nZero_(allocated,resolved);
} }
@@ -403,8 +393,7 @@ FI_ Reg regfile_pin(RegFile_R rf, Reg r_id) {
return r_id; return r_id;
} }
FI_ void regfile_pin_mask(RegFile_R rf, U4 mask) { FI_ void regfile_pin_mask(RegFile_R rf, U4 mask) {
B4 occupied = u4_r(rf->GPR)[0] & mask; B4 occupied = u4_r(rf->GPR)[0] & mask; assert(occupied == false);
assert(occupied == false);
u4_r(rf->GPR)[0] |= mask; u4_r(rf->GPR)[0] |= mask;
} }
FI_ void regfile_free_mask(RegFile_R rf, U4 mask) { FI_ void regfile_free_mask(RegFile_R rf, U4 mask) {
@@ -412,8 +401,7 @@ FI_ void regfile_free_mask(RegFile_R rf, U4 mask) {
u4_r(rf->GPR)[0] &= ~mask; u4_r(rf->GPR)[0] &= ~mask;
} }
FI_ void regfile_free_reg(RegFile_R rf, Reg r_id) { FI_ void regfile_free_reg(RegFile_R rf, Reg r_id) {
/* never free the ABI set */ if (regfile_abi_mask & (1u << r_id)) return; // never free the ABI set
if (regfile_abi_mask & (1u << r_id)) return;
RegFile_RInfo info = regfile_rinfo(rf->GPR, r_id); RegFile_RInfo info = regfile_rinfo(rf->GPR, r_id);
info.section[0] &= ~info.mask; info.section[0] &= ~info.mask;
} }
@@ -447,7 +435,6 @@ FI_ void regfile_reset_to_mask(RegFile_R rf, U4 mask) {
add_si(r.t1.view_3, r.usual_modifiable, 10), add_si(r.t1.view_3, r.usual_modifiable, 10),
mac_yield(), mac_yield(),
}) })
#pragma endregion Mips Atom Procs #pragma endregion Mips Atom Procs
#pragma region Baked Mips Atoms #pragma region Baked Mips Atoms
+26 -30
View File
@@ -237,8 +237,8 @@ enum {
}; };
//screen_env_init. Mirrors the libpsyx's SetDefDispEnv + SetDefDrawEnv + the manual enable_auto_clear / initial_bg_color writes. //screen_env_init. Mirrors the libpsyx's SetDefDispEnv + SetDefDrawEnv + the manual enable_auto_clear / initial_bg_color writes.
internal MipsAtom_(screen_env_init) atom_info(atom_phase(screen_init) internal MipsAtom_(screen_env_init) atom_info(atom_phase(screen_init)
, atom_reads(R_T0, R_ScreenX, R_ScreenY, R_ScreenBuf) , atom_reads(R_ScreenBuf)
, atom_writes(R_T0, R_ScreenX, R_ScreenY) , atom_writes(R_ScreenBuf)
) { ) {
/* display[0] = (0, 0, 320, 240); rest of struct zeroed. */ /* display[0] = (0, 0, 320, 240); rest of struct zeroed. */
add_ui(R_ScreenX, R_0, ScreenRes_X), add_ui(R_ScreenY, R_0, ScreenRes_Y), add_ui(R_ScreenX, R_0, ScreenRes_X), add_ui(R_ScreenY, R_0, ScreenRes_Y),
@@ -441,7 +441,7 @@ typedef Struct_(Binds_PadInputCam) {
Camera* cam; Camera* cam;
}; };
internal MipsAtom_(pad_input_cam) atom_info(atom_bind(Binds_PadInputCam) internal MipsAtom_(pad_input_cam) atom_info(atom_bind(Binds_PadInputCam)
, atom_reads( R_Cam, R_CamPadState, R_TapePtr) , atom_reads( R_Cam, R_CamPadState)
, atom_writes(R_Cam) , atom_writes(R_Cam)
) { ) {
/* Bind pop: state → R_CamPadState (R_T5), cam → R_Cam (R_T4), advance R_TapePtr by 8. */ /* Bind pop: state → R_CamPadState (R_T5), cam → R_Cam (R_T4), advance R_TapePtr by 8. */
@@ -499,20 +499,17 @@ enum {
#define R_OtBase_Code R_T6_Code #define R_OtBase_Code R_T6_Code
}; };
typedef Struct_(Binds_CubeTri) { typedef Struct_(Binds_CubeTri) {
U4 PrimCursor; U1* prim_cursor;
V4_S2* FaceCursor; V4_S2* face_cursor;
V3_S2* VertBase; V3_S2* vert_base;
U4* OtBase; U4* ot_base;
}; };
internal MipsAtom_(rbind_cube_g4_face) atom_info(atom_bind(Binds_CubeTri), atom_phase(cube_g4) internal MipsAtom_(rbind_cube_g4_face) atom_info(atom_bind(Binds_CubeTri), atom_phase(cube_g4)){
, atom_reads(R_TapePtr)
, atom_writes(R_PrimCursor, R_FaceCursor, R_VertBase, R_OtBase, R_TapePtr)
){
/* Pop 4 arguments from the tape directly into the workspace registers */ /* Pop 4 arguments from the tape directly into the workspace registers */
load_word(R_PrimCursor, R_TapePtr, O_(Binds_CubeTri,PrimCursor)), load_word(R_PrimCursor, R_TapePtr, O_(Binds_CubeTri,prim_cursor)),
load_word(R_FaceCursor, R_TapePtr, O_(Binds_CubeTri,FaceCursor)), load_word(R_FaceCursor, R_TapePtr, O_(Binds_CubeTri,face_cursor)),
load_word(R_VertBase, R_TapePtr, O_(Binds_CubeTri,VertBase)), load_word(R_VertBase, R_TapePtr, O_(Binds_CubeTri,vert_base)),
load_word(R_OtBase, R_TapePtr, O_(Binds_CubeTri,OtBase)), load_word(R_OtBase, R_TapePtr, O_(Binds_CubeTri,ot_base)),
LdSlot_ add_ui_self( R_TapePtr, S_(Binds_CubeTri)), LdSlot_ add_ui_self( R_TapePtr, S_(Binds_CubeTri)),
mac_yield() mac_yield()
}; };
@@ -530,11 +527,11 @@ MipsAtom_(cube_g4_face) atom_info(atom_phase(cube_g4),
LdSlot_ mac_gte_load_tri_verts(R_VertBase, R_T0, R_T1, R_T2), LdSlot_ mac_gte_load_tri_verts(R_VertBase, R_T0, R_T1, R_T2),
GteDelay_ load_half_u(R_T3, R_FaceCursor, 3 * S_(S2)), LdSlot_ GteDelay_ load_half_u(R_T3, R_FaceCursor, 3 * S_(S2)), LdSlot_
GteDelay_ load_word(R_AtomJmp, R_TapePtr, 0), LdSlot_ //ac_yield: word 2, GteDelay_ load_word(R_AtomJmp, R_TapePtr, 0), LdSlot_ //ac_yield: word 1,
gte_cmdw_rotate_translate_perspective_triple, gte_cmdw_rotate_translate_perspective_triple,
gte_cmdw_nclip, gte_cmdw_nclip,
gte_mv_from_data_r(R_T0, C2_MAC0), GteDelay_ add_ui_self(R_TapePtr, S_(MipsCode)), // ac_yield: word 1 gte_mv_from_data_r(R_T0, C2_MAC0), GteDelay_ add_ui_self(R_TapePtr, S_(MipsCode)), // ac_yield: word 2
branch_le_zero(R_T0, atom_offset(cull, cube_g4_face_exit)), branch_le_zero(R_T0, atom_offset(cull, cube_g4_face_exit)),
/* BD-slot: Write the prim tag (R_0=0; overwrites the legacy tag word in the prim_buffer). /* BD-slot: Write the prim tag (R_0=0; overwrites the legacy tag word in the prim_buffer).
* If branch IS taken (face culled), the body is skipped and this 0-tag is stranded — * If branch IS taken (face culled), the body is skipped and this 0-tag is stranded —
@@ -564,16 +561,16 @@ MipsAtom_(cube_g4_face) atom_info(atom_phase(cube_g4),
// end: branch(cull) // end: branch(cull)
atom_label(cube_g4_face_exit) atom_label(cube_g4_face_exit)
add_ui_self(R_PrimCursor, S_(Poly_G4)), /* 9 words = Poly_G4 */ add_ui_self(R_PrimCursor, S_(Poly_G4)), // 9 words = Poly_G4
add_ui_self(R_FaceCursor, S_(S2) * 4), /* 4 × S2 = 8 bytes */ add_ui_self(R_FaceCursor, S_(S2) * 4), // 4 × S2 = 8 bytes
jump_reg(R_AtomJmp), BdSlot_ nop // ac_yield: word 3-4 jump_reg(R_AtomJmp), BdSlot_ nop // ac_yield: word 3-4
}; };
typedef Struct_(Binds_FloorTri) { typedef Struct_(Binds_FloorTri) {
U4 PrimCursor; U1* prim_cursor;
V3_S2* FaceCursor; V3_S2* face_cursor;
V3_S2* VertBase; V3_S2* vert_base;
U4* OtBase; U4* ot_base;
}; };
internal internal
MipsAtom_(rbind_floor_f3_face) atom_info(atom_bind(Binds_FloorTri), atom_phase(floor_f3) MipsAtom_(rbind_floor_f3_face) atom_info(atom_bind(Binds_FloorTri), atom_phase(floor_f3)
@@ -581,10 +578,10 @@ MipsAtom_(rbind_floor_f3_face) atom_info(atom_bind(Binds_FloorTri), atom_phase(f
, atom_writes(R_PrimCursor, R_FaceCursor, R_VertBase, R_OtBase, R_TapePtr) , atom_writes(R_PrimCursor, R_FaceCursor, R_VertBase, R_OtBase, R_TapePtr)
){ ){
/* Pop 4 arguments from the tape directly into the workspace registers */ /* Pop 4 arguments from the tape directly into the workspace registers */
load_word(R_PrimCursor, R_TapePtr, O_(Binds_FloorTri,PrimCursor)), load_word(R_PrimCursor, R_TapePtr, O_(Binds_FloorTri,prim_cursor)),
load_word(R_FaceCursor, R_TapePtr, O_(Binds_FloorTri,FaceCursor)), load_word(R_FaceCursor, R_TapePtr, O_(Binds_FloorTri,face_cursor)),
load_word(R_VertBase, R_TapePtr, O_(Binds_FloorTri,VertBase)), load_word(R_VertBase, R_TapePtr, O_(Binds_FloorTri,vert_base)),
load_word(R_OtBase, R_TapePtr, O_(Binds_FloorTri,OtBase)), load_word(R_OtBase, R_TapePtr, O_(Binds_FloorTri,ot_base)),
LdSlot_ add_ui_self( R_TapePtr, S_(Binds_FloorTri)), LdSlot_ add_ui_self( R_TapePtr, S_(Binds_FloorTri)),
mac_yield() mac_yield()
}; };
@@ -626,10 +623,9 @@ atom_label(floor_f3_face_exit)
jump_reg(R_AtomJmp), BdSlot_ nop // ac_yield: word 3-4 jump_reg(R_AtomJmp), BdSlot_ nop // ac_yield: word 3-4
}; };
typedef Struct_(Binds_SyncPrimitiveArena) { U4 used; U4 cursor; }; typedef Struct_(Binds_SyncPrimitiveArena) { U4* used; U1* cursor; };
internal MipsAtom_(sync_primitive_arena) atom_info(atom_bind(Binds_SyncPrimitiveArena) internal MipsAtom_(sync_primitive_arena) atom_info(atom_bind(Binds_SyncPrimitiveArena)
, atom_reads( R_TapePtr, R_PrimCursor) , atom_reads(R_PrimCursor), atom_writes(R_AT)
, atom_writes(R_TapePtr)
){ ){
load_word(R_AT, R_TapePtr, O_(Binds_SyncPrimitiveArena,used)), load_word(R_AT, R_TapePtr, O_(Binds_SyncPrimitiveArena,used)),
load_word(R_T0, R_TapePtr, O_(Binds_SyncPrimitiveArena,cursor)), LdSlot_ load_word(R_T0, R_TapePtr, O_(Binds_SyncPrimitiveArena,cursor)), LdSlot_
+45 -52
View File
@@ -93,11 +93,11 @@ extern SMemory smem;
#define pad0_btn_(btn) btn & smem.pad[0].buttons #define pad0_btn_(btn) btn & smem.pad[0].buttons
#define pad1_btn_(btn) btn & smem.pad[1].buttons #define pad1_btn_(btn) btn & smem.pad[1].buttons
I_ B1* prim__alloc(U4 type_width, Str8 type_name) { I_ U1* prim__alloc(U4 type_width, Str8 type_name) {
gknown PrimitiveArena* pa = & smem.primitives; gknown PrimitiveArena* pa = & smem.primitives;
gknown B1* buf = (B1*) r_(smem.primitives.buf)[smem.active_buf_id]; gknown U1* buf = (U1*) r_(smem.primitives.buf)[smem.active_buf_id];
assert(pa->used + type_width < PrimitiveBuff_Len); assert(pa->used + type_width < PrimitiveBuff_Len);
B1* next = buf + pa->used; U1* next = buf + pa->used;
pa->used += type_width; pa->used += type_width;
return next; return next;
} }
@@ -241,26 +241,15 @@ FI_ void camera_look_at(TapeBuilder_R tb, Camera* c, P3_S4* target, V3_S4* up_in
void update(PrimitiveArena* pa, U4* ordering_buf) void update(PrimitiveArena* pa, U4* ordering_buf)
{ {
TapeBuilder tb = tb_make(slice_ut_arr(smem.MemTape)); TapeBuilder tb = tb_make(slice_ut_arr(smem.MemTape));
/*Pad Input*/ {
// Pad Input
{
tb.used = 0; tb_scope_run(& tb) { tb.used = 0; tb_scope_run(& tb) {
// Grab latest state from bios. // Grab latest state from bios.
tb_emit_(pad_bios_snapshot); tb_emit_(pad_bios_snapshot);
tb_data(& tb, u4_(& smem.pad_raw[0])); tb_data(& tb, u4_(& smem.pad_raw[0]));
tb_data(& tb, u4_(& smem.pad[0])); tb_data(& tb, u4_(& smem.pad[0]));
// tb_emit_(pad_bios_snapshot);
// tb_data_(raw, & smem.pad_raw[1]);
// tb_data_(state, & smem.pad[1]);
tb_emit_(pad_input_cam); tb_emit_(pad_input_cam);
tb_data(& tb, u4_(& smem.pad[0])); tb_data(& tb, u4_(& smem.pad[0]));
tb_data(& tb, u4_(& smem.cam)); tb_data(& tb, u4_(& smem.cam));
// tb_emit_(pad_input_cube_rotation);
// tb_data_(state, & smem.pad[0]);
// tb_data_(cube_rot, & smem.cube.rot);
// tb_data_(floor_rot, & smem.floor.rot);
} }
} }
@@ -298,33 +287,28 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
mt3s2s4_rotation (& smem.cube.rot, & smem.tform_world); mt3s2s4_rotation (& smem.cube.rot, & smem.tform_world);
mt3s2s4_translation(& smem.tform_world, & smem.cube.pos); mt3s2s4_translation(& smem.tform_world, & smem.cube.pos);
mt3s2s4_scale (& smem.tform_world, & smem.cube.scale); mt3s2s4_scale (& smem.tform_world, & smem.cube.scale);
// Combine world and look_at matrix. // Combine world and look_at matrix.
gte_comp_coord_m3s2(& smem.cam.look_at, & smem.tform_world, & smem.tform_view); gte_comp_coord_m3s2(& smem.cam.look_at, & smem.tform_world, & smem.tform_view);
gte_matrix_set_rotation (& smem.tform_view); gte_matrix_set_rotation (& smem.tform_view);
gte_matrix_set_translation(& smem.tform_view); gte_matrix_set_translation(& smem.tform_view);
U4 prim_base = u4_(pa->buf[smem.active_buf_id]); U1* prim_base = u1_r(pa->buf[smem.active_buf_id]);
U4 prim_cursor = prim_base + pa->used; U1* prim_cursor = prim_base + pa->used;
tb.used = 0; tb_scope_run(& tb) {
tb.used = 0; tb_scope(& tb) { tb_emit(& tb, rbind_cube_g4_face); tb_bind_(& tb, Binds_CubeTri,
tb_emit(& tb, rbind_cube_g4_face); .prim_cursor = prim_cursor,
tb_data(& tb, prim_cursor); .face_cursor = smem.cube.faces,
tb_data(& tb, u4_(smem.cube.faces)); .vert_base = smem.cube.verts,
tb_data(& tb, u4_(smem.cube.verts)); .ot_base = ordering_buf,
tb_data(& tb, u4_(ordering_buf)); );
for (U4 i = 0; i < Cube_num_faces; i++) { for (U4 i = 0; i < Cube_num_faces; i++) {
// Two triangles per quad face: (x,y,z) and (x,z,w) tb_emit(& tb, cube_g4_face); // Two triangles per quad face: (x,y,z) and (x,z,w)
tb_emit(& tb, cube_g4_face);
} }
tb_emit(& tb, sync_primitive_arena); tb_bind_(& tb, Binds_SyncPrimitiveArena,
tb_emit(& tb, sync_primitive_arena); .used = & pa->used,
tb_data(& tb, u4_(& pa->used)); .cursor = prim_base,
tb_data(& tb, prim_base); );
} }
tape_run(tb_slice(tb));// Fire off the tape (bigger-clobber variant).
// smem.cube.rot.y += 30; // smem.cube.rot.y += 30;
} }
// Draw floor // Draw floor
@@ -340,33 +324,29 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
gte_matrix_set_rotation (& smem.tform_view); gte_matrix_set_rotation (& smem.tform_view);
gte_matrix_set_translation(& smem.tform_view); gte_matrix_set_translation(& smem.tform_view);
U4 prim_base = u4_(pa->buf[smem.active_buf_id]); U1_R prim_base = u1_r(pa->buf[smem.active_buf_id]);
U4 prim_cursor = prim_base + pa->used; U1_R prim_cursor = prim_base + pa->used;
// TODO(Ed): We should do a bounds check beforehand to confirm pa can hold all tris? // TODO(Ed): We should do a bounds check beforehand to confirm pa can hold all tris?
// The tape atoms in-flight should not need to care. // The tape atoms in-flight should not need to care.
// Prepare the tape. (Push protocol to tape) // Prepare the tape. (Push protocol to tape)
tb.used = 0; tb_scope(& tb) { tb.used = 0; tb_scope_run(& tb) {
// tb_emit(& tb, set_gte_mt3s2s4); tb_emit(& tb, rbind_floor_f3_face); tb_bind_(& tb, Binds_FloorTri,
// tb_data(& tb, u4_(& smem.tform_view)); .prim_cursor = prim_cursor,
.face_cursor = smem.floor.faces,
tb_emit(& tb, rbind_floor_f3_face); .vert_base = smem.floor.verts,
// TODO(Ed): Just use a single context struct ref? .ot_base = ordering_buf,
tb_data(& tb, prim_cursor); );
tb_data(& tb, u4_(smem.floor.faces));
tb_data(& tb, u4_(smem.floor.verts));
tb_data(& tb, u4_(ordering_buf));
for (U4 i = 0; i < Floor_num_faces; i++) { for (U4 i = 0; i < Floor_num_faces; i++) {
tb_emit(& tb, floor_f3_face); tb_emit(& tb, floor_f3_face);
} }
// After floor_f3_face iterations complete, the primitive arena's used counter needs updating. // After floor_f3_face iterations complete, the primitive arena's used counter needs updating.
tb_emit(& tb, sync_primitive_arena); tb_emit(& tb, sync_primitive_arena); tb_bind_(& tb, Binds_SyncPrimitiveArena,
tb_data(& tb, u4_(& pa->used)); .used = & pa->used,
tb_data(& tb, prim_base); .cursor = prim_base,
);
} }
tape_run(tb_slice(tb));// Fire off the tape (bigger-clobber variant).
// C-side state (pa->used) has already been updated by the tape! // C-side state (pa->used) has already been updated by the tape!
// smem.floor.rot.y += 5; // smem.floor.rot.y += 5;
} }
@@ -390,6 +370,19 @@ void gp_display_frame(DoubleBuffer* screen_buf, S4* active_buf_id, U4* ordering_
int main(void) int main(void)
{ {
smem = (SMemory){0}; smem = (SMemory){0};
B4 basic_sample = false; if (basic_sample) {
// We will be defining the tape here along with its atom, then running the tape after.
TapeBuilder tb = tb_make(slice_ut_arr(smem.MemTape));
MipsCode add_one_to_R_T1[] = {
add_ui_self(R_T1, 1),
mac_yield(),
};
tb_emit(& tb, C_(MipsAtom*, add_one_to_R_T1));
Tape tape = tb_end(& tb);
tape_run(tape);
}
// smem.primitives.used = 0; // smem.primitives.used = 0;
// smem.active_buf_id = 0; // smem.active_buf_id = 0;
smem.cam.pos = v3s4(500, -1000, -1500); smem.cam.pos = v3s4(500, -1000, -1500);
+5 -5
View File
@@ -24,7 +24,7 @@ enum {
typedef U4 OrderingTable_Buffer[OrderingTbl_Len]; typedef U4 OrderingTable_Buffer[OrderingTbl_Len];
typedef Array_(OrderingTable_Buffer, 2); typedef Array_(OrderingTable_Buffer, 2);
typedef B1 PrimitiveBuffer[PrimitiveBuff_Len]; typedef U1 PrimitiveBuffer[PrimitiveBuff_Len];
typedef Array_(PrimitiveBuffer, 2); typedef Array_(PrimitiveBuffer, 2);
typedef Struct_(PrimitiveArena) { typedef Struct_(PrimitiveArena) {
A2_PrimitiveBuffer buf; A2_PrimitiveBuffer buf;
@@ -54,8 +54,8 @@ I_ void ent_cube128_init(A8_V3_S2* verts, A6_V4_S2* faces) {
{ 2, 3, 6, 7 }, { 2, 3, 6, 7 },
{ 3, 0, 7, 4 }, { 3, 0, 7, 4 },
}; };
mem_copy(u4_(verts), u4_(& baked_verts), S_(A8_V3_S2) ); mem_copy(b1_r(verts), b1_r(& baked_verts), S_(A8_V3_S2) );
mem_copy(u4_(faces), u4_(& baked_faces), S_(A6_V4_S2) ); mem_copy(b1_r(faces), b1_r(& baked_faces), S_(A6_V4_S2) );
return; return;
} }
typedef Struct_(Ent_Cube) { typedef Struct_(Ent_Cube) {
@@ -83,8 +83,8 @@ I_ void ent_floor_init(A4_V3_S2* verts, A2_V3_S2* faces) {
{ 0, 1, 2 }, { 0, 1, 2 },
{ 1, 3, 2 }, { 1, 3, 2 },
}; };
mem_copy(u4_(verts), u4_(& baked_verts), S_(A4_V3_S2)); mem_copy(b1_r(verts), b1_r(& baked_verts), S_(A4_V3_S2));
mem_copy(u4_(faces), u4_(& baked_faces), S_(A2_V3_S2)); mem_copy(b1_r(faces), b1_r(& baked_faces), S_(A2_V3_S2));
}; };
typedef Struct_(Ent_Floor) { typedef Struct_(Ent_Floor) {
V3_S4 accel; V3_S4 accel;