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. */
303 /* Spill all of the possible argument registers. */
304 add r16 = 16 + 8*16, sp
305 add r17 = 16 + 8*16 + 16, sp
307 stf.spill [r16] = f8, 32
308 stf.spill [r17] = f9, 32
311 stf.spill [r16] = f10, 32
312 stf.spill [r17] = f11, 32
314 stf.spill [r16] = f12, 32
315 stf.spill [r17] = f13, 32
317 stf.spill [r16] = f14, 32
318 stf.spill [r17] = f15, 24
321 st8.spill [r16] = in0, 16
323 st8.spill [r17] = in1, 16
324 add out1 = 16 + 8*16, sp
327 st8.spill [r16] = in2, 16
329 st8.spill [r17] = in3, 16
333 st8.spill [r16] = in4, 16
335 st8.spill [r17] = in5, 16
339 st8.spill [r16] = in6
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
347 /* Dispatch to handle return value. */
351 addl r18 = @ltoffx(.Lld_table), gp
354 ld8.mov r18 = [r18], .Lld_table
357 shladd r18 = r16, 3, r18
373 add sp = FRAME_SIZE, sp
381 add sp = FRAME_SIZE, sp
389 add sp = FRAME_SIZE, sp
397 add sp = FRAME_SIZE, sp
405 add sp = FRAME_SIZE, sp
413 cmp.lt p6, p0 = 8, r8
414 cmp.lt p7, p0 = 16, r8
415 cmp.lt p8, p0 = 24, r8
418 (p6) ld8 r9 = [r17], 16
423 add sp = FRAME_SIZE, sp
431 cmp.lt p6, p0 = 4, r8
434 (p6) ldfs f9 = [r17], 8
435 cmp.lt p7, p0 = 8, r8
436 cmp.lt p8, p0 = 12, r8
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
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
448 (p6) ldfs f14 = [r16]
449 (p7) ldfs f15 = [r17]
451 add sp = FRAME_SIZE, sp
459 cmp.lt p6, p0 = 8, r8
462 (p6) ldfd f9 = [r17], 16
463 cmp.lt p7, p0 = 16, r8
464 cmp.lt p8, p0 = 24, r8
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
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
476 (p6) ldfd f14 = [r16]
477 (p7) ldfd f15 = [r17]
479 add sp = FRAME_SIZE, sp
487 cmp.lt p6, p0 = 16, r8
490 (p6) ldfe f9 = [r17], 32
491 cmp.lt p7, p0 = 32, r8
492 cmp.lt p8, p0 = 48, r8
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
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
504 (p6) ldfe f14 = [r16]
505 (p7) ldfe f15 = [r17]
507 add sp = FRAME_SIZE, sp
511 .endp ffi_closure_unix
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
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