1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1996, 2007, 2008 Red Hat, Inc.
3 Copyright (c) 2008 David Daney
4
5 MIPS Foreign Function Interface
6
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:
14
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17
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 ----------------------------------------------------------------------- */
27
28 #include <ffi.h>
29 #include <ffi_common.h>
30
31 #include <stdlib.h>
32
33 #ifdef __GNUC__
34 # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
35 # define USE__BUILTIN___CLEAR_CACHE 1
36 # endif
37 #endif
38
39 #ifndef USE__BUILTIN___CLEAR_CACHE
40 #include <sys/cachectl.h>
41 #endif
42
43 #ifdef FFI_DEBUG
44 # define FFI_MIPS_STOP_HERE() ffi_stop_here()
45 #else
46 # define FFI_MIPS_STOP_HERE() do {} while(0)
47 #endif
48
49 #ifdef FFI_MIPS_N32
50 #define FIX_ARGP \
51 FFI_ASSERT(argp <= &stack[bytes]); \
52 if (argp == &stack[bytes]) \
53 { \
54 argp = stack; \
55 FFI_MIPS_STOP_HERE(); \
56 }
57 #else
58 #define FIX_ARGP
59 #endif
60
61
62 /* ffi_prep_args is called by the assembly routine once stack space
63 has been allocated for the function's arguments */
64
ffi_prep_args(char * stack,extended_cif * ecif,int bytes,int flags)65 static void ffi_prep_args(char *stack,
66 extended_cif *ecif,
67 int bytes,
68 int flags)
69 {
70 int i;
71 void **p_argv;
72 char *argp;
73 ffi_type **p_arg;
74
75 #ifdef FFI_MIPS_N32
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))];
81 else
82 argp = stack;
83 #else
84 argp = stack;
85 #endif
86
87 memset(stack, 0, bytes);
88
89 #ifdef FFI_MIPS_N32
90 if ( ecif->cif->rstruct_flag != 0 )
91 #else
92 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
93 #endif
94 {
95 *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
96 argp += sizeof(ffi_arg);
97 FIX_ARGP;
98 }
99
100 p_argv = ecif->avalue;
101
102 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
103 {
104 size_t z;
105 unsigned int a;
106
107 /* Align if necessary. */
108 a = (*p_arg)->alignment;
109 if (a < sizeof(ffi_arg))
110 a = sizeof(ffi_arg);
111
112 if ((a - 1) & (unsigned long) argp)
113 {
114 argp = (char *) ALIGN(argp, a);
115 FIX_ARGP;
116 }
117
118 z = (*p_arg)->size;
119 if (z <= sizeof(ffi_arg))
120 {
121 int type = (*p_arg)->type;
122 z = sizeof(ffi_arg);
123
124 /* The size of a pointer depends on the ABI */
125 if (type == FFI_TYPE_POINTER)
126 type =
127 (ecif->cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
128
129 switch (type)
130 {
131 case FFI_TYPE_SINT8:
132 *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
133 break;
134
135 case FFI_TYPE_UINT8:
136 *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
137 break;
138
139 case FFI_TYPE_SINT16:
140 *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
141 break;
142
143 case FFI_TYPE_UINT16:
144 *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
145 break;
146
147 case FFI_TYPE_SINT32:
148 *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
149 break;
150
151 case FFI_TYPE_UINT32:
152 *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
153 break;
154
155 /* This can only happen with 64bit slots. */
156 case FFI_TYPE_FLOAT:
157 *(float *) argp = *(float *)(* p_argv);
158 break;
159
160 /* Handle structures. */
161 default:
162 memcpy(argp, *p_argv, (*p_arg)->size);
163 break;
164 }
165 }
166 else
167 {
168 #ifdef FFI_MIPS_O32
169 memcpy(argp, *p_argv, z);
170 #else
171 {
172 unsigned long end = (unsigned long) argp + z;
173 unsigned long cap = (unsigned long) stack + bytes;
174
175 /* Check if the data will fit within the register space.
176 Handle it if it doesn't. */
177
178 if (end <= cap)
179 memcpy(argp, *p_argv, z);
180 else
181 {
182 unsigned long portion = cap - (unsigned long)argp;
183
184 memcpy(argp, *p_argv, portion);
185 argp = stack;
186 z -= portion;
187 memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),
188 z);
189 }
190 }
191 #endif
192 }
193 p_argv++;
194 argp += z;
195 FIX_ARGP;
196 }
197 }
198
199 #ifdef FFI_MIPS_N32
200
201 /* The n32 spec says that if "a chunk consists solely of a double
202 float field (but not a double, which is part of a union), it
203 is passed in a floating point register. Any other chunk is
204 passed in an integer register". This code traverses structure
205 definitions and generates the appropriate flags. */
206
207 static unsigned
calc_n32_struct_flags(ffi_type * arg,unsigned * loc,unsigned * arg_reg)208 calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg)
209 {
210 unsigned flags = 0;
211 unsigned index = 0;
212
213 ffi_type *e;
214
215 while ((e = arg->elements[index]))
216 {
217 /* Align this object. */
218 *loc = ALIGN(*loc, e->alignment);
219 if (e->type == FFI_TYPE_DOUBLE)
220 {
221 /* Already aligned to FFI_SIZEOF_ARG. */
222 *arg_reg = *loc / FFI_SIZEOF_ARG;
223 if (*arg_reg > 7)
224 break;
225 flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));
226 *loc += e->size;
227 }
228 else
229 *loc += e->size;
230 index++;
231 }
232 /* Next Argument register at alignment of FFI_SIZEOF_ARG. */
233 *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
234
235 return flags;
236 }
237
238 static unsigned
calc_n32_return_struct_flags(ffi_type * arg)239 calc_n32_return_struct_flags(ffi_type *arg)
240 {
241 unsigned flags = 0;
242 unsigned small = FFI_TYPE_SMALLSTRUCT;
243 ffi_type *e;
244
245 /* Returning structures under n32 is a tricky thing.
246 A struct with only one or two floating point fields
247 is returned in $f0 (and $f2 if necessary). Any other
248 struct results at most 128 bits are returned in $2
249 (the first 64 bits) and $3 (remainder, if necessary).
250 Larger structs are handled normally. */
251
252 if (arg->size > 16)
253 return 0;
254
255 if (arg->size > 8)
256 small = FFI_TYPE_SMALLSTRUCT2;
257
258 e = arg->elements[0];
259 if (e->type == FFI_TYPE_DOUBLE)
260 flags = FFI_TYPE_DOUBLE;
261 else if (e->type == FFI_TYPE_FLOAT)
262 flags = FFI_TYPE_FLOAT;
263
264 if (flags && (e = arg->elements[1]))
265 {
266 if (e->type == FFI_TYPE_DOUBLE)
267 flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
268 else if (e->type == FFI_TYPE_FLOAT)
269 flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS;
270 else
271 return small;
272
273 if (flags && (arg->elements[2]))
274 {
275 /* There are three arguments and the first two are
276 floats! This must be passed the old way. */
277 return small;
278 }
279 }
280 else
281 if (!flags)
282 return small;
283
284 return flags;
285 }
286
287 #endif
288
289 /* Perform machine dependent cif processing */
ffi_prep_cif_machdep(ffi_cif * cif)290 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
291 {
292 cif->flags = 0;
293
294 #ifdef FFI_MIPS_O32
295 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
296 * does not have special handling for floating point args.
297 */
298
299 if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
300 {
301 if (cif->nargs > 0)
302 {
303 switch ((cif->arg_types)[0]->type)
304 {
305 case FFI_TYPE_FLOAT:
306 case FFI_TYPE_DOUBLE:
307 cif->flags += (cif->arg_types)[0]->type;
308 break;
309
310 default:
311 break;
312 }
313
314 if (cif->nargs > 1)
315 {
316 /* Only handle the second argument if the first
317 is a float or double. */
318 if (cif->flags)
319 {
320 switch ((cif->arg_types)[1]->type)
321 {
322 case FFI_TYPE_FLOAT:
323 case FFI_TYPE_DOUBLE:
324 cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
325 break;
326
327 default:
328 break;
329 }
330 }
331 }
332 }
333 }
334
335 /* Set the return type flag */
336
337 if (cif->abi == FFI_O32_SOFT_FLOAT)
338 {
339 switch (cif->rtype->type)
340 {
341 case FFI_TYPE_VOID:
342 case FFI_TYPE_STRUCT:
343 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
344 break;
345
346 case FFI_TYPE_SINT64:
347 case FFI_TYPE_UINT64:
348 case FFI_TYPE_DOUBLE:
349 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
350 break;
351
352 case FFI_TYPE_FLOAT:
353 default:
354 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
355 break;
356 }
357 }
358 else
359 {
360 /* FFI_O32 */
361 switch (cif->rtype->type)
362 {
363 case FFI_TYPE_VOID:
364 case FFI_TYPE_STRUCT:
365 case FFI_TYPE_FLOAT:
366 case FFI_TYPE_DOUBLE:
367 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
368 break;
369
370 case FFI_TYPE_SINT64:
371 case FFI_TYPE_UINT64:
372 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
373 break;
374
375 default:
376 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
377 break;
378 }
379 }
380 #endif
381
382 #ifdef FFI_MIPS_N32
383 /* Set the flags necessary for N32 processing */
384 {
385 unsigned arg_reg = 0;
386 unsigned loc = 0;
387 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
388 unsigned index = 0;
389
390 unsigned struct_flags = 0;
391
392 if (cif->rtype->type == FFI_TYPE_STRUCT)
393 {
394 struct_flags = calc_n32_return_struct_flags(cif->rtype);
395
396 if (struct_flags == 0)
397 {
398 /* This means that the structure is being passed as
399 a hidden argument */
400
401 arg_reg = 1;
402 count = (cif->nargs < 7) ? cif->nargs : 7;
403
404 cif->rstruct_flag = !0;
405 }
406 else
407 cif->rstruct_flag = 0;
408 }
409 else
410 cif->rstruct_flag = 0;
411
412 while (count-- > 0 && arg_reg < 8)
413 {
414 switch ((cif->arg_types)[index]->type)
415 {
416 case FFI_TYPE_FLOAT:
417 case FFI_TYPE_DOUBLE:
418 cif->flags +=
419 ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS));
420 arg_reg++;
421 break;
422 case FFI_TYPE_LONGDOUBLE:
423 /* Align it. */
424 arg_reg = ALIGN(arg_reg, 2);
425 /* Treat it as two adjacent doubles. */
426 cif->flags +=
427 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
428 arg_reg++;
429 cif->flags +=
430 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
431 arg_reg++;
432 break;
433
434 case FFI_TYPE_STRUCT:
435 loc = arg_reg * FFI_SIZEOF_ARG;
436 cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
437 &loc, &arg_reg);
438 break;
439
440 default:
441 arg_reg++;
442 break;
443 }
444
445 index++;
446 }
447
448 /* Set the return type flag */
449 switch (cif->rtype->type)
450 {
451 case FFI_TYPE_STRUCT:
452 {
453 if (struct_flags == 0)
454 {
455 /* The structure is returned through a hidden
456 first argument. Do nothing, 'cause FFI_TYPE_VOID
457 is 0 */
458 }
459 else
460 {
461 /* The structure is returned via some tricky
462 mechanism */
463 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
464 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
465 }
466 break;
467 }
468
469 case FFI_TYPE_VOID:
470 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
471 break;
472
473 case FFI_TYPE_FLOAT:
474 case FFI_TYPE_DOUBLE:
475 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
476 break;
477 case FFI_TYPE_LONGDOUBLE:
478 /* Long double is returned as if it were a struct containing
479 two doubles. */
480 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
481 cif->flags += (FFI_TYPE_DOUBLE + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
482 << (4 + (FFI_FLAG_BITS * 8));
483 break;
484 default:
485 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
486 break;
487 }
488 }
489 #endif
490
491 return FFI_OK;
492 }
493
494 /* Low level routine for calling O32 functions */
495 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
496 extended_cif *, unsigned,
497 unsigned, unsigned *, void (*)(void));
498
499 /* Low level routine for calling N32 functions */
500 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
501 extended_cif *, unsigned,
502 unsigned, unsigned *, void (*)(void));
503
ffi_call(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue)504 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
505 {
506 extended_cif ecif;
507
508 ecif.cif = cif;
509 ecif.avalue = avalue;
510
511 /* If the return value is a struct and we don't have a return */
512 /* value address then we need to make one */
513
514 if ((rvalue == NULL) &&
515 (cif->rtype->type == FFI_TYPE_STRUCT))
516 ecif.rvalue = alloca(cif->rtype->size);
517 else
518 ecif.rvalue = rvalue;
519
520 switch (cif->abi)
521 {
522 #ifdef FFI_MIPS_O32
523 case FFI_O32:
524 case FFI_O32_SOFT_FLOAT:
525 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
526 cif->flags, ecif.rvalue, fn);
527 break;
528 #endif
529
530 #ifdef FFI_MIPS_N32
531 case FFI_N32:
532 case FFI_N64:
533 {
534 int copy_rvalue = 0;
535 void *rvalue_copy = ecif.rvalue;
536 if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
537 {
538 /* For structures smaller than 16 bytes we clobber memory
539 in 8 byte increments. Make a copy so we don't clobber
540 the callers memory outside of the struct bounds. */
541 rvalue_copy = alloca(16);
542 copy_rvalue = 1;
543 }
544 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
545 cif->flags, rvalue_copy, fn);
546 if (copy_rvalue)
547 memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size);
548 }
549 break;
550 #endif
551
552 default:
553 FFI_ASSERT(0);
554 break;
555 }
556 }
557
558 #if FFI_CLOSURES
559 #if defined(FFI_MIPS_O32)
560 extern void ffi_closure_O32(void);
561 #else
562 extern void ffi_closure_N32(void);
563 #endif /* FFI_MIPS_O32 */
564
565 ffi_status
ffi_prep_closure_loc(ffi_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data,void * codeloc)566 ffi_prep_closure_loc (ffi_closure *closure,
567 ffi_cif *cif,
568 void (*fun)(ffi_cif*,void*,void**,void*),
569 void *user_data,
570 void *codeloc)
571 {
572 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
573 void * fn;
574 char *clear_location = (char *) codeloc;
575
576 #if defined(FFI_MIPS_O32)
577 FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
578 fn = ffi_closure_O32;
579 #else /* FFI_MIPS_N32 */
580 FFI_ASSERT(cif->abi == FFI_N32 || cif->abi == FFI_N64);
581 fn = ffi_closure_N32;
582 #endif /* FFI_MIPS_O32 */
583
584 #if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
585 /* lui $25,high(fn) */
586 tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
587 /* ori $25,low(fn) */
588 tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
589 /* lui $12,high(codeloc) */
590 tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
591 /* jr $25 */
592 tramp[3] = 0x03200008;
593 /* ori $12,low(codeloc) */
594 tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
595 #else
596 /* N64 has a somewhat larger trampoline. */
597 /* lui $25,high(fn) */
598 tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);
599 /* lui $12,high(codeloc) */
600 tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);
601 /* ori $25,mid-high(fn) */
602 tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);
603 /* ori $12,mid-high(codeloc) */
604 tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);
605 /* dsll $25,$25,16 */
606 tramp[4] = 0x0019cc38;
607 /* dsll $12,$12,16 */
608 tramp[5] = 0x000c6438;
609 /* ori $25,mid-low(fn) */
610 tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);
611 /* ori $12,mid-low(codeloc) */
612 tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);
613 /* dsll $25,$25,16 */
614 tramp[8] = 0x0019cc38;
615 /* dsll $12,$12,16 */
616 tramp[9] = 0x000c6438;
617 /* ori $25,low(fn) */
618 tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff);
619 /* jr $25 */
620 tramp[11] = 0x03200008;
621 /* ori $12,low(codeloc) */
622 tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
623
624 #endif
625
626 closure->cif = cif;
627 closure->fun = fun;
628 closure->user_data = user_data;
629
630 #ifdef USE__BUILTIN___CLEAR_CACHE
631 __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
632 #else
633 cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE);
634 #endif
635 return FFI_OK;
636 }
637
638 /*
639 * Decodes the arguments to a function, which will be stored on the
640 * stack. AR is the pointer to the beginning of the integer arguments
641 * (and, depending upon the arguments, some floating-point arguments
642 * as well). FPR is a pointer to the area where floating point
643 * registers have been saved, if any.
644 *
645 * RVALUE is the location where the function return value will be
646 * stored. CLOSURE is the prepared closure to invoke.
647 *
648 * This function should only be called from assembly, which is in
649 * turn called from a trampoline.
650 *
651 * Returns the function return type.
652 *
653 * Based on the similar routine for sparc.
654 */
655 int
ffi_closure_mips_inner_O32(ffi_closure * closure,void * rvalue,ffi_arg * ar,double * fpr)656 ffi_closure_mips_inner_O32 (ffi_closure *closure,
657 void *rvalue, ffi_arg *ar,
658 double *fpr)
659 {
660 ffi_cif *cif;
661 void **avaluep;
662 ffi_arg *avalue;
663 ffi_type **arg_types;
664 int i, avn, argn, seen_int;
665
666 cif = closure->cif;
667 avalue = alloca (cif->nargs * sizeof (ffi_arg));
668 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
669
670 seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
671 argn = 0;
672
673 if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
674 {
675 rvalue = (void *)(UINT32)ar[0];
676 argn = 1;
677 }
678
679 i = 0;
680 avn = cif->nargs;
681 arg_types = cif->arg_types;
682
683 while (i < avn)
684 {
685 if (i < 2 && !seen_int &&
686 (arg_types[i]->type == FFI_TYPE_FLOAT ||
687 arg_types[i]->type == FFI_TYPE_DOUBLE))
688 {
689 #ifdef __MIPSEB__
690 if (arg_types[i]->type == FFI_TYPE_FLOAT)
691 avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
692 else
693 #endif
694 avaluep[i] = (char *) &fpr[i];
695 }
696 else
697 {
698 if (arg_types[i]->alignment == 8 && (argn & 0x1))
699 argn++;
700 switch (arg_types[i]->type)
701 {
702 case FFI_TYPE_SINT8:
703 avaluep[i] = &avalue[i];
704 *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
705 break;
706
707 case FFI_TYPE_UINT8:
708 avaluep[i] = &avalue[i];
709 *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
710 break;
711
712 case FFI_TYPE_SINT16:
713 avaluep[i] = &avalue[i];
714 *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
715 break;
716
717 case FFI_TYPE_UINT16:
718 avaluep[i] = &avalue[i];
719 *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
720 break;
721
722 default:
723 avaluep[i] = (char *) &ar[argn];
724 break;
725 }
726 seen_int = 1;
727 }
728 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
729 i++;
730 }
731
732 /* Invoke the closure. */
733 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
734
735 if (cif->abi == FFI_O32_SOFT_FLOAT)
736 {
737 switch (cif->rtype->type)
738 {
739 case FFI_TYPE_FLOAT:
740 return FFI_TYPE_INT;
741 case FFI_TYPE_DOUBLE:
742 return FFI_TYPE_UINT64;
743 default:
744 return cif->rtype->type;
745 }
746 }
747 else
748 {
749 return cif->rtype->type;
750 }
751 }
752
753 #if defined(FFI_MIPS_N32)
754
755 static void
copy_struct_N32(char * target,unsigned offset,ffi_abi abi,ffi_type * type,int argn,unsigned arg_offset,ffi_arg * ar,ffi_arg * fpr)756 copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
757 int argn, unsigned arg_offset, ffi_arg *ar,
758 ffi_arg *fpr)
759 {
760 ffi_type **elt_typep = type->elements;
761 while(*elt_typep)
762 {
763 ffi_type *elt_type = *elt_typep;
764 unsigned o;
765 char *tp;
766 char *argp;
767 char *fpp;
768
769 o = ALIGN(offset, elt_type->alignment);
770 arg_offset += o - offset;
771 offset = o;
772 argn += arg_offset / sizeof(ffi_arg);
773 arg_offset = arg_offset % sizeof(ffi_arg);
774
775 argp = (char *)(ar + argn);
776 fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
777
778 tp = target + offset;
779
780 if (elt_type->type == FFI_TYPE_DOUBLE)
781 *(double *)tp = *(double *)fpp;
782 else
783 memcpy(tp, argp + arg_offset, elt_type->size);
784
785 offset += elt_type->size;
786 arg_offset += elt_type->size;
787 elt_typep++;
788 argn += arg_offset / sizeof(ffi_arg);
789 arg_offset = arg_offset % sizeof(ffi_arg);
790 }
791 }
792
793 /*
794 * Decodes the arguments to a function, which will be stored on the
795 * stack. AR is the pointer to the beginning of the integer
796 * arguments. FPR is a pointer to the area where floating point
797 * registers have been saved.
798 *
799 * RVALUE is the location where the function return value will be
800 * stored. CLOSURE is the prepared closure to invoke.
801 *
802 * This function should only be called from assembly, which is in
803 * turn called from a trampoline.
804 *
805 * Returns the function return flags.
806 *
807 */
808 int
ffi_closure_mips_inner_N32(ffi_closure * closure,void * rvalue,ffi_arg * ar,ffi_arg * fpr)809 ffi_closure_mips_inner_N32 (ffi_closure *closure,
810 void *rvalue, ffi_arg *ar,
811 ffi_arg *fpr)
812 {
813 ffi_cif *cif;
814 void **avaluep;
815 ffi_arg *avalue;
816 ffi_type **arg_types;
817 int i, avn, argn;
818
819 cif = closure->cif;
820 avalue = alloca (cif->nargs * sizeof (ffi_arg));
821 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
822
823 argn = 0;
824
825 if (cif->rstruct_flag)
826 {
827 #if _MIPS_SIM==_ABIN32
828 rvalue = (void *)(UINT32)ar[0];
829 #else /* N64 */
830 rvalue = (void *)ar[0];
831 #endif
832 argn = 1;
833 }
834
835 i = 0;
836 avn = cif->nargs;
837 arg_types = cif->arg_types;
838
839 while (i < avn)
840 {
841 if (arg_types[i]->type == FFI_TYPE_FLOAT
842 || arg_types[i]->type == FFI_TYPE_DOUBLE)
843 {
844 ffi_arg *argp = argn >= 8 ? ar + argn : fpr + argn;
845 #ifdef __MIPSEB__
846 if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
847 avaluep[i] = ((char *) argp) + sizeof (float);
848 else
849 #endif
850 avaluep[i] = (char *) argp;
851 }
852 else
853 {
854 unsigned type = arg_types[i]->type;
855
856 if (arg_types[i]->alignment > sizeof(ffi_arg))
857 argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
858
859 ffi_arg *argp = ar + argn;
860
861 /* The size of a pointer depends on the ABI */
862 if (type == FFI_TYPE_POINTER)
863 type = (cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
864
865 switch (type)
866 {
867 case FFI_TYPE_SINT8:
868 avaluep[i] = &avalue[i];
869 *(SINT8 *) &avalue[i] = (SINT8) *argp;
870 break;
871
872 case FFI_TYPE_UINT8:
873 avaluep[i] = &avalue[i];
874 *(UINT8 *) &avalue[i] = (UINT8) *argp;
875 break;
876
877 case FFI_TYPE_SINT16:
878 avaluep[i] = &avalue[i];
879 *(SINT16 *) &avalue[i] = (SINT16) *argp;
880 break;
881
882 case FFI_TYPE_UINT16:
883 avaluep[i] = &avalue[i];
884 *(UINT16 *) &avalue[i] = (UINT16) *argp;
885 break;
886
887 case FFI_TYPE_SINT32:
888 avaluep[i] = &avalue[i];
889 *(SINT32 *) &avalue[i] = (SINT32) *argp;
890 break;
891
892 case FFI_TYPE_UINT32:
893 avaluep[i] = &avalue[i];
894 *(UINT32 *) &avalue[i] = (UINT32) *argp;
895 break;
896
897 case FFI_TYPE_STRUCT:
898 if (argn < 8)
899 {
900 /* Allocate space for the struct as at least part of
901 it was passed in registers. */
902 avaluep[i] = alloca(arg_types[i]->size);
903 copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
904 argn, 0, ar, fpr);
905
906 break;
907 }
908 /* Else fall through. */
909 default:
910 avaluep[i] = (char *) argp;
911 break;
912 }
913 }
914 argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
915 i++;
916 }
917
918 /* Invoke the closure. */
919 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
920
921 return cif->flags >> (FFI_FLAG_BITS * 8);
922 }
923
924 #endif /* FFI_MIPS_N32 */
925
926 #endif /* FFI_CLOSURES */
927