/[dotgnu-pnet]/pnet/libffi/src/x86/ffi.c
ViewVC logotype

Diff of /pnet/libffi/src/x86/ffi.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by ktreichel, Sat Jul 30 19:00:15 2005 UTC revision 1.6 by ktreichel, Wed Aug 17 19:27:01 2005 UTC
# Line 241  void ffi_call(/*@dependent@*/ ffi_cif *c Line 241  void ffi_call(/*@dependent@*/ ffi_cif *c
241    
242  static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,  static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
243                                           void** args, ffi_cif* cif);                                           void** args, ffi_cif* cif);
244  static void ffi_closure_SYSV (ffi_closure *)  void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
245       __attribute__ ((regparm(1)));       __attribute__ ((regparm(1)));
246  static void ffi_closure_raw_SYSV (ffi_raw_closure *)  unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
247         __attribute__ ((regparm(1)));
248    void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
249       __attribute__ ((regparm(1)));       __attribute__ ((regparm(1)));
250    
251  /* This function is jumped to by the trampoline */  /* This function is jumped to by the trampoline */
252    
253  static void  unsigned int FFI_HIDDEN
254  ffi_closure_SYSV (closure)  ffi_closure_SYSV_inner (closure, respp, args)
255       ffi_closure *closure;       ffi_closure *closure;
256         void **respp;
257         void *args;
258  {  {
   // this is our return value storage  
   long double    res;  
   
259    // our various things...    // our various things...
260    ffi_cif       *cif;    ffi_cif       *cif;
261    void         **arg_area;    void         **arg_area;
   unsigned short rtype;  
   void          *resp = (void*)&res;  
   void *args = __builtin_dwarf_cfa ();  
262    
263    cif         = closure->cif;    cif         = closure->cif;
264    arg_area    = (void**) alloca (cif->nargs * sizeof (void*));      arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
# Line 271  ffi_closure_SYSV (closure) Line 269  ffi_closure_SYSV (closure)
269     * a structure, it will re-set RESP to point to the     * a structure, it will re-set RESP to point to the
270     * structure return address.  */     * structure return address.  */
271    
272    ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif);    ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
     
   (closure->fun) (cif, resp, arg_area, closure->user_data);  
273    
274    rtype = cif->flags;    (closure->fun) (cif, *respp, arg_area, closure->user_data);
275    
276    /* now, do a generic return based on the value of rtype */    return cif->flags;
   if (rtype == FFI_TYPE_INT)  
     {  
       asm ("movl (%0),%%eax" : : "r" (resp) : "eax");  
     }  
   else if (rtype == FFI_TYPE_FLOAT)  
     {  
       asm ("flds (%0)" : : "r" (resp) : "st" );  
     }  
   else if (rtype == FFI_TYPE_DOUBLE)  
     {  
       asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );  
     }  
   else if (rtype == FFI_TYPE_LONGDOUBLE)  
     {  
       asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );  
     }  
   else if (rtype == FFI_TYPE_SINT64)  
     {  
       asm ("movl 0(%0),%%eax;"  
            "movl 4(%0),%%edx"  
            : : "r"(resp)  
            : "eax", "edx");  
     }  
 #ifdef X86_WIN32  
   else if (rtype == FFI_TYPE_SINT8) /* 1-byte struct  */  
     {  
       asm ("movsbl (%0),%%eax" : : "r" (resp) : "eax");  
     }  
   else if (rtype == FFI_TYPE_SINT16) /* 2-bytes struct */  
     {  
       asm ("movswl (%0),%%eax" : : "r" (resp) : "eax");  
     }  
 #endif  
277  }  }
278    
279  /*@-exportheader@*/  /*@-exportheader@*/
# Line 394  ffi_prep_closure (ffi_closure* closure, Line 357  ffi_prep_closure (ffi_closure* closure,
357    
358  #if !FFI_NO_RAW_API  #if !FFI_NO_RAW_API
359    
 static void  
 ffi_closure_raw_SYSV (closure)  
      ffi_raw_closure *closure;  
 {  
   // this is our return value storage  
   long double    res;  
   
   // our various things...  
   ffi_raw         *raw_args;  
   ffi_cif         *cif;  
   unsigned short   rtype;  
   void            *resp = (void*)&res;  
   
   /* get the cif */  
   cif = closure->cif;  
   
   /* the SYSV/X86 abi matches the RAW API exactly, well.. almost */  
   raw_args = (ffi_raw*) __builtin_dwarf_cfa ();  
   
   (closure->fun) (cif, resp, raw_args, closure->user_data);  
   
   rtype = cif->flags;  
   
   /* now, do a generic return based on the value of rtype */  
   if (rtype == FFI_TYPE_INT)  
     {  
       asm ("movl (%0),%%eax" : : "r" (resp) : "eax");  
     }  
   else if (rtype == FFI_TYPE_FLOAT)  
     {  
       asm ("flds (%0)" : : "r" (resp) : "st" );  
     }  
   else if (rtype == FFI_TYPE_DOUBLE)  
     {  
       asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );  
     }  
   else if (rtype == FFI_TYPE_LONGDOUBLE)  
     {  
       asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );  
     }  
   else if (rtype == FFI_TYPE_SINT64)  
     {  
       asm ("movl 0(%0),%%eax; movl 4(%0),%%edx"  
            : : "r"(resp)  
            : "eax", "edx");  
     }  
 }  
   
   
   
   
360  ffi_status  ffi_status
361  ffi_prep_raw_closure (ffi_raw_closure* closure,  ffi_prep_raw_closure (ffi_raw_closure* closure,
362                        ffi_cif* cif,                        ffi_cif* cif,

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26