Files
pikuma_ps1/code/hello_camera/gen/macs.h
T
2026-08-10 19:53:34 -04:00

389 lines
18 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#endif
// Auto-generated by ps1_meta.lua — DO NOT EDIT
// Directory: C:\projects\Pikuma\ps1\code\hello_camera/
// source: C:\projects\Pikuma\ps1\code\hello_camera\hello_camera.c
// source: C:\projects\Pikuma\ps1\code\hello_camera\hello_camera.h
// source: C:\projects\Pikuma\ps1\code\hello_camera\hello_camera.atom.c
// Component atoms (MipsAtomComp_(ac_*)) -> macro variants (mac_*)
#ifndef WORD_COUNT
#define WORD_COUNT(name, count) enum { words_##name = (count) };
#endif
#define mac_put_disp_env(reg_transfer, reg_base, port) \
mac_gcmd_push(gp0_word_draw_area_top_left_origin, reg_transfer, reg_base, port) \
, mac_gcmd_push(gp0_word_draw_area_bottom_right_320x240, reg_transfer, reg_base, port) \
, mac_gcmd_push(gp0_word_set_mask_bit(), reg_transfer, reg_base, port) \
, mac_gcmd_push(gp0_word_draw_area_top_left_origin, reg_transfer, reg_base, port) \
, mac_gcmd_push(gp0_word_draw_area_bottom_right_320x240, reg_transfer, reg_base, port)
WORD_COUNT(mac_put_disp_env, 5)
#define mac_put_draw_env(reg_transfer, reg_base, port) \
mac_gcmd_push(gp0_dr_env_tag, reg_transfer, reg_base, port) /* tag (length=15 << 24, addr=0) — packet header for the DR_ENV sequence. The GPU needs this to recognize the next 15 words as a DR_ENV packet and trigger the isbg auto-clear. */ \
, mac_gcmd_push(gp0_word_draw_mode_drawing_allowed, reg_transfer, reg_base, port) /* code[0] DrawMode (dfe=1, dtd=0, tpage=0) */ \
, mac_gcmd_push(gp0_word_set_texture_window(), reg_transfer, reg_base, port) /* code[1] TextureWindow (tw=(0,0)) */ \
, mac_gcmd_push(enc_gp0_draw_area_tl_word(0, ScreenRes_Y), reg_transfer, reg_base, port) /* code[2] DrawArea top-left (clip.x=0, clip.y=ScreenRes_Y=240) */ \
, mac_gcmd_push(gp0_word_draw_area_bottom_right_320x240, reg_transfer, reg_base, port) /* code[3] DrawArea bottom-right (clip.x+w=320, clip.y+h=480) */ \
, mac_gcmd_push(gp0_word_set_draw_offset(), reg_transfer, reg_base, port) /* code[4] DrawOffset (ofs=(0,0)) — bare-cmd word; the GPU uses the current state machine. */ \
, mac_gcmd_push(gp0_word_dr_env_mask(), reg_transfer, reg_base, port) /* code[5] Mask (dtd=0, dfe=1, isbg=1) — 0xE6 cmd + isbg bit. */ \
, mac_gcmd_push(gp0_word_dr_env_bg_color_cmd(1, 7, 7, 7), reg_transfer, reg_base, port) /* code[6] Initial-bg-color + auto-clear (isbg=1, r=7, g=7, b=7). */ \
, mac_gcmd_push(gp0_word_dr_env_draw_mode(1), reg_transfer, reg_base, port) /* code[7] Re-assert DrawMode with isbg=1 (isbg-flag set; the 0xE1 cmd byte plus isbg only). */ /* code[8..10] Padding (NOP — GPU discards; the DR_ENV requires 16 words total). */ \
, mac_gcmd_push(gp0_word_nop(), reg_transfer, reg_base, port) \
, mac_gcmd_push(gp0_word_nop(), reg_transfer, reg_base, port) \
, mac_gcmd_push(gp0_word_nop(), reg_transfer, reg_base, port) /* code[11..12] TextureWindow bottom-right (tw.x+tw.w=0, tw.y+tw.h=0) — libpsyx emits twice. */ \
, mac_gcmd_push(gp0_word_set_texture_window(), reg_transfer, reg_base, port) \
, mac_gcmd_push(gp0_word_set_texture_window(), reg_transfer, reg_base, port) /* code[13..14] Padding (NOP) — completes the 16-word packet. */ \
, mac_gcmd_push(gp0_word_nop(), reg_transfer, reg_base, port) \
, mac_gcmd_push(gp0_word_nop(), reg_transfer, reg_base, port)
WORD_COUNT(mac_put_draw_env, 16)
#define mac_resolve_look_at__input_and_sub(...) \
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)) \
, add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtSub)) \
, load_word(r_scratch, R_TapePtr, O_(Binds_ResolveLookAtScratch,scratch_base)) \
, add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtScratch)) /* 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 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)) /* 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_yield()
WORD_COUNT(mac_resolve_look_at__input_and_sub, 34)
#define mac_resolve_look_at__cross_uz_up_in_to_right(...) \
add_si(r_g, r_scratch, O_(ResolveLookAtScratch,uz)) /* r_g = &uz */ \
, add_si(r_h, r_scratch, O_(ResolveLookAtScratch,up_in)) /* r_h = &up_in */ \
, add_si(r_f, r_scratch, O_(ResolveLookAtScratch,right)) /* r_f = &right (out) */ \
, nop /* Load a (uz).x/y/z into r_a/r_b/r_c. */ \
, load_word(r_a, r_g, O_(V3_S4,x)) \
, load_word(r_b, r_g, O_(V3_S4,y)) \
, load_word(r_c, r_g, O_(V3_S4,z)) \
, nop /* Load b (up_in).x/y/z into r_d + R_AT/R_V0 (hardcoded; reusing the
* body's last two loads is fine because the load-delay slot is the nop
* after the third load, and mtc2 below doesn't read these regs). */ \
, load_word(r_d, r_h, O_(V3_S4,x)) \
, load_word(R_AT, r_h, O_(V3_S4,y)) \
, load_word(R_V0, r_h, O_(V3_S4,z)) \
, nop /* mtc2 a → IR1/2/3, b → D1/2/3 (VXY0/VZ0/VXY1). */ \
, gte_mv_to_data_r(r_a, C2_IR1) \
, gte_mv_to_data_r(r_b, C2_IR2) \
, gte_mv_to_data_r(r_c, C2_IR3) \
, gte_mv_to_data_r(r_d, C2_VXY0) /* D1 = b.x */ \
, gte_mv_to_data_r(R_AT, C2_VZ0) /* D2 = b.y */ \
, gte_mv_to_data_r(R_V0, C2_VXY1) /* D3 = b.z */ \
, nop2 /* MTC2 retirement (CPU→COP2 2-slot delay) */ \
, gte_cmdw_outer_product /* OP fires; MAC1/2/3 = a × b */ /* mfc2 MAC1/2/3 → r_a/r_b/r_c (out.x/y/z). */ \
, gte_mv_from_data_r(r_a, C2_MAC1) \
, gte_mv_from_data_r(r_b, C2_MAC2) \
, gte_mv_from_data_r(r_c, C2_MAC3) \
, nop /* MFC2 retirement */ /* Store out.x/y/z to r_f (out ptr = scratch+32). */ \
, store_word(r_a, r_f, O_(V3_S4,x)) \
, store_word(r_b, r_f, O_(V3_S4,y)) \
, store_word(r_c, r_f, O_(V3_S4,z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__cross_uz_up_in_to_right, 29)
#define mac_resolve_look_at__cross_uz_ux_to_up(...) \
add_si(r_g, r_scratch, O_(ResolveLookAtScratch,uz)) /* r_g = &uz */ \
, add_si(r_h, r_scratch, O_(ResolveLookAtScratch,ux)) /* r_h = &ux */ \
, add_si(r_f, r_scratch, O_(ResolveLookAtScratch,up)) /* r_f = &up (out) */ \
, nop /* Load a (uz).x/y/z into r_a/r_b/r_c. */ \
, load_word(r_a, r_g, O_(V3_S4,x)) \
, load_word(r_b, r_g, O_(V3_S4,y)) \
, load_word(r_c, r_g, O_(V3_S4,z)) \
, nop /* Load b (ux).x/y/z into r_d + R_AT/R_V0. */ \
, load_word(r_d, r_h, O_(V3_S4,x)) \
, load_word(R_AT, r_h, O_(V3_S4,y)) \
, load_word(R_V0, r_h, O_(V3_S4,z)) \
, nop /* mtc2 a → IR1/2/3, b → D1/2/3 (VXY0/VZ0/VXY1). */ \
, gte_mv_to_data_r(r_a, C2_IR1) \
, gte_mv_to_data_r(r_b, C2_IR2) \
, gte_mv_to_data_r(r_c, C2_IR3) \
, gte_mv_to_data_r(r_d, C2_VXY0) \
, gte_mv_to_data_r(R_AT, C2_VZ0) \
, gte_mv_to_data_r(R_V0, C2_VXY1) \
, nop2 \
, gte_cmdw_outer_product \
, gte_mv_from_data_r(r_a, C2_MAC1) \
, gte_mv_from_data_r(r_b, C2_MAC2) \
, gte_mv_from_data_r(r_c, C2_MAC3) \
, nop \
, store_word(r_a, r_f, O_(V3_S4,x)) \
, store_word(r_b, r_f, O_(V3_S4,y)) \
, store_word(r_c, r_f, O_(V3_S4,z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__cross_uz_ux_to_up, 29)
#define mac_resolve_look_at__normalize_fwd_to_uz(...) \
add_si(r_a, r_scratch, O_(ResolveLookAtScratch,fwd)) /* r_a = &fwd */ \
, add_si(r_b, r_scratch, O_(ResolveLookAtScratch,uz)) /* r_b = &uz */ \
, nop /* Load src.x/y/z from r_a into r_e/r_f/r_i. */ \
, load_word(r_e, r_a, O_(V3_S4,x)) \
, load_word(r_f, r_a, O_(V3_S4,y)) \
, load_word(r_i, r_a, O_(V3_S4,z)) \
, nop /* load-delay */ /* Stage 1: mtc2 src → IR1/2/3, SQR fires. */ \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop \
, gte_cmdw_sqr /* Stage 2: mfc2 MAC1/2/3, sum, mtc2 LZCS. */ \
, gte_mv_from_data_r(r_d, C2_MAC1) \
, gte_mv_from_data_r(r_g, C2_MAC2) \
, gte_mv_from_data_r(r_recip_est, C2_MAC3) \
, nop \
, add_u(r_recip_est, r_recip_est, r_g) \
, add_u(r_recip_est, r_recip_est, r_d) \
, gte_mv_to_data_r(r_recip_est, C2_LZCS) \
, nop2 \
, gte_mv_from_data_r(r_h, C2_LZCR) \
, nop /* Stage 3: compute shift amount, align |v|² to bit 24. */ \
, and_i( r_h, r_h, -2) \
, li_s( r_shift, 31) \
, sub_s( r_shift, r_shift, r_h) \
, shift_aright(r_shift, r_shift, 1) \
, add_si( r_a, r_h, -24) /* r_a = LZCR - 24 (overlapping with r_recip_est; src ptr no longer needed) */ \
, branch_lt_zero(r_a, atom_offset(srav_path_fwd_to_uz, aligned_done_fwd_to_uz)) \
, nop \
, jump_rel(atom_offset(aligned_done_fwd_to_uz, srav_path_fwd_to_uz)) \
, shift_lleft_var(r_recip_est, r_recip_est, r_a) \
, atom_label(srav_path_fwd_to_uz) \
, li_s( r_a, 24) \
, sub_s( r_a, r_a, r_h) \
, shift_aright_var(r_recip_est, r_recip_est, r_a) \
, atom_label(aligned_done_fwd_to_uz) /* r_recip_est holds |v|² aligned to bit 24. */ \
, add_si( r_recip_est, r_recip_est, -64) \
, shift_lleft(r_recip_est, r_recip_est, 1) \
, load_upper_i(r_a, u4_hi(& gte_normalize_sqr_tbl)) \
, or_i_self(r_a, u4_lo(& gte_normalize_sqr_tbl)) \
, add_u(r_a, r_a, r_recip_est) \
, load_half(r_recip_est, r_a, 0) \
, nop /* Stage 4: GPF + srav finalize. */ \
, gte_mv_to_data_r(r_recip_est, C2_IR0) \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop2 \
, gte_cmdw_gpf \
, gte_mv_from_data_r(r_e, C2_MAC1) \
, gte_mv_from_data_r(r_f, C2_MAC2) \
, gte_mv_from_data_r(r_i, C2_MAC3) \
, shift_aright_var(r_e, r_e, r_shift) \
, shift_aright_var(r_f, r_f, r_shift) \
, shift_aright_var(r_i, r_i, r_shift) /* Store result.x/y/z to r_b (dst ptr = scratch+16). */ \
, store_word(r_e, r_b, O_(V3_S4,x)) \
, store_word(r_f, r_b, O_(V3_S4,y)) \
, store_word(r_i, r_b, O_(V3_S4,z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__normalize_fwd_to_uz, 59)
#define mac_resolve_look_at__normalize_right_to_ux(...) \
add_si(r_a, r_scratch, O_(ResolveLookAtScratch,right)) /* r_a = &right */ \
, add_si(r_b, r_scratch, O_(ResolveLookAtScratch,ux)) /* r_b = &ux */ \
, nop \
, load_word(r_e, r_a, O_(V3_S4,x)) \
, load_word(r_f, r_a, O_(V3_S4,y)) \
, load_word(r_i, r_a, O_(V3_S4,z)) \
, nop \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop \
, gte_cmdw_sqr \
, gte_mv_from_data_r(r_d, C2_MAC1) \
, gte_mv_from_data_r(r_g, C2_MAC2) \
, gte_mv_from_data_r(r_recip_est, C2_MAC3) \
, nop \
, add_u(r_recip_est, r_recip_est, r_g) \
, add_u(r_recip_est, r_recip_est, r_d) \
, gte_mv_to_data_r(r_recip_est, C2_LZCS) \
, nop2 \
, gte_mv_from_data_r(r_h, C2_LZCR) \
, nop \
, and_i( r_h, r_h, -2) \
, li_s( r_shift, 31) \
, sub_s( r_shift, r_shift, r_h) \
, shift_aright(r_shift, r_shift, 1) \
, add_si( r_a, r_h, -24) \
, branch_lt_zero(r_a, atom_offset(srav_path_right_to_ux, aligned_done_right_to_ux)) \
, nop \
, jump_rel(atom_offset(aligned_done_right_to_ux, srav_path_right_to_ux)) \
, shift_lleft_var(r_recip_est, r_recip_est, r_a) \
, atom_label(srav_path_right_to_ux) \
, li_s( r_a, 24) \
, sub_s( r_a, r_a, r_h) \
, shift_aright_var(r_recip_est, r_recip_est, r_a) \
, atom_label(aligned_done_right_to_ux) \
, add_si( r_recip_est, r_recip_est, -64) \
, shift_lleft(r_recip_est, r_recip_est, 1) \
, load_upper_i(r_a, u4_hi(& gte_normalize_sqr_tbl)) \
, or_i_self(r_a, u4_lo(& gte_normalize_sqr_tbl)) \
, add_u(r_a, r_a, r_recip_est) \
, load_half(r_recip_est, r_a, 0) \
, nop \
, gte_mv_to_data_r(r_recip_est, C2_IR0) \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop2 \
, gte_cmdw_gpf \
, gte_mv_from_data_r(r_e, C2_MAC1) \
, gte_mv_from_data_r(r_f, C2_MAC2) \
, gte_mv_from_data_r(r_i, C2_MAC3) \
, shift_aright_var(r_e, r_e, r_shift) \
, shift_aright_var(r_f, r_f, r_shift) \
, shift_aright_var(r_i, r_i, r_shift) \
, store_word(r_e, r_b, O_(V3_S4,x)) \
, store_word(r_f, r_b, O_(V3_S4,y)) \
, store_word(r_i, r_b, O_(V3_S4,z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__normalize_right_to_ux, 59)
#define mac_resolve_look_at__normalize_up_to_uy(...) \
add_si(r_a, r_scratch, O_(ResolveLookAtScratch,up)) /* r_a = &up */ \
, add_si(r_b, r_scratch, O_(ResolveLookAtScratch,uy)) /* r_b = &uy */ \
, nop \
, load_word(r_e, r_a, O_(V3_S4,x)) \
, load_word(r_f, r_a, O_(V3_S4,y)) \
, load_word(r_i, r_a, O_(V3_S4,z)) \
, nop \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop \
, gte_cmdw_sqr \
, gte_mv_from_data_r(r_d, C2_MAC1) \
, gte_mv_from_data_r(r_g, C2_MAC2) \
, gte_mv_from_data_r(r_recip_est, C2_MAC3) \
, nop \
, add_u(r_recip_est, r_recip_est, r_g) \
, add_u(r_recip_est, r_recip_est, r_d) \
, gte_mv_to_data_r(r_recip_est, C2_LZCS) \
, nop2 \
, gte_mv_from_data_r(r_h, C2_LZCR) \
, nop \
, and_i( r_h, r_h, -2) \
, li_s( r_shift, 31) \
, sub_s( r_shift, r_shift, r_h) \
, shift_aright(r_shift, r_shift, 1) \
, add_si( r_a, r_h, -24) \
, branch_lt_zero(r_a, atom_offset(srav_path_up_to_uy, aligned_done_up_to_uy)) \
, nop \
, jump_rel(atom_offset(aligned_done_up_to_uy, srav_path_up_to_uy)) \
, shift_lleft_var(r_recip_est, r_recip_est, r_a) \
, atom_label(srav_path_up_to_uy) \
, li_s( r_a, 24) \
, sub_s( r_a, r_a, r_h) \
, shift_aright_var(r_recip_est, r_recip_est, r_a) \
, atom_label(aligned_done_up_to_uy) \
, add_si( r_recip_est, r_recip_est, -64) \
, shift_lleft(r_recip_est, r_recip_est, 1) \
, load_upper_i(r_a, u4_hi(& gte_normalize_sqr_tbl)) \
, or_i_self(r_a, u4_lo(& gte_normalize_sqr_tbl)) \
, add_u(r_a, r_a, r_recip_est) \
, load_half(r_recip_est, r_a, 0) \
, nop \
, gte_mv_to_data_r(r_recip_est, C2_IR0) \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop2 \
, gte_cmdw_gpf \
, gte_mv_from_data_r(r_e, C2_MAC1) \
, gte_mv_from_data_r(r_f, C2_MAC2) \
, gte_mv_from_data_r(r_i, C2_MAC3) \
, shift_aright_var(r_e, r_e, r_shift) \
, shift_aright_var(r_f, r_f, r_shift) \
, shift_aright_var(r_i, r_i, r_shift) \
, store_word(r_e, r_b, O_(V3_S4,x)) \
, store_word(r_f, r_b, O_(V3_S4,y)) \
, store_word(r_i, r_b, O_(V3_S4,z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__normalize_up_to_uy, 59)
#define mac_resolve_look_at__populate_and_translate(...) \
load_word(r_look_at, R_TapePtr, O_(Binds_ResolveLookAtPopAndTrans,look_at)) \
, add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtPopAndTrans)) /* Compute the 4 scratch pointers in their dedicated GPRs. */ \
, add_si(r_pux, r_scratch, O_(ResolveLookAtScratch,ux)) /* r_pux = &ux */ \
, add_si(r_puy, r_scratch, O_(ResolveLookAtScratch,uy)) /* r_puy = &uy */ \
, add_si(r_puz, r_scratch, O_(ResolveLookAtScratch,uz)) /* r_puz = &uz */ \
, add_si(r_peye, r_scratch, O_(ResolveLookAtScratch,eye)) /* r_peye = &eye */ \
, nop /* ── m[0] = (S2)ux ── */ \
, load_word(r_tmp0, r_pux, O_(V3_S4,x)) \
, load_word(r_tmp1, r_pux, O_(V3_S4,y)) \
, 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])) /* ── Translation column t[i] = R * (-eye) ─────────────────────────────
* pos = -eye: load eye.x/y/z from r_peye, negate via sub_u from R_0. */ \
, load_word(r_tmp0, r_peye, O_(P3_S4,x)) \
, load_word(r_tmp1, r_peye, O_(P3_S4,y)) \
, load_word(r_tmp2, r_peye, O_(P3_S4,z)) \
, nop \
, sub_u(r_tmp0, R_0, r_tmp0) /* pos.x = -eye.x */ \
, sub_u(r_tmp1, R_0, r_tmp1) \
, sub_u(r_tmp2, R_0, r_tmp2) /* mtc2 IR1/2/3 = pos (for MVMVA — input vector registers). */ \
, gte_mv_to_data_r(r_tmp0, C2_IR1) \
, gte_mv_to_data_r(r_tmp1, C2_IR2) \
, gte_mv_to_data_r(r_tmp2, C2_IR3) \
, nop2 /* MVMVA: MAC1/2/3 = R * IR with cv=0 (no TR vector), mx=0 (rotation matrix),
* sf=0 (no shift), v=0 (V0 = IR1/2/3, no far-plane clipping). The pre-set
* rotation matrix is the one set by the preceding set_gte_world atom.
* gte_cmdw_mvmva is parameterless and defaults to cv=0/mx=0/sf=0/v=0. */ \
, gte_cmdw_mvmva \
, nop /* GTE interlock */ /* mfc2 MAC1/2/3 → r_tmp0/r_tmp1/r_tmp2 (sign-extended into 32-bit GPRs).
* MAC1/2/3 hold R*v with no TR add and no perspective divide — exactly the
* 3 distinct world-space translation values we need for t[0..2]. */ \
, gte_mv_from_data_r(r_tmp0, C2_MAC1) \
, gte_mv_from_data_r(r_tmp1, C2_MAC2) \
, gte_mv_from_data_r(r_tmp2, C2_MAC3) \
, nop \
, store_word(r_tmp0, r_look_at, O_(MT3_S2S4,t[0])) \
, store_word(r_tmp1, r_look_at, O_(MT3_S2S4,t[1])) \
, store_word(r_tmp2, r_look_at, O_(MT3_S2S4,t[2])) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__populate_and_translate, 50)