diagnostic-show-locus.c: remove unused field from class colorizer
[official-gcc.git] / libffi / src / s390 / ffi.c
blob4035b6e366e6655ea263dfcf8df6a678455d1293
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 /*====================================================================*/
27 /* Includes */
28 /* -------- */
29 /*====================================================================*/
31 #include <ffi.h>
32 #include <ffi_common.h>
33 #include <stdint.h>
34 #include "internal.h"
36 /*====================== End of Includes =============================*/
38 /*====================================================================*/
39 /* Defines */
40 /* ------- */
41 /*====================================================================*/
43 /* Maximum number of GPRs available for argument passing. */
44 #define MAX_GPRARGS 5
46 /* Maximum number of FPRs available for argument passing. */
47 #ifdef __s390x__
48 #define MAX_FPRARGS 4
49 #else
50 #define MAX_FPRARGS 2
51 #endif
53 /* Round to multiple of 16. */
54 #define ROUND_SIZE(size) (((size) + 15) & ~15)
56 /*===================== End of Defines ===============================*/
58 /*====================================================================*/
59 /* Externals */
60 /* --------- */
61 /*====================================================================*/
63 struct call_frame
65 void *back_chain;
66 void *eos;
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 /*====================================================================*/
81 /* */
82 /* Name - ffi_check_struct_type. */
83 /* */
84 /* Function - Determine if a structure can be passed within a */
85 /* general purpose or floating point register. */
86 /* */
87 /*====================================================================*/
89 static int
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. */
102 switch (size)
104 case 1:
105 return FFI_TYPE_UINT8;
107 case 2:
108 return FFI_TYPE_UINT16;
110 case 4:
111 if (arg->type == FFI_TYPE_FLOAT)
112 return FFI_TYPE_FLOAT;
113 else
114 return FFI_TYPE_UINT32;
116 case 8:
117 if (arg->type == FFI_TYPE_DOUBLE)
118 return FFI_TYPE_DOUBLE;
119 else
120 return FFI_TYPE_UINT64;
122 default:
123 break;
126 /* Other structs are passed via a pointer to the data. */
127 return FFI_TYPE_POINTER;
130 /*======================== End of Routine ============================*/
132 /*====================================================================*/
133 /* */
134 /* Name - ffi_prep_cif_machdep. */
135 /* */
136 /* Function - Perform machine dependent CIF processing. */
137 /* */
138 /*====================================================================*/
140 ffi_status FFI_HIDDEN
141 ffi_prep_cif_machdep(ffi_cif *cif)
143 size_t struct_size = 0;
144 int n_gpr = 0;
145 int n_fpr = 0;
146 int n_ov = 0;
148 ffi_type **ptr;
149 int i;
151 /* Determine return value handling. */
153 switch (cif->rtype->type)
155 /* Void is easy. */
156 case FFI_TYPE_VOID:
157 cif->flags = FFI390_RET_VOID;
158 break;
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. */
165 break;
167 /* Floating point values are returned in fpr 0. */
168 case FFI_TYPE_FLOAT:
169 cif->flags = FFI390_RET_FLOAT;
170 break;
172 case FFI_TYPE_DOUBLE:
173 cif->flags = FFI390_RET_DOUBLE;
174 break;
176 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
177 case FFI_TYPE_LONGDOUBLE:
178 cif->flags = FFI390_RET_STRUCT;
179 n_gpr++;
180 break;
181 #endif
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;
187 break;
189 case FFI_TYPE_POINTER:
190 case FFI_TYPE_INT:
191 case FFI_TYPE_UINT32:
192 case FFI_TYPE_SINT32:
193 case FFI_TYPE_UINT16:
194 case FFI_TYPE_SINT16:
195 case FFI_TYPE_UINT8:
196 case FFI_TYPE_SINT8:
197 /* These are to be extended to word size. */
198 #ifdef __s390x__
199 cif->flags = FFI390_RET_INT64;
200 #else
201 cif->flags = FFI390_RET_INT32;
202 #endif
203 break;
205 default:
206 FFI_ASSERT (0);
207 break;
210 /* Now for the arguments. */
212 for (ptr = cif->arg_types, i = cif->nargs;
213 i > 0;
214 i--, ptr++)
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;
222 #endif
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;
229 else
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. */
239 switch (type)
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)
246 n_fpr++;
247 else
248 n_ov += sizeof (double) / sizeof (long);
249 break;
251 case FFI_TYPE_FLOAT:
252 if (n_fpr < MAX_FPRARGS)
253 n_fpr++;
254 else
255 n_ov++;
256 break;
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). */
263 #ifndef __s390x__
264 case FFI_TYPE_UINT64:
265 case FFI_TYPE_SINT64:
266 if (n_gpr == MAX_GPRARGS-1)
267 n_gpr = MAX_GPRARGS;
268 if (n_gpr < MAX_GPRARGS)
269 n_gpr += 2;
270 else
271 n_ov += 2;
272 break;
273 #endif
275 /* Everything else is passed in GPRs (until MAX_GPRARGS
276 have been used) or overflows to the stack. */
278 default:
279 if (n_gpr < MAX_GPRARGS)
280 n_gpr++;
281 else
282 n_ov++;
283 break;
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;
292 return FFI_OK;
295 /*======================== End of Routine ============================*/
297 /*====================================================================*/
298 /* */
299 /* Name - ffi_call. */
300 /* */
301 /* Function - Call the FFI routine. */
302 /* */
303 /*====================================================================*/
305 static void
306 ffi_call_int(ffi_cif *cif,
307 void (*fn)(void),
308 void *rvalue,
309 void **avalue,
310 void *closure)
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. */
324 if (rvalue == NULL)
326 if (ret_type & FFI390_RET_IN_MEM)
327 rsize = cif->rtype->size;
328 else
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);
358 if (rsize)
359 rvalue = frame + 1;
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];
382 int type = ty->type;
383 ffi_arg val;
385 restart:
386 switch (type)
388 case FFI_TYPE_SINT8:
389 val = *(SINT8 *)arg;
390 goto do_int;
391 case FFI_TYPE_UINT8:
392 val = *(UINT8 *)arg;
393 goto do_int;
394 case FFI_TYPE_SINT16:
395 val = *(SINT16 *)arg;
396 goto do_int;
397 case FFI_TYPE_UINT16:
398 val = *(UINT16 *)arg;
399 goto do_int;
400 case FFI_TYPE_INT:
401 case FFI_TYPE_SINT32:
402 val = *(SINT32 *)arg;
403 goto do_int;
404 case FFI_TYPE_UINT32:
405 val = *(UINT32 *)arg;
406 goto do_int;
407 case FFI_TYPE_POINTER:
408 val = *(uintptr_t *)arg;
409 do_int:
410 *(n_gpr < MAX_GPRARGS ? p_gpr + n_gpr++ : p_ov + n_ov++) = val;
411 break;
413 case FFI_TYPE_UINT64:
414 case FFI_TYPE_SINT64:
415 #ifdef __s390x__
416 val = *(UINT64 *)arg;
417 goto do_int;
418 #else
419 if (n_gpr == MAX_GPRARGS-1)
420 n_gpr = MAX_GPRARGS;
421 if (n_gpr < MAX_GPRARGS)
422 p_gpr[n_gpr++] = ((UINT32 *) arg)[0],
423 p_gpr[n_gpr++] = ((UINT32 *) arg)[1];
424 else
425 p_ov[n_ov++] = ((UINT32 *) arg)[0],
426 p_ov[n_ov++] = ((UINT32 *) arg)[1];
427 #endif
428 break;
430 case FFI_TYPE_DOUBLE:
431 if (n_fpr < MAX_FPRARGS)
432 p_fpr[n_fpr++] = *(UINT64 *) arg;
433 else
435 #ifdef __s390x__
436 p_ov[n_ov++] = *(UINT64 *) arg;
437 #else
438 p_ov[n_ov++] = ((UINT32 *) arg)[0],
439 p_ov[n_ov++] = ((UINT32 *) arg)[1];
440 #endif
442 break;
444 case FFI_TYPE_FLOAT:
445 val = *(UINT32 *)arg;
446 if (n_fpr < MAX_FPRARGS)
447 p_fpr[n_fpr++] = (UINT64)val << 32;
448 else
449 p_ov[n_ov++] = val;
450 break;
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)
457 goto restart;
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. */
463 #endif
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;
469 goto do_int;
471 default:
472 FFI_ASSERT (0);
473 break;
477 ffi_call_SYSV (frame, ret_type & FFI360_RET_MASK, rvalue, fn, closure);
480 void
481 ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
483 ffi_call_int(cif, fn, rvalue, avalue, NULL);
486 void
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 /*====================================================================*/
496 /* */
497 /* Name - ffi_closure_helper_SYSV. */
498 /* */
499 /* Function - Call a FFI closure target function. */
500 /* */
501 /*====================================================================*/
503 void FFI_HIDDEN
504 ffi_closure_helper_SYSV (ffi_cif *cif,
505 void (*fun)(ffi_cif*,void*,void**,void*),
506 void *user_data,
507 unsigned long *p_gpr,
508 unsigned long long *p_fpr,
509 unsigned long *p_ov)
511 unsigned long long ret_buffer;
513 void *rvalue = &ret_buffer;
514 void **avalue;
515 void **p_arg;
517 int n_gpr = 0;
518 int n_fpr = 0;
519 int n_ov = 0;
521 ffi_type **ptr;
522 int i;
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;
543 #endif
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;
550 else
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)
562 #ifdef __s390x__
563 type = FFI_TYPE_UINT64;
564 #else
565 type = FFI_TYPE_UINT32;
566 #endif
569 /* Now handle all primitive int/float data types. */
570 switch (type)
572 case FFI_TYPE_DOUBLE:
573 if (n_fpr < MAX_FPRARGS)
574 *p_arg = &p_fpr[n_fpr++];
575 else
576 *p_arg = &p_ov[n_ov],
577 n_ov += sizeof (double) / sizeof (long);
578 break;
580 case FFI_TYPE_FLOAT:
581 if (n_fpr < MAX_FPRARGS)
582 *p_arg = &p_fpr[n_fpr++];
583 else
584 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
585 break;
587 case FFI_TYPE_UINT64:
588 case FFI_TYPE_SINT64:
589 #ifdef __s390x__
590 if (n_gpr < MAX_GPRARGS)
591 *p_arg = &p_gpr[n_gpr++];
592 else
593 *p_arg = &p_ov[n_ov++];
594 #else
595 if (n_gpr == MAX_GPRARGS-1)
596 n_gpr = MAX_GPRARGS;
597 if (n_gpr < MAX_GPRARGS)
598 *p_arg = &p_gpr[n_gpr], n_gpr += 2;
599 else
600 *p_arg = &p_ov[n_ov], n_ov += 2;
601 #endif
602 break;
604 case FFI_TYPE_INT:
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;
609 else
610 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
611 break;
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;
617 else
618 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
619 break;
621 case FFI_TYPE_UINT8:
622 case FFI_TYPE_SINT8:
623 if (n_gpr < MAX_GPRARGS)
624 *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
625 else
626 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
627 break;
629 default:
630 FFI_ASSERT (0);
631 break;
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. */
648 case FFI_TYPE_VOID:
649 case FFI_TYPE_STRUCT:
650 case FFI_TYPE_COMPLEX:
651 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
652 case FFI_TYPE_LONGDOUBLE:
653 #endif
654 break;
656 /* Floating point values are returned in fpr 0. */
657 case FFI_TYPE_FLOAT:
658 p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
659 break;
661 case FFI_TYPE_DOUBLE:
662 p_fpr[0] = *(unsigned long long *) rvalue;
663 break;
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:
669 #ifdef __s390x__
670 p_gpr[0] = *(unsigned long *) rvalue;
671 #else
672 p_gpr[0] = ((unsigned long *) rvalue)[0],
673 p_gpr[1] = ((unsigned long *) rvalue)[1];
674 #endif
675 break;
677 case FFI_TYPE_POINTER:
678 case FFI_TYPE_UINT32:
679 case FFI_TYPE_UINT16:
680 case FFI_TYPE_UINT8:
681 p_gpr[0] = *(unsigned long *) rvalue;
682 break;
684 case FFI_TYPE_INT:
685 case FFI_TYPE_SINT32:
686 case FFI_TYPE_SINT16:
687 case FFI_TYPE_SINT8:
688 p_gpr[0] = *(signed long *) rvalue;
689 break;
691 default:
692 FFI_ASSERT (0);
693 break;
697 /*======================== End of Routine ============================*/
699 /*====================================================================*/
700 /* */
701 /* Name - ffi_prep_closure_loc. */
702 /* */
703 /* Function - Prepare a FFI closure. */
704 /* */
705 /*====================================================================*/
707 ffi_status
708 ffi_prep_closure_loc (ffi_closure *closure,
709 ffi_cif *cif,
710 void (*fun) (ffi_cif *, void *, void **, void *),
711 void *user_data,
712 void *codeloc)
714 static unsigned short const template[] = {
715 0x0d10, /* basr %r1,0 */
716 #ifndef __s390x__
717 0x9801, 0x1006, /* lm %r0,%r1,6(%r1) */
718 #else
719 0xeb01, 0x100e, 0x0004, /* lmg %r0,%r1,14(%r1) */
720 #endif
721 0x07f1 /* br %r1 */
724 unsigned long *tramp = (unsigned long *)&closure->tramp;
726 if (cif->abi != FFI_SYSV)
727 return FFI_BAD_ABI;
729 memcpy (tramp, template, sizeof(template));
730 tramp[2] = (unsigned long)codeloc;
731 tramp[3] = (unsigned long)&ffi_closure_SYSV;
733 closure->cif = cif;
734 closure->fun = fun;
735 closure->user_data = user_data;
737 return FFI_OK;
740 /*======================== End of Routine ============================*/
742 /* Build a Go language closure. */
744 ffi_status
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)
749 return FFI_BAD_ABI;
751 closure->tramp = ffi_go_closure_SYSV;
752 closure->cif = cif;
753 closure->fun = fun;
755 return FFI_OK;