xref: /aosp_15_r20/external/libffi/src/aarch64/win64_armasm.S (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
1*1fd5a2e1SPrashanth Swaminathan/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
2*1fd5a2e1SPrashanth SwaminathanPermission is hereby granted, free of charge, to any person obtaining
3*1fd5a2e1SPrashanth Swaminathana copy of this software and associated documentation files (the
4*1fd5a2e1SPrashanth Swaminathan``Software''), to deal in the Software without restriction, including
5*1fd5a2e1SPrashanth Swaminathanwithout limitation the rights to use, copy, modify, merge, publish,
6*1fd5a2e1SPrashanth Swaminathandistribute, sublicense, and/or sell copies of the Software, and to
7*1fd5a2e1SPrashanth Swaminathanpermit persons to whom the Software is furnished to do so, subject to
8*1fd5a2e1SPrashanth Swaminathanthe following conditions:
9*1fd5a2e1SPrashanth SwaminathanThe above copyright notice and this permission notice shall be
10*1fd5a2e1SPrashanth Swaminathanincluded in all copies or substantial portions of the Software.
11*1fd5a2e1SPrashanth SwaminathanTHE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
12*1fd5a2e1SPrashanth SwaminathanEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
13*1fd5a2e1SPrashanth SwaminathanMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
14*1fd5a2e1SPrashanth SwaminathanIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
15*1fd5a2e1SPrashanth SwaminathanCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
16*1fd5a2e1SPrashanth SwaminathanTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17*1fd5a2e1SPrashanth SwaminathanSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
18*1fd5a2e1SPrashanth Swaminathan
19*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM
20*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h>
21*1fd5a2e1SPrashanth Swaminathan#include <ffi.h>
22*1fd5a2e1SPrashanth Swaminathan#include <ffi_cfi.h>
23*1fd5a2e1SPrashanth Swaminathan#include "internal.h"
24*1fd5a2e1SPrashanth Swaminathan
25*1fd5a2e1SPrashanth Swaminathan	OPT	2 /*disable listing */
26*1fd5a2e1SPrashanth Swaminathan/* For some macros to add unwind information */
27*1fd5a2e1SPrashanth Swaminathan#include "ksarm64.h"
28*1fd5a2e1SPrashanth Swaminathan	OPT	1 /*re-enable listing */
29*1fd5a2e1SPrashanth Swaminathan
30*1fd5a2e1SPrashanth Swaminathan#define BE(X)	0
31*1fd5a2e1SPrashanth Swaminathan#define PTR_REG(n)      x##n
32*1fd5a2e1SPrashanth Swaminathan#define PTR_SIZE	8
33*1fd5a2e1SPrashanth Swaminathan
34*1fd5a2e1SPrashanth Swaminathan	IMPORT ffi_closure_SYSV_inner
35*1fd5a2e1SPrashanth Swaminathan	EXPORT	ffi_call_SYSV
36*1fd5a2e1SPrashanth Swaminathan	EXPORT	ffi_closure_SYSV_V
37*1fd5a2e1SPrashanth Swaminathan	EXPORT	ffi_closure_SYSV
38*1fd5a2e1SPrashanth Swaminathan	EXPORT	extend_hfa_type
39*1fd5a2e1SPrashanth Swaminathan	EXPORT	compress_hfa_type
40*1fd5a2e1SPrashanth Swaminathan#ifdef FFI_GO_CLOSURES
41*1fd5a2e1SPrashanth Swaminathan	EXPORT	ffi_go_closure_SYSV_V
42*1fd5a2e1SPrashanth Swaminathan	EXPORT	ffi_go_closure_SYSV
43*1fd5a2e1SPrashanth Swaminathan#endif
44*1fd5a2e1SPrashanth Swaminathan
45*1fd5a2e1SPrashanth Swaminathan	TEXTAREA, ALLIGN=8
46*1fd5a2e1SPrashanth Swaminathan
47*1fd5a2e1SPrashanth Swaminathan/* ffi_call_SYSV
48*1fd5a2e1SPrashanth Swaminathan   extern void ffi_call_SYSV (void *stack, void *frame,
49*1fd5a2e1SPrashanth Swaminathan			      void (*fn)(void), void *rvalue,
50*1fd5a2e1SPrashanth Swaminathan			      int flags, void *closure);
51*1fd5a2e1SPrashanth Swaminathan   Therefore on entry we have:
52*1fd5a2e1SPrashanth Swaminathan   x0 stack
53*1fd5a2e1SPrashanth Swaminathan   x1 frame
54*1fd5a2e1SPrashanth Swaminathan   x2 fn
55*1fd5a2e1SPrashanth Swaminathan   x3 rvalue
56*1fd5a2e1SPrashanth Swaminathan   x4 flags
57*1fd5a2e1SPrashanth Swaminathan   x5 closure
58*1fd5a2e1SPrashanth Swaminathan*/
59*1fd5a2e1SPrashanth Swaminathan
60*1fd5a2e1SPrashanth Swaminathan	NESTED_ENTRY ffi_call_SYSV_fake
61*1fd5a2e1SPrashanth Swaminathan
62*1fd5a2e1SPrashanth Swaminathan	/* For unwind information, Windows has to store fp and lr  */
63*1fd5a2e1SPrashanth Swaminathan	PROLOG_SAVE_REG_PAIR	x29, x30, #-32!
64*1fd5a2e1SPrashanth Swaminathan
65*1fd5a2e1SPrashanth Swaminathan	ALTERNATE_ENTRY ffi_call_SYSV
66*1fd5a2e1SPrashanth Swaminathan	/* Use a stack frame allocated by our caller. */
67*1fd5a2e1SPrashanth Swaminathan	stp	x29, x30, [x1]
68*1fd5a2e1SPrashanth Swaminathan	mov	x29, x1
69*1fd5a2e1SPrashanth Swaminathan	mov	sp, x0
70*1fd5a2e1SPrashanth Swaminathan
71*1fd5a2e1SPrashanth Swaminathan	mov	x9, x2			/* save fn */
72*1fd5a2e1SPrashanth Swaminathan	mov	x8, x3			/* install structure return */
73*1fd5a2e1SPrashanth Swaminathan#ifdef FFI_GO_CLOSURES
74*1fd5a2e1SPrashanth Swaminathan	/*mov	x18, x5			install static chain */
75*1fd5a2e1SPrashanth Swaminathan#endif
76*1fd5a2e1SPrashanth Swaminathan	stp	x3, x4, [x29, #16]	/* save rvalue and flags */
77*1fd5a2e1SPrashanth Swaminathan
78*1fd5a2e1SPrashanth Swaminathan	/* Load the vector argument passing registers, if necessary.  */
79*1fd5a2e1SPrashanth Swaminathan	tbz	x4, #AARCH64_FLAG_ARG_V_BIT, ffi_call_SYSV_L1
80*1fd5a2e1SPrashanth Swaminathan	ldp	q0, q1, [sp, #0]
81*1fd5a2e1SPrashanth Swaminathan	ldp	q2, q3, [sp, #32]
82*1fd5a2e1SPrashanth Swaminathan	ldp	q4, q5, [sp, #64]
83*1fd5a2e1SPrashanth Swaminathan	ldp	q6, q7, [sp, #96]
84*1fd5a2e1SPrashanth Swaminathan
85*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV_L1
86*1fd5a2e1SPrashanth Swaminathan	/* Load the core argument passing registers, including
87*1fd5a2e1SPrashanth Swaminathan	   the structure return pointer.  */
88*1fd5a2e1SPrashanth Swaminathan	ldp     x0, x1, [sp, #16*N_V_ARG_REG + 0]
89*1fd5a2e1SPrashanth Swaminathan	ldp     x2, x3, [sp, #16*N_V_ARG_REG + 16]
90*1fd5a2e1SPrashanth Swaminathan	ldp     x4, x5, [sp, #16*N_V_ARG_REG + 32]
91*1fd5a2e1SPrashanth Swaminathan	ldp     x6, x7, [sp, #16*N_V_ARG_REG + 48]
92*1fd5a2e1SPrashanth Swaminathan
93*1fd5a2e1SPrashanth Swaminathan	/* Deallocate the context, leaving the stacked arguments.  */
94*1fd5a2e1SPrashanth Swaminathan	add	sp, sp, #CALL_CONTEXT_SIZE
95*1fd5a2e1SPrashanth Swaminathan
96*1fd5a2e1SPrashanth Swaminathan	blr     x9			/* call fn */
97*1fd5a2e1SPrashanth Swaminathan
98*1fd5a2e1SPrashanth Swaminathan	ldp	x3, x4, [x29, #16]	/* reload rvalue and flags */
99*1fd5a2e1SPrashanth Swaminathan
100*1fd5a2e1SPrashanth Swaminathan	/* Partially deconstruct the stack frame. */
101*1fd5a2e1SPrashanth Swaminathan	mov     sp, x29
102*1fd5a2e1SPrashanth Swaminathan	ldp     x29, x30, [x29]
103*1fd5a2e1SPrashanth Swaminathan
104*1fd5a2e1SPrashanth Swaminathan	/* Save the return value as directed.  */
105*1fd5a2e1SPrashanth Swaminathan	adr	x5, ffi_call_SYSV_return
106*1fd5a2e1SPrashanth Swaminathan	and	w4, w4, #AARCH64_RET_MASK
107*1fd5a2e1SPrashanth Swaminathan	add	x5, x5, x4, lsl #3
108*1fd5a2e1SPrashanth Swaminathan	br	x5
109*1fd5a2e1SPrashanth Swaminathan
110*1fd5a2e1SPrashanth Swaminathan	/* Note that each table entry is 2 insns, and thus 8 bytes.
111*1fd5a2e1SPrashanth Swaminathan	   For integer data, note that we're storing into ffi_arg
112*1fd5a2e1SPrashanth Swaminathan	   and therefore we want to extend to 64 bits; these types
113*1fd5a2e1SPrashanth Swaminathan	   have two consecutive entries allocated for them.  */
114*1fd5a2e1SPrashanth Swaminathan	ALIGN 4
115*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV_return
116*1fd5a2e1SPrashanth Swaminathan	ret				/* VOID */
117*1fd5a2e1SPrashanth Swaminathan	nop
118*1fd5a2e1SPrashanth Swaminathan	str	x0, [x3]		/* INT64 */
119*1fd5a2e1SPrashanth Swaminathan	ret
120*1fd5a2e1SPrashanth Swaminathan	stp	x0, x1, [x3]		/* INT128 */
121*1fd5a2e1SPrashanth Swaminathan	ret
122*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* UNUSED */
123*1fd5a2e1SPrashanth Swaminathan	ret
124*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* UNUSED */
125*1fd5a2e1SPrashanth Swaminathan	ret
126*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* UNUSED */
127*1fd5a2e1SPrashanth Swaminathan	ret
128*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* UNUSED */
129*1fd5a2e1SPrashanth Swaminathan	ret
130*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* UNUSED */
131*1fd5a2e1SPrashanth Swaminathan	ret
132*1fd5a2e1SPrashanth Swaminathan	st4	{ v0.s, v1.s, v2.s, v3.s }[0], [x3]	/* S4 */
133*1fd5a2e1SPrashanth Swaminathan	ret
134*1fd5a2e1SPrashanth Swaminathan	st3	{ v0.s, v1.s, v2.s }[0], [x3]	/* S3 */
135*1fd5a2e1SPrashanth Swaminathan	ret
136*1fd5a2e1SPrashanth Swaminathan	stp	s0, s1, [x3]		/* S2 */
137*1fd5a2e1SPrashanth Swaminathan	ret
138*1fd5a2e1SPrashanth Swaminathan	str	s0, [x3]		/* S1 */
139*1fd5a2e1SPrashanth Swaminathan	ret
140*1fd5a2e1SPrashanth Swaminathan	st4	{ v0.d, v1.d, v2.d, v3.d }[0], [x3]	/* D4 */
141*1fd5a2e1SPrashanth Swaminathan	ret
142*1fd5a2e1SPrashanth Swaminathan	st3	{ v0.d, v1.d, v2.d }[0], [x3]	/* D3 */
143*1fd5a2e1SPrashanth Swaminathan	ret
144*1fd5a2e1SPrashanth Swaminathan	stp	d0, d1, [x3]		/* D2 */
145*1fd5a2e1SPrashanth Swaminathan	ret
146*1fd5a2e1SPrashanth Swaminathan	str	d0, [x3]		/* D1 */
147*1fd5a2e1SPrashanth Swaminathan	ret
148*1fd5a2e1SPrashanth Swaminathan	str	q3, [x3, #48]		/* Q4 */
149*1fd5a2e1SPrashanth Swaminathan	nop
150*1fd5a2e1SPrashanth Swaminathan	str	q2, [x3, #32]		/* Q3 */
151*1fd5a2e1SPrashanth Swaminathan	nop
152*1fd5a2e1SPrashanth Swaminathan	stp	q0, q1, [x3]		/* Q2 */
153*1fd5a2e1SPrashanth Swaminathan	ret
154*1fd5a2e1SPrashanth Swaminathan	str	q0, [x3]		/* Q1 */
155*1fd5a2e1SPrashanth Swaminathan	ret
156*1fd5a2e1SPrashanth Swaminathan	uxtb	w0, w0			/* UINT8 */
157*1fd5a2e1SPrashanth Swaminathan	str	x0, [x3]
158*1fd5a2e1SPrashanth Swaminathan	ret				/* reserved */
159*1fd5a2e1SPrashanth Swaminathan	nop
160*1fd5a2e1SPrashanth Swaminathan	uxth	w0, w0			/* UINT16 */
161*1fd5a2e1SPrashanth Swaminathan	str	x0, [x3]
162*1fd5a2e1SPrashanth Swaminathan	ret				/* reserved */
163*1fd5a2e1SPrashanth Swaminathan	nop
164*1fd5a2e1SPrashanth Swaminathan	mov	w0, w0			/* UINT32 */
165*1fd5a2e1SPrashanth Swaminathan	str	x0, [x3]
166*1fd5a2e1SPrashanth Swaminathan	ret				/* reserved */
167*1fd5a2e1SPrashanth Swaminathan	nop
168*1fd5a2e1SPrashanth Swaminathan	sxtb	x0, w0			/* SINT8 */
169*1fd5a2e1SPrashanth Swaminathan	str	x0, [x3]
170*1fd5a2e1SPrashanth Swaminathan	ret				/* reserved */
171*1fd5a2e1SPrashanth Swaminathan	nop
172*1fd5a2e1SPrashanth Swaminathan	sxth	x0, w0			/* SINT16 */
173*1fd5a2e1SPrashanth Swaminathan	str	x0, [x3]
174*1fd5a2e1SPrashanth Swaminathan	ret				/* reserved */
175*1fd5a2e1SPrashanth Swaminathan	nop
176*1fd5a2e1SPrashanth Swaminathan	sxtw	x0, w0			/* SINT32 */
177*1fd5a2e1SPrashanth Swaminathan	str	x0, [x3]
178*1fd5a2e1SPrashanth Swaminathan	ret				/* reserved */
179*1fd5a2e1SPrashanth Swaminathan	nop
180*1fd5a2e1SPrashanth Swaminathan
181*1fd5a2e1SPrashanth Swaminathan
182*1fd5a2e1SPrashanth Swaminathan	NESTED_END ffi_call_SYSV_fake
183*1fd5a2e1SPrashanth Swaminathan
184*1fd5a2e1SPrashanth Swaminathan
185*1fd5a2e1SPrashanth Swaminathan/* ffi_closure_SYSV
186*1fd5a2e1SPrashanth Swaminathan   Closure invocation glue. This is the low level code invoked directly by
187*1fd5a2e1SPrashanth Swaminathan   the closure trampoline to setup and call a closure.
188*1fd5a2e1SPrashanth Swaminathan   On entry x17 points to a struct ffi_closure, x16 has been clobbered
189*1fd5a2e1SPrashanth Swaminathan   all other registers are preserved.
190*1fd5a2e1SPrashanth Swaminathan   We allocate a call context and save the argument passing registers,
191*1fd5a2e1SPrashanth Swaminathan   then invoked the generic C ffi_closure_SYSV_inner() function to do all
192*1fd5a2e1SPrashanth Swaminathan   the real work, on return we load the result passing registers back from
193*1fd5a2e1SPrashanth Swaminathan   the call context.
194*1fd5a2e1SPrashanth Swaminathan*/
195*1fd5a2e1SPrashanth Swaminathan
196*1fd5a2e1SPrashanth Swaminathan#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64)
197*1fd5a2e1SPrashanth Swaminathan
198*1fd5a2e1SPrashanth Swaminathan	NESTED_ENTRY	ffi_closure_SYSV_V
199*1fd5a2e1SPrashanth Swaminathan	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!
200*1fd5a2e1SPrashanth Swaminathan
201*1fd5a2e1SPrashanth Swaminathan	/* Save the argument passing vector registers.  */
202*1fd5a2e1SPrashanth Swaminathan	stp	q0, q1, [sp, #16 + 0]
203*1fd5a2e1SPrashanth Swaminathan	stp	q2, q3, [sp, #16 + 32]
204*1fd5a2e1SPrashanth Swaminathan	stp	q4, q5, [sp, #16 + 64]
205*1fd5a2e1SPrashanth Swaminathan	stp	q6, q7, [sp, #16 + 96]
206*1fd5a2e1SPrashanth Swaminathan
207*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_save_argument
208*1fd5a2e1SPrashanth Swaminathan	NESTED_END	ffi_closure_SYSV_V
209*1fd5a2e1SPrashanth Swaminathan
210*1fd5a2e1SPrashanth Swaminathan	NESTED_ENTRY	ffi_closure_SYSV
211*1fd5a2e1SPrashanth Swaminathan	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!
212*1fd5a2e1SPrashanth Swaminathan
213*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_save_argument
214*1fd5a2e1SPrashanth Swaminathan	/* Save the argument passing core registers.  */
215*1fd5a2e1SPrashanth Swaminathan	stp     x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
216*1fd5a2e1SPrashanth Swaminathan	stp     x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
217*1fd5a2e1SPrashanth Swaminathan	stp     x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
218*1fd5a2e1SPrashanth Swaminathan	stp     x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
219*1fd5a2e1SPrashanth Swaminathan
220*1fd5a2e1SPrashanth Swaminathan	/* Load ffi_closure_inner arguments.  */
221*1fd5a2e1SPrashanth Swaminathan	ldp	PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET]	/* load cif, fn */
222*1fd5a2e1SPrashanth Swaminathan	ldr	PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2]	/* load user_data */
223*1fd5a2e1SPrashanth Swaminathan
224*1fd5a2e1SPrashanth Swaminathando_closure
225*1fd5a2e1SPrashanth Swaminathan	add	x3, sp, #16							/* load context */
226*1fd5a2e1SPrashanth Swaminathan	add	x4, sp, #ffi_closure_SYSV_FS		/* load stack */
227*1fd5a2e1SPrashanth Swaminathan	add	x5, sp, #16+CALL_CONTEXT_SIZE		/* load rvalue */
228*1fd5a2e1SPrashanth Swaminathan	mov	x6, x8					/* load struct_rval */
229*1fd5a2e1SPrashanth Swaminathan
230*1fd5a2e1SPrashanth Swaminathan	bl	ffi_closure_SYSV_inner
231*1fd5a2e1SPrashanth Swaminathan
232*1fd5a2e1SPrashanth Swaminathan	/* Load the return value as directed.  */
233*1fd5a2e1SPrashanth Swaminathan	adr	x1, ffi_closure_SYSV_return_base
234*1fd5a2e1SPrashanth Swaminathan	and	w0, w0, #AARCH64_RET_MASK
235*1fd5a2e1SPrashanth Swaminathan	add	x1, x1, x0, lsl #3
236*1fd5a2e1SPrashanth Swaminathan	add	x3, sp, #16+CALL_CONTEXT_SIZE
237*1fd5a2e1SPrashanth Swaminathan	br	x1
238*1fd5a2e1SPrashanth Swaminathan
239*1fd5a2e1SPrashanth Swaminathan	/* Note that each table entry is 2 insns, and thus 8 bytes.  */
240*1fd5a2e1SPrashanth Swaminathan	ALIGN	8
241*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_return_base
242*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog			/* VOID */
243*1fd5a2e1SPrashanth Swaminathan	nop
244*1fd5a2e1SPrashanth Swaminathan	ldr	x0, [x3]		/* INT64 */
245*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
246*1fd5a2e1SPrashanth Swaminathan	ldp	x0, x1, [x3]		/* INT128 */
247*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
248*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* UNUSED */
249*1fd5a2e1SPrashanth Swaminathan	nop
250*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* UNUSED */
251*1fd5a2e1SPrashanth Swaminathan	nop
252*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* UNUSED */
253*1fd5a2e1SPrashanth Swaminathan	nop
254*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* UNUSED */
255*1fd5a2e1SPrashanth Swaminathan	nop
256*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* UNUSED */
257*1fd5a2e1SPrashanth Swaminathan	nop
258*1fd5a2e1SPrashanth Swaminathan	ldr	s3, [x3, #12]		/* S4 */
259*1fd5a2e1SPrashanth Swaminathan	nop
260*1fd5a2e1SPrashanth Swaminathan	ldr	s2, [x3, #8]		/* S3 */
261*1fd5a2e1SPrashanth Swaminathan	nop
262*1fd5a2e1SPrashanth Swaminathan	ldp	s0, s1, [x3]		/* S2 */
263*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
264*1fd5a2e1SPrashanth Swaminathan	ldr	s0, [x3]		/* S1 */
265*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
266*1fd5a2e1SPrashanth Swaminathan	ldr	d3, [x3, #24]		/* D4 */
267*1fd5a2e1SPrashanth Swaminathan	nop
268*1fd5a2e1SPrashanth Swaminathan	ldr	d2, [x3, #16]		/* D3 */
269*1fd5a2e1SPrashanth Swaminathan	nop
270*1fd5a2e1SPrashanth Swaminathan	ldp	d0, d1, [x3]		/* D2 */
271*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
272*1fd5a2e1SPrashanth Swaminathan	ldr	d0, [x3]		/* D1 */
273*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
274*1fd5a2e1SPrashanth Swaminathan	ldr	q3, [x3, #48]		/* Q4 */
275*1fd5a2e1SPrashanth Swaminathan	nop
276*1fd5a2e1SPrashanth Swaminathan	ldr	q2, [x3, #32]		/* Q3 */
277*1fd5a2e1SPrashanth Swaminathan	nop
278*1fd5a2e1SPrashanth Swaminathan	ldp	q0, q1, [x3]		/* Q2 */
279*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
280*1fd5a2e1SPrashanth Swaminathan	ldr	q0, [x3]		/* Q1 */
281*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
282*1fd5a2e1SPrashanth Swaminathan	ldrb	w0, [x3, #BE(7)]	/* UINT8 */
283*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
284*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* reserved */
285*1fd5a2e1SPrashanth Swaminathan	nop
286*1fd5a2e1SPrashanth Swaminathan	ldrh	w0, [x3, #BE(6)]	/* UINT16 */
287*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
288*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* reserved */
289*1fd5a2e1SPrashanth Swaminathan	nop
290*1fd5a2e1SPrashanth Swaminathan	ldr	w0, [x3, #BE(4)]	/* UINT32 */
291*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
292*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* reserved */
293*1fd5a2e1SPrashanth Swaminathan	nop
294*1fd5a2e1SPrashanth Swaminathan	ldrsb	x0, [x3, #BE(7)]	/* SINT8 */
295*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
296*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* reserved */
297*1fd5a2e1SPrashanth Swaminathan	nop
298*1fd5a2e1SPrashanth Swaminathan	ldrsh	x0, [x3, #BE(6)]	/* SINT16 */
299*1fd5a2e1SPrashanth Swaminathan	b	ffi_closure_SYSV_epilog
300*1fd5a2e1SPrashanth Swaminathan	brk	#1000			/* reserved */
301*1fd5a2e1SPrashanth Swaminathan	nop
302*1fd5a2e1SPrashanth Swaminathan	ldrsw	x0, [x3, #BE(4)]	/* SINT32 */
303*1fd5a2e1SPrashanth Swaminathan	nop
304*1fd5a2e1SPrashanth Swaminathan					/* reserved */
305*1fd5a2e1SPrashanth Swaminathan
306*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_epilog
307*1fd5a2e1SPrashanth Swaminathan	EPILOG_RESTORE_REG_PAIR	x29, x30, #ffi_closure_SYSV_FS!
308*1fd5a2e1SPrashanth Swaminathan	EPILOG_RETURN
309*1fd5a2e1SPrashanth Swaminathan	NESTED_END	ffi_closure_SYSV
310*1fd5a2e1SPrashanth Swaminathan
311*1fd5a2e1SPrashanth Swaminathan
312*1fd5a2e1SPrashanth Swaminathan#ifdef FFI_GO_CLOSURES
313*1fd5a2e1SPrashanth Swaminathan	NESTED_ENTRY	ffi_go_closure_SYSV_V
314*1fd5a2e1SPrashanth Swaminathan	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!
315*1fd5a2e1SPrashanth Swaminathan
316*1fd5a2e1SPrashanth Swaminathan	/* Save the argument passing vector registers.  */
317*1fd5a2e1SPrashanth Swaminathan	stp	q0, q1, [sp, #16 + 0]
318*1fd5a2e1SPrashanth Swaminathan	stp	q2, q3, [sp, #16 + 32]
319*1fd5a2e1SPrashanth Swaminathan	stp	q4, q5, [sp, #16 + 64]
320*1fd5a2e1SPrashanth Swaminathan	stp	q6, q7, [sp, #16 + 96]
321*1fd5a2e1SPrashanth Swaminathan	b	ffi_go_closure_SYSV_save_argument
322*1fd5a2e1SPrashanth Swaminathan	NESTED_END	ffi_go_closure_SYSV_V
323*1fd5a2e1SPrashanth Swaminathan
324*1fd5a2e1SPrashanth Swaminathan	NESTED_ENTRY	ffi_go_closure_SYSV
325*1fd5a2e1SPrashanth Swaminathan	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!
326*1fd5a2e1SPrashanth Swaminathan
327*1fd5a2e1SPrashanth Swaminathanffi_go_closure_SYSV_save_argument
328*1fd5a2e1SPrashanth Swaminathan	/* Save the argument passing core registers.  */
329*1fd5a2e1SPrashanth Swaminathan	stp     x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
330*1fd5a2e1SPrashanth Swaminathan	stp     x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
331*1fd5a2e1SPrashanth Swaminathan	stp     x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
332*1fd5a2e1SPrashanth Swaminathan	stp     x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
333*1fd5a2e1SPrashanth Swaminathan
334*1fd5a2e1SPrashanth Swaminathan	/* Load ffi_closure_inner arguments.  */
335*1fd5a2e1SPrashanth Swaminathan	ldp	PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */
336*1fd5a2e1SPrashanth Swaminathan	mov	x2, x18					/* load user_data */
337*1fd5a2e1SPrashanth Swaminathan	b	do_closure
338*1fd5a2e1SPrashanth Swaminathan	NESTED_END	ffi_go_closure_SYSV
339*1fd5a2e1SPrashanth Swaminathan
340*1fd5a2e1SPrashanth Swaminathan#endif /* FFI_GO_CLOSURES */
341*1fd5a2e1SPrashanth Swaminathan
342*1fd5a2e1SPrashanth Swaminathan
343*1fd5a2e1SPrashanth Swaminathan/* void extend_hfa_type (void *dest, void *src, int h) */
344*1fd5a2e1SPrashanth Swaminathan
345*1fd5a2e1SPrashanth Swaminathan	LEAF_ENTRY	extend_hfa_type
346*1fd5a2e1SPrashanth Swaminathan
347*1fd5a2e1SPrashanth Swaminathan	adr	x3, extend_hfa_type_jump_base
348*1fd5a2e1SPrashanth Swaminathan	and	w2, w2, #AARCH64_RET_MASK
349*1fd5a2e1SPrashanth Swaminathan	sub	x2, x2, #AARCH64_RET_S4
350*1fd5a2e1SPrashanth Swaminathan	add	x3, x3, x2, lsl #4
351*1fd5a2e1SPrashanth Swaminathan	br	x3
352*1fd5a2e1SPrashanth Swaminathan
353*1fd5a2e1SPrashanth Swaminathan	ALIGN	4
354*1fd5a2e1SPrashanth Swaminathanextend_hfa_type_jump_base
355*1fd5a2e1SPrashanth Swaminathan	ldp	s16, s17, [x1]		/* S4 */
356*1fd5a2e1SPrashanth Swaminathan	ldp	s18, s19, [x1, #8]
357*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_4
358*1fd5a2e1SPrashanth Swaminathan	nop
359*1fd5a2e1SPrashanth Swaminathan
360*1fd5a2e1SPrashanth Swaminathan	ldp	s16, s17, [x1]		/* S3 */
361*1fd5a2e1SPrashanth Swaminathan	ldr	s18, [x1, #8]
362*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_3
363*1fd5a2e1SPrashanth Swaminathan	nop
364*1fd5a2e1SPrashanth Swaminathan
365*1fd5a2e1SPrashanth Swaminathan	ldp	s16, s17, [x1]		/* S2 */
366*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_2
367*1fd5a2e1SPrashanth Swaminathan	nop
368*1fd5a2e1SPrashanth Swaminathan	nop
369*1fd5a2e1SPrashanth Swaminathan
370*1fd5a2e1SPrashanth Swaminathan	ldr	s16, [x1]		/* S1 */
371*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_1
372*1fd5a2e1SPrashanth Swaminathan	nop
373*1fd5a2e1SPrashanth Swaminathan	nop
374*1fd5a2e1SPrashanth Swaminathan
375*1fd5a2e1SPrashanth Swaminathan	ldp	d16, d17, [x1]		/* D4 */
376*1fd5a2e1SPrashanth Swaminathan	ldp	d18, d19, [x1, #16]
377*1fd5a2e1SPrashanth Swaminathan	b       extend_hfa_type_store_4
378*1fd5a2e1SPrashanth Swaminathan	nop
379*1fd5a2e1SPrashanth Swaminathan
380*1fd5a2e1SPrashanth Swaminathan	ldp     d16, d17, [x1]		/* D3 */
381*1fd5a2e1SPrashanth Swaminathan	ldr     d18, [x1, #16]
382*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_3
383*1fd5a2e1SPrashanth Swaminathan	nop
384*1fd5a2e1SPrashanth Swaminathan
385*1fd5a2e1SPrashanth Swaminathan	ldp	d16, d17, [x1]		/* D2 */
386*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_2
387*1fd5a2e1SPrashanth Swaminathan	nop
388*1fd5a2e1SPrashanth Swaminathan	nop
389*1fd5a2e1SPrashanth Swaminathan
390*1fd5a2e1SPrashanth Swaminathan	ldr	d16, [x1]		/* D1 */
391*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_1
392*1fd5a2e1SPrashanth Swaminathan	nop
393*1fd5a2e1SPrashanth Swaminathan	nop
394*1fd5a2e1SPrashanth Swaminathan
395*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* Q4 */
396*1fd5a2e1SPrashanth Swaminathan	ldp	q18, q19, [x1, #16]
397*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_4
398*1fd5a2e1SPrashanth Swaminathan	nop
399*1fd5a2e1SPrashanth Swaminathan
400*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* Q3 */
401*1fd5a2e1SPrashanth Swaminathan	ldr	q18, [x1, #16]
402*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_3
403*1fd5a2e1SPrashanth Swaminathan	nop
404*1fd5a2e1SPrashanth Swaminathan
405*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* Q2 */
406*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_2
407*1fd5a2e1SPrashanth Swaminathan	nop
408*1fd5a2e1SPrashanth Swaminathan	nop
409*1fd5a2e1SPrashanth Swaminathan
410*1fd5a2e1SPrashanth Swaminathan	ldr	q16, [x1]		/* Q1 */
411*1fd5a2e1SPrashanth Swaminathan	b	extend_hfa_type_store_1
412*1fd5a2e1SPrashanth Swaminathan
413*1fd5a2e1SPrashanth Swaminathanextend_hfa_type_store_4
414*1fd5a2e1SPrashanth Swaminathan	str	q19, [x0, #48]
415*1fd5a2e1SPrashanth Swaminathanextend_hfa_type_store_3
416*1fd5a2e1SPrashanth Swaminathan	str	q18, [x0, #32]
417*1fd5a2e1SPrashanth Swaminathanextend_hfa_type_store_2
418*1fd5a2e1SPrashanth Swaminathan	str	q17, [x0, #16]
419*1fd5a2e1SPrashanth Swaminathanextend_hfa_type_store_1
420*1fd5a2e1SPrashanth Swaminathan	str	q16, [x0]
421*1fd5a2e1SPrashanth Swaminathan	ret
422*1fd5a2e1SPrashanth Swaminathan
423*1fd5a2e1SPrashanth Swaminathan	LEAF_END	extend_hfa_type
424*1fd5a2e1SPrashanth Swaminathan
425*1fd5a2e1SPrashanth Swaminathan
426*1fd5a2e1SPrashanth Swaminathan/* void compress_hfa_type (void *dest, void *reg, int h) */
427*1fd5a2e1SPrashanth Swaminathan
428*1fd5a2e1SPrashanth Swaminathan	LEAF_ENTRY	compress_hfa_type
429*1fd5a2e1SPrashanth Swaminathan
430*1fd5a2e1SPrashanth Swaminathan	adr	x3, compress_hfa_type_jump_base
431*1fd5a2e1SPrashanth Swaminathan	and	w2, w2, #AARCH64_RET_MASK
432*1fd5a2e1SPrashanth Swaminathan	sub	x2, x2, #AARCH64_RET_S4
433*1fd5a2e1SPrashanth Swaminathan	add	x3, x3, x2, lsl #4
434*1fd5a2e1SPrashanth Swaminathan	br	x3
435*1fd5a2e1SPrashanth Swaminathan
436*1fd5a2e1SPrashanth Swaminathan	ALIGN	4
437*1fd5a2e1SPrashanth Swaminathancompress_hfa_type_jump_base
438*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* S4 */
439*1fd5a2e1SPrashanth Swaminathan	ldp	q18, q19, [x1, #32]
440*1fd5a2e1SPrashanth Swaminathan	st4	{ v16.s, v17.s, v18.s, v19.s }[0], [x0]
441*1fd5a2e1SPrashanth Swaminathan	ret
442*1fd5a2e1SPrashanth Swaminathan
443*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* S3 */
444*1fd5a2e1SPrashanth Swaminathan	ldr	q18, [x1, #32]
445*1fd5a2e1SPrashanth Swaminathan	st3	{ v16.s, v17.s, v18.s }[0], [x0]
446*1fd5a2e1SPrashanth Swaminathan	ret
447*1fd5a2e1SPrashanth Swaminathan
448*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* S2 */
449*1fd5a2e1SPrashanth Swaminathan	st2	{ v16.s, v17.s }[0], [x0]
450*1fd5a2e1SPrashanth Swaminathan	ret
451*1fd5a2e1SPrashanth Swaminathan	nop
452*1fd5a2e1SPrashanth Swaminathan
453*1fd5a2e1SPrashanth Swaminathan	ldr	q16, [x1]		/* S1 */
454*1fd5a2e1SPrashanth Swaminathan	st1	{ v16.s }[0], [x0]
455*1fd5a2e1SPrashanth Swaminathan	ret
456*1fd5a2e1SPrashanth Swaminathan	nop
457*1fd5a2e1SPrashanth Swaminathan
458*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* D4 */
459*1fd5a2e1SPrashanth Swaminathan	ldp	q18, q19, [x1, #32]
460*1fd5a2e1SPrashanth Swaminathan	st4	{ v16.d, v17.d, v18.d, v19.d }[0], [x0]
461*1fd5a2e1SPrashanth Swaminathan	ret
462*1fd5a2e1SPrashanth Swaminathan
463*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* D3 */
464*1fd5a2e1SPrashanth Swaminathan	ldr	q18, [x1, #32]
465*1fd5a2e1SPrashanth Swaminathan	st3	{ v16.d, v17.d, v18.d }[0], [x0]
466*1fd5a2e1SPrashanth Swaminathan	ret
467*1fd5a2e1SPrashanth Swaminathan
468*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* D2 */
469*1fd5a2e1SPrashanth Swaminathan	st2	{ v16.d, v17.d }[0], [x0]
470*1fd5a2e1SPrashanth Swaminathan	ret
471*1fd5a2e1SPrashanth Swaminathan	nop
472*1fd5a2e1SPrashanth Swaminathan
473*1fd5a2e1SPrashanth Swaminathan	ldr	q16, [x1]		/* D1 */
474*1fd5a2e1SPrashanth Swaminathan	st1	{ v16.d }[0], [x0]
475*1fd5a2e1SPrashanth Swaminathan	ret
476*1fd5a2e1SPrashanth Swaminathan	nop
477*1fd5a2e1SPrashanth Swaminathan
478*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* Q4 */
479*1fd5a2e1SPrashanth Swaminathan	ldp	q18, q19, [x1, #32]
480*1fd5a2e1SPrashanth Swaminathan	b	compress_hfa_type_store_q4
481*1fd5a2e1SPrashanth Swaminathan	nop
482*1fd5a2e1SPrashanth Swaminathan
483*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* Q3 */
484*1fd5a2e1SPrashanth Swaminathan	ldr	q18, [x1, #32]
485*1fd5a2e1SPrashanth Swaminathan	b	compress_hfa_type_store_q3
486*1fd5a2e1SPrashanth Swaminathan	nop
487*1fd5a2e1SPrashanth Swaminathan
488*1fd5a2e1SPrashanth Swaminathan	ldp	q16, q17, [x1]		/* Q2 */
489*1fd5a2e1SPrashanth Swaminathan	stp	q16, q17, [x0]
490*1fd5a2e1SPrashanth Swaminathan	ret
491*1fd5a2e1SPrashanth Swaminathan	nop
492*1fd5a2e1SPrashanth Swaminathan
493*1fd5a2e1SPrashanth Swaminathan	ldr	q16, [x1]		/* Q1 */
494*1fd5a2e1SPrashanth Swaminathan	str	q16, [x0]
495*1fd5a2e1SPrashanth Swaminathan	ret
496*1fd5a2e1SPrashanth Swaminathan
497*1fd5a2e1SPrashanth Swaminathancompress_hfa_type_store_q4
498*1fd5a2e1SPrashanth Swaminathan	str	q19, [x0, #48]
499*1fd5a2e1SPrashanth Swaminathancompress_hfa_type_store_q3
500*1fd5a2e1SPrashanth Swaminathan	str	q18, [x0, #32]
501*1fd5a2e1SPrashanth Swaminathan	stp	q16, q17, [x0]
502*1fd5a2e1SPrashanth Swaminathan	ret
503*1fd5a2e1SPrashanth Swaminathan
504*1fd5a2e1SPrashanth Swaminathan	LEAF_END	compress_hfa_type
505*1fd5a2e1SPrashanth Swaminathan
506*1fd5a2e1SPrashanth Swaminathan	END