// 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< 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