/js/src/ctypes/libffi/src/x86/sysv.S

http://github.com/zpao/v8monkey · Assembly · 467 lines · 376 code · 45 blank · 46 comment · 8 complexity · e88ad4bddb3635845f6048bf3ba0f9b9 MD5 · raw file

  1. /* -----------------------------------------------------------------------
  2. sysv.S - Copyright (c) 1996, 1998, 2001-2003, 2005, 2008, 2010 Red Hat, Inc.
  3. X86 Foreign Function Interface
  4. Permission is hereby granted, free of charge, to any person obtaining
  5. a copy of this software and associated documentation files (the
  6. ``Software''), to deal in the Software without restriction, including
  7. without limitation the rights to use, copy, modify, merge, publish,
  8. distribute, sublicense, and/or sell copies of the Software, and to
  9. permit persons to whom the Software is furnished to do so, subject to
  10. the following conditions:
  11. The above copyright notice and this permission notice shall be included
  12. in all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
  14. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  17. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  18. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. DEALINGS IN THE SOFTWARE.
  21. ----------------------------------------------------------------------- */
  22. #ifndef __x86_64__
  23. #define LIBFFI_ASM
  24. #include <fficonfig.h>
  25. #include <ffi.h>
  26. .text
  27. .globl ffi_prep_args
  28. .align 4
  29. .globl ffi_call_SYSV
  30. .type ffi_call_SYSV,@function
  31. ffi_call_SYSV:
  32. .LFB1:
  33. pushl %ebp
  34. .LCFI0:
  35. movl %esp,%ebp
  36. .LCFI1:
  37. /* Make room for all of the new args. */
  38. movl 16(%ebp),%ecx
  39. subl %ecx,%esp
  40. /* Align the stack pointer to 16-bytes */
  41. andl $0xfffffff0, %esp
  42. movl %esp,%eax
  43. /* Place all of the ffi_prep_args in position */
  44. pushl 12(%ebp)
  45. pushl %eax
  46. call *8(%ebp)
  47. /* Return stack to previous state and call the function */
  48. addl $8,%esp
  49. call *28(%ebp)
  50. /* Load %ecx with the return type code */
  51. movl 20(%ebp),%ecx
  52. /* Protect %esi. We're going to pop it in the epilogue. */
  53. pushl %esi
  54. /* If the return value pointer is NULL, assume no return value. */
  55. cmpl $0,24(%ebp)
  56. jne 0f
  57. /* Even if there is no space for the return value, we are
  58. obliged to handle floating-point values. */
  59. cmpl $FFI_TYPE_FLOAT,%ecx
  60. jne noretval
  61. fstp %st(0)
  62. jmp epilogue
  63. 0:
  64. call 1f
  65. .Lstore_table:
  66. .long noretval-.Lstore_table /* FFI_TYPE_VOID */
  67. .long retint-.Lstore_table /* FFI_TYPE_INT */
  68. .long retfloat-.Lstore_table /* FFI_TYPE_FLOAT */
  69. .long retdouble-.Lstore_table /* FFI_TYPE_DOUBLE */
  70. .long retlongdouble-.Lstore_table /* FFI_TYPE_LONGDOUBLE */
  71. .long retuint8-.Lstore_table /* FFI_TYPE_UINT8 */
  72. .long retsint8-.Lstore_table /* FFI_TYPE_SINT8 */
  73. .long retuint16-.Lstore_table /* FFI_TYPE_UINT16 */
  74. .long retsint16-.Lstore_table /* FFI_TYPE_SINT16 */
  75. .long retint-.Lstore_table /* FFI_TYPE_UINT32 */
  76. .long retint-.Lstore_table /* FFI_TYPE_SINT32 */
  77. .long retint64-.Lstore_table /* FFI_TYPE_UINT64 */
  78. .long retint64-.Lstore_table /* FFI_TYPE_SINT64 */
  79. .long retstruct-.Lstore_table /* FFI_TYPE_STRUCT */
  80. .long retint-.Lstore_table /* FFI_TYPE_POINTER */
  81. 1:
  82. pop %esi
  83. add (%esi, %ecx, 4), %esi
  84. jmp *%esi
  85. /* Sign/zero extend as appropriate. */
  86. retsint8:
  87. movsbl %al, %eax
  88. jmp retint
  89. retsint16:
  90. movswl %ax, %eax
  91. jmp retint
  92. retuint8:
  93. movzbl %al, %eax
  94. jmp retint
  95. retuint16:
  96. movzwl %ax, %eax
  97. jmp retint
  98. retfloat:
  99. /* Load %ecx with the pointer to storage for the return value */
  100. movl 24(%ebp),%ecx
  101. fstps (%ecx)
  102. jmp epilogue
  103. retdouble:
  104. /* Load %ecx with the pointer to storage for the return value */
  105. movl 24(%ebp),%ecx
  106. fstpl (%ecx)
  107. jmp epilogue
  108. retlongdouble:
  109. /* Load %ecx with the pointer to storage for the return value */
  110. movl 24(%ebp),%ecx
  111. fstpt (%ecx)
  112. jmp epilogue
  113. retint64:
  114. /* Load %ecx with the pointer to storage for the return value */
  115. movl 24(%ebp),%ecx
  116. movl %eax,0(%ecx)
  117. movl %edx,4(%ecx)
  118. jmp epilogue
  119. retint:
  120. /* Load %ecx with the pointer to storage for the return value */
  121. movl 24(%ebp),%ecx
  122. movl %eax,0(%ecx)
  123. retstruct:
  124. /* Nothing to do! */
  125. noretval:
  126. epilogue:
  127. popl %esi
  128. movl %ebp,%esp
  129. popl %ebp
  130. ret
  131. .LFE1:
  132. .ffi_call_SYSV_end:
  133. .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
  134. .align 4
  135. FFI_HIDDEN (ffi_closure_SYSV)
  136. .globl ffi_closure_SYSV
  137. .type ffi_closure_SYSV, @function
  138. ffi_closure_SYSV:
  139. .LFB2:
  140. pushl %ebp
  141. .LCFI2:
  142. movl %esp, %ebp
  143. .LCFI3:
  144. subl $40, %esp
  145. leal -24(%ebp), %edx
  146. movl %edx, -12(%ebp) /* resp */
  147. leal 8(%ebp), %edx
  148. movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */
  149. leal -12(%ebp), %edx
  150. movl %edx, (%esp) /* &resp */
  151. #if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
  152. call ffi_closure_SYSV_inner
  153. #else
  154. movl %ebx, 8(%esp)
  155. .LCFI7:
  156. call 1f
  157. 1: popl %ebx
  158. addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
  159. call ffi_closure_SYSV_inner@PLT
  160. movl 8(%esp), %ebx
  161. #endif
  162. movl -12(%ebp), %ecx
  163. cmpl $FFI_TYPE_INT, %eax
  164. je .Lcls_retint
  165. /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
  166. FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */
  167. cmpl $FFI_TYPE_UINT64, %eax
  168. jge 0f
  169. cmpl $FFI_TYPE_UINT8, %eax
  170. jge .Lcls_retint
  171. 0: cmpl $FFI_TYPE_FLOAT, %eax
  172. je .Lcls_retfloat
  173. cmpl $FFI_TYPE_DOUBLE, %eax
  174. je .Lcls_retdouble
  175. cmpl $FFI_TYPE_LONGDOUBLE, %eax
  176. je .Lcls_retldouble
  177. cmpl $FFI_TYPE_SINT64, %eax
  178. je .Lcls_retllong
  179. cmpl $FFI_TYPE_STRUCT, %eax
  180. je .Lcls_retstruct
  181. .Lcls_epilogue:
  182. movl %ebp, %esp
  183. popl %ebp
  184. ret
  185. .Lcls_retint:
  186. movl (%ecx), %eax
  187. jmp .Lcls_epilogue
  188. .Lcls_retfloat:
  189. flds (%ecx)
  190. jmp .Lcls_epilogue
  191. .Lcls_retdouble:
  192. fldl (%ecx)
  193. jmp .Lcls_epilogue
  194. .Lcls_retldouble:
  195. fldt (%ecx)
  196. jmp .Lcls_epilogue
  197. .Lcls_retllong:
  198. movl (%ecx), %eax
  199. movl 4(%ecx), %edx
  200. jmp .Lcls_epilogue
  201. .Lcls_retstruct:
  202. movl %ebp, %esp
  203. popl %ebp
  204. ret $4
  205. .LFE2:
  206. .size ffi_closure_SYSV, .-ffi_closure_SYSV
  207. #if !FFI_NO_RAW_API
  208. /* Precalculate for e.g. the Solaris 10/x86 assembler. */
  209. #if FFI_TRAMPOLINE_SIZE == 10
  210. #define RAW_CLOSURE_CIF_OFFSET 12
  211. #define RAW_CLOSURE_FUN_OFFSET 16
  212. #define RAW_CLOSURE_USER_DATA_OFFSET 20
  213. #elif FFI_TRAMPOLINE_SIZE == 24
  214. #define RAW_CLOSURE_CIF_OFFSET 24
  215. #define RAW_CLOSURE_FUN_OFFSET 28
  216. #define RAW_CLOSURE_USER_DATA_OFFSET 32
  217. #else
  218. #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
  219. #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
  220. #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
  221. #endif
  222. #define CIF_FLAGS_OFFSET 20
  223. .align 4
  224. FFI_HIDDEN (ffi_closure_raw_SYSV)
  225. .globl ffi_closure_raw_SYSV
  226. .type ffi_closure_raw_SYSV, @function
  227. ffi_closure_raw_SYSV:
  228. .LFB3:
  229. pushl %ebp
  230. .LCFI4:
  231. movl %esp, %ebp
  232. .LCFI5:
  233. pushl %esi
  234. .LCFI6:
  235. subl $36, %esp
  236. movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */
  237. movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
  238. movl %edx, 12(%esp) /* user_data */
  239. leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */
  240. movl %edx, 8(%esp) /* raw_args */
  241. leal -24(%ebp), %edx
  242. movl %edx, 4(%esp) /* &res */
  243. movl %esi, (%esp) /* cif */
  244. call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */
  245. movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */
  246. cmpl $FFI_TYPE_INT, %eax
  247. je .Lrcls_retint
  248. /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
  249. FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */
  250. cmpl $FFI_TYPE_UINT64, %eax
  251. jge 0f
  252. cmpl $FFI_TYPE_UINT8, %eax
  253. jge .Lrcls_retint
  254. 0:
  255. cmpl $FFI_TYPE_FLOAT, %eax
  256. je .Lrcls_retfloat
  257. cmpl $FFI_TYPE_DOUBLE, %eax
  258. je .Lrcls_retdouble
  259. cmpl $FFI_TYPE_LONGDOUBLE, %eax
  260. je .Lrcls_retldouble
  261. cmpl $FFI_TYPE_SINT64, %eax
  262. je .Lrcls_retllong
  263. .Lrcls_epilogue:
  264. addl $36, %esp
  265. popl %esi
  266. popl %ebp
  267. ret
  268. .Lrcls_retint:
  269. movl -24(%ebp), %eax
  270. jmp .Lrcls_epilogue
  271. .Lrcls_retfloat:
  272. flds -24(%ebp)
  273. jmp .Lrcls_epilogue
  274. .Lrcls_retdouble:
  275. fldl -24(%ebp)
  276. jmp .Lrcls_epilogue
  277. .Lrcls_retldouble:
  278. fldt -24(%ebp)
  279. jmp .Lrcls_epilogue
  280. .Lrcls_retllong:
  281. movl -24(%ebp), %eax
  282. movl -20(%ebp), %edx
  283. jmp .Lrcls_epilogue
  284. .LFE3:
  285. .size ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
  286. #endif
  287. .section .eh_frame,EH_FRAME_FLAGS,@progbits
  288. .Lframe1:
  289. .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */
  290. .LSCIE1:
  291. .long 0x0 /* CIE Identifier Tag */
  292. .byte 0x1 /* CIE Version */
  293. #ifdef HAVE_AS_ASCII_PSEUDO_OP
  294. #ifdef __PIC__
  295. .ascii "zR\0" /* CIE Augmentation */
  296. #else
  297. .ascii "\0" /* CIE Augmentation */
  298. #endif
  299. #elif defined HAVE_AS_STRING_PSEUDO_OP
  300. #ifdef __PIC__
  301. .string "zR" /* CIE Augmentation */
  302. #else
  303. .string "" /* CIE Augmentation */
  304. #endif
  305. #else
  306. #error missing .ascii/.string
  307. #endif
  308. .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */
  309. .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */
  310. .byte 0x8 /* CIE RA Column */
  311. #ifdef __PIC__
  312. .byte 0x1 /* .uleb128 0x1; Augmentation size */
  313. .byte 0x1b /* FDE Encoding (pcrel sdata4) */
  314. #endif
  315. .byte 0xc /* DW_CFA_def_cfa */
  316. .byte 0x4 /* .uleb128 0x4 */
  317. .byte 0x4 /* .uleb128 0x4 */
  318. .byte 0x88 /* DW_CFA_offset, column 0x8 */
  319. .byte 0x1 /* .uleb128 0x1 */
  320. .align 4
  321. .LECIE1:
  322. .LSFDE1:
  323. .long .LEFDE1-.LASFDE1 /* FDE Length */
  324. .LASFDE1:
  325. .long .LASFDE1-.Lframe1 /* FDE CIE offset */
  326. #if defined __PIC__ && defined HAVE_AS_X86_PCREL
  327. .long .LFB1-. /* FDE initial location */
  328. #elif defined __PIC__
  329. .long .LFB1@rel
  330. #else
  331. .long .LFB1
  332. #endif
  333. .long .LFE1-.LFB1 /* FDE address range */
  334. #ifdef __PIC__
  335. .byte 0x0 /* .uleb128 0x0; Augmentation size */
  336. #endif
  337. .byte 0x4 /* DW_CFA_advance_loc4 */
  338. .long .LCFI0-.LFB1
  339. .byte 0xe /* DW_CFA_def_cfa_offset */
  340. .byte 0x8 /* .uleb128 0x8 */
  341. .byte 0x85 /* DW_CFA_offset, column 0x5 */
  342. .byte 0x2 /* .uleb128 0x2 */
  343. .byte 0x4 /* DW_CFA_advance_loc4 */
  344. .long .LCFI1-.LCFI0
  345. .byte 0xd /* DW_CFA_def_cfa_register */
  346. .byte 0x5 /* .uleb128 0x5 */
  347. .align 4
  348. .LEFDE1:
  349. .LSFDE2:
  350. .long .LEFDE2-.LASFDE2 /* FDE Length */
  351. .LASFDE2:
  352. .long .LASFDE2-.Lframe1 /* FDE CIE offset */
  353. #if defined __PIC__ && defined HAVE_AS_X86_PCREL
  354. .long .LFB2-. /* FDE initial location */
  355. #elif defined __PIC__
  356. .long .LFB2@rel
  357. #else
  358. .long .LFB2
  359. #endif
  360. .long .LFE2-.LFB2 /* FDE address range */
  361. #ifdef __PIC__
  362. .byte 0x0 /* .uleb128 0x0; Augmentation size */
  363. #endif
  364. .byte 0x4 /* DW_CFA_advance_loc4 */
  365. .long .LCFI2-.LFB2
  366. .byte 0xe /* DW_CFA_def_cfa_offset */
  367. .byte 0x8 /* .uleb128 0x8 */
  368. .byte 0x85 /* DW_CFA_offset, column 0x5 */
  369. .byte 0x2 /* .uleb128 0x2 */
  370. .byte 0x4 /* DW_CFA_advance_loc4 */
  371. .long .LCFI3-.LCFI2
  372. .byte 0xd /* DW_CFA_def_cfa_register */
  373. .byte 0x5 /* .uleb128 0x5 */
  374. #if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
  375. .byte 0x4 /* DW_CFA_advance_loc4 */
  376. .long .LCFI7-.LCFI3
  377. .byte 0x83 /* DW_CFA_offset, column 0x3 */
  378. .byte 0xa /* .uleb128 0xa */
  379. #endif
  380. .align 4
  381. .LEFDE2:
  382. #if !FFI_NO_RAW_API
  383. .LSFDE3:
  384. .long .LEFDE3-.LASFDE3 /* FDE Length */
  385. .LASFDE3:
  386. .long .LASFDE3-.Lframe1 /* FDE CIE offset */
  387. #if defined __PIC__ && defined HAVE_AS_X86_PCREL
  388. .long .LFB3-. /* FDE initial location */
  389. #elif defined __PIC__
  390. .long .LFB3@rel
  391. #else
  392. .long .LFB3
  393. #endif
  394. .long .LFE3-.LFB3 /* FDE address range */
  395. #ifdef __PIC__
  396. .byte 0x0 /* .uleb128 0x0; Augmentation size */
  397. #endif
  398. .byte 0x4 /* DW_CFA_advance_loc4 */
  399. .long .LCFI4-.LFB3
  400. .byte 0xe /* DW_CFA_def_cfa_offset */
  401. .byte 0x8 /* .uleb128 0x8 */
  402. .byte 0x85 /* DW_CFA_offset, column 0x5 */
  403. .byte 0x2 /* .uleb128 0x2 */
  404. .byte 0x4 /* DW_CFA_advance_loc4 */
  405. .long .LCFI5-.LCFI4
  406. .byte 0xd /* DW_CFA_def_cfa_register */
  407. .byte 0x5 /* .uleb128 0x5 */
  408. .byte 0x4 /* DW_CFA_advance_loc4 */
  409. .long .LCFI6-.LCFI5
  410. .byte 0x86 /* DW_CFA_offset, column 0x6 */
  411. .byte 0x3 /* .uleb128 0x3 */
  412. .align 4
  413. .LEFDE3:
  414. #endif
  415. #endif /* ifndef __x86_64__ */
  416. #if defined __ELF__ && defined __linux__
  417. .section .note.GNU-stack,"",@progbits
  418. #endif