1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2000, 2007 Software AG
3 Copyright (c) 2008 Red Hat, Inc
5 S390 Foreign Function Interface
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 ``Software''), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
25 ----------------------------------------------------------------------- */
26 /*====================================================================*/
29 /*====================================================================*/
32 #include <ffi_common.h>
36 /*====================== End of Includes =============================*/
38 /*====================================================================*/
41 /*====================================================================*/
43 /* Maximum number of GPRs available for argument passing. */
46 /* Maximum number of FPRs available for argument passing. */
53 /* Round to multiple of 16. */
54 #define ROUND_SIZE(size) (((size) + 15) & ~15)
56 /*===================== End of Defines ===============================*/
58 /*====================================================================*/
61 /*====================================================================*/
67 unsigned long gpr_args
[5];
68 unsigned long gpr_save
[9];
69 unsigned long long fpr_args
[4];
72 extern void FFI_HIDDEN
ffi_call_SYSV(struct call_frame
*, unsigned, void *,
73 void (*fn
)(void), void *);
75 extern void ffi_closure_SYSV(void);
76 extern void ffi_go_closure_SYSV(void);
78 /*====================== End of Externals ============================*/
80 /*====================================================================*/
82 /* Name - ffi_check_struct_type. */
84 /* Function - Determine if a structure can be passed within a */
85 /* general purpose or floating point register. */
87 /*====================================================================*/
90 ffi_check_struct_type (ffi_type
*arg
)
92 size_t size
= arg
->size
;
94 /* If the struct has just one element, look at that element
95 to find out whether to consider the struct as floating point. */
96 while (arg
->type
== FFI_TYPE_STRUCT
97 && arg
->elements
[0] && !arg
->elements
[1])
98 arg
= arg
->elements
[0];
100 /* Structs of size 1, 2, 4, and 8 are passed in registers,
101 just like the corresponding int/float types. */
105 return FFI_TYPE_UINT8
;
108 return FFI_TYPE_UINT16
;
111 if (arg
->type
== FFI_TYPE_FLOAT
)
112 return FFI_TYPE_FLOAT
;
114 return FFI_TYPE_UINT32
;
117 if (arg
->type
== FFI_TYPE_DOUBLE
)
118 return FFI_TYPE_DOUBLE
;
120 return FFI_TYPE_UINT64
;
126 /* Other structs are passed via a pointer to the data. */
127 return FFI_TYPE_POINTER
;
130 /*======================== End of Routine ============================*/
132 /*====================================================================*/
134 /* Name - ffi_prep_cif_machdep. */
136 /* Function - Perform machine dependent CIF processing. */
138 /*====================================================================*/
140 ffi_status FFI_HIDDEN
141 ffi_prep_cif_machdep(ffi_cif
*cif
)
143 size_t struct_size
= 0;
151 /* Determine return value handling. */
153 switch (cif
->rtype
->type
)
157 cif
->flags
= FFI390_RET_VOID
;
160 /* Structures and complex are returned via a hidden pointer. */
161 case FFI_TYPE_STRUCT
:
162 case FFI_TYPE_COMPLEX
:
163 cif
->flags
= FFI390_RET_STRUCT
;
164 n_gpr
++; /* We need one GPR to pass the pointer. */
167 /* Floating point values are returned in fpr 0. */
169 cif
->flags
= FFI390_RET_FLOAT
;
172 case FFI_TYPE_DOUBLE
:
173 cif
->flags
= FFI390_RET_DOUBLE
;
176 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
177 case FFI_TYPE_LONGDOUBLE
:
178 cif
->flags
= FFI390_RET_STRUCT
;
182 /* Integer values are returned in gpr 2 (and gpr 3
183 for 64-bit values on 31-bit machines). */
184 case FFI_TYPE_UINT64
:
185 case FFI_TYPE_SINT64
:
186 cif
->flags
= FFI390_RET_INT64
;
189 case FFI_TYPE_POINTER
:
191 case FFI_TYPE_UINT32
:
192 case FFI_TYPE_SINT32
:
193 case FFI_TYPE_UINT16
:
194 case FFI_TYPE_SINT16
:
197 /* These are to be extended to word size. */
199 cif
->flags
= FFI390_RET_INT64
;
201 cif
->flags
= FFI390_RET_INT32
;
210 /* Now for the arguments. */
212 for (ptr
= cif
->arg_types
, i
= cif
->nargs
;
216 int type
= (*ptr
)->type
;
218 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
219 /* 16-byte long double is passed like a struct. */
220 if (type
== FFI_TYPE_LONGDOUBLE
)
221 type
= FFI_TYPE_STRUCT
;
224 /* Check how a structure type is passed. */
225 if (type
== FFI_TYPE_STRUCT
|| type
== FFI_TYPE_COMPLEX
)
227 if (type
== FFI_TYPE_COMPLEX
)
228 type
= FFI_TYPE_POINTER
;
230 type
= ffi_check_struct_type (*ptr
);
232 /* If we pass the struct via pointer, we must reserve space
233 to copy its data for proper call-by-value semantics. */
234 if (type
== FFI_TYPE_POINTER
)
235 struct_size
+= ROUND_SIZE ((*ptr
)->size
);
238 /* Now handle all primitive int/float data types. */
241 /* The first MAX_FPRARGS floating point arguments
242 go in FPRs, the rest overflow to the stack. */
244 case FFI_TYPE_DOUBLE
:
245 if (n_fpr
< MAX_FPRARGS
)
248 n_ov
+= sizeof (double) / sizeof (long);
252 if (n_fpr
< MAX_FPRARGS
)
258 /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
259 if one is still available, or else on the stack. If only one
260 register is free, skip the register (it won't be used for any
261 subsequent argument either). */
264 case FFI_TYPE_UINT64
:
265 case FFI_TYPE_SINT64
:
266 if (n_gpr
== MAX_GPRARGS
-1)
268 if (n_gpr
< MAX_GPRARGS
)
275 /* Everything else is passed in GPRs (until MAX_GPRARGS
276 have been used) or overflows to the stack. */
279 if (n_gpr
< MAX_GPRARGS
)
287 /* Total stack space as required for overflow arguments
288 and temporary structure copies. */
290 cif
->bytes
= ROUND_SIZE (n_ov
* sizeof (long)) + struct_size
;
295 /*======================== End of Routine ============================*/
297 /*====================================================================*/
299 /* Name - ffi_call. */
301 /* Function - Call the FFI routine. */
303 /*====================================================================*/
306 ffi_call_int(ffi_cif
*cif
,
312 int ret_type
= cif
->flags
;
313 size_t rsize
= 0, bytes
= cif
->bytes
;
314 unsigned char *stack
, *p_struct
;
315 struct call_frame
*frame
;
316 unsigned long *p_ov
, *p_gpr
;
317 unsigned long long *p_fpr
;
318 int n_fpr
, n_gpr
, n_ov
, i
, n
;
319 ffi_type
**arg_types
;
321 FFI_ASSERT (cif
->abi
== FFI_SYSV
);
323 /* If we don't have a return value, we need to fake one. */
326 if (ret_type
& FFI390_RET_IN_MEM
)
327 rsize
= cif
->rtype
->size
;
329 ret_type
= FFI390_RET_VOID
;
332 /* The stack space will be filled with those areas:
334 dummy structure return (highest addresses)
335 FPR argument register save area
336 GPR argument register save area
337 stack frame for ffi_call_SYSV
338 temporary struct copies
339 overflow argument area (lowest addresses)
341 We set up the following pointers:
343 p_fpr: bottom of the FPR area (growing upwards)
344 p_gpr: bottom of the GPR area (growing upwards)
345 p_ov: bottom of the overflow area (growing upwards)
346 p_struct: top of the struct copy area (growing downwards)
348 All areas are kept aligned to twice the word size.
350 Note that we're going to create the stack frame for both
351 ffi_call_SYSV _and_ the target function right here. This
352 works because we don't make any function calls with more
353 than 5 arguments (indeed only memcpy and ffi_call_SYSV),
354 and thus we don't have any stacked outgoing parameters. */
356 stack
= alloca (bytes
+ sizeof(struct call_frame
) + rsize
);
357 frame
= (struct call_frame
*)(stack
+ bytes
);
361 /* Link the new frame back to the one from this function. */
362 frame
->back_chain
= __builtin_frame_address (0);
364 /* Fill in all of the argument stuff. */
365 p_ov
= (unsigned long *)stack
;
366 p_struct
= (unsigned char *)frame
;
367 p_gpr
= frame
->gpr_args
;
368 p_fpr
= frame
->fpr_args
;
369 n_fpr
= n_gpr
= n_ov
= 0;
371 /* If we returning a structure then we set the first parameter register
372 to the address of where we are returning this structure. */
373 if (cif
->flags
& FFI390_RET_IN_MEM
)
374 p_gpr
[n_gpr
++] = (uintptr_t) rvalue
;
376 /* Now for the arguments. */
377 arg_types
= cif
->arg_types
;
378 for (i
= 0, n
= cif
->nargs
; i
< n
; ++i
)
380 ffi_type
*ty
= arg_types
[i
];
381 void *arg
= avalue
[i
];
394 case FFI_TYPE_SINT16
:
395 val
= *(SINT16
*)arg
;
397 case FFI_TYPE_UINT16
:
398 val
= *(UINT16
*)arg
;
401 case FFI_TYPE_SINT32
:
402 val
= *(SINT32
*)arg
;
404 case FFI_TYPE_UINT32
:
405 val
= *(UINT32
*)arg
;
407 case FFI_TYPE_POINTER
:
408 val
= *(uintptr_t *)arg
;
410 *(n_gpr
< MAX_GPRARGS
? p_gpr
+ n_gpr
++ : p_ov
+ n_ov
++) = val
;
413 case FFI_TYPE_UINT64
:
414 case FFI_TYPE_SINT64
:
416 val
= *(UINT64
*)arg
;
419 if (n_gpr
== MAX_GPRARGS
-1)
421 if (n_gpr
< MAX_GPRARGS
)
422 p_gpr
[n_gpr
++] = ((UINT32
*) arg
)[0],
423 p_gpr
[n_gpr
++] = ((UINT32
*) arg
)[1];
425 p_ov
[n_ov
++] = ((UINT32
*) arg
)[0],
426 p_ov
[n_ov
++] = ((UINT32
*) arg
)[1];
430 case FFI_TYPE_DOUBLE
:
431 if (n_fpr
< MAX_FPRARGS
)
432 p_fpr
[n_fpr
++] = *(UINT64
*) arg
;
436 p_ov
[n_ov
++] = *(UINT64
*) arg
;
438 p_ov
[n_ov
++] = ((UINT32
*) arg
)[0],
439 p_ov
[n_ov
++] = ((UINT32
*) arg
)[1];
445 val
= *(UINT32
*)arg
;
446 if (n_fpr
< MAX_FPRARGS
)
447 p_fpr
[n_fpr
++] = (UINT64
)val
<< 32;
452 case FFI_TYPE_STRUCT
:
453 /* Check how a structure type is passed. */
454 type
= ffi_check_struct_type (ty
);
455 /* Some structures are passed via a type they contain. */
456 if (type
!= FFI_TYPE_POINTER
)
458 /* ... otherwise, passed by reference. fallthru. */
460 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
461 case FFI_TYPE_LONGDOUBLE
:
462 /* 16-byte long double is passed via reference. */
464 case FFI_TYPE_COMPLEX
:
465 /* Complex types are passed via reference. */
466 p_struct
-= ROUND_SIZE (ty
->size
);
467 memcpy (p_struct
, arg
, ty
->size
);
468 val
= (uintptr_t)p_struct
;
477 ffi_call_SYSV (frame
, ret_type
& FFI360_RET_MASK
, rvalue
, fn
, closure
);
481 ffi_call (ffi_cif
*cif
, void (*fn
)(void), void *rvalue
, void **avalue
)
483 ffi_call_int(cif
, fn
, rvalue
, avalue
, NULL
);
487 ffi_call_go (ffi_cif
*cif
, void (*fn
)(void), void *rvalue
,
488 void **avalue
, void *closure
)
490 ffi_call_int(cif
, fn
, rvalue
, avalue
, closure
);
493 /*======================== End of Routine ============================*/
495 /*====================================================================*/
497 /* Name - ffi_closure_helper_SYSV. */
499 /* Function - Call a FFI closure target function. */
501 /*====================================================================*/
504 ffi_closure_helper_SYSV (ffi_cif
*cif
,
505 void (*fun
)(ffi_cif
*,void*,void**,void*),
507 unsigned long *p_gpr
,
508 unsigned long long *p_fpr
,
511 unsigned long long ret_buffer
;
513 void *rvalue
= &ret_buffer
;
524 /* Allocate buffer for argument list pointers. */
525 p_arg
= avalue
= alloca (cif
->nargs
* sizeof (void *));
527 /* If we returning a structure, pass the structure address
528 directly to the target function. Otherwise, have the target
529 function store the return value to the GPR save area. */
530 if (cif
->flags
& FFI390_RET_IN_MEM
)
531 rvalue
= (void *) p_gpr
[n_gpr
++];
533 /* Now for the arguments. */
534 for (ptr
= cif
->arg_types
, i
= cif
->nargs
; i
> 0; i
--, p_arg
++, ptr
++)
536 int deref_struct_pointer
= 0;
537 int type
= (*ptr
)->type
;
539 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
540 /* 16-byte long double is passed like a struct. */
541 if (type
== FFI_TYPE_LONGDOUBLE
)
542 type
= FFI_TYPE_STRUCT
;
545 /* Check how a structure type is passed. */
546 if (type
== FFI_TYPE_STRUCT
|| type
== FFI_TYPE_COMPLEX
)
548 if (type
== FFI_TYPE_COMPLEX
)
549 type
= FFI_TYPE_POINTER
;
551 type
= ffi_check_struct_type (*ptr
);
553 /* If we pass the struct via pointer, remember to
554 retrieve the pointer later. */
555 if (type
== FFI_TYPE_POINTER
)
556 deref_struct_pointer
= 1;
559 /* Pointers are passed like UINTs of the same size. */
560 if (type
== FFI_TYPE_POINTER
)
563 type
= FFI_TYPE_UINT64
;
565 type
= FFI_TYPE_UINT32
;
569 /* Now handle all primitive int/float data types. */
572 case FFI_TYPE_DOUBLE
:
573 if (n_fpr
< MAX_FPRARGS
)
574 *p_arg
= &p_fpr
[n_fpr
++];
576 *p_arg
= &p_ov
[n_ov
],
577 n_ov
+= sizeof (double) / sizeof (long);
581 if (n_fpr
< MAX_FPRARGS
)
582 *p_arg
= &p_fpr
[n_fpr
++];
584 *p_arg
= (char *)&p_ov
[n_ov
++] + sizeof (long) - 4;
587 case FFI_TYPE_UINT64
:
588 case FFI_TYPE_SINT64
:
590 if (n_gpr
< MAX_GPRARGS
)
591 *p_arg
= &p_gpr
[n_gpr
++];
593 *p_arg
= &p_ov
[n_ov
++];
595 if (n_gpr
== MAX_GPRARGS
-1)
597 if (n_gpr
< MAX_GPRARGS
)
598 *p_arg
= &p_gpr
[n_gpr
], n_gpr
+= 2;
600 *p_arg
= &p_ov
[n_ov
], n_ov
+= 2;
605 case FFI_TYPE_UINT32
:
606 case FFI_TYPE_SINT32
:
607 if (n_gpr
< MAX_GPRARGS
)
608 *p_arg
= (char *)&p_gpr
[n_gpr
++] + sizeof (long) - 4;
610 *p_arg
= (char *)&p_ov
[n_ov
++] + sizeof (long) - 4;
613 case FFI_TYPE_UINT16
:
614 case FFI_TYPE_SINT16
:
615 if (n_gpr
< MAX_GPRARGS
)
616 *p_arg
= (char *)&p_gpr
[n_gpr
++] + sizeof (long) - 2;
618 *p_arg
= (char *)&p_ov
[n_ov
++] + sizeof (long) - 2;
623 if (n_gpr
< MAX_GPRARGS
)
624 *p_arg
= (char *)&p_gpr
[n_gpr
++] + sizeof (long) - 1;
626 *p_arg
= (char *)&p_ov
[n_ov
++] + sizeof (long) - 1;
634 /* If this is a struct passed via pointer, we need to
635 actually retrieve that pointer. */
636 if (deref_struct_pointer
)
637 *p_arg
= *(void **)*p_arg
;
641 /* Call the target function. */
642 (fun
) (cif
, rvalue
, avalue
, user_data
);
644 /* Convert the return value. */
645 switch (cif
->rtype
->type
)
647 /* Void is easy, and so is struct. */
649 case FFI_TYPE_STRUCT
:
650 case FFI_TYPE_COMPLEX
:
651 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
652 case FFI_TYPE_LONGDOUBLE
:
656 /* Floating point values are returned in fpr 0. */
658 p_fpr
[0] = (long long) *(unsigned int *) rvalue
<< 32;
661 case FFI_TYPE_DOUBLE
:
662 p_fpr
[0] = *(unsigned long long *) rvalue
;
665 /* Integer values are returned in gpr 2 (and gpr 3
666 for 64-bit values on 31-bit machines). */
667 case FFI_TYPE_UINT64
:
668 case FFI_TYPE_SINT64
:
670 p_gpr
[0] = *(unsigned long *) rvalue
;
672 p_gpr
[0] = ((unsigned long *) rvalue
)[0],
673 p_gpr
[1] = ((unsigned long *) rvalue
)[1];
677 case FFI_TYPE_POINTER
:
678 case FFI_TYPE_UINT32
:
679 case FFI_TYPE_UINT16
:
681 p_gpr
[0] = *(unsigned long *) rvalue
;
685 case FFI_TYPE_SINT32
:
686 case FFI_TYPE_SINT16
:
688 p_gpr
[0] = *(signed long *) rvalue
;
697 /*======================== End of Routine ============================*/
699 /*====================================================================*/
701 /* Name - ffi_prep_closure_loc. */
703 /* Function - Prepare a FFI closure. */
705 /*====================================================================*/
708 ffi_prep_closure_loc (ffi_closure
*closure
,
710 void (*fun
) (ffi_cif
*, void *, void **, void *),
714 static unsigned short const template[] = {
715 0x0d10, /* basr %r1,0 */
717 0x9801, 0x1006, /* lm %r0,%r1,6(%r1) */
719 0xeb01, 0x100e, 0x0004, /* lmg %r0,%r1,14(%r1) */
724 unsigned long *tramp
= (unsigned long *)&closure
->tramp
;
726 if (cif
->abi
!= FFI_SYSV
)
729 memcpy (tramp
, template, sizeof(template));
730 tramp
[2] = (unsigned long)codeloc
;
731 tramp
[3] = (unsigned long)&ffi_closure_SYSV
;
735 closure
->user_data
= user_data
;
740 /*======================== End of Routine ============================*/
742 /* Build a Go language closure. */
745 ffi_prep_go_closure (ffi_go_closure
*closure
, ffi_cif
*cif
,
746 void (*fun
)(ffi_cif
*,void*,void**,void*))
748 if (cif
->abi
!= FFI_SYSV
)
751 closure
->tramp
= ffi_go_closure_SYSV
;