xref: /aosp_15_r20/external/libffi/src/microblaze/sysv.S (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
1*1fd5a2e1SPrashanth Swaminathan/* -----------------------------------------------------------------------
2*1fd5a2e1SPrashanth Swaminathan   sysv.S - Copyright (c) 2012, 2013 Xilinx, Inc
3*1fd5a2e1SPrashanth Swaminathan
4*1fd5a2e1SPrashanth Swaminathan   MicroBlaze Foreign Function Interface
5*1fd5a2e1SPrashanth Swaminathan
6*1fd5a2e1SPrashanth Swaminathan   Permission is hereby granted, free of charge, to any person obtaining
7*1fd5a2e1SPrashanth Swaminathan   a copy of this software and associated documentation files (the
8*1fd5a2e1SPrashanth Swaminathan   ``Software''), to deal in the Software without restriction, including
9*1fd5a2e1SPrashanth Swaminathan   without limitation the rights to use, copy, modify, merge, publish,
10*1fd5a2e1SPrashanth Swaminathan   distribute, sublicense, and/or sell copies of the Software, and to
11*1fd5a2e1SPrashanth Swaminathan   permit persons to whom the Software is furnished to do so, subject to
12*1fd5a2e1SPrashanth Swaminathan   the following conditions:
13*1fd5a2e1SPrashanth Swaminathan
14*1fd5a2e1SPrashanth Swaminathan   The above copyright notice and this permission notice shall be included
15*1fd5a2e1SPrashanth Swaminathan   in all copies or substantial portions of the Software.
16*1fd5a2e1SPrashanth Swaminathan
17*1fd5a2e1SPrashanth Swaminathan   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18*1fd5a2e1SPrashanth Swaminathan   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19*1fd5a2e1SPrashanth Swaminathan   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20*1fd5a2e1SPrashanth Swaminathan   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21*1fd5a2e1SPrashanth Swaminathan   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22*1fd5a2e1SPrashanth Swaminathan   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23*1fd5a2e1SPrashanth Swaminathan   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24*1fd5a2e1SPrashanth Swaminathan   DEALINGS IN THE SOFTWARE.
25*1fd5a2e1SPrashanth Swaminathan   ----------------------------------------------------------------------- */
26*1fd5a2e1SPrashanth Swaminathan
27*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM
28*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h>
29*1fd5a2e1SPrashanth Swaminathan#include <ffi.h>
30*1fd5a2e1SPrashanth Swaminathan
31*1fd5a2e1SPrashanth Swaminathan	/*
32*1fd5a2e1SPrashanth Swaminathan	 * arg[0] (r5)  = ffi_prep_args,
33*1fd5a2e1SPrashanth Swaminathan	 * arg[1] (r6)  = &ecif,
34*1fd5a2e1SPrashanth Swaminathan	 * arg[2] (r7)  = cif->bytes,
35*1fd5a2e1SPrashanth Swaminathan	 * arg[3] (r8)  = cif->flags,
36*1fd5a2e1SPrashanth Swaminathan	 * arg[4] (r9)  = ecif.rvalue,
37*1fd5a2e1SPrashanth Swaminathan	 * arg[5] (r10) = fn
38*1fd5a2e1SPrashanth Swaminathan	 * arg[6] (sp[0]) = cif->rtype->type
39*1fd5a2e1SPrashanth Swaminathan	 * arg[7] (sp[4]) = cif->rtype->size
40*1fd5a2e1SPrashanth Swaminathan	 */
41*1fd5a2e1SPrashanth Swaminathan	.text
42*1fd5a2e1SPrashanth Swaminathan	.globl ffi_call_SYSV
43*1fd5a2e1SPrashanth Swaminathan	.type ffi_call_SYSV, @function
44*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV:
45*1fd5a2e1SPrashanth Swaminathan	/* push callee saves */
46*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, -20
47*1fd5a2e1SPrashanth Swaminathan	swi r19, r1, 0 /* Frame Pointer */
48*1fd5a2e1SPrashanth Swaminathan	swi r20, r1, 4 /* PIC register */
49*1fd5a2e1SPrashanth Swaminathan	swi r21, r1, 8 /* PIC register */
50*1fd5a2e1SPrashanth Swaminathan	swi r22, r1, 12 /* save for locals */
51*1fd5a2e1SPrashanth Swaminathan	swi r23, r1, 16 /* save for locals */
52*1fd5a2e1SPrashanth Swaminathan
53*1fd5a2e1SPrashanth Swaminathan	/* save the r5-r10 registers in the stack */
54*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, -24 /* increment sp to store 6x 32-bit words */
55*1fd5a2e1SPrashanth Swaminathan	swi r5, r1, 0
56*1fd5a2e1SPrashanth Swaminathan	swi r6, r1, 4
57*1fd5a2e1SPrashanth Swaminathan	swi r7, r1, 8
58*1fd5a2e1SPrashanth Swaminathan	swi r8, r1, 12
59*1fd5a2e1SPrashanth Swaminathan	swi r9, r1, 16
60*1fd5a2e1SPrashanth Swaminathan	swi r10, r1, 20
61*1fd5a2e1SPrashanth Swaminathan
62*1fd5a2e1SPrashanth Swaminathan	/* save function pointer */
63*1fd5a2e1SPrashanth Swaminathan	addik r3, r5, 0 /* copy ffi_prep_args into r3 */
64*1fd5a2e1SPrashanth Swaminathan	addik r22, r1, 0 /* save sp for unallocated args into r22 (callee-saved) */
65*1fd5a2e1SPrashanth Swaminathan	addik r23, r10, 0 /* save function address into r23 (callee-saved) */
66*1fd5a2e1SPrashanth Swaminathan
67*1fd5a2e1SPrashanth Swaminathan	/* prepare stack with allocation for n (bytes = r7) args */
68*1fd5a2e1SPrashanth Swaminathan	rsub r1, r7, r1 /* subtract bytes from sp */
69*1fd5a2e1SPrashanth Swaminathan
70*1fd5a2e1SPrashanth Swaminathan	/* prep args for ffi_prep_args call */
71*1fd5a2e1SPrashanth Swaminathan	addik r5, r1, 0 /* store stack pointer into arg[0] */
72*1fd5a2e1SPrashanth Swaminathan	/* r6 still holds ecif for arg[1] */
73*1fd5a2e1SPrashanth Swaminathan
74*1fd5a2e1SPrashanth Swaminathan	/* Call ffi_prep_args(stack, &ecif). */
75*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, -4
76*1fd5a2e1SPrashanth Swaminathan	swi r15, r1, 0 /* store the link register in the frame */
77*1fd5a2e1SPrashanth Swaminathan	brald r15, r3
78*1fd5a2e1SPrashanth Swaminathan	nop /* branch has delay slot */
79*1fd5a2e1SPrashanth Swaminathan	lwi r15, r1, 0
80*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, 4 /* restore the link register from the frame */
81*1fd5a2e1SPrashanth Swaminathan	/* returns calling stack pointer location */
82*1fd5a2e1SPrashanth Swaminathan
83*1fd5a2e1SPrashanth Swaminathan	/* prepare args for fn call, prep_args populates them onto the stack */
84*1fd5a2e1SPrashanth Swaminathan	lwi r5, r1, 0 /* arg[0] */
85*1fd5a2e1SPrashanth Swaminathan	lwi r6, r1, 4 /* arg[1] */
86*1fd5a2e1SPrashanth Swaminathan	lwi r7, r1, 8 /* arg[2] */
87*1fd5a2e1SPrashanth Swaminathan	lwi r8, r1, 12 /* arg[3] */
88*1fd5a2e1SPrashanth Swaminathan	lwi r9, r1, 16 /* arg[4] */
89*1fd5a2e1SPrashanth Swaminathan	lwi r10, r1, 20 /* arg[5] */
90*1fd5a2e1SPrashanth Swaminathan
91*1fd5a2e1SPrashanth Swaminathan	/* call (fn) (...). */
92*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, -4
93*1fd5a2e1SPrashanth Swaminathan	swi r15, r1, 0 /* store the link register in the frame */
94*1fd5a2e1SPrashanth Swaminathan	brald r15, r23
95*1fd5a2e1SPrashanth Swaminathan	nop /* branch has delay slot */
96*1fd5a2e1SPrashanth Swaminathan	lwi r15, r1, 0
97*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, 4 /* restore the link register from the frame */
98*1fd5a2e1SPrashanth Swaminathan
99*1fd5a2e1SPrashanth Swaminathan	/* Remove the space we pushed for the args. */
100*1fd5a2e1SPrashanth Swaminathan	addik r1, r22, 0 /* restore old SP */
101*1fd5a2e1SPrashanth Swaminathan
102*1fd5a2e1SPrashanth Swaminathan	/* restore this functions parameters */
103*1fd5a2e1SPrashanth Swaminathan	lwi r5, r1, 0 /* arg[0] */
104*1fd5a2e1SPrashanth Swaminathan	lwi r6, r1, 4 /* arg[1] */
105*1fd5a2e1SPrashanth Swaminathan	lwi r7, r1, 8 /* arg[2] */
106*1fd5a2e1SPrashanth Swaminathan	lwi r8, r1, 12 /* arg[3] */
107*1fd5a2e1SPrashanth Swaminathan	lwi r9, r1, 16 /* arg[4] */
108*1fd5a2e1SPrashanth Swaminathan	lwi r10, r1, 20 /* arg[5] */
109*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, 24 /* decrement sp to de-allocate 6x 32-bit words */
110*1fd5a2e1SPrashanth Swaminathan
111*1fd5a2e1SPrashanth Swaminathan	/* If the return value pointer is NULL, assume no return value. */
112*1fd5a2e1SPrashanth Swaminathan	beqi r9, ffi_call_SYSV_end
113*1fd5a2e1SPrashanth Swaminathan
114*1fd5a2e1SPrashanth Swaminathan	lwi r22, r1, 48 /* get return type (20 for locals + 28 for arg[6]) */
115*1fd5a2e1SPrashanth Swaminathan	lwi r23, r1, 52 /* get return size (20 for locals + 32 for arg[7])  */
116*1fd5a2e1SPrashanth Swaminathan
117*1fd5a2e1SPrashanth Swaminathan	/* Check if return type is actually a struct, do nothing */
118*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r22, FFI_TYPE_STRUCT
119*1fd5a2e1SPrashanth Swaminathan	beqi r11, ffi_call_SYSV_end
120*1fd5a2e1SPrashanth Swaminathan
121*1fd5a2e1SPrashanth Swaminathan	/* Return 8bit */
122*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r23, 1
123*1fd5a2e1SPrashanth Swaminathan	beqi r11, ffi_call_SYSV_store8
124*1fd5a2e1SPrashanth Swaminathan
125*1fd5a2e1SPrashanth Swaminathan	/* Return 16bit */
126*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r23, 2
127*1fd5a2e1SPrashanth Swaminathan	beqi r11, ffi_call_SYSV_store16
128*1fd5a2e1SPrashanth Swaminathan
129*1fd5a2e1SPrashanth Swaminathan	/* Return 32bit */
130*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r23, 4
131*1fd5a2e1SPrashanth Swaminathan	beqi r11, ffi_call_SYSV_store32
132*1fd5a2e1SPrashanth Swaminathan
133*1fd5a2e1SPrashanth Swaminathan	/* Return 64bit */
134*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r23, 8
135*1fd5a2e1SPrashanth Swaminathan	beqi r11, ffi_call_SYSV_store64
136*1fd5a2e1SPrashanth Swaminathan
137*1fd5a2e1SPrashanth Swaminathan	/* Didn't match anything */
138*1fd5a2e1SPrashanth Swaminathan	bri ffi_call_SYSV_end
139*1fd5a2e1SPrashanth Swaminathan
140*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV_store64:
141*1fd5a2e1SPrashanth Swaminathan	swi r3, r9, 0 /* store word r3 into return value */
142*1fd5a2e1SPrashanth Swaminathan	swi r4, r9, 4 /* store word r4 into return value */
143*1fd5a2e1SPrashanth Swaminathan	bri ffi_call_SYSV_end
144*1fd5a2e1SPrashanth Swaminathan
145*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV_store32:
146*1fd5a2e1SPrashanth Swaminathan	swi r3, r9, 0 /* store word r3 into return value */
147*1fd5a2e1SPrashanth Swaminathan	bri ffi_call_SYSV_end
148*1fd5a2e1SPrashanth Swaminathan
149*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV_store16:
150*1fd5a2e1SPrashanth Swaminathan#ifdef __BIG_ENDIAN__
151*1fd5a2e1SPrashanth Swaminathan	shi r3, r9, 2 /* store half-word r3 into return value */
152*1fd5a2e1SPrashanth Swaminathan#else
153*1fd5a2e1SPrashanth Swaminathan	shi r3, r9, 0 /* store half-word r3 into return value */
154*1fd5a2e1SPrashanth Swaminathan#endif
155*1fd5a2e1SPrashanth Swaminathan	bri ffi_call_SYSV_end
156*1fd5a2e1SPrashanth Swaminathan
157*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV_store8:
158*1fd5a2e1SPrashanth Swaminathan#ifdef __BIG_ENDIAN__
159*1fd5a2e1SPrashanth Swaminathan	sbi r3, r9, 3 /* store byte r3 into return value */
160*1fd5a2e1SPrashanth Swaminathan#else
161*1fd5a2e1SPrashanth Swaminathan	sbi r3, r9, 0 /* store byte r3 into return value */
162*1fd5a2e1SPrashanth Swaminathan#endif
163*1fd5a2e1SPrashanth Swaminathan	bri ffi_call_SYSV_end
164*1fd5a2e1SPrashanth Swaminathan
165*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV_end:
166*1fd5a2e1SPrashanth Swaminathan	/* callee restores */
167*1fd5a2e1SPrashanth Swaminathan	lwi r19, r1, 0 /* frame pointer */
168*1fd5a2e1SPrashanth Swaminathan	lwi r20, r1, 4 /* PIC register */
169*1fd5a2e1SPrashanth Swaminathan	lwi r21, r1, 8 /* PIC register */
170*1fd5a2e1SPrashanth Swaminathan	lwi r22, r1, 12
171*1fd5a2e1SPrashanth Swaminathan	lwi r23, r1, 16
172*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, 20
173*1fd5a2e1SPrashanth Swaminathan
174*1fd5a2e1SPrashanth Swaminathan	/* return from sub-routine (with delay slot) */
175*1fd5a2e1SPrashanth Swaminathan	rtsd r15, 8
176*1fd5a2e1SPrashanth Swaminathan	nop
177*1fd5a2e1SPrashanth Swaminathan
178*1fd5a2e1SPrashanth Swaminathan	.size ffi_call_SYSV, . - ffi_call_SYSV
179*1fd5a2e1SPrashanth Swaminathan
180*1fd5a2e1SPrashanth Swaminathan/* ------------------------------------------------------------------------- */
181*1fd5a2e1SPrashanth Swaminathan
182*1fd5a2e1SPrashanth Swaminathan	/*
183*1fd5a2e1SPrashanth Swaminathan	 * args passed into this function, are passed down to the callee.
184*1fd5a2e1SPrashanth Swaminathan	 * this function is the target of the closure trampoline, as such r12 is
185*1fd5a2e1SPrashanth Swaminathan	 * a pointer to the closure object.
186*1fd5a2e1SPrashanth Swaminathan	 */
187*1fd5a2e1SPrashanth Swaminathan	.text
188*1fd5a2e1SPrashanth Swaminathan	.globl ffi_closure_SYSV
189*1fd5a2e1SPrashanth Swaminathan	.type ffi_closure_SYSV, @function
190*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV:
191*1fd5a2e1SPrashanth Swaminathan	/* push callee saves */
192*1fd5a2e1SPrashanth Swaminathan	addik r11, r1, 28 /* save stack args start location (excluding regs/link) */
193*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, -12
194*1fd5a2e1SPrashanth Swaminathan	swi r19, r1, 0 /* Frame Pointer */
195*1fd5a2e1SPrashanth Swaminathan	swi r20, r1, 4 /* PIC register */
196*1fd5a2e1SPrashanth Swaminathan	swi r21, r1, 8 /* PIC register */
197*1fd5a2e1SPrashanth Swaminathan
198*1fd5a2e1SPrashanth Swaminathan	/* store register args on stack */
199*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, -24
200*1fd5a2e1SPrashanth Swaminathan	swi r5, r1, 0
201*1fd5a2e1SPrashanth Swaminathan	swi r6, r1, 4
202*1fd5a2e1SPrashanth Swaminathan	swi r7, r1, 8
203*1fd5a2e1SPrashanth Swaminathan	swi r8, r1, 12
204*1fd5a2e1SPrashanth Swaminathan	swi r9, r1, 16
205*1fd5a2e1SPrashanth Swaminathan	swi r10, r1, 20
206*1fd5a2e1SPrashanth Swaminathan
207*1fd5a2e1SPrashanth Swaminathan	/* setup args */
208*1fd5a2e1SPrashanth Swaminathan	addik r5, r1, 0 /* register_args */
209*1fd5a2e1SPrashanth Swaminathan	addik r6, r11, 0 /* stack_args */
210*1fd5a2e1SPrashanth Swaminathan	addik r7, r12, 0 /* closure object */
211*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, -8 /* allocate return value */
212*1fd5a2e1SPrashanth Swaminathan	addik r8, r1, 0 /* void* rvalue */
213*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, -8 /* allocate for return type/size values */
214*1fd5a2e1SPrashanth Swaminathan	addik r9, r1, 0 /* void* rtype */
215*1fd5a2e1SPrashanth Swaminathan	addik r10, r1, 4 /* void* rsize */
216*1fd5a2e1SPrashanth Swaminathan
217*1fd5a2e1SPrashanth Swaminathan	/* call the wrap_call function */
218*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, -28 /* allocate args + link reg */
219*1fd5a2e1SPrashanth Swaminathan	swi r15, r1, 0 /* store the link register in the frame */
220*1fd5a2e1SPrashanth Swaminathan	brald r15, r3
221*1fd5a2e1SPrashanth Swaminathan	nop /* branch has delay slot */
222*1fd5a2e1SPrashanth Swaminathan	lwi r15, r1, 0
223*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, 28 /* restore the link register from the frame */
224*1fd5a2e1SPrashanth Swaminathan
225*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_prepare_return:
226*1fd5a2e1SPrashanth Swaminathan	lwi r9, r1, 0 /* rtype */
227*1fd5a2e1SPrashanth Swaminathan	lwi r10, r1, 4 /* rsize */
228*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, 8 /* de-allocate return info values */
229*1fd5a2e1SPrashanth Swaminathan
230*1fd5a2e1SPrashanth Swaminathan	/* Check if return type is actually a struct, store 4 bytes */
231*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r9, FFI_TYPE_STRUCT
232*1fd5a2e1SPrashanth Swaminathan	beqi r11, ffi_closure_SYSV_store32
233*1fd5a2e1SPrashanth Swaminathan
234*1fd5a2e1SPrashanth Swaminathan	/* Return 8bit */
235*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r10, 1
236*1fd5a2e1SPrashanth Swaminathan	beqi r11, ffi_closure_SYSV_store8
237*1fd5a2e1SPrashanth Swaminathan
238*1fd5a2e1SPrashanth Swaminathan	/* Return 16bit */
239*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r10, 2
240*1fd5a2e1SPrashanth Swaminathan	beqi r11, ffi_closure_SYSV_store16
241*1fd5a2e1SPrashanth Swaminathan
242*1fd5a2e1SPrashanth Swaminathan	/* Return 32bit */
243*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r10, 4
244*1fd5a2e1SPrashanth Swaminathan	beqi r11, ffi_closure_SYSV_store32
245*1fd5a2e1SPrashanth Swaminathan
246*1fd5a2e1SPrashanth Swaminathan	/* Return 64bit */
247*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r10, 8
248*1fd5a2e1SPrashanth Swaminathan	beqi r11, ffi_closure_SYSV_store64
249*1fd5a2e1SPrashanth Swaminathan
250*1fd5a2e1SPrashanth Swaminathan	/* Didn't match anything */
251*1fd5a2e1SPrashanth Swaminathan	bri ffi_closure_SYSV_end
252*1fd5a2e1SPrashanth Swaminathan
253*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_store64:
254*1fd5a2e1SPrashanth Swaminathan	lwi r3, r1, 0 /* store word r3 into return value */
255*1fd5a2e1SPrashanth Swaminathan	lwi r4, r1, 4 /* store word r4 into return value */
256*1fd5a2e1SPrashanth Swaminathan	/* 64 bits == 2 words, no sign extend occurs */
257*1fd5a2e1SPrashanth Swaminathan	bri ffi_closure_SYSV_end
258*1fd5a2e1SPrashanth Swaminathan
259*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_store32:
260*1fd5a2e1SPrashanth Swaminathan	lwi r3, r1, 0 /* store word r3 into return value */
261*1fd5a2e1SPrashanth Swaminathan	/* 32 bits == 1 word, no sign extend occurs */
262*1fd5a2e1SPrashanth Swaminathan	bri ffi_closure_SYSV_end
263*1fd5a2e1SPrashanth Swaminathan
264*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_store16:
265*1fd5a2e1SPrashanth Swaminathan#ifdef __BIG_ENDIAN__
266*1fd5a2e1SPrashanth Swaminathan	lhui r3, r1, 2 /* store half-word r3 into return value */
267*1fd5a2e1SPrashanth Swaminathan#else
268*1fd5a2e1SPrashanth Swaminathan	lhui r3, r1, 0 /* store half-word r3 into return value */
269*1fd5a2e1SPrashanth Swaminathan#endif
270*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r9, FFI_TYPE_SINT16
271*1fd5a2e1SPrashanth Swaminathan	bnei r11, ffi_closure_SYSV_end
272*1fd5a2e1SPrashanth Swaminathan	sext16 r3, r3 /* fix sign extend of sint8 */
273*1fd5a2e1SPrashanth Swaminathan	bri ffi_closure_SYSV_end
274*1fd5a2e1SPrashanth Swaminathan
275*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_store8:
276*1fd5a2e1SPrashanth Swaminathan#ifdef __BIG_ENDIAN__
277*1fd5a2e1SPrashanth Swaminathan	lbui r3, r1, 3 /* store byte r3 into return value */
278*1fd5a2e1SPrashanth Swaminathan#else
279*1fd5a2e1SPrashanth Swaminathan	lbui r3, r1, 0 /* store byte r3 into return value */
280*1fd5a2e1SPrashanth Swaminathan#endif
281*1fd5a2e1SPrashanth Swaminathan	rsubi r11, r9, FFI_TYPE_SINT8
282*1fd5a2e1SPrashanth Swaminathan	bnei r11, ffi_closure_SYSV_end
283*1fd5a2e1SPrashanth Swaminathan	sext8 r3, r3 /* fix sign extend of sint8 */
284*1fd5a2e1SPrashanth Swaminathan	bri ffi_closure_SYSV_end
285*1fd5a2e1SPrashanth Swaminathan
286*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_end:
287*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, 8 /* de-allocate return value */
288*1fd5a2e1SPrashanth Swaminathan
289*1fd5a2e1SPrashanth Swaminathan	/* de-allocate stored args */
290*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, 24
291*1fd5a2e1SPrashanth Swaminathan
292*1fd5a2e1SPrashanth Swaminathan	/* callee restores */
293*1fd5a2e1SPrashanth Swaminathan	lwi r19, r1, 0 /* frame pointer */
294*1fd5a2e1SPrashanth Swaminathan	lwi r20, r1, 4 /* PIC register */
295*1fd5a2e1SPrashanth Swaminathan	lwi r21, r1, 8 /* PIC register */
296*1fd5a2e1SPrashanth Swaminathan	addik r1, r1, 12
297*1fd5a2e1SPrashanth Swaminathan
298*1fd5a2e1SPrashanth Swaminathan	/* return from sub-routine (with delay slot) */
299*1fd5a2e1SPrashanth Swaminathan	rtsd r15, 8
300*1fd5a2e1SPrashanth Swaminathan	nop
301*1fd5a2e1SPrashanth Swaminathan
302*1fd5a2e1SPrashanth Swaminathan	.size ffi_closure_SYSV, . - ffi_closure_SYSV
303