| /* ----------------------------------------------------------------------- |
| 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 |