1 /* -----------------------------------------------------------------------
2 unix.S - Copyright (c) 1998 Red Hat, Inc.
3 Copyright (c) 2000 Hewlett Packard Company
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 ----------------------------------------------------------------------- */
32 #include <fficonfig.h>
34 #include "ia64_flags.h"
36 .pred.safe_across_calls p1-p5,p16-p63
39 /* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue,
40 void (*fn)(), int flags);
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. */
52 .save ar.pfs, r36 // loc0
53 alloc loc0 = ar.pfs, 4, 3, 8, 0
62 /* Load up all of the argument registers. */
63 ldf.fill f8 = [in0], 32
64 ldf.fill f9 = [r16], 32
66 ldf.fill f10 = [in0], 32
67 ldf.fill f11 = [r16], 32
69 ldf.fill f12 = [in0], 32
70 ldf.fill f13 = [r16], 32
72 ldf.fill f14 = [in0], 32
73 ldf.fill f15 = [r16], 24
88 /* Deallocate the register save area from the stack frame. */
91 /* Call the target function. */
96 br.call.sptk.many b0 = b6
99 /* Dispatch to handle return value. */
104 addl r18 = @ltoffx(.Lst_table), gp
106 ld8.mov r18 = [r18], .Lst_table
109 shladd r18 = r16, 3, r18
178 cmp.lt p6, p0 = 8, in3
179 cmp.lt p7, p0 = 16, in3
180 cmp.lt p8, p0 = 24, in3
193 br.call.sptk.many b0 = memcpy#
202 cmp.lt p6, p0 = 4, in3
205 (p6) stfs [r16] = f9, 8
206 cmp.lt p7, p0 = 8, in3
207 cmp.lt p8, p0 = 12, in3
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
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
219 (p6) stfs [in1] = f14
220 (p7) stfs [r16] = f15
226 cmp.lt p6, p0 = 8, in3
229 (p6) stfd [r16] = f9, 16
230 cmp.lt p7, p0 = 16, in3
231 cmp.lt p8, p0 = 24, in3
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
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
243 (p6) stfd [in1] = f14
244 (p7) stfd [r16] = f15
250 cmp.lt p6, p0 = 16, in3
253 (p6) stfe [r16] = f9, 32
254 cmp.lt p7, p0 = 32, in3
255 cmp.lt p8, p0 = 48, in3
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
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
267 (p6) stfe [in1] = f14
268 (p7) stfe [r16] = f15
275 .global ffi_closure_unix
276 .proc ffi_closure_unix
278 #define FRAME_SIZE (8*16 + 8*8 + 8*16)
282 .save ar.pfs, r40 // loc0
283 alloc loc0 = ar.pfs, 8, 4, 4, 0
285 add r12 = -FRAME_SIZE, r12
292 /* Retrieve closure pointer and real gp. */
298 /* Spill all of the possible argument registers. */
299 add r16 = 16 + 8*16, sp
300 add r17 = 16 + 8*16 + 16, sp
302 stf.spill [r16] = f8, 32
303 stf.spill [r17] = f9, 32
306 stf.spill [r16] = f10, 32
307 stf.spill [r17] = f11, 32
309 stf.spill [r16] = f12, 32
310 stf.spill [r17] = f13, 32
312 stf.spill [r16] = f14, 32
313 stf.spill [r17] = f15, 24
316 st8.spill [r16] = in0, 16
318 st8.spill [r17] = in1, 16
319 add out1 = 16 + 8*16, sp
322 st8.spill [r16] = in2, 16
324 st8.spill [r17] = in3, 16
328 st8.spill [r16] = in4, 16
330 st8.spill [r17] = in5, 16
334 st8.spill [r16] = in6
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
342 /* Dispatch to handle return value. */
346 addl r18 = @ltoffx(.Lld_table), gp
349 ld8.mov r18 = [r18], .Lld_table
352 shladd r18 = r16, 3, r18
368 add sp = FRAME_SIZE, sp
376 add sp = FRAME_SIZE, sp
384 add sp = FRAME_SIZE, sp
392 add sp = FRAME_SIZE, sp
400 add sp = FRAME_SIZE, sp
408 add sp = FRAME_SIZE, sp
416 add sp = FRAME_SIZE, sp
424 add sp = FRAME_SIZE, sp
432 cmp.lt p6, p0 = 8, r8
433 cmp.lt p7, p0 = 16, r8
434 cmp.lt p8, p0 = 24, r8
437 (p6) ld8 r9 = [r17], 16
442 add sp = FRAME_SIZE, sp
450 cmp.lt p6, p0 = 4, r8
453 (p6) ldfs f9 = [r17], 8
454 cmp.lt p7, p0 = 8, r8
455 cmp.lt p8, p0 = 12, r8
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
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
467 (p6) ldfs f14 = [r16]
468 (p7) ldfs f15 = [r17]
470 add sp = FRAME_SIZE, sp
478 cmp.lt p6, p0 = 8, r8
481 (p6) ldfd f9 = [r17], 16
482 cmp.lt p7, p0 = 16, r8
483 cmp.lt p8, p0 = 24, r8
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
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
495 (p6) ldfd f14 = [r16]
496 (p7) ldfd f15 = [r17]
498 add sp = FRAME_SIZE, sp
506 cmp.lt p6, p0 = 16, r8
509 (p6) ldfe f9 = [r17], 32
510 cmp.lt p7, p0 = 32, r8
511 cmp.lt p8, p0 = 48, r8
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
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
523 (p6) ldfe f14 = [r16]
524 (p7) ldfe f15 = [r17]
526 add sp = FRAME_SIZE, sp
530 .endp ffi_closure_unix
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
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