OSDN Git Service

Initial Contribution
[android-x86/external-libffi.git] / src / sh64 / sysv.S
1 /* -----------------------------------------------------------------------
2    sysv.S - Copyright (c) 2003, 2004, 2006 Kaz Kojima
3    
4    SuperH SHmedia 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, EXPRESS
18    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20    IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23    OTHER DEALINGS IN THE SOFTWARE.
24    ----------------------------------------------------------------------- */
25
26 #define LIBFFI_ASM      
27 #include <fficonfig.h>
28 #include <ffi.h>
29 #ifdef HAVE_MACHINE_ASM_H
30 #include <machine/asm.h>
31 #else
32 /* XXX these lose for some platforms, I'm sure. */
33 #define CNAME(x) x
34 #define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
35 #endif
36
37 #ifdef __LITTLE_ENDIAN__
38 #define OFS_FLT 0
39 #else
40 #define OFS_FLT 4
41 #endif
42
43         .section        .text..SHmedia32,"ax"
44
45         # r2:   ffi_prep_args
46         # r3:   &ecif
47         # r4:   bytes
48         # r5:   flags
49         # r6:   flags2
50         # r7:   rvalue
51         # r8:   fn
52
53         # This assumes we are using gas.
54         .align  5
55 ENTRY(ffi_call_SYSV)
56         # Save registers
57 .LFB1:
58         addi.l  r15, -48, r15
59 .LCFI0:
60         st.q    r15, 40, r32
61         st.q    r15, 32, r31
62         st.q    r15, 24, r30
63         st.q    r15, 16, r29
64         st.q    r15, 8, r28
65         st.l    r15, 4, r18
66         st.l    r15, 0, r14
67 .LCFI1:
68         add.l   r15, r63, r14
69 .LCFI2:
70 #       add     r4, r63, r28
71         add     r5, r63, r29
72         add     r6, r63, r30
73         add     r7, r63, r31
74         add     r8, r63, r32
75
76         addi    r4, (64 + 7), r4
77         andi    r4, ~7, r4
78         sub.l   r15, r4, r15
79
80         ptabs/l r2, tr0
81         add     r15, r63, r2
82         blink   tr0, r18
83
84         addi    r15, 64, r22
85         movi    0, r0
86         movi    0, r1
87         movi    -1, r23
88
89         pt/l    1f, tr1
90         bnei/l  r29, FFI_TYPE_STRUCT, tr1
91         ld.l    r15, 0, r19
92         addi    r15, 8, r15
93         addi    r0, 1, r0
94 1:
95
96 .L_pass:
97         andi    r30, 3, r20
98         shlri   r30, 2, r30
99
100         pt/l    .L_call_it, tr0
101         pt/l    .L_pass_i, tr1
102         pt/l    .L_pass_f, tr2
103
104         beqi/l  r20, FFI_TYPE_VOID, tr0
105         beqi/l  r20, FFI_TYPE_INT, tr1
106         beqi/l  r20, FFI_TYPE_FLOAT, tr2
107
108 .L_pass_d:
109         addi    r0, 1, r0
110         pt/l    3f, tr0
111         movi    12, r20
112         bge/l   r1, r20, tr0
113
114         pt/l    .L_pop_d, tr1
115         pt/l    2f, tr0
116         blink   tr1, r63
117 2:
118         addi.l  r15, 8, r15
119 3:
120         pt/l    .L_pass, tr0
121         addi    r1, 2, r1
122         blink   tr0, r63
123
124 .L_pop_d:
125         pt/l    .L_pop_d_tbl, tr1
126         gettr   tr1, r20
127         shlli   r1, 2, r21
128         add     r20, r21, r20
129         ptabs/l r20, tr1
130         blink   tr1, r63
131
132 .L_pop_d_tbl:
133         fld.d   r15, 0, dr0
134         blink   tr0, r63
135         fld.d   r15, 0, dr2
136         blink   tr0, r63
137         fld.d   r15, 0, dr4
138         blink   tr0, r63
139         fld.d   r15, 0, dr6
140         blink   tr0, r63
141         fld.d   r15, 0, dr8
142         blink   tr0, r63
143         fld.d   r15, 0, dr10
144         blink   tr0, r63
145
146 .L_pass_f:
147         addi    r0, 1, r0
148         pt/l    3f, tr0
149         movi    12, r20
150         bge/l   r1, r20, tr0
151
152         pt/l    .L_pop_f, tr1
153         pt/l    2f, tr0
154         blink   tr1, r63
155 2:
156         addi.l  r15, 8, r15
157 3:
158         pt/l    .L_pass, tr0
159         blink   tr0, r63
160
161 .L_pop_f:
162         pt/l    .L_pop_f_tbl, tr1
163         pt/l    5f, tr2
164         gettr   tr1, r20
165         bge/l   r23, r63, tr2
166         add     r1, r63, r23 
167         shlli   r1, 3, r21
168         addi    r1, 2, r1
169         add     r20, r21, r20
170         ptabs/l r20, tr1
171         blink   tr1, r63
172 5:
173         addi    r23, 1, r21
174         movi    -1, r23
175         shlli   r21, 3, r21
176         add     r20, r21, r20
177         ptabs/l r20, tr1
178         blink   tr1, r63
179
180 .L_pop_f_tbl:
181         fld.s   r15, OFS_FLT, fr0
182         blink   tr0, r63
183         fld.s   r15, OFS_FLT, fr1
184         blink   tr0, r63
185         fld.s   r15, OFS_FLT, fr2
186         blink   tr0, r63
187         fld.s   r15, OFS_FLT, fr3
188         blink   tr0, r63
189         fld.s   r15, OFS_FLT, fr4
190         blink   tr0, r63
191         fld.s   r15, OFS_FLT, fr5
192         blink   tr0, r63
193         fld.s   r15, OFS_FLT, fr6
194         blink   tr0, r63
195         fld.s   r15, OFS_FLT, fr7
196         blink   tr0, r63
197         fld.s   r15, OFS_FLT, fr8
198         blink   tr0, r63
199         fld.s   r15, OFS_FLT, fr9
200         blink   tr0, r63
201         fld.s   r15, OFS_FLT, fr10
202         blink   tr0, r63
203         fld.s   r15, OFS_FLT, fr11
204         blink   tr0, r63
205
206 .L_pass_i:
207         pt/l    3f, tr0
208         movi    8, r20
209         bge/l   r0, r20, tr0
210
211         pt/l    .L_pop_i, tr1
212         pt/l    2f, tr0
213         blink   tr1, r63
214 2:
215         addi.l  r15, 8, r15
216 3:
217         pt/l    .L_pass, tr0
218         addi    r0, 1, r0
219         blink   tr0, r63
220
221 .L_pop_i:
222         pt/l    .L_pop_i_tbl, tr1
223         gettr   tr1, r20
224         shlli   r0, 3, r21
225         add     r20, r21, r20
226         ptabs/l r20, tr1
227         blink   tr1, r63
228
229 .L_pop_i_tbl:
230         ld.q    r15, 0, r2
231         blink   tr0, r63
232         ld.q    r15, 0, r3
233         blink   tr0, r63
234         ld.q    r15, 0, r4
235         blink   tr0, r63
236         ld.q    r15, 0, r5
237         blink   tr0, r63
238         ld.q    r15, 0, r6
239         blink   tr0, r63
240         ld.q    r15, 0, r7
241         blink   tr0, r63
242         ld.q    r15, 0, r8
243         blink   tr0, r63
244         ld.q    r15, 0, r9
245         blink   tr0, r63
246
247 .L_call_it:
248         # call function
249         pt/l    1f, tr1
250         bnei/l  r29, FFI_TYPE_STRUCT, tr1
251         add     r19, r63, r2
252 1:
253         add     r22, r63, r15
254         ptabs/l r32, tr0
255         blink   tr0, r18
256
257         pt/l    .L_ret_i, tr0
258         pt/l    .L_ret_ll, tr1
259         pt/l    .L_ret_d, tr2
260         pt/l    .L_ret_f, tr3
261         pt/l    .L_epilogue, tr4
262
263         beqi/l  r29, FFI_TYPE_INT, tr0
264         beqi/l  r29, FFI_TYPE_UINT32, tr0
265         beqi/l  r29, FFI_TYPE_SINT64, tr1
266         beqi/l  r29, FFI_TYPE_UINT64, tr1
267         beqi/l  r29, FFI_TYPE_DOUBLE, tr2
268         beqi/l  r29, FFI_TYPE_FLOAT, tr3
269
270         pt/l    .L_ret_q, tr0
271         pt/l    .L_ret_h, tr1
272
273         beqi/l  r29, FFI_TYPE_UINT8, tr0
274         beqi/l  r29, FFI_TYPE_UINT16, tr1
275         blink   tr4, r63
276
277 .L_ret_d:
278         fst.d   r31, 0, dr0
279         blink   tr4, r63
280
281 .L_ret_ll:
282         st.q    r31, 0, r2
283         blink   tr4, r63
284
285 .L_ret_f:
286         fst.s   r31, OFS_FLT, fr0
287         blink   tr4, r63
288
289 .L_ret_q:
290         st.b    r31, 0, r2
291         blink   tr4, r63
292
293 .L_ret_h:
294         st.w    r31, 0, r2
295         blink   tr4, r63
296
297 .L_ret_i:
298         st.l    r31, 0, r2
299         # Fall
300
301 .L_epilogue:
302         # Remove the space we pushed for the args
303         add     r14, r63, r15
304
305         ld.l    r15, 0, r14
306         ld.l    r15, 4, r18
307         ld.q    r15, 8, r28
308         ld.q    r15, 16, r29
309         ld.q    r15, 24, r30
310         ld.q    r15, 32, r31
311         ld.q    r15, 40, r32
312         addi.l  r15, 48, r15
313         ptabs   r18, tr0
314         blink   tr0, r63
315
316 .LFE1:
317 .ffi_call_SYSV_end:
318         .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
319
320         .align  5
321 ENTRY(ffi_closure_SYSV)
322 .LFB2:
323         addi.l  r15, -136, r15
324 .LCFI3:
325         st.l    r15, 12, r18
326         st.l    r15, 8, r14
327         st.l    r15, 4, r12
328 .LCFI4:
329         add     r15, r63, r14
330 .LCFI5:
331         /* Stack layout:        
332            ...
333            64 bytes (register parameters)
334            48 bytes (floating register parameters)
335             8 bytes (result)
336             4 bytes (r18)
337             4 bytes (r14)
338             4 bytes (r12)
339             4 bytes (for align)
340            <- new stack pointer
341         */
342         fst.d   r14, 24, dr0
343         fst.d   r14, 32, dr2
344         fst.d   r14, 40, dr4
345         fst.d   r14, 48, dr6
346         fst.d   r14, 56, dr8
347         fst.d   r14, 64, dr10
348         st.q    r14, 72, r2
349         st.q    r14, 80, r3
350         st.q    r14, 88, r4
351         st.q    r14, 96, r5
352         st.q    r14, 104, r6
353         st.q    r14, 112, r7
354         st.q    r14, 120, r8
355         st.q    r14, 128, r9
356
357         add     r1, r63, r2
358         addi    r14, 16, r3
359         addi    r14, 72, r4
360         addi    r14, 24, r5
361         addi    r14, 136, r6
362 #ifdef PIC
363         movi    (((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) >> 16) & 65535), r12
364         shori   ((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) & 65535), r12
365 .LPCS0: ptrel/u r12, tr0
366         movi    ((ffi_closure_helper_SYSV@GOTPLT) & 65535), r1
367         gettr   tr0, r12
368         ldx.l   r1, r12, r1
369         ptabs   r1, tr0
370 #else
371         pt/l    ffi_closure_helper_SYSV, tr0
372 #endif
373         blink   tr0, r18
374
375         shlli   r2, 1, r1
376         movi    (((datalabel .L_table) >> 16) & 65535), r2
377         shori   ((datalabel .L_table) & 65535), r2
378         ldx.w   r2, r1, r1
379         add     r1, r2, r1
380         pt/l    .L_case_v, tr1
381         ptabs   r1, tr0
382         blink   tr0, r63
383
384         .align 2
385 .L_table:
386         .word   .L_case_v - datalabel .L_table  /* FFI_TYPE_VOID */
387         .word   .L_case_i - datalabel .L_table  /* FFI_TYPE_INT */
388         .word   .L_case_f - datalabel .L_table  /* FFI_TYPE_FLOAT */
389         .word   .L_case_d - datalabel .L_table  /* FFI_TYPE_DOUBLE */
390         .word   .L_case_d - datalabel .L_table  /* FFI_TYPE_LONGDOUBLE */
391         .word   .L_case_uq - datalabel .L_table /* FFI_TYPE_UINT8 */
392         .word   .L_case_q - datalabel .L_table  /* FFI_TYPE_SINT8 */
393         .word   .L_case_uh - datalabel .L_table /* FFI_TYPE_UINT16 */
394         .word   .L_case_h - datalabel .L_table  /* FFI_TYPE_SINT16 */
395         .word   .L_case_i - datalabel .L_table  /* FFI_TYPE_UINT32 */
396         .word   .L_case_i - datalabel .L_table  /* FFI_TYPE_SINT32 */
397         .word   .L_case_ll - datalabel .L_table /* FFI_TYPE_UINT64 */
398         .word   .L_case_ll - datalabel .L_table /* FFI_TYPE_SINT64 */
399         .word   .L_case_v - datalabel .L_table  /* FFI_TYPE_STRUCT */
400         .word   .L_case_i - datalabel .L_table  /* FFI_TYPE_POINTER */
401
402         .align 2
403 .L_case_d:
404         fld.d   r14, 16, dr0
405         blink   tr1, r63
406 .L_case_f:
407         fld.s   r14, 16, fr0
408         blink   tr1, r63
409 .L_case_ll:
410         ld.q    r14, 16, r2
411         blink   tr1, r63
412 .L_case_i:
413         ld.l    r14, 16, r2
414         blink   tr1, r63
415 .L_case_q:
416         ld.b    r14, 16, r2
417         blink   tr1, r63
418 .L_case_uq:
419         ld.ub   r14, 16, r2
420         blink   tr1, r63
421 .L_case_h:
422         ld.w    r14, 16, r2
423         blink   tr1, r63
424 .L_case_uh:
425         ld.uw   r14, 16, r2
426         blink   tr1, r63
427 .L_case_v:
428         add.l   r14, r63, r15
429         ld.l    r15, 4, r12
430         ld.l    r15, 8, r14
431         ld.l    r15, 12, r18
432         addi.l  r15, 136, r15
433         ptabs   r18, tr0
434         blink   tr0, r63
435
436 .LFE2:
437 .ffi_closure_SYSV_end:
438         .size    CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
439
440         .section        ".eh_frame","aw",@progbits
441 __FRAME_BEGIN__:
442         .4byte  .LECIE1-.LSCIE1 /* Length of Common Information Entry */
443 .LSCIE1:
444         .4byte  0x0     /* CIE Identifier Tag */
445         .byte   0x1     /* CIE Version */
446 #ifdef PIC
447         .ascii "zR\0"   /* CIE Augmentation */
448 #else
449         .byte   0x0     /* CIE Augmentation */
450 #endif
451         .uleb128 0x1    /* CIE Code Alignment Factor */
452         .sleb128 -4     /* CIE Data Alignment Factor */
453         .byte   0x12    /* CIE RA Column */
454 #ifdef PIC
455         .uleb128 0x1    /* Augmentation size */
456         .byte   0x10    /* FDE Encoding (pcrel) */
457 #endif
458         .byte   0xc     /* DW_CFA_def_cfa */
459         .uleb128 0xf
460         .uleb128 0x0
461         .align  2
462 .LECIE1:
463 .LSFDE1:
464         .4byte  datalabel .LEFDE1-datalabel .LASFDE1    /* FDE Length */
465 .LASFDE1:
466         .4byte  datalabel .LASFDE1-datalabel __FRAME_BEGIN__
467 #ifdef PIC
468         .4byte  .LFB1-. /* FDE initial location */
469 #else
470         .4byte  .LFB1   /* FDE initial location */
471 #endif
472         .4byte  datalabel .LFE1-datalabel .LFB1 /* FDE address range */
473 #ifdef PIC
474         .uleb128 0x0    /* Augmentation size */
475 #endif
476         .byte   0x4     /* DW_CFA_advance_loc4 */
477         .4byte  datalabel .LCFI0-datalabel .LFB1
478         .byte   0xe     /* DW_CFA_def_cfa_offset */
479         .uleb128 0x30
480         .byte   0x4     /* DW_CFA_advance_loc4 */
481         .4byte  datalabel .LCFI1-datalabel .LCFI0
482         .byte   0x8e    /* DW_CFA_offset, column 0xe */
483         .uleb128 0xc
484         .byte   0x92    /* DW_CFA_offset, column 0x12 */
485         .uleb128 0xb
486         .byte   0x9c    /* DW_CFA_offset, column 0x1c */
487         .uleb128 0xa
488         .byte   0x9d    /* DW_CFA_offset, column 0x1d */
489         .uleb128 0x8
490         .byte   0x9e    /* DW_CFA_offset, column 0x1e */
491         .uleb128 0x6
492         .byte   0x9f    /* DW_CFA_offset, column 0x1f */
493         .uleb128 0x4
494         .byte   0xa0    /* DW_CFA_offset, column 0x20 */
495         .uleb128 0x2
496         .byte   0x4     /* DW_CFA_advance_loc4 */
497         .4byte  datalabel .LCFI2-datalabel .LCFI1
498         .byte   0xd     /* DW_CFA_def_cfa_register */
499         .uleb128 0xe
500         .align  2
501 .LEFDE1:
502
503 .LSFDE3:
504         .4byte  datalabel .LEFDE3-datalabel .LASFDE3    /* FDE Length */
505 .LASFDE3:
506         .4byte  datalabel .LASFDE3-datalabel __FRAME_BEGIN__
507 #ifdef PIC
508         .4byte  .LFB2-. /* FDE initial location */
509 #else
510         .4byte  .LFB2   /* FDE initial location */
511 #endif
512         .4byte  datalabel .LFE2-datalabel .LFB2 /* FDE address range */
513 #ifdef PIC
514         .uleb128 0x0    /* Augmentation size */
515 #endif
516         .byte   0x4     /* DW_CFA_advance_loc4 */
517         .4byte  datalabel .LCFI3-datalabel .LFB2
518         .byte   0xe     /* DW_CFA_def_cfa_offset */
519         .uleb128 0x88
520         .byte   0x4     /* DW_CFA_advance_loc4 */
521         .4byte  datalabel .LCFI4-datalabel .LCFI3
522         .byte   0x8c    /* DW_CFA_offset, column 0xc */
523         .uleb128 0x21
524         .byte   0x8e    /* DW_CFA_offset, column 0xe */
525         .uleb128 0x20
526         .byte   0x92    /* DW_CFA_offset, column 0x12 */
527         .uleb128 0x1f
528         .byte   0x4     /* DW_CFA_advance_loc4 */
529         .4byte  datalabel .LCFI5-datalabel .LCFI4
530         .byte   0xd     /* DW_CFA_def_cfa_register */
531         .uleb128 0xe
532         .align  2
533 .LEFDE3: