1/* 2Copyright (C) 1996-1997 Id Software, Inc. 3 4This program is free software; you can redistribute it and/or 5modify it under the terms of the GNU General Public License 6as published by the Free Software Foundation; either version 2 7of the License, or (at your option) any later version. 8 9This program is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13See the GNU General Public License for more details. 14 15You should have received a copy of the GNU General Public License 16along with this program; if not, write to the Free Software 17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19*/ 20// 21// r_edgea.s 22// x86 assembly-language edge-processing code. 23// 24 25#include "asm_i386.h" 26#include "quakeasm.h" 27#include "asm_draw.h" 28 29#if id386 30 31 .data 32Ltemp: .long 0 33float_1_div_0100000h: .long 0x35800000 // 1.0/(float)0x100000 34float_point_999: .single 0.999 35float_1_point_001: .single 1.001 36 37 .text 38 39//-------------------------------------------------------------------- 40 41#define edgestoadd 4+8 // note odd stack offsets because of interleaving 42#define edgelist 8+12 // with pushes 43 44.globl C(R_EdgeCodeStart) 45C(R_EdgeCodeStart): 46 47.globl C(R_InsertNewEdges) 48C(R_InsertNewEdges): 49 pushl %edi 50 pushl %esi // preserve register variables 51 movl edgestoadd(%esp),%edx 52 pushl %ebx 53 movl edgelist(%esp),%ecx 54 55LDoNextEdge: 56 movl et_u(%edx),%eax 57 movl %edx,%edi 58 59LContinueSearch: 60 movl et_u(%ecx),%ebx 61 movl et_next(%ecx),%esi 62 cmpl %ebx,%eax 63 jle LAddedge 64 movl et_u(%esi),%ebx 65 movl et_next(%esi),%ecx 66 cmpl %ebx,%eax 67 jle LAddedge2 68 movl et_u(%ecx),%ebx 69 movl et_next(%ecx),%esi 70 cmpl %ebx,%eax 71 jle LAddedge 72 movl et_u(%esi),%ebx 73 movl et_next(%esi),%ecx 74 cmpl %ebx,%eax 75 jg LContinueSearch 76 77LAddedge2: 78 movl et_next(%edx),%edx 79 movl et_prev(%esi),%ebx 80 movl %esi,et_next(%edi) 81 movl %ebx,et_prev(%edi) 82 movl %edi,et_next(%ebx) 83 movl %edi,et_prev(%esi) 84 movl %esi,%ecx 85 86 cmpl $0,%edx 87 jnz LDoNextEdge 88 jmp LDone 89 90 .align 4 91LAddedge: 92 movl et_next(%edx),%edx 93 movl et_prev(%ecx),%ebx 94 movl %ecx,et_next(%edi) 95 movl %ebx,et_prev(%edi) 96 movl %edi,et_next(%ebx) 97 movl %edi,et_prev(%ecx) 98 99 cmpl $0,%edx 100 jnz LDoNextEdge 101 102LDone: 103 popl %ebx // restore register variables 104 popl %esi 105 popl %edi 106 107 ret 108 109//-------------------------------------------------------------------- 110 111#define predge 4+4 112 113.globl C(R_RemoveEdges) 114C(R_RemoveEdges): 115 pushl %ebx 116 movl predge(%esp),%eax 117 118Lre_loop: 119 movl et_next(%eax),%ecx 120 movl et_nextremove(%eax),%ebx 121 movl et_prev(%eax),%edx 122 testl %ebx,%ebx 123 movl %edx,et_prev(%ecx) 124 jz Lre_done 125 movl %ecx,et_next(%edx) 126 127 movl et_next(%ebx),%ecx 128 movl et_prev(%ebx),%edx 129 movl et_nextremove(%ebx),%eax 130 movl %edx,et_prev(%ecx) 131 testl %eax,%eax 132 movl %ecx,et_next(%edx) 133 jnz Lre_loop 134 135 popl %ebx 136 ret 137 138Lre_done: 139 movl %ecx,et_next(%edx) 140 popl %ebx 141 142 ret 143 144//-------------------------------------------------------------------- 145 146#define pedgelist 4+4 // note odd stack offset because of interleaving 147 // with pushes 148 149.globl C(R_StepActiveU) 150C(R_StepActiveU): 151 pushl %edi 152 movl pedgelist(%esp),%edx 153 pushl %esi // preserve register variables 154 pushl %ebx 155 156 movl et_prev(%edx),%esi 157 158LNewEdge: 159 movl et_u(%esi),%edi 160 161LNextEdge: 162 movl et_u(%edx),%eax 163 movl et_u_step(%edx),%ebx 164 addl %ebx,%eax 165 movl et_next(%edx),%esi 166 movl %eax,et_u(%edx) 167 cmpl %edi,%eax 168 jl LPushBack 169 170 movl et_u(%esi),%edi 171 movl et_u_step(%esi),%ebx 172 addl %ebx,%edi 173 movl et_next(%esi),%edx 174 movl %edi,et_u(%esi) 175 cmpl %eax,%edi 176 jl LPushBack2 177 178 movl et_u(%edx),%eax 179 movl et_u_step(%edx),%ebx 180 addl %ebx,%eax 181 movl et_next(%edx),%esi 182 movl %eax,et_u(%edx) 183 cmpl %edi,%eax 184 jl LPushBack 185 186 movl et_u(%esi),%edi 187 movl et_u_step(%esi),%ebx 188 addl %ebx,%edi 189 movl et_next(%esi),%edx 190 movl %edi,et_u(%esi) 191 cmpl %eax,%edi 192 jnl LNextEdge 193 194LPushBack2: 195 movl %edx,%ebx 196 movl %edi,%eax 197 movl %esi,%edx 198 movl %ebx,%esi 199 200LPushBack: 201// push it back to keep it sorted 202 movl et_prev(%edx),%ecx 203 movl et_next(%edx),%ebx 204 205// done if the -1 in edge_aftertail triggered this 206 cmpl $(C(edge_aftertail)),%edx 207 jz LUDone 208 209// pull the edge out of the edge list 210 movl et_prev(%ecx),%edi 211 movl %ecx,et_prev(%esi) 212 movl %ebx,et_next(%ecx) 213 214// find out where the edge goes in the edge list 215LPushBackLoop: 216 movl et_prev(%edi),%ecx 217 movl et_u(%edi),%ebx 218 cmpl %ebx,%eax 219 jnl LPushBackFound 220 221 movl et_prev(%ecx),%edi 222 movl et_u(%ecx),%ebx 223 cmpl %ebx,%eax 224 jl LPushBackLoop 225 226 movl %ecx,%edi 227 228// put the edge back into the edge list 229LPushBackFound: 230 movl et_next(%edi),%ebx 231 movl %edi,et_prev(%edx) 232 movl %ebx,et_next(%edx) 233 movl %edx,et_next(%edi) 234 movl %edx,et_prev(%ebx) 235 236 movl %esi,%edx 237 movl et_prev(%esi),%esi 238 239 cmpl $(C(edge_tail)),%edx 240 jnz LNewEdge 241 242LUDone: 243 popl %ebx // restore register variables 244 popl %esi 245 popl %edi 246 247 ret 248 249//-------------------------------------------------------------------- 250 251#define surf 4 // note this is loaded before any pushes 252 253 .align 4 254TrailingEdge: 255 movl st_spanstate(%esi),%eax // check for edge inversion 256 decl %eax 257 jnz LInverted 258 259 movl %eax,st_spanstate(%esi) 260 movl st_insubmodel(%esi),%ecx 261 movl 0x12345678,%edx // surfaces[1].st_next 262LPatch0: 263 movl C(r_bmodelactive),%eax 264 subl %ecx,%eax 265 cmpl %esi,%edx 266 movl %eax,C(r_bmodelactive) 267 jnz LNoEmit // surface isn't on top, just remove 268 269// emit a span (current top going away) 270 movl et_u(%ebx),%eax 271 shrl $20,%eax // iu = integral pixel u 272 movl st_last_u(%esi),%edx 273 movl st_next(%esi),%ecx 274 cmpl %edx,%eax 275 jle LNoEmit2 // iu <= surf->last_u, so nothing to emit 276 277 movl %eax,st_last_u(%ecx) // surf->next->last_u = iu; 278 subl %edx,%eax 279 movl %edx,espan_t_u(%ebp) // span->u = surf->last_u; 280 281 movl %eax,espan_t_count(%ebp) // span->count = iu - span->u; 282 movl C(current_iv),%eax 283 movl %eax,espan_t_v(%ebp) // span->v = current_iv; 284 movl st_spans(%esi),%eax 285 movl %eax,espan_t_pnext(%ebp) // span->pnext = surf->spans; 286 movl %ebp,st_spans(%esi) // surf->spans = span; 287 addl $(espan_t_size),%ebp 288 289 movl st_next(%esi),%edx // remove the surface from the surface 290 movl st_prev(%esi),%esi // stack 291 292 movl %edx,st_next(%esi) 293 movl %esi,st_prev(%edx) 294 ret 295 296LNoEmit2: 297 movl %eax,st_last_u(%ecx) // surf->next->last_u = iu; 298 movl st_next(%esi),%edx // remove the surface from the surface 299 movl st_prev(%esi),%esi // stack 300 301 movl %edx,st_next(%esi) 302 movl %esi,st_prev(%edx) 303 ret 304 305LNoEmit: 306 movl st_next(%esi),%edx // remove the surface from the surface 307 movl st_prev(%esi),%esi // stack 308 309 movl %edx,st_next(%esi) 310 movl %esi,st_prev(%edx) 311 ret 312 313LInverted: 314 movl %eax,st_spanstate(%esi) 315 ret 316 317//-------------------------------------------------------------------- 318 319// trailing edge only 320Lgs_trailing: 321 pushl $Lgs_nextedge 322 jmp TrailingEdge 323 324 325.globl C(R_GenerateSpans) 326C(R_GenerateSpans): 327 pushl %ebp // preserve caller's stack frame 328 pushl %edi 329 pushl %esi // preserve register variables 330 pushl %ebx 331 332// clear active surfaces to just the background surface 333 movl C(surfaces),%eax 334 movl C(edge_head_u_shift20),%edx 335 addl $(st_size),%eax 336// %ebp = span_p throughout 337 movl C(span_p),%ebp 338 339 movl $0,C(r_bmodelactive) 340 341 movl %eax,st_next(%eax) 342 movl %eax,st_prev(%eax) 343 movl %edx,st_last_u(%eax) 344 movl C(edge_head)+et_next,%ebx // edge=edge_head.next 345 346// generate spans 347 cmpl $(C(edge_tail)),%ebx // done if empty list 348 jz Lgs_lastspan 349 350Lgs_edgeloop: 351 352 movl et_surfs(%ebx),%edi 353 movl C(surfaces),%eax 354 movl %edi,%esi 355 andl $0xFFFF0000,%edi 356 andl $0xFFFF,%esi 357 jz Lgs_leading // not a trailing edge 358 359// it has a left surface, so a surface is going away for this span 360 shll $(SURF_T_SHIFT),%esi 361 addl %eax,%esi 362 testl %edi,%edi 363 jz Lgs_trailing 364 365// both leading and trailing 366 call TrailingEdge 367 movl C(surfaces),%eax 368 369// --------------------------------------------------------------- 370// handle a leading edge 371// --------------------------------------------------------------- 372 373Lgs_leading: 374 shrl $16-SURF_T_SHIFT,%edi 375 movl C(surfaces),%eax 376 addl %eax,%edi 377 movl 0x12345678,%esi // surf2 = surfaces[1].next; 378LPatch2: 379 movl st_spanstate(%edi),%edx 380 movl st_insubmodel(%edi),%eax 381 testl %eax,%eax 382 jnz Lbmodel_leading 383 384// handle a leading non-bmodel edge 385 386// don't start a span if this is an inverted span, with the end edge preceding 387// the start edge (that is, we've already seen the end edge) 388 testl %edx,%edx 389 jnz Lxl_done 390 391 392// if (surf->key < surf2->key) 393// goto newtop; 394 incl %edx 395 movl st_key(%edi),%eax 396 movl %edx,st_spanstate(%edi) 397 movl st_key(%esi),%ecx 398 cmpl %ecx,%eax 399 jl Lnewtop 400 401// main sorting loop to search through surface stack until insertion point 402// found. Always terminates because background surface is sentinel 403// do 404// { 405// surf2 = surf2->next; 406// } while (surf->key >= surf2->key); 407Lsortloopnb: 408 movl st_next(%esi),%esi 409 movl st_key(%esi),%ecx 410 cmpl %ecx,%eax 411 jge Lsortloopnb 412 413 jmp LInsertAndExit 414 415 416// handle a leading bmodel edge 417 .align 4 418Lbmodel_leading: 419 420// don't start a span if this is an inverted span, with the end edge preceding 421// the start edge (that is, we've already seen the end edge) 422 testl %edx,%edx 423 jnz Lxl_done 424 425 movl C(r_bmodelactive),%ecx 426 incl %edx 427 incl %ecx 428 movl %edx,st_spanstate(%edi) 429 movl %ecx,C(r_bmodelactive) 430 431// if (surf->key < surf2->key) 432// goto newtop; 433 movl st_key(%edi),%eax 434 movl st_key(%esi),%ecx 435 cmpl %ecx,%eax 436 jl Lnewtop 437 438// if ((surf->key == surf2->key) && surf->insubmodel) 439// { 440 jz Lzcheck_for_newtop 441 442// main sorting loop to search through surface stack until insertion point 443// found. Always terminates because background surface is sentinel 444// do 445// { 446// surf2 = surf2->next; 447// } while (surf->key > surf2->key); 448Lsortloop: 449 movl st_next(%esi),%esi 450 movl st_key(%esi),%ecx 451 cmpl %ecx,%eax 452 jg Lsortloop 453 454 jne LInsertAndExit 455 456// Do 1/z sorting to see if we've arrived in the right position 457 movl et_u(%ebx),%eax 458 subl $0xFFFFF,%eax 459 movl %eax,Ltemp 460 fildl Ltemp 461 462 fmuls float_1_div_0100000h // fu = (float)(edge->u - 0xFFFFF) * 463 // (1.0 / 0x100000); 464 465 fld %st(0) // fu | fu 466 fmuls st_d_zistepu(%edi) // fu*surf->d_zistepu | fu 467 flds C(fv) // fv | fu*surf->d_zistepu | fu 468 fmuls st_d_zistepv(%edi) // fv*surf->d_zistepv | fu*surf->d_zistepu | fu 469 fxch %st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu 470 fadds st_d_ziorigin(%edi) // fu*surf->d_zistepu + surf->d_ziorigin | 471 // fv*surf->d_zistepv | fu 472 473 flds st_d_zistepu(%esi) // surf2->d_zistepu | 474 // fu*surf->d_zistepu + surf->d_ziorigin | 475 // fv*surf->d_zistepv | fu 476 fmul %st(3),%st(0) // fu*surf2->d_zistepu | 477 // fu*surf->d_zistepu + surf->d_ziorigin | 478 // fv*surf->d_zistepv | fu 479 fxch %st(1) // fu*surf->d_zistepu + surf->d_ziorigin | 480 // fu*surf2->d_zistepu | 481 // fv*surf->d_zistepv | fu 482 faddp %st(0),%st(2) // fu*surf2->d_zistepu | newzi | fu 483 484 flds C(fv) // fv | fu*surf2->d_zistepu | newzi | fu 485 fmuls st_d_zistepv(%esi) // fv*surf2->d_zistepv | 486 // fu*surf2->d_zistepu | newzi | fu 487 fld %st(2) // newzi | fv*surf2->d_zistepv | 488 // fu*surf2->d_zistepu | newzi | fu 489 fmuls float_point_999 // newzibottom | fv*surf2->d_zistepv | 490 // fu*surf2->d_zistepu | newzi | fu 491 492 fxch %st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv | 493 // newzibottom | newzi | fu 494 fadds st_d_ziorigin(%esi) // fu*surf2->d_zistepu + surf2->d_ziorigin | 495 // fv*surf2->d_zistepv | newzibottom | newzi | 496 // fu 497 faddp %st(0),%st(1) // testzi | newzibottom | newzi | fu 498 fxch %st(1) // newzibottom | testzi | newzi | fu 499 500// if (newzibottom >= testzi) 501// goto Lgotposition; 502 503 fcomp %st(1) // testzi | newzi | fu 504 505 fxch %st(1) // newzi | testzi | fu 506 fmuls float_1_point_001 // newzitop | testzi | fu 507 fxch %st(1) // testzi | newzitop | fu 508 509 fnstsw %ax 510 testb $0x01,%ah 511 jz Lgotposition_fpop3 512 513// if (newzitop >= testzi) 514// { 515 516 fcomp %st(1) // newzitop | fu 517 fnstsw %ax 518 testb $0x45,%ah 519 jz Lsortloop_fpop2 520 521// if (surf->d_zistepu >= surf2->d_zistepu) 522// goto newtop; 523 524 flds st_d_zistepu(%edi) // surf->d_zistepu | newzitop| fu 525 fcomps st_d_zistepu(%esi) // newzitop | fu 526 fnstsw %ax 527 testb $0x01,%ah 528 jz Lgotposition_fpop2 529 530 fstp %st(0) // clear the FPstack 531 fstp %st(0) 532 movl st_key(%edi),%eax 533 jmp Lsortloop 534 535 536Lgotposition_fpop3: 537 fstp %st(0) 538Lgotposition_fpop2: 539 fstp %st(0) 540 fstp %st(0) 541 jmp LInsertAndExit 542 543 544// emit a span (obscures current top) 545 546Lnewtop_fpop3: 547 fstp %st(0) 548Lnewtop_fpop2: 549 fstp %st(0) 550 fstp %st(0) 551 movl st_key(%edi),%eax // reload the sorting key 552 553Lnewtop: 554 movl et_u(%ebx),%eax 555 movl st_last_u(%esi),%edx 556 shrl $20,%eax // iu = integral pixel u 557 movl %eax,st_last_u(%edi) // surf->last_u = iu; 558 cmpl %edx,%eax 559 jle LInsertAndExit // iu <= surf->last_u, so nothing to emit 560 561 subl %edx,%eax 562 movl %edx,espan_t_u(%ebp) // span->u = surf->last_u; 563 564 movl %eax,espan_t_count(%ebp) // span->count = iu - span->u; 565 movl C(current_iv),%eax 566 movl %eax,espan_t_v(%ebp) // span->v = current_iv; 567 movl st_spans(%esi),%eax 568 movl %eax,espan_t_pnext(%ebp) // span->pnext = surf->spans; 569 movl %ebp,st_spans(%esi) // surf->spans = span; 570 addl $(espan_t_size),%ebp 571 572LInsertAndExit: 573// insert before surf2 574 movl %esi,st_next(%edi) // surf->next = surf2; 575 movl st_prev(%esi),%eax 576 movl %eax,st_prev(%edi) // surf->prev = surf2->prev; 577 movl %edi,st_prev(%esi) // surf2->prev = surf; 578 movl %edi,st_next(%eax) // surf2->prev->next = surf; 579 580// --------------------------------------------------------------- 581// leading edge done 582// --------------------------------------------------------------- 583 584// --------------------------------------------------------------- 585// see if there are any more edges 586// --------------------------------------------------------------- 587 588Lgs_nextedge: 589 movl et_next(%ebx),%ebx 590 cmpl $(C(edge_tail)),%ebx 591 jnz Lgs_edgeloop 592 593// clean up at the right edge 594Lgs_lastspan: 595 596// now that we've reached the right edge of the screen, we're done with any 597// unfinished surfaces, so emit a span for whatever's on top 598 movl 0x12345678,%esi // surfaces[1].st_next 599LPatch3: 600 movl C(edge_tail_u_shift20),%eax 601 xorl %ecx,%ecx 602 movl st_last_u(%esi),%edx 603 subl %edx,%eax 604 jle Lgs_resetspanstate 605 606 movl %edx,espan_t_u(%ebp) 607 movl %eax,espan_t_count(%ebp) 608 movl C(current_iv),%eax 609 movl %eax,espan_t_v(%ebp) 610 movl st_spans(%esi),%eax 611 movl %eax,espan_t_pnext(%ebp) 612 movl %ebp,st_spans(%esi) 613 addl $(espan_t_size),%ebp 614 615// reset spanstate for all surfaces in the surface stack 616Lgs_resetspanstate: 617 movl %ecx,st_spanstate(%esi) 618 movl st_next(%esi),%esi 619 cmpl $0x12345678,%esi // &surfaces[1] 620LPatch4: 621 jnz Lgs_resetspanstate 622 623// store the final span_p 624 movl %ebp,C(span_p) 625 626 popl %ebx // restore register variables 627 popl %esi 628 popl %edi 629 popl %ebp // restore the caller's stack frame 630 ret 631 632 633// --------------------------------------------------------------- 634// 1/z sorting for bmodels in the same leaf 635// --------------------------------------------------------------- 636 .align 4 637Lxl_done: 638 incl %edx 639 movl %edx,st_spanstate(%edi) 640 641 jmp Lgs_nextedge 642 643 644 .align 4 645Lzcheck_for_newtop: 646 movl et_u(%ebx),%eax 647 subl $0xFFFFF,%eax 648 movl %eax,Ltemp 649 fildl Ltemp 650 651 fmuls float_1_div_0100000h // fu = (float)(edge->u - 0xFFFFF) * 652 // (1.0 / 0x100000); 653 654 fld %st(0) // fu | fu 655 fmuls st_d_zistepu(%edi) // fu*surf->d_zistepu | fu 656 flds C(fv) // fv | fu*surf->d_zistepu | fu 657 fmuls st_d_zistepv(%edi) // fv*surf->d_zistepv | fu*surf->d_zistepu | fu 658 fxch %st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu 659 fadds st_d_ziorigin(%edi) // fu*surf->d_zistepu + surf->d_ziorigin | 660 // fv*surf->d_zistepv | fu 661 662 flds st_d_zistepu(%esi) // surf2->d_zistepu | 663 // fu*surf->d_zistepu + surf->d_ziorigin | 664 // fv*surf->d_zistepv | fu 665 fmul %st(3),%st(0) // fu*surf2->d_zistepu | 666 // fu*surf->d_zistepu + surf->d_ziorigin | 667 // fv*surf->d_zistepv | fu 668 fxch %st(1) // fu*surf->d_zistepu + surf->d_ziorigin | 669 // fu*surf2->d_zistepu | 670 // fv*surf->d_zistepv | fu 671 faddp %st(0),%st(2) // fu*surf2->d_zistepu | newzi | fu 672 673 flds C(fv) // fv | fu*surf2->d_zistepu | newzi | fu 674 fmuls st_d_zistepv(%esi) // fv*surf2->d_zistepv | 675 // fu*surf2->d_zistepu | newzi | fu 676 fld %st(2) // newzi | fv*surf2->d_zistepv | 677 // fu*surf2->d_zistepu | newzi | fu 678 fmuls float_point_999 // newzibottom | fv*surf2->d_zistepv | 679 // fu*surf2->d_zistepu | newzi | fu 680 681 fxch %st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv | 682 // newzibottom | newzi | fu 683 fadds st_d_ziorigin(%esi) // fu*surf2->d_zistepu + surf2->d_ziorigin | 684 // fv*surf2->d_zistepv | newzibottom | newzi | 685 // fu 686 faddp %st(0),%st(1) // testzi | newzibottom | newzi | fu 687 fxch %st(1) // newzibottom | testzi | newzi | fu 688 689// if (newzibottom >= testzi) 690// goto newtop; 691 692 fcomp %st(1) // testzi | newzi | fu 693 694 fxch %st(1) // newzi | testzi | fu 695 fmuls float_1_point_001 // newzitop | testzi | fu 696 fxch %st(1) // testzi | newzitop | fu 697 698 fnstsw %ax 699 testb $0x01,%ah 700 jz Lnewtop_fpop3 701 702// if (newzitop >= testzi) 703// { 704 705 fcomp %st(1) // newzitop | fu 706 fnstsw %ax 707 testb $0x45,%ah 708 jz Lsortloop_fpop2 709 710// if (surf->d_zistepu >= surf2->d_zistepu) 711// goto newtop; 712 713 flds st_d_zistepu(%edi) // surf->d_zistepu | newzitop | fu 714 fcomps st_d_zistepu(%esi) // newzitop | fu 715 fnstsw %ax 716 testb $0x01,%ah 717 jz Lnewtop_fpop2 718 719Lsortloop_fpop2: 720 fstp %st(0) // clear the FP stack 721 fstp %st(0) 722 movl st_key(%edi),%eax 723 jmp Lsortloop 724 725 726.globl C(R_EdgeCodeEnd) 727C(R_EdgeCodeEnd): 728 729 730//---------------------------------------------------------------------- 731// Surface array address code patching routine 732//---------------------------------------------------------------------- 733 734 .align 4 735.globl C(R_SurfacePatch) 736C(R_SurfacePatch): 737 738 movl C(surfaces),%eax 739 addl $(st_size),%eax 740 movl %eax,LPatch4-4 741 742 addl $(st_next),%eax 743 movl %eax,LPatch0-4 744 movl %eax,LPatch2-4 745 movl %eax,LPatch3-4 746 747 ret 748 749#endif // id386 750 751