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>
1315 lines
37 KiB
Scheme
1315 lines
37 KiB
Scheme
// nicked from output of PGC Rel 1.4 -opt 2
|
|
.text
|
|
.align 8
|
|
.text
|
|
|
|
#define trace_regs(label)\
|
|
adds -16, sp, sp; \
|
|
st.l r1, 4(sp); \
|
|
adds -256, sp, sp; \
|
|
st.l r17, 64(sp); \
|
|
orh ha%label, r0, r17; \
|
|
or l%label, r17, r17; \
|
|
call _reg_dump; \
|
|
adds 256, sp, sp; \
|
|
ld.l 4(sp), r1; \
|
|
adds 16, sp, sp
|
|
|
|
|
|
|
|
//{{{ 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
|
|
//}}}
|
|
|
|
#include "u:\projects\dbi0150\dbi0151\ucode\igc_opco.h"
|
|
#include "\pazpl5\pxpl5sup\pxplmacr.h"
|
|
#include "\pazpl5\pxpl5sup\divpxmap.h"
|
|
#include "\pazpl5\pxpl5sup\dmaengn.h"
|
|
#include "\pazpl5\pxpl5sup\register.h"
|
|
|
|
//{{{ some housekeeping code
|
|
//{{{ tex_scalefac
|
|
|
|
.globl _tex_scalefac
|
|
.align 8
|
|
|
|
_tex_scalefac::
|
|
//
|
|
// fparam1, 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 fparam1, iparam1
|
|
fxfr fparam2, iparam2
|
|
fxfr fparam3, iparam3
|
|
|
|
subs iparam1, iparam2, r0
|
|
bc i2_gt_i1
|
|
subs iparam1, iparam3, r0
|
|
bnc.t igotmax
|
|
mov iparam1, r31
|
|
br igotmax
|
|
mov iparam3, r31
|
|
i2_gt_i1::
|
|
subs iparam2, iparam3, r0
|
|
bnc.t igotmax
|
|
mov iparam2, r31
|
|
br igotmax
|
|
mov iparam3, 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 - i will work out where
|
|
//
|
|
andh 0x7f80, r31, r31 // extract exponent of max
|
|
orh 0x7e80, r0, iparam1
|
|
subu iparam1, r31, r31 // and we have magic
|
|
|
|
bri r1
|
|
ixfr r31, fparam1
|
|
//}}}
|
|
|
|
//{{{ _trunc_test ( int *truncy, float a, float b, float c )
|
|
.globl _trunc_test
|
|
.align 8
|
|
|
|
_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
|
|
|
|
|
|
//}}}
|
|
|
|
//{{{ give_fp returns value of frame pointer
|
|
.globl _give_fp
|
|
.align 8
|
|
|
|
// binitize a primitive
|
|
|
|
_give_fp::
|
|
bri r1
|
|
addu r0, r3, r16
|
|
//}}}
|
|
|
|
//{{{ give_stepping
|
|
.globl _give_stepping
|
|
.align 8
|
|
|
|
|
|
_give_stepping::
|
|
ld.c epsr, r16
|
|
shr 8, r16, r16
|
|
bri r1
|
|
and 0x1f, r16, r16
|
|
//}}}
|
|
|
|
//{{{ give_860type
|
|
.globl _give_860type
|
|
.align 8
|
|
|
|
|
|
_give_860type::
|
|
ld.c epsr, r16
|
|
bri r1
|
|
and 0xff, r16, r16
|
|
//}}}
|
|
|
|
//}}}
|
|
|
|
//
|
|
// 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 )
|
|
//
|
|
|
|
|
|
|
|
#if 0
|
|
//{{{ edgize_tri_fn_p pipelined, dual-instruction GOOD ONE
|
|
|
|
// 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 rcoeffptr pre-decremented by 4 bytes
|
|
//
|
|
.globl _edgize_tri_fn_p
|
|
.align 8
|
|
|
|
_edgize_tri_fn_p::
|
|
|
|
d.pfsub.ss fy1, fy2, f0
|
|
st.l iparam1, 4(rcoeffptr)
|
|
d.pfsub.ss fy2, fy3, f0
|
|
nop
|
|
d.pfsub.ss fy3, fy1, f0
|
|
nop
|
|
//
|
|
d.pfsub.ss fx2, fx1, ftmp2
|
|
nop
|
|
d.pfsub.ss fx3, fx2, ftmp1
|
|
fst.l ftmp2, 8(rcoeffptr) // edge[0] eqn[0]
|
|
d.pfsub.ss fx1, fx3, ftmp2
|
|
fst.l ftmp1, 24(rcoeffptr) // edge[1] eqn [0]
|
|
//
|
|
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
|
|
//
|
|
d.m12tpm.ss fx1, fy2, ftmp1
|
|
fst.l ftmp2, 40(rcoeffptr) // edge[2] eqn [0]
|
|
d.m12tpm.ss fx2, fy3, ftmp2
|
|
nop
|
|
d.m12tpm.ss fx3, fy1, ftmp3
|
|
st.l iparam1, 20(rcoeffptr)
|
|
|
|
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
|
|
nop
|
|
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
|
|
fst.l ftmp1, 12(rcoeffptr) // edge[0] eqn[1]
|
|
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
|
|
fst.l ftmp2, 28(rcoeffptr) // edge[1] eqn[1]
|
|
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
|
|
fst.l ftmp3, 44(rcoeffptr) // edge[2] eqn[1]
|
|
d.i2s1.ss ftmp5, f0, f0
|
|
nop
|
|
d.i2s1.ss ftmp6, f0, f0
|
|
st.l iparam1, 36(rcoeffptr)
|
|
d.pfadd.ss f0, f0, ftmp1
|
|
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
|
|
d.pfadd.ss f0, f0, ftmp2
|
|
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
|
|
pfadd.ss f0, f0, ftmp3
|
|
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
|
|
fnop
|
|
bri r1
|
|
|
|
//}}}
|
|
#endif
|
|
|
|
|
|
|
|
#if 0
|
|
//{{{ preplanaredge
|
|
//
|
|
//
|
|
//
|
|
|
|
.globl _preplanaredge
|
|
.align 8
|
|
|
|
//
|
|
// preplanarize_fn ( float *coeffs, unused, v1, v2, v3, v4 );
|
|
//
|
|
// preplanarize sets up the shared expressions and edgeizes the
|
|
// triangle - we need to cache the deltas dx0, dx1, dx2 into registers,
|
|
// determine whether triangle subtends too small an area on-screen, and do
|
|
// trivial rejection based on screen-space bounds
|
|
//
|
|
// VICIOUS - returns TRIV_REJECT in r31
|
|
//
|
|
_preplanaredge::
|
|
|
|
// preplanaredge - calcDeltas in unc-speak, ROLLED IN WITH edgize_tri
|
|
//
|
|
// dx0 = x1
|
|
// dy0 = y1
|
|
// dx1 = x2 - x1
|
|
// dy1 = y2 - y1
|
|
// dx2 = x3 - x1
|
|
// dy2 = y3 - y1
|
|
// c = 1.0f / (dx1 * dy2) - (dy1 * dx2)
|
|
// dx1*=c
|
|
// dx2*=c
|
|
// dy1*=c
|
|
// dy2*=c
|
|
//
|
|
// nb we can define x0, x1, x2 etc as dx0, dx1, dx2
|
|
//
|
|
#define max_screen_x fx4
|
|
#define max_screen_y fy4
|
|
|
|
orh ha%.C00037, r0, r31 // pre-load 2.0000e+00
|
|
fld.l l%.C00037(r31), ftmp3
|
|
|
|
orh ha%.C362436, r0, r31 // pre-load minimum area
|
|
fld.l l%.C362436(r31), ftmp1
|
|
|
|
orh ha%.Cmax_x, r0, r31
|
|
fld.d l%.Cmax_x(r31), max_screen_x
|
|
|
|
orh ha%_screenize_rec, r0, r31
|
|
or l%_screenize_rec, r31, r31
|
|
fld.d 0(r31), fminx
|
|
fld.d 8(r31), fmaxx
|
|
|
|
// now pipe up repeated expressions
|
|
// dx1 = x1 - x0
|
|
// dy1 = y1 - y0
|
|
// dx2 = x2 - x0
|
|
// dy2 = y2 - y0
|
|
// c = 1.0f / (dx1 * dy2) - (dy1 * dx2)
|
|
|
|
pfsub.ss fx2, fx1, f0
|
|
pfsub.ss fx3, fx1, f0
|
|
pfsub.ss fy2, fy1, f0
|
|
pfsub.ss fy3, fy1, dx1
|
|
pfsub.ss f0, f0, dx2
|
|
m12ttpa.ss dx1, dx2, dy1 // m-stage1 = x1*x2
|
|
m12ttpa.ss f0, f0, dy2 // 2
|
|
m12ttpa.ss dy1, dy2, f0 // m-stage1 = y1*y2, m-stage3 = x1*x2
|
|
i2ap1.ss f0, f0, f0 // x1*x2 into T
|
|
i2st.ss f0, f0, f0 // x1*x2 - y1*y2 into a-stage 1
|
|
//
|
|
// these are rolled into edgize below
|
|
//
|
|
// pfadd.ss f0, f0, f0 // stage 2
|
|
// pfadd.ss f0, f0, f0 // stage 3
|
|
// pfadd.ss f0, f0, fC // into C
|
|
//
|
|
|
|
// in-line edgize_tri !!!
|
|
|
|
// per edge
|
|
//
|
|
// eqn[0]=p1[Y] - p2[Y];
|
|
// eqn[1]=p2[X] - p1[X];
|
|
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
|
|
//
|
|
// so edge1 A = y1-y2
|
|
// so edge1 B = x2-x1
|
|
// C = y2x1 - x2y1
|
|
// so edge2 A = y2-y3
|
|
// so edge2 B = x3-x2
|
|
// C = y3x2 - x3y2
|
|
// so edge3 A = y3-y1
|
|
// so edge3 B = x1-x3
|
|
// C = y1x3 - x1y3
|
|
//
|
|
// nb we enter here with rcoeffptr pre-decremented by 4 bytes
|
|
//
|
|
// there are 15 flops above, of which we need to compute 13
|
|
// (y3-y1, x2-x1 are already in registers), so lets get
|
|
// it down to 13 ticks?
|
|
|
|
m12apm.ss x1, y2, f0
|
|
m12apm.ss x2, y1, f0
|
|
m12apm.ss x2, y3, fC // saved 3 ticks there !
|
|
m12ttpa.ss x3, y2, f0 // push x1y2 to T
|
|
m12tsm.ss x3, y1, f0 // adder 1 = x1y2 - x2y1
|
|
pfmul.ss y3, x1, ftmp1 // ftmp1 = x2y3
|
|
mim1s2.ss y1, y2, ftmp2 // ftmp2 = x3y2, adder1 = y1-y2
|
|
mim1s2.ss ftmp1, ftmp2, ftmp1 // ftmp1 = x3y1, adder3=x1y2-x2y1
|
|
rat1s2.ss x1, x3, fA // fA = edge1 A, T = x3y1
|
|
r2st.ss f0, f0, ftmp2 // adder1=y1x3-x1y3, ftmp2=y1-y2
|
|
// multiplier is now flushed!
|
|
pfsub.ss y2, y3, ftmp3 // tmp3 = x2y3-x3y2
|
|
pfsub.ss x1, x3, ftmp4 // tmp4 = x1 - x3
|
|
pfadd.ss f0, f0, ftmp5 // tmp5 = y1x3 - x1y3
|
|
pfadd.ss f0, f0, ftmp6 // tmp6 = y2 - y3
|
|
pfadd.ss f0, f0, ftmp7 // tmp7 = x1 - x3
|
|
|
|
// now invert C - try to roll this in above?
|
|
//
|
|
// d1 = recp (V)
|
|
// b = d1 * V
|
|
// c = 2 - b
|
|
// d2 = d1 * c
|
|
// e = d2 * V
|
|
// f = 2 - e
|
|
// inv = d2 * f
|
|
|
|
frcp.ss fC, ftmp1 // start 1.0 / fC - 2^-8
|
|
fmul.ss fC, ftmp1, ftmp2 // guess * divisor
|
|
fld.l iparam2(rv1), fv1
|
|
fsub.ss ftmp3, ftmp2, ftmp2 // 2 - (guess * divisor)
|
|
fmul.ss ftmp1, ftmp2, ftmp1 // 2^-15
|
|
fld.l iparam2(rv2), fv2
|
|
fmul.ss fC, ftmp1, ftmp2 // guess * divisor
|
|
fsub.ss ftmp3, ftmp2, ftmp2 // 2 - (guess * divisor)
|
|
fld.l iparam2(rv3), fv3
|
|
fmul.ss ftmp1, ftmp2, fC // 2^-23 - run with it
|
|
|
|
pfmul.ss fC, dx1, f0
|
|
pfmul.ss fC, dx2, f0
|
|
pfmul.ss fC, dy1, f0
|
|
pfmul.ss fC, dy2, f0
|
|
pfmul.ss fC, fC, dx1
|
|
pfmul.ss f0, f0, dx2
|
|
pfmul.ss f0, f0, dy1
|
|
pfmul.ss f0, f0, dy2
|
|
pfmul.ss f0, f0, fC // fC now == C^2
|
|
pfgt fC, ftmp1, f0
|
|
bnc .triv_reject // if area < MINAREA, triv_reject
|
|
|
|
// ******************************************
|
|
// clamp minimax against screen max coordinates
|
|
// now get real minimax xy for binning
|
|
//
|
|
// firstly check triv rejection, max < 0 etc.
|
|
//
|
|
|
|
pfgt.ss ftmp1, fmaxx, f0
|
|
bc .triv_reject
|
|
|
|
pfgt.ss ftmp1, fmaxy, f0
|
|
bc .triv_reject
|
|
|
|
pfgt.ss fminx, max_screen_x, f0
|
|
bc .triv_reject
|
|
|
|
pfgt.ss fminy, max_screen_y, f0
|
|
bc .triv_reject
|
|
|
|
// now check binning
|
|
// get real minx
|
|
pfgt.ss fminx, f0, f0
|
|
bc .no_clamp_fminx
|
|
fmov.ss f0, fminx
|
|
|
|
.no_clamp_fminx::
|
|
|
|
// get real miny
|
|
pfgt.ss fminy, f0, f0
|
|
bc .no_clamp_fminy
|
|
fmov.ss f0, fminy
|
|
|
|
.no_clamp_fminy::
|
|
|
|
// get real maxx
|
|
pfgt.ss max_screen_x, fmaxx, f0
|
|
bc .no_clamp_fmaxx
|
|
fmov.ss max_screen_x, fmaxx
|
|
|
|
.no_clamp_fmaxx::
|
|
// get real maxy
|
|
pfgt.ss max_screen_y, fmaxy, f0
|
|
bc .no_clamp_fmaxy
|
|
fmov.ss max_screen_y, fmaxy
|
|
|
|
.no_clamp_fmaxy::
|
|
|
|
bri r1
|
|
or 0x0, r0, r31
|
|
|
|
.triv_reject::
|
|
bri r1
|
|
or 0x1, r0, r31
|
|
|
|
//}}}
|
|
//{{{ preplanaredge - roll 1/C into pipelined sequence
|
|
//
|
|
//
|
|
//
|
|
|
|
.globl _preplanaredge
|
|
.align 8
|
|
|
|
//
|
|
// preplanarize_fn ( float *coeffs, unused, v1, v2, v3, v4 );
|
|
//
|
|
// preplanarize sets up the shared expressions and edgeizes the
|
|
// triangle - we need to cache the deltas dx0, dx1, dx2 into registers,
|
|
// determine whether triangle subtends too small an area on-screen, and do
|
|
// trivial rejection based on screen-space bounds
|
|
//
|
|
// VICIOUS - returns TRIV_REJECT in r31
|
|
//
|
|
_preplanaredge::
|
|
|
|
// preplanaredge - calcDeltas in unc-speak, ROLLED IN WITH edgize_tri
|
|
//
|
|
// dx0 = x1
|
|
// dy0 = y1
|
|
// dx1 = x2 - x1
|
|
// dy1 = y2 - y1
|
|
// dx2 = x3 - x1
|
|
// dy2 = y3 - y1
|
|
// c = 1.0f / (dx1 * dy2) - (dy1 * dx2)
|
|
// dx1*=c
|
|
// dx2*=c
|
|
// dy1*=c
|
|
// dy2*=c
|
|
//
|
|
// nb we can define x0, x1, x2 etc as dx0, dx1, dx2
|
|
//
|
|
#define max_screen_x fx4
|
|
#define max_screen_y fy4
|
|
|
|
orh ha%.C00037, r0, r31 // pre-load 2.0000e+00
|
|
fld.l l%.C00037(r31), ftmp3
|
|
|
|
orh ha%.C362436, r0, r31 // pre-load minimum area
|
|
fld.l l%.C362436(r31), ftmp1
|
|
|
|
orh ha%.Cmax_x, r0, r31
|
|
fld.d l%.Cmax_x(r31), max_screen_x
|
|
|
|
orh ha%_screenize_rec, r0, r31
|
|
or l%_screenize_rec, r31, r31
|
|
fld.d 0(r31), fminx
|
|
fld.d 8(r31), fmaxx
|
|
|
|
// now pipe up repeated expressions
|
|
// dx1 = x1 - x0
|
|
// dy1 = y1 - y0
|
|
// dx2 = x2 - x0
|
|
// dy2 = y2 - y0
|
|
// c = 1.0f / (dx1 * dy2) - (dy1 * dx2)
|
|
|
|
pfsub.ss fx2, fx1, f0
|
|
pfsub.ss fx3, fx1, f0
|
|
pfsub.ss fy2, fy1, f0
|
|
pfsub.ss fy3, fy1, dx1
|
|
pfsub.ss f0, f0, dx2
|
|
m12ttpa.ss dx1, dx2, dy1 // m-stage1 = x1*x2
|
|
m12ttpa.ss f0, f0, dy2 // 2
|
|
m12ttpa.ss dy1, dy2, f0 // m-stage1 = y1*y2, m-stage3 = x1*x2
|
|
i2ap1.ss f0, f0, f0 // x1*x2 into T
|
|
r2st.ss f0, f0, f0 // x1*x2 - y1*y2 into a-stage 1
|
|
m12apm.ss x1, y2, f0
|
|
m12apm.ss x2, y1, f0 // m 1 2 3 a 1 2 3
|
|
m12apm.ss x2, y3, fC // x2y3 x2y1 x1y2
|
|
frcp.ss fC, frcp
|
|
|
|
// in-line edgize_tri !!!
|
|
|
|
// per edge
|
|
//
|
|
// eqn[0]=p1[Y] - p2[Y];
|
|
// eqn[1]=p2[X] - p1[X];
|
|
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
|
|
//
|
|
// so edge1 A = y1-y2
|
|
// so edge1 B = x2-x1
|
|
// C = y2x1 - x2y1
|
|
// so edge2 A = y2-y3
|
|
// so edge2 B = x3-x2
|
|
// C = y3x2 - x3y2
|
|
// so edge3 A = y3-y1
|
|
// so edge3 B = x1-x3
|
|
// C = y1x3 - x1y3
|
|
//
|
|
// nb we enter here with rcoeffptr pre-decremented by 4 bytes
|
|
//
|
|
// there are 15 flops above, of which we need to compute 13
|
|
// (y3-y1, x2-x1 are already in registers), so lets get
|
|
// it down
|
|
//
|
|
// d1 = recp (V)
|
|
// b = d1 * V
|
|
// c = 2 - b
|
|
// d2 = d1 * c
|
|
// e = d2 * V
|
|
// f = 2 - e
|
|
// inv = d2 * f
|
|
|
|
m12ttpa.ss x3, y2, f0 // push x1y2 to T
|
|
m12tsm.ss x3, y1, f0 // adder 1 = x1y2 - x2y1
|
|
pfmul.ss y3, x1, ftmp1 // ftmp1 = x2y3
|
|
mim1s2.ss y1, y2, ftmp2 // ftmp2 = x3y2, adder1 = y1-y2
|
|
mim1s2.ss ftmp1, ftmp2, ftmp1 // ftmp1 = x3y1, adder3=x1y2-x2y1
|
|
rat1s2.ss x1, x3, fA // fA = edge1 A, T = x3y1
|
|
m12tsm.ss frcp, fC, ftmp2 // adder1=y1x3-x1y3, ftmp2=y1-y2
|
|
ia1s2.ss y2, y3, ftmp3 // tmp3 = x2y3-x3y2
|
|
ia1s2.ss x1, x3, ftmp4 // tmp4 = x1 - x3
|
|
i2s1.ss two, f0, ftmp5 // tmp5 = y1x3 - x1y3 adder1=2-rcp*C
|
|
r2pt.ss frcp, f0, ftmp6 // tmp6 = y2 - y3 push rcp into KR
|
|
pfadd.ss f0, f0, ftmp7 // tmp7 = x1 - x3
|
|
rat1p2.ss f0, f0, f0 // mul-1 = rcp*(2-rcp*c)
|
|
pfmul.ss f0, f0, f0
|
|
pfmul.ss f0, f0, f0
|
|
pfmul.ss f0, f0, frcp
|
|
// now unpipeline ?
|
|
fmul.ss fC, frcp, ftmp // guess*divisor
|
|
fsub.ss two, ftmp, ftmp // 2-guess*divisor
|
|
fmul.ss fC, ftmp, fC // result !
|
|
|
|
|
|
pfmul.ss dx1, fC, f0
|
|
pfmul.ss fC, dx2, f0
|
|
pfmul.ss fC, dy1, f0
|
|
pfmul.ss fC, dy2, f0
|
|
pfmul.ss fC, fC, dx1
|
|
pfmul.ss f0, f0, dx2
|
|
pfmul.ss f0, f0, dy1
|
|
pfmul.ss f0, f0, dy2
|
|
pfmul.ss f0, f0, fC // fC now == C^2
|
|
pfgt fC, ftmp1, f0
|
|
bnc .triv_reject // if area < MINAREA, triv_reject
|
|
|
|
// ******************************************
|
|
// clamp minimax against screen max coordinates
|
|
// now get real minimax xy for binning
|
|
//
|
|
// firstly check triv rejection, max < 0 etc.
|
|
//
|
|
|
|
pfgt.ss ftmp1, fmaxx, f0
|
|
bc .triv_reject
|
|
|
|
pfgt.ss ftmp1, fmaxy, f0
|
|
bc .triv_reject
|
|
|
|
pfgt.ss fminx, max_screen_x, f0
|
|
bc .triv_reject
|
|
|
|
pfgt.ss fminy, max_screen_y, f0
|
|
bc .triv_reject
|
|
|
|
// now check binning
|
|
// get real minx
|
|
pfgt.ss fminx, f0, f0
|
|
bc .no_clamp_fminx
|
|
fmov.ss f0, fminx
|
|
|
|
.no_clamp_fminx::
|
|
|
|
// get real miny
|
|
pfgt.ss fminy, f0, f0
|
|
bc .no_clamp_fminy
|
|
fmov.ss f0, fminy
|
|
|
|
.no_clamp_fminy::
|
|
|
|
// get real maxx
|
|
pfgt.ss max_screen_x, fmaxx, f0
|
|
bc .no_clamp_fmaxx
|
|
fmov.ss max_screen_x, fmaxx
|
|
|
|
.no_clamp_fmaxx::
|
|
// get real maxy
|
|
pfgt.ss max_screen_y, fmaxy, f0
|
|
bc .no_clamp_fmaxy
|
|
fmov.ss max_screen_y, fmaxy
|
|
|
|
.no_clamp_fmaxy::
|
|
|
|
bri r1
|
|
or 0x0, r0, r31
|
|
|
|
.triv_reject::
|
|
bri r1
|
|
or 0x1, r0, r31
|
|
|
|
//}}}
|
|
//{{{ edgize_tri pipelined, dual-instruction
|
|
|
|
// we have in register fy12, fy31, fy23 and
|
|
// fx13, fx21, fx32
|
|
// so this can shrink to 10 ticks from 20
|
|
|
|
// per edge
|
|
//
|
|
// eqn[0]=p1[Y] - p2[Y];
|
|
// eqn[1]=p2[X] - p1[X];
|
|
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
|
|
//
|
|
// so edge1 A = y1-y2
|
|
// so edge1 B = x2-x1
|
|
// C = y2x1 - x2y1
|
|
// so edge2 A = y2-y3
|
|
// so edge2 B = x3-x2
|
|
// C = y3x2 - x3y2
|
|
// so edge3 A = y3-y1
|
|
// so edge3 B = x1-x3
|
|
// C = y1x3 - x1y3
|
|
//
|
|
// nb we enter here with rcoeffptr pre-decremented by 4 bytes
|
|
//
|
|
.globl _edgize_tri
|
|
.align 8
|
|
|
|
_edgize_tri::
|
|
// there are 15 flops above, of which we need to compute 13
|
|
// (y3-y1, x2-x1 are already in registers), so lets get
|
|
// it down to 13 ticks?
|
|
|
|
pfmul.ss x1, y2, f0
|
|
pfmul.ss x2, y1, f0
|
|
pfmul.ss x2, y3, f0
|
|
m12ttpa.ss x3, y2, f0 // push x1y2 to T
|
|
m12tsm.ss x3, y1, f0 // adder 1 = x1y2 - x2y1
|
|
pfmul.ss y3, x1, ftmp1 // ftmp1 = x2y3
|
|
mim1s2.ss y1, y2, ftmp2 // ftmp2 = x3y2, adder1 = y1-y2
|
|
mim1s2.ss ftmp1, ftmp2, ftmp1 // ftmp1 = x3y1, adder3=x1y2-x2y1
|
|
rat1s2.ss x1, x3, fA // fA = edge1 A, T = x3y1
|
|
r2st.ss f0, f0, ftmp2 // adder1=y1x3-x1y3, ftmp2=y1-y2
|
|
// multiplier is now flushed!
|
|
pfsub.ss y2, y3, ftmp3 // tmp3 = x2y3-x3y2
|
|
pfsub.ss x1, x3, ftmp4 // tmp4 = x1 - x3
|
|
pfadd.ss f0, f0, ftmp5 // tmp5 = y1x3 - x1y3
|
|
pfadd.ss f0, f0, ftmp6 // tmp6 = y2 - y3
|
|
pfadd.ss f0, f0, ftmp7 // tmp7 = x1 - x3
|
|
//}}}
|
|
//{{{ _old_planarize_fn_p pipelined DONT STORE OPCODE
|
|
//
|
|
// Hey Ho Lets Go!
|
|
//
|
|
// The definitive planarization algorithm
|
|
//
|
|
// invC=1.0f / (fx1 * (fy2 - fy3)) +
|
|
// (fx2 * (fy3 - fy1)) +
|
|
// (fx3 * (fy1 - fy2));
|
|
//
|
|
// eqn[0]= invC*(fy1 * (fv3 - fv2)) +
|
|
// (fy2 * (fv1 - fv3)) +
|
|
// (fy3 * (fv2 - fv1));
|
|
//
|
|
// a = fv3 - fv2
|
|
// b = fv1 - fv3
|
|
// c = fv2 - fv1
|
|
// d = fy1 * a
|
|
// e = fy2 * b
|
|
// f = fy3 * c
|
|
// g = d + e
|
|
// h = g + f
|
|
// eqn[0] = fC * h
|
|
//
|
|
// eqn[1]= invC*(fv1 * (fx3 - fx2)) +
|
|
// (fv2 * (fx1 - fx3)) +
|
|
// (fv3 * (fx2 - fx1));
|
|
//
|
|
// i = fv1 * fx32
|
|
// j = fv2 * fx13
|
|
// k = fv3 * fx21
|
|
// l = i + j
|
|
// m = k + l
|
|
// eqn[1] = fC * m
|
|
//
|
|
// eqn[2]= invC*(fx1*((fy2*fv3) - (fy3*fv2))) +
|
|
// (fx2*((fy3*fv1) - (fy1*fv3))) +
|
|
// (fx3*((fy1*fv2) - (fy2*fv1)));
|
|
//
|
|
// n = fy2 * fv3
|
|
// o = fy3 * fv2
|
|
// p = fy3 * fv1
|
|
// q = fy1 * fv3
|
|
// r = fy1 * fv2
|
|
// s = fy2 * fv1
|
|
// t = n - o
|
|
// u = p - q
|
|
// v = r - s
|
|
// w = fx1 * t
|
|
// x = fx2 * u
|
|
// y = fx3 * v
|
|
// z = w + x
|
|
// aa= y + z
|
|
// eqn[2] = invC * aa
|
|
//
|
|
|
|
#define ft1 ftmp1
|
|
#define ft2 ftmp2
|
|
#define ft3 ftmp3
|
|
|
|
.globl _old_planarize_fn_p
|
|
.globl _planarize_fn_p
|
|
.align 8
|
|
|
|
_old_planarize_fn_p::
|
|
_planarize_fn_p::
|
|
// m1 m2 m3 | T | a1 a2 a3 | KR | t1 t2 t3
|
|
// n = fy2 * fv3
|
|
// o = fy3 * fv2
|
|
pfmul.ss fy2, fv3, f0 // n ? ? | ? | ? ? ? | ? | ? ? ?
|
|
pfmul.ss fy3, fv2, f0 // o n ? | ? | ? ? ? | ? | ? ? ?
|
|
|
|
// p = fy3 * fv1
|
|
// q = fy1 * fv3
|
|
pfmul.ss fy3, fv1, f0 // p o n | ? | ? ? ? | ? | ? ? ?
|
|
mm12ttpm.ss fy1, fv3, f0 // q p o | n | ? ? ? | ? | ? ? ?
|
|
|
|
// r = fy1 * fv2
|
|
// t = n - o
|
|
// s = fy2 * fv1
|
|
m12tsm.ss fy1, fv2, f0 // r q p | ? | t ? ? | ? | ? ? ?
|
|
mm12ttpm.ss fy2, fv1, f0 // s r q | p | ? t ? | ? | ? ? ?
|
|
|
|
// i = fv1 * fx32
|
|
// u = p - q
|
|
// a = fv3 - fv2
|
|
m12tsm.ss fv1, fx32, f0 // i s r | ? | u ? t | ? | ? ? ?
|
|
pfsub.ss fv3, fv2, ft1 // i s r | ? | a u ? | ? | t ? ?
|
|
|
|
// j = fv2 * fx13
|
|
// k = fv3 * fx21
|
|
// v = r - s
|
|
mm12ttpm.ss fv2, fx13, f0 // j i s | r | ? a u | ? | t ? ?
|
|
m12tsm.ss fv3, fx21, ft2 // k j i | ? | v ? a | ? | t u ?
|
|
|
|
// w = fx1 * t
|
|
// x = fx2 * u
|
|
pfmul.ss fx1, ft1, ft3 // w k j | ? | v ? a | ? | ? u i
|
|
pfmul.ss fx2, ft2, ft1 // x w k | ? | v ? a | ? | j ? i
|
|
|
|
// l = i + j
|
|
// d = fy1 * a
|
|
pfadd.ss ft1, ft3, ft2 // x w k | ? | l v ? | ? | ? a ?
|
|
mm12mpm.ss fy1, ft2, ft3 // d x w | ? | ? l v | ? | ? ? k
|
|
// b = fv1 - fv3
|
|
// c = fv2 - fv1
|
|
pfsub.ss fv1, fv3, ft1 // d x w | ? | b ? l | ? | v ? k
|
|
pfsub.ss fv2, fv1, ft2 // d x w | ? | c b ? | ? | v l k
|
|
// m = k + l
|
|
// y = fx3 * v
|
|
// z = w + x
|
|
rat1p2.ss ft2, ft3, f0 // ? d x | w | m c b | ? | v ? ?
|
|
m12tpm.ss fx3, ft1, ft2 // y ? d | ? | z m c | ? | ? b ?
|
|
|
|
// e = fy2 * b
|
|
// f = fy3 * c
|
|
d.m12ttpa.ss fy2, ft2, ft1 // e y ? | d | ? z m | ? | c ? ?
|
|
fld.l iparam2(rv3), fv3
|
|
d.m12apm.ss fy3, ft1, ft2 // f e y | d | ? ? z | ? | ? m ?
|
|
fld.l iparam2(rv2), fv2
|
|
// last-stage mul+T ->g, fC -> KR, save adder result !
|
|
// eqn[1] = fC * m
|
|
// g = d + e
|
|
d.pfmul.ss fC, ft2, ft1 // e1 f e | d | ? ? z | ? | y ? ?
|
|
nop
|
|
d.r2pt.ss fC, f0, ft2 // ? e1 f | ? | g ? ? | ? | y z ?
|
|
fld.l iparam2(rv1), fv1
|
|
|
|
// aa= y + z
|
|
d.mrm1p2.ss ft1, ft2, ft3 // ? ? e1| ? | aa g ? | ? | ? ? f
|
|
nop
|
|
d.mm12mpm.ss f0, f0, ft2 // ? ? ? | ? | ? aa g | ? | ? e1 f
|
|
adds 4, rcoeffptr, rcoeffptr
|
|
// h = g + f
|
|
// eqn[2] = invC * aa
|
|
d.r2ap1.ss ft3, f0, f0 // ? ? ? | ? | h ? aa | ? | ? e1 ?
|
|
nop
|
|
d.ra1p2.ss f0, f0, f0 // e2 ? ? | ? | ? h ? | ? | ? e1 ?
|
|
nop
|
|
|
|
// eqn[0] = fC * h
|
|
d.i2p1.ss f0, f0, f0 // ? e2 ? | ? | ? ? h | ? | ? e1 ?
|
|
fst.l ft2, 12(rcoeffptr)
|
|
d.rat1p2.ss f0, f0, f0
|
|
nop
|
|
d.mi2p1.ss f0, f0, ft1
|
|
nop
|
|
d.mi2p1.ss ft3, f0, f0
|
|
fst.l ft1, 16(rcoeffptr)++
|
|
mi2p1.ss f0, f0, ft3
|
|
bri r1
|
|
fnop
|
|
fst.l ft3, -8(rcoeffptr)
|
|
|
|
//}}}
|
|
//{{{ edgize_tri_fn_p pipelined, dual-instruction, DONT STORE OPCODE
|
|
|
|
// 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 rcoeffptr pre-decremented by 4 bytes
|
|
//
|
|
.globl _edgize_tri_fn_p
|
|
.align 8
|
|
|
|
_edgize_tri_fn_p::
|
|
|
|
d.pfsub.ss fy1, fy2, f0
|
|
nop
|
|
d.pfsub.ss fy2, fy3, f0
|
|
nop
|
|
d.pfsub.ss fy3, fy1, f0
|
|
nop
|
|
//
|
|
d.pfsub.ss fx2, fx1, ftmp2
|
|
nop
|
|
d.pfsub.ss fx3, fx2, ftmp1
|
|
fst.l ftmp2, 8(rcoeffptr) // edge[0] eqn[0]
|
|
d.pfsub.ss fx1, fx3, ftmp2
|
|
fst.l ftmp1, 24(rcoeffptr) // edge[1] eqn [0]
|
|
//
|
|
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
|
|
//
|
|
d.m12tpm.ss fx1, fy2, ftmp1
|
|
fst.l ftmp2, 40(rcoeffptr) // edge[2] eqn [0]
|
|
d.m12tpm.ss fx2, fy3, ftmp2
|
|
nop
|
|
d.m12tpm.ss fx3, fy1, ftmp3
|
|
nop
|
|
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
|
|
nop
|
|
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
|
|
fst.l ftmp1, 12(rcoeffptr) // edge[0] eqn[1]
|
|
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
|
|
fst.l ftmp2, 28(rcoeffptr) // edge[1] eqn[1]
|
|
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
|
|
fst.l ftmp3, 44(rcoeffptr) // edge[2] eqn[1]
|
|
d.i2s1.ss ftmp5, f0, f0
|
|
nop
|
|
d.i2s1.ss ftmp6, f0, f0
|
|
nop
|
|
d.pfadd.ss f0, f0, ftmp1
|
|
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
|
|
d.pfadd.ss f0, f0, ftmp2
|
|
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
|
|
d.pfadd.ss f0, f0, ftmp3
|
|
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
|
|
fnop
|
|
bri r1
|
|
fnop
|
|
|
|
//}}}
|
|
#endif
|
|
|
|
|
|
#if 0
|
|
//{{{ _new_planarize_fn_p pipelined
|
|
#define df1 ftmp1
|
|
#define df2 ftmp2
|
|
#define ft3 ftmp3
|
|
#define fA ftmp4
|
|
#define fB ftmp5
|
|
#define fC ftmp6
|
|
#define tmp1 ftmp7
|
|
#define tmp2 ftmp8
|
|
|
|
//
|
|
// The new and totally definitive planarization algorithm
|
|
//
|
|
// df1 = fv1 - fv0
|
|
// df2 = fv2 - fv0
|
|
// A = (dy2*df1) - (dy1*df2)
|
|
// B = (dx1*df2) - (dx2*df1)
|
|
// C = fv0 - (A * dx0) - (B * dy0)
|
|
//
|
|
|
|
.globl _new_planarize
|
|
.align 8
|
|
|
|
_new_planarize::
|
|
d.pfsub.ss fv1, fv0, f0
|
|
nop
|
|
d.pfsub.ss fv2, fv0, f0
|
|
fld.l iparam2(rv2), fv2 // load up vertex 1 for next call
|
|
d.i2pt.ss dx0, f0, f0
|
|
nop // st fC from last scalar op
|
|
d.r2pt.ss dy0, f0, df1 // click pipe, drop dy0 into KR
|
|
fld.l iparam2(rv3), fv3 // ditto v2
|
|
d.m12apm.ss dy2, df1, df2 //
|
|
nop
|
|
d.m12apm.ss dy1, df2, f0 //
|
|
nop
|
|
d.pfmul.ss dx1, df2, f0 //
|
|
st.l 4(rcoeffptr), iparam1
|
|
d.pfmul.ss dx2, df1, fA // ... dy2*df1
|
|
adds 4, rcoeffptr, rcoeffptr
|
|
d.i2s1.ss fA, f0, f0 // 1st stage adder = A
|
|
nop
|
|
d.i2ap1.ss f0, f0, f0 // T-reg = dx1*df2
|
|
nop
|
|
d.i2st.ss dx0, f0, f0 // 1st-stage adder = B, 3rd stage = A
|
|
nop
|
|
d.iat1p2.ss f0, f0, fA // 1st stage mult = A*dx0 (KI)
|
|
fst.l fA, 4(rcoeffptr)++
|
|
d.ia1p2.ss f0, f0, f0 // .. click pipes
|
|
nop
|
|
d.rat1s2.ss f0, f0, fB // 1st stage mult = B*dy0 (KR)
|
|
fst.l fB, 4(rcoeffptr)++
|
|
d.i2s1.ss fv0, f0, f0 // 1st stage add = f0 - A*dx0
|
|
nop
|
|
d.ra1p2.ss f0, f0, f0 // .. click pipes
|
|
fld.l iparam2(rv1), fv1
|
|
d.mr2pt.ss f0, f0, tmp1 //
|
|
nop
|
|
ia1p2.ss f0, f0, tmp2 //
|
|
bri r1
|
|
fsub.ss tmp2, tmp1, fC // 21 ticks in total
|
|
nop
|
|
|
|
#undef df1
|
|
#undef df2
|
|
#undef ft3
|
|
#undef fA
|
|
#undef fB
|
|
#undef fC
|
|
#undef tmp1
|
|
#undef tmp2
|
|
|
|
//}}}
|
|
#endif
|
|
|
|
//{{{ 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
|
|
|
|
.Cmax_x: // (0)
|
|
.C640:
|
|
.long 0x442fbf5c // 7.02989990E+02
|
|
|
|
.Cmax_y: // (0)
|
|
.C480:
|
|
.long 0x43ff7eb8 // 5.10989990E+02
|
|
|
|
.C00037: // (0)
|
|
.long 0x40000000 // 2.00000000E+00
|
|
|
|
.C362436: // (0)
|
|
.long 0x3ecccccd // 4.00000006E-01
|
|
|
|
.Czscale1024: // (0)
|
|
.long 0x49800000 // 1.04857600E+06
|
|
|
|
.Czscale: // (0)
|
|
.long 0x497fffff // 1.04857588E+06
|
|
|
|
.Ctexscale: // (0)
|
|
.long 0x477fffff // 6.55359883E+04
|
|
|
|
.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_doneminimax:
|
|
.string "binitize, done minimax"
|
|
.byte 0x0
|
|
|
|
.bini_notfull:
|
|
.string "bin not full"
|
|
.byte 0x0
|
|
|
|
.bini_start:
|
|
.string "bin start binitize"
|
|
.byte 0x0
|
|
|
|
.bini_minimax:
|
|
.string "bin got minimaxes"
|
|
.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
|
|
|