Files
BFM-decomp/src/800b2.c
T
Drew T bd45f1f232 feat(decomp): main lane m13 — 34 banked
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.

  GsTMDfastG3GNL
  func_80012558
  func_800140B8
  func_80014C54
  func_80015A74
  func_80017F14
  func_80018384
  func_800183E0
  func_800191D4
  func_8001931C
  func_80019930
  func_8001BB60
  func_8001CB6C
  func_8001CF48
  func_8001D16C
  func_8001D388
  func_800243EC
  func_80028620
  func_80029124
  func_800298BC
  func_80029FE4
  func_8002AA3C
  func_8002CC4C
  func_8002D320
  func_8002D678
  func_8002E8DC
  func_8002F5C8
  func_80030470
  func_800304C8
  func_80033324
  func_80034B3C
  func_80036FB0
  func_800623A4
  gfx2D_BG0_OBJ_4D8
2026-08-25 02:08:23 -06:00

1160 lines
34 KiB
C

#include "common.h"
/*
* GsTMDfastG3GL (0x80057928) -- PsyQ libgs, HANDWRITTEN assembly (splat marks it
* "Handwritten function"). It is raw GTE code: cop2 compute ops (rtpt/nclip/avsz3/nccs),
* direct lwc2/swc2 to numbered cop2 data registers, cfc2 $31, hand-filled branch delay
* slots and explicit cop2/load-latency nops, 8 arguments (4 in $a0-$a3, 4 on the stack),
* and an allocation that uses only $t0-$t7. gcc-2.7.2 -O2 cannot emit any of this from C.
*
* So it is reproduced the way the project's other handwritten GTE bodies are
* (cookbook: DEFINE_func_8013E2C4 et al.): the whole body is one __asm__ __volatile__
* block. gcc supplies only the label and the zero-frame leaf epilogue (`jr $ra` + nop),
* which is exactly the target's tail. The GTE compute ops are written as `cop2 <imm>`
* because binutils has no rtpt/nclip/avsz3/nccs mnemonics (the splat .s gets them from
* include/gte_macros.inc, which is not reachable from inline asm):
* rtpt = 0x4A280030 -> cop2 0x0280030
* nclip = 0x4B400006 -> cop2 0x1400006
* avsz3 = 0x4B58002D -> cop2 0x158002D
* nccs = 0x4B08041B -> cop2 0x108041B
* No relocations and no symbol references at all: the function touches only its
* arguments and the GTE.
*/
void *GsTMDfastG3GL()
{
__asm__ __volatile__(
".set\tnoreorder\n"
"addiu $sp, $sp, -8\n"
"addu $10, $4, $0\n"
"lw $15, 24($sp)\n"
"lw $2, 28($sp)\n"
"lw $3, 32($sp)\n"
"lw $8, 36($sp)\n"
"lw $3, 4($3)\n"
"addu $11, $0, $0\n"
"sw $2, 12($8)\n"
"blez $15, 2f\n"
" sw $3, 16($8)\n"
"addiu $14, $8, 24\n"
"lui $13, 0xFF\n"
"ori $13, $13, 0xFFFF\n"
"addiu $9, $4, 24\n"
"1:\n"
"lhu $4, -6($9)\n"
"lhu $3, -2($9)\n"
"lhu $2, 2($9)\n"
"sll $4, $4, 3\n"
"addu $4, $5, $4\n"
"sll $3, $3, 3\n"
"addu $3, $5, $3\n"
"sll $2, $2, 3\n"
"addu $2, $5, $2\n"
"lwc2 $0, 0($4)\n"
"lwc2 $1, 4($4)\n"
"lwc2 $2, 0($3)\n"
"lwc2 $3, 4($3)\n"
"lwc2 $4, 0($2)\n"
"lwc2 $5, 4($2)\n"
"nop\n"
"nop\n"
"cop2 0x0280030\n" /* rtpt */
"addiu $2, $8, 36\n"
"cfc2 $12, $31\n"
"nop\n"
"sw $12, 0($2)\n"
"lw $2, 36($8)\n"
"nop\n"
"bltz $2, 3f\n"
" nop\n"
"nop\n"
"nop\n"
"cop2 0x1400006\n" /* nclip */
"swc2 $24, 0($14)\n"
"lw $2, 24($8)\n"
"nop\n"
"blez $2, 3f\n"
" nop\n"
"swc2 $12, 8($7)\n"
"swc2 $13, 16($7)\n"
"swc2 $14, 24($7)\n"
"nop\n"
"nop\n"
"cop2 0x158002D\n" /* avsz3 */
"swc2 $7, 0($14)\n"
"addiu $2, $10, 4\n"
"lwc2 $6, 0($2)\n"
"lhu $2, -8($9)\n"
"nop\n"
"sll $2, $2, 3\n"
"addu $2, $6, $2\n"
"lwc2 $0, 0($2)\n"
"lwc2 $1, 4($2)\n"
"nop\n"
"nop\n"
"cop2 0x108041B\n" /* nccs */
"lw $3, 24($8)\n"
"lw $2, 12($8)\n"
"nop\n"
"srav $3, $3, $2\n"
"lw $2, 16($8)\n"
"sll $3, $3, 2\n"
"addu $2, $2, $3\n"
"sw $2, 52($8)\n"
"addiu $2, $7, 4\n"
"swc2 $22, 0($2)\n"
"addiu $2, $10, 8\n"
"lwc2 $6, 0($2)\n"
"lhu $2, -4($9)\n"
"nop\n"
"sll $2, $2, 3\n"
"addu $2, $6, $2\n"
"lwc2 $0, 0($2)\n"
"lwc2 $1, 4($2)\n"
"nop\n"
"nop\n"
"cop2 0x108041B\n" /* nccs */
"lw $2, 52($8)\n"
"nop\n"
"lw $2, 0($2)\n"
"lui $3, 0x600\n"
"and $2, $2, $13\n"
"or $2, $2, $3\n"
"sw $2, 0($7)\n"
"addiu $2, $7, 12\n"
"swc2 $22, 0($2)\n"
"addiu $2, $10, 12\n"
"lwc2 $6, 0($2)\n"
"lhu $2, 0($9)\n"
"nop\n"
"sll $2, $2, 3\n"
"addu $2, $6, $2\n"
"lwc2 $0, 0($2)\n"
"lwc2 $1, 4($2)\n"
"nop\n"
"nop\n"
"cop2 0x108041B\n" /* nccs */
"lw $3, 52($8)\n"
"and $2, $7, $13\n"
"sw $2, 0($3)\n"
"addiu $2, $7, 20\n"
"swc2 $22, 0($2)\n"
"addiu $7, $7, 28\n"
"3:\n"
"addiu $11, $11, 1\n"
"addiu $9, $9, 28\n"
"slt $2, $11, $15\n"
"bne $2, $0, 1b\n"
" addiu $10, $10, 28\n"
"2:\n"
"addu $2, $7, $0\n"
"addiu $sp, $sp, 8\n"
".set\treorder\n"
: : : "memory");
}
/* GsTMDfastG3GNL (0x80057B14) -- PsyQ libgs, HANDWRITTEN assembly (splat marks it
* "Handwritten function"). Raw GTE code: cop2 compute ops (rtpt/nclip/avsz3), direct
* lwc2/swc2 to numbered cop2 data registers, cfc2 $31, hand-filled branch delay slots
* and explicit cop2/load-latency nops, 8 arguments (4 in $a0-$a3, 4 on the stack),
* allocation uses only $t0-$t7. gcc-2.7.2 -O2 cannot emit this from C.
*
* Reproduced the way the project's other handwritten GTE bodies are (see the banked
* GsTMDfastG3GL directly above): the whole body is one __asm__ __volatile__ block.
* gcc supplies only the label and the zero-frame leaf epilogue (jr $ra + nop), which
* is exactly the target's tail. GTE compute ops written as `cop2 <imm>` because
* binutils has no rtpt/nclip/avsz3 mnemonics reachable from inline asm:
* rtpt = 0x4A280030 -> cop2 0x0280030
* nclip = 0x4B400006 -> cop2 0x1400006
* avsz3 = 0x4B58002D -> cop2 0x158002D
* This is the no-lighting variant of G3GL: instead of per-vertex nccs it copies the
* primitive's three colour words (prim+4/+8/+12) straight into the packet, and the
* primitive/packet stride is 0x1C.
*/
void *GsTMDfastG3GNL()
{
__asm__ __volatile__(
".set\tnoreorder\n"
"addiu $sp, $sp, -8\n"
"lw $14, 24($sp)\n"
"lw $2, 28($sp)\n"
"lw $3, 32($sp)\n"
"lw $8, 36($sp)\n"
"lw $3, 4($3)\n"
"addu $10, $0, $0\n"
"sw $2, 12($8)\n"
"blez $14, 2f\n"
" sw $3, 16($8)\n"
"addiu $15, $8, 36\n"
"addiu $13, $8, 24\n"
"lui $11, 0xFF\n"
"ori $11, $11, 0xFFFF\n"
"addiu $6, $4, 12\n"
"addiu $9, $7, 20\n"
"1:\n"
"lhu $4, 6($6)\n"
"lhu $3, 10($6)\n"
"lhu $2, 14($6)\n"
"sll $4, $4, 3\n"
"addu $4, $5, $4\n"
"sll $3, $3, 3\n"
"addu $3, $5, $3\n"
"sll $2, $2, 3\n"
"addu $2, $5, $2\n"
"lwc2 $0, 0($4)\n"
"lwc2 $1, 4($4)\n"
"lwc2 $2, 0($3)\n"
"lwc2 $3, 4($3)\n"
"lwc2 $4, 0($2)\n"
"lwc2 $5, 4($2)\n"
"nop\n"
"nop\n"
"cop2 0x0280030\n" /* rtpt */
"lw $2, -8($6)\n"
"nop\n"
"sw $2, -16($9)\n"
"cfc2 $12, $31\n"
"nop\n"
"sw $12, 0($15)\n"
"lw $2, 36($8)\n"
"nop\n"
"bltz $2, 3f\n"
" nop\n"
"nop\n"
"nop\n"
"cop2 0x1400006\n" /* nclip */
"lw $2, -4($6)\n"
"nop\n"
"sw $2, -8($9)\n"
"swc2 $24, 0($13)\n"
"lw $2, 24($8)\n"
"nop\n"
"blez $2, 3f\n"
" nop\n"
"swc2 $12, 8($7)\n"
"swc2 $13, 16($7)\n"
"swc2 $14, 24($7)\n"
"nop\n"
"nop\n"
"cop2 0x158002D\n" /* avsz3 */
"lw $2, 0($6)\n"
"nop\n"
"sw $2, 0($9)\n"
"swc2 $7, 0($13)\n"
"lw $3, 24($8)\n"
"lw $2, 12($8)\n"
"addiu $9, $9, 28\n"
"srav $3, $3, $2\n"
"lw $2, 16($8)\n"
"sll $3, $3, 2\n"
"addu $2, $2, $3\n"
"sw $2, 52($8)\n"
"lw $3, 0($2)\n"
"lui $2, 0x600\n"
"and $3, $3, $11\n"
"or $3, $3, $2\n"
"sw $3, 0($7)\n"
"and $3, $7, $11\n"
"lw $2, 52($8)\n"
"addiu $7, $7, 28\n"
"sw $3, 0($2)\n"
"3:\n"
"addiu $10, $10, 1\n"
"slt $2, $10, $14\n"
"bne $2, $0, 1b\n"
" addiu $6, $6, 28\n"
"2:\n"
"addu $2, $7, $0\n"
"addiu $sp, $sp, 8\n"
".set\treorder\n"
: : : "memory");
}
void *GsTMDfastF3GL(void *prim, void *vert, void *norm, void *pkt,
int n, int shift, void *ot, void *work)
{
__asm__ __volatile__(
".include \"gte_macros.inc\"\n"
".set noat\n"
".set\tnoreorder\n"
"addiu $sp, $sp, -8\n"
"addu $t2, $a0, $zero\n"
"lw $t7, 24($sp)\n"
"lw $v0, 28($sp)\n"
"lw $v1, 32($sp)\n"
"lw $t0, 36($sp)\n"
"lw $v1, 4($v1)\n"
"addu $t3, $zero, $zero\n"
"sw $v0, 12($t0)\n"
"blez $t7, .L80057E70\n"
"sw $v1, 16($t0)\n"
"addiu $t6, $t0, 24\n"
"lui $t5, 255\n"
"ori $t5, $t5, 65535\n"
"addiu $t1, $a0, 16\n"
".L80057CB8:\n"
"lhu $a0, 2($t1)\n"
"lhu $v1, 4($t1)\n"
"lhu $v0, 6($t1)\n"
"sll $a0, $a0, 3\n"
"addu $a0, $a1, $a0\n"
"sll $v1, $v1, 3\n"
"addu $v1, $a1, $v1\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a1, $v0\n"
"lwc2 $0, 0($a0)\n"
"lwc2 $1, 4($a0)\n"
"lwc2 $2, 0($v1)\n"
"lwc2 $3, 4($v1)\n"
"lwc2 $4, 0($v0)\n"
"lwc2 $5, 4($v0)\n"
"nop\n"
"nop\n"
"rtpt\n"
"lw $v0, -12($t1)\n"
"nop\n"
"sw $v0, 0($t0)\n"
"lbu $v0, -13($t1)\n"
"nop\n"
"ori $v0, $v0, 16\n"
"sb $v0, 3($t0)\n"
"addiu $v0, $t0, 36\n"
"cfc2 $t4, $31\n"
"nop\n"
"sw $t4, 0($v0)\n"
"lw $v0, 36($t0)\n"
"nop\n"
"bltz $v0, .L80057E5C\n"
"nop\n"
"nop\n"
"nop\n"
"nclip\n"
"swc2 $24, 0($t6)\n"
"lw $v0, 24($t0)\n"
"nop\n"
"blez $v0, .L80057E5C\n"
"nop\n"
"swc2 $12, 8($a3)\n"
"swc2 $13, 16($a3)\n"
"swc2 $14, 24($a3)\n"
"nop\n"
"nop\n"
"avsz3\n"
"swc2 $7, 0($t6)\n"
"lwc2 $6, 0($t0)\n"
"lhu $v0, 0($t1)\n"
"nop\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a2, $v0\n"
"lwc2 $0, 0($v0)\n"
"lwc2 $1, 4($v0)\n"
"nop\n"
"nop\n"
"nccs\n"
"lw $v1, 24($t0)\n"
"lw $v0, 12($t0)\n"
"nop\n"
"srav $v1, $v1, $v0\n"
"lw $v0, 16($t0)\n"
"sll $v1, $v1, 2\n"
"addu $v0, $v0, $v1\n"
"sw $v0, 52($t0)\n"
"addiu $v0, $a3, 4\n"
"swc2 $22, 0($v0)\n"
"addiu $v0, $t2, 8\n"
"lwc2 $6, 0($v0)\n"
"lhu $v0, 0($t1)\n"
"nop\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a2, $v0\n"
"lwc2 $0, 0($v0)\n"
"lwc2 $1, 4($v0)\n"
"nop\n"
"nop\n"
"nccs\n"
"lw $v0, 52($t0)\n"
"nop\n"
"lw $v0, 0($v0)\n"
"lui $v1, 1536\n"
"and $v0, $v0, $t5\n"
"or $v0, $v0, $v1\n"
"sw $v0, 0($a3)\n"
"addiu $v0, $a3, 12\n"
"swc2 $22, 0($v0)\n"
"addiu $v0, $t2, 12\n"
"lwc2 $6, 0($v0)\n"
"lhu $v0, 0($t1)\n"
"nop\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a2, $v0\n"
"lwc2 $0, 0($v0)\n"
"lwc2 $1, 4($v0)\n"
"nop\n"
"nop\n"
"nccs\n"
"lw $v1, 52($t0)\n"
"and $v0, $a3, $t5\n"
"sw $v0, 0($v1)\n"
"addiu $v0, $a3, 20\n"
"swc2 $22, 0($v0)\n"
"addiu $a3, $a3, 28\n"
".L80057E5C:\n"
"addiu $t3, $t3, 1\n"
"addiu $t1, $t1, 24\n"
"slt $v0, $t3, $t7\n"
"bnez $v0, .L80057CB8\n"
"addiu $t2, $t2, 24\n"
".L80057E70:\n"
"addu $v0, $a3, $zero\n"
"addiu $sp, $sp, 8\n"
".set\treorder\n"
);
}
void *GsTMDfastF3GNL(void *prim, void *vert, void *norm, void *pkt,
int n, int shift, void *ot, void *work)
{
__asm__ __volatile__(
".set\tnoreorder\n"
"addiu $sp, $sp, -8\n"
"lw $t6, 24($sp)\n"
"lw $v0, 28($sp)\n"
"lw $v1, 32($sp)\n"
"lw $t0, 36($sp)\n"
"lw $v1, 4($v1)\n"
"addu $t2, $zero, $zero\n"
"sw $v0, 12($t0)\n"
"blez $t6, 2f\n"
" sw $v1, 16($t0)\n"
"lui $t3, 255\n"
"ori $t3, $t3, 65535\n"
"addiu $t5, $t0, 24\n"
"addiu $a2, $a0, 12\n"
"addiu $t1, $a3, 20\n"
"1:\n"
"lhu $a0, 6($a2)\n"
"lhu $v1, 8($a2)\n"
"lhu $v0, 10($a2)\n"
"sll $a0, $a0, 3\n"
"addu $a0, $a1, $a0\n"
"sll $v1, $v1, 3\n"
"addu $v1, $a1, $v1\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a1, $v0\n"
"lwc2 $0, 0($a0)\n"
"lwc2 $1, 4($a0)\n"
"lwc2 $2, 0($v1)\n"
"lwc2 $3, 4($v1)\n"
"lwc2 $4, 0($v0)\n"
"lwc2 $5, 4($v0)\n"
"nop\n"
"nop\n"
"cop2 0x0280030\n" /* rtpt */
"lw $v0, -8($a2)\n"
"nop\n"
"and $v0, $v0, $t3\n"
"sw $v0, -16($t1)\n"
"lbu $v0, -9($a2)\n"
"nop\n"
"ori $v0, $v0, 16\n"
"sb $v0, -13($t1)\n"
"addiu $v0, $t0, 36\n"
"cfc2 $t4, $31\n"
"nop\n"
"sw $t4, 0($v0)\n"
"lw $v0, 36($t0)\n"
"nop\n"
"bltz $v0, 3f\n"
" nop\n"
"nop\n"
"nop\n"
"cop2 0x1400006\n" /* nclip */
"lw $v0, -4($a2)\n"
"nop\n"
"sw $v0, -8($t1)\n"
"swc2 $24, 0($t5)\n"
"lw $v0, 24($t0)\n"
"nop\n"
"blez $v0, 3f\n"
" nop\n"
"swc2 $12, 8($a3)\n"
"swc2 $13, 16($a3)\n"
"swc2 $14, 24($a3)\n"
"nop\n"
"nop\n"
"cop2 0x158002D\n" /* avsz3 */
"lw $v0, 0($a2)\n"
"nop\n"
"sw $v0, 0($t1)\n"
"swc2 $7, 0($t5)\n"
"lw $v1, 24($t0)\n"
"lw $v0, 12($t0)\n"
"addiu $t1, $t1, 28\n"
"srav $v1, $v1, $v0\n"
"lw $v0, 16($t0)\n"
"sll $v1, $v1, 2\n"
"addu $v0, $v0, $v1\n"
"sw $v0, 52($t0)\n"
"lw $v1, 0($v0)\n"
"lui $v0, 1536\n"
"and $v1, $v1, $t3\n"
"or $v1, $v1, $v0\n"
"sw $v1, 0($a3)\n"
"and $v1, $a3, $t3\n"
"lw $v0, 52($t0)\n"
"addiu $a3, $a3, 28\n"
"sw $v1, 0($v0)\n"
"3:\n"
"addiu $t2, $t2, 1\n"
"slt $v0, $t2, $t6\n"
"bnez $v0, 1b\n"
" addiu $a2, $a2, 24\n"
"2:\n"
"addu $v0, $a3, $zero\n"
"addiu $sp, $sp, 8\n"
".set\treorder\n"
);
}
/* GsTMDfastF4GL - handwritten PsyQ libgs assembly (GTE cop2 ops, 12 args,
* explicit $t0-$t9 usage, hand-scheduled delay slots). Not expressible as
* compiler-generated C; encoded verbatim. gcc-2.7.2 -O2 emits no prologue for
* this frameless body and supplies the trailing "jr $ra / nop" epilogue. */
void *GsTMDfastF4GL(void)
{
__asm__ __volatile__(
".word 0x27BDFFF8\n"
".word 0x00805021\n"
".word 0x8FB90018\n"
".word 0x8FA2001C\n"
".word 0x8FA30020\n"
".word 0x8FA80024\n"
".word 0x8C630004\n"
".word 0x00005821\n"
".word 0xAD02000C\n"
".word 0x1B200094\n"
".word 0xAD030010\n"
".word 0x250F0028\n"
".word 0x3C188000\n"
".word 0x250E0018\n"
".word 0x3C0D00FF\n"
".word 0x35ADFFFF\n"
".word 0x24890014\n"
".word 0x95240002\n"
".word 0x95230004\n"
".word 0x95220006\n"
".word 0x000420C0\n"
".word 0x00A42021\n"
".word 0x000318C0\n"
".word 0x00A31821\n"
".word 0x000210C0\n"
".word 0x00A21021\n"
".word 0xC8800000\n"
".word 0xC8810004\n"
".word 0xC8620000\n"
".word 0xC8630004\n"
".word 0xC8440000\n"
".word 0xC8450004\n"
".word 0x00000000\n"
".word 0x00000000\n"
".word 0x4A280030\n"
".word 0x8D22FFF0\n"
".word 0x00000000\n"
".word 0xAD020000\n"
".word 0x9122FFEF\n"
".word 0x00000000\n"
".word 0x34420010\n"
".word 0xA1020003\n"
".word 0x484CF800\n"
".word 0x00000000\n"
".word 0xADEC0000\n"
".word 0x8D020028\n"
".word 0x00000000\n"
".word 0x00581024\n"
".word 0x14400068\n"
".word 0x00000000\n"
".word 0x00000000\n"
".word 0x00000000\n"
".word 0x4B400006\n"
".word 0xE9D80000\n"
".word 0x8D020018\n"
".word 0x00000000\n"
".word 0x18400060\n"
".word 0x00000000\n"
".word 0xE8EC0008\n"
".word 0xE8ED0010\n"
".word 0xE8EE0018\n"
".word 0x95220008\n"
".word 0x00000000\n"
".word 0x000210C0\n"
".word 0x00A21021\n"
".word 0xC8400000\n"
".word 0xC8410004\n"
".word 0x00000000\n"
".word 0x00000000\n"
".word 0x4A180001\n"
".word 0x484CF800\n"
".word 0x00000000\n"
".word 0xADEC0000\n"
".word 0x8D020028\n"
".word 0x00000000\n"
".word 0x00581024\n"
".word 0x1440004C\n"
".word 0x24E20020\n"
".word 0xE84E0000\n"
".word 0x00000000\n"
".word 0x00000000\n"
".word 0x4B68002E\n"
".word 0xE9C70000\n"
".word 0xC9060000\n"
".word 0x95220000\n"
".word 0x00000000\n"
".word 0x000210C0\n"
".word 0x00C21021\n"
".word 0xC8400000\n"
".word 0xC8410004\n"
".word 0x00000000\n"
".word 0x00000000\n"
".word 0x4B08041B\n"
".word 0x8D030018\n"
".word 0x8D02000C\n"
".word 0x00000000\n"
".word 0x00431807\n"
".word 0x8D020010\n"
".word 0x00031880\n"
".word 0x00431021\n"
".word 0xAD020038\n"
".word 0x24E20004\n"
".word 0xE8560000\n"
".word 0x25420008\n"
".word 0xC8460000\n"
".word 0x95220000\n"
".word 0x00000000\n"
".word 0x000210C0\n"
".word 0x00C21021\n"
".word 0xC8400000\n"
".word 0xC8410004\n"
".word 0x00000000\n"
".word 0x00000000\n"
".word 0x4B08041B\n"
".word 0x8D020038\n"
".word 0x00000000\n"
".word 0x8C420000\n"
".word 0x3C030800\n"
".word 0x004D1024\n"
".word 0x00431025\n"
".word 0xACE20000\n"
".word 0x24E2000C\n"
".word 0xE8560000\n"
".word 0x2542000C\n"
".word 0xC8460000\n"
".word 0x95220000\n"
".word 0x00000000\n"
".word 0x000210C0\n"
".word 0x00C21021\n"
".word 0xC8400000\n"
".word 0xC8410004\n"
".word 0x00000000\n"
".word 0x00000000\n"
".word 0x4B08041B\n"
".word 0x8D030038\n"
".word 0x00ED1024\n"
".word 0xAC620000\n"
".word 0x24E20014\n"
".word 0xE8560000\n"
".word 0x25420010\n"
".word 0xC8460000\n"
".word 0x95220000\n"
".word 0x00000000\n"
".word 0x000210C0\n"
".word 0x00C21021\n"
".word 0xC8400000\n"
".word 0xC8410004\n"
".word 0x00000000\n"
".word 0x00000000\n"
".word 0x4B08041B\n"
".word 0x24E2001C\n"
".word 0xE8560000\n"
".word 0x24E70024\n"
".word 0x256B0001\n"
".word 0x25290020\n"
".word 0x0179102A\n"
".word 0x1440FF74\n"
".word 0x254A0020\n"
".word 0x00E01021\n"
".word 0x27BD0008\n"
);
}
/* GsTMDfastF4GNL @ 0x80058284 -- HANDWRITTEN PsyQ libgs TMD primitive walker
* (flat, 4-vertex, lit, non-textured "fast" path). Splat marks it "Handwritten
* function": raw GTE code (rtpt/nclip/rtps/avsz4), direct lwc2/swc2 to numbered
* cop2 data registers, cfc2 $31, hand-filled branch delay slots and explicit
* load-latency nops, 8 arguments (4 in $a0-$a3, 4 on the stack), allocation in
* $t0-$t9 only. Not expressible as compiler-generated C; reproduced verbatim
* the way the project's other handwritten GTE bodies are (see GsTMDfastG3GL
* above): one __asm__ __volatile__ block under .set noreorder. gcc supplies the
* label, the 8-byte frame for the two-word flag/otz scratch pair, and the
* trailing "jr $ra / nop" epilogue -- exactly the target's head and tail.
* GTE compute ops are written as `cop2 <imm>` (binutils has no mnemonics):
* rtpt = 0x4A280030 -> cop2 0x0280030
* nclip = 0x4B400006 -> cop2 0x1400006
* rtps = 0x4A180001 -> cop2 0x0180001
* avsz4 = 0x4B68002E -> cop2 0x168002E
* No relocations and no symbol references: the body touches only its arguments,
* the stack scratch pair and the GTE. */
void *GsTMDfastF4GNL()
{
volatile int g[2];
__asm__ __volatile__(
".set\tnoreorder\n"
"lw $24, 24($29)\n"
"lw $2, 28($29)\n"
"lw $3, 32($29)\n"
"lw $8, 36($29)\n"
"lw $3, 4($3)\n"
"addu $10, $0, $0\n"
"sw $2, 12($8)\n"
"blez $24, 2f\n"
" sw $3, 16($8)\n"
"lui $11, 0xFF\n"
"ori $11, $11, 0xFFFF\n"
"addiu $14, $8, 40\n"
"lui $15, 0x8000\n"
"addiu $13, $8, 24\n"
"addiu $6, $4, 16\n"
"addiu $9, $7, 28\n"
"1:\n"
"lhu $4, 6($6)\n"
"lhu $3, 8($6)\n"
"lhu $2, 10($6)\n"
"sll $4, $4, 3\n"
"addu $4, $5, $4\n"
"sll $3, $3, 3\n"
"addu $3, $5, $3\n"
"sll $2, $2, 3\n"
"addu $2, $5, $2\n"
"lwc2 $0, 0($4)\n"
"lwc2 $1, 4($4)\n"
"lwc2 $2, 0($3)\n"
"lwc2 $3, 4($3)\n"
"lwc2 $4, 0($2)\n"
"lwc2 $5, 4($2)\n"
"nop\n"
"nop\n"
"cop2 0x0280030\n" /* rtpt */
"lw $2, -12($6)\n"
"nop\n"
"and $2, $2, $11\n"
"sw $2, -24($9)\n"
"lbu $2, -13($6)\n"
"nop\n"
"ori $2, $2, 0x10\n"
"sb $2, -21($9)\n"
"cfc2 $12, $31\n"
"nop\n"
"sw $12, 0($14)\n"
"lw $2, 40($8)\n"
"nop\n"
"and $2, $2, $15\n"
"bnez $2, 3f\n"
" nop\n"
"nop\n"
"nop\n"
"cop2 0x1400006\n" /* nclip */
"lw $2, -8($6)\n"
"nop\n"
"sw $2, -16($9)\n"
"swc2 $24, 0($13)\n"
"lw $2, 24($8)\n"
"nop\n"
"blez $2, 3f\n"
" nop\n"
"swc2 $12, 8($7)\n"
"swc2 $13, 16($7)\n"
"swc2 $14, 24($7)\n"
"lhu $2, 12($6)\n"
"nop\n"
"sll $2, $2, 3\n"
"addu $2, $5, $2\n"
"lwc2 $0, 0($2)\n"
"lwc2 $1, 4($2)\n"
"nop\n"
"nop\n"
"cop2 0x0180001\n" /* rtps */
"lw $2, -4($6)\n"
"nop\n"
"sw $2, -8($9)\n"
"cfc2 $12, $31\n"
"nop\n"
"sw $12, 0($14)\n"
"lw $2, 40($8)\n"
"nop\n"
"and $2, $2, $15\n"
"bnez $2, 3f\n"
" addiu $2, $7, 32\n"
"swc2 $14, 0($2)\n"
"nop\n"
"nop\n"
"cop2 0x168002E\n" /* avsz4 */
"lw $2, 0($6)\n"
"nop\n"
"sw $2, 0($9)\n"
"swc2 $7, 0($13)\n"
"lw $3, 24($8)\n"
"lw $2, 12($8)\n"
"addiu $9, $9, 36\n"
"srav $3, $3, $2\n"
"lw $2, 16($8)\n"
"sll $3, $3, 2\n"
"addu $2, $2, $3\n"
"sw $2, 56($8)\n"
"lw $3, 0($2)\n"
"lui $2, 0x800\n"
"and $3, $3, $11\n"
"or $3, $3, $2\n"
"sw $3, 0($7)\n"
"and $3, $7, $11\n"
"lw $2, 56($8)\n"
"addiu $7, $7, 36\n"
"sw $3, 0($2)\n"
"3:\n"
"addiu $10, $10, 1\n"
"slt $2, $10, $24\n"
"bnez $2, 1b\n"
" addiu $6, $6, 32\n"
"2:\n"
"addu $2, $7, $0\n"
".set\treorder\n"
: : : "memory");
}
/*
* GsTMDfastG4GL @ 0x8005845C -- HANDWRITTEN PsyQ libgs TMD primitive walker
* (gouraud, 4-vertex, lit, non-textured "fast" path).
*
* Splat marks this "Handwritten function": it is raw GTE assembly, not
* compiler output --
* - long-lived state in $t0..$t9 (never gcc's allocation order),
* - extra arguments read from the CALLER's frame at 0x18..0x24($sp) after a
* manual `addiu $sp,$sp,-8`, i.e. a private calling convention,
* - cop2 data-register traffic (lwc2/swc2 $0..$27), rtpt/rtps/nclip/avsz4/
* nccs, `cfc2 $t4,$31` flag reads and the mandatory cop2-latency `nop`s.
* None of that is reachable from C, so the body is written as one full inline
* asm block (cookbook: the func_801285E4 / func_80128714 full-inline-asm
* handwritten-wrapper idiom, and the §"handwritten GTE sqr" note).
*
* maspsx interaction (this is the whole trick):
* - the leading `.set<TAB>noreorder` is written with a TAB so maspsx's own
* is_reorder tracker flips to False -- otherwise maspsx auto-fills EVERY
* branch delay slot with a nop, and this function has REAL instructions in
* its delay slots (`sw $v1,16($t1)`, `addiu $v0,$a3,32`, `addiu $t2,..`).
* - maspsx's load-delay pass (_handle_nop_before_next_instruction) is NOT
* gated on is_reorder: it still injects a nop when the next instruction
* re-reads a load's destination through a base register. That fires exactly
* once here, on `lw $v0,56($t1)` -> `lw $v0,0($v0)`, so that one latency nop
* is deliberately NOT written by hand (maspsx emits it).
* - every memory offset is DECIMAL: maspsx's store path calls int(operand)
* base-10 and would raise on "0x38".
*
* Shape of the routine:
* for (i = 0; i < n; i++) // n = arg at 0x18($sp), prim stride 0x24
* RTPT the three leading vertex indices, bail on GTE flag bit31,
* NCLIP + backface/otz reject, RTPS the 4th vertex, AVSZ4 -> OT bucket
* (ot_base + ((otz >> shift) << 2)), then four NCCS colour passes writing
* the packet, and link the packet into the OT.
*/
void GsTMDfastG4GL(void)
{
__asm__ __volatile__(
".set\tnoreorder\n"
"addiu $sp, $sp, -8\n"
"addu $t2, $a0, $zero\n"
"lw $t9, 24($sp)\n"
"lw $v0, 28($sp)\n"
"lw $v1, 32($sp)\n"
"lw $t1, 36($sp)\n"
"lw $v1, 4($v1)\n"
"addu $t3, $zero, $zero\n"
"sw $v0, 12($t1)\n"
"blez $t9, 2f\n"
"sw $v1, 16($t1)\n"
"addiu $t7, $t1, 40\n"
"lui $t8, 0x8000\n"
"addiu $t6, $t1, 24\n"
"lui $t5, 0xff\n"
"ori $t5, $t5, 0xffff\n"
"addiu $t0, $a0, 32\n"
"1:\n"
"lhu $a0, -10($t0)\n"
"lhu $v1, -6($t0)\n"
"lhu $v0, -2($t0)\n"
"sll $a0, $a0, 3\n"
"addu $a0, $a1, $a0\n"
"sll $v1, $v1, 3\n"
"addu $v1, $a1, $v1\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a1, $v0\n"
"lwc2 $0, 0($a0)\n"
"lwc2 $1, 4($a0)\n"
"lwc2 $2, 0($v1)\n"
"lwc2 $3, 4($v1)\n"
"lwc2 $4, 0($v0)\n"
"lwc2 $5, 4($v0)\n"
"nop\n"
"nop\n"
"rtpt\n"
"cfc2 $t4, $31\n"
"nop\n"
"sw $t4, 0($t7)\n"
"lw $v0, 40($t1)\n"
"nop\n"
"and $v0, $v0, $t8\n"
"bne $v0, $zero, 3f\n"
"nop\n"
"nop\n"
"nop\n"
"nclip\n"
"swc2 $24, 0($t6)\n"
"lw $v0, 24($t1)\n"
"nop\n"
"blez $v0, 3f\n"
"nop\n"
"swc2 $12, 8($a3)\n"
"swc2 $13, 16($a3)\n"
"swc2 $14, 24($a3)\n"
"lhu $v0, 2($t0)\n"
"nop\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a1, $v0\n"
"lwc2 $0, 0($v0)\n"
"lwc2 $1, 4($v0)\n"
"nop\n"
"nop\n"
"rtps\n"
"cfc2 $t4, $31\n"
"nop\n"
"sw $t4, 0($t7)\n"
"lw $v0, 40($t1)\n"
"nop\n"
"and $v0, $v0, $t8\n"
"bne $v0, $zero, 3f\n"
"addiu $v0, $a3, 32\n"
"swc2 $14, 0($v0)\n"
"nop\n"
"nop\n"
"avsz4\n"
"swc2 $7, 0($t6)\n"
"addiu $v0, $t2, 4\n"
"lwc2 $6, 0($v0)\n"
"lhu $v0, -12($t0)\n"
"nop\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a2, $v0\n"
"lwc2 $0, 0($v0)\n"
"lwc2 $1, 4($v0)\n"
"nop\n"
"nop\n"
"nccs\n"
"lw $v1, 24($t1)\n"
"lw $v0, 12($t1)\n"
"nop\n"
"srav $v1, $v1, $v0\n"
"lw $v0, 16($t1)\n"
"sll $v1, $v1, 2\n"
"addu $v0, $v0, $v1\n"
"sw $v0, 56($t1)\n"
"addiu $v0, $a3, 4\n"
"swc2 $22, 0($v0)\n"
"addiu $v0, $t2, 8\n"
"lwc2 $6, 0($v0)\n"
"lhu $v0, -8($t0)\n"
"nop\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a2, $v0\n"
"lwc2 $0, 0($v0)\n"
"lwc2 $1, 4($v0)\n"
"nop\n"
"nop\n"
"nccs\n"
"lw $v0, 56($t1)\n"
"lw $v0, 0($v0)\n"
"lui $v1, 0x800\n"
"and $v0, $v0, $t5\n"
"or $v0, $v0, $v1\n"
"sw $v0, 0($a3)\n"
"addiu $v0, $a3, 12\n"
"swc2 $22, 0($v0)\n"
"addiu $v0, $t2, 12\n"
"lwc2 $6, 0($v0)\n"
"lhu $v0, -4($t0)\n"
"nop\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a2, $v0\n"
"lwc2 $0, 0($v0)\n"
"lwc2 $1, 4($v0)\n"
"nop\n"
"nop\n"
"nccs\n"
"lw $v1, 56($t1)\n"
"and $v0, $a3, $t5\n"
"sw $v0, 0($v1)\n"
"addiu $v0, $a3, 20\n"
"swc2 $22, 0($v0)\n"
"addiu $v0, $t2, 16\n"
"lwc2 $6, 0($v0)\n"
"lhu $v0, 0($t0)\n"
"nop\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a2, $v0\n"
"lwc2 $0, 0($v0)\n"
"lwc2 $1, 4($v0)\n"
"nop\n"
"nop\n"
"nccs\n"
"addiu $v0, $a3, 28\n"
"swc2 $22, 0($v0)\n"
"addiu $a3, $a3, 36\n"
"3:\n"
"addiu $t3, $t3, 1\n"
"addiu $t0, $t0, 36\n"
"slt $v0, $t3, $t9\n"
"bne $v0, $zero, 1b\n"
"addiu $t2, $t2, 36\n"
"2:\n"
"addu $v0, $a3, $zero\n"
"addiu $sp, $sp, 8\n"
/* Hand the tracker back: maspsx SWALLOWS .set lines (they never reach
* gas, which is already noreorder from the .ent hook), so this only
* flips is_reorder back to True -- just in time for maspsx to fill the
* delay slot of gcc's own epilogue `j $31` with the final nop. */
".set\treorder\n"
: : : "memory");
}
void GsTMDfastG4GNL(void)
{
__asm__ __volatile__(
".set\tnoreorder\n"
"addiu $sp, $sp, -8\n"
"lw $t8, 24($sp)\n"
"lw $v0, 28($sp)\n"
"lw $v1, 32($sp)\n"
"lw $t0, 36($sp)\n"
"lw $v1, 4($v1)\n"
"addu $t2, $zero, $zero\n"
"sw $v0, 12($t0)\n"
"blez $t8, 2f\n"
"sw $v1, 16($t0)\n"
"addiu $t6, $t0, 40\n"
"lui $t7, 0x8000\n"
"addiu $t5, $t0, 24\n"
"lui $t3, 0xff\n"
"ori $t3, $t3, 0xffff\n"
"addiu $a2, $a0, 16\n"
"addiu $t1, $a3, 28\n"
"1:\n"
"lhu $a0, 6($a2)\n"
"lhu $v1, 10($a2)\n"
"lhu $v0, 14($a2)\n"
"sll $a0, $a0, 3\n"
"addu $a0, $a1, $a0\n"
"sll $v1, $v1, 3\n"
"addu $v1, $a1, $v1\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a1, $v0\n"
"lwc2 $0, 0($a0)\n"
"lwc2 $1, 4($a0)\n"
"lwc2 $2, 0($v1)\n"
"lwc2 $3, 4($v1)\n"
"lwc2 $4, 0($v0)\n"
"lwc2 $5, 4($v0)\n"
"nop\n"
"nop\n"
"rtpt\n"
"lw $v0, -12($a2)\n"
"nop\n"
"sw $v0, -24($t1)\n"
"cfc2 $t4, $31\n"
"nop\n"
"sw $t4, 0($t6)\n"
"lw $v0, 40($t0)\n"
"nop\n"
"and $v0, $v0, $t7\n"
"bne $v0, $zero, 3f\n"
"nop\n"
"nop\n"
"nop\n"
"nclip\n"
"lw $v0, -8($a2)\n"
"nop\n"
"sw $v0, -16($t1)\n"
"swc2 $24, 0($t5)\n"
"lw $v0, 24($t0)\n"
"nop\n"
"blez $v0, 3f\n"
"nop\n"
"swc2 $12, 8($a3)\n"
"swc2 $13, 16($a3)\n"
"swc2 $14, 24($a3)\n"
"lhu $v0, 18($a2)\n"
"nop\n"
"sll $v0, $v0, 3\n"
"addu $v0, $a1, $v0\n"
"lwc2 $0, 0($v0)\n"
"lwc2 $1, 4($v0)\n"
"nop\n"
"nop\n"
"rtps\n"
"lw $v0, -4($a2)\n"
"nop\n"
"sw $v0, -8($t1)\n"
"cfc2 $t4, $31\n"
"nop\n"
"sw $t4, 0($t6)\n"
"lw $v0, 40($t0)\n"
"nop\n"
"and $v0, $v0, $t7\n"
"bne $v0, $zero, 3f\n"
"addiu $v0, $a3, 32\n"
"swc2 $14, 0($v0)\n"
"nop\n"
"nop\n"
"avsz4\n"
"lw $v0, 0($a2)\n"
"nop\n"
"sw $v0, 0($t1)\n"
"swc2 $7, 0($t5)\n"
"lw $v1, 24($t0)\n"
"lw $v0, 12($t0)\n"
"addiu $t1, $t1, 36\n"
"srav $v1, $v1, $v0\n"
"lw $v0, 16($t0)\n"
"sll $v1, $v1, 2\n"
"addu $v0, $v0, $v1\n"
"sw $v0, 56($t0)\n"
"lw $v1, 0($v0)\n"
"lui $v0, 0x800\n"
"and $v1, $v1, $t3\n"
"or $v1, $v1, $v0\n"
"sw $v1, 0($a3)\n"
"and $v1, $a3, $t3\n"
"lw $v0, 56($t0)\n"
"addiu $a3, $a3, 36\n"
"sw $v1, 0($v0)\n"
"3:\n"
"addiu $t2, $t2, 1\n"
"slt $v0, $t2, $t8\n"
"bne $v0, $zero, 1b\n"
"addiu $a2, $a2, 36\n"
"2:\n"
"addu $v0, $a3, $zero\n"
"addiu $sp, $sp, 8\n"
".set\treorder\n"
: : : "memory");
}