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