nseel-cfunc.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  1. /*
  2. Nullsoft Expression Evaluator Library (NS-EEL)
  3. Copyright (C) 1999-2003 Nullsoft, Inc.
  4. nseel-cfunc.c: assembly/C implementation of operator/function templates
  5. This file should be ideally compiled with optimizations towards "minimize size"
  6. This software is provided 'as-is', without any express or implied
  7. warranty. In no event will the authors be held liable for any damages
  8. arising from the use of this software.
  9. Permission is granted to anyone to use this software for any purpose,
  10. including commercial applications, and to alter it and redistribute it
  11. freely, subject to the following restrictions:
  12. 1. The origin of this software must not be misrepresented; you must not
  13. claim that you wrote the original software. If you use this software
  14. in a product, an acknowledgment in the product documentation would be
  15. appreciated but is not required.
  16. 2. Altered source versions must be plainly marked as such, and must not be
  17. misrepresented as being the original software.
  18. 3. This notice may not be removed or altered from any source distribution.
  19. */
  20. #include <windows.h>
  21. #include <math.h>
  22. #include "ns-eel-int.h"
  23. // these are used by our assembly code
  24. static float g_cmpaddtab[2]={0.0,1.0};
  25. static float g_signs[2]={1.0,-1.0};
  26. static double g_closefact = 0.00001;
  27. static float g_half=0.5;
  28. static float negativezeropointfive=-0.5f;
  29. static float onepointfive=1.5f;
  30. /// functions called by built code
  31. #define isnonzero(x) (fabs(x) > g_closefact)
  32. #pragma optimize( "", off )
  33. //---------------------------------------------------------------------------------------------------------------
  34. static double NSEEL_CGEN_CALL _rand(double *x)
  35. {
  36. if (*x < 1.0) *x=1.0;
  37. return (double)(rand()%(int)max(*x,1.0));
  38. }
  39. //---------------------------------------------------------------------------------------------------------------
  40. static double NSEEL_CGEN_CALL _band(double *var, double *var2)
  41. {
  42. return isnonzero(*var) && isnonzero(*var2) ? 1 : 0;
  43. }
  44. //---------------------------------------------------------------------------------------------------------------
  45. static double NSEEL_CGEN_CALL _bor(double *var, double *var2)
  46. {
  47. return isnonzero(*var) || isnonzero(*var2) ? 1 : 0;
  48. }
  49. //---------------------------------------------------------------------------------------------------------------
  50. static double NSEEL_CGEN_CALL _sig(double *x, double *constraint)
  51. {
  52. double t = (1+exp(-*x * (*constraint)));
  53. return isnonzero(t) ? 1.0/t : 0;
  54. }
  55. // end functions called by inline code
  56. // these make room on the stack for local variables, but do not need to
  57. // worry about trashing ebp, since none of our code uses ebp and there's
  58. // a pushad+popad surrounding the call
  59. static double (*__asin)(double) = &asin;
  60. //---------------------------------------------------------------------------------------------------------------
  61. __declspec ( naked ) void nseel_asm_asin(void)
  62. {
  63. FUNC1_ENTER
  64. *__nextBlock = __asin(*parm_a);
  65. FUNC_LEAVE
  66. }
  67. __declspec ( naked ) void nseel_asm_asin_end(void) {}
  68. static double (*__acos)(double) = &acos;
  69. //---------------------------------------------------------------------------------------------------------------
  70. __declspec ( naked ) void nseel_asm_acos(void)
  71. {
  72. FUNC1_ENTER
  73. *__nextBlock = __acos(*parm_a);
  74. FUNC_LEAVE
  75. }
  76. __declspec ( naked ) void nseel_asm_acos_end(void) {}
  77. //---------------------------------------------------------------------------------------------------------------
  78. static double (*__atan)(double) = &atan;
  79. __declspec ( naked ) void nseel_asm_atan(void)
  80. {
  81. FUNC1_ENTER
  82. *__nextBlock = __atan(*parm_a);
  83. FUNC_LEAVE
  84. }
  85. __declspec ( naked ) void nseel_asm_atan_end(void) {}
  86. //---------------------------------------------------------------------------------------------------------------
  87. static double (*__atan2)(double,double) = &atan2;
  88. __declspec ( naked ) void nseel_asm_atan2(void)
  89. {
  90. FUNC2_ENTER
  91. *__nextBlock = __atan2(*parm_b, *parm_a);
  92. FUNC_LEAVE
  93. }
  94. __declspec ( naked ) void nseel_asm_atan2_end(void) {}
  95. //---------------------------------------------------------------------------------------------------------------
  96. static double (NSEEL_CGEN_CALL * __sig)(double *,double *) = &_sig;
  97. __declspec ( naked ) void nseel_asm_sig(void)
  98. {
  99. FUNC2_ENTER
  100. *__nextBlock = __sig(parm_b, parm_a);
  101. FUNC_LEAVE
  102. }
  103. __declspec ( naked ) void nseel_asm_sig_end(void) {}
  104. //---------------------------------------------------------------------------------------------------------------
  105. static double (NSEEL_CGEN_CALL *__rand)(double *) = &_rand;
  106. __declspec ( naked ) void nseel_asm_rand(void)
  107. {
  108. FUNC1_ENTER
  109. *__nextBlock = __rand(parm_a);
  110. FUNC_LEAVE
  111. }
  112. __declspec ( naked ) void nseel_asm_rand_end(void) {}
  113. //---------------------------------------------------------------------------------------------------------------
  114. static double (NSEEL_CGEN_CALL *__band)(double *,double *) = &_band;
  115. __declspec ( naked ) void nseel_asm_band(void)
  116. {
  117. FUNC2_ENTER
  118. *__nextBlock = __band(parm_b, parm_a);
  119. FUNC_LEAVE
  120. }
  121. __declspec ( naked ) void nseel_asm_band_end(void) {}
  122. //---------------------------------------------------------------------------------------------------------------
  123. static double ( NSEEL_CGEN_CALL *__bor)(double *,double *) = &_bor;
  124. __declspec ( naked ) void nseel_asm_bor(void)
  125. {
  126. FUNC2_ENTER
  127. *__nextBlock = __bor(parm_b, parm_a);
  128. FUNC_LEAVE
  129. }
  130. __declspec ( naked ) void nseel_asm_bor_end(void) {}
  131. //---------------------------------------------------------------------------------------------------------------
  132. static double (* __pow)(double,double) = &pow;
  133. __declspec ( naked ) void nseel_asm_pow(void)
  134. {
  135. FUNC2_ENTER
  136. *__nextBlock = __pow(*parm_b, *parm_a);
  137. FUNC_LEAVE
  138. }
  139. __declspec ( naked ) void nseel_asm_pow_end(void) {}
  140. //---------------------------------------------------------------------------------------------------------------
  141. static double (*__exp)(double) = &exp;
  142. __declspec ( naked ) void nseel_asm_exp(void)
  143. {
  144. FUNC1_ENTER
  145. *__nextBlock = __exp(*parm_a);
  146. FUNC_LEAVE
  147. }
  148. __declspec ( naked ) void nseel_asm_exp_end(void) {}
  149. //---------------------------------------------------------------------------------------------------------------
  150. //static double (*__floor)(double) = &floor;
  151. __declspec ( naked ) void nseel_asm_floor(void)
  152. {
  153. FUNC1_ENTER
  154. *__nextBlock = __floor(*parm_a);
  155. FUNC_LEAVE
  156. }
  157. __declspec ( naked ) void nseel_asm_floor_end(void) {}
  158. //---------------------------------------------------------------------------------------------------------------
  159. //static double (*__ceil)(double) = &ceil;
  160. __declspec ( naked ) void nseel_asm_ceil(void)
  161. {
  162. FUNC1_ENTER
  163. *__nextBlock = __ceil(*parm_a);
  164. FUNC_LEAVE
  165. }
  166. __declspec ( naked ) void nseel_asm_ceil_end(void) {}
  167. //---------------------------------------------------------------------------------------------------------------
  168. // do nothing, eh
  169. __declspec ( naked ) void nseel_asm_exec2(void)
  170. {
  171. }
  172. __declspec ( naked ) void nseel_asm_exec2_end(void) { }
  173. __declspec ( naked ) void nseel_asm_invsqrt(void)
  174. {
  175. __asm
  176. {
  177. fld qword ptr [eax]
  178. mov edx, 0x5f3759df
  179. fst dword ptr [esi]
  180. // floating point stack has input, as does [eax]
  181. fmul dword ptr [negativezeropointfive]
  182. mov ecx, [esi]
  183. sar ecx, 1
  184. sub edx, ecx
  185. mov [esi], edx
  186. // st(0) = input, [eax] has x
  187. fmul dword ptr [esi]
  188. fmul dword ptr [esi]
  189. fadd dword ptr [onepointfive]
  190. fmul dword ptr [esi]
  191. mov eax, esi
  192. fstp qword ptr [esi]
  193. add esi, 8
  194. }
  195. }
  196. __declspec ( naked ) void nseel_asm_invsqrt_end(void) {}
  197. //---------------------------------------------------------------------------------------------------------------
  198. __declspec ( naked ) void nseel_asm_sin(void)
  199. {
  200. __asm
  201. {
  202. fld qword ptr [eax]
  203. fsin
  204. mov eax, esi
  205. fstp qword ptr [esi]
  206. add esi, 8
  207. }
  208. }
  209. __declspec ( naked ) void nseel_asm_sin_end(void) {}
  210. //---------------------------------------------------------------------------------------------------------------
  211. __declspec ( naked ) void nseel_asm_cos(void)
  212. {
  213. __asm
  214. {
  215. fld qword ptr [eax]
  216. fcos
  217. mov eax, esi
  218. fstp qword ptr [esi]
  219. add esi, 8
  220. }
  221. }
  222. __declspec ( naked ) void nseel_asm_cos_end(void) {}
  223. //---------------------------------------------------------------------------------------------------------------
  224. __declspec ( naked ) void nseel_asm_tan(void)
  225. {
  226. __asm
  227. {
  228. fld qword ptr [eax]
  229. fsincos
  230. fdiv
  231. mov eax, esi
  232. fstp qword ptr [esi]
  233. add esi, 8
  234. }
  235. }
  236. __declspec ( naked ) void nseel_asm_tan_end(void) {}
  237. //---------------------------------------------------------------------------------------------------------------
  238. __declspec ( naked ) void nseel_asm_sqr(void)
  239. {
  240. __asm
  241. {
  242. fld qword ptr [eax]
  243. fmul st(0), st(0)
  244. mov eax, esi
  245. fstp qword ptr [esi]
  246. add esi, 8
  247. }
  248. }
  249. __declspec ( naked ) void nseel_asm_sqr_end(void) {}
  250. //---------------------------------------------------------------------------------------------------------------
  251. __declspec ( naked ) void nseel_asm_sqrt(void)
  252. {
  253. __asm
  254. {
  255. fld qword ptr [eax]
  256. fabs
  257. fsqrt
  258. mov eax, esi
  259. fstp qword ptr [esi]
  260. add esi, 8
  261. }
  262. }
  263. __declspec ( naked ) void nseel_asm_sqrt_end(void) {}
  264. //---------------------------------------------------------------------------------------------------------------
  265. __declspec ( naked ) void nseel_asm_log(void)
  266. {
  267. __asm
  268. {
  269. fld1
  270. fldl2e
  271. fdiv
  272. fld qword ptr [eax]
  273. mov eax, esi
  274. fyl2x
  275. fstp qword ptr [esi]
  276. add esi, 8
  277. }
  278. }
  279. __declspec ( naked ) void nseel_asm_log_end(void) {}
  280. //---------------------------------------------------------------------------------------------------------------
  281. __declspec ( naked ) void nseel_asm_log10(void)
  282. {
  283. __asm
  284. {
  285. fld1
  286. fldl2t
  287. fdiv
  288. fld qword ptr [eax]
  289. mov eax, esi
  290. fyl2x
  291. fstp qword ptr [esi]
  292. add esi, 8
  293. }
  294. }
  295. __declspec ( naked ) void nseel_asm_log10_end(void) {}
  296. //---------------------------------------------------------------------------------------------------------------
  297. __declspec ( naked ) void nseel_asm_abs(void)
  298. {
  299. __asm
  300. {
  301. fld qword ptr [eax]
  302. fabs
  303. mov eax, esi
  304. fstp qword ptr [esi]
  305. add esi, 8
  306. }
  307. }
  308. __declspec ( naked ) void nseel_asm_abs_end(void) {}
  309. //---------------------------------------------------------------------------------------------------------------
  310. __declspec ( naked ) void nseel_asm_assign(void)
  311. {
  312. __asm
  313. {
  314. fld qword ptr [eax]
  315. fstp qword ptr [ebx]
  316. }
  317. }
  318. __declspec ( naked ) void nseel_asm_assign_end(void) {}
  319. //---------------------------------------------------------------------------------------------------------------
  320. __declspec ( naked ) void nseel_asm_add(void)
  321. {
  322. __asm
  323. {
  324. fld qword ptr [eax]
  325. fadd qword ptr [ebx]
  326. mov eax, esi
  327. fstp qword ptr [esi]
  328. add esi, 8
  329. }
  330. }
  331. __declspec ( naked ) void nseel_asm_add_end(void) {}
  332. //---------------------------------------------------------------------------------------------------------------
  333. __declspec ( naked ) void nseel_asm_sub(void)
  334. {
  335. __asm
  336. {
  337. fld qword ptr [ebx]
  338. fsub qword ptr [eax]
  339. mov eax, esi
  340. fstp qword ptr [esi]
  341. add esi, 8
  342. }
  343. }
  344. __declspec ( naked ) void nseel_asm_sub_end(void) {}
  345. //---------------------------------------------------------------------------------------------------------------
  346. __declspec ( naked ) void nseel_asm_mul(void)
  347. {
  348. __asm
  349. {
  350. fld qword ptr [ebx]
  351. fmul qword ptr [eax]
  352. mov eax, esi
  353. fstp qword ptr [esi]
  354. add esi, 8
  355. }
  356. }
  357. __declspec ( naked ) void nseel_asm_mul_end(void) {}
  358. //---------------------------------------------------------------------------------------------------------------
  359. __declspec ( naked ) void nseel_asm_div(void)
  360. {
  361. __asm
  362. {
  363. fld qword ptr [ebx]
  364. fdiv qword ptr [eax]
  365. mov eax, esi
  366. fstp qword ptr [esi]
  367. add esi, 8
  368. }
  369. }
  370. __declspec ( naked ) void nseel_asm_div_end(void) {}
  371. //---------------------------------------------------------------------------------------------------------------
  372. __declspec ( naked ) void nseel_asm_mod(void)
  373. {
  374. __asm
  375. {
  376. fld qword ptr [ebx]
  377. fld qword ptr [eax]
  378. fsub dword ptr [g_cmpaddtab+4]
  379. fabs
  380. fadd qword ptr [eax]
  381. fadd dword ptr [g_cmpaddtab+4]
  382. fmul dword ptr [g_half]
  383. fistp dword ptr [esi]
  384. fistp dword ptr [esi+4]
  385. mov eax, [esi+4]
  386. xor edx, edx
  387. div dword ptr [esi]
  388. mov [esi], edx
  389. fild dword ptr [esi]
  390. mov eax, esi
  391. fstp qword ptr [esi]
  392. add esi, 8
  393. }
  394. }
  395. __declspec ( naked ) void nseel_asm_mod_end(void) {}
  396. //---------------------------------------------------------------------------------------------------------------
  397. __declspec ( naked ) void nseel_asm_or(void)
  398. {
  399. __asm
  400. {
  401. fld qword ptr [ebx]
  402. fld qword ptr [eax]
  403. fistp qword ptr [esi]
  404. fistp qword ptr [esi+8]
  405. mov ebx, [esi+8]
  406. or [esi], ebx
  407. mov ebx, [esi+12]
  408. or [esi+4], ebx
  409. fild qword ptr [esi]
  410. fstp qword ptr [esi]
  411. mov eax, esi
  412. add esi, 8
  413. }
  414. }
  415. __declspec ( naked ) void nseel_asm_or_end(void) {}
  416. //---------------------------------------------------------------------------------------------------------------
  417. __declspec ( naked ) void nseel_asm_and(void)
  418. {
  419. __asm
  420. {
  421. fld qword ptr [ebx]
  422. fld qword ptr [eax]
  423. fistp qword ptr [esi]
  424. fistp qword ptr [esi+8]
  425. mov ebx, [esi+8]
  426. and [esi], ebx
  427. mov ebx, [esi+12]
  428. and [esi+4], ebx
  429. fild qword ptr [esi]
  430. fstp qword ptr [esi]
  431. mov eax, esi
  432. add esi, 8
  433. }
  434. }
  435. __declspec ( naked ) void nseel_asm_and_end(void) {}
  436. //---------------------------------------------------------------------------------------------------------------
  437. __declspec ( naked ) void nseel_asm_uplus(void) // this is the same as doing nothing, it seems
  438. {
  439. #if 0
  440. __asm
  441. {
  442. mov ebx, nextBlock
  443. mov ecx, [eax]
  444. mov [ebx], ecx
  445. mov ecx, [eax+4]
  446. mov [ebx+4], ecx
  447. mov eax, ebx
  448. add ebx, 8
  449. mov nextBlock, ebx
  450. }
  451. #endif
  452. }
  453. __declspec ( naked ) void nseel_asm_uplus_end(void) {}
  454. //---------------------------------------------------------------------------------------------------------------
  455. __declspec ( naked ) void nseel_asm_uminus(void)
  456. {
  457. __asm
  458. {
  459. mov ecx, [eax]
  460. mov ebx, [eax+4]
  461. xor ebx, 0x80000000
  462. mov [esi], ecx
  463. mov [esi+4], ebx
  464. mov eax, esi
  465. add esi, 8
  466. }
  467. }
  468. __declspec ( naked ) void nseel_asm_uminus_end(void) {}
  469. //---------------------------------------------------------------------------------------------------------------
  470. __declspec ( naked ) void nseel_asm_sign(void)
  471. {
  472. __asm
  473. {
  474. mov ecx, [eax+4]
  475. mov edx, [eax]
  476. test edx, 0FFFFFFFFh
  477. jnz nonzero
  478. // high dword (minus sign bit) is zero
  479. test ecx, 07FFFFFFFh
  480. jz zero // zero zero, return the value passed directly
  481. nonzero:
  482. shr ecx, 31
  483. fld dword ptr [g_signs+ecx*4]
  484. fstp qword ptr [esi]
  485. mov eax, esi
  486. add esi, 8
  487. zero:
  488. }
  489. }
  490. __declspec ( naked ) void nseel_asm_sign_end(void) {}
  491. //---------------------------------------------------------------------------------------------------------------
  492. __declspec ( naked ) void nseel_asm_bnot(void)
  493. {
  494. __asm
  495. {
  496. fld qword ptr [eax]
  497. fabs
  498. fcomp qword ptr [g_closefact]
  499. fstsw ax
  500. shr eax, 6
  501. and eax, (1<<2)
  502. fld dword ptr [g_cmpaddtab+eax]
  503. fstp qword ptr [esi]
  504. mov eax, esi
  505. add esi, 8
  506. }
  507. }
  508. __declspec ( naked ) void nseel_asm_bnot_end(void) {}
  509. //---------------------------------------------------------------------------------------------------------------
  510. __declspec ( naked ) void nseel_asm_if(void)
  511. {
  512. __asm
  513. {
  514. fld qword ptr [eax]
  515. fabs
  516. fcomp qword ptr [g_closefact]
  517. fstsw ax
  518. shr eax, 6
  519. mov dword ptr [esi], 0FFFFFFFFh
  520. mov dword ptr [esi+4], 0FFFFFFFFh
  521. and eax, (1<<2)
  522. mov eax, [esi+eax]
  523. call eax // call the proper function
  524. // at this point, the return value will be in eax, as desired
  525. }
  526. }
  527. __declspec ( naked ) void nseel_asm_if_end(void) {}
  528. #ifdef NSEEL_LOOPFUNC_SUPPORT
  529. #ifndef NSEEL_LOOPFUNC_SUPPORT_MAXLEN
  530. #define NSEEL_LOOPFUNC_SUPPORT_MAXLEN (4096)
  531. #endif
  532. //---------------------------------------------------------------------------------------------------------------
  533. __declspec ( naked ) void nseel_asm_repeat(void)
  534. {
  535. __asm
  536. {
  537. fld qword ptr [eax]
  538. fistp dword ptr [esi]
  539. mov ecx, [esi]
  540. cmp ecx, 1
  541. jl skip
  542. cmp ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
  543. jl again
  544. mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
  545. again:
  546. push ecx
  547. push esi // revert back to last temp workspace
  548. mov ecx, 0FFFFFFFFh
  549. call ecx
  550. pop esi
  551. pop ecx
  552. dec ecx
  553. jnz again
  554. skip:
  555. }
  556. }
  557. __declspec ( naked ) void nseel_asm_repeat_end(void) {}
  558. #endif
  559. //---------------------------------------------------------------------------------------------------------------
  560. __declspec ( naked ) void nseel_asm_equal(void)
  561. {
  562. __asm
  563. {
  564. fld qword ptr [eax]
  565. fsub qword ptr [ebx]
  566. fabs
  567. fcomp qword ptr [g_closefact]
  568. fstsw ax
  569. shr eax, 6
  570. and eax, (1<<2)
  571. fld dword ptr [g_cmpaddtab+eax]
  572. fstp qword ptr [esi]
  573. mov eax, esi
  574. add esi, 8
  575. }
  576. }
  577. __declspec ( naked ) void nseel_asm_equal_end(void) {}
  578. //---------------------------------------------------------------------------------------------------------------
  579. __declspec ( naked ) void nseel_asm_below(void)
  580. {
  581. __asm
  582. {
  583. fld qword ptr [ebx]
  584. fcomp qword ptr [eax]
  585. fstsw ax
  586. shr eax, 6
  587. and eax, (1<<2)
  588. fld dword ptr [g_cmpaddtab+eax]
  589. fstp qword ptr [esi]
  590. mov eax, esi
  591. add esi, 8
  592. }
  593. }
  594. __declspec ( naked ) void nseel_asm_below_end(void) {}
  595. //---------------------------------------------------------------------------------------------------------------
  596. __declspec ( naked ) void nseel_asm_above(void)
  597. {
  598. __asm
  599. {
  600. fld qword ptr [eax]
  601. fcomp qword ptr [ebx]
  602. fstsw ax
  603. shr eax, 6
  604. and eax, (1<<2)
  605. fld dword ptr [g_cmpaddtab+eax]
  606. fstp qword ptr [esi]
  607. mov eax, esi
  608. add esi, 8
  609. }
  610. }
  611. __declspec ( naked ) void nseel_asm_above_end(void) {}
  612. __declspec ( naked ) void nseel_asm_min(void)
  613. {
  614. __asm
  615. {
  616. fld qword ptr [eax]
  617. fld qword ptr [ebx]
  618. fld st(1)
  619. fsub st(0), st(1)
  620. fabs // stack contains fabs(1-2),1,2
  621. fchs
  622. fadd
  623. fadd
  624. fmul dword ptr [g_half]
  625. fstp qword ptr [esi]
  626. mov eax, esi
  627. add esi, 8
  628. }
  629. }
  630. __declspec ( naked ) void nseel_asm_min_end(void) {}
  631. __declspec ( naked ) void nseel_asm_max(void)
  632. {
  633. __asm
  634. {
  635. fld qword ptr [eax]
  636. fld qword ptr [ebx]
  637. fld st(1)
  638. fsub st(0), st(1)
  639. fabs // stack contains fabs(1-2),1,2
  640. fadd
  641. fadd
  642. fmul dword ptr [g_half]
  643. fstp qword ptr [esi]
  644. mov eax, esi
  645. add esi, 8
  646. }
  647. }
  648. __declspec ( naked ) void nseel_asm_max_end(void) {}
  649. #pragma optimize( "", on )