⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ffi.c

📁 gcc的组建
💻 C
📖 第 1 页 / 共 2 页
字号:
          cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);          break;        }    }  else    {      /* FFI_O32 */            switch (cif->rtype->type)        {        case FFI_TYPE_VOID:        case FFI_TYPE_STRUCT:        case FFI_TYPE_FLOAT:        case FFI_TYPE_DOUBLE:          cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);          break;        case FFI_TYPE_SINT64:        case FFI_TYPE_UINT64:          cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);          break;              default:          cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);          break;        }    }#endif#if _MIPS_SIM == _ABIN32  /* Set the flags necessary for N32 processing */  {    unsigned shift = 0;    unsigned count = (cif->nargs < 8) ? cif->nargs : 8;    unsigned index = 0;    unsigned struct_flags = 0;    if (cif->rtype->type == FFI_TYPE_STRUCT)      {	struct_flags = calc_n32_return_struct_flags(cif->rtype);	if (struct_flags == 0)	  {	    /* This means that the structure is being passed as	       a hidden argument */	    shift = FFI_FLAG_BITS;	    count = (cif->nargs < 7) ? cif->nargs : 7;	    cif->rstruct_flag = !0;	  }	else	    cif->rstruct_flag = 0;      }    else      cif->rstruct_flag = 0;    while (count-- > 0)      {	switch ((cif->arg_types)[index]->type)	  {	  case FFI_TYPE_FLOAT:	  case FFI_TYPE_DOUBLE:	    cif->flags += ((cif->arg_types)[index]->type << shift);	    shift += FFI_FLAG_BITS;	    break;	  case FFI_TYPE_STRUCT:	    cif->flags += calc_n32_struct_flags((cif->arg_types)[index],						&shift);	    break;	  default:	    shift += FFI_FLAG_BITS;	  }	index++;      }  /* Set the return type flag */    switch (cif->rtype->type)      {      case FFI_TYPE_STRUCT:	{	  if (struct_flags == 0)	    {	      /* The structure is returned through a hidden		 first argument. Do nothing, 'cause FFI_TYPE_VOID 		 is 0 */	    }	  else	    {	      /* The structure is returned via some tricky		 mechanism */	      cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);	      cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));	    }	  break;	}            case FFI_TYPE_VOID:	/* Do nothing, 'cause FFI_TYPE_VOID is 0 */	break;	      case FFI_TYPE_FLOAT:      case FFI_TYPE_DOUBLE:	cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);	break;	      default:	cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);	break;      }  }#endif    return FFI_OK;}/* Low level routine for calling O32 functions */extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), 			extended_cif *, unsigned, 			unsigned, unsigned *, void (*)());/* Low level routine for calling N32 functions */extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), 			extended_cif *, unsigned, 			unsigned, unsigned *, void (*)());void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue){  extended_cif ecif;  ecif.cif = cif;  ecif.avalue = avalue;    /* If the return value is a struct and we don't have a return	*/  /* value address then we need to make one		        */    if ((rvalue == NULL) &&       (cif->rtype->type == FFI_TYPE_STRUCT))    ecif.rvalue = alloca(cif->rtype->size);  else    ecif.rvalue = rvalue;      switch (cif->abi)     {#if _MIPS_SIM == _ABIO32    case FFI_O32:    case FFI_O32_SOFT_FLOAT:      ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, 		   cif->flags, ecif.rvalue, fn);      break;#endif#if _MIPS_SIM == _ABIN32    case FFI_N32:      ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, 		   cif->flags, ecif.rvalue, fn);      break;#endif    default:      FFI_ASSERT(0);      break;    }}#if FFI_CLOSURES  /* N32 not implemented yet, FFI_CLOSURES not defined */#if defined(FFI_MIPS_O32)extern void ffi_closure_O32(void);#endif /* FFI_MIPS_O32 */ffi_statusffi_prep_closure (ffi_closure *closure,		  ffi_cif *cif,		  void (*fun)(ffi_cif*,void*,void**,void*),		  void *user_data){  unsigned int *tramp = (unsigned int *) &closure->tramp[0];  unsigned int fn;  unsigned int ctx = (unsigned int) closure;#if defined(FFI_MIPS_O32)  FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);  fn = (unsigned int) ffi_closure_O32;#else /* FFI_MIPS_N32 */  FFI_ASSERT(cif->abi == FFI_N32);  FFI_ASSERT(!"not implemented");#endif /* FFI_MIPS_O32 */  tramp[0] = 0x3c190000 | (fn >> 16);     /* lui  $25,high(fn) */  tramp[1] = 0x37390000 | (fn & 0xffff);  /* ori  $25,low(fn)  */  tramp[2] = 0x3c080000 | (ctx >> 16);    /* lui  $8,high(ctx) */  tramp[3] = 0x03200008;                  /* jr   $25          */  tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori  $8,low(ctx)  */  closure->cif = cif;  closure->fun = fun;  closure->user_data = user_data;  /* XXX this is available on Linux, but anything else? */  cacheflush (tramp, FFI_TRAMPOLINE_SIZE, ICACHE);  return FFI_OK;}/* * Decodes the arguments to a function, which will be stored on the * stack. AR is the pointer to the beginning of the integer arguments * (and, depending upon the arguments, some floating-point arguments * as well). FPR is a pointer to the area where floating point * registers have been saved, if any. * * RVALUE is the location where the function return value will be * stored. CLOSURE is the prepared closure to invoke. * * This function should only be called from assembly, which is in * turn called from a trampoline. * * Returns the function return type. * * Based on the similar routine for sparc. */intffi_closure_mips_inner_O32 (ffi_closure *closure,			    void *rvalue, ffi_arg *ar,			    double *fpr){  ffi_cif *cif;  void **avaluep;  ffi_arg *avalue;  ffi_type **arg_types;  int i, avn, argn, seen_int;  cif = closure->cif;  avalue = alloca (cif->nargs * sizeof (ffi_arg));  avaluep = alloca (cif->nargs * sizeof (ffi_arg));  seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);  argn = 0;  if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)    {      rvalue = (void *) ar[0];      argn = 1;    }  i = 0;  avn = cif->nargs;  arg_types = cif->arg_types;  while (i < avn)    {      if (i < 2 && !seen_int &&	  (arg_types[i]->type == FFI_TYPE_FLOAT ||	   arg_types[i]->type == FFI_TYPE_DOUBLE))	{#ifdef __MIPSEB__	  if (arg_types[i]->type == FFI_TYPE_FLOAT)	    avaluep[i] = ((char *) &fpr[i]) + sizeof (float);	  else#endif	    avaluep[i] = (char *) &fpr[i];	}      else	{	  if (arg_types[i]->alignment == 8 && (argn & 0x1))	    argn++;	  switch (arg_types[i]->type)	    {	      case FFI_TYPE_SINT8:		avaluep[i] = &avalue[i];		*(SINT8 *) &avalue[i] = (SINT8) ar[argn];		break;	      case FFI_TYPE_UINT8:		avaluep[i] = &avalue[i];		*(UINT8 *) &avalue[i] = (UINT8) ar[argn];		break;		  	      case FFI_TYPE_SINT16:		avaluep[i] = &avalue[i];		*(SINT16 *) &avalue[i] = (SINT16) ar[argn];		break;		  	      case FFI_TYPE_UINT16:		avaluep[i] = &avalue[i];		*(UINT16 *) &avalue[i] = (UINT16) ar[argn];		break;	      default:		avaluep[i] = (char *) &ar[argn];		break;	    }	  seen_int = 1;	}      argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;      i++;    }  /* Invoke the closure. */  (closure->fun) (cif, rvalue, avaluep, closure->user_data);  if (cif->abi == FFI_O32_SOFT_FLOAT)    {      switch (cif->rtype->type)        {        case FFI_TYPE_FLOAT:          return FFI_TYPE_INT;        case FFI_TYPE_DOUBLE:          return FFI_TYPE_UINT64;        default:          return cif->rtype->type;        }    }  else    {      return cif->rtype->type;    }}#endif /* FFI_CLOSURES */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -