mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-09-23 17:50:04 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b61610d819 | ||
|
|
1b950ab5b5 |
@@ -33,7 +33,7 @@ enum {
|
|||||||
atom_offset_example_atom_proc_skip = _atom_offset_example_atom_proc_skip,
|
atom_offset_example_atom_proc_skip = _atom_offset_example_atom_proc_skip,
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- atom: build_normalize_v3s4 (62 words) ---
|
// --- atom: normalize_v3s4 (62 words) ---
|
||||||
|
|
||||||
#define _atom_offset_aligned_done_srav_path 3
|
#define _atom_offset_aligned_done_srav_path 3
|
||||||
#define _atom_offset_srav_path_aligned_done 4
|
#define _atom_offset_srav_path_aligned_done 4
|
||||||
|
|||||||
@@ -99,8 +99,8 @@ enum {
|
|||||||
R_Atom7 = R_T7,
|
R_Atom7 = R_T7,
|
||||||
R_Atom8 = R_T8,
|
R_Atom8 = R_T8,
|
||||||
R_Atom9 = R_T9,
|
R_Atom9 = R_T9,
|
||||||
R_Atom10 = R_V0, // Tend to be used with gte DMAs
|
R_Atom10 = R_V0, // Tend to be used with gte moves
|
||||||
R_Atom11 = R_V1, // Tend to be used with gte DMAs
|
R_Atom11 = R_V1, // Tend to be used with gte moves
|
||||||
R_Atom12 = R_A0,
|
R_Atom12 = R_A0,
|
||||||
R_Atom13 = R_A1,
|
R_Atom13 = R_A1,
|
||||||
R_Atom14 = R_A2,
|
R_Atom14 = R_A2,
|
||||||
@@ -387,10 +387,6 @@ FI_ Reg regfile__alloc_helper(A2_U2 file, Reg r_id) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/* regfile_alloc picks the next free GPR from regfile_alloc_order.
|
|
||||||
* The table is the first-fit allocation order: T0..T7, V0..V1, A0..A3,
|
|
||||||
* S0..S7, T8..T9. The 24 entries leave room for the tape program to use
|
|
||||||
* any of them while R0, R1, R26-R31 remain reserved. */
|
|
||||||
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) {
|
||||||
|
|||||||
@@ -113,8 +113,8 @@ I_ void resolve_look_at_c11(MT3_S2S4* look_at, P3_S4* eye, P3_S4* target, V3_S4*
|
|||||||
forward = target[0]; sub_v3s4(& forward, eye[0]); // RGA(Lengyel): Affine point - point = zero-weight direction.
|
forward = target[0]; sub_v3s4(& forward, eye[0]); // RGA(Lengyel): Affine point - point = zero-weight direction.
|
||||||
psy_normalize_v3s4(& forward, & uz); // RGA(Lengyel): Normalize the direction bulk. Not finite-point unitization.
|
psy_normalize_v3s4(& forward, & uz); // RGA(Lengyel): Normalize the direction bulk. Not finite-point unitization.
|
||||||
|
|
||||||
cross_v3s4(& uz, up_in, & right); normalize_v3s4(& right, & ux); // RGA(Lengyel): Complement(Wedge(forward, up_in)) -> right axis.
|
cross_v3s4(& uz, up_in, & right); psy_normalize_v3s4(& right, & ux); // RGA(Lengyel): Complement(Wedge(forward, up_in)) -> right axis.
|
||||||
cross_v3s4(& uz, & ux, & up); normalize_v3s4(& up, & uy); // RGA(Lengyel): Complement(Wedge(forward, right)) -> up axis.
|
cross_v3s4(& uz, & ux, & up); psy_normalize_v3s4(& up, & uy); // RGA(Lengyel): Complement(Wedge(forward, right)) -> up axis.
|
||||||
|
|
||||||
// RGA(Lengyel): matrix expansion of the world-to-camera rotation (basis rows).
|
// RGA(Lengyel): matrix expansion of the world-to-camera rotation (basis rows).
|
||||||
look_at->m[0][0] = ux.x; look_at->m[0][1] = ux.y; look_at->m[0][2] = ux.z;
|
look_at->m[0][0] = ux.x; look_at->m[0][1] = ux.y; look_at->m[0][2] = ux.z;
|
||||||
@@ -238,7 +238,6 @@ I_ void resolve_look_at(TapeBuilder_R tb, MT3_S2S4* look_at, P3_S4* eye, P3_S4*
|
|||||||
}
|
}
|
||||||
FI_ void camera_look_at(TapeBuilder_R tb, Camera* c, P3_S4* target, V3_S4* up_in) { resolve_look_at(tb, & c->look_at, & c->pos, target, up_in); }
|
FI_ void camera_look_at(TapeBuilder_R tb, Camera* c, P3_S4* target, V3_S4* up_in) { resolve_look_at(tb, & c->look_at, & c->pos, target, up_in); }
|
||||||
|
|
||||||
GCC_OPTIMIZATION_DISABLE
|
|
||||||
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));
|
||||||
@@ -372,7 +371,6 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
|
|||||||
// smem.floor.rot.y += 5;
|
// smem.floor.rot.y += 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GCC_OPTIMIZATION_ENABLE
|
|
||||||
|
|
||||||
void render(void) {
|
void render(void) {
|
||||||
}
|
}
|
||||||
@@ -389,7 +387,6 @@ void gp_display_frame(DoubleBuffer* screen_buf, S4* active_buf_id, U4* ordering_
|
|||||||
active_buf_id[0] = ! active_buf_id[0]; // Swap current buffer
|
active_buf_id[0] = ! active_buf_id[0]; // Swap current buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
GCC_OPTIMIZATION_DISABLE
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
smem = (SMemory){0};
|
smem = (SMemory){0};
|
||||||
@@ -437,4 +434,3 @@ int main(void)
|
|||||||
};
|
};
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
GCC_OPTIMIZATION_ENABLE
|
|
||||||
|
|||||||
@@ -1041,6 +1041,16 @@ function M.find_atom_proc_decl_for(source, before_pos, mips_atom_ptr_len)
|
|||||||
if source:sub(next_pos, next_pos) == "(" then
|
if source:sub(next_pos, next_pos) == "(" then
|
||||||
local inner, after_paren = M.read_parens(source, next_pos) ---@type string|nil, integer
|
local inner, after_paren = M.read_parens(source, next_pos) ---@type string|nil, integer
|
||||||
if inner then
|
if inner then
|
||||||
|
if ident == "AtomBundleEntry_" then
|
||||||
|
local tmpl = M.split_top_level_commas(inner) ---@type string[]
|
||||||
|
if #tmpl ~= 2 then return nil end
|
||||||
|
local name = M.trim(tmpl[1]) .. "_" .. M.trim(tmpl[2]) ---@type string
|
||||||
|
local formals_pos = M.skip_ws_and_cmt(source, after_paren) ---@type integer
|
||||||
|
if source:sub(formals_pos, formals_pos) ~= "(" then return nil end
|
||||||
|
local real_inner, after_real = M.read_parens(source, formals_pos) ---@type string|nil, integer
|
||||||
|
if not real_inner then return nil end
|
||||||
|
return name, real_inner, name, after_real
|
||||||
|
end
|
||||||
return ident, inner, ident, after_paren
|
return ident, inner, ident, after_paren
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -544,6 +544,35 @@ local function render_section_binds(add, view)
|
|||||||
if not wrote then add("_(none)_"); add("") end
|
if not wrote then add("_(none)_"); add("") end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param add fun(s: string): nil
|
||||||
|
--- @param view ModuleView
|
||||||
|
--- @return nil
|
||||||
|
local function render_section_atom_bundles(add, view)
|
||||||
|
local bundles = (view.corpus and view.corpus.atom_bundles) or {} ---@type table<string, AtomBundle>
|
||||||
|
local names = {} ---@type string[]
|
||||||
|
for name, bundle in pairs(bundles) do ---@type string, AtomBundle
|
||||||
|
if path_in_module(bundle.path, view) then
|
||||||
|
names[#names + 1] = name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #names == 0 then add("_(none)_"); add(""); return end
|
||||||
|
table.sort(names)
|
||||||
|
for _, name in ipairs(names) do ---@type integer, string
|
||||||
|
local bundle = bundles[name] ---@type AtomBundle
|
||||||
|
local entries = bundle.entries or {} ---@type table<string, string>
|
||||||
|
add(string.format("### %s", name))
|
||||||
|
for _, slot in ipairs(bundle.slots or {}) do ---@type integer, string
|
||||||
|
local ident = entries[slot] ---@type string|nil
|
||||||
|
if ident then
|
||||||
|
add(string.format("- `%s` `%s`", slot, ident))
|
||||||
|
else
|
||||||
|
add(string.format("- `%s`", slot))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
add("")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- @param add fun(s: string): nil
|
--- @param add fun(s: string): nil
|
||||||
--- @param view ModuleView
|
--- @param view ModuleView
|
||||||
--- @return nil
|
--- @return nil
|
||||||
@@ -895,6 +924,7 @@ local SECTION_RENDERERS = { ---@type SectionRenderer[]
|
|||||||
{ header = "## Annotations", render = render_section_annotations },
|
{ header = "## Annotations", render = render_section_annotations },
|
||||||
{ header = "## Component annotations", render = render_section_component_annotations },
|
{ header = "## Component annotations", render = render_section_component_annotations },
|
||||||
{ header = "## Binds_* structs", render = render_section_binds },
|
{ header = "## Binds_* structs", render = render_section_binds },
|
||||||
|
{ header = "## Atom bundles", render = render_section_atom_bundles },
|
||||||
{ header = "## Phases / views / ctx", render = render_section_phases },
|
{ header = "## Phases / views / ctx", render = render_section_phases },
|
||||||
{ header = "## Register aliases", render = render_section_aliases },
|
{ header = "## Register aliases", render = render_section_aliases },
|
||||||
{ header = "## Auto-reg", render = render_section_autoreg },
|
{ header = "## Auto-reg", render = render_section_autoreg },
|
||||||
|
|||||||
@@ -127,6 +127,13 @@ local parse_enum_int_literal ---@type fun(text: string, start: integer): (intege
|
|||||||
--- @field body string
|
--- @field body string
|
||||||
--- @field bytes integer|nil
|
--- @field bytes integer|nil
|
||||||
|
|
||||||
|
--- @class AtomBundle
|
||||||
|
--- @field name string
|
||||||
|
--- @field slots string[] -- typedef order
|
||||||
|
--- @field line integer
|
||||||
|
--- @field path string
|
||||||
|
--- @field entries table<string, string>|nil -- slot → B_E when an AtomBundleEntry_ proc exists
|
||||||
|
|
||||||
--- @class AliasEntry
|
--- @class AliasEntry
|
||||||
--- @field name string
|
--- @field name string
|
||||||
--- @field code integer
|
--- @field code integer
|
||||||
@@ -208,6 +215,7 @@ local parse_enum_int_literal ---@type fun(text: string, start: integer): (intege
|
|||||||
--- @field reg_use_schemas table<string, RegUseSchema>
|
--- @field reg_use_schemas table<string, RegUseSchema>
|
||||||
--- @field reg_use_errors RegUseError[]
|
--- @field reg_use_errors RegUseError[]
|
||||||
--- @field tape_chains TapeChain[]
|
--- @field tape_chains TapeChain[]
|
||||||
|
--- @field atom_bundles table<string, AtomBundle>
|
||||||
--- @field _source_file string|nil
|
--- @field _source_file string|nil
|
||||||
--- @field _code_macros table<string, integer>|nil -- bag
|
--- @field _code_macros table<string, integer>|nil -- bag
|
||||||
--- @field _code_macro_bodies table<string, string>|nil -- bag
|
--- @field _code_macro_bodies table<string, string>|nil -- bag
|
||||||
@@ -2439,11 +2447,76 @@ local function parse_typedef_array(source, pos, id2_end, line_of, out, after_typ
|
|||||||
return semi and (semi + 1) or after_paren
|
return semi and (semi + 1) or after_paren
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Parse `MipsAtom *slot, …;` from an AtomBundle_ typedef body.
|
||||||
|
--- Ignores the MipsAtom type token. Slot name is the ident after `*`.
|
||||||
|
--- @param body string
|
||||||
|
--- @return string[]
|
||||||
|
local function parse_atom_bundle_slots(body)
|
||||||
|
local slots = {} ---@type string[]
|
||||||
|
local pos = 1 ---@type integer
|
||||||
|
while pos <= #body do
|
||||||
|
pos = duffle.skip_ws_and_cmt(body, pos)
|
||||||
|
if pos > #body then break end
|
||||||
|
local b = body:byte(pos) ---@type integer
|
||||||
|
if b == BYTE_SEMI then
|
||||||
|
break
|
||||||
|
elseif b == BYTE_COMMA then
|
||||||
|
pos = pos + 1
|
||||||
|
elseif b == BYTE_STAR then
|
||||||
|
local after_star = duffle.skip_ws_and_cmt(body, pos + 1) ---@type integer
|
||||||
|
local ident, ident_end = duffle.read_ident(body, after_star) ---@type string|nil, integer
|
||||||
|
if ident then
|
||||||
|
slots[#slots + 1] = ident
|
||||||
|
pos = ident_end
|
||||||
|
else
|
||||||
|
pos = pos + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local ident, ident_end = duffle.read_ident(body, pos) ---@type string|nil, integer
|
||||||
|
if ident then
|
||||||
|
pos = ident_end
|
||||||
|
else
|
||||||
|
pos = pos + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return slots
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Shape 5: `typedef AtomBundle_(<name>) { MipsAtom *slot, … };`
|
||||||
|
--- @param source string
|
||||||
|
--- @param pos integer
|
||||||
|
--- @param id2_end integer
|
||||||
|
--- @param line_of fun(pos: integer): integer
|
||||||
|
--- @param out SourceScan
|
||||||
|
--- @param after_typedef integer
|
||||||
|
--- @return integer
|
||||||
|
local function parse_typedef_atom_bundle(source, pos, id2_end, line_of, out, after_typedef)
|
||||||
|
local inner, after_paren, open_paren = read_parens_after(source, id2_end, id2_end) ---@type string|nil, integer, integer
|
||||||
|
if not inner then return id2_end end
|
||||||
|
local name = duffle.trim(inner) ---@type string
|
||||||
|
|
||||||
|
local body, after_brace = find_body_braces(source, after_paren, open_paren + 1) ---@type string|nil, integer
|
||||||
|
if not body then return after_brace end
|
||||||
|
if name ~= "" and out.atom_bundles[name] == nil then
|
||||||
|
local bundle = { ---@type AtomBundle
|
||||||
|
name = name,
|
||||||
|
slots = parse_atom_bundle_slots(body),
|
||||||
|
line = line_of(pos),
|
||||||
|
path = out._source_file or "",
|
||||||
|
}
|
||||||
|
out.atom_bundles[name] = bundle
|
||||||
|
end
|
||||||
|
attach_debug_skip_marker(out, "unrelated")
|
||||||
|
return after_brace
|
||||||
|
end
|
||||||
|
|
||||||
local TYPE_FORMS = { ---@type table<string, fun(source: string, pos: integer, id2_end: integer, line_of: fun(pos: integer): integer, out: SourceScan, after_typedef: integer): integer>
|
local TYPE_FORMS = { ---@type table<string, fun(source: string, pos: integer, id2_end: integer, line_of: fun(pos: integer): integer, out: SourceScan, after_typedef: integer): integer>
|
||||||
Struct_ = parse_typedef_struct,
|
Struct_ = parse_typedef_struct,
|
||||||
Enum_ = parse_typedef_enum,
|
Enum_ = parse_typedef_enum,
|
||||||
TSet_ = parse_typedef_tset,
|
TSet_ = parse_typedef_tset,
|
||||||
Array_ = parse_typedef_array,
|
Array_ = parse_typedef_array,
|
||||||
|
AtomBundle_ = parse_typedef_atom_bundle,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Parse: `typedef` declarations.
|
--- Parse: `typedef` declarations.
|
||||||
@@ -2924,6 +2997,7 @@ local function scan_source(source, source_file, code_macros, code_macro_bodies)
|
|||||||
atoms = {},
|
atoms = {},
|
||||||
raw_atoms = {},
|
raw_atoms = {},
|
||||||
binds = {},
|
binds = {},
|
||||||
|
atom_bundles = {},
|
||||||
atom_infos = {},
|
atom_infos = {},
|
||||||
component_atom_infos = {},
|
component_atom_infos = {},
|
||||||
macros = {},
|
macros = {},
|
||||||
@@ -3238,6 +3312,7 @@ local function merge_corpus_registries(corpus)
|
|||||||
corpus.reg_use_schemas = corpus.reg_use_schemas or {}
|
corpus.reg_use_schemas = corpus.reg_use_schemas or {}
|
||||||
corpus.reg_use_errors = corpus.reg_use_errors or {}
|
corpus.reg_use_errors = corpus.reg_use_errors or {}
|
||||||
corpus.tape_chains = corpus.tape_chains or {}
|
corpus.tape_chains = corpus.tape_chains or {}
|
||||||
|
corpus.atom_bundles = corpus.atom_bundles or {}
|
||||||
|
|
||||||
-- Replace the existing corpus collections with empty tables so a re-run on the same corpus produces identical state (deterministic merge).
|
-- Replace the existing corpus collections with empty tables so a re-run on the same corpus produces identical state (deterministic merge).
|
||||||
-- This is safe because M.run is the only writer to these tables within a single orchestrator invocation.
|
-- This is safe because M.run is the only writer to these tables within a single orchestrator invocation.
|
||||||
@@ -3255,6 +3330,7 @@ local function merge_corpus_registries(corpus)
|
|||||||
"reg_use_schemas",
|
"reg_use_schemas",
|
||||||
"reg_use_errors",
|
"reg_use_errors",
|
||||||
"tape_chains",
|
"tape_chains",
|
||||||
|
"atom_bundles",
|
||||||
}) do
|
}) do
|
||||||
corpus[key] = {}
|
corpus[key] = {}
|
||||||
end
|
end
|
||||||
@@ -3362,6 +3438,28 @@ local function merge_corpus_registries(corpus)
|
|||||||
for _, chain in ipairs(scan.tape_chains or {}) do ---@type integer, TapeChain
|
for _, chain in ipairs(scan.tape_chains or {}) do ---@type integer, TapeChain
|
||||||
corpus.tape_chains[#corpus.tape_chains + 1] = chain
|
corpus.tape_chains[#corpus.tape_chains + 1] = chain
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- atom_bundles: keyed by typedef name. First-wins per name (like components).
|
||||||
|
for name, bundle in pairs(scan.atom_bundles or {}) do ---@type string, AtomBundle
|
||||||
|
if corpus.atom_bundles[name] == nil then
|
||||||
|
corpus.atom_bundles[name] = bundle
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Join slot roles to AtomBundleEntry_ identities after catalogs and atoms exist.
|
||||||
|
-- Do not invent a catalog from an entry that has no typedef.
|
||||||
|
for _, bundle in pairs(corpus.atom_bundles) do ---@type string, AtomBundle
|
||||||
|
local entries = {} ---@type table<string, string>
|
||||||
|
for _, slot in ipairs(bundle.slots or {}) do ---@type integer, string
|
||||||
|
local atom_name = bundle.name .. "_" .. slot ---@type string
|
||||||
|
if corpus.atoms_by_name[atom_name] then
|
||||||
|
entries[slot] = atom_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if next(entries) then
|
||||||
|
bundle.entries = entries
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ local PASS_FLAG_DISPATCH_KEY = "__pass__" ---@type string
|
|||||||
--- @field atom_phases table<string, AtomPhaseGroup>
|
--- @field atom_phases table<string, AtomPhaseGroup>
|
||||||
--- @field word_counts WordCounts
|
--- @field word_counts WordCounts
|
||||||
--- @field components table<string, Component>
|
--- @field components table<string, Component>
|
||||||
|
--- @field atom_bundles table<string, AtomBundle>|nil
|
||||||
--- @field collisions CorpusCollision[]
|
--- @field collisions CorpusCollision[]
|
||||||
--- @field resolver SourceResolver
|
--- @field resolver SourceResolver
|
||||||
--- @field component_atom_infos AtomInfoEntry[]|nil
|
--- @field component_atom_infos AtomInfoEntry[]|nil
|
||||||
@@ -665,6 +666,7 @@ local function build_ctx(args)
|
|||||||
atom_phases = {},
|
atom_phases = {},
|
||||||
word_counts = {},
|
word_counts = {},
|
||||||
components = {},
|
components = {},
|
||||||
|
atom_bundles = {},
|
||||||
collisions = {},
|
collisions = {},
|
||||||
resolver = resolution.resolver,
|
resolver = resolution.resolver,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user