blob: d2a4ff1c64a756686c0427ce936f9728aaf5b610 [file] [log] [blame]
/* -----------------------------------------------------------------------
sysv.S
m68k Foreign Function Interface
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
#ifdef HAVE_AS_CFI_PSEUDO_OP
#define CFI_STARTPROC() .cfi_startproc
#define CFI_OFFSET(reg,off) .cfi_offset reg,off
#define CFI_DEF_CFA(reg,off) .cfi_def_cfa reg,off
#define CFI_ENDPROC() .cfi_endproc
#else
#define CFI_STARTPROC()
#define CFI_OFFSET(reg,off)
#define CFI_DEF_CFA(reg,off)
#define CFI_ENDPROC()
#endif
.text
.globl ffi_call_SYSV
.type ffi_call_SYSV,@function
.align 4
ffi_call_SYSV:
CFI_STARTPROC()
link %fp,#0
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %d2,-(%sp)
CFI_OFFSET(2,-12)
| Make room for all of the new args.
sub.l 12(%fp),%sp
| Call ffi_prep_args
move.l 8(%fp),-(%sp)
pea 4(%sp)
#if !defined __PIC__
jsr ffi_prep_args
#else
bsr.l ffi_prep_args@PLTPC
#endif
addq.l #8,%sp
| Pass pointer to struct value, if any
move.l %a0,%a1
| Call the function
move.l 24(%fp),%a0
jsr (%a0)
| Remove the space we pushed for the args
add.l 12(%fp),%sp
| Load the pointer to storage for the return value
move.l 20(%fp),%a1
| Load the return type code
move.l 16(%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 retstruct1
move.l %a0,(%a1)
jbra epilogue
retstruct1:
btst #6,%d2
jbeq retstruct2
move.b %d0,(%a1)
jbra epilogue
retstruct2:
btst #7,%d2
jbeq noretval
move.w %d0,(%a1)
noretval:
epilogue:
move.l (%sp)+,%d2
unlk %fp
rts
CFI_ENDPROC()
.size ffi_call_SYSV,.-ffi_call_SYSV
.globl ffi_closure_SYSV
.type ffi_closure_SYSV, @function
.align 4
ffi_closure_SYSV:
CFI_STARTPROC()
link %fp,#-12
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %sp,-12(%fp)
pea 8(%fp)
pea -12(%fp)
move.l %a0,-(%sp)
#if !defined __PIC__
jsr ffi_closure_SYSV_inner
#else
bsr.l ffi_closure_SYSV_inner@PLTPC
#endif
lsr.l #1,%d0
jne 1f
jcc .Lcls_epilogue
move.l -12(%fp),%d0
.Lcls_epilogue:
unlk %fp
rts
1:
lea -12(%fp),%a0
lsr.l #2,%d0
jne 1f
jcs .Lcls_ret_float
move.l (%a0)+,%d0
move.l (%a0),%d1
jra .Lcls_epilogue
.Lcls_ret_float:
fmove.s (%a0),%fp0
jra .Lcls_epilogue
1:
lsr.l #2,%d0
jne 1f
jcs .Lcls_ret_ldouble
fmove.d (%a0),%fp0
jra .Lcls_epilogue
.Lcls_ret_ldouble:
fmove.x (%a0),%fp0
jra .Lcls_epilogue
1:
lsr.l #2,%d0
jne .Lcls_ret_struct2
jcs .Lcls_ret_struct1
move.l (%a0),%a0
move.l %a0,%d0
jra .Lcls_epilogue
.Lcls_ret_struct1:
move.b (%a0),%d0
jra .Lcls_epilogue
.Lcls_ret_struct2:
move.w (%a0),%d0
jra .Lcls_epilogue
CFI_ENDPROC()
.size ffi_closure_SYSV,.-ffi_closure_SYSV
.globl ffi_closure_struct_SYSV
.type ffi_closure_struct_SYSV, @function
.align 4
ffi_closure_struct_SYSV:
CFI_STARTPROC()
link %fp,#0
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %sp,-12(%fp)
pea 8(%fp)
move.l %a1,-(%sp)
move.l %a0,-(%sp)
#if !defined __PIC__
jsr ffi_closure_SYSV_inner
#else
bsr.l ffi_closure_SYSV_inner@PLTPC
#endif
unlk %fp
rts
CFI_ENDPROC()
.size ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV