blob: dd1594e7c79bc05a86f3e0e310a754c993c8f43e [file] [log] [blame]
Anthony Greenc6dddbd2009-10-04 08:11:33 -04001/* -----------------------------------------------------------------------
Anthony Green1fbf9dc2011-02-13 08:06:39 -05002 ffi.c - Copyright (C) 2011 Anthony Green
3 Copyright (C) 2008 Red Hat, Inc
4 Copyright (C) 2007, 2008 Free Software Foundation, Inc
5 Copyright (c) 1998 Geoffrey Keating
Anthony Greenc6dddbd2009-10-04 08:11:33 -04006
7 PowerPC Foreign Function Interface
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 ``Software''), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice shall be included
18 in all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 OTHER DEALINGS IN THE SOFTWARE.
27 ----------------------------------------------------------------------- */
28
29#include <ffi.h>
30#include <ffi_common.h>
31
32#include <stdlib.h>
33#include <stdio.h>
34
35
36extern void ffi_closure_SYSV (void);
37extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
38
39enum {
40 /* The assembly depends on these exact flags. */
41 FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */
42 FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
43 FLAG_RETURNS_FP = 1 << (31-29),
44 FLAG_RETURNS_64BITS = 1 << (31-28),
45
46 FLAG_RETURNS_128BITS = 1 << (31-27), /* cr6 */
47 FLAG_SYSV_SMST_R4 = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
48 structs. */
49 FLAG_SYSV_SMST_R3 = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
50 structs. */
51 /* Bits (31-24) through (31-19) store shift value for SMST */
52
53 FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
54 FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
55 FLAG_4_GPR_ARGUMENTS = 1 << (31- 5),
56 FLAG_RETVAL_REFERENCE = 1 << (31- 4)
57};
58
59/* About the SYSV ABI. */
60unsigned int NUM_GPR_ARG_REGISTERS = 8;
61#ifndef __NO_FPRS__
62unsigned int NUM_FPR_ARG_REGISTERS = 8;
63#else
64unsigned int NUM_FPR_ARG_REGISTERS = 0;
65#endif
66
67enum { ASM_NEEDS_REGISTERS = 4 };
68
69/* ffi_prep_args_SYSV is called by the assembly routine once stack space
70 has been allocated for the function's arguments.
71
72 The stack layout we want looks like this:
73
74 | Return address from ffi_call_SYSV 4bytes | higher addresses
75 |--------------------------------------------|
76 | Previous backchain pointer 4 | stack pointer here
77 |--------------------------------------------|<+ <<< on entry to
78 | Saved r28-r31 4*4 | | ffi_call_SYSV
79 |--------------------------------------------| |
80 | GPR registers r3-r10 8*4 | | ffi_call_SYSV
81 |--------------------------------------------| |
82 | FPR registers f1-f8 (optional) 8*8 | |
83 |--------------------------------------------| | stack |
84 | Space for copied structures | | grows |
85 |--------------------------------------------| | down V
86 | Parameters that didn't fit in registers | |
87 |--------------------------------------------| | lower addresses
88 | Space for callee's LR 4 | |
89 |--------------------------------------------| | stack pointer here
90 | Current backchain pointer 4 |-/ during
91 |--------------------------------------------| <<< ffi_call_SYSV
92
93*/
94
95void
96ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
97{
98 const unsigned bytes = ecif->cif->bytes;
99 const unsigned flags = ecif->cif->flags;
100
101 typedef union {
102 char *c;
103 unsigned *u;
104 long long *ll;
105 float *f;
106 double *d;
107 } valp;
108
109 /* 'stacktop' points at the previous backchain pointer. */
110 valp stacktop;
111
112 /* 'gpr_base' points at the space for gpr3, and grows upwards as
113 we use GPR registers. */
114 valp gpr_base;
115 int intarg_count;
116
117 /* 'fpr_base' points at the space for fpr1, and grows upwards as
118 we use FPR registers. */
119 valp fpr_base;
120 int fparg_count;
121
122 /* 'copy_space' grows down as we put structures in it. It should
123 stay 16-byte aligned. */
124 valp copy_space;
125
126 /* 'next_arg' grows up as we put parameters in it. */
127 valp next_arg;
128
129 int i, ii MAYBE_UNUSED;
130 ffi_type **ptr;
131 double double_tmp;
132 union {
133 void **v;
134 char **c;
135 signed char **sc;
136 unsigned char **uc;
137 signed short **ss;
138 unsigned short **us;
139 unsigned int **ui;
140 long long **ll;
141 float **f;
142 double **d;
143 } p_argv;
144 size_t struct_copy_size;
145 unsigned gprvalue;
146
147 if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
148 NUM_FPR_ARG_REGISTERS = 0;
149
150 stacktop.c = (char *) stack + bytes;
151 gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
152 intarg_count = 0;
153 fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
154 fparg_count = 0;
155 copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
156 next_arg.u = stack + 2;
157
158 /* Check that everything starts aligned properly. */
159 FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
160 FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
161 FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
162 FFI_ASSERT ((bytes & 0xF) == 0);
163 FFI_ASSERT (copy_space.c >= next_arg.c);
164
165 /* Deal with return values that are actually pass-by-reference. */
166 if (flags & FLAG_RETVAL_REFERENCE)
167 {
168 *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
169 intarg_count++;
170 }
171
172 /* Now for the arguments. */
173 p_argv.v = ecif->avalue;
174 for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
175 i > 0;
176 i--, ptr++, p_argv.v++)
177 {
178 switch ((*ptr)->type)
179 {
180 case FFI_TYPE_FLOAT:
181 /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */
182 if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
183 goto soft_float_prep;
184 double_tmp = **p_argv.f;
185 if (fparg_count >= NUM_FPR_ARG_REGISTERS)
186 {
187 *next_arg.f = (float) double_tmp;
188 next_arg.u += 1;
Anthony Green6a341242009-12-26 06:51:33 -0500189 intarg_count++;
Anthony Greenc6dddbd2009-10-04 08:11:33 -0400190 }
191 else
192 *fpr_base.d++ = double_tmp;
193 fparg_count++;
194 FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
195 break;
196
197 case FFI_TYPE_DOUBLE:
198 /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */
199 if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
200 goto soft_double_prep;
201 double_tmp = **p_argv.d;
202
203 if (fparg_count >= NUM_FPR_ARG_REGISTERS)
204 {
205 if (intarg_count >= NUM_GPR_ARG_REGISTERS
206 && intarg_count % 2 != 0)
207 {
208 intarg_count++;
209 next_arg.u++;
210 }
211 *next_arg.d = double_tmp;
212 next_arg.u += 2;
213 }
214 else
215 *fpr_base.d++ = double_tmp;
216 fparg_count++;
217 FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
218 break;
219
220#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
221 case FFI_TYPE_LONGDOUBLE:
222 if ((ecif->cif->abi != FFI_LINUX)
223 && (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT))
224 goto do_struct;
225 /* The soft float ABI for long doubles works like this,
226 a long double is passed in four consecutive gprs if available.
227 A maximum of 2 long doubles can be passed in gprs.
228 If we do not have 4 gprs left, the long double is passed on the
229 stack, 4-byte aligned. */
230 if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
231 {
232 unsigned int int_tmp = (*p_argv.ui)[0];
233 if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
234 {
235 if (intarg_count < NUM_GPR_ARG_REGISTERS)
236 intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
237 *next_arg.u = int_tmp;
238 next_arg.u++;
239 for (ii = 1; ii < 4; ii++)
240 {
241 int_tmp = (*p_argv.ui)[ii];
242 *next_arg.u = int_tmp;
243 next_arg.u++;
244 }
245 }
246 else
247 {
248 *gpr_base.u++ = int_tmp;
249 for (ii = 1; ii < 4; ii++)
250 {
251 int_tmp = (*p_argv.ui)[ii];
252 *gpr_base.u++ = int_tmp;
253 }
254 }
255 intarg_count +=4;
256 }
257 else
258 {
259 double_tmp = (*p_argv.d)[0];
260
261 if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
262 {
263 if (intarg_count >= NUM_GPR_ARG_REGISTERS
264 && intarg_count % 2 != 0)
265 {
266 intarg_count++;
267 next_arg.u++;
268 }
269 *next_arg.d = double_tmp;
270 next_arg.u += 2;
271 double_tmp = (*p_argv.d)[1];
272 *next_arg.d = double_tmp;
273 next_arg.u += 2;
274 }
275 else
276 {
277 *fpr_base.d++ = double_tmp;
278 double_tmp = (*p_argv.d)[1];
279 *fpr_base.d++ = double_tmp;
280 }
281
282 fparg_count += 2;
283 FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
284 }
285 break;
286#endif
287
288 case FFI_TYPE_UINT64:
289 case FFI_TYPE_SINT64:
290 soft_double_prep:
291 if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
292 intarg_count++;
293 if (intarg_count >= NUM_GPR_ARG_REGISTERS)
294 {
295 if (intarg_count % 2 != 0)
296 {
297 intarg_count++;
298 next_arg.u++;
299 }
300 *next_arg.ll = **p_argv.ll;
301 next_arg.u += 2;
302 }
303 else
304 {
305 /* whoops: abi states only certain register pairs
306 * can be used for passing long long int
307 * specifically (r3,r4), (r5,r6), (r7,r8),
308 * (r9,r10) and if next arg is long long but
309 * not correct starting register of pair then skip
310 * until the proper starting register
311 */
312 if (intarg_count % 2 != 0)
313 {
314 intarg_count ++;
315 gpr_base.u++;
316 }
317 *gpr_base.ll++ = **p_argv.ll;
318 }
319 intarg_count += 2;
320 break;
321
322 case FFI_TYPE_STRUCT:
323#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
324 do_struct:
325#endif
326 struct_copy_size = ((*ptr)->size + 15) & ~0xF;
327 copy_space.c -= struct_copy_size;
328 memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
329
330 gprvalue = (unsigned long) copy_space.c;
331
332 FFI_ASSERT (copy_space.c > next_arg.c);
333 FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
334 goto putgpr;
335
336 case FFI_TYPE_UINT8:
337 gprvalue = **p_argv.uc;
338 goto putgpr;
339 case FFI_TYPE_SINT8:
340 gprvalue = **p_argv.sc;
341 goto putgpr;
342 case FFI_TYPE_UINT16:
343 gprvalue = **p_argv.us;
344 goto putgpr;
345 case FFI_TYPE_SINT16:
346 gprvalue = **p_argv.ss;
347 goto putgpr;
348
349 case FFI_TYPE_INT:
350 case FFI_TYPE_UINT32:
351 case FFI_TYPE_SINT32:
352 case FFI_TYPE_POINTER:
353 soft_float_prep:
354
355 gprvalue = **p_argv.ui;
356
357 putgpr:
358 if (intarg_count >= NUM_GPR_ARG_REGISTERS)
359 *next_arg.u++ = gprvalue;
360 else
361 *gpr_base.u++ = gprvalue;
362 intarg_count++;
363 break;
364 }
365 }
366
367 /* Check that we didn't overrun the stack... */
368 FFI_ASSERT (copy_space.c >= next_arg.c);
369 FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
370 FFI_ASSERT (fpr_base.u
371 <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
372 FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
373}
374
375/* About the LINUX64 ABI. */
376enum {
377 NUM_GPR_ARG_REGISTERS64 = 8,
378 NUM_FPR_ARG_REGISTERS64 = 13
379};
380enum { ASM_NEEDS_REGISTERS64 = 4 };
381
382/* ffi_prep_args64 is called by the assembly routine once stack space
383 has been allocated for the function's arguments.
384
385 The stack layout we want looks like this:
386
387 | Ret addr from ffi_call_LINUX64 8bytes | higher addresses
388 |--------------------------------------------|
389 | CR save area 8bytes |
390 |--------------------------------------------|
391 | Previous backchain pointer 8 | stack pointer here
392 |--------------------------------------------|<+ <<< on entry to
393 | Saved r28-r31 4*8 | | ffi_call_LINUX64
394 |--------------------------------------------| |
395 | GPR registers r3-r10 8*8 | |
396 |--------------------------------------------| |
397 | FPR registers f1-f13 (optional) 13*8 | |
398 |--------------------------------------------| |
399 | Parameter save area | |
400 |--------------------------------------------| |
401 | TOC save area 8 | |
402 |--------------------------------------------| | stack |
403 | Linker doubleword 8 | | grows |
404 |--------------------------------------------| | down V
405 | Compiler doubleword 8 | |
406 |--------------------------------------------| | lower addresses
407 | Space for callee's LR 8 | |
408 |--------------------------------------------| |
409 | CR save area 8 | |
410 |--------------------------------------------| | stack pointer here
411 | Current backchain pointer 8 |-/ during
412 |--------------------------------------------| <<< ffi_call_LINUX64
413
414*/
415
416void FFI_HIDDEN
417ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
418{
419 const unsigned long bytes = ecif->cif->bytes;
420 const unsigned long flags = ecif->cif->flags;
421
422 typedef union {
423 char *c;
424 unsigned long *ul;
425 float *f;
426 double *d;
427 } valp;
428
429 /* 'stacktop' points at the previous backchain pointer. */
430 valp stacktop;
431
432 /* 'next_arg' points at the space for gpr3, and grows upwards as
433 we use GPR registers, then continues at rest. */
434 valp gpr_base;
435 valp gpr_end;
436 valp rest;
437 valp next_arg;
438
439 /* 'fpr_base' points at the space for fpr3, and grows upwards as
440 we use FPR registers. */
441 valp fpr_base;
442 int fparg_count;
443
444 int i, words;
445 ffi_type **ptr;
446 double double_tmp;
447 union {
448 void **v;
449 char **c;
450 signed char **sc;
451 unsigned char **uc;
452 signed short **ss;
453 unsigned short **us;
454 signed int **si;
455 unsigned int **ui;
456 unsigned long **ul;
457 float **f;
458 double **d;
459 } p_argv;
460 unsigned long gprvalue;
461
462 stacktop.c = (char *) stack + bytes;
463 gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
464 gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
465 rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
466 fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
467 fparg_count = 0;
468 next_arg.ul = gpr_base.ul;
469
470 /* Check that everything starts aligned properly. */
471 FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
472 FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
473 FFI_ASSERT ((bytes & 0xF) == 0);
474
475 /* Deal with return values that are actually pass-by-reference. */
476 if (flags & FLAG_RETVAL_REFERENCE)
477 *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
478
479 /* Now for the arguments. */
480 p_argv.v = ecif->avalue;
481 for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
482 i > 0;
483 i--, ptr++, p_argv.v++)
484 {
485 switch ((*ptr)->type)
486 {
487 case FFI_TYPE_FLOAT:
488 double_tmp = **p_argv.f;
489 *next_arg.f = (float) double_tmp;
490 if (++next_arg.ul == gpr_end.ul)
491 next_arg.ul = rest.ul;
492 if (fparg_count < NUM_FPR_ARG_REGISTERS64)
493 *fpr_base.d++ = double_tmp;
494 fparg_count++;
495 FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
496 break;
497
498 case FFI_TYPE_DOUBLE:
499 double_tmp = **p_argv.d;
500 *next_arg.d = double_tmp;
501 if (++next_arg.ul == gpr_end.ul)
502 next_arg.ul = rest.ul;
503 if (fparg_count < NUM_FPR_ARG_REGISTERS64)
504 *fpr_base.d++ = double_tmp;
505 fparg_count++;
506 FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
507 break;
508
509#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
510 case FFI_TYPE_LONGDOUBLE:
511 double_tmp = (*p_argv.d)[0];
512 *next_arg.d = double_tmp;
513 if (++next_arg.ul == gpr_end.ul)
514 next_arg.ul = rest.ul;
515 if (fparg_count < NUM_FPR_ARG_REGISTERS64)
516 *fpr_base.d++ = double_tmp;
517 fparg_count++;
518 double_tmp = (*p_argv.d)[1];
519 *next_arg.d = double_tmp;
520 if (++next_arg.ul == gpr_end.ul)
521 next_arg.ul = rest.ul;
522 if (fparg_count < NUM_FPR_ARG_REGISTERS64)
523 *fpr_base.d++ = double_tmp;
524 fparg_count++;
525 FFI_ASSERT (__LDBL_MANT_DIG__ == 106);
526 FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
527 break;
528#endif
529
530 case FFI_TYPE_STRUCT:
531 words = ((*ptr)->size + 7) / 8;
532 if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
533 {
534 size_t first = gpr_end.c - next_arg.c;
535 memcpy (next_arg.c, *p_argv.c, first);
536 memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
537 next_arg.c = rest.c + words * 8 - first;
538 }
539 else
540 {
541 char *where = next_arg.c;
542
543 /* Structures with size less than eight bytes are passed
544 left-padded. */
545 if ((*ptr)->size < 8)
546 where += 8 - (*ptr)->size;
547
548 memcpy (where, *p_argv.c, (*ptr)->size);
549 next_arg.ul += words;
550 if (next_arg.ul == gpr_end.ul)
551 next_arg.ul = rest.ul;
552 }
553 break;
554
555 case FFI_TYPE_UINT8:
556 gprvalue = **p_argv.uc;
557 goto putgpr;
558 case FFI_TYPE_SINT8:
559 gprvalue = **p_argv.sc;
560 goto putgpr;
561 case FFI_TYPE_UINT16:
562 gprvalue = **p_argv.us;
563 goto putgpr;
564 case FFI_TYPE_SINT16:
565 gprvalue = **p_argv.ss;
566 goto putgpr;
567 case FFI_TYPE_UINT32:
568 gprvalue = **p_argv.ui;
569 goto putgpr;
570 case FFI_TYPE_INT:
571 case FFI_TYPE_SINT32:
572 gprvalue = **p_argv.si;
573 goto putgpr;
574
575 case FFI_TYPE_UINT64:
576 case FFI_TYPE_SINT64:
577 case FFI_TYPE_POINTER:
578 gprvalue = **p_argv.ul;
579 putgpr:
580 *next_arg.ul++ = gprvalue;
581 if (next_arg.ul == gpr_end.ul)
582 next_arg.ul = rest.ul;
583 break;
584 }
585 }
586
587 FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
588 || (next_arg.ul >= gpr_base.ul
589 && next_arg.ul <= gpr_base.ul + 4));
590}
591
592
593
594/* Perform machine dependent cif processing */
595ffi_status
596ffi_prep_cif_machdep (ffi_cif *cif)
597{
598 /* All this is for the SYSV and LINUX64 ABI. */
599 int i;
600 ffi_type **ptr;
601 unsigned bytes;
602 int fparg_count = 0, intarg_count = 0;
603 unsigned flags = 0;
604 unsigned struct_copy_size = 0;
605 unsigned type = cif->rtype->type;
606 unsigned size = cif->rtype->size;
607
608 if (cif->abi == FFI_LINUX_SOFT_FLOAT)
609 NUM_FPR_ARG_REGISTERS = 0;
610
611 if (cif->abi != FFI_LINUX64)
612 {
613 /* All the machine-independent calculation of cif->bytes will be wrong.
614 Redo the calculation for SYSV. */
615
616 /* Space for the frame pointer, callee's LR, and the asm's temp regs. */
617 bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
618
619 /* Space for the GPR registers. */
620 bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
621 }
622 else
623 {
624 /* 64-bit ABI. */
625
626 /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
627 regs. */
628 bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
629
630 /* Space for the mandatory parm save area and general registers. */
631 bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
632 }
633
634 /* Return value handling. The rules for SYSV are as follows:
635 - 32-bit (or less) integer values are returned in gpr3;
636 - Structures of size <= 4 bytes also returned in gpr3;
637 - 64-bit integer values and structures between 5 and 8 bytes are returned
638 in gpr3 and gpr4;
639 - Single/double FP values are returned in fpr1;
640 - Larger structures are allocated space and a pointer is passed as
641 the first argument.
642 - long doubles (if not equivalent to double) are returned in
643 fpr1,fpr2 for Linux and as for large structs for SysV.
644 For LINUX64:
645 - integer values in gpr3;
646 - Structures/Unions by reference;
647 - Single/double FP values in fpr1, long double in fpr1,fpr2.
648 - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
649 - soft-float long doubles are returned in gpr3-gpr6. */
650 switch (type)
651 {
652#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
653 case FFI_TYPE_LONGDOUBLE:
654 if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64
655 && cif->abi != FFI_LINUX_SOFT_FLOAT)
656 goto byref;
657 flags |= FLAG_RETURNS_128BITS;
658 /* Fall through. */
659#endif
660 case FFI_TYPE_DOUBLE:
661 flags |= FLAG_RETURNS_64BITS;
662 /* Fall through. */
663 case FFI_TYPE_FLOAT:
664 /* With FFI_LINUX_SOFT_FLOAT no fp registers are used. */
665 if (cif->abi != FFI_LINUX_SOFT_FLOAT)
666 flags |= FLAG_RETURNS_FP;
667 break;
668
669 case FFI_TYPE_UINT64:
670 case FFI_TYPE_SINT64:
671 flags |= FLAG_RETURNS_64BITS;
672 break;
673
674 case FFI_TYPE_STRUCT:
675 if (cif->abi == FFI_SYSV)
676 {
677 /* The final SYSV ABI says that structures smaller or equal 8 bytes
678 are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
679 in memory. */
680
681 /* Treat structs with size <= 8 bytes. */
682 if (size <= 8)
683 {
684 flags |= FLAG_RETURNS_SMST;
685 /* These structs are returned in r3. We pack the type and the
686 precalculated shift value (needed in the sysv.S) into flags.
687 The same applies for the structs returned in r3/r4. */
688 if (size <= 4)
689 {
690 flags |= FLAG_SYSV_SMST_R3;
691 flags |= 8 * (4 - size) << 8;
692 break;
693 }
694 /* These structs are returned in r3 and r4. See above. */
695 if (size <= 8)
696 {
697 flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4;
698 flags |= 8 * (8 - size) << 8;
699 break;
700 }
701 }
702 }
703#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
704 byref:
705#endif
706 intarg_count++;
707 flags |= FLAG_RETVAL_REFERENCE;
708 /* Fall through. */
709 case FFI_TYPE_VOID:
710 flags |= FLAG_RETURNS_NOTHING;
711 break;
712
713 default:
714 /* Returns 32-bit integer, or similar. Nothing to do here. */
715 break;
716 }
717
718 if (cif->abi != FFI_LINUX64)
719 /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
720 first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
721 goes on the stack. Structures and long doubles (if not equivalent
722 to double) are passed as a pointer to a copy of the structure.
723 Stuff on the stack needs to keep proper alignment. */
724 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
725 {
726 switch ((*ptr)->type)
727 {
728 case FFI_TYPE_FLOAT:
729 /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */
730 if (cif->abi == FFI_LINUX_SOFT_FLOAT)
731 goto soft_float_cif;
732 fparg_count++;
733 /* floating singles are not 8-aligned on stack */
734 break;
735
736#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
737 case FFI_TYPE_LONGDOUBLE:
738 if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
739 goto do_struct;
740 if (cif->abi == FFI_LINUX_SOFT_FLOAT)
741 {
742 if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
743 || intarg_count < NUM_GPR_ARG_REGISTERS)
744 /* A long double in FFI_LINUX_SOFT_FLOAT can use only
745 a set of four consecutive gprs. If we have not enough,
746 we have to adjust the intarg_count value. */
747 intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
748 intarg_count += 4;
749 break;
750 }
751 else
752 fparg_count++;
753 /* Fall thru */
754#endif
755 case FFI_TYPE_DOUBLE:
756 /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */
757 if (cif->abi == FFI_LINUX_SOFT_FLOAT)
758 goto soft_double_cif;
759 fparg_count++;
760 /* If this FP arg is going on the stack, it must be
761 8-byte-aligned. */
762 if (fparg_count > NUM_FPR_ARG_REGISTERS
763 && intarg_count >= NUM_GPR_ARG_REGISTERS
764 && intarg_count % 2 != 0)
765 intarg_count++;
766 break;
767
768 case FFI_TYPE_UINT64:
769 case FFI_TYPE_SINT64:
770 soft_double_cif:
771 /* 'long long' arguments are passed as two words, but
772 either both words must fit in registers or both go
773 on the stack. If they go on the stack, they must
774 be 8-byte-aligned.
775
776 Also, only certain register pairs can be used for
777 passing long long int -- specifically (r3,r4), (r5,r6),
778 (r7,r8), (r9,r10).
779 */
780 if (intarg_count == NUM_GPR_ARG_REGISTERS-1
781 || intarg_count % 2 != 0)
782 intarg_count++;
783 intarg_count += 2;
784 break;
785
786 case FFI_TYPE_STRUCT:
787#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
788 do_struct:
789#endif
790 /* We must allocate space for a copy of these to enforce
791 pass-by-value. Pad the space up to a multiple of 16
792 bytes (the maximum alignment required for anything under
793 the SYSV ABI). */
794 struct_copy_size += ((*ptr)->size + 15) & ~0xF;
795 /* Fall through (allocate space for the pointer). */
796
797 default:
798 soft_float_cif:
799 /* Everything else is passed as a 4-byte word in a GPR, either
800 the object itself or a pointer to it. */
801 intarg_count++;
802 break;
803 }
804 }
805 else
806 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
807 {
808 switch ((*ptr)->type)
809 {
810#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
811 case FFI_TYPE_LONGDOUBLE:
812 if (cif->abi == FFI_LINUX_SOFT_FLOAT)
813 intarg_count += 4;
814 else
815 {
816 fparg_count += 2;
817 intarg_count += 2;
818 }
819 break;
820#endif
821 case FFI_TYPE_FLOAT:
822 case FFI_TYPE_DOUBLE:
823 fparg_count++;
824 intarg_count++;
825 break;
826
827 case FFI_TYPE_STRUCT:
828 intarg_count += ((*ptr)->size + 7) / 8;
829 break;
830
831 default:
832 /* Everything else is passed as a 8-byte word in a GPR, either
833 the object itself or a pointer to it. */
834 intarg_count++;
835 break;
836 }
837 }
838
839 if (fparg_count != 0)
840 flags |= FLAG_FP_ARGUMENTS;
841 if (intarg_count > 4)
842 flags |= FLAG_4_GPR_ARGUMENTS;
843 if (struct_copy_size != 0)
844 flags |= FLAG_ARG_NEEDS_COPY;
845
846 if (cif->abi != FFI_LINUX64)
847 {
848 /* Space for the FPR registers, if needed. */
849 if (fparg_count != 0)
850 bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
851
852 /* Stack space. */
853 if (intarg_count > NUM_GPR_ARG_REGISTERS)
854 bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
855 if (fparg_count > NUM_FPR_ARG_REGISTERS)
856 bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
857 }
858 else
859 {
860 /* Space for the FPR registers, if needed. */
861 if (fparg_count != 0)
862 bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
863
864 /* Stack space. */
865 if (intarg_count > NUM_GPR_ARG_REGISTERS64)
866 bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
867 }
868
869 /* The stack space allocated needs to be a multiple of 16 bytes. */
870 bytes = (bytes + 15) & ~0xF;
871
872 /* Add in the space for the copied structures. */
873 bytes += struct_copy_size;
874
875 cif->flags = flags;
876 cif->bytes = bytes;
877
878 return FFI_OK;
879}
880
881extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
882 void (*fn)(void));
883extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
884 unsigned long, unsigned long *,
885 void (*fn)(void));
886
887void
888ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
889{
890 extended_cif ecif;
891
892 ecif.cif = cif;
893 ecif.avalue = avalue;
894
895 /* If the return value is a struct and we don't have a return */
896 /* value address then we need to make one */
897
898 if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
899 {
900 ecif.rvalue = alloca(cif->rtype->size);
901 }
902 else
903 ecif.rvalue = rvalue;
904
905
906 switch (cif->abi)
907 {
908#ifndef POWERPC64
909 case FFI_SYSV:
910 case FFI_GCC_SYSV:
911 case FFI_LINUX:
912 case FFI_LINUX_SOFT_FLOAT:
913 ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
914 break;
915#else
916 case FFI_LINUX64:
917 ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
918 break;
919#endif
920 default:
921 FFI_ASSERT (0);
922 break;
923 }
924}
925
926
927#ifndef POWERPC64
928#define MIN_CACHE_LINE_SIZE 8
929
930static void
931flush_icache (char *wraddr, char *xaddr, int size)
932{
933 int i;
934 for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
935 __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
936 : : "r" (xaddr + i), "r" (wraddr + i) : "memory");
937 __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
938 : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)
939 : "memory");
940}
941#endif
942
943ffi_status
944ffi_prep_closure_loc (ffi_closure *closure,
945 ffi_cif *cif,
946 void (*fun) (ffi_cif *, void *, void **, void *),
947 void *user_data,
948 void *codeloc)
949{
950#ifdef POWERPC64
951 void **tramp = (void **) &closure->tramp[0];
952
Anthony Green1fbf9dc2011-02-13 08:06:39 -0500953 if (cif->abi != FFI_LINUX64)
954 return FFI_BAD_ABI;
Anthony Greenc6dddbd2009-10-04 08:11:33 -0400955 /* Copy function address and TOC from ffi_closure_LINUX64. */
956 memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
957 tramp[2] = codeloc;
958#else
959 unsigned int *tramp;
960
Anthony Green1fbf9dc2011-02-13 08:06:39 -0500961 if (! (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV))
962 return FFI_BAD_ABI;
Anthony Greenc6dddbd2009-10-04 08:11:33 -0400963
964 tramp = (unsigned int *) &closure->tramp[0];
965 tramp[0] = 0x7c0802a6; /* mflr r0 */
966 tramp[1] = 0x4800000d; /* bl 10 <trampoline_initial+0x10> */
967 tramp[4] = 0x7d6802a6; /* mflr r11 */
968 tramp[5] = 0x7c0803a6; /* mtlr r0 */
969 tramp[6] = 0x800b0000; /* lwz r0,0(r11) */
970 tramp[7] = 0x816b0004; /* lwz r11,4(r11) */
971 tramp[8] = 0x7c0903a6; /* mtctr r0 */
972 tramp[9] = 0x4e800420; /* bctr */
973 *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
974 *(void **) &tramp[3] = codeloc; /* context */
975
976 /* Flush the icache. */
977 flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
978#endif
979
980 closure->cif = cif;
981 closure->fun = fun;
982 closure->user_data = user_data;
983
984 return FFI_OK;
985}
986
987typedef union
988{
989 float f;
990 double d;
991} ffi_dblfl;
992
993int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
994 ffi_dblfl *, unsigned long *);
995
996/* Basically the trampoline invokes ffi_closure_SYSV, and on
997 * entry, r11 holds the address of the closure.
998 * After storing the registers that could possibly contain
999 * parameters to be passed into the stack frame and setting
1000 * up space for a return value, ffi_closure_SYSV invokes the
1001 * following helper function to do most of the work
1002 */
1003
1004int
1005ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
1006 unsigned long *pgr, ffi_dblfl *pfr,
1007 unsigned long *pst)
1008{
1009 /* rvalue is the pointer to space for return value in closure assembly */
1010 /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
1011 /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */
1012 /* pst is the pointer to outgoing parameter stack in original caller */
1013
1014 void ** avalue;
1015 ffi_type ** arg_types;
1016 long i, avn;
1017 long nf; /* number of floating registers already used */
1018 long ng; /* number of general registers already used */
1019 ffi_cif * cif;
1020 double temp;
1021 unsigned size;
1022
1023 cif = closure->cif;
1024 avalue = alloca (cif->nargs * sizeof (void *));
1025 size = cif->rtype->size;
1026
1027 nf = 0;
1028 ng = 0;
1029
1030 /* Copy the caller's structure return value address so that the closure
1031 returns the data directly to the caller.
1032 For FFI_SYSV the result is passed in r3/r4 if the struct size is less
1033 or equal 8 bytes. */
1034
1035 if ((cif->rtype->type == FFI_TYPE_STRUCT
1036 && !((cif->abi == FFI_SYSV) && (size <= 8)))
1037#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1038 || (cif->rtype->type == FFI_TYPE_LONGDOUBLE
1039 && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
1040#endif
1041 )
1042 {
1043 rvalue = (void *) *pgr;
1044 ng++;
1045 pgr++;
1046 }
1047
1048 i = 0;
1049 avn = cif->nargs;
1050 arg_types = cif->arg_types;
1051
1052 /* Grab the addresses of the arguments from the stack frame. */
1053 while (i < avn)
1054 {
1055 switch (arg_types[i]->type)
1056 {
1057 case FFI_TYPE_SINT8:
1058 case FFI_TYPE_UINT8:
1059 /* there are 8 gpr registers used to pass values */
1060 if (ng < 8)
1061 {
1062 avalue[i] = (char *) pgr + 3;
1063 ng++;
1064 pgr++;
1065 }
1066 else
1067 {
1068 avalue[i] = (char *) pst + 3;
1069 pst++;
1070 }
1071 break;
1072
1073 case FFI_TYPE_SINT16:
1074 case FFI_TYPE_UINT16:
1075 /* there are 8 gpr registers used to pass values */
1076 if (ng < 8)
1077 {
1078 avalue[i] = (char *) pgr + 2;
1079 ng++;
1080 pgr++;
1081 }
1082 else
1083 {
1084 avalue[i] = (char *) pst + 2;
1085 pst++;
1086 }
1087 break;
1088
1089 case FFI_TYPE_SINT32:
1090 case FFI_TYPE_UINT32:
1091 case FFI_TYPE_POINTER:
1092 soft_float_closure:
1093 /* there are 8 gpr registers used to pass values */
1094 if (ng < 8)
1095 {
1096 avalue[i] = pgr;
1097 ng++;
1098 pgr++;
1099 }
1100 else
1101 {
1102 avalue[i] = pst;
1103 pst++;
1104 }
1105 break;
1106
1107 case FFI_TYPE_STRUCT:
1108#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1109 do_struct:
1110#endif
1111 /* Structs are passed by reference. The address will appear in a
1112 gpr if it is one of the first 8 arguments. */
1113 if (ng < 8)
1114 {
1115 avalue[i] = (void *) *pgr;
1116 ng++;
1117 pgr++;
1118 }
1119 else
1120 {
1121 avalue[i] = (void *) *pst;
1122 pst++;
1123 }
1124 break;
1125
1126 case FFI_TYPE_SINT64:
1127 case FFI_TYPE_UINT64:
1128 soft_double_closure:
1129 /* passing long long ints are complex, they must
1130 * be passed in suitable register pairs such as
1131 * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
1132 * and if the entire pair aren't available then the outgoing
1133 * parameter stack is used for both but an alignment of 8
1134 * must will be kept. So we must either look in pgr
1135 * or pst to find the correct address for this type
1136 * of parameter.
1137 */
1138 if (ng < 7)
1139 {
1140 if (ng & 0x01)
1141 {
1142 /* skip r4, r6, r8 as starting points */
1143 ng++;
1144 pgr++;
1145 }
1146 avalue[i] = pgr;
1147 ng += 2;
1148 pgr += 2;
1149 }
1150 else
1151 {
1152 if (((long) pst) & 4)
1153 pst++;
1154 avalue[i] = pst;
1155 pst += 2;
Anthony Green6a341242009-12-26 06:51:33 -05001156 ng = 8;
Anthony Greenc6dddbd2009-10-04 08:11:33 -04001157 }
1158 break;
1159
1160 case FFI_TYPE_FLOAT:
1161 /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */
1162 if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1163 goto soft_float_closure;
1164 /* unfortunately float values are stored as doubles
1165 * in the ffi_closure_SYSV code (since we don't check
1166 * the type in that routine).
1167 */
1168
1169 /* there are 8 64bit floating point registers */
1170
1171 if (nf < 8)
1172 {
1173 temp = pfr->d;
1174 pfr->f = (float) temp;
1175 avalue[i] = pfr;
1176 nf++;
1177 pfr++;
1178 }
1179 else
1180 {
1181 /* FIXME? here we are really changing the values
1182 * stored in the original calling routines outgoing
1183 * parameter stack. This is probably a really
1184 * naughty thing to do but...
1185 */
1186 avalue[i] = pst;
1187 pst += 1;
1188 }
1189 break;
1190
1191 case FFI_TYPE_DOUBLE:
1192 /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */
1193 if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1194 goto soft_double_closure;
1195 /* On the outgoing stack all values are aligned to 8 */
1196 /* there are 8 64bit floating point registers */
1197
1198 if (nf < 8)
1199 {
1200 avalue[i] = pfr;
1201 nf++;
1202 pfr++;
1203 }
1204 else
1205 {
1206 if (((long) pst) & 4)
1207 pst++;
1208 avalue[i] = pst;
1209 pst += 2;
1210 }
1211 break;
1212
1213#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1214 case FFI_TYPE_LONGDOUBLE:
1215 if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
1216 goto do_struct;
1217 if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1218 { /* Test if for the whole long double, 4 gprs are available.
1219 otherwise the stuff ends up on the stack. */
1220 if (ng < 5)
1221 {
1222 avalue[i] = pgr;
1223 pgr += 4;
1224 ng += 4;
1225 }
1226 else
1227 {
1228 avalue[i] = pst;
1229 pst += 4;
Anthony Green6a341242009-12-26 06:51:33 -05001230 ng = 8;
Anthony Greenc6dddbd2009-10-04 08:11:33 -04001231 }
1232 break;
1233 }
1234 if (nf < 7)
1235 {
1236 avalue[i] = pfr;
1237 pfr += 2;
1238 nf += 2;
1239 }
1240 else
1241 {
1242 if (((long) pst) & 4)
1243 pst++;
1244 avalue[i] = pst;
1245 pst += 4;
1246 nf = 8;
1247 }
1248 break;
1249#endif
1250
1251 default:
1252 FFI_ASSERT (0);
1253 }
1254
1255 i++;
1256 }
1257
1258
1259 (closure->fun) (cif, rvalue, avalue, closure->user_data);
1260
1261 /* Tell ffi_closure_SYSV how to perform return type promotions.
1262 Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
1263 we have to tell ffi_closure_SYSV how to treat them. We combine the base
1264 type FFI_SYSV_TYPE_SMALL_STRUCT - 1 with the size of the struct.
1265 So a one byte struct gets the return type 16. Return type 1 to 15 are
1266 already used and we never have a struct with size zero. That is the reason
1267 for the subtraction of 1. See the comment in ffitarget.h about ordering.
1268 */
1269 if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
1270 && size <= 8)
1271 return (FFI_SYSV_TYPE_SMALL_STRUCT - 1) + size;
1272#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1273 else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE
1274 && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
1275 return FFI_TYPE_STRUCT;
1276#endif
1277 /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
1278 respectivley UINT64. */
1279 if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1280 {
1281 switch (cif->rtype->type)
1282 {
1283 case FFI_TYPE_FLOAT:
1284 return FFI_TYPE_UINT32;
1285 break;
1286 case FFI_TYPE_DOUBLE:
1287 return FFI_TYPE_UINT64;
1288 break;
1289#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1290 case FFI_TYPE_LONGDOUBLE:
1291 return FFI_TYPE_UINT128;
1292 break;
1293#endif
1294 default:
1295 return cif->rtype->type;
1296 }
1297 }
1298 else
1299 {
1300 return cif->rtype->type;
1301 }
1302}
1303
1304int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
1305 unsigned long *, ffi_dblfl *);
1306
1307int FFI_HIDDEN
1308ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
1309 unsigned long *pst, ffi_dblfl *pfr)
1310{
1311 /* rvalue is the pointer to space for return value in closure assembly */
1312 /* pst is the pointer to parameter save area
1313 (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
1314 /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
1315
1316 void **avalue;
1317 ffi_type **arg_types;
1318 long i, avn;
1319 ffi_cif *cif;
1320 ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
1321
1322 cif = closure->cif;
1323 avalue = alloca (cif->nargs * sizeof (void *));
1324
1325 /* Copy the caller's structure return value address so that the closure
1326 returns the data directly to the caller. */
1327 if (cif->rtype->type == FFI_TYPE_STRUCT)
1328 {
1329 rvalue = (void *) *pst;
1330 pst++;
1331 }
1332
1333 i = 0;
1334 avn = cif->nargs;
1335 arg_types = cif->arg_types;
1336
1337 /* Grab the addresses of the arguments from the stack frame. */
1338 while (i < avn)
1339 {
1340 switch (arg_types[i]->type)
1341 {
1342 case FFI_TYPE_SINT8:
1343 case FFI_TYPE_UINT8:
1344 avalue[i] = (char *) pst + 7;
1345 pst++;
1346 break;
1347
1348 case FFI_TYPE_SINT16:
1349 case FFI_TYPE_UINT16:
1350 avalue[i] = (char *) pst + 6;
1351 pst++;
1352 break;
1353
1354 case FFI_TYPE_SINT32:
1355 case FFI_TYPE_UINT32:
1356 avalue[i] = (char *) pst + 4;
1357 pst++;
1358 break;
1359
1360 case FFI_TYPE_SINT64:
1361 case FFI_TYPE_UINT64:
1362 case FFI_TYPE_POINTER:
1363 avalue[i] = pst;
1364 pst++;
1365 break;
1366
1367 case FFI_TYPE_STRUCT:
1368 /* Structures with size less than eight bytes are passed
1369 left-padded. */
1370 if (arg_types[i]->size < 8)
1371 avalue[i] = (char *) pst + 8 - arg_types[i]->size;
1372 else
1373 avalue[i] = pst;
1374 pst += (arg_types[i]->size + 7) / 8;
1375 break;
1376
1377 case FFI_TYPE_FLOAT:
1378 /* unfortunately float values are stored as doubles
1379 * in the ffi_closure_LINUX64 code (since we don't check
1380 * the type in that routine).
1381 */
1382
1383 /* there are 13 64bit floating point registers */
1384
1385 if (pfr < end_pfr)
1386 {
1387 double temp = pfr->d;
1388 pfr->f = (float) temp;
1389 avalue[i] = pfr;
1390 pfr++;
1391 }
1392 else
1393 avalue[i] = pst;
1394 pst++;
1395 break;
1396
1397 case FFI_TYPE_DOUBLE:
1398 /* On the outgoing stack all values are aligned to 8 */
1399 /* there are 13 64bit floating point registers */
1400
1401 if (pfr < end_pfr)
1402 {
1403 avalue[i] = pfr;
1404 pfr++;
1405 }
1406 else
1407 avalue[i] = pst;
1408 pst++;
1409 break;
1410
1411#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1412 case FFI_TYPE_LONGDOUBLE:
1413 if (pfr + 1 < end_pfr)
1414 {
1415 avalue[i] = pfr;
1416 pfr += 2;
1417 }
1418 else
1419 {
1420 if (pfr < end_pfr)
1421 {
1422 /* Passed partly in f13 and partly on the stack.
1423 Move it all to the stack. */
1424 *pst = *(unsigned long *) pfr;
1425 pfr++;
1426 }
1427 avalue[i] = pst;
1428 }
1429 pst += 2;
1430 break;
1431#endif
1432
1433 default:
1434 FFI_ASSERT (0);
1435 }
1436
1437 i++;
1438 }
1439
1440
1441 (closure->fun) (cif, rvalue, avalue, closure->user_data);
1442
1443 /* Tell ffi_closure_LINUX64 how to perform return type promotions. */
1444 return cif->rtype->type;
1445}