summaryrefslogtreecommitdiff
path: root/libffi/src/s390
diff options
context:
space:
mode:
Diffstat (limited to 'libffi/src/s390')
-rw-r--r--libffi/src/s390/ffi.c753
-rw-r--r--libffi/src/s390/ffitarget.h59
-rw-r--r--libffi/src/s390/sysv.S429
3 files changed, 0 insertions, 1241 deletions
diff --git a/libffi/src/s390/ffi.c b/libffi/src/s390/ffi.c
deleted file mode 100644
index d672b3c..0000000
--- a/libffi/src/s390/ffi.c
+++ /dev/null
@@ -1,753 +0,0 @@
-/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2000 Software AG
-
- S390 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 AUTHOR 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.
- ----------------------------------------------------------------------- */
-/*====================================================================*/
-/* Includes */
-/* -------- */
-/*====================================================================*/
-
-#include <ffi.h>
-#include <ffi_common.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-
-/*====================== End of Includes =============================*/
-
-/*====================================================================*/
-/* Defines */
-/* ------- */
-/*====================================================================*/
-
-/* Maximum number of GPRs available for argument passing. */
-#define MAX_GPRARGS 5
-
-/* Maximum number of FPRs available for argument passing. */
-#ifdef __s390x__
-#define MAX_FPRARGS 4
-#else
-#define MAX_FPRARGS 2
-#endif
-
-/* Round to multiple of 16. */
-#define ROUND_SIZE(size) (((size) + 15) & ~15)
-
-/* If these values change, sysv.S must be adapted! */
-#define FFI390_RET_VOID 0
-#define FFI390_RET_STRUCT 1
-#define FFI390_RET_FLOAT 2
-#define FFI390_RET_DOUBLE 3
-#define FFI390_RET_INT32 4
-#define FFI390_RET_INT64 5
-
-/*===================== End of Defines ===============================*/
-
-/*====================================================================*/
-/* Prototypes */
-/* ---------- */
-/*====================================================================*/
-
-static void ffi_prep_args (unsigned char *, extended_cif *);
-static int ffi_check_float_struct (ffi_type *);
-void
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
-__attribute__ ((visibility ("hidden")))
-#endif
-ffi_closure_helper_SYSV (ffi_closure *, unsigned long *,
- unsigned long long *, unsigned long *);
-
-/*====================== End of Prototypes ===========================*/
-
-/*====================================================================*/
-/* Externals */
-/* --------- */
-/*====================================================================*/
-
-extern void ffi_call_SYSV(unsigned,
- extended_cif *,
- void (*)(unsigned char *, extended_cif *),
- unsigned,
- void *,
- void (*fn)());
-
-extern void ffi_closure_SYSV(void);
-
-/*====================== End of Externals ============================*/
-
-/*====================================================================*/
-/* */
-/* Name - ffi_check_struct_type. */
-/* */
-/* Function - Determine if a structure can be passed within a */
-/* general purpose or floating point register. */
-/* */
-/*====================================================================*/
-
-static int
-ffi_check_struct_type (ffi_type *arg)
-{
- size_t size = arg->size;
-
- /* If the struct has just one element, look at that element
- to find out whether to consider the struct as floating point. */
- while (arg->type == FFI_TYPE_STRUCT
- && arg->elements[0] && !arg->elements[1])
- arg = arg->elements[0];
-
- /* Structs of size 1, 2, 4, and 8 are passed in registers,
- just like the corresponding int/float types. */
- switch (size)
- {
- case 1:
- return FFI_TYPE_UINT8;
-
- case 2:
- return FFI_TYPE_UINT16;
-
- case 4:
- if (arg->type == FFI_TYPE_FLOAT)
- return FFI_TYPE_FLOAT;
- else
- return FFI_TYPE_UINT32;
-
- case 8:
- if (arg->type == FFI_TYPE_DOUBLE)
- return FFI_TYPE_DOUBLE;
- else
- return FFI_TYPE_UINT64;
-
- default:
- break;
- }
-
- /* Other structs are passed via a pointer to the data. */
- return FFI_TYPE_POINTER;
-}
-
-/*======================== End of Routine ============================*/
-
-/*====================================================================*/
-/* */
-/* Name - ffi_prep_args. */
-/* */
-/* Function - Prepare parameters for call to function. */
-/* */
-/* ffi_prep_args is called by the assembly routine once stack space */
-/* has been allocated for the function's arguments. */
-/* */
-/*====================================================================*/
-
-static void
-ffi_prep_args (unsigned char *stack, extended_cif *ecif)
-{
- /* The stack space will be filled with those areas:
-
- FPR argument register save area (highest addresses)
- GPR argument register save area
- temporary struct copies
- overflow argument area (lowest addresses)
-
- We set up the following pointers:
-
- p_fpr: bottom of the FPR area (growing upwards)
- p_gpr: bottom of the GPR area (growing upwards)
- p_ov: bottom of the overflow area (growing upwards)
- p_struct: top of the struct copy area (growing downwards)
-
- All areas are kept aligned to twice the word size. */
-
- int gpr_off = ecif->cif->bytes;
- int fpr_off = gpr_off + ROUND_SIZE (MAX_GPRARGS * sizeof (long));
-
- unsigned long long *p_fpr = (unsigned long long *)(stack + fpr_off);
- unsigned long *p_gpr = (unsigned long *)(stack + gpr_off);
- unsigned char *p_struct = (unsigned char *)p_gpr;
- unsigned long *p_ov = (unsigned long *)stack;
-
- int n_fpr = 0;
- int n_gpr = 0;
- int n_ov = 0;
-
- ffi_type **ptr;
- void **p_argv = ecif->avalue;
- int i;
-
- /* If we returning a structure then we set the first parameter register
- to the address of where we are returning this structure. */
-
- if (ecif->cif->flags == FFI390_RET_STRUCT)
- p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
-
- /* Now for the arguments. */
-
- for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
- i > 0;
- i--, ptr++, p_argv++)
- {
- void *arg = *p_argv;
- int type = (*ptr)->type;
-
- /* Check how a structure type is passed. */
- if (type == FFI_TYPE_STRUCT)
- {
- type = ffi_check_struct_type (*ptr);
-
- /* If we pass the struct via pointer, copy the data. */
- if (type == FFI_TYPE_POINTER)
- {
- p_struct -= ROUND_SIZE ((*ptr)->size);
- memcpy (p_struct, (char *)arg, (*ptr)->size);
- arg = &p_struct;
- }
- }
-
- /* Pointers are passed like UINTs of the same size. */
- if (type == FFI_TYPE_POINTER)
-#ifdef __s390x__
- type = FFI_TYPE_UINT64;
-#else
- type = FFI_TYPE_UINT32;
-#endif
-
- /* Now handle all primitive int/float data types. */
- switch (type)
- {
- case FFI_TYPE_DOUBLE:
- if (n_fpr < MAX_FPRARGS)
- p_fpr[n_fpr++] = *(unsigned long long *) arg;
- else
-#ifdef __s390x__
- p_ov[n_ov++] = *(unsigned long *) arg;
-#else
- p_ov[n_ov++] = ((unsigned long *) arg)[0],
- p_ov[n_ov++] = ((unsigned long *) arg)[1];
-#endif
- break;
-
- case FFI_TYPE_FLOAT:
- if (n_fpr < MAX_FPRARGS)
- p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
- else
- p_ov[n_ov++] = *(unsigned int *) arg;
- break;
-
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
-#ifdef __s390x__
- if (n_gpr < MAX_GPRARGS)
- p_gpr[n_gpr++] = *(unsigned long *) arg;
- else
- p_ov[n_ov++] = *(unsigned long *) arg;
-#else
- if (n_gpr == MAX_GPRARGS-1)
- n_gpr = MAX_GPRARGS;
- if (n_gpr < MAX_GPRARGS)
- p_gpr[n_gpr++] = ((unsigned long *) arg)[0],
- p_gpr[n_gpr++] = ((unsigned long *) arg)[1];
- else
- p_ov[n_ov++] = ((unsigned long *) arg)[0],
- p_ov[n_ov++] = ((unsigned long *) arg)[1];
-#endif
- break;
-
- case FFI_TYPE_UINT32:
- if (n_gpr < MAX_GPRARGS)
- p_gpr[n_gpr++] = *(unsigned int *) arg;
- else
- p_ov[n_ov++] = *(unsigned int *) arg;
- break;
-
- case FFI_TYPE_INT:
- case FFI_TYPE_SINT32:
- if (n_gpr < MAX_GPRARGS)
- p_gpr[n_gpr++] = *(signed int *) arg;
- else
- p_ov[n_ov++] = *(signed int *) arg;
- break;
-
- case FFI_TYPE_UINT16:
- if (n_gpr < MAX_GPRARGS)
- p_gpr[n_gpr++] = *(unsigned short *) arg;
- else
- p_ov[n_ov++] = *(unsigned short *) arg;
- break;
-
- case FFI_TYPE_SINT16:
- if (n_gpr < MAX_GPRARGS)
- p_gpr[n_gpr++] = *(signed short *) arg;
- else
- p_ov[n_ov++] = *(signed short *) arg;
- break;
-
- case FFI_TYPE_UINT8:
- if (n_gpr < MAX_GPRARGS)
- p_gpr[n_gpr++] = *(unsigned char *) arg;
- else
- p_ov[n_ov++] = *(unsigned char *) arg;
- break;
-
- case FFI_TYPE_SINT8:
- if (n_gpr < MAX_GPRARGS)
- p_gpr[n_gpr++] = *(signed char *) arg;
- else
- p_ov[n_ov++] = *(signed char *) arg;
- break;
-
- default:
- FFI_ASSERT (0);
- break;
- }
- }
-}
-
-/*======================== End of Routine ============================*/
-
-/*====================================================================*/
-/* */
-/* Name - ffi_prep_cif_machdep. */
-/* */
-/* Function - Perform machine dependent CIF processing. */
-/* */
-/*====================================================================*/
-
-ffi_status
-ffi_prep_cif_machdep(ffi_cif *cif)
-{
- size_t struct_size = 0;
- int n_gpr = 0;
- int n_fpr = 0;
- int n_ov = 0;
-
- ffi_type **ptr;
- int i;
-
- /* Determine return value handling. */
-
- switch (cif->rtype->type)
- {
- /* Void is easy. */
- case FFI_TYPE_VOID:
- cif->flags = FFI390_RET_VOID;
- break;
-
- /* Structures are returned via a hidden pointer. */
- case FFI_TYPE_STRUCT:
- cif->flags = FFI390_RET_STRUCT;
- n_gpr++; /* We need one GPR to pass the pointer. */
- break;
-
- /* Floating point values are returned in fpr 0. */
- case FFI_TYPE_FLOAT:
- cif->flags = FFI390_RET_FLOAT;
- break;
-
- case FFI_TYPE_DOUBLE:
- cif->flags = FFI390_RET_DOUBLE;
- break;
-
- /* Integer values are returned in gpr 2 (and gpr 3
- for 64-bit values on 31-bit machines). */
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- cif->flags = FFI390_RET_INT64;
- break;
-
- case FFI_TYPE_POINTER:
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- /* These are to be extended to word size. */
-#ifdef __s390x__
- cif->flags = FFI390_RET_INT64;
-#else
- cif->flags = FFI390_RET_INT32;
-#endif
- break;
-
- default:
- FFI_ASSERT (0);
- break;
- }
-
- /* Now for the arguments. */
-
- for (ptr = cif->arg_types, i = cif->nargs;
- i > 0;
- i--, ptr++)
- {
- int type = (*ptr)->type;
-
- /* Check how a structure type is passed. */
- if (type == FFI_TYPE_STRUCT)
- {
- type = ffi_check_struct_type (*ptr);
-
- /* If we pass the struct via pointer, we must reserve space
- to copy its data for proper call-by-value semantics. */
- if (type == FFI_TYPE_POINTER)
- struct_size += ROUND_SIZE ((*ptr)->size);
- }
-
- /* Now handle all primitive int/float data types. */
- switch (type)
- {
- /* The first MAX_FPRARGS floating point arguments
- go in FPRs, the rest overflow to the stack. */
-
- case FFI_TYPE_DOUBLE:
- if (n_fpr < MAX_FPRARGS)
- n_fpr++;
- else
- n_ov += sizeof (double) / sizeof (long);
- break;
-
- case FFI_TYPE_FLOAT:
- if (n_fpr < MAX_FPRARGS)
- n_fpr++;
- else
- n_ov++;
- break;
-
- /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
- if one is still available, or else on the stack. If only one
- register is free, skip the register (it won't be used for any
- subsequent argument either). */
-
-#ifndef __s390x__
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- if (n_gpr == MAX_GPRARGS-1)
- n_gpr = MAX_GPRARGS;
- if (n_gpr < MAX_GPRARGS)
- n_gpr += 2;
- else
- n_ov += 2;
- break;
-#endif
-
- /* Everything else is passed in GPRs (until MAX_GPRARGS
- have been used) or overflows to the stack. */
-
- default:
- if (n_gpr < MAX_GPRARGS)
- n_gpr++;
- else
- n_ov++;
- break;
- }
- }
-
- /* Total stack space as required for overflow arguments
- and temporary structure copies. */
-
- cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
-
- return FFI_OK;
-}
-
-/*======================== End of Routine ============================*/
-
-/*====================================================================*/
-/* */
-/* Name - ffi_call. */
-/* */
-/* Function - Call the FFI routine. */
-/* */
-/*====================================================================*/
-
-void
-ffi_call(ffi_cif *cif,
- void (*fn)(),
- void *rvalue,
- void **avalue)
-{
- int ret_type = cif->flags;
- extended_cif ecif;
-
- ecif.cif = cif;
- ecif.avalue = avalue;
- ecif.rvalue = rvalue;
-
- /* If we don't have a return value, we need to fake one. */
- if (rvalue == NULL)
- {
- if (ret_type == FFI390_RET_STRUCT)
- ecif.rvalue = alloca (cif->rtype->size);
- else
- ret_type = FFI390_RET_VOID;
- }
-
- switch (cif->abi)
- {
- case FFI_SYSV:
- ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
- ret_type, ecif.rvalue, fn);
- break;
-
- default:
- FFI_ASSERT (0);
- break;
- }
-}
-
-/*======================== End of Routine ============================*/
-
-/*====================================================================*/
-/* */
-/* Name - ffi_closure_helper_SYSV. */
-/* */
-/* Function - Call a FFI closure target function. */
-/* */
-/*====================================================================*/
-
-void
-ffi_closure_helper_SYSV (ffi_closure *closure,
- unsigned long *p_gpr,
- unsigned long long *p_fpr,
- unsigned long *p_ov)
-{
- unsigned long long ret_buffer;
-
- void *rvalue = &ret_buffer;
- void **avalue;
- void **p_arg;
-
- int n_gpr = 0;
- int n_fpr = 0;
- int n_ov = 0;
-
- ffi_type **ptr;
- int i;
-
- /* Allocate buffer for argument list pointers. */
-
- p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
-
- /* If we returning a structure, pass the structure address
- directly to the target function. Otherwise, have the target
- function store the return value to the GPR save area. */
-
- if (closure->cif->flags == FFI390_RET_STRUCT)
- rvalue = (void *) p_gpr[n_gpr++];
-
- /* Now for the arguments. */
-
- for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
- i > 0;
- i--, p_arg++, ptr++)
- {
- int deref_struct_pointer = 0;
- int type = (*ptr)->type;
-
- /* Check how a structure type is passed. */
- if (type == FFI_TYPE_STRUCT)
- {
- type = ffi_check_struct_type (*ptr);
-
- /* If we pass the struct via pointer, remember to
- retrieve the pointer later. */
- if (type == FFI_TYPE_POINTER)
- deref_struct_pointer = 1;
- }
-
- /* Pointers are passed like UINTs of the same size. */
- if (type == FFI_TYPE_POINTER)
-#ifdef __s390x__
- type = FFI_TYPE_UINT64;
-#else
- type = FFI_TYPE_UINT32;
-#endif
-
- /* Now handle all primitive int/float data types. */
- switch (type)
- {
- case FFI_TYPE_DOUBLE:
- if (n_fpr < MAX_FPRARGS)
- *p_arg = &p_fpr[n_fpr++];
- else
- *p_arg = &p_ov[n_ov],
- n_ov += sizeof (double) / sizeof (long);
- break;
-
- case FFI_TYPE_FLOAT:
- if (n_fpr < MAX_FPRARGS)
- *p_arg = &p_fpr[n_fpr++];
- else
- *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
- break;
-
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
-#ifdef __s390x__
- if (n_gpr < MAX_GPRARGS)
- *p_arg = &p_gpr[n_gpr++];
- else
- *p_arg = &p_ov[n_ov++];
-#else
- if (n_gpr == MAX_GPRARGS-1)
- n_gpr = MAX_GPRARGS;
- if (n_gpr < MAX_GPRARGS)
- *p_arg = &p_gpr[n_gpr], n_gpr += 2;
- else
- *p_arg = &p_ov[n_ov], n_ov += 2;
-#endif
- break;
-
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- if (n_gpr < MAX_GPRARGS)
- *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
- else
- *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
- break;
-
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- if (n_gpr < MAX_GPRARGS)
- *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
- else
- *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
- break;
-
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- if (n_gpr < MAX_GPRARGS)
- *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
- else
- *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
- break;
-
- default:
- FFI_ASSERT (0);
- break;
- }
-
- /* If this is a struct passed via pointer, we need to
- actually retrieve that pointer. */
- if (deref_struct_pointer)
- *p_arg = *(void **)*p_arg;
- }
-
-
- /* Call the target function. */
- (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
-
- /* Convert the return value. */
- switch (closure->cif->rtype->type)
- {
- /* Void is easy, and so is struct. */
- case FFI_TYPE_VOID:
- case FFI_TYPE_STRUCT:
- break;
-
- /* Floating point values are returned in fpr 0. */
- case FFI_TYPE_FLOAT:
- p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
- break;
-
- case FFI_TYPE_DOUBLE:
- p_fpr[0] = *(unsigned long long *) rvalue;
- break;
-
- /* Integer values are returned in gpr 2 (and gpr 3
- for 64-bit values on 31-bit machines). */
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
-#ifdef __s390x__
- p_gpr[0] = *(unsigned long *) rvalue;
-#else
- p_gpr[0] = ((unsigned long *) rvalue)[0],
- p_gpr[1] = ((unsigned long *) rvalue)[1];
-#endif
- break;
-
- case FFI_TYPE_POINTER:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_UINT8:
- p_gpr[0] = *(unsigned long *) rvalue;
- break;
-
- case FFI_TYPE_INT:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_SINT8:
- p_gpr[0] = *(signed long *) rvalue;
- break;
-
- default:
- FFI_ASSERT (0);
- break;
- }
-}
-
-/*======================== End of Routine ============================*/
-
-/*====================================================================*/
-/* */
-/* Name - ffi_prep_closure. */
-/* */
-/* Function - Prepare a FFI closure. */
-/* */
-/*====================================================================*/
-
-ffi_status
-ffi_prep_closure (ffi_closure *closure,
- ffi_cif *cif,
- void (*fun) (ffi_cif *, void *, void **, void *),
- void *user_data)
-{
- FFI_ASSERT (cif->abi == FFI_SYSV);
-
-#ifndef __s390x__
- *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
- *(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */
- *(short *)&closure->tramp [4] = 0x1006;
- *(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */
- *(long *)&closure->tramp [8] = (long)closure;
- *(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
-#else
- *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
- *(short *)&closure->tramp [2] = 0xeb01; /* lmg %r0,%r1,14(%r1) */
- *(short *)&closure->tramp [4] = 0x100e;
- *(short *)&closure->tramp [6] = 0x0004;
- *(short *)&closure->tramp [8] = 0x07f1; /* br %r1 */
- *(long *)&closure->tramp[16] = (long)closure;
- *(long *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
-#endif
-
- closure->cif = cif;
- closure->user_data = user_data;
- closure->fun = fun;
-
- return FFI_OK;
-}
-
-/*======================== End of Routine ============================*/
-
diff --git a/libffi/src/s390/ffitarget.h b/libffi/src/s390/ffitarget.h
deleted file mode 100644
index 5ec8ade..0000000
--- a/libffi/src/s390/ffitarget.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
- Target configuration macros for S390.
-
- 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 CYGNUS SOLUTIONS 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
-
-#if defined (__s390x__)
-#define S390X
-#endif
-
-/* ---- System specific configurations ----------------------------------- */
-
-#ifndef LIBFFI_ASM
-typedef unsigned long ffi_arg;
-typedef signed long ffi_sarg;
-
-typedef enum ffi_abi {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_DEFAULT_ABI = FFI_SYSV,
- FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
-} ffi_abi;
-#endif
-
-
-/* ---- Definitions for closures ----------------------------------------- */
-
-#define FFI_CLOSURES 1
-#ifdef S390X
-#define FFI_TRAMPOLINE_SIZE 32
-#else
-#define FFI_TRAMPOLINE_SIZE 16
-#endif
-#define FFI_NATIVE_RAW_API 0
-
-#endif
-
diff --git a/libffi/src/s390/sysv.S b/libffi/src/s390/sysv.S
deleted file mode 100644
index e9cbed9..0000000
--- a/libffi/src/s390/sysv.S
+++ /dev/null
@@ -1,429 +0,0 @@
-/* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 2000 Software AG
-
- S390 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 CYGNUS SOLUTIONS 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>
-
-#ifndef __s390x__
-
-.text
-
- # r2: cif->bytes
- # r3: &ecif
- # r4: ffi_prep_args
- # r5: ret_type
- # r6: ecif.rvalue
- # ov: fn
-
- # This assumes we are using gas.
- .globl ffi_call_SYSV
- .type ffi_call_SYSV,%function
-ffi_call_SYSV:
-.LFB1:
- stm %r6,%r15,24(%r15) # Save registers
-.LCFI0:
- basr %r13,0 # Set up base register
-.Lbase:
- lr %r11,%r15 # Set up frame pointer
-.LCFI1:
- sr %r15,%r2
- ahi %r15,-96-48 # Allocate stack
- lr %r8,%r6 # Save ecif.rvalue
- sr %r9,%r9
- ic %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
- l %r7,96(%r11) # Load function address
- st %r11,0(%r15) # Set up back chain
- ahi %r11,-48 # Register save area
-.LCFI2:
-
- la %r2,96(%r15) # Save area
- # r3 already holds &ecif
- basr %r14,%r4 # Call ffi_prep_args
-
- lm %r2,%r6,0(%r11) # Load arguments
- ld %f0,32(%r11)
- ld %f2,40(%r11)
- la %r14,0(%r13,%r9) # Set return address
- br %r7 # ... and call function
-
-.LretNone: # Return void
- l %r4,48+56(%r11)
- lm %r6,%r15,48+24(%r11)
- br %r4
-
-.LretFloat:
- l %r4,48+56(%r11)
- ste %f0,0(%r8) # Return float
- lm %r6,%r15,48+24(%r11)
- br %r4
-
-.LretDouble:
- l %r4,48+56(%r11)
- std %f0,0(%r8) # Return double
- lm %r6,%r15,48+24(%r11)
- br %r4
-
-.LretInt32:
- l %r4,48+56(%r11)
- st %r2,0(%r8) # Return int
- lm %r6,%r15,48+24(%r11)
- br %r4
-
-.LretInt64:
- l %r4,48+56(%r11)
- stm %r2,%r3,0(%r8) # Return long long
- lm %r6,%r15,48+24(%r11)
- br %r4
-
-.Ltable:
- .byte .LretNone-.Lbase # FFI390_RET_VOID
- .byte .LretNone-.Lbase # FFI390_RET_STRUCT
- .byte .LretFloat-.Lbase # FFI390_RET_FLOAT
- .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
- .byte .LretInt32-.Lbase # FFI390_RET_INT32
- .byte .LretInt64-.Lbase # FFI390_RET_INT64
-
-.LFE1:
-.ffi_call_SYSV_end:
- .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
-
-
- .globl ffi_closure_SYSV
- .type ffi_closure_SYSV,%function
-ffi_closure_SYSV:
-.LFB2:
- stm %r12,%r15,48(%r15) # Save registers
-.LCFI10:
- basr %r13,0 # Set up base register
-.Lcbase:
- stm %r2,%r6,8(%r15) # Save arguments
- std %f0,64(%r15)
- std %f2,72(%r15)
- lr %r1,%r15 # Set up stack frame
- ahi %r15,-96
-.LCFI11:
- l %r12,.Lchelper-.Lcbase(%r13) # Get helper function
- lr %r2,%r0 # Closure
- la %r3,8(%r1) # GPRs
- la %r4,64(%r1) # FPRs
- la %r5,96(%r1) # Overflow
- st %r1,0(%r15) # Set up back chain
-
- bas %r14,0(%r12,%r13) # Call helper
-
- l %r4,96+56(%r15)
- ld %f0,96+64(%r15) # Load return registers
- lm %r2,%r3,96+8(%r15)
- lm %r12,%r15,96+48(%r15)
- br %r4
-
- .align 4
-.Lchelper:
- .long ffi_closure_helper_SYSV-.Lcbase
-
-.LFE2:
-
-.ffi_closure_SYSV_end:
- .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
-
-
- .section .eh_frame,EH_FRAME_FLAGS,@progbits
-.Lframe1:
- .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
-.LSCIE1:
- .4byte 0x0 # CIE Identifier Tag
- .byte 0x1 # CIE Version
- .ascii "zR\0" # CIE Augmentation
- .uleb128 0x1 # CIE Code Alignment Factor
- .sleb128 -4 # CIE Data Alignment Factor
- .byte 0xe # CIE RA Column
- .uleb128 0x1 # Augmentation size
- .byte 0x1b # FDE Encoding (pcrel sdata4)
- .byte 0xc # DW_CFA_def_cfa
- .uleb128 0xf
- .uleb128 0x60
- .align 4
-.LECIE1:
-.LSFDE1:
- .4byte .LEFDE1-.LASFDE1 # FDE Length
-.LASFDE1:
- .4byte .LASFDE1-.Lframe1 # FDE CIE offset
- .4byte .LFB1-. # FDE initial location
- .4byte .LFE1-.LFB1 # FDE address range
- .uleb128 0x0 # Augmentation size
- .byte 0x4 # DW_CFA_advance_loc4
- .4byte .LCFI0-.LFB1
- .byte 0x8f # DW_CFA_offset, column 0xf
- .uleb128 0x9
- .byte 0x8e # DW_CFA_offset, column 0xe
- .uleb128 0xa
- .byte 0x8d # DW_CFA_offset, column 0xd
- .uleb128 0xb
- .byte 0x8c # DW_CFA_offset, column 0xc
- .uleb128 0xc
- .byte 0x8b # DW_CFA_offset, column 0xb
- .uleb128 0xd
- .byte 0x8a # DW_CFA_offset, column 0xa
- .uleb128 0xe
- .byte 0x89 # DW_CFA_offset, column 0x9
- .uleb128 0xf
- .byte 0x88 # DW_CFA_offset, column 0x8
- .uleb128 0x10
- .byte 0x87 # DW_CFA_offset, column 0x7
- .uleb128 0x11
- .byte 0x86 # DW_CFA_offset, column 0x6
- .uleb128 0x12
- .byte 0x4 # DW_CFA_advance_loc4
- .4byte .LCFI1-.LCFI0
- .byte 0xd # DW_CFA_def_cfa_register
- .uleb128 0xb
- .byte 0x4 # DW_CFA_advance_loc4
- .4byte .LCFI2-.LCFI1
- .byte 0xe # DW_CFA_def_cfa_offset
- .uleb128 0x90
- .align 4
-.LEFDE1:
-.LSFDE2:
- .4byte .LEFDE2-.LASFDE2 # FDE Length
-.LASFDE2:
- .4byte .LASFDE2-.Lframe1 # FDE CIE offset
- .4byte .LFB2-. # FDE initial location
- .4byte .LFE2-.LFB2 # FDE address range
- .uleb128 0x0 # Augmentation size
- .byte 0x4 # DW_CFA_advance_loc4
- .4byte .LCFI10-.LFB2
- .byte 0x8f # DW_CFA_offset, column 0xf
- .uleb128 0x9
- .byte 0x8e # DW_CFA_offset, column 0xe
- .uleb128 0xa
- .byte 0x8d # DW_CFA_offset, column 0xd
- .uleb128 0xb
- .byte 0x8c # DW_CFA_offset, column 0xc
- .uleb128 0xc
- .byte 0x4 # DW_CFA_advance_loc4
- .4byte .LCFI11-.LCFI10
- .byte 0xe # DW_CFA_def_cfa_offset
- .uleb128 0xc0
- .align 4
-.LEFDE2:
-
-#else
-
-.text
-
- # r2: cif->bytes
- # r3: &ecif
- # r4: ffi_prep_args
- # r5: ret_type
- # r6: ecif.rvalue
- # ov: fn
-
- # This assumes we are using gas.
- .globl ffi_call_SYSV
- .type ffi_call_SYSV,%function
-ffi_call_SYSV:
-.LFB1:
- stmg %r6,%r15,48(%r15) # Save registers
-.LCFI0:
- larl %r13,.Lbase # Set up base register
- lgr %r11,%r15 # Set up frame pointer
-.LCFI1:
- sgr %r15,%r2
- aghi %r15,-160-80 # Allocate stack
- lgr %r8,%r6 # Save ecif.rvalue
- llgc %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
- lg %r7,160(%r11) # Load function address
- stg %r11,0(%r15) # Set up back chain
- aghi %r11,-80 # Register save area
-.LCFI2:
-
- la %r2,160(%r15) # Save area
- # r3 already holds &ecif
- basr %r14,%r4 # Call ffi_prep_args
-
- lmg %r2,%r6,0(%r11) # Load arguments
- ld %f0,48(%r11)
- ld %f2,56(%r11)
- ld %f4,64(%r11)
- ld %f6,72(%r11)
- la %r14,0(%r13,%r9) # Set return address
- br %r7 # ... and call function
-
-.Lbase:
-.LretNone: # Return void
- lg %r4,80+112(%r11)
- lmg %r6,%r15,80+48(%r11)
- br %r4
-
-.LretFloat:
- lg %r4,80+112(%r11)
- ste %f0,0(%r8) # Return float
- lmg %r6,%r15,80+48(%r11)
- br %r4
-
-.LretDouble:
- lg %r4,80+112(%r11)
- std %f0,0(%r8) # Return double
- lmg %r6,%r15,80+48(%r11)
- br %r4
-
-.LretInt32:
- lg %r4,80+112(%r11)
- st %r2,0(%r8) # Return int
- lmg %r6,%r15,80+48(%r11)
- br %r4
-
-.LretInt64:
- lg %r4,80+112(%r11)
- stg %r2,0(%r8) # Return long
- lmg %r6,%r15,80+48(%r11)
- br %r4
-
-.Ltable:
- .byte .LretNone-.Lbase # FFI390_RET_VOID
- .byte .LretNone-.Lbase # FFI390_RET_STRUCT
- .byte .LretFloat-.Lbase # FFI390_RET_FLOAT
- .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
- .byte .LretInt32-.Lbase # FFI390_RET_INT32
- .byte .LretInt64-.Lbase # FFI390_RET_INT64
-
-.LFE1:
-.ffi_call_SYSV_end:
- .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
-
-
- .globl ffi_closure_SYSV
- .type ffi_closure_SYSV,%function
-ffi_closure_SYSV:
-.LFB2:
- stmg %r14,%r15,112(%r15) # Save registers
-.LCFI10:
- stmg %r2,%r6,16(%r15) # Save arguments
- std %f0,128(%r15)
- std %f2,136(%r15)
- std %f4,144(%r15)
- std %f6,152(%r15)
- lgr %r1,%r15 # Set up stack frame
- aghi %r15,-160
-.LCFI11:
- lgr %r2,%r0 # Closure
- la %r3,16(%r1) # GPRs
- la %r4,128(%r1) # FPRs
- la %r5,160(%r1) # Overflow
- stg %r1,0(%r15) # Set up back chain
-
- brasl %r14,ffi_closure_helper_SYSV # Call helper
-
- lg %r14,160+112(%r15)
- ld %f0,160+128(%r15) # Load return registers
- lg %r2,160+16(%r15)
- la %r15,160(%r15)
- br %r14
-.LFE2:
-
-.ffi_closure_SYSV_end:
- .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
-
-
-
- .section .eh_frame,EH_FRAME_FLAGS,@progbits
-.Lframe1:
- .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
-.LSCIE1:
- .4byte 0x0 # CIE Identifier Tag
- .byte 0x1 # CIE Version
- .ascii "zR\0" # CIE Augmentation
- .uleb128 0x1 # CIE Code Alignment Factor
- .sleb128 -8 # CIE Data Alignment Factor
- .byte 0xe # CIE RA Column
- .uleb128 0x1 # Augmentation size
- .byte 0x1b # FDE Encoding (pcrel sdata4)
- .byte 0xc # DW_CFA_def_cfa
- .uleb128 0xf
- .uleb128 0xa0
- .align 8
-.LECIE1:
-.LSFDE1:
- .4byte .LEFDE1-.LASFDE1 # FDE Length
-.LASFDE1:
- .4byte .LASFDE1-.Lframe1 # FDE CIE offset
- .4byte .LFB1-. # FDE initial location
- .4byte .LFE1-.LFB1 # FDE address range
- .uleb128 0x0 # Augmentation size
- .byte 0x4 # DW_CFA_advance_loc4
- .4byte .LCFI0-.LFB1
- .byte 0x8f # DW_CFA_offset, column 0xf
- .uleb128 0x5
- .byte 0x8e # DW_CFA_offset, column 0xe
- .uleb128 0x6
- .byte 0x8d # DW_CFA_offset, column 0xd
- .uleb128 0x7
- .byte 0x8c # DW_CFA_offset, column 0xc
- .uleb128 0x8
- .byte 0x8b # DW_CFA_offset, column 0xb
- .uleb128 0x9
- .byte 0x8a # DW_CFA_offset, column 0xa
- .uleb128 0xa
- .byte 0x89 # DW_CFA_offset, column 0x9
- .uleb128 0xb
- .byte 0x88 # DW_CFA_offset, column 0x8
- .uleb128 0xc
- .byte 0x87 # DW_CFA_offset, column 0x7
- .uleb128 0xd
- .byte 0x86 # DW_CFA_offset, column 0x6
- .uleb128 0xe
- .byte 0x4 # DW_CFA_advance_loc4
- .4byte .LCFI1-.LCFI0
- .byte 0xd # DW_CFA_def_cfa_register
- .uleb128 0xb
- .byte 0x4 # DW_CFA_advance_loc4
- .4byte .LCFI2-.LCFI1
- .byte 0xe # DW_CFA_def_cfa_offset
- .uleb128 0xf0
- .align 8
-.LEFDE1:
-.LSFDE2:
- .4byte .LEFDE2-.LASFDE2 # FDE Length
-.LASFDE2:
- .4byte .LASFDE2-.Lframe1 # FDE CIE offset
- .4byte .LFB2-. # FDE initial location
- .4byte .LFE2-.LFB2 # FDE address range
- .uleb128 0x0 # Augmentation size
- .byte 0x4 # DW_CFA_advance_loc4
- .4byte .LCFI10-.LFB2
- .byte 0x8f # DW_CFA_offset, column 0xf
- .uleb128 0x5
- .byte 0x8e # DW_CFA_offset, column 0xe
- .uleb128 0x6
- .byte 0x4 # DW_CFA_advance_loc4
- .4byte .LCFI11-.LCFI10
- .byte 0xe # DW_CFA_def_cfa_offset
- .uleb128 0x140
- .align 8
-.LEFDE2:
-
-#endif
-