/Modules/_ctypes/libffi_msvc/win64.asm

http://unladen-swallow.googlecode.com/ · Assembly · 156 lines · 116 code · 29 blank · 11 comment · 0 complexity · 57eaa08e78da6afd4601f2dd29b8ac6f MD5 · raw file

  1. PUBLIC ffi_call_AMD64
  2. EXTRN __chkstk:NEAR
  3. EXTRN ffi_closure_SYSV:NEAR
  4. _TEXT SEGMENT
  5. ;;; ffi_closure_OUTER will be called with these registers set:
  6. ;;; rax points to 'closure'
  7. ;;; r11 contains a bit mask that specifies which of the
  8. ;;; first four parameters are float or double
  9. ;;;
  10. ;;; It must move the parameters passed in registers to their stack location,
  11. ;;; call ffi_closure_SYSV for the actual work, then return the result.
  12. ;;;
  13. ffi_closure_OUTER PROC FRAME
  14. ;; save actual arguments to their stack space.
  15. test r11, 1
  16. jne first_is_float
  17. mov QWORD PTR [rsp+8], rcx
  18. jmp second
  19. first_is_float:
  20. movlpd QWORD PTR [rsp+8], xmm0
  21. second:
  22. test r11, 2
  23. jne second_is_float
  24. mov QWORD PTR [rsp+16], rdx
  25. jmp third
  26. second_is_float:
  27. movlpd QWORD PTR [rsp+16], xmm1
  28. third:
  29. test r11, 4
  30. jne third_is_float
  31. mov QWORD PTR [rsp+24], r8
  32. jmp forth
  33. third_is_float:
  34. movlpd QWORD PTR [rsp+24], xmm2
  35. forth:
  36. test r11, 8
  37. jne forth_is_float
  38. mov QWORD PTR [rsp+32], r9
  39. jmp done
  40. forth_is_float:
  41. movlpd QWORD PTR [rsp+32], xmm3
  42. done:
  43. .ALLOCSTACK 40
  44. sub rsp, 40
  45. .ENDPROLOG
  46. mov rcx, rax ; context is first parameter
  47. mov rdx, rsp ; stack is second parameter
  48. add rdx, 40 ; correct our own area
  49. mov rax, ffi_closure_SYSV
  50. call rax ; call the real closure function
  51. ;; Here, code is missing that handles float return values
  52. add rsp, 40
  53. movd xmm0, rax ; In case the closure returned a float.
  54. ret 0
  55. ffi_closure_OUTER ENDP
  56. ;;; ffi_call_AMD64
  57. stack$ = 0
  58. prepfunc$ = 32
  59. ecif$ = 40
  60. bytes$ = 48
  61. flags$ = 56
  62. rvalue$ = 64
  63. fn$ = 72
  64. ffi_call_AMD64 PROC FRAME
  65. mov QWORD PTR [rsp+32], r9
  66. mov QWORD PTR [rsp+24], r8
  67. mov QWORD PTR [rsp+16], rdx
  68. mov QWORD PTR [rsp+8], rcx
  69. .PUSHREG rbp
  70. push rbp
  71. .ALLOCSTACK 48
  72. sub rsp, 48 ; 00000030H
  73. .SETFRAME rbp, 32
  74. lea rbp, QWORD PTR [rsp+32]
  75. .ENDPROLOG
  76. mov eax, DWORD PTR bytes$[rbp]
  77. add rax, 15
  78. and rax, -16
  79. call __chkstk
  80. sub rsp, rax
  81. lea rax, QWORD PTR [rsp+32]
  82. mov QWORD PTR stack$[rbp], rax
  83. mov rdx, QWORD PTR ecif$[rbp]
  84. mov rcx, QWORD PTR stack$[rbp]
  85. call QWORD PTR prepfunc$[rbp]
  86. mov rsp, QWORD PTR stack$[rbp]
  87. movlpd xmm3, QWORD PTR [rsp+24]
  88. movd r9, xmm3
  89. movlpd xmm2, QWORD PTR [rsp+16]
  90. movd r8, xmm2
  91. movlpd xmm1, QWORD PTR [rsp+8]
  92. movd rdx, xmm1
  93. movlpd xmm0, QWORD PTR [rsp]
  94. movd rcx, xmm0
  95. call QWORD PTR fn$[rbp]
  96. ret_int$:
  97. cmp DWORD PTR flags$[rbp], 1 ; FFI_TYPE_INT
  98. jne ret_float$
  99. mov rcx, QWORD PTR rvalue$[rbp]
  100. mov DWORD PTR [rcx], eax
  101. jmp SHORT ret_nothing$
  102. ret_float$:
  103. cmp DWORD PTR flags$[rbp], 2 ; FFI_TYPE_FLOAT
  104. jne SHORT ret_double$
  105. mov rax, QWORD PTR rvalue$[rbp]
  106. movlpd QWORD PTR [rax], xmm0
  107. jmp SHORT ret_nothing$
  108. ret_double$:
  109. cmp DWORD PTR flags$[rbp], 3 ; FFI_TYPE_DOUBLE
  110. jne SHORT ret_int64$
  111. mov rax, QWORD PTR rvalue$[rbp]
  112. movlpd QWORD PTR [rax], xmm0
  113. jmp SHORT ret_nothing$
  114. ret_int64$:
  115. cmp DWORD PTR flags$[rbp], 12 ; FFI_TYPE_SINT64
  116. jne ret_nothing$
  117. mov rcx, QWORD PTR rvalue$[rbp]
  118. mov QWORD PTR [rcx], rax
  119. jmp SHORT ret_nothing$
  120. ret_nothing$:
  121. xor eax, eax
  122. lea rsp, QWORD PTR [rbp+16]
  123. pop rbp
  124. ret 0
  125. ffi_call_AMD64 ENDP
  126. _TEXT ENDS
  127. END