blob: d019a377e5b6ea248e21520852867af5c7b314eb [file] [log] [blame]
/* -----------------------------------------------------------------------
sysv.S
m68k Foreign Function Interface
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
.text
.globl ffi_call_SYSV
.type ffi_call_SYSV,@function
ffi_call_SYSV:
link %fp,#0
move.l %d2,-(%sp)
| Make room for all of the new args.
sub.l 16(%fp),%sp
| Call ffi_prep_args
move.l 12(%fp),-(%sp)
pea 4(%sp)
move.l 8(%fp),%a0
jsr (%a0)
addq.l #8,%sp
| Pass pointer to struct value, if any
move.l %a0,%a1
| Call the function
move.l 32(%fp),%a0
jsr (%a0)
| Remove the space we pushed for the args
add.l 16(%fp),%sp
| Load the pointer to storage for the return value
move.l 28(%fp),%a1
| Load the return type code
move.l 20(%fp),%d2
| If the return value pointer is NULL, assume no return value.
tst.l %a1
jbeq noretval
btst #0,%d2
jbeq retlongint
move.l %d0,(%a1)
jbra epilogue
retlongint:
btst #1,%d2
jbeq retfloat
move.l %d0,(%a1)
move.l %d1,4(%a1)
jbra epilogue
retfloat:
btst #2,%d2
jbeq retdouble
fmove.s %fp0,(%a1)
jbra epilogue
retdouble:
btst #3,%d2
jbeq retlongdouble
fmove.d %fp0,(%a1)
jbra epilogue
retlongdouble:
btst #4,%d2
jbeq retpointer
fmove.x %fp0,(%a1)
jbra epilogue
retpointer:
btst #5,%d2
jbeq retstruct
move.l %a0,(%a1)
jbra epilogue
retstruct:
btst #6,%d2
jbeq noretval
move.l 24(%fp),%d2
bfins %d0,(%a1){#0,%d2}
noretval:
epilogue:
move.l (%sp)+,%d2
unlk %a6
rts
.size ffi_call_SYSV,.-ffi_call_SYSV