asm-nseel-x86-gcc.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566
  1. #if defined(__APPLE__)
  2. #define SAVE_STACK "pushl %ebp\nmovl %esp, %ebp\nandl $-16, %esp\n"
  3. #define RESTORE_STACK "leave\n"
  4. #else
  5. #define SAVE_STACK
  6. #define RESTORE_STACK
  7. #endif
  8. /* note: only EEL_F_SIZE=8 is now supported (no float EEL_F's) */
  9. void nseel_asm_1pdd(void)
  10. {
  11. __asm__(
  12. SAVE_STACK
  13. #ifdef TARGET_X64
  14. "movq (%eax), %xmm0\n"
  15. "subl $128, %rsp\n"
  16. "movl $0xffffffff, %edi\n"
  17. #ifdef AMD64ABI
  18. "movl %rsi, %r15\n"
  19. "call *%edi\n"
  20. "movl %r15, %rsi\n"
  21. "movq xmm0, (%r15)\n"
  22. #else
  23. "call *%edi\n"
  24. "movq xmm0, (%esi)\n"
  25. #endif
  26. "addl $128, %rsp\n"
  27. #else
  28. "subl $8, %esp\n" /* keep stack aligned */
  29. "pushl 4(%eax)\n" /* push parameter */
  30. "pushl (%eax)\n" /* push the rest of the parameter */
  31. "movl $0xffffffff, %edi\n"
  32. "call *%edi\n"
  33. "fstpl (%esi)\n" /* store result */
  34. "addl $16, %esp\n"
  35. #endif
  36. "movl %esi, %eax\n" /* set return value */
  37. "addl $8, %esi\n" /* advance worktab ptr */
  38. RESTORE_STACK
  39. );
  40. }
  41. void nseel_asm_1pdd_end(void){}
  42. void nseel_asm_2pdd(void)
  43. {
  44. __asm__(
  45. SAVE_STACK
  46. #ifdef TARGET_X64
  47. "movq (%eax), xmm1\n"
  48. "movq (%edi), xmm0\n"
  49. "subl $128, %rsp\n"
  50. "movl $0xffffffff, %edi\n"
  51. #ifdef AMD64ABI
  52. "movl %rsi, %r15\n"
  53. "call *%edi\n"
  54. "movl %r15, %rsi\n"
  55. "movq xmm0, (%r15)\n"
  56. #else
  57. "call *%edi\n"
  58. "movq xmm0, (%esi)\n"
  59. #endif
  60. "addl $128, %rsp\n"
  61. #else
  62. "pushl 4(%eax)\n" /* push parameter */
  63. "pushl (%eax)\n" /* push the rest of the parameter */
  64. "pushl 4(%edi)\n" /* push parameter */
  65. "pushl (%edi)\n" /* push the rest of the parameter */
  66. "movl $0xffffffff, %edi\n"
  67. "call *%edi\n"
  68. "fstpl (%esi)\n" /* store result */
  69. "addl $16, %esp\n"
  70. #endif
  71. "movl %esi, %eax\n" /* set return value */
  72. "addl $8, %esi\n" /* advance worktab ptr */
  73. RESTORE_STACK
  74. );
  75. }
  76. void nseel_asm_2pdd_end(void){}
  77. void nseel_asm_2pdds(void)
  78. {
  79. __asm__(
  80. SAVE_STACK
  81. #ifdef TARGET_X64
  82. "movq (%eax), xmm1\n"
  83. "movq (%edi), xmm0\n"
  84. "subl $128, %rsp\n"
  85. "movl $0xffffffff, %eax\n"
  86. #ifdef AMD64ABI
  87. "movl %rsi, %r15\n"
  88. "movl %rdi, %r14\n"
  89. "call *%eax\n"
  90. "movl %r15, %rsi\n"
  91. "movq xmm0, (%r14)\n"
  92. "movl %r14, %rax\n" /* set return value */
  93. #else
  94. "call *%eax\n"
  95. "movq xmm0, (%edi)\n"
  96. "movl %edi, %eax\n" /* set return value */
  97. #endif
  98. "subl $128, %rsp\n"
  99. #else
  100. "pushl 4(%eax)\n" /* push parameter */
  101. "pushl (%eax)\n" /* push the rest of the parameter */
  102. "pushl 4(%edi)\n" /* push parameter */
  103. "pushl (%edi)\n" /* push the rest of the parameter */
  104. "movl $0xffffffff, %eax\n"
  105. "call *%eax\n"
  106. "fstpl (%edi)\n" /* store result */
  107. "addl $16, %esp\n"
  108. "movl %edi, %eax\n" /* set return value */
  109. #endif
  110. RESTORE_STACK
  111. );
  112. }
  113. void nseel_asm_2pdds_end(void){}
  114. void nseel_asm_2pp(void)
  115. {
  116. __asm__(
  117. SAVE_STACK
  118. #ifdef TARGET_X64
  119. #ifdef AMD64ABI
  120. "movl %rsi, %r15\n"
  121. /* rdi is first parameter */
  122. "movl %rax, %rsi\n"
  123. "subl $128, %rsp\n"
  124. "movl $0xffffffff, %eax\n"
  125. "call *%eax\n"
  126. "movl %r15, %rsi\n"
  127. "movq xmm0, (%r15)\n"
  128. #else
  129. "movl %edi, %ecx\n"
  130. "movl %eax, %edx\n"
  131. "subl $128, %rsp\n"
  132. "movl $0xffffffff, %edi\n"
  133. "call *%edi\n"
  134. "movq xmm0, (%esi)\n"
  135. #endif
  136. "addl $128, %rsp\n"
  137. #else
  138. "subl $8, %esp\n" /* keep stack aligned */
  139. "pushl %eax\n" /* push parameter */
  140. "pushl %edi\n" /* push second parameter */
  141. "movl $0xffffffff, %edi\n"
  142. "call *%edi\n"
  143. "fstp" EEL_F_SUFFIX " (%esi)\n" /* store result */
  144. "addl $16, %esp\n"
  145. #endif
  146. "movl %esi, %eax\n" /* set return value */
  147. "addl $" EEL_F_SSTR ", %esi\n" /* advance worktab ptr */
  148. RESTORE_STACK
  149. );
  150. }
  151. void nseel_asm_2pp_end(void) {}
  152. void nseel_asm_1pp(void)
  153. {
  154. __asm__(
  155. SAVE_STACK
  156. #ifdef TARGET_X64
  157. #ifdef AMD64ABI
  158. "movl %rsi, %r15\n"
  159. "movl %eax, %edi\n"
  160. "subl $128, %rsp\n"
  161. "movl $0xffffffff, %rax\n"
  162. "call *%rax\n"
  163. "movl %r15, %rsi\n"
  164. "movq xmm0, (%r15)\n"
  165. #else
  166. "movl %eax, %ecx\n"
  167. "subl $128, %rsp\n"
  168. "movl $0xffffffff, %edi\n"
  169. "call *%edi\n"
  170. "movq xmm0, (%esi)\n"
  171. #endif
  172. "addl $128, %rsp\n"
  173. #else
  174. "subl $12, %esp\n" /* keep stack aligned */
  175. "pushl %eax\n" /* push parameter */
  176. "movl $0xffffffff, %edi\n"
  177. "call *%edi\n"
  178. "fstp" EEL_F_SUFFIX " (%esi)\n" /* store result */
  179. "addl $16, %esp\n"
  180. #endif
  181. "movl %esi, %eax\n" /* set return value */
  182. "addl $" EEL_F_SSTR ", %esi\n" /* advance worktab ptr */
  183. RESTORE_STACK
  184. );
  185. }
  186. void nseel_asm_1pp_end(void){}
  187. //---------------------------------------------------------------------------------------------------------------
  188. // do nothing, eh
  189. void nseel_asm_exec2(void)
  190. {
  191. __asm__(
  192. ""
  193. );
  194. }
  195. void nseel_asm_exec2_end(void) { }
  196. void nseel_asm_invsqrt(void)
  197. {
  198. __asm__(
  199. "fld" EEL_F_SUFFIX " (%eax)\n"
  200. "movl $0x5f3759df, %edx\n"
  201. "fsts (%esi)\n"
  202. #ifdef TARGET_X64
  203. "movl 0xffffffff, %rax\n"
  204. "subl %ecx, %ecx\n"
  205. "fmul" EEL_F_SUFFIX " (%rax)\n"
  206. #else
  207. "fmul" EEL_F_SUFFIX " (0xffffffff)\n"
  208. #endif
  209. "movl (%esi), %ecx\n"
  210. "sarl $1, %ecx\n"
  211. "subl %ecx, %edx\n"
  212. "movl %edx, (%esi)\n"
  213. "fmuls (%esi)\n"
  214. "fmuls (%esi)\n"
  215. #ifdef TARGET_X64
  216. "movl 0xffffffff, %rax\n"
  217. "fadd" EEL_F_SUFFIX " (%rax)\n"
  218. #else
  219. "fadd" EEL_F_SUFFIX " (0xffffffff)\n"
  220. #endif
  221. "fmuls (%esi)\n"
  222. "movl %esi, %eax\n"
  223. "fstp" EEL_F_SUFFIX " (%esi)\n"
  224. "addl $" EEL_F_SSTR ", %esi\n"
  225. );
  226. }
  227. void nseel_asm_invsqrt_end(void) {}
  228. //---------------------------------------------------------------------------------------------------------------
  229. void nseel_asm_sin(void)
  230. {
  231. __asm__(
  232. "fld" EEL_F_SUFFIX " (%eax)\n"
  233. "fsin\n"
  234. "movl %esi, %eax\n"
  235. "fstp" EEL_F_SUFFIX " (%esi)\n"
  236. "addl $" EEL_F_SSTR ", %esi\n"
  237. );
  238. }
  239. void nseel_asm_sin_end(void) {}
  240. //---------------------------------------------------------------------------------------------------------------
  241. void nseel_asm_cos(void)
  242. {
  243. __asm__(
  244. "fld" EEL_F_SUFFIX " (%eax)\n"
  245. "fcos\n"
  246. "movl %esi, %eax\n"
  247. "fstp" EEL_F_SUFFIX " (%esi)\n"
  248. "addl $" EEL_F_SSTR ", %esi\n"
  249. );
  250. }
  251. void nseel_asm_cos_end(void) {}
  252. //---------------------------------------------------------------------------------------------------------------
  253. void nseel_asm_tan(void)
  254. {
  255. __asm__(
  256. "fld" EEL_F_SUFFIX " (%eax)\n"
  257. "fptan\n"
  258. "movl %esi, %eax\n"
  259. "fstp %st(0)\n"
  260. "fstp" EEL_F_SUFFIX " (%esi)\n"
  261. "addl $" EEL_F_SSTR ", %esi\n"
  262. );
  263. }
  264. void nseel_asm_tan_end(void) {}
  265. //---------------------------------------------------------------------------------------------------------------
  266. void nseel_asm_sqr(void)
  267. {
  268. __asm__(
  269. "fld" EEL_F_SUFFIX " (%eax)\n"
  270. "fmul %st(0), %st(0)\n"
  271. "movl %esi, %eax\n"
  272. "fstp" EEL_F_SUFFIX " (%esi)\n"
  273. "addl $" EEL_F_SSTR ", %esi\n"
  274. );
  275. }
  276. void nseel_asm_sqr_end(void) {}
  277. //---------------------------------------------------------------------------------------------------------------
  278. void nseel_asm_sqrt(void)
  279. {
  280. __asm__(
  281. "fld" EEL_F_SUFFIX " (%eax)\n"
  282. "fabs\n"
  283. "fsqrt\n"
  284. "movl %esi, %eax\n"
  285. "fstp" EEL_F_SUFFIX " (%esi)\n"
  286. "addl $" EEL_F_SSTR ", %esi\n"
  287. );
  288. }
  289. void nseel_asm_sqrt_end(void) {}
  290. //---------------------------------------------------------------------------------------------------------------
  291. void nseel_asm_log(void)
  292. {
  293. __asm__(
  294. "fldln2\n"
  295. "fld" EEL_F_SUFFIX " (%eax)\n"
  296. "movl %esi, %eax\n"
  297. "fyl2x\n"
  298. "fstp" EEL_F_SUFFIX " (%esi)\n"
  299. "addl $" EEL_F_SSTR ", %esi\n"
  300. );
  301. }
  302. void nseel_asm_log_end(void) {}
  303. //---------------------------------------------------------------------------------------------------------------
  304. void nseel_asm_log10(void)
  305. {
  306. __asm__(
  307. "fldlg2\n"
  308. "fld" EEL_F_SUFFIX " (%eax)\n"
  309. "movl %esi, %eax\n"
  310. "fyl2x\n"
  311. "fstp" EEL_F_SUFFIX " (%esi)\n"
  312. "addl $" EEL_F_SSTR ", %esi\n"
  313. );
  314. }
  315. void nseel_asm_log10_end(void) {}
  316. //---------------------------------------------------------------------------------------------------------------
  317. void nseel_asm_abs(void)
  318. {
  319. __asm__(
  320. "fld" EEL_F_SUFFIX " (%eax)\n"
  321. "fabs\n"
  322. "movl %esi, %eax\n"
  323. "fstp" EEL_F_SUFFIX " (%esi)\n"
  324. "addl $" EEL_F_SSTR ", %esi\n"
  325. );
  326. }
  327. void nseel_asm_abs_end(void) {}
  328. //---------------------------------------------------------------------------------------------------------------
  329. void nseel_asm_assign(void)
  330. {
  331. #ifdef TARGET_X64
  332. __asm__(
  333. "movll (%rax), %rdx\n"
  334. "movll %rdx, %rcx\n"
  335. "shrl $32, %rdx\n"
  336. "andl $0x7FF00000, %edx\n"
  337. "jz 1f\n"
  338. "cmpl $0x7FF00000, %edx\n"
  339. "je 1f\n"
  340. "jmp 0f\n"
  341. "1:\n"
  342. "subl %rcx, %rcx\n"
  343. "0:\n"
  344. "movll %rcx, (%edi)\n"
  345. );
  346. #else
  347. #if EEL_F_SIZE == 8
  348. __asm__(
  349. "movl 4(%eax), %edx\n"
  350. "movl (%eax), %ecx\n"
  351. "andl $0x7ff00000, %edx\n"
  352. "jz 1f\n" // if exponent=zero, zero
  353. "cmpl $0x7ff00000, %edx\n"
  354. "je 1f\n" // if exponent=all 1s, zero
  355. "movl 4(%eax), %edx\n" // reread
  356. "jmp 0f\n"
  357. "1:\n"
  358. "subl %ecx, %ecx\n"
  359. "subl %edx, %edx\n"
  360. "0:\n"
  361. "movl %ecx, (%edi)\n"
  362. "movl %edx, 4(%edi)\n"
  363. );
  364. #else
  365. __asm__(
  366. "movl (%eax), %ecx\n"
  367. "movl %ecx, (%edi)\n"
  368. );
  369. #endif
  370. #endif
  371. }
  372. void nseel_asm_assign_end(void) {}
  373. //---------------------------------------------------------------------------------------------------------------
  374. void nseel_asm_add(void)
  375. {
  376. __asm__(
  377. "fld" EEL_F_SUFFIX " (%eax)\n"
  378. "fadd" EEL_F_SUFFIX " (%edi)\n"
  379. "movl %esi, %eax\n"
  380. "fstp" EEL_F_SUFFIX " (%esi)\n"
  381. "addl $" EEL_F_SSTR ", %esi\n"
  382. );
  383. }
  384. void nseel_asm_add_end(void) {}
  385. void nseel_asm_add_op(void)
  386. {
  387. __asm__(
  388. "fld" EEL_F_SUFFIX " (%eax)\n"
  389. "fadd" EEL_F_SUFFIX " (%edi)\n"
  390. "movl %edi, %eax\n"
  391. "fstp" EEL_F_SUFFIX " (%edi)\n"
  392. );
  393. }
  394. void nseel_asm_add_op_end(void) {}
  395. //---------------------------------------------------------------------------------------------------------------
  396. void nseel_asm_sub(void)
  397. {
  398. __asm__(
  399. "fld" EEL_F_SUFFIX " (%edi)\n"
  400. "fsub" EEL_F_SUFFIX " (%eax)\n"
  401. "movl %esi, %eax\n"
  402. "fstp" EEL_F_SUFFIX " (%esi)\n"
  403. "addl $" EEL_F_SSTR ", %esi\n"
  404. );
  405. }
  406. void nseel_asm_sub_end(void) {}
  407. void nseel_asm_sub_op(void)
  408. {
  409. __asm__(
  410. "fld" EEL_F_SUFFIX " (%edi)\n"
  411. "fsub" EEL_F_SUFFIX " (%eax)\n"
  412. "movl %edi, %eax\n"
  413. "fstp" EEL_F_SUFFIX " (%edi)\n"
  414. );
  415. }
  416. void nseel_asm_sub_op_end(void) {}
  417. //---------------------------------------------------------------------------------------------------------------
  418. void nseel_asm_mul(void)
  419. {
  420. __asm__(
  421. "fld" EEL_F_SUFFIX " (%edi)\n"
  422. "fmul" EEL_F_SUFFIX " (%eax)\n"
  423. "movl %esi, %eax\n"
  424. "fstp" EEL_F_SUFFIX " (%esi)\n"
  425. "addl $" EEL_F_SSTR ", %esi\n"
  426. );
  427. }
  428. void nseel_asm_mul_end(void) {}
  429. void nseel_asm_mul_op(void)
  430. {
  431. __asm__(
  432. "fld" EEL_F_SUFFIX " (%eax)\n"
  433. "fmul" EEL_F_SUFFIX " (%edi)\n"
  434. "movl %edi, %eax\n"
  435. "fstp" EEL_F_SUFFIX " (%edi)\n"
  436. );
  437. }
  438. void nseel_asm_mul_op_end(void) {}
  439. //---------------------------------------------------------------------------------------------------------------
  440. void nseel_asm_div(void)
  441. {
  442. __asm__(
  443. "fld" EEL_F_SUFFIX " (%edi)\n"
  444. "fdiv" EEL_F_SUFFIX " (%eax)\n"
  445. "movl %esi, %eax\n"
  446. "fstp" EEL_F_SUFFIX " (%esi)\n"
  447. "addl $" EEL_F_SSTR ", %esi\n"
  448. );
  449. }
  450. void nseel_asm_div_end(void) {}
  451. void nseel_asm_div_op(void)
  452. {
  453. __asm__(
  454. "fld" EEL_F_SUFFIX " (%edi)\n"
  455. "fdiv" EEL_F_SUFFIX " (%eax)\n"
  456. "movl %edi, %eax\n"
  457. "fstp" EEL_F_SUFFIX " (%edi)\n"
  458. );
  459. }
  460. void nseel_asm_div_op_end(void) {}
  461. //---------------------------------------------------------------------------------------------------------------
  462. void nseel_asm_mod(void)
  463. {
  464. __asm__(
  465. "fld" EEL_F_SUFFIX " (%edi)\n"
  466. "fld" EEL_F_SUFFIX " (%eax)\n"
  467. "fabs\n"
  468. "fistpl (%esi)\n"
  469. "fabs\n"
  470. "fistpl 4(%esi)\n"
  471. "xorl %edx, %edx\n"
  472. #ifdef TARGET_X64
  473. "subl %eax, %eax\n"
  474. #endif
  475. "cmpl $0, (%esi)\n"
  476. "je 0f\n" // skip devide, set return to 0
  477. "movl 4(%esi), %eax\n"
  478. "divl (%esi)\n"
  479. "0:\n"
  480. "movl %edx, (%esi)\n"
  481. "fildl (%esi)\n"
  482. "movl %esi, %eax\n"
  483. "fstp" EEL_F_SUFFIX " (%esi)\n"
  484. "addl $" EEL_F_SSTR ", %esi\n"
  485. );
  486. }
  487. void nseel_asm_mod_end(void) {}
  488. void nseel_asm_mod_op(void)
  489. {
  490. __asm__(
  491. "fld" EEL_F_SUFFIX " (%edi)\n"
  492. "fld" EEL_F_SUFFIX " (%eax)\n"
  493. "fabs\n"
  494. "fistpl (%edi)\n"
  495. "fabs\n"
  496. "fistpl (%esi)\n"
  497. #ifdef TARGET_X64
  498. "subl %eax, %eax\n"
  499. #endif
  500. "xorl %edx, %edx\n"
  501. "cmpl $0, (%edi)\n"
  502. "je 0f\n" // skip devide, set return to 0
  503. "movl (%esi), %eax\n"
  504. "divl (%edi)\n"
  505. "0:\n"
  506. "movl %edx, (%edi)\n"
  507. "fildl (%edi)\n"
  508. "movl %edi, %eax\n"
  509. "fstp" EEL_F_SUFFIX " (%edi)\n"
  510. );
  511. }
  512. void nseel_asm_mod_op_end(void) {}
  513. //---------------------------------------------------------------------------------------------------------------
  514. void nseel_asm_or(void)
  515. {
  516. __asm__(
  517. "fld" EEL_F_SUFFIX " (%edi)\n"
  518. "fld" EEL_F_SUFFIX " (%eax)\n"
  519. "movl %esi, %eax\n"
  520. "fistpll (%esi)\n"
  521. "fistpll 8(%esi)\n"
  522. #ifdef TARGET_X64
  523. "movll 8(%rsi), %rdi\n"
  524. "orll %rdi, (%rsi)\n"
  525. #else
  526. "movl 8(%esi), %edi\n"
  527. "movl 12(%esi), %ecx\n"
  528. "orl %edi, (%esi)\n"
  529. "orl %ecx, 4(%esi)\n"
  530. #endif
  531. "fildll (%esi)\n"
  532. "fstp" EEL_F_SUFFIX " (%esi)\n"
  533. "addl $" EEL_F_SSTR ", %esi\n"
  534. );
  535. }
  536. void nseel_asm_or_end(void) {}
  537. void nseel_asm_or_op(void)
  538. {
  539. __asm__(
  540. "fld" EEL_F_SUFFIX " (%edi)\n"
  541. "fld" EEL_F_SUFFIX " (%eax)\n"
  542. "fistpll (%edi)\n"
  543. "fistpll (%esi)\n"
  544. #ifdef TARGET_X64
  545. "movll (%rsi), %rax\n"
  546. "orll %rax, (%rdi)\n"
  547. #else
  548. "movl (%esi), %eax\n"
  549. "movl 4(%esi), %ecx\n"
  550. "orl %eax, (%edi)\n"
  551. "orl %ecx, 4(%edi)\n"
  552. #endif
  553. "fildll (%edi)\n"
  554. "movl %edi, %eax\n"
  555. "fstp" EEL_F_SUFFIX " (%edi)\n"
  556. );
  557. }
  558. void nseel_asm_or_op_end(void) {}
  559. //---------------------------------------------------------------------------------------------------------------
  560. void nseel_asm_and(void)
  561. {
  562. __asm__(
  563. "fld" EEL_F_SUFFIX " (%edi)\n"
  564. "fld" EEL_F_SUFFIX " (%eax)\n"
  565. "movl %esi, %eax\n"
  566. "fistpll (%esi)\n"
  567. "fistpll 8(%esi)\n"
  568. #ifdef TARGET_X64
  569. "movll 8(%rsi), %rdi\n"
  570. "andll %rdi, (%rsi)\n"
  571. #else
  572. "movl 8(%esi), %edi\n"
  573. "movl 12(%esi), %ecx\n"
  574. "andl %edi, (%esi)\n"
  575. "andl %ecx, 4(%esi)\n"
  576. #endif
  577. "fildll (%esi)\n"
  578. "fstp" EEL_F_SUFFIX " (%esi)\n"
  579. "addl $" EEL_F_SSTR ", %esi\n"
  580. );
  581. }
  582. void nseel_asm_and_end(void) {}
  583. void nseel_asm_and_op(void)
  584. {
  585. __asm__(
  586. "fld" EEL_F_SUFFIX " (%edi)\n"
  587. "fld" EEL_F_SUFFIX " (%eax)\n"
  588. "fistpll (%edi)\n"
  589. "fistpll (%esi)\n"
  590. #ifdef TARGET_X64
  591. "movll (%rsi), %rax\n"
  592. "andll %rax, (%rdi)\n"
  593. #else
  594. "movl (%esi), %eax\n"
  595. "movl 4(%esi), %ecx\n"
  596. "andl %eax, (%edi)\n"
  597. "andl %ecx, 4(%edi)\n"
  598. #endif
  599. "fildll (%edi)\n"
  600. "movl %edi, %eax\n"
  601. "fstp" EEL_F_SUFFIX " (%edi)\n"
  602. );
  603. }
  604. void nseel_asm_and_op_end(void) {}
  605. //---------------------------------------------------------------------------------------------------------------
  606. void nseel_asm_uplus(void) // this is the same as doing nothing, it seems
  607. {
  608. __asm__(
  609. ""
  610. );
  611. }
  612. void nseel_asm_uplus_end(void) {}
  613. //---------------------------------------------------------------------------------------------------------------
  614. void nseel_asm_uminus(void)
  615. {
  616. __asm__(
  617. #if EEL_F_SIZE == 8
  618. "movl (%eax), %ecx\n"
  619. "movl 4(%eax), %edi\n"
  620. "movl %ecx, (%esi)\n"
  621. "xorl $0x80000000, %edi\n"
  622. "movl %esi, %eax\n"
  623. "movl %edi, 4(%esi)\n"
  624. "addl $8, %esi\n"
  625. #else
  626. "movl (%eax), %ecx\n"
  627. "xorl $0x80000000, %ecx\n"
  628. "movl %esi, %eax\n"
  629. "movl %ecx, (%esi)\n"
  630. "addl $4, %esi\n"
  631. #endif
  632. );
  633. }
  634. void nseel_asm_uminus_end(void) {}
  635. //---------------------------------------------------------------------------------------------------------------
  636. void nseel_asm_sign(void)
  637. {
  638. __asm__(
  639. #ifdef TARGET_X64
  640. "movl $0xFFFFFFFF, %rdi\n"
  641. "movll (%rax), %rcx\n"
  642. "movll $0x7FFFFFFFFFFFFFFF, %rdx\n"
  643. "testl %rdx, %rcx\n"
  644. "jz 1f\n"
  645. "shr $60, %rcx\n"
  646. "andl $8, %rcx\n"
  647. "addll %rdi, %rcx\n"
  648. "movl %rsi, %rax\n"
  649. "addl $8, %rsi\n"
  650. "movll (%rcx), %rdi\n"
  651. "movll %rdi, (%rax)\n"
  652. "1:\n"
  653. #else
  654. "movl $0xFFFFFFFF, %edi\n"
  655. #if EEL_F_SIZE == 8
  656. "movl 4(%eax), %ecx\n"
  657. "movl (%eax), %edx\n"
  658. "testl $0xFFFFFFFF, %edx\n"
  659. "jnz 0f\n"
  660. #else
  661. "movl (%eax), %ecx\n"
  662. #endif
  663. // high dword (minus sign bit) is zero
  664. "test $0x7FFFFFFF, %ecx\n"
  665. "jz 1f\n" // zero zero, return the value passed directly
  666. "0:\n"
  667. #if EEL_F_SIZE == 8
  668. "shrl $28, %ecx\n"
  669. #else
  670. "shrl $29, %ecx\n"
  671. #endif
  672. "andl $" EEL_F_SSTR ", %ecx\n"
  673. "addl %edi, %ecx\n"
  674. "movl %esi, %eax\n"
  675. "addl $" EEL_F_SSTR ", %esi\n"
  676. "movl (%ecx), %edi\n"
  677. #if EEL_F_SIZE == 8
  678. "movl 4(%ecx), %edx\n"
  679. #endif
  680. "movl %edi, (%eax)\n"
  681. #if EEL_F_SIZE == 8
  682. "movl %edx, 4(%eax)\n"
  683. #endif
  684. "1:\n"
  685. #endif
  686. );
  687. }
  688. void nseel_asm_sign_end(void) {}
  689. //---------------------------------------------------------------------------------------------------------------
  690. void nseel_asm_bnot(void)
  691. {
  692. __asm__(
  693. "fld" EEL_F_SUFFIX " (%eax)\n"
  694. "fabs\n"
  695. #ifdef TARGET_X64
  696. "movl $0xFFFFFFFF, %rax\n"
  697. "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
  698. #else
  699. "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
  700. #endif
  701. "fstsw %ax\n"
  702. "test $256, %eax\n"
  703. "movl %esi, %eax\n"
  704. "jz 0f\n"
  705. "fld1\n"
  706. "jmp 1f\n"
  707. "0:\n"
  708. "fldz\n"
  709. "1:\n"
  710. "fstp" EEL_F_SUFFIX " (%esi)\n"
  711. "addl $" EEL_F_SSTR ", %esi\n"
  712. );
  713. }
  714. void nseel_asm_bnot_end(void) {}
  715. //---------------------------------------------------------------------------------------------------------------
  716. void nseel_asm_if(void)
  717. {
  718. __asm__(
  719. "fld" EEL_F_SUFFIX " (%eax)\n"
  720. "fabs\n"
  721. #ifdef TARGET_X64
  722. "movl $0xFFFFFFFF, %rax\n"
  723. "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
  724. "movll $0xFFFFFFFF, %rax\n"
  725. "movll %rax, (%esi)\n" // conversion script will extend these out to full len
  726. "movll $0xFFFFFFFF, %rax\n"
  727. "movll %rax, 8(%esi)\n"
  728. "fstsw %ax\n"
  729. "shrl $5, %rax\n"
  730. "andl $8, %rax\n"
  731. "movll (%rax, %rsi), %rax\n"
  732. "subl $8, %rsp\n"
  733. #else
  734. "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
  735. "movl $0xFFFFFFFF, (%esi)\n"
  736. "movl $0xFFFFFFFF, 4(%esi)\n"
  737. "fstsw %ax\n"
  738. "shrl $6, %eax\n"
  739. "andl $4, %eax\n"
  740. "movl (%eax, %esi), %eax\n"
  741. #endif
  742. "call *%eax\n"
  743. #ifdef TARGET_X64
  744. "addl $8, %rsp\n"
  745. #endif
  746. );
  747. }
  748. void nseel_asm_if_end(void) {}
  749. //---------------------------------------------------------------------------------------------------------------
  750. void nseel_asm_repeat(void)
  751. {
  752. __asm__(
  753. "fld" EEL_F_SUFFIX " (%eax)\n"
  754. "fistpl (%esi)\n"
  755. #ifdef TARGET_X64 // safe not sure if movl ecx will zero the high word
  756. "xorl %ecx, %ecx\n"
  757. #endif
  758. "movl (%esi), %ecx\n"
  759. "cmpl $1, %ecx\n"
  760. "jl 1f\n"
  761. "cmpl $" NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR ", %ecx\n"
  762. "jl 0f\n"
  763. "movl $" NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR ", %ecx\n"
  764. "0:\n"
  765. "movl $0xFFFFFFFF, %edx\n"
  766. "subl $8, %esp\n" /* keep stack aligned -- note this is required on x64 too!*/
  767. "pushl %esi\n" // revert back to last temp workspace
  768. "pushl %ecx\n"
  769. "call *%edx\n"
  770. "popl %ecx\n"
  771. "popl %esi\n"
  772. "addl $8, %esp\n" /* keep stack aligned -- also required on x64*/
  773. "decl %ecx\n"
  774. "jnz 0b\n"
  775. "1:\n"
  776. );
  777. }
  778. void nseel_asm_repeat_end(void) {}
  779. void nseel_asm_repeatwhile(void)
  780. {
  781. __asm__(
  782. "movl $" NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR ", %ecx\n"
  783. "0:\n"
  784. "movl $0xFFFFFFFF, %edx\n"
  785. "subl $8, %esp\n" /* keep stack aligned -- required on x86 and x64*/
  786. "pushl %esi\n" // revert back to last temp workspace
  787. "pushl %ecx\n"
  788. "call *%edx\n"
  789. "popl %ecx\n"
  790. "popl %esi\n"
  791. "addl $8, %esp\n" /* keep stack aligned -- required on x86 and x64 */
  792. "fld" EEL_F_SUFFIX " (%eax)\n"
  793. "fabs\n"
  794. #ifdef TARGET_X64
  795. "movl $0xFFFFFFFF, %rax\n"
  796. "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
  797. #else
  798. "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
  799. #endif
  800. "fstsw %ax\n"
  801. "testl $256, %eax\n"
  802. "jnz 0f\n"
  803. "decl %ecx\n"
  804. "jnz 0b\n"
  805. "0:\n"
  806. "movl %esi, %eax\n"
  807. );
  808. }
  809. void nseel_asm_repeatwhile_end(void) {}
  810. void nseel_asm_band(void)
  811. {
  812. __asm__(
  813. "fld" EEL_F_SUFFIX " (%eax)\n"
  814. "fabs\n"
  815. #ifdef TARGET_X64
  816. "movl $0xFFFFFFFF, %rax\n"
  817. "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
  818. #else
  819. "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
  820. #endif
  821. "fstsw %ax\n"
  822. "testl $256, %eax\n"
  823. "jnz 0f\n" // if Z, then we are nonzero
  824. "movl $0xFFFFFFFF, %ecx\n"
  825. #ifdef TARGET_X64
  826. "subl $8, %rsp\n"
  827. #endif
  828. "call *%ecx\n"
  829. #ifdef TARGET_X64
  830. "addl $8, %rsp\n"
  831. #endif
  832. "fld" EEL_F_SUFFIX " (%eax)\n"
  833. "fabs\n"
  834. #ifdef TARGET_X64
  835. "movl $0xFFFFFFFF, %rax\n"
  836. "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
  837. #else
  838. "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
  839. #endif
  840. "fstsw %ax\n"
  841. "testl $256, %eax\n"
  842. "jnz 0f\n"
  843. "fld1\n"
  844. "jmp 1f\n"
  845. "0:\n"
  846. "fldz\n"
  847. "1:\n"
  848. "movl %esi, %eax\n"
  849. "fstp" EEL_F_SUFFIX " (%esi)\n"
  850. "addl $" EEL_F_SSTR ", %esi\n"
  851. );
  852. }
  853. void nseel_asm_band_end(void) {}
  854. void nseel_asm_bor(void)
  855. {
  856. __asm__(
  857. "fld" EEL_F_SUFFIX " (%eax)\n"
  858. "fabs\n"
  859. #ifdef TARGET_X64
  860. "movl $0xFFFFFFFF, %rax\n"
  861. "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
  862. #else
  863. "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
  864. #endif
  865. "fstsw %ax\n"
  866. "testl $256, %eax\n"
  867. "jz 0f\n" // if Z, then we are nonzero
  868. "movl $0xFFFFFFFF, %ecx\n"
  869. #ifdef TARGET_X64
  870. "subl $8, %rsp\n"
  871. #endif
  872. "call *%ecx\n"
  873. #ifdef TARGET_X64
  874. "addl $8, %rsp\n"
  875. #endif
  876. "fld" EEL_F_SUFFIX " (%eax)\n"
  877. "fabs\n"
  878. #ifdef TARGET_X64
  879. "movl $0xFFFFFFFF, %rax\n"
  880. "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
  881. #else
  882. "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
  883. #endif
  884. "fstsw %ax\n"
  885. "testl $256, %eax\n"
  886. "jz 0f\n"
  887. "fldz\n"
  888. "jmp 1f\n"
  889. "0:\n"
  890. "fld1\n"
  891. "1:\n"
  892. "movl %esi, %eax\n"
  893. "fstp" EEL_F_SUFFIX " (%esi)\n"
  894. "addl $" EEL_F_SSTR ", %esi\n"
  895. );
  896. }
  897. void nseel_asm_bor_end(void) {}
  898. //---------------------------------------------------------------------------------------------------------------
  899. void nseel_asm_equal(void)
  900. {
  901. __asm__(
  902. "fld" EEL_F_SUFFIX " (%eax)\n"
  903. "fsub" EEL_F_SUFFIX " (%edi)\n"
  904. "fabs\n"
  905. #ifdef TARGET_X64
  906. "movl $0xFFFFFFFF, %rax\n"
  907. "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
  908. #else
  909. "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
  910. #endif
  911. "fstsw %ax\n"
  912. "testl $256, %eax\n"
  913. "movl %esi, %eax\n"
  914. "jz 0f\n"
  915. "fld1\n"
  916. "jmp 1f\n"
  917. "0:\n"
  918. "fldz\n"
  919. "1:\n"
  920. "fstp" EEL_F_SUFFIX " (%esi)\n"
  921. "addl $" EEL_F_SSTR ", %esi\n"
  922. );
  923. }
  924. void nseel_asm_equal_end(void) {}
  925. //
  926. //---------------------------------------------------------------------------------------------------------------
  927. void nseel_asm_notequal(void)
  928. {
  929. __asm__(
  930. "fld" EEL_F_SUFFIX " (%eax)\n"
  931. "fsub" EEL_F_SUFFIX " (%edi)\n"
  932. "fabs\n"
  933. #ifdef TARGET_X64
  934. "movl $0xFFFFFFFF, %rax\n"
  935. "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
  936. #else
  937. "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
  938. #endif
  939. "fstsw %ax\n"
  940. "testl $256, %eax\n"
  941. "movl %esi, %eax\n"
  942. "jnz 0f\n"
  943. "fld1\n"
  944. "jmp 1f\n"
  945. "0:\n"
  946. "fldz\n"
  947. "1:\n"
  948. "fstp" EEL_F_SUFFIX " (%esi)\n"
  949. "addl $" EEL_F_SSTR ", %esi\n"
  950. );
  951. }
  952. void nseel_asm_notequal_end(void) {}
  953. //---------------------------------------------------------------------------------------------------------------
  954. void nseel_asm_below(void)
  955. {
  956. __asm__(
  957. "fld" EEL_F_SUFFIX " (%edi)\n"
  958. "fcomp" EEL_F_SUFFIX " (%eax)\n"
  959. "fstsw %ax\n"
  960. "testl $256, %eax\n"
  961. "movl %esi, %eax\n"
  962. "jz 0f\n"
  963. "fld1\n"
  964. "jmp 1f\n"
  965. "0:\n"
  966. "fldz\n"
  967. "1:\n"
  968. "fstp" EEL_F_SUFFIX " (%esi)\n"
  969. "addl $" EEL_F_SSTR ", %esi\n"
  970. );
  971. }
  972. void nseel_asm_below_end(void) {}
  973. //---------------------------------------------------------------------------------------------------------------
  974. void nseel_asm_beloweq(void)
  975. {
  976. __asm__(
  977. "fld" EEL_F_SUFFIX " (%eax)\n"
  978. "fcomp" EEL_F_SUFFIX " (%edi)\n"
  979. "fstsw %ax\n"
  980. "testl $256, %eax\n"
  981. "movl %esi, %eax\n"
  982. "jnz 0f\n"
  983. "fld1\n"
  984. "jmp 1f\n"
  985. "0:\n"
  986. "fldz\n"
  987. "1:\n"
  988. "fstp" EEL_F_SUFFIX " (%esi)\n"
  989. "addl $" EEL_F_SSTR ", %esi\n"
  990. );
  991. }
  992. void nseel_asm_beloweq_end(void) {}
  993. //---------------------------------------------------------------------------------------------------------------
  994. void nseel_asm_above(void)
  995. {
  996. __asm__(
  997. "fld" EEL_F_SUFFIX " (%eax)\n"
  998. "fcomp" EEL_F_SUFFIX " (%edi)\n"
  999. "fstsw %ax\n"
  1000. "testl $256, %eax\n"
  1001. "movl %esi, %eax\n"
  1002. "jz 0f\n"
  1003. "fld1\n"
  1004. "jmp 1f\n"
  1005. "0:\n"
  1006. "fldz\n"
  1007. "1:\n"
  1008. "fstp" EEL_F_SUFFIX " (%esi)\n"
  1009. "addl $" EEL_F_SSTR ", %esi\n"
  1010. );
  1011. }
  1012. void nseel_asm_above_end(void) {}
  1013. void nseel_asm_aboveeq(void)
  1014. {
  1015. __asm__(
  1016. "fld" EEL_F_SUFFIX " (%edi)\n"
  1017. "fcomp" EEL_F_SUFFIX " (%eax)\n"
  1018. "fstsw %ax\n"
  1019. "testl $256, %eax\n"
  1020. "movl %esi, %eax\n"
  1021. "jnz 0f\n"
  1022. "fld1\n"
  1023. "jmp 1f\n"
  1024. "0:\n"
  1025. "fldz\n"
  1026. "1:\n"
  1027. "fstp" EEL_F_SUFFIX " (%esi)\n"
  1028. "addl $" EEL_F_SSTR ", %esi\n"
  1029. );
  1030. }
  1031. void nseel_asm_aboveeq_end(void) {}
  1032. void nseel_asm_min(void)
  1033. {
  1034. __asm__(
  1035. "fld" EEL_F_SUFFIX " (%edi)\n"
  1036. "fcomp" EEL_F_SUFFIX " (%eax)\n"
  1037. "pushl %eax\n"
  1038. "fstsw %ax\n"
  1039. "testl $256, %eax\n"
  1040. "popl %eax\n"
  1041. "jz 0f\n"
  1042. "movl %edi, %eax\n"
  1043. "0:\n"
  1044. );
  1045. }
  1046. void nseel_asm_min_end(void) {}
  1047. void nseel_asm_max(void)
  1048. {
  1049. __asm__(
  1050. "fld" EEL_F_SUFFIX " (%edi)\n"
  1051. "fcomp" EEL_F_SUFFIX " (%eax)\n"
  1052. "pushl %eax\n"
  1053. "fstsw %ax\n"
  1054. "testl $256, %eax\n"
  1055. "popl %eax\n"
  1056. "jnz 0f\n"
  1057. "movl %edi, %eax\n"
  1058. "0:\n"
  1059. );
  1060. }
  1061. void nseel_asm_max_end(void) {}
  1062. // just generic functions left, yay
  1063. void _asm_generic3parm(void)
  1064. {
  1065. __asm__(
  1066. #ifdef TARGET_X64
  1067. #ifdef AMD64ABI
  1068. "movl %rsi, %r15\n"
  1069. "movl %rdi, %rdx\n" // third parameter = parm
  1070. "movl $0xFFFFFFFF, %rdi\n" // first parameter= context
  1071. "movl %ecx, %rsi\n" // second parameter = parm
  1072. "movl %rax, %rcx\n" // fourth parameter = parm
  1073. "movl $0xffffffff, %rax\n" // call function
  1074. "subl $128, %rsp\n"
  1075. "call *%rax\n"
  1076. "movl %r15, %rsi\n"
  1077. "addl $128, %rsp\n"
  1078. #else
  1079. "movl %ecx, %edx\n" // second parameter = parm
  1080. "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
  1081. "movl %rdi, %r8\n" // third parameter = parm
  1082. "movl %rax, %r9\n" // fourth parameter = parm
  1083. "movl $0xffffffff, %edi\n" // call function
  1084. "subl $128, %rsp\n"
  1085. "call *%edi\n"
  1086. "addl $128, %rsp\n"
  1087. #endif
  1088. #else
  1089. SAVE_STACK
  1090. "movl $0xFFFFFFFF, %edx\n"
  1091. "pushl %eax\n" // push parameter
  1092. "pushl %edi\n" // push parameter
  1093. "pushl %ecx\n" // push parameter
  1094. "pushl %edx\n" // push context pointer
  1095. "movl $0xffffffff, %edi\n"
  1096. "call *%edi\n"
  1097. "addl $16, %esp\n"
  1098. RESTORE_STACK
  1099. #endif
  1100. );
  1101. }
  1102. void _asm_generic3parm_end(void) {}
  1103. void _asm_generic3parm_retd(void)
  1104. {
  1105. __asm__(
  1106. #ifdef TARGET_X64
  1107. #ifdef AMD64ABI
  1108. "movl %rsi, %r15\n"
  1109. "movl %rdi, %rdx\n" // third parameter = parm
  1110. "movl $0xFFFFFFFF, %rdi\n" // first parameter= context
  1111. "movl %ecx, %rsi\n" // second parameter = parm
  1112. "movl %rax, %rcx\n" // fourth parameter = parm
  1113. "movl $0xffffffff, %rax\n" // call function
  1114. "subl $128, %rsp\n"
  1115. "call *%rax\n"
  1116. "addl $128, %rsp\n"
  1117. "movl %r15, %rsi\n"
  1118. "movl %r15, %rax\n"
  1119. "movq xmm0, (%r15)\n"
  1120. "addl $8, %rsi\n"
  1121. #else
  1122. "movl %ecx, %edx\n" // second parameter = parm
  1123. "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
  1124. "movl %rdi, %r8\n" // third parameter = parm
  1125. "movl %rax, %r9\n" // fourth parameter = parm
  1126. "movl $0xffffffff, %edi\n" // call function
  1127. "subl $128, %rsp\n"
  1128. "call *%edi\n"
  1129. "addl $128, %rsp\n"
  1130. "movq xmm0, (%rsi)\n"
  1131. "movl %rsi, %rax\n"
  1132. "addl $8, %rsi\n"
  1133. #endif
  1134. #else
  1135. SAVE_STACK
  1136. "movl $0xFFFFFFFF, %edx\n"
  1137. "pushl %eax\n" // push parameter
  1138. "pushl %edi\n" // push parameter
  1139. "pushl %ecx\n" // push parameter
  1140. "pushl %edx\n" // push context pointer
  1141. "movl $0xffffffff, %edi\n"
  1142. "call *%edi\n"
  1143. "movl %esi, %eax\n"
  1144. "fstp" EEL_F_SUFFIX " (%esi)\n"
  1145. "addl $" EEL_F_SSTR ", %esi\n"
  1146. "addl $16, %esp\n"
  1147. RESTORE_STACK
  1148. #endif
  1149. );
  1150. }
  1151. void _asm_generic3parm_retd_end(void) {}
  1152. void _asm_generic2parm(void) // this prob neds to be fixed for ppc
  1153. {
  1154. __asm__(
  1155. #ifdef TARGET_X64
  1156. #ifdef AMD64ABI
  1157. "movl %rsi, %r15\n"
  1158. "movl %edi, %esi\n" // second parameter = parm
  1159. "movl $0xFFFFFFFF, %edi\n" // first parameter= context
  1160. "movl %rax, %rdx\n" // third parameter = parm
  1161. "movl $0xffffffff, %rcx\n" // call function
  1162. "subl $128, %rsp\n"
  1163. "call *%rcx\n"
  1164. "movl %r15, %rsi\n"
  1165. "addl $128, %rsp\n"
  1166. #else
  1167. "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
  1168. "movl %edi, %edx\n" // second parameter = parm
  1169. "movl %rax, %r8\n" // third parameter = parm
  1170. "movl $0xffffffff, %edi\n" // call function
  1171. "subl $128, %rsp\n"
  1172. "call *%edi\n"
  1173. "addl $128, %rsp\n"
  1174. #endif
  1175. #else
  1176. SAVE_STACK
  1177. "movl $0xFFFFFFFF, %edx\n"
  1178. "subl $4, %esp\n" // keep stack aligned
  1179. "pushl %eax\n" // push parameter
  1180. "pushl %edi\n" // push parameter
  1181. "pushl %edx\n" // push context pointer
  1182. "movl $0xffffffff, %edi\n"
  1183. "call *%edi\n"
  1184. "addl $16, %esp\n"
  1185. RESTORE_STACK
  1186. #endif
  1187. );
  1188. }
  1189. void _asm_generic2parm_end(void) {}
  1190. void _asm_generic2parm_retd(void)
  1191. {
  1192. __asm__(
  1193. #ifdef TARGET_X64
  1194. #ifdef AMD64ABI
  1195. "movl %rsi, %r15\n"
  1196. "movl %rdi, %rsi\n" // second parameter = parm
  1197. "movl $0xFFFFFFFF, %rdi\n" // first parameter= context
  1198. "movl %rax, %rdx\n" // third parameter = parm
  1199. "movl $0xffffffff, %rcx\n" // call function
  1200. "subl $128, %rsp\n"
  1201. "call *%rcx\n"
  1202. "movl %r15, %rsi\n"
  1203. "addl $128, %rsp\n"
  1204. "movq xmm0, (%r15)\n"
  1205. "movl %r15, %rax\n"
  1206. "addl $8, %rsi\n"
  1207. #else
  1208. "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
  1209. "movl %edi, %edx\n" // second parameter = parm
  1210. "movl %rax, %r8\n" // third parameter = parm
  1211. "movl $0xffffffff, %edi\n" // call function
  1212. "subl $128, %rsp\n"
  1213. "call *%edi\n"
  1214. "addl $128, %rsp\n"
  1215. "movq xmm0, (%rsi)\n"
  1216. "movl %rsi, %rax\n"
  1217. "addl $8, %rsi\n"
  1218. #endif
  1219. #else
  1220. SAVE_STACK
  1221. "movl $0xFFFFFFFF, %edx\n"
  1222. "pushl %eax\n" // push parameter
  1223. "pushl %edi\n" // push parameter
  1224. "pushl %ecx\n" // push parameter
  1225. "pushl %edx\n" // push context pointer
  1226. "movl $0xffffffff, %edi\n"
  1227. "call *%edi\n"
  1228. "movl %esi, %eax\n"
  1229. "fstp" EEL_F_SUFFIX " (%esi)\n"
  1230. "addl $" EEL_F_SSTR ", %esi\n"
  1231. "addl $16, %esp\n"
  1232. RESTORE_STACK
  1233. #endif
  1234. );
  1235. }
  1236. void _asm_generic2parm_retd_end(void) {}
  1237. void _asm_generic1parm(void) // this prob neds to be fixed for ppc
  1238. {
  1239. __asm__(
  1240. #ifdef TARGET_X64
  1241. #ifdef AMD64ABI
  1242. "movl $0xFFFFFFFF, %rdi\n" // first parameter= context
  1243. "movl %rsi, %r15\n"
  1244. "movl %eax, %rsi\n" // second parameter = parm
  1245. "subl $128, %rsp\n"
  1246. "movl $0xffffffff, %rcx\n" // call function
  1247. "call *%rcx\n"
  1248. "movl %r15, %rsi\n"
  1249. "addl $128, %rsp\n"
  1250. #else
  1251. "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
  1252. "movl %eax, %edx\n" // second parameter = parm
  1253. "movl $0xffffffff, %edi\n" // call function
  1254. "subl $128, %rsp\n"
  1255. "call *%edi\n"
  1256. "addl $128, %rsp\n"
  1257. #endif
  1258. #else
  1259. SAVE_STACK
  1260. "movl $0xFFFFFFFF, %edx\n"
  1261. "subl $8, %esp\n" // keep stack aligned
  1262. "pushl %eax\n" // push parameter
  1263. "pushl %edx\n" // push context pointer
  1264. "movl $0xffffffff, %edi\n"
  1265. "call *%edi\n"
  1266. "addl $16, %esp\n"
  1267. RESTORE_STACK
  1268. #endif
  1269. );
  1270. }
  1271. void _asm_generic1parm_end(void) {}
  1272. void _asm_generic1parm_retd(void) // 1 parameter returning double
  1273. {
  1274. __asm__(
  1275. #ifdef TARGET_X64
  1276. #ifdef AMD64ABI
  1277. "movl %rsi, %r15\n"
  1278. "movl $0xFFFFFFFF, %rdi\n" // first parameter= context
  1279. "movl %rax, %rsi\n" // second parameter = parm
  1280. "movl $0xffffffff, %rcx\n" // call function
  1281. "subl $128, %rsp\n"
  1282. "call *%rcx\n"
  1283. "movl %r15, %rsi\n"
  1284. "addl $128, %rsp\n"
  1285. "movq xmm0, (%r15)\n"
  1286. "movl %r15, %rax\n"
  1287. "addl $8, %rsi\n"
  1288. #else
  1289. "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
  1290. "movl %eax, %edx\n" // second parameter = parm
  1291. "movl $0xffffffff, %edi\n" // call function
  1292. "subl $128, %rsp\n"
  1293. "call *%edi\n"
  1294. "addl $128, %rsp\n"
  1295. "movq xmm0, (%rsi)\n"
  1296. "movl %rsi, %rax\n"
  1297. "addl $8, %rsi\n"
  1298. #endif
  1299. #else
  1300. SAVE_STACK
  1301. "movl $0xFFFFFFFF, %edx\n"
  1302. "subl $8, %esp\n" // keep stack aligned
  1303. "pushl %eax\n" // push parameter
  1304. "pushl %edx\n" // push context pointer
  1305. "movl $0xffffffff, %edi\n"
  1306. "call *%edi\n"
  1307. "movl %esi, %eax\n"
  1308. "fstp" EEL_F_SUFFIX " (%esi)\n"
  1309. "addl $" EEL_F_SSTR ", %esi\n"
  1310. "addl $16, %esp\n"
  1311. RESTORE_STACK
  1312. #endif
  1313. );
  1314. }
  1315. void _asm_generic1parm_retd_end(void) {}
  1316. // this gets its own stub because it's pretty crucial for performance :/
  1317. void _asm_megabuf(void)
  1318. {
  1319. __asm__(
  1320. SAVE_STACK
  1321. #ifdef TARGET_X64
  1322. #ifdef AMD64ABI
  1323. "movl %rsi, %r15\n"
  1324. "movl $0xFFFFFFFF, %rdi\n" // first parameter = context pointer
  1325. "fld" EEL_F_SUFFIX " (%eax)\n"
  1326. "movl $0xFFFFFFFF, %rdx\n"
  1327. "fadd" EEL_F_SUFFIX " (%rdx)\n"
  1328. "fistpl (%r15)\n"
  1329. "xorl %rsi, %rsi\n"
  1330. "movl (%r15), %esi\n" // r15 = esi (from above)
  1331. "movl $0xffffffff, %edx\n"
  1332. "subl $128, %rsp\n"
  1333. "call *%edx\n"
  1334. "movl %r15, %rsi\n"
  1335. "addl $128, %rsp\n"
  1336. "and %rax, %rax\n"
  1337. "jnz 0f\n"
  1338. "movl %r15, %rax\n"
  1339. "movll $0, (%esi)\n"
  1340. "addl $" EEL_F_SSTR ", %rsi\n"
  1341. "0:"
  1342. #else
  1343. "movl $0xFFFFFFFF, %ecx\n" // first parameter = context pointer
  1344. "fld" EEL_F_SUFFIX " (%eax)\n"
  1345. "movl $0xFFFFFFFF, %edx\n"
  1346. "fadd" EEL_F_SUFFIX " (%rdx)\n"
  1347. "fistpl (%esi)\n"
  1348. "xorl %rdx, %rdx\n"
  1349. "movl (%esi), %edx\n"
  1350. "movl $0xffffffff, %edi\n"
  1351. "subl $128, %rsp\n"
  1352. "call *%edi\n"
  1353. "addl $128, %rsp\n"
  1354. "and %rax, %rax\n"
  1355. "jnz 0f\n"
  1356. "movl %rsi, %rax\n"
  1357. "movll $0, (%esi)\n"
  1358. "addl $" EEL_F_SSTR ", %esi\n"
  1359. "0:"
  1360. #endif
  1361. #else
  1362. "movl $0xFFFFFFFF, %edx\n"
  1363. "fld" EEL_F_SUFFIX " (%eax)\n"
  1364. "fadd" EEL_F_SUFFIX " (0xFFFFFFFF)\n"
  1365. "fistpl (%esi)\n"
  1366. "subl $8, %esp\n" // keep stack aligned
  1367. "pushl (%esi)\n" // parameter
  1368. "pushl %edx\n" // push context pointer
  1369. "movl $0xffffffff, %edi\n"
  1370. "call *%edi\n"
  1371. "addl $16, %esp\n"
  1372. "and %eax, %eax\n"
  1373. "jnz 0f\n"
  1374. "movl %esi, %eax\n"
  1375. "movl $0, (%esi)\n"
  1376. #if EEL_F_SIZE == 8
  1377. "movl $0, 4(%esi)\n"
  1378. #endif
  1379. "addl $" EEL_F_SSTR ", %esi\n"
  1380. "0:"
  1381. #endif
  1382. RESTORE_STACK
  1383. );
  1384. }
  1385. void _asm_megabuf_end(void) {}
  1386. #ifdef TARGET_X64
  1387. void win64_callcode()
  1388. {
  1389. __asm__(
  1390. #ifdef AMD64ABI
  1391. "movll %edi, %eax\n"
  1392. #else
  1393. "movll %ecx, %eax\n"
  1394. #endif
  1395. "push %rbx\n"
  1396. "push %rbp\n"
  1397. #ifndef AMD64ABI
  1398. "push %rdi\n"
  1399. "push %rsi\n"
  1400. "push %r12\n"
  1401. "push %r13\n"
  1402. #endif
  1403. "push %r14\n" // on AMD64ABI, we'll use r14/r15 to save edi/esi
  1404. "push %r15\n"
  1405. "call %eax\n"
  1406. "pop %r15\n"
  1407. "pop %r14\n"
  1408. #ifndef AMD64ABI
  1409. "pop %r13\n"
  1410. "pop %r12\n"
  1411. "pop %rsi\n"
  1412. "pop %rdi\n"
  1413. "fclex\n"
  1414. #endif
  1415. "pop %rbp\n"
  1416. "pop %rbx\n"
  1417. "ret\n"
  1418. );
  1419. }
  1420. #endif