vm_x86a.s 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. //
  19. // vm_x86a.s
  20. // linux x86 vm support
  21. #include "qasm.h"
  22. .extern C(instructionPointers)
  23. .data
  24. .align 4
  25. programStack .long 0
  26. opStack .long 0
  27. syscallNum .long 0
  28. .text
  29. .globl C(AsmCAll)
  30. C(AsmCall):
  31. movl (%edi),%eax
  32. subl 4,%edi
  33. orl %eax,%eax
  34. jl systemCall
  35. // calling another vm function
  36. shll 2,%eax
  37. addl C(instructionPointers),%eax
  38. call (%eax)
  39. ret
  40. systemCall:
  41. // convert negative num to system call number
  42. // and store right before the first arg
  43. negl %eax
  44. decl %eax
  45. movl %eax,syscallNum
  46. ///---- UNFINISHED FROM HERE
  47. mov dword ptr syscallNum, eax // so C code can get at it
  48. mov dword ptr programStack, esi // so C code can get at it
  49. mov dword ptr opStack, edi
  50. push ecx
  51. push esi // we may call recursively, so the
  52. push edi // statics aren't guaranteed to be around
  53. }
  54. // save the stack to allow recursive VM entry
  55. currentVM->programStack = programStack - 4;
  56. *(int *)((byte *)currentVM->dataBase + programStack + 4) = syscallNum;
  57. //VM_LogSyscalls( (int *)((byte *)currentVM->dataBase + programStack + 4) );
  58. *(opStack+1) = currentVM->systemCall( (int *)((byte *)currentVM->dataBase + programStack + 4) );
  59. _asm {
  60. pop edi
  61. pop esi
  62. pop ecx
  63. add edi, 4 // we added the return value
  64. ret
  65. }
  66. }
  67. //--------------------------------------------
  68. movl val(%esp),%ecx
  69. movl $0x100,%edx // 0x10000000000 as dividend
  70. cmpl %edx,%ecx
  71. jle LOutOfRange
  72. subl %eax,%eax
  73. divl %ecx
  74. ret
  75. LOutOfRange:
  76. movl $0xFFFFFFFF,%eax
  77. ret
  78. #if 0
  79. #define in 4
  80. #define out 8
  81. .align 2
  82. .globl C(TransformVector)
  83. C(TransformVector):
  84. movl in(%esp),%eax
  85. movl out(%esp),%edx
  86. flds (%eax) // in[0]
  87. fmuls C(vright) // in[0]*vright[0]
  88. flds (%eax) // in[0] | in[0]*vright[0]
  89. fmuls C(vup) // in[0]*vup[0] | in[0]*vright[0]
  90. flds (%eax) // in[0] | in[0]*vup[0] | in[0]*vright[0]
  91. fmuls C(vpn) // in[0]*vpn[0] | in[0]*vup[0] | in[0]*vright[0]
  92. flds 4(%eax) // in[1] | ...
  93. fmuls C(vright)+4 // in[1]*vright[1] | ...
  94. flds 4(%eax) // in[1] | in[1]*vright[1] | ...
  95. fmuls C(vup)+4 // in[1]*vup[1] | in[1]*vright[1] | ...
  96. flds 4(%eax) // in[1] | in[1]*vup[1] | in[1]*vright[1] | ...
  97. fmuls C(vpn)+4 // in[1]*vpn[1] | in[1]*vup[1] | in[1]*vright[1] | ...
  98. fxch %st(2) // in[1]*vright[1] | in[1]*vup[1] | in[1]*vpn[1] | ...
  99. faddp %st(0),%st(5) // in[1]*vup[1] | in[1]*vpn[1] | ...
  100. faddp %st(0),%st(3) // in[1]*vpn[1] | ...
  101. faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
  102. flds 8(%eax) // in[2] | ...
  103. fmuls C(vright)+8 // in[2]*vright[2] | ...
  104. flds 8(%eax) // in[2] | in[2]*vright[2] | ...
  105. fmuls C(vup)+8 // in[2]*vup[2] | in[2]*vright[2] | ...
  106. flds 8(%eax) // in[2] | in[2]*vup[2] | in[2]*vright[2] | ...
  107. fmuls C(vpn)+8 // in[2]*vpn[2] | in[2]*vup[2] | in[2]*vright[2] | ...
  108. fxch %st(2) // in[2]*vright[2] | in[2]*vup[2] | in[2]*vpn[2] | ...
  109. faddp %st(0),%st(5) // in[2]*vup[2] | in[2]*vpn[2] | ...
  110. faddp %st(0),%st(3) // in[2]*vpn[2] | ...
  111. faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
  112. fstps 8(%edx) // out[2]
  113. fstps 4(%edx) // out[1]
  114. fstps (%edx) // out[0]
  115. ret
  116. #endif
  117. #define EMINS 4+4
  118. #define EMAXS 4+8
  119. #define P 4+12
  120. .align 2
  121. .globl C(BoxOnPlaneSide)
  122. C(BoxOnPlaneSide):
  123. pushl %ebx
  124. movl P(%esp),%edx
  125. movl EMINS(%esp),%ecx
  126. xorl %eax,%eax
  127. movl EMAXS(%esp),%ebx
  128. movb pl_signbits(%edx),%al
  129. cmpb $8,%al
  130. jge Lerror
  131. flds pl_normal(%edx) // p->normal[0]
  132. fld %st(0) // p->normal[0] | p->normal[0]
  133. jmp Ljmptab(,%eax,4)
  134. //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  135. //dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  136. Lcase0:
  137. fmuls (%ebx) // p->normal[0]*emaxs[0] | p->normal[0]
  138. flds pl_normal+4(%edx) // p->normal[1] | p->normal[0]*emaxs[0] |
  139. // p->normal[0]
  140. fxch %st(2) // p->normal[0] | p->normal[0]*emaxs[0] |
  141. // p->normal[1]
  142. fmuls (%ecx) // p->normal[0]*emins[0] |
  143. // p->normal[0]*emaxs[0] | p->normal[1]
  144. fxch %st(2) // p->normal[1] | p->normal[0]*emaxs[0] |
  145. // p->normal[0]*emins[0]
  146. fld %st(0) // p->normal[1] | p->normal[1] |
  147. // p->normal[0]*emaxs[0] |
  148. // p->normal[0]*emins[0]
  149. fmuls 4(%ebx) // p->normal[1]*emaxs[1] | p->normal[1] |
  150. // p->normal[0]*emaxs[0] |
  151. // p->normal[0]*emins[0]
  152. flds pl_normal+8(%edx) // p->normal[2] | p->normal[1]*emaxs[1] |
  153. // p->normal[1] | p->normal[0]*emaxs[0] |
  154. // p->normal[0]*emins[0]
  155. fxch %st(2) // p->normal[1] | p->normal[1]*emaxs[1] |
  156. // p->normal[2] | p->normal[0]*emaxs[0] |
  157. // p->normal[0]*emins[0]
  158. fmuls 4(%ecx) // p->normal[1]*emins[1] |
  159. // p->normal[1]*emaxs[1] |
  160. // p->normal[2] | p->normal[0]*emaxs[0] |
  161. // p->normal[0]*emins[0]
  162. fxch %st(2) // p->normal[2] | p->normal[1]*emaxs[1] |
  163. // p->normal[1]*emins[1] |
  164. // p->normal[0]*emaxs[0] |
  165. // p->normal[0]*emins[0]
  166. fld %st(0) // p->normal[2] | p->normal[2] |
  167. // p->normal[1]*emaxs[1] |
  168. // p->normal[1]*emins[1] |
  169. // p->normal[0]*emaxs[0] |
  170. // p->normal[0]*emins[0]
  171. fmuls 8(%ebx) // p->normal[2]*emaxs[2] |
  172. // p->normal[2] |
  173. // p->normal[1]*emaxs[1] |
  174. // p->normal[1]*emins[1] |
  175. // p->normal[0]*emaxs[0] |
  176. // p->normal[0]*emins[0]
  177. fxch %st(5) // p->normal[0]*emins[0] |
  178. // p->normal[2] |
  179. // p->normal[1]*emaxs[1] |
  180. // p->normal[1]*emins[1] |
  181. // p->normal[0]*emaxs[0] |
  182. // p->normal[2]*emaxs[2]
  183. faddp %st(0),%st(3) //p->normal[2] |
  184. // p->normal[1]*emaxs[1] |
  185. // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  186. // p->normal[0]*emaxs[0] |
  187. // p->normal[2]*emaxs[2]
  188. fmuls 8(%ecx) //p->normal[2]*emins[2] |
  189. // p->normal[1]*emaxs[1] |
  190. // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  191. // p->normal[0]*emaxs[0] |
  192. // p->normal[2]*emaxs[2]
  193. fxch %st(1) //p->normal[1]*emaxs[1] |
  194. // p->normal[2]*emins[2] |
  195. // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  196. // p->normal[0]*emaxs[0] |
  197. // p->normal[2]*emaxs[2]
  198. faddp %st(0),%st(3) //p->normal[2]*emins[2] |
  199. // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  200. // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
  201. // p->normal[2]*emaxs[2]
  202. fxch %st(3) //p->normal[2]*emaxs[2] +
  203. // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  204. // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
  205. // p->normal[2]*emins[2]
  206. faddp %st(0),%st(2) //p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  207. // dist1 | p->normal[2]*emins[2]
  208. jmp LSetSides
  209. //dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  210. //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  211. Lcase1:
  212. fmuls (%ecx) // emins[0]
  213. flds pl_normal+4(%edx)
  214. fxch %st(2)
  215. fmuls (%ebx) // emaxs[0]
  216. fxch %st(2)
  217. fld %st(0)
  218. fmuls 4(%ebx) // emaxs[1]
  219. flds pl_normal+8(%edx)
  220. fxch %st(2)
  221. fmuls 4(%ecx) // emins[1]
  222. fxch %st(2)
  223. fld %st(0)
  224. fmuls 8(%ebx) // emaxs[2]
  225. fxch %st(5)
  226. faddp %st(0),%st(3)
  227. fmuls 8(%ecx) // emins[2]
  228. fxch %st(1)
  229. faddp %st(0),%st(3)
  230. fxch %st(3)
  231. faddp %st(0),%st(2)
  232. jmp LSetSides
  233. //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  234. //dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  235. Lcase2:
  236. fmuls (%ebx) // emaxs[0]
  237. flds pl_normal+4(%edx)
  238. fxch %st(2)
  239. fmuls (%ecx) // emins[0]
  240. fxch %st(2)
  241. fld %st(0)
  242. fmuls 4(%ecx) // emins[1]
  243. flds pl_normal+8(%edx)
  244. fxch %st(2)
  245. fmuls 4(%ebx) // emaxs[1]
  246. fxch %st(2)
  247. fld %st(0)
  248. fmuls 8(%ebx) // emaxs[2]
  249. fxch %st(5)
  250. faddp %st(0),%st(3)
  251. fmuls 8(%ecx) // emins[2]
  252. fxch %st(1)
  253. faddp %st(0),%st(3)
  254. fxch %st(3)
  255. faddp %st(0),%st(2)
  256. jmp LSetSides
  257. //dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  258. //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  259. Lcase3:
  260. fmuls (%ecx) // emins[0]
  261. flds pl_normal+4(%edx)
  262. fxch %st(2)
  263. fmuls (%ebx) // emaxs[0]
  264. fxch %st(2)
  265. fld %st(0)
  266. fmuls 4(%ecx) // emins[1]
  267. flds pl_normal+8(%edx)
  268. fxch %st(2)
  269. fmuls 4(%ebx) // emaxs[1]
  270. fxch %st(2)
  271. fld %st(0)
  272. fmuls 8(%ebx) // emaxs[2]
  273. fxch %st(5)
  274. faddp %st(0),%st(3)
  275. fmuls 8(%ecx) // emins[2]
  276. fxch %st(1)
  277. faddp %st(0),%st(3)
  278. fxch %st(3)
  279. faddp %st(0),%st(2)
  280. jmp LSetSides
  281. //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  282. //dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  283. Lcase4:
  284. fmuls (%ebx) // emaxs[0]
  285. flds pl_normal+4(%edx)
  286. fxch %st(2)
  287. fmuls (%ecx) // emins[0]
  288. fxch %st(2)
  289. fld %st(0)
  290. fmuls 4(%ebx) // emaxs[1]
  291. flds pl_normal+8(%edx)
  292. fxch %st(2)
  293. fmuls 4(%ecx) // emins[1]
  294. fxch %st(2)
  295. fld %st(0)
  296. fmuls 8(%ecx) // emins[2]
  297. fxch %st(5)
  298. faddp %st(0),%st(3)
  299. fmuls 8(%ebx) // emaxs[2]
  300. fxch %st(1)
  301. faddp %st(0),%st(3)
  302. fxch %st(3)
  303. faddp %st(0),%st(2)
  304. jmp LSetSides
  305. //dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  306. //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  307. Lcase5:
  308. fmuls (%ecx) // emins[0]
  309. flds pl_normal+4(%edx)
  310. fxch %st(2)
  311. fmuls (%ebx) // emaxs[0]
  312. fxch %st(2)
  313. fld %st(0)
  314. fmuls 4(%ebx) // emaxs[1]
  315. flds pl_normal+8(%edx)
  316. fxch %st(2)
  317. fmuls 4(%ecx) // emins[1]
  318. fxch %st(2)
  319. fld %st(0)
  320. fmuls 8(%ecx) // emins[2]
  321. fxch %st(5)
  322. faddp %st(0),%st(3)
  323. fmuls 8(%ebx) // emaxs[2]
  324. fxch %st(1)
  325. faddp %st(0),%st(3)
  326. fxch %st(3)
  327. faddp %st(0),%st(2)
  328. jmp LSetSides
  329. //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  330. //dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  331. Lcase6:
  332. fmuls (%ebx) // emaxs[0]
  333. flds pl_normal+4(%edx)
  334. fxch %st(2)
  335. fmuls (%ecx) // emins[0]
  336. fxch %st(2)
  337. fld %st(0)
  338. fmuls 4(%ecx) // emins[1]
  339. flds pl_normal+8(%edx)
  340. fxch %st(2)
  341. fmuls 4(%ebx) // emaxs[1]
  342. fxch %st(2)
  343. fld %st(0)
  344. fmuls 8(%ecx) // emins[2]
  345. fxch %st(5)
  346. faddp %st(0),%st(3)
  347. fmuls 8(%ebx) // emaxs[2]
  348. fxch %st(1)
  349. faddp %st(0),%st(3)
  350. fxch %st(3)
  351. faddp %st(0),%st(2)
  352. jmp LSetSides
  353. //dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  354. //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  355. Lcase7:
  356. fmuls (%ecx) // emins[0]
  357. flds pl_normal+4(%edx)
  358. fxch %st(2)
  359. fmuls (%ebx) // emaxs[0]
  360. fxch %st(2)
  361. fld %st(0)
  362. fmuls 4(%ecx) // emins[1]
  363. flds pl_normal+8(%edx)
  364. fxch %st(2)
  365. fmuls 4(%ebx) // emaxs[1]
  366. fxch %st(2)
  367. fld %st(0)
  368. fmuls 8(%ecx) // emins[2]
  369. fxch %st(5)
  370. faddp %st(0),%st(3)
  371. fmuls 8(%ebx) // emaxs[2]
  372. fxch %st(1)
  373. faddp %st(0),%st(3)
  374. fxch %st(3)
  375. faddp %st(0),%st(2)
  376. LSetSides:
  377. // sides = 0;
  378. // if (dist1 >= p->dist)
  379. // sides = 1;
  380. // if (dist2 < p->dist)
  381. // sides |= 2;
  382. faddp %st(0),%st(2) // dist1 | dist2
  383. fcomps pl_dist(%edx)
  384. xorl %ecx,%ecx
  385. fnstsw %ax
  386. fcomps pl_dist(%edx)
  387. andb $1,%ah
  388. xorb $1,%ah
  389. addb %ah,%cl
  390. fnstsw %ax
  391. andb $1,%ah
  392. addb %ah,%ah
  393. addb %ah,%cl
  394. // return sides;
  395. popl %ebx
  396. movl %ecx,%eax // return status
  397. ret
  398. Lerror:
  399. movl 1, %eax
  400. ret
  401. #endif // id386