1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1996, 2007, 2008 Red Hat, Inc.
3 Copyright (c) 2008 David Daney
5 MIPS Foreign Function Interface
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 ``Software''), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 ----------------------------------------------------------------------- */
29 #include <ffi_common.h>
34 # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
35 # define USE__BUILTIN___CLEAR_CACHE 1
39 #ifndef USE__BUILTIN___CLEAR_CACHE
40 #include <sys/cachectl.h>
44 # define FFI_MIPS_STOP_HERE() ffi_stop_here()
46 # define FFI_MIPS_STOP_HERE() do {} while(0)
51 FFI_ASSERT(argp <= &stack[bytes]); \
52 if (argp == &stack[bytes]) \
55 FFI_MIPS_STOP_HERE(); \
62 /* ffi_prep_args is called by the assembly routine once stack space
63 has been allocated for the function's arguments */
65 static void ffi_prep_args(char *stack,
76 /* If more than 8 double words are used, the remainder go
77 on the stack. We reorder stuff on the stack here to
78 support this easily. */
79 if (bytes > 8 * sizeof(ffi_arg))
80 argp = &stack[bytes - (8 * sizeof(ffi_arg))];
87 memset(stack, 0, bytes);
90 if ( ecif->cif->rstruct_flag != 0 )
92 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
95 *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
96 argp += sizeof(ffi_arg);
100 p_argv = ecif->avalue;
102 for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++)
107 /* Align if necessary. */
108 a = (*p_arg)->alignment;
109 if (a < sizeof(ffi_arg))
112 if ((a - 1) & (unsigned long) argp)
114 argp = (char *) ALIGN(argp, a);
119 if (z <= sizeof(ffi_arg))
121 int type = (*p_arg)->type;
124 /* The size of a pointer depends on the ABI */
125 if (type == FFI_TYPE_POINTER)
126 type = (ecif->cif->abi == FFI_N64
127 || ecif->cif->abi == FFI_N64_SOFT_FLOAT)
128 ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
130 if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT
131 || ecif->cif->abi == FFI_N64_SOFT_FLOAT))
136 type = FFI_TYPE_UINT32;
138 case FFI_TYPE_DOUBLE:
139 type = FFI_TYPE_UINT64;
148 *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
152 *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
155 case FFI_TYPE_SINT16:
156 *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
159 case FFI_TYPE_UINT16:
160 *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
163 case FFI_TYPE_SINT32:
164 *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
167 case FFI_TYPE_UINT32:
168 *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
171 /* This can only happen with 64bit slots. */
173 *(float *) argp = *(float *)(* p_argv);
176 /* Handle structures. */
178 memcpy(argp, *p_argv, (*p_arg)->size);
185 memcpy(argp, *p_argv, z);
188 unsigned long end = (unsigned long) argp + z;
189 unsigned long cap = (unsigned long) stack + bytes;
191 /* Check if the data will fit within the register space.
192 Handle it if it doesn't. */
195 memcpy(argp, *p_argv, z);
198 unsigned long portion = cap - (unsigned long)argp;
200 memcpy(argp, *p_argv, portion);
203 memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),
217 /* The n32 spec says that if "a chunk consists solely of a double
218 float field (but not a double, which is part of a union), it
219 is passed in a floating point register. Any other chunk is
220 passed in an integer register". This code traverses structure
221 definitions and generates the appropriate flags. */
224 calc_n32_struct_flags(int soft_float, ffi_type *arg,
225 unsigned *loc, unsigned *arg_reg)
235 while ((e = arg->elements[index]))
237 /* Align this object. */
238 *loc = ALIGN(*loc, e->alignment);
239 if (e->type == FFI_TYPE_DOUBLE)
241 /* Already aligned to FFI_SIZEOF_ARG. */
242 *arg_reg = *loc / FFI_SIZEOF_ARG;
245 flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));
252 /* Next Argument register at alignment of FFI_SIZEOF_ARG. */
253 *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
259 calc_n32_return_struct_flags(int soft_float, ffi_type *arg)
262 unsigned small = FFI_TYPE_SMALLSTRUCT;
265 /* Returning structures under n32 is a tricky thing.
266 A struct with only one or two floating point fields
267 is returned in $f0 (and $f2 if necessary). Any other
268 struct results at most 128 bits are returned in $2
269 (the first 64 bits) and $3 (remainder, if necessary).
270 Larger structs are handled normally. */
276 small = FFI_TYPE_SMALLSTRUCT2;
278 e = arg->elements[0];
280 if (e->type == FFI_TYPE_DOUBLE)
281 flags = FFI_TYPE_DOUBLE;
282 else if (e->type == FFI_TYPE_FLOAT)
283 flags = FFI_TYPE_FLOAT;
285 if (flags && (e = arg->elements[1]))
287 if (e->type == FFI_TYPE_DOUBLE)
288 flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
289 else if (e->type == FFI_TYPE_FLOAT)
290 flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS;
294 if (flags && (arg->elements[2]))
296 /* There are three arguments and the first two are
297 floats! This must be passed the old way. */
301 flags += FFI_TYPE_STRUCT_SOFT;
312 /* Perform machine dependent cif processing */
313 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
318 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
319 * does not have special handling for floating point args.
322 if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
326 switch ((cif->arg_types)[0]->type)
329 case FFI_TYPE_DOUBLE:
330 cif->flags += (cif->arg_types)[0]->type;
339 /* Only handle the second argument if the first
340 is a float or double. */
343 switch ((cif->arg_types)[1]->type)
346 case FFI_TYPE_DOUBLE:
347 cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
358 /* Set the return type flag */
360 if (cif->abi == FFI_O32_SOFT_FLOAT)
362 switch (cif->rtype->type)
365 case FFI_TYPE_STRUCT:
366 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
369 case FFI_TYPE_SINT64:
370 case FFI_TYPE_UINT64:
371 case FFI_TYPE_DOUBLE:
372 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
377 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
384 switch (cif->rtype->type)
387 case FFI_TYPE_STRUCT:
389 case FFI_TYPE_DOUBLE:
390 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
393 case FFI_TYPE_SINT64:
394 case FFI_TYPE_UINT64:
395 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
399 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
406 /* Set the flags necessary for N32 processing */
409 unsigned arg_reg = 0;
411 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
414 unsigned struct_flags = 0;
415 int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT
416 || cif->abi == FFI_N64_SOFT_FLOAT);
418 if (cif->rtype->type == FFI_TYPE_STRUCT)
420 struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
422 if (struct_flags == 0)
424 /* This means that the structure is being passed as
428 count = (cif->nargs < 7) ? cif->nargs : 7;
430 cif->rstruct_flag = !0;
433 cif->rstruct_flag = 0;
436 cif->rstruct_flag = 0;
438 while (count-- > 0 && arg_reg < 8)
440 type = (cif->arg_types)[index]->type;
446 type = FFI_TYPE_UINT32;
448 case FFI_TYPE_DOUBLE:
449 type = FFI_TYPE_UINT64;
458 case FFI_TYPE_DOUBLE:
460 ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS));
463 case FFI_TYPE_LONGDOUBLE:
465 arg_reg = ALIGN(arg_reg, 2);
466 /* Treat it as two adjacent doubles. */
474 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
477 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
482 case FFI_TYPE_STRUCT:
483 loc = arg_reg * FFI_SIZEOF_ARG;
484 cif->flags += calc_n32_struct_flags(soft_float,
485 (cif->arg_types)[index],
497 /* Set the return type flag */
498 switch (cif->rtype->type)
500 case FFI_TYPE_STRUCT:
502 if (struct_flags == 0)
504 /* The structure is returned through a hidden
505 first argument. Do nothing, 'cause FFI_TYPE_VOID
510 /* The structure is returned via some tricky
512 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
513 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
519 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
522 case FFI_TYPE_POINTER:
523 if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32)
524 cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
526 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
532 cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
535 /* else fall through */
536 case FFI_TYPE_DOUBLE:
538 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
540 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
543 case FFI_TYPE_LONGDOUBLE:
544 /* Long double is returned as if it were a struct containing
548 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
549 cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8));
553 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
554 cif->flags += (FFI_TYPE_DOUBLE
555 + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
556 << (4 + (FFI_FLAG_BITS * 8));
560 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
569 /* Low level routine for calling O32 functions */
570 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
571 extended_cif *, unsigned,
572 unsigned, unsigned *, void (*)(void));
574 /* Low level routine for calling N32 functions */
575 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
576 extended_cif *, unsigned,
577 unsigned, void *, void (*)(void));
579 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
584 ecif.avalue = avalue;
586 /* If the return value is a struct and we don't have a return */
587 /* value address then we need to make one */
589 if ((rvalue == NULL) &&
590 (cif->rtype->type == FFI_TYPE_STRUCT))
591 ecif.rvalue = alloca(cif->rtype->size);
593 ecif.rvalue = rvalue;
599 case FFI_O32_SOFT_FLOAT:
600 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
601 cif->flags, ecif.rvalue, fn);
607 case FFI_N32_SOFT_FLOAT:
609 case FFI_N64_SOFT_FLOAT:
613 char *rvalue_copy = ecif.rvalue;
614 if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
616 /* For structures smaller than 16 bytes we clobber memory
617 in 8 byte increments. Make a copy so we don't clobber
618 the callers memory outside of the struct bounds. */
619 rvalue_copy = alloca(16);
622 else if (cif->rtype->type == FFI_TYPE_FLOAT
623 && (cif->abi == FFI_N64_SOFT_FLOAT
624 || cif->abi == FFI_N32_SOFT_FLOAT))
626 rvalue_copy = alloca (8);
628 #if defined(__MIPSEB__) || defined(_MIPSEB)
632 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
633 cif->flags, rvalue_copy, fn);
635 memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
647 #if defined(FFI_MIPS_O32)
648 extern void ffi_closure_O32(void);
650 extern void ffi_closure_N32(void);
651 #endif /* FFI_MIPS_O32 */
654 ffi_prep_closure_loc (ffi_closure *closure,
656 void (*fun)(ffi_cif*,void*,void**,void*),
660 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
662 char *clear_location = (char *) codeloc;
664 #if defined(FFI_MIPS_O32)
665 FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
666 fn = ffi_closure_O32;
667 #else /* FFI_MIPS_N32 */
668 FFI_ASSERT(cif->abi == FFI_N32 || cif->abi == FFI_N64);
669 fn = ffi_closure_N32;
670 #endif /* FFI_MIPS_O32 */
672 #if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
673 /* lui $25,high(fn) */
674 tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
675 /* ori $25,low(fn) */
676 tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
677 /* lui $12,high(codeloc) */
678 tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
680 tramp[3] = 0x03200008;
681 /* ori $12,low(codeloc) */
682 tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
684 /* N64 has a somewhat larger trampoline. */
685 /* lui $25,high(fn) */
686 tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);
687 /* lui $12,high(codeloc) */
688 tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);
689 /* ori $25,mid-high(fn) */
690 tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);
691 /* ori $12,mid-high(codeloc) */
692 tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);
693 /* dsll $25,$25,16 */
694 tramp[4] = 0x0019cc38;
695 /* dsll $12,$12,16 */
696 tramp[5] = 0x000c6438;
697 /* ori $25,mid-low(fn) */
698 tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);
699 /* ori $12,mid-low(codeloc) */
700 tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);
701 /* dsll $25,$25,16 */
702 tramp[8] = 0x0019cc38;
703 /* dsll $12,$12,16 */
704 tramp[9] = 0x000c6438;
705 /* ori $25,low(fn) */
706 tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff);
708 tramp[11] = 0x03200008;
709 /* ori $12,low(codeloc) */
710 tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
716 closure->user_data = user_data;
718 #ifdef USE__BUILTIN___CLEAR_CACHE
719 __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
721 cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE);
727 * Decodes the arguments to a function, which will be stored on the
728 * stack. AR is the pointer to the beginning of the integer arguments
729 * (and, depending upon the arguments, some floating-point arguments
730 * as well). FPR is a pointer to the area where floating point
731 * registers have been saved, if any.
733 * RVALUE is the location where the function return value will be
734 * stored. CLOSURE is the prepared closure to invoke.
736 * This function should only be called from assembly, which is in
737 * turn called from a trampoline.
739 * Returns the function return type.
741 * Based on the similar routine for sparc.
744 ffi_closure_mips_inner_O32 (ffi_closure *closure,
745 void *rvalue, ffi_arg *ar,
751 ffi_type **arg_types;
752 int i, avn, argn, seen_int;
755 avalue = alloca (cif->nargs * sizeof (ffi_arg));
756 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
758 seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
761 if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
763 rvalue = (void *)(UINT32)ar[0];
769 arg_types = cif->arg_types;
773 if (i < 2 && !seen_int &&
774 (arg_types[i]->type == FFI_TYPE_FLOAT ||
775 arg_types[i]->type == FFI_TYPE_DOUBLE ||
776 arg_types[i]->type == FFI_TYPE_LONGDOUBLE))
778 #if defined(__MIPSEB__) || defined(_MIPSEB)
779 if (arg_types[i]->type == FFI_TYPE_FLOAT)
780 avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
783 avaluep[i] = (char *) &fpr[i];
787 if (arg_types[i]->alignment == 8 && (argn & 0x1))
789 switch (arg_types[i]->type)
792 avaluep[i] = &avalue[i];
793 *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
797 avaluep[i] = &avalue[i];
798 *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
801 case FFI_TYPE_SINT16:
802 avaluep[i] = &avalue[i];
803 *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
806 case FFI_TYPE_UINT16:
807 avaluep[i] = &avalue[i];
808 *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
812 avaluep[i] = (char *) &ar[argn];
817 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
821 /* Invoke the closure. */
822 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
824 if (cif->abi == FFI_O32_SOFT_FLOAT)
826 switch (cif->rtype->type)
830 case FFI_TYPE_DOUBLE:
831 return FFI_TYPE_UINT64;
833 return cif->rtype->type;
838 return cif->rtype->type;
842 #if defined(FFI_MIPS_N32)
845 copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
846 int argn, unsigned arg_offset, ffi_arg *ar,
847 ffi_arg *fpr, int soft_float)
849 ffi_type **elt_typep = type->elements;
852 ffi_type *elt_type = *elt_typep;
858 o = ALIGN(offset, elt_type->alignment);
859 arg_offset += o - offset;
861 argn += arg_offset / sizeof(ffi_arg);
862 arg_offset = arg_offset % sizeof(ffi_arg);
864 argp = (char *)(ar + argn);
865 fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
867 tp = target + offset;
869 if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
870 *(double *)tp = *(double *)fpp;
872 memcpy(tp, argp + arg_offset, elt_type->size);
874 offset += elt_type->size;
875 arg_offset += elt_type->size;
877 argn += arg_offset / sizeof(ffi_arg);
878 arg_offset = arg_offset % sizeof(ffi_arg);
883 * Decodes the arguments to a function, which will be stored on the
884 * stack. AR is the pointer to the beginning of the integer
885 * arguments. FPR is a pointer to the area where floating point
886 * registers have been saved.
888 * RVALUE is the location where the function return value will be
889 * stored. CLOSURE is the prepared closure to invoke.
891 * This function should only be called from assembly, which is in
892 * turn called from a trampoline.
894 * Returns the function return flags.
898 ffi_closure_mips_inner_N32 (ffi_closure *closure,
899 void *rvalue, ffi_arg *ar,
905 ffi_type **arg_types;
911 soft_float = cif->abi == FFI_N64_SOFT_FLOAT
912 || cif->abi == FFI_N32_SOFT_FLOAT;
913 avalue = alloca (cif->nargs * sizeof (ffi_arg));
914 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
918 if (cif->rstruct_flag)
920 #if _MIPS_SIM==_ABIN32
921 rvalue = (void *)(UINT32)ar[0];
923 rvalue = (void *)ar[0];
930 arg_types = cif->arg_types;
934 if (arg_types[i]->type == FFI_TYPE_FLOAT
935 || arg_types[i]->type == FFI_TYPE_DOUBLE
936 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE)
938 argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
939 if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1)))
941 argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment);
944 #if defined(__MIPSEB__) || defined(_MIPSEB)
945 if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
946 avaluep[i] = ((char *) argp) + sizeof (float);
949 avaluep[i] = (char *) argp;
953 unsigned type = arg_types[i]->type;
955 if (arg_types[i]->alignment > sizeof(ffi_arg))
956 argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
960 /* The size of a pointer depends on the ABI */
961 if (type == FFI_TYPE_POINTER)
962 type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT)
963 ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
965 if (soft_float && type == FFI_TYPE_FLOAT)
966 type = FFI_TYPE_UINT32;
971 avaluep[i] = &avalue[i];
972 *(SINT8 *) &avalue[i] = (SINT8) *argp;
976 avaluep[i] = &avalue[i];
977 *(UINT8 *) &avalue[i] = (UINT8) *argp;
980 case FFI_TYPE_SINT16:
981 avaluep[i] = &avalue[i];
982 *(SINT16 *) &avalue[i] = (SINT16) *argp;
985 case FFI_TYPE_UINT16:
986 avaluep[i] = &avalue[i];
987 *(UINT16 *) &avalue[i] = (UINT16) *argp;
990 case FFI_TYPE_SINT32:
991 avaluep[i] = &avalue[i];
992 *(SINT32 *) &avalue[i] = (SINT32) *argp;
995 case FFI_TYPE_UINT32:
996 avaluep[i] = &avalue[i];
997 *(UINT32 *) &avalue[i] = (UINT32) *argp;
1000 case FFI_TYPE_STRUCT:
1003 /* Allocate space for the struct as at least part of
1004 it was passed in registers. */
1005 avaluep[i] = alloca(arg_types[i]->size);
1006 copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
1007 argn, 0, ar, fpr, soft_float);
1011 /* Else fall through. */
1013 avaluep[i] = (char *) argp;
1017 argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
1021 /* Invoke the closure. */
1022 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
1024 return cif->flags >> (FFI_FLAG_BITS * 8);
1027 #endif /* FFI_MIPS_N32 */
1029 #endif /* FFI_CLOSURES */