summaryrefslogtreecommitdiff
path: root/Modules/_ctypes/libffi/src/xtensa/ffi.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_ctypes/libffi/src/xtensa/ffi.c')
-rw-r--r--Modules/_ctypes/libffi/src/xtensa/ffi.c298
1 files changed, 0 insertions, 298 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;
-}