blob: 301188bc9c17f5142ada552eed6f676a5c0d3079 [file] [log] [blame]
Thomas Wouters89f507f2006-12-13 04:49:30 +00001PUBLIC 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