Merge -r 127928:132243 from trunk
[official-gcc.git] / libffi / src / mips / ffi.c
blobd0ce201a1516a4f1640b9d34b2bfb29826aeaeaa
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, 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 CYGNUS SOLUTIONS 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 ----------------------------------------------------------------------- */
26 #include <ffi.h>
27 #include <ffi_common.h>
29 #include <stdlib.h>
31 #ifdef FFI_DEBUG
32 # define FFI_MIPS_STOP_HERE() ffi_stop_here()
33 #else
34 # define FFI_MIPS_STOP_HERE() do {} while(0)
35 #endif
37 #ifdef FFI_MIPS_N32
38 #define FIX_ARGP \
39 FFI_ASSERT(argp <= &stack[bytes]); \
40 if (argp == &stack[bytes]) \
41 { \
42 argp = stack; \
43 FFI_MIPS_STOP_HERE(); \
45 #else
46 #define FIX_ARGP
47 #endif
50 /* ffi_prep_args is called by the assembly routine once stack space
51 has been allocated for the function's arguments */
53 static void ffi_prep_args(char *stack,
54 extended_cif *ecif,
55 int bytes,
56 int flags)
58 int i;
59 void **p_argv;
60 char *argp;
61 ffi_type **p_arg;
63 #ifdef FFI_MIPS_N32
64 /* If more than 8 double words are used, the remainder go
65 on the stack. We reorder stuff on the stack here to
66 support this easily. */
67 if (bytes > 8 * sizeof(ffi_arg))
68 argp = &stack[bytes - (8 * sizeof(ffi_arg))];
69 else
70 argp = stack;
71 #else
72 argp = stack;
73 #endif
75 memset(stack, 0, bytes);
77 #ifdef FFI_MIPS_N32
78 if ( ecif->cif->rstruct_flag != 0 )
79 #else
80 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
81 #endif
83 *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
84 argp += sizeof(ffi_arg);
85 FIX_ARGP;
88 p_argv = ecif->avalue;
90 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
92 size_t z;
93 unsigned int a;
95 /* Align if necessary. */
96 a = (*p_arg)->alignment;
97 if (a < sizeof(ffi_arg))
98 a = sizeof(ffi_arg);
100 if ((a - 1) & (unsigned long) argp)
102 argp = (char *) ALIGN(argp, a);
103 FIX_ARGP;
106 z = (*p_arg)->size;
107 if (z <= sizeof(ffi_arg))
109 int type = (*p_arg)->type;
110 z = sizeof(ffi_arg);
112 /* The size of a pointer depends on the ABI */
113 if (type == FFI_TYPE_POINTER)
114 type =
115 (ecif->cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
117 switch (type)
119 case FFI_TYPE_SINT8:
120 *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
121 break;
123 case FFI_TYPE_UINT8:
124 *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
125 break;
127 case FFI_TYPE_SINT16:
128 *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
129 break;
131 case FFI_TYPE_UINT16:
132 *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
133 break;
135 case FFI_TYPE_SINT32:
136 *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
137 break;
139 case FFI_TYPE_UINT32:
140 *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
141 break;
143 /* This can only happen with 64bit slots. */
144 case FFI_TYPE_FLOAT:
145 *(float *) argp = *(float *)(* p_argv);
146 break;
148 /* Handle structures. */
149 default:
150 memcpy(argp, *p_argv, (*p_arg)->size);
151 break;
154 else
156 #ifdef FFI_MIPS_O32
157 memcpy(argp, *p_argv, z);
158 #else
160 unsigned long end = (unsigned long) argp + z;
161 unsigned long cap = (unsigned long) stack + bytes;
163 /* Check if the data will fit within the register space.
164 Handle it if it doesn't. */
166 if (end <= cap)
167 memcpy(argp, *p_argv, z);
168 else
170 unsigned long portion = cap - (unsigned long)argp;
172 memcpy(argp, *p_argv, portion);
173 argp = stack;
174 z -= portion;
175 memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),
179 #endif
181 p_argv++;
182 argp += z;
183 FIX_ARGP;
187 #ifdef FFI_MIPS_N32
189 /* The n32 spec says that if "a chunk consists solely of a double
190 float field (but not a double, which is part of a union), it
191 is passed in a floating point register. Any other chunk is
192 passed in an integer register". This code traverses structure
193 definitions and generates the appropriate flags. */
195 static unsigned
196 calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg)
198 unsigned flags = 0;
199 unsigned index = 0;
201 ffi_type *e;
203 while ((e = arg->elements[index]))
205 /* Align this object. */
206 *loc = ALIGN(*loc, e->alignment);
207 if (e->type == FFI_TYPE_DOUBLE)
209 /* Already aligned to FFI_SIZEOF_ARG. */
210 *arg_reg = *loc / FFI_SIZEOF_ARG;
211 if (*arg_reg > 7)
212 break;
213 flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));
214 *loc += e->size;
216 else
217 *loc += e->size;
218 index++;
220 /* Next Argument register at alignment of FFI_SIZEOF_ARG. */
221 *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
223 return flags;
226 static unsigned
227 calc_n32_return_struct_flags(ffi_type *arg)
229 unsigned flags = 0;
230 unsigned small = FFI_TYPE_SMALLSTRUCT;
231 ffi_type *e;
233 /* Returning structures under n32 is a tricky thing.
234 A struct with only one or two floating point fields
235 is returned in $f0 (and $f2 if necessary). Any other
236 struct results at most 128 bits are returned in $2
237 (the first 64 bits) and $3 (remainder, if necessary).
238 Larger structs are handled normally. */
240 if (arg->size > 16)
241 return 0;
243 if (arg->size > 8)
244 small = FFI_TYPE_SMALLSTRUCT2;
246 e = arg->elements[0];
247 if (e->type == FFI_TYPE_DOUBLE)
248 flags = FFI_TYPE_DOUBLE;
249 else if (e->type == FFI_TYPE_FLOAT)
250 flags = FFI_TYPE_FLOAT;
252 if (flags && (e = arg->elements[1]))
254 if (e->type == FFI_TYPE_DOUBLE)
255 flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
256 else if (e->type == FFI_TYPE_FLOAT)
257 flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS;
258 else
259 return small;
261 if (flags && (arg->elements[2]))
263 /* There are three arguments and the first two are
264 floats! This must be passed the old way. */
265 return small;
268 else
269 if (!flags)
270 return small;
272 return flags;
275 #endif
277 /* Perform machine dependent cif processing */
278 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
280 cif->flags = 0;
282 #ifdef FFI_MIPS_O32
283 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
284 * does not have special handling for floating point args.
287 if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
289 if (cif->nargs > 0)
291 switch ((cif->arg_types)[0]->type)
293 case FFI_TYPE_FLOAT:
294 case FFI_TYPE_DOUBLE:
295 cif->flags += (cif->arg_types)[0]->type;
296 break;
298 default:
299 break;
302 if (cif->nargs > 1)
304 /* Only handle the second argument if the first
305 is a float or double. */
306 if (cif->flags)
308 switch ((cif->arg_types)[1]->type)
310 case FFI_TYPE_FLOAT:
311 case FFI_TYPE_DOUBLE:
312 cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
313 break;
315 default:
316 break;
323 /* Set the return type flag */
325 if (cif->abi == FFI_O32_SOFT_FLOAT)
327 switch (cif->rtype->type)
329 case FFI_TYPE_VOID:
330 case FFI_TYPE_STRUCT:
331 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
332 break;
334 case FFI_TYPE_SINT64:
335 case FFI_TYPE_UINT64:
336 case FFI_TYPE_DOUBLE:
337 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
338 break;
340 case FFI_TYPE_FLOAT:
341 default:
342 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
343 break;
346 else
348 /* FFI_O32 */
349 switch (cif->rtype->type)
351 case FFI_TYPE_VOID:
352 case FFI_TYPE_STRUCT:
353 case FFI_TYPE_FLOAT:
354 case FFI_TYPE_DOUBLE:
355 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
356 break;
358 case FFI_TYPE_SINT64:
359 case FFI_TYPE_UINT64:
360 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
361 break;
363 default:
364 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
365 break;
368 #endif
370 #ifdef FFI_MIPS_N32
371 /* Set the flags necessary for N32 processing */
373 unsigned arg_reg = 0;
374 unsigned loc = 0;
375 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
376 unsigned index = 0;
378 unsigned struct_flags = 0;
380 if (cif->rtype->type == FFI_TYPE_STRUCT)
382 struct_flags = calc_n32_return_struct_flags(cif->rtype);
384 if (struct_flags == 0)
386 /* This means that the structure is being passed as
387 a hidden argument */
389 arg_reg = 1;
390 count = (cif->nargs < 7) ? cif->nargs : 7;
392 cif->rstruct_flag = !0;
394 else
395 cif->rstruct_flag = 0;
397 else
398 cif->rstruct_flag = 0;
400 while (count-- > 0 && arg_reg < 8)
402 switch ((cif->arg_types)[index]->type)
404 case FFI_TYPE_FLOAT:
405 case FFI_TYPE_DOUBLE:
406 cif->flags +=
407 ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS));
408 arg_reg++;
409 break;
410 case FFI_TYPE_LONGDOUBLE:
411 /* Align it. */
412 arg_reg = ALIGN(arg_reg, 2);
413 /* Treat it as two adjacent doubles. */
414 cif->flags +=
415 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
416 arg_reg++;
417 cif->flags +=
418 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
419 arg_reg++;
420 break;
422 case FFI_TYPE_STRUCT:
423 loc = arg_reg * FFI_SIZEOF_ARG;
424 cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
425 &loc, &arg_reg);
426 break;
428 default:
429 arg_reg++;
430 break;
433 index++;
436 /* Set the return type flag */
437 switch (cif->rtype->type)
439 case FFI_TYPE_STRUCT:
441 if (struct_flags == 0)
443 /* The structure is returned through a hidden
444 first argument. Do nothing, 'cause FFI_TYPE_VOID
445 is 0 */
447 else
449 /* The structure is returned via some tricky
450 mechanism */
451 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
452 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
454 break;
457 case FFI_TYPE_VOID:
458 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
459 break;
461 case FFI_TYPE_FLOAT:
462 case FFI_TYPE_DOUBLE:
463 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
464 break;
465 case FFI_TYPE_LONGDOUBLE:
466 /* Long double is returned as if it were a struct containing
467 two doubles. */
468 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
469 cif->flags += (FFI_TYPE_DOUBLE + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
470 << (4 + (FFI_FLAG_BITS * 8));
471 break;
472 default:
473 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
474 break;
477 #endif
479 return FFI_OK;
482 /* Low level routine for calling O32 functions */
483 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
484 extended_cif *, unsigned,
485 unsigned, unsigned *, void (*)());
487 /* Low level routine for calling N32 functions */
488 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
489 extended_cif *, unsigned,
490 unsigned, unsigned *, void (*)());
492 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
494 extended_cif ecif;
496 ecif.cif = cif;
497 ecif.avalue = avalue;
499 /* If the return value is a struct and we don't have a return */
500 /* value address then we need to make one */
502 if ((rvalue == NULL) &&
503 (cif->rtype->type == FFI_TYPE_STRUCT))
504 ecif.rvalue = alloca(cif->rtype->size);
505 else
506 ecif.rvalue = rvalue;
508 switch (cif->abi)
510 #ifdef FFI_MIPS_O32
511 case FFI_O32:
512 case FFI_O32_SOFT_FLOAT:
513 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
514 cif->flags, ecif.rvalue, fn);
515 break;
516 #endif
518 #ifdef FFI_MIPS_N32
519 case FFI_N32:
520 case FFI_N64:
522 int copy_rvalue = 0;
523 void *rvalue_copy = ecif.rvalue;
524 if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
526 /* For structures smaller than 16 bytes we clobber memory
527 in 8 byte increments. Make a copy so we don't clobber
528 the callers memory outside of the struct bounds. */
529 rvalue_copy = alloca(16);
530 copy_rvalue = 1;
532 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
533 cif->flags, rvalue_copy, fn);
534 if (copy_rvalue)
535 memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size);
537 break;
538 #endif
540 default:
541 FFI_ASSERT(0);
542 break;
546 #if FFI_CLOSURES
547 #if defined(FFI_MIPS_O32)
548 extern void ffi_closure_O32(void);
549 #else
550 extern void ffi_closure_N32(void);
551 #endif /* FFI_MIPS_O32 */
553 ffi_status
554 ffi_prep_closure_loc (ffi_closure *closure,
555 ffi_cif *cif,
556 void (*fun)(ffi_cif*,void*,void**,void*),
557 void *user_data,
558 void *codeloc)
560 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
561 void * fn;
562 char *clear_location = (char *) codeloc;
564 #if defined(FFI_MIPS_O32)
565 FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
566 fn = ffi_closure_O32;
567 #else /* FFI_MIPS_N32 */
568 FFI_ASSERT(cif->abi == FFI_N32 || cif->abi == FFI_N64);
569 fn = ffi_closure_N32;
570 #endif /* FFI_MIPS_O32 */
572 #if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
573 /* lui $25,high(fn) */
574 tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
575 /* ori $25,low(fn) */
576 tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
577 /* lui $12,high(codeloc) */
578 tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
579 /* jr $25 */
580 tramp[3] = 0x03200008;
581 /* ori $12,low(codeloc) */
582 tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
583 #else
584 /* N64 has a somewhat larger trampoline. */
585 /* lui $25,high(fn) */
586 tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);
587 /* lui $12,high(codeloc) */
588 tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);
589 /* ori $25,mid-high(fn) */
590 tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);
591 /* ori $12,mid-high(codeloc) */
592 tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);
593 /* dsll $25,$25,16 */
594 tramp[4] = 0x0019cc38;
595 /* dsll $12,$12,16 */
596 tramp[5] = 0x000c6438;
597 /* ori $25,mid-low(fn) */
598 tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);
599 /* ori $12,mid-low(codeloc) */
600 tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);
601 /* dsll $25,$25,16 */
602 tramp[8] = 0x0019cc38;
603 /* dsll $12,$12,16 */
604 tramp[9] = 0x000c6438;
605 /* ori $25,low(fn) */
606 tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff);
607 /* jr $25 */
608 tramp[11] = 0x03200008;
609 /* ori $12,low(codeloc) */
610 tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
612 #endif
614 closure->cif = cif;
615 closure->fun = fun;
616 closure->user_data = user_data;
618 __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
620 return FFI_OK;
624 * Decodes the arguments to a function, which will be stored on the
625 * stack. AR is the pointer to the beginning of the integer arguments
626 * (and, depending upon the arguments, some floating-point arguments
627 * as well). FPR is a pointer to the area where floating point
628 * registers have been saved, if any.
630 * RVALUE is the location where the function return value will be
631 * stored. CLOSURE is the prepared closure to invoke.
633 * This function should only be called from assembly, which is in
634 * turn called from a trampoline.
636 * Returns the function return type.
638 * Based on the similar routine for sparc.
641 ffi_closure_mips_inner_O32 (ffi_closure *closure,
642 void *rvalue, ffi_arg *ar,
643 double *fpr)
645 ffi_cif *cif;
646 void **avaluep;
647 ffi_arg *avalue;
648 ffi_type **arg_types;
649 int i, avn, argn, seen_int;
651 cif = closure->cif;
652 avalue = alloca (cif->nargs * sizeof (ffi_arg));
653 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
655 seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
656 argn = 0;
658 if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
660 rvalue = (void *)(UINT32)ar[0];
661 argn = 1;
664 i = 0;
665 avn = cif->nargs;
666 arg_types = cif->arg_types;
668 while (i < avn)
670 if (i < 2 && !seen_int &&
671 (arg_types[i]->type == FFI_TYPE_FLOAT ||
672 arg_types[i]->type == FFI_TYPE_DOUBLE))
674 #ifdef __MIPSEB__
675 if (arg_types[i]->type == FFI_TYPE_FLOAT)
676 avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
677 else
678 #endif
679 avaluep[i] = (char *) &fpr[i];
681 else
683 if (arg_types[i]->alignment == 8 && (argn & 0x1))
684 argn++;
685 switch (arg_types[i]->type)
687 case FFI_TYPE_SINT8:
688 avaluep[i] = &avalue[i];
689 *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
690 break;
692 case FFI_TYPE_UINT8:
693 avaluep[i] = &avalue[i];
694 *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
695 break;
697 case FFI_TYPE_SINT16:
698 avaluep[i] = &avalue[i];
699 *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
700 break;
702 case FFI_TYPE_UINT16:
703 avaluep[i] = &avalue[i];
704 *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
705 break;
707 default:
708 avaluep[i] = (char *) &ar[argn];
709 break;
711 seen_int = 1;
713 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
714 i++;
717 /* Invoke the closure. */
718 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
720 if (cif->abi == FFI_O32_SOFT_FLOAT)
722 switch (cif->rtype->type)
724 case FFI_TYPE_FLOAT:
725 return FFI_TYPE_INT;
726 case FFI_TYPE_DOUBLE:
727 return FFI_TYPE_UINT64;
728 default:
729 return cif->rtype->type;
732 else
734 return cif->rtype->type;
738 #if defined(FFI_MIPS_N32)
740 static void
741 copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
742 int argn, unsigned arg_offset, ffi_arg *ar,
743 ffi_arg *fpr)
745 ffi_type **elt_typep = type->elements;
746 while(*elt_typep)
748 ffi_type *elt_type = *elt_typep;
749 unsigned o;
750 char *tp;
751 char *argp;
752 char *fpp;
754 o = ALIGN(offset, elt_type->alignment);
755 arg_offset += o - offset;
756 offset = o;
757 argn += arg_offset / sizeof(ffi_arg);
758 arg_offset = arg_offset % sizeof(ffi_arg);
760 argp = (char *)(ar + argn);
761 fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
763 tp = target + offset;
765 if (elt_type->type == FFI_TYPE_DOUBLE)
766 *(double *)tp = *(double *)fpp;
767 else
768 memcpy(tp, argp + arg_offset, elt_type->size);
770 offset += elt_type->size;
771 arg_offset += elt_type->size;
772 elt_typep++;
773 argn += arg_offset / sizeof(ffi_arg);
774 arg_offset = arg_offset % sizeof(ffi_arg);
779 * Decodes the arguments to a function, which will be stored on the
780 * stack. AR is the pointer to the beginning of the integer
781 * arguments. FPR is a pointer to the area where floating point
782 * registers have been saved.
784 * RVALUE is the location where the function return value will be
785 * stored. CLOSURE is the prepared closure to invoke.
787 * This function should only be called from assembly, which is in
788 * turn called from a trampoline.
790 * Returns the function return flags.
794 ffi_closure_mips_inner_N32 (ffi_closure *closure,
795 void *rvalue, ffi_arg *ar,
796 ffi_arg *fpr)
798 ffi_cif *cif;
799 void **avaluep;
800 ffi_arg *avalue;
801 ffi_type **arg_types;
802 int i, avn, argn;
804 cif = closure->cif;
805 avalue = alloca (cif->nargs * sizeof (ffi_arg));
806 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
808 argn = 0;
810 if (cif->rstruct_flag)
812 #if _MIPS_SIM==_ABIN32
813 rvalue = (void *)(UINT32)ar[0];
814 #else /* N64 */
815 rvalue = (void *)ar[0];
816 #endif
817 argn = 1;
820 i = 0;
821 avn = cif->nargs;
822 arg_types = cif->arg_types;
824 while (i < avn)
826 if (arg_types[i]->type == FFI_TYPE_FLOAT
827 || arg_types[i]->type == FFI_TYPE_DOUBLE)
829 ffi_arg *argp = argn >= 8 ? ar + argn : fpr + argn;
830 #ifdef __MIPSEB__
831 if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
832 avaluep[i] = ((char *) argp) + sizeof (float);
833 else
834 #endif
835 avaluep[i] = (char *) argp;
837 else
839 unsigned type = arg_types[i]->type;
841 if (arg_types[i]->alignment > sizeof(ffi_arg))
842 argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
844 ffi_arg *argp = ar + argn;
846 /* The size of a pointer depends on the ABI */
847 if (type == FFI_TYPE_POINTER)
848 type = (cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
850 switch (type)
852 case FFI_TYPE_SINT8:
853 avaluep[i] = &avalue[i];
854 *(SINT8 *) &avalue[i] = (SINT8) *argp;
855 break;
857 case FFI_TYPE_UINT8:
858 avaluep[i] = &avalue[i];
859 *(UINT8 *) &avalue[i] = (UINT8) *argp;
860 break;
862 case FFI_TYPE_SINT16:
863 avaluep[i] = &avalue[i];
864 *(SINT16 *) &avalue[i] = (SINT16) *argp;
865 break;
867 case FFI_TYPE_UINT16:
868 avaluep[i] = &avalue[i];
869 *(UINT16 *) &avalue[i] = (UINT16) *argp;
870 break;
872 case FFI_TYPE_SINT32:
873 avaluep[i] = &avalue[i];
874 *(SINT32 *) &avalue[i] = (SINT32) *argp;
875 break;
877 case FFI_TYPE_UINT32:
878 avaluep[i] = &avalue[i];
879 *(UINT32 *) &avalue[i] = (UINT32) *argp;
880 break;
882 case FFI_TYPE_STRUCT:
883 if (argn < 8)
885 /* Allocate space for the struct as at least part of
886 it was passed in registers. */
887 avaluep[i] = alloca(arg_types[i]->size);
888 copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
889 argn, 0, ar, fpr);
891 break;
893 /* Else fall through. */
894 default:
895 avaluep[i] = (char *) argp;
896 break;
899 argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
900 i++;
903 /* Invoke the closure. */
904 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
906 return cif->flags >> (FFI_FLAG_BITS * 8);
909 #endif /* FFI_MIPS_N32 */
911 #endif /* FFI_CLOSURES */