1
/* -----------------------------------------------------------------------
2
ffi.c - Copyright (c) 1998 Geoffrey Keating
4
PowerPC Foreign Function Interface
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:
14
The above copyright notice and this permission notice shall be included
15
in all copies or substantial portions of the Software.
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
----------------------------------------------------------------------- */
27
#include <ffi_common.h>
33
extern void ffi_closure_SYSV(void);
34
extern void FFI_HIDDEN ffi_closure_LINUX64(void);
37
/* The assembly depends on these exact flags. */
38
FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */
39
FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
40
FLAG_RETURNS_FP = 1 << (31-29),
41
FLAG_RETURNS_64BITS = 1 << (31-28),
42
FLAG_RETURNS_128BITS = 1 << (31-27),
44
FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
45
FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
46
FLAG_4_GPR_ARGUMENTS = 1 << (31- 5),
47
FLAG_RETVAL_REFERENCE = 1 << (31- 4)
50
/* About the SYSV ABI. */
52
NUM_GPR_ARG_REGISTERS = 8,
53
NUM_FPR_ARG_REGISTERS = 8
55
enum { ASM_NEEDS_REGISTERS = 4 };
57
/* ffi_prep_args_SYSV is called by the assembly routine once stack space
58
has been allocated for the function's arguments.
60
The stack layout we want looks like this:
62
| Return address from ffi_call_SYSV 4bytes | higher addresses
63
|--------------------------------------------|
64
| Previous backchain pointer 4 | stack pointer here
65
|--------------------------------------------|<+ <<< on entry to
66
| Saved r28-r31 4*4 | | ffi_call_SYSV
67
|--------------------------------------------| |
68
| GPR registers r3-r10 8*4 | | ffi_call_SYSV
69
|--------------------------------------------| |
70
| FPR registers f1-f8 (optional) 8*8 | |
71
|--------------------------------------------| | stack |
72
| Space for copied structures | | grows |
73
|--------------------------------------------| | down V
74
| Parameters that didn't fit in registers | |
75
|--------------------------------------------| | lower addresses
76
| Space for callee's LR 4 | |
77
|--------------------------------------------| | stack pointer here
78
| Current backchain pointer 4 |-/ during
79
|--------------------------------------------| <<< ffi_call_SYSV
84
void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
87
const unsigned bytes = ecif->cif->bytes;
88
const unsigned flags = ecif->cif->flags;
90
/* 'stacktop' points at the previous backchain pointer. */
91
unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
93
/* 'gpr_base' points at the space for gpr3, and grows upwards as
94
we use GPR registers. */
95
unsigned *gpr_base = stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
98
/* 'fpr_base' points at the space for fpr1, and grows upwards as
99
we use FPR registers. */
100
double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS;
103
/* 'copy_space' grows down as we put structures in it. It should
104
stay 16-byte aligned. */
105
char *copy_space = ((flags & FLAG_FP_ARGUMENTS)
109
/* 'next_arg' grows up as we put parameters in it. */
110
unsigned *next_arg = stack + 2;
116
size_t struct_copy_size;
119
/* Check that everything starts aligned properly. */
120
FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
121
FFI_ASSERT(((unsigned)(char *)copy_space & 0xF) == 0);
122
FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
123
FFI_ASSERT((bytes & 0xF) == 0);
124
FFI_ASSERT(copy_space >= (char *)next_arg);
126
/* Deal with return values that are actually pass-by-reference. */
127
if (flags & FLAG_RETVAL_REFERENCE)
129
*gpr_base++ = (unsigned long)(char *)ecif->rvalue;
133
/* Now for the arguments. */
134
p_argv = ecif->avalue;
135
for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
137
i--, ptr++, p_argv++)
139
switch ((*ptr)->type)
142
double_tmp = *(float *)*p_argv;
143
if (fparg_count >= NUM_FPR_ARG_REGISTERS)
145
*(float *)next_arg = (float)double_tmp;
149
*fpr_base++ = double_tmp;
151
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
154
case FFI_TYPE_DOUBLE:
155
double_tmp = *(double *)*p_argv;
157
if (fparg_count >= NUM_FPR_ARG_REGISTERS)
159
if (intarg_count >= NUM_GPR_ARG_REGISTERS
160
&& intarg_count % 2 != 0)
165
*(double *)next_arg = double_tmp;
169
*fpr_base++ = double_tmp;
171
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
174
case FFI_TYPE_UINT64:
175
case FFI_TYPE_SINT64:
176
if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
178
if (intarg_count >= NUM_GPR_ARG_REGISTERS)
180
if (intarg_count%2 != 0)
185
*(long long *)next_arg = *(long long *)*p_argv;
190
/* whoops: abi states only certain register pairs
191
* can be used for passing long long int
192
* specifically (r3,r4), (r5,r6), (r7,r8),
193
* (r9,r10) and if next arg is long long but
194
* not correct starting register of pair then skip
195
* until the proper starting register
197
if (intarg_count%2 != 0)
202
*(long long *)gpr_base = *(long long *)*p_argv;
208
case FFI_TYPE_STRUCT:
209
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
210
case FFI_TYPE_LONGDOUBLE:
212
struct_copy_size = ((*ptr)->size + 15) & ~0xF;
213
copy_space -= struct_copy_size;
214
memcpy(copy_space, (char *)*p_argv, (*ptr)->size);
216
gprvalue = (unsigned long)copy_space;
218
FFI_ASSERT(copy_space > (char *)next_arg);
219
FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY);
223
gprvalue = *(unsigned char *)*p_argv;
226
gprvalue = *(signed char *)*p_argv;
228
case FFI_TYPE_UINT16:
229
gprvalue = *(unsigned short *)*p_argv;
231
case FFI_TYPE_SINT16:
232
gprvalue = *(signed short *)*p_argv;
236
case FFI_TYPE_UINT32:
237
case FFI_TYPE_SINT32:
238
case FFI_TYPE_POINTER:
239
gprvalue = *(unsigned *)*p_argv;
241
if (intarg_count >= NUM_GPR_ARG_REGISTERS)
242
*next_arg++ = gprvalue;
244
*gpr_base++ = gprvalue;
250
/* Check that we didn't overrun the stack... */
251
FFI_ASSERT(copy_space >= (char *)next_arg);
252
FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
253
FFI_ASSERT((unsigned *)fpr_base
254
<= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
255
FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
258
/* About the LINUX64 ABI. */
260
NUM_GPR_ARG_REGISTERS64 = 8,
261
NUM_FPR_ARG_REGISTERS64 = 13
263
enum { ASM_NEEDS_REGISTERS64 = 4 };
265
/* ffi_prep_args64 is called by the assembly routine once stack space
266
has been allocated for the function's arguments.
268
The stack layout we want looks like this:
270
| Ret addr from ffi_call_LINUX64 8bytes | higher addresses
271
|--------------------------------------------|
272
| CR save area 8bytes |
273
|--------------------------------------------|
274
| Previous backchain pointer 8 | stack pointer here
275
|--------------------------------------------|<+ <<< on entry to
276
| Saved r28-r31 4*8 | | ffi_call_LINUX64
277
|--------------------------------------------| |
278
| GPR registers r3-r10 8*8 | |
279
|--------------------------------------------| |
280
| FPR registers f1-f13 (optional) 13*8 | |
281
|--------------------------------------------| |
282
| Parameter save area | |
283
|--------------------------------------------| |
284
| TOC save area 8 | |
285
|--------------------------------------------| | stack |
286
| Linker doubleword 8 | | grows |
287
|--------------------------------------------| | down V
288
| Compiler doubleword 8 | |
289
|--------------------------------------------| | lower addresses
290
| Space for callee's LR 8 | |
291
|--------------------------------------------| |
293
|--------------------------------------------| | stack pointer here
294
| Current backchain pointer 8 |-/ during
295
|--------------------------------------------| <<< ffi_call_LINUX64
300
void FFI_HIDDEN ffi_prep_args64(extended_cif *ecif, unsigned long *const stack)
303
const unsigned long bytes = ecif->cif->bytes;
304
const unsigned long flags = ecif->cif->flags;
306
/* 'stacktop' points at the previous backchain pointer. */
307
unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
309
/* 'next_arg' points at the space for gpr3, and grows upwards as
310
we use GPR registers, then continues at rest. */
311
unsigned long *const gpr_base = stacktop - ASM_NEEDS_REGISTERS64
312
- NUM_GPR_ARG_REGISTERS64;
313
unsigned long *const gpr_end = gpr_base + NUM_GPR_ARG_REGISTERS64;
314
unsigned long *const rest = stack + 6 + NUM_GPR_ARG_REGISTERS64;
315
unsigned long *next_arg = gpr_base;
317
/* 'fpr_base' points at the space for fpr3, and grows upwards as
318
we use FPR registers. */
319
double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS64;
326
unsigned long gprvalue;
328
/* Check that everything starts aligned properly. */
329
FFI_ASSERT(((unsigned long)(char *)stack & 0xF) == 0);
330
FFI_ASSERT(((unsigned long)(char *)stacktop & 0xF) == 0);
331
FFI_ASSERT((bytes & 0xF) == 0);
333
/* Deal with return values that are actually pass-by-reference. */
334
if (flags & FLAG_RETVAL_REFERENCE)
335
*next_arg++ = (unsigned long)(char *)ecif->rvalue;
337
/* Now for the arguments. */
338
p_argv = ecif->avalue;
339
for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
341
i--, ptr++, p_argv++)
343
switch ((*ptr)->type)
346
double_tmp = *(float *)*p_argv;
347
*(float *)next_arg = (float)double_tmp;
348
if (++next_arg == gpr_end)
350
if (fparg_count < NUM_FPR_ARG_REGISTERS64)
351
*fpr_base++ = double_tmp;
353
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
356
case FFI_TYPE_DOUBLE:
357
double_tmp = *(double *)*p_argv;
358
*(double *)next_arg = double_tmp;
359
if (++next_arg == gpr_end)
361
if (fparg_count < NUM_FPR_ARG_REGISTERS64)
362
*fpr_base++ = double_tmp;
364
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
367
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
368
case FFI_TYPE_LONGDOUBLE:
369
double_tmp = ((double *) *p_argv)[0];
370
*(double *) next_arg = double_tmp;
371
if (++next_arg == gpr_end)
373
if (fparg_count < NUM_FPR_ARG_REGISTERS64)
374
*fpr_base++ = double_tmp;
376
double_tmp = ((double *) *p_argv)[1];
377
*(double *) next_arg = double_tmp;
378
if (++next_arg == gpr_end)
380
if (fparg_count < NUM_FPR_ARG_REGISTERS64)
381
*fpr_base++ = double_tmp;
383
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
387
case FFI_TYPE_STRUCT:
388
words = ((*ptr)->size + 7) / 8;
389
if (next_arg >= gpr_base && next_arg + words > gpr_end)
391
size_t first = (char *) gpr_end - (char *) next_arg;
392
memcpy((char *) next_arg, (char *) *p_argv, first);
393
memcpy((char *) rest, (char *) *p_argv + first,
394
(*ptr)->size - first);
395
next_arg = (unsigned long *) ((char *) rest + words * 8 - first);
399
char *where = (char *) next_arg;
401
/* Structures with size less than eight bytes are passed
403
if ((*ptr)->size < 8)
404
where += 8 - (*ptr)->size;
406
memcpy (where, (char *) *p_argv, (*ptr)->size);
408
if (next_arg == gpr_end)
414
gprvalue = *(unsigned char *)*p_argv;
417
gprvalue = *(signed char *)*p_argv;
419
case FFI_TYPE_UINT16:
420
gprvalue = *(unsigned short *)*p_argv;
422
case FFI_TYPE_SINT16:
423
gprvalue = *(signed short *)*p_argv;
425
case FFI_TYPE_UINT32:
426
gprvalue = *(unsigned int *)*p_argv;
429
case FFI_TYPE_SINT32:
430
gprvalue = *(signed int *)*p_argv;
433
case FFI_TYPE_UINT64:
434
case FFI_TYPE_SINT64:
435
case FFI_TYPE_POINTER:
436
gprvalue = *(unsigned long *)*p_argv;
438
*next_arg++ = gprvalue;
439
if (next_arg == gpr_end)
445
FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS
446
|| (next_arg >= gpr_base && next_arg <= gpr_base + 4));
451
/* Perform machine dependent cif processing */
452
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
454
/* All this is for the SYSV and LINUX64 ABI. */
458
int fparg_count = 0, intarg_count = 0;
460
unsigned struct_copy_size = 0;
461
unsigned type = cif->rtype->type;
462
unsigned size = cif->rtype->size;
464
if (cif->abi != FFI_LINUX64)
466
/* All the machine-independent calculation of cif->bytes will be wrong.
467
Redo the calculation for SYSV. */
469
/* Space for the frame pointer, callee's LR, and the asm's temp regs. */
470
bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int);
472
/* Space for the GPR registers. */
473
bytes += NUM_GPR_ARG_REGISTERS * sizeof(int);
479
/* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
481
bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof(long);
483
/* Space for the mandatory parm save area and general registers. */
484
bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof(long);
486
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
487
if (type == FFI_TYPE_LONGDOUBLE)
488
type = FFI_TYPE_DOUBLE;
492
/* Return value handling. The rules for SYSV are as follows:
493
- 32-bit (or less) integer values are returned in gpr3;
494
- Structures of size <= 4 bytes also returned in gpr3;
495
- 64-bit integer values and structures between 5 and 8 bytes are returned
497
- Single/double FP values are returned in fpr1;
498
- Larger structures and long double (if not equivalent to double) values
499
are allocated space and a pointer is passed as the first argument.
501
- integer values in gpr3;
502
- Structures/Unions by reference;
503
- Single/double FP values in fpr1, long double in fpr1,fpr2. */
506
case FFI_TYPE_DOUBLE:
507
flags |= FLAG_RETURNS_64BITS;
510
flags |= FLAG_RETURNS_FP;
513
case FFI_TYPE_UINT64:
514
case FFI_TYPE_SINT64:
515
flags |= FLAG_RETURNS_64BITS;
518
case FFI_TYPE_STRUCT:
519
if (cif->abi == FFI_SYSV)
521
/* The final SYSV ABI says that structures smaller or equal 8 bytes
522
are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
525
/* Treat structs with size <= 8 bytes. */
527
flags |= FLAG_RETURNS_SMST;
528
/* These structs are returned in r3. We pack the type and the
529
precalculated shift value (needed in the sysv.S) into flags.
530
The same applies for the structs returned in r3/r4. */
532
flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1 )
533
| (8 * (4 - size) << 4);
536
/* These structs are returned in r3 and r4. See above. */
538
flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2 )
539
| (8 * (8 - size) << 4);
544
/* else fall through. */
545
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
546
case FFI_TYPE_LONGDOUBLE:
547
if (type == FFI_TYPE_LONGDOUBLE && cif->abi == FFI_LINUX64)
549
flags |= FLAG_RETURNS_128BITS;
550
flags |= FLAG_RETURNS_FP;
555
flags |= FLAG_RETVAL_REFERENCE;
558
flags |= FLAG_RETURNS_NOTHING;
562
/* Returns 32-bit integer, or similar. Nothing to do here. */
566
if (cif->abi != FFI_LINUX64)
567
/* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
568
first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
569
goes on the stack. Structures and long doubles (if not equivalent
570
to double) are passed as a pointer to a copy of the structure.
571
Stuff on the stack needs to keep proper alignment. */
572
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
574
switch ((*ptr)->type)
578
/* floating singles are not 8-aligned on stack */
581
case FFI_TYPE_DOUBLE:
583
/* If this FP arg is going on the stack, it must be
585
if (fparg_count > NUM_FPR_ARG_REGISTERS
586
&& intarg_count >= NUM_GPR_ARG_REGISTERS
587
&& intarg_count % 2 != 0)
591
case FFI_TYPE_UINT64:
592
case FFI_TYPE_SINT64:
593
/* 'long long' arguments are passed as two words, but
594
either both words must fit in registers or both go
595
on the stack. If they go on the stack, they must
598
Also, only certain register pairs can be used for
599
passing long long int -- specifically (r3,r4), (r5,r6),
602
if (intarg_count == NUM_GPR_ARG_REGISTERS-1
603
|| intarg_count%2 != 0)
608
case FFI_TYPE_STRUCT:
609
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
610
case FFI_TYPE_LONGDOUBLE:
612
/* We must allocate space for a copy of these to enforce
613
pass-by-value. Pad the space up to a multiple of 16
614
bytes (the maximum alignment required for anything under
616
struct_copy_size += ((*ptr)->size + 15) & ~0xF;
617
/* Fall through (allocate space for the pointer). */
620
/* Everything else is passed as a 4-byte word in a GPR, either
621
the object itself or a pointer to it. */
627
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
629
switch ((*ptr)->type)
631
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
632
case FFI_TYPE_LONGDOUBLE:
638
case FFI_TYPE_DOUBLE:
643
case FFI_TYPE_STRUCT:
644
intarg_count += ((*ptr)->size + 7) / 8;
648
/* Everything else is passed as a 8-byte word in a GPR, either
649
the object itself or a pointer to it. */
655
if (fparg_count != 0)
656
flags |= FLAG_FP_ARGUMENTS;
657
if (intarg_count > 4)
658
flags |= FLAG_4_GPR_ARGUMENTS;
659
if (struct_copy_size != 0)
660
flags |= FLAG_ARG_NEEDS_COPY;
662
if (cif->abi != FFI_LINUX64)
664
/* Space for the FPR registers, if needed. */
665
if (fparg_count != 0)
666
bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
669
if (intarg_count > NUM_GPR_ARG_REGISTERS)
670
bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int);
671
if (fparg_count > NUM_FPR_ARG_REGISTERS)
672
bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double);
676
/* Space for the FPR registers, if needed. */
677
if (fparg_count != 0)
678
bytes += NUM_FPR_ARG_REGISTERS64 * sizeof(double);
681
if (intarg_count > NUM_GPR_ARG_REGISTERS64)
682
bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof(long);
685
/* The stack space allocated needs to be a multiple of 16 bytes. */
686
bytes = (bytes + 15) & ~0xF;
688
/* Add in the space for the copied structures. */
689
bytes += struct_copy_size;
699
extern void ffi_call_SYSV(/*@out@*/ extended_cif *,
701
/*@out@*/ unsigned *,
703
extern void FFI_HIDDEN ffi_call_LINUX64(/*@out@*/ extended_cif *,
704
unsigned long, unsigned long,
705
/*@out@*/ unsigned long *,
710
void ffi_call(/*@dependent@*/ ffi_cif *cif,
712
/*@out@*/ void *rvalue,
713
/*@dependent@*/ void **avalue)
718
ecif.avalue = avalue;
720
/* If the return value is a struct and we don't have a return */
721
/* value address then we need to make one */
723
if ((rvalue == NULL) &&
724
(cif->rtype->type == FFI_TYPE_STRUCT))
727
ecif.rvalue = alloca(cif->rtype->size);
731
ecif.rvalue = rvalue;
740
ffi_call_SYSV(&ecif, -cif->bytes,
741
cif->flags, ecif.rvalue, fn);
747
ffi_call_LINUX64(&ecif, -(long) cif->bytes,
748
cif->flags, ecif.rvalue, fn);
760
static void flush_icache(char *, int);
762
#define MIN_CACHE_LINE_SIZE 8
764
static void flush_icache(char * addr1, int size)
768
for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) {
770
__asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory");
772
addr = addr1 + size - 1;
773
__asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory");
778
ffi_prep_closure (ffi_closure* closure,
780
void (*fun)(ffi_cif*, void*, void**, void*),
784
void **tramp = (void **) &closure->tramp[0];
786
FFI_ASSERT (cif->abi == FFI_LINUX64);
787
/* Copy function address and TOC from ffi_closure_LINUX64. */
788
memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
789
tramp[2] = (void *) closure;
793
FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
795
tramp = (unsigned int *) &closure->tramp[0];
796
tramp[0] = 0x7c0802a6; /* mflr r0 */
797
tramp[1] = 0x4800000d; /* bl 10 <trampoline_initial+0x10> */
798
tramp[4] = 0x7d6802a6; /* mflr r11 */
799
tramp[5] = 0x7c0803a6; /* mtlr r0 */
800
tramp[6] = 0x800b0000; /* lwz r0,0(r11) */
801
tramp[7] = 0x816b0004; /* lwz r11,4(r11) */
802
tramp[8] = 0x7c0903a6; /* mtctr r0 */
803
tramp[9] = 0x4e800420; /* bctr */
804
*(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */
805
*(void **) &tramp[3] = (void *)closure; /* context */
807
/* Flush the icache. */
808
flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
813
closure->user_data = user_data;
824
int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*,
825
ffi_dblfl*, unsigned long*);
827
/* Basically the trampoline invokes ffi_closure_SYSV, and on
828
* entry, r11 holds the address of the closure.
829
* After storing the registers that could possibly contain
830
* parameters to be passed into the stack frame and setting
831
* up space for a return value, ffi_closure_SYSV invokes the
832
* following helper function to do most of the work
836
ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
837
unsigned long * pgr, ffi_dblfl * pfr,
840
/* rvalue is the pointer to space for return value in closure assembly */
841
/* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
842
/* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */
843
/* pst is the pointer to outgoing parameter stack in original caller */
846
ffi_type ** arg_types;
848
long nf; /* number of floating registers already used */
849
long ng; /* number of general registers already used */
855
avalue = alloca(cif->nargs * sizeof(void *));
856
size = cif->rtype->size;
861
/* Copy the caller's structure return value address so that the closure
862
returns the data directly to the caller.
863
For FFI_SYSV the result is passed in r3/r4 if the struct size is less
866
if (cif->rtype->type == FFI_TYPE_STRUCT)
868
if (!((cif->abi == FFI_SYSV) && (size <= 8))) {
869
rvalue = (void *) *pgr;
877
arg_types = cif->arg_types;
879
/* Grab the addresses of the arguments from the stack frame. */
882
switch (arg_types[i]->type)
886
/* there are 8 gpr registers used to pass values */
888
avalue[i] = (((char *)pgr)+3);
892
avalue[i] = (((char *)pst)+3);
897
case FFI_TYPE_SINT16:
898
case FFI_TYPE_UINT16:
899
/* there are 8 gpr registers used to pass values */
901
avalue[i] = (((char *)pgr)+2);
905
avalue[i] = (((char *)pst)+2);
910
case FFI_TYPE_SINT32:
911
case FFI_TYPE_UINT32:
912
case FFI_TYPE_POINTER:
913
/* there are 8 gpr registers used to pass values */
924
case FFI_TYPE_STRUCT:
925
/* Structs are passed by reference. The address will appear in a
926
gpr if it is one of the first 8 arguments. */
928
avalue[i] = (void *) *pgr;
932
avalue[i] = (void *) *pst;
937
case FFI_TYPE_SINT64:
938
case FFI_TYPE_UINT64:
939
/* passing long long ints are complex, they must
940
* be passed in suitable register pairs such as
941
* (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
942
* and if the entire pair aren't available then the outgoing
943
* parameter stack is used for both but an alignment of 8
944
* must will be kept. So we must either look in pgr
945
* or pst to find the correct address for this type
950
/* skip r4, r6, r8 as starting points */
958
if (((long)pst) & 4) pst++;
965
/* unfortunately float values are stored as doubles
966
* in the ffi_closure_SYSV code (since we don't check
967
* the type in that routine).
970
/* there are 8 64bit floating point registers */
974
pfr->f = (float)temp;
979
/* FIXME? here we are really changing the values
980
* stored in the original calling routines outgoing
981
* parameter stack. This is probably a really
982
* naughty thing to do but...
990
case FFI_TYPE_DOUBLE:
991
/* On the outgoing stack all values are aligned to 8 */
992
/* there are 8 64bit floating point registers */
999
if (((long)pst) & 4) pst++;
1014
(closure->fun) (cif, rvalue, avalue, closure->user_data);
1016
/* Tell ffi_closure_SYSV how to perform return type promotions.
1017
Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
1018
we have to tell ffi_closure_SYSV how to treat them. */
1019
if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
1021
return FFI_SYSV_TYPE_SMALL_STRUCT + size;
1022
return cif->rtype->type;
1026
int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*,
1030
ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
1031
unsigned long *pst, ffi_dblfl *pfr)
1033
/* rvalue is the pointer to space for return value in closure assembly */
1034
/* pst is the pointer to parameter save area
1035
(r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
1036
/* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
1039
ffi_type **arg_types;
1042
ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
1045
avalue = alloca (cif->nargs * sizeof (void *));
1047
/* Copy the caller's structure return value address so that the closure
1048
returns the data directly to the caller. */
1049
if (cif->rtype->type == FFI_TYPE_STRUCT)
1051
rvalue = (void *) *pst;
1057
arg_types = cif->arg_types;
1059
/* Grab the addresses of the arguments from the stack frame. */
1062
switch (arg_types[i]->type)
1064
case FFI_TYPE_SINT8:
1065
case FFI_TYPE_UINT8:
1066
avalue[i] = (char *) pst + 7;
1070
case FFI_TYPE_SINT16:
1071
case FFI_TYPE_UINT16:
1072
avalue[i] = (char *) pst + 6;
1076
case FFI_TYPE_SINT32:
1077
case FFI_TYPE_UINT32:
1078
avalue[i] = (char *) pst + 4;
1082
case FFI_TYPE_SINT64:
1083
case FFI_TYPE_UINT64:
1084
case FFI_TYPE_POINTER:
1089
case FFI_TYPE_STRUCT:
1090
/* Structures with size less than eight bytes are passed
1092
if (arg_types[i]->size < 8)
1093
avalue[i] = (char *) pst + 8 - arg_types[i]->size;
1096
pst += (arg_types[i]->size + 7) / 8;
1099
case FFI_TYPE_FLOAT:
1100
/* unfortunately float values are stored as doubles
1101
* in the ffi_closure_LINUX64 code (since we don't check
1102
* the type in that routine).
1105
/* there are 13 64bit floating point registers */
1109
double temp = pfr->d;
1110
pfr->f = (float) temp;
1119
case FFI_TYPE_DOUBLE:
1120
/* On the outgoing stack all values are aligned to 8 */
1121
/* there are 13 64bit floating point registers */
1133
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1134
case FFI_TYPE_LONGDOUBLE:
1135
if (pfr + 1 < end_pfr)
1144
/* Passed partly in f13 and partly on the stack.
1145
Move it all to the stack. */
1146
*pst = *(unsigned long *) pfr;
1163
(closure->fun) (cif, rvalue, avalue, closure->user_data);
1165
/* Tell ffi_closure_LINUX64 how to perform return type promotions. */
1166
return cif->rtype->type;