xref: /aosp_15_r20/external/libffi/src/x86/sysv_intel.S (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
1*1fd5a2e1SPrashanth Swaminathan/* -----------------------------------------------------------------------
2*1fd5a2e1SPrashanth Swaminathan   sysv.S - Copyright (c) 2017  Anthony Green
3*1fd5a2e1SPrashanth Swaminathan          - Copyright (c) 2013  The Written Word, Inc.
4*1fd5a2e1SPrashanth Swaminathan          - Copyright (c) 1996,1998,2001-2003,2005,2008,2010  Red Hat, Inc.
5*1fd5a2e1SPrashanth Swaminathan
6*1fd5a2e1SPrashanth Swaminathan   X86 Foreign Function Interface
7*1fd5a2e1SPrashanth Swaminathan
8*1fd5a2e1SPrashanth Swaminathan   Permission is hereby granted, free of charge, to any person obtaining
9*1fd5a2e1SPrashanth Swaminathan   a copy of this software and associated documentation files (the
10*1fd5a2e1SPrashanth Swaminathan   ``Software''), to deal in the Software without restriction, including
11*1fd5a2e1SPrashanth Swaminathan   without limitation the rights to use, copy, modify, merge, publish,
12*1fd5a2e1SPrashanth Swaminathan   distribute, sublicense, and/or sell copies of the Software, and to
13*1fd5a2e1SPrashanth Swaminathan   permit persons to whom the Software is furnished to do so, subject to
14*1fd5a2e1SPrashanth Swaminathan   the following conditions:
15*1fd5a2e1SPrashanth Swaminathan
16*1fd5a2e1SPrashanth Swaminathan   The above copyright notice and this permission notice shall be included
17*1fd5a2e1SPrashanth Swaminathan   in all copies or substantial portions of the Software.
18*1fd5a2e1SPrashanth Swaminathan
19*1fd5a2e1SPrashanth Swaminathan   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20*1fd5a2e1SPrashanth Swaminathan   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21*1fd5a2e1SPrashanth Swaminathan   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22*1fd5a2e1SPrashanth Swaminathan   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23*1fd5a2e1SPrashanth Swaminathan   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24*1fd5a2e1SPrashanth Swaminathan   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25*1fd5a2e1SPrashanth Swaminathan   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26*1fd5a2e1SPrashanth Swaminathan   DEALINGS IN THE SOFTWARE.
27*1fd5a2e1SPrashanth Swaminathan   ----------------------------------------------------------------------- */
28*1fd5a2e1SPrashanth Swaminathan
29*1fd5a2e1SPrashanth Swaminathan#ifndef __x86_64__
30*1fd5a2e1SPrashanth Swaminathan#ifdef _MSC_VER
31*1fd5a2e1SPrashanth Swaminathan
32*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM
33*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h>
34*1fd5a2e1SPrashanth Swaminathan#include <ffi.h>
35*1fd5a2e1SPrashanth Swaminathan#include <ffi_cfi.h>
36*1fd5a2e1SPrashanth Swaminathan#include "internal.h"
37*1fd5a2e1SPrashanth Swaminathan
38*1fd5a2e1SPrashanth Swaminathan#define C2(X, Y)  X ## Y
39*1fd5a2e1SPrashanth Swaminathan#define C1(X, Y)  C2(X, Y)
40*1fd5a2e1SPrashanth Swaminathan#define L(X)     C1(L, X)
41*1fd5a2e1SPrashanth Swaminathan# define ENDF(X) X ENDP
42*1fd5a2e1SPrashanth Swaminathan
43*1fd5a2e1SPrashanth Swaminathan/* This macro allows the safe creation of jump tables without an
44*1fd5a2e1SPrashanth Swaminathan   actual table.  The entry points into the table are all 8 bytes.
45*1fd5a2e1SPrashanth Swaminathan   The use of ORG asserts that we're at the correct location.  */
46*1fd5a2e1SPrashanth Swaminathan/* ??? The clang assembler doesn't handle .org with symbolic expressions.  */
47*1fd5a2e1SPrashanth Swaminathan#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
48*1fd5a2e1SPrashanth Swaminathan# define E(BASE, X)	ALIGN 8
49*1fd5a2e1SPrashanth Swaminathan#else
50*1fd5a2e1SPrashanth Swaminathan# define E(BASE, X)	ALIGN 8; ORG BASE + X * 8
51*1fd5a2e1SPrashanth Swaminathan#endif
52*1fd5a2e1SPrashanth Swaminathan
53*1fd5a2e1SPrashanth Swaminathan    .686P
54*1fd5a2e1SPrashanth Swaminathan    .MODEL FLAT
55*1fd5a2e1SPrashanth Swaminathan
56*1fd5a2e1SPrashanth SwaminathanEXTRN	@ffi_closure_inner@8:PROC
57*1fd5a2e1SPrashanth Swaminathan_TEXT SEGMENT
58*1fd5a2e1SPrashanth Swaminathan
59*1fd5a2e1SPrashanth Swaminathan/* This is declared as
60*1fd5a2e1SPrashanth Swaminathan
61*1fd5a2e1SPrashanth Swaminathan   void ffi_call_i386(struct call_frame *frame, char *argp)
62*1fd5a2e1SPrashanth Swaminathan        __attribute__((fastcall));
63*1fd5a2e1SPrashanth Swaminathan
64*1fd5a2e1SPrashanth Swaminathan   Thus the arguments are present in
65*1fd5a2e1SPrashanth Swaminathan
66*1fd5a2e1SPrashanth Swaminathan        ecx: frame
67*1fd5a2e1SPrashanth Swaminathan        edx: argp
68*1fd5a2e1SPrashanth Swaminathan*/
69*1fd5a2e1SPrashanth Swaminathan
70*1fd5a2e1SPrashanth SwaminathanALIGN 16
71*1fd5a2e1SPrashanth SwaminathanPUBLIC @ffi_call_i386@8
72*1fd5a2e1SPrashanth Swaminathan@ffi_call_i386@8 PROC
73*1fd5a2e1SPrashanth SwaminathanL(UW0):
74*1fd5a2e1SPrashanth Swaminathan	cfi_startproc
75*1fd5a2e1SPrashanth Swaminathan #if !HAVE_FASTCALL
76*1fd5a2e1SPrashanth Swaminathan	mov	    ecx, [esp+4]
77*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [esp+8]
78*1fd5a2e1SPrashanth Swaminathan #endif
79*1fd5a2e1SPrashanth Swaminathan	mov	    eax, [esp]		/* move the return address */
80*1fd5a2e1SPrashanth Swaminathan	mov	    [ecx], ebp		/* store ebp into local frame */
81*1fd5a2e1SPrashanth Swaminathan	mov 	[ecx+4], eax	/* store retaddr into local frame */
82*1fd5a2e1SPrashanth Swaminathan
83*1fd5a2e1SPrashanth Swaminathan	/* New stack frame based off ebp.  This is a itty bit of unwind
84*1fd5a2e1SPrashanth Swaminathan	   trickery in that the CFA *has* changed.  There is no easy way
85*1fd5a2e1SPrashanth Swaminathan	   to describe it correctly on entry to the function.  Fortunately,
86*1fd5a2e1SPrashanth Swaminathan	   it doesn't matter too much since at all points we can correctly
87*1fd5a2e1SPrashanth Swaminathan	   unwind back to ffi_call.  Note that the location to which we
88*1fd5a2e1SPrashanth Swaminathan	   moved the return address is (the new) CFA-4, so from the
89*1fd5a2e1SPrashanth Swaminathan	   perspective of the unwind info, it hasn't moved.  */
90*1fd5a2e1SPrashanth Swaminathan	mov 	ebp, ecx
91*1fd5a2e1SPrashanth SwaminathanL(UW1):
92*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa(%ebp, 8)
93*1fd5a2e1SPrashanth Swaminathan	// cfi_rel_offset(%ebp, 0)
94*1fd5a2e1SPrashanth Swaminathan
95*1fd5a2e1SPrashanth Swaminathan	mov 	esp, edx		/* set outgoing argument stack */
96*1fd5a2e1SPrashanth Swaminathan	mov 	eax, [20+R_EAX*4+ebp]	/* set register arguments */
97*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [20+R_EDX*4+ebp]
98*1fd5a2e1SPrashanth Swaminathan	mov	    ecx, [20+R_ECX*4+ebp]
99*1fd5a2e1SPrashanth Swaminathan
100*1fd5a2e1SPrashanth Swaminathan	call	dword ptr [ebp+8]
101*1fd5a2e1SPrashanth Swaminathan
102*1fd5a2e1SPrashanth Swaminathan	mov	    ecx, [12+ebp]		/* load return type code */
103*1fd5a2e1SPrashanth Swaminathan	mov 	[ebp+8], ebx		/* preserve %ebx */
104*1fd5a2e1SPrashanth SwaminathanL(UW2):
105*1fd5a2e1SPrashanth Swaminathan	// cfi_rel_offset(%ebx, 8)
106*1fd5a2e1SPrashanth Swaminathan
107*1fd5a2e1SPrashanth Swaminathan	and 	ecx, X86_RET_TYPE_MASK
108*1fd5a2e1SPrashanth Swaminathan	lea 	ebx, [L(store_table) + ecx * 8]
109*1fd5a2e1SPrashanth Swaminathan	mov 	ecx, [ebp+16]		/* load result address */
110*1fd5a2e1SPrashanth Swaminathan	jmp	    ebx
111*1fd5a2e1SPrashanth Swaminathan
112*1fd5a2e1SPrashanth Swaminathan	ALIGN	8
113*1fd5a2e1SPrashanth SwaminathanL(store_table):
114*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_FLOAT)
115*1fd5a2e1SPrashanth Swaminathan	fstp	DWORD PTR [ecx]
116*1fd5a2e1SPrashanth Swaminathan	jmp	L(e1)
117*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_DOUBLE)
118*1fd5a2e1SPrashanth Swaminathan	fstp	QWORD PTR [ecx]
119*1fd5a2e1SPrashanth Swaminathan	jmp	L(e1)
120*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_LDOUBLE)
121*1fd5a2e1SPrashanth Swaminathan	fstp	QWORD PTR [ecx]
122*1fd5a2e1SPrashanth Swaminathan	jmp	L(e1)
123*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_SINT8)
124*1fd5a2e1SPrashanth Swaminathan	movsx	eax, al
125*1fd5a2e1SPrashanth Swaminathan	mov	[ecx], eax
126*1fd5a2e1SPrashanth Swaminathan	jmp	L(e1)
127*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_SINT16)
128*1fd5a2e1SPrashanth Swaminathan	movsx	eax, ax
129*1fd5a2e1SPrashanth Swaminathan	mov	[ecx], eax
130*1fd5a2e1SPrashanth Swaminathan	jmp	L(e1)
131*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_UINT8)
132*1fd5a2e1SPrashanth Swaminathan	movzx	eax, al
133*1fd5a2e1SPrashanth Swaminathan	mov	[ecx], eax
134*1fd5a2e1SPrashanth Swaminathan	jmp	L(e1)
135*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_UINT16)
136*1fd5a2e1SPrashanth Swaminathan	movzx	eax, ax
137*1fd5a2e1SPrashanth Swaminathan	mov	[ecx], eax
138*1fd5a2e1SPrashanth Swaminathan	jmp	L(e1)
139*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_INT64)
140*1fd5a2e1SPrashanth Swaminathan	mov	[ecx+4], edx
141*1fd5a2e1SPrashanth Swaminathan	/* fallthru */
142*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_int 32)
143*1fd5a2e1SPrashanth Swaminathan	mov	[ecx], eax
144*1fd5a2e1SPrashanth Swaminathan	/* fallthru */
145*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_VOID)
146*1fd5a2e1SPrashanth SwaminathanL(e1):
147*1fd5a2e1SPrashanth Swaminathan	mov	    ebx, [ebp+8]
148*1fd5a2e1SPrashanth Swaminathan	mov	    esp, ebp
149*1fd5a2e1SPrashanth Swaminathan	pop 	ebp
150*1fd5a2e1SPrashanth SwaminathanL(UW3):
151*1fd5a2e1SPrashanth Swaminathan	// cfi_remember_state
152*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa(%esp, 4)
153*1fd5a2e1SPrashanth Swaminathan	// cfi_restore(%ebx)
154*1fd5a2e1SPrashanth Swaminathan	// cfi_restore(%ebp)
155*1fd5a2e1SPrashanth Swaminathan	ret
156*1fd5a2e1SPrashanth SwaminathanL(UW4):
157*1fd5a2e1SPrashanth Swaminathan	// cfi_restore_state
158*1fd5a2e1SPrashanth Swaminathan
159*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_STRUCTPOP)
160*1fd5a2e1SPrashanth Swaminathan	jmp	    L(e1)
161*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_STRUCTARG)
162*1fd5a2e1SPrashanth Swaminathan	jmp	    L(e1)
163*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_STRUCT_1B)
164*1fd5a2e1SPrashanth Swaminathan	mov 	[ecx], al
165*1fd5a2e1SPrashanth Swaminathan	jmp	    L(e1)
166*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_STRUCT_2B)
167*1fd5a2e1SPrashanth Swaminathan	mov 	[ecx], ax
168*1fd5a2e1SPrashanth Swaminathan	jmp	    L(e1)
169*1fd5a2e1SPrashanth Swaminathan
170*1fd5a2e1SPrashanth Swaminathan	/* Fill out the table so that bad values are predictable.  */
171*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_UNUSED14)
172*1fd5a2e1SPrashanth Swaminathan	int 3
173*1fd5a2e1SPrashanth SwaminathanE(L(store_table), X86_RET_UNUSED15)
174*1fd5a2e1SPrashanth Swaminathan	int 3
175*1fd5a2e1SPrashanth Swaminathan
176*1fd5a2e1SPrashanth SwaminathanL(UW5):
177*1fd5a2e1SPrashanth Swaminathan	// cfi_endproc
178*1fd5a2e1SPrashanth SwaminathanENDF(@ffi_call_i386@8)
179*1fd5a2e1SPrashanth Swaminathan
180*1fd5a2e1SPrashanth Swaminathan/* The inner helper is declared as
181*1fd5a2e1SPrashanth Swaminathan
182*1fd5a2e1SPrashanth Swaminathan   void ffi_closure_inner(struct closure_frame *frame, char *argp)
183*1fd5a2e1SPrashanth Swaminathan	__attribute_((fastcall))
184*1fd5a2e1SPrashanth Swaminathan
185*1fd5a2e1SPrashanth Swaminathan   Thus the arguments are placed in
186*1fd5a2e1SPrashanth Swaminathan
187*1fd5a2e1SPrashanth Swaminathan	ecx:	frame
188*1fd5a2e1SPrashanth Swaminathan	edx:	argp
189*1fd5a2e1SPrashanth Swaminathan*/
190*1fd5a2e1SPrashanth Swaminathan
191*1fd5a2e1SPrashanth Swaminathan/* Macros to help setting up the closure_data structure.  */
192*1fd5a2e1SPrashanth Swaminathan
193*1fd5a2e1SPrashanth Swaminathan#if HAVE_FASTCALL
194*1fd5a2e1SPrashanth Swaminathan# define closure_FS	(40 + 4)
195*1fd5a2e1SPrashanth Swaminathan# define closure_CF	0
196*1fd5a2e1SPrashanth Swaminathan#else
197*1fd5a2e1SPrashanth Swaminathan# define closure_FS	(8 + 40 + 12)
198*1fd5a2e1SPrashanth Swaminathan# define closure_CF	8
199*1fd5a2e1SPrashanth Swaminathan#endif
200*1fd5a2e1SPrashanth Swaminathan
201*1fd5a2e1SPrashanth SwaminathanFFI_CLOSURE_SAVE_REGS MACRO
202*1fd5a2e1SPrashanth Swaminathan	mov 	[esp + closure_CF+16+R_EAX*4], eax
203*1fd5a2e1SPrashanth Swaminathan	mov 	[esp + closure_CF+16+R_EDX*4], edx
204*1fd5a2e1SPrashanth Swaminathan	mov 	[esp + closure_CF+16+R_ECX*4], ecx
205*1fd5a2e1SPrashanth SwaminathanENDM
206*1fd5a2e1SPrashanth Swaminathan
207*1fd5a2e1SPrashanth SwaminathanFFI_CLOSURE_COPY_TRAMP_DATA MACRO
208*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [eax+FFI_TRAMPOLINE_SIZE]      /* copy cif */
209*1fd5a2e1SPrashanth Swaminathan	mov 	ecx, [eax+FFI_TRAMPOLINE_SIZE+4]    /* copy fun */
210*1fd5a2e1SPrashanth Swaminathan	mov 	eax, [eax+FFI_TRAMPOLINE_SIZE+8];   /* copy user_data */
211*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+28], edx
212*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+32], ecx
213*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+36], eax
214*1fd5a2e1SPrashanth SwaminathanENDM
215*1fd5a2e1SPrashanth Swaminathan
216*1fd5a2e1SPrashanth Swaminathan#if HAVE_FASTCALL
217*1fd5a2e1SPrashanth SwaminathanFFI_CLOSURE_PREP_CALL MACRO
218*1fd5a2e1SPrashanth Swaminathan	mov	    ecx, esp                    /* load closure_data */
219*1fd5a2e1SPrashanth Swaminathan	lea 	edx, [esp+closure_FS+4]     /* load incoming stack */
220*1fd5a2e1SPrashanth SwaminathanENDM
221*1fd5a2e1SPrashanth Swaminathan#else
222*1fd5a2e1SPrashanth SwaminathanFFI_CLOSURE_PREP_CALL MACRO
223*1fd5a2e1SPrashanth Swaminathan	lea 	ecx, [esp+closure_CF]       /* load closure_data */
224*1fd5a2e1SPrashanth Swaminathan	lea 	edx, [esp+closure_FS+4]     /* load incoming stack */
225*1fd5a2e1SPrashanth Swaminathan	mov 	[esp], ecx
226*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+4], edx
227*1fd5a2e1SPrashanth SwaminathanENDM
228*1fd5a2e1SPrashanth Swaminathan#endif
229*1fd5a2e1SPrashanth Swaminathan
230*1fd5a2e1SPrashanth SwaminathanFFI_CLOSURE_CALL_INNER MACRO UWN
231*1fd5a2e1SPrashanth Swaminathan	call	@ffi_closure_inner@8
232*1fd5a2e1SPrashanth SwaminathanENDM
233*1fd5a2e1SPrashanth Swaminathan
234*1fd5a2e1SPrashanth SwaminathanFFI_CLOSURE_MASK_AND_JUMP MACRO LABEL
235*1fd5a2e1SPrashanth Swaminathan	and	    eax, X86_RET_TYPE_MASK
236*1fd5a2e1SPrashanth Swaminathan	lea 	edx, [LABEL+eax*8]
237*1fd5a2e1SPrashanth Swaminathan	mov 	eax, [esp+closure_CF]       /* optimiztic load */
238*1fd5a2e1SPrashanth Swaminathan	jmp	    edx
239*1fd5a2e1SPrashanth SwaminathanENDM
240*1fd5a2e1SPrashanth Swaminathan
241*1fd5a2e1SPrashanth SwaminathanALIGN 16
242*1fd5a2e1SPrashanth SwaminathanPUBLIC ffi_go_closure_EAX
243*1fd5a2e1SPrashanth Swaminathanffi_go_closure_EAX PROC C
244*1fd5a2e1SPrashanth SwaminathanL(UW6):
245*1fd5a2e1SPrashanth Swaminathan	// cfi_startproc
246*1fd5a2e1SPrashanth Swaminathan	sub	esp, closure_FS
247*1fd5a2e1SPrashanth SwaminathanL(UW7):
248*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa_offset(closure_FS + 4)
249*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_SAVE_REGS
250*1fd5a2e1SPrashanth Swaminathan	mov     edx, [eax+4]			/* copy cif */
251*1fd5a2e1SPrashanth Swaminathan	mov 	ecx, [eax +8]			/* copy fun */
252*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+28], edx
253*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+32], ecx
254*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+36], eax	/* closure is user_data */
255*1fd5a2e1SPrashanth Swaminathan	jmp	L(do_closure_i386)
256*1fd5a2e1SPrashanth SwaminathanL(UW8):
257*1fd5a2e1SPrashanth Swaminathan	// cfi_endproc
258*1fd5a2e1SPrashanth SwaminathanENDF(ffi_go_closure_EAX)
259*1fd5a2e1SPrashanth Swaminathan
260*1fd5a2e1SPrashanth SwaminathanALIGN 16
261*1fd5a2e1SPrashanth SwaminathanPUBLIC ffi_go_closure_ECX
262*1fd5a2e1SPrashanth Swaminathanffi_go_closure_ECX PROC C
263*1fd5a2e1SPrashanth SwaminathanL(UW9):
264*1fd5a2e1SPrashanth Swaminathan	// cfi_startproc
265*1fd5a2e1SPrashanth Swaminathan	sub 	esp, closure_FS
266*1fd5a2e1SPrashanth SwaminathanL(UW10):
267*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa_offset(closure_FS + 4)
268*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_SAVE_REGS
269*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [ecx+4]			/* copy cif */
270*1fd5a2e1SPrashanth Swaminathan	mov 	eax, [ecx+8]			/* copy fun */
271*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+28], edx
272*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+32], eax
273*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+36], ecx	/* closure is user_data */
274*1fd5a2e1SPrashanth Swaminathan	jmp	L(do_closure_i386)
275*1fd5a2e1SPrashanth SwaminathanL(UW11):
276*1fd5a2e1SPrashanth Swaminathan	// cfi_endproc
277*1fd5a2e1SPrashanth SwaminathanENDF(ffi_go_closure_ECX)
278*1fd5a2e1SPrashanth Swaminathan
279*1fd5a2e1SPrashanth Swaminathan/* The closure entry points are reached from the ffi_closure trampoline.
280*1fd5a2e1SPrashanth Swaminathan   On entry, %eax contains the address of the ffi_closure.  */
281*1fd5a2e1SPrashanth Swaminathan
282*1fd5a2e1SPrashanth SwaminathanALIGN 16
283*1fd5a2e1SPrashanth SwaminathanPUBLIC ffi_closure_i386
284*1fd5a2e1SPrashanth Swaminathanffi_closure_i386 PROC C
285*1fd5a2e1SPrashanth SwaminathanL(UW12):
286*1fd5a2e1SPrashanth Swaminathan	// cfi_startproc
287*1fd5a2e1SPrashanth Swaminathan	sub	    esp, closure_FS
288*1fd5a2e1SPrashanth SwaminathanL(UW13):
289*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa_offset(closure_FS + 4)
290*1fd5a2e1SPrashanth Swaminathan
291*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_SAVE_REGS
292*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_COPY_TRAMP_DATA
293*1fd5a2e1SPrashanth Swaminathan
294*1fd5a2e1SPrashanth Swaminathan	/* Entry point from preceeding Go closures.  */
295*1fd5a2e1SPrashanth SwaminathanL(do_closure_i386)::
296*1fd5a2e1SPrashanth Swaminathan
297*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_PREP_CALL
298*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_CALL_INNER(14)
299*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_MASK_AND_JUMP L(C1(load_table,2))
300*1fd5a2e1SPrashanth Swaminathan
301*1fd5a2e1SPrashanth Swaminathan    ALIGN 8
302*1fd5a2e1SPrashanth SwaminathanL(load_table2):
303*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_FLOAT)
304*1fd5a2e1SPrashanth Swaminathan	fld 	dword ptr [esp+closure_CF]
305*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
306*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_DOUBLE)
307*1fd5a2e1SPrashanth Swaminathan	fld 	qword ptr [esp+closure_CF]
308*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
309*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_LDOUBLE)
310*1fd5a2e1SPrashanth Swaminathan	fld 	qword ptr [esp+closure_CF]
311*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
312*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_SINT8)
313*1fd5a2e1SPrashanth Swaminathan	movsx	eax, al
314*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
315*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_SINT16)
316*1fd5a2e1SPrashanth Swaminathan	movsx	eax, ax
317*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
318*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_UINT8)
319*1fd5a2e1SPrashanth Swaminathan	movzx	eax, al
320*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
321*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_UINT16)
322*1fd5a2e1SPrashanth Swaminathan	movzx	eax, ax
323*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
324*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_INT64)
325*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [esp+closure_CF+4]
326*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
327*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_INT32)
328*1fd5a2e1SPrashanth Swaminathan	nop
329*1fd5a2e1SPrashanth Swaminathan	/* fallthru */
330*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_VOID)
331*1fd5a2e1SPrashanth SwaminathanL(e2):
332*1fd5a2e1SPrashanth Swaminathan	add 	esp, closure_FS
333*1fd5a2e1SPrashanth SwaminathanL(UW16):
334*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(-closure_FS)
335*1fd5a2e1SPrashanth Swaminathan	ret
336*1fd5a2e1SPrashanth SwaminathanL(UW17):
337*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(closure_FS)
338*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_STRUCTPOP)
339*1fd5a2e1SPrashanth Swaminathan	add 	esp, closure_FS
340*1fd5a2e1SPrashanth SwaminathanL(UW18):
341*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(-closure_FS)
342*1fd5a2e1SPrashanth Swaminathan	ret	4
343*1fd5a2e1SPrashanth SwaminathanL(UW19):
344*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(closure_FS)
345*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_STRUCTARG)
346*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
347*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_STRUCT_1B)
348*1fd5a2e1SPrashanth Swaminathan	movzx	eax, al
349*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
350*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_STRUCT_2B)
351*1fd5a2e1SPrashanth Swaminathan	movzx	eax, ax
352*1fd5a2e1SPrashanth Swaminathan	jmp	L(e2)
353*1fd5a2e1SPrashanth Swaminathan
354*1fd5a2e1SPrashanth Swaminathan	/* Fill out the table so that bad values are predictable.  */
355*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_UNUSED14)
356*1fd5a2e1SPrashanth Swaminathan	int 3
357*1fd5a2e1SPrashanth SwaminathanE(L(load_table2), X86_RET_UNUSED15)
358*1fd5a2e1SPrashanth Swaminathan	int 3
359*1fd5a2e1SPrashanth Swaminathan
360*1fd5a2e1SPrashanth SwaminathanL(UW20):
361*1fd5a2e1SPrashanth Swaminathan	// cfi_endproc
362*1fd5a2e1SPrashanth SwaminathanENDF(ffi_closure_i386)
363*1fd5a2e1SPrashanth Swaminathan
364*1fd5a2e1SPrashanth SwaminathanALIGN 16
365*1fd5a2e1SPrashanth SwaminathanPUBLIC	ffi_go_closure_STDCALL
366*1fd5a2e1SPrashanth Swaminathanffi_go_closure_STDCALL PROC C
367*1fd5a2e1SPrashanth SwaminathanL(UW21):
368*1fd5a2e1SPrashanth Swaminathan	// cfi_startproc
369*1fd5a2e1SPrashanth Swaminathan	sub 	esp, closure_FS
370*1fd5a2e1SPrashanth SwaminathanL(UW22):
371*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa_offset(closure_FS + 4)
372*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_SAVE_REGS
373*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [ecx+4]			/* copy cif */
374*1fd5a2e1SPrashanth Swaminathan	mov 	eax, [ecx+8]			/* copy fun */
375*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+28], edx
376*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+32], eax
377*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+closure_CF+36], ecx	/* closure is user_data */
378*1fd5a2e1SPrashanth Swaminathan	jmp	L(do_closure_STDCALL)
379*1fd5a2e1SPrashanth SwaminathanL(UW23):
380*1fd5a2e1SPrashanth Swaminathan	// cfi_endproc
381*1fd5a2e1SPrashanth SwaminathanENDF(ffi_go_closure_STDCALL)
382*1fd5a2e1SPrashanth Swaminathan
383*1fd5a2e1SPrashanth Swaminathan/* For REGISTER, we have no available parameter registers, and so we
384*1fd5a2e1SPrashanth Swaminathan   enter here having pushed the closure onto the stack.  */
385*1fd5a2e1SPrashanth Swaminathan
386*1fd5a2e1SPrashanth SwaminathanALIGN 16
387*1fd5a2e1SPrashanth SwaminathanPUBLIC ffi_closure_REGISTER
388*1fd5a2e1SPrashanth Swaminathanffi_closure_REGISTER PROC C
389*1fd5a2e1SPrashanth SwaminathanL(UW24):
390*1fd5a2e1SPrashanth Swaminathan	// cfi_startproc
391*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa(%esp, 8)
392*1fd5a2e1SPrashanth Swaminathan	// cfi_offset(%eip, -8)
393*1fd5a2e1SPrashanth Swaminathan	sub 	esp, closure_FS-4
394*1fd5a2e1SPrashanth SwaminathanL(UW25):
395*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa_offset(closure_FS + 4)
396*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_SAVE_REGS
397*1fd5a2e1SPrashanth Swaminathan	mov	ecx, [esp+closure_FS-4] 	/* load retaddr */
398*1fd5a2e1SPrashanth Swaminathan	mov	eax, [esp+closure_FS]		/* load closure */
399*1fd5a2e1SPrashanth Swaminathan	mov	[esp+closure_FS], ecx		/* move retaddr */
400*1fd5a2e1SPrashanth Swaminathan	jmp	L(do_closure_REGISTER)
401*1fd5a2e1SPrashanth SwaminathanL(UW26):
402*1fd5a2e1SPrashanth Swaminathan	// cfi_endproc
403*1fd5a2e1SPrashanth SwaminathanENDF(ffi_closure_REGISTER)
404*1fd5a2e1SPrashanth Swaminathan
405*1fd5a2e1SPrashanth Swaminathan/* For STDCALL (and others), we need to pop N bytes of arguments off
406*1fd5a2e1SPrashanth Swaminathan   the stack following the closure.  The amount needing to be popped
407*1fd5a2e1SPrashanth Swaminathan   is returned to us from ffi_closure_inner.  */
408*1fd5a2e1SPrashanth Swaminathan
409*1fd5a2e1SPrashanth SwaminathanALIGN 16
410*1fd5a2e1SPrashanth SwaminathanPUBLIC ffi_closure_STDCALL
411*1fd5a2e1SPrashanth Swaminathanffi_closure_STDCALL PROC C
412*1fd5a2e1SPrashanth SwaminathanL(UW27):
413*1fd5a2e1SPrashanth Swaminathan	// cfi_startproc
414*1fd5a2e1SPrashanth Swaminathan	sub 	esp, closure_FS
415*1fd5a2e1SPrashanth SwaminathanL(UW28):
416*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa_offset(closure_FS + 4)
417*1fd5a2e1SPrashanth Swaminathan
418*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_SAVE_REGS
419*1fd5a2e1SPrashanth Swaminathan
420*1fd5a2e1SPrashanth Swaminathan	/* Entry point from ffi_closure_REGISTER.  */
421*1fd5a2e1SPrashanth SwaminathanL(do_closure_REGISTER)::
422*1fd5a2e1SPrashanth Swaminathan
423*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_COPY_TRAMP_DATA
424*1fd5a2e1SPrashanth Swaminathan
425*1fd5a2e1SPrashanth Swaminathan	/* Entry point from preceeding Go closure.  */
426*1fd5a2e1SPrashanth SwaminathanL(do_closure_STDCALL)::
427*1fd5a2e1SPrashanth Swaminathan
428*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_PREP_CALL
429*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_CALL_INNER(29)
430*1fd5a2e1SPrashanth Swaminathan
431*1fd5a2e1SPrashanth Swaminathan	mov 	ecx, eax
432*1fd5a2e1SPrashanth Swaminathan	shr 	ecx, X86_RET_POP_SHIFT	    /* isolate pop count */
433*1fd5a2e1SPrashanth Swaminathan	lea 	ecx, [esp+closure_FS+ecx]	/* compute popped esp */
434*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [esp+closure_FS]		/* move return address */
435*1fd5a2e1SPrashanth Swaminathan	mov 	[ecx], edx
436*1fd5a2e1SPrashanth Swaminathan
437*1fd5a2e1SPrashanth Swaminathan	/* From this point on, the value of %esp upon return is %ecx+4,
438*1fd5a2e1SPrashanth Swaminathan	   and we've copied the return address to %ecx to make return easy.
439*1fd5a2e1SPrashanth Swaminathan	   There's no point in representing this in the unwind info, as
440*1fd5a2e1SPrashanth Swaminathan	   there is always a window between the mov and the ret which
441*1fd5a2e1SPrashanth Swaminathan	   will be wrong from one point of view or another.  */
442*1fd5a2e1SPrashanth Swaminathan
443*1fd5a2e1SPrashanth Swaminathan	FFI_CLOSURE_MASK_AND_JUMP  L(C1(load_table,3))
444*1fd5a2e1SPrashanth Swaminathan
445*1fd5a2e1SPrashanth Swaminathan    ALIGN 8
446*1fd5a2e1SPrashanth SwaminathanL(load_table3):
447*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_FLOAT)
448*1fd5a2e1SPrashanth Swaminathan	fld    DWORD PTR [esp+closure_CF]
449*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
450*1fd5a2e1SPrashanth Swaminathan	ret
451*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_DOUBLE)
452*1fd5a2e1SPrashanth Swaminathan	fld    QWORD PTR [esp+closure_CF]
453*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
454*1fd5a2e1SPrashanth Swaminathan	ret
455*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_LDOUBLE)
456*1fd5a2e1SPrashanth Swaminathan	fld    QWORD PTR [esp+closure_CF]
457*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
458*1fd5a2e1SPrashanth Swaminathan	ret
459*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_SINT8)
460*1fd5a2e1SPrashanth Swaminathan	movsx   eax, al
461*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
462*1fd5a2e1SPrashanth Swaminathan	ret
463*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_SINT16)
464*1fd5a2e1SPrashanth Swaminathan	movsx   eax, ax
465*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
466*1fd5a2e1SPrashanth Swaminathan	ret
467*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_UINT8)
468*1fd5a2e1SPrashanth Swaminathan	movzx   eax, al
469*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
470*1fd5a2e1SPrashanth Swaminathan	ret
471*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_UINT16)
472*1fd5a2e1SPrashanth Swaminathan	movzx   eax, ax
473*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
474*1fd5a2e1SPrashanth Swaminathan	ret
475*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_INT64)
476*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [esp+closure_CF+4]
477*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
478*1fd5a2e1SPrashanth Swaminathan	ret
479*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_int 32)
480*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
481*1fd5a2e1SPrashanth Swaminathan	ret
482*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_VOID)
483*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
484*1fd5a2e1SPrashanth Swaminathan	ret
485*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_STRUCTPOP)
486*1fd5a2e1SPrashanth Swaminathan	mov     esp, ecx
487*1fd5a2e1SPrashanth Swaminathan	ret
488*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_STRUCTARG)
489*1fd5a2e1SPrashanth Swaminathan	mov 	esp, ecx
490*1fd5a2e1SPrashanth Swaminathan	ret
491*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_STRUCT_1B)
492*1fd5a2e1SPrashanth Swaminathan	movzx	eax, al
493*1fd5a2e1SPrashanth Swaminathan	mov 	esp, ecx
494*1fd5a2e1SPrashanth Swaminathan	ret
495*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_STRUCT_2B)
496*1fd5a2e1SPrashanth Swaminathan	movzx	eax, ax
497*1fd5a2e1SPrashanth Swaminathan	mov 	esp, ecx
498*1fd5a2e1SPrashanth Swaminathan	ret
499*1fd5a2e1SPrashanth Swaminathan
500*1fd5a2e1SPrashanth Swaminathan	/* Fill out the table so that bad values are predictable.  */
501*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_UNUSED14)
502*1fd5a2e1SPrashanth Swaminathan	int 3
503*1fd5a2e1SPrashanth SwaminathanE(L(load_table3), X86_RET_UNUSED15)
504*1fd5a2e1SPrashanth Swaminathan	int 3
505*1fd5a2e1SPrashanth Swaminathan
506*1fd5a2e1SPrashanth SwaminathanL(UW31):
507*1fd5a2e1SPrashanth Swaminathan	// cfi_endproc
508*1fd5a2e1SPrashanth SwaminathanENDF(ffi_closure_STDCALL)
509*1fd5a2e1SPrashanth Swaminathan
510*1fd5a2e1SPrashanth Swaminathan#if !FFI_NO_RAW_API
511*1fd5a2e1SPrashanth Swaminathan
512*1fd5a2e1SPrashanth Swaminathan#define raw_closure_S_FS	(16+16+12)
513*1fd5a2e1SPrashanth Swaminathan
514*1fd5a2e1SPrashanth SwaminathanALIGN 16
515*1fd5a2e1SPrashanth SwaminathanPUBLIC ffi_closure_raw_SYSV
516*1fd5a2e1SPrashanth Swaminathanffi_closure_raw_SYSV PROC C
517*1fd5a2e1SPrashanth SwaminathanL(UW32):
518*1fd5a2e1SPrashanth Swaminathan	// cfi_startproc
519*1fd5a2e1SPrashanth Swaminathan	sub 	esp, raw_closure_S_FS
520*1fd5a2e1SPrashanth SwaminathanL(UW33):
521*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa_offset(raw_closure_S_FS + 4)
522*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+raw_closure_S_FS-4], ebx
523*1fd5a2e1SPrashanth SwaminathanL(UW34):
524*1fd5a2e1SPrashanth Swaminathan	// cfi_rel_offset(%ebx, raw_closure_S_FS-4)
525*1fd5a2e1SPrashanth Swaminathan
526*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [eax+FFI_TRAMPOLINE_SIZE+8]	/* load cl->user_data */
527*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+12], edx
528*1fd5a2e1SPrashanth Swaminathan	lea 	edx, [esp+raw_closure_S_FS+4]		/* load raw_args */
529*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+8], edx
530*1fd5a2e1SPrashanth Swaminathan	lea 	edx, [esp+16]				/* load &res */
531*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+4], edx
532*1fd5a2e1SPrashanth Swaminathan	mov 	ebx, [eax+FFI_TRAMPOLINE_SIZE]		/* load cl->cif */
533*1fd5a2e1SPrashanth Swaminathan	mov 	[esp], ebx
534*1fd5a2e1SPrashanth Swaminathan	call	DWORD PTR [eax+FFI_TRAMPOLINE_SIZE+4]		/* call cl->fun */
535*1fd5a2e1SPrashanth Swaminathan
536*1fd5a2e1SPrashanth Swaminathan	mov 	eax, [ebx+20]			/* load cif->flags */
537*1fd5a2e1SPrashanth Swaminathan	and 	eax, X86_RET_TYPE_MASK
538*1fd5a2e1SPrashanth Swaminathan// #ifdef __PIC__
539*1fd5a2e1SPrashanth Swaminathan// 	call	__x86.get_pc_thunk.bx
540*1fd5a2e1SPrashanth Swaminathan// L(pc4):
541*1fd5a2e1SPrashanth Swaminathan// 	lea 	ecx, L(load_table4)-L(pc4)(%ebx, %eax, 8), %ecx
542*1fd5a2e1SPrashanth Swaminathan// #else
543*1fd5a2e1SPrashanth Swaminathan	lea 	ecx, [L(load_table4)+eax+8]
544*1fd5a2e1SPrashanth Swaminathan// #endif
545*1fd5a2e1SPrashanth Swaminathan	mov 	ebx, [esp+raw_closure_S_FS-4]
546*1fd5a2e1SPrashanth SwaminathanL(UW35):
547*1fd5a2e1SPrashanth Swaminathan	// cfi_restore(%ebx)
548*1fd5a2e1SPrashanth Swaminathan	mov 	eax, [esp+16]				/* Optimistic load */
549*1fd5a2e1SPrashanth Swaminathan	jmp	    dword ptr [ecx]
550*1fd5a2e1SPrashanth Swaminathan
551*1fd5a2e1SPrashanth Swaminathan	ALIGN 8
552*1fd5a2e1SPrashanth SwaminathanL(load_table4):
553*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_FLOAT)
554*1fd5a2e1SPrashanth Swaminathan	fld 	DWORD PTR [esp +16]
555*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
556*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_DOUBLE)
557*1fd5a2e1SPrashanth Swaminathan	fld 	QWORD PTR [esp +16]
558*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
559*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_LDOUBLE)
560*1fd5a2e1SPrashanth Swaminathan	fld 	QWORD PTR [esp +16]
561*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
562*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_SINT8)
563*1fd5a2e1SPrashanth Swaminathan	movsx	eax, al
564*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
565*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_SINT16)
566*1fd5a2e1SPrashanth Swaminathan	movsx	eax, ax
567*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
568*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_UINT8)
569*1fd5a2e1SPrashanth Swaminathan	movzx	eax, al
570*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
571*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_UINT16)
572*1fd5a2e1SPrashanth Swaminathan	movzx	eax, ax
573*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
574*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_INT64)
575*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [esp+16+4]
576*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
577*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_int 32)
578*1fd5a2e1SPrashanth Swaminathan	nop
579*1fd5a2e1SPrashanth Swaminathan	/* fallthru */
580*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_VOID)
581*1fd5a2e1SPrashanth SwaminathanL(e4):
582*1fd5a2e1SPrashanth Swaminathan	add 	esp, raw_closure_S_FS
583*1fd5a2e1SPrashanth SwaminathanL(UW36):
584*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(-raw_closure_S_FS)
585*1fd5a2e1SPrashanth Swaminathan	ret
586*1fd5a2e1SPrashanth SwaminathanL(UW37):
587*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(raw_closure_S_FS)
588*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_STRUCTPOP)
589*1fd5a2e1SPrashanth Swaminathan	add 	esp, raw_closure_S_FS
590*1fd5a2e1SPrashanth SwaminathanL(UW38):
591*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(-raw_closure_S_FS)
592*1fd5a2e1SPrashanth Swaminathan	ret	4
593*1fd5a2e1SPrashanth SwaminathanL(UW39):
594*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(raw_closure_S_FS)
595*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_STRUCTARG)
596*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
597*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_STRUCT_1B)
598*1fd5a2e1SPrashanth Swaminathan	movzx	eax, al
599*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
600*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_STRUCT_2B)
601*1fd5a2e1SPrashanth Swaminathan	movzx	eax, ax
602*1fd5a2e1SPrashanth Swaminathan	jmp	L(e4)
603*1fd5a2e1SPrashanth Swaminathan
604*1fd5a2e1SPrashanth Swaminathan	/* Fill out the table so that bad values are predictable.  */
605*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_UNUSED14)
606*1fd5a2e1SPrashanth Swaminathan	int 3
607*1fd5a2e1SPrashanth SwaminathanE(L(load_table4), X86_RET_UNUSED15)
608*1fd5a2e1SPrashanth Swaminathan	int 3
609*1fd5a2e1SPrashanth Swaminathan
610*1fd5a2e1SPrashanth SwaminathanL(UW40):
611*1fd5a2e1SPrashanth Swaminathan	// cfi_endproc
612*1fd5a2e1SPrashanth SwaminathanENDF(ffi_closure_raw_SYSV)
613*1fd5a2e1SPrashanth Swaminathan
614*1fd5a2e1SPrashanth Swaminathan#define raw_closure_T_FS	(16+16+8)
615*1fd5a2e1SPrashanth Swaminathan
616*1fd5a2e1SPrashanth SwaminathanALIGN 16
617*1fd5a2e1SPrashanth SwaminathanPUBLIC ffi_closure_raw_THISCALL
618*1fd5a2e1SPrashanth Swaminathanffi_closure_raw_THISCALL PROC C
619*1fd5a2e1SPrashanth SwaminathanL(UW41):
620*1fd5a2e1SPrashanth Swaminathan	// cfi_startproc
621*1fd5a2e1SPrashanth Swaminathan	/* Rearrange the stack such that %ecx is the first argument.
622*1fd5a2e1SPrashanth Swaminathan	   This means moving the return address.  */
623*1fd5a2e1SPrashanth Swaminathan	pop 	edx
624*1fd5a2e1SPrashanth SwaminathanL(UW42):
625*1fd5a2e1SPrashanth Swaminathan	// cfi_def_cfa_offset(0)
626*1fd5a2e1SPrashanth Swaminathan	// cfi_register(%eip, %edx)
627*1fd5a2e1SPrashanth Swaminathan	push	ecx
628*1fd5a2e1SPrashanth SwaminathanL(UW43):
629*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(4)
630*1fd5a2e1SPrashanth Swaminathan	push 	edx
631*1fd5a2e1SPrashanth SwaminathanL(UW44):
632*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(4)
633*1fd5a2e1SPrashanth Swaminathan	// cfi_rel_offset(%eip, 0)
634*1fd5a2e1SPrashanth Swaminathan	sub 	esp, raw_closure_T_FS
635*1fd5a2e1SPrashanth SwaminathanL(UW45):
636*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(raw_closure_T_FS)
637*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+raw_closure_T_FS-4], ebx
638*1fd5a2e1SPrashanth SwaminathanL(UW46):
639*1fd5a2e1SPrashanth Swaminathan	// cfi_rel_offset(%ebx, raw_closure_T_FS-4)
640*1fd5a2e1SPrashanth Swaminathan
641*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [eax+FFI_TRAMPOLINE_SIZE+8]	/* load cl->user_data */
642*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+12], edx
643*1fd5a2e1SPrashanth Swaminathan	lea 	edx, [esp+raw_closure_T_FS+4]		/* load raw_args */
644*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+8], edx
645*1fd5a2e1SPrashanth Swaminathan	lea 	edx, [esp+16]				/* load &res */
646*1fd5a2e1SPrashanth Swaminathan	mov 	[esp+4], edx
647*1fd5a2e1SPrashanth Swaminathan	mov 	ebx, [eax+FFI_TRAMPOLINE_SIZE]		/* load cl->cif */
648*1fd5a2e1SPrashanth Swaminathan	mov 	[esp], ebx
649*1fd5a2e1SPrashanth Swaminathan	call	DWORD PTR [eax+FFI_TRAMPOLINE_SIZE+4]		/* call cl->fun */
650*1fd5a2e1SPrashanth Swaminathan
651*1fd5a2e1SPrashanth Swaminathan	mov 	eax, [ebx+20]				/* load cif->flags */
652*1fd5a2e1SPrashanth Swaminathan	and 	eax, X86_RET_TYPE_MASK
653*1fd5a2e1SPrashanth Swaminathan// #ifdef __PIC__
654*1fd5a2e1SPrashanth Swaminathan// 	call	__x86.get_pc_thunk.bx
655*1fd5a2e1SPrashanth Swaminathan// L(pc5):
656*1fd5a2e1SPrashanth Swaminathan// 	leal	L(load_table5)-L(pc5)(%ebx, %eax, 8), %ecx
657*1fd5a2e1SPrashanth Swaminathan// #else
658*1fd5a2e1SPrashanth Swaminathan	lea 	ecx, [L(load_table5)+eax*8]
659*1fd5a2e1SPrashanth Swaminathan//#endif
660*1fd5a2e1SPrashanth Swaminathan	mov 	ebx, [esp+raw_closure_T_FS-4]
661*1fd5a2e1SPrashanth SwaminathanL(UW47):
662*1fd5a2e1SPrashanth Swaminathan	// cfi_restore(%ebx)
663*1fd5a2e1SPrashanth Swaminathan	mov 	eax, [esp+16]				/* Optimistic load */
664*1fd5a2e1SPrashanth Swaminathan	jmp	    DWORD PTR [ecx]
665*1fd5a2e1SPrashanth Swaminathan
666*1fd5a2e1SPrashanth Swaminathan	AlIGN 4
667*1fd5a2e1SPrashanth SwaminathanL(load_table5):
668*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_FLOAT)
669*1fd5a2e1SPrashanth Swaminathan	fld	DWORD PTR [esp +16]
670*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
671*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_DOUBLE)
672*1fd5a2e1SPrashanth Swaminathan	fld	QWORD PTR [esp +16]
673*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
674*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_LDOUBLE)
675*1fd5a2e1SPrashanth Swaminathan	fld	QWORD PTR [esp+16]
676*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
677*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_SINT8)
678*1fd5a2e1SPrashanth Swaminathan	movsx	eax, al
679*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
680*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_SINT16)
681*1fd5a2e1SPrashanth Swaminathan	movsx	eax, ax
682*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
683*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_UINT8)
684*1fd5a2e1SPrashanth Swaminathan	movzx	eax, al
685*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
686*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_UINT16)
687*1fd5a2e1SPrashanth Swaminathan	movzx	eax, ax
688*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
689*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_INT64)
690*1fd5a2e1SPrashanth Swaminathan	mov 	edx, [esp+16+4]
691*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
692*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_int 32)
693*1fd5a2e1SPrashanth Swaminathan	nop
694*1fd5a2e1SPrashanth Swaminathan	/* fallthru */
695*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_VOID)
696*1fd5a2e1SPrashanth SwaminathanL(e5):
697*1fd5a2e1SPrashanth Swaminathan	add 	esp, raw_closure_T_FS
698*1fd5a2e1SPrashanth SwaminathanL(UW48):
699*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(-raw_closure_T_FS)
700*1fd5a2e1SPrashanth Swaminathan	/* Remove the extra %ecx argument we pushed.  */
701*1fd5a2e1SPrashanth Swaminathan	ret	4
702*1fd5a2e1SPrashanth SwaminathanL(UW49):
703*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(raw_closure_T_FS)
704*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_STRUCTPOP)
705*1fd5a2e1SPrashanth Swaminathan	add 	esp, raw_closure_T_FS
706*1fd5a2e1SPrashanth SwaminathanL(UW50):
707*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(-raw_closure_T_FS)
708*1fd5a2e1SPrashanth Swaminathan	ret	8
709*1fd5a2e1SPrashanth SwaminathanL(UW51):
710*1fd5a2e1SPrashanth Swaminathan	// cfi_adjust_cfa_offset(raw_closure_T_FS)
711*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_STRUCTARG)
712*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
713*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_STRUCT_1B)
714*1fd5a2e1SPrashanth Swaminathan	movzx	eax, al
715*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
716*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_STRUCT_2B)
717*1fd5a2e1SPrashanth Swaminathan	movzx	eax, ax
718*1fd5a2e1SPrashanth Swaminathan	jmp	L(e5)
719*1fd5a2e1SPrashanth Swaminathan
720*1fd5a2e1SPrashanth Swaminathan	/* Fill out the table so that bad values are predictable.  */
721*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_UNUSED14)
722*1fd5a2e1SPrashanth Swaminathan	int 3
723*1fd5a2e1SPrashanth SwaminathanE(L(load_table5), X86_RET_UNUSED15)
724*1fd5a2e1SPrashanth Swaminathan	int 3
725*1fd5a2e1SPrashanth Swaminathan
726*1fd5a2e1SPrashanth SwaminathanL(UW52):
727*1fd5a2e1SPrashanth Swaminathan	// cfi_endproc
728*1fd5a2e1SPrashanth SwaminathanENDF(ffi_closure_raw_THISCALL)
729*1fd5a2e1SPrashanth Swaminathan
730*1fd5a2e1SPrashanth Swaminathan#endif /* !FFI_NO_RAW_API */
731*1fd5a2e1SPrashanth Swaminathan
732*1fd5a2e1SPrashanth Swaminathan#ifdef X86_DARWIN
733*1fd5a2e1SPrashanth Swaminathan# define COMDAT(X)							\
734*1fd5a2e1SPrashanth Swaminathan        .section __TEXT,__text,coalesced,pure_instructions;		\
735*1fd5a2e1SPrashanth Swaminathan        .weak_definition X;						\
736*1fd5a2e1SPrashanth Swaminathan        FFI_HIDDEN(X)
737*1fd5a2e1SPrashanth Swaminathan#elif defined __ELF__ && !(defined(__sun__) && defined(__svr4__))
738*1fd5a2e1SPrashanth Swaminathan# define COMDAT(X)							\
739*1fd5a2e1SPrashanth Swaminathan	.section .text.X,"axG",@progbits,X,comdat;			\
740*1fd5a2e1SPrashanth Swaminathan	PUBLIC	X;							\
741*1fd5a2e1SPrashanth Swaminathan	FFI_HIDDEN(X)
742*1fd5a2e1SPrashanth Swaminathan#else
743*1fd5a2e1SPrashanth Swaminathan# define COMDAT(X)
744*1fd5a2e1SPrashanth Swaminathan#endif
745*1fd5a2e1SPrashanth Swaminathan
746*1fd5a2e1SPrashanth Swaminathan// #if defined(__PIC__)
747*1fd5a2e1SPrashanth Swaminathan// 	COMDAT(C(__x86.get_pc_thunk.bx))
748*1fd5a2e1SPrashanth Swaminathan// C(__x86.get_pc_thunk.bx):
749*1fd5a2e1SPrashanth Swaminathan// 	movl	(%esp), %ebx
750*1fd5a2e1SPrashanth Swaminathan// 	ret
751*1fd5a2e1SPrashanth Swaminathan// ENDF(C(__x86.get_pc_thunk.bx))
752*1fd5a2e1SPrashanth Swaminathan// # if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
753*1fd5a2e1SPrashanth Swaminathan// 	COMDAT(C(__x86.get_pc_thunk.dx))
754*1fd5a2e1SPrashanth Swaminathan// C(__x86.get_pc_thunk.dx):
755*1fd5a2e1SPrashanth Swaminathan// 	movl	(%esp), %edx
756*1fd5a2e1SPrashanth Swaminathan// 	ret
757*1fd5a2e1SPrashanth Swaminathan// ENDF(C(__x86.get_pc_thunk.dx))
758*1fd5a2e1SPrashanth Swaminathan// #endif /* DARWIN || HIDDEN */
759*1fd5a2e1SPrashanth Swaminathan// #endif /* __PIC__ */
760*1fd5a2e1SPrashanth Swaminathan
761*1fd5a2e1SPrashanth Swaminathan#if 0
762*1fd5a2e1SPrashanth Swaminathan/* Sadly, OSX cctools-as doesn't understand .cfi directives at all.  */
763*1fd5a2e1SPrashanth Swaminathan
764*1fd5a2e1SPrashanth Swaminathan#ifdef __APPLE__
765*1fd5a2e1SPrashanth Swaminathan.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
766*1fd5a2e1SPrashanth SwaminathanEHFrame0:
767*1fd5a2e1SPrashanth Swaminathan#elif defined(X86_WIN32)
768*1fd5a2e1SPrashanth Swaminathan.section .eh_frame,"r"
769*1fd5a2e1SPrashanth Swaminathan#elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)
770*1fd5a2e1SPrashanth Swaminathan.section .eh_frame,EH_FRAME_FLAGS,@unwind
771*1fd5a2e1SPrashanth Swaminathan#else
772*1fd5a2e1SPrashanth Swaminathan.section .eh_frame,EH_FRAME_FLAGS,@progbits
773*1fd5a2e1SPrashanth Swaminathan#endif
774*1fd5a2e1SPrashanth Swaminathan
775*1fd5a2e1SPrashanth Swaminathan#ifdef HAVE_AS_X86_PCREL
776*1fd5a2e1SPrashanth Swaminathan# define PCREL(X)	X - .
777*1fd5a2e1SPrashanth Swaminathan#else
778*1fd5a2e1SPrashanth Swaminathan# define PCREL(X)	X@rel
779*1fd5a2e1SPrashanth Swaminathan#endif
780*1fd5a2e1SPrashanth Swaminathan
781*1fd5a2e1SPrashanth Swaminathan/* Simplify advancing between labels.  Assume DW_CFA_advance_loc1 fits.  */
782*1fd5a2e1SPrashanth Swaminathan#define ADV(N, P)	.byte 2, L(N)-L(P)
783*1fd5a2e1SPrashanth Swaminathan
784*1fd5a2e1SPrashanth Swaminathan	.balign 4
785*1fd5a2e1SPrashanth SwaminathanL(CIE):
786*1fd5a2e1SPrashanth Swaminathan	.set	L(set0),L(ECIE)-L(SCIE)
787*1fd5a2e1SPrashanth Swaminathan	.long	L(set0)			/* CIE Length */
788*1fd5a2e1SPrashanth SwaminathanL(SCIE):
789*1fd5a2e1SPrashanth Swaminathan	.long	0			/* CIE Identifier Tag */
790*1fd5a2e1SPrashanth Swaminathan	.byte	1			/* CIE Version */
791*1fd5a2e1SPrashanth Swaminathan	.ascii	"zR\0"			/* CIE Augmentation */
792*1fd5a2e1SPrashanth Swaminathan	.byte	1			/* CIE Code Alignment Factor */
793*1fd5a2e1SPrashanth Swaminathan	.byte	0x7c			/* CIE Data Alignment Factor */
794*1fd5a2e1SPrashanth Swaminathan	.byte	0x8			/* CIE RA Column */
795*1fd5a2e1SPrashanth Swaminathan	.byte	1			/* Augmentation size */
796*1fd5a2e1SPrashanth Swaminathan	.byte	0x1b			/* FDE Encoding (pcrel sdata4) */
797*1fd5a2e1SPrashanth Swaminathan	.byte	0xc, 4, 4		/* DW_CFA_def_cfa, %esp offset 4 */
798*1fd5a2e1SPrashanth Swaminathan	.byte	0x80+8, 1		/* DW_CFA_offset, %eip offset 1*-4 */
799*1fd5a2e1SPrashanth Swaminathan	.balign 4
800*1fd5a2e1SPrashanth SwaminathanL(ECIE):
801*1fd5a2e1SPrashanth Swaminathan
802*1fd5a2e1SPrashanth Swaminathan	.set	L(set1),L(EFDE1)-L(SFDE1)
803*1fd5a2e1SPrashanth Swaminathan	.long	L(set1)			/* FDE Length */
804*1fd5a2e1SPrashanth SwaminathanL(SFDE1):
805*1fd5a2e1SPrashanth Swaminathan	.long	L(SFDE1)-L(CIE)		/* FDE CIE offset */
806*1fd5a2e1SPrashanth Swaminathan	.long	PCREL(L(UW0))		/* Initial location */
807*1fd5a2e1SPrashanth Swaminathan	.long	L(UW5)-L(UW0)		/* Address range */
808*1fd5a2e1SPrashanth Swaminathan	.byte	0			/* Augmentation size */
809*1fd5a2e1SPrashanth Swaminathan	ADV(UW1, UW0)
810*1fd5a2e1SPrashanth Swaminathan	.byte	0xc, 5, 8		/* DW_CFA_def_cfa, %ebp 8 */
811*1fd5a2e1SPrashanth Swaminathan	.byte	0x80+5, 2		/* DW_CFA_offset, %ebp 2*-4 */
812*1fd5a2e1SPrashanth Swaminathan	ADV(UW2, UW1)
813*1fd5a2e1SPrashanth Swaminathan	.byte	0x80+3, 0		/* DW_CFA_offset, %ebx 0*-4 */
814*1fd5a2e1SPrashanth Swaminathan	ADV(UW3, UW2)
815*1fd5a2e1SPrashanth Swaminathan	.byte	0xa			/* DW_CFA_remember_state */
816*1fd5a2e1SPrashanth Swaminathan	.byte	0xc, 4, 4		/* DW_CFA_def_cfa, %esp 4 */
817*1fd5a2e1SPrashanth Swaminathan	.byte	0xc0+3			/* DW_CFA_restore, %ebx */
818*1fd5a2e1SPrashanth Swaminathan	.byte	0xc0+5			/* DW_CFA_restore, %ebp */
819*1fd5a2e1SPrashanth Swaminathan	ADV(UW4, UW3)
820*1fd5a2e1SPrashanth Swaminathan	.byte	0xb			/* DW_CFA_restore_state */
821*1fd5a2e1SPrashanth Swaminathan	.balign	4
822*1fd5a2e1SPrashanth SwaminathanL(EFDE1):
823*1fd5a2e1SPrashanth Swaminathan
824*1fd5a2e1SPrashanth Swaminathan	.set	L(set2),L(EFDE2)-L(SFDE2)
825*1fd5a2e1SPrashanth Swaminathan	.long	L(set2)			/* FDE Length */
826*1fd5a2e1SPrashanth SwaminathanL(SFDE2):
827*1fd5a2e1SPrashanth Swaminathan	.long	L(SFDE2)-L(CIE)		/* FDE CIE offset */
828*1fd5a2e1SPrashanth Swaminathan	.long	PCREL(L(UW6))		/* Initial location */
829*1fd5a2e1SPrashanth Swaminathan	.long	L(UW8)-L(UW6)		/* Address range */
830*1fd5a2e1SPrashanth Swaminathan	.byte	0			/* Augmentation size */
831*1fd5a2e1SPrashanth Swaminathan	ADV(UW7, UW6)
832*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
833*1fd5a2e1SPrashanth Swaminathan	.balign	4
834*1fd5a2e1SPrashanth SwaminathanL(EFDE2):
835*1fd5a2e1SPrashanth Swaminathan
836*1fd5a2e1SPrashanth Swaminathan	.set	L(set3),L(EFDE3)-L(SFDE3)
837*1fd5a2e1SPrashanth Swaminathan	.long	L(set3)			/* FDE Length */
838*1fd5a2e1SPrashanth SwaminathanL(SFDE3):
839*1fd5a2e1SPrashanth Swaminathan	.long	L(SFDE3)-L(CIE)		/* FDE CIE offset */
840*1fd5a2e1SPrashanth Swaminathan	.long	PCREL(L(UW9))		/* Initial location */
841*1fd5a2e1SPrashanth Swaminathan	.long	L(UW11)-L(UW9)		/* Address range */
842*1fd5a2e1SPrashanth Swaminathan	.byte	0			/* Augmentation size */
843*1fd5a2e1SPrashanth Swaminathan	ADV(UW10, UW9)
844*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
845*1fd5a2e1SPrashanth Swaminathan	.balign	4
846*1fd5a2e1SPrashanth SwaminathanL(EFDE3):
847*1fd5a2e1SPrashanth Swaminathan
848*1fd5a2e1SPrashanth Swaminathan	.set	L(set4),L(EFDE4)-L(SFDE4)
849*1fd5a2e1SPrashanth Swaminathan	.long	L(set4)			/* FDE Length */
850*1fd5a2e1SPrashanth SwaminathanL(SFDE4):
851*1fd5a2e1SPrashanth Swaminathan	.long	L(SFDE4)-L(CIE)		/* FDE CIE offset */
852*1fd5a2e1SPrashanth Swaminathan	.long	PCREL(L(UW12))		/* Initial location */
853*1fd5a2e1SPrashanth Swaminathan	.long	L(UW20)-L(UW12)		/* Address range */
854*1fd5a2e1SPrashanth Swaminathan	.byte	0			/* Augmentation size */
855*1fd5a2e1SPrashanth Swaminathan	ADV(UW13, UW12)
856*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
857*1fd5a2e1SPrashanth Swaminathan#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX
858*1fd5a2e1SPrashanth Swaminathan	ADV(UW14, UW13)
859*1fd5a2e1SPrashanth Swaminathan	.byte	0x80+3, (40-(closure_FS+4))/-4  /* DW_CFA_offset %ebx */
860*1fd5a2e1SPrashanth Swaminathan	ADV(UW15, UW14)
861*1fd5a2e1SPrashanth Swaminathan	.byte	0xc0+3			/* DW_CFA_restore %ebx */
862*1fd5a2e1SPrashanth Swaminathan	ADV(UW16, UW15)
863*1fd5a2e1SPrashanth Swaminathan#else
864*1fd5a2e1SPrashanth Swaminathan	ADV(UW16, UW13)
865*1fd5a2e1SPrashanth Swaminathan#endif
866*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
867*1fd5a2e1SPrashanth Swaminathan	ADV(UW17, UW16)
868*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
869*1fd5a2e1SPrashanth Swaminathan	ADV(UW18, UW17)
870*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
871*1fd5a2e1SPrashanth Swaminathan	ADV(UW19, UW18)
872*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
873*1fd5a2e1SPrashanth Swaminathan	.balign	4
874*1fd5a2e1SPrashanth SwaminathanL(EFDE4):
875*1fd5a2e1SPrashanth Swaminathan
876*1fd5a2e1SPrashanth Swaminathan	.set	L(set5),L(EFDE5)-L(SFDE5)
877*1fd5a2e1SPrashanth Swaminathan	.long	L(set5)			/* FDE Length */
878*1fd5a2e1SPrashanth SwaminathanL(SFDE5):
879*1fd5a2e1SPrashanth Swaminathan	.long	L(SFDE5)-L(CIE)		/* FDE CIE offset */
880*1fd5a2e1SPrashanth Swaminathan	.long	PCREL(L(UW21))		/* Initial location */
881*1fd5a2e1SPrashanth Swaminathan	.long	L(UW23)-L(UW21)		/* Address range */
882*1fd5a2e1SPrashanth Swaminathan	.byte	0			/* Augmentation size */
883*1fd5a2e1SPrashanth Swaminathan	ADV(UW22, UW21)
884*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
885*1fd5a2e1SPrashanth Swaminathan	.balign	4
886*1fd5a2e1SPrashanth SwaminathanL(EFDE5):
887*1fd5a2e1SPrashanth Swaminathan
888*1fd5a2e1SPrashanth Swaminathan	.set	L(set6),L(EFDE6)-L(SFDE6)
889*1fd5a2e1SPrashanth Swaminathan	.long	L(set6)			/* FDE Length */
890*1fd5a2e1SPrashanth SwaminathanL(SFDE6):
891*1fd5a2e1SPrashanth Swaminathan	.long	L(SFDE6)-L(CIE)		/* FDE CIE offset */
892*1fd5a2e1SPrashanth Swaminathan	.long	PCREL(L(UW24))		/* Initial location */
893*1fd5a2e1SPrashanth Swaminathan	.long	L(UW26)-L(UW24)		/* Address range */
894*1fd5a2e1SPrashanth Swaminathan	.byte	0			/* Augmentation size */
895*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
896*1fd5a2e1SPrashanth Swaminathan	.byte	0x80+8, 2		/* DW_CFA_offset %eip, 2*-4 */
897*1fd5a2e1SPrashanth Swaminathan	ADV(UW25, UW24)
898*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
899*1fd5a2e1SPrashanth Swaminathan	.balign	4
900*1fd5a2e1SPrashanth SwaminathanL(EFDE6):
901*1fd5a2e1SPrashanth Swaminathan
902*1fd5a2e1SPrashanth Swaminathan	.set	L(set7),L(EFDE7)-L(SFDE7)
903*1fd5a2e1SPrashanth Swaminathan	.long	L(set7)			/* FDE Length */
904*1fd5a2e1SPrashanth SwaminathanL(SFDE7):
905*1fd5a2e1SPrashanth Swaminathan	.long	L(SFDE7)-L(CIE)		/* FDE CIE offset */
906*1fd5a2e1SPrashanth Swaminathan	.long	PCREL(L(UW27))		/* Initial location */
907*1fd5a2e1SPrashanth Swaminathan	.long	L(UW31)-L(UW27)		/* Address range */
908*1fd5a2e1SPrashanth Swaminathan	.byte	0			/* Augmentation size */
909*1fd5a2e1SPrashanth Swaminathan	ADV(UW28, UW27)
910*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
911*1fd5a2e1SPrashanth Swaminathan#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX
912*1fd5a2e1SPrashanth Swaminathan	ADV(UW29, UW28)
913*1fd5a2e1SPrashanth Swaminathan	.byte	0x80+3, (40-(closure_FS+4))/-4  /* DW_CFA_offset %ebx */
914*1fd5a2e1SPrashanth Swaminathan	ADV(UW30, UW29)
915*1fd5a2e1SPrashanth Swaminathan	.byte	0xc0+3			/* DW_CFA_restore %ebx */
916*1fd5a2e1SPrashanth Swaminathan#endif
917*1fd5a2e1SPrashanth Swaminathan	.balign	4
918*1fd5a2e1SPrashanth SwaminathanL(EFDE7):
919*1fd5a2e1SPrashanth Swaminathan
920*1fd5a2e1SPrashanth Swaminathan#if !FFI_NO_RAW_API
921*1fd5a2e1SPrashanth Swaminathan	.set	L(set8),L(EFDE8)-L(SFDE8)
922*1fd5a2e1SPrashanth Swaminathan	.long	L(set8)			/* FDE Length */
923*1fd5a2e1SPrashanth SwaminathanL(SFDE8):
924*1fd5a2e1SPrashanth Swaminathan	.long	L(SFDE8)-L(CIE)		/* FDE CIE offset */
925*1fd5a2e1SPrashanth Swaminathan	.long	PCREL(L(UW32))		/* Initial location */
926*1fd5a2e1SPrashanth Swaminathan	.long	L(UW40)-L(UW32)		/* Address range */
927*1fd5a2e1SPrashanth Swaminathan	.byte	0			/* Augmentation size */
928*1fd5a2e1SPrashanth Swaminathan	ADV(UW33, UW32)
929*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */
930*1fd5a2e1SPrashanth Swaminathan	ADV(UW34, UW33)
931*1fd5a2e1SPrashanth Swaminathan	.byte	0x80+3, 2		/* DW_CFA_offset %ebx 2*-4 */
932*1fd5a2e1SPrashanth Swaminathan	ADV(UW35, UW34)
933*1fd5a2e1SPrashanth Swaminathan	.byte	0xc0+3			/* DW_CFA_restore %ebx */
934*1fd5a2e1SPrashanth Swaminathan	ADV(UW36, UW35)
935*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
936*1fd5a2e1SPrashanth Swaminathan	ADV(UW37, UW36)
937*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */
938*1fd5a2e1SPrashanth Swaminathan	ADV(UW38, UW37)
939*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
940*1fd5a2e1SPrashanth Swaminathan	ADV(UW39, UW38)
941*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */
942*1fd5a2e1SPrashanth Swaminathan	.balign	4
943*1fd5a2e1SPrashanth SwaminathanL(EFDE8):
944*1fd5a2e1SPrashanth Swaminathan
945*1fd5a2e1SPrashanth Swaminathan	.set	L(set9),L(EFDE9)-L(SFDE9)
946*1fd5a2e1SPrashanth Swaminathan	.long	L(set9)			/* FDE Length */
947*1fd5a2e1SPrashanth SwaminathanL(SFDE9):
948*1fd5a2e1SPrashanth Swaminathan	.long	L(SFDE9)-L(CIE)		/* FDE CIE offset */
949*1fd5a2e1SPrashanth Swaminathan	.long	PCREL(L(UW41))		/* Initial location */
950*1fd5a2e1SPrashanth Swaminathan	.long	L(UW52)-L(UW41)		/* Address range */
951*1fd5a2e1SPrashanth Swaminathan	.byte	0			/* Augmentation size */
952*1fd5a2e1SPrashanth Swaminathan	ADV(UW42, UW41)
953*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, 0			/* DW_CFA_def_cfa_offset */
954*1fd5a2e1SPrashanth Swaminathan	.byte	0x9, 8, 2		/* DW_CFA_register %eip, %edx */
955*1fd5a2e1SPrashanth Swaminathan	ADV(UW43, UW42)
956*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
957*1fd5a2e1SPrashanth Swaminathan	ADV(UW44, UW43)
958*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
959*1fd5a2e1SPrashanth Swaminathan	.byte	0x80+8, 2		/* DW_CFA_offset %eip 2*-4 */
960*1fd5a2e1SPrashanth Swaminathan	ADV(UW45, UW44)
961*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */
962*1fd5a2e1SPrashanth Swaminathan	ADV(UW46, UW45)
963*1fd5a2e1SPrashanth Swaminathan	.byte	0x80+3, 3		/* DW_CFA_offset %ebx 3*-4 */
964*1fd5a2e1SPrashanth Swaminathan	ADV(UW47, UW46)
965*1fd5a2e1SPrashanth Swaminathan	.byte	0xc0+3			/* DW_CFA_restore %ebx */
966*1fd5a2e1SPrashanth Swaminathan	ADV(UW48, UW47)
967*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
968*1fd5a2e1SPrashanth Swaminathan	ADV(UW49, UW48)
969*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */
970*1fd5a2e1SPrashanth Swaminathan	ADV(UW50, UW49)
971*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
972*1fd5a2e1SPrashanth Swaminathan	ADV(UW51, UW50)
973*1fd5a2e1SPrashanth Swaminathan	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */
974*1fd5a2e1SPrashanth Swaminathan	.balign	4
975*1fd5a2e1SPrashanth SwaminathanL(EFDE9):
976*1fd5a2e1SPrashanth Swaminathan#endif /* !FFI_NO_RAW_API */
977*1fd5a2e1SPrashanth Swaminathan
978*1fd5a2e1SPrashanth Swaminathan#ifdef _WIN32
979*1fd5a2e1SPrashanth Swaminathan	.def	 @feat.00;
980*1fd5a2e1SPrashanth Swaminathan	.scl	3;
981*1fd5a2e1SPrashanth Swaminathan	.type	0;
982*1fd5a2e1SPrashanth Swaminathan	.endef
983*1fd5a2e1SPrashanth Swaminathan	PUBLIC	@feat.00
984*1fd5a2e1SPrashanth Swaminathan@feat.00 = 1
985*1fd5a2e1SPrashanth Swaminathan#endif
986*1fd5a2e1SPrashanth Swaminathan
987*1fd5a2e1SPrashanth Swaminathan#endif /* ifndef _MSC_VER */
988*1fd5a2e1SPrashanth Swaminathan#endif /* ifndef __x86_64__ */
989*1fd5a2e1SPrashanth Swaminathan
990*1fd5a2e1SPrashanth Swaminathan#if defined __ELF__ && defined __linux__
991*1fd5a2e1SPrashanth Swaminathan	.section	.note.GNU-stack,"",@progbits
992*1fd5a2e1SPrashanth Swaminathan#endif
993*1fd5a2e1SPrashanth Swaminathan#endif
994*1fd5a2e1SPrashanth Swaminathan
995*1fd5a2e1SPrashanth SwaminathanEND