Files
TeslaRel410/sda4/DPL3/VRENDER/PXPL5SUP/PXPL5OPT.S
T
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
Un-ignored: the dev drive is the ground truth the restoration and
emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer
source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio
content). Kept in-repo for the pod-owner community.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:41:15 -05:00

3125 lines
72 KiB
ArmAsm

// nicked from output of PGC Rel 1.4 -opt 2
.text
.align 8
.text
//{{{ Heavy description
//
// DIVISION pxpl5 support code
//
// over and above the normal transform / light / clip, pxpl5
// requires triangles to be prepared for display by converting them
// into screen-space linear expressions. Both scan-conversion and shading
// information need to be so converted
//
// constructing linear expressions for scan-conversion is EDGIZing
// constructing linear expressions for shading is PLANARIZing
// putting triangles into 64x128 pixel bins is BINITIZing
//
// these are some optimized routines for edgizing, planarizing and
// binitizing
//
// it is clear that this software is just not fast enough when coded in C for
// 2 reasons - inefficient register usage (crap compiler) and excessive memory
// hits. Memory hits occur at function calls, where stack frames are moved
// and registers saved away to adhere to C calling conventions - lets trash
// the calling conventions (and make this undebuggable!)
//
// The functions below are very optimized to NEVER hit memory. The price
// we pay is that they are not directly callable in C - the C-callable
// code is in pxpl5tri.ss, and is a bunch of triangle functions, which
// save away volatile registers, chain together calls to these functions,
// then restore registers and return
//
// HOWEVER - note safe_binitize_fn, which every 256 triangles or so is forced
// to call some C, and which may under worst-case circumstances call malloc.
// dont be scared, it works
//
// depressing timings - the gayboy coding of planarize executes in 116 ticks,
// the steroid-laden version 73 ticks - this is for 32 fpu ops. So, I
// shall make this even worse, by introducing a zbuf_plus2_fn, which
// both z-buffers, AND planarizes 2 other functions at the same time. This
// can take advantage of the 3-ness of the i860 pipe by unrolling 3
// planarizations at once. It is also optimized for the PAZ primitive of
// z-buffer, luminance, specularity - using z-buffer, planar, planar I get
// 97k triangles/sec .. lets try to get 130k from zbuf_plus2_fn
//
// oh rats - the VERTEX and NORM_COL are now separated in memory - I need to
// pass in offset from Z, otherOffset from Z into z_buf_plus2
//
// define some useful registers, which are
// pointers to 4 vertices rv1 .. rv4
// 4 x coordinates fx1 .. fx4
// 4 y coordinates fy1 .. fy4
// 3 value coordinates fv1 .. fv3
// minimaxes fminx, fminy, fmaxx, fmaxy
// repeated expressions fx23, fx31, fx12, fC
//}}}
//{{{ declare register assignments
//
//
// integer registers first
//
//
//
//
//
//
// put r1 in here for bri
// and I dont need
// fp param regs start at f16 (pig!) so we have no choice but to use low
// fp regs
// its not clear how to make sure they dont get thumped - by carefully lining
// up important floats with the correct API registers, transfers are
// minimized, and all above f16 are safe for permanent
// storage - however, it aint apparent how pgi allocate temporary floats
// i'll try to get away with doing no maths? but that's a pig since I have
// to pre-multiply texture coordinates by homo corrdinate, and that must be
// done after clipping. So lets roll the homo prod into the floating-point
// front end, and simply assume that what are in the vertices are genuinely
// scan-convertible values; so I need to have fixed homo from Z - more
// assembly code i fear
//
//
//
// fp registers
//
//
// screen-space minimax for binitizing
// PASS NO FLOAT PARAMETERS IN HERE OR YOU ARE S T U F F E D
//
// x, y coords for tris/quads
// repeated expressions fx32, fx13, fx21, fC
// screen-space function values for planarizing
//}}}
//
// these are the function prototypes
//
// extern void preplanarize_fn ( float *coeffs, VERTEX *v1, VERTEX *v2, VERTEX *v3, VERTEX *v4 );
// extern void edgize_tri_fn ( void );
// extern void edgize_quad_fn ( void );
// extern void zbuffer_fn ( void );
// extern void zb_plus2_fn ( void );
// extern void planarize_fn ( int pp5_opcode, int index );
// extern void binitize_fn ( int macro_lo, int macro_hi,
// int scrmaxx, int scrmaxy, int scrbinsx )
// extern void safe_binitize_fn ( int macro_lo, int macro_hi, int scrbinsx )
//
//{{{ preplanarize_fn
//
//
//
.globl _preplanarize_fn
.align 8
//
// preplanarize_fn ( float *coeffs, unused, v1, v2, v3, v4 );
//
// preplanarize sets up all of the triangle code
//
// we need to cache all x,y into registers,
// precompute x23, x31, x12 and C, and determine
// minimax x, y for the triangle
//
//
_preplanarize_fn::
//
// scattered amongst these minimax tests are the subtractions
// to precompute v2[Y] - v3[Y] etc for computing 1.0f/C
//
// p->x23=v2x - v3x;
// p->x31=v3x - v1x;
// p->x12=v1x - v2x;
//
fld.d 0( r18 ), f12
fld.d 0( r19 ), f14
fld.d 0( r20 ), f16
// fld.d 0( r18 ), f12 // load x AND y in same op
// fld.d 0( r19 ), f14
// fld.d 0( r20 ), f16
orh ha%.C00037, r0, r31 // pre-load 2.0000e+00
// now minimax x
// algorithm
//
// if (a > b) {
// maxx=a;
// minx=b;
// }
// else {
// maxx=b;
// minx=a;
// }
//
// if (c > maxx) {
// maxc=c;
// }
// else if (c < minx) {
// minx=c;
// }
// now minimax x
pfsub.ss f13 , f15 , f0
pfsub.ss f15 , f17 , f0
pfsub.ss f17 , f13 , f0
pfsub.ss f0, f0, f22
pfsub.ss f0, f0, f20
pfgt.ss f12 , f14 , f21
bc _fx1gtfx2
_fx2gtfx1::
fmov.ss f14 , f10
br _checkx3
fmov.ss f12 , f8
_fx1gtfx2::
fmov.ss f12 , f10
fmov.ss f14 , f8
_checkx3::
pfgt.ss f16 , f10 , f0
bc _fx3max
pfgt.ss f8 , f16 , f0
bc _fx3min
br _minimaxy
_fx3min::
fmov.ss f16 , f8
br _minimaxydb
pfgt.ss f13 , f15 , f0
_fx3max::
fmov.ss f16 , f10
// now minimax y
_minimaxy::
pfgt.ss f13 , f15 , f0
_minimaxydb::
bc _fy1gtfy2
_fy2gtfy1::
fmov.ss f15 , f11
br _checky3
fmov.ss f13 , f9
_fy1gtfy2::
fmov.ss f13 , f11
fmov.ss f15 , f9
_checky3::
pfgt.ss f17 , f11 , f0
fld.l l%.C00037(r31), f30
bc _fy3max
pfgt.ss f9 , f17 , f0
bc _fy3min
br _endminimaxdb
pfmul.ss f12 , f20 , f0 // delayed branch op repeated
_fy3min::
fmov.ss f17 , f9
br _endminimaxdb
pfmul.ss f12 , f20 , f0 // delayed branch op repeated
_fy3max::
fmov.ss f17 , f11
// repeated expressions f20 , f21 , f22 , f23
//
// The definitive planarization algorithm
//
// invC=1.0f / ( f12 * ( f15 - f17 )) +
// ( f14 * ( f17 - f13 )) +
// ( f16 * ( f13 - f15 ));
//
// eqn[0]= invC*( f13 * ( f26 - f25 )) +
// ( f15 * ( f24 - f26 )) +
// ( f17 * ( f25 - f24 ));
//
// eqn[1]= invC*( f24 * ( f16 - f14 )) +
// ( f25 * ( f12 - f16 )) +
// ( f26 * ( f14 - f12 ));
//
// eqn[2]= invC*( f12 *(( f15 * f26 ) - ( f17 * f25 ))) +
// ( f14 *(( f17 * f24 ) - ( f13 * f26 ))) +
// ( f16 *(( f13 * f25 ) - ( f15 * f24 )));
//
// 11 ticks all told
_endminimax::
pfmul.ss f12 , f20 , f0
_endminimaxdb::
pfmul.ss f14 , f21 , f0
pfmul.ss f16 , f22 , f0
// use T-reg as staging post...
rat1s2.ss f12 , f16 , f0
i2pt.ss f0, f0, f0
rat1s2.ss f14 , f12 , f0
pfsub.ss f16 , f14 , f21
i2apt.ss f0, f0, f0
pfadd.ss f0, f0, f22
pfadd.ss f0, f0, f20
pfadd.ss f0, f0, f23
//
// straight out of the i860 prog ref man
//
// to iterate towards 1/V;
//
// G_new=G_old*(2.0f-(G_old*V))
//
// 20 ticks !? pretty poor
frcp.ss f23 , f28 // start 1.0 / f23 - 2^-8
fmul.ss f23 , f28 , f29 // guess * divisor
fsub.ss f30 , f29 , f29 // 2 - (guess * divisor)
fmul.ss f28 , f29 , f28 // 2^-15
fmul.ss f23 , f28 , f29 // guess * divisor
fsub.ss f30 , f29 , f29 // 2 - (guess * divisor)
bri r1
fmul.ss f28 , f29 , f23 // 2^-23 - run with it
//}}}
//{{{ preplanarize_fn_p
//
//
//
.globl _preplanarize_fn_p
.align 8
//
// preplanarize_fn ( float *coeffs, unused, v1, v2, v3, v4 );
//
// preplanarize sets up all of the triangle code
//
// we need to cache all x,y into registers,
// precompute x23, x31, x12 and C, and determine
// minimax x, y for the triangle
//
//
_preplanarize_fn_p::
//
// scattered amongst these minimax tests are the subtractions
// to precompute v2[Y] - v3[Y] etc for computing 1.0f/C
//
// p->x23=v2x - v3x;
// p->x31=v3x - v1x;
// p->x12=v1x - v2x;
//
// fld.d 0( r18 ), f12
// fld.d 0( r19 ), f14
// fld.d 0( r20 ), f16
// fld.d 0( r18 ), f12 // load x AND y in same op
// fld.d 0( r19 ), f14
// fld.d 0( r20 ), f16
orh ha%.C00037, r0, r31 // pre-load 2.0000e+00
// now minimax x
// algorithm
//
// if (a > b) {
// maxx=a;
// minx=b;
// }
// else {
// maxx=b;
// minx=a;
// }
//
// if (c > maxx) {
// maxc=c;
// }
// else if (c < minx) {
// minx=c;
// }
// now minimax x
pfsub.ss f13 , f15 , f0
pfsub.ss f15 , f17 , f0
pfsub.ss f17 , f13 , f0
pfsub.ss f0, f0, f22
pfsub.ss f0, f0, f20
pfgt.ss f12 , f14 , f21
fld.l r17 ( r18 ), f24
bc _fx1gtfx2_p
_fx2gtfx1_p::
fmov.ss f14 , f10
br _checkx3_p
fmov.ss f12 , f8
_fx1gtfx2_p::
fmov.ss f12 , f10
fmov.ss f14 , f8
_checkx3_p::
pfgt.ss f16 , f10 , f0
bc _fx3max_p
pfgt.ss f8 , f16 , f0
bc _fx3min_p
br _minimaxy_p
_fx3min_p::
fmov.ss f16 , f8
br _minimaxydb_p
pfgt.ss f13 , f15 , f0
_fx3max_p::
fmov.ss f16 , f10
// now minimax y
_minimaxy_p::
pfgt.ss f13 , f15 , f0
_minimaxydb_p::
fld.l r17 ( r19 ), f25
bc _fy1gtfy2_p
_fy2gtfy1_p::
fmov.ss f15 , f11
br _checky3_p
fmov.ss f13 , f9
_fy1gtfy2_p::
fmov.ss f13 , f11
fmov.ss f15 , f9
_checky3_p::
fld.l r17 ( r20 ), f26
pfgt.ss f17 , f11 , f0
fld.l l%.C00037(r31), f30
bc _fy3max_p
pfgt.ss f9 , f17 , f0
bc _fy3min_p
br _endminimaxdb_p
pfmul.ss f12 , f20 , f0 // delayed branch op repeated
_fy3min_p::
fmov.ss f17 , f9
br _endminimaxdb_p
pfmul.ss f12 , f20 , f0 // delayed branch op repeated
_fy3max_p::
fmov.ss f17 , f11
// repeated expressions f20 , f21 , f22 , f23
//
// The definitive planarization algorithm
//
// invC=1.0f / ( f12 * ( f15 - f17 )) +
// ( f14 * ( f17 - f13 )) +
// ( f16 * ( f13 - f15 ));
//
// eqn[0]= invC*( f13 * ( f26 - f25 )) +
// ( f15 * ( f24 - f26 )) +
// ( f17 * ( f25 - f24 ));
//
// eqn[1]= invC*( f24 * ( f16 - f14 )) +
// ( f25 * ( f12 - f16 )) +
// ( f26 * ( f14 - f12 ));
//
// eqn[2]= invC*( f12 *(( f15 * f26 ) - ( f17 * f25 ))) +
// ( f14 *(( f17 * f24 ) - ( f13 * f26 ))) +
// ( f16 *(( f13 * f25 ) - ( f15 * f24 )));
//
// 11 ticks all told
_endminimax_p::
pfmul.ss f12 , f20 , f0
_endminimaxdb_p::
pfmul.ss f14 , f21 , f0
pfmul.ss f16 , f22 , f0
// use T-reg as staging post...
rat1s2.ss f12 , f16 , f0
i2pt.ss f0, f0, f0
rat1s2.ss f14 , f12 , f0
pfsub.ss f16 , f14 , f21
i2apt.ss f0, f0, f0
pfadd.ss f0, f0, f22
pfadd.ss f0, f0, f20
pfadd.ss f0, f0, f23
//
// straight out of the i860 prog ref man
//
// to iterate towards 1/V;
//
// G_new=G_old*(2.0f-(G_old*V))
//
// 20 ticks !? pretty poor
frcp.ss f23 , f28 // start 1.0 / f23 - 2^-8
fmul.ss f23 , f28 , f29 // guess * divisor
fsub.ss f30 , f29 , f29 // 2 - (guess * divisor)
fmul.ss f28 , f29 , f28 // 2^-15
fmul.ss f23 , f28 , f29 // guess * divisor
fsub.ss f30 , f29 , f29 // 2 - (guess * divisor)
bri r1
fmul.ss f28 , f29 , f23 // 2^-23 - run with it
//}}}
//{{{ edgize_tri_fn
// per edge
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// not pipelined
//
.globl _edgize_tri_fn
.align 8
_edgize_tri_fn::
// edgize edge 1 v1 -> v2
//{{{ edgize f12 , f14 , f13 , f15
fsub.ss f13 , f15 , f28
adds 0x601, r0, r16
st.l r16 , 4( r5 )
fsub.ss f14 , f12 , f29
adds 4, r5 , r5
fst.l f28 , 4( r5 )++
fmul.ss f15 , f12 , f28
fst.l f29 , 4( r5 )++
fmul.ss f13 , f14 , f29
fsub.ss f28 , f29 , f28
adds 0x602, r0, r16
fst.l f28 , 4( r5 )++
//}}}
//{{{ edgize f14 , f16 , f15 , f17
fsub.ss f15 , f17 , f28
st.l r16 , 4( r5 )
adds 4, r5 , r5
fsub.ss f16 , f14 , f29
fst.l f28 , 4( r5 )++
fmul.ss f17 , f14 , f28
adds 0x603, r0, r16
fst.l f29 , 4( r5 )++
fmul.ss f15 , f16 , f29
fsub.ss f28 , f29 , f28
fst.l f28 , 4( r5 )++
//}}}
//{{{ edgize f16 , f12 , f17 , f13
fsub.ss f17 , f13 , f28
st.l r16 , 4( r5 )
adds 4, r5 , r5
fsub.ss f12 , f16 , f29
fst.l f28 , 4( r5 )++
fmul.ss f13 , f16 , f28
fst.l f29 , 4( r5 )++
fmul.ss f17 , f12 , f29
fsub.ss f28 , f29 , f28
bri r1
fst.l f28 , 4( r5 )++
//}}}
//}}}
//{{{ edgize_tri_fn_p pipelined, dual-instruction, full Ramonic thunder
// per edge
//
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// good general approach for anything 'triangly' - open out the loop in
// 3s, dealing with a vertex at a time. The coding couldnt be simpler,
// and yields a floating point result per tick
//
//
// nb
// we enter here with r5 pre-decremented by 4 bytes
//
.globl _edgize_tri_fn_p
.align 8
//
// use r16 , r7 , r8 as holders for
// edge1 op, edge2 op, edge3 op
//
_edgize_tri_fn_p::
d.pfsub.ss f13 , f15 , f0
st.l r16 , 4( r5 )
d.pfsub.ss f15 , f17 , f0
nop
d.pfsub.ss f17 , f13 , f0
nop
d.pfsub.ss f14 , f12 , f29
nop
d.pfsub.ss f16 , f14 , f28
fst.l f29 , 8( r5 ) // edge[0] eqn[0]
d.pfsub.ss f12 , f16 , f29
fst.l f28 , 24( r5 ) // edge[1] eqn [0]
d.m12tpm.ss f14 , f13 , f28
fst.l f29 , 40( r5 ) // edge[2] eqn [0]
d.m12tpm.ss f16 , f15 , f29
nop
d.m12tpm.ss f12 , f17 , f30
st.l r7 , 20( r5 )
d.pfmul.ss f15 , f12 , f31 // f14 * f13
mov r5 , r31
d.pfmul.ss f17 , f14 , f27 // f16 * f15
fst.l f28 , 12( r5 ) // edge[0] eqn[1]
d.pfmul.ss f13 , f16 , f4 // f12 * f17
fst.l f29 , 28( r5 ) // edge[1] eqn[1]
d.i2s1.ss f31 , f0, f0
fst.l f30 , 44( r5 ) // edge[2] eqn[1]
d.i2s1.ss f27 , f0, f0
nop
d.i2s1.ss f4 , f0, f0
st.l r8 , 36( r5 )
d.pfadd.ss f0, f0, f28
adds 48, r5 , r5
d.pfadd.ss f0, f0, f29
fst.l f28 , 16(r31) // edge[0] eqn[2]
d.pfadd.ss f0, f0, f30
fst.l f29 , 32(r31) // edge[1] eqn[2]
fnop
bri r1
fnop
fst.l f30 , 48(r31) // edge[2] eqn[2]
//}}}
//{{{ edgize_quad_fn not implemented
.globl _edgize_quad_fn
.align 8
_edgize_quad_fn::
bri r1
nop
//}}}
//{{{ zbuffer_fn unpipelined
.globl _zbuffer_fn
.align 8
_zbuffer_fn::
// byte 24 into MESH_VERTEX is z-coord of xformpos
adds r0, r1, r6
or ( ( ( 0x422100 | ((( ( (( 0 )+( 32 )) ) ) & 0xff) << 0) | ((((( ( 20 ) )+2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x422100 | ((( ( (( 0 )+( 32 )) ) ) & 0xff) << 0) | ((((( ( 20 ) )+2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
call _planarize_fn
adds 24, r0, r17
// store 'do zbuffer, no arguments' into coeff store
or ( ( ( 0x24300 | ((( ( (( 0 )+( 32 )) ) ) & 0xff) << 0) | (((( ( 20 ) )+115) & 0xff) << 23) ) |(2<<18)|(0<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( 0 )+( 32 )) ) ) & 0xff) << 0) | (((( ( 20 ) )+115) & 0xff) << 23) ) |(2<<18)|(0<<20)) )>>16)&0xffff, r16 , r16
st.l r16 , 4( r5 )
bri r6
adds 4, r5 , r5
//}}}
//{{{ zbuffer_fn_p pipelined - loads NEXT variable, assumes Z pre-loaded
.globl _zbuffer_fn_p
.align 8
_zbuffer_fn_p::
// byte 24 into MESH_VERTEX is z-coord of xformpos
or ( ( ( 0x422100 | ((( ( (( 0 )+( 32 )) ) ) & 0xff) << 0) | ((((( ( 20 ) )+2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x422100 | ((( ( (( 0 )+( 32 )) ) ) & 0xff) << 0) | ((((( ( 20 ) )+2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
or r0, r1, r6
call _planarize_fn_p
nop
// store 'do zbuffer, no arguments' into coeff store
or ( ( ( 0x24300 | ((( ( (( 0 )+( 32 )) ) ) & 0xff) << 0) | (((( ( 20 ) )+115) & 0xff) << 23) ) |(2<<18)|(0<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( 0 )+( 32 )) ) ) & 0xff) << 0) | (((( ( 20 ) )+115) & 0xff) << 23) ) |(2<<18)|(0<<20)) )>>16)&0xffff, r16 , r16
st.l r16 , 4( r5 )
bri r6
adds 4, r5 , r5
//}}}
//{{{ planarize_fn Ramones version - blitzkrieg bop
//
// Hey Ho Lets Go!
//
// The definitive planarization algorithm
//
// invC=1.0f / ( f12 * ( f15 - f17 )) +
// ( f14 * ( f17 - f13 )) +
// ( f16 * ( f13 - f15 ));
//
// eqn[0]= invC*( f13 * ( f26 - f25 )) +
// ( f15 * ( f24 - f26 )) +
// ( f17 * ( f25 - f24 ));
//
// a = f26 - f25
// b = f24 - f26
// c = f25 - f24
// d = f13 * a
// e = f15 * b
// f = f17 * c
// g = d + e
// h = g + f
// eqn[0] = f23 * h
//
// eqn[1]= invC*( f24 * ( f16 - f14 )) +
// ( f25 * ( f12 - f16 )) +
// ( f26 * ( f14 - f12 ));
//
// i = f24 * f20
// j = f25 * f21
// k = f26 * f22
// l = i + j
// m = k + l
// eqn[1] = f23 * m
//
// eqn[2]= invC*( f12 *(( f15 * f26 ) - ( f17 * f25 ))) +
// ( f14 *(( f17 * f24 ) - ( f13 * f26 ))) +
// ( f16 *(( f13 * f25 ) - ( f15 * f24 )));
//
// n = f15 * f26
// o = f17 * f25
// p = f17 * f24
// q = f13 * f26
// r = f13 * f25
// s = f15 * f24
// t = n - o
// u = p - q
// v = r - s
// w = f12 * t
// x = f14 * u
// y = f16 * v
// z = w + x
// aa= y + z
// eqn[2] = invC * aa
//
.globl _planarize_fn
.align 8
_planarize_fn::
ld.l 0( r18 ), r31
fld.l r17 (r31), f24
ld.l 0( r19 ), r31
fld.l r17 (r31), f25
ld.l 0( r20 ), r31
fld.l r17 (r31), f26
// ld.l r31, 0( r17 )
// fld.l r31( r19 ), f25
//
// ld.l r31, 0( r17 )
// fld.l r31( r19 ), f25
//
//
// fld.l r17 ( r20 ), f26
//
// fld.l r17 ( r18 ), f24
// m1 m2 m3 | T | a1 a2 a3 | KR | t1 t2 t3
// n = f15 * f26
// o = f17 * f25
pfmul.ss f15 , f26 , f0 // n ? ? | ? | ? ? ? | ? | ? ? ?
pfmul.ss f17 , f25 , f0 // o n ? | ? | ? ? ? | ? | ? ? ?
// p = f17 * f24
// q = f13 * f26
pfmul.ss f17 , f24 , f0 // p o n | ? | ? ? ? | ? | ? ? ?
mm12ttpm.ss f13 , f26 , f0 // q p o | n | ? ? ? | ? | ? ? ?
// r = f13 * f25
// t = n - o
// s = f15 * f24
m12tsm.ss f13 , f25 , f0 // r q p | ? | t ? ? | ? | ? ? ?
mm12ttpm.ss f15 , f24 , f0 // s r q | p | ? t ? | ? | ? ? ?
// i = f24 * f20
// u = p - q
// a = f26 - f25
m12tsm.ss f24 , f20 , f0 // i s r | ? | u ? t | ? | ? ? ?
pfsub.ss f26 , f25 , f28 // i s r | ? | a u ? | ? | t ? ?
// j = f25 * f21
// k = f26 * f22
// v = r - s
mm12ttpm.ss f25 , f21 , f0 // j i s | r | ? a u | ? | t ? ?
m12tsm.ss f26 , f22 , f29 // k j i | ? | v ? a | ? | t u ?
// w = f12 * t
// x = f14 * u
pfmul.ss f12 , f28 , f30 // w k j | ? | v ? a | ? | ? u i
pfmul.ss f14 , f29 , f28 // x w k | ? | v ? a | ? | j ? i
// l = i + j
// d = f13 * a
pfadd.ss f28 , f30 , f29 // x w k | ? | l v ? | ? | ? a ?
mm12mpm.ss f13 , f29 , f30 // d x w | ? | ? l v | ? | ? ? k
// b = f24 - f26
// c = f25 - f24
pfsub.ss f24 , f26 , f28 // d x w | ? | b ? l | ? | v ? k
// st.l r16 , 20( r5 )
pfsub.ss f25 , f24 , f29 // d x w | ? | c b ? | ? | v l k
// fld.l r17 ( r20 ), f26
// m = k + l
// y = f16 * v
// z = w + x
rat1p2.ss f29 , f30 , f0 // ? d x | w | m c b | ? | v ? ?
// fld.l r17 ( r19 ), f25
m12tpm.ss f16 , f28 , f29 // y ? d | ? | z m c | ? | ? b ?
// fld.l r17 ( r18 ), f24
// e = f15 * b
// f = f17 * c
m12ttpa.ss f15 , f29 , f28 // e y ? | d | ? z m | ? | c ? ?
m12apm.ss f17 , f28 , f29 // f e y | d | ? ? z | ? | ? m ?
// last-stage mul+T ->g, f23 -> KR, save adder result !
// eqn[1] = f23 * m
// g = d + e
pfmul.ss f23 , f29 , f28 // e1 f e | d | ? ? z | ? | y ? ?
r2pt.ss f23 , f0, f29 // ? e1 f | ? | g ? ? | ? | y z ?
// aa= y + z
mrm1p2.ss f28 , f29 , f30 // ? ? e1| ? | aa g ? | ? | ? ? f
mm12mpm.ss f0, f0, f29 // ? ? ? | ? | ? aa g | ? | ? e1 f
// h = g + f
// eqn[2] = invC * aa
r2ap1.ss f30 , f0, f0 // ? ? ? | ? | h ? aa | ? | ? e1 ?
ra1p2.ss f0, f0, f0 // e2 ? ? | ? | ? h ? | ? | ? e1 ?
// eqn[0] = f23 * h
d.i2p1.ss f0, f0, f0 // ? e2 ? | ? | ? ? h | ? | ? e1 ?
st.l r16 , 4( r5 )
d.rat1p2.ss f0, f0, f0
nop
d.mi2p1.ss f0, f0, f28
fst.l f29 , 12( r5 )
d.mi2p1.ss f28 , f0, f0
fst.l f28 , 16( r5 )++
mi2p1.ss f0, f0, f30
bri r1
fnop
fst.l f30 , -8( r5 )
// rat1p2.ss f0, f0, f0 // e0 ? e2| ? | ? ? ? | ? | ? e1 ?
// mi2p1.ss f0, f0, f28 // ? e0 ? | ? | ? ? ? | ? | e2 e1 ?
// fst.l f29 , 8( r5 )
// mi2p1.ss f0, f0, f0 // ? ? e0| ? | ? ? ? | ? | ? ? ?
// fst.l f28 , 12( r5 )++
// mi2p1.ss f0, f0, f30 // ? ? ? | ? | ? ? ? | ? | ? ? e0
// bri r1
// fst.l f30 , -8( r5 )
//}}}
//{{{ planarize_fn_p pipelined Ramones version - imateenagelobotomy
//
// Hey Ho Lets Go!
//
// The definitive planarization algorithm
//
// invC=1.0f / ( f12 * ( f15 - f17 )) +
// ( f14 * ( f17 - f13 )) +
// ( f16 * ( f13 - f15 ));
//
// eqn[0]= invC*( f13 * ( f26 - f25 )) +
// ( f15 * ( f24 - f26 )) +
// ( f17 * ( f25 - f24 ));
//
// a = f26 - f25
// b = f24 - f26
// c = f25 - f24
// d = f13 * a
// e = f15 * b
// f = f17 * c
// g = d + e
// h = g + f
// eqn[0] = f23 * h
//
// eqn[1]= invC*( f24 * ( f16 - f14 )) +
// ( f25 * ( f12 - f16 )) +
// ( f26 * ( f14 - f12 ));
//
// i = f24 * f20
// j = f25 * f21
// k = f26 * f22
// l = i + j
// m = k + l
// eqn[1] = f23 * m
//
// eqn[2]= invC*( f12 *(( f15 * f26 ) - ( f17 * f25 ))) +
// ( f14 *(( f17 * f24 ) - ( f13 * f26 ))) +
// ( f16 *(( f13 * f25 ) - ( f15 * f24 )));
//
// n = f15 * f26
// o = f17 * f25
// p = f17 * f24
// q = f13 * f26
// r = f13 * f25
// s = f15 * f24
// t = n - o
// u = p - q
// v = r - s
// w = f12 * t
// x = f14 * u
// y = f16 * v
// z = w + x
// aa= y + z
// eqn[2] = invC * aa
//
.globl _planarize_fn_p
.align 8
_planarize_fn_p::
// m1 m2 m3 | T | a1 a2 a3 | KR | t1 t2 t3
// n = f15 * f26
// o = f17 * f25
pfmul.ss f15 , f26 , f0 // n ? ? | ? | ? ? ? | ? | ? ? ?
pfmul.ss f17 , f25 , f0 // o n ? | ? | ? ? ? | ? | ? ? ?
// p = f17 * f24
// q = f13 * f26
pfmul.ss f17 , f24 , f0 // p o n | ? | ? ? ? | ? | ? ? ?
mm12ttpm.ss f13 , f26 , f0 // q p o | n | ? ? ? | ? | ? ? ?
// r = f13 * f25
// t = n - o
// s = f15 * f24
m12tsm.ss f13 , f25 , f0 // r q p | ? | t ? ? | ? | ? ? ?
mm12ttpm.ss f15 , f24 , f0 // s r q | p | ? t ? | ? | ? ? ?
// i = f24 * f20
// u = p - q
// a = f26 - f25
m12tsm.ss f24 , f20 , f0 // i s r | ? | u ? t | ? | ? ? ?
pfsub.ss f26 , f25 , f28 // i s r | ? | a u ? | ? | t ? ?
// j = f25 * f21
// k = f26 * f22
// v = r - s
mm12ttpm.ss f25 , f21 , f0 // j i s | r | ? a u | ? | t ? ?
m12tsm.ss f26 , f22 , f29 // k j i | ? | v ? a | ? | t u ?
// w = f12 * t
// x = f14 * u
pfmul.ss f12 , f28 , f30 // w k j | ? | v ? a | ? | ? u i
pfmul.ss f14 , f29 , f28 // x w k | ? | v ? a | ? | j ? i
// l = i + j
// d = f13 * a
pfadd.ss f28 , f30 , f29 // x w k | ? | l v ? | ? | ? a ?
mm12mpm.ss f13 , f29 , f30 // d x w | ? | ? l v | ? | ? ? k
// b = f24 - f26
// c = f25 - f24
d.pfsub.ss f24 , f26 , f28 // d x w | ? | b ? l | ? | v ? k
nop
d.pfsub.ss f25 , f24 , f29 // d x w | ? | c b ? | ? | v l k
fld.l r17 ( r20 ), f26
// m = k + l
// y = f16 * v
// z = w + x
d.rat1p2.ss f29 , f30 , f0 // ? d x | w | m c b | ? | v ? ?
nop
d.m12tpm.ss f16 , f28 , f29 // y ? d | ? | z m c | ? | ? b ?
nop
// e = f15 * b
// f = f17 * c
d.m12ttpa.ss f15 , f29 , f28 // e y ? | d | ? z m | ? | c ? ?
nop
d.m12apm.ss f17 , f28 , f29 // f e y | d | ? ? z | ? | ? m ?
fld.l r17 ( r19 ), f25
// last-stage mul+T ->g, f23 -> KR, save adder result !
// eqn[1] = f23 * m
// g = d + e
d.pfmul.ss f23 , f29 , f28 // e1 f e | d | ? ? z | ? | y ? ?
nop
d.r2pt.ss f23 , f0, f29 // ? e1 f | ? | g ? ? | ? | y z ?
nop
// aa= y + z
d.mrm1p2.ss f28 , f29 , f30 // ? ? e1| ? | aa g ? | ? | ? ? f
nop
d.mm12mpm.ss f0, f0, f29 // ? ? ? | ? | ? aa g | ? | ? e1 f
fld.l r17 ( r18 ), f24
// h = g + f
// eqn[2] = invC * aa
d.r2ap1.ss f30 , f0, f0 // ? ? ? | ? | h ? aa | ? | ? e1 ?
nop
d.ra1p2.ss f0, f0, f0 // e2 ? ? | ? | ? h ? | ? | ? e1 ?
nop
// eqn[0] = f23 * h
d.i2p1.ss f0, f0, f0 // ? e2 ? | ? | ? ? h | ? | ? e1 ?
st.l r16 , 4( r5 )
d.rat1p2.ss f0, f0, f0
nop
d.mi2p1.ss f0, f0, f28
fst.l f29 , 12( r5 )
d.mi2p1.ss f30 , f0, f0
fst.l f28 , 16( r5 )++
mi2p1.ss f0, f0, f30
bri r1
fnop
fst.l f30 , -8( r5 )
// rat1p2.ss f0, f0, f0 // e0 ? e2| ? | ? ? ? | ? | ? e1 ?
// mi2p1.ss f0, f0, f28 // ? e0 ? | ? | ? ? ? | ? | e2 e1 ?
// fst.l f29 , 8( r5 )
// mi2p1.ss f0, f0, f0 // ? ? e0| ? | ? ? ? | ? | ? ? ?
// fst.l f28 , 12( r5 )++
// mi2p1.ss f0, f0, f30 // ? ? ? | ? | ? ? ? | ? | ? ? e0
// bri r1
// fst.l f30 , -8( r5 )
//}}}
//{{{ binitize_fn not implemented
.globl _binitize_fn
.align 8
// binitize a primitive
_binitize_fn::
bri r1
nop
//}}}
//{{{ safe_binitize_fn pipelined intro
// void safe_binitize ( int macro_lo, int macro_hi,
// float f8 , float f9 ,
// float f10 , float f11 ,
// int screen_bins_x )
//
// binitize a triangle known to be on-screen, i.e minimax x y
// are within screen-space
//
.globl _safe_binitize_fn
.align 8
// binitize a primitive
_safe_binitize_fn::
//{{{ locals defines for this fn
// leave xmin, max intact !
//
// these MUST be < r16 !!
//
// head, tail
// DMA_opcodes[512]
// int r13
// *next
// byte count of 255*2
// 16 bins in 1024
//}}}
//
// NB fxfr MUST have NOP as companion, or you are shafted
//
// minx=(int) f8 ;
// miny=(int) f9 ;
// maxx=(int) f10 ;
// maxy=(int) f11 ;
// minx >>= 6 ;
// miny >>= 7 ;
// maxx >>= 6 ;
// maxy >>= 7 ;
// {
// screenbin * r24 =&screenbins[(miny<<bins_shift)+minx];
// screenbin * r25 = r24 ;
// ==> go mango
d.pftrunc.sd f8 , f0
orh ha%_screenbins, r0, r31
d.pftrunc.sd f9 , f0
ld.l l%_screenbins(r31), r31
d.pftrunc.sd f10 , f0
nop
d.pftrunc.sd f11 , f28
nop
d.fxfr f28 , r7
nop
d.pfadd.sd f0, f0, f30
shr 6 , r7 , r9
d.fxfr f30 , r8
nop
d.pfadd.sd f0, f0, f28
shr 7 , r8 , r10
d.fxfr f28 , r7
nop
pfadd.sd f0, f0, f30
shr 6 , r7 , r11
fxfr f30 , r8
nop
shl 4 , r10 , r24
adds r9 , r24 , r24
shr 7 , r8 , r12
// each r14 is head/tail pointer, so 8 bytes per r14 entry
shl 3, r24 , r24
adds r31, r24 , r24
subs r12 , r10 , r26
// while ( r26 )
_y_loop::
mov r24 , r25
_y_loopdb::
subs r11 , r9 , r27
// while ( r27 )
_x_loop::
ld.l 4 ( r25 ), r14
_x_loopdb::
ld.l 2048 ( r14 ), r13
xor 2040 , r13 , r0
bnc.t _bin_not_full
adds r13 , r14 , r31 // was at bin_not_full, execute as delayed br
_bin_full::
//{{{ the incredibly expensive 'bin is full branch'
// dont panic -
// this branch is infrequent - happens every 256 triangles
// note that it can result in a call to malloc!
//
// if ( r14 -> r13 == 2040 ) {
// binchunk *nextbin=next_binchunk ();
//
// r14 ->DMA_opcodes[ r13 ++]=(int) nextbin;
// r14 ->DMA_opcodes[ r13 ++]= (0x00000000) ;
// r14 =nextbin;
// r25 ->tail= r14 ;
// r13 =0;
// }
//
// damn, we enter C land here - push all registers onto stack
// note that floating-point registers are no longer needed
//
st.l r16, -4(sp)
st.l r17, -8(sp)
st.l r18, -12(sp)
st.l r19, -16(sp)
st.l r20, -20(sp)
st.l r21, -24(sp)
st.l r22, -28(sp)
st.l r23, -32(sp)
st.l r24, -36(sp)
st.l r25, -40(sp)
st.l r26, -44(sp)
st.l r27, -48(sp)
st.l r28, -52(sp)
st.l r29, -56(sp)
st.l r30, -60(sp)
st.l r1, -64(sp)
call _next_binchunk
adds -68, sp, sp
// now r16 holds nextbin
// note that r14 and r13 are preserved after this call ( < r16)
adds r13 , r14 , r31 // construct pointer to coeff store
st.l r16 , 2052 ( r14 ) // do linked list thing
mov r16 , r14 // return val from next_binchunk
st.l r16 , 0(r31) // save it away
adds (0x00000000) , r0, r16 // chain in new r14
st.l r16 , 4(r31) // and save this opcode away
// lets restore registers
adds 68, sp, sp
ld.l -4(sp), r16
ld.l -8(sp), r17
ld.l -12(sp), r18
ld.l -16(sp), r19
ld.l -20(sp), r20
ld.l -24(sp), r21
ld.l -28(sp), r22
ld.l -32(sp), r23
ld.l -36(sp), r24
ld.l -40(sp), r25
ld.l -44(sp), r26
ld.l -48(sp), r27
ld.l -52(sp), r28
ld.l -56(sp), r29
ld.l -60(sp), r30
ld.l -64(sp), r1
// so now to patch up the new r14 - simply fall thru
// into the r14 not full branch
mov r0, r13
mov r14 , r31
st.l r14 , 4 ( r25 )
//}}}
_bin_not_full::
// r14 ->DMA_opcodes[ r13 ++]=macro_lo;
// r14 ->DMA_opcodes[ r13 ++]=macro_hi;
// r14 -> r13 = r13 ;
// r25 ++;
adds 8, r13 , r13
st.l r16 , 0(r31)
adds 8 , r25 , r25
st.l r17 , 4(r31)
st.l r13 , 2048 ( r14 )
_bump_x::
// r24 +=screen_bins_x;
bte r0, r27 , _bump_y
ld.l 4 ( r25 ), r14
br _x_loopdb
adds -1, r27 , r27
_bump_y::
bte r0, r26 , _exit_binitize
adds 128 , r24 , r24
adds -1, r26 , r26
br _y_loopdb
mov r24 , r25
_exit_binitize:
bri r1
nop
//}}}
//{{{ tex_scalefac
.globl _tex_scalefac
.align 8
_tex_scalefac::
//
// f8 , 2, 3 hold 3 z values - find which is biggest, scale
// it up to have no leading zeros, return scale factor (1.0, 2.0 etc)
// sign bit guaranteed not set
// z not yet munged by scale bits, so z in range 0.0 .. 1.0
// biggest test is easy - fxfr to integer registers,
// do integer compare to determine biggest
// extract exponent from biggest, all 3 zs
//
// use r31 to hold max, use int parameter registers as temporaries
//
// this would appear to take 16ish ticks
//
fxfr f8 , r16
fxfr f9 , r17
fxfr f10 , r18
subs r16 , r17 , r0
bc i2_gt_i1
subs r16 , r18 , r0
bnc.t igotmax
mov r16 , r31
br igotmax
mov r18 , r31
i2_gt_i1::
subs r17 , r18 , r0
bnc.t igotmax
mov r17 , r31
br igotmax
mov r18 , r31
igotmax::
//
// compute exponent difference between 0.999 and max
//
// dont worry, its just IEEE-754 - read the i860 databook
//
// warning - it may fall down in a heap if we ever give it
// a denormal, so just set the far clipping plane somewhere
// sensible - ill work out where
//
andh 0x7f80, r31, r31 // extract exponent of max
orh 0x7e80, r0, r16
subu r16 , r31, r31 // and we have magic
bri r1
ixfr r31, f8
//}}}
//{{{ _trunc_test ( int *truncy, float a, float b, float c )
.globl _trunc_test
.align 8
// binitize a primitive
_trunc_test::
adds -64, sp, sp
fst.d f2, 0(sp)
fst.d f4, 8(sp)
fst.d f6, 16(sp)
fst.d f8, 24(sp)
st.l r4, 28(sp)
st.l r5, 32(sp)
st.l r6, 36(sp)
pftrunc.sd f8, f0
pftrunc.sd f9, f0
pftrunc.sd f10, f0
pfadd.sd f0, f0, f2
pfadd.sd f0, f0, f4
pfadd.sd f0, f0, f6
fxfr f2, r4
fxfr f4, r5
fxfr f6, r6
st.l r4, 0(r16)
st.l r5, 4(r16)
st.l r6, 8(r16)
fld.d 0(sp), f2
fld.d 8(sp), f4
fld.d 16(sp), f6
fld.d 24(sp), f8
ld.l 28(sp), r4
ld.l 32(sp), r5
ld.l 36(sp), r6
bri r1
adds 64, sp, sp
//}}}
//{{{ about this code
//
//
// These functions are C-callable, and simply chain together
// calls to other functions in pxpl5asm.ss, which do not themselves
// adhere to C calling conventions and register allocation
//
// These are the triangle functions - for each type of triangle
// rendereable by the system, a different function exists. The currently
// implemented set of triangles is
//
// diffuseI, intrinsic
// diffuser, diffuseg, diffuseb
// z-buffered, diffuser, diffuseg, diffuseb
// z-buffered, diffuseI, specularI, intrinsic
// z-buffered, diffuseI, specularI, textured, intrinsic
// z-buffered, diffuser, diffuseg, diffuseb, specularI, textured
// z-buffered, flat, textured
//
// which are enough to cover PAZ 1 shading model, white light PAZ 2
// shading model, optimized lightscape / Eindhoven radiosity, skyfly
// texturing, white light texturing
//}}}
//{{{ some pxpl5 examples
// put some opcodes into r5, r6, r7
or ( ( ( 0x24300 | ((( ( 121 ) ) & 0xff) << 0) | (((( ( 14 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r25 ; orh (( ( ( 0x24300 | ((( ( 121 ) ) & 0xff) << 0) | (((( ( 14 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r25 , r25
or ( ( ( 0x400d00 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r26 ; orh (( ( ( 0x400d00 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r26 , r26
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r27 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r27 , r27
//}}}
//{{{ triangle function entry and exit
//}}}
//{{{ some pxpl5 comments and defines
//
// rendering is split into 2 phases; scan-conversion and shading. only
// scan-conversion uses the tree; shading operates SIMD on all pixels,
// regardless of their x,y locations.
//
// these functions deal only with scan-conversion. we therefore need
// access to only a very restricted subset of pxpl5 opcodes; those
// for edgizing, and those for planarizing, plus some enable-manipulation
// opcodes.
//
// to render a triangle, we perform 4 basic operations;
//
// a) initialize enable flag
// b) enable all interior pixels
// c) scan-convert screen-space variables into memory
// d) perform clean-up housekeeping
//
// only c) is ever performed more than once per primitive
//
// a) involves either
// clearing enable flag
// CLRENABS()
// or loading enable from memory
// MEMintoENAB(src)
//
// b) involves executing the edgize expressions, which are either
// TREEgeZERO()
// or TREEltZERO()
// dependent on the direction of the edge
//
// c) involves just one instruction
// TREEintoMEM(dst,len)
//
// d) involves storing some pixel type information, intrinsic colour,
// texture ID etc into memory; just one instruction
// SCAintoMEM(dst, dlen)
// and/ saving enable flag into memory;
// or ENABintoMEM(dst)
//
//
//}}}
//
// triangle, diffuse lit, inherit z-buffer and material
// 9 64-bit words
//
//{{{ _tri_d
.globl _tri_d
.align 8
_tri_d::
fst.d f2, -8(sp); fst.d f4, -16(sp); fst.d f6, -24(sp); st.l r4, -28(sp); st.l r5, -32(sp); st.l r6, -36(sp); st.l r7, -40(sp); st.l r8, -44(sp); st.l r9, -48(sp); st.l r10, -52(sp); st.l r11, -56(sp); st.l r12, -60(sp); st.l r13, -64(sp); st.l r14, -68(sp); st.l r15, -72(sp); st.l r1, -76(sp); mov r16 , r22 ; adds -80, sp, sp; fmov.ss f8 , f3 ; adds -4, r16 , r5
st.l r0, 4( r5 )
or ( ( 0x300 | ((( ( (( (( (( (( (( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) )+( 8 )) )+( 16 )) )+( 16 )) )+( 16 )) )+( 4 )) ) ) & 0xff) << 0) ) )&0xffff, r0, r7 ; orh (( ( 0x300 | ((( ( (( (( (( (( (( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) )+( 8 )) )+( 16 )) )+( 16 )) )+( 16 )) )+( 4 )) ) ) & 0xff) << 0) ) )>>16)&0xffff, r7 , r7
st.l r7 , 8( r5 )
adds 8, r5 , r5
fld.d 0( r18 ), f12
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
fld.d 0( r19 ), f14
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r7 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r7 , r7
fld.d 0( r20 ), f16
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r8 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r8 , r8
// offset 52 = diffuse slot of NORMCOL, piped loads
or 52, r0, r17
call _preplanarize_fn_p
addu r0, r0, r21
call _edgize_tri_fn_p
nop
// offset 56 = specular slot of NORMCOL
or ( ( ( 0x24300 | ((( ( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
or r0, r18 , r19
call _planarize_fn_p
or r0, r18 , r20
//
// NOTE vertex pointers no longer needed, dont restore
// r17 holds macro, which is SEND with embedded count
// of 64-bit words
// zbuf diffuse triangle is 9 64-bit words
//
or ( (0x10000000| 9 ) )&0xffff, r0, r17 ; orh (( (0x10000000| 9 ) )>>16)&0xffff, r17 , r17
mov r22 , r16
call _safe_binitize_fn
addu 10, r0, r18
adds 80, sp, sp; adds 4, r5 , r16 ; ld.l -76(sp), r1; ld.l -72(sp), r15; ld.l -68(sp), r14; ld.l -64(sp), r13; ld.l -60(sp), r12; ld.l -56(sp), r11; ld.l -52(sp), r10; ld.l -48(sp), r9; ld.l -44(sp), r8; ld.l -40(sp), r7; ld.l -36(sp), r6; ld.l -32(sp), r5; ld.l -28(sp), r4; fld.d -24(sp), f6; fld.d -16(sp), f4; bri r1; fld.d -8(sp), f2;
//}}}
//
// triangle, just z-buffer, apply material
// 11 64-bit words
//
//{{{ _tri_zb
.globl _tri_zb
.align 8
_tri_zb::
fst.d f2, -8(sp); fst.d f4, -16(sp); fst.d f6, -24(sp); st.l r4, -28(sp); st.l r5, -32(sp); st.l r6, -36(sp); st.l r7, -40(sp); st.l r8, -44(sp); st.l r9, -48(sp); st.l r10, -52(sp); st.l r11, -56(sp); st.l r12, -60(sp); st.l r13, -64(sp); st.l r14, -68(sp); st.l r15, -72(sp); st.l r1, -76(sp); mov r16 , r22 ; adds -80, sp, sp; fmov.ss f8 , f3 ; adds -4, r16 , r5
st.l r0, 4( r5 )
or ( ( 0x100 ) )&0xffff, r0, r7 ; orh (( ( 0x100 ) )>>16)&0xffff, r7 , r7
st.l r7 , 8( r5 )
adds 8, r5 , r5
fld.d 0( r18 ), f12
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
fld.d 0( r19 ), f14
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r7 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r7 , r7
fld.d 0( r20 ), f16
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r8 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r8 , r8
adds 24, r0, r17
call _preplanarize_fn_p
addu r0, r0, r21
call _edgize_tri_fn_p
nop
// load-ahead for z-buffer_fn_p
// into v1, v2, v3
// offset 52 = diffuse slot of NORMCOL, piped loads
or r0, r18 , r19
or r0, r18 , r20
call _zbuffer_fn_p
or 24, r0, r17
or ( ( ( 0xf700 | ((( ( ( (( (( 0 )+( 32 )) )+( 20 )) ) ) ) & 0xff) << 0) | (((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )-( ( (( (( 0 )+( 32 )) )+( 20 )) ) )) ) )+116) & 0x7f) << 23) ) |(1<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0xf700 | ((( ( ( (( (( 0 )+( 32 )) )+( 20 )) ) ) ) & 0xff) << 0) | (((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )-( ( (( (( 0 )+( 32 )) )+( 20 )) ) )) ) )+116) & 0x7f) << 23) ) |(1<<20)) )>>16)&0xffff, r16 , r16
st.l r16 , 4( r5 )
fst.l f3 , 8( r5 )++
or ( ( 0xb500 | ((( ( (( (( (( (( (( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) )+( 8 )) )+( 16 )) )+( 16 )) )+( 16 )) )+( 4 )) ) ) & 0xff) << 0) ) )&0xffff, r0, r7 ; orh (( ( 0xb500 | ((( ( (( (( (( (( (( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) )+( 8 )) )+( 16 )) )+( 16 )) )+( 16 )) )+( 4 )) ) ) & 0xff) << 0) ) )>>16)&0xffff, r7 , r7
st.l r7 , 4( r5 )
adds 4, r5 , r5
or ( (0x10000000| 11 ) )&0xffff, r0, r17 ; orh (( (0x10000000| 11 ) )>>16)&0xffff, r17 , r17
mov r22 , r16
call _safe_binitize_fn
addu 10, r0, r18
adds 80, sp, sp; adds 4, r5 , r16 ; ld.l -76(sp), r1; ld.l -72(sp), r15; ld.l -68(sp), r14; ld.l -64(sp), r13; ld.l -60(sp), r12; ld.l -56(sp), r11; ld.l -52(sp), r10; ld.l -48(sp), r9; ld.l -44(sp), r8; ld.l -40(sp), r7; ld.l -36(sp), r6; ld.l -32(sp), r5; ld.l -28(sp), r4; fld.d -24(sp), f6; fld.d -16(sp), f4; bri r1; fld.d -8(sp), f2;
//}}}
//
// triangle, z-buffered, diffuse lit
// 12 64-bit words
//
//{{{ _tri_zb_d
.globl _tri_zb_d
.align 8
_tri_zb_d::
fst.d f2, -8(sp); fst.d f4, -16(sp); fst.d f6, -24(sp); st.l r4, -28(sp); st.l r5, -32(sp); st.l r6, -36(sp); st.l r7, -40(sp); st.l r8, -44(sp); st.l r9, -48(sp); st.l r10, -52(sp); st.l r11, -56(sp); st.l r12, -60(sp); st.l r13, -64(sp); st.l r14, -68(sp); st.l r15, -72(sp); st.l r1, -76(sp); mov r16 , r22 ; adds -80, sp, sp; fmov.ss f8 , f3 ; adds -4, r16 , r5
or ( ( 0x100 ) )&0xffff, r0, r7 ; orh (( ( 0x100 ) )>>16)&0xffff, r7 , r7
st.l r7 , 4( r5 )
adds 4, r5 , r5
fld.d 0( r18 ), f12
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
fld.d 0( r19 ), f14
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r7 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r7 , r7
fld.d 0( r20 ), f16
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r8 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r8 , r8
adds 24, r0, r17
call _preplanarize_fn_p
addu r0, r0, r21
call _edgize_tri_fn_p
nop
// load-ahead for z-buffer_fn_p
// into v1, v2, v3
//
// now use r22 to modify vertex pointers
// remember these are pointers to the data we will load during
// zbuffer_fn_p
//
// offset 52 = diffuse slot of NORMCOL, piped loads
call _zbuffer_fn_p
or 52, r0, r17
// offset 56 = specular slot of NORMCOL
or ( ( ( 0x24300 | ((( ( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
or r0, r18 , r19
call _planarize_fn_p
or r0, r18 , r20
or ( ( ( 0xf700 | ((( ( ( (( (( 0 )+( 32 )) )+( 20 )) ) ) ) & 0xff) << 0) | (((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )-( ( (( (( 0 )+( 32 )) )+( 20 )) ) )) ) )+116) & 0x7f) << 23) ) |(1<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0xf700 | ((( ( ( (( (( 0 )+( 32 )) )+( 20 )) ) ) ) & 0xff) << 0) | (((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )-( ( (( (( 0 )+( 32 )) )+( 20 )) ) )) ) )+116) & 0x7f) << 23) ) |(1<<20)) )>>16)&0xffff, r16 , r16
st.l r16 , 4( r5 )
fst.l f3 , 8( r5 )++
// NOTE vertex pointers no longer needed, dont restore
// r17 holds macro, which is SEND with embedded count
// of 64-bit words
// zbuf diffuse triangle is 12 64-bit words
//
or ( (0x10000000| 12 ) )&0xffff, r0, r17 ; orh (( (0x10000000| 12 ) )>>16)&0xffff, r17 , r17
mov r22 , r16
call _safe_binitize_fn
addu 10, r0, r18
adds 80, sp, sp; adds 4, r5 , r16 ; ld.l -76(sp), r1; ld.l -72(sp), r15; ld.l -68(sp), r14; ld.l -64(sp), r13; ld.l -60(sp), r12; ld.l -56(sp), r11; ld.l -52(sp), r10; ld.l -48(sp), r9; ld.l -44(sp), r8; ld.l -40(sp), r7; ld.l -36(sp), r6; ld.l -32(sp), r5; ld.l -28(sp), r4; fld.d -24(sp), f6; fld.d -16(sp), f4; bri r1; fld.d -8(sp), f2;
//}}}
//
// triangle, z-buffered, diffuse lit, specular lit
// 14 64-bit words
//
//{{{ _tri_zb_d_s
.globl _tri_zb_d_s
.align 8
_tri_zb_d_s::
fst.d f2, -8(sp); fst.d f4, -16(sp); fst.d f6, -24(sp); st.l r4, -28(sp); st.l r5, -32(sp); st.l r6, -36(sp); st.l r7, -40(sp); st.l r8, -44(sp); st.l r9, -48(sp); st.l r10, -52(sp); st.l r11, -56(sp); st.l r12, -60(sp); st.l r13, -64(sp); st.l r14, -68(sp); st.l r15, -72(sp); st.l r1, -76(sp); mov r16 , r22 ; adds -80, sp, sp; fmov.ss f8 , f3 ; adds -4, r16 , r5
or ( ( 0x100 ) )&0xffff, r0, r7 ; orh (( ( 0x100 ) )>>16)&0xffff, r7 , r7
st.l r7 , 4( r5 )
adds 4, r5 , r5
fld.d 0( r18 ), f12
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
fld.d 0( r19 ), f14
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r7 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r7 , r7
fld.d 0( r20 ), f16
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r8 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r8 , r8
adds 24, r0, r17
call _preplanarize_fn_p
addu r0, r0, r21
call _edgize_tri_fn_p
nop
// load-ahead for z-buffer_fn_p
// into v1, v2, v3
//
// now use r22 to modify vertex pointers
// remember these are pointers to the data we will load during
// zbuffer_fn_p
//
// offset 52 = diffuse slot of NORMCOL, piped loads
call _zbuffer_fn_p
or 52, r0, r17
// offset 56 = specular slot of NORMCOL
or ( ( ( 0x24300 | ((( ( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
call _planarize_fn_p
or 56, r0, r17
// and these loads are not needed, but re-load specular, force
// cache-hits by referencing same vertex !
or ( ( ( 0x24300 | ((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
or r0, r18 , r19
call _planarize_fn_p
or r0, r18 , r20
or ( ( ( 0xf700 | ((( ( ( (( (( 0 )+( 32 )) )+( 20 )) ) ) ) & 0xff) << 0) | (((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )-( ( (( (( 0 )+( 32 )) )+( 20 )) ) )) ) )+116) & 0x7f) << 23) ) |(1<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0xf700 | ((( ( ( (( (( 0 )+( 32 )) )+( 20 )) ) ) ) & 0xff) << 0) | (((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )-( ( (( (( 0 )+( 32 )) )+( 20 )) ) )) ) )+116) & 0x7f) << 23) ) |(1<<20)) )>>16)&0xffff, r16 , r16
st.l r16 , 4( r5 )
fst.l f3 , 8( r5 )++
// NOTE vertex pointers no longer needed, dont restore
// r17 holds macro, which is SEND with embedded count
// of 64-bit words
// zbuf diffuse specular triangle is 14 64-bit words
//
or ( (0x10000000| 14 ) )&0xffff, r0, r17 ; orh (( (0x10000000| 14 ) )>>16)&0xffff, r17 , r17
mov r22 , r16
call _safe_binitize_fn
addu 10, r0, r18
adds 80, sp, sp; adds 4, r5 , r16 ; ld.l -76(sp), r1; ld.l -72(sp), r15; ld.l -68(sp), r14; ld.l -64(sp), r13; ld.l -60(sp), r12; ld.l -56(sp), r11; ld.l -52(sp), r10; ld.l -48(sp), r9; ld.l -44(sp), r8; ld.l -40(sp), r7; ld.l -36(sp), r6; ld.l -32(sp), r5; ld.l -28(sp), r4; fld.d -24(sp), f6; fld.d -16(sp), f4; bri r1; fld.d -8(sp), f2;
//}}}
//
// triangle, z-buffered, diffuse lit, specular lit, textured
// 40 64-bit words
//
//{{{ _tri_zb_d_s_tex
.globl _tri_zb_d_s_tex
.align 8
_tri_zb_d_s_tex::
fst.d f2, -8(sp); fst.d f4, -16(sp); fst.d f6, -24(sp); st.l r4, -28(sp); st.l r5, -32(sp); st.l r6, -36(sp); st.l r7, -40(sp); st.l r8, -44(sp); st.l r9, -48(sp); st.l r10, -52(sp); st.l r11, -56(sp); st.l r12, -60(sp); st.l r13, -64(sp); st.l r14, -68(sp); st.l r15, -72(sp); st.l r1, -76(sp); mov r16 , r22 ; adds -80, sp, sp; fmov.ss f8 , f3 ; adds -4, r16 , r5
or ( ( 0x100 ) )&0xffff, r0, r7 ; orh (( ( 0x100 ) )>>16)&0xffff, r7 , r7
st.l r7 , 4( r5 )
adds 4, r5 , r5
fld.d 0( r18 ), f12
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
fld.d 0( r19 ), f14
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r7 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r7 , r7
fld.d 0( r20 ), f16
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r8 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r8 , r8
addu r0, r0, r21
call _preplanarize_fn
adds 24, r0, r17
call _edgize_tri_fn_p
nop
//
// now use r22 to modify vertex pointers
// remember these are pointers to the data we will load during
// zbuffer_fn_p
//
// offset 52 = diffuse slot of NORMCOL, piped loads
call _zbuffer_fn_p
or 52, r0, r17
// offset 16 = specular slot of NORMCOL
or ( ( ( 0x24300 | ((( ( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
call _planarize_fn_p
or 56, r0, r17
// offset 28 = texu
or ( ( ( 0x24300 | ((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) ) ) & 0xff) << 0) | (((( ( 8 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
call _planarize_fn_p
or 28, r0, r17
// offset 32 = texv
or ( ( ( 0x24300 | ((( ( (( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) )+( 8 )) ) ) & 0xff) << 0) | (((( ( 16 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) )+( 8 )) ) ) & 0xff) << 0) | (((( ( 16 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
call _planarize_fn_p
or 32, r0, r17
// offset 36 = texh
or ( ( ( 0x24300 | ((( ( (( (( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) )+( 8 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 16 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( (( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) )+( 8 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 16 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
call _planarize_fn_p
or 36, r0, r17
// and these loads are not needed, but re-load specular, force
// cache-hits by referencing same vertex !
or ( ( ( 0x24300 | ((( ( (( (( (( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) )+( 8 )) )+( 16 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 16 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x24300 | ((( ( (( (( (( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )+( 8 )) )+( 8 )) )+( 16 )) )+( 16 )) ) ) & 0xff) << 0) | (((( ( 16 ) )+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
or r0, r18 , r20
call _planarize_fn_p
or r0, r18 , r19
or ( ( ( 0xf700 | ((( ( ( (( (( 0 )+( 32 )) )+( 20 )) ) ) ) & 0xff) << 0) | (((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )-( ( (( (( 0 )+( 32 )) )+( 20 )) ) )) ) )+116) & 0x7f) << 23) ) |(1<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0xf700 | ((( ( ( (( (( 0 )+( 32 )) )+( 20 )) ) ) ) & 0xff) << 0) | (((( ( (( (( (( (( (( (( 0 )+( 32 )) )+( 20 )) )+( 6 )) )+( 8 )) )+( 16 )) )-( ( (( (( 0 )+( 32 )) )+( 20 )) ) )) ) )+116) & 0x7f) << 23) ) |(1<<20)) )>>16)&0xffff, r16 , r16
st.l r16 , 4( r5 )
fst.l f3 , 8( r5 )++
// NOTE vertex pointers no longer needed, dont restore
// r16 holds macro, which is SEND with embedded count
// of 64-bit words
// zbuf diffuse specular textured triangle is 20 64-bit words
//
or ( (0x10000000| 20 ) )&0xffff, r0, r17 ; orh (( (0x10000000| 20 ) )>>16)&0xffff, r17 , r17
mov r22 , r16
call _safe_binitize_fn
addu 10, r0, r18
adds 80, sp, sp; adds 4, r5 , r16 ; ld.l -76(sp), r1; ld.l -72(sp), r15; ld.l -68(sp), r14; ld.l -64(sp), r13; ld.l -60(sp), r12; ld.l -56(sp), r11; ld.l -52(sp), r10; ld.l -48(sp), r9; ld.l -44(sp), r8; ld.l -40(sp), r7; ld.l -36(sp), r6; ld.l -32(sp), r5; ld.l -28(sp), r4; fld.d -24(sp), f6; fld.d -16(sp), f4; bri r1; fld.d -8(sp), f2;
//}}}
//
// triangle, z-buffered, flat, textured
// not exactly implemented
//
//
//{{{ _tri_zb_f_tex
.globl _tri_zb_f_tex
.align 8
_tri_zb_f_tex::
fst.d f2, -8(sp); fst.d f4, -16(sp); fst.d f6, -24(sp); st.l r4, -28(sp); st.l r5, -32(sp); st.l r6, -36(sp); st.l r7, -40(sp); st.l r8, -44(sp); st.l r9, -48(sp); st.l r10, -52(sp); st.l r11, -56(sp); st.l r12, -60(sp); st.l r13, -64(sp); st.l r14, -68(sp); st.l r15, -72(sp); st.l r1, -76(sp); mov r16 , r22 ; adds -80, sp, sp; fmov.ss f8 , f3 ; adds -4, r16 , r5
or ( ( 0x100 ) )&0xffff, r0, r7 ; orh (( ( 0x100 ) )>>16)&0xffff, r7 , r7
st.l r7 , 4( r5 )
adds 4, r5 , r5
fld.d 0( r18 ), f12
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r16 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r16 , r16
fld.d 0( r19 ), f14
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r7 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r7 , r7
fld.d 0( r20 ), f16
or ( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )&0xffff, r0, r8 ; orh (( ( ( 0x414200 | ((((2)+115) & 0xff) << 23) ) |(2<<18)|(2<<20)) )>>16)&0xffff, r8 , r8
call _preplanarize_fn
addu r0, r0, r21
call _edgize_tri_fn_p
nop
fld.l 24( r18 ), f24
fld.l 24( r19 ), f25
call _zbuffer_fn_p
fld.l 24( r20 ), f26
// now do homo, u, v next for max coherence
addu 0x666, r0, r16
call _planarize_fn
addu 28, r0, r17
addu 0x666, r0, r16
call _planarize_fn
addu 32, r0, r17
addu 0x666, r0, r16
call _planarize_fn
addu 36, r0, r17
addu 0x666, r0, r16
addu 4, r0, r17
call _safe_binitize_fn
addu 10, r0, r18
adds 80, sp, sp; adds 4, r5 , r16 ; ld.l -76(sp), r1; ld.l -72(sp), r15; ld.l -68(sp), r14; ld.l -64(sp), r13; ld.l -60(sp), r12; ld.l -56(sp), r11; ld.l -52(sp), r10; ld.l -48(sp), r9; ld.l -44(sp), r8; ld.l -40(sp), r7; ld.l -36(sp), r6; ld.l -32(sp), r5; ld.l -28(sp), r4; fld.d -24(sp), f6; fld.d -16(sp), f4; bri r1; fld.d -8(sp), f2;
//}}}
//
// triangle, z-buffered, diffuse lit, specular lit, textured, MIPPed
// not exactly implemented
//
//{{{ _tri_zb_d_s_texm
.globl _tri_zb_d_s_texm
.align 8
_tri_zb_d_s_texm::
bri r1
nop
//}}}
//{{{ fsr access
.globl _getFsr
.align 8
_getFsr::
bri r1
ld.c fsr, r16
.globl _setFsr
.align 8
_setFsr::
bri r1
st.c r16, fsr
//}}}
//{{{ _reg_dump
.globl _reg_dump
.align 8
_reg_dump::
//{{{ proc entry - save r1 r2 r3
addu -256, sp, sp
st.l r1,0(sp)
adds 256,sp,r1
// save r2 **before** call into stack frame
st.l r1,4(sp)
st.l fp,8(sp)
//}}}
//{{{ save r4..r31, f2..f31
st.l r4, 12(sp)
st.l r5, 16(sp)
st.l r6, 20(sp)
st.l r7, 24(sp)
st.l r8, 28(sp)
st.l r9, 32(sp)
st.l r10, 36(sp)
st.l r11, 40(sp)
st.l r12, 44(sp)
st.l r13, 48(sp)
st.l r14, 52(sp)
st.l r15, 56(sp)
st.l r16, 60(sp)
//st.l r17, 64(sp)
st.l r18, 68(sp)
st.l r19, 72(sp)
st.l r20, 76(sp)
st.l r21, 80(sp)
st.l r22, 84(sp)
st.l r23, 88(sp)
st.l r24, 92(sp)
st.l r25, 96(sp)
st.l r26, 100(sp)
st.l r27, 104(sp)
st.l r28, 108(sp)
st.l r29, 112(sp)
st.l r30, 116(sp)
st.l r31, 120(sp)
adds 120, sp, sp
fst.l f2, 4(sp)++
fst.l f3, 4(sp)++
fst.l f4, 4(sp)++
fst.l f5, 4(sp)++
fst.l f6, 4(sp)++
fst.l f7, 4(sp)++
fst.l f8, 4(sp)++
fst.l f9, 4(sp)++
fst.l f10, 4(sp)++
fst.l f11, 4(sp)++
fst.l f12, 4(sp)++
fst.l f13, 4(sp)++
fst.l f14, 4(sp)++
fst.l f15, 4(sp)++
fst.l f16, 4(sp)++
fst.l f17, 4(sp)++
fst.l f18, 4(sp)++
fst.l f19, 4(sp)++
fst.l f20, 4(sp)++
fst.l f21, 4(sp)++
fst.l f22, 4(sp)++
fst.l f23, 4(sp)++
fst.l f24, 4(sp)++
fst.l f25, 4(sp)++
fst.l f26, 4(sp)++
fst.l f27, 4(sp)++
fst.l f28, 4(sp)++
fst.l f29, 4(sp)++
fst.l f30, 4(sp)++
fst.l f31, 4(sp)++
adds -240, sp, sp
//}}}
call _trace_regs
mov sp, r16
//{{{ restore all
ld.l 12(sp) , r4
ld.l 16(sp) , r5
ld.l 20(sp) , r6
ld.l 24(sp) , r7
ld.l 28(sp) , r8
ld.l 32(sp) , r9
ld.l 36(sp) , r10
ld.l 40(sp) , r11
ld.l 44(sp) , r12
ld.l 48(sp) , r13
ld.l 52(sp) , r14
ld.l 56(sp) , r15
ld.l 60(sp) , r16
ld.l 64(sp) , r17
ld.l 68(sp) , r18
ld.l 72(sp) , r19
ld.l 76(sp) , r20
ld.l 80(sp) , r21
ld.l 84(sp) , r22
ld.l 88(sp) , r23
ld.l 92(sp) , r24
ld.l 96(sp) , r25
ld.l 100(sp) , r26
ld.l 104(sp) , r27
ld.l 108(sp) , r28
ld.l 112(sp) , r29
ld.l 116(sp) , r30
ld.l 120(sp) , r31
adds 120, sp, sp
fld.l 4(sp)++, f2
fld.l 4(sp)++, f3
fld.l 4(sp)++, f4
fld.l 4(sp)++, f5
fld.l 4(sp)++, f6
fld.l 4(sp)++, f7
fld.l 4(sp)++, f8
fld.l 4(sp)++, f9
fld.l 4(sp)++, f10
fld.l 4(sp)++, f11
fld.l 4(sp)++, f12
fld.l 4(sp)++, f13
fld.l 4(sp)++, f14
fld.l 4(sp)++, f15
fld.l 4(sp)++, f16
fld.l 4(sp)++, f17
fld.l 4(sp)++, f18
fld.l 4(sp)++, f19
fld.l 4(sp)++, f20
fld.l 4(sp)++, f21
fld.l 4(sp)++, f22
fld.l 4(sp)++, f23
fld.l 4(sp)++, f24
fld.l 4(sp)++, f25
fld.l 4(sp)++, f26
fld.l 4(sp)++, f27
fld.l 4(sp)++, f28
fld.l 4(sp)++, f29
fld.l 4(sp)++, f30
fld.l 4(sp)++, f31
adds -240, sp, sp
//}}}
//{{{ proc exit
ld.l 0(sp),r1
ld.l 8(sp),fp
bri r1
addu 256, sp, sp
//}}}
//}}}
// constant for 1/x code
.data
.align 8
.C00037: // (0)
.long 0x40000000 // 2.00000000E+00
.tri_entry:
.string "triangle entry"
.byte 0x0
.tri_preplanarize:
.string "preplanarize"
.byte 0x0
.tri_edgeized:
.string "edgized triangle"
.byte 0x0
.tri_zbufized:
.string "zbuffered triangle"
.byte 0x0
.tri_planarized:
.string "planarized something"
.byte 0x0
.preplane_gotc:
.string "halfway thru preplane"
.byte 0x0
.plane_loadedvs:
.string "planarize - have loaded fv1 etc."
.byte 0x0
.bini_full:
.string "bin full"
.byte 0x0
.bini_notfull:
.string "bin not full"
.byte 0x0
.bini_start:
.string "bin start binitize"
.byte 0x0
.bini_endfull:
.string "end of bin full"
.byte 0x0
.bini_more_x:
.string "more than 1 x-bin"
.byte 0x0
.bini_more_y:
.string "more than 1 y-bin"
.byte 0x0
.bini_x_loop:
.string "x-loop in binitize"
.byte 0x0
.bini_check_usage:
.string "check usage count"
.byte 0x0
.r5r6r7opcodes:
.string "r5 r6 r7 have opcodes?"
.byte 0x0
.bini_pipe_minimax:
.string "computed minimax piped"
.byte 0x0