]> git.ipfire.org Git - thirdparty/gcc.git/blame - libffi/src/powerpc/ffi.c
004-09-02 Andreas Tobler <a.tobler@schweiz.ch>
[thirdparty/gcc.git] / libffi / src / powerpc / ffi.c
CommitLineData
63e5e3e0
AG
1/* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1998 Geoffrey Keating
63e5e3e0 3
16070e45 4 PowerPC Foreign Function Interface
63e5e3e0
AG
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 ``Software''), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
24 ----------------------------------------------------------------------- */
25
26#include <ffi.h>
27#include <ffi_common.h>
28
29#include <stdlib.h>
cc4c8975
KH
30#include <stdio.h>
31
e9b84181
JJ
32#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 1)
33# define hidden __attribute__ ((visibility ("hidden")))
34#else
35# define hidden
36#endif
37
38
cc4c8975 39extern void ffi_closure_SYSV(void);
e9b84181 40extern void hidden ffi_closure_LINUX64(void);
63e5e3e0
AG
41
42enum {
43 /* The assembly depends on these exact flags. */
44 FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
45 FLAG_RETURNS_FP = 1 << (31-29),
46 FLAG_RETURNS_64BITS = 1 << (31-28),
47
48 FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
49 FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
50 FLAG_4_GPR_ARGUMENTS = 1 << (31- 5),
51 FLAG_RETVAL_REFERENCE = 1 << (31- 4)
52};
53
54/* About the SYSV ABI. */
55enum {
56 NUM_GPR_ARG_REGISTERS = 8,
57 NUM_FPR_ARG_REGISTERS = 8
58};
59enum { ASM_NEEDS_REGISTERS = 4 };
60
e9b84181 61/* ffi_prep_args_SYSV is called by the assembly routine once stack space
63e5e3e0
AG
62 has been allocated for the function's arguments.
63
64 The stack layout we want looks like this:
65
66 | Return address from ffi_call_SYSV 4bytes | higher addresses
67 |--------------------------------------------|
16070e45 68 | Previous backchain pointer 4 | stack pointer here
63e5e3e0
AG
69 |--------------------------------------------|<+ <<< on entry to
70 | Saved r28-r31 4*4 | | ffi_call_SYSV
71 |--------------------------------------------| |
72 | GPR registers r3-r10 8*4 | | ffi_call_SYSV
73 |--------------------------------------------| |
74 | FPR registers f1-f8 (optional) 8*8 | |
75 |--------------------------------------------| | stack |
76 | Space for copied structures | | grows |
77 |--------------------------------------------| | down V
78 | Parameters that didn't fit in registers | |
79 |--------------------------------------------| | lower addresses
80 | Space for callee's LR 4 | |
81 |--------------------------------------------| | stack pointer here
82 | Current backchain pointer 4 |-/ during
83 |--------------------------------------------| <<< ffi_call_SYSV
84
16070e45 85*/
63e5e3e0
AG
86
87/*@-exportheader@*/
e9b84181 88void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
63e5e3e0
AG
89/*@=exportheader@*/
90{
91 const unsigned bytes = ecif->cif->bytes;
92 const unsigned flags = ecif->cif->flags;
16070e45 93
63e5e3e0 94 /* 'stacktop' points at the previous backchain pointer. */
fecf735c 95 unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
63e5e3e0
AG
96
97 /* 'gpr_base' points at the space for gpr3, and grows upwards as
98 we use GPR registers. */
99 unsigned *gpr_base = stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
100 int intarg_count = 0;
101
102 /* 'fpr_base' points at the space for fpr1, and grows upwards as
103 we use FPR registers. */
104 double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS;
105 int fparg_count = 0;
106
107 /* 'copy_space' grows down as we put structures in it. It should
108 stay 16-byte aligned. */
109 char *copy_space = ((flags & FLAG_FP_ARGUMENTS)
110 ? (char *)fpr_base
111 : (char *)gpr_base);
112
113 /* 'next_arg' grows up as we put parameters in it. */
114 unsigned *next_arg = stack + 2;
115
116 int i;
117 ffi_type **ptr;
118 double double_tmp;
119 void **p_argv;
120 size_t struct_copy_size;
121 unsigned gprvalue;
122
123 /* Check that everything starts aligned properly. */
124 FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
125 FFI_ASSERT(((unsigned)(char *)copy_space & 0xF) == 0);
126 FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
127 FFI_ASSERT((bytes & 0xF) == 0);
128 FFI_ASSERT(copy_space >= (char *)next_arg);
129
130 /* Deal with return values that are actually pass-by-reference. */
131 if (flags & FLAG_RETVAL_REFERENCE)
16070e45
AT
132 {
133 *gpr_base++ = (unsigned long)(char *)ecif->rvalue;
134 intarg_count++;
135 }
63e5e3e0
AG
136
137 /* Now for the arguments. */
138 p_argv = ecif->avalue;
139 for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
140 i > 0;
141 i--, ptr++, p_argv++)
142 {
143 switch ((*ptr)->type)
144 {
145 case FFI_TYPE_FLOAT:
7b5102af
TT
146 double_tmp = *(float *)*p_argv;
147 if (fparg_count >= NUM_FPR_ARG_REGISTERS)
148 {
149 *(float *)next_arg = (float)double_tmp;
150 next_arg += 1;
151 }
63e5e3e0 152 else
7b5102af
TT
153 *fpr_base++ = double_tmp;
154 fparg_count++;
155 FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
156 break;
157
158 case FFI_TYPE_DOUBLE:
159 double_tmp = *(double *)*p_argv;
63e5e3e0
AG
160
161 if (fparg_count >= NUM_FPR_ARG_REGISTERS)
162 {
163 if (intarg_count%2 != 0)
164 {
165 intarg_count++;
166 next_arg++;
167 }
168 *(double *)next_arg = double_tmp;
169 next_arg += 2;
170 }
171 else
172 *fpr_base++ = double_tmp;
173 fparg_count++;
174 FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
175 break;
176
177 case FFI_TYPE_UINT64:
178 case FFI_TYPE_SINT64:
179 if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
180 intarg_count++;
181 if (intarg_count >= NUM_GPR_ARG_REGISTERS)
182 {
183 if (intarg_count%2 != 0)
184 {
185 intarg_count++;
186 next_arg++;
187 }
188 *(long long *)next_arg = *(long long *)*p_argv;
189 next_arg += 2;
190 }
191 else
192 {
16070e45
AT
193 /* whoops: abi states only certain register pairs
194 * can be used for passing long long int
195 * specifically (r3,r4), (r5,r6), (r7,r8),
196 * (r9,r10) and if next arg is long long but
197 * not correct starting register of pair then skip
198 * until the proper starting register
cc4c8975 199 */
16070e45
AT
200 if (intarg_count%2 != 0)
201 {
202 intarg_count ++;
203 gpr_base++;
204 }
63e5e3e0
AG
205 *(long long *)gpr_base = *(long long *)*p_argv;
206 gpr_base += 2;
207 }
208 intarg_count += 2;
209 break;
210
211 case FFI_TYPE_STRUCT:
212#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
213 case FFI_TYPE_LONGDOUBLE:
214#endif
215 struct_copy_size = ((*ptr)->size + 15) & ~0xF;
216 copy_space -= struct_copy_size;
217 memcpy(copy_space, (char *)*p_argv, (*ptr)->size);
16070e45 218
e9b84181 219 gprvalue = (unsigned long)copy_space;
63e5e3e0
AG
220
221 FFI_ASSERT(copy_space > (char *)next_arg);
222 FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY);
223 goto putgpr;
224
225 case FFI_TYPE_UINT8:
226 gprvalue = *(unsigned char *)*p_argv;
227 goto putgpr;
228 case FFI_TYPE_SINT8:
229 gprvalue = *(signed char *)*p_argv;
230 goto putgpr;
231 case FFI_TYPE_UINT16:
232 gprvalue = *(unsigned short *)*p_argv;
233 goto putgpr;
234 case FFI_TYPE_SINT16:
235 gprvalue = *(signed short *)*p_argv;
236 goto putgpr;
237
238 case FFI_TYPE_INT:
239 case FFI_TYPE_UINT32:
240 case FFI_TYPE_SINT32:
241 case FFI_TYPE_POINTER:
242 gprvalue = *(unsigned *)*p_argv;
243 putgpr:
244 if (intarg_count >= NUM_GPR_ARG_REGISTERS)
245 *next_arg++ = gprvalue;
246 else
247 *gpr_base++ = gprvalue;
248 intarg_count++;
249 break;
250 }
251 }
252
253 /* Check that we didn't overrun the stack... */
254 FFI_ASSERT(copy_space >= (char *)next_arg);
255 FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
256 FFI_ASSERT((unsigned *)fpr_base
257 <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
258 FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
259}
260
e9b84181
JJ
261/* About the LINUX64 ABI. */
262enum {
263 NUM_GPR_ARG_REGISTERS64 = 8,
264 NUM_FPR_ARG_REGISTERS64 = 13
265};
266enum { ASM_NEEDS_REGISTERS64 = 4 };
267
268/* ffi_prep_args64 is called by the assembly routine once stack space
269 has been allocated for the function's arguments.
270
271 The stack layout we want looks like this:
272
273 | Ret addr from ffi_call_LINUX64 8bytes | higher addresses
274 |--------------------------------------------|
275 | CR save area 8bytes |
276 |--------------------------------------------|
16070e45 277 | Previous backchain pointer 8 | stack pointer here
e9b84181
JJ
278 |--------------------------------------------|<+ <<< on entry to
279 | Saved r28-r31 4*8 | | ffi_call_LINUX64
280 |--------------------------------------------| |
281 | GPR registers r3-r10 8*8 | |
282 |--------------------------------------------| |
283 | FPR registers f1-f13 (optional) 13*8 | |
284 |--------------------------------------------| |
285 | Parameter save area | |
286 |--------------------------------------------| |
287 | TOC save area 8 | |
288 |--------------------------------------------| | stack |
b00badcd 289 | Linker doubleword 8 | | grows |
e9b84181
JJ
290 |--------------------------------------------| | down V
291 | Compiler doubleword 8 | |
292 |--------------------------------------------| | lower addresses
293 | Space for callee's LR 8 | |
294 |--------------------------------------------| |
295 | CR save area 8 | |
296 |--------------------------------------------| | stack pointer here
297 | Current backchain pointer 8 |-/ during
298 |--------------------------------------------| <<< ffi_call_LINUX64
299
16070e45 300*/
e9b84181
JJ
301
302/*@-exportheader@*/
303void hidden ffi_prep_args64(extended_cif *ecif, unsigned long *const stack)
304/*@=exportheader@*/
305{
306 const unsigned long bytes = ecif->cif->bytes;
307 const unsigned long flags = ecif->cif->flags;
308
309 /* 'stacktop' points at the previous backchain pointer. */
310 unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
311
312 /* 'next_arg' points at the space for gpr3, and grows upwards as
313 we use GPR registers, then continues at rest. */
314 unsigned long *const gpr_base = stacktop - ASM_NEEDS_REGISTERS64
16070e45 315 - NUM_GPR_ARG_REGISTERS64;
e9b84181
JJ
316 unsigned long *const gpr_end = gpr_base + NUM_GPR_ARG_REGISTERS64;
317 unsigned long *const rest = stack + 6 + NUM_GPR_ARG_REGISTERS64;
318 unsigned long *next_arg = gpr_base;
319
320 /* 'fpr_base' points at the space for fpr3, and grows upwards as
321 we use FPR registers. */
322 double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS64;
323 int fparg_count = 0;
324
325 int i, words;
326 ffi_type **ptr;
327 double double_tmp;
328 void **p_argv;
329 unsigned long gprvalue;
330
331 /* Check that everything starts aligned properly. */
332 FFI_ASSERT(((unsigned long)(char *)stack & 0xF) == 0);
333 FFI_ASSERT(((unsigned long)(char *)stacktop & 0xF) == 0);
334 FFI_ASSERT((bytes & 0xF) == 0);
335
336 /* Deal with return values that are actually pass-by-reference. */
337 if (flags & FLAG_RETVAL_REFERENCE)
338 *next_arg++ = (unsigned long)(char *)ecif->rvalue;
339
340 /* Now for the arguments. */
341 p_argv = ecif->avalue;
342 for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
343 i > 0;
344 i--, ptr++, p_argv++)
345 {
346 switch ((*ptr)->type)
347 {
348 case FFI_TYPE_FLOAT:
349 double_tmp = *(float *)*p_argv;
350 *(float *)next_arg = (float)double_tmp;
351 if (++next_arg == gpr_end)
352 next_arg = rest;
353 if (fparg_count < NUM_FPR_ARG_REGISTERS64)
354 *fpr_base++ = double_tmp;
355 fparg_count++;
356 FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
357 break;
358
359 case FFI_TYPE_DOUBLE:
360 double_tmp = *(double *)*p_argv;
361 *(double *)next_arg = double_tmp;
362 if (++next_arg == gpr_end)
363 next_arg = rest;
364 if (fparg_count < NUM_FPR_ARG_REGISTERS64)
365 *fpr_base++ = double_tmp;
366 fparg_count++;
367 FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
368 break;
369
e9b84181
JJ
370#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
371 case FFI_TYPE_LONGDOUBLE:
4243752c
AM
372 double_tmp = ((double *) *p_argv)[0];
373 *(double *) next_arg = double_tmp;
374 if (++next_arg == gpr_end)
375 next_arg = rest;
376 if (fparg_count < NUM_FPR_ARG_REGISTERS64)
377 *fpr_base++ = double_tmp;
378 fparg_count++;
379 double_tmp = ((double *) *p_argv)[1];
380 *(double *) next_arg = double_tmp;
381 if (++next_arg == gpr_end)
382 next_arg = rest;
383 if (fparg_count < NUM_FPR_ARG_REGISTERS64)
384 *fpr_base++ = double_tmp;
385 fparg_count++;
386 FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
387 break;
e9b84181 388#endif
4243752c
AM
389
390 case FFI_TYPE_STRUCT:
e9b84181
JJ
391 words = ((*ptr)->size + 7) / 8;
392 if (next_arg >= gpr_base && next_arg + words > gpr_end)
393 {
5af1c806 394 size_t first = (char *) gpr_end - (char *) next_arg;
e9b84181
JJ
395 memcpy((char *) next_arg, (char *) *p_argv, first);
396 memcpy((char *) rest, (char *) *p_argv + first,
397 (*ptr)->size - first);
5af1c806 398 next_arg = (unsigned long *) ((char *) rest + words * 8 - first);
e9b84181
JJ
399 }
400 else
401 {
b00badcd
AM
402 char *where = (char *) next_arg;
403
404 /* Structures with size less than eight bytes are passed
405 left-padded. */
406 if ((*ptr)->size < 8)
407 where += 8 - (*ptr)->size;
408
409 memcpy (where, (char *) *p_argv, (*ptr)->size);
e9b84181
JJ
410 next_arg += words;
411 if (next_arg == gpr_end)
412 next_arg = rest;
413 }
414 break;
415
416 case FFI_TYPE_UINT8:
417 gprvalue = *(unsigned char *)*p_argv;
418 goto putgpr;
419 case FFI_TYPE_SINT8:
420 gprvalue = *(signed char *)*p_argv;
421 goto putgpr;
422 case FFI_TYPE_UINT16:
423 gprvalue = *(unsigned short *)*p_argv;
424 goto putgpr;
425 case FFI_TYPE_SINT16:
426 gprvalue = *(signed short *)*p_argv;
427 goto putgpr;
428 case FFI_TYPE_UINT32:
429 gprvalue = *(unsigned int *)*p_argv;
430 goto putgpr;
431 case FFI_TYPE_INT:
432 case FFI_TYPE_SINT32:
433 gprvalue = *(signed int *)*p_argv;
434 goto putgpr;
16070e45 435
e9b84181
JJ
436 case FFI_TYPE_UINT64:
437 case FFI_TYPE_SINT64:
438 case FFI_TYPE_POINTER:
439 gprvalue = *(unsigned long *)*p_argv;
440 putgpr:
441 *next_arg++ = gprvalue;
442 if (next_arg == gpr_end)
443 next_arg = rest;
444 break;
445 }
446 }
447
448 FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS
449 || (next_arg >= gpr_base && next_arg <= gpr_base + 4));
450}
451
452
453
63e5e3e0
AG
454/* Perform machine dependent cif processing */
455ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
456{
e9b84181 457 /* All this is for the SYSV and LINUX64 ABI. */
63e5e3e0
AG
458 int i;
459 ffi_type **ptr;
460 unsigned bytes;
461 int fparg_count = 0, intarg_count = 0;
462 unsigned flags = 0;
463 unsigned struct_copy_size = 0;
bf310028 464 unsigned type = cif->rtype->type;
63e5e3e0 465
e9b84181 466 if (cif->abi != FFI_LINUX64)
16070e45 467 {
e9b84181
JJ
468 /* All the machine-independent calculation of cif->bytes will be wrong.
469 Redo the calculation for SYSV. */
63e5e3e0 470
e9b84181
JJ
471 /* Space for the frame pointer, callee's LR, and the asm's temp regs. */
472 bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int);
63e5e3e0 473
e9b84181
JJ
474 /* Space for the GPR registers. */
475 bytes += NUM_GPR_ARG_REGISTERS * sizeof(int);
476 }
477 else
478 {
479 /* 64-bit ABI. */
480
481 /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
482 regs. */
483 bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof(long);
484
485 /* Space for the mandatory parm save area and general registers. */
486 bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof(long);
bf310028
AM
487
488#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
489 if (type == FFI_TYPE_LONGDOUBLE)
490 type = FFI_TYPE_DOUBLE;
491#endif
e9b84181
JJ
492 }
493
494 /* Return value handling. The rules for SYSV are as follows:
63e5e3e0
AG
495 - 32-bit (or less) integer values are returned in gpr3;
496 - Structures of size <= 4 bytes also returned in gpr3;
497 - 64-bit integer values and structures between 5 and 8 bytes are returned
16070e45 498 in gpr3 and gpr4;
63e5e3e0
AG
499 - Single/double FP values are returned in fpr1;
500 - Larger structures and long double (if not equivalent to double) values
16070e45 501 are allocated space and a pointer is passed as the first argument.
e9b84181
JJ
502 For LINUX64:
503 - integer values in gpr3;
bf310028
AM
504 - Structures/Unions by reference;
505 - Single/double FP values in fpr1, long double in fpr1,fpr2. */
506 switch (type)
63e5e3e0
AG
507 {
508 case FFI_TYPE_DOUBLE:
509 flags |= FLAG_RETURNS_64BITS;
510 /* Fall through. */
511 case FFI_TYPE_FLOAT:
512 flags |= FLAG_RETURNS_FP;
513 break;
514
515 case FFI_TYPE_UINT64:
516 case FFI_TYPE_SINT64:
517 flags |= FLAG_RETURNS_64BITS;
518 break;
519
520 case FFI_TYPE_STRUCT:
e9b84181 521 if (cif->abi != FFI_GCC_SYSV && cif->abi != FFI_LINUX64)
fecf735c
MK
522 {
523 if (cif->rtype->size <= 4)
63e5e3e0 524 break;
fecf735c
MK
525 else if (cif->rtype->size <= 8)
526 {
527 flags |= FLAG_RETURNS_64BITS;
528 break;
529 }
530 }
63e5e3e0
AG
531 /* else fall through. */
532#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
533 case FFI_TYPE_LONGDOUBLE:
534#endif
535 intarg_count++;
536 flags |= FLAG_RETVAL_REFERENCE;
537 /* Fall through. */
538 case FFI_TYPE_VOID:
539 flags |= FLAG_RETURNS_NOTHING;
540 break;
541
542 default:
543 /* Returns 32-bit integer, or similar. Nothing to do here. */
544 break;
545 }
546
e9b84181
JJ
547 if (cif->abi != FFI_LINUX64)
548 /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
549 first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
550 goes on the stack. Structures and long doubles (if not equivalent
551 to double) are passed as a pointer to a copy of the structure.
552 Stuff on the stack needs to keep proper alignment. */
553 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
554 {
555 switch ((*ptr)->type)
556 {
557 case FFI_TYPE_FLOAT:
558 fparg_count++;
559 /* floating singles are not 8-aligned on stack */
560 break;
7b5102af 561
e9b84181
JJ
562 case FFI_TYPE_DOUBLE:
563 fparg_count++;
564 /* If this FP arg is going on the stack, it must be
565 8-byte-aligned. */
566 if (fparg_count > NUM_FPR_ARG_REGISTERS
567 && intarg_count%2 != 0)
568 intarg_count++;
569 break;
63e5e3e0 570
e9b84181
JJ
571 case FFI_TYPE_UINT64:
572 case FFI_TYPE_SINT64:
573 /* 'long long' arguments are passed as two words, but
574 either both words must fit in registers or both go
575 on the stack. If they go on the stack, they must
576 be 8-byte-aligned. */
577 if (intarg_count == NUM_GPR_ARG_REGISTERS-1
578 || (intarg_count >= NUM_GPR_ARG_REGISTERS
579 && intarg_count%2 != 0))
580 intarg_count++;
581 intarg_count += 2;
582 break;
583
584 case FFI_TYPE_STRUCT:
585#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
586 case FFI_TYPE_LONGDOUBLE:
587#endif
588 /* We must allocate space for a copy of these to enforce
589 pass-by-value. Pad the space up to a multiple of 16
590 bytes (the maximum alignment required for anything under
591 the SYSV ABI). */
592 struct_copy_size += ((*ptr)->size + 15) & ~0xF;
593 /* Fall through (allocate space for the pointer). */
594
595 default:
596 /* Everything else is passed as a 4-byte word in a GPR, either
597 the object itself or a pointer to it. */
63e5e3e0 598 intarg_count++;
e9b84181
JJ
599 break;
600 }
601 }
602 else
603 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
604 {
605 switch ((*ptr)->type)
606 {
bf310028
AM
607#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
608 case FFI_TYPE_LONGDOUBLE:
609 fparg_count += 2;
610 intarg_count += 2;
611 break;
612#endif
e9b84181
JJ
613 case FFI_TYPE_FLOAT:
614 case FFI_TYPE_DOUBLE:
615 fparg_count++;
616 intarg_count++;
617 break;
63e5e3e0 618
e9b84181 619 case FFI_TYPE_STRUCT:
5af1c806 620 intarg_count += ((*ptr)->size + 7) / 8;
e9b84181 621 break;
63e5e3e0 622
e9b84181
JJ
623 default:
624 /* Everything else is passed as a 8-byte word in a GPR, either
625 the object itself or a pointer to it. */
626 intarg_count++;
627 break;
628 }
629 }
63e5e3e0
AG
630
631 if (fparg_count != 0)
632 flags |= FLAG_FP_ARGUMENTS;
633 if (intarg_count > 4)
634 flags |= FLAG_4_GPR_ARGUMENTS;
635 if (struct_copy_size != 0)
636 flags |= FLAG_ARG_NEEDS_COPY;
63e5e3e0 637
e9b84181
JJ
638 if (cif->abi != FFI_LINUX64)
639 {
640 /* Space for the FPR registers, if needed. */
641 if (fparg_count != 0)
642 bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
643
644 /* Stack space. */
645 if (intarg_count > NUM_GPR_ARG_REGISTERS)
646 bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int);
647 if (fparg_count > NUM_FPR_ARG_REGISTERS)
648 bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double);
649 }
650 else
651 {
652 /* Space for the FPR registers, if needed. */
653 if (fparg_count != 0)
654 bytes += NUM_FPR_ARG_REGISTERS64 * sizeof(double);
655
656 /* Stack space. */
657 if (intarg_count > NUM_GPR_ARG_REGISTERS64)
658 bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof(long);
659 }
63e5e3e0
AG
660
661 /* The stack space allocated needs to be a multiple of 16 bytes. */
662 bytes = (bytes + 15) & ~0xF;
663
664 /* Add in the space for the copied structures. */
665 bytes += struct_copy_size;
666
667 cif->flags = flags;
668 cif->bytes = bytes;
669
670 return FFI_OK;
671}
672
673/*@-declundef@*/
674/*@-exportheader@*/
16070e45
AT
675extern void ffi_call_SYSV(/*@out@*/ extended_cif *,
676 unsigned, unsigned,
677 /*@out@*/ unsigned *,
63e5e3e0 678 void (*fn)());
16070e45 679extern void hidden ffi_call_LINUX64(/*@out@*/ extended_cif *,
e9b84181 680 unsigned long, unsigned long,
16070e45 681 /*@out@*/ unsigned long *,
e9b84181 682 void (*fn)());
63e5e3e0
AG
683/*@=declundef@*/
684/*@=exportheader@*/
685
16070e45
AT
686void ffi_call(/*@dependent@*/ ffi_cif *cif,
687 void (*fn)(),
688 /*@out@*/ void *rvalue,
63e5e3e0
AG
689 /*@dependent@*/ void **avalue)
690{
691 extended_cif ecif;
692
693 ecif.cif = cif;
694 ecif.avalue = avalue;
16070e45 695
63e5e3e0
AG
696 /* If the return value is a struct and we don't have a return */
697 /* value address then we need to make one */
698
16070e45 699 if ((rvalue == NULL) &&
63e5e3e0
AG
700 (cif->rtype->type == FFI_TYPE_STRUCT))
701 {
702 /*@-sysunrecog@*/
703 ecif.rvalue = alloca(cif->rtype->size);
704 /*@=sysunrecog@*/
705 }
706 else
707 ecif.rvalue = rvalue;
16070e45
AT
708
709
710 switch (cif->abi)
63e5e3e0 711 {
e9b84181 712#ifndef POWERPC64
63e5e3e0
AG
713 case FFI_SYSV:
714 case FFI_GCC_SYSV:
715 /*@-usedef@*/
16070e45 716 ffi_call_SYSV(&ecif, -cif->bytes,
63e5e3e0
AG
717 cif->flags, ecif.rvalue, fn);
718 /*@=usedef@*/
719 break;
e9b84181
JJ
720#else
721 case FFI_LINUX64:
722 /*@-usedef@*/
723 ffi_call_LINUX64(&ecif, -(long) cif->bytes,
724 cif->flags, ecif.rvalue, fn);
725 /*@=usedef@*/
726 break;
727#endif
63e5e3e0
AG
728 default:
729 FFI_ASSERT(0);
730 break;
731 }
732}
cc4c8975
KH
733
734
e9b84181 735#ifndef POWERPC64
cc4c8975
KH
736static void flush_icache(char *, int);
737
e9b84181
JJ
738#define MIN_CACHE_LINE_SIZE 8
739
740static void flush_icache(char * addr1, int size)
741{
742 int i;
743 char * addr;
744 for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) {
16070e45
AT
745 addr = addr1 + i;
746 __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory");
e9b84181
JJ
747 }
748 addr = addr1 + size - 1;
749 __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory");
750}
751#endif
752
cc4c8975
KH
753ffi_status
754ffi_prep_closure (ffi_closure* closure,
755 ffi_cif* cif,
756 void (*fun)(ffi_cif*, void*, void**, void*),
757 void *user_data)
758{
e9b84181
JJ
759#ifdef POWERPC64
760 void **tramp = (void **) &closure->tramp[0];
761
762 FFI_ASSERT (cif->abi == FFI_LINUX64);
763 /* Copy function address and TOC from ffi_closure_LINUX64. */
764 memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
765 tramp[2] = (void *) closure;
766#else
cc4c8975
KH
767 unsigned int *tramp;
768
769 FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
770
771 tramp = (unsigned int *) &closure->tramp[0];
772 tramp[0] = 0x7c0802a6; /* mflr r0 */
773 tramp[1] = 0x4800000d; /* bl 10 <trampoline_initial+0x10> */
774 tramp[4] = 0x7d6802a6; /* mflr r11 */
775 tramp[5] = 0x7c0803a6; /* mtlr r0 */
776 tramp[6] = 0x800b0000; /* lwz r0,0(r11) */
777 tramp[7] = 0x816b0004; /* lwz r11,4(r11) */
778 tramp[8] = 0x7c0903a6; /* mtctr r0 */
779 tramp[9] = 0x4e800420; /* bctr */
780 *(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */
781 *(void **) &tramp[3] = (void *)closure; /* context */
782
e9b84181
JJ
783 /* Flush the icache. */
784 flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
785#endif
786
cc4c8975
KH
787 closure->cif = cif;
788 closure->fun = fun;
789 closure->user_data = user_data;
790
cc4c8975
KH
791 return FFI_OK;
792}
793
e9b84181 794typedef union
cc4c8975 795{
e9b84181
JJ
796 float f;
797 double d;
798} ffi_dblfl;
cc4c8975 799
16070e45 800int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*,
e9b84181 801 ffi_dblfl*, unsigned long*);
cc4c8975 802
16070e45 803/* Basically the trampoline invokes ffi_closure_SYSV, and on
cc4c8975
KH
804 * entry, r11 holds the address of the closure.
805 * After storing the registers that could possibly contain
806 * parameters to be passed into the stack frame and setting
16070e45 807 * up space for a return value, ffi_closure_SYSV invokes the
cc4c8975
KH
808 * following helper function to do most of the work
809 */
810
811int
16070e45
AT
812ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
813 unsigned long * pgr, ffi_dblfl * pfr,
814 unsigned long * pst)
cc4c8975
KH
815{
816 /* rvalue is the pointer to space for return value in closure assembly */
817 /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
818 /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */
819 /* pst is the pointer to outgoing parameter stack in original caller */
820
821 void ** avalue;
822 ffi_type ** arg_types;
823 long i, avn;
824 long nf; /* number of floating registers already used */
825 long ng; /* number of general registers already used */
16070e45
AT
826 ffi_cif * cif;
827 double temp;
cc4c8975
KH
828
829 cif = closure->cif;
830 avalue = alloca(cif->nargs * sizeof(void *));
831
832 nf = 0;
833 ng = 0;
834
835 /* Copy the caller's structure return value address so that the closure
836 returns the data directly to the caller. */
837 if (cif->rtype->type == FFI_TYPE_STRUCT)
838 {
e9b84181 839 rvalue = (void *) *pgr;
cc4c8975
KH
840 ng++;
841 pgr++;
842 }
843
844 i = 0;
845 avn = cif->nargs;
846 arg_types = cif->arg_types;
16070e45 847
cc4c8975
KH
848 /* Grab the addresses of the arguments from the stack frame. */
849 while (i < avn)
850 {
851 switch (arg_types[i]->type)
852 {
853 case FFI_TYPE_SINT8:
854 case FFI_TYPE_UINT8:
16070e45
AT
855 /* there are 8 gpr registers used to pass values */
856 if (ng < 8) {
857 avalue[i] = (((char *)pgr)+3);
858 ng++;
859 pgr++;
860 } else {
861 avalue[i] = (((char *)pst)+3);
862 pst++;
863 }
cc4c8975 864 break;
16070e45 865
cc4c8975
KH
866 case FFI_TYPE_SINT16:
867 case FFI_TYPE_UINT16:
16070e45
AT
868 /* there are 8 gpr registers used to pass values */
869 if (ng < 8) {
870 avalue[i] = (((char *)pgr)+2);
871 ng++;
872 pgr++;
873 } else {
874 avalue[i] = (((char *)pst)+2);
875 pst++;
876 }
cc4c8975
KH
877 break;
878
879 case FFI_TYPE_SINT32:
880 case FFI_TYPE_UINT32:
881 case FFI_TYPE_POINTER:
086a4bd7 882 /* there are 8 gpr registers used to pass values */
16070e45
AT
883 if (ng < 8) {
884 avalue[i] = pgr;
885 ng++;
886 pgr++;
887 } else {
888 avalue[i] = pst;
889 pst++;
890 }
cc4c8975 891 break;
bf310028 892
086a4bd7 893 case FFI_TYPE_STRUCT:
16070e45 894 /* Structs are passed by reference. The address will appear in a
086a4bd7 895 gpr if it is one of the first 8 arguments. */
16070e45
AT
896 if (ng < 8) {
897 avalue[i] = (void *) *pgr;
898 ng++;
899 pgr++;
900 } else {
901 avalue[i] = (void *) *pst;
902 pst++;
903 }
086a4bd7 904 break;
cc4c8975
KH
905
906 case FFI_TYPE_SINT64:
907 case FFI_TYPE_UINT64:
908 /* passing long long ints are complex, they must
16070e45
AT
909 * be passed in suitable register pairs such as
910 * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
911 * and if the entire pair aren't available then the outgoing
912 * parameter stack is used for both but an alignment of 8
913 * must will be kept. So we must either look in pgr
914 * or pst to find the correct address for this type
915 * of parameter.
916 */
917 if (ng < 7) {
918 if (ng & 0x01) {
919 /* skip r4, r6, r8 as starting points */
920 ng++;
921 pgr++;
922 }
923 avalue[i] = pgr;
924 ng+=2;
925 pgr+=2;
926 } else {
927 if (((long)pst) & 4) pst++;
928 avalue[i] = pst;
929 pst+=2;
930 }
931 break;
cc4c8975
KH
932
933 case FFI_TYPE_FLOAT:
16070e45
AT
934 /* unfortunately float values are stored as doubles
935 * in the ffi_closure_SYSV code (since we don't check
936 * the type in that routine).
937 */
938
939 /* there are 8 64bit floating point registers */
940
941 if (nf < 8) {
942 temp = pfr->d;
943 pfr->f = (float)temp;
944 avalue[i] = pfr;
945 nf++;
946 pfr++;
947 } else {
cc4c8975 948 /* FIXME? here we are really changing the values
16070e45
AT
949 * stored in the original calling routines outgoing
950 * parameter stack. This is probably a really
951 * naughty thing to do but...
952 */
953 avalue[i] = pst;
954 nf++;
955 pst+=1;
956 }
cc4c8975
KH
957 break;
958
959 case FFI_TYPE_DOUBLE:
960 /* On the outgoing stack all values are aligned to 8 */
16070e45
AT
961 /* there are 8 64bit floating point registers */
962
963 if (nf < 8) {
964 avalue[i] = pfr;
965 nf++;
966 pfr++;
967 } else {
968 if (((long)pst) & 4) pst++;
969 avalue[i] = pst;
970 nf++;
971 pst+=2;
972 }
cc4c8975
KH
973 break;
974
975 default:
976 FFI_ASSERT(0);
977 }
978
979 i++;
980 }
981
982
983 (closure->fun) (cif, rvalue, avalue, closure->user_data);
984
e9b84181 985 /* Tell ffi_closure_SYSV how to perform return type promotions. */
cc4c8975
KH
986 return cif->rtype->type;
987
988}
989
e9b84181
JJ
990int hidden ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*,
991 ffi_dblfl*);
cc4c8975 992
e9b84181 993int hidden
16070e45 994ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
bf310028 995 unsigned long *pst, ffi_dblfl *pfr)
e9b84181
JJ
996{
997 /* rvalue is the pointer to space for return value in closure assembly */
998 /* pst is the pointer to parameter save area
999 (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
1000 /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
1001
bf310028
AM
1002 void **avalue;
1003 ffi_type **arg_types;
1004 long i, avn;
16070e45 1005 ffi_cif *cif;
bf310028 1006 ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
cc4c8975 1007
e9b84181 1008 cif = closure->cif;
bf310028 1009 avalue = alloca (cif->nargs * sizeof (void *));
cc4c8975 1010
e9b84181
JJ
1011 /* Copy the caller's structure return value address so that the closure
1012 returns the data directly to the caller. */
1013 if (cif->rtype->type == FFI_TYPE_STRUCT)
1014 {
1015 rvalue = (void *) *pst;
e9b84181
JJ
1016 pst++;
1017 }
1018
1019 i = 0;
1020 avn = cif->nargs;
1021 arg_types = cif->arg_types;
16070e45 1022
e9b84181
JJ
1023 /* Grab the addresses of the arguments from the stack frame. */
1024 while (i < avn)
1025 {
1026 switch (arg_types[i]->type)
1027 {
1028 case FFI_TYPE_SINT8:
1029 case FFI_TYPE_UINT8:
1030 avalue[i] = (char *) pst + 7;
e9b84181
JJ
1031 pst++;
1032 break;
16070e45 1033
e9b84181
JJ
1034 case FFI_TYPE_SINT16:
1035 case FFI_TYPE_UINT16:
1036 avalue[i] = (char *) pst + 6;
e9b84181
JJ
1037 pst++;
1038 break;
1039
1040 case FFI_TYPE_SINT32:
1041 case FFI_TYPE_UINT32:
1042 avalue[i] = (char *) pst + 4;
e9b84181
JJ
1043 pst++;
1044 break;
1045
1046 case FFI_TYPE_SINT64:
1047 case FFI_TYPE_UINT64:
1048 case FFI_TYPE_POINTER:
1049 avalue[i] = pst;
e9b84181
JJ
1050 pst++;
1051 break;
1052
1053 case FFI_TYPE_STRUCT:
b00badcd
AM
1054 /* Structures with size less than eight bytes are passed
1055 left-padded. */
1056 if (arg_types[i]->size < 8)
e9b84181
JJ
1057 avalue[i] = (char *) pst + 8 - arg_types[i]->size;
1058 else
1059 avalue[i] = pst;
e9b84181
JJ
1060 pst += (arg_types[i]->size + 7) / 8;
1061 break;
1062
1063 case FFI_TYPE_FLOAT:
1064 /* unfortunately float values are stored as doubles
16070e45
AT
1065 * in the ffi_closure_LINUX64 code (since we don't check
1066 * the type in that routine).
1067 */
e9b84181 1068
16070e45 1069 /* there are 13 64bit floating point registers */
e9b84181 1070
16070e45 1071 if (pfr < end_pfr)
bf310028
AM
1072 {
1073 double temp = pfr->d;
1074 pfr->f = (float) temp;
1075 avalue[i] = pfr;
1076 pfr++;
1077 }
1078 else
1079 avalue[i] = pst;
e9b84181
JJ
1080 pst++;
1081 break;
1082
1083 case FFI_TYPE_DOUBLE:
1084 /* On the outgoing stack all values are aligned to 8 */
16070e45 1085 /* there are 13 64bit floating point registers */
e9b84181 1086
bf310028
AM
1087 if (pfr < end_pfr)
1088 {
1089 avalue[i] = pfr;
1090 pfr++;
1091 }
1092 else
1093 avalue[i] = pst;
e9b84181
JJ
1094 pst++;
1095 break;
1096
bf310028
AM
1097#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1098 case FFI_TYPE_LONGDOUBLE:
4243752c 1099 if (pfr + 1 < end_pfr)
bf310028
AM
1100 {
1101 avalue[i] = pfr;
1102 pfr += 2;
1103 }
1104 else
1105 {
1106 if (pfr < end_pfr)
1107 {
1108 /* Passed partly in f13 and partly on the stack.
1109 Move it all to the stack. */
1110 *pst = *(unsigned long *) pfr;
1111 pfr++;
1112 }
1113 avalue[i] = pst;
1114 }
1115 pst += 2;
1116 break;
1117#endif
1118
e9b84181
JJ
1119 default:
1120 FFI_ASSERT(0);
1121 }
1122
1123 i++;
1124 }
1125
1126
1127 (closure->fun) (cif, rvalue, avalue, closure->user_data);
1128
1129 /* Tell ffi_closure_LINUX64 how to perform return type promotions. */
1130 return cif->rtype->type;
e9b84181 1131}