/Modules/_ctypes/libffi_msvc/win32.S

http://unladen-swallow.googlecode.com/ · Assembly · 243 lines · 167 code · 49 blank · 27 comment · 17 complexity · f932527ade12cc7c74b5037af590eebd MD5 · raw file

  1. /* -----------------------------------------------------------------------
  2. win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc.
  3. Copyright (c) 2001 John Beniton
  4. Copyright (c) 2002 Ranjit Mathew
  5. X86 Foreign Function Interface
  6. Permission is hereby granted, free of charge, to any person obtaining
  7. a copy of this software and associated documentation files (the
  8. ``Software''), to deal in the Software without restriction, including
  9. without limitation the rights to use, copy, modify, merge, publish,
  10. distribute, sublicense, and/or sell copies of the Software, and to
  11. permit persons to whom the Software is furnished to do so, subject to
  12. the following conditions:
  13. The above copyright notice and this permission notice shall be included
  14. in all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19. OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21. OTHER DEALINGS IN THE SOFTWARE.
  22. ----------------------------------------------------------------------- */
  23. #define LIBFFI_ASM
  24. #include <fficonfig.h>
  25. #include <ffi.h>
  26. .text
  27. .globl ffi_prep_args
  28. # This assumes we are using gas.
  29. .balign 16
  30. .globl _ffi_call_SYSV
  31. _ffi_call_SYSV:
  32. pushl %ebp
  33. movl %esp,%ebp
  34. #THe: save previous %esi, and store the current stack pointer in %esi
  35. pushl %esi
  36. movl %esp,%esi
  37. # Make room for all of the new args.
  38. movl 16(%ebp),%ecx
  39. subl %ecx,%esp
  40. movl %esp,%eax
  41. # Place all of the ffi_prep_args in position
  42. pushl 12(%ebp)
  43. pushl %eax
  44. call *8(%ebp)
  45. # Return stack to previous state and call the function
  46. addl $8,%esp
  47. # FIXME: Align the stack to a 128-bit boundary to avoid
  48. # potential performance hits.
  49. call *28(%ebp)
  50. # Remove the space we pushed for the args
  51. movl 16(%ebp),%ecx
  52. addl %ecx,%esp
  53. sub %esp,%esi # calculate stack pointer difference
  54. # Load %ecx with the return type code
  55. movl 20(%ebp),%ecx
  56. # If the return value pointer is NULL, assume no return value.
  57. cmpl $0,24(%ebp)
  58. jne retint
  59. # Even if there is no space for the return value, we are
  60. # obliged to handle floating-point values.
  61. cmpl $FFI_TYPE_FLOAT,%ecx
  62. jne noretval
  63. fstp %st(0)
  64. jmp epilogue
  65. retint:
  66. cmpl $FFI_TYPE_INT,%ecx
  67. jne retfloat
  68. # Load %ecx with the pointer to storage for the return value
  69. movl 24(%ebp),%ecx
  70. movl %eax,0(%ecx)
  71. jmp epilogue
  72. retfloat:
  73. cmpl $FFI_TYPE_FLOAT,%ecx
  74. jne retdouble
  75. # Load %ecx with the pointer to storage for the return value
  76. movl 24(%ebp),%ecx
  77. fstps (%ecx)
  78. jmp epilogue
  79. retdouble:
  80. cmpl $FFI_TYPE_DOUBLE,%ecx
  81. jne retlongdouble
  82. # Load %ecx with the pointer to storage for the return value
  83. movl 24(%ebp),%ecx
  84. fstpl (%ecx)
  85. jmp epilogue
  86. retlongdouble:
  87. cmpl $FFI_TYPE_LONGDOUBLE,%ecx
  88. jne retint64
  89. # Load %ecx with the pointer to storage for the return value
  90. movl 24(%ebp),%ecx
  91. fstpt (%ecx)
  92. jmp epilogue
  93. retint64:
  94. cmpl $FFI_TYPE_SINT64,%ecx
  95. jne retstruct
  96. # Load %ecx with the pointer to storage for the return value
  97. movl 24(%ebp),%ecx
  98. movl %eax,0(%ecx)
  99. movl %edx,4(%ecx)
  100. retstruct:
  101. # Nothing to do!
  102. noretval:
  103. epilogue:
  104. movl %esi,%eax # return the stack pointer detlta in %eax
  105. popl %esi # restore previous %esi
  106. movl %ebp,%esp
  107. popl %ebp
  108. ret
  109. .ffi_call_SYSV_end:
  110. # This assumes we are using gas.
  111. .balign 16
  112. .globl _ffi_call_STDCALL
  113. _ffi_call_STDCALL:
  114. pushl %ebp
  115. movl %esp,%ebp
  116. #THe: save previous %esi, and store the current stack pointer in %esi
  117. pushl %esi
  118. movl %esp,%esi
  119. # Make room for all of the new args.
  120. movl 16(%ebp),%ecx
  121. subl %ecx,%esp
  122. movl %esp,%eax
  123. # Place all of the ffi_prep_args in position
  124. pushl 12(%ebp)
  125. pushl %eax
  126. call *8(%ebp)
  127. # Return stack to previous state and call the function
  128. addl $8,%esp
  129. # FIXME: Align the stack to a 128-bit boundary to avoid
  130. # potential performance hits.
  131. call *28(%ebp)
  132. sub %esp,%esi # difference in stack
  133. # stdcall functions pop arguments off the stack themselves
  134. # Load %ecx with the return type code
  135. movl 20(%ebp),%ecx
  136. # If the return value pointer is NULL, assume no return value.
  137. cmpl $0,24(%ebp)
  138. jne sc_retint
  139. # Even if there is no space for the return value, we are
  140. # obliged to handle floating-point values.
  141. cmpl $FFI_TYPE_FLOAT,%ecx
  142. jne sc_noretval
  143. fstp %st(0)
  144. jmp sc_epilogue
  145. sc_retint:
  146. cmpl $FFI_TYPE_INT,%ecx
  147. jne sc_retfloat
  148. # Load %ecx with the pointer to storage for the return value
  149. movl 24(%ebp),%ecx
  150. movl %eax,0(%ecx)
  151. jmp sc_epilogue
  152. sc_retfloat:
  153. cmpl $FFI_TYPE_FLOAT,%ecx
  154. jne sc_retdouble
  155. # Load %ecx with the pointer to storage for the return value
  156. movl 24(%ebp),%ecx
  157. fstps (%ecx)
  158. jmp sc_epilogue
  159. sc_retdouble:
  160. cmpl $FFI_TYPE_DOUBLE,%ecx
  161. jne sc_retlongdouble
  162. # Load %ecx with the pointer to storage for the return value
  163. movl 24(%ebp),%ecx
  164. fstpl (%ecx)
  165. jmp sc_epilogue
  166. sc_retlongdouble:
  167. cmpl $FFI_TYPE_LONGDOUBLE,%ecx
  168. jne sc_retint64
  169. # Load %ecx with the pointer to storage for the return value
  170. movl 24(%ebp),%ecx
  171. fstpt (%ecx)
  172. jmp sc_epilogue
  173. sc_retint64:
  174. cmpl $FFI_TYPE_SINT64,%ecx
  175. jne sc_retstruct
  176. # Load %ecx with the pointer to storage for the return value
  177. movl 24(%ebp),%ecx
  178. movl %eax,0(%ecx)
  179. movl %edx,4(%ecx)
  180. sc_retstruct:
  181. # Nothing to do!
  182. sc_noretval:
  183. sc_epilogue:
  184. movl %esi,%eax # return the stack difference
  185. popl %esi # restore previous %esi value
  186. movl %ebp,%esp
  187. popl %ebp
  188. ret
  189. .ffi_call_STDCALL_end: