ada: Disable PIE mode during the build of the Ada front-end
[official-gcc.git] / libffi / src / ia64 / unix.S
blobe2547e02b3aa1c173bdbc80fc8ef78c00194c34f
1 /* -----------------------------------------------------------------------
2    unix.S - Copyright (c) 1998, 2008 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,
23    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29    DEALINGS IN THE SOFTWARE.
30    ----------------------------------------------------------------------- */
32 #define LIBFFI_ASM      
33 #include <fficonfig.h>
34 #include <ffi.h>
35 #include "ia64_flags.h"
37         .pred.safe_across_calls p1-p5,p16-p63
38 .text
40 /* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue,
41                       void (*fn)(void), int flags);
42  */
44         .align 16
45         .global ffi_call_unix
46         .proc   ffi_call_unix
47 ffi_call_unix:
48         .prologue
49         /* Bit o trickiness.  We actually share a stack frame with ffi_call.
50            Rely on the fact that ffi_call uses a vframe and don't bother
51            tracking one here at all.  */
52         .fframe 0
53         .save   ar.pfs, r36 // loc0
54         alloc   loc0 = ar.pfs, 4, 3, 8, 0
55         .save   rp, loc1
56         mov     loc1 = b0
57         .body
58         add     r16 = 16, in0
59         mov     loc2 = gp
60         mov     r8 = in1
61         ;;
63         /* Load up all of the argument registers.  */
64         ldf.fill f8 = [in0], 32
65         ldf.fill f9 = [r16], 32
66         ;;
67         ldf.fill f10 = [in0], 32
68         ldf.fill f11 = [r16], 32
69         ;;
70         ldf.fill f12 = [in0], 32
71         ldf.fill f13 = [r16], 32
72         ;;
73         ldf.fill f14 = [in0], 32
74         ldf.fill f15 = [r16], 24
75         ;;
76         ld8     out0 = [in0], 16
77         ld8     out1 = [r16], 16
78         ;;
79         ld8     out2 = [in0], 16
80         ld8     out3 = [r16], 16
81         ;;
82         ld8     out4 = [in0], 16
83         ld8     out5 = [r16], 16
84         ;;
85         ld8     out6 = [in0]
86         ld8     out7 = [r16]
87         ;;
89         /* Deallocate the register save area from the stack frame.  */
90         mov     sp = in0
92         /* Call the target function.  */
93         ld8     r16 = [in2], 8
94         ;;
95         ld8     gp = [in2]
96         mov     b6 = r16
97         br.call.sptk.many b0 = b6
98         ;;
100         /* Dispatch to handle return value.  */
101         mov     gp = loc2
102         zxt1    r16 = in3
103         ;;
104         mov     ar.pfs = loc0
105         addl    r18 = @ltoffx(.Lst_table), gp
106         ;;
107         ld8.mov r18 = [r18], .Lst_table
108         mov     b0 = loc1
109         ;;
110         shladd  r18 = r16, 3, r18
111         ;;
112         ld8     r17 = [r18]
113         shr     in3 = in3, 8
114         ;;
115         add     r17 = r17, r18
116         ;;
117         mov     b6 = r17
118         br      b6
119         ;;
121 .Lst_void:
122         br.ret.sptk.many b0
123         ;;
124 .Lst_uint8:
125         zxt1    r8 = r8
126         ;;
127         st8     [in1] = r8
128         br.ret.sptk.many b0
129         ;;
130 .Lst_sint8:
131         sxt1    r8 = r8
132         ;;
133         st8     [in1] = r8
134         br.ret.sptk.many b0
135         ;;
136 .Lst_uint16:
137         zxt2    r8 = r8
138         ;;
139         st8     [in1] = r8
140         br.ret.sptk.many b0
141         ;;
142 .Lst_sint16:
143         sxt2    r8 = r8
144         ;;
145         st8     [in1] = r8
146         br.ret.sptk.many b0
147         ;;
148 .Lst_uint32:
149         zxt4    r8 = r8
150         ;;
151         st8     [in1] = r8
152         br.ret.sptk.many b0
153         ;;
154 .Lst_sint32:
155         sxt4    r8 = r8
156         ;;
157         st8     [in1] = r8
158         br.ret.sptk.many b0
159         ;;
160 .Lst_int64:
161         st8     [in1] = r8
162         br.ret.sptk.many b0
163         ;;
164 .Lst_float:
165         stfs    [in1] = f8
166         br.ret.sptk.many b0
167         ;;
168 .Lst_double:
169         stfd    [in1] = f8
170         br.ret.sptk.many b0
171         ;;
172 .Lst_ldouble:
173         stfe    [in1] = f8
174         br.ret.sptk.many b0
175         ;;
177 .Lst_small_struct:
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         ;;
194         // ia64 software calling convention requires
195         // top 16 bytes of stack to be scratch space
196         // PLT resolver uses that scratch space at
197         // 'memcpy' symbol reolution time
198         add     sp = -16, sp
199         br.call.sptk.many b0 = memcpy#
200         ;;
201         mov     ar.pfs = loc0
202         mov     b0 = loc1
203         mov     gp = loc2
204         br.ret.sptk.many b0
206 .Lst_hfa_float:
207         add     r16 = 4, in1
208         cmp.lt  p6, p0 = 4, in3
209         ;;
210         stfs    [in1] = f8, 8
211 (p6)    stfs    [r16] = f9, 8
212         cmp.lt  p7, p0 = 8, in3
213         cmp.lt  p8, p0 = 12, in3
214         ;;
215 (p7)    stfs    [in1] = f10, 8
216 (p8)    stfs    [r16] = f11, 8
217         cmp.lt  p9, p0 = 16, in3
218         cmp.lt  p10, p0 = 20, in3
219         ;;
220 (p9)    stfs    [in1] = f12, 8
221 (p10)   stfs    [r16] = f13, 8
222         cmp.lt  p6, p0 = 24, in3
223         cmp.lt  p7, p0 = 28, in3
224         ;;
225 (p6)    stfs    [in1] = f14
226 (p7)    stfs    [r16] = f15
227         br.ret.sptk.many b0
228         ;;
230 .Lst_hfa_double:
231         add     r16 = 8, in1
232         cmp.lt  p6, p0 = 8, in3
233         ;;
234         stfd    [in1] = f8, 16
235 (p6)    stfd    [r16] = f9, 16
236         cmp.lt  p7, p0 = 16, in3
237         cmp.lt  p8, p0 = 24, in3
238         ;;
239 (p7)    stfd    [in1] = f10, 16
240 (p8)    stfd    [r16] = f11, 16
241         cmp.lt  p9, p0 = 32, in3
242         cmp.lt  p10, p0 = 40, in3
243         ;;
244 (p9)    stfd    [in1] = f12, 16
245 (p10)   stfd    [r16] = f13, 16
246         cmp.lt  p6, p0 = 48, in3
247         cmp.lt  p7, p0 = 56, in3
248         ;;
249 (p6)    stfd    [in1] = f14
250 (p7)    stfd    [r16] = f15
251         br.ret.sptk.many b0
252         ;;
254 .Lst_hfa_ldouble:
255         add     r16 = 16, in1
256         cmp.lt  p6, p0 = 16, in3
257         ;;
258         stfe    [in1] = f8, 32
259 (p6)    stfe    [r16] = f9, 32
260         cmp.lt  p7, p0 = 32, in3
261         cmp.lt  p8, p0 = 48, in3
262         ;;
263 (p7)    stfe    [in1] = f10, 32
264 (p8)    stfe    [r16] = f11, 32
265         cmp.lt  p9, p0 = 64, in3
266         cmp.lt  p10, p0 = 80, in3
267         ;;
268 (p9)    stfe    [in1] = f12, 32
269 (p10)   stfe    [r16] = f13, 32
270         cmp.lt  p6, p0 = 96, in3
271         cmp.lt  p7, p0 = 112, in3
272         ;;
273 (p6)    stfe    [in1] = f14
274 (p7)    stfe    [r16] = f15
275         br.ret.sptk.many b0
276         ;;
278         .endp ffi_call_unix
280         .align 16
281         .global ffi_closure_unix
282         .proc ffi_closure_unix
284 #define FRAME_SIZE      (8*16 + 8*8 + 8*16)
286 ffi_closure_unix:
287         .prologue
288         .save   ar.pfs, r40 // loc0
289         alloc   loc0 = ar.pfs, 8, 4, 4, 0
290         .fframe FRAME_SIZE
291         add     r12 = -FRAME_SIZE, r12
292         .save   rp, loc1
293         mov     loc1 = b0
294         .save   ar.unat, loc2
295         mov     loc2 = ar.unat
296         .body
298         /* Retrieve closure pointer and real gp.  */
299 #ifdef _ILP32
300         addp4   out0 = 0, gp
301         addp4   gp = 16, gp
302 #else
303         mov     out0 = gp
304         add     gp = 16, gp
305 #endif
306         ;;
307         ld8     gp = [gp]
309         /* Spill all of the possible argument registers.  */
310         add     r16 = 16 + 8*16, sp
311         add     r17 = 16 + 8*16 + 16, sp
312         ;;
313         stf.spill [r16] = f8, 32
314         stf.spill [r17] = f9, 32
315         mov     loc3 = gp
316         ;;
317         stf.spill [r16] = f10, 32
318         stf.spill [r17] = f11, 32
319         ;;
320         stf.spill [r16] = f12, 32
321         stf.spill [r17] = f13, 32
322         ;;
323         stf.spill [r16] = f14, 32
324         stf.spill [r17] = f15, 24
325         ;;
326         .mem.offset 0, 0
327         st8.spill [r16] = in0, 16
328         .mem.offset 8, 0
329         st8.spill [r17] = in1, 16
330         add     out1 = 16 + 8*16, sp
331         ;;
332         .mem.offset 0, 0
333         st8.spill [r16] = in2, 16
334         .mem.offset 8, 0
335         st8.spill [r17] = in3, 16
336         add     out2 = 16, sp
337         ;;
338         .mem.offset 0, 0
339         st8.spill [r16] = in4, 16
340         .mem.offset 8, 0
341         st8.spill [r17] = in5, 16
342         mov     out3 = r8
343         ;;
344         .mem.offset 0, 0
345         st8.spill [r16] = in6
346         .mem.offset 8, 0
347         st8.spill [r17] = in7
349         /* Invoke ffi_closure_unix_inner for the hard work.  */
350         br.call.sptk.many b0 = ffi_closure_unix_inner
351         ;;
353         /* Dispatch to handle return value.  */
354         mov     gp = loc3
355         zxt1    r16 = r8
356         ;;
357         addl    r18 = @ltoffx(.Lld_table), gp
358         mov     ar.pfs = loc0
359         ;;
360         ld8.mov r18 = [r18], .Lld_table
361         mov     b0 = loc1
362         ;;
363         shladd  r18 = r16, 3, r18
364         mov     ar.unat = loc2
365         ;;
366         ld8     r17 = [r18]
367         shr     r8 = r8, 8
368         ;;
369         add     r17 = r17, r18
370         add     r16 = 16, sp
371         ;;
372         mov     b6 = r17
373         br      b6
374         ;;
375         .label_state 1
377 .Lld_void:
378         .restore sp
379         add     sp = FRAME_SIZE, sp
380         br.ret.sptk.many b0
381         ;;
382 .Lld_int:
383         .body
384         .copy_state 1
385         ld8     r8 = [r16]
386         .restore sp
387         add     sp = FRAME_SIZE, sp
388         br.ret.sptk.many b0
389         ;;
390 .Lld_float:
391         .body
392         .copy_state 1
393         ldfs    f8 = [r16]
394         .restore sp
395         add     sp = FRAME_SIZE, sp
396         br.ret.sptk.many b0
397         ;;
398 .Lld_double:
399         .body
400         .copy_state 1
401         ldfd    f8 = [r16]
402         .restore sp
403         add     sp = FRAME_SIZE, sp
404         br.ret.sptk.many b0
405         ;;
406 .Lld_ldouble:
407         .body
408         .copy_state 1
409         ldfe    f8 = [r16]
410         .restore sp
411         add     sp = FRAME_SIZE, sp
412         br.ret.sptk.many b0
413         ;;
415 .Lld_small_struct:
416         .body
417         .copy_state 1
418         add     r17 = 8, r16
419         cmp.lt  p6, p0 = 8, r8
420         cmp.lt  p7, p0 = 16, r8
421         cmp.lt  p8, p0 = 24, r8
422         ;;
423         ld8     r8 = [r16], 16
424 (p6)    ld8     r9 = [r17], 16
425         ;;
426 (p7)    ld8     r10 = [r16]
427 (p8)    ld8     r11 = [r17]
428         .restore sp
429         add     sp = FRAME_SIZE, sp
430         br.ret.sptk.many b0
431         ;;
433 .Lld_hfa_float:
434         .body
435         .copy_state 1
436         add     r17 = 4, r16
437         cmp.lt  p6, p0 = 4, r8
438         ;;
439         ldfs    f8 = [r16], 8
440 (p6)    ldfs    f9 = [r17], 8
441         cmp.lt  p7, p0 = 8, r8
442         cmp.lt  p8, p0 = 12, r8
443         ;;
444 (p7)    ldfs    f10 = [r16], 8
445 (p8)    ldfs    f11 = [r17], 8
446         cmp.lt  p9, p0 = 16, r8
447         cmp.lt  p10, p0 = 20, r8
448         ;;
449 (p9)    ldfs    f12 = [r16], 8
450 (p10)   ldfs    f13 = [r17], 8
451         cmp.lt  p6, p0 = 24, r8
452         cmp.lt  p7, p0 = 28, r8
453         ;;
454 (p6)    ldfs    f14 = [r16]
455 (p7)    ldfs    f15 = [r17]
456         .restore sp
457         add     sp = FRAME_SIZE, sp
458         br.ret.sptk.many b0
459         ;;
461 .Lld_hfa_double:
462         .body
463         .copy_state 1
464         add     r17 = 8, r16
465         cmp.lt  p6, p0 = 8, r8
466         ;;
467         ldfd    f8 = [r16], 16
468 (p6)    ldfd    f9 = [r17], 16
469         cmp.lt  p7, p0 = 16, r8
470         cmp.lt  p8, p0 = 24, r8
471         ;;
472 (p7)    ldfd    f10 = [r16], 16
473 (p8)    ldfd    f11 = [r17], 16
474         cmp.lt  p9, p0 = 32, r8
475         cmp.lt  p10, p0 = 40, r8
476         ;;
477 (p9)    ldfd    f12 = [r16], 16
478 (p10)   ldfd    f13 = [r17], 16
479         cmp.lt  p6, p0 = 48, r8
480         cmp.lt  p7, p0 = 56, r8
481         ;;
482 (p6)    ldfd    f14 = [r16]
483 (p7)    ldfd    f15 = [r17]
484         .restore sp
485         add     sp = FRAME_SIZE, sp
486         br.ret.sptk.many b0
487         ;;
489 .Lld_hfa_ldouble:
490         .body
491         .copy_state 1
492         add     r17 = 16, r16
493         cmp.lt  p6, p0 = 16, r8
494         ;;
495         ldfe    f8 = [r16], 32
496 (p6)    ldfe    f9 = [r17], 32
497         cmp.lt  p7, p0 = 32, r8
498         cmp.lt  p8, p0 = 48, r8
499         ;;
500 (p7)    ldfe    f10 = [r16], 32
501 (p8)    ldfe    f11 = [r17], 32
502         cmp.lt  p9, p0 = 64, r8
503         cmp.lt  p10, p0 = 80, r8
504         ;;
505 (p9)    ldfe    f12 = [r16], 32
506 (p10)   ldfe    f13 = [r17], 32
507         cmp.lt  p6, p0 = 96, r8
508         cmp.lt  p7, p0 = 112, r8
509         ;;
510 (p6)    ldfe    f14 = [r16]
511 (p7)    ldfe    f15 = [r17]
512         .restore sp
513         add     sp = FRAME_SIZE, sp
514         br.ret.sptk.many b0
515         ;;
517         .endp   ffi_closure_unix
519         .section .rodata
520         .align  8
521 .Lst_table:
522         data8   @pcrel(.Lst_void)               // FFI_TYPE_VOID
523         data8   @pcrel(.Lst_sint32)             // FFI_TYPE_INT
524         data8   @pcrel(.Lst_float)              // FFI_TYPE_FLOAT
525         data8   @pcrel(.Lst_double)             // FFI_TYPE_DOUBLE
526         data8   @pcrel(.Lst_ldouble)            // FFI_TYPE_LONGDOUBLE
527         data8   @pcrel(.Lst_uint8)              // FFI_TYPE_UINT8
528         data8   @pcrel(.Lst_sint8)              // FFI_TYPE_SINT8
529         data8   @pcrel(.Lst_uint16)             // FFI_TYPE_UINT16
530         data8   @pcrel(.Lst_sint16)             // FFI_TYPE_SINT16
531         data8   @pcrel(.Lst_uint32)             // FFI_TYPE_UINT32
532         data8   @pcrel(.Lst_sint32)             // FFI_TYPE_SINT32
533         data8   @pcrel(.Lst_int64)              // FFI_TYPE_UINT64
534         data8   @pcrel(.Lst_int64)              // FFI_TYPE_SINT64
535         data8   @pcrel(.Lst_void)               // FFI_TYPE_STRUCT
536         data8   @pcrel(.Lst_int64)              // FFI_TYPE_POINTER
537         data8   @pcrel(.Lst_void)               // FFI_TYPE_COMPLEX (not implemented)
538         data8   @pcrel(.Lst_small_struct)       // FFI_IA64_TYPE_SMALL_STRUCT
539         data8   @pcrel(.Lst_hfa_float)          // FFI_IA64_TYPE_HFA_FLOAT
540         data8   @pcrel(.Lst_hfa_double)         // FFI_IA64_TYPE_HFA_DOUBLE
541         data8   @pcrel(.Lst_hfa_ldouble)        // FFI_IA64_TYPE_HFA_LDOUBLE
543 .Lld_table:
544         data8   @pcrel(.Lld_void)               // FFI_TYPE_VOID
545         data8   @pcrel(.Lld_int)                // FFI_TYPE_INT
546         data8   @pcrel(.Lld_float)              // FFI_TYPE_FLOAT
547         data8   @pcrel(.Lld_double)             // FFI_TYPE_DOUBLE
548         data8   @pcrel(.Lld_ldouble)            // FFI_TYPE_LONGDOUBLE
549         data8   @pcrel(.Lld_int)                // FFI_TYPE_UINT8
550         data8   @pcrel(.Lld_int)                // FFI_TYPE_SINT8
551         data8   @pcrel(.Lld_int)                // FFI_TYPE_UINT16
552         data8   @pcrel(.Lld_int)                // FFI_TYPE_SINT16
553         data8   @pcrel(.Lld_int)                // FFI_TYPE_UINT32
554         data8   @pcrel(.Lld_int)                // FFI_TYPE_SINT32
555         data8   @pcrel(.Lld_int)                // FFI_TYPE_UINT64
556         data8   @pcrel(.Lld_int)                // FFI_TYPE_SINT64
557         data8   @pcrel(.Lld_void)               // FFI_TYPE_STRUCT
558         data8   @pcrel(.Lld_int)                // FFI_TYPE_POINTER
559         data8   @pcrel(.Lld_void)               // FFI_TYPE_COMPLEX (not implemented)
560         data8   @pcrel(.Lld_small_struct)       // FFI_IA64_TYPE_SMALL_STRUCT
561         data8   @pcrel(.Lld_hfa_float)          // FFI_IA64_TYPE_HFA_FLOAT
562         data8   @pcrel(.Lld_hfa_double)         // FFI_IA64_TYPE_HFA_DOUBLE
563         data8   @pcrel(.Lld_hfa_ldouble)        // FFI_IA64_TYPE_HFA_LDOUBLE
565 #if defined __ELF__ && defined __linux__
566         .section        .note.GNU-stack,"",@progbits
567 #endif