1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2011 Anthony Green
3 Copyright (c) 2008 David Daney
4 Copyright (c) 1996, 2007, 2008, 2011 Red Hat, Inc.
6 MIPS Foreign Function Interface
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 ``Software''), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice shall be included
17 in all copies or substantial portions of the Software.
19 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 DEALINGS IN THE SOFTWARE.
27 ----------------------------------------------------------------------- */
30 #include <ffi_common.h>
35 # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
36 # define USE__BUILTIN___CLEAR_CACHE 1
40 #ifndef USE__BUILTIN___CLEAR_CACHE
41 # if defined(__OpenBSD__)
42 # include <mips64/sysarch.h>
44 # include <sys/cachectl.h>
49 # define FFI_MIPS_STOP_HERE() ffi_stop_here()
51 # define FFI_MIPS_STOP_HERE() do {} while(0)
56 FFI_ASSERT(argp <= &stack[bytes]); \
57 if (argp == &stack[bytes]) \
60 FFI_MIPS_STOP_HERE(); \
67 /* ffi_prep_args is called by the assembly routine once stack space
68 has been allocated for the function's arguments */
70 static void ffi_prep_args(char *stack
,
81 /* If more than 8 double words are used, the remainder go
82 on the stack. We reorder stuff on the stack here to
83 support this easily. */
84 if (bytes
> 8 * sizeof(ffi_arg
))
85 argp
= &stack
[bytes
- (8 * sizeof(ffi_arg
))];
92 memset(stack
, 0, bytes
);
95 if ( ecif
->cif
->rstruct_flag
!= 0 )
97 if ( ecif
->cif
->rtype
->type
== FFI_TYPE_STRUCT
)
100 *(ffi_arg
*) argp
= (ffi_arg
) ecif
->rvalue
;
101 argp
+= sizeof(ffi_arg
);
105 p_argv
= ecif
->avalue
;
107 for (i
= 0, p_arg
= ecif
->cif
->arg_types
; i
< ecif
->cif
->nargs
; i
++, p_arg
++)
112 /* Align if necessary. */
113 a
= (*p_arg
)->alignment
;
114 if (a
< sizeof(ffi_arg
))
117 if ((a
- 1) & (unsigned long) argp
)
119 argp
= (char *) ALIGN(argp
, a
);
124 if (z
<= sizeof(ffi_arg
))
126 int type
= (*p_arg
)->type
;
129 /* The size of a pointer depends on the ABI */
130 if (type
== FFI_TYPE_POINTER
)
131 type
= (ecif
->cif
->abi
== FFI_N64
132 || ecif
->cif
->abi
== FFI_N64_SOFT_FLOAT
)
133 ? FFI_TYPE_SINT64
: FFI_TYPE_SINT32
;
135 if (i
< 8 && (ecif
->cif
->abi
== FFI_N32_SOFT_FLOAT
136 || ecif
->cif
->abi
== FFI_N64_SOFT_FLOAT
))
141 type
= FFI_TYPE_UINT32
;
143 case FFI_TYPE_DOUBLE
:
144 type
= FFI_TYPE_UINT64
;
153 *(ffi_arg
*)argp
= *(SINT8
*)(* p_argv
);
157 *(ffi_arg
*)argp
= *(UINT8
*)(* p_argv
);
160 case FFI_TYPE_SINT16
:
161 *(ffi_arg
*)argp
= *(SINT16
*)(* p_argv
);
164 case FFI_TYPE_UINT16
:
165 *(ffi_arg
*)argp
= *(UINT16
*)(* p_argv
);
168 case FFI_TYPE_SINT32
:
169 *(ffi_arg
*)argp
= *(SINT32
*)(* p_argv
);
172 case FFI_TYPE_UINT32
:
174 /* The N32 ABI requires that 32-bit integers
175 be sign-extended to 64-bits, regardless of
176 whether they are signed or unsigned. */
177 *(ffi_arg
*)argp
= *(SINT32
*)(* p_argv
);
179 *(ffi_arg
*)argp
= *(UINT32
*)(* p_argv
);
183 /* This can only happen with 64bit slots. */
185 *(float *) argp
= *(float *)(* p_argv
);
188 /* Handle structures. */
190 memcpy(argp
, *p_argv
, (*p_arg
)->size
);
197 memcpy(argp
, *p_argv
, z
);
200 unsigned long end
= (unsigned long) argp
+ z
;
201 unsigned long cap
= (unsigned long) stack
+ bytes
;
203 /* Check if the data will fit within the register space.
204 Handle it if it doesn't. */
207 memcpy(argp
, *p_argv
, z
);
210 unsigned long portion
= cap
- (unsigned long)argp
;
212 memcpy(argp
, *p_argv
, portion
);
215 memcpy(argp
, (void*)((unsigned long)(*p_argv
) + portion
),
229 /* The n32 spec says that if "a chunk consists solely of a double
230 float field (but not a double, which is part of a union), it
231 is passed in a floating point register. Any other chunk is
232 passed in an integer register". This code traverses structure
233 definitions and generates the appropriate flags. */
236 calc_n32_struct_flags(int soft_float
, ffi_type
*arg
,
237 unsigned *loc
, unsigned *arg_reg
)
247 while ((e
= arg
->elements
[index
]))
249 /* Align this object. */
250 *loc
= ALIGN(*loc
, e
->alignment
);
251 if (e
->type
== FFI_TYPE_DOUBLE
)
253 /* Already aligned to FFI_SIZEOF_ARG. */
254 *arg_reg
= *loc
/ FFI_SIZEOF_ARG
;
257 flags
+= (FFI_TYPE_DOUBLE
<< (*arg_reg
* FFI_FLAG_BITS
));
264 /* Next Argument register at alignment of FFI_SIZEOF_ARG. */
265 *arg_reg
= ALIGN(*loc
, FFI_SIZEOF_ARG
) / FFI_SIZEOF_ARG
;
271 calc_n32_return_struct_flags(int soft_float
, ffi_type
*arg
)
274 unsigned small
= FFI_TYPE_SMALLSTRUCT
;
277 /* Returning structures under n32 is a tricky thing.
278 A struct with only one or two floating point fields
279 is returned in $f0 (and $f2 if necessary). Any other
280 struct results at most 128 bits are returned in $2
281 (the first 64 bits) and $3 (remainder, if necessary).
282 Larger structs are handled normally. */
288 small
= FFI_TYPE_SMALLSTRUCT2
;
290 e
= arg
->elements
[0];
292 if (e
->type
== FFI_TYPE_DOUBLE
)
293 flags
= FFI_TYPE_DOUBLE
;
294 else if (e
->type
== FFI_TYPE_FLOAT
)
295 flags
= FFI_TYPE_FLOAT
;
297 if (flags
&& (e
= arg
->elements
[1]))
299 if (e
->type
== FFI_TYPE_DOUBLE
)
300 flags
+= FFI_TYPE_DOUBLE
<< FFI_FLAG_BITS
;
301 else if (e
->type
== FFI_TYPE_FLOAT
)
302 flags
+= FFI_TYPE_FLOAT
<< FFI_FLAG_BITS
;
306 if (flags
&& (arg
->elements
[2]))
308 /* There are three arguments and the first two are
309 floats! This must be passed the old way. */
313 flags
+= FFI_TYPE_STRUCT_SOFT
;
324 /* Perform machine dependent cif processing */
325 ffi_status
ffi_prep_cif_machdep(ffi_cif
*cif
)
330 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
331 * does not have special handling for floating point args.
334 if (cif
->rtype
->type
!= FFI_TYPE_STRUCT
&& cif
->abi
== FFI_O32
)
338 switch ((cif
->arg_types
)[0]->type
)
341 case FFI_TYPE_DOUBLE
:
342 cif
->flags
+= (cif
->arg_types
)[0]->type
;
351 /* Only handle the second argument if the first
352 is a float or double. */
355 switch ((cif
->arg_types
)[1]->type
)
358 case FFI_TYPE_DOUBLE
:
359 cif
->flags
+= (cif
->arg_types
)[1]->type
<< FFI_FLAG_BITS
;
370 /* Set the return type flag */
372 if (cif
->abi
== FFI_O32_SOFT_FLOAT
)
374 switch (cif
->rtype
->type
)
377 case FFI_TYPE_STRUCT
:
378 cif
->flags
+= cif
->rtype
->type
<< (FFI_FLAG_BITS
* 2);
381 case FFI_TYPE_SINT64
:
382 case FFI_TYPE_UINT64
:
383 case FFI_TYPE_DOUBLE
:
384 cif
->flags
+= FFI_TYPE_UINT64
<< (FFI_FLAG_BITS
* 2);
389 cif
->flags
+= FFI_TYPE_INT
<< (FFI_FLAG_BITS
* 2);
396 switch (cif
->rtype
->type
)
399 case FFI_TYPE_STRUCT
:
401 case FFI_TYPE_DOUBLE
:
402 cif
->flags
+= cif
->rtype
->type
<< (FFI_FLAG_BITS
* 2);
405 case FFI_TYPE_SINT64
:
406 case FFI_TYPE_UINT64
:
407 cif
->flags
+= FFI_TYPE_UINT64
<< (FFI_FLAG_BITS
* 2);
411 cif
->flags
+= FFI_TYPE_INT
<< (FFI_FLAG_BITS
* 2);
418 /* Set the flags necessary for N32 processing */
421 unsigned arg_reg
= 0;
423 unsigned count
= (cif
->nargs
< 8) ? cif
->nargs
: 8;
426 unsigned struct_flags
= 0;
427 int soft_float
= (cif
->abi
== FFI_N32_SOFT_FLOAT
428 || cif
->abi
== FFI_N64_SOFT_FLOAT
);
430 if (cif
->rtype
->type
== FFI_TYPE_STRUCT
)
432 struct_flags
= calc_n32_return_struct_flags(soft_float
, cif
->rtype
);
434 if (struct_flags
== 0)
436 /* This means that the structure is being passed as
440 count
= (cif
->nargs
< 7) ? cif
->nargs
: 7;
442 cif
->rstruct_flag
= !0;
445 cif
->rstruct_flag
= 0;
448 cif
->rstruct_flag
= 0;
450 while (count
-- > 0 && arg_reg
< 8)
452 type
= (cif
->arg_types
)[index
]->type
;
458 type
= FFI_TYPE_UINT32
;
460 case FFI_TYPE_DOUBLE
:
461 type
= FFI_TYPE_UINT64
;
470 case FFI_TYPE_DOUBLE
:
472 ((cif
->arg_types
)[index
]->type
<< (arg_reg
* FFI_FLAG_BITS
));
475 case FFI_TYPE_LONGDOUBLE
:
477 arg_reg
= ALIGN(arg_reg
, 2);
478 /* Treat it as two adjacent doubles. */
486 (FFI_TYPE_DOUBLE
<< (arg_reg
* FFI_FLAG_BITS
));
489 (FFI_TYPE_DOUBLE
<< (arg_reg
* FFI_FLAG_BITS
));
494 case FFI_TYPE_STRUCT
:
495 loc
= arg_reg
* FFI_SIZEOF_ARG
;
496 cif
->flags
+= calc_n32_struct_flags(soft_float
,
497 (cif
->arg_types
)[index
],
509 /* Set the return type flag */
510 switch (cif
->rtype
->type
)
512 case FFI_TYPE_STRUCT
:
514 if (struct_flags
== 0)
516 /* The structure is returned through a hidden
517 first argument. Do nothing, 'cause FFI_TYPE_VOID
522 /* The structure is returned via some tricky
524 cif
->flags
+= FFI_TYPE_STRUCT
<< (FFI_FLAG_BITS
* 8);
525 cif
->flags
+= struct_flags
<< (4 + (FFI_FLAG_BITS
* 8));
531 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
534 case FFI_TYPE_POINTER
:
535 if (cif
->abi
== FFI_N32_SOFT_FLOAT
|| cif
->abi
== FFI_N32
)
536 cif
->flags
+= FFI_TYPE_SINT32
<< (FFI_FLAG_BITS
* 8);
538 cif
->flags
+= FFI_TYPE_INT
<< (FFI_FLAG_BITS
* 8);
544 cif
->flags
+= FFI_TYPE_SINT32
<< (FFI_FLAG_BITS
* 8);
547 /* else fall through */
548 case FFI_TYPE_DOUBLE
:
550 cif
->flags
+= FFI_TYPE_INT
<< (FFI_FLAG_BITS
* 8);
552 cif
->flags
+= cif
->rtype
->type
<< (FFI_FLAG_BITS
* 8);
555 case FFI_TYPE_LONGDOUBLE
:
556 /* Long double is returned as if it were a struct containing
560 cif
->flags
+= FFI_TYPE_STRUCT
<< (FFI_FLAG_BITS
* 8);
561 cif
->flags
+= FFI_TYPE_SMALLSTRUCT2
<< (4 + (FFI_FLAG_BITS
* 8));
565 cif
->flags
+= FFI_TYPE_STRUCT
<< (FFI_FLAG_BITS
* 8);
566 cif
->flags
+= (FFI_TYPE_DOUBLE
567 + (FFI_TYPE_DOUBLE
<< FFI_FLAG_BITS
))
568 << (4 + (FFI_FLAG_BITS
* 8));
572 cif
->flags
+= FFI_TYPE_INT
<< (FFI_FLAG_BITS
* 8);
581 /* Low level routine for calling O32 functions */
582 extern int ffi_call_O32(void (*)(char *, extended_cif
*, int, int),
583 extended_cif
*, unsigned,
584 unsigned, unsigned *, void (*)(void));
586 /* Low level routine for calling N32 functions */
587 extern int ffi_call_N32(void (*)(char *, extended_cif
*, int, int),
588 extended_cif
*, unsigned,
589 unsigned, void *, void (*)(void));
591 void ffi_call(ffi_cif
*cif
, void (*fn
)(void), void *rvalue
, void **avalue
)
596 ecif
.avalue
= avalue
;
598 /* If the return value is a struct and we don't have a return */
599 /* value address then we need to make one */
601 if ((rvalue
== NULL
) &&
602 (cif
->rtype
->type
== FFI_TYPE_STRUCT
))
603 ecif
.rvalue
= alloca(cif
->rtype
->size
);
605 ecif
.rvalue
= rvalue
;
611 case FFI_O32_SOFT_FLOAT
:
612 ffi_call_O32(ffi_prep_args
, &ecif
, cif
->bytes
,
613 cif
->flags
, ecif
.rvalue
, fn
);
619 case FFI_N32_SOFT_FLOAT
:
621 case FFI_N64_SOFT_FLOAT
:
625 char *rvalue_copy
= ecif
.rvalue
;
626 if (cif
->rtype
->type
== FFI_TYPE_STRUCT
&& cif
->rtype
->size
< 16)
628 /* For structures smaller than 16 bytes we clobber memory
629 in 8 byte increments. Make a copy so we don't clobber
630 the callers memory outside of the struct bounds. */
631 rvalue_copy
= alloca(16);
634 else if (cif
->rtype
->type
== FFI_TYPE_FLOAT
635 && (cif
->abi
== FFI_N64_SOFT_FLOAT
636 || cif
->abi
== FFI_N32_SOFT_FLOAT
))
638 rvalue_copy
= alloca (8);
640 #if defined(__MIPSEB__) || defined(_MIPSEB)
644 ffi_call_N32(ffi_prep_args
, &ecif
, cif
->bytes
,
645 cif
->flags
, rvalue_copy
, fn
);
647 memcpy(ecif
.rvalue
, rvalue_copy
+ copy_offset
, cif
->rtype
->size
);
659 #if defined(FFI_MIPS_O32)
660 extern void ffi_closure_O32(void);
662 extern void ffi_closure_N32(void);
663 #endif /* FFI_MIPS_O32 */
666 ffi_prep_closure_loc (ffi_closure
*closure
,
668 void (*fun
)(ffi_cif
*,void*,void**,void*),
672 unsigned int *tramp
= (unsigned int *) &closure
->tramp
[0];
674 char *clear_location
= (char *) codeloc
;
676 #if defined(FFI_MIPS_O32)
677 if (cif
->abi
!= FFI_O32
&& cif
->abi
!= FFI_O32_SOFT_FLOAT
)
679 fn
= ffi_closure_O32
;
681 #if _MIPS_SIM ==_ABIN32
682 if (cif
->abi
!= FFI_N32
683 && cif
->abi
!= FFI_N32_SOFT_FLOAT
)
686 if (cif
->abi
!= FFI_N64
687 && cif
->abi
!= FFI_N64_SOFT_FLOAT
)
690 fn
= ffi_closure_N32
;
691 #endif /* FFI_MIPS_O32 */
693 #if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
694 /* lui $25,high(fn) */
695 tramp
[0] = 0x3c190000 | ((unsigned)fn
>> 16);
696 /* ori $25,low(fn) */
697 tramp
[1] = 0x37390000 | ((unsigned)fn
& 0xffff);
698 /* lui $12,high(codeloc) */
699 tramp
[2] = 0x3c0c0000 | ((unsigned)codeloc
>> 16);
701 tramp
[3] = 0x03200008;
702 /* ori $12,low(codeloc) */
703 tramp
[4] = 0x358c0000 | ((unsigned)codeloc
& 0xffff);
705 /* N64 has a somewhat larger trampoline. */
706 /* lui $25,high(fn) */
707 tramp
[0] = 0x3c190000 | ((unsigned long)fn
>> 48);
708 /* lui $12,high(codeloc) */
709 tramp
[1] = 0x3c0c0000 | ((unsigned long)codeloc
>> 48);
710 /* ori $25,mid-high(fn) */
711 tramp
[2] = 0x37390000 | (((unsigned long)fn
>> 32 ) & 0xffff);
712 /* ori $12,mid-high(codeloc) */
713 tramp
[3] = 0x358c0000 | (((unsigned long)codeloc
>> 32) & 0xffff);
714 /* dsll $25,$25,16 */
715 tramp
[4] = 0x0019cc38;
716 /* dsll $12,$12,16 */
717 tramp
[5] = 0x000c6438;
718 /* ori $25,mid-low(fn) */
719 tramp
[6] = 0x37390000 | (((unsigned long)fn
>> 16 ) & 0xffff);
720 /* ori $12,mid-low(codeloc) */
721 tramp
[7] = 0x358c0000 | (((unsigned long)codeloc
>> 16) & 0xffff);
722 /* dsll $25,$25,16 */
723 tramp
[8] = 0x0019cc38;
724 /* dsll $12,$12,16 */
725 tramp
[9] = 0x000c6438;
726 /* ori $25,low(fn) */
727 tramp
[10] = 0x37390000 | ((unsigned long)fn
& 0xffff);
729 tramp
[11] = 0x03200008;
730 /* ori $12,low(codeloc) */
731 tramp
[12] = 0x358c0000 | ((unsigned long)codeloc
& 0xffff);
737 closure
->user_data
= user_data
;
739 #ifdef USE__BUILTIN___CLEAR_CACHE
740 __builtin___clear_cache(clear_location
, clear_location
+ FFI_TRAMPOLINE_SIZE
);
742 cacheflush (clear_location
, FFI_TRAMPOLINE_SIZE
, ICACHE
);
748 * Decodes the arguments to a function, which will be stored on the
749 * stack. AR is the pointer to the beginning of the integer arguments
750 * (and, depending upon the arguments, some floating-point arguments
751 * as well). FPR is a pointer to the area where floating point
752 * registers have been saved, if any.
754 * RVALUE is the location where the function return value will be
755 * stored. CLOSURE is the prepared closure to invoke.
757 * This function should only be called from assembly, which is in
758 * turn called from a trampoline.
760 * Returns the function return type.
762 * Based on the similar routine for sparc.
765 ffi_closure_mips_inner_O32 (ffi_closure
*closure
,
766 void *rvalue
, ffi_arg
*ar
,
772 ffi_type
**arg_types
;
773 int i
, avn
, argn
, seen_int
;
776 avalue
= alloca (cif
->nargs
* sizeof (ffi_arg
));
777 avaluep
= alloca (cif
->nargs
* sizeof (ffi_arg
));
779 seen_int
= (cif
->abi
== FFI_O32_SOFT_FLOAT
);
782 if ((cif
->flags
>> (FFI_FLAG_BITS
* 2)) == FFI_TYPE_STRUCT
)
784 rvalue
= (void *)(UINT32
)ar
[0];
790 arg_types
= cif
->arg_types
;
794 if (i
< 2 && !seen_int
&&
795 (arg_types
[i
]->type
== FFI_TYPE_FLOAT
||
796 arg_types
[i
]->type
== FFI_TYPE_DOUBLE
||
797 arg_types
[i
]->type
== FFI_TYPE_LONGDOUBLE
))
799 #if defined(__MIPSEB__) || defined(_MIPSEB)
800 if (arg_types
[i
]->type
== FFI_TYPE_FLOAT
)
801 avaluep
[i
] = ((char *) &fpr
[i
]) + sizeof (float);
804 avaluep
[i
] = (char *) &fpr
[i
];
808 if (arg_types
[i
]->alignment
== 8 && (argn
& 0x1))
810 switch (arg_types
[i
]->type
)
813 avaluep
[i
] = &avalue
[i
];
814 *(SINT8
*) &avalue
[i
] = (SINT8
) ar
[argn
];
818 avaluep
[i
] = &avalue
[i
];
819 *(UINT8
*) &avalue
[i
] = (UINT8
) ar
[argn
];
822 case FFI_TYPE_SINT16
:
823 avaluep
[i
] = &avalue
[i
];
824 *(SINT16
*) &avalue
[i
] = (SINT16
) ar
[argn
];
827 case FFI_TYPE_UINT16
:
828 avaluep
[i
] = &avalue
[i
];
829 *(UINT16
*) &avalue
[i
] = (UINT16
) ar
[argn
];
833 avaluep
[i
] = (char *) &ar
[argn
];
838 argn
+= ALIGN(arg_types
[i
]->size
, FFI_SIZEOF_ARG
) / FFI_SIZEOF_ARG
;
842 /* Invoke the closure. */
843 (closure
->fun
) (cif
, rvalue
, avaluep
, closure
->user_data
);
845 if (cif
->abi
== FFI_O32_SOFT_FLOAT
)
847 switch (cif
->rtype
->type
)
851 case FFI_TYPE_DOUBLE
:
852 return FFI_TYPE_UINT64
;
854 return cif
->rtype
->type
;
859 return cif
->rtype
->type
;
863 #if defined(FFI_MIPS_N32)
866 copy_struct_N32(char *target
, unsigned offset
, ffi_abi abi
, ffi_type
*type
,
867 int argn
, unsigned arg_offset
, ffi_arg
*ar
,
868 ffi_arg
*fpr
, int soft_float
)
870 ffi_type
**elt_typep
= type
->elements
;
873 ffi_type
*elt_type
= *elt_typep
;
879 o
= ALIGN(offset
, elt_type
->alignment
);
880 arg_offset
+= o
- offset
;
882 argn
+= arg_offset
/ sizeof(ffi_arg
);
883 arg_offset
= arg_offset
% sizeof(ffi_arg
);
885 argp
= (char *)(ar
+ argn
);
886 fpp
= (char *)(argn
>= 8 ? ar
+ argn
: fpr
+ argn
);
888 tp
= target
+ offset
;
890 if (elt_type
->type
== FFI_TYPE_DOUBLE
&& !soft_float
)
891 *(double *)tp
= *(double *)fpp
;
893 memcpy(tp
, argp
+ arg_offset
, elt_type
->size
);
895 offset
+= elt_type
->size
;
896 arg_offset
+= elt_type
->size
;
898 argn
+= arg_offset
/ sizeof(ffi_arg
);
899 arg_offset
= arg_offset
% sizeof(ffi_arg
);
904 * Decodes the arguments to a function, which will be stored on the
905 * stack. AR is the pointer to the beginning of the integer
906 * arguments. FPR is a pointer to the area where floating point
907 * registers have been saved.
909 * RVALUE is the location where the function return value will be
910 * stored. CLOSURE is the prepared closure to invoke.
912 * This function should only be called from assembly, which is in
913 * turn called from a trampoline.
915 * Returns the function return flags.
919 ffi_closure_mips_inner_N32 (ffi_closure
*closure
,
920 void *rvalue
, ffi_arg
*ar
,
926 ffi_type
**arg_types
;
932 soft_float
= cif
->abi
== FFI_N64_SOFT_FLOAT
933 || cif
->abi
== FFI_N32_SOFT_FLOAT
;
934 avalue
= alloca (cif
->nargs
* sizeof (ffi_arg
));
935 avaluep
= alloca (cif
->nargs
* sizeof (ffi_arg
));
939 if (cif
->rstruct_flag
)
941 #if _MIPS_SIM==_ABIN32
942 rvalue
= (void *)(UINT32
)ar
[0];
944 rvalue
= (void *)ar
[0];
951 arg_types
= cif
->arg_types
;
955 if (arg_types
[i
]->type
== FFI_TYPE_FLOAT
956 || arg_types
[i
]->type
== FFI_TYPE_DOUBLE
957 || arg_types
[i
]->type
== FFI_TYPE_LONGDOUBLE
)
959 argp
= (argn
>= 8 || soft_float
) ? ar
+ argn
: fpr
+ argn
;
960 if ((arg_types
[i
]->type
== FFI_TYPE_LONGDOUBLE
) && ((unsigned)argp
& (arg_types
[i
]->alignment
-1)))
962 argp
=(ffi_arg
*)ALIGN(argp
,arg_types
[i
]->alignment
);
965 #if defined(__MIPSEB__) || defined(_MIPSEB)
966 if (arg_types
[i
]->type
== FFI_TYPE_FLOAT
&& argn
< 8)
967 avaluep
[i
] = ((char *) argp
) + sizeof (float);
970 avaluep
[i
] = (char *) argp
;
974 unsigned type
= arg_types
[i
]->type
;
976 if (arg_types
[i
]->alignment
> sizeof(ffi_arg
))
977 argn
= ALIGN(argn
, arg_types
[i
]->alignment
/ sizeof(ffi_arg
));
981 /* The size of a pointer depends on the ABI */
982 if (type
== FFI_TYPE_POINTER
)
983 type
= (cif
->abi
== FFI_N64
|| cif
->abi
== FFI_N64_SOFT_FLOAT
)
984 ? FFI_TYPE_SINT64
: FFI_TYPE_SINT32
;
986 if (soft_float
&& type
== FFI_TYPE_FLOAT
)
987 type
= FFI_TYPE_UINT32
;
992 avaluep
[i
] = &avalue
[i
];
993 *(SINT8
*) &avalue
[i
] = (SINT8
) *argp
;
997 avaluep
[i
] = &avalue
[i
];
998 *(UINT8
*) &avalue
[i
] = (UINT8
) *argp
;
1001 case FFI_TYPE_SINT16
:
1002 avaluep
[i
] = &avalue
[i
];
1003 *(SINT16
*) &avalue
[i
] = (SINT16
) *argp
;
1006 case FFI_TYPE_UINT16
:
1007 avaluep
[i
] = &avalue
[i
];
1008 *(UINT16
*) &avalue
[i
] = (UINT16
) *argp
;
1011 case FFI_TYPE_SINT32
:
1012 avaluep
[i
] = &avalue
[i
];
1013 *(SINT32
*) &avalue
[i
] = (SINT32
) *argp
;
1016 case FFI_TYPE_UINT32
:
1017 avaluep
[i
] = &avalue
[i
];
1018 *(UINT32
*) &avalue
[i
] = (UINT32
) *argp
;
1021 case FFI_TYPE_STRUCT
:
1024 /* Allocate space for the struct as at least part of
1025 it was passed in registers. */
1026 avaluep
[i
] = alloca(arg_types
[i
]->size
);
1027 copy_struct_N32(avaluep
[i
], 0, cif
->abi
, arg_types
[i
],
1028 argn
, 0, ar
, fpr
, soft_float
);
1032 /* Else fall through. */
1034 avaluep
[i
] = (char *) argp
;
1038 argn
+= ALIGN(arg_types
[i
]->size
, sizeof(ffi_arg
)) / sizeof(ffi_arg
);
1042 /* Invoke the closure. */
1043 (closure
->fun
) (cif
, rvalue
, avaluep
, closure
->user_data
);
1045 return cif
->flags
>> (FFI_FLAG_BITS
* 8);
1048 #endif /* FFI_MIPS_N32 */
1050 #endif /* FFI_CLOSURES */