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