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