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