|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.