Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libffi / src / ia64 / unix.S
blob7c68b2d3a62d2b103811c8a8b7abe8a8877a9143
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         mov     out0 = gp
294         add     gp = 16, gp
295         ;;
296         ld8     gp = [gp]
298         /* Spill all of the possible argument registers.  */
299         add     r16 = 16 + 8*16, sp
300         add     r17 = 16 + 8*16 + 16, sp
301         ;;
302         stf.spill [r16] = f8, 32
303         stf.spill [r17] = f9, 32
304         mov     loc3 = gp
305         ;;
306         stf.spill [r16] = f10, 32
307         stf.spill [r17] = f11, 32
308         ;;
309         stf.spill [r16] = f12, 32
310         stf.spill [r17] = f13, 32
311         ;;
312         stf.spill [r16] = f14, 32
313         stf.spill [r17] = f15, 24
314         ;;
315         .mem.offset 0, 0
316         st8.spill [r16] = in0, 16
317         .mem.offset 8, 0
318         st8.spill [r17] = in1, 16
319         add     out1 = 16 + 8*16, sp
320         ;;
321         .mem.offset 0, 0
322         st8.spill [r16] = in2, 16
323         .mem.offset 8, 0
324         st8.spill [r17] = in3, 16
325         add     out2 = 16, sp
326         ;;
327         .mem.offset 0, 0
328         st8.spill [r16] = in4, 16
329         .mem.offset 8, 0
330         st8.spill [r17] = in5, 16
331         mov     out3 = r8
332         ;;
333         .mem.offset 0, 0
334         st8.spill [r16] = in6
335         .mem.offset 8, 0
336         st8.spill [r17] = in7
338         /* Invoke ffi_closure_unix_inner for the hard work.  */
339         br.call.sptk.many b0 = ffi_closure_unix_inner
340         ;;
342         /* Dispatch to handle return value.  */
343         mov     gp = loc3
344         zxt1    r16 = r8
345         ;;
346         addl    r18 = @ltoffx(.Lld_table), gp
347         mov     ar.pfs = loc0
348         ;;
349         ld8.mov r18 = [r18], .Lld_table
350         mov     b0 = loc1
351         ;;
352         shladd  r18 = r16, 3, r18
353         mov     ar.unat = loc2
354         ;;
355         ld8     r17 = [r18]
356         shr     r8 = r8, 8
357         ;;
358         add     r17 = r17, r18
359         add     r16 = 16, sp
360         ;;
361         mov     b6 = r17
362         br      b6
363         ;;
364         .label_state 1
366 .Lld_void:
367         .restore sp
368         add     sp = FRAME_SIZE, sp
369         br.ret.sptk.many b0
370         ;;
371 .Lld_int8:
372         .body
373         .copy_state 1
374         ld1     r8 = [r16]
375         .restore sp
376         add     sp = FRAME_SIZE, sp
377         br.ret.sptk.many b0
378         ;;
379 .Lld_int16:
380         .body
381         .copy_state 1
382         ld2     r8 = [r16]
383         .restore sp
384         add     sp = FRAME_SIZE, sp
385         br.ret.sptk.many b0
386         ;;
387 .Lld_int32:
388         .body
389         .copy_state 1
390         ld4     r8 = [r16]
391         .restore sp
392         add     sp = FRAME_SIZE, sp
393         br.ret.sptk.many b0
394         ;;
395 .Lld_int64:
396         .body
397         .copy_state 1
398         ld8     r8 = [r16]
399         .restore sp
400         add     sp = FRAME_SIZE, sp
401         br.ret.sptk.many b0
402         ;;
403 .Lld_float:
404         .body
405         .copy_state 1
406         ldfs    f8 = [r16]
407         .restore sp
408         add     sp = FRAME_SIZE, sp
409         br.ret.sptk.many b0
410         ;;
411 .Lld_double:
412         .body
413         .copy_state 1
414         ldfd    f8 = [r16]
415         .restore sp
416         add     sp = FRAME_SIZE, sp
417         br.ret.sptk.many b0
418         ;;
419 .Lld_ldouble:
420         .body
421         .copy_state 1
422         ldfe    f8 = [r16]
423         .restore sp
424         add     sp = FRAME_SIZE, sp
425         br.ret.sptk.many b0
426         ;;
428 .Lld_small_struct:
429         .body
430         .copy_state 1
431         add     r17 = 8, r16
432         cmp.lt  p6, p0 = 8, r8
433         cmp.lt  p7, p0 = 16, r8
434         cmp.lt  p8, p0 = 24, r8
435         ;;
436         ld8     r8 = [r16], 16
437 (p6)    ld8     r9 = [r17], 16
438         ;;
439 (p7)    ld8     r10 = [r16]
440 (p8)    ld8     r11 = [r17]
441         .restore sp
442         add     sp = FRAME_SIZE, sp
443         br.ret.sptk.many b0
444         ;;
446 .Lld_hfa_float:
447         .body
448         .copy_state 1
449         add     r17 = 4, r16
450         cmp.lt  p6, p0 = 4, r8
451         ;;
452         ldfs    f8 = [r16], 8
453 (p6)    ldfs    f9 = [r17], 8
454         cmp.lt  p7, p0 = 8, r8
455         cmp.lt  p8, p0 = 12, r8
456         ;;
457 (p7)    ldfs    f10 = [r16], 8
458 (p8)    ldfs    f11 = [r17], 8
459         cmp.lt  p9, p0 = 16, r8
460         cmp.lt  p10, p0 = 20, r8
461         ;;
462 (p9)    ldfs    f12 = [r16], 8
463 (p10)   ldfs    f13 = [r17], 8
464         cmp.lt  p6, p0 = 24, r8
465         cmp.lt  p7, p0 = 28, r8
466         ;;
467 (p6)    ldfs    f14 = [r16]
468 (p7)    ldfs    f15 = [r17]
469         .restore sp
470         add     sp = FRAME_SIZE, sp
471         br.ret.sptk.many b0
472         ;;
474 .Lld_hfa_double:
475         .body
476         .copy_state 1
477         add     r17 = 8, r16
478         cmp.lt  p6, p0 = 8, r8
479         ;;
480         ldfd    f8 = [r16], 16
481 (p6)    ldfd    f9 = [r17], 16
482         cmp.lt  p7, p0 = 16, r8
483         cmp.lt  p8, p0 = 24, r8
484         ;;
485 (p7)    ldfd    f10 = [r16], 16
486 (p8)    ldfd    f11 = [r17], 16
487         cmp.lt  p9, p0 = 32, r8
488         cmp.lt  p10, p0 = 40, r8
489         ;;
490 (p9)    ldfd    f12 = [r16], 16
491 (p10)   ldfd    f13 = [r17], 16
492         cmp.lt  p6, p0 = 48, r8
493         cmp.lt  p7, p0 = 56, r8
494         ;;
495 (p6)    ldfd    f14 = [r16]
496 (p7)    ldfd    f15 = [r17]
497         .restore sp
498         add     sp = FRAME_SIZE, sp
499         br.ret.sptk.many b0
500         ;;
502 .Lld_hfa_ldouble:
503         .body
504         .copy_state 1
505         add     r17 = 16, r16
506         cmp.lt  p6, p0 = 16, r8
507         ;;
508         ldfe    f8 = [r16], 32
509 (p6)    ldfe    f9 = [r17], 32
510         cmp.lt  p7, p0 = 32, r8
511         cmp.lt  p8, p0 = 48, r8
512         ;;
513 (p7)    ldfe    f10 = [r16], 32
514 (p8)    ldfe    f11 = [r17], 32
515         cmp.lt  p9, p0 = 64, r8
516         cmp.lt  p10, p0 = 80, r8
517         ;;
518 (p9)    ldfe    f12 = [r16], 32
519 (p10)   ldfe    f13 = [r17], 32
520         cmp.lt  p6, p0 = 96, r8
521         cmp.lt  p7, p0 = 112, r8
522         ;;
523 (p6)    ldfe    f14 = [r16]
524 (p7)    ldfe    f15 = [r17]
525         .restore sp
526         add     sp = FRAME_SIZE, sp
527         br.ret.sptk.many b0
528         ;;
530         .endp   ffi_closure_unix
532         .section .rodata
533         .align  8
534 .Lst_table:
535         data8   @pcrel(.Lst_void)               // FFI_TYPE_VOID
536         data8   @pcrel(.Lst_sint32)             // FFI_TYPE_INT
537         data8   @pcrel(.Lst_float)              // FFI_TYPE_FLOAT
538         data8   @pcrel(.Lst_double)             // FFI_TYPE_DOUBLE
539         data8   @pcrel(.Lst_ldouble)            // FFI_TYPE_LONGDOUBLE
540         data8   @pcrel(.Lst_uint8)              // FFI_TYPE_UINT8
541         data8   @pcrel(.Lst_sint8)              // FFI_TYPE_SINT8
542         data8   @pcrel(.Lst_uint16)             // FFI_TYPE_UINT16
543         data8   @pcrel(.Lst_sint16)             // FFI_TYPE_SINT16
544         data8   @pcrel(.Lst_uint32)             // FFI_TYPE_UINT32
545         data8   @pcrel(.Lst_sint32)             // FFI_TYPE_SINT32
546         data8   @pcrel(.Lst_int64)              // FFI_TYPE_UINT64
547         data8   @pcrel(.Lst_int64)              // FFI_TYPE_SINT64
548         data8   @pcrel(.Lst_void)               // FFI_TYPE_STRUCT
549         data8   @pcrel(.Lst_int64)              // FFI_TYPE_POINTER
550         data8   @pcrel(.Lst_small_struct)       // FFI_IA64_TYPE_SMALL_STRUCT
551         data8   @pcrel(.Lst_hfa_float)          // FFI_IA64_TYPE_HFA_FLOAT
552         data8   @pcrel(.Lst_hfa_double)         // FFI_IA64_TYPE_HFA_DOUBLE
553         data8   @pcrel(.Lst_hfa_ldouble)        // FFI_IA64_TYPE_HFA_LDOUBLE
555 .Lld_table:
556         data8   @pcrel(.Lld_void)               // FFI_TYPE_VOID
557         data8   @pcrel(.Lld_int32)              // FFI_TYPE_INT
558         data8   @pcrel(.Lld_float)              // FFI_TYPE_FLOAT
559         data8   @pcrel(.Lld_double)             // FFI_TYPE_DOUBLE
560         data8   @pcrel(.Lld_ldouble)            // FFI_TYPE_LONGDOUBLE
561         data8   @pcrel(.Lld_int8)               // FFI_TYPE_UINT8
562         data8   @pcrel(.Lld_int8)               // FFI_TYPE_SINT8
563         data8   @pcrel(.Lld_int16)              // FFI_TYPE_UINT16
564         data8   @pcrel(.Lld_int16)              // FFI_TYPE_SINT16
565         data8   @pcrel(.Lld_int32)              // FFI_TYPE_UINT32
566         data8   @pcrel(.Lld_int32)              // FFI_TYPE_SINT32
567         data8   @pcrel(.Lld_int64)              // FFI_TYPE_UINT64
568         data8   @pcrel(.Lld_int64)              // FFI_TYPE_SINT64
569         data8   @pcrel(.Lld_void)               // FFI_TYPE_STRUCT
570         data8   @pcrel(.Lld_int64)              // FFI_TYPE_POINTER
571         data8   @pcrel(.Lld_small_struct)       // FFI_IA64_TYPE_SMALL_STRUCT
572         data8   @pcrel(.Lld_hfa_float)          // FFI_IA64_TYPE_HFA_FLOAT
573         data8   @pcrel(.Lld_hfa_double)         // FFI_IA64_TYPE_HFA_DOUBLE
574         data8   @pcrel(.Lld_hfa_ldouble)        // FFI_IA64_TYPE_HFA_LDOUBLE