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