mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-08-07 08:08:49 +00:00
gte_nclip docs
This commit is contained in:
+34
-5
@@ -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
@@ -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
+1
Submodule toolchain/psyq_iwyu added at 5cbf9f68d1
Reference in New Issue
Block a user