diff --git a/code/duffle/gen/macs.h b/code/duffle/gen/macs.h index 1e6fee8..1261b2a 100644 --- a/code/duffle/gen/macs.h +++ b/code/duffle/gen/macs.h @@ -60,8 +60,8 @@ WORD_COUNT(mac_yield_tail, 3) /* atom_dbg_skip */ #define mac_load_v2s2(rs_x, rs_y, r_base, offset) \ - load_half( rs_x, r_base, O_(V3_S2,x)) \ -, load_half( rs_y, r_base, 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 */ @@ -72,9 +72,9 @@ WORD_COUNT(mac_store_v2s2, 2) /* atom_dbg_skip */ #define mac_load_v3s4(rs_x, rs_y, rs_z, r_base, offset) \ - load_word( rs_x, r_base, O_(V3_S4,x)) \ -, load_word( rs_y, r_base, O_(V3_S4,y)) \ -, load_word( rs_z, r_base, O_(V3_S4,z)) + load_word( rs_x, r_base, offset + O_(V3_S4,x)) \ +, load_word( rs_y, r_base, offset + O_(V3_S4,y)) \ +, load_word( rs_z, r_base, offset + O_(V3_S4,z)) WORD_COUNT(mac_load_v3s4, 3) /* atom_dbg_skip */ diff --git a/code/duffle/lottes_tape.h b/code/duffle/lottes_tape.h index 7d16ae7..3ae0958 100644 --- a/code/duffle/lottes_tape.h +++ b/code/duffle/lottes_tape.h @@ -100,6 +100,8 @@ enum { // S 0-7 }; +typedef U2 Reg; // Register parameter used with atom or atom component procedures + typedef U4 const MipsCode; // Underlying type to mips asm words. typedef Slice_(MipsCode); @@ -150,7 +152,7 @@ typedef Slice_(MipsAtom); typedef Slice_MipsAtom Tape; /* The 'Exit' Atom */ -atom_dbg_skip MipsAtom_(tape_exit) { jump_reg(rret_addr), nop }; +atom_dbg_skip MipsAtom_(tape_exit) { jump_reg(R_RA), nop }; // TODO(Ed): When we have a substantial workload/throughput, profile each of these to see impact at ABI boundaries. diff --git a/code/duffle/math.atom.c b/code/duffle/math.atom.c index e9eee41..541d009 100644 --- a/code/duffle/math.atom.c +++ b/code/duffle/math.atom.c @@ -10,8 +10,8 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(math_atom_c); #pragma region MACs (Mips Atom Component) 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_(ac_load_v2s2, ab, { - load_half( rs_x, r_base, O_(V3_S2,x)), - load_half( rs_y, r_base, 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_(ac_store_v2s2, ab, { @@ -20,16 +20,22 @@ FI_ Slice_MipsCode ac_store_v2s2(AtomBuilder_R ab, U4 rt_x, U4 rt_y, U4 base, U4 }) FI_ Slice_MipsCode ac_load_v3s4(AtomBuilder_R ab, U4 rs_x, U4 rs_y, U4 rs_z, U4 r_base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ac_load_v3s4, ab, { - load_word( rs_x, r_base, O_(V3_S4,x)), - load_word( rs_y, r_base, O_(V3_S4,y)), - load_word( rs_z, r_base, O_(V3_S4,z)), + load_word( rs_x, r_base, offset + O_(V3_S4,x)), + load_word( rs_y, r_base, offset + O_(V3_S4,y)), + load_word( rs_z, r_base, offset + O_(V3_S4,z)), }) +// TODO(Ed): we could generate these mappings properly.. +#define ac_load_p3s4 ac_load_v3s4 +#define mac_load_p3s4 mac_load_v3s4 FI_ Slice_MipsCode ac_store_v3s4(AtomBuilder_R ab, U4 rt_x, U4 rt_y, U4 rt_z, U4 base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ac_store_v3s4, ab, { store_word(rt_x, base, offset + O_(V3_S4,x)), store_word(rt_y, base, offset + O_(V3_S4,y)), store_word(rt_z, base, offset + O_(V3_S4,z)), }) +// TODO(Ed): we could generate these mappings properly.. +#define ac_store_p3s4 ac_store_v3s4 +#define mac_store_p3s4 mac_store_v3s4 FI_ Slice_MipsCode ac_sub_v3s4(AtomBuilder_R ab, U4 rds_x, U4 rds_y, U4 rds_z, U4 rt_x, U4 rt_y, U4 rt_z) atom_dbg_skip MipsAtomComp_Proc_(ac_sub_v3s4, ab, { sub_s(rds_x, rds_x, rt_x), diff --git a/code/duffle/mips.atom.c b/code/duffle/mips.atom.c index e50f79d..dd0d157 100644 --- a/code/duffle/mips.atom.c +++ b/code/duffle/mips.atom.c @@ -20,14 +20,14 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(mips_atom_c); * 6. sp += 8 */ internal MipsAtom_(mips_flush_icache) { - add_ui(rstack_ptr, rstack_ptr, -MipsStackAlignment), // sp -= 8 - store_word(rret_addr, rstack_ptr, S_(U4)), // sw $ra, 4($sp) - add_ui(rret_0, rdiscard, bios_flushcache), // addiu $a0, $0, 0x44 - add_ui(rtmp_0, rdiscard, bios_table_addr), // addiu $t0, $0, 0xA0 - jump_link(rtmp_0, rret_addr), nop, // jalr $t0, $ra, BD slot - load_word(rret_addr, rstack_ptr, S_(U4)), // lw $ra, 4($sp) - jump_reg(rret_addr), // jr $ra - add_ui(rstack_ptr, rstack_ptr, MipsStackAlignment), // sp += 8 (BD) + add_ui(R_SP, R_SP, -MipsStackAlignment), // sp -= 8 + store_word(R_RA, R_SP, S_(U4)), // sw $ra, 4($sp) + add_ui(R_V0, R_0, bios_flushcache), // addiu $a0, $0, 0x44 + add_ui(R_T0, R_0, bios_table_addr), // addiu $t0, $0, 0xA0 + jump_link(R_T0, R_RA), nop, // jalr $t0, $ra, BD slot + load_word(R_RA, R_SP, S_(U4)), // lw $ra, 4($sp) + jump_reg(R_RA), // jr $ra + add_ui(R_SP, R_SP, MipsStackAlignment), // sp += 8 (BD) mac_yield(), }; diff --git a/code/duffle/mips.h b/code/duffle/mips.h index dd62a7a..e283b57 100644 --- a/code/duffle/mips.h +++ b/code/duffle/mips.h @@ -136,31 +136,31 @@ enum { /* Semantic Aliases for MIPS Registers (O32 ABI) */ - , rdiscard = R_0 /* Hardwired to 0 */ - , rasm_tmp = R_AT /* Assembler temporary (destroyed by some assembler pseudoinstructions!) */ - , rret_0 = R_V0 /* Function return value */ - , rret_1 = R_V1 /* Second return value (e.g., 64-bit) */ - , rarg_0 = R_A0 /* First function argument */ - , rarg_1 = R_A1 /* Second function argument */ - , rarg_2 = R_A2 /* Third function argument */ - , rarg_3 = R_A3 /* Fourth function argument */ - , rtmp_0 = R_T0 /* Temporary (Caller saved) */ - , rtmp_1 = R_T1 /* Temporary (Caller saved) */ - , rtmp_2 = R_T2 /* Temporary (Caller saved) */ - , rtmp_3 = R_T3 /* Temporary (Caller saved) */ - , rtmp_4 = R_T4 /* Temporary (Caller saved) — common GTE base pointer */ - , rtmp_9 = R_T9 /* Temporary (Caller saved) — common GTE base pointer */ - , rstatic_0 = R_S0 /* Static (Callee saved, preserved across calls) */ - , rstatic_1 = R_S1 - , rstatic_2 = R_S2 - , rstatic_3 = R_S3 - , rstatic_4 = R_S4 - , rstatic_5 = R_S5 - , rstatic_6 = R_S6 - , rstatic_7 = R_S7 - , rsaved_0 = R_S0 /* Alias for rstatic_0 (alternate vocabulary) */ - , rstack_ptr = R_SP /* Stack Pointer */ - , rret_addr = R_RA /* Return Address (populated by JAL) */ + // , rdiscard = R_0 /* Hardwired to 0 */ + // , rasm_tmp = R_AT /* Assembler temporary (destroyed by some assembler pseudoinstructions!) */ + // , rret_0 = R_V0 /* Function return value */ + // , rret_1 = R_V1 /* Second return value (e.g., 64-bit) */ + // , rarg_0 = R_A0 /* First function argument */ + // , rarg_1 = R_A1 /* Second function argument */ + // , rarg_2 = R_A2 /* Third function argument */ + // , rarg_3 = R_A3 /* Fourth function argument */ + // , rtmp_0 = R_T0 /* Temporary (Caller saved) */ + // , rtmp_1 = R_T1 /* Temporary (Caller saved) */ + // , rtmp_2 = R_T2 /* Temporary (Caller saved) */ + // , rtmp_3 = R_T3 /* Temporary (Caller saved) */ + // , rtmp_4 = R_T4 /* Temporary (Caller saved) — common GTE base pointer */ + // , rtmp_9 = R_T9 /* Temporary (Caller saved) — common GTE base pointer */ + // , rstatic_0 = R_S0 /* Static (Callee saved, preserved across calls) */ + // , rstatic_1 = R_S1 + // , rstatic_2 = R_S2 + // , rstatic_3 = R_S3 + // , rstatic_4 = R_S4 + // , rstatic_5 = R_S5 + // , rstatic_6 = R_S6 + // , rstatic_7 = R_S7 + // , rsaved_0 = R_S0 /* Alias for rstatic_0 (alternate vocabulary) */ + // , rstack_ptr = R_SP /* Stack Pointer */ + // , rret_addr = R_RA /* Return Address (populated by JAL) */ /* --- MIPS CPU Opcodes (Bits 31-26) --- */ @@ -453,7 +453,7 @@ enum { _BitOffsets = 0 #define shift_amount(rd, rt, n) shift_lleft(rd, rt, n) /* nop — sll $0, $0, 0 */ -#define nop shift_lleft(rdiscard, rdiscard, 0) +#define nop shift_lleft(R_0, R_0, 0) #define nop2 nop, nop // li_s — load signed 16-bit immediate into GPR (addiu rt, $0, imm — sign-extends). diff --git a/code/duffle/pad.c b/code/duffle/pad.c index 22dba47..ce183b3 100644 --- a/code/duffle/pad.c +++ b/code/duffle/pad.c @@ -36,13 +36,13 @@ NI_ void pad_bios_init_start(PadBiosRaw* raw0, PadBiosRaw* raw1) * $t2 = 0xB0 (BIOS B-table address) */ asm volatile( asm_words( - or_u( rarg_2, rarg_1, rdiscard), /* $a2 = $a1 = raw1 */ - add_ui( rarg_1, rdiscard, bios_pad_buffer_size), /* $a1 = 0x22 */ - add_ui( rarg_3, rdiscard, bios_pad_buffer_size), /* $a3 = 0x22 */ - add_ui( rtmp_1, rdiscard, bios_init_pad_2), /* $t1 = 0x12 */ - add_ui( rtmp_2, rdiscard, bios_btable_addr), /* $t2 = 0xB0 */ - call_reg(rtmp_2), /* jalr $t2, $ra */ - nop /* BD slot */ + or_u( R_A2, R_A0, R_0), /* $a2 = $a1 = raw1 */ + add_ui( R_A1, R_0, bios_pad_buffer_size), /* $a1 = 0x22 */ + add_ui( R_A3, R_0, bios_pad_buffer_size), /* $a3 = 0x22 */ + add_ui( R_T1, R_0, bios_init_pad_2), /* $t1 = 0x12 */ + add_ui( R_T2, R_0, bios_btable_addr), /* $t2 = 0xB0 */ + call_reg(R_T2), /* jalr $t2, $ra */ + nop /* BD slot */ ) asm_rpins, r_use(p0), r_use(p1) asm_clobber: @@ -62,9 +62,9 @@ NI_ void pad_bios_init_start(PadBiosRaw* raw0, PadBiosRaw* raw1) /* B(13h) StartPAD2() — no args. The BIOS preserves $sp. */ asm volatile( asm_words( - add_ui( rtmp_1, rdiscard, bios_start_pad_2), /* $t1 = 0x13 */ - add_ui( rtmp_2, rdiscard, bios_btable_addr), /* $t2 = 0xB0 (re-load) */ - call_reg(rtmp_2), /* jalr $t2, $ra */ + add_ui( R_T1, R_0, bios_start_pad_2), /* $t1 = 0x13 */ + add_ui( R_T2, R_0, bios_btable_addr), /* $t2 = 0xB0 (re-load) */ + call_reg(R_T2), /* jalr $t2, $ra */ nop /* BD slot */ ) asm_clobber: diff --git a/code/hello_camera/hello_camera.atom.c b/code/hello_camera/hello_camera.atom.c index 5433c00..f7ee004 100644 --- a/code/hello_camera/hello_camera.atom.c +++ b/code/hello_camera/hello_camera.atom.c @@ -188,26 +188,17 @@ typedef Struct_(ResolveLookAtScratch) { */ typedef Struct_(Binds_ResolveLookAtSub) { - U4 target; /* U4 (C-side P3_S4* — read by atom 0 directly; NOT a scratchpad address) */ - U4 eye; /* U4 (C-side P3_S4* — read by atom 0 directly; staged into scratchpad by atom 0) */ - U4 up_in; /* U4 (C-side V3_S4* — read by atom 0 directly; staged into scratchpad by atom 0) */ - U4 scratchpad; + P3_S4* target; /* U4 (C-side P3_S4* — read by atom 0 directly; NOT a scratchpad address) */ + P3_S4* eye; /* U4 (C-side P3_S4* — read by atom 0 directly; staged into scratchpad by atom 0) */ + V3_S4* up_in; /* U4 (C-side V3_S4* — read by atom 0 directly; staged into scratchpad by atom 0) */ + ResolveLookAtScratch* scratchpad; }; /* Atom 0 in the bundle: input_and_sub. Stages C-side inputs into the scratchpad and computes fwd = target - eye. - * Inputs (C-side pointers popped from the tape): - * r_target_ptr : P3_S4* (C-side struct; atom 0 reads target.x/y/z directly) - * r_eye_ptr : P3_S4* (C-side struct; staged into scratchpad at +96/+100/+104) - * r_up_in_ptr : V3_S4* (C-side struct; staged into scratchpad at +128/+132/+136) - * r_scratch : R_ResolveScratch (R_T4) — scratch base, read by atoms 1-6 - * - * Bind-pop layout: - * Binds_ResolveLookAtSub * Staging work: * * Stage eye.x/y/z → scratch (for atom 6's translation column) * * Stage up_in.x/y/z → scratch (for atom 2's outer-product operand) * * Compute fwd = target - eye, store fwd.x/y/z → scratch+0/+4/+8 (for atom 1) - * * GPR codes (assigned by resolve_look_at_init): * r_target_ptr : R_T0 * r_eye_ptr : R_T1 @@ -219,56 +210,35 @@ typedef Struct_(Binds_ResolveLookAtSub) { * r_tmp3 : R_T7 (stage eye/up_in + load target.y) * R_AT : hardcoded (load eye.y / eye.z / target.z) * R_V0 : hardcoded (load eye.z / target.z) - * * Pool cost: 8 GPRs + R_T4 (carrier) + R_AT + R_V0 (hardcoded) = 11 GPRs. */ -internal MipsAtom* resolve_look_at__input_and_sub_proc(AtomArena_R aa, U4 r_scratch +internal MipsAtom* resolve_look_at__input_and_sub_proc(AtomArena_R aa, + // TODO(Ed): We can resolve scratch at anytime its fixed to a specific address. + U4 r_scratch , U4 r_target_ptr,U4 r_eye_ptr, U4 r_up_in_ptr , U4 r_tmp0, U4 r_tmp1, U4 r_tmp2, U4 r_tmp3 ) MipsAtom_Proc_(resolve_look_at__input_and_sub, aa, { - /* Pop the 3 C-side pointers + scratch_base from the tape. */ load_word(r_target_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,target)), load_word(r_eye_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,eye)), load_word(r_up_in_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,up_in)), load_word(r_scratch, R_TapePtr, O_(Binds_ResolveLookAtSub,scratchpad)), add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtSub)), - /* Stage eye.x/y/z into the scratchpad (atom 6 reads these for the translation - * column). Reuse r_tmp0/r_tmp1/r_tmp2. Offsets via O_(ResolveLookAtScratch,*). */ - load_word(r_tmp0, r_eye_ptr, O_(P3_S4,x)), - load_word(r_tmp1, r_eye_ptr, O_(P3_S4,y)), - load_word(r_tmp2, r_eye_ptr, O_(P3_S4,z)), - nop, /* load-delay */ - store_word(r_tmp0, r_scratch, O_(ResolveLookAtScratch,eye.x)), - store_word(r_tmp1, r_scratch, O_(ResolveLookAtScratch,eye.y)), - store_word(r_tmp2, r_scratch, O_(ResolveLookAtScratch,eye.z)), + // Stage eye.x/y/z into the scratchpad (atom 6 reads these for the translation column). + mac_load_p3s4( r_tmp0, r_tmp1, r_tmp2, r_eye_ptr, 0), + mac_store_p3s4(r_tmp0, r_tmp1, r_tmp2, r_scratch, O_(ResolveLookAtScratch,eye)), - /* Stage up_in.x/y/z into the scratchpad (atom 2 reads these for the outer - * product with uz). Reuse r_tmp0/r_tmp1/r_tmp2. */ - load_word(r_tmp0, r_up_in_ptr, O_(V3_S4,x)), - load_word(r_tmp1, r_up_in_ptr, O_(V3_S4,y)), - load_word(r_tmp2, r_up_in_ptr, O_(V3_S4,z)), - nop, /* load-delay */ - store_word(r_tmp0, r_scratch, O_(ResolveLookAtScratch,up_in.x)), - store_word(r_tmp1, r_scratch, O_(ResolveLookAtScratch,up_in.y)), - store_word(r_tmp2, r_scratch, O_(ResolveLookAtScratch,up_in.z)), + /* Stage up_in.x/y/z into the scratchpad. */ + mac_load_p3s4( r_tmp0, r_tmp1, r_tmp2, r_up_in_ptr, 0), + mac_store_p3s4(r_tmp0, r_tmp1, r_tmp2, r_scratch, O_(ResolveLookAtScratch,up_in)), /* Compute fwd = target - eye. */ - load_word(r_tmp0, r_target_ptr, O_(P3_S4,x)), - load_word(r_tmp1, r_target_ptr, O_(P3_S4,y)), - load_word(r_tmp2, r_target_ptr, O_(P3_S4,z)), - load_word(r_tmp3, r_eye_ptr, O_(P3_S4,x)), - load_word(R_AT, r_eye_ptr, O_(P3_S4,y)), - load_word(R_V0, r_eye_ptr, O_(P3_S4,z)), - nop, /* load-delay */ - sub_u(r_tmp0, r_tmp0, r_tmp3), - sub_u(r_tmp1, r_tmp1, R_AT), - sub_u(r_tmp2, r_tmp2, R_V0), - - /* Store fwd.x/y/z (atom 1 reads these as the normalize src). */ - store_word(r_tmp0, r_scratch, O_(ResolveLookAtScratch,fwd.x)), - store_word(r_tmp1, r_scratch, O_(ResolveLookAtScratch,fwd.y)), - store_word(r_tmp2, r_scratch, O_(ResolveLookAtScratch,fwd.z)), + mac_load_p3s4(r_tmp0, r_tmp1, r_tmp2, r_target_ptr, 0), + mac_load_p3s4(r_tmp3, R_AT, R_V0, r_eye_ptr, 0), + mac_sub_v3s4( + r_tmp0, r_tmp1, r_tmp2, + r_tmp3, R_AT, R_V0), + mac_store_v3s4(r_tmp0, r_tmp1, r_tmp2, r_scratch, O_(ResolveLookAtScratch,fwd)), mac_yield() })