/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
- PUBLIC ffi_call_AMD64
- EXTRN __chkstk:NEAR
- EXTRN ffi_closure_SYSV:NEAR
- _TEXT SEGMENT
- ;;; ffi_closure_OUTER will be called with these registers set:
- ;;; rax points to 'closure'
- ;;; r11 contains a bit mask that specifies which of the
- ;;; first four parameters are float or double
- ;;;
- ;;; It must move the parameters passed in registers to their stack location,
- ;;; call ffi_closure_SYSV for the actual work, then return the result.
- ;;;
- ffi_closure_OUTER PROC FRAME
- ;; save actual arguments to their stack space.
- test r11, 1
- jne first_is_float
- mov QWORD PTR [rsp+8], rcx
- jmp second
- first_is_float:
- movlpd QWORD PTR [rsp+8], xmm0
- second:
- test r11, 2
- jne second_is_float
- mov QWORD PTR [rsp+16], rdx
- jmp third
- second_is_float:
- movlpd QWORD PTR [rsp+16], xmm1
- third:
- test r11, 4
- jne third_is_float
- mov QWORD PTR [rsp+24], r8
- jmp forth
- third_is_float:
- movlpd QWORD PTR [rsp+24], xmm2
- forth:
- test r11, 8
- jne forth_is_float
- mov QWORD PTR [rsp+32], r9
- jmp done
- forth_is_float:
- movlpd QWORD PTR [rsp+32], xmm3
- done:
- .ALLOCSTACK 40
- sub rsp, 40
- .ENDPROLOG
- mov rcx, rax ; context is first parameter
- mov rdx, rsp ; stack is second parameter
- add rdx, 40 ; correct our own area
- mov rax, ffi_closure_SYSV
- call rax ; call the real closure function
- ;; Here, code is missing that handles float return values
- add rsp, 40
- movd xmm0, rax ; In case the closure returned a float.
- ret 0
- ffi_closure_OUTER ENDP
- ;;; ffi_call_AMD64
- stack$ = 0
- prepfunc$ = 32
- ecif$ = 40
- bytes$ = 48
- flags$ = 56
- rvalue$ = 64
- fn$ = 72
- ffi_call_AMD64 PROC FRAME
- mov QWORD PTR [rsp+32], r9
- mov QWORD PTR [rsp+24], r8
- mov QWORD PTR [rsp+16], rdx
- mov QWORD PTR [rsp+8], rcx
- .PUSHREG rbp
- push rbp
- .ALLOCSTACK 48
- sub rsp, 48 ; 00000030H
- .SETFRAME rbp, 32
- lea rbp, QWORD PTR [rsp+32]
- .ENDPROLOG
- mov eax, DWORD PTR bytes$[rbp]
- add rax, 15
- and rax, -16
- call __chkstk
- sub rsp, rax
- lea rax, QWORD PTR [rsp+32]
- mov QWORD PTR stack$[rbp], rax
- mov rdx, QWORD PTR ecif$[rbp]
- mov rcx, QWORD PTR stack$[rbp]
- call QWORD PTR prepfunc$[rbp]
- mov rsp, QWORD PTR stack$[rbp]
- movlpd xmm3, QWORD PTR [rsp+24]
- movd r9, xmm3
- movlpd xmm2, QWORD PTR [rsp+16]
- movd r8, xmm2
- movlpd xmm1, QWORD PTR [rsp+8]
- movd rdx, xmm1
- movlpd xmm0, QWORD PTR [rsp]
- movd rcx, xmm0
- call QWORD PTR fn$[rbp]
- ret_int$:
- cmp DWORD PTR flags$[rbp], 1 ; FFI_TYPE_INT
- jne ret_float$
- mov rcx, QWORD PTR rvalue$[rbp]
- mov DWORD PTR [rcx], eax
- jmp SHORT ret_nothing$
- ret_float$:
- cmp DWORD PTR flags$[rbp], 2 ; FFI_TYPE_FLOAT
- jne SHORT ret_double$
- mov rax, QWORD PTR rvalue$[rbp]
- movlpd QWORD PTR [rax], xmm0
- jmp SHORT ret_nothing$
- ret_double$:
- cmp DWORD PTR flags$[rbp], 3 ; FFI_TYPE_DOUBLE
- jne SHORT ret_int64$
- mov rax, QWORD PTR rvalue$[rbp]
- movlpd QWORD PTR [rax], xmm0
- jmp SHORT ret_nothing$
- ret_int64$:
- cmp DWORD PTR flags$[rbp], 12 ; FFI_TYPE_SINT64
- jne ret_nothing$
- mov rcx, QWORD PTR rvalue$[rbp]
- mov QWORD PTR [rcx], rax
- jmp SHORT ret_nothing$
-
- ret_nothing$:
- xor eax, eax
- lea rsp, QWORD PTR [rbp+16]
- pop rbp
- ret 0
- ffi_call_AMD64 ENDP
- _TEXT ENDS
- END