--- ./boehm-gc/include/private/gcconfig.h.orig	2002-04-22 02:05:04.000000000 -0400
+++ ./boehm-gc/include/private/gcconfig.h	2003-05-07 23:12:28.000000000 -0400
@@ -369,7 +369,7 @@
 #   define mach_type_known
 # endif
 # if defined(__s390__) && defined(LINUX)
-#    define S370
+#    define S390
 #    define mach_type_known
 # endif
 # if defined(__GNU__)
@@ -418,7 +418,8 @@
 		    /* 		        (CX_UX and DGUX)		*/
 		    /* 		   S370	      ==> 370-like machine	*/
 		    /* 			running Amdahl UTS4		*/
-		    /*			or a 390 running LINUX		*/
+		    /*		   S390       ==> 390-line machine      */
+		    /*			running LINUX			*/
 		    /* 		   ARM32      ==> Intel StrongARM	*/
 		    /* 		   IA64	      ==> Intel IPF		*/
 		    /*				  (e.g. Itanium)	*/
@@ -1528,12 +1529,29 @@
 #	define DATAEND (_end)
 #	define HEURISTIC2
 #   endif
+# endif
+
+# ifdef S390
+#   define MACH_TYPE "S390"
+#   define USE_GENERIC_PUSH_REGS
+#   ifndef __s390x__
+#	define ALIGNMENT   4
+#	define CPP_WORDSZ 32
+#   else
+#	define ALIGNMENT   8
+#	define CPP_WORDSZ 64
+#	define HBLKSIZE 4096
+#   endif
 #   ifdef LINUX
 #       define OS_TYPE "LINUX"
 #       define HEURISTIC1
 #       define DYNAMIC_LOADING
         extern int __data_start[];
 #       define DATASTART ((ptr_t)(__data_start))
+	extern int _end[];
+#	define DATAEND (_end)
+#	define CACHE_LINE_SIZE 256
+#	define GETPAGESIZE() 4096
 #   endif
 # endif
 
@@ -1818,7 +1836,7 @@
 # define CAN_SAVE_CALL_STACKS
 # define CAN_SAVE_CALL_ARGS
 #endif
-#if defined(I386) && defined(LINUX)
+#if (defined(I386) || defined(S390)) && defined(LINUX)
     /* SAVE_CALL_CHAIN is supported if the code is compiled to save	*/
     /* frame pointers by default, i.e. no -fomit-frame-pointer flag.	*/
 # define CAN_SAVE_CALL_STACKS
--- ./boehm-gc/include/private/gc_locks.h.orig	2001-10-16 05:01:39.000000000 -0400
+++ ./boehm-gc/include/private/gc_locks.h	2003-05-07 23:12:28.000000000 -0400
@@ -209,6 +209,21 @@
         }
 #       define GC_TEST_AND_SET_DEFINED
 #    endif /* ARM32 */
+#    ifdef S390
+	inline static int GC_test_and_set(volatile unsigned int *spinlock) {
+	 int ret;
+	 /* See linuxthreads/sysdeps/s390/s390-32/pt-machine.h in glibc-2.2 */
+	   __asm__ __volatile__(
+		"	la	1,%1\n"
+		"	lhi	0,1\n"
+		"	l	%0,%1\n"
+		"0:	cs	%0,0,0(1)\n"
+		"	jl	0b"
+		: "=&d" (ret), "+m" (*spinlock)
+		: : "0", "1", "cc");
+	   return(ret);
+	}
+#    endif
 #  endif /* __GNUC__ */
 #  if (defined(ALPHA) && !defined(__GNUC__))
 #    define GC_test_and_set(addr) __cxx_test_and_set_atomic(addr, 1)
@@ -326,6 +341,42 @@
         }
 #      endif /* 0 */
 #     endif /* IA64 */
+#     if defined(S390)
+#      if !defined(GENERIC_COMPARE_AND_SWAP)
+#       ifndef __s390x__
+	 inline static GC_bool GC_compare_and_exchange(volatile C_word *addr,
+						       GC_word old, GC_word new_val) {
+	  int retval;
+	
+	   __asm__ __volatile (
+		"	lr	0,%2\n"
+		"	cs	0,%3,%1\n"
+		"	ipm	%0\n"
+		"	srl	%0,28\n"
+		: "=&d" (retval), "+m" (*addr)
+		: "d" (old), "d" (new_val)
+		: "0", "cc");
+	   return(retval == 0);
+	}
+#       else
+         inline static GC_bool GC_compare_and_exchange(volatile C_word *addr,
+						       GC_word old, GC_word new_v
+al) {
+	  int retval;
+
+	   __asm__ __volatile (
+		"	lgr	0,%2\n"
+		"	csg	0,%3,%1\n"
+		"	ipm	%0\n"
+		"	srl	%0,28\n"
+		: "=&d" (retval), "+m" (*addr)
+		: "d" (old), "d" (new_val)
+		: "0", "cc");
+	   return(retval == 0)
+	}
+#       endif
+#      endif
+#     endif
 #     if !defined(GENERIC_COMPARE_AND_SWAP)
         /* Returns the original value of *addr.	*/
         inline static GC_word GC_atomic_add(volatile GC_word *addr,
--- ./libffi/include/ffi.h.in.orig	2002-03-12 17:35:56.000000000 -0500
+++ ./libffi/include/ffi.h.in	2003-05-07 23:12:28.000000000 -0400
@@ -251,6 +251,13 @@
   FFI_DEFAULT_ABI = FFI_SYSV,
 #endif
 
+  /* ---- S390 - 31 & 64-bit ------ */
+
+#if defined(S390) || defined(S390X)
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
   /* Leave this for debugging purposes */
   FFI_LAST_ABI
 
--- ./libffi/src/s390/ffi.c.orig	1969-12-31 19:00:00.000000000 -0500
+++ ./libffi/src/s390/ffi.c	2003-05-07 23:12:28.000000000 -0400
@@ -0,0 +1,591 @@
+#ifndef __s390x__
+/* -----------------------------------------------------------------------
+   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                                  */
+/*                           -------                                  */
+/*====================================================================*/
+
+#define MAX_GPRARGS 5        /* Max. no. of GPR available             */
+#define MAX_FPRARGS 2        /* Max. no. of FPR available             */
+
+#define STR_GPR     1        /* Structure will fit in 1 or 2 GPR      */
+#define STR_FPR     2        /* Structure will fit in a FPR           */
+#define STR_STACK   3        /* Structure needs to go on stack        */
+
+/*===================== End of Defines ===============================*/
+
+/*====================================================================*/
+/*                            Types                                   */
+/*                            -----                                   */
+/*====================================================================*/
+
+typedef struct stackLayout
+{
+  int   *backChain;
+  int   *endOfStack;
+  int   glue[2];
+  int   scratch[2];
+  int   gprArgs[MAX_GPRARGS];
+  int   notUsed;
+  union
+  {
+    float  f;
+    double d;
+  } fprArgs[MAX_FPRARGS];
+  int   unUsed[8];
+  int   outArgs[100];
+} stackLayout;
+
+/*======================== End of Types ==============================*/
+
+/*====================================================================*/
+/*                          Prototypes                                */
+/*                          ----------                                */
+/*====================================================================*/
+
+void ffi_prep_args(stackLayout *, extended_cif *);
+static int  ffi_check_struct(ffi_type *, unsigned int *);
+static void ffi_insert_int(int, stackLayout *, int *, int *);
+static void ffi_insert_int64(long long, stackLayout *, int *, int *);
+static void ffi_insert_double(double, stackLayout *, int *, int *);
+
+/*====================== End of Prototypes ===========================*/
+
+/*====================================================================*/
+/*                          Externals                                 */
+/*                          ---------                                 */
+/*====================================================================*/
+
+extern void ffi_call_SYSV(void (*)(stackLayout *, extended_cif *),
+			  extended_cif *,
+			  unsigned, unsigned,
+			  unsigned *,
+			  void (*fn)());
+
+/*====================== End of Externals ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_check_struct.                                       */
+/*                                                                    */
+/* Function - Determine if a structure can be passed within a         */
+/*            general or floating point register.                     */
+/*                                                                    */
+/*====================================================================*/
+
+int
+ffi_check_struct(ffi_type *arg, unsigned int *strFlags)
+{
+ ffi_type *element;
+ int      i_Element;
+
+ for (i_Element = 0; arg->elements[i_Element]; i_Element++) {
+   element = arg->elements[i_Element];
+   switch (element->type) {
+   case FFI_TYPE_DOUBLE :
+     *strFlags |= STR_FPR;
+     break;
+    
+   case FFI_TYPE_STRUCT :
+     *strFlags |= ffi_check_struct(element, strFlags);
+     break;
+    
+   default :
+     *strFlags |= STR_GPR;
+   }
+ }
+ return (*strFlags);
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_insert_int.                                         */
+/*                                                                    */
+/* Function - Insert an integer parameter in a register if there are  */
+/*            spares else on the stack.                               */
+/*                                                                    */
+/*====================================================================*/
+
+void
+ffi_insert_int(int gprValue, stackLayout *stack,
+               int *intArgC, int *outArgC)
+{
+  if (*intArgC < MAX_GPRARGS) {
+    stack->gprArgs[*intArgC] = gprValue;
+    *intArgC += 1;
+  }
+  else {
+    stack->outArgs[*outArgC++] = gprValue;
+    *outArgC += 1;
+  }
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_insert_int64.                                       */
+/*                                                                    */
+/* Function - Insert a long long parameter in registers if there are  */
+/*            spares else on the stack.                               */
+/*                                                                    */
+/*====================================================================*/
+
+void
+ffi_insert_int64(long long llngValue, stackLayout *stack,
+                 int *intArgC, int *outArgC)
+{
+
+  if (*intArgC < (MAX_GPRARGS-1)) {
+    memcpy(&stack->gprArgs[*intArgC],
+	   &llngValue, sizeof(long long));	
+    *intArgC += 2;
+  }
+  else {
+    memcpy(&stack->outArgs[*outArgC],
+	   &llngValue, sizeof(long long));
+    *outArgC += 2;
+  }
+
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_insert_double.                                      */
+/*                                                                    */
+/* Function - Insert a double parameter in a FP register if there is  */
+/*            a spare else on the stack.                              */
+/*                                                                    */
+/*====================================================================*/
+
+void
+ffi_insert_double(double dblValue, stackLayout *stack,
+                  int *fprArgC, int *outArgC)
+{
+
+  if (*fprArgC < MAX_FPRARGS) {
+    stack->fprArgs[*fprArgC].d = dblValue;
+    *fprArgC += 1;
+  }
+  else {
+    memcpy(&stack->outArgs[*outArgC],
+	   &dblValue,sizeof(double));
+    *outArgC += 2;
+  }
+
+}
+
+/*======================== 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.                   */
+/*                                                                    */
+/* The stack layout we want looks like this:                          */
+/* *------------------------------------------------------------*     */
+/* |  0     | Back chain (a 0 here signifies end of back chain) |     */
+/* +--------+---------------------------------------------------+     */
+/* |  4     | EOS (end of stack, not used on Linux for S390)    |     */
+/* +--------+---------------------------------------------------+     */
+/* |  8     | Glue used in other linkage formats                |     */
+/* +--------+---------------------------------------------------+     */
+/* | 12     | Glue used in other linkage formats                |     */
+/* +--------+---------------------------------------------------+     */
+/* | 16     | Scratch area                                      |     */
+/* +--------+---------------------------------------------------+     */
+/* | 20     | Scratch area                                      |     */
+/* +--------+---------------------------------------------------+     */
+/* | 24     | GPR parameter register 1                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 28     | GPR parameter register 2                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 32     | GPR parameter register 3                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 36     | GPR parameter register 4                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 40     | GPR parameter register 5                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 44     | Unused                                            |     */
+/* +--------+---------------------------------------------------+     */
+/* | 48     | FPR parameter register 1                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 56     | FPR parameter register 2                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 64     | Unused                                            |     */
+/* +--------+---------------------------------------------------+     */
+/* | 96     | Outgoing args (length x)                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 96+x   | Copy area for structures (length y)               |     */
+/* +--------+---------------------------------------------------+     */
+/* | 96+x+y | Possible stack alignment                          |     */
+/* *------------------------------------------------------------*     */
+/*                                                                    */
+/*====================================================================*/
+
+void
+ffi_prep_args(stackLayout *stack, extended_cif *ecif)
+{
+  const unsigned bytes = ecif->cif->bytes;
+  const unsigned flags = ecif->cif->flags;
+
+  /*----------------------------------------------------------*/
+  /* Pointer to the copy area on stack for structures         */
+  /*----------------------------------------------------------*/
+  char *copySpace = (char *) stack + bytes + sizeof(stackLayout);
+
+  /*----------------------------------------------------------*/
+  /* Count of general and floating point register usage       */
+  /*----------------------------------------------------------*/
+  int intArgC = 0,
+    fprArgC = 0,
+    outArgC = 0;
+
+  int      i;
+  ffi_type **ptr;
+  void     **p_argv;
+  size_t   structCopySize;
+  unsigned gprValue, strFlags = 0;
+  unsigned long long llngValue;
+  double   dblValue;
+
+  /* Now for the arguments.  */
+  p_argv  = ecif->avalue;
+
+  /*----------------------------------------------------------------------*/
+  /* If we returning a structure then we set the first parameter register */
+  /* to the address of where we are returning this structure              */
+  /*----------------------------------------------------------------------*/
+  if (flags == FFI_TYPE_STRUCT)
+    stack->gprArgs[intArgC++] = (int) ecif->rvalue;
+
+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+       i > 0;
+       i--, ptr++, p_argv++)
+    {
+      switch ((*ptr)->type) {
+
+      case FFI_TYPE_FLOAT:
+	if (fprArgC < MAX_FPRARGS)
+	  stack->fprArgs[fprArgC++].f = *(float *) *p_argv;
+	else
+	  stack->outArgs[outArgC++] = *(int *) *p_argv;
+	break;
+
+      case FFI_TYPE_DOUBLE:
+	dblValue = *(double *) *p_argv;
+	ffi_insert_double(dblValue, stack, &fprArgC, &outArgC);
+	break;
+	
+      case FFI_TYPE_UINT64:
+      case FFI_TYPE_SINT64:
+	llngValue = *(unsigned long long *) *p_argv;
+	ffi_insert_int64(llngValue, stack, &intArgC, &outArgC);
+	break;
+
+      case FFI_TYPE_UINT8:
+	gprValue = *(unsigned char *)*p_argv;
+	ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+	break;
+
+      case FFI_TYPE_SINT8:
+	gprValue = *(signed char *)*p_argv;
+	ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+	break;
+
+      case FFI_TYPE_UINT16:
+	gprValue = *(unsigned short *)*p_argv;
+	ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+	break;
+
+      case FFI_TYPE_SINT16:
+	gprValue = *(signed short *)*p_argv;
+	ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+	break;
+
+      case FFI_TYPE_STRUCT:
+	/*--------------------------------------------------*/
+	/* If structure > 8 bytes then it goes on the stack */
+	/*--------------------------------------------------*/
+	if (((*ptr)->size > 8) ||
+	    ((*ptr)->size > 4  &&
+	     (*ptr)->size < 8))
+	  strFlags = STR_STACK;
+	else
+	  strFlags = ffi_check_struct((ffi_type *) *ptr, &strFlags);
+
+	switch (strFlags) {
+	/*-------------------------------------------*/
+	/* Structure that will fit in one or two GPR */
+	/*-------------------------------------------*/
+	case STR_GPR :
+	  if ((*ptr)->size <= 4) {
+	    gprValue = *(unsigned int *) *p_argv;
+	    gprValue = gprValue >> ((4 - (*ptr)->size) * 8);
+	    ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+	  }
+	  else {
+	    llngValue = *(unsigned long long *) *p_argv;
+	    ffi_insert_int64(llngValue, stack, &intArgC, &outArgC);
+	  }
+	  break;
+
+	/*-------------------------------------------*/
+	/* Structure that will fit in one FPR        */
+	/*-------------------------------------------*/
+	case STR_FPR :
+	  dblValue = *(double *) *p_argv;
+	  ffi_insert_double(dblValue, stack, &fprArgC, &outArgC);
+	  break;
+
+	/*-------------------------------------------*/
+	/* Structure that must be copied to stack    */
+	/*-------------------------------------------*/
+	default :
+	  structCopySize = (((*ptr)->size + 15) & ~0xF);
+	  copySpace -= structCopySize;
+	  memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
+	  gprValue = (unsigned) copySpace;
+	  if (intArgC < MAX_GPRARGS)
+	    stack->gprArgs[intArgC++] = gprValue;
+	  else
+	    stack->outArgs[outArgC++] = gprValue;
+	}
+	break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+      case FFI_TYPE_LONGDOUBLE:
+	structCopySize = (((*ptr)->size + 15) & ~0xF);
+	copySpace -= structCopySize;
+	memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
+	gprValue = (unsigned) copySpace;
+	if (intArgC < MAX_GPRARGS)
+	  stack->gprArgs[intArgC++] = gprValue;
+	else
+	  stack->outArgs[outArgC++] = gprValue;
+	break;
+#endif
+
+      case FFI_TYPE_INT:
+      case FFI_TYPE_UINT32:
+      case FFI_TYPE_SINT32:
+      case FFI_TYPE_POINTER:
+	gprValue = *(unsigned *)*p_argv;
+	if (intArgC < MAX_GPRARGS)
+	  stack->gprArgs[intArgC++] = gprValue;
+	else
+	  stack->outArgs[outArgC++] = gprValue;
+	break;
+
+      }
+    }
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_cif_machdep.                                   */
+/*                                                                    */
+/* Function - Perform machine dependent CIF processing.               */
+/*                                                                    */
+/*====================================================================*/
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int i;
+  ffi_type **ptr;
+  unsigned bytes;
+  int fpArgC  = 0,
+    intArgC = 0;
+  unsigned flags = 0;
+  unsigned structCopySize = 0;
+
+  /*-----------------------------------------------------------------*/
+  /* Extra space required in stack for overflow parameters.          */
+  /*-----------------------------------------------------------------*/
+  bytes = 0;
+
+  /*--------------------------------------------------------*/
+  /* Return value handling.  The rules are as follows:	    */
+  /* - 32-bit (or less) integer values are returned in gpr2 */
+  /* - Structures are returned as pointers in gpr2	    */
+  /* - 64-bit integer values are returned in gpr2 and 3	    */
+  /* - Single/double FP values are returned in fpr0	    */
+  /*--------------------------------------------------------*/
+  flags = cif->rtype->type;
+
+  /*------------------------------------------------------------------------*/
+  /* The first MAX_GPRARGS words of integer arguments, and the      	    */
+  /* first MAX_FPRARGS floating point arguments, go in registers; the rest  */
+  /* goes on the stack.  Structures and long doubles (if not equivalent     */
+  /* to double) are passed as a pointer to a copy of the structure.	    */
+  /* Stuff on the stack needs to keep proper alignment.  		    */
+  /*------------------------------------------------------------------------*/
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+	  fpArgC++;
+	  if (fpArgC > MAX_FPRARGS && intArgC%2 != 0)
+	    intArgC++;
+	  break;
+
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	  /*----------------------------------------------------*/
+	  /* 'long long' arguments are passed as two words, but */
+	  /* either both words must fit in registers or both go */
+	  /* on the stack.  If they go on the stack, they must  */
+	  /* be 8-byte-aligned. 			 	      */
+	  /*----------------------------------------------------*/
+	  if ((intArgC == MAX_GPRARGS-1) ||
+	      (intArgC >= MAX_GPRARGS)   &&
+	      (intArgC%2 != 0))
+	    intArgC++;
+	  intArgC += 2;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	  /*----------------------------------------------------*/
+	  /* We must allocate space for a copy of these to      */
+	  /* enforce pass-by-value. Pad the space up to a       */
+	  /* multiple of 16 bytes (the maximum alignment 	      */
+	  /* required for anything under the SYSV ABI). 	      */
+	  /*----------------------------------------------------*/
+	  structCopySize += ((*ptr)->size + 15) & ~0xF;
+	  /*----------------------------------------------------*/
+	  /* Fall through (allocate space for the pointer).     */
+	  /*----------------------------------------------------*/
+
+	default:
+	  /*----------------------------------------------------*/
+	  /* Everything else is passed as a 4-byte word in a    */
+	  /* GPR either the object itself or a pointer to it.   */
+	  /*----------------------------------------------------*/
+	  intArgC++;
+	  break;
+	}
+    }
+
+  /*-----------------------------------------------------------------*/
+  /* Stack space.                                                    */
+  /*-----------------------------------------------------------------*/
+  if (intArgC > MAX_GPRARGS)
+    bytes += (intArgC - MAX_GPRARGS) * sizeof(int);
+  if (fpArgC > MAX_FPRARGS)
+    bytes += (fpArgC - MAX_FPRARGS) * sizeof(double);
+
+  /*-----------------------------------------------------------------*/
+  /* The stack space allocated needs to be a multiple of 16 bytes.   */
+  /*-----------------------------------------------------------------*/
+  bytes = (bytes + 15) & ~0xF;
+
+  /*-----------------------------------------------------------------*/
+  /* Add in the space for the copied structures.                     */
+  /*-----------------------------------------------------------------*/
+  bytes += structCopySize;
+
+  cif->flags = flags;
+  cif->bytes = bytes;
+
+  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)
+{
+  extended_cif ecif;
+
+  ecif.cif    = cif;
+  ecif.avalue = avalue;
+
+  /*-----------------------------------------------------------------*/
+  /* If the return value is a struct and we don't have a return      */
+  /* value address then we need to make one                          */
+  /*-----------------------------------------------------------------*/
+  if ((rvalue == NULL) &&
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    ecif.rvalue = alloca(cif->rtype->size);
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi)
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args,
+		    &ecif, cif->bytes,
+		    cif->flags, ecif.rvalue, fn);
+      break;
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+/*======================== End of Routine ============================*/
+#endif /* #ifndef __s390x__ */
--- ./libffi/src/s390/sysv.S.orig	1969-12-31 19:00:00.000000000 -0500
+++ ./libffi/src/s390/sysv.S	2003-05-07 23:12:28.000000000 -0400
@@ -0,0 +1,184 @@
+#ifndef __s390x__
+/* -----------------------------------------------------------------------
+   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 <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#endif
+	
+.text
+ 
+	# r2:	ffi_prep_args
+	# r3:	&ecif
+	# r4:	cif->bytes
+	# r5:	fig->flags
+	# r6:	ecif.rvalue
+	# sp+0: fn
+ 
+	# This assumes we are using gas.
+	.globl	ffi_call_SYSV
+	.type	ffi_call_SYSV,%function
+ffi_call_SYSV:
+	# Save registers
+	stm	%r6,%r15,24(%r15)
+	l	%r7,96(%r15)	       # Get A(fn)
+	lr	%r0,%r15
+	ahi	%r15,-128	       # Make room for my args
+	st	%r0,0(%r15)	       # Set backchain
+	lr	%r11,%r15	       # Establish my stack register
+	sr	%r15,%r4	       # Make room for fn args
+	ahi	%r15,-96	       # Make room for new frame
+	lr	%r10,%r15	       # Establish stack build area
+	ahi	%r15,-96	       # Stack for next call
+	lr	%r1,%r7
+	stm	%r2,%r7,96(%r11)       # Save args on my stack
+ 
+#------------------------------------------------------------------
+#	move first 3 parameters in registers
+#------------------------------------------------------------------
+	lr	%r9,%r2		       # r9:	 &ffi_prep_args
+	lr	%r2,%r10	       # Parm 1: &stack Parm 2: &ecif
+	basr	%r14,%r9	       # call ffi_prep_args
+ 
+#------------------------------------------------------------------
+#	load  first 5 parameter registers
+#------------------------------------------------------------------
+	lm	%r2,%r6,24(%r10)
+ 
+#------------------------------------------------------------------
+#	load  fp parameter registers
+#------------------------------------------------------------------
+	ld	%f0,48(%r10)
+	ld	%f2,56(%r10)
+ 
+#------------------------------------------------------------------
+#	call  function
+#------------------------------------------------------------------
+	lr	%r15,%r10	       # Set new stack
+	l	%r9,116(%r11)	       # Get &fn
+	basr	%r14,%r9	       # Call function
+ 
+#------------------------------------------------------------------
+#	On return:
+#	   r2: Return value (r3: Return value + 4 for long long)
+#------------------------------------------------------------------
+ 
+#------------------------------------------------------------------
+#	If the return value pointer is NULL, assume no return value.
+#------------------------------------------------------------------
+	icm	%r6,15,112(%r11)
+	jz	.Lepilogue
+ 
+	l	%r5,108(%r11)	       # Get return type
+        sll     %r5,2                  /* Form displacement            */
+	basr	%r1,0		       /* Establish base	       */
+        la      %r1,.LretTable-ffi_call_SYSV(%r1)
+        alr     %r5,%r1                /* Address actual entry         */
+        br      %r5                    /* Branch to the jump           */
+
+.LretTable:
+        j       .LretPointer           /* Void                         */
+        j       .LretInt               /* Integer                      */
+        j       .LretFloat             /* Float                        */
+        j       .LretDouble            /* Double                       */
+        j       .LretLongDouble        /* Long Double                  */
+        j       .LretByte              /* Unsigned Byte                */
+        j       .LretByte              /* Signed Byte                  */
+        j       .LretShort             /* Unsigned Short               */
+        j       .LretShort             /* Signed Short                 */
+        j       .LretInt               /* Unsigned Integer             */
+        j       .LretInt               /* Signed Integer               */
+        j       .LretLong              /* Unsigned Long                */
+        j       .LretLong              /* Signed Long                  */
+        j       .Lepilogue             /* Structure                    */
+        j       .LretPointer           /* Pointer                      */
+
+#------------------------------------------------------------------
+#       return BYTE
+#------------------------------------------------------------------
+.LretByte:
+        stc     %r2,0(%r6)
+        j       .Lepilogue
+
+#------------------------------------------------------------------
+#       return SHORT
+#------------------------------------------------------------------
+.LretShort:
+        stcm    %r2,3,0(%r6)
+        j       .Lepilogue
+
+#------------------------------------------------------------------
+#	return INT
+#------------------------------------------------------------------
+.LretInt: 
+	st	%r2,0(%r6)
+	j	.Lepilogue
+ 
+#------------------------------------------------------------------
+#	return LONG LONG (signed/unsigned)
+#------------------------------------------------------------------
+.LretLong:
+	stm	%r2,%r3,0(%r6)
+	j	.Lepilogue
+ 
+#------------------------------------------------------------------
+#	return FLOAT
+#------------------------------------------------------------------
+.LretFloat:
+	ste	%f0,0(%r6)
+	j	.Lepilogue
+ 
+#------------------------------------------------------------------
+#	return DOUBLE or LONGDOUBLE
+#------------------------------------------------------------------
+.LretDouble:
+.LretLongDouble:
+	std	%f0,0(%r6)
+	j	.Lepilogue
+ 
+#------------------------------------------------------------------
+# Structure - rvalue already set as sent as 1st parm to routine
+#------------------------------------------------------------------
+.LretStruct:
+	j 	.Lepilogue
+ 
+#------------------------------------------------------------------
+#	return a pointer
+#------------------------------------------------------------------
+.LretPointer:
+	st	%r2,0(%r6)
+	j	.Lepilogue
+ 
+.Lepilogue:
+	l	%r15,0(%r11)
+	l	%r4,56(%r15)
+	lm	%r6,%r15,24(%r15)
+	br	%r4
+ 
+.ffi_call_SYSV_end:
+	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+#endif /* #ifndef __s390x__ */
--- ./libffi/src/types.c.orig	2001-03-26 21:39:16.000000000 -0500
+++ ./libffi/src/types.c	2003-05-07 23:12:28.000000000 -0400
@@ -42,7 +42,7 @@
 FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32);
 FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT);
 
-#if defined ALPHA || defined SPARC64
+#if defined ALPHA || defined SPARC64 || defined S390X
 
 FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);
 
--- ./libffi/src/s390/ffi64.c.orig	1969-12-31 19:00:00.000000000 -0500
+++ ./libffi/src/s390/ffi64.c	2003-05-07 23:12:28.000000000 -0400
@@ -0,0 +1,585 @@
+#ifdef __s390x__
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2000 Software AG
+
+   S390 Foreign Function Interface
+
+   $Id: $
+
+   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>
+#include <stdint.h>
+
+/*====================== End of Includes =============================*/
+
+/*====================================================================*/
+/*                           Defines                                  */
+/*                           -------                                  */
+/*====================================================================*/
+
+#define MAX_GPRARGS 5        /* Max. no. of GPR available             */
+#define MAX_FPRARGS 4        /* Max. no. of FPR available             */
+
+#define STR_GPR     1        /* Structure will fit in 1 or 2 GPR      */
+#define STR_FPR     2        /* Structure will fit in a FPR           */
+#define STR_STACK   3        /* Structure needs to go on stack        */
+
+/*===================== End of Defines ===============================*/
+
+/*====================================================================*/
+/*                            Types                                   */
+/*                            -----                                   */
+/*====================================================================*/
+
+typedef struct stackLayout
+{
+   uint64_t  *backChain;		/*   0 */
+   uint64_t  *endOfStack;		/*   8 */
+   uint64_t  glue[2];			/*  16 */
+   uint64_t  scratch[2];		/*  32 */
+   uint64_t  gprArgs[MAX_GPRARGS];	/*  48 */
+   uint64_t  notUsed;			/*  88 */
+   uint64_t  fprArgs[MAX_FPRARGS];	/*  96 */
+   uint64_t  unUsed[4];			/* 128 */
+   uint64_t  outArgs[44];		/* 160 */
+ } stackLayout;				/* 512 */
+
+/*======================== End of Types ==============================*/
+
+/*====================================================================*/
+/*                          Prototypes                                */
+/*                          ----------                                */
+/*====================================================================*/
+
+void ffi_prep_args(stackLayout *, extended_cif *);
+static int  ffi_check_struct(ffi_type *, unsigned int *);
+
+/*====================== End of Prototypes ===========================*/
+
+/*====================================================================*/
+/*                          Externals                                 */
+/*                          ---------                                 */
+/*====================================================================*/
+
+extern void ffi_call_SYSV(void (*)(stackLayout *, extended_cif *),
+			  extended_cif *,
+			  unsigned, unsigned,
+			  unsigned *,
+			  void (*fn)());
+
+/*====================== End of Externals ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_check_struct.                                       */
+/*                                                                    */
+/* Function - Determine if a structure can be passed within a         */
+/*            general or floating point register.                     */
+/*                                                                    */
+/*====================================================================*/
+
+int
+ffi_check_struct(ffi_type *arg, unsigned int *strFlags)
+{
+ ffi_type *element;
+ int      i_Element;
+
+	for (i_Element = 0; arg->elements[i_Element]; i_Element++) {
+		element = arg->elements[i_Element];
+		switch (element->type) {
+			case FFI_TYPE_DOUBLE :
+				*strFlags |= STR_FPR;
+			break;
+
+			case FFI_TYPE_STRUCT :
+				*strFlags |= ffi_check_struct(element, strFlags);
+			break;
+
+			default :
+				*strFlags |= STR_GPR;
+		}
+	}
+	return (*strFlags);
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_insert_int.                                         */
+/*                                                                    */
+/* Function - Insert an integer or long parameter in a register if    */
+/*            there are spares else on the stack.                     */
+/*                                                                    */
+/*====================================================================*/
+
+static inline void
+ffi_insert_int(uint64_t gprValue, stackLayout *stack,
+               int *intArgC, int *outArgC)
+{
+
+	if (*intArgC < MAX_GPRARGS) {
+		stack->gprArgs[*intArgC] = gprValue;
+		*intArgC += 1;
+	}
+	else {
+		stack->outArgs[*outArgC] = gprValue;
+		*outArgC += 1;
+	}
+
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_insert_float.                                       */
+/*                                                                    */
+/* Function - Insert a float parameter in a FP register if there is   */
+/*            a spare else on the stack.                              */
+/*                                                                    */
+/*====================================================================*/
+
+static inline void
+ffi_insert_float(uint64_t fltValue, stackLayout *stack,
+                 int *fprArgC, int *outArgC)
+{
+
+	if (*fprArgC < MAX_FPRARGS) {
+		stack->fprArgs[*fprArgC] = fltValue << 32;
+		*fprArgC += 1;
+	}
+	else {
+		stack->outArgs[*outArgC] = fltValue;
+		*outArgC += 1;
+	}
+
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_insert_double.                                      */
+/*                                                                    */
+/* Function - Insert a double parameter in a FP register if there is  */
+/*            a spare else on the stack.                              */
+/*                                                                    */
+/*====================================================================*/
+
+static inline void
+ffi_insert_double(uint64_t dblValue, stackLayout *stack,
+                  int *fprArgC, int *outArgC)
+{
+
+        if (*fprArgC < MAX_FPRARGS) {
+                stack->fprArgs[*fprArgC] = dblValue;
+                *fprArgC += 1;
+        }
+        else {
+                stack->outArgs[*outArgC] = dblValue;
+                *outArgC += 1;
+        }
+
+}
+
+/*======================== 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.                   */
+/*                                                                    */
+/* The stack layout we want looks like this:                          */
+/* *------------------------------------------------------------*     */
+/* |   0    | Back chain (a 0 here signifies end of back chain) |     */
+/* +--------+---------------------------------------------------+     */
+/* |   8    | EOS (end of stack, not used on Linux for S390)    |     */
+/* +--------+---------------------------------------------------+     */
+/* |  16    | Glue used in other linkage formats                |     */
+/* +--------+---------------------------------------------------+     */
+/* |  24    | Glue used in other linkage formats                |     */
+/* +--------+---------------------------------------------------+     */
+/* |  32    | Scratch area                                      |     */
+/* +--------+---------------------------------------------------+     */
+/* |  40    | Scratch area                                      |     */
+/* +--------+---------------------------------------------------+     */
+/* |  48    | GPR parameter register 1                          |     */
+/* +--------+---------------------------------------------------+     */
+/* |  56    | GPR parameter register 2                          |     */
+/* +--------+---------------------------------------------------+     */
+/* |  64    | GPR parameter register 3                          |     */
+/* +--------+---------------------------------------------------+     */
+/* |  72    | GPR parameter register 4                          |     */
+/* +--------+---------------------------------------------------+     */
+/* |  80    | GPR parameter register 5                          |     */
+/* +--------+---------------------------------------------------+     */
+/* |  88    | Unused                                            |     */
+/* +--------+---------------------------------------------------+     */
+/* |  96    | FPR parameter register 1                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 112    | FPR parameter register 2                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 120    | FPR parameter register 3                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 128    | FPR parameter register 4                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 136    | Unused                                            |     */
+/* +--------+---------------------------------------------------+     */
+/* | 160    | Outgoing args (length x)                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 160+x  | Copy area for structures (length y)               |     */
+/* +--------+---------------------------------------------------+     */
+/* | 160+x+y| Possible stack alignment                          |     */
+/* *------------------------------------------------------------*     */
+/*                                                                    */
+/*====================================================================*/
+
+void
+ffi_prep_args(stackLayout *stack, extended_cif *ecif)
+{
+ const unsigned bytes = ecif->cif->bytes;
+ const unsigned flags = ecif->cif->flags;
+
+ /*----------------------------------------------------------*/
+ /* Pointer to the copy area on stack for structures         */
+ /*----------------------------------------------------------*/
+ char *copySpace = (char *) stack + bytes + sizeof(stackLayout);
+
+ /*----------------------------------------------------------*/
+ /* Count of general and floating point register usage       */
+ /*----------------------------------------------------------*/
+ int intArgC = 0,
+     fprArgC = 0,
+     outArgC = 0;
+
+ int      i;
+ ffi_type **ptr;
+ void     **p_argv;
+ size_t   structCopySize;
+ unsigned strFlags = 0;
+ uint64_t lngValue;
+ union
+ {
+    uint32_t i[2];
+    float    f[2];
+    uint64_t l;
+ } prmData;
+
+  prmData.l = 0;
+
+  /* Now for the arguments.  */
+  p_argv  = ecif->avalue;
+
+  /*----------------------------------------------------------------------*/
+  /* If we returning a structure then we set the first parameter register */
+  /* to the address of where we are returning this structure              */
+  /*----------------------------------------------------------------------*/
+  if (flags == FFI_TYPE_STRUCT)
+     stack->gprArgs[intArgC++] = (int) ecif->rvalue;
+
+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+       i > 0;
+       i--, ptr++, p_argv++)
+    {
+      switch ((*ptr)->type) {
+
+		case FFI_TYPE_FLOAT:
+			prmData.f[1] = *(float *) *p_argv;
+			ffi_insert_float(prmData.l, stack, &fprArgC, &outArgC);
+			break;
+
+		case FFI_TYPE_DOUBLE:
+			lngValue = *(uint64_t *) *p_argv;
+			ffi_insert_double(lngValue, stack, &fprArgC, &outArgC);
+			break;
+	
+		case FFI_TYPE_UINT64:
+		case FFI_TYPE_SINT64:
+		case FFI_TYPE_POINTER:
+			lngValue = *(uint64_t *) *p_argv;
+			ffi_insert_int(lngValue, stack, &intArgC, &outArgC);
+		break;
+
+		case FFI_TYPE_UINT8:
+			prmData.i[1] = *(unsigned char *) *p_argv;
+			ffi_insert_int(prmData.l, stack, &intArgC, &outArgC);
+		break;
+
+		case FFI_TYPE_SINT8:
+			prmData.i[1] = *(signed char *) *p_argv;
+			ffi_insert_int(prmData.l, stack, &intArgC, &outArgC);
+		break;
+
+		case FFI_TYPE_UINT16:
+			prmData.i[1] = *(unsigned short *) *p_argv;
+			ffi_insert_int(prmData.l, stack, &intArgC, &outArgC);
+		break;
+
+		case FFI_TYPE_SINT16:
+			prmData.i[1] = *(signed short *) *p_argv;
+			ffi_insert_int(prmData.l, stack, &intArgC, &outArgC);
+		break;
+
+		case FFI_TYPE_STRUCT:
+			/*--------------------------------------------------*/
+			/* If structure > 8 bytes then it goes on the stack */
+			/*--------------------------------------------------*/
+			if (((*ptr)->size > 8) ||
+			    ((*ptr)->size > 4  &&
+			     (*ptr)->size < 8))
+				strFlags = STR_STACK;
+			else
+				strFlags = ffi_check_struct((ffi_type *) *ptr, &strFlags);
+
+			switch (strFlags) {
+				/*-------------------------------------------*/
+				/* Structure that will fit in a GPR          */
+				/*-------------------------------------------*/
+				case STR_GPR :
+					if ((*ptr)->size <= 8) {
+						lngValue = *(uint64_t *) *p_argv;
+						lngValue = lngValue >> ((8 - (*ptr)->size) * 8);
+						ffi_insert_int(lngValue, stack, &intArgC, &outArgC);
+					}
+					else {
+						lngValue = *(uint64_t *) *p_argv;
+						ffi_insert_int(lngValue, stack, &intArgC, &outArgC);
+					}
+				break;
+
+				/*-------------------------------------------*/
+				/* Structure that will fit in one FPR        */
+				/*-------------------------------------------*/
+				case STR_FPR :
+					lngValue = *(uint64_t *) *p_argv;
+					ffi_insert_double(lngValue, stack, &fprArgC, &outArgC);
+				break;
+
+				/*-------------------------------------------*/
+				/* Structure that must be copied to stack    */
+				/*-------------------------------------------*/
+				default :
+					structCopySize = (((*ptr)->size + 15) & ~0xF);
+					copySpace -= structCopySize;
+					memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
+					lngValue = (uint64_t) copySpace;
+					ffi_insert_int(lngValue, stack, &intArgC, &outArgC);
+			}
+		break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+		case FFI_TYPE_LONGDOUBLE:
+			structCopySize = (((*ptr)->size + 15) & ~0xF);
+			copySpace -= structCopySize;
+			memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
+			lngValue = (unsigned) copySpace;
+			if (intArgC < MAX_GPRARGS)
+				stack->gprArgs[intArgC++] = lngValue;
+			else
+				stack->outArgs[outArgC++] = lngValue;
+		break;
+#endif
+
+		case FFI_TYPE_INT:
+		case FFI_TYPE_UINT32:
+		case FFI_TYPE_SINT32:
+			prmData.i[1] = *(uint32_t *) *p_argv;
+			ffi_insert_int(prmData.l, stack, &intArgC, &outArgC);
+		break;
+
+	}
+    }
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_cif_machdep.                                   */
+/*                                                                    */
+/* Function - Perform machine dependent CIF processing.               */
+/*                                                                    */
+/*====================================================================*/
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int i;
+  ffi_type **ptr;
+  unsigned bytes;
+  int fpArgC  = 0,
+      intArgC = 0;
+  unsigned flags = 0;
+  unsigned structCopySize = 0;
+
+  /*-----------------------------------------------------------------*/
+  /* Extra space required in stack for overflow parameters.          */
+  /*-----------------------------------------------------------------*/
+  bytes = 0;
+
+  /*--------------------------------------------------------*/
+  /* Return value handling.  The rules are as follows:	    */			
+  /* - 64-bit (or less) integer values are returned in gpr2 */
+  /* - Structures are returned as pointers in gpr2	    */
+  /* - Single/double FP values are returned in fpr0	    */
+  /*--------------------------------------------------------*/
+  flags = cif->rtype->type;
+
+  /*--------------------------------------------------------------------------*/
+  /* The first MAX_GPRARGS words of integer arguments, and the      	      */
+  /* first MAX_FPRARGS floating point arguments, go in registers; the rest    */
+  /* goes on the stack.  Structures and long doubles (if not equivalent       */
+  /* to double) are passed as a pointer to a copy of the structure.	      */
+  /* Stuff on the stack needs to keep proper alignment.  		      */
+  /*--------------------------------------------------------------------------*/
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+  {
+      switch ((*ptr)->type)
+	{
+		case FFI_TYPE_FLOAT:
+		case FFI_TYPE_DOUBLE:
+	  		fpArgC++;
+	  		if (fpArgC > MAX_FPRARGS)
+	    			intArgC++;
+	  	break;
+
+		case FFI_TYPE_UINT64:
+		case FFI_TYPE_SINT64:
+			/*----------------------------------------------------*/
+	 		/* 'long long' arguments are passed as two words, but */
+	     		/* either both words must fit in registers or both go */
+	     		/* on the stack.  If they go on the stack, they must  */
+	     		/* be 8-byte-aligned. 			 	      */
+			/*----------------------------------------------------*/
+	      	    	if (intArgC >= MAX_GPRARGS)  
+	    			intArgC++;
+	  	break;
+
+		case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+		case FFI_TYPE_LONGDOUBLE:
+#endif
+			/*----------------------------------------------------*/
+	  		/* We must allocate space for a copy of these to      */
+	     		/* enforce pass-by-value. Pad the space up to a       */
+	     		/* multiple of 16 bytes (the maximum alignment 	      */
+	     		/* required for anything under the SYSV ABI). 	      */
+			/*----------------------------------------------------*/
+	  		structCopySize += ((*ptr)->size + 15) & ~0xF;
+			/*----------------------------------------------------*/
+	  		/* Fall through (allocate space for the pointer).     */
+			/*----------------------------------------------------*/
+
+		default:
+			/*----------------------------------------------------*/
+	  		/* Everything else is passed as a 4-byte word in a    */
+	     		/* GPR either the object itself or a pointer to it.   */
+			/*----------------------------------------------------*/
+	  		intArgC++;
+	  	break;
+	}
+  }
+
+  /*-----------------------------------------------------------------*/
+  /* Stack space.                                                    */
+  /*-----------------------------------------------------------------*/
+  if (intArgC > MAX_GPRARGS)
+    	bytes += (intArgC - MAX_GPRARGS) * sizeof(uint64_t);
+  if (fpArgC > MAX_FPRARGS)
+    	bytes += (fpArgC - MAX_FPRARGS) * sizeof(double);
+
+  /*-----------------------------------------------------------------*/
+  /* The stack space allocated needs to be a multiple of 16 bytes.   */
+  /*-----------------------------------------------------------------*/
+  bytes = (bytes + 15) & ~0xF;
+
+  /*-----------------------------------------------------------------*/
+  /* Add in the space for the copied structures.                     */
+  /*-----------------------------------------------------------------*/
+  bytes += structCopySize;
+
+  cif->flags = flags;
+  cif->bytes = bytes;
+
+  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)
+{
+  extended_cif ecif;
+
+  ecif.cif    = cif;
+  ecif.avalue = avalue;
+
+  /*-----------------------------------------------------------------*/
+  /* If the return value is a struct and we don't have a return      */
+  /* value address then we need to make one                          */
+  /*-----------------------------------------------------------------*/
+  if ((rvalue == NULL) &&
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+      ecif.rvalue = alloca(cif->rtype->size);
+  else
+      ecif.rvalue = rvalue;
+
+    switch (cif->abi)
+  {
+    	case FFI_SYSV:
+      		ffi_call_SYSV(ffi_prep_args,
+			      &ecif, cif->bytes,
+			      cif->flags, ecif.rvalue, fn);
+      	break;
+
+    	default:
+      		FFI_ASSERT(0);
+      	break;
+  }
+}
+
+/*======================== End of Routine ============================*/
+#endif /* ifdef __s390x__ */
--- ./libffi/src/s390/unix64.S.orig	1969-12-31 19:00:00.000000000 -0500
+++ ./libffi/src/s390/unix64.S	2003-05-07 23:12:28.000000000 -0400
@@ -0,0 +1,188 @@
+#ifdef __s390x__
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2000 Software AG
+
+   S390 Foreign Function Interface
+
+   $Id: sysv.S,v 1.1.1.1 1998/10/07 04:27:22 toshok Exp $
+
+   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 <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#endif
+	
+.text
+
+	# r2:   ffi_prep_args
+	# r3:   &ecif
+	# r4:   cif->bytes
+	# r5:   fig->flags
+	# r6:   ecif.rvalue
+	# sp+0: fn
+
+	# This assumes we are using gas.
+	.globl	ffi_call_SYSV
+	.type 	ffi_call_SYSV,%function
+ffi_call_SYSV:
+	# Save registers
+        stmg    %r6,%r15,48(%r15)
+        lg      %r7,160(%r15)          # Get A(fn)
+        lgr     %r0,%r15
+        aghi    %r15,-256              # Make room for my args
+        stg     %r0,0(%r15)            # Set backchain
+        lgr     %r11,%r15              # Establish my stack register
+        sgr     %r15,%r4               # Make room for fn args
+        aghi    %r15,-256              # Make room for new frame
+        lgr     %r10,%r15              # Establish stack build area
+        aghi    %r15,-512              # Stack for next call
+        lgr     %r1,%r7
+        stmg    %r2,%r7,160(%r11)      # Save args on my stack
+
+#------------------------------------------------------------------
+#       move first 3 parameters in registers
+#------------------------------------------------------------------
+        lgr     %r9,%r2                # r9:     &ffi_prep_args
+        lgr     %r2,%r10               # Parm 1: &stack Parm 2: &ecif
+        basr    %r14,%r9               # call ffi_prep_args
+
+#------------------------------------------------------------------
+#       load  first 5 parameter registers
+#------------------------------------------------------------------
+        lmg     %r2,%r6,48(%r10)
+
+#------------------------------------------------------------------
+#       load  fp parameter registers
+#------------------------------------------------------------------
+        ld      %f0,96(%r10)
+        ld      %f2,104(%r10)
+	ld	%f4,112(%r10)
+	ld	%f6,120(%r10)
+
+#------------------------------------------------------------------
+#       call  function
+#------------------------------------------------------------------
+        lgr     %r15,%r10              # Set new stack
+        lg      %r9,200(%r11)          # Get &fn
+        basr    %r14,%r9               # Call function
+
+#------------------------------------------------------------------
+#       On return:
+#          r2: Return value (r3: Return value + 4 for long long)
+#------------------------------------------------------------------
+
+#------------------------------------------------------------------
+#       If the return value pointer is NULL, assume no return value.
+#------------------------------------------------------------------
+        lg      %r6,192(%r11)
+	ltgr    %r6,%r6
+        jz      .Lepilogue
+
+        lg      %r5,184(%r11)          # Get return type
+        sllg    %r5,%r5,2              /* Form displacement            */
+        larl    %r1,.LretTable         /* Establish base register      */
+	algr	%r5,%r1		       /* Address actual entry         */
+        br      %r5                    /* Branch to the jump           */
+
+.LretTable:
+        j       .LretPointer           /* Void                         */
+        j       .LretInt               /* Integer                      */
+        j       .LretFloat             /* Float                        */
+        j       .LretDouble            /* Double                       */
+        j       .LretLongDouble        /* Long Double                  */
+        j       .LretByte              /* Unsigned Byte                */
+        j       .LretByte              /* Signed Byte                  */
+        j       .LretShort             /* Unsigned Short               */
+        j       .LretShort             /* Signed Short                 */
+	j	.LretInt	       /* Unsigned Integer	       */
+	j       .LretInt               /* Signed Integer               */
+	j	.LretLong	       /* Unsigned Long		       */
+	j       .LretLong              /* Signed Long                  */
+        j       .Lepilogue             /* Structure                    */
+        j       .LretPointer           /* Pointer                      */
+
+#------------------------------------------------------------------
+#       return BYTE
+#------------------------------------------------------------------
+.LretByte:
+        stc     %r2,0(%r6)
+        j       .Lepilogue
+
+#------------------------------------------------------------------
+#       return SHORT
+#------------------------------------------------------------------
+.LretShort:
+        stcm    %r2,3,0(%r6)
+        j       .Lepilogue
+
+#------------------------------------------------------------------
+#       return INT
+#------------------------------------------------------------------
+.LretInt:
+        st      %r2,0(%r6)
+        j       .Lepilogue
+
+#------------------------------------------------------------------
+#       return LONG LONG (signed/unsigned)
+#------------------------------------------------------------------
+.LretLong:
+        stg     %r2,0(%r6)
+        j       .Lepilogue
+
+#------------------------------------------------------------------
+#       return FLOAT
+#------------------------------------------------------------------
+.LretFloat:
+        ste     %f0,0(%r6)
+        j       .Lepilogue
+
+#------------------------------------------------------------------
+#       return DOUBLE or LONGDOUBLE
+#------------------------------------------------------------------
+.LretDouble:
+.LretLongDouble:
+        std     %f0,0(%r6)
+        j       .Lepilogue
+
+#------------------------------------------------------------------
+# Structure: rvalue already set as sent as 1st parm to routine
+#------------------------------------------------------------------
+.LretStruct:
+	j	.Lepilogue
+
+#------------------------------------------------------------------
+#       return a pointer
+#------------------------------------------------------------------
+.LretPointer:
+        stg     %r2,0(%r6)
+        j       .Lepilogue
+
+.Lepilogue:
+        lg      %r15,0(%r11)
+        lg      %r4,112(%r15)
+        lmg     %r6,%r15,48(%r15)
+        br      %r4
+
+.ffi_call_SYSV_end:
+        .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+#endif /* ifdef __s390x__ */
--- ./libffi/configure.in.orig	2003-01-27 20:43:56.000000000 -0500
+++ ./libffi/configure.in	2003-05-07 23:12:28.000000000 -0400
@@ -67,6 +67,8 @@
 powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
 rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
 arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
+s390-*-linux*) TARGET=S390; TARGETDIR=s390;;
+s390x-*-linux*) TARGET=S390X; TARGETDIR=s390;;
 esac
 
 if test $TARGETDIR = unknown; then
@@ -85,6 +87,8 @@
 AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
 AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
 AM_CONDITIONAL(ARM, test x$TARGET = xARM)
+AM_CONDITIONAL(S390, test x$TARGET = xS390)
+AM_CONDITIONAL(S390X, test x$TARGET = xS390X)
 
 AC_HEADER_STDC
 AC_CHECK_FUNCS(memcpy)
--- ./libffi/configure.orig	2003-01-28 17:59:05.000000000 -0500
+++ ./libffi/configure	2003-05-07 23:12:28.000000000 -0400
@@ -2392,6 +2392,8 @@
 powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
 rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
 arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
+s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+s390x-*-linux-*) TARGET=S390X; TARGETDIR=s390;;
 esac
 
 if test $TARGETDIR = unknown; then
@@ -2507,6 +2509,24 @@
   ARM_FALSE=
 fi
 
+
+if test x$TARGET = xS390; then
+  S390_TRUE=
+  S390_FALSE='#'
+else
+  S390_TRUE='#'
+  S390_FALSE=
+fi
+
+
+if test x$TARGET = xS390X; then
+  S390X_TRUE=
+  S390X_FALSE='#'
+else
+  S390X_TRUE='#'
+  S390X_FALSE=
+fi
+
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
 echo "configure:2512: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
@@ -3729,6 +3749,10 @@
 s%@POWERPC_DARWIN_FALSE@%$POWERPC_DARWIN_FALSE%g
 s%@ARM_TRUE@%$ARM_TRUE%g
 s%@ARM_FALSE@%$ARM_FALSE%g
+s%@S390_TRUE@%$S390_TRUE%g
+s%@S390_FALSE@%$S390_FALSE%g
+s%@S390X_TRUE@%$S390X_TRUE%g
+s%@S390X_FALSE@%$S390X_FALSE%g
 s%@CPP@%$CPP%g
 s%@ALLOCA@%$ALLOCA%g
 s%@TARGET@%$TARGET%g
--- ./libffi/Makefile.am.orig	2003-01-27 20:43:56.000000000 -0500
+++ ./libffi/Makefile.am	2003-05-07 23:12:28.000000000 -0400
@@ -15,7 +15,9 @@
 		src/powerpc/ffi_darwin.c \
 		src/powerpc/darwin.S src/powerpc/aix.S \
 		src/powerpc/darwin_closure.S src/powerpc/aix_closures.S \
-		src/arm/ffi.c src/arm/sysv.S
+		src/arm/ffi.c src/arm/sysv.S \
+		src/s390/ffi.c src/s390/sysv.S \
+		src/s390/ffi64.c src/s390/unix64.S
 
 VPATH = @srcdir@:@srcdir@/src:@srcdir@/src/@TARGETDIR@
 
@@ -94,6 +96,8 @@
 TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closures.S
 TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
 TARGET_SRC_ARM =  src/arm/sysv.S src/arm/ffi.c
+TARGET_SRC_S390 = src/s390/sysv.S src/s390/ffi.c
+TARGET_SRC_S390X = $(TARGET_SRC_S390) src/s390/unix64.S src/s390/ffi64.c
 
 ##libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c $(TARGET_SRC_@TARGET@)
 ## Work around automake deficiency
@@ -147,6 +151,14 @@
 libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
 libffi_convenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
 endif
+if S390
+libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
+libfficonvenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
+endif
+if S390X
+libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_S390X)
+libfficonvenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_S390X)
+endif
 
 AM_CFLAGS = -fexceptions
 
--- ./libffi/Makefile.in.orig	2003-01-28 17:59:05.000000000 -0500
+++ ./libffi/Makefile.in	2003-05-07 23:12:28.000000000 -0400
@@ -173,6 +173,8 @@
 TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closures.S
 TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
 TARGET_SRC_ARM = src/arm/sysv.S src/arm/ffi.c
+TARGET_SRC_S390 = src/s390/sysv.S src/s390/ffi.c
+TARGET_SRC_S390X = $(TARGET_SRC_S390) src/s390/unix64.S src/s390/ffi64.c
 
 libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
 		src/raw_api.c src/java_raw_api.c
@@ -189,6 +191,8 @@
 @POWERPC_AIX_TRUE@libffi_la_SOURCES = @POWERPC_AIX_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_AIX)
 @POWERPC_DARWIN_TRUE@libffi_la_SOURCES = @POWERPC_DARWIN_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_DARWIN)
 @ARM_TRUE@libffi_la_SOURCES = @ARM_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
+@S390_TRUE@libffi_la_SOURCES = @S390_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
+@S390X_TRUE@libffi_la_SOURCES = @S390X_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_S390X)
 @MIPS_GCC_TRUE@libffi_convenience_la_SOURCES = @MIPS_GCC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC)
 @MIPS_SGI_TRUE@libffi_convenience_la_SOURCES = @MIPS_SGI_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI)
 @X86_TRUE@libffi_convenience_la_SOURCES = @X86_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86)
@@ -201,6 +205,8 @@
 @POWERPC_AIX_TRUE@libffi_convenience_la_SOURCES = @POWERPC_AIX_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_AIX)
 @POWERPC_DARWIN_TRUE@libffi_convenience_la_SOURCES = @POWERPC_DARWIN_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_DARWIN)
 @ARM_TRUE@libffi_convenience_la_SOURCES = @ARM_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
+@S390_TRUE@libffi_convenience_la_SOURCES = @S390_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
+@S390X_TRUE@libffi_convenience_la_SOURCES = @S390X_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_S390X)
 
 AM_CFLAGS = -fexceptions
 
@@ -254,6 +260,13 @@
 @ARM_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @ARM_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @ARM_TRUE@src/arm/sysv.lo src/arm/ffi.lo
+@S390_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@S390_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@S390_TRUE@src/s390/sysv.lo src/s390/ffi.lo
+@S390X_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@S390X_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@S390X_TRUE@src/s390/sysv.lo src/s390/ffi.lo \
+@S390X_TRUE@src/s390/unix64.lo src/s390/ffi64.lo
 @POWERPC_DARWIN_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
 @POWERPC_DARWIN_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
 @POWERPC_DARWIN_TRUE@src/java_raw_api.lo src/powerpc/ffi_darwin.lo \
@@ -296,6 +309,13 @@
 @ARM_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo src/types.lo \
 @ARM_TRUE@src/raw_api.lo src/java_raw_api.lo src/arm/sysv.lo \
 @ARM_TRUE@src/arm/ffi.lo
+@S390_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo src/types.lo \
+@S390_TRUE@src/raw_api.lo src/java_raw_api.lo src/s390/sysv.lo \
+@S390_TRUE@src/s390/ffi.lo
+@S390X_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo src/types.lo \
+@S390X_TRUE@src/raw_api.lo src/java_raw_api.lo src/s390/unix64.lo \
+@S390X_TRUE@src/s390/ffi64.lo \
+@S390X_TRUE@src/s390/sysv.lo src/s390/ffi.lo
 @POWERPC_DARWIN_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @POWERPC_DARWIN_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @POWERPC_DARWIN_TRUE@src/powerpc/ffi_darwin.lo src/powerpc/darwin.lo \
