/Modules/_ctypes/libffi/src/x86/freebsd.S

http://unladen-swallow.googlecode.com/ · Assembly · 458 lines · 366 code · 45 blank · 47 comment · 2 complexity · c125f62411b796c8f45d5dce944ea54b MD5 · raw file

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