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