gte_nclip docs

This commit is contained in:
ed
2026-06-04 19:40:21 -04:00
parent 8d03366d92
commit 915b14ef31
3 changed files with 107 additions and 77 deletions
+34 -5
View File
@@ -509,7 +509,7 @@ enum { _C2_OPS_ = 0
*/ */
#define gte_rtpt() \ #define gte_rtpt() \
asm volatile( \ asm volatile( \
asm_inline( nop(), nop(), gte_cmdw_rtpt ) \ asm_inline( nop, nop, gte_cmdw_rtpt ) \
asm_clobber( clb_system ) \ asm_clobber( clb_system ) \
) )
@@ -519,11 +519,40 @@ enum { _C2_OPS_ = 0
"nop;" \ "nop;" \
"cop2 0x0280030;") "cop2 0x0280030;")
/**
* @brief Normal clipping (8 cycles)
*
* @details Computes the sign of three screen coordinates (C2_SXY0-2) used for
* backface culling. If the value of C2_MAC0 is negative, the coordinates are
* inverted and thus the triangle is back facing.
*
* The following equation is performed when executing this GTE command:
*
* MAC0 = SX0*SY1 + SX1*SY2 + SX2*SY0 - SX0*SY2 - SX1*SY0 - SX2*SY1
*
* Encoder-style emission (no inline-asm strings in the code body):
* 1. Two `nop` words fill the COP2 pipeline latency - the GTE
* pipeline takes a few cycles per op, and the nops let any
* preceding lwc2/swc2/RTPT retire before NCLIP starts reading
* its inputs from SXY0/SXY1/SXY2.
* 2. The NCLIP command word itself is `gte_cmdw_nclip` (see the
* pre-baked encoders above) - `0x01400006` decoded as
* `op_cop2` | CO(1) | cmd=NCLIP, with all SF/MX/V/CV/LM fields
* zero. NCLIP is spec-clean in the original PsyQ source
* (unlike RTPS/RTPT which carry the `gte_cmdw_psyq_compat`
* quirk), so `gte_cmdw_nclip` does NOT OR in any reserved bits.
*
* Clobbers the caller-saved GPRs via `clb_system` (per the kernel
* ABI) plus the standard "memory" barrier. Does not clobber any COP2
* data/control register - those have to be saved by the caller if
* they need to survive across the call (NCLIP writes MAC0 only; it
* is purely a sign-of-double-product computation on SXY0..2).
*/
#define gte_nclip() \ #define gte_nclip() \
__asm__ volatile( \ asm volatile( \
"nop;" \ asm_inline( nop, nop, gte_cmdw_nclip ) \
"nop;" \ asm_clobber( clb_system ) \
"cop2 0x01400006;") )
#define gte_stotz(r0) __asm__ volatile("swc2 $7, 0( %0 )" : : "r"(r0) : "memory") #define gte_stotz(r0) __asm__ volatile("swc2 $7, 0( %0 )" : : "r"(r0) : "memory")
+4 -4
View File
@@ -231,7 +231,7 @@ enum { _BitOffsets = 0
* shift_ll(rd, rt, shamt) → sll rd, rt, shamt * shift_ll(rd, rt, shamt) → sll rd, rt, shamt
* jump_reg(rs) → jr rs * jump_reg(rs) → jr rs
* jump_link(rs, rd) → jalr rs (link in rd, default $ra) * jump_link(rs, rd) → jalr rs (link in rd, default $ra)
* nop() → sll $0, $0, 0 * nop → sll $0, $0, 0
*/ */
#define load_word(rt, base, off) enc_i(op_lw, (base), (rt), (off)) #define load_word(rt, base, off) enc_i(op_lw, (base), (rt), (off))
#define load_byte(rt, base, off) enc_i(op_lb, (base), (rt), (off)) #define load_byte(rt, base, off) enc_i(op_lb, (base), (rt), (off))
@@ -335,7 +335,7 @@ enum { _BitOffsets = 0
#define shamt(rd, rt, n) shift_ll(rd, rt, n) #define shamt(rd, rt, n) shift_ll(rd, rt, n)
/* nop — canonical sll $0, $0, 0 */ /* nop — canonical sll $0, $0, 0 */
#define nop() shift_ll(rdiscard, rdiscard, 0) #define nop shift_ll(rdiscard, rdiscard, 0)
#define load_imm_1w(rt, imm) add_ui((rt), R_0, (imm)) #define load_imm_1w(rt, imm) add_ui((rt), R_0, (imm))
#define load_imm_1w_s0(rt, imm) add_si((rt)), R_0, (imm)) #define load_imm_1w_s0(rt, imm) add_si((rt)), R_0, (imm))
@@ -491,7 +491,7 @@ Code CodeBlob_(mips_flush_icache) {
add_ui(rret_0, rdiscard, bios_flushcache), /* addiu $a0, $0, 0x44 */ add_ui(rret_0, rdiscard, bios_flushcache), /* addiu $a0, $0, 0x44 */
add_ui(rtmp_0, rdiscard, bios_table_addr), /* addiu $t0, $0, 0xA0 */ add_ui(rtmp_0, rdiscard, bios_table_addr), /* addiu $t0, $0, 0xA0 */
jump_link(rtmp_0, rret_addr), /* jalr $t0, $ra */ jump_link(rtmp_0, rret_addr), /* jalr $t0, $ra */
nop(), /* BD slot */ nop, /* BD slot */
load_word(rret_addr, rstack_ptr, 4), /* lw $ra, 4($sp) */ load_word(rret_addr, rstack_ptr, 4), /* lw $ra, 4($sp) */
jump_reg(rret_addr), /* jr $ra */ jump_reg(rret_addr), /* jr $ra */
add_ui(rstack_ptr, rstack_ptr, 8) /* sp += 8 (BD) */ add_ui(rstack_ptr, rstack_ptr, 8) /* sp += 8 (BD) */
@@ -511,7 +511,7 @@ FI_ void mips_flush_icache(void) { C_(VoidFn*, codeblob_mips_flush_icache)(); }
, add_ui(rret_0, rdiscard, bios_flushcache) \ , add_ui(rret_0, rdiscard, bios_flushcache) \
, add_ui(rtmp_0, rdiscard, bios_table_addr) \ , add_ui(rtmp_0, rdiscard, bios_table_addr) \
, jump_link(rtmp_0, rret_addr) \ , jump_link(rtmp_0, rret_addr) \
, nop() \ , nop \
, load_word(rret_addr, rstack_ptr, 4) \ , load_word(rret_addr, rstack_ptr, 4) \
, jump_reg(rret_addr) \ , jump_reg(rret_addr) \
, add_ui(rstack_ptr, rstack_ptr, 8) \ , add_ui(rstack_ptr, rstack_ptr, 8) \
Submodule toolchain/psyq_iwyu added at 5cbf9f68d1