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