r_edgea.s 18 KB

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