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