1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2011 Anthony Green
3 Copyright (c) 2008 David Daney
4 Copyright (c) 1996, 2007, 2008, 2011 Red Hat, Inc.
5
6 MIPS Foreign Function Interface
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 ``Software''), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice shall be included
17 in all copies or substantial portions of the Software.
18
19 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 DEALINGS IN THE SOFTWARE.
27 ----------------------------------------------------------------------- */
28
29 #include <ffi.h>
30 #include <ffi_common.h>
31
32 #include <stdint.h>
33 #include <stdlib.h>
34
35 #ifdef __GNUC__
36 # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
37 # define USE__BUILTIN___CLEAR_CACHE 1
38 # endif
39 #endif
40
41 #ifndef USE__BUILTIN___CLEAR_CACHE
42 # if defined(__FreeBSD__)
43 # include <machine/sysarch.h>
44 # elif defined(__OpenBSD__)
45 # include <mips64/sysarch.h>
46 # else
47 # include <sys/cachectl.h>
48 # endif
49 #endif
50
51 #ifdef FFI_DEBUG
52 # define FFI_MIPS_STOP_HERE() ffi_stop_here()
53 #else
54 # define FFI_MIPS_STOP_HERE() do {} while(0)
55 #endif
56
57 #ifdef FFI_MIPS_N32
58 #define FIX_ARGP \
59 FFI_ASSERT(argp <= &stack[bytes]); \
60 if (argp == &stack[bytes]) \
61 { \
62 argp = stack; \
63 FFI_MIPS_STOP_HERE(); \
64 }
65 #else
66 #define FIX_ARGP
67 #endif
68
69
70 /* ffi_prep_args is called by the assembly routine once stack space
71 has been allocated for the function's arguments */
72
73 static void ffi_prep_args(char *stack,
74 extended_cif *ecif,
75 int bytes,
76 int flags)
77 {
78 int i;
79 void **p_argv;
80 char *argp;
81 ffi_type **p_arg;
82
83 #ifdef FFI_MIPS_N32
84 /* If more than 8 double words are used, the remainder go
85 on the stack. We reorder stuff on the stack here to
86 support this easily. */
87 if (bytes > 8 * sizeof(ffi_arg))
88 argp = &stack[bytes - (8 * sizeof(ffi_arg))];
89 else
90 argp = stack;
91 #else
92 argp = stack;
93 #endif
94
95 memset(stack, 0, bytes);
96
97 #ifdef FFI_MIPS_N32
98 if ( ecif->cif->rstruct_flag != 0 )
99 #else
100 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
101 #endif
102 {
103 *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
104 argp += sizeof(ffi_arg);
105 FIX_ARGP;
106 }
107
108 p_argv = ecif->avalue;
109
110 for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++)
111 {
112 size_t z;
113 unsigned int a;
114
115 /* Align if necessary. */
116 a = (*p_arg)->alignment;
117 if (a < sizeof(ffi_arg))
118 a = sizeof(ffi_arg);
119
120 if ((a - 1) & (unsigned long) argp)
121 {
122 argp = (char *) FFI_ALIGN(argp, a);
123 FIX_ARGP;
124 }
125
126 z = (*p_arg)->size;
127 if (z <= sizeof(ffi_arg))
128 {
129 int type = (*p_arg)->type;
130 z = sizeof(ffi_arg);
131
132 /* The size of a pointer depends on the ABI */
133 if (type == FFI_TYPE_POINTER)
134 type = (ecif->cif->abi == FFI_N64
135 || ecif->cif->abi == FFI_N64_SOFT_FLOAT)
136 ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
137
138 if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT
139 || ecif->cif->abi == FFI_N64_SOFT_FLOAT))
140 {
141 switch (type)
142 {
143 case FFI_TYPE_FLOAT:
144 type = FFI_TYPE_UINT32;
145 break;
146 case FFI_TYPE_DOUBLE:
147 type = FFI_TYPE_UINT64;
148 break;
149 default:
150 break;
151 }
152 }
153 switch (type)
154 {
155 case FFI_TYPE_SINT8:
156 *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
157 break;
158
159 case FFI_TYPE_UINT8:
160 *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
161 break;
162
163 case FFI_TYPE_SINT16:
164 *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
165 break;
166
167 case FFI_TYPE_UINT16:
168 *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
169 break;
170
171 case FFI_TYPE_SINT32:
172 *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
173 break;
174
175 case FFI_TYPE_UINT32:
176 #ifdef FFI_MIPS_N32
177 /* The N32 ABI requires that 32-bit integers
178 be sign-extended to 64-bits, regardless of
179 whether they are signed or unsigned. */
180 *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
181 #else
182 *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
183 #endif
184 break;
185
186 /* This can only happen with 64bit slots. */
187 case FFI_TYPE_FLOAT:
188 *(float *) argp = *(float *)(* p_argv);
189 break;
190
191 /* Handle structures. */
192 default:
193 memcpy(argp, *p_argv, (*p_arg)->size);
194 break;
195 }
196 }
197 else
198 {
199 #ifdef FFI_MIPS_O32
200 memcpy(argp, *p_argv, z);
201 #else
202 {
203 unsigned long end = (unsigned long) argp + z;
204 unsigned long cap = (unsigned long) stack + bytes;
205
206 /* Check if the data will fit within the register space.
207 Handle it if it doesn't. */
208
209 if (end <= cap)
210 memcpy(argp, *p_argv, z);
211 else
212 {
213 unsigned long portion = cap - (unsigned long)argp;
214
215 memcpy(argp, *p_argv, portion);
216 argp = stack;
217 z -= portion;
218 memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),
219 z);
220 }
221 }
222 #endif
223 }
224 p_argv++;
225 argp += z;
226 FIX_ARGP;
227 }
228 }
229
230 #ifdef FFI_MIPS_N32
231
232 /* The n32 spec says that if "a chunk consists solely of a double
233 float field (but not a double, which is part of a union), it
234 is passed in a floating point register. Any other chunk is
235 passed in an integer register". This code traverses structure
236 definitions and generates the appropriate flags. */
237
238 static unsigned
239 calc_n32_struct_flags(int soft_float, ffi_type *arg,
240 unsigned *loc, unsigned *arg_reg)
241 {
242 unsigned flags = 0;
243 unsigned index = 0;
244
245 ffi_type *e;
246
247 if (soft_float)
248 return 0;
249
250 while ((e = arg->elements[index]))
251 {
252 /* Align this object. */
253 *loc = FFI_ALIGN(*loc, e->alignment);
254 if (e->type == FFI_TYPE_DOUBLE)
255 {
256 /* Already aligned to FFI_SIZEOF_ARG. */
257 *arg_reg = *loc / FFI_SIZEOF_ARG;
258 if (*arg_reg > 7)
259 break;
260 flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));
261 *loc += e->size;
262 }
263 else
264 *loc += e->size;
265 index++;
266 }
267 /* Next Argument register at alignment of FFI_SIZEOF_ARG. */
268 *arg_reg = FFI_ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
269
270 return flags;
271 }
272
273 static unsigned
274 calc_n32_return_struct_flags(int soft_float, ffi_type *arg)
275 {
276 unsigned flags = 0;
277 unsigned small = FFI_TYPE_SMALLSTRUCT;
278 ffi_type *e;
279
280 /* Returning structures under n32 is a tricky thing.
281 A struct with only one or two floating point fields
282 is returned in $f0 (and $f2 if necessary). Any other
283 struct results at most 128 bits are returned in $2
284 (the first 64 bits) and $3 (remainder, if necessary).
285 Larger structs are handled normally. */
286
287 if (arg->size > 16)
288 return 0;
289
290 if (arg->size > 8)
291 small = FFI_TYPE_SMALLSTRUCT2;
292
293 e = arg->elements[0];
294
295 if (e->type == FFI_TYPE_DOUBLE)
296 flags = FFI_TYPE_DOUBLE;
297 else if (e->type == FFI_TYPE_FLOAT)
298 flags = FFI_TYPE_FLOAT;
299
300 if (flags && (e = arg->elements[1]))
301 {
302 if (e->type == FFI_TYPE_DOUBLE)
303 flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
304 else if (e->type == FFI_TYPE_FLOAT)
305 flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS;
306 else
307 return small;
308
309 if (flags && (arg->elements[2]))
310 {
311 /* There are three arguments and the first two are
312 floats! This must be passed the old way. */
313 return small;
314 }
315 if (soft_float)
316 flags += FFI_TYPE_STRUCT_SOFT;
317 }
318 else
319 if (!flags)
320 return small;
321
322 return flags;
323 }
324
325 #endif
326
327 /* Perform machine dependent cif processing */
328 static ffi_status ffi_prep_cif_machdep_int(ffi_cif *cif, unsigned nfixedargs)
329 {
330 cif->flags = 0;
331 cif->mips_nfixedargs = nfixedargs;
332
333 #ifdef FFI_MIPS_O32
334 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
335 * does not have special handling for floating point args.
336 */
337
338 if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
339 {
340 if (cif->nargs > 0 && cif->nargs == nfixedargs)
341 {
342 switch ((cif->arg_types)[0]->type)
343 {
344 case FFI_TYPE_FLOAT:
345 case FFI_TYPE_DOUBLE:
346 cif->flags += (cif->arg_types)[0]->type;
347 break;
348
349 default:
350 break;
351 }
352
353 if (cif->nargs > 1)
354 {
355 /* Only handle the second argument if the first
356 is a float or double. */
357 if (cif->flags)
358 {
359 switch ((cif->arg_types)[1]->type)
360 {
361 case FFI_TYPE_FLOAT:
362 case FFI_TYPE_DOUBLE:
363 cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
364 break;
365
366 default:
367 break;
368 }
369 }
370 }
371 }
372 }
373
374 /* Set the return type flag */
375
376 if (cif->abi == FFI_O32_SOFT_FLOAT)
377 {
378 switch (cif->rtype->type)
379 {
380 case FFI_TYPE_VOID:
381 case FFI_TYPE_STRUCT:
382 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
383 break;
384
385 case FFI_TYPE_SINT64:
386 case FFI_TYPE_UINT64:
387 case FFI_TYPE_DOUBLE:
388 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
389 break;
390
391 case FFI_TYPE_FLOAT:
392 default:
393 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
394 break;
395 }
396 }
397 else
398 {
399 /* FFI_O32 */
400 switch (cif->rtype->type)
401 {
402 case FFI_TYPE_VOID:
403 case FFI_TYPE_STRUCT:
404 case FFI_TYPE_FLOAT:
405 case FFI_TYPE_DOUBLE:
406 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
407 break;
408
409 case FFI_TYPE_SINT64:
410 case FFI_TYPE_UINT64:
411 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
412 break;
413
414 default:
415 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
416 break;
417 }
418 }
419 #endif
420
421 #ifdef FFI_MIPS_N32
422 /* Set the flags necessary for N32 processing */
423 {
424 int type;
425 unsigned arg_reg = 0;
426 unsigned loc = 0;
427 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
428 unsigned index = 0;
429
430 unsigned struct_flags = 0;
431 int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT
432 || cif->abi == FFI_N64_SOFT_FLOAT);
433
434 if (cif->rtype->type == FFI_TYPE_STRUCT)
435 {
436 struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
437
438 if (struct_flags == 0)
439 {
440 /* This means that the structure is being passed as
441 a hidden argument */
442
443 arg_reg = 1;
444 count = (cif->nargs < 7) ? cif->nargs : 7;
445
446 cif->rstruct_flag = !0;
447 }
448 else
449 cif->rstruct_flag = 0;
450 }
451 else
452 cif->rstruct_flag = 0;
453
454 while (count-- > 0 && arg_reg < 8)
455 {
456 type = (cif->arg_types)[index]->type;
457
458 // Pass variadic arguments in integer registers even if they're floats
459 if (soft_float || index >= nfixedargs)
460 {
461 switch (type)
462 {
463 case FFI_TYPE_FLOAT:
464 type = FFI_TYPE_UINT32;
465 break;
466 case FFI_TYPE_DOUBLE:
467 type = FFI_TYPE_UINT64;
468 break;
469 default:
470 break;
471 }
472 }
473 switch (type)
474 {
475 case FFI_TYPE_FLOAT:
476 case FFI_TYPE_DOUBLE:
477 cif->flags +=
478 ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS));
479 arg_reg++;
480 break;
481 case FFI_TYPE_LONGDOUBLE:
482 /* Align it. */
483 arg_reg = FFI_ALIGN(arg_reg, 2);
484 /* Treat it as two adjacent doubles. */
485 if (soft_float || index >= nfixedargs)
486 {
487 arg_reg += 2;
488 }
489 else
490 {
491 cif->flags +=
492 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
493 arg_reg++;
494 cif->flags +=
495 (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
496 arg_reg++;
497 }
498 break;
499
500 case FFI_TYPE_STRUCT:
501 loc = arg_reg * FFI_SIZEOF_ARG;
502 cif->flags += calc_n32_struct_flags(soft_float || index >= nfixedargs,
503 (cif->arg_types)[index],
504 &loc, &arg_reg);
505 break;
506
507 default:
508 arg_reg++;
509 break;
510 }
511
512 index++;
513 }
514
515 /* Set the return type flag */
516 switch (cif->rtype->type)
517 {
518 case FFI_TYPE_STRUCT:
519 {
520 if (struct_flags == 0)
521 {
522 /* The structure is returned through a hidden
523 first argument. Do nothing, 'cause FFI_TYPE_VOID
524 is 0 */
525 }
526 else
527 {
528 /* The structure is returned via some tricky
529 mechanism */
530 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
531 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
532 }
533 break;
534 }
535
536 case FFI_TYPE_VOID:
537 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
538 break;
539
540 case FFI_TYPE_POINTER:
541 if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32)
542 cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
543 else
544 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
545 break;
546
547 case FFI_TYPE_FLOAT:
548 if (soft_float)
549 {
550 cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
551 break;
552 }
553 /* else fall through */
554 case FFI_TYPE_DOUBLE:
555 if (soft_float)
556 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
557 else
558 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
559 break;
560
561 case FFI_TYPE_LONGDOUBLE:
562 /* Long double is returned as if it were a struct containing
563 two doubles. */
564 if (soft_float)
565 {
566 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
567 cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8));
568 }
569 else
570 {
571 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
572 cif->flags += (FFI_TYPE_DOUBLE
573 + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
574 << (4 + (FFI_FLAG_BITS * 8));
575 }
576 break;
577 default:
578 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
579 break;
580 }
581 }
582 #endif
583
584 return FFI_OK;
585 }
586
587 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
588 {
589 return ffi_prep_cif_machdep_int(cif, cif->nargs);
590 }
591
592 ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
593 unsigned nfixedargs,
594 unsigned ntotalargs MAYBE_UNUSED)
595 {
596 return ffi_prep_cif_machdep_int(cif, nfixedargs);
597 }
598
599 /* Low level routine for calling O32 functions */
600 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
601 extended_cif *, unsigned,
602 unsigned, unsigned *, void (*)(void), void *closure);
603
604 /* Low level routine for calling N32 functions */
605 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
606 extended_cif *, unsigned,
607 unsigned, void *, void (*)(void), void *closure);
608
609 void ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue,
610 void **avalue, void *closure)
611 {
612 extended_cif ecif;
613
614 ecif.cif = cif;
615 ecif.avalue = avalue;
616
617 /* If the return value is a struct and we don't have a return */
618 /* value address then we need to make one */
619
620 if ((rvalue == NULL) &&
621 (cif->rtype->type == FFI_TYPE_STRUCT))
622 ecif.rvalue = alloca(cif->rtype->size);
623 else
624 ecif.rvalue = rvalue;
625
626 switch (cif->abi)
627 {
628 #ifdef FFI_MIPS_O32
629 case FFI_O32:
630 case FFI_O32_SOFT_FLOAT:
631 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
632 cif->flags, ecif.rvalue, fn, closure);
633 break;
634 #endif
635
636 #ifdef FFI_MIPS_N32
637 case FFI_N32:
638 case FFI_N32_SOFT_FLOAT:
639 case FFI_N64:
640 case FFI_N64_SOFT_FLOAT:
641 {
642 int copy_rvalue = 0;
643 int copy_offset = 0;
644 char *rvalue_copy = ecif.rvalue;
645 if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
646 {
647 /* For structures smaller than 16 bytes we clobber memory
648 in 8 byte increments. Make a copy so we don't clobber
649 the callers memory outside of the struct bounds. */
650 rvalue_copy = alloca(16);
651 copy_rvalue = 1;
652 }
653 else if (cif->rtype->type == FFI_TYPE_FLOAT
654 && (cif->abi == FFI_N64_SOFT_FLOAT
655 || cif->abi == FFI_N32_SOFT_FLOAT))
656 {
657 rvalue_copy = alloca (8);
658 copy_rvalue = 1;
659 #if defined(__MIPSEB__) || defined(_MIPSEB)
660 copy_offset = 4;
661 #endif
662 }
663 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
664 cif->flags, rvalue_copy, fn, closure);
665 if (copy_rvalue)
666 memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
667 }
668 break;
669 #endif
670
671 default:
672 FFI_ASSERT(0);
673 break;
674 }
675 }
676
677 void
678 ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
679 {
680 ffi_call_int (cif, fn, rvalue, avalue, NULL);
681 }
682
683 void
684 ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
685 void **avalue, void *closure)
686 {
687 ffi_call_int (cif, fn, rvalue, avalue, closure);
688 }
689
690
691 #if FFI_CLOSURES
692 #if defined(FFI_MIPS_O32)
693 extern void ffi_closure_O32(void);
694 extern void ffi_go_closure_O32(void);
695 #else
696 extern void ffi_closure_N32(void);
697 extern void ffi_go_closure_N32(void);
698 #endif /* FFI_MIPS_O32 */
699
700 ffi_status
701 ffi_prep_closure_loc (ffi_closure *closure,
702 ffi_cif *cif,
703 void (*fun)(ffi_cif*,void*,void**,void*),
704 void *user_data,
705 void *codeloc)
706 {
707 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
708 void * fn;
709 char *clear_location = (char *) codeloc;
710
711 #if defined(FFI_MIPS_O32)
712 if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT)
713 return FFI_BAD_ABI;
714 fn = ffi_closure_O32;
715 #else
716 #if _MIPS_SIM ==_ABIN32
717 if (cif->abi != FFI_N32
718 && cif->abi != FFI_N32_SOFT_FLOAT)
719 return FFI_BAD_ABI;
720 #else
721 if (cif->abi != FFI_N64
722 && cif->abi != FFI_N64_SOFT_FLOAT)
723 return FFI_BAD_ABI;
724 #endif
725 fn = ffi_closure_N32;
726 #endif /* FFI_MIPS_O32 */
727
728 #if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
729 /* lui $25,high(fn) */
730 tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
731 /* ori $25,low(fn) */
732 tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
733 /* lui $12,high(codeloc) */
734 tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
735 /* jr $25 */
736 #if !defined(__mips_isa_rev) || (__mips_isa_rev<6)
737 tramp[3] = 0x03200008;
738 #else
739 tramp[3] = 0x03200009;
740 #endif
741 /* ori $12,low(codeloc) */
742 tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
743 #else
744 /* N64 has a somewhat larger trampoline. */
745 /* lui $25,high(fn) */
746 tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);
747 /* lui $12,high(codeloc) */
748 tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);
749 /* ori $25,mid-high(fn) */
750 tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);
751 /* ori $12,mid-high(codeloc) */
752 tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);
753 /* dsll $25,$25,16 */
754 tramp[4] = 0x0019cc38;
755 /* dsll $12,$12,16 */
756 tramp[5] = 0x000c6438;
757 /* ori $25,mid-low(fn) */
758 tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);
759 /* ori $12,mid-low(codeloc) */
760 tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);
761 /* dsll $25,$25,16 */
762 tramp[8] = 0x0019cc38;
763 /* dsll $12,$12,16 */
764 tramp[9] = 0x000c6438;
765 /* ori $25,low(fn) */
766 tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff);
767 /* jr $25 */
768 #if !defined(__mips_isa_rev) || (__mips_isa_rev<6)
769 tramp[11] = 0x03200008;
770 #else
771 tramp[11] = 0x03200009;
772 #endif
773 /* ori $12,low(codeloc) */
774 tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
775
776 #endif
777
778 closure->cif = cif;
779 closure->fun = fun;
780 closure->user_data = user_data;
781
782 #if !defined(__FreeBSD__)
783 #ifdef USE__BUILTIN___CLEAR_CACHE
784 __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
785 #else
786 cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE);
787 #endif
788 #endif /* ! __FreeBSD__ */
789 return FFI_OK;
790 }
791
792 /*
793 * Decodes the arguments to a function, which will be stored on the
794 * stack. AR is the pointer to the beginning of the integer arguments
795 * (and, depending upon the arguments, some floating-point arguments
796 * as well). FPR is a pointer to the area where floating point
797 * registers have been saved, if any.
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 type.
806 *
807 * Based on the similar routine for sparc.
808 */
809 int
810 ffi_closure_mips_inner_O32 (ffi_cif *cif,
811 void (*fun)(ffi_cif*, void*, void**, void*),
812 void *user_data,
813 void *rvalue, ffi_arg *ar,
814 double *fpr)
815 {
816 void **avaluep;
817 ffi_arg *avalue;
818 ffi_type **arg_types;
819 int i, avn, argn, seen_int;
820
821 avalue = alloca (cif->nargs * sizeof (ffi_arg));
822 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
823
824 seen_int = (cif->abi == FFI_O32_SOFT_FLOAT) || (cif->mips_nfixedargs != cif->nargs);
825 argn = 0;
826
827 if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
828 {
829 rvalue = (void *)(uintptr_t)ar[0];
830 argn = 1;
831 seen_int = 1;
832 }
833
834 i = 0;
835 avn = cif->nargs;
836 arg_types = cif->arg_types;
837
838 while (i < avn)
839 {
840 if (arg_types[i]->alignment == 8 && (argn & 0x1))
841 argn++;
842 if (i < 2 && !seen_int &&
843 (arg_types[i]->type == FFI_TYPE_FLOAT ||
844 arg_types[i]->type == FFI_TYPE_DOUBLE ||
845 arg_types[i]->type == FFI_TYPE_LONGDOUBLE))
846 {
847 #if defined(__MIPSEB__) || defined(_MIPSEB)
848 if (arg_types[i]->type == FFI_TYPE_FLOAT)
849 avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
850 else
851 #endif
852 avaluep[i] = (char *) &fpr[i];
853 }
854 else
855 {
856 switch (arg_types[i]->type)
857 {
858 case FFI_TYPE_SINT8:
859 avaluep[i] = &avalue[i];
860 *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
861 break;
862
863 case FFI_TYPE_UINT8:
864 avaluep[i] = &avalue[i];
865 *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
866 break;
867
868 case FFI_TYPE_SINT16:
869 avaluep[i] = &avalue[i];
870 *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
871 break;
872
873 case FFI_TYPE_UINT16:
874 avaluep[i] = &avalue[i];
875 *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
876 break;
877
878 default:
879 avaluep[i] = (char *) &ar[argn];
880 break;
881 }
882 seen_int = 1;
883 }
884 argn += FFI_ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
885 i++;
886 }
887
888 /* Invoke the closure. */
889 fun(cif, rvalue, avaluep, user_data);
890
891 if (cif->abi == FFI_O32_SOFT_FLOAT)
892 {
893 switch (cif->rtype->type)
894 {
895 case FFI_TYPE_FLOAT:
896 return FFI_TYPE_INT;
897 case FFI_TYPE_DOUBLE:
898 return FFI_TYPE_UINT64;
899 default:
900 return cif->rtype->type;
901 }
902 }
903 else
904 {
905 return cif->rtype->type;
906 }
907 }
908
909 #if defined(FFI_MIPS_N32)
910
911 static void
912 copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
913 int argn, unsigned arg_offset, ffi_arg *ar,
914 ffi_arg *fpr, int soft_float)
915 {
916 ffi_type **elt_typep = type->elements;
917 while(*elt_typep)
918 {
919 ffi_type *elt_type = *elt_typep;
920 unsigned o;
921 char *tp;
922 char *argp;
923 char *fpp;
924
925 o = FFI_ALIGN(offset, elt_type->alignment);
926 arg_offset += o - offset;
927 offset = o;
928 argn += arg_offset / sizeof(ffi_arg);
929 arg_offset = arg_offset % sizeof(ffi_arg);
930
931 argp = (char *)(ar + argn);
932 fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
933
934 tp = target + offset;
935
936 if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
937 *(double *)tp = *(double *)fpp;
938 else
939 memcpy(tp, argp + arg_offset, elt_type->size);
940
941 offset += elt_type->size;
942 arg_offset += elt_type->size;
943 elt_typep++;
944 argn += arg_offset / sizeof(ffi_arg);
945 arg_offset = arg_offset % sizeof(ffi_arg);
946 }
947 }
948
949 /*
950 * Decodes the arguments to a function, which will be stored on the
951 * stack. AR is the pointer to the beginning of the integer
952 * arguments. FPR is a pointer to the area where floating point
953 * registers have been saved.
954 *
955 * RVALUE is the location where the function return value will be
956 * stored. CLOSURE is the prepared closure to invoke.
957 *
958 * This function should only be called from assembly, which is in
959 * turn called from a trampoline.
960 *
961 * Returns the function return flags.
962 *
963 */
964 int
965 ffi_closure_mips_inner_N32 (ffi_cif *cif,
966 void (*fun)(ffi_cif*, void*, void**, void*),
967 void *user_data,
968 void *rvalue, ffi_arg *ar,
969 ffi_arg *fpr)
970 {
971 void **avaluep;
972 ffi_arg *avalue;
973 ffi_type **arg_types;
974 int i, avn, argn;
975 int soft_float;
976 ffi_arg *argp;
977
978 soft_float = cif->abi == FFI_N64_SOFT_FLOAT
979 || cif->abi == FFI_N32_SOFT_FLOAT;
980 avalue = alloca (cif->nargs * sizeof (ffi_arg));
981 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
982
983 argn = 0;
984
985 if (cif->rstruct_flag)
986 {
987 #if _MIPS_SIM==_ABIN32
988 rvalue = (void *)(UINT32)ar[0];
989 #else /* N64 */
990 rvalue = (void *)ar[0];
991 #endif
992 argn = 1;
993 }
994
995 i = 0;
996 avn = cif->nargs;
997 arg_types = cif->arg_types;
998
999 while (i < avn)
1000 {
1001 if (arg_types[i]->type == FFI_TYPE_FLOAT
1002 || arg_types[i]->type == FFI_TYPE_DOUBLE
1003 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE)
1004 {
1005 argp = (argn >= 8 || i >= cif->mips_nfixedargs || soft_float) ? ar + argn : fpr + argn;
1006 if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((uintptr_t)argp & (arg_types[i]->alignment-1)))
1007 {
1008 argp=(ffi_arg*)FFI_ALIGN(argp,arg_types[i]->alignment);
1009 argn++;
1010 }
1011 #if defined(__MIPSEB__) || defined(_MIPSEB)
1012 if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
1013 avaluep[i] = ((char *) argp) + sizeof (float);
1014 else
1015 #endif
1016 avaluep[i] = (char *) argp;
1017 }
1018 else
1019 {
1020 unsigned type = arg_types[i]->type;
1021
1022 if (arg_types[i]->alignment > sizeof(ffi_arg))
1023 argn = FFI_ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
1024
1025 argp = ar + argn;
1026
1027 /* The size of a pointer depends on the ABI */
1028 if (type == FFI_TYPE_POINTER)
1029 type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT)
1030 ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
1031
1032 if (soft_float && type == FFI_TYPE_FLOAT)
1033 type = FFI_TYPE_UINT32;
1034
1035 switch (type)
1036 {
1037 case FFI_TYPE_SINT8:
1038 avaluep[i] = &avalue[i];
1039 *(SINT8 *) &avalue[i] = (SINT8) *argp;
1040 break;
1041
1042 case FFI_TYPE_UINT8:
1043 avaluep[i] = &avalue[i];
1044 *(UINT8 *) &avalue[i] = (UINT8) *argp;
1045 break;
1046
1047 case FFI_TYPE_SINT16:
1048 avaluep[i] = &avalue[i];
1049 *(SINT16 *) &avalue[i] = (SINT16) *argp;
1050 break;
1051
1052 case FFI_TYPE_UINT16:
1053 avaluep[i] = &avalue[i];
1054 *(UINT16 *) &avalue[i] = (UINT16) *argp;
1055 break;
1056
1057 case FFI_TYPE_SINT32:
1058 avaluep[i] = &avalue[i];
1059 *(SINT32 *) &avalue[i] = (SINT32) *argp;
1060 break;
1061
1062 case FFI_TYPE_UINT32:
1063 avaluep[i] = &avalue[i];
1064 *(UINT32 *) &avalue[i] = (UINT32) *argp;
1065 break;
1066
1067 case FFI_TYPE_STRUCT:
1068 if (argn < 8)
1069 {
1070 /* Allocate space for the struct as at least part of
1071 it was passed in registers. */
1072 avaluep[i] = alloca(arg_types[i]->size);
1073 copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
1074 argn, 0, ar, fpr, i >= cif->mips_nfixedargs || soft_float);
1075
1076 break;
1077 }
1078 /* Else fall through. */
1079 default:
1080 avaluep[i] = (char *) argp;
1081 break;
1082 }
1083 }
1084 argn += FFI_ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
1085 i++;
1086 }
1087
1088 /* Invoke the closure. */
1089 fun (cif, rvalue, avaluep, user_data);
1090
1091 return cif->flags >> (FFI_FLAG_BITS * 8);
1092 }
1093
1094 #endif /* FFI_MIPS_N32 */
1095
1096 #if defined(FFI_MIPS_O32)
1097 extern void ffi_closure_O32(void);
1098 extern void ffi_go_closure_O32(void);
1099 #else
1100 extern void ffi_closure_N32(void);
1101 extern void ffi_go_closure_N32(void);
1102 #endif /* FFI_MIPS_O32 */
1103
1104 ffi_status
1105 ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
1106 void (*fun)(ffi_cif*,void*,void**,void*))
1107 {
1108 void * fn;
1109
1110 #if defined(FFI_MIPS_O32)
1111 if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT)
1112 return FFI_BAD_ABI;
1113 fn = ffi_go_closure_O32;
1114 #else
1115 #if _MIPS_SIM ==_ABIN32
1116 if (cif->abi != FFI_N32
1117 && cif->abi != FFI_N32_SOFT_FLOAT)
1118 return FFI_BAD_ABI;
1119 #else
1120 if (cif->abi != FFI_N64
1121 && cif->abi != FFI_N64_SOFT_FLOAT)
1122 return FFI_BAD_ABI;
1123 #endif
1124 fn = ffi_go_closure_N32;
1125 #endif /* FFI_MIPS_O32 */
1126
1127 closure->tramp = (void *)fn;
1128 closure->cif = cif;
1129 closure->fun = fun;
1130
1131 return FFI_OK;
1132 }
1133
1134 #endif /* FFI_CLOSURES */