* src/ia64/ffitarget.h (ffi_arg) ADD DI attribute.
[official-gcc.git] / libffi / src / ia64 / unix.S
blob45dabb74c9e7d4c89054758774ed9ee62c79a879
1 /* -----------------------------------------------------------------------
2    unix.S - Copyright (c) 1998 Red Hat, Inc.
3             Copyright (c) 2000 Hewlett Packard Company
4    
5    IA64/unix Foreign Function Interface 
7    Primary author: Hans Boehm, HP Labs
9    Loosely modeled on Cygnus code for other platforms.
11    Permission is hereby granted, free of charge, to any person obtaining
12    a copy of this software and associated documentation files (the
13    ``Software''), to deal in the Software without restriction, including
14    without limitation the rights to use, copy, modify, merge, publish,
15    distribute, sublicense, and/or sell copies of the Software, and to
16    permit persons to whom the Software is furnished to do so, subject to
17    the following conditions:
19    The above copyright notice and this permission notice shall be included
20    in all copies or substantial portions of the Software.
22    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
23    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25    IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28    OTHER DEALINGS IN THE SOFTWARE.
29    ----------------------------------------------------------------------- */
31 #define LIBFFI_ASM      
32 #include <fficonfig.h>
33 #include <ffi.h>
34 #include "ia64_flags.h"
36         .pred.safe_across_calls p1-p5,p16-p63
37 .text
39 /* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue,
40                       void (*fn)(), int flags);
41  */
43         .align 16
44         .global ffi_call_unix
45         .proc   ffi_call_unix
46 ffi_call_unix:
47         .prologue
48         /* Bit o trickiness.  We actually share a stack frame with ffi_call.
49            Rely on the fact that ffi_call uses a vframe and don't bother
50            tracking one here at all.  */
51         .fframe 0
52         .save   ar.pfs, r36 // loc0
53         alloc   loc0 = ar.pfs, 4, 3, 8, 0
54         .save   rp, loc1
55         mov     loc1 = b0
56         .body
57         add     r16 = 16, in0
58         mov     loc2 = gp
59         mov     r8 = in1
60         ;;
62         /* Load up all of the argument registers.  */
63         ldf.fill f8 = [in0], 32
64         ldf.fill f9 = [r16], 32
65         ;;
66         ldf.fill f10 = [in0], 32
67         ldf.fill f11 = [r16], 32
68         ;;
69         ldf.fill f12 = [in0], 32
70         ldf.fill f13 = [r16], 32
71         ;;
72         ldf.fill f14 = [in0], 32
73         ldf.fill f15 = [r16], 24
74         ;;
75         ld8     out0 = [in0], 16
76         ld8     out1 = [r16], 16
77         ;;
78         ld8     out2 = [in0], 16
79         ld8     out3 = [r16], 16
80         ;;
81         ld8     out4 = [in0], 16
82         ld8     out5 = [r16], 16
83         ;;
84         ld8     out6 = [in0]
85         ld8     out7 = [r16]
86         ;;
88         /* Deallocate the register save area from the stack frame.  */
89         mov     sp = in0
91         /* Call the target function.  */
92         ld8     r16 = [in2], 8
93         ;;
94         ld8     gp = [in2]
95         mov     b6 = r16
96         br.call.sptk.many b0 = b6
97         ;;
99         /* Dispatch to handle return value.  */
100         mov     gp = loc2
101         zxt1    r16 = in3
102         ;;
103         mov     ar.pfs = loc0
104         addl    r18 = @ltoffx(.Lst_table), gp
105         ;;
106         ld8.mov r18 = [r18], .Lst_table
107         mov     b0 = loc1
108         ;;
109         shladd  r18 = r16, 3, r18
110         ;;
111         ld8     r17 = [r18]
112         shr     in3 = in3, 8
113         ;;
114         add     r17 = r17, r18
115         ;;
116         mov     b6 = r17
117         br      b6
118         ;;
120 .Lst_void:
121         br.ret.sptk.many b0
122         ;;
123 .Lst_uint8:
124         zxt1    r8 = r8
125         ;;
126         st8     [in1] = r8
127         br.ret.sptk.many b0
128         ;;
129 .Lst_sint8:
130         sxt1    r8 = r8
131         ;;
132         st8     [in1] = r8
133         br.ret.sptk.many b0
134         ;;
135 .Lst_uint16:
136         zxt2    r8 = r8
137         ;;
138         st8     [in1] = r8
139         br.ret.sptk.many b0
140         ;;
141 .Lst_sint16:
142         sxt2    r8 = r8
143         ;;
144         st8     [in1] = r8
145         br.ret.sptk.many b0
146         ;;
147 .Lst_uint32:
148         zxt4    r8 = r8
149         ;;
150         st8     [in1] = r8
151         br.ret.sptk.many b0
152         ;;
153 .Lst_sint32:
154         sxt4    r8 = r8
155         ;;
156         st8     [in1] = r8
157         br.ret.sptk.many b0
158         ;;
159 .Lst_int64:
160         st8     [in1] = r8
161         br.ret.sptk.many b0
162         ;;
163 .Lst_float:
164         stfs    [in1] = f8
165         br.ret.sptk.many b0
166         ;;
167 .Lst_double:
168         stfd    [in1] = f8
169         br.ret.sptk.many b0
170         ;;
171 .Lst_ldouble:
172         stfe    [in1] = f8
173         br.ret.sptk.many b0
174         ;;
176 .Lst_small_struct:
177         add     sp = -16, sp
178         cmp.lt  p6, p0 = 8, in3
179         cmp.lt  p7, p0 = 16, in3
180         cmp.lt  p8, p0 = 24, in3
181         ;;
182         add     r16 = 8, sp
183         add     r17 = 16, sp
184         add     r18 = 24, sp
185         ;;
186         st8     [sp] = r8
187 (p6)    st8     [r16] = r9
188         mov     out0 = in1
189 (p7)    st8     [r17] = r10
190 (p8)    st8     [r18] = r11
191         mov     out1 = sp
192         mov     out2 = in3
193         br.call.sptk.many b0 = memcpy#
194         ;;
195         mov     ar.pfs = loc0
196         mov     b0 = loc1
197         mov     gp = loc2
198         br.ret.sptk.many b0
200 .Lst_hfa_float:
201         add     r16 = 4, in1
202         cmp.lt  p6, p0 = 4, in3
203         ;;
204         stfs    [in1] = f8, 8
205 (p6)    stfs    [r16] = f9, 8
206         cmp.lt  p7, p0 = 8, in3
207         cmp.lt  p8, p0 = 12, in3
208         ;;
209 (p7)    stfs    [in1] = f10, 8
210 (p8)    stfs    [r16] = f11, 8
211         cmp.lt  p9, p0 = 16, in3
212         cmp.lt  p10, p0 = 20, in3
213         ;;
214 (p9)    stfs    [in1] = f12, 8
215 (p10)   stfs    [r16] = f13, 8
216         cmp.lt  p6, p0 = 24, in3
217         cmp.lt  p7, p0 = 28, in3
218         ;;
219 (p6)    stfs    [in1] = f14
220 (p7)    stfs    [r16] = f15
221         br.ret.sptk.many b0
222         ;;
224 .Lst_hfa_double:
225         add     r16 = 8, in1
226         cmp.lt  p6, p0 = 8, in3
227         ;;
228         stfd    [in1] = f8, 16
229 (p6)    stfd    [r16] = f9, 16
230         cmp.lt  p7, p0 = 16, in3
231         cmp.lt  p8, p0 = 24, in3
232         ;;
233 (p7)    stfd    [in1] = f10, 16
234 (p8)    stfd    [r16] = f11, 16
235         cmp.lt  p9, p0 = 32, in3
236         cmp.lt  p10, p0 = 40, in3
237         ;;
238 (p9)    stfd    [in1] = f12, 16
239 (p10)   stfd    [r16] = f13, 16
240         cmp.lt  p6, p0 = 48, in3
241         cmp.lt  p7, p0 = 56, in3
242         ;;
243 (p6)    stfd    [in1] = f14
244 (p7)    stfd    [r16] = f15
245         br.ret.sptk.many b0
246         ;;
248 .Lst_hfa_ldouble:
249         add     r16 = 16, in1
250         cmp.lt  p6, p0 = 16, in3
251         ;;
252         stfe    [in1] = f8, 32
253 (p6)    stfe    [r16] = f9, 32
254         cmp.lt  p7, p0 = 32, in3
255         cmp.lt  p8, p0 = 48, in3
256         ;;
257 (p7)    stfe    [in1] = f10, 32
258 (p8)    stfe    [r16] = f11, 32
259         cmp.lt  p9, p0 = 64, in3
260         cmp.lt  p10, p0 = 80, in3
261         ;;
262 (p9)    stfe    [in1] = f12, 32
263 (p10)   stfe    [r16] = f13, 32
264         cmp.lt  p6, p0 = 96, in3
265         cmp.lt  p7, p0 = 112, in3
266         ;;
267 (p6)    stfe    [in1] = f14
268 (p7)    stfe    [r16] = f15
269         br.ret.sptk.many b0
270         ;;
272         .endp ffi_call_unix
274         .align 16
275         .global ffi_closure_unix
276         .proc ffi_closure_unix
278 #define FRAME_SIZE      (8*16 + 8*8 + 8*16)
280 ffi_closure_unix:
281         .prologue
282         .save   ar.pfs, r40 // loc0
283         alloc   loc0 = ar.pfs, 8, 4, 4, 0
284         .fframe FRAME_SIZE
285         add     r12 = -FRAME_SIZE, r12
286         .save   rp, loc1
287         mov     loc1 = b0
288         .save   ar.unat, loc2
289         mov     loc2 = ar.unat
290         .body
292         /* Retrieve closure pointer and real gp.  */
293 #ifdef _ILP32
294         addp4   out0 = 0, gp
295         addp4   gp = 16, gp
296 #else
297         mov     out0 = gp
298         add     gp = 16, gp
299 #endif
300         ;;
301         ld8     gp = [gp]
303         /* Spill all of the possible argument registers.  */
304         add     r16 = 16 + 8*16, sp
305         add     r17 = 16 + 8*16 + 16, sp
306         ;;
307         stf.spill [r16] = f8, 32
308         stf.spill [r17] = f9, 32
309         mov     loc3 = gp
310         ;;
311         stf.spill [r16] = f10, 32
312         stf.spill [r17] = f11, 32
313         ;;
314         stf.spill [r16] = f12, 32
315         stf.spill [r17] = f13, 32
316         ;;
317         stf.spill [r16] = f14, 32
318         stf.spill [r17] = f15, 24
319         ;;
320         .mem.offset 0, 0
321         st8.spill [r16] = in0, 16
322         .mem.offset 8, 0
323         st8.spill [r17] = in1, 16
324         add     out1 = 16 + 8*16, sp
325         ;;
326         .mem.offset 0, 0
327         st8.spill [r16] = in2, 16
328         .mem.offset 8, 0
329         st8.spill [r17] = in3, 16
330         add     out2 = 16, sp
331         ;;
332         .mem.offset 0, 0
333         st8.spill [r16] = in4, 16
334         .mem.offset 8, 0
335         st8.spill [r17] = in5, 16
336         mov     out3 = r8
337         ;;
338         .mem.offset 0, 0
339         st8.spill [r16] = in6
340         .mem.offset 8, 0
341         st8.spill [r17] = in7
343         /* Invoke ffi_closure_unix_inner for the hard work.  */
344         br.call.sptk.many b0 = ffi_closure_unix_inner
345         ;;
347         /* Dispatch to handle return value.  */
348         mov     gp = loc3
349         zxt1    r16 = r8
350         ;;
351         addl    r18 = @ltoffx(.Lld_table), gp
352         mov     ar.pfs = loc0
353         ;;
354         ld8.mov r18 = [r18], .Lld_table
355         mov     b0 = loc1
356         ;;
357         shladd  r18 = r16, 3, r18
358         mov     ar.unat = loc2
359         ;;
360         ld8     r17 = [r18]
361         shr     r8 = r8, 8
362         ;;
363         add     r17 = r17, r18
364         add     r16 = 16, sp
365         ;;
366         mov     b6 = r17
367         br      b6
368         ;;
369         .label_state 1
371 .Lld_void:
372         .restore sp
373         add     sp = FRAME_SIZE, sp
374         br.ret.sptk.many b0
375         ;;
376 .Lld_int:
377         .body
378         .copy_state 1
379         ld8     r8 = [r16]
380         .restore sp
381         add     sp = FRAME_SIZE, sp
382         br.ret.sptk.many b0
383         ;;
384 .Lld_float:
385         .body
386         .copy_state 1
387         ldfs    f8 = [r16]
388         .restore sp
389         add     sp = FRAME_SIZE, sp
390         br.ret.sptk.many b0
391         ;;
392 .Lld_double:
393         .body
394         .copy_state 1
395         ldfd    f8 = [r16]
396         .restore sp
397         add     sp = FRAME_SIZE, sp
398         br.ret.sptk.many b0
399         ;;
400 .Lld_ldouble:
401         .body
402         .copy_state 1
403         ldfe    f8 = [r16]
404         .restore sp
405         add     sp = FRAME_SIZE, sp
406         br.ret.sptk.many b0
407         ;;
409 .Lld_small_struct:
410         .body
411         .copy_state 1
412         add     r17 = 8, r16
413         cmp.lt  p6, p0 = 8, r8
414         cmp.lt  p7, p0 = 16, r8
415         cmp.lt  p8, p0 = 24, r8
416         ;;
417         ld8     r8 = [r16], 16
418 (p6)    ld8     r9 = [r17], 16
419         ;;
420 (p7)    ld8     r10 = [r16]
421 (p8)    ld8     r11 = [r17]
422         .restore sp
423         add     sp = FRAME_SIZE, sp
424         br.ret.sptk.many b0
425         ;;
427 .Lld_hfa_float:
428         .body
429         .copy_state 1
430         add     r17 = 4, r16
431         cmp.lt  p6, p0 = 4, r8
432         ;;
433         ldfs    f8 = [r16], 8
434 (p6)    ldfs    f9 = [r17], 8
435         cmp.lt  p7, p0 = 8, r8
436         cmp.lt  p8, p0 = 12, r8
437         ;;
438 (p7)    ldfs    f10 = [r16], 8
439 (p8)    ldfs    f11 = [r17], 8
440         cmp.lt  p9, p0 = 16, r8
441         cmp.lt  p10, p0 = 20, r8
442         ;;
443 (p9)    ldfs    f12 = [r16], 8
444 (p10)   ldfs    f13 = [r17], 8
445         cmp.lt  p6, p0 = 24, r8
446         cmp.lt  p7, p0 = 28, r8
447         ;;
448 (p6)    ldfs    f14 = [r16]
449 (p7)    ldfs    f15 = [r17]
450         .restore sp
451         add     sp = FRAME_SIZE, sp
452         br.ret.sptk.many b0
453         ;;
455 .Lld_hfa_double:
456         .body
457         .copy_state 1
458         add     r17 = 8, r16
459         cmp.lt  p6, p0 = 8, r8
460         ;;
461         ldfd    f8 = [r16], 16
462 (p6)    ldfd    f9 = [r17], 16
463         cmp.lt  p7, p0 = 16, r8
464         cmp.lt  p8, p0 = 24, r8
465         ;;
466 (p7)    ldfd    f10 = [r16], 16
467 (p8)    ldfd    f11 = [r17], 16
468         cmp.lt  p9, p0 = 32, r8
469         cmp.lt  p10, p0 = 40, r8
470         ;;
471 (p9)    ldfd    f12 = [r16], 16
472 (p10)   ldfd    f13 = [r17], 16
473         cmp.lt  p6, p0 = 48, r8
474         cmp.lt  p7, p0 = 56, r8
475         ;;
476 (p6)    ldfd    f14 = [r16]
477 (p7)    ldfd    f15 = [r17]
478         .restore sp
479         add     sp = FRAME_SIZE, sp
480         br.ret.sptk.many b0
481         ;;
483 .Lld_hfa_ldouble:
484         .body
485         .copy_state 1
486         add     r17 = 16, r16
487         cmp.lt  p6, p0 = 16, r8
488         ;;
489         ldfe    f8 = [r16], 32
490 (p6)    ldfe    f9 = [r17], 32
491         cmp.lt  p7, p0 = 32, r8
492         cmp.lt  p8, p0 = 48, r8
493         ;;
494 (p7)    ldfe    f10 = [r16], 32
495 (p8)    ldfe    f11 = [r17], 32
496         cmp.lt  p9, p0 = 64, r8
497         cmp.lt  p10, p0 = 80, r8
498         ;;
499 (p9)    ldfe    f12 = [r16], 32
500 (p10)   ldfe    f13 = [r17], 32
501         cmp.lt  p6, p0 = 96, r8
502         cmp.lt  p7, p0 = 112, r8
503         ;;
504 (p6)    ldfe    f14 = [r16]
505 (p7)    ldfe    f15 = [r17]
506         .restore sp
507         add     sp = FRAME_SIZE, sp
508         br.ret.sptk.many b0
509         ;;
511         .endp   ffi_closure_unix
513         .section .rodata
514         .align  8
515 .Lst_table:
516         data8   @pcrel(.Lst_void)               // FFI_TYPE_VOID
517         data8   @pcrel(.Lst_sint32)             // FFI_TYPE_INT
518         data8   @pcrel(.Lst_float)              // FFI_TYPE_FLOAT
519         data8   @pcrel(.Lst_double)             // FFI_TYPE_DOUBLE
520         data8   @pcrel(.Lst_ldouble)            // FFI_TYPE_LONGDOUBLE
521         data8   @pcrel(.Lst_uint8)              // FFI_TYPE_UINT8
522         data8   @pcrel(.Lst_sint8)              // FFI_TYPE_SINT8
523         data8   @pcrel(.Lst_uint16)             // FFI_TYPE_UINT16
524         data8   @pcrel(.Lst_sint16)             // FFI_TYPE_SINT16
525         data8   @pcrel(.Lst_uint32)             // FFI_TYPE_UINT32
526         data8   @pcrel(.Lst_sint32)             // FFI_TYPE_SINT32
527         data8   @pcrel(.Lst_int64)              // FFI_TYPE_UINT64
528         data8   @pcrel(.Lst_int64)              // FFI_TYPE_SINT64
529         data8   @pcrel(.Lst_void)               // FFI_TYPE_STRUCT
530         data8   @pcrel(.Lst_int64)              // FFI_TYPE_POINTER
531         data8   @pcrel(.Lst_small_struct)       // FFI_IA64_TYPE_SMALL_STRUCT
532         data8   @pcrel(.Lst_hfa_float)          // FFI_IA64_TYPE_HFA_FLOAT
533         data8   @pcrel(.Lst_hfa_double)         // FFI_IA64_TYPE_HFA_DOUBLE
534         data8   @pcrel(.Lst_hfa_ldouble)        // FFI_IA64_TYPE_HFA_LDOUBLE
536 .Lld_table:
537         data8   @pcrel(.Lld_void)               // FFI_TYPE_VOID
538         data8   @pcrel(.Lld_int)                // FFI_TYPE_INT
539         data8   @pcrel(.Lld_float)              // FFI_TYPE_FLOAT
540         data8   @pcrel(.Lld_double)             // FFI_TYPE_DOUBLE
541         data8   @pcrel(.Lld_ldouble)            // FFI_TYPE_LONGDOUBLE
542         data8   @pcrel(.Lld_int)                // FFI_TYPE_UINT8
543         data8   @pcrel(.Lld_int)                // FFI_TYPE_SINT8
544         data8   @pcrel(.Lld_int)                // FFI_TYPE_UINT16
545         data8   @pcrel(.Lld_int)                // FFI_TYPE_SINT16
546         data8   @pcrel(.Lld_int)                // FFI_TYPE_UINT32
547         data8   @pcrel(.Lld_int)                // FFI_TYPE_SINT32
548         data8   @pcrel(.Lld_int)                // FFI_TYPE_UINT64
549         data8   @pcrel(.Lld_int)                // FFI_TYPE_SINT64
550         data8   @pcrel(.Lld_void)               // FFI_TYPE_STRUCT
551         data8   @pcrel(.Lld_int)                // FFI_TYPE_POINTER
552         data8   @pcrel(.Lld_small_struct)       // FFI_IA64_TYPE_SMALL_STRUCT
553         data8   @pcrel(.Lld_hfa_float)          // FFI_IA64_TYPE_HFA_FLOAT
554         data8   @pcrel(.Lld_hfa_double)         // FFI_IA64_TYPE_HFA_DOUBLE
555         data8   @pcrel(.Lld_hfa_ldouble)        // FFI_IA64_TYPE_HFA_LDOUBLE