/Modules/_ctypes/libffi/src/m68k/sysv.S
http://unladen-swallow.googlecode.com/ · Assembly · 234 lines · 179 code · 29 blank · 26 comment · 5 complexity · 9de0630e99a0b634afe5519c60c2be86 MD5 · raw file
- /* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 1998 Andreas Schwab
- Copyright (c) 2008 Red Hat, Inc.
-
- m68k Foreign Function Interface
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #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
- #if defined __ELF__ && defined __linux__
- .section .note.GNU-stack,"",@progbits
- #endif