xref: /aosp_15_r20/external/libffi/src/mips/n32.S (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
1*1fd5a2e1SPrashanth Swaminathan/* -----------------------------------------------------------------------
2*1fd5a2e1SPrashanth Swaminathan   n32.S - Copyright (c) 1996, 1998, 2005, 2007, 2009, 2010  Red Hat, Inc.
3*1fd5a2e1SPrashanth Swaminathan
4*1fd5a2e1SPrashanth Swaminathan   MIPS 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/* Only build this code if we are compiling for n32 */
32*1fd5a2e1SPrashanth Swaminathan
33*1fd5a2e1SPrashanth Swaminathan#if defined(FFI_MIPS_N32)
34*1fd5a2e1SPrashanth Swaminathan
35*1fd5a2e1SPrashanth Swaminathan#define callback a0
36*1fd5a2e1SPrashanth Swaminathan#define bytes	 a2
37*1fd5a2e1SPrashanth Swaminathan#define flags	 a3
38*1fd5a2e1SPrashanth Swaminathan#define raddr    a4
39*1fd5a2e1SPrashanth Swaminathan#define fn       a5
40*1fd5a2e1SPrashanth Swaminathan#define closure  a6
41*1fd5a2e1SPrashanth Swaminathan
42*1fd5a2e1SPrashanth Swaminathan/* Note: to keep stack 16 byte aligned we need even number slots
43*1fd5a2e1SPrashanth Swaminathan   used 9 slots here
44*1fd5a2e1SPrashanth Swaminathan*/
45*1fd5a2e1SPrashanth Swaminathan#define SIZEOF_FRAME	( 10 * FFI_SIZEOF_ARG )
46*1fd5a2e1SPrashanth Swaminathan
47*1fd5a2e1SPrashanth Swaminathan#ifdef __GNUC__
48*1fd5a2e1SPrashanth Swaminathan	.abicalls
49*1fd5a2e1SPrashanth Swaminathan#endif
50*1fd5a2e1SPrashanth Swaminathan#if !defined(__mips_isa_rev) || (__mips_isa_rev<6)
51*1fd5a2e1SPrashanth Swaminathan	.set mips4
52*1fd5a2e1SPrashanth Swaminathan#endif
53*1fd5a2e1SPrashanth Swaminathan	.text
54*1fd5a2e1SPrashanth Swaminathan	.align	2
55*1fd5a2e1SPrashanth Swaminathan	.globl	ffi_call_N32
56*1fd5a2e1SPrashanth Swaminathan	.ent	ffi_call_N32
57*1fd5a2e1SPrashanth Swaminathanffi_call_N32:
58*1fd5a2e1SPrashanth Swaminathan.LFB0:
59*1fd5a2e1SPrashanth Swaminathan	.frame	$fp, SIZEOF_FRAME, ra
60*1fd5a2e1SPrashanth Swaminathan	.mask	0xc0000000,-FFI_SIZEOF_ARG
61*1fd5a2e1SPrashanth Swaminathan	.fmask	0x00000000,0
62*1fd5a2e1SPrashanth Swaminathan
63*1fd5a2e1SPrashanth Swaminathan	# Prologue
64*1fd5a2e1SPrashanth Swaminathan	SUBU	$sp, SIZEOF_FRAME			# Frame size
65*1fd5a2e1SPrashanth Swaminathan.LCFI00:
66*1fd5a2e1SPrashanth Swaminathan	REG_S	$fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp)	# Save frame pointer
67*1fd5a2e1SPrashanth Swaminathan	REG_S	ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp)	# Save return address
68*1fd5a2e1SPrashanth Swaminathan.LCFI01:
69*1fd5a2e1SPrashanth Swaminathan	move	$fp, $sp
70*1fd5a2e1SPrashanth Swaminathan.LCFI02:
71*1fd5a2e1SPrashanth Swaminathan	move	t9, callback	# callback function pointer
72*1fd5a2e1SPrashanth Swaminathan	REG_S	bytes, 2*FFI_SIZEOF_ARG($fp) # bytes
73*1fd5a2e1SPrashanth Swaminathan	REG_S	flags, 3*FFI_SIZEOF_ARG($fp) # flags
74*1fd5a2e1SPrashanth Swaminathan	REG_S	raddr, 4*FFI_SIZEOF_ARG($fp) # raddr
75*1fd5a2e1SPrashanth Swaminathan	REG_S	fn,    5*FFI_SIZEOF_ARG($fp) # fn
76*1fd5a2e1SPrashanth Swaminathan	REG_S	closure, 6*FFI_SIZEOF_ARG($fp) # closure
77*1fd5a2e1SPrashanth Swaminathan
78*1fd5a2e1SPrashanth Swaminathan	# Allocate at least 4 words in the argstack
79*1fd5a2e1SPrashanth Swaminathan	move	v0, bytes
80*1fd5a2e1SPrashanth Swaminathan	bge	bytes, 4 * FFI_SIZEOF_ARG, bigger
81*1fd5a2e1SPrashanth Swaminathan	LI	v0, 4 * FFI_SIZEOF_ARG
82*1fd5a2e1SPrashanth Swaminathan	b	sixteen
83*1fd5a2e1SPrashanth Swaminathan
84*1fd5a2e1SPrashanth Swaminathan	bigger:
85*1fd5a2e1SPrashanth Swaminathan	ADDU	t4, v0, 2 * FFI_SIZEOF_ARG -1	# make sure it is aligned
86*1fd5a2e1SPrashanth Swaminathan	and	v0, t4, -2 * FFI_SIZEOF_ARG		# to a proper boundry.
87*1fd5a2e1SPrashanth Swaminathan
88*1fd5a2e1SPrashanth Swaminathansixteen:
89*1fd5a2e1SPrashanth Swaminathan	SUBU	$sp, $sp, v0	# move the stack pointer to reflect the
90*1fd5a2e1SPrashanth Swaminathan				# arg space
91*1fd5a2e1SPrashanth Swaminathan
92*1fd5a2e1SPrashanth Swaminathan	move	a0, $sp         # 4 * FFI_SIZEOF_ARG
93*1fd5a2e1SPrashanth Swaminathan	ADDU	a3, $fp, 3 * FFI_SIZEOF_ARG
94*1fd5a2e1SPrashanth Swaminathan
95*1fd5a2e1SPrashanth Swaminathan	# Call ffi_prep_args
96*1fd5a2e1SPrashanth Swaminathan	jal	t9
97*1fd5a2e1SPrashanth Swaminathan
98*1fd5a2e1SPrashanth Swaminathan	# Copy the stack pointer to t9
99*1fd5a2e1SPrashanth Swaminathan	move	t9, $sp
100*1fd5a2e1SPrashanth Swaminathan
101*1fd5a2e1SPrashanth Swaminathan	# Fix the stack if there are more than 8 64bit slots worth
102*1fd5a2e1SPrashanth Swaminathan	# of arguments.
103*1fd5a2e1SPrashanth Swaminathan
104*1fd5a2e1SPrashanth Swaminathan	# Load the number of bytes
105*1fd5a2e1SPrashanth Swaminathan	REG_L	t6, 2*FFI_SIZEOF_ARG($fp)
106*1fd5a2e1SPrashanth Swaminathan
107*1fd5a2e1SPrashanth Swaminathan	# Is it bigger than 8 * FFI_SIZEOF_ARG?
108*1fd5a2e1SPrashanth Swaminathan	daddiu	t8, t6, -(8 * FFI_SIZEOF_ARG)
109*1fd5a2e1SPrashanth Swaminathan	bltz	t8, loadregs
110*1fd5a2e1SPrashanth Swaminathan
111*1fd5a2e1SPrashanth Swaminathan	ADDU	t9, t9, t8
112*1fd5a2e1SPrashanth Swaminathan
113*1fd5a2e1SPrashanth Swaminathanloadregs:
114*1fd5a2e1SPrashanth Swaminathan
115*1fd5a2e1SPrashanth Swaminathan	REG_L	t6, 3*FFI_SIZEOF_ARG($fp)  # load the flags word into t6.
116*1fd5a2e1SPrashanth Swaminathan
117*1fd5a2e1SPrashanth Swaminathan#ifdef __mips_soft_float
118*1fd5a2e1SPrashanth Swaminathan	REG_L	a0, 0*FFI_SIZEOF_ARG(t9)
119*1fd5a2e1SPrashanth Swaminathan	REG_L	a1, 1*FFI_SIZEOF_ARG(t9)
120*1fd5a2e1SPrashanth Swaminathan	REG_L	a2, 2*FFI_SIZEOF_ARG(t9)
121*1fd5a2e1SPrashanth Swaminathan	REG_L	a3, 3*FFI_SIZEOF_ARG(t9)
122*1fd5a2e1SPrashanth Swaminathan	REG_L	a4, 4*FFI_SIZEOF_ARG(t9)
123*1fd5a2e1SPrashanth Swaminathan	REG_L	a5, 5*FFI_SIZEOF_ARG(t9)
124*1fd5a2e1SPrashanth Swaminathan	REG_L	a6, 6*FFI_SIZEOF_ARG(t9)
125*1fd5a2e1SPrashanth Swaminathan	REG_L	a7, 7*FFI_SIZEOF_ARG(t9)
126*1fd5a2e1SPrashanth Swaminathan#else
127*1fd5a2e1SPrashanth Swaminathan	and	t4, t6, ((1<<FFI_FLAG_BITS)-1)
128*1fd5a2e1SPrashanth Swaminathan	REG_L	a0, 0*FFI_SIZEOF_ARG(t9)
129*1fd5a2e1SPrashanth Swaminathan	beqz	t4, arg1_next
130*1fd5a2e1SPrashanth Swaminathan	bne	t4, FFI_TYPE_FLOAT, arg1_doublep
131*1fd5a2e1SPrashanth Swaminathan	l.s	$f12, 0*FFI_SIZEOF_ARG(t9)
132*1fd5a2e1SPrashanth Swaminathan	b	arg1_next
133*1fd5a2e1SPrashanth Swaminathanarg1_doublep:
134*1fd5a2e1SPrashanth Swaminathan	l.d	$f12, 0*FFI_SIZEOF_ARG(t9)
135*1fd5a2e1SPrashanth Swaminathanarg1_next:
136*1fd5a2e1SPrashanth Swaminathan
137*1fd5a2e1SPrashanth Swaminathan	SRL	t4, t6, 1*FFI_FLAG_BITS
138*1fd5a2e1SPrashanth Swaminathan	and	t4, ((1<<FFI_FLAG_BITS)-1)
139*1fd5a2e1SPrashanth Swaminathan	REG_L	a1, 1*FFI_SIZEOF_ARG(t9)
140*1fd5a2e1SPrashanth Swaminathan	beqz	t4, arg2_next
141*1fd5a2e1SPrashanth Swaminathan	bne	t4, FFI_TYPE_FLOAT, arg2_doublep
142*1fd5a2e1SPrashanth Swaminathan	l.s	$f13, 1*FFI_SIZEOF_ARG(t9)
143*1fd5a2e1SPrashanth Swaminathan	b	arg2_next
144*1fd5a2e1SPrashanth Swaminathanarg2_doublep:
145*1fd5a2e1SPrashanth Swaminathan	l.d	$f13, 1*FFI_SIZEOF_ARG(t9)
146*1fd5a2e1SPrashanth Swaminathanarg2_next:
147*1fd5a2e1SPrashanth Swaminathan
148*1fd5a2e1SPrashanth Swaminathan	SRL	t4, t6, 2*FFI_FLAG_BITS
149*1fd5a2e1SPrashanth Swaminathan	and	t4, ((1<<FFI_FLAG_BITS)-1)
150*1fd5a2e1SPrashanth Swaminathan	REG_L	a2, 2*FFI_SIZEOF_ARG(t9)
151*1fd5a2e1SPrashanth Swaminathan	beqz	t4, arg3_next
152*1fd5a2e1SPrashanth Swaminathan	bne	t4, FFI_TYPE_FLOAT, arg3_doublep
153*1fd5a2e1SPrashanth Swaminathan	l.s	$f14, 2*FFI_SIZEOF_ARG(t9)
154*1fd5a2e1SPrashanth Swaminathan	b	arg3_next
155*1fd5a2e1SPrashanth Swaminathanarg3_doublep:
156*1fd5a2e1SPrashanth Swaminathan	l.d	$f14, 2*FFI_SIZEOF_ARG(t9)
157*1fd5a2e1SPrashanth Swaminathanarg3_next:
158*1fd5a2e1SPrashanth Swaminathan
159*1fd5a2e1SPrashanth Swaminathan	SRL	t4, t6, 3*FFI_FLAG_BITS
160*1fd5a2e1SPrashanth Swaminathan	and	t4, ((1<<FFI_FLAG_BITS)-1)
161*1fd5a2e1SPrashanth Swaminathan	REG_L	a3, 3*FFI_SIZEOF_ARG(t9)
162*1fd5a2e1SPrashanth Swaminathan	beqz	t4, arg4_next
163*1fd5a2e1SPrashanth Swaminathan	bne	t4, FFI_TYPE_FLOAT, arg4_doublep
164*1fd5a2e1SPrashanth Swaminathan	l.s	$f15, 3*FFI_SIZEOF_ARG(t9)
165*1fd5a2e1SPrashanth Swaminathan	b	arg4_next
166*1fd5a2e1SPrashanth Swaminathanarg4_doublep:
167*1fd5a2e1SPrashanth Swaminathan	l.d	$f15, 3*FFI_SIZEOF_ARG(t9)
168*1fd5a2e1SPrashanth Swaminathanarg4_next:
169*1fd5a2e1SPrashanth Swaminathan
170*1fd5a2e1SPrashanth Swaminathan	SRL	t4, t6, 4*FFI_FLAG_BITS
171*1fd5a2e1SPrashanth Swaminathan	and	t4, ((1<<FFI_FLAG_BITS)-1)
172*1fd5a2e1SPrashanth Swaminathan	REG_L	a4, 4*FFI_SIZEOF_ARG(t9)
173*1fd5a2e1SPrashanth Swaminathan	beqz	t4, arg5_next
174*1fd5a2e1SPrashanth Swaminathan	bne	t4, FFI_TYPE_FLOAT, arg5_doublep
175*1fd5a2e1SPrashanth Swaminathan	l.s	$f16, 4*FFI_SIZEOF_ARG(t9)
176*1fd5a2e1SPrashanth Swaminathan	b	arg5_next
177*1fd5a2e1SPrashanth Swaminathanarg5_doublep:
178*1fd5a2e1SPrashanth Swaminathan	l.d	$f16, 4*FFI_SIZEOF_ARG(t9)
179*1fd5a2e1SPrashanth Swaminathanarg5_next:
180*1fd5a2e1SPrashanth Swaminathan
181*1fd5a2e1SPrashanth Swaminathan	SRL	t4, t6, 5*FFI_FLAG_BITS
182*1fd5a2e1SPrashanth Swaminathan	and	t4, ((1<<FFI_FLAG_BITS)-1)
183*1fd5a2e1SPrashanth Swaminathan	REG_L	a5, 5*FFI_SIZEOF_ARG(t9)
184*1fd5a2e1SPrashanth Swaminathan	beqz	t4, arg6_next
185*1fd5a2e1SPrashanth Swaminathan	bne	t4, FFI_TYPE_FLOAT, arg6_doublep
186*1fd5a2e1SPrashanth Swaminathan	l.s	$f17, 5*FFI_SIZEOF_ARG(t9)
187*1fd5a2e1SPrashanth Swaminathan	b	arg6_next
188*1fd5a2e1SPrashanth Swaminathanarg6_doublep:
189*1fd5a2e1SPrashanth Swaminathan	l.d	$f17, 5*FFI_SIZEOF_ARG(t9)
190*1fd5a2e1SPrashanth Swaminathanarg6_next:
191*1fd5a2e1SPrashanth Swaminathan
192*1fd5a2e1SPrashanth Swaminathan	SRL	t4, t6, 6*FFI_FLAG_BITS
193*1fd5a2e1SPrashanth Swaminathan	and	t4, ((1<<FFI_FLAG_BITS)-1)
194*1fd5a2e1SPrashanth Swaminathan	REG_L	a6, 6*FFI_SIZEOF_ARG(t9)
195*1fd5a2e1SPrashanth Swaminathan	beqz	t4, arg7_next
196*1fd5a2e1SPrashanth Swaminathan	bne	t4, FFI_TYPE_FLOAT, arg7_doublep
197*1fd5a2e1SPrashanth Swaminathan	l.s	$f18, 6*FFI_SIZEOF_ARG(t9)
198*1fd5a2e1SPrashanth Swaminathan	b	arg7_next
199*1fd5a2e1SPrashanth Swaminathanarg7_doublep:
200*1fd5a2e1SPrashanth Swaminathan	l.d	$f18, 6*FFI_SIZEOF_ARG(t9)
201*1fd5a2e1SPrashanth Swaminathanarg7_next:
202*1fd5a2e1SPrashanth Swaminathan
203*1fd5a2e1SPrashanth Swaminathan	SRL	t4, t6, 7*FFI_FLAG_BITS
204*1fd5a2e1SPrashanth Swaminathan	and	t4, ((1<<FFI_FLAG_BITS)-1)
205*1fd5a2e1SPrashanth Swaminathan	REG_L	a7, 7*FFI_SIZEOF_ARG(t9)
206*1fd5a2e1SPrashanth Swaminathan	beqz	t4, arg8_next
207*1fd5a2e1SPrashanth Swaminathan	bne	t4, FFI_TYPE_FLOAT, arg8_doublep
208*1fd5a2e1SPrashanth Swaminathan 	l.s	$f19, 7*FFI_SIZEOF_ARG(t9)
209*1fd5a2e1SPrashanth Swaminathan	b	arg8_next
210*1fd5a2e1SPrashanth Swaminathanarg8_doublep:
211*1fd5a2e1SPrashanth Swaminathan 	l.d	$f19, 7*FFI_SIZEOF_ARG(t9)
212*1fd5a2e1SPrashanth Swaminathanarg8_next:
213*1fd5a2e1SPrashanth Swaminathan#endif
214*1fd5a2e1SPrashanth Swaminathan
215*1fd5a2e1SPrashanth Swaminathancallit:
216*1fd5a2e1SPrashanth Swaminathan	# Load the function pointer
217*1fd5a2e1SPrashanth Swaminathan	REG_L	t9, 5*FFI_SIZEOF_ARG($fp)
218*1fd5a2e1SPrashanth Swaminathan
219*1fd5a2e1SPrashanth Swaminathan	# install the static chain(t7=$15)
220*1fd5a2e1SPrashanth Swaminathan	REG_L	t7, 6*FFI_SIZEOF_ARG($fp)
221*1fd5a2e1SPrashanth Swaminathan
222*1fd5a2e1SPrashanth Swaminathan	# If the return value pointer is NULL, assume no return value.
223*1fd5a2e1SPrashanth Swaminathan	REG_L	t5, 4*FFI_SIZEOF_ARG($fp)
224*1fd5a2e1SPrashanth Swaminathan	beqz	t5, noretval
225*1fd5a2e1SPrashanth Swaminathan
226*1fd5a2e1SPrashanth Swaminathan	# Shift the return type flag over
227*1fd5a2e1SPrashanth Swaminathan	SRL	t6, 8*FFI_FLAG_BITS
228*1fd5a2e1SPrashanth Swaminathan
229*1fd5a2e1SPrashanth Swaminathan	beq	t6, FFI_TYPE_SINT32, retint
230*1fd5a2e1SPrashanth Swaminathan	bne     t6, FFI_TYPE_INT, retfloat
231*1fd5a2e1SPrashanth Swaminathanretint:
232*1fd5a2e1SPrashanth Swaminathan	jal	t9
233*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
234*1fd5a2e1SPrashanth Swaminathan	REG_S	v0, 0(t4)
235*1fd5a2e1SPrashanth Swaminathan	b	epilogue
236*1fd5a2e1SPrashanth Swaminathan
237*1fd5a2e1SPrashanth Swaminathanretfloat:
238*1fd5a2e1SPrashanth Swaminathan#ifndef __mips_soft_float
239*1fd5a2e1SPrashanth Swaminathan	bne     t6, FFI_TYPE_FLOAT, retdouble
240*1fd5a2e1SPrashanth Swaminathan	jal	t9
241*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
242*1fd5a2e1SPrashanth Swaminathan	s.s	$f0, 0(t4)
243*1fd5a2e1SPrashanth Swaminathan	b	epilogue
244*1fd5a2e1SPrashanth Swaminathan
245*1fd5a2e1SPrashanth Swaminathanretdouble:
246*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_DOUBLE, retstruct_d
247*1fd5a2e1SPrashanth Swaminathan	jal	t9
248*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
249*1fd5a2e1SPrashanth Swaminathan	s.d	$f0, 0(t4)
250*1fd5a2e1SPrashanth Swaminathan	b	epilogue
251*1fd5a2e1SPrashanth Swaminathan
252*1fd5a2e1SPrashanth Swaminathanretstruct_d:
253*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_D, retstruct_f
254*1fd5a2e1SPrashanth Swaminathan	jal	t9
255*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
256*1fd5a2e1SPrashanth Swaminathan	s.d	$f0, 0(t4)
257*1fd5a2e1SPrashanth Swaminathan	b	epilogue
258*1fd5a2e1SPrashanth Swaminathan
259*1fd5a2e1SPrashanth Swaminathanretstruct_f:
260*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_F, retstruct_d_d
261*1fd5a2e1SPrashanth Swaminathan	jal	t9
262*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
263*1fd5a2e1SPrashanth Swaminathan	s.s	$f0, 0(t4)
264*1fd5a2e1SPrashanth Swaminathan	b	epilogue
265*1fd5a2e1SPrashanth Swaminathan
266*1fd5a2e1SPrashanth Swaminathanretstruct_d_d:
267*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_DD, retstruct_f_f
268*1fd5a2e1SPrashanth Swaminathan	jal	t9
269*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
270*1fd5a2e1SPrashanth Swaminathan	s.d	$f0, 0(t4)
271*1fd5a2e1SPrashanth Swaminathan	s.d	$f2, 8(t4)
272*1fd5a2e1SPrashanth Swaminathan	b	epilogue
273*1fd5a2e1SPrashanth Swaminathan
274*1fd5a2e1SPrashanth Swaminathanretstruct_f_f:
275*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_FF, retstruct_d_f
276*1fd5a2e1SPrashanth Swaminathan	jal	t9
277*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
278*1fd5a2e1SPrashanth Swaminathan	s.s	$f0, 0(t4)
279*1fd5a2e1SPrashanth Swaminathan	s.s	$f2, 4(t4)
280*1fd5a2e1SPrashanth Swaminathan	b	epilogue
281*1fd5a2e1SPrashanth Swaminathan
282*1fd5a2e1SPrashanth Swaminathanretstruct_d_f:
283*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_DF, retstruct_f_d
284*1fd5a2e1SPrashanth Swaminathan	jal	t9
285*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
286*1fd5a2e1SPrashanth Swaminathan	s.d	$f0, 0(t4)
287*1fd5a2e1SPrashanth Swaminathan	s.s	$f2, 8(t4)
288*1fd5a2e1SPrashanth Swaminathan	b	epilogue
289*1fd5a2e1SPrashanth Swaminathan
290*1fd5a2e1SPrashanth Swaminathanretstruct_f_d:
291*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_FD, retstruct_d_soft
292*1fd5a2e1SPrashanth Swaminathan	jal	t9
293*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
294*1fd5a2e1SPrashanth Swaminathan	s.s	$f0, 0(t4)
295*1fd5a2e1SPrashanth Swaminathan	s.d	$f2, 8(t4)
296*1fd5a2e1SPrashanth Swaminathan	b	epilogue
297*1fd5a2e1SPrashanth Swaminathan#endif
298*1fd5a2e1SPrashanth Swaminathan
299*1fd5a2e1SPrashanth Swaminathanretstruct_d_soft:
300*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft
301*1fd5a2e1SPrashanth Swaminathan	jal	t9
302*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
303*1fd5a2e1SPrashanth Swaminathan	sd	v0, 0(t4)
304*1fd5a2e1SPrashanth Swaminathan	b	epilogue
305*1fd5a2e1SPrashanth Swaminathan
306*1fd5a2e1SPrashanth Swaminathanretstruct_f_soft:
307*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_F_SOFT, retstruct_d_d_soft
308*1fd5a2e1SPrashanth Swaminathan	jal	t9
309*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
310*1fd5a2e1SPrashanth Swaminathan	sw	v0, 0(t4)
311*1fd5a2e1SPrashanth Swaminathan	b	epilogue
312*1fd5a2e1SPrashanth Swaminathan
313*1fd5a2e1SPrashanth Swaminathanretstruct_d_d_soft:
314*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_DD_SOFT, retstruct_f_f_soft
315*1fd5a2e1SPrashanth Swaminathan	jal	t9
316*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
317*1fd5a2e1SPrashanth Swaminathan	sd	v0, 0(t4)
318*1fd5a2e1SPrashanth Swaminathan	sd	v1, 8(t4)
319*1fd5a2e1SPrashanth Swaminathan	b	epilogue
320*1fd5a2e1SPrashanth Swaminathan
321*1fd5a2e1SPrashanth Swaminathanretstruct_f_f_soft:
322*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_FF_SOFT, retstruct_d_f_soft
323*1fd5a2e1SPrashanth Swaminathan	jal	t9
324*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
325*1fd5a2e1SPrashanth Swaminathan	sw	v0, 0(t4)
326*1fd5a2e1SPrashanth Swaminathan	sw	v1, 4(t4)
327*1fd5a2e1SPrashanth Swaminathan	b	epilogue
328*1fd5a2e1SPrashanth Swaminathan
329*1fd5a2e1SPrashanth Swaminathanretstruct_d_f_soft:
330*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_DF_SOFT, retstruct_f_d_soft
331*1fd5a2e1SPrashanth Swaminathan	jal	t9
332*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
333*1fd5a2e1SPrashanth Swaminathan	sd	v0, 0(t4)
334*1fd5a2e1SPrashanth Swaminathan	sw	v1, 8(t4)
335*1fd5a2e1SPrashanth Swaminathan	b	epilogue
336*1fd5a2e1SPrashanth Swaminathan
337*1fd5a2e1SPrashanth Swaminathanretstruct_f_d_soft:
338*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_FD_SOFT, retstruct_small
339*1fd5a2e1SPrashanth Swaminathan	jal	t9
340*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
341*1fd5a2e1SPrashanth Swaminathan	sw	v0, 0(t4)
342*1fd5a2e1SPrashanth Swaminathan	sd	v1, 8(t4)
343*1fd5a2e1SPrashanth Swaminathan	b	epilogue
344*1fd5a2e1SPrashanth Swaminathan
345*1fd5a2e1SPrashanth Swaminathanretstruct_small:
346*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2
347*1fd5a2e1SPrashanth Swaminathan	jal	t9
348*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
349*1fd5a2e1SPrashanth Swaminathan	REG_S	v0, 0(t4)
350*1fd5a2e1SPrashanth Swaminathan	b	epilogue
351*1fd5a2e1SPrashanth Swaminathan
352*1fd5a2e1SPrashanth Swaminathanretstruct_small2:
353*1fd5a2e1SPrashanth Swaminathan	bne	t6, FFI_TYPE_STRUCT_SMALL2, retstruct
354*1fd5a2e1SPrashanth Swaminathan	jal	t9
355*1fd5a2e1SPrashanth Swaminathan	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
356*1fd5a2e1SPrashanth Swaminathan	REG_S	v0, 0(t4)
357*1fd5a2e1SPrashanth Swaminathan	REG_S	v1, 8(t4)
358*1fd5a2e1SPrashanth Swaminathan	b	epilogue
359*1fd5a2e1SPrashanth Swaminathan
360*1fd5a2e1SPrashanth Swaminathanretstruct:
361*1fd5a2e1SPrashanth Swaminathannoretval:
362*1fd5a2e1SPrashanth Swaminathan	jal	t9
363*1fd5a2e1SPrashanth Swaminathan
364*1fd5a2e1SPrashanth Swaminathan	# Epilogue
365*1fd5a2e1SPrashanth Swaminathanepilogue:
366*1fd5a2e1SPrashanth Swaminathan	move	$sp, $fp
367*1fd5a2e1SPrashanth Swaminathan	REG_L	$fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer
368*1fd5a2e1SPrashanth Swaminathan	REG_L	ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp)  # Restore return address
369*1fd5a2e1SPrashanth Swaminathan	ADDU	$sp, SIZEOF_FRAME		      # Fix stack pointer
370*1fd5a2e1SPrashanth Swaminathan	j	ra
371*1fd5a2e1SPrashanth Swaminathan
372*1fd5a2e1SPrashanth Swaminathan.LFE0:
373*1fd5a2e1SPrashanth Swaminathan	.end	ffi_call_N32
374*1fd5a2e1SPrashanth Swaminathan
375*1fd5a2e1SPrashanth Swaminathan/* ffi_closure_N32. Expects address of the passed-in ffi_closure in t0
376*1fd5a2e1SPrashanth Swaminathan   ($12). Stores any arguments passed in registers onto the stack,
377*1fd5a2e1SPrashanth Swaminathan   then calls ffi_closure_mips_inner_N32, which then decodes
378*1fd5a2e1SPrashanth Swaminathan   them.
379*1fd5a2e1SPrashanth Swaminathan
380*1fd5a2e1SPrashanth Swaminathan	Stack layout:
381*1fd5a2e1SPrashanth Swaminathan
382*1fd5a2e1SPrashanth Swaminathan	20 - Start of parameters, original sp
383*1fd5a2e1SPrashanth Swaminathan	19 - Called function a7 save
384*1fd5a2e1SPrashanth Swaminathan	18 - Called function a6 save
385*1fd5a2e1SPrashanth Swaminathan	17 - Called function a5 save
386*1fd5a2e1SPrashanth Swaminathan	16 - Called function a4 save
387*1fd5a2e1SPrashanth Swaminathan	15 - Called function a3 save
388*1fd5a2e1SPrashanth Swaminathan	14 - Called function a2 save
389*1fd5a2e1SPrashanth Swaminathan	13 - Called function a1 save
390*1fd5a2e1SPrashanth Swaminathan	12 - Called function a0 save
391*1fd5a2e1SPrashanth Swaminathan	11 - Called function f19
392*1fd5a2e1SPrashanth Swaminathan	10 - Called function f18
393*1fd5a2e1SPrashanth Swaminathan	 9 - Called function f17
394*1fd5a2e1SPrashanth Swaminathan	 8 - Called function f16
395*1fd5a2e1SPrashanth Swaminathan	 7 - Called function f15
396*1fd5a2e1SPrashanth Swaminathan         6 - Called function f14
397*1fd5a2e1SPrashanth Swaminathan         5 - Called function f13
398*1fd5a2e1SPrashanth Swaminathan         4 - Called function f12
399*1fd5a2e1SPrashanth Swaminathan	 3 - return value high (v1 or $f2)
400*1fd5a2e1SPrashanth Swaminathan	 2 - return value low (v0 or $f0)
401*1fd5a2e1SPrashanth Swaminathan	 1 - ra save
402*1fd5a2e1SPrashanth Swaminathan	 0 - gp save our sp  points here
403*1fd5a2e1SPrashanth Swaminathan	 */
404*1fd5a2e1SPrashanth Swaminathan
405*1fd5a2e1SPrashanth Swaminathan#define SIZEOF_FRAME2	(20 * FFI_SIZEOF_ARG)
406*1fd5a2e1SPrashanth Swaminathan
407*1fd5a2e1SPrashanth Swaminathan#define A7_OFF2		(19 * FFI_SIZEOF_ARG)
408*1fd5a2e1SPrashanth Swaminathan#define A6_OFF2		(18 * FFI_SIZEOF_ARG)
409*1fd5a2e1SPrashanth Swaminathan#define A5_OFF2		(17 * FFI_SIZEOF_ARG)
410*1fd5a2e1SPrashanth Swaminathan#define A4_OFF2		(16 * FFI_SIZEOF_ARG)
411*1fd5a2e1SPrashanth Swaminathan#define A3_OFF2		(15 * FFI_SIZEOF_ARG)
412*1fd5a2e1SPrashanth Swaminathan#define A2_OFF2		(14 * FFI_SIZEOF_ARG)
413*1fd5a2e1SPrashanth Swaminathan#define A1_OFF2		(13 * FFI_SIZEOF_ARG)
414*1fd5a2e1SPrashanth Swaminathan#define A0_OFF2		(12 * FFI_SIZEOF_ARG)
415*1fd5a2e1SPrashanth Swaminathan
416*1fd5a2e1SPrashanth Swaminathan#define F19_OFF2	(11 * FFI_SIZEOF_ARG)
417*1fd5a2e1SPrashanth Swaminathan#define F18_OFF2	(10 * FFI_SIZEOF_ARG)
418*1fd5a2e1SPrashanth Swaminathan#define F17_OFF2	(9  * FFI_SIZEOF_ARG)
419*1fd5a2e1SPrashanth Swaminathan#define F16_OFF2	(8  * FFI_SIZEOF_ARG)
420*1fd5a2e1SPrashanth Swaminathan#define F15_OFF2	(7  * FFI_SIZEOF_ARG)
421*1fd5a2e1SPrashanth Swaminathan#define F14_OFF2	(6  * FFI_SIZEOF_ARG)
422*1fd5a2e1SPrashanth Swaminathan#define F13_OFF2	(5  * FFI_SIZEOF_ARG)
423*1fd5a2e1SPrashanth Swaminathan#define F12_OFF2	(4  * FFI_SIZEOF_ARG)
424*1fd5a2e1SPrashanth Swaminathan
425*1fd5a2e1SPrashanth Swaminathan#define V1_OFF2		(3  * FFI_SIZEOF_ARG)
426*1fd5a2e1SPrashanth Swaminathan#define V0_OFF2		(2  * FFI_SIZEOF_ARG)
427*1fd5a2e1SPrashanth Swaminathan
428*1fd5a2e1SPrashanth Swaminathan#define RA_OFF2		(1  * FFI_SIZEOF_ARG)
429*1fd5a2e1SPrashanth Swaminathan#define GP_OFF2		(0  * FFI_SIZEOF_ARG)
430*1fd5a2e1SPrashanth Swaminathan
431*1fd5a2e1SPrashanth Swaminathan	.align	2
432*1fd5a2e1SPrashanth Swaminathan	.globl	ffi_go_closure_N32
433*1fd5a2e1SPrashanth Swaminathan	.ent	ffi_go_closure_N32
434*1fd5a2e1SPrashanth Swaminathanffi_go_closure_N32:
435*1fd5a2e1SPrashanth Swaminathan.LFB1:
436*1fd5a2e1SPrashanth Swaminathan	.frame	$sp, SIZEOF_FRAME2, ra
437*1fd5a2e1SPrashanth Swaminathan	.mask	0x90000000,-(SIZEOF_FRAME2 - RA_OFF2)
438*1fd5a2e1SPrashanth Swaminathan	.fmask	0x00000000,0
439*1fd5a2e1SPrashanth Swaminathan	SUBU	$sp, SIZEOF_FRAME2
440*1fd5a2e1SPrashanth Swaminathan.LCFI10:
441*1fd5a2e1SPrashanth Swaminathan	.cpsetup t9, GP_OFF2, ffi_go_closure_N32
442*1fd5a2e1SPrashanth Swaminathan	REG_S	ra, RA_OFF2($sp)	# Save return address
443*1fd5a2e1SPrashanth Swaminathan.LCFI11:
444*1fd5a2e1SPrashanth Swaminathan
445*1fd5a2e1SPrashanth Swaminathan	REG_S	a0, A0_OFF2($sp)
446*1fd5a2e1SPrashanth Swaminathan	REG_S	a1, A1_OFF2($sp)
447*1fd5a2e1SPrashanth Swaminathan	REG_S	a2, A2_OFF2($sp)
448*1fd5a2e1SPrashanth Swaminathan	REG_S	a3, A3_OFF2($sp)
449*1fd5a2e1SPrashanth Swaminathan	REG_S	a4, A4_OFF2($sp)
450*1fd5a2e1SPrashanth Swaminathan	REG_S	a5, A5_OFF2($sp)
451*1fd5a2e1SPrashanth Swaminathan
452*1fd5a2e1SPrashanth Swaminathan	# Call ffi_closure_mips_inner_N32 to do the real work.
453*1fd5a2e1SPrashanth Swaminathan	LA	t9, ffi_closure_mips_inner_N32
454*1fd5a2e1SPrashanth Swaminathan	REG_L	a0, 8($15)   # cif
455*1fd5a2e1SPrashanth Swaminathan	REG_L	a1, 16($15) # fun
456*1fd5a2e1SPrashanth Swaminathan	move	a2, t7                     # userdata=closure
457*1fd5a2e1SPrashanth Swaminathan	ADDU	a3, $sp, V0_OFF2           # rvalue
458*1fd5a2e1SPrashanth Swaminathan	ADDU	a4, $sp, A0_OFF2           # ar
459*1fd5a2e1SPrashanth Swaminathan	ADDU	a5, $sp, F12_OFF2          # fpr
460*1fd5a2e1SPrashanth Swaminathan
461*1fd5a2e1SPrashanth Swaminathan	b	$do_closure
462*1fd5a2e1SPrashanth Swaminathan
463*1fd5a2e1SPrashanth Swaminathan.LFE1:
464*1fd5a2e1SPrashanth Swaminathan	.end	ffi_go_closure_N32
465*1fd5a2e1SPrashanth Swaminathan
466*1fd5a2e1SPrashanth Swaminathan	.align	2
467*1fd5a2e1SPrashanth Swaminathan	.globl	ffi_closure_N32
468*1fd5a2e1SPrashanth Swaminathan	.ent	ffi_closure_N32
469*1fd5a2e1SPrashanth Swaminathanffi_closure_N32:
470*1fd5a2e1SPrashanth Swaminathan.LFB2:
471*1fd5a2e1SPrashanth Swaminathan	.frame	$sp, SIZEOF_FRAME2, ra
472*1fd5a2e1SPrashanth Swaminathan	.mask	0x90000000,-(SIZEOF_FRAME2 - RA_OFF2)
473*1fd5a2e1SPrashanth Swaminathan	.fmask	0x00000000,0
474*1fd5a2e1SPrashanth Swaminathan	SUBU	$sp, SIZEOF_FRAME2
475*1fd5a2e1SPrashanth Swaminathan.LCFI20:
476*1fd5a2e1SPrashanth Swaminathan	.cpsetup t9, GP_OFF2, ffi_closure_N32
477*1fd5a2e1SPrashanth Swaminathan	REG_S	ra, RA_OFF2($sp)	# Save return address
478*1fd5a2e1SPrashanth Swaminathan.LCFI21:
479*1fd5a2e1SPrashanth Swaminathan	REG_S	a0, A0_OFF2($sp)
480*1fd5a2e1SPrashanth Swaminathan	REG_S	a1, A1_OFF2($sp)
481*1fd5a2e1SPrashanth Swaminathan	REG_S	a2, A2_OFF2($sp)
482*1fd5a2e1SPrashanth Swaminathan	REG_S	a3, A3_OFF2($sp)
483*1fd5a2e1SPrashanth Swaminathan	REG_S	a4, A4_OFF2($sp)
484*1fd5a2e1SPrashanth Swaminathan	REG_S	a5, A5_OFF2($sp)
485*1fd5a2e1SPrashanth Swaminathan
486*1fd5a2e1SPrashanth Swaminathan	# Call ffi_closure_mips_inner_N32 to do the real work.
487*1fd5a2e1SPrashanth Swaminathan	LA	t9, ffi_closure_mips_inner_N32
488*1fd5a2e1SPrashanth Swaminathan	REG_L	a0, 56($12)   # cif
489*1fd5a2e1SPrashanth Swaminathan	REG_L	a1, 64($12)   # fun
490*1fd5a2e1SPrashanth Swaminathan	REG_L	a2, 72($12) # user_data
491*1fd5a2e1SPrashanth Swaminathan	ADDU	a3, $sp, V0_OFF2
492*1fd5a2e1SPrashanth Swaminathan	ADDU	a4, $sp, A0_OFF2
493*1fd5a2e1SPrashanth Swaminathan	ADDU	a5, $sp, F12_OFF2
494*1fd5a2e1SPrashanth Swaminathan
495*1fd5a2e1SPrashanth Swaminathan$do_closure:
496*1fd5a2e1SPrashanth Swaminathan	# Store all possible argument registers. If there are more than
497*1fd5a2e1SPrashanth Swaminathan	# fit in registers, then they were stored on the stack.
498*1fd5a2e1SPrashanth Swaminathan	REG_S	a6, A6_OFF2($sp)
499*1fd5a2e1SPrashanth Swaminathan	REG_S	a7, A7_OFF2($sp)
500*1fd5a2e1SPrashanth Swaminathan
501*1fd5a2e1SPrashanth Swaminathan#ifndef __mips_soft_float
502*1fd5a2e1SPrashanth Swaminathan	# Store all possible float/double registers.
503*1fd5a2e1SPrashanth Swaminathan	s.d	$f12, F12_OFF2($sp)
504*1fd5a2e1SPrashanth Swaminathan	s.d	$f13, F13_OFF2($sp)
505*1fd5a2e1SPrashanth Swaminathan	s.d	$f14, F14_OFF2($sp)
506*1fd5a2e1SPrashanth Swaminathan	s.d	$f15, F15_OFF2($sp)
507*1fd5a2e1SPrashanth Swaminathan	s.d	$f16, F16_OFF2($sp)
508*1fd5a2e1SPrashanth Swaminathan	s.d	$f17, F17_OFF2($sp)
509*1fd5a2e1SPrashanth Swaminathan	s.d	$f18, F18_OFF2($sp)
510*1fd5a2e1SPrashanth Swaminathan	s.d	$f19, F19_OFF2($sp)
511*1fd5a2e1SPrashanth Swaminathan#endif
512*1fd5a2e1SPrashanth Swaminathan
513*1fd5a2e1SPrashanth Swaminathan	jalr	t9
514*1fd5a2e1SPrashanth Swaminathan
515*1fd5a2e1SPrashanth Swaminathan	# Return flags are in v0
516*1fd5a2e1SPrashanth Swaminathan	bne     v0, FFI_TYPE_SINT32, cls_retint
517*1fd5a2e1SPrashanth Swaminathan	lw	v0, V0_OFF2($sp)
518*1fd5a2e1SPrashanth Swaminathan	b	cls_epilogue
519*1fd5a2e1SPrashanth Swaminathan
520*1fd5a2e1SPrashanth Swaminathancls_retint:
521*1fd5a2e1SPrashanth Swaminathan	bne     v0, FFI_TYPE_INT, cls_retfloat
522*1fd5a2e1SPrashanth Swaminathan	REG_L	v0, V0_OFF2($sp)
523*1fd5a2e1SPrashanth Swaminathan	b	cls_epilogue
524*1fd5a2e1SPrashanth Swaminathan
525*1fd5a2e1SPrashanth Swaminathancls_retfloat:
526*1fd5a2e1SPrashanth Swaminathan#ifndef __mips_soft_float
527*1fd5a2e1SPrashanth Swaminathan	bne     v0, FFI_TYPE_FLOAT, cls_retdouble
528*1fd5a2e1SPrashanth Swaminathan	l.s	$f0, V0_OFF2($sp)
529*1fd5a2e1SPrashanth Swaminathan	b	cls_epilogue
530*1fd5a2e1SPrashanth Swaminathan
531*1fd5a2e1SPrashanth Swaminathancls_retdouble:
532*1fd5a2e1SPrashanth Swaminathan	bne	v0, FFI_TYPE_DOUBLE, cls_retstruct_d
533*1fd5a2e1SPrashanth Swaminathan	l.d	$f0, V0_OFF2($sp)
534*1fd5a2e1SPrashanth Swaminathan	b	cls_epilogue
535*1fd5a2e1SPrashanth Swaminathan
536*1fd5a2e1SPrashanth Swaminathancls_retstruct_d:
537*1fd5a2e1SPrashanth Swaminathan	bne	v0, FFI_TYPE_STRUCT_D, cls_retstruct_f
538*1fd5a2e1SPrashanth Swaminathan	l.d	$f0, V0_OFF2($sp)
539*1fd5a2e1SPrashanth Swaminathan	b	cls_epilogue
540*1fd5a2e1SPrashanth Swaminathan
541*1fd5a2e1SPrashanth Swaminathancls_retstruct_f:
542*1fd5a2e1SPrashanth Swaminathan	bne	v0, FFI_TYPE_STRUCT_F, cls_retstruct_d_d
543*1fd5a2e1SPrashanth Swaminathan	l.s	$f0, V0_OFF2($sp)
544*1fd5a2e1SPrashanth Swaminathan	b	cls_epilogue
545*1fd5a2e1SPrashanth Swaminathan
546*1fd5a2e1SPrashanth Swaminathancls_retstruct_d_d:
547*1fd5a2e1SPrashanth Swaminathan	bne	v0, FFI_TYPE_STRUCT_DD, cls_retstruct_f_f
548*1fd5a2e1SPrashanth Swaminathan	l.d	$f0, V0_OFF2($sp)
549*1fd5a2e1SPrashanth Swaminathan	l.d	$f2, V1_OFF2($sp)
550*1fd5a2e1SPrashanth Swaminathan	b	cls_epilogue
551*1fd5a2e1SPrashanth Swaminathan
552*1fd5a2e1SPrashanth Swaminathancls_retstruct_f_f:
553*1fd5a2e1SPrashanth Swaminathan	bne	v0, FFI_TYPE_STRUCT_FF, cls_retstruct_d_f
554*1fd5a2e1SPrashanth Swaminathan	l.s	$f0, V0_OFF2($sp)
555*1fd5a2e1SPrashanth Swaminathan	l.s	$f2, V1_OFF2($sp)
556*1fd5a2e1SPrashanth Swaminathan	b	cls_epilogue
557*1fd5a2e1SPrashanth Swaminathan
558*1fd5a2e1SPrashanth Swaminathancls_retstruct_d_f:
559*1fd5a2e1SPrashanth Swaminathan	bne	v0, FFI_TYPE_STRUCT_DF, cls_retstruct_f_d
560*1fd5a2e1SPrashanth Swaminathan	l.d	$f0, V0_OFF2($sp)
561*1fd5a2e1SPrashanth Swaminathan	l.s	$f2, V1_OFF2($sp)
562*1fd5a2e1SPrashanth Swaminathan	b	cls_epilogue
563*1fd5a2e1SPrashanth Swaminathan
564*1fd5a2e1SPrashanth Swaminathancls_retstruct_f_d:
565*1fd5a2e1SPrashanth Swaminathan	bne	v0, FFI_TYPE_STRUCT_FD, cls_retstruct_small2
566*1fd5a2e1SPrashanth Swaminathan	l.s	$f0, V0_OFF2($sp)
567*1fd5a2e1SPrashanth Swaminathan	l.d	$f2, V1_OFF2($sp)
568*1fd5a2e1SPrashanth Swaminathan	b	cls_epilogue
569*1fd5a2e1SPrashanth Swaminathan#endif
570*1fd5a2e1SPrashanth Swaminathan
571*1fd5a2e1SPrashanth Swaminathancls_retstruct_small2:
572*1fd5a2e1SPrashanth Swaminathan	REG_L	v0, V0_OFF2($sp)
573*1fd5a2e1SPrashanth Swaminathan	REG_L	v1, V1_OFF2($sp)
574*1fd5a2e1SPrashanth Swaminathan
575*1fd5a2e1SPrashanth Swaminathan	# Epilogue
576*1fd5a2e1SPrashanth Swaminathancls_epilogue:
577*1fd5a2e1SPrashanth Swaminathan	REG_L	ra,  RA_OFF2($sp)	 # Restore return address
578*1fd5a2e1SPrashanth Swaminathan	.cpreturn
579*1fd5a2e1SPrashanth Swaminathan	ADDU	$sp, SIZEOF_FRAME2
580*1fd5a2e1SPrashanth Swaminathan	j	ra
581*1fd5a2e1SPrashanth Swaminathan.LFE2:
582*1fd5a2e1SPrashanth Swaminathan	.end	ffi_closure_N32
583*1fd5a2e1SPrashanth Swaminathan
584*1fd5a2e1SPrashanth Swaminathan#ifdef __GNUC__
585*1fd5a2e1SPrashanth Swaminathan        .section        .eh_frame,"aw",@progbits
586*1fd5a2e1SPrashanth Swaminathan.Lframe1:
587*1fd5a2e1SPrashanth Swaminathan        .4byte  .LECIE1-.LSCIE1		# length
588*1fd5a2e1SPrashanth Swaminathan.LSCIE1:
589*1fd5a2e1SPrashanth Swaminathan        .4byte  0x0			# CIE
590*1fd5a2e1SPrashanth Swaminathan        .byte   0x1			# Version 1
591*1fd5a2e1SPrashanth Swaminathan        .ascii  "\000"			# Augmentation
592*1fd5a2e1SPrashanth Swaminathan        .uleb128 0x1			# Code alignment 1
593*1fd5a2e1SPrashanth Swaminathan        .sleb128 -4			# Data alignment -4
594*1fd5a2e1SPrashanth Swaminathan        .byte   0x1f			# Return Address $31
595*1fd5a2e1SPrashanth Swaminathan        .byte   0xc			# DW_CFA_def_cfa
596*1fd5a2e1SPrashanth Swaminathan        .uleb128 0x1d			# in $sp
597*1fd5a2e1SPrashanth Swaminathan        .uleb128 0x0			# offset 0
598*1fd5a2e1SPrashanth Swaminathan        .align  EH_FRAME_ALIGN
599*1fd5a2e1SPrashanth Swaminathan.LECIE1:
600*1fd5a2e1SPrashanth Swaminathan
601*1fd5a2e1SPrashanth Swaminathan.LSFDE0:
602*1fd5a2e1SPrashanth Swaminathan        .4byte  .LEFDE0-.LASFDE0	# length.
603*1fd5a2e1SPrashanth Swaminathan.LASFDE0:
604*1fd5a2e1SPrashanth Swaminathan        .4byte  .LASFDE0-.Lframe1	# CIE_pointer.
605*1fd5a2e1SPrashanth Swaminathan        FDE_ADDR_BYTES  .LFB0		# initial_location.
606*1fd5a2e1SPrashanth Swaminathan        FDE_ADDR_BYTES  .LFE0-.LFB0	# address_range.
607*1fd5a2e1SPrashanth Swaminathan        .byte   0x4			# DW_CFA_advance_loc4
608*1fd5a2e1SPrashanth Swaminathan        .4byte  .LCFI00-.LFB0		# to .LCFI00
609*1fd5a2e1SPrashanth Swaminathan        .byte   0xe			# DW_CFA_def_cfa_offset
610*1fd5a2e1SPrashanth Swaminathan        .uleb128 SIZEOF_FRAME		# adjust stack.by SIZEOF_FRAME
611*1fd5a2e1SPrashanth Swaminathan        .byte   0x4			# DW_CFA_advance_loc4
612*1fd5a2e1SPrashanth Swaminathan        .4byte  .LCFI01-.LCFI00		# to .LCFI01
613*1fd5a2e1SPrashanth Swaminathan        .byte   0x9e			# DW_CFA_offset of $fp
614*1fd5a2e1SPrashanth Swaminathan        .uleb128 2*FFI_SIZEOF_ARG/4	#
615*1fd5a2e1SPrashanth Swaminathan        .byte   0x9f			# DW_CFA_offset of ra
616*1fd5a2e1SPrashanth Swaminathan        .uleb128 1*FFI_SIZEOF_ARG/4	#
617*1fd5a2e1SPrashanth Swaminathan        .byte   0x4			# DW_CFA_advance_loc4
618*1fd5a2e1SPrashanth Swaminathan        .4byte  .LCFI02-.LCFI01		# to .LCFI02
619*1fd5a2e1SPrashanth Swaminathan        .byte   0xd			# DW_CFA_def_cfa_register
620*1fd5a2e1SPrashanth Swaminathan        .uleb128 0x1e			# in $fp
621*1fd5a2e1SPrashanth Swaminathan        .align  EH_FRAME_ALIGN
622*1fd5a2e1SPrashanth Swaminathan.LEFDE0:
623*1fd5a2e1SPrashanth Swaminathan
624*1fd5a2e1SPrashanth Swaminathan.LSFDE1:
625*1fd5a2e1SPrashanth Swaminathan	.4byte	.LEFDE1-.LASFDE1	# length
626*1fd5a2e1SPrashanth Swaminathan.LASFDE1:
627*1fd5a2e1SPrashanth Swaminathan	.4byte	.LASFDE1-.Lframe1	# CIE_pointer.
628*1fd5a2e1SPrashanth Swaminathan	FDE_ADDR_BYTES	.LFB1		# initial_location.
629*1fd5a2e1SPrashanth Swaminathan	FDE_ADDR_BYTES	.LFE1-.LFB1	# address_range.
630*1fd5a2e1SPrashanth Swaminathan	.byte	0x4			# DW_CFA_advance_loc4
631*1fd5a2e1SPrashanth Swaminathan	.4byte	.LCFI10-.LFB1		# to .LCFI10
632*1fd5a2e1SPrashanth Swaminathan	.byte	0xe			# DW_CFA_def_cfa_offset
633*1fd5a2e1SPrashanth Swaminathan	.uleb128 SIZEOF_FRAME2		# adjust stack.by SIZEOF_FRAME
634*1fd5a2e1SPrashanth Swaminathan	.byte	0x4			# DW_CFA_advance_loc4
635*1fd5a2e1SPrashanth Swaminathan	.4byte	.LCFI11-.LCFI10		# to .LCFI11
636*1fd5a2e1SPrashanth Swaminathan	.byte	0x9c			# DW_CFA_offset of $gp ($28)
637*1fd5a2e1SPrashanth Swaminathan	.uleb128 (SIZEOF_FRAME2 - GP_OFF2)/4
638*1fd5a2e1SPrashanth Swaminathan	.byte	0x9f			# DW_CFA_offset of ra ($31)
639*1fd5a2e1SPrashanth Swaminathan	.uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4
640*1fd5a2e1SPrashanth Swaminathan	.align	EH_FRAME_ALIGN
641*1fd5a2e1SPrashanth Swaminathan.LEFDE1:
642*1fd5a2e1SPrashanth Swaminathan
643*1fd5a2e1SPrashanth Swaminathan.LSFDE2:
644*1fd5a2e1SPrashanth Swaminathan	.4byte	.LEFDE2-.LASFDE2	# length
645*1fd5a2e1SPrashanth Swaminathan.LASFDE2:
646*1fd5a2e1SPrashanth Swaminathan	.4byte	.LASFDE2-.Lframe1	# CIE_pointer.
647*1fd5a2e1SPrashanth Swaminathan	FDE_ADDR_BYTES	.LFB2		# initial_location.
648*1fd5a2e1SPrashanth Swaminathan	FDE_ADDR_BYTES	.LFE2-.LFB2	# address_range.
649*1fd5a2e1SPrashanth Swaminathan	.byte	0x4			# DW_CFA_advance_loc4
650*1fd5a2e1SPrashanth Swaminathan	.4byte	.LCFI20-.LFB2		# to .LCFI20
651*1fd5a2e1SPrashanth Swaminathan	.byte	0xe			# DW_CFA_def_cfa_offset
652*1fd5a2e1SPrashanth Swaminathan	.uleb128 SIZEOF_FRAME2		# adjust stack.by SIZEOF_FRAME
653*1fd5a2e1SPrashanth Swaminathan	.byte	0x4			# DW_CFA_advance_loc4
654*1fd5a2e1SPrashanth Swaminathan	.4byte	.LCFI21-.LCFI20		# to .LCFI21
655*1fd5a2e1SPrashanth Swaminathan	.byte	0x9c			# DW_CFA_offset of $gp ($28)
656*1fd5a2e1SPrashanth Swaminathan	.uleb128 (SIZEOF_FRAME2 - GP_OFF2)/4
657*1fd5a2e1SPrashanth Swaminathan	.byte	0x9f			# DW_CFA_offset of ra ($31)
658*1fd5a2e1SPrashanth Swaminathan	.uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4
659*1fd5a2e1SPrashanth Swaminathan	.align	EH_FRAME_ALIGN
660*1fd5a2e1SPrashanth Swaminathan.LEFDE2:
661*1fd5a2e1SPrashanth Swaminathan#endif /* __GNUC__ */
662*1fd5a2e1SPrashanth Swaminathan
663*1fd5a2e1SPrashanth Swaminathan#endif
664