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*)); |
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@*/ |
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, |