summaryrefslogtreecommitdiff
path: root/Modules/_ctypes/libffi/src/tile
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_ctypes/libffi/src/tile')
-rw-r--r--Modules/_ctypes/libffi/src/tile/ffi.c355
-rw-r--r--Modules/_ctypes/libffi/src/tile/ffitarget.h65
-rw-r--r--Modules/_ctypes/libffi/src/tile/tile.S360
3 files changed, 0 insertions, 780 deletions
diff --git a/Modules/_ctypes/libffi/src/tile/ffi.c b/Modules/_ctypes/libffi/src/tile/ffi.c
deleted file mode 100644
index 3a94469c7f..0000000000
--- a/Modules/_ctypes/libffi/src/tile/ffi.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2012 Tilera Corp.
-
- TILE 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>
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <arch/abi.h>
-#include <arch/icache.h>
-#include <arch/opcode.h>
-
-
-/* The first 10 registers are used to pass arguments and return values. */
-#define NUM_ARG_REGS 10
-
-/* Performs a raw function call with the given NUM_ARG_REGS register arguments
- and the specified additional stack arguments (if any). */
-extern void ffi_call_tile(ffi_sarg reg_args[NUM_ARG_REGS],
- const ffi_sarg *stack_args,
- size_t stack_args_bytes,
- void (*fnaddr)(void))
- FFI_HIDDEN;
-
-/* This handles the raw call from the closure stub, cleaning up the
- parameters and delegating to ffi_closure_tile_inner. */
-extern void ffi_closure_tile(void) FFI_HIDDEN;
-
-
-ffi_status
-ffi_prep_cif_machdep(ffi_cif *cif)
-{
- /* We always allocate room for all registers. Even if we don't
- use them as parameters, they get returned in the same array
- as struct return values so we need to make room. */
- if (cif->bytes < NUM_ARG_REGS * FFI_SIZEOF_ARG)
- cif->bytes = NUM_ARG_REGS * FFI_SIZEOF_ARG;
-
- if (cif->rtype->size > NUM_ARG_REGS * FFI_SIZEOF_ARG)
- cif->flags = FFI_TYPE_STRUCT;
- else
- cif->flags = FFI_TYPE_INT;
-
- /* Nothing to do. */
- return FFI_OK;
-}
-
-
-static long
-assign_to_ffi_arg(ffi_sarg *out, void *in, const ffi_type *type,
- int write_to_reg)
-{
- switch (type->type)
- {
- case FFI_TYPE_SINT8:
- *out = *(SINT8 *)in;
- return 1;
-
- case FFI_TYPE_UINT8:
- *out = *(UINT8 *)in;
- return 1;
-
- case FFI_TYPE_SINT16:
- *out = *(SINT16 *)in;
- return 1;
-
- case FFI_TYPE_UINT16:
- *out = *(UINT16 *)in;
- return 1;
-
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT32:
-#ifndef __LP64__
- case FFI_TYPE_POINTER:
-#endif
- /* Note that even unsigned 32-bit quantities are sign extended
- on tilegx when stored in a register. */
- *out = *(SINT32 *)in;
- return 1;
-
- case FFI_TYPE_FLOAT:
-#ifdef __tilegx__
- if (write_to_reg)
- {
- /* Properly sign extend the value. */
- union { float f; SINT32 s32; } val;
- val.f = *(float *)in;
- *out = val.s32;
- }
- else
-#endif
- {
- *(float *)out = *(float *)in;
- }
- return 1;
-
- case FFI_TYPE_SINT64:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_DOUBLE:
-#ifdef __LP64__
- case FFI_TYPE_POINTER:
-#endif
- *(UINT64 *)out = *(UINT64 *)in;
- return sizeof(UINT64) / FFI_SIZEOF_ARG;
-
- case FFI_TYPE_STRUCT:
- memcpy(out, in, type->size);
- return (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG;
-
- case FFI_TYPE_VOID:
- /* Must be a return type. Nothing to do. */
- return 0;
-
- default:
- FFI_ASSERT(0);
- return -1;
- }
-}
-
-
-void
-ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
-{
- ffi_sarg * const arg_mem = alloca(cif->bytes);
- ffi_sarg * const reg_args = arg_mem;
- ffi_sarg * const stack_args = &reg_args[NUM_ARG_REGS];
- ffi_sarg *argp = arg_mem;
- ffi_type ** const arg_types = cif->arg_types;
- const long num_args = cif->nargs;
- long i;
-
- if (cif->flags == FFI_TYPE_STRUCT)
- {
- /* Pass a hidden pointer to the return value. We make sure there
- is scratch space for the callee to store the return value even if
- our caller doesn't care about it. */
- *argp++ = (intptr_t)(rvalue ? rvalue : alloca(cif->rtype->size));
-
- /* No more work needed to return anything. */
- rvalue = NULL;
- }
-
- for (i = 0; i < num_args; i++)
- {
- ffi_type *type = arg_types[i];
- void * const arg_in = avalue[i];
- ptrdiff_t arg_word = argp - arg_mem;
-
-#ifndef __tilegx__
- /* Doubleword-aligned values are always in an even-number register
- pair, or doubleword-aligned stack slot if out of registers. */
- long align = arg_word & (type->alignment > FFI_SIZEOF_ARG);
- argp += align;
- arg_word += align;
-#endif
-
- if (type->type == FFI_TYPE_STRUCT)
- {
- const size_t arg_size_in_words =
- (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG;
-
- if (arg_word < NUM_ARG_REGS &&
- arg_word + arg_size_in_words > NUM_ARG_REGS)
- {
- /* Args are not allowed to span registers and the stack. */
- argp = stack_args;
- }
-
- memcpy(argp, arg_in, type->size);
- argp += arg_size_in_words;
- }
- else
- {
- argp += assign_to_ffi_arg(argp, arg_in, arg_types[i], 1);
- }
- }
-
- /* Actually do the call. */
- ffi_call_tile(reg_args, stack_args,
- cif->bytes - (NUM_ARG_REGS * FFI_SIZEOF_ARG), fn);
-
- if (rvalue != NULL)
- assign_to_ffi_arg(rvalue, reg_args, cif->rtype, 0);
-}
-
-
-/* Template code for closure. */
-extern const UINT64 ffi_template_tramp_tile[] FFI_HIDDEN;
-
-
-ffi_status
-ffi_prep_closure_loc (ffi_closure *closure,
- ffi_cif *cif,
- void (*fun)(ffi_cif*, void*, void**, void*),
- void *user_data,
- void *codeloc)
-{
-#ifdef __tilegx__
- /* TILE-Gx */
- SINT64 c;
- SINT64 h;
- int s;
- UINT64 *out;
-
- if (cif->abi != FFI_UNIX)
- return FFI_BAD_ABI;
-
- out = (UINT64 *)closure->tramp;
-
- c = (intptr_t)closure;
- h = (intptr_t)ffi_closure_tile;
- s = 0;
-
- /* Find the smallest shift count that doesn't lose information
- (i.e. no need to explicitly insert high bits of the address that
- are just the sign extension of the low bits). */
- while ((c >> s) != (SINT16)(c >> s) || (h >> s) != (SINT16)(h >> s))
- s += 16;
-
-#define OPS(a, b, shift) \
- (create_Imm16_X0((a) >> (shift)) | create_Imm16_X1((b) >> (shift)))
-
- /* Emit the moveli. */
- *out++ = ffi_template_tramp_tile[0] | OPS(c, h, s);
- for (s -= 16; s >= 0; s -= 16)
- *out++ = ffi_template_tramp_tile[1] | OPS(c, h, s);
-
-#undef OPS
-
- *out++ = ffi_template_tramp_tile[2];
-
-#else
- /* TILEPro */
- UINT64 *out;
- intptr_t delta;
-
- if (cif->abi != FFI_UNIX)
- return FFI_BAD_ABI;
-
- out = (UINT64 *)closure->tramp;
- delta = (intptr_t)ffi_closure_tile - (intptr_t)codeloc;
-
- *out++ = ffi_template_tramp_tile[0] | create_JOffLong_X1(delta >> 3);
-#endif
-
- closure->cif = cif;
- closure->fun = fun;
- closure->user_data = user_data;
-
- invalidate_icache(closure->tramp, (char *)out - closure->tramp,
- getpagesize());
-
- return FFI_OK;
-}
-
-
-/* This is called by the assembly wrapper for closures. This does
- all of the work. On entry reg_args[0] holds the values the registers
- had when the closure was invoked. On return reg_args[1] holds the register
- values to be returned to the caller (many of which may be garbage). */
-void FFI_HIDDEN
-ffi_closure_tile_inner(ffi_closure *closure,
- ffi_sarg reg_args[2][NUM_ARG_REGS],
- ffi_sarg *stack_args)
-{
- ffi_cif * const cif = closure->cif;
- void ** const avalue = alloca(cif->nargs * sizeof(void *));
- void *rvalue;
- ffi_type ** const arg_types = cif->arg_types;
- ffi_sarg * const reg_args_in = reg_args[0];
- ffi_sarg * const reg_args_out = reg_args[1];
- ffi_sarg * argp;
- long i, arg_word, nargs = cif->nargs;
- /* Use a union to guarantee proper alignment for double. */
- union { ffi_sarg arg[NUM_ARG_REGS]; double d; UINT64 u64; } closure_ret;
-
- /* Start out reading register arguments. */
- argp = reg_args_in;
-
- /* Copy the caller's structure return address to that the closure
- returns the data directly to the caller. */
- if (cif->flags == FFI_TYPE_STRUCT)
- {
- /* Return by reference via hidden pointer. */
- rvalue = (void *)(intptr_t)*argp++;
- arg_word = 1;
- }
- else
- {
- /* Return the value in registers. */
- rvalue = &closure_ret;
- arg_word = 0;
- }
-
- /* Grab the addresses of the arguments. */
- for (i = 0; i < nargs; i++)
- {
- ffi_type * const type = arg_types[i];
- const size_t arg_size_in_words =
- (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG;
-
-#ifndef __tilegx__
- /* Doubleword-aligned values are always in an even-number register
- pair, or doubleword-aligned stack slot if out of registers. */
- long align = arg_word & (type->alignment > FFI_SIZEOF_ARG);
- argp += align;
- arg_word += align;
-#endif
-
- if (arg_word == NUM_ARG_REGS ||
- (arg_word < NUM_ARG_REGS &&
- arg_word + arg_size_in_words > NUM_ARG_REGS))
- {
- /* Switch to reading arguments from the stack. */
- argp = stack_args;
- arg_word = NUM_ARG_REGS;
- }
-
- avalue[i] = argp;
- argp += arg_size_in_words;
- arg_word += arg_size_in_words;
- }
-
- /* Invoke the closure. */
- closure->fun(cif, rvalue, avalue, closure->user_data);
-
- if (cif->flags != FFI_TYPE_STRUCT)
- {
- /* Canonicalize for register representation. */
- assign_to_ffi_arg(reg_args_out, &closure_ret, cif->rtype, 1);
- }
-}
diff --git a/Modules/_ctypes/libffi/src/tile/ffitarget.h b/Modules/_ctypes/libffi/src/tile/ffitarget.h
deleted file mode 100644
index 679fb5d904..0000000000
--- a/Modules/_ctypes/libffi/src/tile/ffitarget.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012 Tilera Corp.
- Target configuration macros for TILE.
-
- 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
-
-#include <arch/abi.h>
-
-typedef uint_reg_t ffi_arg;
-typedef int_reg_t ffi_sarg;
-
-typedef enum ffi_abi {
- FFI_FIRST_ABI = 0,
- FFI_UNIX,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX
-} ffi_abi;
-#endif
-
-/* ---- Definitions for closures ----------------------------------------- */
-#define FFI_CLOSURES 1
-
-#ifdef __tilegx__
-/* We always pass 8-byte values, even in -m32 mode. */
-# define FFI_SIZEOF_ARG 8
-# ifdef __LP64__
-# define FFI_TRAMPOLINE_SIZE (8 * 5) /* 5 bundles */
-# else
-# define FFI_TRAMPOLINE_SIZE (8 * 3) /* 3 bundles */
-# endif
-#else
-# define FFI_SIZEOF_ARG 4
-# define FFI_TRAMPOLINE_SIZE 8 /* 1 bundle */
-#endif
-#define FFI_NATIVE_RAW_API 0
-
-#endif
diff --git a/Modules/_ctypes/libffi/src/tile/tile.S b/Modules/_ctypes/libffi/src/tile/tile.S
deleted file mode 100644
index d1f82cb3db..0000000000
--- a/Modules/_ctypes/libffi/src/tile/tile.S
+++ /dev/null
@@ -1,360 +0,0 @@
-/* -----------------------------------------------------------------------
- tile.S - Copyright (c) 2011 Tilera Corp.
-
- Tilera TILEPro and TILE-Gx 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>
-
-/* Number of bytes in a register. */
-#define REG_SIZE FFI_SIZEOF_ARG
-
-/* Number of bytes in stack linkage area for backtracing.
-
- A note about the ABI: on entry to a procedure, sp points to a stack
- slot where it must spill the return address if it's not a leaf.
- REG_SIZE bytes beyond that is a slot owned by the caller which
- contains the sp value that the caller had when it was originally
- entered (i.e. the caller's frame pointer). */
-#define LINKAGE_SIZE (2 * REG_SIZE)
-
-/* The first 10 registers are used to pass arguments and return values. */
-#define NUM_ARG_REGS 10
-
-#ifdef __tilegx__
-#define SW st
-#define LW ld
-#define BGZT bgtzt
-#else
-#define SW sw
-#define LW lw
-#define BGZT bgzt
-#endif
-
-
-/* void ffi_call_tile (int_reg_t reg_args[NUM_ARG_REGS],
- const int_reg_t *stack_args,
- unsigned long stack_args_bytes,
- void (*fnaddr)(void));
-
- On entry, REG_ARGS contain the outgoing register values,
- and STACK_ARGS contains STACK_ARG_BYTES of additional values
- to be passed on the stack. If STACK_ARG_BYTES is zero, then
- STACK_ARGS is ignored.
-
- When the invoked function returns, the values of r0-r9 are
- blindly stored back into REG_ARGS for the caller to examine. */
-
- .section .text.ffi_call_tile, "ax", @progbits
- .align 8
- .globl ffi_call_tile
- FFI_HIDDEN(ffi_call_tile)
-ffi_call_tile:
-
-/* Incoming arguments. */
-#define REG_ARGS r0
-#define INCOMING_STACK_ARGS r1
-#define STACK_ARG_BYTES r2
-#define ORIG_FNADDR r3
-
-/* Temporary values. */
-#define FRAME_SIZE r10
-#define TMP r11
-#define TMP2 r12
-#define OUTGOING_STACK_ARGS r13
-#define REG_ADDR_PTR r14
-#define RETURN_REG_ADDR r15
-#define FNADDR r16
-
- .cfi_startproc
- {
- /* Save return address. */
- SW sp, lr
- .cfi_offset lr, 0
- /* Prepare to spill incoming r52. */
- addi TMP, sp, -REG_SIZE
- /* Increase frame size to have room to spill r52 and REG_ARGS.
- The +7 is to round up mod 8. */
- addi FRAME_SIZE, STACK_ARG_BYTES, \
- REG_SIZE + REG_SIZE + LINKAGE_SIZE + 7
- }
- {
- /* Round stack frame size to a multiple of 8 to satisfy ABI. */
- andi FRAME_SIZE, FRAME_SIZE, -8
- /* Compute where to spill REG_ARGS value. */
- addi TMP2, sp, -(REG_SIZE * 2)
- }
- {
- /* Spill incoming r52. */
- SW TMP, r52
- .cfi_offset r52, -REG_SIZE
- /* Set up our frame pointer. */
- move r52, sp
- .cfi_def_cfa_register r52
- /* Push stack frame. */
- sub sp, sp, FRAME_SIZE
- }
- {
- /* Prepare to set up stack linkage. */
- addi TMP, sp, REG_SIZE
- /* Prepare to memcpy stack args. */
- addi OUTGOING_STACK_ARGS, sp, LINKAGE_SIZE
- /* Save REG_ARGS which we will need after we call the subroutine. */
- SW TMP2, REG_ARGS
- }
- {
- /* Set up linkage info to hold incoming stack pointer. */
- SW TMP, r52
- }
- {
- /* Skip stack args memcpy if we don't have any stack args (common). */
- blezt STACK_ARG_BYTES, .Ldone_stack_args_memcpy
- }
-
-.Lmemcpy_stack_args:
- {
- /* Load incoming argument from stack_args. */
- LW TMP, INCOMING_STACK_ARGS
- addi INCOMING_STACK_ARGS, INCOMING_STACK_ARGS, REG_SIZE
- }
- {
- /* Store stack argument into outgoing stack argument area. */
- SW OUTGOING_STACK_ARGS, TMP
- addi OUTGOING_STACK_ARGS, OUTGOING_STACK_ARGS, REG_SIZE
- addi STACK_ARG_BYTES, STACK_ARG_BYTES, -REG_SIZE
- }
- {
- BGZT STACK_ARG_BYTES, .Lmemcpy_stack_args
- }
-.Ldone_stack_args_memcpy:
-
- {
- /* Copy aside ORIG_FNADDR so we can overwrite its register. */
- move FNADDR, ORIG_FNADDR
- /* Prepare to load argument registers. */
- addi REG_ADDR_PTR, r0, REG_SIZE
- /* Load outgoing r0. */
- LW r0, r0
- }
-
- /* Load up argument registers from the REG_ARGS array. */
-#define LOAD_REG(REG, PTR) \
- { \
- LW REG, PTR ; \
- addi PTR, PTR, REG_SIZE \
- }
-
- LOAD_REG(r1, REG_ADDR_PTR)
- LOAD_REG(r2, REG_ADDR_PTR)
- LOAD_REG(r3, REG_ADDR_PTR)
- LOAD_REG(r4, REG_ADDR_PTR)
- LOAD_REG(r5, REG_ADDR_PTR)
- LOAD_REG(r6, REG_ADDR_PTR)
- LOAD_REG(r7, REG_ADDR_PTR)
- LOAD_REG(r8, REG_ADDR_PTR)
- LOAD_REG(r9, REG_ADDR_PTR)
-
- {
- /* Call the subroutine. */
- jalr FNADDR
- }
-
- {
- /* Restore original lr. */
- LW lr, r52
- /* Prepare to recover ARGS, which we spilled earlier. */
- addi TMP, r52, -(2 * REG_SIZE)
- }
- {
- /* Restore ARGS, so we can fill it in with the return regs r0-r9. */
- LW RETURN_REG_ADDR, TMP
- /* Prepare to restore original r52. */
- addi TMP, r52, -REG_SIZE
- }
-
- {
- /* Pop stack frame. */
- move sp, r52
- /* Restore original r52. */
- LW r52, TMP
- }
-
-#define STORE_REG(REG, PTR) \
- { \
- SW PTR, REG ; \
- addi PTR, PTR, REG_SIZE \
- }
-
- /* Return all register values by reference. */
- STORE_REG(r0, RETURN_REG_ADDR)
- STORE_REG(r1, RETURN_REG_ADDR)
- STORE_REG(r2, RETURN_REG_ADDR)
- STORE_REG(r3, RETURN_REG_ADDR)
- STORE_REG(r4, RETURN_REG_ADDR)
- STORE_REG(r5, RETURN_REG_ADDR)
- STORE_REG(r6, RETURN_REG_ADDR)
- STORE_REG(r7, RETURN_REG_ADDR)
- STORE_REG(r8, RETURN_REG_ADDR)
- STORE_REG(r9, RETURN_REG_ADDR)
-
- {
- jrp lr
- }
-
- .cfi_endproc
- .size ffi_call_tile, .-ffi_call_tile
-
-/* ffi_closure_tile(...)
-
- On entry, lr points to the closure plus 8 bytes, and r10
- contains the actual return address.
-
- This function simply dumps all register parameters into a stack array
- and passes the closure, the registers array, and the stack arguments
- to C code that does all of the actual closure processing. */
-
- .section .text.ffi_closure_tile, "ax", @progbits
- .align 8
- .globl ffi_closure_tile
- FFI_HIDDEN(ffi_closure_tile)
-
- .cfi_startproc
-/* Room to spill all NUM_ARG_REGS incoming registers, plus frame linkage. */
-#define CLOSURE_FRAME_SIZE (((NUM_ARG_REGS * REG_SIZE * 2 + LINKAGE_SIZE) + 7) & -8)
-ffi_closure_tile:
- {
-#ifdef __tilegx__
- st sp, lr
- .cfi_offset lr, 0
-#else
- /* Save return address (in r10 due to closure stub wrapper). */
- SW sp, r10
- .cfi_return_column r10
- .cfi_offset r10, 0
-#endif
- /* Compute address for stack frame linkage. */
- addli r10, sp, -(CLOSURE_FRAME_SIZE - REG_SIZE)
- }
- {
- /* Save incoming stack pointer in linkage area. */
- SW r10, sp
- .cfi_offset sp, -(CLOSURE_FRAME_SIZE - REG_SIZE)
- /* Push a new stack frame. */
- addli sp, sp, -CLOSURE_FRAME_SIZE
- .cfi_adjust_cfa_offset CLOSURE_FRAME_SIZE
- }
-
- {
- /* Create pointer to where to start spilling registers. */
- addi r10, sp, LINKAGE_SIZE
- }
-
- /* Spill all the incoming registers. */
- STORE_REG(r0, r10)
- STORE_REG(r1, r10)
- STORE_REG(r2, r10)
- STORE_REG(r3, r10)
- STORE_REG(r4, r10)
- STORE_REG(r5, r10)
- STORE_REG(r6, r10)
- STORE_REG(r7, r10)
- STORE_REG(r8, r10)
- {
- /* Save r9. */
- SW r10, r9
-#ifdef __tilegx__
- /* Pointer to closure is passed in r11. */
- move r0, r11
-#else
- /* Compute pointer to the closure object. Because the closure
- starts with a "jal ffi_closure_tile", we can just take the
- value of lr (a phony return address pointing into the closure)
- and subtract 8. */
- addi r0, lr, -8
-#endif
- /* Compute a pointer to the register arguments we just spilled. */
- addi r1, sp, LINKAGE_SIZE
- }
- {
- /* Compute a pointer to the extra stack arguments (if any). */
- addli r2, sp, CLOSURE_FRAME_SIZE + LINKAGE_SIZE
- /* Call C code to deal with all of the grotty details. */
- jal ffi_closure_tile_inner
- }
- {
- addli r10, sp, CLOSURE_FRAME_SIZE
- }
- {
- /* Restore the return address. */
- LW lr, r10
- /* Compute pointer to registers array. */
- addli r10, sp, LINKAGE_SIZE + (NUM_ARG_REGS * REG_SIZE)
- }
- /* Return all the register values, which C code may have set. */
- LOAD_REG(r0, r10)
- LOAD_REG(r1, r10)
- LOAD_REG(r2, r10)
- LOAD_REG(r3, r10)
- LOAD_REG(r4, r10)
- LOAD_REG(r5, r10)
- LOAD_REG(r6, r10)
- LOAD_REG(r7, r10)
- LOAD_REG(r8, r10)
- LOAD_REG(r9, r10)
- {
- /* Pop the frame. */
- addli sp, sp, CLOSURE_FRAME_SIZE
- jrp lr
- }
-
- .cfi_endproc
- .size ffi_closure_tile, . - ffi_closure_tile
-
-
-/* What follows are code template instructions that get copied to the
- closure trampoline by ffi_prep_closure_loc. The zeroed operands
- get replaced by their proper values at runtime. */
-
- .section .text.ffi_template_tramp_tile, "ax", @progbits
- .align 8
- .globl ffi_template_tramp_tile
- FFI_HIDDEN(ffi_template_tramp_tile)
-ffi_template_tramp_tile:
-#ifdef __tilegx__
- {
- moveli r11, 0 /* backpatched to address of containing closure. */
- moveli r10, 0 /* backpatched to ffi_closure_tile. */
- }
- /* Note: the following bundle gets generated multiple times
- depending on the pointer value (esp. useful for -m32 mode). */
- { shl16insli r11, r11, 0 ; shl16insli r10, r10, 0 }
- { info 2+8 /* for backtracer: -> pc in lr, frame size 0 */ ; jr r10 }
-#else
- /* 'jal .' yields a PC-relative offset of zero so we can OR in the
- right offset at runtime. */
- { move r10, lr ; jal . /* ffi_closure_tile */ }
-#endif
-
- .size ffi_template_tramp_tile, . - ffi_template_tramp_tile