s390: Kill trailing whitespace
[libffi.git] / src / s390 / ffi.c
1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2000, 2007 Software AG
3 Copyright (c) 2008 Red Hat, Inc
4
5 S390 Foreign Function Interface
6
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:
14
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17
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 /*====================================================================*/
30
31 #include <ffi.h>
32 #include <ffi_common.h>
33
34 #include <stdlib.h>
35 #include <stdio.h>
36
37 /*====================== End of Includes =============================*/
38
39 /*====================================================================*/
40 /* Defines */
41 /* ------- */
42 /*====================================================================*/
43
44 /* Maximum number of GPRs available for argument passing. */
45 #define MAX_GPRARGS 5
46
47 /* Maximum number of FPRs available for argument passing. */
48 #ifdef __s390x__
49 #define MAX_FPRARGS 4
50 #else
51 #define MAX_FPRARGS 2
52 #endif
53
54 /* Round to multiple of 16. */
55 #define ROUND_SIZE(size) (((size) + 15) & ~15)
56
57 /* If these values change, sysv.S must be adapted! */
58 #define FFI390_RET_VOID 0
59 #define FFI390_RET_STRUCT 1
60 #define FFI390_RET_FLOAT 2
61 #define FFI390_RET_DOUBLE 3
62 #define FFI390_RET_INT32 4
63 #define FFI390_RET_INT64 5
64
65 /*===================== End of Defines ===============================*/
66
67 /*====================================================================*/
68 /* Externals */
69 /* --------- */
70 /*====================================================================*/
71
72 extern void ffi_call_SYSV(unsigned,
73 extended_cif *,
74 void (*)(unsigned char *, extended_cif *),
75 unsigned,
76 void *,
77 void (*fn)(void), void *);
78
79 extern void ffi_closure_SYSV(void);
80 extern void ffi_go_closure_SYSV(void);
81
82 /*====================== End of Externals ============================*/
83
84 /*====================================================================*/
85 /* */
86 /* Name - ffi_check_struct_type. */
87 /* */
88 /* Function - Determine if a structure can be passed within a */
89 /* general purpose or floating point register. */
90 /* */
91 /*====================================================================*/
92
93 static int
94 ffi_check_struct_type (ffi_type *arg)
95 {
96 size_t size = arg->size;
97
98 /* If the struct has just one element, look at that element
99 to find out whether to consider the struct as floating point. */
100 while (arg->type == FFI_TYPE_STRUCT
101 && arg->elements[0] && !arg->elements[1])
102 arg = arg->elements[0];
103
104 /* Structs of size 1, 2, 4, and 8 are passed in registers,
105 just like the corresponding int/float types. */
106 switch (size)
107 {
108 case 1:
109 return FFI_TYPE_UINT8;
110
111 case 2:
112 return FFI_TYPE_UINT16;
113
114 case 4:
115 if (arg->type == FFI_TYPE_FLOAT)
116 return FFI_TYPE_FLOAT;
117 else
118 return FFI_TYPE_UINT32;
119
120 case 8:
121 if (arg->type == FFI_TYPE_DOUBLE)
122 return FFI_TYPE_DOUBLE;
123 else
124 return FFI_TYPE_UINT64;
125
126 default:
127 break;
128 }
129
130 /* Other structs are passed via a pointer to the data. */
131 return FFI_TYPE_POINTER;
132 }
133
134 /*======================== End of Routine ============================*/
135
136 /*====================================================================*/
137 /* */
138 /* Name - ffi_prep_args. */
139 /* */
140 /* Function - Prepare parameters for call to function. */
141 /* */
142 /* ffi_prep_args is called by the assembly routine once stack space */
143 /* has been allocated for the function's arguments. */
144 /* */
145 /*====================================================================*/
146
147 static void
148 ffi_prep_args (unsigned char *stack, extended_cif *ecif)
149 {
150 /* The stack space will be filled with those areas:
151
152 FPR argument register save area (highest addresses)
153 GPR argument register save area
154 temporary struct copies
155 overflow argument area (lowest addresses)
156
157 We set up the following pointers:
158
159 p_fpr: bottom of the FPR area (growing upwards)
160 p_gpr: bottom of the GPR area (growing upwards)
161 p_ov: bottom of the overflow area (growing upwards)
162 p_struct: top of the struct copy area (growing downwards)
163
164 All areas are kept aligned to twice the word size. */
165
166 int gpr_off = ecif->cif->bytes;
167 int fpr_off = gpr_off + ROUND_SIZE (MAX_GPRARGS * sizeof (long));
168
169 unsigned long long *p_fpr = (unsigned long long *)(stack + fpr_off);
170 unsigned long *p_gpr = (unsigned long *)(stack + gpr_off);
171 unsigned char *p_struct = (unsigned char *)p_gpr;
172 unsigned long *p_ov = (unsigned long *)stack;
173
174 int n_fpr = 0;
175 int n_gpr = 0;
176 int n_ov = 0;
177
178 ffi_type **ptr;
179 void **p_argv = ecif->avalue;
180 int i;
181
182 /* If we returning a structure then we set the first parameter register
183 to the address of where we are returning this structure. */
184
185 if (ecif->cif->flags == FFI390_RET_STRUCT)
186 p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
187
188 /* Now for the arguments. */
189
190 for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
191 i > 0;
192 i--, ptr++, p_argv++)
193 {
194 void *arg = *p_argv;
195 int type = (*ptr)->type;
196
197 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
198 /* 16-byte long double is passed like a struct. */
199 if (type == FFI_TYPE_LONGDOUBLE)
200 type = FFI_TYPE_STRUCT;
201 #endif
202
203 /* Check how a structure type is passed. */
204 if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
205 {
206 if (type == FFI_TYPE_COMPLEX)
207 type = FFI_TYPE_POINTER;
208 else
209 type = ffi_check_struct_type (*ptr);
210
211 /* If we pass the struct via pointer, copy the data. */
212 if (type == FFI_TYPE_POINTER)
213 {
214 p_struct -= ROUND_SIZE ((*ptr)->size);
215 memcpy (p_struct, (char *)arg, (*ptr)->size);
216 arg = &p_struct;
217 }
218 }
219
220 /* Now handle all primitive int/pointer/float data types. */
221 switch (type)
222 {
223 case FFI_TYPE_DOUBLE:
224 if (n_fpr < MAX_FPRARGS)
225 p_fpr[n_fpr++] = *(unsigned long long *) arg;
226 else
227 #ifdef __s390x__
228 p_ov[n_ov++] = *(unsigned long *) arg;
229 #else
230 p_ov[n_ov++] = ((unsigned long *) arg)[0],
231 p_ov[n_ov++] = ((unsigned long *) arg)[1];
232 #endif
233 break;
234
235 case FFI_TYPE_FLOAT:
236 if (n_fpr < MAX_FPRARGS)
237 p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
238 else
239 p_ov[n_ov++] = *(unsigned int *) arg;
240 break;
241
242 case FFI_TYPE_POINTER:
243 if (n_gpr < MAX_GPRARGS)
244 p_gpr[n_gpr++] = (unsigned long)*(unsigned char **) arg;
245 else
246 p_ov[n_ov++] = (unsigned long)*(unsigned char **) arg;
247 break;
248
249 case FFI_TYPE_UINT64:
250 case FFI_TYPE_SINT64:
251 #ifdef __s390x__
252 if (n_gpr < MAX_GPRARGS)
253 p_gpr[n_gpr++] = *(unsigned long *) arg;
254 else
255 p_ov[n_ov++] = *(unsigned long *) arg;
256 #else
257 if (n_gpr == MAX_GPRARGS-1)
258 n_gpr = MAX_GPRARGS;
259 if (n_gpr < MAX_GPRARGS)
260 p_gpr[n_gpr++] = ((unsigned long *) arg)[0],
261 p_gpr[n_gpr++] = ((unsigned long *) arg)[1];
262 else
263 p_ov[n_ov++] = ((unsigned long *) arg)[0],
264 p_ov[n_ov++] = ((unsigned long *) arg)[1];
265 #endif
266 break;
267
268 case FFI_TYPE_UINT32:
269 if (n_gpr < MAX_GPRARGS)
270 p_gpr[n_gpr++] = *(unsigned int *) arg;
271 else
272 p_ov[n_ov++] = *(unsigned int *) arg;
273 break;
274
275 case FFI_TYPE_INT:
276 case FFI_TYPE_SINT32:
277 if (n_gpr < MAX_GPRARGS)
278 p_gpr[n_gpr++] = *(signed int *) arg;
279 else
280 p_ov[n_ov++] = *(signed int *) arg;
281 break;
282
283 case FFI_TYPE_UINT16:
284 if (n_gpr < MAX_GPRARGS)
285 p_gpr[n_gpr++] = *(unsigned short *) arg;
286 else
287 p_ov[n_ov++] = *(unsigned short *) arg;
288 break;
289
290 case FFI_TYPE_SINT16:
291 if (n_gpr < MAX_GPRARGS)
292 p_gpr[n_gpr++] = *(signed short *) arg;
293 else
294 p_ov[n_ov++] = *(signed short *) arg;
295 break;
296
297 case FFI_TYPE_UINT8:
298 if (n_gpr < MAX_GPRARGS)
299 p_gpr[n_gpr++] = *(unsigned char *) arg;
300 else
301 p_ov[n_ov++] = *(unsigned char *) arg;
302 break;
303
304 case FFI_TYPE_SINT8:
305 if (n_gpr < MAX_GPRARGS)
306 p_gpr[n_gpr++] = *(signed char *) arg;
307 else
308 p_ov[n_ov++] = *(signed char *) arg;
309 break;
310
311 default:
312 FFI_ASSERT (0);
313 break;
314 }
315 }
316 }
317
318 /*======================== End of Routine ============================*/
319
320 /*====================================================================*/
321 /* */
322 /* Name - ffi_prep_cif_machdep. */
323 /* */
324 /* Function - Perform machine dependent CIF processing. */
325 /* */
326 /*====================================================================*/
327
328 ffi_status
329 ffi_prep_cif_machdep(ffi_cif *cif)
330 {
331 size_t struct_size = 0;
332 int n_gpr = 0;
333 int n_fpr = 0;
334 int n_ov = 0;
335
336 ffi_type **ptr;
337 int i;
338
339 /* Determine return value handling. */
340
341 switch (cif->rtype->type)
342 {
343 /* Void is easy. */
344 case FFI_TYPE_VOID:
345 cif->flags = FFI390_RET_VOID;
346 break;
347
348 /* Structures and complex are returned via a hidden pointer. */
349 case FFI_TYPE_STRUCT:
350 case FFI_TYPE_COMPLEX:
351 cif->flags = FFI390_RET_STRUCT;
352 n_gpr++; /* We need one GPR to pass the pointer. */
353 break;
354
355 /* Floating point values are returned in fpr 0. */
356 case FFI_TYPE_FLOAT:
357 cif->flags = FFI390_RET_FLOAT;
358 break;
359
360 case FFI_TYPE_DOUBLE:
361 cif->flags = FFI390_RET_DOUBLE;
362 break;
363
364 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
365 case FFI_TYPE_LONGDOUBLE:
366 cif->flags = FFI390_RET_STRUCT;
367 n_gpr++;
368 break;
369 #endif
370 /* Integer values are returned in gpr 2 (and gpr 3
371 for 64-bit values on 31-bit machines). */
372 case FFI_TYPE_UINT64:
373 case FFI_TYPE_SINT64:
374 cif->flags = FFI390_RET_INT64;
375 break;
376
377 case FFI_TYPE_POINTER:
378 case FFI_TYPE_INT:
379 case FFI_TYPE_UINT32:
380 case FFI_TYPE_SINT32:
381 case FFI_TYPE_UINT16:
382 case FFI_TYPE_SINT16:
383 case FFI_TYPE_UINT8:
384 case FFI_TYPE_SINT8:
385 /* These are to be extended to word size. */
386 #ifdef __s390x__
387 cif->flags = FFI390_RET_INT64;
388 #else
389 cif->flags = FFI390_RET_INT32;
390 #endif
391 break;
392
393 default:
394 FFI_ASSERT (0);
395 break;
396 }
397
398 /* Now for the arguments. */
399
400 for (ptr = cif->arg_types, i = cif->nargs;
401 i > 0;
402 i--, ptr++)
403 {
404 int type = (*ptr)->type;
405
406 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
407 /* 16-byte long double is passed like a struct. */
408 if (type == FFI_TYPE_LONGDOUBLE)
409 type = FFI_TYPE_STRUCT;
410 #endif
411
412 /* Check how a structure type is passed. */
413 if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
414 {
415 if (type == FFI_TYPE_COMPLEX)
416 type = FFI_TYPE_POINTER;
417 else
418 type = ffi_check_struct_type (*ptr);
419
420 /* If we pass the struct via pointer, we must reserve space
421 to copy its data for proper call-by-value semantics. */
422 if (type == FFI_TYPE_POINTER)
423 struct_size += ROUND_SIZE ((*ptr)->size);
424 }
425
426 /* Now handle all primitive int/float data types. */
427 switch (type)
428 {
429 /* The first MAX_FPRARGS floating point arguments
430 go in FPRs, the rest overflow to the stack. */
431
432 case FFI_TYPE_DOUBLE:
433 if (n_fpr < MAX_FPRARGS)
434 n_fpr++;
435 else
436 n_ov += sizeof (double) / sizeof (long);
437 break;
438
439 case FFI_TYPE_FLOAT:
440 if (n_fpr < MAX_FPRARGS)
441 n_fpr++;
442 else
443 n_ov++;
444 break;
445
446 /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
447 if one is still available, or else on the stack. If only one
448 register is free, skip the register (it won't be used for any
449 subsequent argument either). */
450
451 #ifndef __s390x__
452 case FFI_TYPE_UINT64:
453 case FFI_TYPE_SINT64:
454 if (n_gpr == MAX_GPRARGS-1)
455 n_gpr = MAX_GPRARGS;
456 if (n_gpr < MAX_GPRARGS)
457 n_gpr += 2;
458 else
459 n_ov += 2;
460 break;
461 #endif
462
463 /* Everything else is passed in GPRs (until MAX_GPRARGS
464 have been used) or overflows to the stack. */
465
466 default:
467 if (n_gpr < MAX_GPRARGS)
468 n_gpr++;
469 else
470 n_ov++;
471 break;
472 }
473 }
474
475 /* Total stack space as required for overflow arguments
476 and temporary structure copies. */
477
478 cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
479
480 return FFI_OK;
481 }
482
483 /*======================== End of Routine ============================*/
484
485 /*====================================================================*/
486 /* */
487 /* Name - ffi_call. */
488 /* */
489 /* Function - Call the FFI routine. */
490 /* */
491 /*====================================================================*/
492
493 static void
494 ffi_call_int(ffi_cif *cif,
495 void (*fn)(void),
496 void *rvalue,
497 void **avalue,
498 void *closure)
499 {
500 int ret_type = cif->flags;
501 extended_cif ecif;
502
503 ecif.cif = cif;
504 ecif.avalue = avalue;
505 ecif.rvalue = rvalue;
506
507 /* If we don't have a return value, we need to fake one. */
508 if (rvalue == NULL)
509 {
510 if (ret_type == FFI390_RET_STRUCT)
511 ecif.rvalue = alloca (cif->rtype->size);
512 else
513 ret_type = FFI390_RET_VOID;
514 }
515
516 switch (cif->abi)
517 {
518 case FFI_SYSV:
519 ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
520 ret_type, ecif.rvalue, fn, closure);
521 break;
522
523 default:
524 FFI_ASSERT (0);
525 break;
526 }
527 }
528
529 void
530 ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
531 {
532 ffi_call_int(cif, fn, rvalue, avalue, NULL);
533 }
534
535 void
536 ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
537 void **avalue, void *closure)
538 {
539 ffi_call_int(cif, fn, rvalue, avalue, closure);
540 }
541
542 /*======================== End of Routine ============================*/
543
544 /*====================================================================*/
545 /* */
546 /* Name - ffi_closure_helper_SYSV. */
547 /* */
548 /* Function - Call a FFI closure target function. */
549 /* */
550 /*====================================================================*/
551
552 FFI_HIDDEN
553 void
554 ffi_closure_helper_SYSV (ffi_cif *cif,
555 void (*fun)(ffi_cif*,void*,void**,void*),
556 void *user_data,
557 unsigned long *p_gpr,
558 unsigned long long *p_fpr,
559 unsigned long *p_ov)
560 {
561 unsigned long long ret_buffer;
562
563 void *rvalue = &ret_buffer;
564 void **avalue;
565 void **p_arg;
566
567 int n_gpr = 0;
568 int n_fpr = 0;
569 int n_ov = 0;
570
571 ffi_type **ptr;
572 int i;
573
574 /* Allocate buffer for argument list pointers. */
575
576 p_arg = avalue = alloca (cif->nargs * sizeof (void *));
577
578 /* If we returning a structure, pass the structure address
579 directly to the target function. Otherwise, have the target
580 function store the return value to the GPR save area. */
581
582 if (cif->flags == FFI390_RET_STRUCT)
583 rvalue = (void *) p_gpr[n_gpr++];
584
585 /* Now for the arguments. */
586
587 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, p_arg++, ptr++)
588 {
589 int deref_struct_pointer = 0;
590 int type = (*ptr)->type;
591
592 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
593 /* 16-byte long double is passed like a struct. */
594 if (type == FFI_TYPE_LONGDOUBLE)
595 type = FFI_TYPE_STRUCT;
596 #endif
597
598 /* Check how a structure type is passed. */
599 if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
600 {
601 if (type == FFI_TYPE_COMPLEX)
602 type = FFI_TYPE_POINTER;
603 else
604 type = ffi_check_struct_type (*ptr);
605
606 /* If we pass the struct via pointer, remember to
607 retrieve the pointer later. */
608 if (type == FFI_TYPE_POINTER)
609 deref_struct_pointer = 1;
610 }
611
612 /* Pointers are passed like UINTs of the same size. */
613 if (type == FFI_TYPE_POINTER)
614 #ifdef __s390x__
615 type = FFI_TYPE_UINT64;
616 #else
617 type = FFI_TYPE_UINT32;
618 #endif
619
620 /* Now handle all primitive int/float data types. */
621 switch (type)
622 {
623 case FFI_TYPE_DOUBLE:
624 if (n_fpr < MAX_FPRARGS)
625 *p_arg = &p_fpr[n_fpr++];
626 else
627 *p_arg = &p_ov[n_ov],
628 n_ov += sizeof (double) / sizeof (long);
629 break;
630
631 case FFI_TYPE_FLOAT:
632 if (n_fpr < MAX_FPRARGS)
633 *p_arg = &p_fpr[n_fpr++];
634 else
635 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
636 break;
637
638 case FFI_TYPE_UINT64:
639 case FFI_TYPE_SINT64:
640 #ifdef __s390x__
641 if (n_gpr < MAX_GPRARGS)
642 *p_arg = &p_gpr[n_gpr++];
643 else
644 *p_arg = &p_ov[n_ov++];
645 #else
646 if (n_gpr == MAX_GPRARGS-1)
647 n_gpr = MAX_GPRARGS;
648 if (n_gpr < MAX_GPRARGS)
649 *p_arg = &p_gpr[n_gpr], n_gpr += 2;
650 else
651 *p_arg = &p_ov[n_ov], n_ov += 2;
652 #endif
653 break;
654
655 case FFI_TYPE_INT:
656 case FFI_TYPE_UINT32:
657 case FFI_TYPE_SINT32:
658 if (n_gpr < MAX_GPRARGS)
659 *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
660 else
661 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
662 break;
663
664 case FFI_TYPE_UINT16:
665 case FFI_TYPE_SINT16:
666 if (n_gpr < MAX_GPRARGS)
667 *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
668 else
669 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
670 break;
671
672 case FFI_TYPE_UINT8:
673 case FFI_TYPE_SINT8:
674 if (n_gpr < MAX_GPRARGS)
675 *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
676 else
677 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
678 break;
679
680 default:
681 FFI_ASSERT (0);
682 break;
683 }
684
685 /* If this is a struct passed via pointer, we need to
686 actually retrieve that pointer. */
687 if (deref_struct_pointer)
688 *p_arg = *(void **)*p_arg;
689 }
690
691
692 /* Call the target function. */
693 (fun) (cif, rvalue, avalue, user_data);
694
695 /* Convert the return value. */
696 switch (cif->rtype->type)
697 {
698 /* Void is easy, and so is struct. */
699 case FFI_TYPE_VOID:
700 case FFI_TYPE_STRUCT:
701 case FFI_TYPE_COMPLEX:
702 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
703 case FFI_TYPE_LONGDOUBLE:
704 #endif
705 break;
706
707 /* Floating point values are returned in fpr 0. */
708 case FFI_TYPE_FLOAT:
709 p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
710 break;
711
712 case FFI_TYPE_DOUBLE:
713 p_fpr[0] = *(unsigned long long *) rvalue;
714 break;
715
716 /* Integer values are returned in gpr 2 (and gpr 3
717 for 64-bit values on 31-bit machines). */
718 case FFI_TYPE_UINT64:
719 case FFI_TYPE_SINT64:
720 #ifdef __s390x__
721 p_gpr[0] = *(unsigned long *) rvalue;
722 #else
723 p_gpr[0] = ((unsigned long *) rvalue)[0],
724 p_gpr[1] = ((unsigned long *) rvalue)[1];
725 #endif
726 break;
727
728 case FFI_TYPE_POINTER:
729 case FFI_TYPE_UINT32:
730 case FFI_TYPE_UINT16:
731 case FFI_TYPE_UINT8:
732 p_gpr[0] = *(unsigned long *) rvalue;
733 break;
734
735 case FFI_TYPE_INT:
736 case FFI_TYPE_SINT32:
737 case FFI_TYPE_SINT16:
738 case FFI_TYPE_SINT8:
739 p_gpr[0] = *(signed long *) rvalue;
740 break;
741
742 default:
743 FFI_ASSERT (0);
744 break;
745 }
746 }
747
748 /*======================== End of Routine ============================*/
749
750 /*====================================================================*/
751 /* */
752 /* Name - ffi_prep_closure_loc. */
753 /* */
754 /* Function - Prepare a FFI closure. */
755 /* */
756 /*====================================================================*/
757
758 ffi_status
759 ffi_prep_closure_loc (ffi_closure *closure,
760 ffi_cif *cif,
761 void (*fun) (ffi_cif *, void *, void **, void *),
762 void *user_data,
763 void *codeloc)
764 {
765 if (cif->abi != FFI_SYSV)
766 return FFI_BAD_ABI;
767
768 #ifndef __s390x__
769 *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
770 *(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */
771 *(short *)&closure->tramp [4] = 0x1006;
772 *(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */
773 *(long *)&closure->tramp [8] = (long)codeloc;
774 *(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
775 #else
776 *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
777 *(short *)&closure->tramp [2] = 0xeb01; /* lmg %r0,%r1,14(%r1) */
778 *(short *)&closure->tramp [4] = 0x100e;
779 *(short *)&closure->tramp [6] = 0x0004;
780 *(short *)&closure->tramp [8] = 0x07f1; /* br %r1 */
781 *(long *)&closure->tramp[16] = (long)codeloc;
782 *(long *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
783 #endif
784
785 closure->cif = cif;
786 closure->user_data = user_data;
787 closure->fun = fun;
788
789 return FFI_OK;
790 }
791
792 /*======================== End of Routine ============================*/
793
794 /* Build a Go language closure. */
795
796 ffi_status
797 ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
798 void (*fun)(ffi_cif*,void*,void**,void*))
799 {
800 if (cif->abi != FFI_SYSV)
801 return FFI_BAD_ABI;
802
803 closure->tramp = ffi_go_closure_SYSV;
804 closure->cif = cif;
805 closure->fun = fun;
806
807 return FFI_OK;
808 }