123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /* -----------------------------------------------------------------------
- sysv.S
- CSKY 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>
- .macro CSKY_FUNC_START name
- .text
- .align 2
- .globl \name
- .type \name, @function
- \name:
- .endm
- #ifdef __CSKYABIV2__
- /*
- * a0: fn
- * a1: &ecif
- * a2: cif->bytes
- * a3: fig->flags
- * sp+0: ecif.rvalue
- */
- CSKY_FUNC_START ffi_call_SYSV
- /* Save registers */
- .cfi_startproc
- subi sp, 28
- .cfi_def_cfa_offset 28
- stw a0, (sp, 0x0)
- .cfi_offset 0, -28
- stw a1, (sp, 0x4)
- .cfi_offset 1, -24
- stw a2, (sp, 0x8)
- .cfi_offset 2, -20
- stw a3, (sp, 0xC)
- .cfi_offset 3, -16
- stw l0, (sp, 0x10)
- .cfi_offset 4, -12
- stw l1, (sp, 0x14)
- .cfi_offset 5, -8
- stw lr, (sp, 0x18)
- .cfi_offset 15, -4
- mov l0, sp
- .cfi_def_cfa_register 4
- /* Make room for all of the new args. */
- subu sp, sp, a2
- /* Place all of the ffi_prep_args in position */
- mov a0, sp
- /* a1 already set */
- /* Call ffi_prep_args(stack, &ecif) */
- jsri ffi_prep_args
- /* move first 4 parameters in registers */
- ldw a0, (sp, 0x0)
- ldw a1, (sp, 0x4)
- ldw a2, (sp, 0x8)
- ldw a3, (sp, 0xC)
- /* and adjust stack */
- subu lr, l0, sp /* cif->bytes == l0 - sp */
- cmphsi lr, 16
- movi l1, 16
- movt lr, l1
- addu sp, sp, lr
- ldw l1, (l0, 0) /* load fn() in advance */
- /* call (fn) (...) */
- jsr l1
- /* Remove the space we pushed for the args */
- mov sp, l0
- /* Load r2 with the pointer to storage for the return value */
- ldw a2, (sp, 0x1C)
- /* Load r3 with the return type code */
- ldw a3, (sp, 0xC)
- /* If the return value pointer is NULL, assume no return value. */
- cmpnei a2, 0
- bf .Lepilogue
- cmpnei a3, FFI_TYPE_STRUCT
- bf .Lepilogue
- /* return INT64 */
- cmpnei a3, FFI_TYPE_SINT64
- bt .Lretint
- /* stw a0, (a2, 0x0) at .Lretint */
- stw a1, (a2, 0x4)
- .Lretint:
- /* return INT */
- stw a0, (a2, 0x0)
- .Lepilogue:
- ldw a0, (sp, 0x0)
- ldw a1, (sp, 0x4)
- ldw a2, (sp, 0x8)
- ldw a3, (sp, 0xC)
- ldw l0, (sp, 0x10)
- ldw l1, (sp, 0x14)
- ldw lr, (sp, 0x18)
- addi sp, sp, 28
- rts
- .cfi_endproc
- .size ffi_call_SYSV, .-ffi_call_SYSV
- /*
- * unsigned int FFI_HIDDEN
- * ffi_closure_SYSV_inner (closure, respp, args)
- * ffi_closure *closure;
- * void **respp;
- * void *args;
- */
- CSKY_FUNC_START ffi_closure_SYSV
- .cfi_startproc
- mov a2, sp
- addi a1, sp, 16
- subi sp, sp, 24
- .cfi_def_cfa_offset 40
- stw a1, (sp, 0x10)
- .cfi_offset 1, -24
- stw lr, (sp, 0x14)
- .cfi_offset 15, -20
- stw sp, (sp, 0x8)
- addi a1, sp, 8
- jsri ffi_closure_SYSV_inner
- ldw a0, (sp, 0x0)
- /*
- * if FFI_TYPE_SINT64, need a1.
- * if FFI_TYPE_INT, ignore a1.
- */
- ldw a1, (sp, 0x4)
- ldw lr, (sp, 0x14)
- addi sp, sp, 40
- rts
- .cfi_endproc
- .size ffi_closure_SYSV, .-ffi_closure_SYSV
- CSKY_FUNC_START ffi_csky_trampoline
- subi sp, sp, 16
- stw a0, (sp, 0x0)
- stw a1, (sp, 0x4)
- stw a2, (sp, 0x8)
- stw a3, (sp, 0xC)
- lrw a0, [.Lctx]
- lrw a1, [.Lfun]
- jmp a1
- .Lctx:
- mov a0, a0
- mov a0, a0
- .Lfun:
- .size ffi_csky_trampoline, .-ffi_csky_trampoline
- CSKY_FUNC_START ffi_csky_cacheflush
- mov t0, r7
- movi r7, 123
- trap 0
- mov r7, t0
- rts
- .size ffi_csky_cacheflush, .-ffi_csky_cacheflush
- #else /* !__CSKYABIV2__ */
- /*
- * a0: fn
- * a1: &ecif
- * a2: cif->bytes
- * a3: fig->flags
- * a4: ecif.rvalue
- */
- CSKY_FUNC_START ffi_call_SYSV
- /* Save registers */
- .cfi_startproc
- subi sp, 32
- subi sp, 8
- .cfi_def_cfa_offset 40
- stw a0, (sp, 0x0)
- .cfi_offset 2, -40
- stw a1, (sp, 0x4)
- .cfi_offset 3, -36
- stw a2, (sp, 0x8)
- .cfi_offset 4, -32
- stw a3, (sp, 0xC)
- .cfi_offset 5, -28
- stw a4, (sp, 0x10)
- .cfi_offset 6, -24
- stw a5, (sp, 0x14)
- .cfi_offset 7, -20
- stw l0, (sp, 0x18)
- .cfi_offset 8, -16
- stw l1, (sp, 0x1C)
- .cfi_offset 9, -12
- stw lr, (sp, 0x20)
- .cfi_offset 15, -8
- mov l0, sp
- .cfi_def_cfa_register 8
- /* Make room for all of the new args. */
- subu sp, sp, a2
- /* Place all of the ffi_prep_args in position */
- mov a0, sp
- /* a1 already set */
- /* Call ffi_prep_args(stack, &ecif) */
- jsri ffi_prep_args
- /* move first 4 parameters in registers */
- ldw a0, (sp, 0x0)
- ldw a1, (sp, 0x4)
- ldw a2, (sp, 0x8)
- ldw a3, (sp, 0xC)
- ldw a4, (sp, 0x10)
- ldw a5, (sp, 0x14)
- /* and adjust stack */
- mov lr, l0
- subu lr, sp /* cif->bytes == l0 - sp */
- movi l1, 24
- cmphs lr, l1
- movt lr, l1
- addu sp, sp, lr
- ldw l1, (l0, 0) /* load fn() in advance */
- /* call (fn) (...) */
- jsr l1
- /* Remove the space we pushed for the args */
- mov sp, l0
- /* Load r2 with the pointer to storage for the return value */
- ldw a2, (sp, 0x10)
- /* Load r3 with the return type code */
- ldw a3, (sp, 0xC)
- /* If the return value pointer is NULL, assume no return value. */
- cmpnei a2, 0
- bf .Lepilogue
- cmpnei a3, FFI_TYPE_STRUCT
- bf .Lepilogue
- /* return INT64 */
- cmpnei a3, FFI_TYPE_SINT64
- bt .Lretint
- /* stw a0, (a2, 0x0) at .Lretint */
- stw a1, (a2, 0x4)
- .Lretint:
- /* return INT */
- stw a0, (a2, 0x0)
- .Lepilogue:
- ldw a0, (sp, 0x0)
- ldw a1, (sp, 0x4)
- ldw a2, (sp, 0x8)
- ldw a3, (sp, 0xC)
- ldw a4, (sp, 0x10)
- ldw a5, (sp, 0x14)
- ldw l0, (sp, 0x18)
- ldw l1, (sp, 0x1C)
- ldw lr, (sp, 0x20)
- addi sp, sp, 32
- addi sp, sp, 8
- rts
- .cfi_endproc
- .size ffi_call_SYSV, .-ffi_call_SYSV
- /*
- * unsigned int FFI_HIDDEN
- * ffi_closure_SYSV_inner (closure, respp, args)
- * ffi_closure *closure;
- * void **respp;
- * void *args;
- */
- CSKY_FUNC_START ffi_closure_SYSV
- .cfi_startproc
- mov a2, sp
- mov a1, sp
- addi a1, 24
- subi sp, sp, 24
- .cfi_def_cfa_offset 48
- stw a1, (sp, 0x10)
- .cfi_offset 3, -32
- stw lr, (sp, 0x14)
- .cfi_offset 15, -28
- stw sp, (sp, 0x8)
- mov a1, sp
- addi a1, 8
- jsri ffi_closure_SYSV_inner
- ldw a0, (sp, 0x0)
- /*
- * if FFI_TYPE_SINT64, need a1.
- * if FFI_TYPE_INT, ignore a1.
- */
- ldw a1, (sp, 0x4)
- ldw lr, (sp, 0x14)
- addi sp, sp, 24
- addi sp, sp, 24
- rts
- .cfi_endproc
- .size ffi_closure_SYSV, .-ffi_closure_SYSV
- CSKY_FUNC_START ffi_csky_trampoline
- subi sp, 24
- stw a0, (sp, 0x0)
- stw a1, (sp, 0x4)
- stw a2, (sp, 0x8)
- stw a3, (sp, 0xC)
- stw a4, (sp, 0x10)
- stw a5, (sp, 0x14)
- lrw a0, [.Lctx]
- lrw a1, [.Lfun]
- jmp a1
- .Lctx:
- mov a0, a0
- mov a0, a0
- .Lfun:
- .size ffi_csky_trampoline, .-ffi_csky_trampoline
- CSKY_FUNC_START ffi_csky_cacheflush
- lrw r1, 123
- trap 0
- rts
- .size ffi_csky_cacheflush, .-ffi_csky_cacheflush
- #endif /* __CSKYABIV2__ */
|