diff options
Diffstat (limited to 'Modules/_ctypes/libffi/src/xtensa')
-rw-r--r-- | Modules/_ctypes/libffi/src/xtensa/ffi.c | 298 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/xtensa/ffitarget.h | 53 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/xtensa/sysv.S | 253 |
3 files changed, 0 insertions, 604 deletions
diff --git a/Modules/_ctypes/libffi/src/xtensa/ffi.c b/Modules/_ctypes/libffi/src/xtensa/ffi.c deleted file mode 100644 index fd94dafbe3..0000000000 --- a/Modules/_ctypes/libffi/src/xtensa/ffi.c +++ /dev/null @@ -1,298 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2013 Tensilica, Inc. - - XTENSA 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. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> - -/* - |----------------------------------------| - | | - on entry to ffi_call ----> |----------------------------------------| - | caller stack frame for registers a0-a3 | - |----------------------------------------| - | | - | additional arguments | - entry of the function ---> |----------------------------------------| - | copy of function arguments a2-a7 | - | - - - - - - - - - - - - - | - | | - - The area below the entry line becomes the new stack frame for the function. - -*/ - - -#define FFI_TYPE_STRUCT_REGS FFI_TYPE_LAST - - -extern void ffi_call_SYSV(void *rvalue, unsigned rsize, unsigned flags, - void(*fn)(void), unsigned nbytes, extended_cif*); -extern void ffi_closure_SYSV(void) FFI_HIDDEN; - -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - switch(cif->rtype->type) { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - cif->flags = cif->rtype->type; - break; - case FFI_TYPE_VOID: - case FFI_TYPE_FLOAT: - cif->flags = FFI_TYPE_UINT32; - break; - case FFI_TYPE_DOUBLE: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - cif->flags = FFI_TYPE_UINT64; // cif->rtype->type; - break; - case FFI_TYPE_STRUCT: - cif->flags = FFI_TYPE_STRUCT; //_REGS; - /* Up to 16 bytes are returned in registers */ - if (cif->rtype->size > 4 * 4) { - /* returned structure is referenced by a register; use 8 bytes - (including 4 bytes for potential additional alignment) */ - cif->flags = FFI_TYPE_STRUCT; - cif->bytes += 8; - } - break; - - default: - cif->flags = FFI_TYPE_UINT32; - break; - } - - /* Round the stack up to a full 4 register frame, just in case - (we use this size in movsp). This way, it's also a multiple of - 8 bytes for 64-bit arguments. */ - cif->bytes = ALIGN(cif->bytes, 16); - - return FFI_OK; -} - -void ffi_prep_args(extended_cif *ecif, unsigned char* stack) -{ - unsigned int i; - unsigned long *addr; - ffi_type **ptr; - - union { - void **v; - char **c; - signed char **sc; - unsigned char **uc; - signed short **ss; - unsigned short **us; - unsigned int **i; - long long **ll; - float **f; - double **d; - } p_argv; - - /* Verify that everything is aligned up properly */ - FFI_ASSERT (((unsigned long) stack & 0x7) == 0); - - p_argv.v = ecif->avalue; - addr = (unsigned long*)stack; - - /* structures with a size greater than 16 bytes are passed in memory */ - if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && ecif->cif->rtype->size > 16) - { - *addr++ = (unsigned long)ecif->rvalue; - } - - for (i = ecif->cif->nargs, ptr = ecif->cif->arg_types; - i > 0; - i--, ptr++, p_argv.v++) - { - switch ((*ptr)->type) - { - case FFI_TYPE_SINT8: - *addr++ = **p_argv.sc; - break; - case FFI_TYPE_UINT8: - *addr++ = **p_argv.uc; - break; - case FFI_TYPE_SINT16: - *addr++ = **p_argv.ss; - break; - case FFI_TYPE_UINT16: - *addr++ = **p_argv.us; - break; - case FFI_TYPE_FLOAT: - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: - *addr++ = **p_argv.i; - break; - case FFI_TYPE_DOUBLE: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - if (((unsigned long)addr & 4) != 0) - addr++; - *(unsigned long long*)addr = **p_argv.ll; - addr += sizeof(unsigned long long) / sizeof (addr); - break; - - case FFI_TYPE_STRUCT: - { - unsigned long offs; - unsigned long size; - - if (((unsigned long)addr & 4) != 0 && (*ptr)->alignment > 4) - addr++; - - offs = (unsigned long) addr - (unsigned long) stack; - size = (*ptr)->size; - - /* Entire structure must fit the argument registers or referenced */ - if (offs < FFI_REGISTER_NARGS * 4 - && offs + size > FFI_REGISTER_NARGS * 4) - addr = (unsigned long*) (stack + FFI_REGISTER_NARGS * 4); - - memcpy((char*) addr, *p_argv.c, size); - addr += (size + 3) / 4; - break; - } - - default: - FFI_ASSERT(0); - } - } -} - - -void ffi_call(ffi_cif* cif, void(*fn)(void), void *rvalue, void **avalue) -{ - extended_cif ecif; - unsigned long rsize = cif->rtype->size; - int flags = cif->flags; - void *alloc = NULL; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* Note that for structures that are returned in registers (size <= 16 bytes) - we allocate a temporary buffer and use memcpy to copy it to the final - destination. The reason is that the target address might be misaligned or - the length not a multiple of 4 bytes. Handling all those cases would be - very complex. */ - - if (flags == FFI_TYPE_STRUCT && (rsize <= 16 || rvalue == NULL)) - { - alloc = alloca(ALIGN(rsize, 4)); - ecif.rvalue = alloc; - } - else - { - ecif.rvalue = rvalue; - } - - if (cif->abi != FFI_SYSV) - FFI_ASSERT(0); - - ffi_call_SYSV (ecif.rvalue, rsize, cif->flags, fn, cif->bytes, &ecif); - - if (alloc != NULL && rvalue != NULL) - memcpy(rvalue, alloc, rsize); -} - -extern void ffi_trampoline(); -extern void ffi_cacheflush(void* start, void* end); - -ffi_status -ffi_prep_closure_loc (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data, - void *codeloc) -{ - /* copye trampoline to stack and patch 'ffi_closure_SYSV' pointer */ - memcpy(closure->tramp, ffi_trampoline, FFI_TRAMPOLINE_SIZE); - *(unsigned int*)(&closure->tramp[8]) = (unsigned int)ffi_closure_SYSV; - - // Do we have this function? - // __builtin___clear_cache(closer->tramp, closer->tramp + FFI_TRAMPOLINE_SIZE) - ffi_cacheflush(closure->tramp, closure->tramp + FFI_TRAMPOLINE_SIZE); - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - return FFI_OK; -} - - -long FFI_HIDDEN -ffi_closure_SYSV_inner(ffi_closure *closure, void **values, void *rvalue) -{ - ffi_cif *cif; - ffi_type **arg_types; - void **avalue; - int i, areg; - - cif = closure->cif; - if (cif->abi != FFI_SYSV) - return FFI_BAD_ABI; - - areg = 0; - - int rtype = cif->rtype->type; - if (rtype == FFI_TYPE_STRUCT && cif->rtype->size > 4 * 4) - { - rvalue = *values; - areg++; - } - - cif = closure->cif; - arg_types = cif->arg_types; - avalue = alloca(cif->nargs * sizeof(void *)); - - for (i = 0; i < cif->nargs; i++) - { - if (arg_types[i]->alignment == 8 && (areg & 1) != 0) - areg++; - - // skip the entry 16,a1 framework, add 16 bytes (4 registers) - if (areg == FFI_REGISTER_NARGS) - areg += 4; - - if (arg_types[i]->type == FFI_TYPE_STRUCT) - { - int numregs = ((arg_types[i]->size + 3) & ~3) / 4; - if (areg < FFI_REGISTER_NARGS && areg + numregs > FFI_REGISTER_NARGS) - areg = FFI_REGISTER_NARGS + 4; - } - - avalue[i] = &values[areg]; - areg += (arg_types[i]->size + 3) / 4; - } - - (closure->fun)(cif, rvalue, avalue, closure->user_data); - - return rtype; -} diff --git a/Modules/_ctypes/libffi/src/xtensa/ffitarget.h b/Modules/_ctypes/libffi/src/xtensa/ffitarget.h deleted file mode 100644 index 0ba728bc94..0000000000 --- a/Modules/_ctypes/libffi/src/xtensa/ffitarget.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 2013 Tensilica, Inc. - Target configuration macros for XTENSA. - - 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. - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -#ifndef LIBFFI_H -#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." -#endif - -#ifndef LIBFFI_ASM -typedef unsigned long ffi_arg; -typedef signed long ffi_sarg; - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - FFI_SYSV, - FFI_LAST_ABI, - FFI_DEFAULT_ABI = FFI_SYSV -} ffi_abi; -#endif - -#define FFI_REGISTER_NARGS 6 - -/* ---- Definitions for closures ----------------------------------------- */ - -#define FFI_CLOSURES 1 -#define FFI_NATIVE_RAW_API 0 -#define FFI_TRAMPOLINE_SIZE 24 - -#endif diff --git a/Modules/_ctypes/libffi/src/xtensa/sysv.S b/Modules/_ctypes/libffi/src/xtensa/sysv.S deleted file mode 100644 index 64e6a0918d..0000000000 --- a/Modules/_ctypes/libffi/src/xtensa/sysv.S +++ /dev/null @@ -1,253 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 2013 Tensilica, Inc. - - XTENSA 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> - -#define ENTRY(name) .text; .globl name; .type name,@function; .align 4; name: -#define END(name) .size name , . - name - -/* Assert that the table below is in sync with ffi.h. */ - -#if FFI_TYPE_UINT8 != 5 \ - || FFI_TYPE_SINT8 != 6 \ - || FFI_TYPE_UINT16 != 7 \ - || FFI_TYPE_SINT16 != 8 \ - || FFI_TYPE_UINT32 != 9 \ - || FFI_TYPE_SINT32 != 10 \ - || FFI_TYPE_UINT64 != 11 -#error "xtensa/sysv.S out of sync with ffi.h" -#endif - - -/* ffi_call_SYSV (rvalue, rbytes, flags, (*fnaddr)(), bytes, ecif) - void *rvalue; a2 - unsigned long rbytes; a3 - unsigned flags; a4 - void (*fnaddr)(); a5 - unsigned long bytes; a6 - extended_cif* ecif) a7 -*/ - -ENTRY(ffi_call_SYSV) - - entry a1, 32 # 32 byte frame for using call8 below - - mov a10, a7 # a10(->arg0): ecif - sub a11, a1, a6 # a11(->arg1): stack pointer - mov a7, a1 # fp - movsp a1, a11 # set new sp = old_sp - bytes - - movi a8, ffi_prep_args - callx8 a8 # ffi_prep_args(ecif, stack) - - # prepare to move stack pointer back up to 6 arguments - # note that 'bytes' is already aligned - - movi a10, 6*4 - sub a11, a6, a10 - movgez a6, a10, a11 - add a6, a1, a6 - - - # we can pass up to 6 arguments in registers - # for simplicity, just load 6 arguments - # (the stack size is at least 32 bytes, so no risk to cross boundaries) - - l32i a10, a1, 0 - l32i a11, a1, 4 - l32i a12, a1, 8 - l32i a13, a1, 12 - l32i a14, a1, 16 - l32i a15, a1, 20 - - # move stack pointer - - movsp a1, a6 - - callx8 a5 # (*fn)(args...) - - # Handle return value(s) - - beqz a2, .Lexit - - movi a5, FFI_TYPE_STRUCT - bne a4, a5, .Lstore - movi a5, 16 - blt a5, a3, .Lexit - - s32i a10, a2, 0 - blti a3, 5, .Lexit - addi a3, a3, -1 - s32i a11, a2, 4 - blti a3, 8, .Lexit - s32i a12, a2, 8 - blti a3, 12, .Lexit - s32i a13, a2, 12 - -.Lexit: retw - -.Lstore: - addi a4, a4, -FFI_TYPE_UINT8 - bgei a4, 7, .Lexit # should never happen - movi a6, store_calls - add a4, a4, a4 - addx4 a6, a4, a6 # store_table + idx * 8 - jx a6 - - .align 8 -store_calls: - # UINT8 - s8i a10, a2, 0 - retw - - # SINT8 - .align 8 - s8i a10, a2, 0 - retw - - # UINT16 - .align 8 - s16i a10, a2, 0 - retw - - # SINT16 - .align 8 - s16i a10, a2, 0 - retw - - # UINT32 - .align 8 - s32i a10, a2, 0 - retw - - # SINT32 - .align 8 - s32i a10, a2, 0 - retw - - # UINT64 - .align 8 - s32i a10, a2, 0 - s32i a11, a2, 4 - retw - -END(ffi_call_SYSV) - - -/* - * void ffi_cacheflush (unsigned long start, unsigned long end) - */ - -#define EXTRA_ARGS_SIZE 24 - -ENTRY(ffi_cacheflush) - - entry a1, 16 - -1: dhwbi a2, 0 - ihi a2, 0 - addi a2, a2, 4 - blt a2, a3, 1b - - retw - -END(ffi_cacheflush) - -/* ffi_trampoline is copied to the stack */ - -ENTRY(ffi_trampoline) - - entry a1, 16 + (FFI_REGISTER_NARGS * 4) + (4 * 4) # [ 0] - j 2f # [ 3] - .align 4 # [ 6] -1: .long 0 # [ 8] -2: l32r a15, 1b # [12] - _mov a14, a0 # [15] - callx0 a15 # [18] - # [21] -END(ffi_trampoline) - -/* - * ffi_closure() - * - * a0: closure + 21 - * a14: return address (a0) - */ - -ENTRY(ffi_closure_SYSV) - - /* intentionally omitting entry here */ - - # restore return address (a0) and move pointer to closure to a10 - addi a10, a0, -21 - mov a0, a14 - - # allow up to 4 arguments as return values - addi a11, a1, 4 * 4 - - # save up to 6 arguments to stack (allocated by entry below) - s32i a2, a11, 0 - s32i a3, a11, 4 - s32i a4, a11, 8 - s32i a5, a11, 12 - s32i a6, a11, 16 - s32i a7, a11, 20 - - movi a8, ffi_closure_SYSV_inner - mov a12, a1 - callx8 a8 # .._inner(*closure, **avalue, *rvalue) - - # load up to four return arguments - l32i a2, a1, 0 - l32i a3, a1, 4 - l32i a4, a1, 8 - l32i a5, a1, 12 - - # (sign-)extend return value - movi a11, FFI_TYPE_UINT8 - bne a10, a11, 1f - extui a2, a2, 0, 8 - retw - -1: movi a11, FFI_TYPE_SINT8 - bne a10, a11, 1f - sext a2, a2, 7 - retw - -1: movi a11, FFI_TYPE_UINT16 - bne a10, a11, 1f - extui a2, a2, 0, 16 - retw - -1: movi a11, FFI_TYPE_SINT16 - bne a10, a11, 1f - sext a2, a2, 15 - -1: retw - -END(ffi_closure_SYSV) |