2009-06-04 Andrew Haley <aph@redhat.com>
[official-gcc.git] / libffi / src / mips / ffi.c
blobf21182b222353d3903cd72fffc09f534deec02fc
1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1996, 2007 Red Hat, Inc.
4 MIPS 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,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 DEALINGS IN THE SOFTWARE.
25 ----------------------------------------------------------------------- */
27 #include <ffi.h>
28 #include <ffi_common.h>
30 #include <stdlib.h>
32 #ifdef FFI_DEBUG
33 # define FFI_MIPS_STOP_HERE() ffi_stop_here()
34 #else
35 # define FFI_MIPS_STOP_HERE() do {} while(0)
36 #endif
38 #ifdef FFI_MIPS_N32
39 #define FIX_ARGP \
40 FFI_ASSERT(argp <= &stack[bytes]); \
41 if (argp == &stack[bytes]) \
42 { \
43 argp = stack; \
44 FFI_MIPS_STOP_HERE(); \
46 #else
47 #define FIX_ARGP
48 #endif
51 /* ffi_prep_args is called by the assembly routine once stack space
52 has been allocated for the function's arguments */
54 static void ffi_prep_args(char *stack,
55 extended_cif *ecif,
56 int bytes,
57 int flags)
59 int i;
60 void **p_argv;
61 char *argp;
62 ffi_type **p_arg;
64 #ifdef FFI_MIPS_N32
65 /* If more than 8 double words are used, the remainder go
66 on the stack. We reorder stuff on the stack here to
67 support this easily. */
68 if (bytes > 8 * sizeof(ffi_arg))
69 argp = &stack[bytes - (8 * sizeof(ffi_arg))];
70 else
71 argp = stack;
72 #else
73 argp = stack;
74 #endif
76 memset(stack, 0, bytes);
78 #ifdef FFI_MIPS_N32
79 if ( ecif->cif->rstruct_flag != 0 )
80 #else
81 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
82 #endif
84 *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
85 argp += sizeof(ffi_arg);
86 FIX_ARGP;
89 p_argv = ecif->avalue;
91 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
93 size_t z;
94 unsigned int a;
96 /* Align if necessary. */
97 a = (*p_arg)->alignment;
98 if (a < sizeof(ffi_arg))
99 a = sizeof(ffi_arg);
101 if ((a - 1) & (unsigned long) argp)
103 argp = (char *) ALIGN(argp, a);
104 FIX_ARGP;
107 z = (*p_arg)->size;
108 if (z <= sizeof(ffi_arg))
110 int type = (*p_arg)->type;
111 z = sizeof(ffi_arg);
113 /* The size of a pointer depends on the ABI */
114 if (type == FFI_TYPE_POINTER)
115 type =
116 (ecif->cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
118 switch (type)
120 case FFI_TYPE_SINT8:
121 *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
122 break;
124 case FFI_TYPE_UINT8:
125 *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
126 break;
128 case FFI_TYPE_SINT16:
129 *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
130 break;
132 case FFI_TYPE_UINT16:
133 *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
134 break;
136 case FFI_TYPE_SINT32:
137 *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
138 break;
140 case FFI_TYPE_UINT32:
141 *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
142 break;
144 /* This can only happen with 64bit slots. */
145 case FFI_TYPE_FLOAT:
146 *(float *) argp = *(float *)(* p_argv);
147 break;
149 /* Handle structures. */
150 default:
151 memcpy(argp, *p_argv, (*p_arg)->size);
152 break;
155 else
157 #ifdef FFI_MIPS_O32
158 memcpy(argp, *p_argv, z);
159 #else
161 unsigned long end = (unsigned long) argp + z;
162 unsigned long cap = (unsigned long) stack + bytes;
164 /* Check if the data will fit within the register space.
165 Handle it if it doesn't. */
167 if (end <= cap)
168 memcpy(argp, *p_argv, z);
169 else
171 unsigned long portion = cap - (unsigned long)argp;
173 memcpy(argp, *p_argv, portion);
174 argp = stack;
175 z -= portion;
176 memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),
180 #endif
182 p_argv++;
183 argp += z;
184 FIX_ARGP;
188 #ifdef FFI_MIPS_N32
190 /* The n32 spec says that if "a chunk consists solely of a double
191 float field (but not a double, which is part of a union), it
192 is passed in a floating point register. Any other chunk is
193 passed in an integer register". This code traverses structure
194 definitions and generates the appropriate flags. */
196 static unsigned
197 calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg)
199 unsigned flags = 0;
200 unsigned index = 0;
202 ffi_type *e;
204 while ((e = arg->elements[index]))
206 /* Align this object. */
207 *loc = ALIGN(*loc, e->alignment);
208 if (e->type == FFI_TYPE_DOUBLE)
210 /* Already aligned to FFI_SIZEOF_ARG. */
211 *arg_reg = *loc / FFI_SIZEOF_ARG;
212 if (*arg_reg > 7)
213 break;
214 flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));
215 *loc += e->size;
217 else
218 *loc += e->size;
219 index++;
221 /* Next Argument register at alignment of FFI_SIZEOF_ARG. */
222 *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
224 return flags;
227 static unsigned
228 calc_n32_return_struct_flags(ffi_type *arg)
230 unsigned flags = 0;
231 unsigned small = FFI_TYPE_SMALLSTRUCT;
232 ffi_type *e;
234 /* Returning structures under n32 is a tricky thing.
235 A struct with only one or two floating point fields
236 is returned in $f0 (and $f2 if necessary). Any other
237 struct results at most 128 bits are returned in $2
238 (the first 64 bits) and $3 (remainder, if necessary).
239 Larger structs are handled normally. */
241 if (arg->size > 16)
242 return 0;
244 if (arg->size > 8)
245 small = FFI_TYPE_SMALLSTRUCT2;
247 e = arg->elements[0];
248 if (e->type == FFI_TYPE_DOUBLE)
249 flags = FFI_TYPE_DOUBLE;
250 else if (e->type == FFI_TYPE_FLOAT)
251 flags = FFI_TYPE_FLOAT;
253 if (flags && (e = arg->elements[1]))
255 if (e->type == FFI_TYPE_DOUBLE)
256 flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
257 else if (e->type == FFI_TYPE_FLOAT)
258 flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS;
259 else
260 return small;
262 if (flags && (arg->elements[2]))
264 /* There are three arguments and the first two are
265 floats! This must be passed the old way. */
266 return small;
269 else
270 if (!flags)
271 return small;
273 return flags;
276 #endif
278 /* Perform machine dependent cif processing */
279 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
281 cif->flags = 0;
283 #ifdef FFI_MIPS_O32
284 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
285 * does not have special handling for floating point args.
288 if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
290 if (cif->nargs > 0)
292 switch ((cif->arg_types)[0]->type)
294 case FFI_TYPE_FLOAT:
295 case FFI_TYPE_DOUBLE:
296 cif->flags += (cif->arg_types)[0]->type;
297 break;
299 default:
300 break;
303 if (cif->nargs > 1)
305 /* Only handle the second argument if the first
306 is a float or double. */
307 if (cif->flags)
309 switch ((cif->arg_types)[1]->type)
311 case FFI_TYPE_FLOAT:
312 case FFI_TYPE_DOUBLE:
313 cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
314 break;
316 default:
317 break;
324 /* Set the return type flag */
326 if (cif->abi == FFI_O32_SOFT_FLOAT)
328 switch (cif->rtype->type)
330 case FFI_TYPE_VOID:
331 case FFI_TYPE_STRUCT:
332 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
333 break;
335 case FFI_TYPE_SINT64:
336 case FFI_TYPE_UINT64:
337 case FFI_TYPE_DOUBLE:
338 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
339 break;
341 case FFI_TYPE_FLOAT:
342 default:
343 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
344 break;
347 else
349 /* FFI_O32 */
350 switch (cif->rtype->type)
352 case FFI_TYPE_VOID:
353 case FFI_TYPE_STRUCT:
354 case FFI_TYPE_FLOAT:
355 case FFI_TYPE_DOUBLE:
356 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
357 break;
359 case FFI_TYPE_SINT64:
360 case FFI_TYPE_UINT64:
361 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
362 break;
364 default:
365 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
366 break;
369 #endif
371 #ifdef FFI_MIPS_N32
372 /* Set the flags necessary for N32 processing */
374 unsigned arg_reg = 0;
375 unsigned loc = 0;
376 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
377 unsigned index = 0;
379 unsigned struct_flags = 0;
381 if (cif->rtype->type == FFI_TYPE_STRUCT)
383 struct_flags = calc_n32_return_struct_flags(cif->rtype);
385 if (struct_flags == 0)
387 /* This means that the structure is being passed as
388 a hidden argument */
390 arg_reg = 1;
391 count = (cif->nargs < 7) ? cif->nargs : 7;
393 cif->rstruct_flag = !0;
395 else
396 cif->rstruct_flag = 0;
398 else
399 cif->rstruct_flag = 0;
401 while (count-- > 0 && arg_reg < 8)
403 switch ((cif->arg_types)[index]->type)
405 case FFI_TYPE_FLOAT:
406 case FFI_TYPE_DOUBLE:
407 cif->flags +=
408 ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS));
409 arg_reg++;
410 break;
411 case FFI_TYPE_LONGDOUBLE:
412 /* Align it. */
413 arg_reg = ALIGN(arg_reg, 2);
414 /* Treat it as two adjacent doubles. */
415 cif->flags +=
416 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
417 arg_reg++;
418 cif->flags +=
419 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
420 arg_reg++;
421 break;
423 case FFI_TYPE_STRUCT:
424 loc = arg_reg * FFI_SIZEOF_ARG;
425 cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
426 &loc, &arg_reg);
427 break;
429 default:
430 arg_reg++;
431 break;
434 index++;
437 /* Set the return type flag */
438 switch (cif->rtype->type)
440 case FFI_TYPE_STRUCT:
442 if (struct_flags == 0)
444 /* The structure is returned through a hidden
445 first argument. Do nothing, 'cause FFI_TYPE_VOID
446 is 0 */
448 else
450 /* The structure is returned via some tricky
451 mechanism */
452 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
453 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
455 break;
458 case FFI_TYPE_VOID:
459 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
460 break;
462 case FFI_TYPE_FLOAT:
463 case FFI_TYPE_DOUBLE:
464 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
465 break;
466 case FFI_TYPE_LONGDOUBLE:
467 /* Long double is returned as if it were a struct containing
468 two doubles. */
469 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
470 cif->flags += (FFI_TYPE_DOUBLE + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
471 << (4 + (FFI_FLAG_BITS * 8));
472 break;
473 default:
474 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
475 break;
478 #endif
480 return FFI_OK;
483 /* Low level routine for calling O32 functions */
484 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
485 extended_cif *, unsigned,
486 unsigned, unsigned *, void (*)());
488 /* Low level routine for calling N32 functions */
489 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
490 extended_cif *, unsigned,
491 unsigned, unsigned *, void (*)());
493 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
495 extended_cif ecif;
497 ecif.cif = cif;
498 ecif.avalue = avalue;
500 /* If the return value is a struct and we don't have a return */
501 /* value address then we need to make one */
503 if ((rvalue == NULL) &&
504 (cif->rtype->type == FFI_TYPE_STRUCT))
505 ecif.rvalue = alloca(cif->rtype->size);
506 else
507 ecif.rvalue = rvalue;
509 switch (cif->abi)
511 #ifdef FFI_MIPS_O32
512 case FFI_O32:
513 case FFI_O32_SOFT_FLOAT:
514 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
515 cif->flags, ecif.rvalue, fn);
516 break;
517 #endif
519 #ifdef FFI_MIPS_N32
520 case FFI_N32:
521 case FFI_N64:
523 int copy_rvalue = 0;
524 void *rvalue_copy = ecif.rvalue;
525 if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
527 /* For structures smaller than 16 bytes we clobber memory
528 in 8 byte increments. Make a copy so we don't clobber
529 the callers memory outside of the struct bounds. */
530 rvalue_copy = alloca(16);
531 copy_rvalue = 1;
533 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
534 cif->flags, rvalue_copy, fn);
535 if (copy_rvalue)
536 memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size);
538 break;
539 #endif
541 default:
542 FFI_ASSERT(0);
543 break;
547 #if FFI_CLOSURES
548 #if defined(FFI_MIPS_O32)
549 extern void ffi_closure_O32(void);
550 #else
551 extern void ffi_closure_N32(void);
552 #endif /* FFI_MIPS_O32 */
554 ffi_status
555 ffi_prep_closure_loc (ffi_closure *closure,
556 ffi_cif *cif,
557 void (*fun)(ffi_cif*,void*,void**,void*),
558 void *user_data,
559 void *codeloc)
561 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
562 void * fn;
563 char *clear_location = (char *) codeloc;
565 #if defined(FFI_MIPS_O32)
566 FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
567 fn = ffi_closure_O32;
568 #else /* FFI_MIPS_N32 */
569 FFI_ASSERT(cif->abi == FFI_N32 || cif->abi == FFI_N64);
570 fn = ffi_closure_N32;
571 #endif /* FFI_MIPS_O32 */
573 #if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
574 /* lui $25,high(fn) */
575 tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
576 /* ori $25,low(fn) */
577 tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
578 /* lui $12,high(codeloc) */
579 tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
580 /* jr $25 */
581 tramp[3] = 0x03200008;
582 /* ori $12,low(codeloc) */
583 tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
584 #else
585 /* N64 has a somewhat larger trampoline. */
586 /* lui $25,high(fn) */
587 tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);
588 /* lui $12,high(codeloc) */
589 tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);
590 /* ori $25,mid-high(fn) */
591 tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);
592 /* ori $12,mid-high(codeloc) */
593 tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);
594 /* dsll $25,$25,16 */
595 tramp[4] = 0x0019cc38;
596 /* dsll $12,$12,16 */
597 tramp[5] = 0x000c6438;
598 /* ori $25,mid-low(fn) */
599 tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);
600 /* ori $12,mid-low(codeloc) */
601 tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);
602 /* dsll $25,$25,16 */
603 tramp[8] = 0x0019cc38;
604 /* dsll $12,$12,16 */
605 tramp[9] = 0x000c6438;
606 /* ori $25,low(fn) */
607 tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff);
608 /* jr $25 */
609 tramp[11] = 0x03200008;
610 /* ori $12,low(codeloc) */
611 tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
613 #endif
615 closure->cif = cif;
616 closure->fun = fun;
617 closure->user_data = user_data;
619 __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
621 return FFI_OK;
625 * Decodes the arguments to a function, which will be stored on the
626 * stack. AR is the pointer to the beginning of the integer arguments
627 * (and, depending upon the arguments, some floating-point arguments
628 * as well). FPR is a pointer to the area where floating point
629 * registers have been saved, if any.
631 * RVALUE is the location where the function return value will be
632 * stored. CLOSURE is the prepared closure to invoke.
634 * This function should only be called from assembly, which is in
635 * turn called from a trampoline.
637 * Returns the function return type.
639 * Based on the similar routine for sparc.
642 ffi_closure_mips_inner_O32 (ffi_closure *closure,
643 void *rvalue, ffi_arg *ar,
644 double *fpr)
646 ffi_cif *cif;
647 void **avaluep;
648 ffi_arg *avalue;
649 ffi_type **arg_types;
650 int i, avn, argn, seen_int;
652 cif = closure->cif;
653 avalue = alloca (cif->nargs * sizeof (ffi_arg));
654 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
656 seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
657 argn = 0;
659 if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
661 rvalue = (void *)(UINT32)ar[0];
662 argn = 1;
665 i = 0;
666 avn = cif->nargs;
667 arg_types = cif->arg_types;
669 while (i < avn)
671 if (i < 2 && !seen_int &&
672 (arg_types[i]->type == FFI_TYPE_FLOAT ||
673 arg_types[i]->type == FFI_TYPE_DOUBLE))
675 #ifdef __MIPSEB__
676 if (arg_types[i]->type == FFI_TYPE_FLOAT)
677 avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
678 else
679 #endif
680 avaluep[i] = (char *) &fpr[i];
682 else
684 if (arg_types[i]->alignment == 8 && (argn & 0x1))
685 argn++;
686 switch (arg_types[i]->type)
688 case FFI_TYPE_SINT8:
689 avaluep[i] = &avalue[i];
690 *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
691 break;
693 case FFI_TYPE_UINT8:
694 avaluep[i] = &avalue[i];
695 *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
696 break;
698 case FFI_TYPE_SINT16:
699 avaluep[i] = &avalue[i];
700 *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
701 break;
703 case FFI_TYPE_UINT16:
704 avaluep[i] = &avalue[i];
705 *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
706 break;
708 default:
709 avaluep[i] = (char *) &ar[argn];
710 break;
712 seen_int = 1;
714 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
715 i++;
718 /* Invoke the closure. */
719 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
721 if (cif->abi == FFI_O32_SOFT_FLOAT)
723 switch (cif->rtype->type)
725 case FFI_TYPE_FLOAT:
726 return FFI_TYPE_INT;
727 case FFI_TYPE_DOUBLE:
728 return FFI_TYPE_UINT64;
729 default:
730 return cif->rtype->type;
733 else
735 return cif->rtype->type;
739 #if defined(FFI_MIPS_N32)
741 static void
742 copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
743 int argn, unsigned arg_offset, ffi_arg *ar,
744 ffi_arg *fpr)
746 ffi_type **elt_typep = type->elements;
747 while(*elt_typep)
749 ffi_type *elt_type = *elt_typep;
750 unsigned o;
751 char *tp;
752 char *argp;
753 char *fpp;
755 o = ALIGN(offset, elt_type->alignment);
756 arg_offset += o - offset;
757 offset = o;
758 argn += arg_offset / sizeof(ffi_arg);
759 arg_offset = arg_offset % sizeof(ffi_arg);
761 argp = (char *)(ar + argn);
762 fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
764 tp = target + offset;
766 if (elt_type->type == FFI_TYPE_DOUBLE)
767 *(double *)tp = *(double *)fpp;
768 else
769 memcpy(tp, argp + arg_offset, elt_type->size);
771 offset += elt_type->size;
772 arg_offset += elt_type->size;
773 elt_typep++;
774 argn += arg_offset / sizeof(ffi_arg);
775 arg_offset = arg_offset % sizeof(ffi_arg);
780 * Decodes the arguments to a function, which will be stored on the
781 * stack. AR is the pointer to the beginning of the integer
782 * arguments. FPR is a pointer to the area where floating point
783 * registers have been saved.
785 * RVALUE is the location where the function return value will be
786 * stored. CLOSURE is the prepared closure to invoke.
788 * This function should only be called from assembly, which is in
789 * turn called from a trampoline.
791 * Returns the function return flags.
795 ffi_closure_mips_inner_N32 (ffi_closure *closure,
796 void *rvalue, ffi_arg *ar,
797 ffi_arg *fpr)
799 ffi_cif *cif;
800 void **avaluep;
801 ffi_arg *avalue;
802 ffi_type **arg_types;
803 int i, avn, argn;
805 cif = closure->cif;
806 avalue = alloca (cif->nargs * sizeof (ffi_arg));
807 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
809 argn = 0;
811 if (cif->rstruct_flag)
813 #if _MIPS_SIM==_ABIN32
814 rvalue = (void *)(UINT32)ar[0];
815 #else /* N64 */
816 rvalue = (void *)ar[0];
817 #endif
818 argn = 1;
821 i = 0;
822 avn = cif->nargs;
823 arg_types = cif->arg_types;
825 while (i < avn)
827 if (arg_types[i]->type == FFI_TYPE_FLOAT
828 || arg_types[i]->type == FFI_TYPE_DOUBLE)
830 ffi_arg *argp = argn >= 8 ? ar + argn : fpr + argn;
831 #ifdef __MIPSEB__
832 if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
833 avaluep[i] = ((char *) argp) + sizeof (float);
834 else
835 #endif
836 avaluep[i] = (char *) argp;
838 else
840 unsigned type = arg_types[i]->type;
842 if (arg_types[i]->alignment > sizeof(ffi_arg))
843 argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
845 ffi_arg *argp = ar + argn;
847 /* The size of a pointer depends on the ABI */
848 if (type == FFI_TYPE_POINTER)
849 type = (cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
851 switch (type)
853 case FFI_TYPE_SINT8:
854 avaluep[i] = &avalue[i];
855 *(SINT8 *) &avalue[i] = (SINT8) *argp;
856 break;
858 case FFI_TYPE_UINT8:
859 avaluep[i] = &avalue[i];
860 *(UINT8 *) &avalue[i] = (UINT8) *argp;
861 break;
863 case FFI_TYPE_SINT16:
864 avaluep[i] = &avalue[i];
865 *(SINT16 *) &avalue[i] = (SINT16) *argp;
866 break;
868 case FFI_TYPE_UINT16:
869 avaluep[i] = &avalue[i];
870 *(UINT16 *) &avalue[i] = (UINT16) *argp;
871 break;
873 case FFI_TYPE_SINT32:
874 avaluep[i] = &avalue[i];
875 *(SINT32 *) &avalue[i] = (SINT32) *argp;
876 break;
878 case FFI_TYPE_UINT32:
879 avaluep[i] = &avalue[i];
880 *(UINT32 *) &avalue[i] = (UINT32) *argp;
881 break;
883 case FFI_TYPE_STRUCT:
884 if (argn < 8)
886 /* Allocate space for the struct as at least part of
887 it was passed in registers. */
888 avaluep[i] = alloca(arg_types[i]->size);
889 copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
890 argn, 0, ar, fpr);
892 break;
894 /* Else fall through. */
895 default:
896 avaluep[i] = (char *) argp;
897 break;
900 argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
901 i++;
904 /* Invoke the closure. */
905 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
907 return cif->flags >> (FFI_FLAG_BITS * 8);
910 #endif /* FFI_MIPS_N32 */
912 #endif /* FFI_CLOSURES */