r_edgea.s 17 KB

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