Update missing changes for 3.0.9r4.
[libffi.git] / src / mips / ffi.c
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
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 = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; 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 = (ecif->cif->abi == FFI_N64
127 || ecif->cif->abi == FFI_N64_SOFT_FLOAT)
128 ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
129
130 if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT
131 || ecif->cif->abi == FFI_N64_SOFT_FLOAT))
132 {
133 switch (type)
134 {
135 case FFI_TYPE_FLOAT:
136 type = FFI_TYPE_UINT32;
137 break;
138 case FFI_TYPE_DOUBLE:
139 type = FFI_TYPE_UINT64;
140 break;
141 default:
142 break;
143 }
144 }
145 switch (type)
146 {
147 case FFI_TYPE_SINT8:
148 *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
149 break;
150
151 case FFI_TYPE_UINT8:
152 *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
153 break;
154
155 case FFI_TYPE_SINT16:
156 *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
157 break;
158
159 case FFI_TYPE_UINT16:
160 *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
161 break;
162
163 case FFI_TYPE_SINT32:
164 *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
165 break;
166
167 case FFI_TYPE_UINT32:
168 *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
169 break;
170
171 /* This can only happen with 64bit slots. */
172 case FFI_TYPE_FLOAT:
173 *(float *) argp = *(float *)(* p_argv);
174 break;
175
176 /* Handle structures. */
177 default:
178 memcpy(argp, *p_argv, (*p_arg)->size);
179 break;
180 }
181 }
182 else
183 {
184 #ifdef FFI_MIPS_O32
185 memcpy(argp, *p_argv, z);
186 #else
187 {
188 unsigned long end = (unsigned long) argp + z;
189 unsigned long cap = (unsigned long) stack + bytes;
190
191 /* Check if the data will fit within the register space.
192 Handle it if it doesn't. */
193
194 if (end <= cap)
195 memcpy(argp, *p_argv, z);
196 else
197 {
198 unsigned long portion = cap - (unsigned long)argp;
199
200 memcpy(argp, *p_argv, portion);
201 argp = stack;
202 z -= portion;
203 memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),
204 z);
205 }
206 }
207 #endif
208 }
209 p_argv++;
210 argp += z;
211 FIX_ARGP;
212 }
213 }
214
215 #ifdef FFI_MIPS_N32
216
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. */
222
223 static unsigned
224 calc_n32_struct_flags(int soft_float, ffi_type *arg,
225 unsigned *loc, unsigned *arg_reg)
226 {
227 unsigned flags = 0;
228 unsigned index = 0;
229
230 ffi_type *e;
231
232 if (soft_float)
233 return 0;
234
235 while ((e = arg->elements[index]))
236 {
237 /* Align this object. */
238 *loc = ALIGN(*loc, e->alignment);
239 if (e->type == FFI_TYPE_DOUBLE)
240 {
241 /* Already aligned to FFI_SIZEOF_ARG. */
242 *arg_reg = *loc / FFI_SIZEOF_ARG;
243 if (*arg_reg > 7)
244 break;
245 flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));
246 *loc += e->size;
247 }
248 else
249 *loc += e->size;
250 index++;
251 }
252 /* Next Argument register at alignment of FFI_SIZEOF_ARG. */
253 *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
254
255 return flags;
256 }
257
258 static unsigned
259 calc_n32_return_struct_flags(int soft_float, ffi_type *arg)
260 {
261 unsigned flags = 0;
262 unsigned small = FFI_TYPE_SMALLSTRUCT;
263 ffi_type *e;
264
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. */
271
272 if (arg->size > 16)
273 return 0;
274
275 if (arg->size > 8)
276 small = FFI_TYPE_SMALLSTRUCT2;
277
278 e = arg->elements[0];
279
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;
284
285 if (flags && (e = arg->elements[1]))
286 {
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;
291 else
292 return small;
293
294 if (flags && (arg->elements[2]))
295 {
296 /* There are three arguments and the first two are
297 floats! This must be passed the old way. */
298 return small;
299 }
300 if (soft_float)
301 flags += FFI_TYPE_STRUCT_SOFT;
302 }
303 else
304 if (!flags)
305 return small;
306
307 return flags;
308 }
309
310 #endif
311
312 /* Perform machine dependent cif processing */
313 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
314 {
315 cif->flags = 0;
316
317 #ifdef FFI_MIPS_O32
318 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
319 * does not have special handling for floating point args.
320 */
321
322 if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
323 {
324 if (cif->nargs > 0)
325 {
326 switch ((cif->arg_types)[0]->type)
327 {
328 case FFI_TYPE_FLOAT:
329 case FFI_TYPE_DOUBLE:
330 cif->flags += (cif->arg_types)[0]->type;
331 break;
332
333 default:
334 break;
335 }
336
337 if (cif->nargs > 1)
338 {
339 /* Only handle the second argument if the first
340 is a float or double. */
341 if (cif->flags)
342 {
343 switch ((cif->arg_types)[1]->type)
344 {
345 case FFI_TYPE_FLOAT:
346 case FFI_TYPE_DOUBLE:
347 cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
348 break;
349
350 default:
351 break;
352 }
353 }
354 }
355 }
356 }
357
358 /* Set the return type flag */
359
360 if (cif->abi == FFI_O32_SOFT_FLOAT)
361 {
362 switch (cif->rtype->type)
363 {
364 case FFI_TYPE_VOID:
365 case FFI_TYPE_STRUCT:
366 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
367 break;
368
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);
373 break;
374
375 case FFI_TYPE_FLOAT:
376 default:
377 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
378 break;
379 }
380 }
381 else
382 {
383 /* FFI_O32 */
384 switch (cif->rtype->type)
385 {
386 case FFI_TYPE_VOID:
387 case FFI_TYPE_STRUCT:
388 case FFI_TYPE_FLOAT:
389 case FFI_TYPE_DOUBLE:
390 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
391 break;
392
393 case FFI_TYPE_SINT64:
394 case FFI_TYPE_UINT64:
395 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
396 break;
397
398 default:
399 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
400 break;
401 }
402 }
403 #endif
404
405 #ifdef FFI_MIPS_N32
406 /* Set the flags necessary for N32 processing */
407 {
408 int type;
409 unsigned arg_reg = 0;
410 unsigned loc = 0;
411 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
412 unsigned index = 0;
413
414 unsigned struct_flags = 0;
415 int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT
416 || cif->abi == FFI_N64_SOFT_FLOAT);
417
418 if (cif->rtype->type == FFI_TYPE_STRUCT)
419 {
420 struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
421
422 if (struct_flags == 0)
423 {
424 /* This means that the structure is being passed as
425 a hidden argument */
426
427 arg_reg = 1;
428 count = (cif->nargs < 7) ? cif->nargs : 7;
429
430 cif->rstruct_flag = !0;
431 }
432 else
433 cif->rstruct_flag = 0;
434 }
435 else
436 cif->rstruct_flag = 0;
437
438 while (count-- > 0 && arg_reg < 8)
439 {
440 type = (cif->arg_types)[index]->type;
441 if (soft_float)
442 {
443 switch (type)
444 {
445 case FFI_TYPE_FLOAT:
446 type = FFI_TYPE_UINT32;
447 break;
448 case FFI_TYPE_DOUBLE:
449 type = FFI_TYPE_UINT64;
450 break;
451 default:
452 break;
453 }
454 }
455 switch (type)
456 {
457 case FFI_TYPE_FLOAT:
458 case FFI_TYPE_DOUBLE:
459 cif->flags +=
460 ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS));
461 arg_reg++;
462 break;
463 case FFI_TYPE_LONGDOUBLE:
464 /* Align it. */
465 arg_reg = ALIGN(arg_reg, 2);
466 /* Treat it as two adjacent doubles. */
467 if (soft_float)
468 {
469 arg_reg += 2;
470 }
471 else
472 {
473 cif->flags +=
474 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
475 arg_reg++;
476 cif->flags +=
477 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
478 arg_reg++;
479 }
480 break;
481
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],
486 &loc, &arg_reg);
487 break;
488
489 default:
490 arg_reg++;
491 break;
492 }
493
494 index++;
495 }
496
497 /* Set the return type flag */
498 switch (cif->rtype->type)
499 {
500 case FFI_TYPE_STRUCT:
501 {
502 if (struct_flags == 0)
503 {
504 /* The structure is returned through a hidden
505 first argument. Do nothing, 'cause FFI_TYPE_VOID
506 is 0 */
507 }
508 else
509 {
510 /* The structure is returned via some tricky
511 mechanism */
512 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
513 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
514 }
515 break;
516 }
517
518 case FFI_TYPE_VOID:
519 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
520 break;
521
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);
525 else
526 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
527 break;
528
529 case FFI_TYPE_FLOAT:
530 if (soft_float)
531 {
532 cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
533 break;
534 }
535 /* else fall through */
536 case FFI_TYPE_DOUBLE:
537 if (soft_float)
538 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
539 else
540 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
541 break;
542
543 case FFI_TYPE_LONGDOUBLE:
544 /* Long double is returned as if it were a struct containing
545 two doubles. */
546 if (soft_float)
547 {
548 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
549 cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8));
550 }
551 else
552 {
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));
557 }
558 break;
559 default:
560 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
561 break;
562 }
563 }
564 #endif
565
566 return FFI_OK;
567 }
568
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));
573
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));
578
579 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
580 {
581 extended_cif ecif;
582
583 ecif.cif = cif;
584 ecif.avalue = avalue;
585
586 /* If the return value is a struct and we don't have a return */
587 /* value address then we need to make one */
588
589 if ((rvalue == NULL) &&
590 (cif->rtype->type == FFI_TYPE_STRUCT))
591 ecif.rvalue = alloca(cif->rtype->size);
592 else
593 ecif.rvalue = rvalue;
594
595 switch (cif->abi)
596 {
597 #ifdef FFI_MIPS_O32
598 case FFI_O32:
599 case FFI_O32_SOFT_FLOAT:
600 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
601 cif->flags, ecif.rvalue, fn);
602 break;
603 #endif
604
605 #ifdef FFI_MIPS_N32
606 case FFI_N32:
607 case FFI_N32_SOFT_FLOAT:
608 case FFI_N64:
609 case FFI_N64_SOFT_FLOAT:
610 {
611 int copy_rvalue = 0;
612 int copy_offset = 0;
613 char *rvalue_copy = ecif.rvalue;
614 if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
615 {
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);
620 copy_rvalue = 1;
621 }
622 else if (cif->rtype->type == FFI_TYPE_FLOAT
623 && (cif->abi == FFI_N64_SOFT_FLOAT
624 || cif->abi == FFI_N32_SOFT_FLOAT))
625 {
626 rvalue_copy = alloca (8);
627 copy_rvalue = 1;
628 #if defined(__MIPSEB__) || defined(_MIPSEB)
629 copy_offset = 4;
630 #endif
631 }
632 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
633 cif->flags, rvalue_copy, fn);
634 if (copy_rvalue)
635 memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
636 }
637 break;
638 #endif
639
640 default:
641 FFI_ASSERT(0);
642 break;
643 }
644 }
645
646 #if FFI_CLOSURES
647 #if defined(FFI_MIPS_O32)
648 extern void ffi_closure_O32(void);
649 #else
650 extern void ffi_closure_N32(void);
651 #endif /* FFI_MIPS_O32 */
652
653 ffi_status
654 ffi_prep_closure_loc (ffi_closure *closure,
655 ffi_cif *cif,
656 void (*fun)(ffi_cif*,void*,void**,void*),
657 void *user_data,
658 void *codeloc)
659 {
660 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
661 void * fn;
662 char *clear_location = (char *) codeloc;
663
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 */
671
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);
679 /* jr $25 */
680 tramp[3] = 0x03200008;
681 /* ori $12,low(codeloc) */
682 tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
683 #else
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);
707 /* jr $25 */
708 tramp[11] = 0x03200008;
709 /* ori $12,low(codeloc) */
710 tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
711
712 #endif
713
714 closure->cif = cif;
715 closure->fun = fun;
716 closure->user_data = user_data;
717
718 #ifdef USE__BUILTIN___CLEAR_CACHE
719 __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
720 #else
721 cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE);
722 #endif
723 return FFI_OK;
724 }
725
726 /*
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.
732 *
733 * RVALUE is the location where the function return value will be
734 * stored. CLOSURE is the prepared closure to invoke.
735 *
736 * This function should only be called from assembly, which is in
737 * turn called from a trampoline.
738 *
739 * Returns the function return type.
740 *
741 * Based on the similar routine for sparc.
742 */
743 int
744 ffi_closure_mips_inner_O32 (ffi_closure *closure,
745 void *rvalue, ffi_arg *ar,
746 double *fpr)
747 {
748 ffi_cif *cif;
749 void **avaluep;
750 ffi_arg *avalue;
751 ffi_type **arg_types;
752 int i, avn, argn, seen_int;
753
754 cif = closure->cif;
755 avalue = alloca (cif->nargs * sizeof (ffi_arg));
756 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
757
758 seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
759 argn = 0;
760
761 if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
762 {
763 rvalue = (void *)(UINT32)ar[0];
764 argn = 1;
765 }
766
767 i = 0;
768 avn = cif->nargs;
769 arg_types = cif->arg_types;
770
771 while (i < avn)
772 {
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))
777 {
778 #if defined(__MIPSEB__) || defined(_MIPSEB)
779 if (arg_types[i]->type == FFI_TYPE_FLOAT)
780 avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
781 else
782 #endif
783 avaluep[i] = (char *) &fpr[i];
784 }
785 else
786 {
787 if (arg_types[i]->alignment == 8 && (argn & 0x1))
788 argn++;
789 switch (arg_types[i]->type)
790 {
791 case FFI_TYPE_SINT8:
792 avaluep[i] = &avalue[i];
793 *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
794 break;
795
796 case FFI_TYPE_UINT8:
797 avaluep[i] = &avalue[i];
798 *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
799 break;
800
801 case FFI_TYPE_SINT16:
802 avaluep[i] = &avalue[i];
803 *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
804 break;
805
806 case FFI_TYPE_UINT16:
807 avaluep[i] = &avalue[i];
808 *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
809 break;
810
811 default:
812 avaluep[i] = (char *) &ar[argn];
813 break;
814 }
815 seen_int = 1;
816 }
817 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
818 i++;
819 }
820
821 /* Invoke the closure. */
822 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
823
824 if (cif->abi == FFI_O32_SOFT_FLOAT)
825 {
826 switch (cif->rtype->type)
827 {
828 case FFI_TYPE_FLOAT:
829 return FFI_TYPE_INT;
830 case FFI_TYPE_DOUBLE:
831 return FFI_TYPE_UINT64;
832 default:
833 return cif->rtype->type;
834 }
835 }
836 else
837 {
838 return cif->rtype->type;
839 }
840 }
841
842 #if defined(FFI_MIPS_N32)
843
844 static void
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)
848 {
849 ffi_type **elt_typep = type->elements;
850 while(*elt_typep)
851 {
852 ffi_type *elt_type = *elt_typep;
853 unsigned o;
854 char *tp;
855 char *argp;
856 char *fpp;
857
858 o = ALIGN(offset, elt_type->alignment);
859 arg_offset += o - offset;
860 offset = o;
861 argn += arg_offset / sizeof(ffi_arg);
862 arg_offset = arg_offset % sizeof(ffi_arg);
863
864 argp = (char *)(ar + argn);
865 fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
866
867 tp = target + offset;
868
869 if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
870 *(double *)tp = *(double *)fpp;
871 else
872 memcpy(tp, argp + arg_offset, elt_type->size);
873
874 offset += elt_type->size;
875 arg_offset += elt_type->size;
876 elt_typep++;
877 argn += arg_offset / sizeof(ffi_arg);
878 arg_offset = arg_offset % sizeof(ffi_arg);
879 }
880 }
881
882 /*
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.
887 *
888 * RVALUE is the location where the function return value will be
889 * stored. CLOSURE is the prepared closure to invoke.
890 *
891 * This function should only be called from assembly, which is in
892 * turn called from a trampoline.
893 *
894 * Returns the function return flags.
895 *
896 */
897 int
898 ffi_closure_mips_inner_N32 (ffi_closure *closure,
899 void *rvalue, ffi_arg *ar,
900 ffi_arg *fpr)
901 {
902 ffi_cif *cif;
903 void **avaluep;
904 ffi_arg *avalue;
905 ffi_type **arg_types;
906 int i, avn, argn;
907 int soft_float;
908 ffi_arg *argp;
909
910 cif = closure->cif;
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));
915
916 argn = 0;
917
918 if (cif->rstruct_flag)
919 {
920 #if _MIPS_SIM==_ABIN32
921 rvalue = (void *)(UINT32)ar[0];
922 #else /* N64 */
923 rvalue = (void *)ar[0];
924 #endif
925 argn = 1;
926 }
927
928 i = 0;
929 avn = cif->nargs;
930 arg_types = cif->arg_types;
931
932 while (i < avn)
933 {
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)
937 {
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)))
940 {
941 argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment);
942 argn++;
943 }
944 #if defined(__MIPSEB__) || defined(_MIPSEB)
945 if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
946 avaluep[i] = ((char *) argp) + sizeof (float);
947 else
948 #endif
949 avaluep[i] = (char *) argp;
950 }
951 else
952 {
953 unsigned type = arg_types[i]->type;
954
955 if (arg_types[i]->alignment > sizeof(ffi_arg))
956 argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
957
958 argp = ar + argn;
959
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;
964
965 if (soft_float && type == FFI_TYPE_FLOAT)
966 type = FFI_TYPE_UINT32;
967
968 switch (type)
969 {
970 case FFI_TYPE_SINT8:
971 avaluep[i] = &avalue[i];
972 *(SINT8 *) &avalue[i] = (SINT8) *argp;
973 break;
974
975 case FFI_TYPE_UINT8:
976 avaluep[i] = &avalue[i];
977 *(UINT8 *) &avalue[i] = (UINT8) *argp;
978 break;
979
980 case FFI_TYPE_SINT16:
981 avaluep[i] = &avalue[i];
982 *(SINT16 *) &avalue[i] = (SINT16) *argp;
983 break;
984
985 case FFI_TYPE_UINT16:
986 avaluep[i] = &avalue[i];
987 *(UINT16 *) &avalue[i] = (UINT16) *argp;
988 break;
989
990 case FFI_TYPE_SINT32:
991 avaluep[i] = &avalue[i];
992 *(SINT32 *) &avalue[i] = (SINT32) *argp;
993 break;
994
995 case FFI_TYPE_UINT32:
996 avaluep[i] = &avalue[i];
997 *(UINT32 *) &avalue[i] = (UINT32) *argp;
998 break;
999
1000 case FFI_TYPE_STRUCT:
1001 if (argn < 8)
1002 {
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);
1008
1009 break;
1010 }
1011 /* Else fall through. */
1012 default:
1013 avaluep[i] = (char *) argp;
1014 break;
1015 }
1016 }
1017 argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
1018 i++;
1019 }
1020
1021 /* Invoke the closure. */
1022 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
1023
1024 return cif->flags >> (FFI_FLAG_BITS * 8);
1025 }
1026
1027 #endif /* FFI_MIPS_N32 */
1028
1029 #endif /* FFI_CLOSURES */