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

📄 ffi_darwin.c

📁 this gcc-g++-3.3.1.tar.gz is a source file of gcc, you can learn more about gcc through this codes f
💻 C
📖 第 1 页 / 共 2 页
字号:
    {      /*@-sysunrecog@*/      ecif.rvalue = alloca(cif->rtype->size);      /*@=sysunrecog@*/    }  else    ecif.rvalue = rvalue;      switch (cif->abi)     {    case FFI_AIX:      /*@-usedef@*/      ffi_call_AIX(&ecif, -cif->bytes, 		   cif->flags, ecif.rvalue, fn, ffi_prep_args);      /*@=usedef@*/      break;    case FFI_DARWIN:      /*@-usedef@*/      ffi_call_DARWIN(&ecif, -cif->bytes, 		      cif->flags, ecif.rvalue, fn, ffi_prep_args);      /*@=usedef@*/      break;    default:      FFI_ASSERT(0);      break;    }}static void flush_icache(char *);static void flush_range(char *, int);   /* The layout of a function descriptor.  A C function pointer really    *//* points to one of these.                                              */typedef struct aix_fd_struct {    void *code_pointer;    void *toc;} aix_fd;/* here I'd like to add the stack frame layout we use in darwin_closure.S * and aix_clsoure.S */* SP previous -> +---------------------------------------+ <--- child frame                  | back chain to caller 4                |                   +---------------------------------------+ 4                  | saved CR 4                            |                   +---------------------------------------+ 8                   | saved LR 4                            |                   +---------------------------------------+ 12                  | reserved for compilers 4              |                   +---------------------------------------+ 16                  | reserved for binders 4                |                   +---------------------------------------+ 20                  | saved TOC pointer 4                   |                   +---------------------------------------+ 24                  | always reserved 8*4=32 (previous GPRs)|                   | according to the linkage convention   |                  | from AIX                              |                  +---------------------------------------+ 56                  | our FPR area 13*8=104                 |                  | f1                                    |                  | .                                     |                  | f13                                   |                   +---------------------------------------+ 160                  | result area 8                         |                  +---------------------------------------+ 168                  | alignement to the next multiple of 16 |SP current -->    +---------------------------------------+ 176 <- parent frame                  | back chain to caller 4                |                   +---------------------------------------+ 180                  | saved CR 4                            |                   +---------------------------------------+ 184                  | saved LR 4                            |                   +---------------------------------------+ 188                  | reserved for compilers 4              |                   +---------------------------------------+ 192                  | reserved for binders 4                |                   +---------------------------------------+ 196                  | saved TOC pointer 4                   |                   +---------------------------------------+ 200                  | always reserved 8*4=32  we store our  |                  | GPRs here                             |                  | r3                                    |                  | .                                     |                  | r10                                   |                  +---------------------------------------+ 232                  | PST area, overflow part               |                   +---------------------------------------+ xxx                  | ????                                  |                   +---------------------------------------+ xxx*/ffi_statusffi_prep_closure (ffi_closure* closure,                      ffi_cif* cif,                  void (*fun)(ffi_cif*, void*, void**, void*),                  void *user_data){  unsigned int *tramp;  struct ffi_aix_trampoline_struct *tramp_aix;  aix_fd *fd;   switch (cif->abi)    {      case FFI_DARWIN:      FFI_ASSERT (cif->abi == FFI_DARWIN);      tramp = (unsigned int *) &closure->tramp[0];      tramp[0] = 0x7c0802a6;  /*   mflr    r0 */      tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */      tramp[4] = 0x7d6802a6;  /*   mflr    r11 */      tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11)  /* function address */      tramp[6] = 0x7c0803a6;  /*   mtlr    r0  */      tramp[7] = 0x7d8903a6;  /*   mtctr   r12 */      tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11)  /* static chain */      tramp[9] = 0x4e800420;  /*   bctr */      *(void **) &tramp[2] = (void *)ffi_closure_ASM; /* function */      *(void **) &tramp[3] = (void *)closure;          /* context */      closure->cif = cif;      closure->fun = fun;      closure->user_data = user_data;      /* Flush the icache. Only necessary on Darwin  */      flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);           break;    case FFI_AIX:      tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);      fd = (aix_fd *)(void *)ffi_closure_ASM;      FFI_ASSERT (cif->abi == FFI_AIX);      tramp_aix->code_pointer = fd->code_pointer;      tramp_aix->toc = fd->toc;      tramp_aix->static_chain = closure;      closure->cif = cif;      closure->fun = fun;      closure->user_data = user_data;    default:      FFI_ASSERT(0);      break;    }  return FFI_OK;}static voidflush_icache(char *addr){#ifndef _AIX  __asm__ volatile (                "dcbf 0,%0;"                "sync;"                "icbi 0,%0;"                "sync;"                "isync;"                : : "r"(addr) : "memory");#endif}static voidflush_range(char * addr1, int size){#define MIN_LINE_SIZE 32  int i;  for (i = 0; i < size; i += MIN_LINE_SIZE)    flush_icache(addr1+i);  flush_icache(addr1+size-1);}int ffi_closure_helper_DARWIN (ffi_closure*, void*, unsigned long*,                                     unsigned long*, unsigned long*);/* Basically the trampoline invokes ffi_closure_ASM, and on * entry, r11 holds the address of the closure. * After storing the registers that could possibly contain * parameters to be passed into the stack frame and setting * up space for a return value, ffi_closure_ASM invokes the * following helper function to do most of the work */intffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,            unsigned long * pgr, unsigned long * pfr,            unsigned long * pst){  /* rvalue is the pointer to space for return value in closure assembly */  /* pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM */  /* pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM */  /* pst is the pointer to outgoing parameter stack in original caller */  void **          avalue;  ffi_type **      arg_types;  long             i, avn;  long             nf;   /* number of floating registers already used */  long             ng;   /* number of general registers already used */  ffi_cif *        cif;  double           temp;  cif = closure->cif;  avalue = alloca(cif->nargs * sizeof(void *));  nf = 0;  ng = 0;  /* Copy the caller's structure return value address so that the closure     returns the data directly to the caller.  */  if (cif->rtype->type == FFI_TYPE_STRUCT)    {      rvalue = (void *)pgr;      ng++;            pgr++;    }  i = 0;  avn = cif->nargs;  arg_types = cif->arg_types;  /* Grab the addresses of the arguments from the stack frame.  */  while (i < avn)    {      switch (arg_types[i]->type)        {        case FFI_TYPE_SINT8:        case FFI_TYPE_UINT8:        /* there are 8 gpr registers used to pass values */          if (ng < 8) {             avalue[i] = (((char *)pgr)+3);             ng++;             pgr++;          } else {             avalue[i] = (((char *)pst)+3);             pst++;          }          break;        case FFI_TYPE_SINT16:        case FFI_TYPE_UINT16:        /* there are 8 gpr registers used to pass values */          if (ng < 8) {             avalue[i] = (((char *)pgr)+2);             ng++;             pgr++;          } else {             avalue[i] = (((char *)pst)+2);             pst++;          }          break;        case FFI_TYPE_SINT32:        case FFI_TYPE_UINT32:        case FFI_TYPE_POINTER:        case FFI_TYPE_STRUCT:        /* there are 8 gpr registers used to pass values */          if (ng < 8) {               avalue[i] = pgr;             ng++;             pgr++;          } else {             avalue[i] = pst;             pst++;          }          break;        case FFI_TYPE_SINT64:        case FFI_TYPE_UINT64:          /* long long ints are passed in two gpr's if available or in            * the pst, one place is a bit odd, when a long long passes	   * the boundary between gpr and pst area we have to increment	   * the pst by one.           */           if (ng < 7) {              avalue[i] = pgr;              ng+=2;              pgr+=2;           } else if (ng == 7) {              avalue[i] = pgr;              ng++;              pgr++;              pst++;           } else {              avalue[i] = pst;              pst+=2;           }           break;        case FFI_TYPE_FLOAT:          /* a float value consumes a GPR           *           * there are 13 64bit floating point registers 	   */          	  if ((ng > 7) && (nf < 13)) {	     pst++;	  }          if (nf < 13) {	     temp = *(double*)pfr;             *(float*)pfr = (float)temp;             avalue[i] = pfr;             nf++;             pfr+=2;             ng++;	     pgr++;	                   } else {             avalue[i] = pst;             nf++;             pst++;          }          break;        case FFI_TYPE_DOUBLE:	  /* a double value consumes two GPRs           *             * there are 13 64bit floating point registers 	   */	  if ((ng == 7) && (nf < 13)) {             pst++;	/* if only one gpr is left the double steals it */	  } else if ((ng > 7) && (nf < 13)) {	     pst+=2;	/* a double consumes two GPRs in Darwin/AIX */	  }          if (nf < 13) {             avalue[i] = pfr;             nf++;             pfr+=2;	     ng+=2;	     pgr+=2;          } else {             avalue[i] = pst;             nf++;             pst+=2;          }          break;        default:          FFI_ASSERT(0);               }      i++;    }  (closure->fun) (cif, rvalue, avalue, closure->user_data);  /* Tell ffi_closure_ASM to perform return type promotions.  */  return cif->rtype->type;}

⌨️ 快捷键说明

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