Annotation of quake2/linux/r_draw16.s, revision 1.1.1.1

1.1       root        1: //
                      2: // d_draw16.s
                      3: // x86 assembly-language horizontal 8-bpp span-drawing code, with 16-pixel
                      4: // subdivision.
                      5: //
                      6: 
                      7: #include "qasm.h"
                      8: #include "d_ifacea.h"
                      9: 
                     10: #if    id386
                     11: 
                     12: //----------------------------------------------------------------------
                     13: // 8-bpp horizontal span drawing code for polygons, with no transparency and
                     14: // 16-pixel subdivision.
                     15: //
                     16: // Assumes there is at least one span in pspans, and that every span
                     17: // contains at least one pixel
                     18: //----------------------------------------------------------------------
                     19: 
                     20:        .data
                     21: 
                     22:        .text
                     23: 
                     24: // out-of-line, rarely-needed clamping code
                     25: 
                     26: LClampHigh0:
                     27:        movl    C(bbextents),%esi
                     28:        jmp             LClampReentry0
                     29: LClampHighOrLow0:
                     30:        jg              LClampHigh0
                     31:        xorl    %esi,%esi
                     32:        jmp             LClampReentry0
                     33: 
                     34: LClampHigh1:
                     35:        movl    C(bbextentt),%edx
                     36:        jmp             LClampReentry1
                     37: LClampHighOrLow1:
                     38:        jg              LClampHigh1
                     39:        xorl    %edx,%edx
                     40:        jmp             LClampReentry1
                     41: 
                     42: LClampLow2:
                     43:        movl    $4096,%ebp
                     44:        jmp             LClampReentry2
                     45: LClampHigh2:
                     46:        movl    C(bbextents),%ebp
                     47:        jmp             LClampReentry2
                     48: 
                     49: LClampLow3:
                     50:        movl    $4096,%ecx
                     51:        jmp             LClampReentry3
                     52: LClampHigh3:
                     53:        movl    C(bbextentt),%ecx
                     54:        jmp             LClampReentry3
                     55: 
                     56: LClampLow4:
                     57:        movl    $4096,%eax
                     58:        jmp             LClampReentry4
                     59: LClampHigh4:
                     60:        movl    C(bbextents),%eax
                     61:        jmp             LClampReentry4
                     62: 
                     63: LClampLow5:
                     64:        movl    $4096,%ebx
                     65:        jmp             LClampReentry5
                     66: LClampHigh5:
                     67:        movl    C(bbextentt),%ebx
                     68:        jmp             LClampReentry5
                     69: 
                     70: 
                     71: #define pspans 4+16
                     72: 
                     73:        .align 4
                     74: .globl C(D_DrawSpans16)
                     75: C(D_DrawSpans16):
                     76:        pushl   %ebp                            // preserve caller's stack frame
                     77:        pushl   %edi
                     78:        pushl   %esi                            // preserve register variables
                     79:        pushl   %ebx
                     80: 
                     81: //
                     82: // set up scaled-by-16 steps, for 16-long segments; also set up cacheblock
                     83: // and span list pointers
                     84: //
                     85: // TODO: any overlap from rearranging?
                     86:        flds    C(d_sdivzstepu)
                     87:        fmuls   fp_16
                     88:        movl    C(cacheblock),%edx
                     89:        flds    C(d_tdivzstepu)
                     90:        fmuls   fp_16
                     91:        movl    pspans(%esp),%ebx       // point to the first span descriptor
                     92:        flds    C(d_zistepu)
                     93:        fmuls   fp_16
                     94:        movl    %edx,pbase                      // pbase = cacheblock
                     95:        fstps   zi16stepu
                     96:        fstps   tdivz16stepu
                     97:        fstps   sdivz16stepu
                     98: 
                     99: LSpanLoop:
                    100: //
                    101: // set up the initial s/z, t/z, and 1/z on the FP stack, and generate the
                    102: // initial s and t values
                    103: //
                    104: // FIXME: pipeline FILD?
                    105:        fildl   espan_t_v(%ebx)
                    106:        fildl   espan_t_u(%ebx)
                    107: 
                    108:        fld             %st(1)                  // dv | du | dv
                    109:        fmuls   C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv
                    110:        fld             %st(1)                  // du | dv*d_sdivzstepv | du | dv
                    111:        fmuls   C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
                    112:        fld             %st(2)                  // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
                    113:        fmuls   C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu |
                    114:                                                        //  dv*d_sdivzstepv | du | dv
                    115:        fxch    %st(1)                  // du*d_sdivzstepu | du*d_tdivzstepu |
                    116:                                                        //  dv*d_sdivzstepv | du | dv
                    117:        faddp   %st(0),%st(2)   // du*d_tdivzstepu |
                    118:                                                        //  du*d_sdivzstepu + dv*d_sdivzstepv | du | dv
                    119:        fxch    %st(1)                  // du*d_sdivzstepu + dv*d_sdivzstepv |
                    120:                                                        //  du*d_tdivzstepu | du | dv
                    121:        fld             %st(3)                  // dv | du*d_sdivzstepu + dv*d_sdivzstepv |
                    122:                                                        //  du*d_tdivzstepu | du | dv
                    123:        fmuls   C(d_tdivzstepv) // dv*d_tdivzstepv |
                    124:                                                        //  du*d_sdivzstepu + dv*d_sdivzstepv |
                    125:                                                        //  du*d_tdivzstepu | du | dv
                    126:        fxch    %st(1)                  // du*d_sdivzstepu + dv*d_sdivzstepv |
                    127:                                                        //  dv*d_tdivzstepv | du*d_tdivzstepu | du | dv
                    128:        fadds   C(d_sdivzorigin)        // sdivz = d_sdivzorigin + dv*d_sdivzstepv +
                    129:                                                        //  du*d_sdivzstepu; stays in %st(2) at end
                    130:        fxch    %st(4)                  // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du |
                    131:                                                        //  s/z
                    132:        fmuls   C(d_zistepv)            // dv*d_zistepv | dv*d_tdivzstepv |
                    133:                                                        //  du*d_tdivzstepu | du | s/z
                    134:        fxch    %st(1)                  // dv*d_tdivzstepv |  dv*d_zistepv |
                    135:                                                        //  du*d_tdivzstepu | du | s/z
                    136:        faddp   %st(0),%st(2)   // dv*d_zistepv |
                    137:                                                        //  dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z
                    138:        fxch    %st(2)                  // du | dv*d_tdivzstepv + du*d_tdivzstepu |
                    139:                                                        //  dv*d_zistepv | s/z
                    140:        fmuls   C(d_zistepu)            // du*d_zistepu |
                    141:                                                        //  dv*d_tdivzstepv + du*d_tdivzstepu |
                    142:                                                        //  dv*d_zistepv | s/z
                    143:        fxch    %st(1)                  // dv*d_tdivzstepv + du*d_tdivzstepu |
                    144:                                                        //  du*d_zistepu | dv*d_zistepv | s/z
                    145:        fadds   C(d_tdivzorigin)        // tdivz = d_tdivzorigin + dv*d_tdivzstepv +
                    146:                                                        //  du*d_tdivzstepu; stays in %st(1) at end
                    147:        fxch    %st(2)                  // dv*d_zistepv | du*d_zistepu | t/z | s/z
                    148:        faddp   %st(0),%st(1)   // dv*d_zistepv + du*d_zistepu | t/z | s/z
                    149: 
                    150:        flds    fp_64k                  // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z
                    151:        fxch    %st(1)                  // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z
                    152:        fadds   C(d_ziorigin)           // zi = d_ziorigin + dv*d_zistepv +
                    153:                                                        //  du*d_zistepu; stays in %st(0) at end
                    154:                                                        // 1/z | fp_64k | t/z | s/z
                    155: //
                    156: // calculate and clamp s & t
                    157: //
                    158:        fdivr   %st(0),%st(1)   // 1/z | z*64k | t/z | s/z
                    159: 
                    160: //
                    161: // point %edi to the first pixel in the span
                    162: //
                    163:        movl    C(d_viewbuffer),%ecx
                    164:        movl    espan_t_v(%ebx),%eax
                    165:        movl    %ebx,pspantemp  // preserve spans pointer
                    166: 
                    167:        movl    C(tadjust),%edx
                    168:        movl    C(sadjust),%esi
                    169:        movl    C(d_scantable)(,%eax,4),%edi    // v * screenwidth
                    170:        addl    %ecx,%edi
                    171:        movl    espan_t_u(%ebx),%ecx
                    172:        addl    %ecx,%edi                               // pdest = &pdestspan[scans->u];
                    173:        movl    espan_t_count(%ebx),%ecx
                    174: 
                    175: //
                    176: // now start the FDIV for the end of the span
                    177: //
                    178:        cmpl    $16,%ecx
                    179:        ja              LSetupNotLast1
                    180: 
                    181:        decl    %ecx
                    182:        jz              LCleanup1               // if only one pixel, no need to start an FDIV
                    183:        movl    %ecx,spancountminus1
                    184: 
                    185: // finish up the s and t calcs
                    186:        fxch    %st(1)                  // z*64k | 1/z | t/z | s/z
                    187: 
                    188:        fld             %st(0)                  // z*64k | z*64k | 1/z | t/z | s/z
                    189:        fmul    %st(4),%st(0)   // s | z*64k | 1/z | t/z | s/z
                    190:        fxch    %st(1)                  // z*64k | s | 1/z | t/z | s/z
                    191:        fmul    %st(3),%st(0)   // t | s | 1/z | t/z | s/z
                    192:        fxch    %st(1)                  // s | t | 1/z | t/z | s/z
                    193:        fistpl  s                               // 1/z | t | t/z | s/z
                    194:        fistpl  t                               // 1/z | t/z | s/z
                    195: 
                    196:        fildl   spancountminus1
                    197: 
                    198:        flds    C(d_tdivzstepu) // C(d_tdivzstepu) | spancountminus1
                    199:        flds    C(d_zistepu)            // C(d_zistepu) | C(d_tdivzstepu) | spancountminus1
                    200:        fmul    %st(2),%st(0)   // C(d_zistepu)*scm1 | C(d_tdivzstepu) | scm1
                    201:        fxch    %st(1)                  // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1
                    202:        fmul    %st(2),%st(0)   // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1
                    203:        fxch    %st(2)                  // scm1 | C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1
                    204:        fmuls   C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_zistepu)*scm1 |
                    205:                                                        //  C(d_tdivzstepu)*scm1
                    206:        fxch    %st(1)                  // C(d_zistepu)*scm1 | C(d_sdivzstepu)*scm1 |
                    207:                                                        //  C(d_tdivzstepu)*scm1
                    208:        faddp   %st(0),%st(3)   // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1
                    209:        fxch    %st(1)                  // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1
                    210:        faddp   %st(0),%st(3)   // C(d_sdivzstepu)*scm1
                    211:        faddp   %st(0),%st(3)
                    212: 
                    213:        flds    fp_64k
                    214:        fdiv    %st(1),%st(0)   // this is what we've gone to all this trouble to
                    215:                                                        //  overlap
                    216:        jmp             LFDIVInFlight1
                    217: 
                    218: LCleanup1:
                    219: // finish up the s and t calcs
                    220:        fxch    %st(1)                  // z*64k | 1/z | t/z | s/z
                    221: 
                    222:        fld             %st(0)                  // z*64k | z*64k | 1/z | t/z | s/z
                    223:        fmul    %st(4),%st(0)   // s | z*64k | 1/z | t/z | s/z
                    224:        fxch    %st(1)                  // z*64k | s | 1/z | t/z | s/z
                    225:        fmul    %st(3),%st(0)   // t | s | 1/z | t/z | s/z
                    226:        fxch    %st(1)                  // s | t | 1/z | t/z | s/z
                    227:        fistpl  s                               // 1/z | t | t/z | s/z
                    228:        fistpl  t                               // 1/z | t/z | s/z
                    229:        jmp             LFDIVInFlight1
                    230: 
                    231:        .align  4
                    232: LSetupNotLast1:
                    233: // finish up the s and t calcs
                    234:        fxch    %st(1)                  // z*64k | 1/z | t/z | s/z
                    235: 
                    236:        fld             %st(0)                  // z*64k | z*64k | 1/z | t/z | s/z
                    237:        fmul    %st(4),%st(0)   // s | z*64k | 1/z | t/z | s/z
                    238:        fxch    %st(1)                  // z*64k | s | 1/z | t/z | s/z
                    239:        fmul    %st(3),%st(0)   // t | s | 1/z | t/z | s/z
                    240:        fxch    %st(1)                  // s | t | 1/z | t/z | s/z
                    241:        fistpl  s                               // 1/z | t | t/z | s/z
                    242:        fistpl  t                               // 1/z | t/z | s/z
                    243: 
                    244:        fadds   zi16stepu
                    245:        fxch    %st(2)
                    246:        fadds   sdivz16stepu
                    247:        fxch    %st(2)
                    248:        flds    tdivz16stepu
                    249:        faddp   %st(0),%st(2)
                    250:        flds    fp_64k
                    251:        fdiv    %st(1),%st(0)   // z = 1/1/z
                    252:                                                        // this is what we've gone to all this trouble to
                    253:                                                        //  overlap
                    254: LFDIVInFlight1:
                    255: 
                    256:        addl    s,%esi
                    257:        addl    t,%edx
                    258:        movl    C(bbextents),%ebx
                    259:        movl    C(bbextentt),%ebp
                    260:        cmpl    %ebx,%esi
                    261:        ja              LClampHighOrLow0
                    262: LClampReentry0:
                    263:        movl    %esi,s
                    264:        movl    pbase,%ebx
                    265:        shll    $16,%esi
                    266:        cmpl    %ebp,%edx
                    267:        movl    %esi,sfracf
                    268:        ja              LClampHighOrLow1
                    269: LClampReentry1:
                    270:        movl    %edx,t
                    271:        movl    s,%esi                                  // sfrac = scans->sfrac;
                    272:        shll    $16,%edx
                    273:        movl    t,%eax                                  // tfrac = scans->tfrac;
                    274:        sarl    $16,%esi
                    275:        movl    %edx,tfracf
                    276: 
                    277: //
                    278: // calculate the texture starting address
                    279: //
                    280:        sarl    $16,%eax
                    281:        movl    C(cachewidth),%edx
                    282:        imull   %edx,%eax                               // (tfrac >> 16) * cachewidth
                    283:        addl    %ebx,%esi
                    284:        addl    %eax,%esi                               // psource = pbase + (sfrac >> 16) +
                    285:                                                                        //           ((tfrac >> 16) * cachewidth);
                    286: //
                    287: // determine whether last span or not
                    288: //
                    289:        cmpl    $16,%ecx
                    290:        jna             LLastSegment
                    291: 
                    292: //
                    293: // not the last segment; do full 16-wide segment
                    294: //
                    295: LNotLastSegment:
                    296: 
                    297: //
                    298: // advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
                    299: // get there
                    300: //
                    301: 
                    302: // pick up after the FDIV that was left in flight previously
                    303: 
                    304:        fld             %st(0)                  // duplicate it
                    305:        fmul    %st(4),%st(0)   // s = s/z * z
                    306:        fxch    %st(1)
                    307:        fmul    %st(3),%st(0)   // t = t/z * z
                    308:        fxch    %st(1)
                    309:        fistpl  snext
                    310:        fistpl  tnext
                    311:        movl    snext,%eax
                    312:        movl    tnext,%edx
                    313: 
                    314:        movb    (%esi),%bl      // get first source texel
                    315:        subl    $16,%ecx                // count off this segments' pixels
                    316:        movl    C(sadjust),%ebp
                    317:        movl    %ecx,counttemp  // remember count of remaining pixels
                    318: 
                    319:        movl    C(tadjust),%ecx
                    320:        movb    %bl,(%edi)      // store first dest pixel
                    321: 
                    322:        addl    %eax,%ebp
                    323:        addl    %edx,%ecx
                    324: 
                    325:        movl    C(bbextents),%eax
                    326:        movl    C(bbextentt),%edx
                    327: 
                    328:        cmpl    $4096,%ebp
                    329:        jl              LClampLow2
                    330:        cmpl    %eax,%ebp
                    331:        ja              LClampHigh2
                    332: LClampReentry2:
                    333: 
                    334:        cmpl    $4096,%ecx
                    335:        jl              LClampLow3
                    336:        cmpl    %edx,%ecx
                    337:        ja              LClampHigh3
                    338: LClampReentry3:
                    339: 
                    340:        movl    %ebp,snext
                    341:        movl    %ecx,tnext
                    342: 
                    343:        subl    s,%ebp
                    344:        subl    t,%ecx
                    345:        
                    346: //
                    347: // set up advancetable
                    348: //
                    349:        movl    %ecx,%eax
                    350:        movl    %ebp,%edx
                    351:        sarl    $20,%eax                        // tstep >>= 16;
                    352:        jz              LZero
                    353:        sarl    $20,%edx                        // sstep >>= 16;
                    354:        movl    C(cachewidth),%ebx
                    355:        imull   %ebx,%eax
                    356:        jmp             LSetUp1
                    357: 
                    358: LZero:
                    359:        sarl    $20,%edx                        // sstep >>= 16;
                    360:        movl    C(cachewidth),%ebx
                    361: 
                    362: LSetUp1:
                    363: 
                    364:        addl    %edx,%eax                       // add in sstep
                    365:                                                                // (tstep >> 16) * cachewidth + (sstep >> 16);
                    366:        movl    tfracf,%edx
                    367:        movl    %eax,advancetable+4     // advance base in t
                    368:        addl    %ebx,%eax                       // ((tstep >> 16) + 1) * cachewidth +
                    369:                                                                //  (sstep >> 16);
                    370:        shll    $12,%ebp                        // left-justify sstep fractional part
                    371:        movl    sfracf,%ebx
                    372:        shll    $12,%ecx                        // left-justify tstep fractional part
                    373:        movl    %eax,advancetable       // advance extra in t
                    374: 
                    375:        movl    %ecx,tstep
                    376:        addl    %ecx,%edx                       // advance tfrac fractional part by tstep frac
                    377: 
                    378:        sbbl    %ecx,%ecx                       // turn tstep carry into -1 (0 if none)
                    379:        addl    %ebp,%ebx                       // advance sfrac fractional part by sstep frac
                    380:        adcl    advancetable+4(,%ecx,4),%esi    // point to next source texel
                    381: 
                    382:        addl    tstep,%edx
                    383:        sbbl    %ecx,%ecx
                    384:        movb    (%esi),%al
                    385:        addl    %ebp,%ebx
                    386:        movb    %al,1(%edi)
                    387:        adcl    advancetable+4(,%ecx,4),%esi
                    388: 
                    389:        addl    tstep,%edx
                    390:        sbbl    %ecx,%ecx
                    391:        addl    %ebp,%ebx
                    392:        movb    (%esi),%al
                    393:        adcl    advancetable+4(,%ecx,4),%esi
                    394: 
                    395:        addl    tstep,%edx
                    396:        sbbl    %ecx,%ecx
                    397:        movb    %al,2(%edi)
                    398:        addl    %ebp,%ebx
                    399:        movb    (%esi),%al
                    400:        adcl    advancetable+4(,%ecx,4),%esi
                    401: 
                    402:        addl    tstep,%edx
                    403:        sbbl    %ecx,%ecx
                    404:        movb    %al,3(%edi)
                    405:        addl    %ebp,%ebx
                    406:        movb    (%esi),%al
                    407:        adcl    advancetable+4(,%ecx,4),%esi
                    408: 
                    409:        addl    tstep,%edx
                    410:        sbbl    %ecx,%ecx
                    411:        movb    %al,4(%edi)
                    412:        addl    %ebp,%ebx
                    413:        movb    (%esi),%al
                    414:        adcl    advancetable+4(,%ecx,4),%esi
                    415: 
                    416:        addl    tstep,%edx
                    417:        sbbl    %ecx,%ecx
                    418:        movb    %al,5(%edi)
                    419:        addl    %ebp,%ebx
                    420:        movb    (%esi),%al
                    421:        adcl    advancetable+4(,%ecx,4),%esi
                    422: 
                    423:        addl    tstep,%edx
                    424:        sbbl    %ecx,%ecx
                    425:        movb    %al,6(%edi)
                    426:        addl    %ebp,%ebx
                    427:        movb    (%esi),%al
                    428:        adcl    advancetable+4(,%ecx,4),%esi
                    429: 
                    430:        addl    tstep,%edx
                    431:        sbbl    %ecx,%ecx
                    432:        movb    %al,7(%edi)
                    433:        addl    %ebp,%ebx
                    434:        movb    (%esi),%al
                    435:        adcl    advancetable+4(,%ecx,4),%esi
                    436: 
                    437: 
                    438: //
                    439: // start FDIV for end of next segment in flight, so it can overlap
                    440: //
                    441:        movl    counttemp,%ecx
                    442:        cmpl    $16,%ecx                        // more than one segment after this?
                    443:        ja              LSetupNotLast2  // yes
                    444: 
                    445:        decl    %ecx
                    446:        jz              LFDIVInFlight2  // if only one pixel, no need to start an FDIV
                    447:        movl    %ecx,spancountminus1
                    448:        fildl   spancountminus1
                    449: 
                    450:        flds    C(d_zistepu)            // C(d_zistepu) | spancountminus1
                    451:        fmul    %st(1),%st(0)   // C(d_zistepu)*scm1 | scm1
                    452:        flds    C(d_tdivzstepu) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1
                    453:        fmul    %st(2),%st(0)   // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1
                    454:        fxch    %st(1)                  // C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1 | scm1
                    455:        faddp   %st(0),%st(3)   // C(d_tdivzstepu)*scm1 | scm1
                    456:        fxch    %st(1)                  // scm1 | C(d_tdivzstepu)*scm1
                    457:        fmuls   C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1
                    458:        fxch    %st(1)                  // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1
                    459:        faddp   %st(0),%st(3)   // C(d_sdivzstepu)*scm1
                    460:        flds    fp_64k                  // 64k | C(d_sdivzstepu)*scm1
                    461:        fxch    %st(1)                  // C(d_sdivzstepu)*scm1 | 64k
                    462:        faddp   %st(0),%st(4)   // 64k
                    463: 
                    464:        fdiv    %st(1),%st(0)   // this is what we've gone to all this trouble to
                    465:                                                        //  overlap
                    466:        jmp             LFDIVInFlight2
                    467: 
                    468:        .align  4
                    469: LSetupNotLast2:
                    470:        fadds   zi16stepu
                    471:        fxch    %st(2)
                    472:        fadds   sdivz16stepu
                    473:        fxch    %st(2)
                    474:        flds    tdivz16stepu
                    475:        faddp   %st(0),%st(2)
                    476:        flds    fp_64k
                    477:        fdiv    %st(1),%st(0)   // z = 1/1/z
                    478:                                                        // this is what we've gone to all this trouble to
                    479:                                                        //  overlap
                    480: LFDIVInFlight2:
                    481:        movl    %ecx,counttemp
                    482: 
                    483:        addl    tstep,%edx
                    484:        sbbl    %ecx,%ecx
                    485:        movb    %al,8(%edi)
                    486:        addl    %ebp,%ebx
                    487:        movb    (%esi),%al
                    488:        adcl    advancetable+4(,%ecx,4),%esi
                    489: 
                    490:        addl    tstep,%edx
                    491:        sbbl    %ecx,%ecx
                    492:        movb    %al,9(%edi)
                    493:        addl    %ebp,%ebx
                    494:        movb    (%esi),%al
                    495:        adcl    advancetable+4(,%ecx,4),%esi
                    496: 
                    497:        addl    tstep,%edx
                    498:        sbbl    %ecx,%ecx
                    499:        movb    %al,10(%edi)
                    500:        addl    %ebp,%ebx
                    501:        movb    (%esi),%al
                    502:        adcl    advancetable+4(,%ecx,4),%esi
                    503: 
                    504:        addl    tstep,%edx
                    505:        sbbl    %ecx,%ecx
                    506:        movb    %al,11(%edi)
                    507:        addl    %ebp,%ebx
                    508:        movb    (%esi),%al
                    509:        adcl    advancetable+4(,%ecx,4),%esi
                    510: 
                    511:        addl    tstep,%edx
                    512:        sbbl    %ecx,%ecx
                    513:        movb    %al,12(%edi)
                    514:        addl    %ebp,%ebx
                    515:        movb    (%esi),%al
                    516:        adcl    advancetable+4(,%ecx,4),%esi
                    517: 
                    518:        addl    tstep,%edx
                    519:        sbbl    %ecx,%ecx
                    520:        movb    %al,13(%edi)
                    521:        addl    %ebp,%ebx
                    522:        movb    (%esi),%al
                    523:        adcl    advancetable+4(,%ecx,4),%esi
                    524: 
                    525:        addl    tstep,%edx
                    526:        sbbl    %ecx,%ecx
                    527:        movb    %al,14(%edi)
                    528:        addl    %ebp,%ebx
                    529:        movb    (%esi),%al
                    530:        adcl    advancetable+4(,%ecx,4),%esi
                    531: 
                    532:        addl    $16,%edi
                    533:        movl    %edx,tfracf
                    534:        movl    snext,%edx
                    535:        movl    %ebx,sfracf
                    536:        movl    tnext,%ebx
                    537:        movl    %edx,s
                    538:        movl    %ebx,t
                    539: 
                    540:        movl    counttemp,%ecx          // retrieve count
                    541: 
                    542: //
                    543: // determine whether last span or not
                    544: //
                    545:        cmpl    $16,%ecx                                // are there multiple segments remaining?
                    546:        movb    %al,-1(%edi)
                    547:        ja              LNotLastSegment         // yes
                    548: 
                    549: //
                    550: // last segment of scan
                    551: //
                    552: LLastSegment:
                    553: 
                    554: //
                    555: // advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
                    556: // get there. The number of pixels left is variable, and we want to land on the
                    557: // last pixel, not step one past it, so we can't run into arithmetic problems
                    558: //
                    559:        testl   %ecx,%ecx
                    560:        jz              LNoSteps                // just draw the last pixel and we're done
                    561: 
                    562: // pick up after the FDIV that was left in flight previously
                    563: 
                    564: 
                    565:        fld             %st(0)                  // duplicate it
                    566:        fmul    %st(4),%st(0)   // s = s/z * z
                    567:        fxch    %st(1)
                    568:        fmul    %st(3),%st(0)   // t = t/z * z
                    569:        fxch    %st(1)
                    570:        fistpl  snext
                    571:        fistpl  tnext
                    572: 
                    573:        movb    (%esi),%al              // load first texel in segment
                    574:        movl    C(tadjust),%ebx
                    575:        movb    %al,(%edi)              // store first pixel in segment
                    576:        movl    C(sadjust),%eax
                    577: 
                    578:        addl    snext,%eax
                    579:        addl    tnext,%ebx
                    580: 
                    581:        movl    C(bbextents),%ebp
                    582:        movl    C(bbextentt),%edx
                    583: 
                    584:        cmpl    $4096,%eax
                    585:        jl              LClampLow4
                    586:        cmpl    %ebp,%eax
                    587:        ja              LClampHigh4
                    588: LClampReentry4:
                    589:        movl    %eax,snext
                    590: 
                    591:        cmpl    $4096,%ebx
                    592:        jl              LClampLow5
                    593:        cmpl    %edx,%ebx
                    594:        ja              LClampHigh5
                    595: LClampReentry5:
                    596: 
                    597:        cmpl    $1,%ecx                 // don't bother 
                    598:        je              LOnlyOneStep    // if two pixels in segment, there's only one step,
                    599:                                                        //  of the segment length
                    600:        subl    s,%eax
                    601:        subl    t,%ebx
                    602: 
                    603:        addl    %eax,%eax               // convert to 15.17 format so multiply by 1.31
                    604:        addl    %ebx,%ebx               //  reciprocal yields 16.48
                    605: 
                    606:        imull   reciprocal_table_16-8(,%ecx,4)  // sstep = (snext - s) /
                    607:                                                                                        //  (spancount-1)
                    608:        movl    %edx,%ebp
                    609: 
                    610:        movl    %ebx,%eax
                    611:        imull   reciprocal_table_16-8(,%ecx,4)  // tstep = (tnext - t) /
                    612:                                                                                        //  (spancount-1)
                    613: LSetEntryvec:
                    614: //
                    615: // set up advancetable
                    616: //
                    617:        movl    entryvec_table_16(,%ecx,4),%ebx
                    618:        movl    %edx,%eax
                    619:        movl    %ebx,jumptemp           // entry point into code for RET later
                    620:        movl    %ebp,%ecx
                    621:        sarl    $16,%edx                        // tstep >>= 16;
                    622:        movl    C(cachewidth),%ebx
                    623:        sarl    $16,%ecx                        // sstep >>= 16;
                    624:        imull   %ebx,%edx
                    625: 
                    626:        addl    %ecx,%edx                       // add in sstep
                    627:                                                                // (tstep >> 16) * cachewidth + (sstep >> 16);
                    628:        movl    tfracf,%ecx
                    629:        movl    %edx,advancetable+4     // advance base in t
                    630:        addl    %ebx,%edx                       // ((tstep >> 16) + 1) * cachewidth +
                    631:                                                                //  (sstep >> 16);
                    632:        shll    $16,%ebp                        // left-justify sstep fractional part
                    633:        movl    sfracf,%ebx
                    634:        shll    $16,%eax                        // left-justify tstep fractional part
                    635:        movl    %edx,advancetable       // advance extra in t
                    636: 
                    637:        movl    %eax,tstep
                    638:        movl    %ecx,%edx
                    639:        addl    %eax,%edx
                    640:        sbbl    %ecx,%ecx
                    641:        addl    %ebp,%ebx
                    642:        adcl    advancetable+4(,%ecx,4),%esi
                    643: 
                    644:        jmp             *jumptemp                       // jump to the number-of-pixels handler
                    645: 
                    646: //----------------------------------------
                    647: 
                    648: LNoSteps:
                    649:        movb    (%esi),%al              // load first texel in segment
                    650:        subl    $15,%edi                        // adjust for hardwired offset
                    651:        jmp             LEndSpan
                    652: 
                    653: 
                    654: LOnlyOneStep:
                    655:        subl    s,%eax
                    656:        subl    t,%ebx
                    657:        movl    %eax,%ebp
                    658:        movl    %ebx,%edx
                    659:        jmp             LSetEntryvec
                    660: 
                    661: //----------------------------------------
                    662: 
                    663: .globl Entry2_16, Entry3_16, Entry4_16, Entry5_16
                    664: .globl Entry6_16, Entry7_16, Entry8_16, Entry9_16
                    665: .globl Entry10_16, Entry11_16, Entry12_16, Entry13_16
                    666: .globl Entry14_16, Entry15_16, Entry16_16
                    667: 
                    668: Entry2_16:
                    669:        subl    $14,%edi                // adjust for hardwired offsets
                    670:        movb    (%esi),%al
                    671:        jmp             LEntry2_16
                    672: 
                    673: //----------------------------------------
                    674: 
                    675: Entry3_16:
                    676:        subl    $13,%edi                // adjust for hardwired offsets
                    677:        addl    %eax,%edx
                    678:        movb    (%esi),%al
                    679:        sbbl    %ecx,%ecx
                    680:        addl    %ebp,%ebx
                    681:        adcl    advancetable+4(,%ecx,4),%esi
                    682:        jmp             LEntry3_16
                    683: 
                    684: //----------------------------------------
                    685: 
                    686: Entry4_16:
                    687:        subl    $12,%edi                // adjust for hardwired offsets
                    688:        addl    %eax,%edx
                    689:        movb    (%esi),%al
                    690:        sbbl    %ecx,%ecx
                    691:        addl    %ebp,%ebx
                    692:        adcl    advancetable+4(,%ecx,4),%esi
                    693:        addl    tstep,%edx
                    694:        jmp             LEntry4_16
                    695: 
                    696: //----------------------------------------
                    697: 
                    698: Entry5_16:
                    699:        subl    $11,%edi                // adjust for hardwired offsets
                    700:        addl    %eax,%edx
                    701:        movb    (%esi),%al
                    702:        sbbl    %ecx,%ecx
                    703:        addl    %ebp,%ebx
                    704:        adcl    advancetable+4(,%ecx,4),%esi
                    705:        addl    tstep,%edx
                    706:        jmp             LEntry5_16
                    707: 
                    708: //----------------------------------------
                    709: 
                    710: Entry6_16:
                    711:        subl    $10,%edi                // adjust for hardwired offsets
                    712:        addl    %eax,%edx
                    713:        movb    (%esi),%al
                    714:        sbbl    %ecx,%ecx
                    715:        addl    %ebp,%ebx
                    716:        adcl    advancetable+4(,%ecx,4),%esi
                    717:        addl    tstep,%edx
                    718:        jmp             LEntry6_16
                    719: 
                    720: //----------------------------------------
                    721: 
                    722: Entry7_16:
                    723:        subl    $9,%edi         // adjust for hardwired offsets
                    724:        addl    %eax,%edx
                    725:        movb    (%esi),%al
                    726:        sbbl    %ecx,%ecx
                    727:        addl    %ebp,%ebx
                    728:        adcl    advancetable+4(,%ecx,4),%esi
                    729:        addl    tstep,%edx
                    730:        jmp             LEntry7_16
                    731: 
                    732: //----------------------------------------
                    733: 
                    734: Entry8_16:
                    735:        subl    $8,%edi         // adjust for hardwired offsets
                    736:        addl    %eax,%edx
                    737:        movb    (%esi),%al
                    738:        sbbl    %ecx,%ecx
                    739:        addl    %ebp,%ebx
                    740:        adcl    advancetable+4(,%ecx,4),%esi
                    741:        addl    tstep,%edx
                    742:        jmp             LEntry8_16
                    743: 
                    744: //----------------------------------------
                    745: 
                    746: Entry9_16:
                    747:        subl    $7,%edi         // adjust for hardwired offsets
                    748:        addl    %eax,%edx
                    749:        movb    (%esi),%al
                    750:        sbbl    %ecx,%ecx
                    751:        addl    %ebp,%ebx
                    752:        adcl    advancetable+4(,%ecx,4),%esi
                    753:        addl    tstep,%edx
                    754:        jmp             LEntry9_16
                    755: 
                    756: //----------------------------------------
                    757: 
                    758: Entry10_16:
                    759:        subl    $6,%edi         // adjust for hardwired offsets
                    760:        addl    %eax,%edx
                    761:        movb    (%esi),%al
                    762:        sbbl    %ecx,%ecx
                    763:        addl    %ebp,%ebx
                    764:        adcl    advancetable+4(,%ecx,4),%esi
                    765:        addl    tstep,%edx
                    766:        jmp             LEntry10_16
                    767: 
                    768: //----------------------------------------
                    769: 
                    770: Entry11_16:
                    771:        subl    $5,%edi         // adjust for hardwired offsets
                    772:        addl    %eax,%edx
                    773:        movb    (%esi),%al
                    774:        sbbl    %ecx,%ecx
                    775:        addl    %ebp,%ebx
                    776:        adcl    advancetable+4(,%ecx,4),%esi
                    777:        addl    tstep,%edx
                    778:        jmp             LEntry11_16
                    779: 
                    780: //----------------------------------------
                    781: 
                    782: Entry12_16:
                    783:        subl    $4,%edi         // adjust for hardwired offsets
                    784:        addl    %eax,%edx
                    785:        movb    (%esi),%al
                    786:        sbbl    %ecx,%ecx
                    787:        addl    %ebp,%ebx
                    788:        adcl    advancetable+4(,%ecx,4),%esi
                    789:        addl    tstep,%edx
                    790:        jmp             LEntry12_16
                    791: 
                    792: //----------------------------------------
                    793: 
                    794: Entry13_16:
                    795:        subl    $3,%edi         // adjust for hardwired offsets
                    796:        addl    %eax,%edx
                    797:        movb    (%esi),%al
                    798:        sbbl    %ecx,%ecx
                    799:        addl    %ebp,%ebx
                    800:        adcl    advancetable+4(,%ecx,4),%esi
                    801:        addl    tstep,%edx
                    802:        jmp             LEntry13_16
                    803: 
                    804: //----------------------------------------
                    805: 
                    806: Entry14_16:
                    807:        subl    $2,%edi         // adjust for hardwired offsets
                    808:        addl    %eax,%edx
                    809:        movb    (%esi),%al
                    810:        sbbl    %ecx,%ecx
                    811:        addl    %ebp,%ebx
                    812:        adcl    advancetable+4(,%ecx,4),%esi
                    813:        addl    tstep,%edx
                    814:        jmp             LEntry14_16
                    815: 
                    816: //----------------------------------------
                    817: 
                    818: Entry15_16:
                    819:        decl    %edi            // adjust for hardwired offsets
                    820:        addl    %eax,%edx
                    821:        movb    (%esi),%al
                    822:        sbbl    %ecx,%ecx
                    823:        addl    %ebp,%ebx
                    824:        adcl    advancetable+4(,%ecx,4),%esi
                    825:        addl    tstep,%edx
                    826:        jmp             LEntry15_16
                    827: 
                    828: //----------------------------------------
                    829: 
                    830: Entry16_16:
                    831:        addl    %eax,%edx
                    832:        movb    (%esi),%al
                    833:        sbbl    %ecx,%ecx
                    834:        addl    %ebp,%ebx
                    835:        adcl    advancetable+4(,%ecx,4),%esi
                    836: 
                    837:        addl    tstep,%edx
                    838:        sbbl    %ecx,%ecx
                    839:        movb    %al,1(%edi)
                    840:        addl    %ebp,%ebx
                    841:        movb    (%esi),%al
                    842:        adcl    advancetable+4(,%ecx,4),%esi
                    843:        addl    tstep,%edx
                    844: LEntry15_16:
                    845:        sbbl    %ecx,%ecx
                    846:        movb    %al,2(%edi)
                    847:        addl    %ebp,%ebx
                    848:        movb    (%esi),%al
                    849:        adcl    advancetable+4(,%ecx,4),%esi
                    850:        addl    tstep,%edx
                    851: LEntry14_16:
                    852:        sbbl    %ecx,%ecx
                    853:        movb    %al,3(%edi)
                    854:        addl    %ebp,%ebx
                    855:        movb    (%esi),%al
                    856:        adcl    advancetable+4(,%ecx,4),%esi
                    857:        addl    tstep,%edx
                    858: LEntry13_16:
                    859:        sbbl    %ecx,%ecx
                    860:        movb    %al,4(%edi)
                    861:        addl    %ebp,%ebx
                    862:        movb    (%esi),%al
                    863:        adcl    advancetable+4(,%ecx,4),%esi
                    864:        addl    tstep,%edx
                    865: LEntry12_16:
                    866:        sbbl    %ecx,%ecx
                    867:        movb    %al,5(%edi)
                    868:        addl    %ebp,%ebx
                    869:        movb    (%esi),%al
                    870:        adcl    advancetable+4(,%ecx,4),%esi
                    871:        addl    tstep,%edx
                    872: LEntry11_16:
                    873:        sbbl    %ecx,%ecx
                    874:        movb    %al,6(%edi)
                    875:        addl    %ebp,%ebx
                    876:        movb    (%esi),%al
                    877:        adcl    advancetable+4(,%ecx,4),%esi
                    878:        addl    tstep,%edx
                    879: LEntry10_16:
                    880:        sbbl    %ecx,%ecx
                    881:        movb    %al,7(%edi)
                    882:        addl    %ebp,%ebx
                    883:        movb    (%esi),%al
                    884:        adcl    advancetable+4(,%ecx,4),%esi
                    885:        addl    tstep,%edx
                    886: LEntry9_16:
                    887:        sbbl    %ecx,%ecx
                    888:        movb    %al,8(%edi)
                    889:        addl    %ebp,%ebx
                    890:        movb    (%esi),%al
                    891:        adcl    advancetable+4(,%ecx,4),%esi
                    892:        addl    tstep,%edx
                    893: LEntry8_16:
                    894:        sbbl    %ecx,%ecx
                    895:        movb    %al,9(%edi)
                    896:        addl    %ebp,%ebx
                    897:        movb    (%esi),%al
                    898:        adcl    advancetable+4(,%ecx,4),%esi
                    899:        addl    tstep,%edx
                    900: LEntry7_16:
                    901:        sbbl    %ecx,%ecx
                    902:        movb    %al,10(%edi)
                    903:        addl    %ebp,%ebx
                    904:        movb    (%esi),%al
                    905:        adcl    advancetable+4(,%ecx,4),%esi
                    906:        addl    tstep,%edx
                    907: LEntry6_16:
                    908:        sbbl    %ecx,%ecx
                    909:        movb    %al,11(%edi)
                    910:        addl    %ebp,%ebx
                    911:        movb    (%esi),%al
                    912:        adcl    advancetable+4(,%ecx,4),%esi
                    913:        addl    tstep,%edx
                    914: LEntry5_16:
                    915:        sbbl    %ecx,%ecx
                    916:        movb    %al,12(%edi)
                    917:        addl    %ebp,%ebx
                    918:        movb    (%esi),%al
                    919:        adcl    advancetable+4(,%ecx,4),%esi
                    920:        addl    tstep,%edx
                    921: LEntry4_16:
                    922:        sbbl    %ecx,%ecx
                    923:        movb    %al,13(%edi)
                    924:        addl    %ebp,%ebx
                    925:        movb    (%esi),%al
                    926:        adcl    advancetable+4(,%ecx,4),%esi
                    927: LEntry3_16:
                    928:        movb    %al,14(%edi)
                    929:        movb    (%esi),%al
                    930: LEntry2_16:
                    931: 
                    932: LEndSpan:
                    933: 
                    934: //
                    935: // clear s/z, t/z, 1/z from FP stack
                    936: //
                    937:        fstp %st(0)
                    938:        fstp %st(0)
                    939:        fstp %st(0)
                    940: 
                    941:        movl    pspantemp,%ebx                          // restore spans pointer
                    942:        movl    espan_t_pnext(%ebx),%ebx        // point to next span
                    943:        testl   %ebx,%ebx                       // any more spans?
                    944:        movb    %al,15(%edi)
                    945:        jnz             LSpanLoop                       // more spans
                    946: 
                    947:        popl    %ebx                            // restore register variables
                    948:        popl    %esi
                    949:        popl    %edi
                    950:        popl    %ebp                            // restore the caller's stack frame
                    951:        ret
                    952: 
                    953: //----------------------------------------------------------------------
                    954: // 8-bpp horizontal span z drawing codefor polygons, with no transparency.
                    955: //
                    956: // Assumes there is at least one span in pzspans, and that every span
                    957: // contains at least one pixel
                    958: //----------------------------------------------------------------------
                    959: 
                    960:        .text
                    961: 
                    962: // z-clamp on a non-negative gradient span
                    963: LClamp:
                    964:        movl    $0x40000000,%edx
                    965:        xorl    %ebx,%ebx
                    966:        fstp    %st(0)
                    967:        jmp             LZDraw
                    968: 
                    969: // z-clamp on a negative gradient span
                    970: LClampNeg:
                    971:        movl    $0x40000000,%edx
                    972:        xorl    %ebx,%ebx
                    973:        fstp    %st(0)
                    974:        jmp             LZDrawNeg
                    975: 
                    976: 
                    977: #define pzspans        4+16
                    978: 
                    979: .globl C(D_DrawZSpans)
                    980: C(D_DrawZSpans):
                    981:        pushl   %ebp                            // preserve caller's stack frame
                    982:        pushl   %edi
                    983:        pushl   %esi                            // preserve register variables
                    984:        pushl   %ebx
                    985: 
                    986:        flds    C(d_zistepu)
                    987:        movl    C(d_zistepu),%eax
                    988:        movl    pzspans(%esp),%esi
                    989:        testl   %eax,%eax
                    990:        jz              LFNegSpan
                    991: 
                    992:        fmuls   Float2ToThe31nd
                    993:        fistpl  izistep         // note: we are relying on FP exceptions being turned
                    994:                                                // off here to avoid range problems
                    995:        movl    izistep,%ebx    // remains loaded for all spans
                    996: 
                    997: LFSpanLoop:
                    998: // set up the initial 1/z value
                    999:        fildl   espan_t_v(%esi)
                   1000:        fildl   espan_t_u(%esi)
                   1001:        movl    espan_t_v(%esi),%ecx
                   1002:        movl    C(d_pzbuffer),%edi
                   1003:        fmuls   C(d_zistepu)
                   1004:        fxch    %st(1)
                   1005:        fmuls   C(d_zistepv)
                   1006:        fxch    %st(1)
                   1007:        fadds   C(d_ziorigin)
                   1008:        imull   C(d_zrowbytes),%ecx
                   1009:        faddp   %st(0),%st(1)
                   1010: 
                   1011: // clamp if z is nearer than 2 (1/z > 0.5)
                   1012:        fcoms   float_point5
                   1013:        addl    %ecx,%edi
                   1014:        movl    espan_t_u(%esi),%edx
                   1015:        addl    %edx,%edx                               // word count
                   1016:        movl    espan_t_count(%esi),%ecx
                   1017:        addl    %edx,%edi                               // pdest = &pdestspan[scans->u];
                   1018:        pushl   %esi            // preserve spans pointer
                   1019:        fnstsw  %ax
                   1020:        testb   $0x45,%ah
                   1021:        jz              LClamp
                   1022: 
                   1023:        fmuls   Float2ToThe31nd
                   1024:        fistpl  izi                     // note: we are relying on FP exceptions being turned
                   1025:                                                // off here to avoid problems when the span is closer
                   1026:                                                // than 1/(2**31)
                   1027:        movl    izi,%edx
                   1028: 
                   1029: // at this point:
                   1030: // %ebx = izistep
                   1031: // %ecx = count
                   1032: // %edx = izi
                   1033: // %edi = pdest
                   1034: 
                   1035: LZDraw:
                   1036: 
                   1037: // do a single pixel up front, if necessary to dword align the destination
                   1038:        testl   $2,%edi
                   1039:        jz              LFMiddle
                   1040:        movl    %edx,%eax
                   1041:        addl    %ebx,%edx
                   1042:        shrl    $16,%eax
                   1043:        decl    %ecx
                   1044:        movw    %ax,(%edi)
                   1045:        addl    $2,%edi
                   1046: 
                   1047: // do middle a pair of aligned dwords at a time
                   1048: LFMiddle:
                   1049:        pushl   %ecx
                   1050:        shrl    $1,%ecx                         // count / 2
                   1051:        jz              LFLast                          // no aligned dwords to do
                   1052:        shrl    $1,%ecx                         // (count / 2) / 2
                   1053:        jnc             LFMiddleLoop            // even number of aligned dwords to do
                   1054: 
                   1055:        movl    %edx,%eax
                   1056:        addl    %ebx,%edx
                   1057:        shrl    $16,%eax
                   1058:        movl    %edx,%esi
                   1059:        addl    %ebx,%edx
                   1060:        andl    $0xFFFF0000,%esi
                   1061:        orl             %esi,%eax
                   1062:        movl    %eax,(%edi)
                   1063:        addl    $4,%edi
                   1064:        andl    %ecx,%ecx
                   1065:        jz              LFLast
                   1066: 
                   1067: LFMiddleLoop:
                   1068:        movl    %edx,%eax
                   1069:        addl    %ebx,%edx
                   1070:        shrl    $16,%eax
                   1071:        movl    %edx,%esi
                   1072:        addl    %ebx,%edx
                   1073:        andl    $0xFFFF0000,%esi
                   1074:        orl             %esi,%eax
                   1075:        movl    %edx,%ebp
                   1076:        movl    %eax,(%edi)
                   1077:        addl    %ebx,%edx
                   1078:        shrl    $16,%ebp
                   1079:        movl    %edx,%esi
                   1080:        addl    %ebx,%edx
                   1081:        andl    $0xFFFF0000,%esi
                   1082:        orl             %esi,%ebp
                   1083:        movl    %ebp,4(%edi)    // FIXME: eliminate register contention
                   1084:        addl    $8,%edi
                   1085: 
                   1086:        decl    %ecx
                   1087:        jnz             LFMiddleLoop
                   1088: 
                   1089: LFLast:
                   1090:        popl    %ecx                    // retrieve count
                   1091:        popl    %esi                    // retrieve span pointer
                   1092: 
                   1093: // do the last, unaligned pixel, if there is one
                   1094:        andl    $1,%ecx                 // is there an odd pixel left to do?
                   1095:        jz              LFSpanDone              // no
                   1096:        shrl    $16,%edx
                   1097:        movw    %dx,(%edi)              // do the final pixel's z
                   1098: 
                   1099: LFSpanDone:
                   1100:        movl    espan_t_pnext(%esi),%esi
                   1101:        testl   %esi,%esi
                   1102:        jnz             LFSpanLoop
                   1103: 
                   1104:        jmp             LFDone
                   1105: 
                   1106: LFNegSpan:
                   1107:        fmuls   FloatMinus2ToThe31nd
                   1108:        fistpl  izistep         // note: we are relying on FP exceptions being turned
                   1109:                                                // off here to avoid range problems
                   1110:        movl    izistep,%ebx    // remains loaded for all spans
                   1111: 
                   1112: LFNegSpanLoop:
                   1113: // set up the initial 1/z value
                   1114:        fildl   espan_t_v(%esi)
                   1115:        fildl   espan_t_u(%esi)
                   1116:        movl    espan_t_v(%esi),%ecx
                   1117:        movl    C(d_pzbuffer),%edi
                   1118:        fmuls   C(d_zistepu)
                   1119:        fxch    %st(1)
                   1120:        fmuls   C(d_zistepv)
                   1121:        fxch    %st(1)
                   1122:        fadds   C(d_ziorigin)
                   1123:        imull   C(d_zrowbytes),%ecx
                   1124:        faddp   %st(0),%st(1)
                   1125: 
                   1126: // clamp if z is nearer than 2 (1/z > 0.5)
                   1127:        fcoms   float_point5
                   1128:        addl    %ecx,%edi
                   1129:        movl    espan_t_u(%esi),%edx
                   1130:        addl    %edx,%edx                               // word count
                   1131:        movl    espan_t_count(%esi),%ecx
                   1132:        addl    %edx,%edi                               // pdest = &pdestspan[scans->u];
                   1133:        pushl   %esi            // preserve spans pointer
                   1134:        fnstsw  %ax
                   1135:        testb   $0x45,%ah
                   1136:        jz              LClampNeg
                   1137: 
                   1138:        fmuls   Float2ToThe31nd
                   1139:        fistpl  izi                     // note: we are relying on FP exceptions being turned
                   1140:                                                // off here to avoid problems when the span is closer
                   1141:                                                // than 1/(2**31)
                   1142:        movl    izi,%edx
                   1143: 
                   1144: // at this point:
                   1145: // %ebx = izistep
                   1146: // %ecx = count
                   1147: // %edx = izi
                   1148: // %edi = pdest
                   1149: 
                   1150: LZDrawNeg:
                   1151: 
                   1152: // do a single pixel up front, if necessary to dword align the destination
                   1153:        testl   $2,%edi
                   1154:        jz              LFNegMiddle
                   1155:        movl    %edx,%eax
                   1156:        subl    %ebx,%edx
                   1157:        shrl    $16,%eax
                   1158:        decl    %ecx
                   1159:        movw    %ax,(%edi)
                   1160:        addl    $2,%edi
                   1161: 
                   1162: // do middle a pair of aligned dwords at a time
                   1163: LFNegMiddle:
                   1164:        pushl   %ecx
                   1165:        shrl    $1,%ecx                         // count / 2
                   1166:        jz              LFNegLast                       // no aligned dwords to do
                   1167:        shrl    $1,%ecx                         // (count / 2) / 2
                   1168:        jnc             LFNegMiddleLoop         // even number of aligned dwords to do
                   1169: 
                   1170:        movl    %edx,%eax
                   1171:        subl    %ebx,%edx
                   1172:        shrl    $16,%eax
                   1173:        movl    %edx,%esi
                   1174:        subl    %ebx,%edx
                   1175:        andl    $0xFFFF0000,%esi
                   1176:        orl             %esi,%eax
                   1177:        movl    %eax,(%edi)
                   1178:        addl    $4,%edi
                   1179:        andl    %ecx,%ecx
                   1180:        jz              LFNegLast
                   1181: 
                   1182: LFNegMiddleLoop:
                   1183:        movl    %edx,%eax
                   1184:        subl    %ebx,%edx
                   1185:        shrl    $16,%eax
                   1186:        movl    %edx,%esi
                   1187:        subl    %ebx,%edx
                   1188:        andl    $0xFFFF0000,%esi
                   1189:        orl             %esi,%eax
                   1190:        movl    %edx,%ebp
                   1191:        movl    %eax,(%edi)
                   1192:        subl    %ebx,%edx
                   1193:        shrl    $16,%ebp
                   1194:        movl    %edx,%esi
                   1195:        subl    %ebx,%edx
                   1196:        andl    $0xFFFF0000,%esi
                   1197:        orl             %esi,%ebp
                   1198:        movl    %ebp,4(%edi)    // FIXME: eliminate register contention
                   1199:        addl    $8,%edi
                   1200: 
                   1201:        decl    %ecx
                   1202:        jnz             LFNegMiddleLoop
                   1203: 
                   1204: LFNegLast:
                   1205:        popl    %ecx                    // retrieve count
                   1206:        popl    %esi                    // retrieve span pointer
                   1207: 
                   1208: // do the last, unaligned pixel, if there is one
                   1209:        andl    $1,%ecx                 // is there an odd pixel left to do?
                   1210:        jz              LFNegSpanDone   // no
                   1211:        shrl    $16,%edx
                   1212:        movw    %dx,(%edi)              // do the final pixel's z
                   1213: 
                   1214: LFNegSpanDone:
                   1215:        movl    espan_t_pnext(%esi),%esi
                   1216:        testl   %esi,%esi
                   1217:        jnz             LFNegSpanLoop
                   1218: 
                   1219: LFDone:
                   1220:        popl    %ebx                            // restore register variables
                   1221:        popl    %esi
                   1222:        popl    %edi
                   1223:        popl    %ebp                            // restore the caller's stack frame
                   1224:        ret
                   1225: 
                   1226: #endif // id386
                   1227: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.