Snap for 8426163 from 346fc30ba1b84cca643e0d970175358d79554d8c to mainline-tzdata2-release

Change-Id: Ia267e268d01dfd385c70ee18084a3089bb0d8ee0
diff --git a/.appveyor.yml b/.appveyor.yml
deleted file mode 100644
index ece8a94..0000000
--- a/.appveyor.yml
+++ /dev/null
@@ -1,66 +0,0 @@
-shallow_clone: true
-
-# We're currently only testing libffi built with Microsoft's
-# tools.
-# This matrix should be expanded to include at least:
-#  32- and 64-bit gcc/cygwin
-#  32- and 64-bit gcc/mingw
-#  32- and 64-bit clang/mingw
-#  and perhaps more.
-
-image: Visual Studio 2017
-platform:
-  - x64
-  - x86
-  - arm
-  - arm64
-
-environment:
-  global:
-    CYG_ROOT: C:/cygwin
-    CYG_CACHE: C:/cygwin/var/cache/setup
-    CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/
-  matrix:
-    - VSVER: 15
-
-install:
-  - ps: >-
-      If ($env:Platform -Match "x86") {
-          $env:VCVARS_PLATFORM="x86"
-          $env:BUILD="i686-pc-cygwin"
-          $env:HOST="i686-pc-cygwin"
-          $env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh"
-          $env:SRC_ARCHITECTURE="x86"
-        } ElseIf ($env:Platform -Match "arm64") {
-          $env:VCVARS_PLATFORM="x86_arm64"
-          $env:BUILD="i686-pc-cygwin"
-          $env:HOST="aarch64-w64-cygwin"
-          $env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -marm64"
-          $env:SRC_ARCHITECTURE="aarch64"
-        } ElseIf ($env:Platform -Match "arm") {
-          $env:VCVARS_PLATFORM="x86_arm"
-          $env:BUILD="i686-pc-cygwin"
-          $env:HOST="arm-w32-cygwin"
-          $env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -marm"
-          $env:SRC_ARCHITECTURE="arm"
-        } Else {
-          $env:VCVARS_PLATFORM="amd64"
-          $env:BUILD="x86_64-w64-cygwin"
-          $env:HOST="x86_64-w64-cygwin"
-          $env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -m64"
-          $env:SRC_ARCHITECTURE="x86"
-      }
-  - 'appveyor DownloadFile https://cygwin.com/setup-x86.exe -FileName setup.exe'
-  - 'setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P dejagnu >NUL'
-  - '%CYG_ROOT%/bin/bash -lc "cygcheck -dc cygwin"'
-  - echo call VsDevCmd to set VS150COMNTOOLS
-  - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"
-  - ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS"))
-  - echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%"
-  - call "%VSCOMNTOOLS%..\..\vc\Auxiliary\Build\vcvarsall.bat" %VCVARS_PLATFORM%
-
-build_script:
-  - c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./autogen.sh;)"
-  - c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./configure CC='%MSVCC%' CXX='%MSVCC%' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' AR='/cygdrive/c/projects/libffi/.travis/ar-lib lib' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)"
-  - c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp src/%SRC_ARCHITECTURE%/ffitarget.h include; make; find .;)"
-  - c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp `find . -name 'libffi-?.dll'` $HOST/testsuite/; make check; cat `find ./ -name libffi.log`)"
diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index f7d3833..0000000
--- a/.gitattributes
+++ /dev/null
@@ -1,4 +0,0 @@
-*	text=auto
-
-*.sln	text eol=crlf
-*.vcxproj*	text eol=crlf
diff --git a/.github/issue_template.md b/.github/issue_template.md
deleted file mode 100644
index e197e2c..0000000
--- a/.github/issue_template.md
+++ /dev/null
@@ -1,10 +0,0 @@
-## System Details
-
-<!--- What platform are you working with? eg. the output of config.guess -->
-<!--- Provide any toolchain details here. eg. compiler version -->
-
-## Problems Description
-
-<!--- Provide a description of the problem here -->
-<!--- If this is a configure-time problem, attach config.log -->
-<!--- If this is a testsuite problem, attach the relevant log output -->
diff --git a/.gitignore b/.gitignore
index 5d39689..287489c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,38 +1 @@
-.libs
-.deps
-*.o
-*.lo
-.dirstamp
-*.la
-Makefile
-!testsuite/libffi.bhaible/Makefile
-Makefile.in
-aclocal.m4
-compile
-!.travis/compile
-configure
-depcomp
-doc/libffi.info
-*~
-fficonfig.h.in
-fficonfig.h
 include/ffi.h
-include/ffitarget.h
-install-sh
-libffi.pc
-libtool
-libtool-ldflags
-ltmain.sh
-m4/libtool.m4
-m4/lt*.m4
-mdate-sh
-missing
-stamp-h1
-libffi*gz
-autom4te.cache
-libffi.xcodeproj/xcuserdata
-libffi.xcodeproj/project.xcworkspace
-build_*/
-darwin_*/
-src/arm/trampoline.S
-**/texinfo.tex
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 7cd3a18..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,75 +0,0 @@
----
-sudo: required
-
-language: cpp
-
-# For qemu-powered targets, get the list of supported processors from
-# travis by setting QEMU_CPU=help, then set -mcpu= for the compilers
-# accordingly.
-
-matrix:
-  include:
-    - os: linux
-      env: HOST=or1k-elf RUNTESTFLAGS="--target_board or1k-sim" DEJAGNU="/opt/.travis/site.exp"
-    - os: linux
-      env: HOST=m32r-elf RUNTESTFLAGS="--target_board m32r-sim" DEJAGNU="/opt/.travis/site.exp"
-    - os: linux
-      env: HOST=bfin-elf RUNTESTFLAGS="--target_board bfin-sim" DEJAGNU="/opt/.travis/site.exp"
-# This configuration is still using the native x86 toolchain?
-#    - os: osx
-#      env: HOST=aarch64-apple-darwin13
-    - os: osx
-      env: HOST=x86_64-apple-darwin10
-    - os: linux
-      env: HOST=x86_64-w64-mingw32 MEVAL='export CC="x86_64-w64-mingw32-gcc" && CXX="x86_64-w64-mingw32-g++" RUNTESTFLAGS="--target_board wine-sim" DEJAGNU="$TRAVIS_BUILD_DIR/.travis/site.exp" CONFIGURE_OPTIONS=--disable-shared LIBFFI_TEST_OPTIMIZATION="-O2"
-    - os: linux
-      env: HOST=sh4-linux-gnu CONFIGURE_OPTIONS=--disable-shared QEMU_LD_PREFIX=/usr/sh4-linux-gnu
-    - os: linux
-      env: HOST=alpha-linux-gnu CONFIGURE_OPTIONS=--disable-shared QEMU_LD_PREFIX=/usr/alpha-linux-gnu
-    - os: linux
-      env: HOST=m68k-linux-gnu MEVAL='export CC="m68k-linux-gnu-gcc-8 -mcpu=547x" && CXX="m68k-linux-gnu-g++-8 -mcpu=547x"' CONFIGURE_OPTIONS=--disable-shared QEMU_LD_PREFIX=/usr/m68k-linux-gnu QEMU_CPU=cfv4e
-    - os: linux
-      env: HOST=s390x-linux-gnu MEVAL='export CC="s390x-linux-gnu-gcc-8" && CXX="s390x-linux-gnu-g++-8"' CONFIGURE_OPTIONS=--disable-shared QEMU_LD_PREFIX=/usr/s390x-linux-gnu QEMU_CPU=max
-    - os: linux
-      env: HOST=arm32v7-linux-gnu LIBFFI_TEST_OPTIMIZATION="-O0"
-    - os: linux
-      env: HOST=arm32v7-linux-gnu LIBFFI_TEST_OPTIMIZATION="-O2"
-    - os: linux
-      env: HOST=arm32v7-linux-gnu LIBFFI_TEST_OPTIMIZATION="-O2 -fomit-frame-pointer"
-# The sparc64 linux system in the GCC compile farm is non-responsive.
-#    - os: linux
-#      env: HOST=sparc64-linux-gnu
-# Having problems getting logs for this one...
-#    - os: linux
-#      env: HOST=powerpc64le-unknown-linux-gnu
-#    - os: linux
-#      env: HOST=aarch64-linux-gnu
-# The mips64 linux system in the GCC compile farm is not allowing logins
-#    - os: linux
-#      env: HOST=mips64el-linux-gnu
-    - os: linux
-      compiler: gcc
-      env: HOST=i386-pc-linux-gnu MEVAL='export CC="$CC -m32" && CXX="$CXX -m32"'
-    - os: linux
-      compiler: gcc
-    - os: linux
-      compiler: gcc
-      env: CONFIGURE_OPTIONS=--disable-shared
-    - os: linux
-      compiler: clang
-    - os: linux
-      compiler: clang
-      env: CONFIGURE_OPTIONS=--disable-shared
-    - os: linux
-      env: HOST=moxie-elf MEVAL='export PATH=/opt/moxielogic/bin:$PATH && CC=moxie-elf-gcc && CXX=moxie-elf-g++' LDFLAGS=-Tsim.ld RUNTESTFLAGS="--target_board moxie-sim" DEJAGNU="$TRAVIS_BUILD_DIR/.travis/site.exp"
-
-before_install:
-  - if test x"$MEVAL" != x; then eval ${MEVAL}; fi
-
-install:
-  - travis_wait 30 ./.travis/install.sh
-
-script:
-  - if ! test x"$MEVAL" = x; then eval ${MEVAL}; fi
-  - travis_wait 115 sleep infinity &
-  - ./.travis/build.sh
diff --git a/.travis/ar-lib b/.travis/ar-lib
deleted file mode 100755
index 0baa4f6..0000000
--- a/.travis/ar-lib
+++ /dev/null
@@ -1,270 +0,0 @@
-#! /bin/sh
-# Wrapper for Microsoft lib.exe
-
-me=ar-lib
-scriptversion=2012-03-01.08; # UTC
-
-# Copyright (C) 2010-2018 Free Software Foundation, Inc.
-# Written by Peter Rosin <peda@lysator.liu.se>.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# This file is maintained in Automake, please report
-# bugs to <bug-automake@gnu.org> or send patches to
-# <automake-patches@gnu.org>.
-
-
-# func_error message
-func_error ()
-{
-  echo "$me: $1" 1>&2
-  exit 1
-}
-
-file_conv=
-
-# func_file_conv build_file
-# Convert a $build file to $host form and store it in $file
-# Currently only supports Windows hosts.
-func_file_conv ()
-{
-  file=$1
-  case $file in
-    / | /[!/]*) # absolute file, and not a UNC file
-      if test -z "$file_conv"; then
-	# lazily determine how to convert abs files
-	case `uname -s` in
-	  MINGW*)
-	    file_conv=mingw
-	    ;;
-	  CYGWIN*)
-	    file_conv=cygwin
-	    ;;
-	  *)
-	    file_conv=wine
-	    ;;
-	esac
-      fi
-      case $file_conv in
-	mingw)
-	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
-	  ;;
-	cygwin)
-	  file=`cygpath -m "$file" || echo "$file"`
-	  ;;
-	wine)
-	  file=`winepath -w "$file" || echo "$file"`
-	  ;;
-      esac
-      ;;
-  esac
-}
-
-# func_at_file at_file operation archive
-# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
-# for each of them.
-# When interpreting the content of the @FILE, do NOT use func_file_conv,
-# since the user would need to supply preconverted file names to
-# binutils ar, at least for MinGW.
-func_at_file ()
-{
-  operation=$2
-  archive=$3
-  at_file_contents=`cat "$1"`
-  eval set x "$at_file_contents"
-  shift
-
-  for member
-  do
-    $AR -NOLOGO $operation:"$member" "$archive" || exit $?
-  done
-}
-
-case $1 in
-  '')
-     func_error "no command.  Try '$0 --help' for more information."
-     ;;
-  -h | --h*)
-    cat <<EOF
-Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
-
-Members may be specified in a file named with @FILE.
-EOF
-    exit $?
-    ;;
-  -v | --v*)
-    echo "$me, version $scriptversion"
-    exit $?
-    ;;
-esac
-
-if test $# -lt 3; then
-  func_error "you must specify a program, an action and an archive"
-fi
-
-AR=$1
-shift
-while :
-do
-  if test $# -lt 2; then
-    func_error "you must specify a program, an action and an archive"
-  fi
-  case $1 in
-    -lib | -LIB \
-    | -ltcg | -LTCG \
-    | -machine* | -MACHINE* \
-    | -subsystem* | -SUBSYSTEM* \
-    | -verbose | -VERBOSE \
-    | -wx* | -WX* )
-      AR="$AR $1"
-      shift
-      ;;
-    *)
-      action=$1
-      shift
-      break
-      ;;
-  esac
-done
-orig_archive=$1
-shift
-func_file_conv "$orig_archive"
-archive=$file
-
-# strip leading dash in $action
-action=${action#-}
-
-delete=
-extract=
-list=
-quick=
-replace=
-index=
-create=
-
-while test -n "$action"
-do
-  case $action in
-    d*) delete=yes  ;;
-    x*) extract=yes ;;
-    t*) list=yes    ;;
-    q*) quick=yes   ;;
-    r*) replace=yes ;;
-    s*) index=yes   ;;
-    S*)             ;; # the index is always updated implicitly
-    c*) create=yes  ;;
-    u*)             ;; # TODO: don't ignore the update modifier
-    v*)             ;; # TODO: don't ignore the verbose modifier
-    *)
-      func_error "unknown action specified"
-      ;;
-  esac
-  action=${action#?}
-done
-
-case $delete$extract$list$quick$replace,$index in
-  yes,* | ,yes)
-    ;;
-  yesyes*)
-    func_error "more than one action specified"
-    ;;
-  *)
-    func_error "no action specified"
-    ;;
-esac
-
-if test -n "$delete"; then
-  if test ! -f "$orig_archive"; then
-    func_error "archive not found"
-  fi
-  for member
-  do
-    case $1 in
-      @*)
-        func_at_file "${1#@}" -REMOVE "$archive"
-        ;;
-      *)
-        func_file_conv "$1"
-        $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
-        ;;
-    esac
-  done
-
-elif test -n "$extract"; then
-  if test ! -f "$orig_archive"; then
-    func_error "archive not found"
-  fi
-  if test $# -gt 0; then
-    for member
-    do
-      case $1 in
-        @*)
-          func_at_file "${1#@}" -EXTRACT "$archive"
-          ;;
-        *)
-          func_file_conv "$1"
-          $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
-          ;;
-      esac
-    done
-  else
-    $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
-    do
-      $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
-    done
-  fi
-
-elif test -n "$quick$replace"; then
-  if test ! -f "$orig_archive"; then
-    if test -z "$create"; then
-      echo "$me: creating $orig_archive"
-    fi
-    orig_archive=
-  else
-    orig_archive=$archive
-  fi
-
-  for member
-  do
-    case $1 in
-    @*)
-      func_file_conv "${1#@}"
-      set x "$@" "@$file"
-      ;;
-    *)
-      func_file_conv "$1"
-      set x "$@" "$file"
-      ;;
-    esac
-    shift
-    shift
-  done
-
-  if test -n "$orig_archive"; then
-    $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
-  else
-    $AR -NOLOGO -OUT:"$archive" "$@" || exit $?
-  fi
-
-elif test -n "$list"; then
-  if test ! -f "$orig_archive"; then
-    func_error "archive not found"
-  fi
-  $AR -NOLOGO -LIST "$archive" || exit $?
-fi
diff --git a/.travis/bfin-sim.exp b/.travis/bfin-sim.exp
deleted file mode 100644
index 13cd0ff..0000000
--- a/.travis/bfin-sim.exp
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (C) 2010, 2019  Free Software Foundation, Inc.
-#
-# This file is part of DejaGnu.
-#
-# DejaGnu is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# DejaGnu is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with DejaGnu; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# This is a list of toolchains that are supported on this board.
-set_board_info target_install {bfin-elf}
-
-# Load the generic configuration for this board. This will define a basic set
-# of routines needed by the tool to communicate with the board.
-load_generic_config "sim"
-
-# basic-sim.exp is a basic description for the standard Cygnus simulator.
-load_base_board_description "basic-sim"
-
-# "bfin" is the name of the sim subdir in devo/sim.
-setup_sim bfin
-
-# No multilib options needed by default.
-process_multilib_options ""
-
-# We only support newlib on this target. We assume that all multilib
-# options have been specified before we get here.
-
-set_board_info compiler  "[find_gcc]"
-set_board_info cflags    "[libgloss_include_flags] [newlib_include_flags]"
-set_board_info ldflags   "[libgloss_link_flags] [newlib_link_flags]"
-
-# Configuration settings for testsuites
-set_board_info noargs 1
-set_board_info gdb,nosignals 1
-set_board_info gdb,noresults 1
-set_board_info gdb,cannot_call_functions 1
-set_board_info gdb,skip_float_tests 1
-set_board_info gdb,can_reverse 1
-set_board_info gdb,use_precord 1
-
-# More time is needed
-set_board_info gcc,timeout 800
-set_board_info gdb,timeout 60
-
-# Used by a few gcc.c-torture testcases to delimit how large the stack can
-# be.
-set_board_info gcc,stack_size  5000
-
diff --git a/.travis/build-cross-in-container.sh b/.travis/build-cross-in-container.sh
deleted file mode 100755
index 11447db..0000000
--- a/.travis/build-cross-in-container.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-cd /opt
-
-set -x
-echo $PATH
-export PATH=/usr/local/bin:$PATH
-echo $PATH
-
-ls -l /usr/local/bin
-
-./configure --host=${HOST}
-make
-make dist
-make check RUNTESTFLAGS="-a $RUNTESTFLAGS" || true
-
-
diff --git a/.travis/build-in-container.sh b/.travis/build-in-container.sh
deleted file mode 100755
index 1a7fa76..0000000
--- a/.travis/build-in-container.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-cd /opt
-
-export QEMU_LD_PREFIX=/usr/${HOST}
-
-./configure ${HOST+--host=$HOST --disable-shared}
-make
-make dist
-make check RUNTESTFLAGS="-a $RUNTESTFLAGS" || true
-
-
diff --git a/.travis/build.sh b/.travis/build.sh
deleted file mode 100755
index db596b3..0000000
--- a/.travis/build.sh
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/bin/bash
-
-set -x
-
-if [ -z ${QEMU_CPU+x} ]; then
-    export SET_QEMU_CPU=
-else
-    export SET_QEMU_CPU="-e QEMU_CPU=${QEMU_CPU}"
-fi
-
-# Default to podman where available, docker otherwise.
-# Override by setting the DOCKER environment variable.
-if test -z "$DOCKER"; then
-  which podman > /dev/null 2>&1
-  if [ $? != 0 ]; then
-    export DOCKER=docker
-  else
-    export DOCKER=podman
-  fi
-fi
-
-function build_cfarm()
-{
-    curl -u ${CFARM_AUTH} https://cfarm-test-libffi-libffi.apps.home.labdroid.net/test?host=${HOST}\&commit=${TRAVIS_COMMIT} | tee build.log
-    echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-    echo $(tail build.log | grep '^==LOGFILE==')
-    echo $(tail build.log | grep '^==LOGFILE==' | cut -b13-)
-    echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-    curl -u ${CFARM_AUTH} "$(tail build.log | grep '^==LOGFILE==' | cut -b13-)" > libffi.log
-
-    ./rlgl l https://rl.gl
-    ID=$(./rlgl start)
-    ./rlgl e --id=$ID --policy=https://github.com/libffi/rlgl-policy.git libffi.log
-    exit $?
-}
-
-function build_linux()
-{
-    ./autogen.sh
-    ./configure ${HOST+--host=$HOST} ${CONFIGURE_OPTIONS}
-    make
-    make dist
-    make check RUNTESTFLAGS="-a $RUNTESTFLAGS"
-
-    ./rlgl l https://rl.gl
-    ID=$(./rlgl start)
-    ./rlgl e --id=$ID --policy=https://github.com/libffi/rlgl-policy.git */testsuite/libffi.log
-    exit $?
-}
-
-function build_foreign_linux()
-{
-    ${DOCKER} run --rm -t -i -v `pwd`:/opt ${SET_QEMU_CPU} -e LIBFFI_TEST_OPTIMIZATION="${LIBFFI_TEST_OPTIMIZATION}" $2 bash -c /opt/.travis/build-in-container.sh
-
-    ./rlgl l https://rl.gl
-    ID=$(./rlgl start)
-    ./rlgl e --id=$ID --policy=https://github.com/libffi/rlgl-policy.git */testsuite/libffi.log
-    exit $?
-}
-
-function build_cross_linux()
-{
-    ${DOCKER} run --rm -t -i -v `pwd`:/opt ${SET_QEMU_CPU} -e HOST="${HOST}" -e CC="${HOST}-gcc-8 ${GCC_OPTIONS}" -e CXX="${HOST}-g++-8 ${GCC_OPTIONS}" -e LIBFFI_TEST_OPTIMIZATION="${LIBFFI_TEST_OPTIMIZATION}" moxielogic/cross-ci-build-container:latest bash -c /opt/.travis/build-in-container.sh
-
-    ./rlgl l https://rl.gl
-    ID=$(./rlgl start)
-    ./rlgl e --id=$ID --policy=https://github.com/libffi/rlgl-policy.git */testsuite/libffi.log
-    exit $?
-}
-
-function build_cross()
-{
-    ${DOCKER} pull quay.io/moxielogic/libffi-ci-${HOST} 
-    ${DOCKER} run --rm -t -i -v `pwd`:/opt -e HOST="${HOST}" -e CC="${HOST}-gcc ${GCC_OPTIONS}" -e CXX="${HOST}-g++ ${GCC_OPTIONS}" -e TRAVIS_BUILD_DIR=/opt -e DEJAGNU="${DEJAGNU}" -e RUNTESTFLAGS="${RUNTESTFLAGS}" -e LIBFFI_TEST_OPTIMIZATION="${LIBFFI_TEST_OPTIMIZATION}" quay.io/moxielogic/libffi-ci-${HOST} bash -c /opt/.travis/build-cross-in-container.sh
-
-    ./rlgl l https://rl.gl
-    ID=$(./rlgl start)
-    ./rlgl e --id=$ID --policy=https://github.com/libffi/rlgl-policy.git */testsuite/libffi.log
-    exit $?
-}
-
-function build_ios()
-{
-    which python
-# export PYTHON_BIN=/usr/local/bin/python
-    ./generate-darwin-source-and-headers.py --only-ios
-    xcodebuild -showsdks
-    xcodebuild -project libffi.xcodeproj -target "libffi-iOS" -configuration Release -sdk iphoneos11.4
-    exit $?
-}
-
-function build_macosx()
-{
-    which python
-# export PYTHON_BIN=/usr/local/bin/python
-    ./generate-darwin-source-and-headers.py --only-osx
-    xcodebuild -showsdks
-    xcodebuild -project libffi.xcodeproj -target "libffi-Mac" -configuration Release -sdk macosx10.13
-    exit $?
-}
-
-case "$HOST" in
-    arm-apple-darwin*)
-	./autogen.sh
-	build_ios
-	;;
-    x86_64-apple-darwin*)
-	./autogen.sh
-	build_macosx
-	;;
-    arm32v7-linux-gnu)
-	./autogen.sh
-        build_foreign_linux arm moxielogic/arm32v7-ci-build-container:latest 
-	;;
-    aarch64-linux-gnu| powerpc64le-unknown-linux-gnu | mips64el-linux-gnu | sparc64-linux-gnu)
-        build_cfarm
-	;;
-    bfin-elf )
-	./autogen.sh
-	GCC_OPTIONS=-msim build_cross
-	;;
-    m32r-elf )
-	./autogen.sh
-	build_cross
-	;;
-    or1k-elf )
-	./autogen.sh
-	build_cross
-	;;
-    m68k-linux-gnu )
-	./autogen.sh
-	GCC_OPTIONS=-mcpu=547x build_cross_linux
-	;;
-    alpha-linux-gnu | sh4-linux-gnu | s390x-linux-gnu )
-	./autogen.sh
-	build_cross_linux
-	;;
-    *)
-	./autogen.sh
-	build_linux
-	;;
-esac
diff --git a/.travis/compile b/.travis/compile
deleted file mode 100755
index 655932a..0000000
--- a/.travis/compile
+++ /dev/null
@@ -1,351 +0,0 @@
-#! /bin/sh
-# Wrapper for compilers which do not understand '-c -o'.
-
-scriptversion=2018-03-27.18; # UTC
-
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
-# Written by Tom Tromey <tromey@cygnus.com>.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# This file is maintained in Automake, please report
-# bugs to <bug-automake@gnu.org> or send patches to
-# <automake-patches@gnu.org>.
-
-nl='
-'
-
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent tools from complaining about whitespace usage.
-IFS=" ""	$nl"
-
-file_conv=
-
-# func_file_conv build_file lazy
-# Convert a $build file to $host form and store it in $file
-# Currently only supports Windows hosts. If the determined conversion
-# type is listed in (the comma separated) LAZY, no conversion will
-# take place.
-func_file_conv ()
-{
-  file=$1
-  case $file in
-    / | /[!/]*) # absolute file, and not a UNC file
-      if test -z "$file_conv"; then
-	# lazily determine how to convert abs files
-	case `uname -s` in
-	  MINGW*)
-	    file_conv=mingw
-	    ;;
-	  CYGWIN*)
-	    file_conv=cygwin
-	    ;;
-	  *)
-	    file_conv=wine
-	    ;;
-	esac
-      fi
-      case $file_conv/,$2, in
-	*,$file_conv,*)
-	  ;;
-	mingw/*)
-	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
-	  ;;
-	cygwin/*)
-	  file=`cygpath -m "$file" || echo "$file"`
-	  ;;
-	wine/*)
-	  file=`winepath -w "$file" || echo "$file"`
-	  ;;
-      esac
-      ;;
-  esac
-}
-
-# func_cl_dashL linkdir
-# Make cl look for libraries in LINKDIR
-func_cl_dashL ()
-{
-  func_file_conv "$1"
-  if test -z "$lib_path"; then
-    lib_path=$file
-  else
-    lib_path="$lib_path;$file"
-  fi
-  linker_opts="$linker_opts -LIBPATH:$file"
-}
-
-# func_cl_dashl library
-# Do a library search-path lookup for cl
-func_cl_dashl ()
-{
-  lib=$1
-  found=no
-  save_IFS=$IFS
-  IFS=';'
-  for dir in $lib_path $LIB
-  do
-    IFS=$save_IFS
-    if $shared && test -f "$dir/$lib.dll.lib"; then
-      found=yes
-      lib=$dir/$lib.dll.lib
-      break
-    fi
-    if test -f "$dir/$lib.lib"; then
-      found=yes
-      lib=$dir/$lib.lib
-      break
-    fi
-    if test -f "$dir/lib$lib.a"; then
-      found=yes
-      lib=$dir/lib$lib.a
-      break
-    fi
-  done
-  IFS=$save_IFS
-
-  if test "$found" != yes; then
-    lib=$lib.lib
-  fi
-}
-
-# func_cl_wrapper cl arg...
-# Adjust compile command to suit cl
-func_cl_wrapper ()
-{
-  # Assume a capable shell
-  lib_path=
-  shared=:
-  linker_opts=
-  for arg
-  do
-    if test -n "$eat"; then
-      eat=
-    else
-      case $1 in
-	-o)
-	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
-	  eat=1
-	  case $2 in
-	    *.o | *.[oO][bB][jJ])
-	      func_file_conv "$2"
-	      set x "$@" -Fo"$file"
-	      shift
-	      ;;
-	    *)
-	      func_file_conv "$2"
-	      set x "$@" -Fe"$file"
-	      shift
-	      ;;
-	  esac
-	  ;;
-	-I)
-	  eat=1
-	  func_file_conv "$2" mingw
-	  set x "$@" -I"$file"
-	  shift
-	  ;;
-	-I*)
-	  func_file_conv "${1#-I}" mingw
-	  set x "$@" -I"$file"
-	  shift
-	  ;;
-	-l)
-	  eat=1
-	  func_cl_dashl "$2"
-	  set x "$@" "$lib"
-	  shift
-	  ;;
-	-l*)
-	  func_cl_dashl "${1#-l}"
-	  set x "$@" "$lib"
-	  shift
-	  ;;
-	-L)
-	  eat=1
-	  func_cl_dashL "$2"
-	  ;;
-	-L*)
-	  func_cl_dashL "${1#-L}"
-	  ;;
-	-static)
-	  shared=false
-	  ;;
-	-warn)
-	  eat=1
-	  ;;
-	-Wl,*)
-	  arg=${1#-Wl,}
-	  save_ifs="$IFS"; IFS=','
-	  for flag in $arg; do
-	    IFS="$save_ifs"
-	    linker_opts="$linker_opts $flag"
-	  done
-	  IFS="$save_ifs"
-	  ;;
-	-Xlinker)
-	  eat=1
-	  linker_opts="$linker_opts $2"
-	  ;;
-	-*)
-	  set x "$@" "$1"
-	  shift
-	  ;;
-	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
-	  func_file_conv "$1"
-	  set x "$@" -Tp"$file"
-	  shift
-	  ;;
-	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
-	  func_file_conv "$1" mingw
-	  set x "$@" "$file"
-	  shift
-	  ;;
-	*)
-	  set x "$@" "$1"
-	  shift
-	  ;;
-      esac
-    fi
-    shift
-  done
-  if test -n "$linker_opts"; then
-    linker_opts="-link$linker_opts"
-  fi
-  exec "$@" $linker_opts
-  exit 1
-}
-
-eat=
-
-case $1 in
-  '')
-     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
-     exit 1;
-     ;;
-  -h | --h*)
-    cat <<\EOF
-Usage: compile [--help] [--version] PROGRAM [ARGS]
-
-Wrapper for compilers which do not understand '-c -o'.
-Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
-arguments, and rename the output as expected.
-
-If you are trying to build a whole package this is not the
-right script to run: please start by reading the file 'INSTALL'.
-
-Report bugs to <bug-automake@gnu.org>.
-EOF
-    exit $?
-    ;;
-  -v | --v*)
-    echo "compile $scriptversion"
-    exit $?
-    ;;
-  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
-  icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
-    func_cl_wrapper "$@"      # Doesn't return...
-    ;;
-esac
-
-ofile=
-cfile=
-
-for arg
-do
-  if test -n "$eat"; then
-    eat=
-  else
-    case $1 in
-      -o)
-	# configure might choose to run compile as 'compile cc -o foo foo.c'.
-	# So we strip '-o arg' only if arg is an object.
-	eat=1
-	case $2 in
-	  *.o | *.obj)
-	    ofile=$2
-	    ;;
-	  *)
-	    set x "$@" -o "$2"
-	    shift
-	    ;;
-	esac
-	;;
-      *.c)
-	cfile=$1
-	set x "$@" "$1"
-	shift
-	;;
-      *)
-	set x "$@" "$1"
-	shift
-	;;
-    esac
-  fi
-  shift
-done
-
-if test -z "$ofile" || test -z "$cfile"; then
-  # If no '-o' option was seen then we might have been invoked from a
-  # pattern rule where we don't need one.  That is ok -- this is a
-  # normal compilation that the losing compiler can handle.  If no
-  # '.c' file was seen then we are probably linking.  That is also
-  # ok.
-  exec "$@"
-fi
-
-# Name of file we expect compiler to create.
-cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
-
-# Create the lock directory.
-# Note: use '[/\\:.-]' here to ensure that we don't use the same name
-# that we are using for the .o file.  Also, base the name on the expected
-# object file name, since that is what matters with a parallel build.
-lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
-while true; do
-  if mkdir "$lockdir" >/dev/null 2>&1; then
-    break
-  fi
-  sleep 1
-done
-# FIXME: race condition here if user kills between mkdir and trap.
-trap "rmdir '$lockdir'; exit 1" 1 2 15
-
-# Run the compile.
-"$@"
-ret=$?
-
-if test -f "$cofile"; then
-  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
-elif test -f "${cofile}bj"; then
-  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
-fi
-
-rmdir "$lockdir"
-exit $ret
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC0"
-# time-stamp-end: "; # UTC"
-# End:
diff --git a/.travis/install.sh b/.travis/install.sh
deleted file mode 100755
index eb7f80f..0000000
--- a/.travis/install.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-set -x
-
-if [[ $TRAVIS_OS_NAME != 'linux' ]]; then
-    brew update > brew-update.log 2>&1
-    # fix an issue with libtool on travis by reinstalling it
-    brew uninstall libtool;
-    brew install libtool dejagnu;
-
-    # Download and extract the rlgl client
-    wget -qO - https://rl.gl/cli/rlgl-darwin-amd64.tgz | \
-	tar --strip-components=2 -xvzf - ./rlgl/rlgl
-
-else
-
-    # Download and extract the rlgl client
-    wget -qO - http://rl.gl/cli/rlgl-linux-amd64.tgz | \
-	tar --strip-components=2 -xvzf - ./rlgl/rlgl
-
-    sudo apt-get clean # clear the cache
-    sudo apt-get update
-    case $HOST in
-	aarch64-linux-gnu | powerpc64le-unknown-linux-gnu | mips64el-linux-gnu | sparc64-linux-gnu)
-        ;;	  
-	alpha-linux-gnu | arm32v7-linux-gnu | m68k-linux-gnu | sh4-linux-gnu | s390x-linux-gnu )
-	    sudo apt-get install qemu-user-static
-	    ;;
-	hppa-linux-gnu )
-	    sudo apt-get install -y qemu-user-static g++-5-hppa-linux-gnu
-	    ;;
-	i386-pc-linux-gnu)
-	    sudo apt-get install gcc-multilib g++-multilib;
-	    ;;
-	moxie-elf)
-	    echo 'deb https://repos.moxielogic.org:7114/MoxieLogic moxiedev main' | sudo tee -a /etc/apt/sources.list
-	    sudo apt-get clean # clear the cache
-	    sudo apt-get update ## -qq
-	    sudo apt-get update
-	    sudo apt-get install -y --allow-unauthenticated moxielogic-moxie-elf-gcc moxielogic-moxie-elf-gcc-c++ moxielogic-moxie-elf-gcc-libstdc++ moxielogic-moxie-elf-gdb-sim
-	    ;;
-	x86_64-w64-mingw32)
-	    sudo apt-get install gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 wine;
-	    ;;
-	i686-w32-mingw32)
-	    sudo apt-get install gcc-mingw-w64-i686 g++-mingw-w64-i686 wine;
-	    ;;
-    esac
-    case $HOST in
-	arm32v7-linux-gnu | aarch64-linux-gnu | ppc64le-linux-gnu | s390x-linux-gnu)
-        # don't install host tools
-        ;;
-	*)
-	    sudo apt-get install dejagnu texinfo sharutils
-	    ;;
-    esac
-fi
diff --git a/.travis/m32r-sim.exp b/.travis/m32r-sim.exp
deleted file mode 100644
index b3341f2..0000000
--- a/.travis/m32r-sim.exp
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (C) 2010, 2019  Free Software Foundation, Inc.
-#
-# This file is part of DejaGnu.
-#
-# DejaGnu is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# DejaGnu is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with DejaGnu; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# This is a list of toolchains that are supported on this board.
-set_board_info target_install {m32r-elf}
-
-# Load the generic configuration for this board. This will define a basic set
-# of routines needed by the tool to communicate with the board.
-load_generic_config "sim"
-
-# basic-sim.exp is a basic description for the standard Cygnus simulator.
-load_base_board_description "basic-sim"
-
-# "m32r" is the name of the sim subdir in devo/sim.
-setup_sim m32r
-
-# No multilib options needed by default.
-process_multilib_options ""
-
-# We only support newlib on this target. We assume that all multilib
-# options have been specified before we get here.
-
-set_board_info compiler  "[find_gcc]"
-set_board_info cflags    "[libgloss_include_flags] [newlib_include_flags]"
-set_board_info ldflags   "[libgloss_link_flags] [newlib_link_flags]"
-
-# Configuration settings for testsuites
-set_board_info noargs 1
-set_board_info gdb,nosignals 1
-set_board_info gdb,noresults 1
-set_board_info gdb,cannot_call_functions 1
-set_board_info gdb,skip_float_tests 1
-set_board_info gdb,can_reverse 1
-set_board_info gdb,use_precord 1
-
-# More time is needed
-set_board_info gcc,timeout 800
-set_board_info gdb,timeout 60
-
-# Used by a few gcc.c-torture testcases to delimit how large the stack can
-# be.
-set_board_info gcc,stack_size  5000
-
diff --git a/.travis/moxie-sim.exp b/.travis/moxie-sim.exp
deleted file mode 100644
index 3a6042e..0000000
--- a/.travis/moxie-sim.exp
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2010  Free Software Foundation, Inc.
-#
-# This file is part of DejaGnu.
-#
-# DejaGnu is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# DejaGnu is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with DejaGnu; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# This is a list of toolchains that are supported on this board.
-set_board_info target_install {moxie-elf}
-
-# Load the generic configuration for this board. This will define a basic set
-# of routines needed by the tool to communicate with the board.
-load_generic_config "sim"
-
-# basic-sim.exp is a basic description for the standard Cygnus simulator.
-load_base_board_description "basic-sim"
-
-# "moxie" is the name of the sim subdir in devo/sim.
-setup_sim moxie
-
-# No multilib options needed by default.
-process_multilib_options ""
-
-# We only support newlib on this target. We assume that all multilib
-# options have been specified before we get here.
-
-set_board_info compiler  "[find_gcc]"
-set_board_info cflags    "[libgloss_include_flags] [newlib_include_flags]"
-set_board_info ldflags   "[libgloss_link_flags] [newlib_link_flags]"
-# No linker script needed.
-set_board_info ldscript "-Tsim.ld"
-
-# Configuration settings for testsuites
-set_board_info noargs 1
-set_board_info gdb,nosignals 1
-set_board_info gdb,noresults 1
-set_board_info gdb,cannot_call_functions 1
-set_board_info gdb,skip_float_tests 1
-set_board_info gdb,can_reverse 1
-set_board_info gdb,use_precord 1
-
-# More time is needed
-set_board_info gcc,timeout 800
-set_board_info gdb,timeout 60
-
-# Used by a few gcc.c-torture testcases to delimit how large the stack can
-# be.
-set_board_info gcc,stack_size  5000
-
diff --git a/.travis/or1k-sim.exp b/.travis/or1k-sim.exp
deleted file mode 100644
index 64e1444..0000000
--- a/.travis/or1k-sim.exp
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (C) 2010, 2019  Free Software Foundation, Inc.
-#
-# This file is part of DejaGnu.
-#
-# DejaGnu is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# DejaGnu is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with DejaGnu; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# This is a list of toolchains that are supported on this board.
-set_board_info target_install {or1k-elf}
-
-# Load the generic configuration for this board. This will define a basic set
-# of routines needed by the tool to communicate with the board.
-load_generic_config "sim"
-
-# basic-sim.exp is a basic description for the standard Cygnus simulator.
-load_base_board_description "basic-sim"
-
-# "or1k" is the name of the sim subdir in devo/sim.
-setup_sim or1k
-
-# No multilib options needed by default.
-process_multilib_options ""
-
-# We only support newlib on this target. We assume that all multilib
-# options have been specified before we get here.
-
-set_board_info compiler  "[find_gcc]"
-set_board_info cflags    "[libgloss_include_flags] [newlib_include_flags]"
-set_board_info ldflags   "[libgloss_link_flags] [newlib_link_flags]"
-
-# Configuration settings for testsuites
-set_board_info noargs 1
-set_board_info gdb,nosignals 1
-set_board_info gdb,noresults 1
-set_board_info gdb,cannot_call_functions 1
-set_board_info gdb,skip_float_tests 1
-set_board_info gdb,can_reverse 1
-set_board_info gdb,use_precord 1
-
-# More time is needed
-set_board_info gcc,timeout 800
-set_board_info gdb,timeout 60
-
-# Used by a few gcc.c-torture testcases to delimit how large the stack can
-# be.
-set_board_info gcc,stack_size  5000
-
diff --git a/.travis/site.exp b/.travis/site.exp
deleted file mode 100644
index 644ec63..0000000
--- a/.travis/site.exp
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2008, 2010, 2018, 2019  Anthony Green
-
-# Make sure we look in the right place for the board description files.
-if ![info exists boards_dir] {
-    set boards_dir {}
-}
-
-lappend boards_dir $::env(TRAVIS_BUILD_DIR)/.travis
-
-verbose "Global Config File: target_triplet is $target_triplet" 2
-global target_list
-
-case "$target_triplet" in {
-    { "bfin-elf" } {
-	set target_list "bfin-sim"
-    }
-    { "m32r-elf" } {
-	set target_list "m32r-sim"
-    }
-    { "moxie-elf" } {
-	set target_list "moxie-sim"
-    }
-    { "or1k-elf" } {
-	set target_list "or1k-sim"
-    }
-}
-
diff --git a/.travis/wine-sim.exp b/.travis/wine-sim.exp
deleted file mode 100644
index 8bdab67..0000000
--- a/.travis/wine-sim.exp
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (C) 2010, 2019  Free Software Foundation, Inc.
-#
-# This file is part of DejaGnu.
-#
-# DejaGnu is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# DejaGnu is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with DejaGnu; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# This is a list of toolchains that are supported on this board.
-set_board_info target_install {i686-w64-mingw32}
-
-# Load the generic configuration for this board. This will define a basic set
-# of routines needed by the tool to communicate with the board.
-load_generic_config "sim"
-
-set_board_info sim "wineconsole --backend=curses"
-set_board_info is_simulator 1
-
-# No multilib options needed by default.
-process_multilib_options ""
-
-# We only support newlib on this target. We assume that all multilib
-# options have been specified before we get here.
-
-set_board_info compiler  "[find_gcc]"
-set_board_info cflags    "[libgloss_include_flags] [newlib_include_flags]"
-set_board_info ldflags   "[libgloss_link_flags] [newlib_link_flags]"
-
-# Configuration settings for testsuites
-set_board_info noargs 1
-set_board_info gdb,nosignals 1
-set_board_info gdb,noresults 1
-set_board_info gdb,cannot_call_functions 1
-set_board_info gdb,skip_float_tests 1
-set_board_info gdb,can_reverse 1
-set_board_info gdb,use_precord 1
-
-# More time is needed
-set_board_info gcc,timeout 800
-set_board_info gdb,timeout 60
-
-# Used by a few gcc.c-torture testcases to delimit how large the stack can
-# be.
-set_board_info gcc,stack_size  5000
-
diff --git a/Android.bp b/Android.bp
index 32c473b..1c9a4ec 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,49 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    default_applicable_licenses: ["external_libffi_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-//
-// large-scale-change included anything that looked like it might be a license
-// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc.
-//
-// Please consider removing redundant or irrelevant files from 'license_text:'.
-// See: http://go/android-license-faq
-license {
-    name: "external_libffi_license",
-    visibility: [":__subpackages__"],
-    license_kinds: [
-        "SPDX-license-identifier-Apache-2.0",
-        "SPDX-license-identifier-GPL",
-        "SPDX-license-identifier-GPL-2.0",
-        "SPDX-license-identifier-GPL-3.0",
-        "SPDX-license-identifier-LGPL",
-        "SPDX-license-identifier-LGPL-2.1",
-        "SPDX-license-identifier-MIT",
-        "SPDX-license-identifier-MPL",
-        "legacy_unencumbered",
-    ],
-    license_text: [
-        "LICENSE",
-        "LICENSE-BUILDTOOLS",
-    ],
-}
-
 genrule {
     name: "ffi_header",
     cmd: "$(location gen_ffi_header.sh) < $(in) > $(out)",
@@ -63,19 +20,15 @@
     tool_files: ["gen_ffi_header.sh"],
 }
 
-cc_library {
+cc_library_static {
     name: "libffi",
     host_supported: true,
     vendor_available: true,
     cflags: [
         "-Wall",
         "-Werror",
-
         "-Wno-error=incompatible-pointer-types",
         "-Wno-incompatible-pointer-types",
-
-        "-Wno-deprecated-declarations",
-        "-Wno-missing-field-initializers",
         "-Wno-null-pointer-arithmetic",
         "-Wno-pointer-arith",
         "-Wno-sign-compare",
@@ -112,6 +65,7 @@
             srcs: [
                 "src/x86/ffi.c",
                 "src/x86/sysv.S",
+                "src/x86/win32.S",
             ],
             asflags: [
                 "-DHAVE_AS_X86_PCREL",
@@ -122,9 +76,7 @@
         x86_64: {
             srcs: [
                 "src/x86/ffi64.c",
-                "src/x86/ffiw64.c",
                 "src/x86/unix64.S",
-                "src/x86/win64.S",
             ],
             asflags: [
                 "-DHAVE_AS_X86_PCREL",
@@ -133,8 +85,13 @@
             export_include_dirs: ["linux-x86_64"],
         },
     },
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.virt",
-    ],
+    target: {
+        darwin_x86_64: {
+            exclude_srcs: ["src/x86/unix64.S"],
+            srcs: [
+                "src/x86/darwin.S",
+                "src/x86/darwin64.S",
+            ],
+        },
+    },
 }
diff --git a/ChangeLog.old b/ChangeLog.old
deleted file mode 100644
index 8de1ca7..0000000
--- a/ChangeLog.old
+++ /dev/null
@@ -1,7407 +0,0 @@
-Libffi change logs used to be maintained in separate ChangeLog files.
-These days we generate them directly from the git commit messages.
-The old ChangeLog files are saved here in order to maintain the historical
-record.
-
-=============================================================================
-From the old ChangeLog.libffi-3.1 file...
-
-2014-03-16  Josh Triplett  <josh@joshtriplett.org>
-
-	* ChangeLog: Archive to ChangeLog.libffi-3.1 and delete.  Future
-	changelogs will come from git, with autogenerated snapshots shipped in
-	distributed tarballs.
-
-2014-03-16  Josh Triplett  <josh@joshtriplett.org>
-
-	Add support for stdcall, thiscall, and fastcall on non-Windows
-	x86-32.
-
-	Linux supports the stdcall calling convention, either via
-	functions explicitly declared with the stdcall attribute, or via
-	code compiled with -mrtd which effectively makes stdcall the
-	default.
-
-	This introduces FFI_STDCALL, FFI_THISCALL, and FFI_FASTCALL on
-	non-Windows x86-32 platforms, as non-default calling conventions.
-
-	* Makefile.am: Compile in src/x86/win32.S on non-Windows x86-32.
-	* src/x86/ffitarget.h: Add FFI_STDCALL, FFI_THISCALL, and
-	FFI_FASTCALL on non-Windows x86-32.  Increase trampoline size to
-	accomodate these calling conventions, and unify some ifdeffery.
-	* src/x86/ffi.c: Add support for FFI_STDCALL, FFI_THISCALL, and
-	FFI_FASTCALL on non-Windows x86-32 platforms; update ifdeffery.
-	* src/x86/win32.S: Support compiling on non-Windows x86-32
-	platforms.  On those platforms, avoid redefining the SYSV symbols
-	already provided by src/x86/sysv.S.
-	* testsuite/libffi.call/closure_stdcall.c: Run on non-Windows.
-	#define __stdcall if needed.
-	* testsuite/libffi.call/closure_thiscall.c: Run on non-Windows.
-	#define __fastcall if needed.
-	* testsuite/libffi.call/fastthis1_win32.c: Run on non-Windows.
-	* testsuite/libffi.call/fastthis2_win32.c: Ditto.
-	* testsuite/libffi.call/fastthis3_win32.c: Ditto.
-	* testsuite/libffi.call/many2_win32.c: Ditto.
-	* testsuite/libffi.call/many_win32.c: Ditto.
-	* testsuite/libffi.call/strlen2_win32.c: Ditto.
-	* testsuite/libffi.call/strlen_win32.c: Ditto.
-	* testsuite/libffi.call/struct1_win32.c: Ditto.
-	* testsuite/libffi.call/struct2_win32.c: Ditto.
-
-2014-03-16  Josh Triplett  <josh@joshtriplett.org>
-
-	* prep_cif.c: Remove unnecessary ifdef for X86_WIN32.
-	ffi_prep_cif_core had a special case for X86_WIN32, checking for
-	FFI_THISCALL in addition to the FFI_FIRST_ABI-to-FFI_LAST_ABI
-	range before returning FFI_BAD_ABI.  However, on X86_WIN32,
-	FFI_THISCALL already falls in that range, making the special case
-	unnecessary.  Remove it.
-
-2014-03-16  Josh Triplett  <josh@joshtriplett.org>
-
-	* testsuite/libffi.call/closure_stdcall.c,
-	testsuite/libffi.call/closure_thiscall.c: Remove fragile stack
-	pointer checks.  These files included inline assembly to save the
-	stack pointer before and after the call, and compare the values.
-	However, compilers can and do leave the stack in different states
-	for these two pieces of inline assembly, such as by saving a
-	temporary value on the stack across the call; observed with gcc
-	-Os, and verified as spurious through careful inspection of
-	disassembly.
-
-2014-03-16  Josh Triplett  <josh@joshtriplett.org>
-
-	* testsuite/libffi.call/many.c: Avoid spurious failure due to
-	excess floating-point precision.
-	* testsuite/libffi.call/many_win32.c: Ditto.
-
-2014-03-16  Josh Triplett <josh@joshtriplett.org>
-
-	* libtool-ldflags: Re-add.
-
-2014-03-16  Josh Triplett <josh@joshtriplett.org>
-
-	* Makefile.in, aclocal.m4, compile, config.guess, config.sub,
-	configure, depcomp, include/Makefile.in, install-sh,
-	libtool-ldflags, ltmain.sh, m4/libtool.m4, m4/ltoptions.m4,
-	m4/ltsugar.m4, m4/ltversion.m4, m4/lt~obsolete.m4,
-	man/Makefile.in, mdate-sh, missing, testsuite/Makefile.in: Delete
-	autogenerated files from version control.
-	* .gitignore: Add autogenerated files.
-	* autogen.sh: New script to generate the autogenerated files.
-	* README: Document requirement to run autogen.sh when building
-	directly from version control.
-	* .travis.yml: Run autogen.sh
-
-2014-03-14  Anthony Green <green@moxielogic.com>
-
-	* configure, Makefile.in: Rebuilt.
-
-2014-03-10  Mike Hommey <mh+mozilla@glandium.org>
-
-	* configure.ac: Allow building for mipsel with Android NDK r8.
-	* Makefile.am (AM_MAKEFLAGS): Replace double quotes with single
-	quotes.
-
-2014-03-10  Landry Breuil <landry@openbsd.org>
-
-	* configure.ac: Ensure the linker supports @unwind sections in libffi.
-
-2014-03-01  Anthony Green  <green@moxielogic.com>
-
-	* Makefile.am (EXTRA_DIST): Replace old scripts with
-	generate-darwin-source-and-headers.py.
-	* Makefile.in: Rebuilt.
-
-2014-02-28  Anthony Green  <green@moxielogic.com>
-
-	* Makefile.am (AM_CFLAGS): Reintroduce missing -DFFI_DEBUG for
-	--enable-debug builds.
-	* Makefile.in: Rebuilt.
-
-2014-02-28  Makoto Kato  <m_kato@ga2.so-net.ne.jp>
-
-	* src/closures.c: Fix build failure when using clang for Android.
-
-2014-02-28  Marcin Wojdyr  <wojdyr@gmail.com>
-
-	* libffi.pc.in (toolexeclibdir): use -L${toolexeclibdir} instead
-	of -L${libdir}.
-
-2014-02-28  Paulo Pizarro  <paulo.pizarro@gmail.com>
-
-	* src/bfin/sysv.S: Calling functions in shared libraries requires
-	considering the GOT.
-
-2014-02-28  Josh Triplett  <josh@joshtriplett.org>
-
-	* src/x86/ffi64.c (classify_argument): Handle case where
-	FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE.
-
-2014-02-28  Anthony Green  <green@moxielogic.com>
-
-	* ltmain.sh: Generate with libtool-2.4.2.418.
-	* m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4: Ditto.
-	* configure: Rebuilt.
-
-2014-02-28  Dominik Vogt  <vogt@linux.vnet.ibm.com>
-
-	* configure.ac (AC_ARG_ENABLE struct): Fix typo in help
-	message.
-	(AC_ARG_ENABLE raw_api): Ditto.
-	* configure, fficonfig.h.in: Rebuilt.
-
-2014-02-28  Will Newton  <will.newton@linaro.org>
-
-	* src/arm/sysv.S: Initialize IP register with FP.
-
-2014-02-28  Yufeng Zhang  <yufeng.zhang@arm.com>
-
-	* src/aarch64/sysv.S (ffi_closure_SYSV): Use x29 as the
-	main CFA reg; update cfi_rel_offset.
-
-2014-02-15  Marcus Comstedt  <marcus@mc.pp.se>
-
-	* src/powerpc/ffi_linux64.c, src/powerpc/linux64_closure.S: Remove
-	assumption on contents of r11 in closure.
-
-2014-02-09  Heiher  <r@hev.cc>
-
-	* src/mips/n32.S: Fix call floating point va function.
-
-2014-01-21  Zachary Waldowski  <zach@waldowski.me>
-
-	* src/aarch64/ffi.c: Fix missing semicolons on assertions under
-	debug mode.
-
-2013-12-30  Zachary Waldowski  <zach@waldowski.me>
-
-	* .gitignore: Exclude darwin_* generated source and build_* trees.
-	* src/aarch64/ffi.c, src/arm/ffi.c, src/x86/ffi.c: Inhibit Clang
-	previous prototype warnings.
-	* src/arm/ffi.c: Prevent NULL dereference, fix short type warning
-	* src/dlmalloc.c: Fix warnings from set_segment_flags return type,
-	and the native use of size_t for malloc on platforms
-	* src/arm/sysv.S: Use unified syntax. Clang clean-ups for
-	ARM_FUNC_START.
-	* generate-osx-source-and-headers.py: Remove.
-	* build-ios.sh: Remove.
-	* libffi.xcodeproj/project.pbxproj: Rebuild targets. Include
-	x86_64+aarch64 pieces in library.  Export headers properly.
-	* src/x86/ffi64.c: More Clang warning clean-ups.
-	* src/closures.c (open_temp_exec_file_dir): Use size_t.
-	* src/prep_cif.c (ffi_prep_cif_core): Cast ALIGN result.
-	* src/aarch64/sysv.S: Use CNAME for global symbols.  Only use
-	.size for ELF targets.
-	* src/aarch64/ffi.c: Clean up for double == long double.  Clean up
-	from Clang warnings.  Use Clang cache invalidation builtin.  Use
-	size_t in place of unsigned in many places.  Accommodate for
-	differences in Apple AArch64 ABI.
-
-2013-12-02  Daniel Rodríguez Troitiño  <drodrigueztroitino@yahoo.es>
-
-	* generate-darwin-source-and-headers.py: Clean up, modernize,
-	merged version of previous scripts.
-
-2013-11-21  Anthony Green  <green@moxielogic.com>
-
-	* configure, Makefile.in, include/Makefile.in, include/ffi.h.in,
-	man/Makefile.in, testsuite/Makefile.in, fficonfig.h.in: Rebuilt.
-
-2013-11-21  Alan Modra  <amodra@gmail.com>
-
-	* Makefile.am (EXTRA_DIST): Add new src/powerpc files.
-	(nodist_libffi_la_SOURCES <POWERPC, POWERPC_FREEBSD>): Likewise.
-	* configure.ac (HAVE_LONG_DOUBLE_VARIANT): Define for powerpc.
-	* include/ffi.h.in (ffi_prep_types): Declare.
-	* src/prep_cif.c (ffi_prep_cif_core): Call ffi_prep_types.
-	* src/types.c (FFI_NONCONST_TYPEDEF): Define and use for
-	HAVE_LONG_DOUBLE_VARIANT.
-	* src/powerpc/ffi_powerpc.h: New file.
-	* src/powerpc/ffi.c: Split into..
-	* src/powerpc/ffi_sysv.c: ..new file, and..
-	* src/powerpc/ffi_linux64.c: ..new file, rewriting parts.
-	* src/powerpc/ffitarget.h (enum ffi_abi): Rewrite powerpc ABI
-	selection as bits controlling features.
-	* src/powerpc/linux64.S: For consistency, use POWERPC64 rather
-	than __powerpc64__.
-	* src/powerpc/linux64_closure.S: Likewise.
-	* src/powerpc/ppc_closure.S: Likewise.  Move .note.FNU-stack
-	inside guard.
-	* src/powerpc/sysv.S: Likewise.
-	* configure: Regenerate.
-	* fficonfig.h.in: Regenerate.
-	* Makefile.in: Regenerate.
-
-2013-11-20  Alan Modra  <amodra@gmail.com>
-
-	* src/powerpc/ffi.c (ffi_prep_cif_machdep_core): Use
-	NUM_FPR_ARG_REGISTERS64 and NUM_GPR_ARG_REGISTERS64 not their
-	32-bit versions for 64-bit code.
-	* src/powerpc/linux64_closure.S: Don't use the return value area
-	as a parameter save area on ELFv2.
-
-2013-11-18  Iain Sandoe  <iain@codesourcery.com>
-
-	* src/powerpc/darwin.S (EH): Correct use of pcrel FDE encoding.
-	* src/powerpc/darwin_closure.S (EH): Likewise. Modernise picbase
-	labels.
-
-2013-11-18  Anthony Green  <green@moxielogic.com>
-
-	* src/arm/ffi.c (ffi_call): Hoist declaration of temp to top of
-	function.
-	* src/arm/ffi.c (ffi_closure_inner): Moderize function declaration
-	to appease compiler.
-	Thanks for Gregory P. Smith <greg@krypto.org>.
-
-2013-11-18  Anthony Green  <green@moxielogic.com>
-
-	* README (tested): Mention PowerPC ELFv2.
-
-2013-11-16  Alan Modra  <amodra@gmail.com>
-
-	* src/powerpc/ppc_closure.S: Move errant #endif to where it belongs.
-	Don't bl .Luint128.
-
-2013-11-16  Alan Modra  <amodra@gmail.com>
-
-	* src/powerpc/ffi.c (ffi_prep_cif_machdep_core): Use #if _CALL_ELF
-	test to select parameter save sizing for ELFv2 vs. ELFv1.
-	* src/powerpc/ffitarget.h (FFI_V2_TYPE_FLOAT_HOMOG,
-	FFI_V2_TYPE_DOUBLE_HOMOG, FFI_V2_TYPE_SMALL_STRUCT): Define.
-	(FFI_TRAMPOLINE_SIZE): Define variant for ELFv2.
-	* src/powerpc/ffi.c (FLAG_ARG_NEEDS_PSAVE): Define.
-	(discover_homogeneous_aggregate): New function.
-	(ffi_prep_args64): Adjust start of param save area for ELFv2.
-	Handle homogenous floating point struct parms.
-	(ffi_prep_cif_machdep_core): Adjust space calculation for ELFv2.
-	Handle ELFv2 return values.  Set FLAG_ARG_NEEDS_PSAVE.  Handle
-	homogenous floating point structs.
-	(ffi_call): Increase size of smst_buffer for ELFv2.  Handle ELFv2.
-	(flush_icache): Compile for ELFv2.
-	(ffi_prep_closure_loc): Set up ELFv2 trampoline.
-	(ffi_closure_helper_LINUX64): Don't return all structs directly
-	to caller.  Handle homogenous floating point structs.  Handle
-	ELFv2 struct return values.
-	* src/powerpc/linux64.S (ffi_call_LINUX64): Set up r2 for
-	ELFv2.  Adjust toc save location.  Call function pointer using
-	r12.  Handle FLAG_RETURNS_SMST.  Don't predict branches.
-	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Set up r2
-	for ELFv2.  Define ELFv2 versions of STACKFRAME, PARMSAVE, and
-	RETVAL.  Handle possibly missing parameter save area.  Handle
-	ELFv2 return values.
-	(.note.GNU-stack): Move inside outer #ifdef.
-
-2013-11-16  Alan Modra  <amodra@gmail.com>
-
-	* src/powerpc/ffi.c (ffi_prep_cif_machdep): Revert 2013-02-08
-	change.  Do not consume an int arg when returning a small struct
-	for FFI_SYSV ABI.
-	(ffi_call): Only use bounce buffer when FLAG_RETURNS_SMST.
-	Properly copy bounce buffer to destination.
-	* src/powerpc/sysv.S: Revert 2013-02-08 change.
-	* src/powerpc/ppc_closure.S: Remove stray '+'.
-
-2013-11-16  Alan Modra  <amodra@gmail.com>
-
-	* src/powerpc/ffi.c (ffi_prep_args64): Align struct parameters
-	according to __STRUCT_PARM_ALIGN__.
-	(ffi_prep_cif_machdep_core): Likewise.
-	(ffi_closure_helper_LINUX64): Likewise.
-
-2013-11-16  Alan Modra  <amodra@gmail.com>
-
-	* src/powerpc/linux64.S (ffi_call_LINUX64): Tweak restore of r28.
-	(.note.GNU-stack): Move inside outer #ifdef.
-	* src/powerpc/linux64_closure.S (STACKFRAME, PARMSAVE,
-	RETVAL): Define and use throughout.
-	(ffi_closure_LINUX64): Save fprs before buying stack.
-	(.note.GNU-stack): Move inside outer #ifdef.
-
-2013-11-16  Alan Modra  <amodra@gmail.com>
-
-	* src/powerpc/ffitarget.h (FFI_TARGET_SPECIFIC_VARIADIC): Define.
-	(FFI_EXTRA_CIF_FIELDS): Define.
-	* src/powerpc/ffi.c (ffi_prep_args64): Save fprs as per the
-	ABI, not to both fpr and param save area.
-	(ffi_prep_cif_machdep_core): Renamed from ffi_prep_cif_machdep.
-	Keep initial flags.  Formatting.  Remove dead FFI_LINUX_SOFT_FLOAT
-	code.
-	(ffi_prep_cif_machdep, ffi_prep_cif_machdep_var): New functions.
-	(ffi_closure_helper_LINUX64): Pass floating point as per ABI,
-	not to both fpr and parameter save areas.
-
-	* libffi/testsuite/libffi.call/cls_double_va.c (main): Correct
-	function cast and don't call ffi_prep_cif.
-	* libffi/testsuite/libffi.call/cls_longdouble_va.c (main): Likewise.
-
-2013-11-15  Andrew Haley  <aph@redhat.com>
-
-	* doc/libffi.texi (Closure Example): Fix the sample code.
-	* doc/libffi.info, doc/stamp-vti, doc/version.texi: Rebuilt.
-
-2013-11-15  Andrew Haley  <aph@redhat.com>
-
-	* testsuite/libffi.call/va_struct1.c (main): Fix broken test.
-	* testsuite/libffi.call/cls_uint_va.c (cls_ret_T_fn): Likewise
-	* testsuite/libffi.call/cls_struct_va1.c (test_fn): Likewise.
-	* testsuite/libffi.call/va_1.c (main): Likewise.
-
-2013-11-14  David Schneider  <david.schneider@bivab.de>
-
-	* src/arm/ffi.c: Fix register allocation for mixed float and
-	doubles.
-	* testsuite/libffi.call/cls_many_mixed_float_double.c: Testcase
-	for many mixed float and double arguments.
-
-2013-11-13  Alan Modra  <amodra@gmail.com>
-
-	* doc/libffi.texi (Simple Example): Correct example code.
-	* doc/libffi.info, doc/stamp-vti, doc/version.texi: Rebuilt.
-
-2013-11-13  Anthony Green  <green@moxielogic.com>
-
-	* include/ffi_common.h: Respect HAVE_ALLOCA_H for GNU compiler
-	based build. (Thanks to tmr111116 on github)
-
-2013-11-09  Anthony Green  <green@moxielogic.com>
-
-	* m4/libtool.m4: Refresh.
-	* configure, Makefile.in: Rebuilt.
-	* README: Add more notes about next release.
-
-2013-11-09  Shigeharu TAKENO  <shige@iee.niit.ac.jp>
-
-	* m4/ax_gcc_archflag.m4 (ax_gcc_arch): Don't recognize
-	UltraSPARC-IIi as ultrasparc3.
-
-2013-11-06  Mark Kettenis  <kettenis@gnu.org>
-
-	* src/x86/freebsd.S (ffi_call_SYSV): Align the stack pointer to
-        16-bytes.
-
-2013-11-06  Konstantin Belousov <kib@freebsd.org>
-
-	* src/x86/freebsd.S (ffi_closure_raw_SYSV): Mark the assembler
-	source as not requiring executable stack.
-
-2013-11-02  Anthony Green  <green@moxielogic.com>
-
-	* doc/libffi.texi (The Basics): Clarify return value buffer size
-	requirements.  Also, NULL result buffer pointers are no longer
-	supported.
-	* doc/libffi.info: Rebuilt.
-
-2013-11-02  Mischa Jonker  <mjonker@synopsys.com>
-
-	* Makefile.am (nodist_libffi_la_SOURCES): Fix build error.
-	* Makefile.in: Rebuilt.
-
-2013-11-02  David Schneider  <david.schneider@bivab.de>
-
-	* src/arm/ffi.c: more robust argument handling for closures on arm hardfloat
-	* testsuite/libffi.call/many_mixed.c: New file.
-	* testsuite/libffi.call/cls_many_mixed_args.c: More tests.
-
-2013-11-02  Vitaly Budovski
-
-	* src/x86/ffi.c (ffi_prep_cif_machdep): Don't align stack for win32.
-
-2013-10-23  Mark H Weaver  <mhw@netris.org>
-
-	* src/mips/ffi.c: Fix handling of uint32_t arguments on the
-	MIPS N32 ABI.
-
-2013-10-13  Sandra Loosemore  <sandra@codesourcery.com>
-
-	* README: Add Nios II to table of supported platforms.
-	* Makefile.am (EXTRA_DIST): Add nios2 files.
-	(nodist_libffi_la_SOURCES): Likewise.
-	* Makefile.in: Regenerated.
-	* configure.ac (nios2*-linux*): New host.
-	(NIOS2): Add AM_CONDITIONAL.
-	* configure: Regenerated.
-	* src/nios2/ffi.c: New.
-	* src/nios2/ffitarget.h: New.
-	* src/nios2/sysv.S: New.
-	* src/prep_cif.c (initialize_aggregate): Handle extra structure
-	alignment via FFI_AGGREGATE_ALIGNMENT.
-	(ffi_prep_cif_core): Conditionalize structure return for NIOS2.
-
-2013-10-10  Sandra Loosemore  <sandra@codesourcery.com>
-
-	* testsuite/libffi.call/cls_many_mixed_args.c (cls_ret_double_fn):
-	Fix uninitialized variable.
-
-2013-10-11  Marcus Shawcroft  <marcus.shawcroft@arm.com>
-
-	* testsuite/libffi.call/many.c (many): Replace * with +.
-
-2013-10-08  OndÅ™ej Bílka  <neleai@seznam.cz>
-
-	* src/aarch64/ffi.c, src/aarch64/sysv.S, src/arm/ffi.c,
-	src/arm/gentramp.sh, src/bfin/sysv.S, src/closures.c,
-	src/dlmalloc.c, src/ia64/ffi.c, src/microblaze/ffi.c,
-	src/microblaze/sysv.S, src/powerpc/darwin_closure.S,
-	src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/sh/ffi.c,
-	src/tile/tile.S, testsuite/libffi.call/nested_struct11.c: Fix
-	spelling errors.
-
-2013-10-08  Anthony Green  <green@moxielogic.com>
-
-	* aclocal.m4, compile, config.guess, config.sub, depcomp,
-	install-sh, mdate-sh, missing, texinfo.tex: Update from upstream.
-	* configure.ac: Update version to 3.0.14-rc0.
-	* Makefile.in, configure, Makefile.in, include/Makefile.in,
-	man/Makefile.in, testsuite/Makefile.in: Rebuilt.
-	* README: Mention M88K and VAX.
-
-2013-07-15  Miod Vallat  <miod@openbsd.org>
-
-	* Makefile.am,
-	configure.ac,
-	src/m88k/ffi.c,
-	src/m88k/ffitarget.h,
-	src/m88k/obsd.S,
-	src/vax/elfbsd.S,
-	src/vax/ffi.c,
-	src/vax/ffitarget.h: Add m88k and vax support.
-
-2013-06-24 Alan Modra  <amodra@gmail.com>
-
-	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Move var declaration
-	before statements.
-	(ffi_prep_args64): Support little-endian.
-	(ffi_closure_helper_SYSV, ffi_closure_helper_LINUX64): Likewise.
-	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Likewise.
-	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Likewise.
-
-2013-06-12  Mischa Jonker  <mjonker@synopsys.com>
-
-	 * configure.ac: Add support for ARC.
-	 * Makefile.am: Likewise.
-	 * README: Add ARC details.
-	 * src/arc/arcompact.S: New.
-	 * src/arc/ffi.c: Likewise.
-	 * src/arc/ffitarget.h: Likewise.
-
-2013-03-28  David Schneider  <david.schneider@bivab.de>
-
-	 * src/arm/ffi.c: Fix support for ARM hard-float calling convention.
-	 * src/arm/sysv.S: call different methods for SYSV and VFP ABIs.
-	 * testsuite/libffi.call/cls_many_mixed_args.c: testcase for a closure with
-	 mixed arguments, many doubles.
-	 * testsuite/libffi.call/many_double.c: testcase for calling a function using
-	 more than 8 doubles.
-	 * testcase/libffi.call/many.c: use absolute value to check result against an
-	 epsilon
-
-2013-03-17  Anthony Green  <green@moxielogic.com>
-
-	* README: Update for 3.0.13.
-	* configure.ac: Ditto.
-	* configure: Rebuilt.
-	* doc/*: Update version.
-
-2013-03-17  Dave Korn  <dave.korn.cygwin@gmail.com>
-
-	* src/closures.c (is_emutramp_enabled
-	[!FFI_MMAP_EXEC_EMUTRAMP_PAX]): Move default definition outside
-	enclosing #if scope.
-
-2013-03-17  Anthony Green  <green@moxielogic.com>
-
-	* configure.ac: Only modify toolexecdir in certain cases.
-	* configure: Rebuilt.
-
-2013-03-16  Gilles Talis  <gilles.talis@gmail.com>
-
-	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Don't use
-	fparg_count,etc on __NO_FPRS__ targets.
-
-2013-03-16  Alan Hourihane  <alanh@fairlite.co.uk>
-
-	* src/m68k/sysv.S (epilogue): Don't use extb instruction on
-	m680000 machines.
-
-2013-03-16  Alex Gaynor <alex.gaynor@gmail.com>
-
-	* src/x86/ffi.c (ffi_prep_cif_machdep): Always align stack.
-
-2013-03-13  Markos Chandras <markos.chandras@imgtec.com>
-
-	* configure.ac: Add support for Imagination Technologies Meta.
-	* Makefile.am: Likewise.
-	* README: Add Imagination Technologies Meta details.
-	* src/metag/ffi.c: New.
-	* src/metag/ffitarget.h: Likewise.
-	* src/metag/sysv.S: Likewise.
-
-2013-02-24  Andreas Schwab  <schwab@linux-m68k.org>
-
-	* doc/libffi.texi (Structures): Fix missing category argument of
-	@deftp.
-
-2013-02-11  Anthony Green <green@moxielogic.com>
-
-	* configure.ac: Update release number to 3.0.12.
-	* configure: Rebuilt.
-	* README: Update release info.
-
-2013-02-10  Anthony Green <green@moxielogic.com>
-
-	* README: Add Moxie.
-	* src/moxie/ffi.c: Created.
-	* src/moxie/eabi.S: Created.
-	* src/moxie/ffitarget.h: Created.
-	* Makefile.am (nodist_libffi_la_SOURCES): Add Moxie.
-	* Makefile.in: Rebuilt.
-	* configure.ac: Add Moxie.
-	* configure: Rebuilt.
-	* testsuite/libffi.call/huge_struct.c: Disable format string
-	warnings for moxie*-*-elf tests.
-
-2013-02-10  Anthony Green <green@moxielogic.com>
-
-	* Makefile.am (LTLDFLAGS): Fix reference.
-	* Makefile.in: Rebuilt.
-
-2013-02-10  Anthony Green <green@moxielogic.com>
-
-	* README: Update supported platforms.  Update test results link.
-
-2013-02-09  Anthony Green <green@moxielogic.com>
-
-	* testsuite/libffi.call/negint.c: Remove forced -O2.
-	* testsuite/libffi.call/many2.c (foo): Remove GCCism.
-	* testsuite/libffi.call/ffitest.h: Add default PRIuPTR definition.
-
-	* src/sparc/v8.S (ffi_closure_v8): Import ancient ulonglong
-	closure return type fix developed by Martin v. Löwis for cpython
-	fork.
-
-2013-02-08  Andreas Tobler  <andreast@fgznet.ch>
-
-	* src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix small struct
-	support.
-	* src/powerpc/sysv.S: Ditto.
-
-2013-02-08  Anthony Green <green@moxielogic.com>
-
-	* testsuite/libffi.call/cls_longdouble.c: Remove xfail for
-	arm*-*-*.
-
-2013-02-08  Anthony Green <green@moxielogic.com>
-
-	* src/sparc/ffi.c (ffi_prep_closure_loc): Fix cache flushing for GCC.
-
-2013-02-08  Matthias Klose  <doko@ubuntu.com>
-
-	* man/ffi_prep_cif.3: Clean up for debian linter.
-
-2013-02-08  Peter Bergner  <bergner@vnet.ibm.com>
-
-	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Account for FP args pushed
-	on the stack.
-
-2013-02-08  Anthony Green <green@moxielogic.com>
-
-	* Makefile.am (EXTRA_DIST): Add missing files.
-	* testsuite/Makefile.am (EXTRA_DIST): Ditto.
-	* Makefile.in: Rebuilt.
-
-2013-02-08  Anthony Green <green@moxielogic.com>
-
-	* configure.ac: Move sparc asm config checks to within functions
-	for compatibility with sun tools.
-	* configure: Rebuilt.
-	* src/sparc/ffi.c (ffi_prep_closure_loc): Flush cache on v9
-	systems.
-	* src/sparc/v8.S (ffi_flush_icache): Implement a sparc v9 cache
-	flusher.
-
-2013-02-08  Nathan Rossi <nathan.rossi@xilinx.com>
-
-	* src/microblaze/ffi.c (ffi_closure_call_SYSV): Fix handling of
-	small big-endian structures.
-	(ffi_prep_args): Ditto.
-
-2013-02-07  Anthony Green <green@moxielogic.com>
-
-	* src/sparc/v8.S (ffi_call_v8): Fix typo from last patch
-	(effectively hiding ffi_call_v8).
-
-2013-02-07  Anthony Green <green@moxielogic.com>
-
-	* configure.ac: Update bug reporting address.
-	* configure.in: Rebuild.
-
-	* src/sparc/v8.S (ffi_flush_icache): Out-of-line cache flusher for
-	Sun compiler.
-	* src/sparc/ffi.c (ffi_call): Remove warning.
-	Call ffi_flush_icache for non-GCC builds.
-	(ffi_prep_closure_loc): Use ffi_flush_icache.
-
-	* Makefile.am (EXTRA_DIST): Add libtool-ldflags.
-	* Makefile.in: Rebuilt.
-	* libtool-ldflags: New file.
-
-2013-02-07  Daniel Schepler <dschepler@gmail.com>
-
-	* configure.ac: Correctly identify x32 systems as 64-bit.
-	* m4/libtool.m4: Remove libtool expr error.
-	* aclocal.m4, configure: Rebuilt.
-
-2013-02-07  Anthony Green <green@moxielogic.com>
-
-	* configure.ac: Fix GCC usage test.
-	* configure: Rebuilt.
-	* README: Mention LLVM/GCC x86_64 issue.
-	* testsuite/Makefile.in: Rebuilt.
-
-2013-02-07  Anthony Green <green@moxielogic.com>
-
-	* testsuite/libffi.call/cls_double_va.c (main): Replace // style
-	comments with /* */ for xlc compiler.
-	* testsuite/libffi.call/stret_large.c (main): Ditto.
-	* testsuite/libffi.call/stret_large2.c (main): Ditto.
-	* testsuite/libffi.call/nested_struct1.c (main): Ditto.
-	* testsuite/libffi.call/huge_struct.c (main): Ditto.
-	* testsuite/libffi.call/float_va.c (main): Ditto.
-	* testsuite/libffi.call/cls_struct_va1.c (main): Ditto.
-	* testsuite/libffi.call/cls_pointer_stack.c (main): Ditto.
-	* testsuite/libffi.call/cls_pointer.c (main): Ditto.
-	* testsuite/libffi.call/cls_longdouble_va.c (main): Ditto.
-
-2013-02-06  Anthony Green <green@moxielogic.com>
-
-	* man/ffi_prep_cif.3: Clean up for debian lintian checker.
-
-2013-02-06  Anthony Green <green@moxielogic.com>
-
-	* Makefile.am (pkgconfigdir): Add missing pkgconfig install bits.
-	* Makefile.in: Rebuild.
-
-2013-02-02  Mark H Weaver <mhw@netris.org>
-
-	* src/x86/ffi64.c (ffi_call): Sign-extend integer arguments passed
-	via general purpose registers.
-
-2013-01-21  Nathan Rossi <nathan.rossi@xilinx.com>
-
-	* README: Add MicroBlaze details.
-	* Makefile.am: Add MicroBlaze support.
-	* configure.ac: Likewise.
-	* src/microblaze/ffi.c: New.
-	* src/microblaze/ffitarget.h: Likewise.
-	* src/microblaze/sysv.S: Likewise.
-
-2013-01-21  Nathan Rossi <nathan.rossi@xilinx.com>
-	* testsuite/libffi.call/return_uc.c: Fixed issue.
-
-2013-01-21  Chris Zankel   <chris@zankel.net>
-
-	* README: Add Xtensa support.
-	* Makefile.am: Likewise.
-	* configure.ac: Likewise.
-	* Makefile.in Regenerate.
-	* configure: Likewise.
-	* src/prep_cif.c: Handle Xtensa.
-	* src/xtensa: New directory.
-	* src/xtensa/ffi.c: New file.
-	* src/xtensa/ffitarget.h: Ditto.
-	* src/xtensa/sysv.S: Ditto.
-
-2013-01-11  Anthony Green  <green@moxielogic.com>
-
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Replace // style
-	comments with /* */ for xlc compiler.
-	* src/powerpc/aix.S (ffi_call_AIX): Ditto.
-	* testsuite/libffi.call/ffitest.h (allocate_mmap): Delete
-	deprecated inline function.
-	* testsuite/libffi.special/ffitestcxx.h: Ditto.
-	* README: Add update for AIX support.
-
-2013-01-11  Anthony Green  <green@moxielogic.com>
-
-	* configure.ac: Robustify pc relative reloc check.
-	* m4/ax_cc_maxopt.m4: Don't -malign-double.  This is an ABI
-	changing option for 32-bit x86.
-	* aclocal.m4, configure: Rebuilt.
-	* README: Update supported target list.
-
-2013-01-10  Anthony Green  <green@moxielogic.com>
-
-	* README (tested): Add Compiler column to table.
-
-2013-01-10  Anthony Green  <green@moxielogic.com>
-
-	* src/x86/ffi64.c (struct register_args): Make sse array and array
-	of unions for sunpro compiler compatibility.
-
-2013-01-10  Anthony Green  <green@moxielogic.com>
-
-	* configure.ac: Test target platform size_t size.  Handle both 32
-	and 64-bit builds for x86_64-* and i?86-* targets (allowing for
-	CFLAG option to change default settings).
-	* configure, aclocal.m4: Rebuilt.
-
-2013-01-10  Anthony Green  <green@moxielogic.com>
-
-	* testsuite/libffi.special/special.exp: Only run exception
-	handling tests when using GNU compiler.
-
-	* m4/ax_compiler_vendor.m4: New file.
-	* configure.ac: Test for compiler vendor and don't use
-	AX_CFLAGS_WARN_ALL with the sun compiler.
-	* aclocal.m4, configure: Rebuilt.
-
-2013-01-10  Anthony Green  <green@moxielogic.com>
-
-	* include/ffi_common.h: Don't use GCCisms to define types when
-	building with the SUNPRO compiler.
-
-2013-01-10  Anthony Green  <green@moxielogic.com>
-
-	* configure.ac: Put local.exp in the right place.
-	* configure: Rebuilt.
-
-	* src/x86/ffi.c: Update comment about regparm function attributes.
-	* src/x86/sysv.S (ffi_closure_SYSV): The SUNPRO compiler requires
-	that all function arguments be passed on the stack (no regparm
-	support).
-
-2013-01-08  Anthony Green  <green@moxielogic.com>
-
-	* configure.ac: Generate local.exp.  This sets CC_FOR_TARGET
-	when we are using the vendor compiler.
-	* testsuite/Makefile.am (EXTRA_DEJAGNU_SITE_CONFIG): Point to
-	../local.exp.
-	* configure, testsuite/Makefile.in: Rebuilt.
-
-	* testsuite/libffi.call/call.exp: Run tests with different
-	options, depending on whether or not we are using gcc or the
-	vendor compiler.
-	* testsuite/lib/libffi.exp (libffi-init): Set using_gcc based on
-	whether or not we are building/testing with gcc.
-
-2013-01-08  Anthony Green  <green@moxielogic.com>
-
-	* configure.ac: Switch x86 solaris target to X86 by default.
-	* configure: Rebuilt.
-
-2013-01-08  Anthony Green  <green@moxielogic.com>
-
-	* configure.ac: Fix test for read-only eh_frame.
-	* configure: Rebuilt.
-
-2013-01-08  Anthony Green  <green@moxielogic.com>
-
-	* src/x86/sysv.S, src/x86/unix64.S: Only emit DWARF unwind info
-	when building with the GNU toolchain.
-	* testsuite/libffi.call/ffitest.h (CHECK): Fix for Solaris vendor
-	compiler.
-
-2013-01-07  Thorsten Glaser <tg@mirbsd.org>
-
-	* testsuite/libffi.call/cls_uchar_va.c,
-	testsuite/libffi.call/cls_ushort_va.c,
-	testsuite/libffi.call/va_1.c: Testsuite fixes.
-
-2013-01-07  Thorsten Glaser <tg@mirbsd.org>
-
-	* src/m68k/ffi.c (CIF_FLAGS_SINT8, CIF_FLAGS_SINT16): Define.
-	(ffi_prep_cif_machdep): Fix 8-bit and 16-bit signed calls.
-	* src/m68k/sysv.S (ffi_call_SYSV, ffi_closure_SYSV): Ditto.
-
-2013-01-04  Anthony Green  <green@moxielogic.com>
-
-	* Makefile.am (AM_CFLAGS): Don't automatically add -fexceptions
-	and -Wall.  This is set in the configure script after testing for
-	GCC.
-	* Makefile.in: Rebuilt.
-
-2013-01-02  rofl0r <https://github.com/rofl0r>
-
-	* src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix build error on ppc
-	when long double == double.
-
-2013-01-02  Reini Urban  <rurban@x-ray.at>
-
-	* Makefile.am (libffi_la_LDFLAGS): Add -no-undefined to LDFLAGS
-	(required for shared libs on cygwin/mingw).
-	* Makefile.in: Rebuilt.
-
-2012-10-31  Alan Modra  <amodra@gmail.co>
-
-	* src/powerpc/linux64_closure.S: Add new ABI support.
-	* src/powerpc/linux64.S: Likewise.
-
-2012-10-30  Magnus Granberg  <zorry@gentoo.org>
-	    Pavel Labushev  <pavel.labushev@runbox.ru>
-
-	* configure.ac: New options pax_emutramp
-	* configure, fficonfig.h.in: Regenerated
-	* src/closures.c: New function emutramp_enabled_check() and
-	checks.
-
-2012-10-30  Frederick Cheung  <frederick.cheung@gmail.com>
-
-	* configure.ac: Enable FFI_MAP_EXEC_WRIT for Darwin 12 (mountain
-	lion) and future version.
-	* configure: Rebuild.
-
-2012-10-30  James Greenhalgh  <james.greenhalgh at arm.com>
-            Marcus Shawcroft  <marcus.shawcroft at arm.com>
-
-        * README: Add details of aarch64 port.
-        * src/aarch64/ffi.c: New.
-        * src/aarch64/ffitarget.h: Likewise.
-        * src/aarch64/sysv.S: Likewise.
-	* Makefile.am: Support aarch64.
-	* configure.ac: Support aarch64.
-	* Makefile.in, configure: Rebuilt.
-
-2012-10-30  James Greenhalgh  <james.greenhalgh at arm.com>
-            Marcus Shawcroft  <marcus.shawcroft at arm.com>
-
-        * testsuite/lib/libffi.exp: Add support for aarch64.
-        * testsuite/libffi.call/cls_struct_va1.c: New.
-        * testsuite/libffi.call/cls_uchar_va.c: Likewise.
-        * testsuite/libffi.call/cls_uint_va.c: Likewise.
-        * testsuite/libffi.call/cls_ulong_va.c: Likewise.
-        * testsuite/libffi.call/cls_ushort_va.c: Likewise.
-        * testsuite/libffi.call/nested_struct11.c: Likewise.
-        * testsuite/libffi.call/uninitialized.c: Likewise.
-        * testsuite/libffi.call/va_1.c: Likewise.
-        * testsuite/libffi.call/va_struct1.c: Likewise.
-        * testsuite/libffi.call/va_struct2.c: Likewise.
-        * testsuite/libffi.call/va_struct3.c: Likewise.
-
-2012-10-12  Walter Lee  <walt@tilera.com>
-
-        * Makefile.am: Add TILE-Gx/TILEPro support.
-        * configure.ac: Likewise.
-        * Makefile.in: Regenerate.
-        * configure: Likewise.
-        * src/prep_cif.c (ffi_prep_cif_core): Handle TILE-Gx/TILEPro.
-        * src/tile: New directory.
-        * src/tile/ffi.c: New file.
-        * src/tile/ffitarget.h: Ditto.
-        * src/tile/tile.S: Ditto.
-
-2012-10-12  Matthias Klose  <doko@ubuntu.com>
-
-	* generate-osx-source-and-headers.py: Normalize whitespace.
-
-2012-09-14  David Edelsohn  <dje.gcc@gmail.com>
-
-	* configure: Regenerated.
-
-2012-08-26  Andrew Pinski  <apinski@cavium.com>
-
-	PR libffi/53014
-	* src/mips/ffi.c (ffi_prep_closure_loc): Allow n32 with soft-float and n64 with
-	soft-float.
-
-2012-08-08  Uros Bizjak  <ubizjak@gmail.com>
-
-	* src/s390/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
-	just return FFI_BAD_ABI when things are wrong.
-
-2012-07-18  H.J. Lu  <hongjiu.lu@intel.com>
-
-	PR libffi/53982
-	PR libffi/53973
-	* src/x86/ffitarget.h: Check __ILP32__ instead of __LP64__ for x32.
-	(FFI_SIZEOF_JAVA_RAW): Defined to 4 for x32.
-
-2012-05-16  H.J. Lu  <hongjiu.lu@intel.com>
-
-	* configure: Regenerated.
-
-2012-05-05  Nicolas Lelong
-
-	* libffi.xcodeproj/project.pbxproj: Fixes.
-	* README: Update for iOS builds.
-
-2012-04-23  Alexandre Keunecke I. de Mendonca <alexandre.keunecke@gmail.com>
-
-	* configure.ac: Add Blackfin/sysv support
-	* Makefile.am: Add Blackfin/sysv support
-	* src/bfin/ffi.c:  Add Blackfin/sysv support
-	* src/bfin/ffitarget.h: Add Blackfin/sysv support
-
-2012-04-11  Anthony Green  <green@moxielogic.com>
-
-	* Makefile.am (EXTRA_DIST): Add new script.
-	* Makefile.in: Rebuilt.
-
-2012-04-11  Zachary Waldowski  <zwaldowski@gmail.com>
-
-	* generate-ios-source-and-headers.py,
-	libffi.xcodeproj/project.pbxproj: Support a Mac static library via
-	Xcode. Set iOS compatibility to 4.0.  Move iOS trampoline
-	generation into an Xcode "run script" phase.  Include both as
-	Xcode build scripts. Don't always regenerate config files.
-
-2012-04-10  Anthony Green  <green@moxielogic.com>
-
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Add missing semicolon.
-
-2012-04-06  Anthony Green  <green@moxielogic.com>
-
-	* Makefile.am (EXTRA_DIST): Add new iOS/xcode files.
-	* Makefile.in: Rebuilt.
-
-2012-04-06  Mike Lewis  <mikelikespie@gmail.com>
-
-	* generate-ios-source-and-headers.py: New file.
-	* libffi.xcodeproj/project.pbxproj: New file.
-	* README: Update instructions on building iOS binary.
-	* build-ios.sh: Delete.
-
-2012-04-06  Anthony Green  <green@moxielogic.com>
-
-	* src/x86/ffi64.c (UINT128): Define differently for Intel and GNU
-	compilers, then use it.
-
-2012-04-06  H.J. Lu  <hongjiu.lu@intel.com>
-
-	* m4/libtool.m4 (_LT_ENABLE_LOCK): Support x32.
-
-2012-04-06  Anthony Green  <green@moxielogic.com>
-
-	* testsuite/Makefile.am (EXTRA_DIST): Add missing test cases.
-	* testsuite/Makefile.in: Rebuilt.
-
-2012-04-05  Zachary Waldowski  <zwaldowski@gmail.com>
-
-	* include/ffi.h.in: Add missing trampoline table fields.
-	* src/arm/sysv.S: Fix ENTRY definition, and wrap symbol references
-	in CNAME.
-	* src/x86/ffi.c: Wrap Windows specific code in ifdefs.
-
-2012-04-02  Peter Bergner  <bergner@vnet.ibm.com>
-
-	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp.
-	Silence casting pointer to integer of different size warning.
-	Delete goto to previously deleted label.
-	(ffi_call): Silence possibly undefined warning.
-	(ffi_closure_helper_SYSV): Declare variable type.
-
-2012-04-02  Peter Rosin  <peda@lysator.liu.se>
-
-	* src/x86/win32.S (ffi_call_win32): Sign/zero extend the return
-	value in the Intel version as is already done for the AT&T version.
-	(ffi_closure_SYSV): Likewise.
-	(ffi_closure_raw_SYSV): Likewise.
-	(ffi_closure_STDCALL): Likewise.
-
-2012-03-29  Peter Rosin  <peda@lysator.liu.se>
-
-	* src/x86/win32.S (ffi_closure_raw_THISCALL): Unify the frame
-	generation, fix the ENDP label and remove the surplus third arg
-	from the 'lea' insn.
-
-2012-03-29  Peter Rosin  <peda@lysator.liu.se>
-
-	* src/x86/win32.S (ffi_closure_raw_SYSV): Make the 'stubraw' label
-	visible outside the PROC, so that ffi_closure_raw_THISCALL can see
-	it.  Also instruct the assembler to add a frame to the function.
-
-2012-03-23  Peter Rosin  <peda@lysator.liu.se>
-
-	* Makefile.am (AM_CPPFLAGS): Add -DFFI_BUILDING.
-	* Makefile.in: Rebuilt.
-	* include/ffi.h.in [MSVC]: Add __declspec(dllimport) decorations
-	to all data exports, when compiling libffi clients using MSVC.
-
-2012-03-29  Peter Rosin  <peda@lysator.liu.se>
-
-	* src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and
-	make it the default for MSVC.
-	(FFI_TYPE_MS_STRUCT): New structure return convention.
-	* src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure
-	return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT
-	instead of an ordinary FFI_TYPE_STRUCT.
-	(ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT.
-	(ffi_call): Likewise.
-	(ffi_prep_incoming_args_SYSV): Likewise.
-	(ffi_raw_call): Likewise.
-	(ffi_prep_closure_loc): Treat FFI_MS_CDECL as FFI_SYSV.
-	* src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT,
-	return a pointer to the result structure in eax and don't pop
-	that pointer from the stack, the caller takes care of it.
-	(ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT.
-	(ffi_closure_raw_SYSV): Likewise.
-
-2012-03-22  Peter Rosin  <peda@lysator.liu.se>
-
-	* testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline
-	assembly version with Intel syntax.
-	* testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise.
-
-2012-03-23  Peter Rosin  <peda@lysator.liu.se>
-
-	* testsuite/libffi.call/ffitest.h: Provide abstration of
-	__attribute__((fastcall)) in the form of a __FASTCALL__
-	define.  Define it to __fastcall for MSVC.
-	* testsuite/libffi.call/fastthis1_win32.c: Use the above.
-	* testsuite/libffi.call/fastthis2_win32.c: Likewise.
-	* testsuite/libffi.call/fastthis3_win32.c: Likewise.
-	* testsuite/libffi.call/strlen2_win32.c: Likewise.
-	* testsuite/libffi.call/struct1_win32.c: Likewise.
-	* testsuite/libffi.call/struct2_win32.c: Likewise.
-
-2012-03-22  Peter Rosin  <peda@lysator.liu.se>
-
-	* src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual
-	frame on function entry, MASM adds one automatically.
-
-2012-03-22  Peter Rosin  <peda@lysator.liu.se>
-
-	* testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing
-	bits in the MSVC headers.
-
-2012-03-22  Peter Rosin  <peda@lysator.liu.se>
-
-	* testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style
-	with no declarations after statements.
-	* testsuite/libffi.call/cls_16byte.c: Likewise.
-	* testsuite/libffi.call/cls_18byte.c: Likewise.
-	* testsuite/libffi.call/cls_19byte.c: Likewise.
-	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte1.c: Likewise.
-	* testsuite/libffi.call/cls_24byte.c: Likewise.
-	* testsuite/libffi.call/cls_2byte.c: Likewise.
-	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_3byte1.c: Likewise.
-	* testsuite/libffi.call/cls_3byte2.c: Likewise.
-	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_4byte.c: Likewise.
-	* testsuite/libffi.call/cls_5_1_byte.c: Likewise.
-	* testsuite/libffi.call/cls_5byte.c: Likewise.
-	* testsuite/libffi.call/cls_64byte.c: Likewise.
-	* testsuite/libffi.call/cls_6_1_byte.c: Likewise.
-	* testsuite/libffi.call/cls_6byte.c: Likewise.
-	* testsuite/libffi.call/cls_7_1_byte.c: Likewise.
-	* testsuite/libffi.call/cls_7byte.c: Likewise.
-	* testsuite/libffi.call/cls_8byte.c: Likewise.
-	* testsuite/libffi.call/cls_9byte1.c: Likewise.
-	* testsuite/libffi.call/cls_9byte2.c: Likewise.
-	* testsuite/libffi.call/cls_align_double.c: Likewise.
-	* testsuite/libffi.call/cls_align_float.c: Likewise.
-	* testsuite/libffi.call/cls_align_longdouble.c: Likewise.
-	* testsuite/libffi.call/cls_align_longdouble_split.c: Likewise.
-	* testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise.
-	* testsuite/libffi.call/cls_align_pointer.c: Likewise.
-	* testsuite/libffi.call/cls_align_sint16.c: Likewise.
-	* testsuite/libffi.call/cls_align_sint32.c: Likewise.
-	* testsuite/libffi.call/cls_align_sint64.c: Likewise.
-	* testsuite/libffi.call/cls_align_uint16.c: Likewise.
-	* testsuite/libffi.call/cls_align_uint32.c: Likewise.
-	* testsuite/libffi.call/cls_align_uint64.c: Likewise.
-	* testsuite/libffi.call/cls_dbls_struct.c: Likewise.
-	* testsuite/libffi.call/cls_pointer_stack.c: Likewise.
-	* testsuite/libffi.call/err_bad_typedef.c: Likewise.
-	* testsuite/libffi.call/huge_struct.c: Likewise.
-	* testsuite/libffi.call/nested_struct.c: Likewise.
-	* testsuite/libffi.call/nested_struct1.c: Likewise.
-	* testsuite/libffi.call/nested_struct10.c: Likewise.
-	* testsuite/libffi.call/nested_struct2.c: Likewise.
-	* testsuite/libffi.call/nested_struct3.c: Likewise.
-	* testsuite/libffi.call/nested_struct4.c: Likewise.
-	* testsuite/libffi.call/nested_struct5.c: Likewise.
-	* testsuite/libffi.call/nested_struct6.c: Likewise.
-	* testsuite/libffi.call/nested_struct7.c: Likewise.
-	* testsuite/libffi.call/nested_struct8.c: Likewise.
-	* testsuite/libffi.call/nested_struct9.c: Likewise.
-	* testsuite/libffi.call/stret_large.c: Likewise.
-	* testsuite/libffi.call/stret_large2.c: Likewise.
-	* testsuite/libffi.call/stret_medium.c: Likewise.
-	* testsuite/libffi.call/stret_medium2.c: Likewise.
-	* testsuite/libffi.call/struct1.c: Likewise.
-	* testsuite/libffi.call/struct1_win32.c: Likewise.
-	* testsuite/libffi.call/struct2.c: Likewise.
-	* testsuite/libffi.call/struct2_win32.c: Likewise.
-	* testsuite/libffi.call/struct3.c: Likewise.
-	* testsuite/libffi.call/struct4.c: Likewise.
-	* testsuite/libffi.call/struct5.c: Likewise.
-	* testsuite/libffi.call/struct6.c: Likewise.
-	* testsuite/libffi.call/struct7.c: Likewise.
-	* testsuite/libffi.call/struct8.c: Likewise.
-	* testsuite/libffi.call/struct9.c: Likewise.
-	* testsuite/libffi.call/testclosure.c: Likewise.
-
-2012-03-21  Peter Rosin	 <peda@lysator.liu.se>
-
-	* testsuite/libffi.call/float_va.c (float_va_fn): Use %f when
-	printing doubles (%lf is for long doubles).
-	(main): Likewise.
-
-2012-03-21  Peter Rosin  <peda@lysator.liu.se>
-
-	* testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*]
-	(set_ld_library_path_env_vars): Add the library search dir to PATH
-	(and save PATH for later).
-	(restore_ld_library_path_env_vars): Restore PATH.
-
-2012-03-21  Peter Rosin  <peda@lysator.liu.se>
-
-	* testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*]
-	(set_ld_library_path_env_vars): Add the library search dir to PATH
-	(and save PATH for later).
-	(restore_ld_library_path_env_vars): Restore PATH.
-
-2012-03-20  Peter Rosin  <peda@lysator.liu.se>
-
-	* testsuite/libffi.call/strlen2_win32.c (main): Remove bug.
-	* src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label
-	visible outside the PROC, so that ffi_closure_THISCALL can see it.
-
-2012-03-20  Peter Rosin  <peda@lysator.liu.se>
-
-	* testsuite/libffi.call/strlen2_win32.c (main): Remove bug.
-	* src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label
-	visible outside the PROC, so that ffi_closure_THISCALL can see it.
-
-2012-03-19  Alan Hourihane  <alanh@fairlite.co.uk>
-
-	* src/m68k/ffi.c: Add MINT support.
-	* src/m68k/sysv.S: Ditto.
-
-2012-03-06  Chung-Lin Tang  <cltang@codesourcery.com>
-
-	* src/arm/ffi.c (ffi_call): Add __ARM_EABI__ guard around call to
-	ffi_call_VFP().
-	(ffi_prep_closure_loc): Add __ARM_EABI__ guard around use of
-	ffi_closure_VFP.
-	* src/arm/sysv.S: Add __ARM_EABI__ guard around VFP code.
-
-2012-03-19  chennam  <csit@axway.com>
-
-	* src/powerpc/ffi_darwin.c (ffi_prep_closure_loc): Fix AIX closure
-	support.
-
-2012-03-13  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
-	just return FFI_BAD_ABI when things are wrong.
-	* src/sh64/ffi.c (ffi_prep_closure_loc): Ditto.
-
-2012-03-09  David Edelsohn  <dje.gcc@gmail.com>
-
-	* src/powerpc/aix_closure.S (ffi_closure_ASM): Adjust for Darwin64
-	change to return value of ffi_closure_helper_DARWIN and load type
-	from return type.
-
-2012-03-03  H.J. Lu  <hongjiu.lu@intel.com>
-
-	* src/x86/ffi64.c (ffi_call): Cast the return value to unsigned
-	long.
-	(ffi_prep_closure_loc): Cast to 64bit address in trampoline.
-	(ffi_closure_unix64_inner): Cast return pointer to unsigned long
-	first.
-
-	* src/x86/ffitarget.h (FFI_SIZEOF_ARG): Defined to 8 for x32.
-	(ffi_arg): Set to unsigned long long for x32.
-	(ffi_sarg): Set to long long for x32.
-
-2012-03-03  H.J. Lu  <hongjiu.lu@intel.com>
-
-	* src/prep_cif.c (ffi_prep_cif_core): Properly check bad ABI.
-
-2012-03-03  Andoni Morales Alastruey  <ylatuya@gmail.com>
-
-	* configure.ac: Add -no-undefined for both 32- and 64-bit x86
-	windows-like hosts.
-	* configure: Rebuilt.
-
-2012-02-27  Mikael Pettersson  <mikpe@it.uu.se>
-
-	PR libffi/52223
-	* Makefile.am (FLAGS_TO_PASS): Define.
-	* Makefile.in: Regenerate.
-
-2012-02-23  Anthony Green  <green@moxielogic.com>
-
-	* src/*/ffitarget.h: Ensure that users never include ffitarget.h
-	directly.
-
-2012-02-23  Kai Tietz  <ktietz@redhat.com>
-
-	PR libffi/52221
-	* src/x86/ffi.c (ffi_closure_raw_THISCALL): New
-	prototype.
-	(ffi_prep_raw_closure_loc): Use ffi_closure_raw_THISCALL for
-	thiscall-convention.
-	(ffi_raw_call): Use ffi_prep_args_raw.
-	* src/x86/win32.S (ffi_closure_raw_THISCALL): Add
-	implementation for stub.
-
-2012-02-10  Kai Tietz  <ktietz@redhat.com>
-
-	* configure.ac (AM_LTLDFLAGS): Add -no-undefine for x64
-	windows target.
-	* configure: Regenerated.
-
-2012-02-08  Kai Tietz  <ktietz@redhat.com>
-
-	* src/prep_cif.c (ffi_prep_cif): Allow for X86_WIN32
-	also FFI_THISCALL.
-	* src/x86/ffi.c (ffi_closure_THISCALL): Add prototype.
-	(FFI_INIT_TRAMPOLINE_THISCALL): New trampoline code.
-	(ffi_prep_closure_loc): Add FFI_THISCALL support.
-	* src/x86/ffitarget.h (FFI_TRAMPOLINE_SIZE): Adjust size.
-	* src/x86/win32.S (ffi_closure_THISCALL): New closure code
-	for thiscall-calling convention.
-	* testsuite/libffi.call/closure_thiscall.c: New test.
-
-2012-01-28  Kai Tietz  <ktietz@redhat.com>
-
-	* src/libffi/src/x86/ffi.c (ffi_call_win32): Add new
-	argument to prototype for specify calling-convention.
-	(ffi_call): Add support for stdcall/thiscall convention.
-	(ffi_prep_args): Likewise.
-	(ffi_raw_call): Likewise.
-	* src/x86/ffitarget.h (ffi_abi): Add FFI_THISCALL and
-	FFI_FASTCALL.
-	* src/x86/win32.S (_ffi_call_win32): Add support for
-	fastcall/thiscall calling-convention calls.
-	* testsuite/libffi.call/fastthis1_win32.c: New test.
-	* testsuite/libffi.call/fastthis2_win32.c: New test.
-	* testsuite/libffi.call/fastthis3_win32.c: New test.
-	* testsuite/libffi.call/strlen2_win32.c: New test.
-	* testsuite/libffi.call/many2_win32.c: New test.
-	* testsuite/libffi.call/struct1_win32.c: New test.
-	* testsuite/libffi.call/struct2_win32.c: New test.
-
-2012-01-23  Uros Bizjak  <ubizjak@gmail.com>
-
-	* src/alpha/ffi.c (ffi_prep_closure_loc): Check for bad ABI.
-
-2012-01-23  Anthony Green  <green@moxielogic.com>
-	    Chris Young  <cdyoung@ntlworld.com>
-
-	* configure.ac: Add Amiga support.
-	* configure: Rebuilt.
-
-2012-01-23  Dmitry Nadezhin  <dmitry.nadezhin@gmail.com>
-
-	* include/ffi_common.h (LIKELY, UNLIKELY): Fix definitions.
-
-2012-01-23  Andreas Schwab  <schwab@linux-m68k.org>
-
-	* src/m68k/sysv.S (ffi_call_SYSV): Properly test for plain
-	mc68000.  Test for __HAVE_68881__ in addition to __MC68881__.
-
-2012-01-19  Jakub Jelinek  <jakub@redhat.com>
-
-	PR rtl-optimization/48496
-	* src/ia64/ffi.c (ffi_call): Fix up aliasing violations.
-
-2012-01-09  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* configure.ac (i?86-*-*): Set TARGET to X86_64.
-	* configure: Regenerate.
-
-2011-12-07  Andrew Pinski  <apinski@cavium.com>
-
-	PR libffi/50051
-	* src/mips/n32.S: Add ".set mips4".
-
-2011-11-21  Andreas Tobler  <andreast@fgznet.ch>
-
-	* configure: Regenerate.
-
-2011-11-12  David Gilbert <david.gilbert@linaro.org>
-
-	* doc/libffi.texi, include/ffi.h.in, include/ffi_common.h,
-	man/Makefile.am, man/ffi.3, man/ffi_prep_cif.3,
-	man/ffi_prep_cif_var.3, src/arm/ffi.c, src/arm/ffitarget.h,
-	src/cris/ffi.c, src/prep_cif.c,
-	testsuite/libffi.call/cls_double_va.c,
-	testsuite/libffi.call/cls_longdouble_va.c,
-	testsuite/libffi.call/float_va.c: Many changes to support variadic
-	function calls.
-
-2011-11-12  Kyle Moffett <Kyle.D.Moffett@boeing.com>
-
-	* src/powerpc/ffi.c, src/powerpc/ffitarget.h,
-	src/powerpc/ppc_closure.S, src/powerpc/sysv.S: Many changes for
-	softfloat powerpc variants.
-
-2011-11-12  Petr Salinger <Petr.Salinger@seznam.cz>
-
-	* configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Fix kfreebsd support.
-	* configure: Rebuilt.
-
-2011-11-12  Timothy Wall  <twall@users.sf.net>
-
-	* src/arm/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): Max
-	alignment of 4 for wince on ARM.
-
-2011-11-12  Kyle Moffett <Kyle.D.Moffett@boeing.com>
-	    Anthony Green <green@moxielogic.com>
-
-	* src/ppc/sysv.S, src/ppc/ffi.c: Remove use of ppc string
-	instructions (not available on some cores, like the PPC440).
-
-2011-11-12  Kimura Wataru  <kimuraw@i.nifty.jp>
-
-	* m4/ax_enable_builddir: Change from string comparison to numeric
-	comparison for wc output.
-	* configure.ac: Enable FFI_MMAP_EXEC_WRIT for darwin11 aka Mac OS
-	X 10.7.
-	* configure: Rebuilt.
-
-2011-11-12  Anthony Green  <green@moxielogic.com>
-
-	* Makefile.am (AM_CCASFLAGS): Add -g option to build assembly
-	files with debug info.
-	* Makefile.in: Rebuilt.
-
-2011-11-12  Jasper Lievisse Adriaanse <jasper@openbsd.org>
-
-	* README: Update list of supported OpenBSD systems.
-
-2011-11-12  Anthony Green  <green@moxielogic.com>
-
-	* libtool-version: Update.
-	* Makefile.am (nodist_libffi_la_SOURCES): Add src/debug.c if
-	FFI_DEBUG.
-	(libffi_la_SOURCES): Remove src/debug.c
-	(EXTRA_DIST): Add src/debug.c
-	* Makefile.in: Rebuilt.
-	* README: Update for 3.0.11.
-
-2011-11-10  Richard Henderson  <rth@redhat.com>
-
-	* configure.ac (GCC_AS_CFI_PSEUDO_OP): Use it instead of inline check.
-	* configure, aclocal.m4: Rebuild.
-
-2011-09-04  Iain Sandoe  <iains@gcc.gnu.org>
-
-	PR libffi/49594
-	* src/powerpc/darwin_closure.S (stubs): Make the stub binding
-	helper reference track the architecture pointer size.
-
-2011-08-25  Andrew Haley  <aph@redhat.com>
-
-	* src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Remove hard-coded assembly
-	instructions.
-	* src/arm/sysv.S (ffi_arm_trampoline): Put them here instead.
-
-2011-07-11  Andrew Haley  <aph@redhat.com>
-
-        * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Clear icache.
-
-2011-06-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* testsuite/libffi.call/cls_double_va.c: Move PR number to comment.
-	* testsuite/libffi.call/cls_longdouble_va.c: Likewise.
-
-2011-06-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	PR libffi/46660
-	* testsuite/libffi.call/cls_double_va.c: xfail dg-output on
-	mips-sgi-irix6*.
-	* testsuite/libffi.call/cls_longdouble_va.c: Likewise.
-
-2011-06-14  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* testsuite/libffi.call/huge_struct.c (test_large_fn): Use PRIu8,
-	PRId8 instead of %hhu, %hhd.
-	* testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRId8,
-	PRIu8): Define.
-	[__sgi__] (PRId8, PRIu8): Define.
-
-2011-04-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* src/alpha/osf.S (UA_SI, FDE_ENCODING, FDE_ENCODE, FDE_ARANGE):
-	Define.
-	Use them to handle ELF vs. ECOFF differences.
-	[__osf__] (_GLOBAL__F_ffi_call_osf): Define.
-
-2011-03-30  Timothy Wall  <twall@users.sf.net>
-
-	* src/powerpc/darwin.S: Fix unknown FDE encoding.
-	* src/powerpc/darwin_closure.S: ditto.
-
-2011-02-25  Anthony Green  <green@moxielogic.com>
-
-	* src/powerpc/ffi.c (ffi_prep_closure_loc): Allow for more
-	32-bit ABIs.
-
-2011-02-15  Anthony Green  <green@moxielogic.com>
-
-	* m4/ax_cc_maxopt.m4: Don't -malign-double or use -ffast-math.
-	* configure: Rebuilt.
-
-2011-02-13  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
-
-	* configure: Regenerate.
-
-2011-02-13  Anthony Green  <green@moxielogic.com>
-
-	* include/ffi_common.h (UNLIKELY, LIKELY): Define.
-	* src/x86/ffi64.c (UNLIKELY, LIKELY): Remove definition.
-	* src/prep_cif.c (UNLIKELY, LIKELY): Remove definition.
-
-	* src/prep_cif.c (initialize_aggregate): Convert assertion into
-	FFI_BAD_TYPEDEF return.  Initialize arg size and alignment to 0.
-
-	* src/pa/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
-	just return FFI_BAD_ABI when things are wrong.
-	* src/arm/ffi.c (ffi_prep_closure_loc): Ditto.
-	* src/powerpc/ffi.c (ffi_prep_closure_loc): Ditto.
-	* src/mips/ffi.c (ffi_prep_closure_loc): Ditto.
-	* src/ia64/ffi.c (ffi_prep_closure_loc): Ditto.
-	* src/avr32/ffi.c (ffi_prep_closure_loc): Ditto.
-
-2011-02-11  Anthony Green  <green@moxielogic.com>
-
-	* src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
-	just return FFI_BAD_ABI when things are wrong.
-
-2012-02-11  Eric Botcazou  <ebotcazou@adacore.com>
-
-	* src/sparc/v9.S (STACKFRAME): Bump to 176.
-
-2011-02-09  Stuart Shelton  <srcshelton@gmail.com>
-
-	http://bugs.gentoo.org/show_bug.cgi?id=286911
-	* src/mips/ffitarget.h: Clean up error messages.
-	* src/java_raw_api.c (ffi_java_translate_args): Cast raw arg to
-	ffi_raw*.
-	* include/ffi.h.in: Add pragma for SGI compiler.
-
-2011-02-09  Anthony Green  <green@moxielogic.com>
-
-	* configure.ac: Add powerpc64-*-darwin* support.
-
-2011-02-09  Anthony Green <green@moxielogic.com>
-
-	* README: Mention Interix.
-
-2011-02-09  Jonathan Callen  <abcd@gentoo.org>
-
-	* configure.ac: Add Interix to win32/cygwin/mingw case.
-	* configure: Ditto.
-	* src/closures.c: Treat Interix like Cygwin, instead of as a
-	generic win32.
-
-2011-02-09  Anthony Green <green@moxielogic.com>
-
-	* testsuite/libffi.call/err_bad_typedef.c: Remove xfail.
-	* testsuite/libffi.call/err_bad_abi.c: Remove xfail.
-	* src/x86/ffi64.c (UNLIKELY, LIKELY): Define.
-	(ffi_prep_closure_loc): Check for bad ABI.
-	* src/prep_cif.c (UNLIKELY, LIKELY): Define.
-	(initialize_aggregate): Check for bad types.
-
-2011-02-09  Landon Fuller <landonf@plausible.coop>
-
-	* Makefile.am (EXTRA_DIST): Add build-ios.sh, src/arm/gentramp.sh,
-	src/arm/trampoline.S.
-	(nodist_libffi_la_SOURCES): Add src/arc/trampoline.S.
-	* configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Define.
-	* src/arm/ffi.c (ffi_trampoline_table)
-	(ffi_closure_trampoline_table_page, ffi_trampoline_table_entry)
-	(FFI_TRAMPOLINE_CODELOC_CONFIG, FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET)
-	(FFI_TRAMPOLINE_COUNT, ffi_trampoline_lock, ffi_trampoline_tables)
-	(ffi_trampoline_table_alloc, ffi_closure_alloc, ffi_closure_free):
-	Define for FFI_EXEC_TRAMPOLINE_TABLE case (iOS).
-	(ffi_prep_closure_loc): Handl FFI_EXEC_TRAMPOLINE_TABLE case
-	separately.
-	* src/arm/sysv.S: Handle Apple iOS host.
-	* src/closures.c: Handle FFI_EXEC_TRAMPOLINE_TABLE case.
-	* build-ios.sh: New file.
-	* fficonfig.h.in, configure, Makefile.in: Rebuilt.
-	* README: Mention ARM iOS.
-
-2011-02-08  Oren Held  <orenhe@il.ibm.com>
-
-	* src/dlmalloc.c (_STRUCT_MALLINFO): Define in order to avoid
-	redefinition of mallinfo on HP-UX.
-
-2011-02-08  Ginn Chen  <ginn.chen@oracle.com>
-
-	* src/sparc/ffi.c (ffi_call): Make compatible with Solaris Studio
-	aggregate return ABI.  Flush cache.
-	(ffi_prep_closure_loc): Flush cache.
-
-2011-02-11  Anthony Green  <green@moxielogic.com>
-
-	From Tom Honermann <tom.honermann@oracle.com>:
-	* src/powerpc/aix.S (ffi_call_AIX): Support for xlc toolchain on
-	AIX.  Declare .ffi_prep_args.  Insert nops after branch
-	instructions so that the AIX linker can insert TOC reload
-	instructions.
-	* src/powerpc/aix_closure.S: Declare .ffi_closure_helper_DARWIN.
-
-2011-02-08  Ed  <ed@kdtc.net>
-
-	* src/powerpc/asm.h: Fix grammar nit in comment.
-
-2011-02-08  Uli Link  <ul.mcamafia@linkitup.de>
-
-	* include/ffi.h.in (FFI_64_BIT_MAX): Define and use.
-
-2011-02-09  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	PR libffi/46661
-	* testsuite/libffi.call/cls_pointer.c (main): Cast void * to
-	uintptr_t first.
-	* testsuite/libffi.call/cls_pointer_stack.c (main): Likewise.
-
-2011-02-08  Rafael Avila de Espindola  <respindola@mozilla.com>
-
-	* configure.ac: Fix x86 test for pc related relocs.
-	* configure: Rebuilt.
-
-2011-02-07  Joel Sherrill <joel.sherrill@oarcorp.com>
-
-	* libffi/src/m68k/ffi.c: Add RTEMS support for cache flushing.
-	Handle case when CPU variant does not have long double support.
-	* libffi/src/m68k/sysv.S: Add support for mc68000, Coldfire,
-	and cores with soft floating point.
-
-2011-02-07  Joel Sherrill <joel.sherrill@oarcorp.com>
-
-	* configure.ac: Add mips*-*-rtems* support.
-	* configure: Regenerate.
-	* src/mips/ffitarget.h: Ensure needed constants are available
-	for targets which do not have sgidefs.h.
-
-2011-01-26  Dave Korn  <dave.korn.cygwin@gmail.com>
-
-	PR target/40125
-	* configure.ac (AM_LTLDFLAGS): Add -bindir option for windows DLLs.
-	* configure: Regenerate.
-
-2010-12-18  Iain Sandoe  <iains@gcc.gnu.org>
-
-	PR libffi/29152
-	PR libffi/42378
-	* src/powerpc/darwin_closure.S: Provide Darwin64 implementation,
-	update comments.
-	* src/powerpc/ffitarget.h (POWERPC_DARWIN64): New,
-	(FFI_TRAMPOLINE_SIZE): Update for Darwin64.
-	* src/powerpc/darwin.S: Provide Darwin64 implementation,
-	update comments.
-	* src/powerpc/ffi_darwin.c: Likewise.
-
-2010-12-06  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* configure.ac (libffi_cv_as_ascii_pseudo_op): Use double
-	backslashes.
-	(libffi_cv_as_string_pseudo_op): Likewise.
-	* configure: Regenerate.
-
-2010-12-03  Chung-Lin Tang  <cltang@codesourcery.com>
-
-	* src/arm/sysv.S (ffi_closure_SYSV): Add UNWIND to .pad directive.
-	(ffi_closure_VFP): Same.
-	(ffi_call_VFP): Move down to before ffi_closure_VFP. Add '.fpu vfp'
-	directive.
-
-2010-12-01  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* testsuite/libffi.call/ffitest.h [__sgi] (PRId64, PRIu64): Define.
-	(PRIuPTR): Define.
-
-2010-11-29  Richard Henderson  <rth@redhat.com>
-	    Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* src/x86/sysv.S (FDE_ENCODING, FDE_ENCODE): Define.
-	(.eh_frame): Use FDE_ENCODING.
-	(.LASFDE1, .LASFDE2, LASFDE3): Simplify with FDE_ENCODE.
-
-2010-11-22  Jacek Caban <jacek@codeweavers.com>
-
-	* configure.ac: Check for symbol underscores on mingw-w64.
-	* configure: Rebuilt.
-	* src/x86/win64.S: Correctly access extern symbols in respect to
-	underscores.
-
-2010-11-15  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* testsuite/lib/libffi-dg.exp: Rename ...
-	* testsuite/lib/libffi.exp: ... to this.
-	* libffi/testsuite/libffi.call/call.exp: Don't load libffi-dg.exp.
-	* libffi/testsuite/libffi.special/special.exp: Likewise.
-
-2010-10-28  Chung-Lin Tang  <cltang@codesourcery.com>
-
-	* src/arm/ffi.c (ffi_prep_args): Add VFP register argument handling
-	code, new parameter, and return value. Update comments.
-	(ffi_prep_cif_machdep): Add case for VFP struct return values. Add
-	call to layout_vfp_args().
-	(ffi_call_SYSV): Update declaration.
-	(ffi_call_VFP): New declaration.
-	(ffi_call): Add VFP struct return conditions. Call ffi_call_VFP()
-	when ABI is FFI_VFP.
-	(ffi_closure_VFP): New declaration.
-	(ffi_closure_SYSV_inner): Add new vfp_args parameter, update call to
-	ffi_prep_incoming_args_SYSV().
-	(ffi_prep_incoming_args_SYSV): Update parameters. Add VFP argument
-	case handling.
-	(ffi_prep_closure_loc): Pass ffi_closure_VFP to trampoline
-	construction under VFP hard-float.
-	(rec_vfp_type_p): New function.
-	(vfp_type_p): Same.
-	(place_vfp_arg): Same.
-	(layout_vfp_args): Same.
-	* src/arm/ffitarget.h (ffi_abi): Add FFI_VFP. Define FFI_DEFAULT_ABI
-	based on __ARM_PCS_VFP.
-	(FFI_EXTRA_CIF_FIELDS): Define for adding VFP hard-float specific
-	fields.
-	(FFI_TYPE_STRUCT_VFP_FLOAT): Define internally used type code.
-	(FFI_TYPE_STRUCT_VFP_DOUBLE): Same.
-	* src/arm/sysv.S (ffi_call_SYSV): Change call of ffi_prep_args() to
-	direct call. Move function pointer load upwards.
-	(ffi_call_VFP): New function.
-	(ffi_closure_VFP): Same.
-
-	* testsuite/lib/libffi-dg.exp (check-flags): New function.
-	(dg-skip-if): New function.
-	* testsuite/libffi.call/cls_double_va.c: Skip if target is arm*-*-*
-	and compiler options include -mfloat-abi=hard.
-	* testsuite/libffi.call/cls_longdouble_va.c: Same.
-
-2010-10-01  Jakub Jelinek  <jakub@redhat.com>
-
-	PR libffi/45677
-	* src/x86/ffi64.c (ffi_prep_cif_machdep): Ensure cif->bytes is
-	a multiple of 8.
-	* testsuite/libffi.call/many2.c: New test.
-
-2010-08-20  Mark Wielaard  <mjw@redhat.com>
-
-	* src/closures.c (open_temp_exec_file_mnt): Check if getmntent_r
-	returns NULL.
-
-2010-08-09  Andreas Tobler  <andreast@fgznet.ch>
-
-	* configure.ac: Add target powerpc64-*-freebsd*.
-	* configure: Regenerate.
-	* testsuite/libffi.call/cls_align_longdouble_split.c: Pass
-	-mlong-double-128 only to linux targets.
-	* testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise.
-	* testsuite/libffi.call/cls_longdouble.c: Likewise.
-	* testsuite/libffi.call/huge_struct.c: Likewise.
-
-2010-08-05  Dan Witte  <dwitte@mozilla.com>
-
-        * Makefile.am: Pass FFI_DEBUG define to msvcc.sh for linking to the
-        debug CRT when --enable-debug is given.
-        * configure.ac: Define it.
-        * msvcc.sh: Translate -g and -DFFI_DEBUG appropriately.
-
-2010-08-04  Dan Witte  <dwitte@mozilla.com>
-
-	* src/x86/ffitarget.h: Add X86_ANY define for all x86/x86_64
-	platforms.
-	* src/x86/ffi.c: Remove redundant ifdef checks.
-	* src/prep_cif.c: Push stack space computation into src/x86/ffi.c
-	for X86_ANY so return value space doesn't get added twice.
-
-2010-08-03  Neil Rashbrooke <neil@parkwaycc.co.uk>
-
-	* msvcc.sh: Don't pass -safeseh to ml64 because behavior is buggy.
-
-2010-07-22  Dan Witte  <dwitte@mozilla.com>
-
-	* src/*/ffitarget.h: Make FFI_LAST_ABI one past the last valid ABI.
-	* src/prep_cif.c: Fix ABI assertion.
-        * src/cris/ffi.c: Ditto.
-
-2010-07-10  Evan Phoenix  <evan@fallingsnow.net>
-
-	* src/closures.c (selinux_enabled_check): Fix strncmp usage bug.
-
-2010-07-07  Dan Horák <dan@danny.cz>
-
-	* include/ffi.h.in: Protect #define with #ifndef.
-	* src/powerpc/ffitarget.h: Ditto.
-	* src/s390/ffitarget.h: Ditto.
-	* src/sparc/ffitarget.h: Ditto.
-
-2010-07-07   Neil Roberts <neil@linux.intel.com>
-
-	* src/x86/sysv.S (ffi_call_SYSV): Align the stack pointer to
-	16-bytes.
-
-2010-07-02  Jakub Jelinek  <jakub@redhat.com>
-
-	* Makefile.am (AM_MAKEFLAGS): Pass also mandir to submakes.
-	* Makefile.in: Regenerated.
-
-2010-05-19  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* configure.ac (libffi_cv_as_x86_pcrel): Check for illegal in as
-	output, too.
-	(libffi_cv_as_ascii_pseudo_op): Check for .ascii.
-	(libffi_cv_as_string_pseudo_op): Check for .string.
-	* configure: Regenerate.
-	* fficonfig.h.in: Regenerate.
-	* src/x86/sysv.S (.eh_frame): Use .ascii, .string or error.
-
-2010-05-11  Dan Witte  <dwitte@mozilla.com>
-
-	* doc/libffi.tex: Document previous change.
-
-2010-05-11  Makoto Kato <m_kato@ga2.so-net.ne.jp>
-
-	* src/x86/ffi.c (ffi_call): Don't copy structs passed by value.
-
-2010-05-05  Michael Kohler <michaelkohler@live.com>
-
-	* src/dlmalloc.c (dlfree): Fix spelling.
-	* src/ia64/ffi.c (ffi_prep_cif_machdep): Ditto.
-	* configure.ac: Ditto.
-	* configure: Rebuilt.
-
-2010-04-13  Dan Witte  <dwitte@mozilla.com>
-
-	* msvcc.sh: Build with -W3 instead of -Wall.
-	* src/powerpc/ffi_darwin.c: Remove build warnings.
-	* src/x86/ffi.c: Ditto.
-	* src/x86/ffitarget.h: Ditto.
-
-2010-04-12  Dan Witte  <dwitte@mozilla.com>
-	    Walter Meinl <wuno@lsvw.de>
-
-	* configure.ac: Add OS/2 support.
-	* configure: Rebuilt.
-	* src/closures.c: Ditto.
-	* src/dlmalloc.c: Ditto.
-	* src/x86/win32.S: Ditto.
-
-2010-04-07  Jakub Jelinek  <jakub@redhat.com>
-
-	* testsuite/libffi.call/err_bad_abi.c: Remove unused args variable.
-
-2010-04-02  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
-
-	* Makefile.in: Regenerate.
-	* aclocal.m4: Regenerate.
-	* include/Makefile.in: Regenerate.
-	* man/Makefile.in: Regenerate.
-	* testsuite/Makefile.in: Regenerate.
-
-2010-03-30  Dan Witte  <dwitte@mozilla.com>
-
-	* msvcc.sh: Disable build warnings.
-	* README (tested): Clarify windows build procedure.
-
-2010-03-15  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* configure.ac (libffi_cv_as_x86_64_unwind_section_type): New test.
-	* configure: Regenerate.
-	* fficonfig.h.in: Regenerate.
-	* libffi/src/x86/unix64.S (.eh_frame)
-	[HAVE_AS_X86_64_UNWIND_SECTION_TYPE]: Use @unwind section type.
-
-2010-03-14  Matthias Klose  <doko@ubuntu.com>
-
-	* src/x86/ffi64.c: Fix typo in comment.
-	* src/x86/ffi.c: Use /* ... */ comment style.
-
-2010-02-24  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* doc/libffi.texi (The Closure API): Fix typo.
-	* doc/libffi.info: Remove.
-
-2010-02-15  Matthias Klose  <doko@ubuntu.com>
-
-	* src/arm/sysv.S (__ARM_ARCH__): Define for processor
-	__ARM_ARCH_7EM__.
-
-2010-01-15  Anthony Green  <green@redhat.com>
-
-	* README: Add notes on building with Microsoft Visual C++.
-
-2010-01-15  Daniel Witte  <dwitte@mozilla.com>
-
-	* msvcc.sh: New file.
-
-	* src/x86/win32.S: Port assembly routines to MSVC and #ifdef.
-	* src/x86/ffi.c: Tweak function declaration and remove excess
-	parens.
-	* include/ffi.h.in: Add __declspec(align(8)) to typedef struct
-	ffi_closure.
-
-	* src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new
-	function ffi_call_win32 on X86_WIN32.
-	* src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32.
-	(ffi_call_STDCALL): Remove.
-
-	* src/prep_cif.c (ffi_prep_cif): Move stack space allocation code
-	to ffi_prep_cif_machdep for x86.
-	* src/x86/ffi.c (ffi_prep_cif_machdep): To here.
-
-2010-01-15  Oliver Kiddle  <okiddle@yahoo.co.uk>
-
-	* src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for
-	Sun Studio compiler compatibility.
-
-2010-01-12  Conrad Irwin <conrad.irwin@gmail.com>
-
-	* doc/libffi.texi: Add closure example.
-
-2010-01-07  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	PR libffi/40701
-	* testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL,
-	PRIuLL, PRId64, PRIu64, PRIuPTR): Define.
-	* testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on
-	alpha*-dec-osf*.
-	* testsuite/libffi.call/cls_align_uint64.c: Likewise.
-	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
-	* testsuite/libffi.call/return_ll1.c: Likewise.
-	* testsuite/libffi.call/stret_medium2.c: Likewise.
-	* testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast
-	MAP_FAILED to char *.
-
-2010-01-06  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	* src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__.
-
-2009-12-31  Anthony Green  <green@redhat.com>
-
-	* README: Update for libffi 3.0.9.
-
-2009-12-27  Matthias Klose  <doko@ubuntu.com>
-
-	* configure.ac (HAVE_LONG_DOUBLE): Define for mips when
-	appropriate.
-	* configure: Rebuilt.
-
-2009-12-26  Anthony Green  <green@redhat.com>
-
-	* testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for
-	avr32*-*-*.
-	* testsuite/libffi.call/cls_double_va.c: Ditto.
-
-2009-12-26  Andreas Tobler  <a.tobler@schweiz.org>
-
-	* testsuite/libffi.call/ffitest.h: Conditionally include stdint.h
-	and inttypes.h.
-	* testsuite/libffi.special/unwindtest.cc: Ditto.
-
-2009-12-26  Andreas Tobler  <a.tobler@schweiz.org>
-
-	* configure.ac: Add amd64-*-openbsd*.
-	* configure: Rebuilt.
-	* testsuite/lib/libffi-dg.exp (libffi_target_compile): Link
-	openbsd programs with -lpthread.
-
-2009-12-26  Anthony Green  <green@redhat.com>
-
-	* testsuite/libffi.call/cls_double_va.c,
-	testsuite/libffi.call/cls_longdouble.c,
-	testsuite/libffi.call/cls_longdouble_va.c,
-	testsuite/libffi.call/cls_pointer.c,
-	testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for
-	mips*-*-* and arm*-*-*.
-	* testsuite/libffi.call/cls_align_longdouble_split.c,
-	testsuite/libffi.call/cls_align_longdouble_split2.c,
-	testsuite/libffi.call/stret_medium2.c,
-	testsuite/libffi.call/stret_medium.c,
-	testsuite/libffi.call/stret_large.c,
-	testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*.
-
-2009-12-31  Kay Tietz  <ktietz70@googlemail.com>
-
-	* testsuite/libffi.call/ffitest.h,
-	testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix
-	definitions.
-
-2009-12-31  Carlo Bramini  <carlo.bramix@libero.it>
-
-	* configure.ac (AM_LTLDFLAGS): Define for windows hosts.
-	* Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS.
-	* configure: Rebuilt.
-	* Makefile.in: Rebuilt.
-
-2009-12-31  Anthony Green  <green@redhat.com>
-	    Blake Chaffin.
-
-	* testsuite/libffi.call/huge_struct.c: New test case from Blake
-	Chaffin @ Apple.
-
-2009-12-28  David Edelsohn  <edelsohn@gnu.org>
-
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to
-	local variables.
-	(aix_adjust_aggregate_sizes): New function.
-	(ffi_prep_cif_machdep): Call it.
-
-2009-12-26  Andreas Tobler  <a.tobler@schweiz.org>
-
-	* configure.ac: Define FFI_MMAP_EXEC_WRIT for the given targets.
-	* configure: Regenerate.
-	* fficonfig.h.in: Likewise.
-	* src/closures.c: Remove the FFI_MMAP_EXEC_WRIT definition for
-	Solaris/x86.
-
-2009-12-26  Andreas Schwab  <schwab@linux-m68k.org>
-
-	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Advance intarg_count
-	when a float arguments is passed in memory.
-	(ffi_closure_helper_SYSV): Mark general registers as used up when
-	a 64bit or soft-float long double argument is passed in memory.
-
-2009-12-25  Matthias Klose  <doko@ubuntu.com>
-
-	* man/ffi_call.3: Fix #include in examples.
-	* doc/libffi.texi: Add dircategory.
-
-2009-12-25  Frank Everdij <f.p.x.everdij@tudelft.nl>
-
-	* include/ffi.h.in: Placed '__GNUC__' ifdef around
-	'__attribute__((aligned(8)))' in ffi_closure, fixes compile for
-	IRIX MIPSPro c99.
-	* include/ffi_common.h: Added '__sgi' define to non
-	'__attribute__((__mode__()))' integer typedefs.
-	* src/mips/ffi.c (ffi_call, ffi_closure_mips_inner_O32,
-	ffi_closure_mips_inner_N32): Added 'defined(_MIPSEB)' to BE check.
-	(ffi_closure_mips_inner_O32, ffi_closure_mips_inner_N32): Added
-	FFI_LONGDOUBLE support and alignment(N32 only).
-	* src/mips/ffitarget.h: Corrected '#include <sgidefs.h>' for IRIX and
-	fixed non '__attribute__((__mode__()))' integer typedefs.
-	* src/mips/n32.S: Put '#ifdef linux' around '.abicalls' and '.eh_frame'
-	since they are Linux/GNU Assembler specific.
-
-2009-12-25  Bradley Smith  <brad@brad-smith.co.uk>
-
-	* configure.ac, Makefile.am, src/avr32/ffi.c,
-	src/avr32/ffitarget.h,
-	src/avr32/sysv.S: Add AVR32 port.
-	* configure, Makefile.in: Rebuilt.
-
-2009-12-21  Andreas Tobler  <a.tobler@schweiz.org>
-
-	* configure.ac: Make i?86 build on FreeBSD and OpenBSD.
-	* configure: Regenerate.
-
-2009-12-15  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
-
-	* testsuite/libffi.call/ffitest.h: Define PRIuPTR on PA HP-UX.
-
-2009-12-13  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
-
-	* src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE
-	type on HP-UX.
-
-2012-02-13  Kai Tietz  <ktietz@redhat.com>
-
-	PR libffi/52221
-	* src/x86/ffi.c (ffi_prep_raw_closure_loc): Add thiscall
-	support for X86_WIN32.
-	(FFI_INIT_TRAMPOLINE_THISCALL): Fix displacement.
-
-2009-12-11  Eric Botcazou  <ebotcazou@adacore.com>
-
-	* src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long
-	double' arguments.
-
-2009-12-11  Eric Botcazou  <ebotcazou@adacore.com>
-
-	* testsuite/libffi.call/ffitest.h: Define PRIuPTR on Solaris < 10.
-
-2009-12-10  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-	PR libffi/40700
-	* src/closures.c [X86_64 && __sun__ && __svr4__]
-	(FFI_MMAP_EXEC_WRIT): Define.
-
-2009-12-08  David Daney  <ddaney@caviumnetworks.com>
-
-	* testsuite/libffi.call/stret_medium.c: Remove xfail for mips*-*-*
-	* testsuite/libffi.call/cls_align_longdouble_split2.c: Same.
-	* testsuite/libffi.call/stret_large.c: Same.
-	* testsuite/libffi.call/cls_align_longdouble_split.c: Same.
-	* testsuite/libffi.call/stret_large2.c: Same.
-	* testsuite/libffi.call/stret_medium2.c: Same.
-
-2009-12-07  David Edelsohn  <edelsohn@gnu.org>
-
-	* src/powerpc/aix_closure.S (libffi_closure_ASM): Fix tablejump
-	typo.
-
-2009-12-05  David Edelsohn  <edelsohn@gnu.org>
-
-	* src/powerpc/aix.S: Update AIX32 code to be consistent with AIX64
-	code.
-	* src/powerpc/aix_closure.S: Same.
-
-2009-12-05  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
-
-	* Makefile.in: Regenerate.
-	* configure: Regenerate.
-	* include/Makefile.in: Regenerate.
-	* man/Makefile.in: Regenerate.
-	* testsuite/Makefile.in: Regenerate.
-
-2009-12-04  David Edelsohn  <edelsohn@gnu.org>
-
-	* src/powerpc/aix_closure.S: Reorganize 64-bit code to match
-	linux64_closure.S.
-
-2009-12-04  Uros Bizjak  <ubizjak@gmail.com>
-
-	PR libffi/41908
-	* src/x86/ffi64.c (classify_argument): Update from
-	gcc/config/i386/i386.c.
-	(ffi_closure_unix64_inner): Do not use the address of two consecutive
-	SSE registers directly.
-	* testsuite/libffi.call/cls_dbls_struct.c (main): Remove xfail
-	for x86_64 linux targets.
-
-2009-12-04  David Edelsohn  <edelsohn@gnu.org>
-
-	* src/powerpc/ffi_darwin.c (ffi_closure_helper_DARWIN): Increment
-	pfr for long double split between fpr13 and stack.
-
-2009-12-03  David Edelsohn  <edelsohn@gnu.org>
-
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Increment next_arg and
-	fparg_count twice for long double.
-
-2009-12-03  David Edelsohn  <edelsohn@gnu.org>
-
-	PR libffi/42243
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Remove extra parentheses.
-
-2009-12-03  Uros Bizjak  <ubizjak@gmail.com>
-
-	* testsuite/libffi.call/cls_longdouble_va.c (main): Fix format string.
-	Remove xfails for x86 linux targets.
-
-2009-12-02  David Edelsohn  <edelsohn@gnu.org>
-
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Fix typo in INT64
-	case.
-
-2009-12-01  David Edelsohn  <edelsohn@gnu.org>
-
-	* src/powerpc/aix.S (ffi_call_AIX): Convert to more standard
-	register usage.  Call ffi_prep_args directly.  Add long double
-	return value support.
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment
-	applies to FFI_TYPE_DOUBLE.  Correct fpr_base increment typo.
-	Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases.
-	(ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit
-	mode.
-	(ffi_closure_helper_DARWIN): Remove nf and ng counters.  Move temp
-	into case.
-	* src/powerpc/aix_closure.S: Maintain 16 byte stack alignment.
-	Allocate result area between params and FPRs.
-
-2009-11-30  David Edelsohn  <edelsohn@gnu.org>
-
-	PR target/35484
-	* src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and
-	AIX64.
-	* src/powerpc/aix.S: Implement AIX64 version.
-	* src/powerpc/aix_closure.S: Implement AIX64 version.
-	(ffi_closure_ASM): Use extsb, lha and displament addresses.
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64
-	support.
-	(ffi_prep_cif_machdep): Same.
-	(ffi_call): Same.
-	(ffi_closure_helper_DARWIN): Same.
-
-2009-11-02  Andreas Tobler  <a.tobler@schweiz.org>
-
-	PR libffi/41908
-	* testsuite/libffi.call/testclosure.c: New test.
-
-2009-09-28  Kai Tietz  <kai.tietz@onevision.com>
-
-	* src/x86/win64.S (_ffi_call_win64 stack): Remove for gnu
-	assembly version use of ___chkstk.
-
-2009-09-23  Matthias Klose  <doko@ubuntu.com>
-
-	PR libffi/40242, PR libffi/41443
-	* src/arm/sysv.S (__ARM_ARCH__): Define for processors
-	__ARM_ARCH_6T2__, __ARM_ARCH_6M__, __ARM_ARCH_7__,
-	__ARM_ARCH_7A__, __ARM_ARCH_7R__, __ARM_ARCH_7M__.
-	Change the conditionals to __SOFTFP__ || __ARM_EABI__
-	for -mfloat-abi=softfp to work.
-
-2009-09-17  Loren J. Rittle  <ljrittle@acm.org>
-
-	PR testsuite/32843 (strikes again)
-	* src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to
-	enable proper extension on char and short.
-
-2009-09-15  David Daney  <ddaney@caviumnetworks.com>
-
-	* src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special
-	handling for FFI_TYPE_POINTER.
-	* src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT,
-	FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT,
-	FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT,
-	FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines.
-	(FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations.
-	(enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float.
-	* src/mips/n32.S (ffi_call_N32): Add handling for soft-float
-	structure and pointer returns.
-	(ffi_closure_N32): Add handling for pointer returns.
-	* src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags,
-	calc_n32_return_struct_flags): Handle soft-float.
-	(ffi_prep_cif_machdep):  Handle soft-float, fix pointer handling.
-	(ffi_call_N32): Declare proper argument types.
-	(ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle
-	soft-float.
-
-2009-08-24  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
-
-	* configure.ac (AC_PREREQ): Bump to 2.64.
-
-2009-08-22  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
-
-	* Makefile.am (install-html, install-pdf): Remove.
-	* Makefile.in: Regenerate.
-
-	* Makefile.in: Regenerate.
-	* aclocal.m4: Regenerate.
-	* configure: Regenerate.
-	* fficonfig.h.in: Regenerate.
-	* include/Makefile.in: Regenerate.
-	* man/Makefile.in: Regenerate.
-	* testsuite/Makefile.in: Regenerate.
-
-2011-08-22  Jasper Lievisse Adriaanse <jasper@openbsd.org>
-
-	* configure.ac: Add OpenBSD/hppa and OpenBSD/powerpc support.
-	* configure: Rebuilt.
-
-2009-07-30  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
-
-	* configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force.
-
-2009-07-24  Dave Korn  <dave.korn.cygwin@gmail.com>
-
-	PR libffi/40807
-	* src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending
-	return types for X86_WIN32.
-	* src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types.
-	(_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV,
-	_ffi_closure_STDCALL): Likewise.
-
-	* src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin.
-	(dlmmap, dlmunmap): Also use these functions on Cygwin.
-
-2009-07-11  Richard Sandiford  <rdsandiford@googlemail.com>
-
-	PR testsuite/40699
-	PR testsuite/40707
-	PR testsuite/40709
-	* testsuite/lib/libffi-dg.exp: Revert 2009-07-02, 2009-07-01 and
-	2009-06-30 commits.
-
-2009-07-01  Richard Sandiford  <r.sandiford@uk.ibm.com>
-
-	* testsuite/lib/libffi-dg.exp (libffi-init): Set ld_library_path
-	to "" before adding paths.  (This reinstates an assignment that
-	was removed by my 2009-06-30 commit, but changes the initial
-	value from "." to "".)
-
-2009-07-01  H.J. Lu  <hongjiu.lu@intel.com>
-
-	PR testsuite/40601
-	* testsuite/lib/libffi-dg.exp (libffi-init): Properly set
-	gccdir.  Adjust ld_library_path for gcc only if gccdir isn't
-	empty.
-
-2009-06-30  Richard Sandiford  <r.sandiford@uk.ibm.com>
-
-	* testsuite/lib/libffi-dg.exp (libffi-init): Don't add "."
-	to ld_library_path.  Use add_path.  Add just find_libgcc_s
-	to ld_library_path, not every libgcc multilib directory.
-
-2009-06-16  Wim Lewis  <wiml@hhhh.org>
-
-	* src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are
-	supposed to be callee-saved.
-	* src/powerpc/sysv.S (small_struct_return_value): Fix overrun of
-	return buffer for odd-size structs.
-
-2009-06-16  Andreas Tobler  <a.tobler@schweiz.org>
-
-	PR libffi/40444
-	* testsuite/lib/libffi-dg.exp (libffi_target_compile): Add
-	allow_stack_execute for Darwin.
-
-2009-06-16  Andrew Haley  <aph@redhat.com>
-
-	* configure.ac (TARGETDIR): Add missing blank lines.
-	* configure: Regenerate.
-
-2009-06-16  Andrew Haley  <aph@redhat.com>
-
-	* testsuite/libffi.call/cls_align_sint64.c,
-	testsuite/libffi.call/cls_align_uint64.c,
-	testsuite/libffi.call/cls_longdouble_va.c,
-	testsuite/libffi.call/cls_ulonglong.c,
-	testsuite/libffi.call/return_ll1.c,
-	testsuite/libffi.call/stret_medium2.c: Fix printf format
-	specifiers.
-	* testsuite/libffi.call/ffitest.h,
-	testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define.
-
-2009-06-15  Andrew Haley  <aph@redhat.com>
-
-	* testsuite/libffi.call/err_bad_typedef.c: xfail everywhere.
-	* testsuite/libffi.call/err_bad_abi.c: Likewise.
-
-2009-06-12  Andrew Haley  <aph@redhat.com>
-
-	* Makefile.am: Remove info_TEXINFOS.
-
-2009-06-12  Andrew Haley  <aph@redhat.com>
-
-	* ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c,
-	testsuite/libffi.call/cls_align_uint64.c,
-	testsuite/libffi.call/cls_ulonglong.c,
-	testsuite/libffi.call/return_ll1.c,
-	testsuite/libffi.call/stret_medium2.c: Fix printf format
-	specifiers.
-	testsuite/libffi.special/unwindtest.cc: include stdint.h.
-
-2009-06-11  Timothy Wall  <twall@users.sf.net>
-
-	* Makefile.am,
-	configure.ac,
-	include/ffi.h.in,
-	include/ffi_common.h,
-	src/closures.c,
-	src/dlmalloc.c,
-	src/x86/ffi.c,
-	src/x86/ffitarget.h,
-	src/x86/win64.S (new),
-	README: Added win64 support (mingw or MSVC)
-	* Makefile.in,
-	include/Makefile.in,
-	man/Makefile.in,
-	testsuite/Makefile.in,
-	configure,
-	aclocal.m4: Regenerated
-	* ltcf-c.sh: properly escape cygwin/w32 path
-	* man/ffi_call.3: Clarify size requirements for return value.
-	* src/x86/ffi64.c: Fix filename in comment.
-	* src/x86/win32.S: Remove unused extern.
-
-	* testsuite/libffi.call/closure_fn0.c,
-	testsuite/libffi.call/closure_fn1.c,
-	testsuite/libffi.call/closure_fn2.c,
-	testsuite/libffi.call/closure_fn3.c,
-	testsuite/libffi.call/closure_fn4.c,
-	testsuite/libffi.call/closure_fn5.c,
-	testsuite/libffi.call/closure_fn6.c,
-	testsuite/libffi.call/closure_stdcall.c,
-	testsuite/libffi.call/cls_12byte.c,
-	testsuite/libffi.call/cls_16byte.c,
-	testsuite/libffi.call/cls_18byte.c,
-	testsuite/libffi.call/cls_19byte.c,
-	testsuite/libffi.call/cls_1_1byte.c,
-	testsuite/libffi.call/cls_20byte.c,
-	testsuite/libffi.call/cls_20byte1.c,
-	testsuite/libffi.call/cls_24byte.c,
-	testsuite/libffi.call/cls_2byte.c,
-	testsuite/libffi.call/cls_3_1byte.c,
-	testsuite/libffi.call/cls_3byte1.c,
- 	testsuite/libffi.call/cls_3byte2.c,
- 	testsuite/libffi.call/cls_4_1byte.c,
- 	testsuite/libffi.call/cls_4byte.c,
- 	testsuite/libffi.call/cls_5_1_byte.c,
- 	testsuite/libffi.call/cls_5byte.c,
- 	testsuite/libffi.call/cls_64byte.c,
- 	testsuite/libffi.call/cls_6_1_byte.c,
- 	testsuite/libffi.call/cls_6byte.c,
- 	testsuite/libffi.call/cls_7_1_byte.c,
- 	testsuite/libffi.call/cls_7byte.c,
- 	testsuite/libffi.call/cls_8byte.c,
- 	testsuite/libffi.call/cls_9byte1.c,
- 	testsuite/libffi.call/cls_9byte2.c,
- 	testsuite/libffi.call/cls_align_double.c,
- 	testsuite/libffi.call/cls_align_float.c,
- 	testsuite/libffi.call/cls_align_longdouble.c,
- 	testsuite/libffi.call/cls_align_longdouble_split.c,
- 	testsuite/libffi.call/cls_align_longdouble_split2.c,
- 	testsuite/libffi.call/cls_align_pointer.c,
- 	testsuite/libffi.call/cls_align_sint16.c,
- 	testsuite/libffi.call/cls_align_sint32.c,
- 	testsuite/libffi.call/cls_align_sint64.c,
- 	testsuite/libffi.call/cls_align_uint16.c,
- 	testsuite/libffi.call/cls_align_uint32.c,
- 	testsuite/libffi.call/cls_align_uint64.c,
- 	testsuite/libffi.call/cls_dbls_struct.c,
- 	testsuite/libffi.call/cls_double.c,
- 	testsuite/libffi.call/cls_double_va.c,
- 	testsuite/libffi.call/cls_float.c,
- 	testsuite/libffi.call/cls_longdouble.c,
- 	testsuite/libffi.call/cls_longdouble_va.c,
- 	testsuite/libffi.call/cls_multi_schar.c,
- 	testsuite/libffi.call/cls_multi_sshort.c,
- 	testsuite/libffi.call/cls_multi_sshortchar.c,
- 	testsuite/libffi.call/cls_multi_uchar.c,
- 	testsuite/libffi.call/cls_multi_ushort.c,
- 	testsuite/libffi.call/cls_multi_ushortchar.c,
- 	testsuite/libffi.call/cls_pointer.c,
- 	testsuite/libffi.call/cls_pointer_stack.c,
- 	testsuite/libffi.call/cls_schar.c,
- 	testsuite/libffi.call/cls_sint.c,
- 	testsuite/libffi.call/cls_sshort.c,
- 	testsuite/libffi.call/cls_uchar.c,
- 	testsuite/libffi.call/cls_uint.c,
- 	testsuite/libffi.call/cls_ulonglong.c,
- 	testsuite/libffi.call/cls_ushort.c,
- 	testsuite/libffi.call/err_bad_abi.c,
- 	testsuite/libffi.call/err_bad_typedef.c,
- 	testsuite/libffi.call/float2.c,
- 	testsuite/libffi.call/huge_struct.c,
- 	testsuite/libffi.call/nested_struct.c,
- 	testsuite/libffi.call/nested_struct1.c,
- 	testsuite/libffi.call/nested_struct10.c,
- 	testsuite/libffi.call/nested_struct2.c,
- 	testsuite/libffi.call/nested_struct3.c,
- 	testsuite/libffi.call/nested_struct4.c,
- 	testsuite/libffi.call/nested_struct5.c,
- 	testsuite/libffi.call/nested_struct6.c,
- 	testsuite/libffi.call/nested_struct7.c,
- 	testsuite/libffi.call/nested_struct8.c,
- 	testsuite/libffi.call/nested_struct9.c,
- 	testsuite/libffi.call/problem1.c,
- 	testsuite/libffi.call/return_ldl.c,
- 	testsuite/libffi.call/return_ll1.c,
- 	testsuite/libffi.call/stret_large.c,
- 	testsuite/libffi.call/stret_large2.c,
- 	testsuite/libffi.call/stret_medium.c,
- 	testsuite/libffi.call/stret_medium2.c,
-	testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead
-	of checking for MMAP.  Use intptr_t instead of long casts.
-
-2009-06-11  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*.
-	* testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*.
-	* testsuite/libffi.call/err_bad_typedef.c: Likewise.
-
-2009-06-09  Andrew Haley  <aph@redhat.com>
-
-	* src/x86/freebsd.S: Add missing file.
-
-2009-06-08  Andrew Haley  <aph@redhat.com>
-
-	Import from libffi 3.0.8:
-
-	* doc/libffi.texi: New file.
-	* doc/libffi.info: Likewise.
-	* doc/stamp-vti: Likewise.
-	* man/Makefile.am: New file.
-	* man/ffi_call.3: New file.
-
-	* Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S,
-	src/dlmalloc.c.
-	(nodist_libffi_la_SOURCES): Add X86_FREEBSD.
-
-	* configure.ac: Bump version to 3.0.8.
-	parisc*-*-linux*: Add.
-	i386-*-freebsd* | i386-*-openbsd*: Add.
-	powerpc-*-beos*: Add.
-	AM_CONDITIONAL X86_FREEBSD: Add.
-	AC_CONFIG_FILES: Add man/Makefile.
-
-	* include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void).
-
-2009-06-08  Andrew Haley  <aph@redhat.com>
-
-	* README: Import from libffi 3.0.8.
-
-2009-06-08  Andrew Haley  <aph@redhat.com>
-
-	* testsuite/libffi.call/err_bad_abi.c: Add xfails.
-	* testsuite/libffi.call/cls_longdouble_va.c: Add xfails.
-	* testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*.
-	* testsuite/libffi.call/err_bad_typedef.c: Add xfails.
-
-	* testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args.
-	* testsuite/libffi.call/stret_medium.c: Likewise.
-	* testsuite/libffi.call/stret_large2.c: Likewise.
-	* testsuite/libffi.call/stret_large.c:  Likewise.
-
-2008-12-26  Timothy Wall  <twall@users.sf.net>
-
-	* testsuite/libffi.call/cls_longdouble.c,
-	testsuite/libffi.call/cls_longdouble_va.c,
-	testsuite/libffi.call/cls_align_longdouble.c,
-	testsuite/libffi.call/cls_align_longdouble_split.c,
-	testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected
-	failures on x86_64 cygwin/mingw.
-
-2008-12-22  Timothy Wall  <twall@users.sf.net>
-
-	* testsuite/libffi.call/closure_fn0.c,
-	testsuite/libffi.call/closure_fn1.c,
-	testsuite/libffi.call/closure_fn2.c,
-	testsuite/libffi.call/closure_fn3.c,
-	testsuite/libffi.call/closure_fn4.c,
-	testsuite/libffi.call/closure_fn5.c,
-	testsuite/libffi.call/closure_fn6.c,
-	testsuite/libffi.call/closure_loc_fn0.c,
-	testsuite/libffi.call/closure_stdcall.c,
-	testsuite/libffi.call/cls_align_pointer.c,
-	testsuite/libffi.call/cls_pointer.c,
-	testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
-	pointer to integer (intptr_t).
-	* testsuite/libffi.call/cls_longdouble.c: disable for win64.
-
-2008-07-24  Anthony Green  <green@redhat.com>
-
-	* testsuite/libffi.call/cls_dbls_struct.c,
-	testsuite/libffi.call/cls_double_va.c,
-	testsuite/libffi.call/cls_longdouble.c,
-	testsuite/libffi.call/cls_longdouble_va.c,
-	testsuite/libffi.call/cls_pointer.c,
-	testsuite/libffi.call/cls_pointer_stack.c,
-	testsuite/libffi.call/err_bad_abi.c: Clean up failures from
-	compiler warnings.
-
-2008-03-04  Anthony Green  <green@redhat.com>
-	    Blake Chaffin
-	    hos@tamanegi.org
-
-	* testsuite/libffi.call/cls_align_longdouble_split2.c
-	  testsuite/libffi.call/cls_align_longdouble_split.c
-	  testsuite/libffi.call/cls_dbls_struct.c
-	  testsuite/libffi.call/cls_double_va.c
-	  testsuite/libffi.call/cls_longdouble.c
-	  testsuite/libffi.call/cls_longdouble_va.c
-	  testsuite/libffi.call/cls_pointer.c
-	  testsuite/libffi.call/cls_pointer_stack.c
-	  testsuite/libffi.call/err_bad_abi.c
-	  testsuite/libffi.call/err_bad_typedef.c
-	  testsuite/libffi.call/stret_large2.c
-	  testsuite/libffi.call/stret_large.c
-	  testsuite/libffi.call/stret_medium2.c
-	  testsuite/libffi.call/stret_medium.c: New tests from Apple.
-
-2009-06-05  Andrew Haley  <aph@redhat.com>
-
-	* src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from
-	libffi.
-
-2009-06-04  Andrew Haley  <aph@redhat.com>
-
-	* src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out
-	stdcall changes.
-
-2008-02-26  Anthony Green  <green@redhat.com>
-	    Thomas Heller  <theller@ctypes.org>
-
-	* src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C
-	comment.
-
-2008-02-03  Timothy Wall  <twall@users.sf.net>
-
-	* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return
-	  offset based on code pointer, not data pointer.
-
-2008-01-31  Timothy Wall <twall@users.sf.net>
-
-	* testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
-	closures.
-	* src/x86/ffitarget.h: Increase size of trampoline for stdcall
-	closures.
-	* src/x86/win32.S: Add assembly for stdcall closure.
-	* src/x86/ffi.c: Initialize stdcall closure trampoline.
-
-2009-06-04  Andrew Haley  <aph@redhat.com>
-
-	* include/ffi.h.in: Change void (*)() to void (*)(void).
-	* src/x86/ffi.c: Likewise.
-
-2009-06-04  Andrew Haley  <aph@redhat.com>
-
-	* src/powerpc/ppc_closure.S: Insert licence header.
-	* src/powerpc/linux64_closure.S: Likewise.
-	* src/m68k/sysv.S: Likewise.
-
-	* src/sh64/ffi.c: Change void (*)() to void (*)(void).
-	* src/powerpc/ffi.c: Likewise.
-	* src/powerpc/ffi_darwin.c: Likewise.
-	* src/m32r/ffi.c: Likewise.
-	* src/sh64/ffi.c: Likewise.
-	* src/x86/ffi64.c: Likewise.
-	* src/alpha/ffi.c: Likewise.
-	* src/alpha/osf.S: Likewise.
-	* src/frv/ffi.c: Likewise.
-	* src/s390/ffi.c: Likewise.
-	* src/pa/ffi.c: Likewise.
-	* src/pa/hpux32.S: Likewise.
-	* src/ia64/unix.S: Likewise.
-	* src/ia64/ffi.c: Likewise.
-	* src/sparc/ffi.c: Likewise.
-	* src/mips/ffi.c: Likewise.
-	* src/sh/ffi.c: Likewise.
-
-2008-02-15  David Daney  <ddaney@avtrex.com>
-
-	* src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE):
-	Define (conditionally), and use it to include cachectl.h.
-	(ffi_prep_closure_loc): Fix cache flushing.
-	* src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define.
-
-2009-06-04  Andrew Haley  <aph@redhat.com>
-
-	include/ffi.h.in,
-	src/arm/ffitarget.h,
-	src/arm/ffi.c,
-	src/arm/sysv.S,
-	src/powerpc/ffitarget.h,
-	src/closures.c,
-	src/sh64/ffitarget.h,
-	src/sh64/ffi.c,
-	src/sh64/sysv.S,
-	src/types.c,
-	src/x86/ffi64.c,
-	src/x86/ffitarget.h,
-	src/x86/win32.S,
-	src/x86/darwin.S,
-	src/x86/ffi.c,
-	src/x86/sysv.S,
-	src/x86/unix64.S,
-	src/alpha/ffitarget.h,
-	src/alpha/ffi.c,
-	src/alpha/osf.S,
-	src/m68k/ffitarget.h,
-	src/frv/ffitarget.h,
-	src/frv/ffi.c,
-	src/s390/ffitarget.h,
-	src/s390/sysv.S,
-	src/cris/ffitarget.h,
-	src/pa/linux.S,
-	src/pa/ffitarget.h,
-	src/pa/ffi.c,
-	src/raw_api.c,
-	src/ia64/ffitarget.h,
-	src/ia64/unix.S,
-	src/ia64/ffi.c,
-	src/ia64/ia64_flags.h,
-	src/java_raw_api.c,
-	src/debug.c,
-	src/sparc/v9.S,
-	src/sparc/ffitarget.h,
-	src/sparc/ffi.c,
-	src/sparc/v8.S,
-	src/mips/ffitarget.h,
-	src/mips/n32.S,
-	src/mips/o32.S,
-	src/mips/ffi.c,
-	src/prep_cif.c,
-	src/sh/ffitarget.h,
-	src/sh/ffi.c,
-	src/sh/sysv.S: Update license text.
-
-2009-05-22  Dave Korn  <dave.korn.cygwin@gmail.com>
-
-	* src/x86/win32.S (_ffi_closure_STDCALL):  New function.
-	(.eh_frame):  Add FDE for it.
-
-2009-05-22  Dave Korn  <dave.korn.cygwin@gmail.com>
-
-	* configure.ac:  Also check if assembler supports pc-relative
-	relocs on X86_WIN32 targets.
-	* configure:  Regenerate.
-	* src/x86/win32.S (ffi_prep_args):  Declare extern, not global.
-	(_ffi_call_SYSV):  Add missing function type symbol .def and
-	add EH markup labels.
-	(_ffi_call_STDCALL):  Likewise.
-	(_ffi_closure_SYSV):  Likewise.
-	(_ffi_closure_raw_SYSV):  Likewise.
-	(.eh_frame):  Add hand-crafted EH data.
-
-2009-04-09  Jakub Jelinek  <jakub@redhat.com>
-
-	* testsuite/lib/libffi-dg.exp: Change copyright header to refer to
-	version 3 of the GNU General Public License and to point readers
-	at the COPYING3 file and the FSF's license web page.
-	* testsuite/libffi.call/call.exp: Likewise.
-	* testsuite/libffi.special/special.exp: Likewise.
-
-2009-03-01  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
-
-	* configure: Regenerate.
-
-2008-12-18  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	PR libffi/26048
-	* configure.ac (HAVE_AS_X86_PCREL): New test.
-	* configure: Regenerate.
-	* fficonfig.h.in: Regenerate.
-	* src/x86/sysv.S [!FFI_NO_RAW_API]: Precalculate
-	RAW_CLOSURE_CIF_OFFSET, RAW_CLOSURE_FUN_OFFSET,
-	RAW_CLOSURE_USER_DATA_OFFSET for the Solaris 10/x86 assembler.
-	(.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL.
-	* src/x86/unix64.S (.Lstore_table): Move to .text section.
-	(.Lload_table): Likewise.
-	(.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL.
-
-2008-12-18  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
-
-	* configure: Regenerate.
-
-2008-11-21  Eric Botcazou  <ebotcazou@adacore.com>
-
-	* src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for
-	signed/unsigned int8/16 return values.
-	* src/sparc/v8.S (ffi_call_v8): Likewise.
-	(ffi_closure_v8): Likewise.
-
-2008-09-26  Peter O'Gorman  <pogma@thewrittenword.com>
-	    Steve Ellcey  <sje@cup.hp.com>
-
-	* configure: Regenerate for new libtool.
-	* Makefile.in: Ditto.
-	* include/Makefile.in: Ditto.
-	* aclocal.m4: Ditto.
-
-2008-08-25  Andreas Tobler  <a.tobler@schweiz.org>
-
-	* src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and
-	FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum.
-	Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT.
-	Adjust copyright notice.
-	* src/powerpc/ffi.c: Add two new flags to indicate if we have one
-	register or two register to use for FFI_SYSV structs.
-	(ffi_prep_cif_machdep): Pass the right register flag introduced above.
-	(ffi_closure_helper_SYSV): Fix the return type for
-	FFI_SYSV_TYPE_SMALL_STRUCT. Comment.
-	Adjust copyright notice.
-
-2008-07-16  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned
-	int.
-
-2008-06-17  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
-
-	* configure: Regenerate.
-	* include/Makefile.in: Regenerate.
-	* testsuite/Makefile.in: Regenerate.
-
-2008-06-07  Joseph Myers  <joseph@codesourcery.com>
-
-	* configure.ac (parisc*-*-linux*, powerpc-*-sysv*,
-	powerpc-*-beos*): Remove.
-	* configure: Regenerate.
-
-2008-05-09  Julian Brown  <julian@codesourcery.com>
-
-	* Makefile.am (LTLDFLAGS): New.
-	(libffi_la_LDFLAGS): Use above.
-	* Makefile.in: Regenerate.
-
-2008-04-18  Paolo Bonzini  <bonzini@gnu.org>
-
-	PR bootstrap/35457
-	* aclocal.m4: Regenerate.
-	* configure: Regenerate.
-
-2008-03-26  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/sysv.S: Add .note.GNU-stack on Linux.
-	* src/sh64/sysv.S: Likewise.
-
-2008-03-26  Daniel Jacobowitz  <dan@debian.org>
-
-	* src/arm/sysv.S: Fix ARM comment marker.
-
-2008-03-26  Jakub Jelinek  <jakub@redhat.com>
-
-	* src/alpha/osf.S: Add .note.GNU-stack on Linux.
-	* src/s390/sysv.S: Likewise.
-	* src/powerpc/ppc_closure.S: Likewise.
-	* src/powerpc/sysv.S: Likewise.
-	* src/x86/unix64.S: Likewise.
-	* src/x86/sysv.S: Likewise.
-	* src/sparc/v8.S: Likewise.
-	* src/sparc/v9.S: Likewise.
-	* src/m68k/sysv.S: Likewise.
-	* src/arm/sysv.S: Likewise.
-
-2008-03-16  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
-
-	* aclocal.m4: Regenerate.
-	* configure: Likewise.
-	* Makefile.in: Likewise.
-	* include/Makefile.in: Likewise.
-	* testsuite/Makefile.in: Likewise.
-
-2008-02-12  Bjoern Koenig  <bkoenig@alpha-tierchen.de>
-	    Andreas Tobler  <a.tobler@schweiz.org>
-
-	* configure.ac: Add amd64-*-freebsd* target.
-	* configure: Regenerate.
-
-2008-01-30  H.J. Lu  <hongjiu.lu@intel.com>
-
-	PR libffi/34612
-	* src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when
-	returning struct.
-
-	* testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer"
-	tests.
-
-2008-01-24  David Edelsohn  <edelsohn@gnu.org>
-
-	* configure: Regenerate.
-
-2008-01-06  Andreas Tobler  <a.tobler@schweiz.org>
-
-	* src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko.
-
-2008-01-05  Andreas Tobler  <a.tobler@schweiz.org>
-
-	PR testsuite/32843
-	* src/x86/ffi.c (ffi_prep_cif_machdep): Add code for
-	signed/unsigned int8/16 for X86_DARWIN.
-	Updated copyright info.
-	Handle one and two byte structs with special cif->flags.
-	* src/x86/ffitarget.h: Add special types for one and two byte structs.
-	Updated copyright info.
-	* src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like
-	sysv.S
-	Remove code to pop args from the stack after call.
-	Special-case signed/unsigned for int8/16, one and two byte structs.
-	(ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8,
-	FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32,
-	FFI_TYPE_SINT32.
-	Updated copyright info.
-
-2007-12-08  David Daney  <ddaney@avtrex.com>
-
-	* src/mips/n32.S (ffi_call_N32):  Replace dadd with ADDU, dsub with
-	SUBU, add with ADDU and use smaller code sequences.
-
-2007-12-07  David Daney  <ddaney@avtrex.com>
-
-	* src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return
-	type.
-
-2007-12-06  David Daney  <ddaney@avtrex.com>
-
-	* include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not	already
-	defined.
-	(ffi_java_raw): New typedef.
-	(ffi_java_raw_call, ffi_java_ptrarray_to_raw,
-	ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to
-	ffi_java_raw.
-	(ffi_java_raw_closure) : Same.
-	(ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change
-	parameter types.
-	* src/java_raw_api.c (ffi_java_raw_size):  Replace FFI_SIZEOF_ARG with
-	FFI_SIZEOF_JAVA_RAW.
-	(ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw.
-	Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use
-	sizeof(ffi_java_raw) for alignment calculations.
-	(ffi_java_ptrarray_to_raw): Same.
-	(ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER
-	if FFI_SIZEOF_JAVA_RAW == 4.
-	(ffi_java_raw_to_rvalue): Same.
-	(ffi_java_raw_call): Change type of raw to ffi_java_raw.
-	(ffi_java_translate_args): Same.
-	(ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change
-	parameter types.
-	* src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI.
-
-2007-12-06  David Daney  <ddaney@avtrex.com>
-
-	* src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on
-	pointer values.
-
-2007-12-01  Andreas Tobler  <a.tobler@schweiz.org>
-
-	PR libffi/31937
-	* src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT.
-	Add local FFI_TYPE_UINT128 to handle soft-float long-double-128.
-	* src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and
-	set the NUM_FPR_ARG_REGISTERS according to.
-	Add support for potential soft-float support under hard-float
-	architecture.
-	(ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of
-	FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according
-	to the FFI_LINUX_SOFT_FLOAT ABI.
-	(ffi_prep_cif_machdep): Likewise.
-	(ffi_closure_helper_SYSV): Likewise.
-	* src/powerpc/ppc_closure.S: Make sure not to store float/double
-	on archs where __NO_FPRS__ is true.
-	Add FFI_TYPE_UINT128 support.
-	* src/powerpc/sysv.S: Add support for soft-float long-double-128.
-	Adjust copyright notice.
-
-2007-11-25  Andreas Tobler  <a.tobler@schweiz.org>
-
-	* src/closures.c: Move defintion of MAYBE_UNUSED from here to ...
-	* include/ffi_common.h: ... here.
-	Update copyright.
-
-2007-11-17  Andreas Tobler  <a.tobler@schweiz.org>
-
-	* src/powerpc/sysv.S: Load correct cr to compare if we have long double.
-	* src/powerpc/linux64.S: Likewise.
-	* src/powerpc/ffi.c: Add a comment to show which part goes into cr6.
-	* testsuite/libffi.call/return_ldl.c: New test.
-
-2007-09-04    <aph@redhat.com>
-
-	* src/arm/sysv.S (UNWIND): New.
-	(Whole file): Conditionally compile unwinder directives.
-	* src/arm/sysv.S: Add unwinder directives.
-
-	* src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes.
-	Only treat r0 as a struct address if we're actually returning a
-	struct by address.
-	Only copy the bytes that are actually within a struct.
-	(ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes
-	is returned in r0, not passed by address.
-	(ffi_call): Allocate a word-sized temporary for the case where
-	a composite is returned in r0.
-	(ffi_prep_incoming_args_SYSV): Align as necessary.
-
-2007-08-05  Steven Newbury  <s_j_newbury@yahoo.co.uk>
-
-	* src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of
-	directly using the sys_cacheflush syscall.
-
-2007-07-27  Andrew Haley  <aph@redhat.com>
-
-	* src/arm/sysv.S (ffi_closure_SYSV): Add soft-float.
-
-2007-09-03  Maciej W. Rozycki  <macro@linux-mips.org>
-
-	* Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS.
-	* configure.ac: Likewise.
-	* Makefile.in: Regenerate.
-	* include/Makefile.in: Likewise.
-	* testsuite/Makefile.in: Likewise.
-	* configure: Likewise.
-
-2007-08-24  David Daney  <ddaney@avtrex.com>
-
-	* testsuite/libffi.call/return_sl.c: New test.
-
-2007-08-10  David Daney  <ddaney@avtrex.com>
-
-	* testsuite/libffi.call/cls_multi_ushort.c,
-	testsuite/libffi.call/cls_align_uint16.c,
-	testsuite/libffi.call/nested_struct1.c,
-	testsuite/libffi.call/nested_struct3.c,
-	testsuite/libffi.call/cls_7_1_byte.c,
-	testsuite/libffi.call/nested_struct5.c,
-	testsuite/libffi.call/cls_double.c,
-	testsuite/libffi.call/nested_struct7.c,
-	testsuite/libffi.call/cls_sint.c,
-	testsuite/libffi.call/nested_struct9.c,
-	testsuite/libffi.call/cls_20byte1.c,
-	testsuite/libffi.call/cls_multi_sshortchar.c,
-	testsuite/libffi.call/cls_align_sint64.c,
-	testsuite/libffi.call/cls_3byte2.c,
-	testsuite/libffi.call/cls_multi_schar.c,
-	testsuite/libffi.call/cls_multi_uchar.c,
-	testsuite/libffi.call/cls_19byte.c,
-	testsuite/libffi.call/cls_9byte1.c,
-	testsuite/libffi.call/cls_align_float.c,
-	testsuite/libffi.call/closure_fn1.c,
-	testsuite/libffi.call/problem1.c,
-	testsuite/libffi.call/closure_fn3.c,
-	testsuite/libffi.call/cls_sshort.c,
-	testsuite/libffi.call/closure_fn5.c,
-	testsuite/libffi.call/cls_align_double.c,
-	testsuite/libffi.call/nested_struct.c,
-	testsuite/libffi.call/cls_2byte.c,
-	testsuite/libffi.call/nested_struct10.c,
-	testsuite/libffi.call/cls_4byte.c,
-	testsuite/libffi.call/cls_6byte.c,
-	testsuite/libffi.call/cls_8byte.c,
-	testsuite/libffi.call/cls_multi_sshort.c,
-	testsuite/libffi.call/cls_align_sint16.c,
-	testsuite/libffi.call/cls_align_uint32.c,
-	testsuite/libffi.call/cls_20byte.c,
-	testsuite/libffi.call/cls_float.c,
-	testsuite/libffi.call/nested_struct2.c,
-	testsuite/libffi.call/cls_5_1_byte.c,
-	testsuite/libffi.call/nested_struct4.c,
-	testsuite/libffi.call/cls_24byte.c,
-	testsuite/libffi.call/nested_struct6.c,
-	testsuite/libffi.call/cls_64byte.c,
-	testsuite/libffi.call/nested_struct8.c,
-	testsuite/libffi.call/cls_uint.c,
-	testsuite/libffi.call/cls_multi_ushortchar.c,
-	testsuite/libffi.call/cls_schar.c,
-	testsuite/libffi.call/cls_uchar.c,
-	testsuite/libffi.call/cls_align_uint64.c,
-	testsuite/libffi.call/cls_ulonglong.c,
-	testsuite/libffi.call/cls_align_longdouble.c,
-	testsuite/libffi.call/cls_1_1byte.c,
-	testsuite/libffi.call/cls_12byte.c,
-	testsuite/libffi.call/cls_3_1byte.c,
-	testsuite/libffi.call/cls_3byte1.c,
-	testsuite/libffi.call/cls_4_1byte.c,
-	testsuite/libffi.call/cls_6_1_byte.c,
-	testsuite/libffi.call/cls_16byte.c,
-	testsuite/libffi.call/cls_18byte.c,
-	testsuite/libffi.call/closure_fn0.c,
-	testsuite/libffi.call/cls_9byte2.c,
-	testsuite/libffi.call/closure_fn2.c,
-	testsuite/libffi.call/closure_fn4.c,
-	testsuite/libffi.call/cls_ushort.c,
-	testsuite/libffi.call/closure_fn6.c,
-	testsuite/libffi.call/cls_5byte.c,
-	testsuite/libffi.call/cls_align_pointer.c,
-	testsuite/libffi.call/cls_7byte.c,
-	testsuite/libffi.call/cls_align_sint32.c,
-	testsuite/libffi.special/unwindtest_ffi_call.cc,
-	testsuite/libffi.special/unwindtest.cc: Remove xfail for mips64*-*-*.
-
-2007-08-10  David Daney  <ddaney@avtrex.com>
-
-	PR libffi/28313
-	* configure.ac: Don't treat mips64 as a special case.
-	* Makefile.am (nodist_libffi_la_SOURCES): Add n32.S.
-	* configure: Regenerate
-	* Makefile.in: Ditto.
-	* fficonfig.h.in: Ditto.
-	* src/mips/ffitarget.h (REG_L, REG_S, SUBU, ADDU, SRL, LI): Indent.
-	(LA, EH_FRAME_ALIGN, FDE_ADDR_BYTES): New preprocessor macros.
-	(FFI_DEFAULT_ABI): Set for n64 case.
-	(FFI_CLOSURES, FFI_TRAMPOLINE_SIZE): Define for n32 and n64 cases.
-	* src/mips/n32.S (ffi_call_N32): Add debug macros and labels for FDE.
-	(ffi_closure_N32): New function.
-	(.eh_frame): New section
-	* src/mips/o32.S: Clean up comments.
-	(ffi_closure_O32): Pass ffi_closure parameter in $12.
-	* src/mips/ffi.c: Use FFI_MIPS_N32 instead of
-	_MIPS_SIM == _ABIN32 throughout.
-	(FFI_MIPS_STOP_HERE): New, use in place of
-	ffi_stop_here.
-	(ffi_prep_args): Use unsigned long to hold pointer values.  Rewrite
-	to support n32/n64 ABIs.
-	(calc_n32_struct_flags): Rewrite.
-	(calc_n32_return_struct_flags): Remove unused variable.  Reverse
-	position of flag bits.
-	(ffi_prep_cif_machdep): Rewrite n32 portion.
-	(ffi_call): Enable for n64.  Add special handling for small structure
-	return values.
-	(ffi_prep_closure_loc): Add n32 and n64 support.
-	(ffi_closure_mips_inner_O32): Add cast to silence warning.
-	(copy_struct_N32, ffi_closure_mips_inner_N32): New functions.
-
-2007-08-08  David Daney  <ddaney@avtrex.com>
-
-	* testsuite/libffi.call/ffitest.h (ffi_type_mylong): Remove definition.
-	* testsuite/libffi.call/cls_align_uint16.c (main): Use correct type
-	specifiers.
-	* testsuite/libffi.call/nested_struct1.c (main): Ditto.
-	* testsuite/libffi.call/cls_sint.c (main): Ditto.
-	* testsuite/libffi.call/nested_struct9.c (main): Ditto.
-	* testsuite/libffi.call/cls_20byte1.c (main): Ditto.
-	* testsuite/libffi.call/cls_9byte1.c (main): Ditto.
-	* testsuite/libffi.call/closure_fn1.c (main): Ditto.
-	* testsuite/libffi.call/closure_fn3.c (main): Ditto.
-	* testsuite/libffi.call/return_dbl2.c (main): Ditto.
-	* testsuite/libffi.call/cls_sshort.c (main): Ditto.
-	* testsuite/libffi.call/return_fl3.c (main): Ditto.
-	* testsuite/libffi.call/closure_fn5.c (main): Ditto.
-	* testsuite/libffi.call/nested_struct.c (main): Ditto.
-	* testsuite/libffi.call/nested_struct10.c (main): Ditto.
-	* testsuite/libffi.call/return_ll1.c (main): Ditto.
-	* testsuite/libffi.call/cls_8byte.c (main): Ditto.
-	* testsuite/libffi.call/cls_align_uint32.c (main): Ditto.
-	* testsuite/libffi.call/cls_align_sint16.c (main): Ditto.
-	* testsuite/libffi.call/cls_20byte.c (main): Ditto.
-	* testsuite/libffi.call/nested_struct2.c (main): Ditto.
-	* testsuite/libffi.call/cls_24byte.c (main): Ditto.
-	* testsuite/libffi.call/nested_struct6.c (main): Ditto.
-	* testsuite/libffi.call/cls_uint.c (main): Ditto.
-	* testsuite/libffi.call/cls_12byte.c (main): Ditto.
-	* testsuite/libffi.call/cls_16byte.c (main): Ditto.
-	* testsuite/libffi.call/closure_fn0.c (main): Ditto.
-	* testsuite/libffi.call/cls_9byte2.c (main): Ditto.
-	* testsuite/libffi.call/closure_fn2.c (main): Ditto.
-	* testsuite/libffi.call/return_dbl1.c (main): Ditto.
-	* testsuite/libffi.call/closure_fn4.c (main): Ditto.
-	* testsuite/libffi.call/closure_fn6.c (main): Ditto.
-	* testsuite/libffi.call/cls_align_sint32.c (main): Ditto.
-
-2007-08-07  Andrew Haley  <aph@redhat.com>
-
-	* src/x86/sysv.S (ffi_closure_raw_SYSV): Fix typo in previous
-	checkin.
-
-2007-08-06  Andrew Haley  <aph@redhat.com>
-
-	PR testsuite/32843
-	* src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8,
-	FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32,
-	FFI_TYPE_SINT32.
-
-2007-08-02  David Daney  <ddaney@avtrex.com>
-
-	* testsuite/libffi.call/return_ul.c (main): Define return type as
-	ffi_arg.  Use proper printf conversion specifier.
-
-2007-07-30  Andrew Haley  <aph@redhat.com>
-
-	PR testsuite/32843
-	* src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for
-	signed/unsigned int8/16.
-	* src/x86/sysv.S (ffi_call_SYSV): Rewrite to:
-	Use a jump table.
-	Remove code to pop args from the stack after call.
-	Special-case signed/unsigned int8/16.
-	* testsuite/libffi.call/return_sc.c (main): Revert.
-
-2007-07-26  Richard Guenther  <rguenther@suse.de>
-
-	PR testsuite/32843
-	* testsuite/libffi.call/return_sc.c (main): Verify call
-	result as signed char, not ffi_arg.
-
-2007-07-16  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* configure.ac (i?86-*-solaris2.1[0-9]): Set TARGET to X86_64.
-	* configure: Regenerate.
-
-2007-07-11  David Daney  <ddaney@avtrex.com>
-
-	* src/mips/ffi.c: Don't include sys/cachectl.h.
-	(ffi_prep_closure_loc): Use __builtin___clear_cache() instead of
-	cacheflush().
-
-2007-05-18  Aurelien Jarno  <aurelien@aurel32.net>
-
-	* src/arm/ffi.c (ffi_prep_closure_loc): Renamed and ajusted
-	from (ffi_prep_closure): ... this.
-	(FFI_INIT_TRAMPOLINE): Adjust.
-
-2005-12-31  Phil Blundell  <pb@reciva.com>
-
-	* src/arm/ffi.c (ffi_prep_incoming_args_SYSV,
-	ffi_closure_SYSV_inner, ffi_prep_closure): New, add closure support.
-	* src/arm/sysv.S(ffi_closure_SYSV): Likewise.
-	* src/arm/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise.
-	(FFI_CLOSURES): Enable closure support.
-
-2007-07-03  Andrew Haley  <aph@hedges.billgatliff.com>
-
-	* testsuite/libffi.call/cls_multi_ushort.c,
-	testsuite/libffi.call/cls_align_uint16.c,
-	testsuite/libffi.call/nested_struct1.c,
-	testsuite/libffi.call/nested_struct3.c,
-	testsuite/libffi.call/cls_7_1_byte.c,
-	testsuite/libffi.call/cls_double.c,
-	testsuite/libffi.call/nested_struct5.c,
-	testsuite/libffi.call/nested_struct7.c,
-	testsuite/libffi.call/cls_sint.c,
-	testsuite/libffi.call/nested_struct9.c,
-	testsuite/libffi.call/cls_20byte1.c,
-	testsuite/libffi.call/cls_multi_sshortchar.c,
-	testsuite/libffi.call/cls_align_sint64.c,
-	testsuite/libffi.call/cls_3byte2.c,
-	testsuite/libffi.call/cls_multi_schar.c,
-	testsuite/libffi.call/cls_multi_uchar.c,
-	testsuite/libffi.call/cls_19byte.c,
-	testsuite/libffi.call/cls_9byte1.c,
-	testsuite/libffi.call/cls_align_float.c,
-	testsuite/libffi.call/closure_fn1.c,
-	testsuite/libffi.call/problem1.c,
-	testsuite/libffi.call/closure_fn3.c,
-	testsuite/libffi.call/cls_sshort.c,
-	testsuite/libffi.call/closure_fn5.c,
-	testsuite/libffi.call/cls_align_double.c,
-	testsuite/libffi.call/cls_2byte.c,
-	testsuite/libffi.call/nested_struct.c,
-	testsuite/libffi.call/nested_struct10.c,
-	testsuite/libffi.call/cls_4byte.c,
-	testsuite/libffi.call/cls_6byte.c,
-	testsuite/libffi.call/cls_8byte.c,
-	testsuite/libffi.call/cls_multi_sshort.c,
-	testsuite/libffi.call/cls_align_uint32.c,
-	testsuite/libffi.call/cls_align_sint16.c,
-	testsuite/libffi.call/cls_float.c,
-	testsuite/libffi.call/cls_20byte.c,
-	testsuite/libffi.call/cls_5_1_byte.c,
-	testsuite/libffi.call/nested_struct2.c,
-	testsuite/libffi.call/cls_24byte.c,
-	testsuite/libffi.call/nested_struct4.c,
-	testsuite/libffi.call/nested_struct6.c,
-	testsuite/libffi.call/cls_64byte.c,
-	testsuite/libffi.call/nested_struct8.c,
-	testsuite/libffi.call/cls_uint.c,
-	testsuite/libffi.call/cls_multi_ushortchar.c,
-	testsuite/libffi.call/cls_schar.c,
-	testsuite/libffi.call/cls_uchar.c,
-	testsuite/libffi.call/cls_align_uint64.c,
-	testsuite/libffi.call/cls_ulonglong.c,
-	testsuite/libffi.call/cls_align_longdouble.c,
-	testsuite/libffi.call/cls_1_1byte.c,
-	testsuite/libffi.call/cls_12byte.c,
-	testsuite/libffi.call/cls_3_1byte.c,
-	testsuite/libffi.call/cls_3byte1.c,
-	testsuite/libffi.call/cls_4_1byte.c,
-	testsuite/libffi.call/cls_6_1_byte.c,
-	testsuite/libffi.call/cls_16byte.c,
-	testsuite/libffi.call/cls_18byte.c,
-	testsuite/libffi.call/closure_fn0.c,
-	testsuite/libffi.call/cls_9byte2.c,
-	testsuite/libffi.call/closure_fn2.c,
-	testsuite/libffi.call/closure_fn4.c,
-	testsuite/libffi.call/cls_ushort.c,
-	testsuite/libffi.call/closure_fn6.c,
-	testsuite/libffi.call/cls_5byte.c,
-	testsuite/libffi.call/cls_align_pointer.c,
-	testsuite/libffi.call/cls_7byte.c,
-	testsuite/libffi.call/cls_align_sint32.c,
-	testsuite/libffi.special/unwindtest_ffi_call.cc,
-	testsuite/libffi.special/unwindtest.cc: Enable for ARM.
-
-2007-07-05  H.J. Lu  <hongjiu.lu@intel.com>
-
-	* aclocal.m4: Regenerated.
-
-2007-06-02  Paolo Bonzini  <bonzini@gnu.org>
-
-	* configure: Regenerate.
-
-2007-05-23  Steve Ellcey  <sje@cup.hp.com>
-
-	* Makefile.in: Regenerate.
-	* configure: Regenerate.
-	* aclocal.m4: Regenerate.
-	* include/Makefile.in: Regenerate.
-	* testsuite/Makefile.in: Regenerate.
-
-2007-05-10  Roman Zippel <zippel@linux-m68k.org>
-
-	* src/m68k/ffi.c (ffi_prep_incoming_args_SYSV,
-	ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support.
-	* src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise.
-	* src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise.
-	(FFI_CLOSURES): Enable closure support.
-
-2007-05-10  Roman Zippel <zippel@linux-m68k.org>
-
-	* configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test.
-	* configure: Regenerate.
-	* fficonfig.h.in: Regenerate.
-	* src/m68k/sysv.S (CFI_STARTPROC,CFI_ENDPROC,
-	CFI_OFFSET,CFI_DEF_CFA): New macros.
-	(ffi_call_SYSV): Add callframe annotation.
-
-2007-05-10  Roman Zippel <zippel@linux-m68k.org>
-
-	* src/m68k/ffi.c (ffi_prep_args,ffi_prep_cif_machdep): Fix
-	numerous test suite failures.
-	* src/m68k/sysv.S (ffi_call_SYSV): Likewise.
-
-2007-04-11  Paolo Bonzini  <bonzini@gnu.org>
-
-	* Makefile.am (EXTRA_DIST): Bring up to date.
-	* Makefile.in: Regenerate.
-	* src/frv/eabi.S: Remove RCS keyword.
-
-2007-04-06  Richard Henderson  <rth@redhat.com>
-
-	* configure.ac: Tidy target case.
-	(HAVE_LONG_DOUBLE): Allow the target to override.
-	* configure: Regenerate.
-	* include/ffi.h.in: Don't define ffi_type_foo if
-	LIBFFI_HIDE_BASIC_TYPES is defined.
-	(ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define
-	to ffi_type_double.
-	* types.c (LIBFFI_HIDE_BASIC_TYPES): Define.
-	(FFI_TYPEDEF, ffi_type_void): Mark the data const.
-	(ffi_type_longdouble): Special case for Alpha.  Don't define
-	if long double == double.
-
-	* src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value.
-	(ffi_prep_cif_machdep): Handle it as the 128-bit type.
-	(ffi_call, ffi_closure_osf_inner): Likewise.
-	(ffi_closure_osf_inner): Likewise.  Mark hidden.
-	(ffi_call_osf, ffi_closure_osf): Mark hidden.
-	* src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition.
-	* src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden.
-	(load_table): Handle 128-bit long double.
-
-	* testsuite/libffi.call/float4.c: Add -mieee for alpha.
-
-2007-04-06  Tom Tromey  <tromey@redhat.com>
-
-	PR libffi/31491:
-	* README: Fixed bug in example.
-
-2007-04-03  Jakub Jelinek  <jakub@redhat.com>
-
-	* src/closures.c: Include sys/statfs.h.
-	(_GNU_SOURCE): Define on Linux.
-	(FFI_MMAP_EXEC_SELINUX): Define.
-	(selinux_enabled): New variable.
-	(selinux_enabled_check): New function.
-	(is_selinux_enabled): Define.
-	(dlmmap): Use it.
-
-2007-03-24  Uros Bizjak  <ubizjak@gmail.com>
-
-	* testsuite/libffi.call/return_fl2.c (return_fl): Mark as static.
-	Use 'volatile float sum' to create sum of floats to avoid false
-	negative due to excess precision on ix86 targets.
-	(main): Ditto.
-
-2007-03-08  Alexandre Oliva  <aoliva@redhat.com>
-
-	* src/powerpc/ffi.c (flush_icache): Fix left-over from previous
-	patch.
-	(ffi_prep_closure_loc): Remove unneeded casts.  Add needed ones.
-
-2007-03-07  Alexandre Oliva  <aoliva@redhat.com>
-
-	* include/ffi.h.in (ffi_closure_alloc, ffi_closure_free): New.
-	(ffi_prep_closure_loc): New.
-	(ffi_prep_raw_closure_loc): New.
-	(ffi_prep_java_raw_closure_loc): New.
-	* src/closures.c: New file.
-	* src/dlmalloc.c [FFI_MMAP_EXEC_WRIT] (struct malloc_segment):
-	Replace sflags with exec_offset.
-	[FFI_MMAP_EXEC_WRIT] (mmap_exec_offset, add_segment_exec_offset,
-	sub_segment_exec_offset): New macros.
-	(get_segment_flags, set_segment_flags, check_segment_merge): New
-	macros.
-	(is_mmapped_segment, is_extern_segment): Use get_segment_flags.
-	(add_segment, sys_alloc, create_mspace, create_mspace_with_base,
-	destroy_mspace): Use new macros.
-	(sys_alloc): Silence warning.
-	* Makefile.am (libffi_la_SOURCES): Add src/closures.c.
-	* Makefile.in: Rebuilt.
-	* src/prep_cif [FFI_CLOSURES] (ffi_prep_closure): Implement in
-	terms of ffi_prep_closure_loc.
-	* src/raw_api.c (ffi_prep_raw_closure_loc): Renamed and adjusted
-	from...
-	(ffi_prep_raw_closure): ... this.  Re-implement in terms of the
-	renamed version.
-	* src/java_raw_api (ffi_prep_java_raw_closure_loc): Renamed and
-	adjusted from...
-	(ffi_prep_java_raw_closure): ... this.  Re-implement in terms of
-	the renamed version.
-	* src/alpha/ffi.c (ffi_prep_closure_loc): Renamed from
-	(ffi_prep_closure): ... this.
-	* src/pa/ffi.c: Likewise.
-	* src/cris/ffi.c: Likewise.  Adjust.
-	* src/frv/ffi.c: Likewise.
-	* src/ia64/ffi.c: Likewise.
-	* src/mips/ffi.c: Likewise.
-	* src/powerpc/ffi_darwin.c: Likewise.
-	* src/s390/ffi.c: Likewise.
-	* src/sh/ffi.c: Likewise.
-	* src/sh64/ffi.c: Likewise.
-	* src/sparc/ffi.c: Likewise.
-	* src/x86/ffi64.c: Likewise.
-	* src/x86/ffi.c: Likewise.
-	(FFI_INIT_TRAMPOLINE): Adjust.
-	(ffi_prep_raw_closure_loc): Renamed and adjusted from...
-	(ffi_prep_raw_closure): ... this.
-	* src/powerpc/ffi.c (ffi_prep_closure_loc): Renamed from
-	(ffi_prep_closure): ... this.
-	(flush_icache): Adjust.
-
-2007-03-07  Alexandre Oliva  <aoliva@redhat.com>
-
-	* src/dlmalloc.c: New file, imported version 2.8.3 of Doug
-	Lea's malloc.
-
-2007-03-01  Brooks Moses  <brooks.moses@codesourcery.com>
-
-	* Makefile.am: Add dummy install-pdf target.
-	* Makefile.in: Regenerate
-
-2007-02-13  Andreas Krebbel  <krebbel1@de.ibm.com>
-
-	* src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep,
-	ffi_closure_helper_SYSV): Add long double handling.
-
-2007-02-02  Jakub Jelinek  <jakub@redhat.com>
-
-	* src/powerpc/linux64.S (ffi_call_LINUX64): Move restore of r2
-	immediately after bctrl instruction.
-
-2007-01-18  Alexandre Oliva  <aoliva@redhat.com>
-
-	* Makefile.am (all-recursive, install-recursive,
-	mostlyclean-recursive, clean-recursive, distclean-recursive,
-	maintainer-clean-recursive): Add missing targets.
-	* Makefile.in: Rebuilt.
-
-2006-12-14  Andreas Tobler  <a.tobler@schweiz.org>
-
-	* configure.ac: Add TARGET for x86_64-*-darwin*.
-	* Makefile.am (nodist_libffi_la_SOURCES): Add rules for 64-bit sources
-	for X86_DARWIN.
-	* src/x86/ffitarget.h: Set trampoline size for x86_64-*-darwin*.
-	* src/x86/darwin64.S: New file for x86_64-*-darwin* support.
-	* configure: Regenerate.
-	* Makefile.in: Regenerate.
-	* include/Makefile.in: Regenerate.
-	* testsuite/Makefile.in: Regenerate.
-	* testsuite/libffi.special/unwindtest_ffi_call.cc: New test case for
-	ffi_call only.
-
-2006-12-13  Andreas Tobler <a.tobler@schweiz.org>
-
-	* aclocal.m4: Regenerate with aclocal -I .. as written in the
-	Makefile.am.
-
-2006-10-31  Geoffrey Keating  <geoffk@apple.com>
-
-	* src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New.
-	(ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for
-	Darwin.
-	* testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL.
-	* testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL.
-
-2006-10-10  Paolo Bonzini  <bonzini@gnu.org>
-	    Sandro Tolaini  <tolaini@libero.it>
-
-	* configure.ac [i*86-*-darwin*]: Set X86_DARWIN symbol and
-	conditional.
-	* configure: Regenerated.
-	* Makefile.am (nodist_libffi_la_SOURCES) [X86_DARWIN]: New case.
-	(EXTRA_DIST): Add src/x86/darwin.S.
-	* Makefile.in: Regenerated.
-	* include/Makefile.in: Regenerated.
-	* testsuite/Makefile.in: Regenerated.
-
-	* src/x86/ffi.c (ffi_prep_cif_machdep) [X86_DARWIN]: Treat like
-	X86_WIN32, and additionally align stack to 16 bytes.
-	* src/x86/darwin.S: New, based on sysv.S.
-	* src/prep_cif.c (ffi_prep_cif) [X86_DARWIN]: Align > 8-byte structs.
-
-2006-09-12  David Daney  <ddaney@avtrex.com>
-
-	PR libffi/23935
-	* include/Makefile.am: Install both ffi.h and ffitarget.h in
-	$(libdir)/gcc/$(target_alias)/$(gcc_version)/include.
-	* aclocal.m4: Regenerated for automake 1.9.6.
-	* Makefile.in: Regenerated.
-	* include/Makefile.in: Regenerated.
-	* testsuite/Makefile.in: Regenerated.
-
-2006-08-17  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* include/ffi_common.h (struct): Revert accidental commit.
-
-2006-08-15  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* include/ffi_common.h: Remove lint directives.
-	* include/ffi.h.in: Likewise.
-
-2006-07-25  Torsten Schoenfeld  <kaffeetisch@gmx.de>
-
-	* include/ffi.h.in (ffi_type_ulong, ffi_type_slong): Define correctly
-	for 32-bit architectures.
-	* testsuite/libffi.call/return_ul.c: New test case.
-
-2006-07-19  David Daney  <ddaney@avtrex.com>
-
-	* testsuite/libffi.call/closure_fn6.c: Remove xfail for mips,
-	xfail remains for mips64.
-
-2006-05-23  Carlos O'Donell  <carlos@codesourcery.com>
-
-	* Makefile.am: Add install-html target. Add install-html to .PHONY
-	* Makefile.in: Regenerate.
-	* aclocal.m4: Regenerate.
-	* include/Makefile.in: Regenerate.
-	* testsuite/Makefile.in: Regenerate.
-
-2006-05-18  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
-
-	* pa/ffi.c (ffi_prep_args_pa32): Load floating point arguments from
-	stack slot.
-
-2006-04-22  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* README: Remove notice about 'Crazy Comments'.
-	* src/debug.c: Remove lint directives. Cleanup white spaces.
-	* src/java_raw_api.c: Likewise.
-	* src/prep_cif.c: Likewise.
-	* src/raw_api.c: Likewise.
-	* src/ffitest.c: Delete. No longer needed, all test cases migrated
-	to the testsuite.
-	* src/arm/ffi.c: Remove lint directives.
-	* src/m32r/ffi.c: Likewise.
-	* src/pa/ffi.c: Likewise.
-	* src/powerpc/ffi.c: Likewise.
-	* src/powerpc/ffi_darwin.c: Likewise.
-	* src/sh/ffi.c: Likewise.
-	* src/sh64/ffi.c: Likewise.
-	* src/x86/ffi.c: Likewise.
-	* testsuite/libffi.call/float2.c: Likewise.
-	* testsuite/libffi.call/promotion.c: Likewise.
-	* testsuite/libffi.call/struct1.c: Likewise.
-
-2006-04-13  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/pa/hpux32.S: Correct unwind offset calculation for
-	ffi_closure_pa32.
-	* src/pa/linux.S: Likewise.
-
-2006-04-12  James E Wilson  <wilson@specifix.com>
-
-	PR libgcj/26483
-	* src/ia64/ffi.c (stf_spill, ldf_fill): Rewrite as macros.
-	(hfa_type_load): Call stf_spill.
-	(hfa_type_store): Call ldf_fill.
-	(ffi_call): Adjust calls to above routines.  Add local temps for
-	macro result.
-
-2006-04-10  Matthias Klose  <doko@debian.org>
-
-	* testsuite/lib/libffi-dg.exp (libffi-init): Recognize multilib
-	directory names containing underscores.
-
-2006-04-07  James E Wilson  <wilson@specifix.com>
-
-	* testsuite/libffi.call/float4.c: New testcase.
-
-2006-04-05  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
-	    Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* Makefile.am: Add PA_HPUX port.
-	* Makefile.in: Regenerate.
-	* include/Makefile.in: Likewise.
-	* testsuite/Makefile.in: Likewise.
-	* configure.ac: Add PA_HPUX rules.
-	* configure: Regenerate.
-	* src/pa/ffitarget.h: Rename linux target to PA_LINUX.
-	Add PA_HPUX and PA64_HPUX.
-	Rename FFI_LINUX ABI to FFI_PA32 ABI.
-	(FFI_TRAMPOLINE_SIZE): Define for 32-bit HP-UX targets.
-	(FFI_TYPE_SMALL_STRUCT2): Define.
-	(FFI_TYPE_SMALL_STRUCT4): Likewise.
-	(FFI_TYPE_SMALL_STRUCT8): Likewise.
-	(FFI_TYPE_SMALL_STRUCT3): Redefine.
-	(FFI_TYPE_SMALL_STRUCT5): Likewise.
-	(FFI_TYPE_SMALL_STRUCT6): Likewise.
-	(FFI_TYPE_SMALL_STRUCT7): Likewise.
-	* src/pa/ffi.c (ROUND_DOWN): Delete.
-	(fldw, fstw, fldd, fstd): Use '__asm__'.
-	(ffi_struct_type): Add support for FFI_TYPE_SMALL_STRUCT2,
-	FFI_TYPE_SMALL_STRUCT4 and FFI_TYPE_SMALL_STRUCT8.
-	(ffi_prep_args_LINUX): Rename to ffi_prep_args_pa32. Update comment.
-	Simplify incrementing of stack slot variable. Change type of local
-	'n' to unsigned int.
-	(ffi_size_stack_LINUX): Rename to ffi_size_stack_pa32. Handle long
-	double on PA_HPUX.
-	(ffi_prep_cif_machdep): Likewise.
-	(ffi_call): Likewise.
-	(ffi_closure_inner_LINUX): Rename to ffi_closure_inner_pa32. Change
-	return type to ffi_status. Simplify incrementing of stack slot
-	variable. Only copy floating point argument registers when PA_LINUX
-	is true. Reformat debug statement.
-	Add support for FFI_TYPE_SMALL_STRUCT2, FFI_TYPE_SMALL_STRUCT4 and
-	FFI_TYPE_SMALL_STRUCT8.
-	(ffi_closure_LINUX): Rename to ffi_closure_pa32. Add 'extern' to
-	declaration.
-	(ffi_prep_closure): Make linux trampoline conditional on PA_LINUX.
-	Add nops to cache flush.  Add trampoline for PA_HPUX.
-	* src/pa/hpux32.S: New file.
-	* src/pa/linux.S (ffi_call_LINUX): Rename to ffi_call_pa32. Rename
-	ffi_prep_args_LINUX to ffi_prep_args_pa32.
-	Localize labels. Add support for 2, 4 and 8-byte small structs. Handle
-	unaligned destinations in 3, 5, 6 and 7-byte small structs. Order
-	argument type checks so that common argument types appear first.
-	(ffi_closure_LINUX): Rename to ffi_closure_pa32. Rename
-	ffi_closure_inner_LINUX to ffi_closure_inner_pa32.
-
-2006-03-24  Alan Modra  <amodra@bigpond.net.au>
-
-	* src/powerpc/ffitarget.h (enum ffi_abi): Add FFI_LINUX.  Default
-	for 32-bit using IBM extended double format.  Fix FFI_LAST_ABI.
-	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Handle linux variant of
-	FFI_TYPE_LONGDOUBLE.
-	(ffi_prep_args64): Assert using IBM extended double.
-	(ffi_prep_cif_machdep): Don't munge FFI_TYPE_LONGDOUBLE type.
-	Handle FFI_LINUX FFI_TYPE_LONGDOUBLE return and args.
-	(ffi_call): Handle FFI_LINUX.
-	(ffi_closure_helper_SYSV): Non FFI_LINUX long double return needs
-	gpr3 return pointer as for struct return.  Handle FFI_LINUX
-	FFI_TYPE_LONGDOUBLE return and args.  Don't increment "nf"
-	unnecessarily.
-	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Load both f1 and f2
-	for FFI_TYPE_LONGDOUBLE.  Move epilogue insns into case table.
-	Don't use r6 as pointer to results, instead use sp offset.  Don't
-	make a special call to load lr with case table address, instead
-	use offset from previous call.
-	* src/powerpc/sysv.S (ffi_call_SYSV): Save long double return.
-	* src/powerpc/linux64.S (ffi_call_LINUX64): Simplify long double
-	return.
-
-2006-03-15  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments
-	passed with FP registers correctly.
-	(ffi_closure_helper_SYSV): Likewise.
-	* src/sh64/sysv.S: Likewise.
-
-2006-03-01  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif,
-	args and userdata unused.
-	(closure_test_fn1): Mark cif and userdata unused.
-	(main): Remove unused res.
-
-2006-02-28  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/call.exp: Adjust FSF address. Add test runs for
-	-O2, -O3, -Os and the warning flags -W -Wall.
-	* testsuite/libffi.special/special.exp: Likewise.
-	* testsuite/libffi.call/ffitest.h: Add an __UNUSED__ macro to mark
-	unused parameter unused for gcc or else do nothing.
-	* testsuite/libffi.special/ffitestcxx.h: Likewise.
-	* testsuite/libffi.call/cls_12byte.c (cls_struct_12byte_gn): Mark cif
-	and userdata unused.
-	* testsuite/libffi.call/cls_16byte.c (cls_struct_16byte_gn): Likewise.
-	* testsuite/libffi.call/cls_18byte.c (cls_struct_18byte_gn): Likewise.
-	* testsuite/libffi.call/cls_19byte.c (cls_struct_19byte_gn): Likewise.
-	* testsuite/libffi.call/cls_1_1byte.c (cls_struct_1_1byte_gn): Likewise.
-	* testsuite/libffi.call/cls_20byte.c (cls_struct_20byte_gn): Likewise.
-	* testsuite/libffi.call/cls_20byte1.c (cls_struct_20byte_gn): Likewise.
-	* testsuite/libffi.call/cls_24byte.c (cls_struct_24byte_gn): Likewise.
-	* testsuite/libffi.call/cls_2byte.c (cls_struct_2byte_gn): Likewise.
-	* testsuite/libffi.call/cls_3_1byte.c (cls_struct_3_1byte_gn): Likewise.
-	* testsuite/libffi.call/cls_3byte1.c (cls_struct_3byte_gn): Likewise.
-	* testsuite/libffi.call/cls_3byte2.c (cls_struct_3byte_gn1): Likewise.
-	* testsuite/libffi.call/cls_4_1byte.c (cls_struct_4_1byte_gn): Likewise.
-	* testsuite/libffi.call/cls_4byte.c (cls_struct_4byte_gn): Likewise.
-	* testsuite/libffi.call/cls_5_1_byte.c (cls_struct_5byte_gn): Likewise.
-	* testsuite/libffi.call/cls_5byte.c (cls_struct_5byte_gn): Likewise.
-	* testsuite/libffi.call/cls_64byte.c (cls_struct_64byte_gn): Likewise.
-	* testsuite/libffi.call/cls_6_1_byte.c (cls_struct_6byte_gn): Likewise.
-	* testsuite/libffi.call/cls_6byte.c (cls_struct_6byte_gn): Likewise.
-	* testsuite/libffi.call/cls_7_1_byte.c (cls_struct_7byte_gn): Likewise.
-	* testsuite/libffi.call/cls_7byte.c (cls_struct_7byte_gn): Likewise.
-	* testsuite/libffi.call/cls_8byte.c (cls_struct_8byte_gn): Likewise.
-	* testsuite/libffi.call/cls_9byte1.c (cls_struct_9byte_gn): Likewise.
-	* testsuite/libffi.call/cls_9byte2.c (cls_struct_9byte_gn): Likewise.
-	* testsuite/libffi.call/cls_align_double.c (cls_struct_align_gn):
-	Likewise.
-	* testsuite/libffi.call/cls_align_float.c (cls_struct_align_gn):
-	Likewise.
-	* testsuite/libffi.call/cls_align_longdouble.c (cls_struct_align_gn):
-	Likewise.
-	* testsuite/libffi.call/cls_align_pointer.c (cls_struct_align_fn): Cast
-	void* to avoid compiler warning.
-	(main): Likewise.
-	(cls_struct_align_gn): Mark cif and userdata unused.
-	* testsuite/libffi.call/cls_align_sint16.c (cls_struct_align_gn):
-	Likewise.
-	* testsuite/libffi.call/cls_align_sint32.c (cls_struct_align_gn):
-	Likewise.
-	* testsuite/libffi.call/cls_align_sint64.c (cls_struct_align_gn):
-	Likewise.
-	* testsuite/libffi.call/cls_align_uint16.c (cls_struct_align_gn):
-	Likewise.
-	* testsuite/libffi.call/cls_align_uint32.c (cls_struct_align_gn):
-	Likewise.
-	* testsuite/libffi.call/cls_double.c (cls_ret_double_fn): Likewise.
-	* testsuite/libffi.call/cls_float.c (cls_ret_float_fn): Likewise.
-	* testsuite/libffi.call/cls_multi_schar.c (test_func_gn): Mark cif and
-	data unused.
-	(main): Cast res_call to silence gcc.
-	* testsuite/libffi.call/cls_multi_sshort.c (test_func_gn): Mark cif and
-	data unused.
-	(main): Cast res_call to silence gcc.
-	* testsuite/libffi.call/cls_multi_sshortchar.c (test_func_gn): Mark cif
-	and data unused.
-	(main): Cast res_call to silence gcc.
-	* testsuite/libffi.call/cls_multi_uchar.c (test_func_gn): Mark cif and
-	data unused.
-	(main): Cast res_call to silence gcc.
-	* testsuite/libffi.call/cls_multi_ushort.c (test_func_gn): Mark cif and
-	data unused.
-	(main): Cast res_call to silence gcc.
-	* testsuite/libffi.call/cls_multi_ushortchar.c (test_func_gn): Mark cif
-	and data unused.
-	(main): Cast res_call to silence gcc.
-	* testsuite/libffi.call/cls_schar.c (cls_ret_schar_fn): Mark cif and
-	userdata unused.
-	(cls_ret_schar_fn): Cast printf parameter to silence gcc.
-	* testsuite/libffi.call/cls_sint.c (cls_ret_sint_fn): Mark cif and
-	userdata unused.
-	(cls_ret_sint_fn): Cast printf parameter to silence gcc.
-	* testsuite/libffi.call/cls_sshort.c (cls_ret_sshort_fn): Mark cif and
-	userdata unused.
-	(cls_ret_sshort_fn): Cast printf parameter to silence gcc.
-	* testsuite/libffi.call/cls_uchar.c (cls_ret_uchar_fn):  Mark cif and
-	userdata unused.
-	(cls_ret_uchar_fn): Cast printf parameter to silence gcc.
-	* testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Mark cif and
-	userdata unused.
-	(cls_ret_uint_fn): Cast printf parameter to silence gcc.
-	* testsuite/libffi.call/cls_ulonglong.c (cls_ret_ulonglong_fn): Mark cif
-	and userdata unused.
-	* testsuite/libffi.call/cls_ushort.c (cls_ret_ushort_fn): Mark cif and
-	userdata unused.
-	(cls_ret_ushort_fn): Cast printf parameter to silence gcc.
-	* testsuite/libffi.call/float.c (floating): Remove unused parameter e.
-	* testsuite/libffi.call/float1.c (main): Remove unused variable i.
-	Cleanup white spaces.
-	* testsuite/libffi.call/negint.c (checking): Remove unused variable i.
-	* testsuite/libffi.call/nested_struct.c (cls_struct_combined_gn): Mark
-	cif and userdata unused.
-	* testsuite/libffi.call/nested_struct1.c (cls_struct_combined_gn):
-	Likewise.
-	* testsuite/libffi.call/nested_struct10.c (B_gn): Likewise.
-	* testsuite/libffi.call/nested_struct2.c (B_fn): Adjust printf
-	formatters to silence gcc.
-	(B_gn): Mark cif and userdata unused.
-	* testsuite/libffi.call/nested_struct3.c (B_gn): Mark cif and userdata
-	unused.
-	* testsuite/libffi.call/nested_struct4.c: Mention related PR.
-	(B_gn): Mark cif and userdata unused.
-	* testsuite/libffi.call/nested_struct5.c (B_gn): Mark cif and userdata
-	unused.
-	* testsuite/libffi.call/nested_struct6.c: Mention related PR.
-	(B_gn): Mark cif and userdata unused.
-	* testsuite/libffi.call/nested_struct7.c (B_gn): Mark cif and userdata
-	unused.
-	* testsuite/libffi.call/nested_struct8.c (B_gn): Likewise.
-	* testsuite/libffi.call/nested_struct9.c (B_gn): Likewise.
-	* testsuite/libffi.call/problem1.c (stub): Likewise.
-	* testsuite/libffi.call/pyobjc-tc.c (main): Cast the result to silence
-	gcc.
-	* testsuite/libffi.call/return_fl2.c (return_fl): Add the note mentioned
-	in the last commit for this test case in the test case itself.
-	* testsuite/libffi.call/closure_fn0.c (closure_test_fn0): Mark cif as
-	unused.
-	* testsuite/libffi.call/closure_fn1.c (closure_test_fn1): Likewise.
-	* testsuite/libffi.call/closure_fn2.c (closure_test_fn2): Likewise.
-	* testsuite/libffi.call/closure_fn3.c (closure_test_fn3): Likewise.
-	* testsuite/libffi.call/closure_fn4.c (closure_test_fn0): Likewise.
-	* testsuite/libffi.call/closure_fn5.c (closure_test_fn5): Likewise.
-	* testsuite/libffi.call/closure_fn6.c (closure_test_fn0): Likewise.
-
-2006-02-22  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/sysv.S: Fix register numbers in the FDE for
-	ffi_closure_SYSV.
-
-2006-02-20  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/return_fl2.c (return_fl): Remove static
-	declaration to avoid a false negative on ix86. See PR323.
-
-2006-02-18  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/ffi.c (ffi_closure_helper_SYSV): Remove unused variable
-	and cast integer to void * if needed.  Update the pointer to
-	the FP register saved area correctly.
-
-2006-02-17  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/nested_struct6.c: XFAIL this test until PR25630
-	is fixed.
-	* testsuite/libffi.call/nested_struct4.c: Likewise.
-
-2006-02-16  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/return_dbl.c: New test case.
-	* testsuite/libffi.call/return_dbl1.c: Likewise.
-	* testsuite/libffi.call/return_dbl2.c: Likewise.
-	* testsuite/libffi.call/return_fl.c: Likewise.
-	* testsuite/libffi.call/return_fl1.c: Likewise.
-	* testsuite/libffi.call/return_fl2.c: Likewise.
-	* testsuite/libffi.call/return_fl3.c: Likewise.
-	* testsuite/libffi.call/closure_fn6.c: Likewise.
-
-	* testsuite/libffi.call/nested_struct2.c: Remove ffi_type_mylong
-	definition.
-	* testsuite/libffi.call/ffitest.h: Add ffi_type_mylong definition
-	here to be used by other test cases too.
-
-	* testsuite/libffi.call/nested_struct10.c: New test case.
-	* testsuite/libffi.call/nested_struct9.c: Likewise.
-	* testsuite/libffi.call/nested_struct8.c: Likewise.
-	* testsuite/libffi.call/nested_struct7.c: Likewise.
-	* testsuite/libffi.call/nested_struct6.c: Likewise.
-	* testsuite/libffi.call/nested_struct5.c: Likewise.
-	* testsuite/libffi.call/nested_struct4.c: Likewise.
-
-2006-01-21  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* configure.ac: Enable libffi for sparc64-*-freebsd*.
-	* configure: Rebuilt.
-
-2006-01-18  Jakub Jelinek  <jakub@redhat.com>
-
-	* src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3,
-	instead do the shifting inline.
-	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5
-	shift count unconditionally.  Simplify load sequences for 1, 2, 3, 4
-	and 8 byte structs, for the remaining struct sizes don't call
-	__lshrdi3, instead do the shifting inline.
-
-2005-12-07  Thiemo Seufer  <ths@networkno.de>
-
-	* src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add
-	missing parentheses.
-	* src/mips/o32.S (ffi_call_O32): Code formatting. Define
-	and use A3_OFF, FP_OFF, RA_OFF. Micro-optimizations.
-	(ffi_closure_O32): Likewise, but with newly defined A3_OFF2,
-	A2_OFF2, A1_OFF2, A0_OFF2, RA_OFF2, FP_OFF2, S0_OFF2, GP_OFF2,
-	V1_OFF2, V0_OFF2, FA_1_1_OFF2, FA_1_0_OFF2, FA_0_1_OFF2,
-	FA_0_0_OFF2.
-	* src/mips/ffi.c (ffi_prep_args): Code formatting. Fix
-	endianness bugs.
-	(ffi_prep_closure): Improve trampoline instruction scheduling.
-	(ffi_closure_mips_inner_O32): Fix endianness bugs.
-
-2005-12-03  Alan Modra  <amodra@bigpond.net.au>
-
-	* src/powerpc/ffi.c: Formatting.
-	(ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions.
-	(ffi_prep_args64): Likewise.
-
-2005-09-30  Geoffrey Keating  <geoffk@apple.com>
-
-	* testsuite/lib/libffi-dg.exp (libffi_target_compile): For
-	darwin, use -shared-libgcc not -lgcc_s, and explain why.
-
-2005-09-26  Tom Tromey  <tromey@redhat.com>
-
-	* testsuite/libffi.call/float1.c (value_type): New typedef.
-	(CANARY): New define.
-	(main): Check for result buffer overflow.
-	* src/powerpc/linux64.S: Handle linux64 long double returns.
-	* src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant.
-	(ffi_prep_cif_machdep): Handle linux64 long double returns.
-
-2005-08-25  Alan Modra  <amodra@bigpond.net.au>
-
-	PR target/23404
-	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Correct placement of stack
-	homed fp args.
-	(ffi_status ffi_prep_cif_machdep): Correct stack sizing for same.
-
-2005-08-11  Jakub Jelinek  <jakub@redhat.com>
-
-	* configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test.
-	(AH_BOTTOM): Add FFI_HIDDEN definition.
-	* configure: Rebuilt.
-	* fficonfig.h.in: Rebuilt.
-	* src/powerpc/ffi.c (hidden): Remove.
-	(ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64,
-	ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden.
-	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64,
-	.ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden.
-	* src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove,
-	add FFI_HIDDEN to its prototype.
-	(ffi_closure_SYSV_inner): New.
-	* src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New.
-	* src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New.
-
-2005-08-10  Alfred M. Szmidt  <ams@gnu.org>
-
-	PR libffi/21819:
-	* configure: Rebuilt.
-	* configure.ac: Handle i*86-*-gnu*.
-
-2005-08-09  Jakub Jelinek  <jakub@redhat.com>
-
-	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Use
-	DW_CFA_offset_extended_sf rather than
-	DW_CFA_GNU_negative_offset_extended.
-	* src/powerpc/sysv.S (ffi_call_SYSV): Likewise.
-
-2005-07-22  SUGIOKA Toshinobu  <sugioka@itonet.co.jp>
-
-	* src/sh/sysv.S (ffi_call_SYSV): Stop argument popping correctly
-	on sh3.
-	(ffi_closure_SYSV): Change the stack layout for sh3 struct argument.
-	* src/sh/ffi.c (ffi_prep_args): Fix sh3 argument copy, when it is
-	partially on register.
-	(ffi_closure_helper_SYSV): Likewise.
-	(ffi_prep_cif_machdep): Don't set too many cif->flags.
-
-2005-07-20  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/ffi.c (ffi_call): Handle small structures correctly.
-	Remove empty line.
-	* src/sh64/ffi.c (simple_type): Remove.
-	(return_type): Handle small structures correctly.
-	(ffi_prep_args): Likewise.
-	(ffi_call): Likewise.
-	(ffi_closure_helper_SYSV): Likewise.
-	* src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return.
-	Emit position independent code if PIC and remove wrong datalabel
-	prefixes from EH data.
-
-2005-07-19  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD.
-	* Makefile.in: Regenerate.
-	* include/Makefile.in: Likewise.
-	* testsuite/Makefile.in: Likewise.
-	* configure.ac: Add POWERPC_FREEBSD rules.
-	* configure: Regenerate.
-	* src/powerpc/ffitarget.h: Add POWERPC_FREEBSD rules.
-	(FFI_SYSV_TYPE_SMALL_STRUCT): Define.
-	* src/powerpc/ffi.c: Add flags to handle small structure returns
-	in ffi_call_SYSV.
-	(ffi_prep_cif_machdep): Handle small structures for SYSV 4 ABI.
-	Aka FFI_SYSV.
-	(ffi_closure_helper_SYSV): Likewise.
-	* src/powerpc/ppc_closure.S: Add return types for small structures.
-	* src/powerpc/sysv.S: Add bits to handle small structures for
-	final SYSV 4 ABI.
-
-2005-07-10  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/cls_5_1_byte.c: New test file.
-	* testsuite/libffi.call/cls_6_1_byte.c: Likewise.
-	* testsuite/libffi.call/cls_7_1_byte.c: Likewise.
-
-2005-07-05  Randolph Chung  <tausq@debian.org>
-
-	* src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1
-	as FFI_TYPE_SMALL_STRUCT3.  Break out handling for 5-7 byte
-	structures.  Kill compilation warnings.
-	(ffi_closure_inner_LINUX): Print return values as hex in debug
-	message.  Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3.
-	Properly handle 5-7 byte structure returns.
-	* src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1)
-	(FFI_TYPE_SMALL_STRUCT2): Remove.
-	(FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5)
-	(FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define.
-	* src/pa/linux.S: Mark source file as using PA1.1 assembly.
-	(checksmst1, checksmst2): Remove.
-	(checksmst3): Optimize handling of 3-byte struct returns.
-	(checksmst567): Properly handle 5-7 byte struct returns.
-
-2005-06-15  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	PR libgcj/21943
-	* src/mips/n32.S: Enforce PIC code.
-	* src/mips/o32.S: Likewise.
-
-2005-06-15  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* configure.ac: Treat i*86-*-solaris2.10 and up as X86_64.
-	* configure: Regenerate.
-
-2005-06-01  Alan Modra  <amodra@bigpond.net.au>
-
-	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't use JUMPTARGET
-	to call ffi_closure_helper_SYSV.  Append @local instead.
-	* src/powerpc/sysv.S (ffi_call_SYSV): Likewise for ffi_prep_args_SYSV.
-
-2005-05-17  Kelley Cook  <kcook@gcc.gnu.org>
-
-	* configure.ac: Use AC_C_BIGENDIAN instead of AC_C_BIGENDIAN_CROSS.
-	Use AC_CHECK_SIZEOF instead of AC_COMPILE_CHECK_SIZEOF.
-	* Makefile.am (ACLOCAL_AMFLAGS): Remove -I ../config.
-	* aclocal.m4, configure, fficonfig.h.in, Makefile.in,
-	include/Makefile.in, testsuite/Makefile.in: Regenerate.
-
-2005-05-09  Mike Stump  <mrs@apple.com>
-
-	* configure: Regenerate.
-
-2005-05-08  Richard Henderson  <rth@redhat.com>
-
-	PR libffi/21285
-	* src/alpha/osf.S: Update unwind into to match code.
-
-2005-05-04  Andreas Degert <ad@papyrus-gmbh.de>
-	    Richard Henderson  <rth@redhat.com>
-
-	* src/x86/ffi64.c (ffi_prep_cif_machdep): Save sse-used flag in
-	bit 11 of flags.
-	(ffi_call): Mask return type field.  Pass ssecount to ffi_call_unix64.
-	(ffi_prep_closure): Set carry bit if sse-used flag set.
-	* src/x86/unix64.S (ffi_call_unix64): Add ssecount argument.
-	Only load sse registers if ssecount non-zero.
-	(ffi_closure_unix64): Only save sse registers if carry set on entry.
-
-2005-04-29  Ralf Corsepius  <ralf.corsepius@rtems.org>
-
-	* configure.ac: Add i*86-*-rtems*, sparc*-*-rtems*,
-	powerpc-*rtems*, arm*-*-rtems*, sh-*-rtems*.
-	* configure: Regenerate.
-
-2005-04-20  Hans-Peter Nilsson  <hp@axis.com>
-
-	* testsuite/lib/libffi-dg.exp (libffi-dg-test-1): In regsub use,
-	have Tcl8.3-compatible intermediate variable.
-
-2005-04-18  Simon Posnjak <simon.posnjak@siol.net>
-	    Hans-Peter Nilsson  <hp@axis.com>
-
-	* Makefile.am: Add CRIS support.
-	* configure.ac: Likewise.
-	* Makefile.in, configure, testsuite/Makefile.in,
-	include/Makefile.in: Regenerate.
-	* src/cris: New directory.
-	* src/cris/ffi.c, src/cris/sysv.S, src/cris/ffitarget.h: New files.
-	* src/prep_cif.c (ffi_prep_cif): Wrap in #ifndef __CRIS__.
-
-	* testsuite/lib/libffi-dg.exp (libffi-dg-test-1): Replace \n with
-	\r?\n in output tests.
-
-2005-04-12  Mike Stump  <mrs@apple.com>
-
-	* configure: Regenerate.
-
-2005-03-30  Hans Boehm  <Hans.Boehm@hp.com>
-
-	* src/ia64/ffitarget.h (ffi_arg): Use long long instead of DI.
-
-2005-03-30  Steve Ellcey  <sje@cup.hp.com>
-
-	* src/ia64/ffitarget.h (ffi_arg) ADD DI attribute.
-	(ffi_sarg) Ditto.
-	* src/ia64/unix.S (ffi_closure_unix): Extend gp
-	to 64 bits in ILP32 mode.
-	Load 64 bits even for short data.
-
-2005-03-23  Mike Stump  <mrs@apple.com>
-
-	* src/powerpc/darwin.S: Update for -m64 multilib.
-	* src/powerpc/darwin_closure.S: Likewise.
-
-2005-03-21  Zack Weinberg  <zack@codesourcery.com>
-
-	* configure.ac: Do not invoke TL_AC_GCC_VERSION.
-	Do not set tool_include_dir.
-	* aclocal.m4, configure, Makefile.in, testsuite/Makefile.in:
-	Regenerate.
-	* include/Makefile.am: Set gcc_version and toollibffidir.
-	* include/Makefile.in: Regenerate.
-
-2005-02-22  Andrew Haley  <aph@redhat.com>
-
-	* src/powerpc/ffi.c (ffi_prep_cif_machdep): Bump alignment to
-	odd-numbered register pairs for 64-bit integer types.
-
-2005-02-23  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	PR libffi/20104
-	* testsuite/libffi.call/return_ll1.c: New test case.
-
-2005-02-11  Janis Johnson  <janis187@us.ibm.com>
-
-	* testsuite/libffi.call/cls_align_longdouble.c: Remove dg-options.
-	* testsuite/libffi.call/float.c: Ditto.
-	* testsuite/libffi.call/float2.c: Ditto.
-	* testsuite/libffi.call/float3.c: Ditto.
-
-2005-02-08  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/frv/ffitarget.h: Remove PPC stuff which does not belong to frv.
-
-2005-01-12  Eric Botcazou  <ebotcazou@libertysurf.fr>
-
-	* testsuite/libffi.special/special.exp (cxx_options): Add
-	-shared-libgcc.
-
-2004-12-31  Richard Henderson  <rth@redhat.com>
-
-	* src/types.c (FFI_AGGREGATE_TYPEDEF): Remove.
-	(FFI_TYPEDEF): Rename from FFI_INTEGRAL_TYPEDEF.  Replace size and
-	offset parameters with a type parameter; deduce size and structure
-	alignment.  Update all users.
-
-2004-12-31  Richard Henderson  <rth@redhat.com>
-
-	* src/types.c (FFI_TYPE_POINTER): Define with sizeof.
-	(FFI_TYPE_LONGDOUBLE): Fix for ia64.
-	* src/ia64/ffitarget.h (struct ffi_ia64_trampoline_struct): Move
-	into ffi_prep_closure.
-	* src/ia64/ia64_flags.h, src/ia64/ffi.c, src/ia64/unix.S: Rewrite
-	from scratch.
-
-2004-12-27  Richard Henderson  <rth@redhat.com>
-
-	* src/x86/unix64.S: Fix typo in unwind info.
-
-2004-12-25  Richard Henderson  <rth@redhat.com>
-
-	* src/x86/ffi64.c (struct register_args): Rename from stackLayout.
-	(enum x86_64_reg_class): Add X86_64_COMPLEX_X87_CLASS.
-	(merge_classes): Check for it.
-	(SSE_CLASS_P): New.
-	(classify_argument): Pass byte_offset by value; perform all updates
-	inside struct case.
-	(examine_argument): Add classes argument; handle
-	X86_64_COMPLEX_X87_CLASS.
-	(ffi_prep_args): Merge into ...
-	(ffi_call): ... here.  Share stack frame with ffi_call_unix64.
-	(ffi_prep_cif_machdep): Setup cif->flags for proper structure return.
-	(ffi_fill_return_value): Remove.
-	(ffi_prep_closure): Remove dead assert.
-	(ffi_closure_unix64_inner): Rename from ffi_closure_UNIX64_inner.
-	Rewrite to use struct register_args instead of va_list.  Create
-	flags for handling structure returns.
-	* src/x86/unix64.S: Remove dead strings.
-	(ffi_call_unix64): Rename from ffi_call_UNIX64.  Rewrite to share
-	stack frame with ffi_call.  Handle structure returns properly.
-	(float2sse, floatfloat2sse, double2sse): Remove.
-	(sse2float, sse2double, sse2floatfloat): Remove.
-	(ffi_closure_unix64): Rename from ffi_closure_UNIX64.  Rewrite
-	to handle structure returns properly.
-
-2004-12-08  David Edelsohn  <edelsohn@gnu.org>
-
-	* Makefile.am (AM_MAKEFLAGS): Remove duplicate LIBCFLAGS and
-	PICFLAG.
-	* Makefile.in: Regenerated.
-
-2004-12-02  Richard Sandiford  <rsandifo@redhat.com>
-
-	* configure.ac: Use TL_AC_GCC_VERSION to set gcc_version.
-	* configure, aclocal.m4, Makefile.in: Regenerate.
-	* include/Makefile.in, testsuite/Makefile.in: Regenerate.
-
-2004-11-29  Kelley Cook  <kcook@gcc.gnu.org>
-
-	* configure: Regenerate for libtool change.
-
-2004-11-25  Kelley Cook  <kcook@gcc.gnu.org>
-
-	* configure: Regenerate for libtool reversion.
-
-2004-11-24  Kelley Cook  <kcook@gcc.gnu.org>
-
-	* configure: Regenerate for libtool change.
-
-2004-11-23  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
-
-	* testsuite/lib/libffi-dg.exp: Use new procs in target-libpath.exp.
-
-2004-11-23  Richard Sandiford  <rsandifo@redhat.com>
-
-	* src/mips/o32.S (ffi_call_O32, ffi_closure_O32): Use jalr instead
-	of jal.  Use an absolute encoding for the frame information.
-
-2004-11-23  Kelley Cook  <kcook@gcc.gnu.org>
-
-	* Makefile.am: Remove no-dependencies.  Add ACLOCAL_AMFLAGS.
-	* acinclude.m4: Delete logic for sincludes.
-	* aclocal.m4, Makefile.in, configure: Regenerate.
-	* include/Makefile: Likewise.
-	* testsuite/Makefile: Likewise.
-
-2004-11-22  Eric Botcazou  <ebotcazou@libertysurf.fr>
-
-	* src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers
-	on a 8-byte boundary.
-	* src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments.
-
-2004-10-27  Richard Earnshaw  <rearnsha@arm.com>
-
-	* src/arm/ffi.c (ffi_prep_cif_machdep): Handle functions that return
-	long long values.  Round stack allocation to a multiple of 8 bytes
-	for ATPCS compatibility.
-	* src/arm/sysv.S (ffi_call_SYSV): Rework to avoid use of APCS register
-	names.  Handle returning long long types.  Add Thumb and interworking
-	support.  Improve soft-float code.
-
-2004-10-27  Richard Earnshaw  <rearnsha@arm.com>
-
-	* testsuite/lib/libffi-db.exp (load_gcc_lib): New function.
-	(libffi_exit): New function.
-	(libffi_init): Build the testglue wrapper if needed.
-
-2004-10-25  Eric Botcazou  <ebotcazou@libertysurf.fr>
-
-	PR other/18138
-	* testsuite/lib/libffi-dg.exp: Accept more than one multilib libgcc.
-
-2004-10-25  Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
-
-	* src/m32r/libffitarget.h (FFI_CLOSURES): Set to 0.
-
-2004-10-20  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/sysv.S (ffi_call_SYSV): Don't align for double data.
-	* testsuite/libffi.call/float3.c: New test case.
-
-2004-10-18  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/ffi.c (ffi_prep_closure): Set T bit in trampoline for
-	the function returning a structure pointed with R2.
-	* src/sh/sysv.S (ffi_closure_SYSV): Use R2 as the pointer to
-	the structure return value if T bit set.  Emit position
-	independent code and EH data if PIC.
-
-2004-10-13  Kazuhiro Inaoka  <inaoka.kazuhiro@renesas.com>
-
-	* Makefile.am: Add m32r support.
-	* configure.ac: Likewise.
-	* Makefile.in: Regenerate.
-	* confiugre: Regenerate.
-	* src/types.c: Add m32r port to FFI_INTERNAL_TYPEDEF
-	(uint64, sint64, double, longdouble)
-	* src/m32r: New directory.
-	* src/m32r/ffi.c: New file.
-	* src/m32r/sysv.S: Likewise.
-	* src/m32r/ffitarget.h: Likewise.
-
-2004-10-02  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* testsuite/libffi.call/negint.c: New test case.
-
-2004-09-14  H.J. Lu  <hongjiu.lu@intel.com>
-
-	PR libgcj/17465
-	* testsuite/lib/libffi-dg.exp: Don't use global ld_library_path.
-	Set up LD_LIBRARY_PATH, SHLIB_PATH, LD_LIBRARYN32_PATH,
-	LD_LIBRARY64_PATH, LD_LIBRARY_PATH_32, LD_LIBRARY_PATH_64 and
-	DYLD_LIBRARY_PATH.
-
-2004-09-05  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/many_win32.c: Remove whitespaces.
-	* testsuite/libffi.call/promotion.c: Likewise.
-	* testsuite/libffi.call/return_ll.c: Remove unused var. Cleanup
-	whitespaces.
-	* testsuite/libffi.call/return_sc.c: Likewise.
-	* testsuite/libffi.call/return_uc.c: Likewise.
-
-2004-09-05  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/powerpc/darwin.S: Fix comments and identation.
-	* src/powerpc/darwin_closure.S: Likewise.
-
-2004-09-02  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/powerpc/ffi_darwin.c: Add flag for longdouble return values.
-	(ffi_prep_args): Handle longdouble arguments.
-	(ffi_prep_cif_machdep): Set flags for longdouble. Calculate space for
-	longdouble.
-	(ffi_closure_helper_DARWIN): Add closure handling for longdouble.
-	* src/powerpc/darwin.S (_ffi_call_DARWIN): Add handling of longdouble
-	values.
-	* src/powerpc/darwin_closure.S (_ffi_closure_ASM): Likewise.
-	* src/types.c: Defined longdouble size and alignment for darwin.
-
-2004-09-02  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/powerpc/aix.S: Remove whitespaces.
-	* src/powerpc/aix_closure.S: Likewise.
-	* src/powerpc/asm.h: Likewise.
-	* src/powerpc/ffi.c: Likewise.
-	* src/powerpc/ffitarget.h: Likewise.
-	* src/powerpc/linux64.S: Likewise.
-	* src/powerpc/linux64_closure.S: Likewise.
-	* src/powerpc/ppc_closure.S: Likewise.
-	* src/powerpc/sysv.S: Likewise.
-
-2004-08-30  Anthony Green  <green@redhat.com>
-
-	* Makefile.am: Add frv support.
-	* Makefile.in, testsuite/Makefile.in: Rebuilt.
-	* configure.ac: Read configure.host.
-	* configure.in: Read configure.host.
-	* configure.host: New file.  frv-elf needs libgloss.
-	* include/ffi.h.in: Force ffi_closure to have a nice big (8)
-	alignment.  This is needed to frv and shouldn't harm the others.
-	* include/ffi_common.h (ALIGN_DOWN): New macro.
-	* src/frv/ffi.c, src/frv/ffitarget.h, src/frv/eabi.S: New files.
-
-2004-08-24  David Daney  <daney@avtrex.com>
-
-	* testsuite/libffi.call/closure_fn0.c: Xfail mips64* instead of mips*.
-	* testsuite/libffi.call/closure_fn1.c: Likewise.
-	* testsuite/libffi.call/closure_fn2.c  Likewise.
-	* testsuite/libffi.call/closure_fn3.c: Likewise.
-	* testsuite/libffi.call/closure_fn4.c: Likewise.
-	* testsuite/libffi.call/closure_fn5.c: Likewise.
-	* testsuite/libffi.call/cls_18byte.c: Likewise.
-	* testsuite/libffi.call/cls_19byte.c: Likewise.
-	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte1.c: Likewise.
-	* testsuite/libffi.call/cls_24byte.c: Likewise.
-	* testsuite/libffi.call/cls_2byte.c: Likewise.
-	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_3byte1.c: Likewise.
-	* testsuite/libffi.call/cls_3byte2.c: Likewise.
-	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_4byte.c: Likewise.
-	* testsuite/libffi.call/cls_64byte.c: Likewise.
-	* testsuite/libffi.call/cls_6byte.c: Likewise.
-	* testsuite/libffi.call/cls_7byte.c: Likewise.
-	* testsuite/libffi.call/cls_8byte.c: Likewise.
-	* testsuite/libffi.call/cls_9byte1.c: Likewise.
-	* testsuite/libffi.call/cls_9byte2.c: Likewise.
-	* testsuite/libffi.call/cls_align_double.c: Likewise.
-	* testsuite/libffi.call/cls_align_float.c: Likewise.
-	* testsuite/libffi.call/cls_align_longdouble.c: Likewise.
-	* testsuite/libffi.call/cls_align_pointer.c: Likewise.
-	* testsuite/libffi.call/cls_align_sint16.c: Likewise.
-	* testsuite/libffi.call/cls_align_sint32.c: Likewise.
-	* testsuite/libffi.call/cls_align_sint64.c: Likewise.
-	* testsuite/libffi.call/cls_align_uint16.c: Likewise.
-	* testsuite/libffi.call/cls_align_uint32.c: Likewise.
-	* testsuite/libffi.call/cls_align_uint64.c: Likewise.
-	* testsuite/libffi.call/cls_double.c: Likewise.
-	* testsuite/libffi.call/cls_float.c: Likewise.
-	* testsuite/libffi.call/cls_multi_schar.c: Likewise.
-	* testsuite/libffi.call/cls_multi_sshort.c: Likewise.
-	* testsuite/libffi.call/cls_multi_sshortchar.c: Likewise.
-	* testsuite/libffi.call/cls_multi_uchar.c: Likewise.
-	* testsuite/libffi.call/cls_multi_ushort.c: Likewise.
-	* testsuite/libffi.call/cls_multi_ushortchar.c: Likewise.
-	* testsuite/libffi.call/cls_schar.c: Likewise.
-	* testsuite/libffi.call/cls_sint.c: Likewise.
-	* testsuite/libffi.call/cls_sshort.c: Likewise.
-	* testsuite/libffi.call/cls_uchar.c: Likewise.
-	* testsuite/libffi.call/cls_uint.c: Likewise.
-	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
-	* testsuite/libffi.call/cls_ushort.c: Likewise.
-	* testsuite/libffi.call/nested_struct.c: Likewise.
-	* testsuite/libffi.call/nested_struct1.c: Likewise.
-	* testsuite/libffi.call/nested_struct2.c: Likewise.
-	* testsuite/libffi.call/nested_struct3.c: Likewise.
-	* testsuite/libffi.call/problem1.c: Likewise.
-	* testsuite/libffi.special/unwindtest.cc: Likewise.
-	* testsuite/libffi.call/cls_12byte.c: Likewise and set return value
-	to zero.
-	* testsuite/libffi.call/cls_16byte.c: Likewise.
-	* testsuite/libffi.call/cls_5byte.c: Likewise.
-
-2004-08-23  David Daney <daney@avtrex.com>
-
-	PR libgcj/13141
-	* src/mips/ffitarget.h (FFI_O32_SOFT_FLOAT): New ABI.
-	* src/mips/ffi.c (ffi_prep_args): Fix alignment calculation.
-	(ffi_prep_cif_machdep): Handle FFI_O32_SOFT_FLOAT floating point
-	parameters and return types.
-	(ffi_call): Handle FFI_O32_SOFT_FLOAT ABI.
-	(ffi_prep_closure): Ditto.
-	(ffi_closure_mips_inner_O32): Handle FFI_O32_SOFT_FLOAT ABI, fix
-	alignment calculations.
-	* src/mips/o32.S (ffi_closure_O32): Don't use floating point
-	instructions if FFI_O32_SOFT_FLOAT, make stack frame ABI compliant.
-
-2004-08-14  Casey Marshall <csm@gnu.org>
-
-	* src/mips/ffi.c (ffi_pref_cif_machdep): set `cif->flags' to
-	contain `FFI_TYPE_UINT64' as return type for any 64-bit
-	integer (O32 ABI only).
-	(ffi_prep_closure): new function.
-	(ffi_closure_mips_inner_O32): new function.
-	* src/mips/ffitarget.h: Define `FFI_CLOSURES' and
-	`FFI_TRAMPOLINE_SIZE' appropriately if the ABI is o32.
-	* src/mips/o32.S (ffi_call_O32): add labels for .eh_frame. Return
-	64 bit integers correctly.
-	(ffi_closure_O32): new function.
-	Added DWARF-2 unwind info for both functions.
-
-2004-08-10  Andrew Haley  <aph@redhat.com>
-
-	* src/x86/ffi64.c (ffi_prep_args ): 8-align all stack arguments.
-
-2004-08-01  Robert Millan  <robertmh@gnu.org>
-
-	* configure.ac: Detect knetbsd-gnu and kfreebsd-gnu.
-	* configure: Regenerate.
-
-2004-07-30  Maciej W. Rozycki  <macro@linux-mips.org>
-
-	* acinclude.m4 (AC_FUNC_MMAP_BLACKLIST): Check for <sys/mman.h>
-	and mmap() explicitly instead of relying on preset autoconf cache
-	variables.
-	* aclocal.m4: Regenerate.
-	* configure: Regenerate.
-
-2004-07-11  Ulrich Weigand  <uweigand@de.ibm.com>
-
-	* src/s390/ffi.c (ffi_prep_args): Fix C aliasing violation.
-	(ffi_check_float_struct): Remove unused prototype.
-
-2004-06-30  Geoffrey Keating  <geoffk@apple.com>
-
-	* src/powerpc/ffi_darwin.c (flush_icache): ';' is a comment
-	character on Darwin, use '\n\t' instead.
-
-2004-06-26  Matthias Klose  <doko@debian.org>
-
-	* libtool-version: Fix typo in revision/age.
-
-2004-06-17  Matthias Klose  <doko@debian.org>
-
-	* libtool-version: New.
-	* Makefile.am (libffi_la_LDFLAGS): Use -version-info for soname.
-	* Makefile.in: Regenerate.
-
-2004-06-15  Paolo Bonzini  <bonzini@gnu.org>
-
-	* Makefile.am: Remove useless multilib rules.
-	* Makefile.in: Regenerate.
-	* aclocal.m4: Regenerate with automake 1.8.5.
-	* configure.ac: Remove useless multilib configury.
-	* configure: Regenerate.
-
-2004-06-15  Paolo Bonzini  <bonzini@gnu.org>
-
-	* .cvsignore: New file.
-
-2004-06-10  Jakub Jelinek  <jakub@redhat.com>
-
-	* src/ia64/unix.S (ffi_call_unix): Insert group barrier break
-	fp_done.
-	(ffi_closure_UNIX): Fix f14/f15 adjustment if FLOAT_SZ is ever
-	changed from 8.
-
-2004-06-06  Sean McNeil  <sean@mcneil.com>
-
-	* configure.ac: Add x86_64-*-freebsd* support.
-	* configure: Regenerate.
-
-2004-04-26  Joe Buck <jbuck@welsh-buck.org>
-
-	Bug 15093
-	* configure.ac: Test for existence of mmap and sys/mman.h before
-	checking blacklist.  Fix suggested by Jim Wilson.
-	* configure: Regenerate.
-
-2004-04-26  Matt Austern  <austern@apple.com>
-
-	* src/powerpc/darwin.S: Go through a non-lazy pointer for initial
-	FDE location.
-	* src/powerpc/darwin_closure.S: Likewise.
-
-2004-04-24  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/cls_multi_schar.c (main): Fix initialization
-	error. Reported by Thomas Heller <theller@python.net>.
-	* testsuite/libffi.call/cls_multi_sshort.c (main): Likewise.
-	* testsuite/libffi.call/cls_multi_ushort.c (main): Likewise.
-
-2004-03-20  Matthias Klose  <doko@debian.org>
-
-	* src/pa/linux.S: Fix typo.
-
-2004-03-19  Matthias Klose  <doko@debian.org>
-
-	* Makefile.am: Update.
-	* Makefile.in: Regenerate.
-	* src/pa/ffi.h.in: Remove.
-	* src/pa/ffitarget.h: New file.
-
-2004-02-10  Randolph Chung  <tausq@debian.org>
-
-	* Makefile.am: Add PA support.
-	* Makefile.in: Regenerate.
-	* include/Makefile.in: Regenerate.
-	* configure.ac: Add PA target.
-	* configure: Regenerate.
-	* src/pa/ffi.c: New file.
-	* src/pa/ffi.h.in: Add PA support.
-	* src/pa/linux.S: New file.
-	* prep_cif.c: Add PA support.
-
-2004-03-16  Hosaka Yuji  <hos@tamanegi.org>
-
-	* src/types.c: Fix alignment size of X86_WIN32 case int64 and
-	double.
-	* src/x86/ffi.c (ffi_prep_args): Replace ecif->cif->rtype->type
-	with ecif->cif->flags.
-	(ffi_call, ffi_prep_incoming_args_SYSV): Replace cif->rtype->type
-	with cif->flags.
-	(ffi_prep_cif_machdep): Add X86_WIN32 struct case.
-	(ffi_closure_SYSV): Add 1 or 2-bytes struct case for X86_WIN32.
-	* src/x86/win32.S (retstruct1b, retstruct2b, sc_retstruct1b,
-	sc_retstruct2b): Add for 1 or 2-bytes struct case.
-
-2004-03-15 Kelley Cook <kcook@gcc.gnu.org>
-
-	* configure.in: Rename file to ...
-	* configure.ac: ... this.
-	* fficonfig.h.in: Regenerate.
-	* Makefile.in: Regenerate.
-	* include/Makefile.in: Regenerate.
-	* testsuite/Makefile.in: Regenerate.
-
-2004-03-12  Matt Austern  <austern@apple.com>
-
-	* src/powerpc/darwin.S: Fix EH information so it corresponds to
-	changes in EH format resulting from addition of linkonce support.
-	* src/powerpc/darwin_closure.S: Likewise.
-
-2004-03-11  Andreas Tobler  <a.tobler@schweiz.ch>
-	    Paolo Bonzini  <bonzini@gnu.org>
-
-	* Makefile.am (AUTOMAKE_OPTIONS): Set them.
-	Remove VPATH. Remove rules for object files. Remove multilib support.
-	(AM_CCASFLAGS): Add.
-	* configure.in (AC_CONFIG_HEADERS): Relace AM_CONFIG_HEADER.
-	(AC_PREREQ): Bump version to 2.59.
-	(AC_INIT): Fill with version info and bug address.
-	(ORIGINAL_LD_FOR_MULTILIBS): Remove.
-	(AM_ENABLE_MULTILIB): Use this instead of AC_ARG_ENABLE.
-	De-precious CC so that the right flags are passed down to multilibs.
-	(AC_MSG_ERROR): Replace obsolete macro AC_ERROR.
-	(AC_CONFIG_FILES): Replace obsolete macro AC_LINK_FILES.
-	(AC_OUTPUT): Reorganize the output with AC_CONFIG_COMMANDS.
-	* configure: Rebuilt.
-	* aclocal.m4: Likewise.
-	* Makefile.in, include/Makefile.in, testsuite/Makefile.in: Likewise.
-	* fficonfig.h.in: Likewise.
-
-2004-03-11  Andreas Schwab  <schwab@suse.de>
-
-	* src/ia64/ffi.c (ffi_prep_incoming_args_UNIX): Get floating point
-	arguments from fp registers only for the first 8 parameter slots.
-	Don't convert a float parameter when passed in memory.
-
-2004-03-09  Hans-Peter Nilsson  <hp@axis.com>
-
-	* configure: Regenerate for config/accross.m4 correction.
-
-2004-02-25  Matt Kraai  <kraai@alumni.cmu.edu>
-
-	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Change
-	ecif->cif->bytes to bytes.
-	(ffi_prep_cif_machdep): Add braces around nested if statement.
-
-2004-02-09  Alan Modra  <amodra@bigpond.net.au>
-
-	* src/types.c (pointer): POWERPC64 has 8 byte pointers.
-
-	* src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling.
-	(ffi_closure_helper_LINUX64): Fix typo.
-	* testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128
-	for powerpc64-*-*.
-	* testsuite/libffi.call/float.c: Likewise.
-	* testsuite/libffi.call/float2.c: Likewise.
-
-2004-02-08  Alan Modra  <amodra@bigpond.net.au>
-
-	* src/powerpc/ffi.c (ffi_prep_cif_machdep <FFI_LINUX64>): Correct
-	long double function return and long double arg handling.
-	(ffi_closure_helper_LINUX64): Formatting.  Delete unused "ng" var.
-	Use "end_pfr" instead of "nf".  Correct long double handling.
-	Localise "temp".
-	* src/powerpc/linux64.S (ffi_call_LINUX64): Save f2 long double
-	return value.
-	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Allocate
-	space for long double return value.  Adjust stack frame and offsets.
-	Load f2 long double return.
-
-2004-02-07  Alan Modra  <amodra@bigpond.net.au>
-
-	* src/types.c: Use 16 byte long double for POWERPC64.
-
-2004-01-25  Eric Botcazou  <ebotcazou@libertysurf.fr>
-
-	* src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array
-	when the structure return address is passed in %o0.
-	(ffi_V9_return_struct): Rename into ffi_v9_layout_struct.
-	(ffi_v9_layout_struct): Align the field following a nested structure
-	on a word boundary.  Use memmove instead of memcpy.
-	(ffi_call): Update call to ffi_V9_return_struct.
-	(ffi_prep_closure): Define 'ctx' only for V8.
-	(ffi_closure_sparc_inner): Clone into ffi_closure_sparc_inner_v8
-	and ffi_closure_sparc_inner_v9.
-	(ffi_closure_sparc_inner_v8): Return long doubles by reference.
-	Always skip the structure return address.  For structures and long
-	doubles, copy the argument directly.
-	(ffi_closure_sparc_inner_v9): Skip the structure return address only
-	if required.  Shift the maximum floating-point slot accordingly.  For
-	big structures, copy the argument directly; otherwise, left-justify the
-	argument and call ffi_v9_layout_struct to lay out the structure on
-	the stack.
-	* src/sparc/v8.S: Undef STACKFRAME before defining it.
-	(ffi_closure_v8): Pass the structure return address.  Update call to
-	ffi_closure_sparc_inner_v8.  Short-circuit FFI_TYPE_INT handling.
-	Skip the 'unimp' insn when returning long doubles and structures.
-	* src/sparc/v9.S: Undef STACKFRAME before defining it.
-	(ffi_closure_v9): Increase the frame size by 2 words.  Short-circuit
-	FFI_TYPE_INT handling.  Load structures both in integers and
-	floating-point registers on return.
-	* README: Update status of the SPARC port.
-
-2004-01-24  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/pyobjc-tc.c (main): Treat result value
-	as of type ffi_arg.
-	* testsuite/libffi.call/struct3.c (main): Fix CHECK.
-
-2004-01-22  Ulrich Weigand  <uweigand@de.ibm.com>
-
-	* testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Treat result
-	value as of type ffi_arg, not unsigned int.
-
-2004-01-21  Michael Ritzert  <ritzert@t-online.de>
-
-	* ffi64.c (ffi_prep_args): Cast the RHS of an assignment instead
-	of the LHS.
-
-2004-01-12  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_32 for
-	Solaris.
-
-2004-01-08  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* testsuite/libffi.call/ffitest.h (allocate_mmap): Cast MAP_FAILED
-	to void *.
-
-2003-12-10  Richard Henderson  <rth@redhat.com>
-
-	* testsuite/libffi.call/cls_align_pointer.c: Cast pointers to
-	size_t instead of int.
-
-2003-12-04  Hosaka Yuji  <hos@tamanegi.org>
-
-	* testsuite/libffi.call/many_win32.c: Include <float.h>.
-	* testsuite/libffi.call/many_win32.c (main): Replace variable
-	int i with unsigned long ul.
-
-	* testsuite/libffi.call/cls_align_uint64.c: New test case.
-	* testsuite/libffi.call/cls_align_sint64.c: Likewise.
-	* testsuite/libffi.call/cls_align_uint32.c: Likewise.
-	* testsuite/libffi.call/cls_align_sint32.c: Likewise.
-	* testsuite/libffi.call/cls_align_uint16.c: Likewise.
-	* testsuite/libffi.call/cls_align_sint16.c: Likewise.
-	* testsuite/libffi.call/cls_align_float.c: Likewise.
-	* testsuite/libffi.call/cls_align_double.c: Likewise.
-	* testsuite/libffi.call/cls_align_longdouble.c: Likewise.
-	* testsuite/libffi.call/cls_align_pointer.c: Likewise.
-
-2003-12-02  Hosaka Yuji  <hos@tamanegi.org>
-
-	PR other/13221
-	* src/x86/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV):
-	Align arguments to 32 bits.
-
-2003-12-01  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	PR other/13221
-	* testsuite/libffi.call/cls_multi_sshort.c: New test case.
-	* testsuite/libffi.call/cls_multi_sshortchar.c: Likewise.
-	* testsuite/libffi.call/cls_multi_uchar.c: Likewise.
-	* testsuite/libffi.call/cls_multi_schar.c: Likewise.
-	* testsuite/libffi.call/cls_multi_ushortchar.c: Likewise.
-	* testsuite/libffi.call/cls_multi_ushort.c: Likewise.
-
-	* testsuite/libffi.special/unwindtest.cc: Cosmetics.
-
-2003-11-26  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
-
-	* testsuite/libffi.call/ffitest.h: Include <fcntl.h>.
-	* testsuite/libffi.special/ffitestcxx.h: Likewise.
-
-2003-11-22  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* Makefile.in: Rebuilt.
-	* configure: Likewise.
-	* testsuite/libffi.special/unwindtest.cc: Convert the mmap to
-	the right type.
-
-2003-11-21  Andreas Jaeger  <aj@suse.de>
-	    Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* acinclude.m4: Add AC_FUNC_MMAP_BLACKLIST.
-	* configure.in: Call AC_FUNC_MMAP_BLACKLIST.
-	* Makefile.in: Rebuilt.
-	* aclocal.m4: Likewise.
-	* configure: Likewise.
-	* fficonfig.h.in: Likewise.
-	* testsuite/lib/libffi-dg.exp: Add include dir.
-	* testsuite/libffi.call/ffitest.h: Add MMAP definitions.
-	* testsuite/libffi.special/ffitestcxx.h: Likewise.
-	* testsuite/libffi.call/closure_fn0.c: Use MMAP functionality
-	for ffi_closure if available.
-	* testsuite/libffi.call/closure_fn1.c: Likewise.
-	* testsuite/libffi.call/closure_fn2.c: Likewise.
-	* testsuite/libffi.call/closure_fn3.c: Likewise.
-	* testsuite/libffi.call/closure_fn4.c: Likewise.
-	* testsuite/libffi.call/closure_fn5.c: Likewise.
-	* testsuite/libffi.call/cls_12byte.c: Likewise.
-	* testsuite/libffi.call/cls_16byte.c: Likewise.
-	* testsuite/libffi.call/cls_18byte.c: Likewise.
-	* testsuite/libffi.call/cls_19byte.c: Likewise.
-	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte1.c: Likewise.
-	* testsuite/libffi.call/cls_24byte.c: Likewise.
-	* testsuite/libffi.call/cls_2byte.c: Likewise.
-	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_3byte1.c: Likewise.
-	* testsuite/libffi.call/cls_3byte2.c: Likewise.
-	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_4byte.c: Likewise.
-	* testsuite/libffi.call/cls_5byte.c: Likewise.
-	* testsuite/libffi.call/cls_64byte.c: Likewise.
-	* testsuite/libffi.call/cls_6byte.c: Likewise.
-	* testsuite/libffi.call/cls_7byte.c: Likewise.
-	* testsuite/libffi.call/cls_8byte.c: Likewise.
-	* testsuite/libffi.call/cls_9byte1.c: Likewise.
-	* testsuite/libffi.call/cls_9byte2.c: Likewise.
-	* testsuite/libffi.call/cls_double.c: Likewise.
-	* testsuite/libffi.call/cls_float.c: Likewise.
-	* testsuite/libffi.call/cls_schar.c: Likewise.
-	* testsuite/libffi.call/cls_sint.c: Likewise.
-	* testsuite/libffi.call/cls_sshort.c: Likewise.
-	* testsuite/libffi.call/cls_uchar.c: Likewise.
-	* testsuite/libffi.call/cls_uint.c: Likewise.
-	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
-	* testsuite/libffi.call/cls_ushort.c: Likewise.
-	* testsuite/libffi.call/nested_struct.c: Likewise.
-	* testsuite/libffi.call/nested_struct1.c: Likewise.
-	* testsuite/libffi.call/nested_struct2.c: Likewise.
-	* testsuite/libffi.call/nested_struct3.c: Likewise.
-	* testsuite/libffi.call/problem1.c: Likewise.
-	* testsuite/libffi.special/unwindtest.cc: Likewise.
-
-2003-11-20  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/lib/libffi-dg.exp: Make the -lgcc_s conditional.
-
-2003-11-19  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/lib/libffi-dg.exp: Add DYLD_LIBRARY_PATH for darwin.
-	Add -lgcc_s to additional flags.
-
-2003-11-12  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* configure.in, include/Makefile.am: PR libgcj/11147, install
-	the ffitarget.h header file in a gcc versioned and target
-	dependent place.
-	* configure: Regenerated.
-	* Makefile.in, include/Makefile.in: Likewise.
-	* testsuite/Makefile.in: Likewise.
-
-2003-11-09  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/closure_fn0.c: Print result and check
-	with dg-output to make debugging easier.
-	* testsuite/libffi.call/closure_fn1.c: Likewise.
-	* testsuite/libffi.call/closure_fn2.c: Likewise.
-	* testsuite/libffi.call/closure_fn3.c: Likewise.
-	* testsuite/libffi.call/closure_fn4.c: Likewise.
-	* testsuite/libffi.call/closure_fn5.c: Likewise.
-	* testsuite/libffi.call/cls_12byte.c: Likewise.
-	* testsuite/libffi.call/cls_16byte.c: Likewise.
-	* testsuite/libffi.call/cls_18byte.c: Likewise.
-	* testsuite/libffi.call/cls_19byte.c: Likewise.
-	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte1.c: Likewise.
-	* testsuite/libffi.call/cls_24byte.c: Likewise.
-	* testsuite/libffi.call/cls_2byte.c: Likewise.
-	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_3byte1.c: Likewise.
-	* testsuite/libffi.call/cls_3byte2.c: Likewise.
-	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_4byte.c: Likewise.
-	* testsuite/libffi.call/cls_5byte.c: Likewise.
-	* testsuite/libffi.call/cls_64byte.c: Likewise.
-	* testsuite/libffi.call/cls_6byte.c: Likewise.
-	* testsuite/libffi.call/cls_7byte.c: Likewise.
-	* testsuite/libffi.call/cls_8byte.c: Likewise.
-	* testsuite/libffi.call/cls_9byte1.c: Likewise.
-	* testsuite/libffi.call/cls_9byte2.c: Likewise.
-	* testsuite/libffi.call/cls_double.c: Likewise.
-	* testsuite/libffi.call/cls_float.c: Likewise.
-	* testsuite/libffi.call/cls_schar.c: Likewise.
-	* testsuite/libffi.call/cls_sint.c: Likewise.
-	* testsuite/libffi.call/cls_sshort.c: Likewise.
-	* testsuite/libffi.call/cls_uchar.c: Likewise.
-	* testsuite/libffi.call/cls_uint.c: Likewise.
-	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
-	* testsuite/libffi.call/cls_ushort.c: Likewise.
-	* testsuite/libffi.call/problem1.c: Likewise.
-
-	* testsuite/libffi.special/unwindtest.cc: Make ffi_closure
-	static.
-
-2003-11-08  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/cls_9byte2.c: New test case.
-	* testsuite/libffi.call/cls_9byte1.c: Likewise.
-	* testsuite/libffi.call/cls_64byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte1.c: Likewise.
-	* testsuite/libffi.call/cls_19byte.c: Likewise.
-	* testsuite/libffi.call/cls_18byte.c: Likewise.
-	* testsuite/libffi.call/closure_fn4.c: Likewise.
-	* testsuite/libffi.call/closure_fn5.c: Likewise.
-	* testsuite/libffi.call/cls_schar.c: Likewise.
-	* testsuite/libffi.call/cls_sint.c: Likewise.
-	* testsuite/libffi.call/cls_sshort.c: Likewise.
-	* testsuite/libffi.call/nested_struct2.c: Likewise.
-	* testsuite/libffi.call/nested_struct3.c: Likewise.
-
-2003-11-08  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/cls_double.c: Do a check on the result.
-	* testsuite/libffi.call/cls_uchar.c: Likewise.
-	* testsuite/libffi.call/cls_uint.c: Likewise.
-	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
-	* testsuite/libffi.call/cls_ushort.c: Likewise.
-	* testsuite/libffi.call/return_sc.c: Cleanup whitespaces.
-
-2003-11-06  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/prep_cif.c (ffi_prep_cif): Move the validity check after
-	the initialization.
-
-2003-10-23  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/java_raw_api.c (ffi_java_ptrarray_to_raw): Replace
-	FFI_ASSERT(FALSE) with FFI_ASSERT(0).
-
-2003-10-22  David Daney  <ddaney@avtrex.com>
-
-	* src/mips/ffitarget.h: Replace undefined UINT32 and friends with
-	__attribute__((__mode__(__SI__))) and friends.
-
-2003-10-22  Andreas Schwab  <schwab@suse.de>
-
-	* src/ia64/ffi.c: Replace FALSE/TRUE with false/true.
-
-2003-10-21  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* configure.in: AC_LINK_FILES(ffitarget.h).
-	* configure: Regenerate.
-	* Makefile.in: Likewise.
-	* include/Makefile.in: Likewise.
-	* testsuite/Makefile.in: Likewise.
-	* fficonfig.h.in: Likewise.
-
-2003-10-21  Paolo Bonzini  <bonzini@gnu.org>
-	    Richard Henderson  <rth@redhat.com>
-
-	Avoid that ffi.h includes fficonfig.h.
-
-	* Makefile.am (EXTRA_DIST): Include ffitarget.h files
-	(TARGET_SRC_MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX.
-	(TARGET_SRC_MIPS_SGI): Removed.
-	(MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX.
-	(MIPS_SGI): Removed.
-	(CLEANFILES): Removed.
-	(mostlyclean-am, clean-am, mostlyclean-sub, clean-sub): New
-	targets.
-	* acconfig.h: Removed.
-	* configure.in: Compute sizeofs only for double and long double.
-	Use them to define and subst HAVE_LONG_DOUBLE.  Include comments
-	into AC_DEFINE instead of using acconfig.h.  Create
-	include/ffitarget.h instead of include/fficonfig.h.  Rename
-	MIPS_GCC to MIPS_IRIX, drop MIPS_SGI since we are in gcc's tree.
-	AC_DEFINE EH_FRAME_FLAGS.
-	* include/Makefile.am (DISTCLEANFILES): New automake macro.
-	(hack_DATA): Add ffitarget.h.
-	* include/ffi.h.in: Remove all system specific definitions.
-	Declare raw API even if it is not installed, why bother?
-	Use limits.h instead of SIZEOF_* to define ffi_type_*.  Do
-	not define EH_FRAME_FLAGS, it is in fficonfig.h now.  Include
-	ffitarget.h instead of fficonfig.h.  Remove ALIGN macro.
-	(UINT_ARG, INT_ARG): Removed, use ffi_arg and ffi_sarg instead.
-	* include/ffi_common.h (bool): Do not define.
-	(ffi_assert): Accept failed assertion.
-	(ffi_type_test): Return void and accept file/line.
-	(FFI_ASSERT): Pass stringized failed assertion.
-	(FFI_ASSERT_AT): New macro.
-	(FFI_ASSERT_VALID_TYPE): New macro.
-	(UINT8, SINT8, UINT16, SINT16, UINT32, SINT32,
-	UINT64, SINT64): Define here with gcc's __attribute__ macro
-	instead of in ffi.h
-	(FLOAT32, ALIGN): Define here instead of in ffi.h
-	* include/ffi-mips.h: Removed.  Its content moved to
-	src/mips/ffitarget.h after separating assembly and C sections.
-	* src/alpha/ffi.c, src/alpha/ffi.c, src/java_raw_api.c
-	src/prep_cif.c, src/raw_api.c, src/ia64/ffi.c,
-	src/mips/ffi.c, src/mips/n32.S, src/mips/o32.S,
-	src/mips/ffitarget.h, src/sparc/ffi.c, src/x86/ffi64.c:
-	SIZEOF_ARG -> FFI_SIZEOF_ARG.
-	* src/ia64/ffi.c: Include stdbool.h (provided by GCC 2.95+).
-	* src/debug.c (ffi_assert): Accept stringized failed assertion.
-	(ffi_type_test): Rewritten.
-	* src/prep-cif.c (initialize_aggregate, ffi_prep_cif): Call
-	FFI_ASSERT_VALID_TYPE.
-	* src/alpha/ffitarget.h, src/arm/ffitarget.h,
-	src/ia64/ffitarget.h, src/m68k/ffitarget.h,
-	src/mips/ffitarget.h, src/powerpc/ffitarget.h,
-	src/s390/ffitarget.h, src/sh/ffitarget.h,
-	src/sh64/ffitarget.h, src/sparc/ffitarget.h,
-	src/x86/ffitarget.h: New files.
-	* src/alpha/osf.S, src/arm/sysv.S, src/ia64/unix.S,
-	src/m68k/sysv.S, src/mips/n32.S, src/mips/o32.S,
-	src/powerpc/aix.S, src/powerpc/darwin.S,
-	src/powerpc/ffi_darwin.c, src/powerpc/linux64.S,
-	src/powerpc/linux64_closure.S, src/powerpc/ppc_closure.S,
-	src/powerpc/sysv.S, src/s390/sysv.S, src/sh/sysv.S,
-	src/sh64/sysv.S, src/sparc/v8.S, src/sparc/v9.S,
-	src/x86/sysv.S, src/x86/unix64.S, src/x86/win32.S:
-	include fficonfig.h
-
-2003-10-20  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* src/mips/ffi.c: Use _ABIN32, _ABIO32 instead of external
-	_MIPS_SIM_NABI32, _MIPS_SIM_ABI32.
-
-2003-10-19  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Declare bytes again.
-	Used when FFI_DEBUG = 1.
-
-2003-10-14  Alan Modra  <amodra@bigpond.net.au>
-
-	* src/types.c (double, longdouble): Default POWERPC64 to 8 byte size
-	and align.
-
-2003-10-06  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* include/ffi_mips.h: Define FFI_MIPS_N32 for N32/N64 ABIs,
-	FFI_MIPS_O32 for O32 ABI.
-
-2003-10-01  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_64 for
-	SPARC64. Cleanup whitespaces.
-
-2003-09-19  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* testsuite/libffi.call/closure_fn0.c: Xfail mips, arm,
-	strongarm, xscale. Cleanup whitespaces.
-	* testsuite/libffi.call/closure_fn1.c: Likewise.
-	* testsuite/libffi.call/closure_fn2.c: Likewise.
-	* testsuite/libffi.call/closure_fn3.c: Likewise.
-	* testsuite/libffi.call/cls_12byte.c: Likewise.
-	* testsuite/libffi.call/cls_16byte.c: Likewise.
-	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte.c: Likewise.
-	* testsuite/libffi.call/cls_24byte.c: Likewise.
-	* testsuite/libffi.call/cls_2byte.c: Likewise.
-	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_3byte1.c: Likewise.
-	* testsuite/libffi.call/cls_3byte2.c: Likewise.
-	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_4byte.c: Likewise.
-	* testsuite/libffi.call/cls_5byte.c: Likewise.
-	* testsuite/libffi.call/cls_6byte.c: Likewise.
-	* testsuite/libffi.call/cls_7byte.c: Likewise.
-	* testsuite/libffi.call/cls_8byte.c: Likewise.
-	* testsuite/libffi.call/cls_double.c: Likewise.
-	* testsuite/libffi.call/cls_float.c: Likewise.
-	* testsuite/libffi.call/cls_uchar.c: Likewise.
-	* testsuite/libffi.call/cls_uint.c: Likewise.
-	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
-	* testsuite/libffi.call/cls_ushort.c: Likewise.
-	* testsuite/libffi.call/nested_struct.c: Likewise.
-	* testsuite/libffi.call/nested_struct1.c: Likewise.
-	* testsuite/libffi.call/problem1.c: Likewise.
-	* testsuite/libffi.special/unwindtest.cc: Likewise.
-	* testsuite/libffi.call/pyobjc-tc.c: Cleanup whitespaces.
-
-2003-09-18  David Edelsohn  <edelsohn@gnu.org>
-
-	* src/powerpc/aix.S: Cleanup whitespaces.
-	* src/powerpc/aix_closure.S: Likewise.
-
-2003-09-18  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/powerpc/darwin.S: Cleanup whitespaces, comment formatting.
-	* src/powerpc/darwin_closure.S: Likewise.
-	* src/powerpc/ffi_darwin.c: Likewise.
-
-2003-09-18  Andreas Tobler  <a.tobler@schweiz.ch>
-	    David Edelsohn  <edelsohn@gnu.org>
-
-	* src/types.c (double): Add AIX and Darwin to the right TYPEDEF.
-	* src/powerpc/aix_closure.S: Remove the pointer to the outgoing
-	parameter stack.
-	* src/powerpc/darwin_closure.S: Likewise.
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Handle structures
-	according to the Darwin/AIX ABI.
-	(ffi_prep_cif_machdep): Likewise.
-	(ffi_closure_helper_DARWIN): Likewise.
-	Remove the outgoing parameter stack logic. Simplify the evaluation
-	of the different CASE types.
-	(ffi_prep_clousure): Avoid the casts on lvalues. Change the branch
-	statement in the trampoline code.
-
-2003-09-18  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/ffi.c (ffi_prep_args): Take account into the alignement
-	for the register size.
-	(ffi_closure_helper_SYSV): Handle the structure return value
-	address correctly.
-	(ffi_closure_helper_SYSV): Return the appropriate type when
-	the registers are used for the structure return value.
-	* src/sh/sysv.S (ffi_closure_SYSV): Fix the stack layout for
-	the 64-bit return value.  Update copyright years.
-
-2003-09-17  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* testsuite/lib/libffi-dg.exp (libffi_target_compile): Search in
-	srcdir for ffi_mips.h.
-
-2003-09-12  Alan Modra  <amodra@bigpond.net.au>
-
-	* src/prep_cif.c (initialize_aggregate): Include tail padding in
-	structure size.
-	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct
-	placement of float result.
-	* testsuite/libffi.special/unwindtest.cc (closure_test_fn1): Correct
-	cast of "resp" for big-endian 64 bit machines.
-
-2003-09-11  Alan Modra  <amodra@bigpond.net.au>
-
-	* src/types.c (double, longdouble): Merge identical SH and ARM
-	typedefs, and add POWERPC64.
-	* src/powerpc/ffi.c (ffi_prep_args64): Correct next_arg calc for
-	struct split over gpr and rest.
-	(ffi_prep_cif_machdep): Correct intarg_count for structures.
-	* src/powerpc/linux64.S (ffi_call_LINUX64): Fix gpr offsets.
-
-2003-09-09  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/powerpc/ffi.c (ffi_closure_helper_SYSV) Handle struct
-	passing correctly.
-
-2003-09-09  Alan Modra  <amodra@bigpond.net.au>
-
-	* configure: Regenerate.
-
-2003-09-04  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* Makefile.am: Remove build rules for ffitest.
-	* Makefile.in: Rebuilt.
-
-2003-09-04  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/java_raw_api.c: Include <stdlib.h> to fix compiler warning
-	about implicit declaration of abort().
-
-2003-09-04  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* Makefile.am: Add dejagnu test framework. Fixes PR other/11411.
-	* Makefile.in: Rebuilt.
-	* configure.in: Add dejagnu test framework.
-	* configure: Rebuilt.
-
-	* testsuite/Makefile.am: New file.
-	* testsuite/Makefile.in: Built
-	* testsuite/lib/libffi-dg.exp: New file.
-	* testsuite/config/default.exp: Likewise.
-	* testsuite/libffi.call/call.exp: Likewise.
-	* testsuite/libffi.call/ffitest.h: Likewise.
-	* testsuite/libffi.call/closure_fn0.c: Likewise.
-	* testsuite/libffi.call/closure_fn1.c: Likewise.
-	* testsuite/libffi.call/closure_fn2.c: Likewise.
-	* testsuite/libffi.call/closure_fn3.c: Likewise.
-	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
-	* testsuite/libffi.call/cls_2byte.c: Likewise.
-	* testsuite/libffi.call/cls_3byte1.c: Likewise.
-	* testsuite/libffi.call/cls_3byte2.c: Likewise.
-	* testsuite/libffi.call/cls_4byte.c: Likewise.
-	* testsuite/libffi.call/cls_5byte.c: Likewise.
-	* testsuite/libffi.call/cls_6byte.c: Likewise.
-	* testsuite/libffi.call/cls_7byte.c: Likewise.
-	* testsuite/libffi.call/cls_8byte.c: Likewise.
-	* testsuite/libffi.call/cls_12byte.c: Likewise.
-	* testsuite/libffi.call/cls_16byte.c: Likewise.
-	* testsuite/libffi.call/cls_20byte.c: Likewise.
-	* testsuite/libffi.call/cls_24byte.c: Likewise.
-	* testsuite/libffi.call/cls_double.c: Likewise.
-	* testsuite/libffi.call/cls_float.c: Likewise.
-	* testsuite/libffi.call/cls_uchar.c: Likewise.
-	* testsuite/libffi.call/cls_uint.c: Likewise.
-	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
-	* testsuite/libffi.call/cls_ushort.c: Likewise.
-	* testsuite/libffi.call/float.c: Likewise.
-	* testsuite/libffi.call/float1.c: Likewise.
-	* testsuite/libffi.call/float2.c: Likewise.
-	* testsuite/libffi.call/many.c: Likewise.
-	* testsuite/libffi.call/many_win32.c: Likewise.
-	* testsuite/libffi.call/nested_struct.c: Likewise.
-	* testsuite/libffi.call/nested_struct1.c: Likewise.
-	* testsuite/libffi.call/pyobjc-tc.c: Likewise.
-	* testsuite/libffi.call/problem1.c: Likewise.
-	* testsuite/libffi.call/promotion.c: Likewise.
-	* testsuite/libffi.call/return_ll.c: Likewise.
-	* testsuite/libffi.call/return_sc.c: Likewise.
-	* testsuite/libffi.call/return_uc.c: Likewise.
-	* testsuite/libffi.call/strlen.c: Likewise.
-	* testsuite/libffi.call/strlen_win32.c: Likewise.
-	* testsuite/libffi.call/struct1.c: Likewise.
-	* testsuite/libffi.call/struct2.c: Likewise.
-	* testsuite/libffi.call/struct3.c: Likewise.
-	* testsuite/libffi.call/struct4.c: Likewise.
-	* testsuite/libffi.call/struct5.c: Likewise.
-	* testsuite/libffi.call/struct6.c: Likewise.
-	* testsuite/libffi.call/struct7.c: Likewise.
-	* testsuite/libffi.call/struct8.c: Likewise.
-	* testsuite/libffi.call/struct9.c: Likewise.
-	* testsuite/libffi.special/special.exp: New file.
-	* testsuite/libffi.special/ffitestcxx.h: Likewise.
-	* testsuite/libffi.special/unwindtest.cc: Likewise.
-
-
-2003-08-13  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/ffi.c (OFS_INT16): Set 0 for little endian case.  Update
-	copyright years.
-
-2003-08-02  Alan Modra  <amodra@bigpond.net.au>
-
-	* src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc
-	structure passing.
-	(ffi_closure_helper_LINUX64): Likewise.
-	* src/powerpc/linux64.S: Remove code writing to parm save area.
-	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Use return
-	address in lr from ffi_closure_helper_LINUX64 call to calculate
-	table address.  Optimize function tail.
-
-2003-07-28  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/sparc/ffi.c: Handle all floating point registers.
-	* src/sparc/v9.S: Likewise. Fixes second part of PR target/11410.
-
-2003-07-11  Gerald Pfeifer  <pfeifer@dbai.tuwien.ac.at>
-
-	* README: Note that libffi is not part of GCC.  Update the project
-	URL and status.
-
-2003-06-19  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
-
-	* src/powerpc/ppc_closure.S: Include ffi.h.
-
-2003-06-13  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* src/x86/sysv.S: Avoid gas-only .uleb128/.sleb128 directives.
-	Use C style comments.
-
-2003-06-13  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
-
-	* Makefile.am: Add SHmedia support.  Fix a typo of SH support.
-	* Makefile.in: Regenerate.
-	* configure.in (sh64-*-linux*, sh5*-*-linux*): Add target.
-	* configure: Regenerate.
-	* include/ffi.h.in: Add SHmedia support.
-	* src/sh64/ffi.c: New file.
-	* src/sh64/sysv.S: New file.
-
-2003-05-16  Jakub Jelinek  <jakub@redhat.com>
-
-	* configure.in (HAVE_RO_EH_FRAME): Check whether .eh_frame section
-	should be read-only.
-	* configure: Rebuilt.
-	* fficonfig.h.in: Rebuilt.
-	* include/ffi.h.in (EH_FRAME_FLAGS): Define.
-	* src/alpha/osf.S: Use EH_FRAME_FLAGS.
-	* src/powerpc/linux64.S: Likewise.
-	* src/powerpc/linux64_closure.S: Likewise.  Include ffi.h.
-	* src/powerpc/sysv.S: Use EH_FRAME_FLAGS.  Use pcrel encoding
-	if -fpic/-fPIC/-mrelocatable.
-	* src/powerpc/powerpc_closure.S: Likewise.
-	* src/sparc/v8.S: If HAVE_RO_EH_FRAME is defined, don't include
-	#write in .eh_frame flags.
-	* src/sparc/v9.S: Likewise.
-	* src/x86/unix64.S: Use EH_FRAME_FLAGS.
-	* src/x86/sysv.S: Likewise.  Use pcrel encoding if -fpic/-fPIC.
-	* src/s390/sysv.S: Use EH_FRAME_FLAGS.  Include ffi.h.
-
-2003-05-07  Jeff Sturm  <jsturm@one-point.com>
-
-	Fixes PR bootstrap/10656
-	* configure.in (HAVE_AS_REGISTER_PSEUDO_OP): Test assembler
-	support for .register pseudo-op.
-	* src/sparc/v8.S: Use it.
-	* fficonfig.h.in: Rebuilt.
-	* configure: Rebuilt.
-
-2003-04-18  Jakub Jelinek  <jakub@redhat.com>
-
-	* include/ffi.h.in (POWERPC64): Define if 64-bit.
-	(enum ffi_abi): Add FFI_LINUX64 on POWERPC.
-	Make it the default on POWERPC64.
-	(FFI_TRAMPOLINE_SIZE): Define to 24 on POWERPC64.
-	* configure.in: Change powerpc-*-linux* into powerpc*-*-linux*.
-	* configure: Rebuilt.
-	* src/powerpc/ffi.c (hidden): Define.
-	(ffi_prep_args_SYSV): Renamed from
-	ffi_prep_args.  Cast pointers to unsigned long to shut up warnings.
-	(NUM_GPR_ARG_REGISTERS64, NUM_FPR_ARG_REGISTERS64,
-	ASM_NEEDS_REGISTERS64): New.
-	(ffi_prep_args64): New function.
-	(ffi_prep_cif_machdep): Handle FFI_LINUX64 ABI.
-	(ffi_call): Likewise.
-	(ffi_prep_closure): Likewise.
-	(flush_icache): Surround by #ifndef POWERPC64.
-	(ffi_dblfl): New union type.
-	(ffi_closure_helper_SYSV): Use it to avoid aliasing problems.
-	(ffi_closure_helper_LINUX64): New function.
-	* src/powerpc/ppc_closure.S: Surround whole file by #ifndef
-	__powerpc64__.
-	* src/powerpc/sysv.S: Likewise.
-	(ffi_call_SYSV): Rename ffi_prep_args to ffi_prep_args_SYSV.
-	* src/powerpc/linux64.S: New file.
-	* src/powerpc/linux64_closure.S: New file.
-	* Makefile.am (EXTRA_DIST): Add src/powerpc/linux64.S and
-	src/powerpc/linux64_closure.S.
-	(TARGET_SRC_POWERPC): Likewise.
-
-	* src/ffitest.c (closure_test_fn, closure_test_fn1, closure_test_fn2,
-	closure_test_fn3): Fix result printing on big-endian 64-bit
-	machines.
-	(main): Print tst2_arg instead of uninitialized tst2_result.
-
-	* src/ffitest.c (main): Hide what closure pointer really points to
-	from the compiler.
-
-2003-04-16  Richard Earnshaw  <rearnsha@arm.com>
-
-	* configure.in (arm-*-netbsdelf*): Add configuration.
-	(configure): Regenerated.
-
-2003-04-04  Loren J. Rittle  <ljrittle@acm.org>
-
-	* include/Makefile.in: Regenerate.
-
-2003-03-21  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
-
-	* libffi/include/ffi.h.in: Define X86 instead of X86_64 in 32
-	bit mode.
-	* libffi/src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV):
-	Receive closure pointer through parameter, read args using
-	__builtin_dwarf_cfa.
-	(FFI_INIT_TRAMPOLINE): Send closure reference through eax.
-
-2003-03-12  Andreas Schwab  <schwab@suse.de>
-
-	* configure.in: Avoid trailing /. in toolexeclibdir.
-	* configure: Rebuilt.
-
-2003-03-03  Andreas Tobler <a.tobler@schweiz.ch>
-
-	* src/powerpc/darwin_closure.S: Recode to fit dynamic libraries.
-
-2003-02-06  Andreas Tobler <a.tobler@schweiz.ch>
-
-	* libffi/src/powerpc/darwin_closure.S:
-	Fix alignement bug, allocate 8 bytes for the result.
-	* libffi/src/powerpc/aix_closure.S:
-	Likewise.
-	* libffi/src/powerpc/ffi_darwin.c:
-	Update stackframe description for aix/darwin_closure.S.
-
-2003-02-06  Jakub Jelinek  <jakub@redhat.com>
-
-	* src/s390/ffi.c (ffi_closure_helper_SYSV): Add hidden visibility
-	attribute.
-
-2003-01-31  Christian Cornelssen  <ccorn@cs.tu-berlin.de>,
-	    Andreas Schwab  <schwab@suse.de>
-
-	* configure.in: Adjust command to source config-ml.in to account
-	for changes to the libffi_basedir definition.
-	(libffi_basedir): Remove ${srcdir} from value and include trailing
-	slash if nonempty.
-
-	* configure: Regenerate.
-
-2003-01-29  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
-
-	* src/powerpc/ppc_closure.S: Recode to fit shared libs.
-
-2003-01-28  Andrew Haley  <aph@redhat.com>
-
-	* include/ffi.h.in: Enable FFI_CLOSURES for x86_64.
-	* src/x86/ffi64.c (ffi_prep_closure): New.
-	(ffi_closure_UNIX64_inner): New.
-	* src/x86/unix64.S (ffi_closure_UNIX64): New.
-
-2003-01-27  Alexandre Oliva  <aoliva@redhat.com>
-
-	* configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST.
-	Remove USE_LIBDIR conditional.
-	* Makefile.am (toolexecdir, toolexeclibdir): Don't override.
-	* Makefile.in, configure: Rebuilt.
-
-2003-01027  David Edelsohn  <edelsohn@gnu.org>
-
-	* Makefile.am (TARGET_SRC_POWERPC_AIX): Fix typo.
-	* Makefile.in: Regenerate.
-
-2003-01-22  Andrew Haley  <aph@redhat.com>
-
-	* src/powerpc/darwin.S (_ffi_call_AIX): Add Augmentation size to
-	unwind info.
-
-2003-01-21  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/powerpc/darwin.S: Add unwind info.
-	* src/powerpc/darwin_closure.S: Likewise.
-
-2003-01-14  Andrew Haley  <aph@redhat.com>
-
-	* src/x86/ffi64.c (ffi_prep_args): Check for void retval.
-	(ffi_prep_cif_machdep): Likewise.
-	* src/x86/unix64.S: Add unwind info.
-
-2003-01-14  Andreas Jaeger  <aj@suse.de>
-
-	* src/ffitest.c (main): Only use ffi_closures if those are
-	supported.
-
-2003-01-13 Andreas Tobler <a.tobler@schweiz.ch>
-
-	* libffi/src/ffitest.c
-	 add closure testcases
-
-2003-01-13 Kevin B. Hendricks <khendricks@ivey.uwo.ca>
-
-	* libffi/src/powerpc/ffi.c
-	 fix alignment bug for float (4 byte aligned iso 8 byte)
-
-2003-01-09  Geoffrey Keating  <geoffk@apple.com>
-
-	* src/powerpc/ffi_darwin.c: Remove RCS version string.
-	* src/powerpc/darwin.S: Remove RCS version string.
-
-2003-01-03  Jeff Sturm  <jsturm@one-point.com>
-
-	* include/ffi.h.in: Add closure defines for SPARC, SPARC64.
-	* src/ffitest.c (main): Use static storage for closure.
-	* src/sparc/ffi.c (ffi_prep_closure, ffi_closure_sparc_inner): New.
-	* src/sparc/v8.S (ffi_closure_v8): New.
-	* src/sparc/v9.S (ffi_closure_v9): New.
-
-2002-11-10  Ranjit Mathew <rmathew@hotmail.com>
-
-	* include/ffi.h.in: Added FFI_STDCALL ffi_type
-	  enumeration for X86_WIN32.
-	* src/x86/win32.S: Added ffi_call_STDCALL function
-	  definition.
-	* src/x86/ffi.c (ffi_call/ffi_raw_call): Added
-	  switch cases for recognising FFI_STDCALL and
-	  calling ffi_call_STDCALL if target is X86_WIN32.
-	* src/ffitest.c (my_stdcall_strlen/stdcall_many):
-	  stdcall versions of the "my_strlen" and "many"
-	  test functions (for X86_WIN32).
-	  Added test cases to test stdcall invocation using
-	  these functions.
-
-2002-12-02  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/sysv.S: Add DWARF2 unwind info.
-
-2002-11-27  Ulrich Weigand  <uweigand@de.ibm.com>
-
-	* src/s390/sysv.S (.eh_frame section): Make section read-only.
-
-2002-11-26  Jim Wilson  <wilson@redhat.com>
-
-	* src/types.c (FFI_TYPE_POINTER): Has size 8 on IA64.
-
-2002-11-23  H.J. Lu <hjl@gnu.org>
-
-	* acinclude.m4: Add dummy AM_PROG_LIBTOOL.
-	Include ../config/accross.m4.
-	* aclocal.m4; Rebuild.
-	* configure: Likewise.
-
-2002-11-15  Ulrich Weigand  <uweigand@de.ibm.com>
-
-	* src/s390/sysv.S (.eh_frame section): Adapt to pcrel FDE encoding.
-
-2002-11-11  DJ Delorie  <dj@redhat.com>
-
-	* configure.in: Look for common files in the right place.
-
-2002-10-08  Ulrich Weigand  <uweigand@de.ibm.com>
-
-	* src/java_raw_api.c (ffi_java_raw_to_ptrarray): Interpret
-	raw data as _Jv_word values, not ffi_raw.
-	(ffi_java_ptrarray_to_raw): Likewise.
-	(ffi_java_rvalue_to_raw): New function.
-	(ffi_java_raw_call): Call it.
-	(ffi_java_raw_to_rvalue): New function.
-	(ffi_java_translate_args): Call it.
-	* src/ffitest.c (closure_test_fn): Interpret return value
-	as ffi_arg, not int.
-	* src/s390/ffi.c (ffi_prep_cif_machdep): Add missing
-	FFI_TYPE_POINTER case.
-	(ffi_closure_helper_SYSV): Likewise.  Also, assume return
-	values extended to word size.
-
-2002-10-02  Andreas Jaeger  <aj@suse.de>
-
-	* src/x86/ffi64.c (ffi_prep_cif_machdep): Remove debug output.
-
-2002-10-01  Bo Thorsen  <bo@smetana.suse.de>
-
-	* include/ffi.h.in: Fix i386 win32 compilation.
-
-2002-09-30  Ulrich Weigand  <uweigand@de.ibm.com>
-
-	* configure.in: Add s390x-*-linux-* target.
-	* configure: Regenerate.
-	* include/ffi.h.in: Define S390X for s390x targets.
-	(FFI_CLOSURES): Define for s390/s390x.
-	(FFI_TRAMPOLINE_SIZE): Likewise.
-	(FFI_NATIVE_RAW_API): Likewise.
-	* src/prep_cif.c (ffi_prep_cif): Do not compute stack space for s390.
-	* src/types.c (FFI_TYPE_POINTER): Use 8-byte pointers on s390x.
-	* src/s390/ffi.c: Major rework of existing code.  Add support for
-	s390x targets.  Add closure support.
-	* src/s390/sysv.S: Likewise.
-
-2002-09-29  Richard Earnshaw  <rearnsha@arm.com>
-
-	* src/arm/sysv.S: Fix typo.
-
-2002-09-28  Richard Earnshaw  <rearnsha@arm.com>
-
-	* src/arm/sysv.S: If we don't have machine/asm.h and the pre-processor
-	has defined __USER_LABEL_PREFIX__, then use it in CNAME.
-	(ffi_call_SYSV): Handle soft-float.
-
-2002-09-27  Bo Thorsen  <bo@suse.de>
-
-	* include/ffi.h.in: Fix multilib x86-64 support.
-
-2002-09-22  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
-
-	* Makefile.am (all-multi): Fix multilib parallel build.
-
-2002-07-19  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* configure.in (sh[34]*-*-linux*): Add brackets.
-	* configure: Regenerate.
-
-2002-07-18  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* Makefile.am: Add SH support.
-	* Makefile.in: Regenerate.
-	* configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target.
-	* configure: Regenerate.
-	* include/ffi.h.in: Add SH support.
-	* src/sh/ffi.c: New file.
-	* src/sh/sysv.S: New file.
-	* src/types.c: Add SH support.
-
-2002-07-16  Bo Thorsen  <bo@suse.de>
-
-	* src/x86/ffi64.c: New file that adds x86-64 support.
-	* src/x86/unix64.S: New file that handles argument setup for
-	x86-64.
-	* src/x86/sysv.S: Don't use this on x86-64.
-	* src/x86/ffi.c: Don't use this on x86-64.
-	Remove unused vars.
-	* src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation
-	for x86-64.
-	* src/ffitest.c (struct6): New test that tests a special case in
-	the x86-64 ABI.
-	(struct7): Likewise.
-	(struct8): Likewise.
-	(struct9): Likewise.
-	(closure_test_fn): Silence warning about this when it's not used.
-	(main): Add the new tests.
-	(main): Fix a couple of wrong casts and silence some compiler warnings.
-	* include/ffi.h.in: Add x86-64 ABI definition.
-	* fficonfig.h.in: Regenerate.
-	* Makefile.am: Add x86-64 support.
-	* configure.in: Likewise.
-	* Makefile.in: Regenerate.
-	* configure: Likewise.
-
-2002-06-24  Bo Thorsen  <bo@suse.de>
-
-	* src/types.c: Merge settings for similar architectures.
-	Add x86-64 sizes and alignments.
-
-2002-06-23  Bo Thorsen  <bo@suse.de>
-
-	* src/arm/ffi.c (ffi_prep_args): Remove unused vars.
-	* src/sparc/ffi.c (ffi_prep_args_v8): Likewise.
-	* src/mips/ffi.c (ffi_prep_args): Likewise.
-	* src/m68k/ffi.c (ffi_prep_args): Likewise.
-
-2002-07-18  H.J. Lu  (hjl@gnu.org)
-
-	* Makefile.am (TARGET_SRC_MIPS_LINUX): New.
-	(libffi_la_SOURCES): Support MIPS_LINUX.
-	(libffi_convenience_la_SOURCES): Likewise.
-	* Makefile.in: Regenerated.
-
-	* configure.in (mips64*-*): Skip.
-	(mips*-*-linux*): New.
-	* configure: Regenerated.
-
-	* src/mips/ffi.c: Include <sgidefs.h>.
-
-2002-06-06  Ulrich Weigand  <uweigand@de.ibm.com>
-
-	* src/s390/sysv.S: Save/restore %r6.  Add DWARF-2 unwind info.
-
-2002-05-27  Roger Sayle  <roger@eyesopen.com>
-
-	* src/x86/ffi.c (ffi_prep_args): Remove reference to avn.
-
-2002-05-27  Bo Thorsen  <bo@suse.de>
-
-	* src/x86/ffi.c (ffi_prep_args): Remove unused variable and
-	fix formatting.
-
-2002-05-13  Andreas Tobler  <a.tobler@schweiz.ch>
-
-	* src/powerpc/ffi_darwin.c (ffi_prep_closure): Declare fd at
-	beginning of function (for older apple cc).
-
-2002-05-08  Alexandre Oliva  <aoliva@redhat.com>
-
-	* configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at
-	script entry, and set LD to it when configuring multilibs.
-	* configure: Rebuilt.
-
-2002-05-05  Jason Thorpe  <thorpej@wasabisystems.com>
-
-	* configure.in (sparc64-*-netbsd*): Add target.
-	(sparc-*-netbsdelf*): Likewise.
-	* configure: Regenerate.
-
-2002-04-28  David S. Miller  <davem@redhat.com>
-
-	* configure.in, configure: Fix SPARC test in previous change.
-
-2002-04-29  Gerhard Tonn  <GerhardTonn@swol.de>
-
-	* Makefile.am: Add Linux for S/390 support.
-	* Makefile.in: Regenerate.
-	* configure.in: Add Linux for S/390 support.
-	* configure: Regenerate.
-	* include/ffi.h.in: Add Linux for S/390 support.
-	* src/s390/ffi.c: New file from libffi CVS tree.
-	* src/s390/sysv.S: New file from libffi CVS tree.
-
-2002-04-28  Jakub Jelinek  <jakub@redhat.com>
-
-	* configure.in (HAVE_AS_SPARC_UA_PCREL): Check for working
-	%r_disp32().
-	* src/sparc/v8.S: Use it.
-	* src/sparc/v9.S: Likewise.
-	* fficonfig.h.in: Rebuilt.
-	* configure: Rebuilt.
-
-2002-04-08  Hans Boehm  <Hans_Boehm@hp.com>
-
-	* src/java_raw_api.c (ffi_java_raw_size): Handle FFI_TYPE_DOUBLE
-	correctly.
-	* src/ia64/unix.S: Add unwind information. Fix comments.
-	Save sp in a way that's compatible with unwind info.
-	(ffi_call_unix): Correctly restore sp in all cases.
-	* src/ia64/ffi.c: Add, fix comments.
-
-2002-04-08  Jakub Jelinek  <jakub@redhat.com>
-
-	* src/sparc/v8.S: Make .eh_frame dependent on target word size.
-
-2002-04-06  Jason Thorpe  <thorpej@wasabisystems.com>
-
-	* configure.in (alpha*-*-netbsd*): Add target.
-	* configure: Regenerate.
-
-2002-04-04  Jeff Sturm  <jsturm@one-point.com>
-
-	* src/sparc/v8.S: Add unwind info.
-	* src/sparc/v9.S: Likewise.
-
-2002-03-30  Krister Walfridsson  <cato@df.lth.se>
-
-	* configure.in: Enable i*86-*-netbsdelf*.
-	* configure: Rebuilt.
-
-2002-03-29  David Billinghurst <David.Billinghurst@riotinto.com>
-
-	PR other/2620
-	* src/mips/n32.s: Delete
-	* src/mips/o32.s: Delete
-
-2002-03-21  Loren J. Rittle  <ljrittle@acm.org>
-
-	* configure.in: Enable alpha*-*-freebsd*.
-	* configure: Rebuilt.
-
-2002-03-17  Bryce McKinlay  <bryce@waitaki.otago.ac.nz>
-
-	* Makefile.am: libfficonvenience -> libffi_convenience.
-	* Makefile.in: Rebuilt.
-
-	* Makefile.am: Define ffitest_OBJECTS.
-	* Makefile.in: Rebuilt.
-
-2002-03-07  Andreas Tobler  <toa@pop.agri.ch>
-	    David Edelsohn  <edelsohn@gnu.org>
-
-	* Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files.
-	(TARGET_SRC_POWERPC_AIX): Add aix_closure.S.
-	(TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S.
-	* Makefile.in: Regenerate.
-	* include/ffi.h.in: Add AIX and Darwin closure definitions.
-	* src/powerpc/ffi_darwin.c (ffi_prep_closure): New function.
-	(flush_icache, flush_range): New functions.
-	(ffi_closure_helper_DARWIN): New function.
-	* src/powerpc/aix_closure.S: New file.
-	* src/powerpc/darwin_closure.S: New file.
-
-2002-02-24  Jeff Sturm  <jsturm@one-point.com>
-
-	* include/ffi.h.in: Add typedef for ffi_arg.
-	* src/ffitest.c (main): Declare rint with ffi_arg.
-
-2002-02-21  Andreas Tobler  <toa@pop.agri.ch>
-
-	* src/powerpc/ffi_darwin.c (ffi_prep_args): Skip appropriate
-	number of GPRs for floating-point arguments.
-
-2002-01-31  Anthony Green  <green@redhat.com>
-
-	* configure: Rebuilt.
-	* configure.in: Replace CHECK_SIZEOF and endian tests with
-	cross-compiler friendly macros.
-	* aclocal.m4 (AC_COMPILE_CHECK_SIZEOF, AC_C_BIGENDIAN_CROSS): New
-	macros.
-
-2002-01-18  David Edelsohn  <edelsohn@gnu.org>
-
-	* src/powerpc/darwin.S (_ffi_call_AIX): New.
-	* src/powerpc/aix.S (ffi_call_DARWIN): New.
-
-2002-01-17  David Edelsohn  <edelsohn@gnu.org>
-
-	* Makefile.am (EXTRA_DIST): Add Darwin and AIX files.
-	(TARGET_SRC_POWERPC_AIX): New.
-	(POWERPC_AIX): New stanza.
-	* Makefile.in: Regenerate.
-	* configure.in: Add AIX case.
-	* configure: Regenerate.
-	* include/ffi.h.in (ffi_abi): Add FFI_AIX.
-	* src/powerpc/ffi_darwin.c (ffi_status): Use "long" to scale frame
-	size.  Fix "long double" support.
-	(ffi_call): Add FFI_AIX case.
-	* src/powerpc/aix.S: New.
-
-2001-10-09  John Hornkvist  <john@toastedmarshmallow.com>
-
-	Implement Darwin PowerPC ABI.
-	* configure.in: Handle powerpc-*-darwin*.
-	* Makefile.am: Set source files for POWERPC_DARWIN.
-	* configure: Rebuilt.
-	* Makefile.in: Rebuilt.
-	* include/ffi.h.in: Define FFI_DARWIN and FFI_DEFAULT_ABI for
-	POWERPC_DARWIN.
-	* src/powerpc/darwin.S: New file.
-	* src/powerpc/ffi_darwin.c: New file.
-
-2001-10-07  Joseph S. Myers  <jsm28@cam.ac.uk>
-
-	* src/x86/ffi.c: Fix spelling error of "separate" as "seperate".
-
-2001-07-16  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* src/x86/sysv.S: Avoid gas-only .balign directive.
-	Use C style comments.
-
-2001-07-16  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* src/alpha/ffi.c (ffi_prep_closure): Avoid gas-only mnemonic.
-	Fixes PR bootstrap/3563.
-
-2001-06-26  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* src/alpha/osf.S (ffi_closure_osf): Use .rdata for ECOFF.
-
-2001-06-25  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* configure.in: Recognize sparc*-sun-* host.
-	* configure: Regenerate.
-
-2001-06-06  Andrew Haley  <aph@redhat.com>
-
-	* src/alpha/osf.S (__FRAME_BEGIN__): Conditionalize for ELF.
-
-2001-06-03  Andrew Haley  <aph@redhat.com>
-
-	* src/alpha/osf.S: Add unwind info.
-	* src/powerpc/sysv.S: Add unwind info.
-	* src/powerpc/ppc_closure.S: Likewise.
-
-2000-05-31  Jeff Sturm  <jsturm@one-point.com>
-
-	* configure.in: Fix AC_ARG_ENABLE usage.
-	* configure: Rebuilt.
-
-2001-05-06  Bryce McKinlay  <bryce@waitaki.otago.ac.nz>
-
-	* configure.in: Remove warning about beta code.
-	* configure: Rebuilt.
-
-2001-04-25  Hans Boehm <Hans_Boehm@hp.com>
-
-	* src/ia64/unix.S: Restore stack pointer when returning from
-	ffi_closure_UNIX.
-	* src/ia64/ffi.c: Fix typo in comment.
-
-2001-04-18  Jim Wilson  <wilson@redhat.com>
-
-	* src/ia64/unix.S: Delete unnecessary increment and decrement of loc2
-	to eliminate RAW DV.
-
-2001-04-12  Bryce McKinlay  <bryce@albatross.co.nz>
-
-	* Makefile.am: Make a libtool convenience library.
-	* Makefile.in: Rebuilt.
-
-2001-03-29  Bryce McKinlay  <bryce@albatross.co.nz>
-
-	* configure.in: Use different syntax for subdirectory creation.
-	* configure: Rebuilt.
-
-2001-03-27  Jon Beniston  <jon@beniston.com>
-
-	* configure.in: Added X86_WIN32 target (Win32, CygWin, MingW).
-	* configure: Rebuilt.
-	* Makefile.am: Added X86_WIN32 target support.
-	* Makefile.in: Rebuilt.
-
-	* include/ffi.h.in: Added X86_WIN32 target support.
-
-	* src/ffitest.c: Doesn't run structure tests for X86_WIN32 targets.
-	* src/types.c: Added X86_WIN32 target support.
-
-	* src/x86/win32.S: New file. Based on sysv.S, but with EH
-	stuff removed and made to work with CygWin's gas.
-
-2001-03-26  Bryce McKinlay  <bryce@albatross.co.nz>
-
-	* configure.in: Make target subdirectory in build dir.
-	* Makefile.am: Override suffix based rules to specify correct output
-	subdirectory.
-	* Makefile.in: Rebuilt.
-	* configure: Rebuilt.
-
-2001-03-23  Kevin B Hendricks  <khendricks@ivey.uwo.ca>
-
-	* src/powerpc/ppc_closure.S: New file.
-	* src/powerpc/ffi.c (ffi_prep_args): Fixed ABI compatibility bug
-	involving long long and register pairs.
-	(ffi_prep_closure): New function.
-	(flush_icache): Likewise.
-	(ffi_closure_helper_SYSV): Likewise.
-	* include/ffi.h.in (FFI_CLOSURES): Define on PPC.
-	(FFI_TRAMPOLINE_SIZE): Likewise.
-	(FFI_NATIVE_RAW_API): Likewise.
-	* Makefile.in: Rebuilt.
-	* Makefile.am (EXTRA_DIST): Added src/powerpc/ppc_closure.S.
-	(TARGET_SRC_POWERPC): Likewise.
-
-2001-03-19  Tom Tromey  <tromey@redhat.com>
-
-	* Makefile.in: Rebuilt.
-	* Makefile.am (ffitest_LDFLAGS): New macro.
-
-2001-03-02  Nick Clifton  <nickc@redhat.com>
-
-	* include/ffi.h.in: Remove RCS ident string.
-	* include/ffi_mips.h: Remove RCS ident string.
-	* src/debug.c: Remove RCS ident string.
-	* src/ffitest.c: Remove RCS ident string.
-	* src/prep_cif.c: Remove RCS ident string.
-	* src/types.c: Remove RCS ident string.
-	* src/alpha/ffi.c: Remove RCS ident string.
-	* src/alpha/osf.S: Remove RCS ident string.
-	* src/arm/ffi.c: Remove RCS ident string.
-	* src/arm/sysv.S: Remove RCS ident string.
-	* src/mips/ffi.c: Remove RCS ident string.
-	* src/mips/n32.S: Remove RCS ident string.
-	* src/mips/o32.S: Remove RCS ident string.
-	* src/sparc/ffi.c: Remove RCS ident string.
-	* src/sparc/v8.S: Remove RCS ident string.
-	* src/sparc/v9.S: Remove RCS ident string.
-	* src/x86/ffi.c: Remove RCS ident string.
-	* src/x86/sysv.S: Remove RCS ident string.
-
-2001-02-08  Joseph S. Myers  <jsm28@cam.ac.uk>
-
-	* include/ffi.h.in: Change sourceware.cygnus.com references to
-	gcc.gnu.org.
-
-2000-12-09  Richard Henderson  <rth@redhat.com>
-
-	* src/alpha/ffi.c (ffi_call): Simplify struct return test.
-	(ffi_closure_osf_inner): Index rather than increment avalue
-	and arg_types.  Give ffi_closure_osf the raw return value type.
-	* src/alpha/osf.S (ffi_closure_osf): Handle return value type
-	promotion.
-
-2000-12-07  Richard Henderson  <rth@redhat.com>
-
-	* src/raw_api.c (ffi_translate_args): Fix typo.
-	(ffi_prep_closure): Likewise.
-
-	* include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and
-	FFI_TRAMPOLINE_SIZE.
-	* src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal
-	cif->bytes for new ffi_call_osf implementation.
-	(ffi_prep_args): Absorb into ...
-	(ffi_call): ... here.  Do all stack allocation here and
-	avoid a callback function.
-	(ffi_prep_closure, ffi_closure_osf_inner): New.
-	* src/alpha/osf.S (ffi_call_osf): Reimplement with no callback.
-	(ffi_closure_osf): New.
-
-2000-09-10  Alexandre Oliva  <aoliva@redhat.com>
-
-	* config.guess, config.sub, install-sh: Removed.
-	* ltconfig, ltmain.sh, missing, mkinstalldirs: Likewise.
-	* Makefile.in: Rebuilt.
-
-	* acinclude.m4: Include libtool macros from the top level.
-	* aclocal.m4, configure: Rebuilt.
-
-2000-08-22  Alexandre Oliva  <aoliva@redhat.com>
-
-	* configure.in [i*86-*-freebsd*] (TARGET, TARGETDIR): Set.
-	* configure: Rebuilt.
-
-2000-05-11  Scott Bambrough  <scottb@netwinder.org>
-
-	* libffi/src/arm/sysv.S (ffi_call_SYSV): Doubles are not saved to
-	memory correctly.  Use conditional instructions, not branches where
-	possible.
-
-2000-05-04  Tom Tromey  <tromey@cygnus.com>
-
-	* configure: Rebuilt.
-	* configure.in: Match `arm*-*-linux-*'.
-	From Chris Dornan <cdornan@arm.com>.
-
-2000-04-28  Jakub Jelinek  <jakub@redhat.com>
-
-	* Makefile.am (SUBDIRS): Define.
-	(AM_MAKEFLAGS): Likewise.
-	(Multilib support.): Add section.
-	* Makefile.in: Rebuilt.
-	* ltconfig (extra_compiler_flags, extra_compiler_flags_value):
-	New variables. Set for gcc using -print-multi-lib. Export them
-	to libtool.
-	(sparc64-*-linux-gnu*): Use libsuff 64 for search paths.
-	* ltmain.sh (B|b|V): Don't throw away gcc's -B, -b and -V options
-	for -shared links.
-	(extra_compiler_flags_value, extra_compiler_flags): Check these
-	for extra compiler options which need to be passed down in
-	compiler_flags.
-
-2000-04-16  Anthony Green  <green@redhat.com>
-
-	* configure: Rebuilt.
-	* configure.in: Change i*86-pc-linux* to i*86-*-linux*.
-
-2000-04-14  Jakub Jelinek  <jakub@redhat.com>
-
-	* include/ffi.h.in (SPARC64): Define for 64bit SPARC builds.
-	Set SPARC FFI_DEFAULT_ABI based on SPARC64 define.
-	* src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args.
-	Replace all void * sizeofs with sizeof(int).
-	Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is
-	different than DOUBLE.
-	Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere).
-	(ffi_prep_args_v9): New function.
-	(ffi_prep_cif_machdep): Handle V9 ABI and long long on V8.
-	(ffi_V9_return_struct): New function.
-	(ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from
-	32bit code (not yet cross-arch calls).
-	* src/sparc/v8.S: Add struct return delay nop.
-	Handle long long.
-	* src/sparc/v9.S: New file.
-	* src/prep_cif.c (ffi_prep_cif): Return structure pointer
-	is used on sparc64 only for structures larger than 32 bytes.
-	Pass by reference for structures is done for structure arguments
-	larger than 16 bytes.
-	* src/ffitest.c (main): Use 64bit rint on sparc64.
-	Run long long tests on sparc.
-	* src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and
-	sparc64.
-	(FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits
-	on sparc64.
-	* configure.in (sparc-*-linux*): New supported target.
-	(sparc64-*-linux*): Likewise.
-	* configure: Rebuilt.
-	* Makefile.am: Add v9.S to SPARC files.
-	* Makefile.in: Likewise.
-	(LINK): Surround $(CCLD) into double quotes, so that multilib
-	compiles work correctly.
-
-2000-04-04  Alexandre Petit-Bianco  <apbianco@cygnus.com>
-
-	* configure: Rebuilt.
-	* configure.in: (i*86-*-solaris*): New libffi target. Patch
-	proposed by Bryce McKinlay.
-
-2000-03-20  Tom Tromey  <tromey@cygnus.com>
-
-	* Makefile.in: Hand edit for java_raw_api.lo.
-
-2000-03-08  Bryce McKinlay  <bryce@albatross.co.nz>
-
-	* config.guess, config.sub: Update from the gcc tree.
-	Fix for PR libgcj/168.
-
-2000-03-03  Tom Tromey  <tromey@cygnus.com>
-
-	* Makefile.in: Fixed ia64 by hand.
-
-	* configure: Rebuilt.
-	* configure.in (--enable-multilib): New option.
-	(libffi_basedir): New subst.
-	(AC_OUTPUT): Added multilib code.
-
-2000-03-02  Tom Tromey  <tromey@cygnus.com>
-
-	* Makefile.in: Rebuilt.
-	* Makefile.am (TARGET_SRC_IA64): Use `ia64', not `alpha', as
-	directory name.
-
-2000-02-25  Hans Boehm <boehm@acm.org>
-
-	* src/ia64/ffi.c, src/ia64/ia64_flags.h, src/ia64/unix.S: New
-	files.
-	* src/raw_api.c (ffi_translate_args): Fixed typo in argument
-	list.
-	(ffi_prep_raw_closure): Use ffi_translate_args, not
-	ffi_closure_translate.
-	* src/java_raw_api.c: New file.
-	* src/ffitest.c (closure_test_fn): New function.
-	(main): Define `rint' as long long on IA64.  Added new test when
-	FFI_CLOSURES is defined.
-	* include/ffi.h.in (ALIGN): Use size_t, not unsigned.
-	(ffi_abi): Recognize IA64.
-	(ffi_raw): Added `flt' field.
-	Added "Java raw API" code.
-	* configure.in: Recognize ia64.
-	* Makefile.am (TARGET_SRC_IA64): New macro.
-	(libffi_la_common_SOURCES): Added java_raw_api.c.
-	(libffi_la_SOURCES): Define in IA64 case.
-
-2000-01-04  Tom Tromey  <tromey@cygnus.com>
-
-	* Makefile.in: Rebuilt with newer automake.
-
-1999-12-31  Tom Tromey  <tromey@cygnus.com>
-
-	* Makefile.am (INCLUDES): Added -I$(top_srcdir)/src.
-
-1999-09-01  Tom Tromey  <tromey@cygnus.com>
-
-	* include/ffi.h.in: Removed PACKAGE and VERSION defines and
-	undefs.
-	* fficonfig.h.in: Rebuilt.
-	* configure: Rebuilt.
-	* configure.in: Pass 3rd argument to AM_INIT_AUTOMAKE.
-	Use AM_PROG_LIBTOOL (automake 1.4 compatibility).
-	* acconfig.h: Don't #undef PACKAGE or VERSION.
-
-1999-08-09  Anthony Green  <green@cygnus.com>
-
-	* include/ffi.h.in: Try to work around messy header problem
-	with PACKAGE and VERSION.
-
-	* configure: Rebuilt.
-	* configure.in: Change version to 2.00-beta.
-
-	* fficonfig.h.in: Rebuilt.
-	* acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define.
-
-	* src/x86/ffi.c (ffi_raw_call): Rename.
-
-1999-08-02  Kresten Krab Thorup  <krab@dominiq.is.s.u-tokyo.ac.jp>
-
-	* src/x86/ffi.c (ffi_closure_SYSV): New function.
-	(ffi_prep_incoming_args_SYSV): Ditto.
-	(ffi_prep_closure): Ditto.
-	(ffi_closure_raw_SYSV): Ditto.
-	(ffi_prep_raw_closure): More ditto.
-	(ffi_call_raw): Final ditto.
-
-	* include/ffi.h.in: Add definitions for closure and raw API.
-
-	* src/x86/ffi.c (ffi_prep_cif_machdep): Added case for
-	FFI_TYPE_UINT64.
-
-	* Makefile.am (libffi_la_common_SOURCES): Added raw_api.c
-
-	* src/raw_api.c: New file.
-
-	* include/ffi.h.in (ffi_raw): New type.
-	(UINT_ARG, SINT_ARG): New defines.
-	(ffi_closure, ffi_raw_closure): New types.
-	(ffi_prep_closure, ffi_prep_raw_closure): New declarations.
-
-	* configure.in: Add check for endianness and sizeof void*.
-
-	* src/x86/sysv.S (ffi_call_SYSV): Call fixup routine via argument,
-	instead of directly.
-
-	* configure: Rebuilt.
-
-Thu Jul  8 14:28:42 1999  Anthony Green  <green@cygnus.com>
-
-	* configure.in: Add x86 and powerpc BeOS configurations.
-	From Makoto Kato <m_kato@ga2.so-net.ne.jp>.
-
-1999-05-09  Anthony Green  <green@cygnus.com>
-
-	* configure.in: Add warning about this being beta code.
-	Remove src/Makefile.am from the picture.
-	* configure: Rebuilt.
-
-	* Makefile.am: Move logic from src/Makefile.am.  Add changes
-	to support libffi as a target library.
-	* Makefile.in: Rebuilt.
-
-	* aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh:
-	Upgraded to new autoconf, automake, libtool.
-
-	* README: Tweaks.
-
-	* LICENSE: Update copyright date.
-
-	* src/Makefile.am, src/Makefile.in: Removed.
-
-1998-11-29  Anthony Green  <green@cygnus.com>
-
-	* include/ChangeLog: Removed.
-	* src/ChangeLog: Removed.
-	* src/mips/ChangeLog: Removed.
-	* src/sparc/ChangeLog: Remboved.
-	* src/x86/ChangeLog: Removed.
-
-	* ChangeLog.v1: Created.
-
-=============================================================================
-From the old ChangeLog.libffi file....
-
-2011-02-08  Andreas Tobler  <andreast@fgznet.ch>
-
-	* testsuite/lib/libffi.exp: Tweak for stand-alone mode.
-
-2009-12-25  Samuli Suominen  <ssuominen@gentoo.org>
-
-	* configure.ac: Undefine _AC_ARG_VAR_PRECIOUS for autoconf 2.64.
-	* configure: Rebuilt.
-	* fficonfig.h.in: Rebuilt.
-
-2009-06-16  Andrew Haley  <aph@redhat.com>
-
-	* testsuite/libffi.call/cls_align_sint64.c,
-	testsuite/libffi.call/cls_align_uint64.c,
-	testsuite/libffi.call/cls_longdouble_va.c,
-	testsuite/libffi.call/cls_ulonglong.c,
-	testsuite/libffi.call/return_ll1.c,
-	testsuite/libffi.call/stret_medium2.c: Fix printf format
-	specifiers.
-	* testsuite/libffi.call/huge_struct.c: Ad x86 XFAILs.
-	* testsuite/libffi.call/float2.c: Fix dg-excess-errors.
-	* testsuite/libffi.call/ffitest.h,
-	testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define.
-
-2009-06-12  Andrew Haley  <aph@redhat.com>
-
-	* testsuite/libffi.call/cls_align_sint64.c,
-	testsuite/libffi.call/cls_align_uint64.c,
-	testsuite/libffi.call/cls_ulonglong.c,
-	testsuite/libffi.call/return_ll1.c,
-	testsuite/libffi.call/stret_medium2.c: Fix printf format
-	specifiers.
-	testsuite/libffi.special/unwindtest.cc: include stdint.h.
-
-2009-06-11  Timothy Wall  <twall@users.sf.net>
-
-	* Makefile.am,
-        configure.ac,
-        include/ffi.h.in,
-        include/ffi_common.h,
-        src/closures.c,
-        src/dlmalloc.c,
-        src/x86/ffi.c,
-        src/x86/ffitarget.h,
-        src/x86/win64.S (new),
-	README: Added win64 support (mingw or MSVC)
-        * Makefile.in,
-        include/Makefile.in,
-        man/Makefile.in,
-        testsuite/Makefile.in,
-        configure,
-        aclocal.m4: Regenerated
-        * ltcf-c.sh: properly escape cygwin/w32 path
-        * man/ffi_call.3: Clarify size requirements for return value.
-        * src/x86/ffi64.c: Fix filename in comment.
-        * src/x86/win32.S: Remove unused extern.
-
-        * testsuite/libffi.call/closure_fn0.c,
-        testsuite/libffi.call/closure_fn1.c,
-        testsuite/libffi.call/closure_fn2.c,
-        testsuite/libffi.call/closure_fn3.c,
-        testsuite/libffi.call/closure_fn4.c,
-        testsuite/libffi.call/closure_fn5.c,
-        testsuite/libffi.call/closure_fn6.c,
-	testsuite/libffi.call/closure_stdcall.c,
-	testsuite/libffi.call/cls_12byte.c,
-	testsuite/libffi.call/cls_16byte.c,
-	testsuite/libffi.call/cls_18byte.c,
-	testsuite/libffi.call/cls_19byte.c,
-	testsuite/libffi.call/cls_1_1byte.c,
-	testsuite/libffi.call/cls_20byte.c,
-	testsuite/libffi.call/cls_20byte1.c,
-	testsuite/libffi.call/cls_24byte.c,
-	testsuite/libffi.call/cls_2byte.c,
-	testsuite/libffi.call/cls_3_1byte.c,
-	testsuite/libffi.call/cls_3byte1.c,
- 	testsuite/libffi.call/cls_3byte2.c,
- 	testsuite/libffi.call/cls_4_1byte.c,
- 	testsuite/libffi.call/cls_4byte.c,
- 	testsuite/libffi.call/cls_5_1_byte.c,
- 	testsuite/libffi.call/cls_5byte.c,
- 	testsuite/libffi.call/cls_64byte.c,
- 	testsuite/libffi.call/cls_6_1_byte.c,
- 	testsuite/libffi.call/cls_6byte.c,
- 	testsuite/libffi.call/cls_7_1_byte.c,
- 	testsuite/libffi.call/cls_7byte.c,
- 	testsuite/libffi.call/cls_8byte.c,
- 	testsuite/libffi.call/cls_9byte1.c,
- 	testsuite/libffi.call/cls_9byte2.c,
- 	testsuite/libffi.call/cls_align_double.c,
- 	testsuite/libffi.call/cls_align_float.c,
- 	testsuite/libffi.call/cls_align_longdouble.c,
- 	testsuite/libffi.call/cls_align_longdouble_split.c,
- 	testsuite/libffi.call/cls_align_longdouble_split2.c,
- 	testsuite/libffi.call/cls_align_pointer.c,
- 	testsuite/libffi.call/cls_align_sint16.c,
- 	testsuite/libffi.call/cls_align_sint32.c,
- 	testsuite/libffi.call/cls_align_sint64.c,
- 	testsuite/libffi.call/cls_align_uint16.c,
- 	testsuite/libffi.call/cls_align_uint32.c,
- 	testsuite/libffi.call/cls_align_uint64.c,
- 	testsuite/libffi.call/cls_dbls_struct.c,
- 	testsuite/libffi.call/cls_double.c,
- 	testsuite/libffi.call/cls_double_va.c,
- 	testsuite/libffi.call/cls_float.c,
- 	testsuite/libffi.call/cls_longdouble.c,
- 	testsuite/libffi.call/cls_longdouble_va.c,
- 	testsuite/libffi.call/cls_multi_schar.c,
- 	testsuite/libffi.call/cls_multi_sshort.c,
- 	testsuite/libffi.call/cls_multi_sshortchar.c,
- 	testsuite/libffi.call/cls_multi_uchar.c,
- 	testsuite/libffi.call/cls_multi_ushort.c,
- 	testsuite/libffi.call/cls_multi_ushortchar.c,
- 	testsuite/libffi.call/cls_pointer.c,
- 	testsuite/libffi.call/cls_pointer_stack.c,
- 	testsuite/libffi.call/cls_schar.c,
- 	testsuite/libffi.call/cls_sint.c,
- 	testsuite/libffi.call/cls_sshort.c,
- 	testsuite/libffi.call/cls_uchar.c,
- 	testsuite/libffi.call/cls_uint.c,
- 	testsuite/libffi.call/cls_ulonglong.c,
- 	testsuite/libffi.call/cls_ushort.c,
- 	testsuite/libffi.call/err_bad_abi.c,
- 	testsuite/libffi.call/err_bad_typedef.c,
- 	testsuite/libffi.call/float2.c,
- 	testsuite/libffi.call/huge_struct.c,
- 	testsuite/libffi.call/nested_struct.c,
- 	testsuite/libffi.call/nested_struct1.c,
- 	testsuite/libffi.call/nested_struct10.c,
- 	testsuite/libffi.call/nested_struct2.c,
- 	testsuite/libffi.call/nested_struct3.c,
- 	testsuite/libffi.call/nested_struct4.c,
- 	testsuite/libffi.call/nested_struct5.c,
- 	testsuite/libffi.call/nested_struct6.c,
- 	testsuite/libffi.call/nested_struct7.c,
- 	testsuite/libffi.call/nested_struct8.c,
- 	testsuite/libffi.call/nested_struct9.c,
- 	testsuite/libffi.call/problem1.c,
- 	testsuite/libffi.call/return_ldl.c,
- 	testsuite/libffi.call/return_ll1.c,
- 	testsuite/libffi.call/stret_large.c,
- 	testsuite/libffi.call/stret_large2.c,
- 	testsuite/libffi.call/stret_medium.c,
- 	testsuite/libffi.call/stret_medium2.c,
-        testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead
-        of checking for MMAP.  Use intptr_t instead of long casts.
-
-2009-06-04  Andrew Haley  <aph@redhat.com>
-
-	* src/powerpc/ffitarget.h: Fix misapplied merge from gcc.
-
-2009-06-04  Andrew Haley  <aph@redhat.com>
-
-	* src/mips/o32.S,
-	src/mips/n32.S: Fix licence formatting.
-
-2009-06-04  Andrew Haley  <aph@redhat.com>
-
-	* src/x86/darwin.S: Fix licence formatting.
-	src/x86/win32.S: Likewise.
-	src/sh64/sysv.S: Likewise.
-	src/sh/sysv.S: Likewise.
-
-2009-06-04  Andrew Haley  <aph@redhat.com>
-
-	* src/sh64/ffi.c: Remove lint directives.  Was missing from merge
-	of Andreas Tobler's patch from 2006-04-22.
-	
-2009-06-04  Andrew Haley  <aph@redhat.com>
-
-	* src/sh/ffi.c: Apply missing hunk from Alexandre Oliva's patch of
-	2007-03-07.
-
-2008-12-26  Timothy Wall  <twall@users.sf.net>
-
-	* testsuite/libffi.call/cls_longdouble.c,
-        testsuite/libffi.call/cls_longdouble_va.c,
-        testsuite/libffi.call/cls_align_longdouble.c,
-        testsuite/libffi.call/cls_align_longdouble_split.c,
-        testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected
-        failures on x86_64 cygwin/mingw.
-
-2008-12-22  Timothy Wall  <twall@users.sf.net>
-
-	* testsuite/libffi.call/closure_fn0.c,
-        testsuite/libffi.call/closure_fn1.c,    
-        testsuite/libffi.call/closure_fn2.c,    
-        testsuite/libffi.call/closure_fn3.c,    
-        testsuite/libffi.call/closure_fn4.c,    
-        testsuite/libffi.call/closure_fn5.c,    
-        testsuite/libffi.call/closure_fn6.c,    
-        testsuite/libffi.call/closure_loc_fn0.c,    
-        testsuite/libffi.call/closure_stdcall.c,    
-        testsuite/libffi.call/cls_align_pointer.c,    
-        testsuite/libffi.call/cls_pointer.c,    
-        testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
-        pointer to integer (intptr_t).
-        * testsuite/libffi.call/cls_longdouble.c: disable for win64.
-	
-2008-12-19  Anthony Green  <green@redhat.com>
-
-	* configure.ac: Bump version to 3.0.8.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-	* libtool-version: Increment revision.
-	* README: Update for new release.
-
-2008-11-11  Anthony Green  <green@redhat.com>
-
-	* configure.ac: Bump version to 3.0.7.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-	* libtool-version: Increment revision.
-	* README: Update for new release.
-
-2008-08-25  Andreas Tobler  <a.tobler@schweiz.org>
-
-	* src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and
-	FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum.
-	Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT.
-	Adjust copyright notice.
-	* src/powerpc/ffi.c: Add two new flags to indicate if we have one
-	register or two register to use for FFI_SYSV structs.
-	(ffi_prep_cif_machdep): Pass the right register flag introduced above.
-	(ffi_closure_helper_SYSV): Fix the return type for
-	FFI_SYSV_TYPE_SMALL_STRUCT. Comment.
-	Adjust copyright notice.
-
-2008-07-24  Anthony Green  <green@redhat.com>
-
-	* testsuite/libffi.call/cls_dbls_struct.c,
-	testsuite/libffi.call/cls_double_va.c,
-	testsuite/libffi.call/cls_longdouble.c,
-	testsuite/libffi.call/cls_longdouble_va.c,
-	testsuite/libffi.call/cls_pointer.c,
-	testsuite/libffi.call/cls_pointer_stack.c,
-	testsuite/libffi.call/err_bad_abi.c: Clean up failures from
-	compiler warnings.
-
-2008-07-17  Anthony Green  <green@redhat.com>
-
-	* configure.ac: Bump version to 3.0.6.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-	* libtool-version: Increment revision.  Add documentation.
-	* README: Update for new release.
-
-2008-07-16  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned
-	int.
-
-2008-07-16  Kaz Kojima  <kkojima@gcc.gnu.org>
-
-	* src/sh/sysv.S: Add .note.GNU-stack on Linux.
-	* src/sh64/sysv.S: Likewise.
-
-2008-04-03  Anthony Green  <green@redhat.com>
-
-	* libffi.pc.in (Libs): Add -L${libdir}.
-	* configure.ac: Bump version to 3.0.5.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-	* libtool-version: Increment revision.
-	* README: Update for new release.
-
-2008-04-03  Anthony Green  <green@redhat.com>
-	    Xerces Ranby  <xerxes@zafena.se>
-
-	* include/ffi.h.in: Wrap definition of target architecture to
-	protect from double definitions.
-
-2008-03-22  Moriyoshi Koizumi  <moriyoshi@gmail.com>
-
-	* src/x86/ffi.c (ffi_prep_closure_loc): Fix for bug revealed in
-	closure_loc_fn0.c.
-	* testsuite/libffi.call/closure_loc_fn0.c (closure_loc_test_fn0):
-	New test.
-
-2008-03-04  Anthony Green  <green@redhat.com>
-	    Blake Chaffin
-	    hos@tamanegi.org
-
-	* testsuite/libffi.call/cls_align_longdouble_split2.c
-          testsuite/libffi.call/cls_align_longdouble_split.c
-          testsuite/libffi.call/cls_dbls_struct.c
-          testsuite/libffi.call/cls_double_va.c
-          testsuite/libffi.call/cls_longdouble.c
-          testsuite/libffi.call/cls_longdouble_va.c
-          testsuite/libffi.call/cls_pointer.c
-          testsuite/libffi.call/cls_pointer_stack.c
-          testsuite/libffi.call/err_bad_abi.c
-          testsuite/libffi.call/err_bad_typedef.c
-          testsuite/libffi.call/huge_struct.c
-          testsuite/libffi.call/stret_large2.c
-          testsuite/libffi.call/stret_large.c
-          testsuite/libffi.call/stret_medium2.c
-          testsuite/libffi.call/stret_medium.c: New tests from Apple.
-
-2008-02-26  Jakub Jelinek  <jakub@redhat.com>
-            Anthony Green  <green@redhat.com>
-
-	* src/alpha/osf.S: Add .note.GNU-stack on Linux.
-	* src/s390/sysv.S: Likewise.
-	* src/powerpc/linux64.S: Likewise.
-	* src/powerpc/linux64_closure.S: Likewise.
-	* src/powerpc/ppc_closure.S: Likewise.
-	* src/powerpc/sysv.S: Likewise.
-	* src/x86/unix64.S: Likewise.
-	* src/x86/sysv.S: Likewise.
-	* src/sparc/v8.S: Likewise.
-	* src/sparc/v9.S: Likewise.
-	* src/m68k/sysv.S: Likewise.
-	* src/ia64/unix.S: Likewise.
-	* src/arm/sysv.S: Likewise.
-
-2008-02-26  Anthony Green  <green@redhat.com>
-            Thomas Heller  <theller@ctypes.org>
-
-	* src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C
-	comment.
-
-2008-02-26  Anthony Green  <green@redhat.org>
-            Thomas Heller  <theller@ctypes.org>
-
-	* include/ffi.h.in: Change void (*)() to void (*)(void).
-
-2008-02-26  Anthony Green  <green@redhat.org>
-            Thomas Heller  <theller@ctypes.org>
-
-	* src/alpha/ffi.c: Change void (*)() to void (*)(void).
-	src/alpha/osf.S, src/arm/ffi.c, src/frv/ffi.c, src/ia64/ffi.c,
-	src/ia64/unix.S, src/java_raw_api.c, src/m32r/ffi.c,
-	src/mips/ffi.c, src/pa/ffi.c, src/pa/hpux32.S, src/pa/linux.S,
-	src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/raw_api.c,
-	src/s390/ffi.c, src/sh/ffi.c, src/sh64/ffi.c, src/sparc/ffi.c,
-	src/x86/ffi.c, src/x86/unix64.S, src/x86/darwin64.S,
-	src/x86/ffi64.c: Ditto.
-
-2008-02-24  Anthony Green  <green@redhat.org>
-
-	* configure.ac: Accept openbsd*, not just openbsd.
-	Bump version to 3.0.4.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-	* libtool-version: Increment revision.
-	* README: Update for new release.
-
-2008-02-22  Anthony Green  <green@redhat.com>
-
-	* README: Clean up list of tested platforms.
-
-2008-02-22  Anthony Green  <green@redhat.com>
-
-	* configure.ac: Bump version to 3.0.3.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-	* libtool-version: Increment revision.
-	* README: Update for new release.  Clean up test docs.
-
-2008-02-22  Bjoern Koenig  <bkoenig@alpha-tierchen.de>
-	    Andreas Tobler  <a.tobler@schweiz.org>
-
-	* configure.ac: Add amd64-*-freebsd* target.
-	* configure: Regenerate.
-
-2008-02-22  Thomas Heller <theller@ctypes.org>
-
-	* configure.ac: Add x86 OpenBSD support.
-	* configure: Rebuilt.
-
-2008-02-21  Thomas Heller <theller@ctypes.org>
-
-	* README: Change "make test" to "make check".
-
-2008-02-21  Anthony Green  <green@redhat.com>
-
-	* configure.ac: Bump version to 3.0.2.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-	* libtool-version: Increment revision.
-	* README: Update for new release.
-
-2008-02-21  Björn König <bkoenig@alpha-tierchen.de>
-
-	* src/x86/freebsd.S: New file.
-	* configure.ac: Add x86 FreeBSD support.
-	* Makefile.am: Ditto.
-
-2008-02-15  Anthony Green  <green@redhat.com>
-
-	* configure.ac: Bump version to 3.0.1.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-	* libtool-version: Increment revision.
-	* README: Update for new release.
-
-2008-02-15  David Daney	 <ddaney@avtrex.com>
-
-	* src/mips/ffi.c: Remove extra '>' from include directive.
-	(ffi_prep_closure_loc): Use clear_location instead of tramp.
-
-2008-02-15  Anthony Green  <green@redhat.com>
-
-	* configure.ac: Bump version to 3.0.0.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-
-2008-02-15  David Daney	 <ddaney@avtrex.com>
-
-	* src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE):
-	Define (conditionally), and use it to include cachectl.h.
-	(ffi_prep_closure_loc): Fix cache flushing.
-	* src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define.
-
-2008-02-15  Anthony Green  <green@redhat.com>
-
-        * man/ffi_call.3, man/ffi_prep_cif.3, man/ffi.3:
-	Update dates and remove all references to ffi_prep_closure.
-	* configure.ac: Bump version to 2.99.9.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-
-2008-02-15  Anthony Green  <green@redhat.com>
-
-	* man/ffi_prep_closure.3: Delete.
-	* man/Makefile.am (EXTRA_DIST): Remove ffi_prep_closure.3.
-	(man_MANS): Ditto.
-	* man/Makefile.in: Rebuilt.
-	* configure.ac: Bump version to 2.99.8.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-
-2008-02-14  Anthony Green  <green@redhat.com>
-
-	* configure.ac: Bump version to 2.99.7.
-	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
-	* include/ffi.h.in LICENSE src/debug.c src/closures.c
-          src/ffitest.c src/s390/sysv.S src/s390/ffitarget.h
-          src/types.c src/m68k/ffitarget.h src/raw_api.c src/frv/ffi.c
-          src/frv/ffitarget.h src/sh/ffi.c src/sh/sysv.S
-          src/sh/ffitarget.h src/powerpc/ffitarget.h src/pa/ffi.c
-          src/pa/ffitarget.h src/pa/linux.S src/java_raw_api.c
-          src/cris/ffitarget.h src/x86/ffi.c src/x86/sysv.S
-          src/x86/unix64.S src/x86/win32.S src/x86/ffitarget.h
-          src/x86/ffi64.c src/x86/darwin.S src/ia64/ffi.c
-          src/ia64/ffitarget.h src/ia64/ia64_flags.h src/ia64/unix.S
-          src/sparc/ffi.c src/sparc/v9.S src/sparc/ffitarget.h
-          src/sparc/v8.S src/alpha/ffi.c src/alpha/ffitarget.h
-          src/alpha/osf.S src/sh64/ffi.c src/sh64/sysv.S
-          src/sh64/ffitarget.h src/mips/ffi.c src/mips/ffitarget.h
-          src/mips/n32.S src/mips/o32.S src/arm/ffi.c src/arm/sysv.S
-          src/arm/ffitarget.h src/prep_cif.c: Update license text.
-
-2008-02-14  Anthony Green  <green@redhat.com>
-
-	* README: Update tested platforms.
-	* configure.ac: Bump version to 2.99.6.
-	* configure: Rebuilt.
-
-2008-02-14  Anthony Green  <green@redhat.com>
-
-	* configure.ac: Bump version to 2.99.5.
-	* configure: Rebuilt.
-	* Makefile.am (EXTRA_DIST): Add darwin64.S
-	* Makefile.in: Rebuilt.
-	* testsuite/lib/libffi-dg.exp: Remove libstdc++ bits from GCC tree.
-	* LICENSE: Update WARRANTY.
-
-2008-02-14  Anthony Green  <green@redhat.com>
-
-	* libffi.pc.in (libdir): Fix libdir definition.
-	* configure.ac: Bump version to 2.99.4.
-	* configure: Rebuilt.
-
-2008-02-14  Anthony Green  <green@redhat.com>
-
-	* README: Update.
-	* libffi.info: New file.
-	* doc/stamp-vti: New file.
-	* configure.ac: Bump version to 2.99.3.
-	* configure: Rebuilt.
-
-2008-02-14  Anthony Green  <green@redhat.com>
-
-	* Makefile.am (SUBDIRS): Add man dir.
-	* Makefile.in: Rebuilt.
-	* configure.ac: Create Makefile.
-	* configure: Rebuilt.
-        * man/ffi_call.3 man/ffi_prep_cif.3 man/ffi_prep_closure.3
-          man/Makefile.am man/Makefile.in: New files.
-
-2008-02-14  Tom Tromey  <tromey@redhat.com>
-
-	* aclocal.m4, Makefile.in, configure, fficonfig.h.in: Rebuilt.
-	* mdate-sh, texinfo.tex: New files.
-	* Makefile.am (info_TEXINFOS): New variable.
-	* doc/libffi.texi: New file.
-	* doc/version.texi: Likewise.
-
-2008-02-14  Anthony Green  <green@redhat.com>
-
-	* Makefile.am (AM_CFLAGS): Don't compile with -D$(TARGET).
-	(lib_LTLIBRARIES): Define.
-	(toolexeclib_LIBRARIES): Undefine.
-	* Makefile.in: Rebuilt.
-	* configure.ac: Reset version to 2.99.1.
-	* configure.in: Rebuilt.
-
-2008-02-14  Anthony Green  <green@redhat.com>
-
-	* libffi.pc.in: Use @PACKAGE_NAME@ and @PACKAGE_VERSION@.
-	* configure.ac: Reset version to 2.99.1.
-	* configure.in: Rebuilt.
-	* Makefile.am (EXTRA_DIST): Add ChangeLog.libffi.
-	* Makefile.in: Rebuilt.
-	* LICENSE: Update copyright notice.
-
-2008-02-14  Anthony Green  <green@redhat.com>
-
-	* include/Makefile.am (nodist_includes_HEADERS): Define.  Don't
-	distribute ffitarget.h or ffi.h from the build include dir.
-	* Makefile.in: Rebuilt.
-
-2008-02-14  Anthony Green  <green@redhat.com>
-
-	* include/Makefile.am (includesdir): Install headers under libdir.
-	(pkgconfigdir): Define. Install libffi.pc.
-	* include/Makefile.in: Rebuilt.
-	* libffi.pc.in: Create.
-	* libtool-version: Increment CURRENT
-	* configure.ac: Add libffi.pc.in
-	* configure: Rebuilt.
-
-2008-02-03  Anthony Green  <green@redhat.com>
-
-	* include/Makefile.am (includesdir): Fix header install with
-	DESTDIR.
-	* include/Makefile.in: Rebuilt.
-
-2008-02-03  Timothy Wall  <twall@users.sf.net>
-
-	* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return
-          offset based on code pointer, not data pointer.
-
-2008-02-01  Anthony Green  <green@redhat.com>
-
-	* include/Makefile.am: Fix header installs.
-	* Makefile.am: Ditto.
-	* include/Makefile.in: Rebuilt.
-	* Makefile.in: Ditto.
-
-2008-02-01  Anthony Green  <green@redhat.com>
-
-	* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL,
-	FFI_INIT_TRAMPOLINE): Revert my broken changes to twall's last
-	patch.
-
-2008-01-31  Anthony Green  <green@redhat.com>
-
-	* Makefile.am (EXTRA_DIST): Add missing files.
-	* testsuite/Makefile.am: Ditto.
-	* Makefile.in, testsuite/Makefile.in: Rebuilt.
-
-2008-01-31  Timothy Wall <twall@users.sf.net>
-
-	* testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
-	closures.
-	* src/x86/ffitarget.h: Increase size of trampoline for stdcall
-	closures.
-	* src/x86/win32.S: Add assembly for stdcall closure.
-	* src/x86/ffi.c: Initialize stdcall closure trampoline.
-
-2008-01-30  H.J. Lu <hongjiu.lu@intel.com>
-
-	PR libffi/34612
-	* src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when
-	returning struct.
-
-	* testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer"
-	tests.
-
-2008-01-30  Anthony Green  <green@redhat.com>
-
-	* Makefile.am, include/Makefile.am: Move headers to
-	libffi_la_SOURCES for new automake.
-	* Makefile.in, include/Makefile.in: Rebuilt.
-
-	* testsuite/lib/wrapper.exp: Copied from gcc tree to allow for
-	execution outside of gcc tree.
-	* testsuite/lib/target-libpath.exp: Ditto.
-
-	* testsuite/lib/libffi-dg.exp: Many changes to allow for execution
-	outside of gcc tree.
-
-
-=============================================================================
-From the old ChangeLog.libgcj file....
-
-2004-01-14  Kelley Cook  <kcook@gcc.gnu.org>
-
-	* configure.in: Add in AC_PREREQ(2.13)
-
-2003-02-20  Alexandre Oliva  <aoliva@redhat.com>
-
-	* configure.in: Propagate ORIGINAL_LD_FOR_MULTILIBS to
-	config.status.
-	* configure: Rebuilt.
-
-2002-01-27  Alexandre Oliva  <aoliva@redhat.com>
-
-	* configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST.
-	Remove USE_LIBDIR conditional.
-	* Makefile.am (toolexecdir, toolexeclibdir): Don't override.
-	* Makefile.in, configure: Rebuilt.
-
-Mon Aug  9 18:33:38 1999  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
-
-	* include/Makefile.in: Rebuilt.
-	* Makefile.in: Rebuilt
-	* Makefile.am (toolexeclibdir): Add $(MULTISUBDIR) even for native
-	builds.
-	Use USE_LIBDIR.
-
-	* configure: Rebuilt.
-	* configure.in (USE_LIBDIR): Define for native builds.
-	Use lowercase in configure --help explanations.
-
-1999-08-08  Anthony Green  <green@cygnus.com>
-
-	* include/ffi.h.in (FFI_FN): Remove `...'.
-
-1999-08-08  Anthony Green  <green@cygnus.com>
-
-	* Makefile.in: Rebuilt.
-	* Makefile.am (AM_CFLAGS): Compile with -fexceptions.
-
-	* src/x86/sysv.S: Add exception handling metadata.
-
-
-=============================================================================
-	
-The libffi version 1 ChangeLog archive.
-
-Version 1 of libffi had per-directory ChangeLogs.  Current and future
-versions have a single ChangeLog file in the root directory.  The
-version 1 ChangeLogs have all been concatenated into this file for
-future reference only.
-
---- libffi ----------------------------------------------------------------
-
-Mon Oct  5 02:17:50 1998  Anthony Green  <green@cygnus.com>
-
-	* configure.in: Boosted rev.
-	* configure, Makefile.in, aclocal.m4: Rebuilt.
-	* README: Boosted rev and updated release notes.
-
-Mon Oct  5 01:03:03 1998  Anthony Green  <green@cygnus.com>
-
-	* configure.in: Boosted rev.
-	* configure, Makefile.in, aclocal.m4: Rebuilt.
-	* README: Boosted rev and updated release notes.
-
-1998-07-25  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
-
-	* m68k/ffi.c (ffi_prep_cif_machdep): Use bitmask for cif->flags.
-	Correctly handle small structures.
-	(ffi_prep_args): Also handle small structures.
-	(ffi_call): Pass size of return type to ffi_call_SYSV.
-	* m68k/sysv.S: Adjust for above changes.  Correctly align small
-	structures in the return value.
-
-	* types.c (uint64, sint64) [M68K]: Change alignment to 4.
-
-Fri Apr 17 17:26:58 1998  Anthony Green  <green@hoser.cygnus.com>
-
-	* configure.in: Boosted rev.
-	* configure,Makefile.in,aclocal.m4: Rebuilt.
-	* README: Boosted rev and added release notes.
-
-Sun Feb 22 00:50:41 1998  Geoff Keating  <geoffk@ozemail.com.au>
-
-	* configure.in: Add PowerPC config bits.
-
-1998-02-14  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
-
-	* configure.in: Add m68k config bits.  Change AC_CANONICAL_SYSTEM
-	to AC_CANONICAL_HOST, this is not a compiler.  Use $host instead
-	of $target.  Remove AC_CHECK_SIZEOF(char), we already know the
-	result.  Fix argument of AC_ARG_ENABLE.
-	* configure, fficonfig.h.in: Rebuilt.
-
-Tue Feb 10 20:53:40 1998  Richard Henderson  <rth@cygnus.com>
-
-	* configure.in: Add Alpha config bits.
-
-Tue May 13 13:39:20 1997  Anthony Green  <green@hoser.cygnus.com>
-
-	* README: Updated dates and reworded Irix comments.
-
-	* configure.in: Removed AC_PROG_RANLIB.
-
-	* Makefile.in, aclocal.m4, config.guess, config.sub, configure,
-	ltmain.sh, */Makefile.in: libtoolized again and	rebuilt with 
-	automake and autoconf.
-	
-Sat May 10 18:44:50 1997  Tom Tromey  <tromey@cygnus.com>
-
-	* configure, aclocal.m4: Rebuilt.
-	* configure.in: Don't compute EXTRADIST; now handled in
-	src/Makefile.in.  Removed macros implied by AM_INIT_AUTOMAKE.
-	Don't run AM_MAINTAINER_MODE.
-
-Thu May  8 14:34:05 1997  Anthony Green  <green@hoser.cygnus.com>
-
-	* missing, ltmain.sh, ltconfig.sh: Created. These are new files
-	required by automake and libtool.
-
-	* README: Boosted rev to 1.14. Added notes.
-
-	* acconfig.h: Moved PACKAGE and VERSION for new automake.
-	
-	* configure.in: Changes for libtool.
-	
-	* Makefile.am (check): make test now make check. Uses libtool now.
-
-	* Makefile.in, configure.in, aclocal.h, fficonfig.h.in: Rebuilt.
-
-Thu May  1 16:27:07 1997  Anthony Green  <green@hoser.cygnus.com>
-
-	* missing: Added file required by new automake.
-
-Tue Nov 26 14:10:42 1996  Anthony Green  <green@csk3.cygnus.com>
-
-	* acconfig.h: Added USING_PURIFY flag. This is defined when
-	--enable-purify-safety was used at configure time.
-
-	* configure.in (allsources): Added --enable-purify-safety switch.
-	(VERSION): Boosted rev to 1.13.
-	* configure: Rebuilt.
-
-Fri Nov 22 06:46:12 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* configure.in (VERSION): Boosted rev to 1.12.
-	Removed special CFLAGS hack for gcc.
-	* configure: Rebuilt.
-
-	* README: Boosted rev to 1.12. Added notes.
-
-	* Many files: Cygnus Support changed to Cygnus Solutions.
-
-Wed Oct 30 11:15:25 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* configure.in (VERSION): Boosted rev to 1.11.
-	* configure: Rebuilt.
-
-	* README: Boosted rev to 1.11. Added notes about GNU make.
-
-Tue Oct 29 12:25:12 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* configure.in: Fixed -Wall trick.
-	(VERSION): Boosted rev.
-	* configure: Rebuilt
-
-	* acconfig.h: Needed for --enable-debug configure switch.
-
-	* README: Boosted rev to 1.09. Added more notes on building
-	libffi, and LCLint.
-
-	* configure.in: Added --enable-debug switch. Boosted rev to
-	1.09.
-	* configure: Rebuilt
-
-Tue Oct 15 13:11:28 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* configure.in (VERSION): Boosted rev to 1.08
-	* configure: Rebuilt.
-
-	* README: Added n32 bug fix notes.
-
-	* Makefile.am: Added "make lint" production. 
-	* Makefile.in: Rebuilt.
-
-Mon Oct 14 10:54:46 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* README: Added web page reference.
-
-	* configure.in, README: Boosted rev to 1.05
-	* configure: Rebuilt.
-
-	* README: Fixed n32 sample code.
-
-Fri Oct 11 17:09:28 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* README: Added sparc notes.
-
-	* configure.in, README: Boosted rev to 1.04.
-	* configure: Rebuilt.
-
-Thu Oct 10 10:31:03 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* configure.in, README: Boosted rev to 1.03.
-	* configure: Rebuilt.
-
-	* README: Added struct notes. 
-
-	* Makefile.am (EXTRA_DIST): Added LICENSE to distribution.
-	* Makefile.in: Rebuilt.
-
-	* README: Removed Linux section. No special notes now
-	because aggregates arg/return types work.
-
-Wed Oct  9 16:16:42 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* README, configure.in (VERSION): Boosted rev to 1.02
-	* configure: Rebuilt.
-
-Tue Oct  8 11:56:33 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* README (NOTE): Added n32 notes.
-
-	* Makefile.am: Added test production.
-	* Makefile: Rebuilt
-
-	* README: spell checked!
-
-	* configure.in (VERSION): Boosted rev to 1.01
-	* configure: Rebuilt.
-
-Mon Oct  7 15:50:22 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* configure.in: Added nasty bit to support SGI tools.
-	* configure: Rebuilt.
-	
-	* README: Added SGI notes. Added note about automake bug.
-
-Mon Oct  7 11:00:28 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* README: Rewrote intro, and fixed examples.
-
-Fri Oct  4 10:19:55 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* configure.in: -D$TARGET is no longer used as a compiler switch.
-	It is now inserted into ffi.h at configure time.
-	* configure: Rebuilt.
-
-	* FFI_ABI and FFI_STATUS are now ffi_abi and ffi_status.
-
-Thu Oct  3 13:47:34 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* README, LICENSE: Created. Wrote some docs.
-
-	* configure.in: Don't barf on i586-unknown-linuxaout.
-	Added EXTRADIST code for "make dist".
-	* configure: Rebuilt.
-
-	* */Makefile.in: Rebuilt with patched automake. 
-
-Tue Oct  1 17:12:25 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* Makefile.am, aclocal.m4, config.guess, config.sub,
-	configure.in, fficonfig.h.in, install-sh, mkinstalldirs, 
-	stamp-h.in: Created
-	* Makefile.in, configure: Generated
-
---- libffi/include --------------------------------------------------------
-
-Tue Feb 24 13:09:36 1998  Anthony Green  <green@gerbil.cygnus.com>
-
-	* ffi_mips.h: Updated FFI_TYPE_STRUCT_* values based on
-	ffi.h.in changes.  This is a work-around for SGI's "simple"
-	assembler.
-
-Sun Feb 22 00:51:55 1998  Geoff Keating  <geoffk@ozemail.com.au>
-
-	* ffi.h.in: PowerPC support.
-
-1998-02-14  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
-
-	* ffi.h.in: Add m68k support.
-	(FFI_TYPE_LONGDOUBLE): Make it a separate value.
-
-Tue Feb 10 20:55:16 1998  Richard Henderson  <rth@cygnus.com>
-
-	* ffi.h.in (SIZEOF_ARG): Use a pointer type by default.
-
-	* ffi.h.in: Alpha support.
-
-Fri Nov 22 06:48:45 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.h.in, ffi_common.h: Cygnus Support -> Cygnus Solutions.
-
-Wed Nov 20 22:31:01 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.h.in: Added ffi_type_void definition.
-
-Tue Oct 29 12:22:40 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* Makefile.am (hack_DATA): Always install ffi_mips.h.
-
-	* ffi.h.in: Removed FFI_DEBUG. It's now in the correct
-	place (acconfig.h).
-	Added #include <stddef.h> for size_t definition.
-
-Tue Oct 15 17:23:35 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.h.in, ffi_common.h, ffi_mips.h: More clean up.
-	Commented out #define of FFI_DEBUG.
-
-Tue Oct 15 13:01:06 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi_common.h: Added bool definition.
-
-	* ffi.h.in, ffi_common.h: Clean up based on LCLint output.
-	Added funny /*@...@*/ comments to annotate source.
-
-Mon Oct 14 12:29:23 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.h.in: Interface changes based on feedback from Jim
-	Blandy.
-
-Fri Oct 11 16:49:35 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.h.in: Small change for sparc support.
-
-Thu Oct 10 14:53:37 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi_mips.h: Added FFI_TYPE_STRUCT_* definitions for 
-	special structure return types.
-
-Wed Oct  9 13:55:57 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.h.in: Added SIZEOF_ARG definition for X86
-
-Tue Oct  8 11:40:36 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.h.in (FFI_FN): Added macro for eliminating compiler warnings.
-	Use it to case your function pointers to the proper type.
-
-	* ffi_mips.h (SIZEOF_ARG): Added magic to fix type promotion bug.
-
-	* Makefile.am (EXTRA_DIST): Added ffi_mips.h to EXTRA_DIST.
-	* Makefile: Rebuilt.
-
-	* ffi_mips.h: Created. Moved all common mips definitions here.
-
-Mon Oct  7 10:58:12 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.h.in: The SGI assember is very picky about parens. Redefined
- 	some macros to avoid problems.
-
-	* ffi.h.in: Added FFI_DEFAULT_ABI definitions. Also added
-	externs for pointer, and 64bit integral ffi_types.
-
-Fri Oct  4 09:51:37 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.h.in: Added FFI_ABI member to ffi_cif and changed
-	function prototypes accordingly.
-	Added #define @TARGET@. Now programs including ffi.h don't 
-	have to specify this themselves.
-
-Thu Oct  3 15:36:44 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.h.in: Changed ffi_prep_cif's values from void* to void**
-
-	* Makefile.am (EXTRA_DIST): Added EXTRA_DIST for "make dist"
-	to work.
-	* Makefile.in: Regenerated.
-
-Wed Oct  2 10:16:59 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* Makefile.am: Created
-	* Makefile.in: Generated
-
-	* ffi_common.h: Added rcsid comment
-
-Tue Oct  1 17:13:51 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.h.in, ffi_common.h: Created
-
---- libffi/src ------------------------------------------------------------
-
-Mon Oct  5 02:17:50 1998  Anthony Green  <green@cygnus.com>
-
-	* arm/ffi.c, arm/sysv.S: Created.
-
-	* Makefile.am: Added arm files.
-	* Makefile.in: Rebuilt.
-
-Mon Oct  5 01:41:38 1998  Anthony Green  <green@rtl.cygnus.com>
-
-	* Makefile.am (libffi_la_LDFLAGS): Incremented revision.
-
-Sun Oct  4 16:27:17 1998  Anthony Green  <green@cygnus.com>
-
-	* alpha/osf.S (ffi_call_osf): Patch for DU assembler.
-
-	* ffitest.c (main): long long and long double return values work
-	for x86.
-
-Fri Apr 17 11:50:58 1998  Anthony Green  <green@hoser.cygnus.com>
-
-	* Makefile.in: Rebuilt.
-
-	* ffitest.c (main): Floating point tests not executed for systems
- 	with broken lond double (SunOS 4 w/ GCC).
-
-	* types.c: Fixed x86 alignment info for long long types.
-
-Thu Apr 16 07:15:28 1998  Anthony Green  <green@ada.cygnus.com>
-
-	* ffitest.c: Added more notes about GCC bugs under Irix 6.
-
-Wed Apr 15 08:42:22 1998  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffitest.c (struct5): New test function.
-	(main): New test with struct5.
-
-Thu Mar  5 10:48:11 1998  Anthony Green  <green@tootie.to.cygnus.com>
-
-	* prep_cif.c (initialize_aggregate): Fix assertion for
-	nested structures.
-
-Tue Feb 24 16:33:41 1998  Anthony Green  <green@hoser.cygnus.com>
-
-	* prep_cif.c (ffi_prep_cif): Added long double support for sparc.
-
-Sun Feb 22 00:52:18 1998  Geoff Keating  <geoffk@ozemail.com.au>
-
-	* powerpc/asm.h: New file.
-	* powerpc/ffi.c: New file.
-	* powerpc/sysv.S: New file.
-	* Makefile.am: PowerPC port.
-	* ffitest.c (main): Allow all tests to run even in presence of gcc
- 	bug on PowerPC.
-
-1998-02-17  Anthony Green  <green@hoser.cygnus.com>
-
-	* mips/ffi.c: Fixed comment typo.
-
-	* x86/ffi.c (ffi_prep_cif_machdep), x86/sysv.S (retfloat): 
-	Fixed x86 long double return handling.
-
-	* types.c: Fixed x86 long double alignment info.
-
-1998-02-14  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
-
-	* types.c: Add m68k support.
-
-	* ffitest.c (floating): Add long double parameter.
-	(return_ll, ldblit): New functions to test long long and long
-	double return value.
-	(main): Fix type error in assignment of ts[1-4]_type.elements.
-	Add tests for long long and long double arguments and return
-	values.
-
-	* prep_cif.c (ffi_prep_cif) [M68K]: Don't allocate argument for
-	struct value pointer.
-
-	* m68k/ffi.c, m68k/sysv.S: New files.
-	* Makefile.am: Add bits for m68k port.  Add kludge to work around
-	automake deficiency.
-	(test): Don't require "." in $PATH.
-	* Makefile.in: Rebuilt.
-
-Wed Feb 11 07:36:50 1998  Anthony Green  <green@hoser.cygnus.com>
-
-	* Makefile.in: Rebuilt.
-
-Tue Feb 10 20:56:00 1998  Richard Henderson  <rth@cygnus.com>
-
-	* alpha/ffi.c, alpha/osf.S: New files.
-	* Makefile.am: Alpha port.
-
-Tue Nov 18 14:12:07 1997  Anthony Green  <green@hoser.cygnus.com>
-
-	* mips/ffi.c (ffi_prep_cif_machdep): Initialize rstruct_flag
-	for n32.
-
-Tue Jun  3 17:18:20 1997  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffitest.c (main): Added hack to get structure tests working
-	correctly.
-
-Sat May 10 19:06:42 1997  Tom Tromey  <tromey@cygnus.com>
-
-	* Makefile.in: Rebuilt.
-	* Makefile.am (EXTRA_DIST): Explicitly list all distributable
-	files in subdirs.
-	(VERSION, CC): Removed.
-
-Thu May  8 17:19:01 1997  Anthony Green  <green@hoser.cygnus.com>
-
-	* Makefile.am: Many changes for new automake and libtool.
-	* Makefile.in: Rebuilt.
-
-Fri Nov 22 06:57:56 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffitest.c (main): Fixed test case for non mips machines.
-
-Wed Nov 20 22:31:59 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* types.c: Added ffi_type_void declaration.
-
-Tue Oct 29 13:07:19 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffitest.c (main): Fixed character constants.
-	(main): Emit warning for structure test 3 failure on Sun.
-
-	* Makefile.am (VPATH): Fixed VPATH def'n so automake won't
-	strip it out. 
-	Moved distdir hack from libffi to automake. 
-	(ffitest): Added missing -c for $(COMPILE) (change in automake).
-	* Makefile.in: Rebuilt.
-	
-Tue Oct 15 13:08:20 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* Makefile.am: Added "make lint" production. 
-	* Makefile.in: Rebuilt.
-
-	* prep_cif.c (STACK_ARG_SIZE): Improved STACK_ARG_SIZE macro.
-  	Clean up based on LCLint output. Added funny /*@...@*/ comments to
- 	annotate source.
-
-	* ffitest.c, debug.c: Cleaned up code.
-
-Mon Oct 14 12:26:56 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffitest.c: Changes based on interface changes.
-
-	* prep_cif.c (ffi_prep_cif): Cleaned up interface based on
-	feedback from Jim Blandy.
-
-Fri Oct 11 15:53:18 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffitest.c: Reordered tests while porting to sparc.
-	Made changes to handle lame structure passing for sparc.
-	Removed calls to fflush().
-
-	* prep_cif.c (ffi_prep_cif): Added special case for sparc
-	aggregate type arguments.
-
-Thu Oct 10 09:56:51 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffitest.c (main): Added structure passing/returning tests.
-
-	* prep_cif.c (ffi_prep_cif): Perform proper initialization
-	of structure return types if needed.
-	(initialize_aggregate): Bug fix
-
-Wed Oct  9 16:04:20 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* types.c: Added special definitions for x86 (double doesn't
-	need double word alignment).
-
-	* ffitest.c: Added many tests
-
-Tue Oct  8 09:19:22 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* prep_cif.c (ffi_prep_cif): Fixed assertion.
-
-	* debug.c (ffi_assert): Must return a non void now.
-
-	* Makefile.am: Added test production.
-	* Makefile: Rebuilt.
-
-	* ffitest.c (main): Created. 
-
-	* types.c: Created. Stripped common code out of */ffi.c.
-
-	* prep_cif.c: Added missing stdlib.h include.
-
-	* debug.c (ffi_type_test): Used "a" to eliminate compiler
-	warnings in non-debug builds. Included ffi_common.h.
-
-Mon Oct  7 15:36:42 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* Makefile.am: Added a rule for .s -> .o
-	This is required by the SGI compiler.
-	* Makefile: Rebuilt.
-
-Fri Oct  4 09:51:08 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* prep_cif.c (initialize_aggregate): Moved abi specification
-	to ffi_prep_cif().
-
-Thu Oct  3 15:37:37 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* prep_cif.c (ffi_prep_cif): Changed values from void* to void**.
-	(initialize_aggregate): Fixed aggregate type initialization.
-
-	* Makefile.am (EXTRA_DIST): Added support code for "make dist".
-	* Makefile.in: Regenerated.
-
-Wed Oct  2 11:41:57 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* debug.c, prep_cif: Created.
-
-	* Makefile.am: Added debug.o and prep_cif.o to OBJ.
-	* Makefile.in: Regenerated.
-
-	* Makefile.am (INCLUDES): Added missing -I../include
-	* Makefile.in: Regenerated.
-
-Tue Oct  1 17:11:51 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* error.c, Makefile.am: Created.
-	* Makefile.in: Generated.
-
---- libffi/src/x86 --------------------------------------------------------
-
-Sun Oct  4 16:27:17 1998  Anthony Green  <green@cygnus.com>
-
-	* sysv.S (retlongdouble): Fixed long long return value support.
-	* ffi.c (ffi_prep_cif_machdep): Ditto.
-
-Wed May 13 04:30:33 1998  Anthony Green  <green@raft.ppp.tsoft.net>
-
-	* ffi.c (ffi_prep_cif_machdep): Fixed long double return value
-	support.
-
-Wed Apr 15 08:43:20 1998  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.c (ffi_prep_args): small struct support was missing.
-
-Thu May  8 16:53:58 1997  Anthony Green  <green@hoser.cygnus.com>
-
-	* objects.mak: Removed.
-
-Mon Dec  2 15:12:58 1996  Tom Tromey  <tromey@cygnus.com>
-
-	* sysv.S: Use .balign, for a.out Linux boxes.
-
-Tue Oct 15 13:06:50 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.c: Clean up based on LCLint output.
-	Added funny /*@...@*/ comments to annotate source.
-
-Fri Oct 11 16:43:38 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.c (ffi_call): Added assertion for bad ABIs.
-
-Wed Oct  9 13:57:27 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* sysv.S (retdouble): Fixed double return problems.
-
-	* ffi.c	(ffi_call): Corrected fn arg definition.
-	(ffi_prep_cif_machdep): Fixed double return problems
-
-Tue Oct  8 12:12:49 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.c: Moved ffi_type definitions to types.c.
-	(ffi_prep_args): Fixed type promotion bug.
-
-Mon Oct  7 15:53:06 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
-
-Fri Oct  4 09:54:53 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
-	remaining args.
-
-Wed Oct  2 10:07:05 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.c, sysv.S, objects.mak: Created.
-	(ffi_prep_cif): cif->rvalue no longer initialized to NULL.
-	(ffi_prep_cif_machdep): Moved machine independent cif processing
-	to src/prep_cif.c. Introduced ffi_prep_cif_machdep().
-
---- libffi/src/mips -------------------------------------------------------
-
-Tue Feb 17 17:18:07 1998  Anthony Green  <green@hoser.cygnus.com>
-
-	* o32.S: Fixed typo in comment.
-
-	* ffi.c (ffi_prep_cif_machdep): Fixed argument processing.
-
-Thu May  8 16:53:58 1997  Anthony Green  <green@hoser.cygnus.com>
-
-	* o32.s, n32.s: Wrappers for SGI tool support.
-
-	* objects.mak: Removed.
-
-Tue Oct 29 14:37:45 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.c (ffi_prep_args): Changed int z to size_t z.
-
-Tue Oct 15 13:17:25 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* n32.S: Fixed bad stack munging. 
-
-	* ffi.c: Moved prototypes for ffi_call_?32() to here from
-	ffi_mips.h because extended_cif is not defined in ffi_mips.h.
-
-Mon Oct 14 12:42:02 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.c: Interface changes based on feedback from Jim Blandy.
-
-Thu Oct 10 11:22:16 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* n32.S, ffi.c: Lots of changes to support passing and 
-	returning structures with the n32 calling convention.
-
-	* n32.S: Fixed fn pointer bug.
-
-	* ffi.c (ffi_prep_cif_machdep): Fix for o32 structure
-	return values.
-	(ffi_prep_args): Fixed n32 structure passing when structures
-	partially fit in registers.
-
-Wed Oct  9 13:49:25 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* objects.mak: Added n32.o.
-
-	* n32.S: Created.
-
-	* ffi.c (ffi_prep_args): Added magic to support proper
-	n32 processing.
-
-Tue Oct  8 10:37:35 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.c: Moved ffi_type definitions to types.c.
-	(ffi_prep_args): Fixed type promotion bug.
-
-	* o32.S: This code is only built for o32 compiles.
-	A lot of the #define cruft has moved to ffi_mips.h.
-
-	* ffi.c (ffi_prep_cif_machdep): Fixed arg flags. Second arg
-	is only processed if the first is either a float or double.
-
-Mon Oct  7 15:33:59 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* o32.S: Modified to compile under each of o32, n32 and n64.
-
-	* ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
-
-Fri Oct  4 09:53:25 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
-	remaining args.
-
-Wed Oct  2 17:41:22 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* o32.S: Removed crufty definitions.
-
-Wed Oct  2 12:53:42 1996  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.c (ffi_prep_cif): cif->rvalue no longer initialized to NULL.
-	(ffi_prep_cif_machdep): Moved all machine independent cif processing
-	to src/prep_cif.c. Introduced ffi_prep_cif_machdep. Return types
-	of FFI_TYPE_STRUCT are no different than FFI_TYPE_INT.
-
-Tue Oct  1 17:11:02 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.c, o32.S, object.mak: Created
-	
---- libffi/src/sparc ------------------------------------------------------
-
-Tue Feb 24 16:33:18 1998  Anthony Green  <green@hoser.cygnus.com>
-
-	* ffi.c (ffi_prep_args): Added long double support.
-
-Thu May  8 16:53:58 1997  Anthony Green  <green@hoser.cygnus.com>
-
-	* objects.mak: Removed.
-
-Thu May  1 16:07:56 1997  Anthony Green  <green@hoser.cygnus.com>
-
-	* v8.S: Fixed minor portability problem reported by 
-	Russ McManus <mcmanr@eq.gs.com>.
-
-Tue Nov 26 14:12:43 1996  Anthony Green  <green@csk3.cygnus.com>
-
-	* v8.S: Used STACKFRAME define elsewhere. 
-
-	* ffi.c (ffi_prep_args): Zero out space when USING_PURIFY
-	is set.
-	(ffi_prep_cif_machdep): Allocate the correct stack frame 
-	space for functions with < 6 args.
-
-Tue Oct 29 15:08:55 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.c (ffi_prep_args): int z is now size_t z.
-
-Mon Oct 14 13:31:24 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* v8.S (ffi_call_V8): Gordon rewrites this again. It looks
-	great now.
-
-	* ffi.c (ffi_call): The comment about hijacked registers
-	is no longer valid after gordoni hacked v8.S.
-
-        * v8.S (ffi_call_V8): Rewrote with gordoni. Much simpler.
-	
-	* v8.S, ffi.c: ffi_call() had changed to accept more than
-	two args, so v8.S had to change (because it hijacks incoming
-	arg registers).
-
-	* ffi.c: Interface changes based on feedback from Jim Blandy.
-
-Thu Oct 10 17:48:16 1996  Anthony Green  <green@rtl.cygnus.com>
-
-	* ffi.c, v8.S, objects.mak: Created.
-	
-
diff --git a/LICENSE b/LICENSE
index acb2f7a..a66fab4 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-libffi - Copyright (c) 1996-2019  Anthony Green, Red Hat, Inc and others.
+libffi - Copyright (c) 1996-2014  Anthony Green, Red Hat, Inc and others.
 See source files for details.
 
 Permission is hereby granted, free of charge, to any person obtaining
diff --git a/LICENSE-BUILDTOOLS b/LICENSE-BUILDTOOLS
deleted file mode 100644
index d1d626e..0000000
--- a/LICENSE-BUILDTOOLS
+++ /dev/null
@@ -1,353 +0,0 @@
-The libffi source distribution contains certain code that is not part
-of libffi, and is only used as tooling to assist with the building and
-testing of libffi.  This includes the msvcc.sh script used to wrap the
-Microsoft compiler with GNU compatible command-line options,
-make_sunver.pl, and the libffi test code distributed in the
-testsuite/libffi.bhaible directory.  This code is distributed with
-libffi for the purpose of convenience only, and libffi is in no way
-derived from this code.
-
-msvcc.sh an testsuite/libffi.bhaible are both distributed under the
-terms of the GNU GPL version 2, as below.
-
-
-
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-                            NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/METADATA b/METADATA
deleted file mode 100644
index cfd64f9..0000000
--- a/METADATA
+++ /dev/null
@@ -1,20 +0,0 @@
-name: "libffi"
-description: "A portable foreign-function interface library."
-third_party {
-  url {
-    type: GIT
-    value: "https://github.com/libffi/libffi.git"
-  }
-  version: "v3.3"
-  # would be NOTICE save for:
-  #   .travis/
-  #   testsuite/lib*/
-  #   libtool-ldflags
-  #   LICENSE-BUILDTOOLS
-  license_type: RESTRICTED
-  last_upgrade_date {
-    year: 2020
-    month: 3
-    day: 26
-  }
-}
diff --git a/Makefile.am b/Makefile.am
index 4fd6193..0e40451 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,112 +5,239 @@
 ACLOCAL_AMFLAGS = -I m4
 
 SUBDIRS = include testsuite man
-if BUILD_DOCS
-## This hack is needed because it doesn't seem possible to make a
-## conditional info_TEXINFOS in Automake.  At least Automake 1.14
-## either gives errors -- if this attempted in the most
-## straightforward way -- or simply unconditionally tries to build the
-## info file.
-SUBDIRS += doc
-endif
 
-EXTRA_DIST = LICENSE ChangeLog.old					\
-	m4/libtool.m4 m4/lt~obsolete.m4					\
+EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj			\
+	 src/aarch64/ffi.c src/aarch64/ffitarget.h src/aarch64/sysv.S	\
+	 src/alpha/ffi.c src/alpha/osf.S			\
+	 src/alpha/ffitarget.h src/arc/ffi.c src/arc/arcompact.S	\
+	 src/arc/ffitarget.h src/arm/ffi.c src/arm/sysv.S		\
+	 src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S		\
+	 src/avr32/ffitarget.h src/cris/ffi.c src/cris/sysv.S		\
+	 src/cris/ffitarget.h src/ia64/ffi.c src/ia64/ffitarget.h	\
+	 src/ia64/ia64_flags.h src/ia64/unix.S src/mips/ffi.c		\
+	 src/mips/n32.S src/mips/o32.S src/metag/ffi.c			\
+	 src/metag/ffitarget.h src/metag/sysv.S src/moxie/ffi.c		\
+	 src/moxie/ffitarget.h src/moxie/eabi.S src/mips/ffitarget.h	\
+	 src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h		\
+	 src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h		\
+	 src/m88k/ffi.c src/m88k/obsd.S src/m88k/ffitarget.h		\
+	 src/microblaze/ffi.c src/microblaze/sysv.S			\
+	 src/microblaze/ffitarget.h					\
+	 src/nios2/ffi.c src/nios2/ffitarget.h src/nios2/sysv.S		\
+	 src/or1k/ffi.c src/or1k/ffitarget.h src/or1k/sysv.S		\
+	 src/powerpc/ffi.c src/powerpc/ffi_powerpc.h			\
+	 src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c		\
+	 src/powerpc/sysv.S src/powerpc/linux64.S			\
+	 src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S	\
+	 src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S	\
+	 src/powerpc/aix_closure.S src/powerpc/darwin_closure.S		\
+	 src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h		\
+	 src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h		\
+	 src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h src/sh64/ffi.c	\
+	 src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S		\
+	 src/sparc/v9.S src/sparc/ffitarget.h src/sparc/ffi.c		\
+	 src/x86/darwin64.S src/x86/ffi.c src/x86/sysv.S		\
+	 src/x86/win32.S src/x86/darwin.S src/x86/win64.S		\
+	 src/x86/freebsd.S src/x86/ffi64.c src/x86/unix64.S		\
+	 src/x86/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c		\
+	 src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c src/bfin/ffi.c	\
+	 src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S		\
+	 src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c		\
+	 src/tile/ffitarget.h src/tile/tile.S libtool-version		\
+	 src/vax/ffi.c src/vax/ffitarget.h src/vax/elfbsd.S		\
+	 src/xtensa/ffitarget.h src/xtensa/ffi.c src/xtensa/sysv.S	\
+	 ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4		\
 	 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4			\
-	 m4/ltversion.m4 src/debug.c msvcc.sh				\
-	generate-darwin-source-and-headers.py				\
-	libffi.xcodeproj/project.pbxproj				\
-	libtool-ldflags libtool-version configure.host README.md        \
-	libffi.map.in LICENSE-BUILDTOOLS msvc_build make_sunver.pl	
+	 m4/ltversion.m4 src/arm/gentramp.sh src/debug.c msvcc.sh	\
+	 generate-darwin-source-and-headers.py				\
+	 libffi.xcodeproj/project.pbxproj src/arm/trampoline.S		\
+	 libtool-ldflags ChangeLog.libffi-3.1
 
-# local.exp is generated by configure
-DISTCLEANFILES = local.exp
+info_TEXINFOS = doc/libffi.texi
+
+## ################################################################
+
+##
+## This section is for make and multilib madness.
+##
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+	'AR_FLAGS=$(AR_FLAGS)' \
+	'CC_FOR_BUILD=$(CC_FOR_BUILD)' \
+	'CFLAGS=$(CFLAGS)' \
+	'CXXFLAGS=$(CXXFLAGS)' \
+	'CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)' \
+	'CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)' \
+	'INSTALL=$(INSTALL)' \
+	'INSTALL_DATA=$(INSTALL_DATA)' \
+	'INSTALL_PROGRAM=$(INSTALL_PROGRAM)' \
+	'INSTALL_SCRIPT=$(INSTALL_SCRIPT)' \
+	'JC1FLAGS=$(JC1FLAGS)' \
+	'LDFLAGS=$(LDFLAGS)' \
+	'LIBCFLAGS=$(LIBCFLAGS)' \
+	'LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)' \
+	'MAKE=$(MAKE)' \
+	'MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)' \
+	'PICFLAG=$(PICFLAG)' \
+	'PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)' \
+	'RUNTESTFLAGS=$(RUNTESTFLAGS)' \
+	'SHELL=$(SHELL)' \
+	'exec_prefix=$(exec_prefix)' \
+	'infodir=$(infodir)' \
+	'libdir=$(libdir)' \
+	'mandir=$(mandir)' \
+	'prefix=$(prefix)' \
+	'AR=$(AR)' \
+	'AS=$(AS)' \
+	'CC=$(CC)' \
+	'CXX=$(CXX)' \
+	'LD=$(LD)' \
+	'NM=$(NM)' \
+	'RANLIB=$(RANLIB)' \
+	'DESTDIR=$(DESTDIR)'
 
 # Subdir rules rely on $(FLAGS_TO_PASS)
 FLAGS_TO_PASS = $(AM_MAKEFLAGS)
 
 MAKEOVERRIDES=
 
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libffi.pc
-
 toolexeclib_LTLIBRARIES = libffi.la
 noinst_LTLIBRARIES = libffi_convenience.la
 
 libffi_la_SOURCES = src/prep_cif.c src/types.c \
 		src/raw_api.c src/java_raw_api.c src/closures.c
 
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libffi.pc
+
+nodist_libffi_la_SOURCES =
+
 if FFI_DEBUG
-libffi_la_SOURCES += src/debug.c
+nodist_libffi_la_SOURCES += src/debug.c
 endif
 
-noinst_HEADERS = \
-	src/aarch64/ffitarget.h src/aarch64/internal.h			\
-	src/alpha/ffitarget.h src/alpha/internal.h			\
-	src/arc/ffitarget.h						\
-	src/arm/ffitarget.h src/arm/internal.h				\
-	src/avr32/ffitarget.h						\
-	src/bfin/ffitarget.h						\
-	src/cris/ffitarget.h						\
-	src/frv/ffitarget.h						\
-	src/ia64/ffitarget.h src/ia64/ia64_flags.h			\
-	src/m32r/ffitarget.h						\
-	src/m68k/ffitarget.h						\
-	src/m88k/ffitarget.h						\
-	src/metag/ffitarget.h						\
-	src/microblaze/ffitarget.h					\
-	src/mips/ffitarget.h						\
-	src/moxie/ffitarget.h						\
-	src/nios2/ffitarget.h						\
-	src/or1k/ffitarget.h						\
-	src/pa/ffitarget.h						\
-	src/powerpc/ffitarget.h src/powerpc/asm.h src/powerpc/ffi_powerpc.h \
-	src/riscv/ffitarget.h						\
-	src/s390/ffitarget.h src/s390/internal.h			\
-	src/sh/ffitarget.h						\
-	src/sh64/ffitarget.h						\
-	src/sparc/ffitarget.h src/sparc/internal.h			\
-	src/tile/ffitarget.h						\
-	src/vax/ffitarget.h						\
-	src/x86/ffitarget.h src/x86/internal.h src/x86/internal64.h src/x86/asmnames.h \
-	src/xtensa/ffitarget.h						\
-	src/dlmalloc.c
-
-EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \
-	src/aarch64/win64_armasm.S src/alpha/ffi.c src/alpha/osf.S \
-	src/arc/ffi.c src/arc/arcompact.S src/arm/ffi.c	\
-	src/arm/sysv.S src/arm/ffi.c src/arm/sysv_msvc_arm32.S \
-	src/avr32/ffi.c src/avr32/sysv.S src/bfin/ffi.c	\
-	src/bfin/sysv.S src/cris/ffi.c src/cris/sysv.S src/frv/ffi.c \
-	src/frv/eabi.S src/ia64/ffi.c src/ia64/unix.S src/m32r/ffi.c \
-	src/m32r/sysv.S src/m68k/ffi.c src/m68k/sysv.S src/m88k/ffi.c \
-	src/m88k/obsd.S src/metag/ffi.c src/metag/sysv.S \
-	src/microblaze/ffi.c src/microblaze/sysv.S src/mips/ffi.c \
-	src/mips/o32.S src/mips/n32.S src/moxie/ffi.c \
-	src/moxie/eabi.S src/nios2/ffi.c src/nios2/sysv.S \
-	src/or1k/ffi.c src/or1k/sysv.S src/pa/ffi.c src/pa/linux.S \
-	src/pa/hpux32.S src/powerpc/ffi.c src/powerpc/ffi_sysv.c \
-	src/powerpc/ffi_linux64.c src/powerpc/sysv.S \
-	src/powerpc/linux64.S src/powerpc/linux64_closure.S \
-	src/powerpc/ppc_closure.S src/powerpc/aix.S \
-	src/powerpc/darwin.S src/powerpc/aix_closure.S \
-	src/powerpc/darwin_closure.S src/powerpc/ffi_darwin.c \
-	src/riscv/ffi.c src/riscv/sysv.S src/s390/ffi.c	\
-	src/s390/sysv.S src/sh/ffi.c src/sh/sysv.S src/sh64/ffi.c \
-	src/sh64/sysv.S src/sparc/ffi.c src/sparc/ffi64.c \
-	src/sparc/v8.S src/sparc/v9.S src/tile/ffi.c src/tile/tile.S \
-	src/vax/ffi.c src/vax/elfbsd.S src/x86/ffi.c src/x86/sysv.S \
-	src/x86/ffiw64.c src/x86/win64.S src/x86/ffi64.c \
-	src/x86/unix64.S src/x86/sysv_intel.S src/x86/win64_intel.S \
-	src/xtensa/ffi.c src/xtensa/sysv.S
-
-TARGET_OBJ = @TARGET_OBJ@
-libffi_la_LIBADD = $(TARGET_OBJ)
+if MIPS
+nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
+endif
+if BFIN
+nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S
+endif
+if X86
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S src/x86/win32.S
+endif
+if X86_FREEBSD
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S src/x86/win32.S
+endif
+if X86_WIN32
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
+endif
+if X86_WIN64
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S
+endif
+if X86_DARWIN
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
+if X86_DARWIN32
+nodist_libffi_la_SOURCES += src/x86/win32.S
+endif
+endif
+if SPARC
+nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
+endif
+if ALPHA
+nodist_libffi_la_SOURCES += src/alpha/ffi.c src/alpha/osf.S
+endif
+if IA64
+nodist_libffi_la_SOURCES += src/ia64/ffi.c src/ia64/unix.S
+endif
+if M32R
+nodist_libffi_la_SOURCES += src/m32r/sysv.S src/m32r/ffi.c
+endif
+if M68K
+nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S
+endif
+if M88K
+nodist_libffi_la_SOURCES += src/m88k/ffi.c src/m88k/obsd.S
+endif
+if MOXIE
+nodist_libffi_la_SOURCES += src/moxie/ffi.c src/moxie/eabi.S
+endif
+if MICROBLAZE
+nodist_libffi_la_SOURCES += src/microblaze/ffi.c src/microblaze/sysv.S
+endif
+if NIOS2
+nodist_libffi_la_SOURCES += src/nios2/sysv.S src/nios2/ffi.c
+endif
+if OR1K
+nodist_libffi_la_SOURCES += src/or1k/sysv.S src/or1k/ffi.c
+endif
+if POWERPC
+nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
+endif
+if POWERPC_AIX
+nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
+endif
+if POWERPC_DARWIN
+nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
+endif
+if POWERPC_FREEBSD
+nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
+endif
+if AARCH64
+nodist_libffi_la_SOURCES += src/aarch64/sysv.S src/aarch64/ffi.c
+endif
+if ARC
+nodist_libffi_la_SOURCES += src/arc/arcompact.S src/arc/ffi.c
+endif
+if ARM
+nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
+if FFI_EXEC_TRAMPOLINE_TABLE
+nodist_libffi_la_SOURCES += src/arm/trampoline.S
+endif
+endif
+if AVR32
+nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/ffi.c
+endif
+if LIBFFI_CRIS
+nodist_libffi_la_SOURCES += src/cris/sysv.S src/cris/ffi.c
+endif
+if FRV
+nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi.c
+endif
+if S390
+nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
+endif
+if X86_64
+nodist_libffi_la_SOURCES += src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
+endif
+if SH
+nodist_libffi_la_SOURCES += src/sh/sysv.S src/sh/ffi.c
+endif
+if SH64
+nodist_libffi_la_SOURCES += src/sh64/sysv.S src/sh64/ffi.c
+endif
+if PA_LINUX
+nodist_libffi_la_SOURCES += src/pa/linux.S src/pa/ffi.c
+endif
+if PA_HPUX
+nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c
+endif
+if TILE
+nodist_libffi_la_SOURCES += src/tile/tile.S src/tile/ffi.c
+endif
+if XTENSA
+nodist_libffi_la_SOURCES += src/xtensa/sysv.S src/xtensa/ffi.c
+endif
+if METAG
+nodist_libffi_la_SOURCES += src/metag/sysv.S src/metag/ffi.c
+endif
+if VAX
+nodist_libffi_la_SOURCES += src/vax/elfbsd.S src/vax/ffi.c
+endif
 
 libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
-EXTRA_libffi_convenience_la_SOURCES = $(EXTRA_libffi_la_SOURCES)
-libffi_convenience_la_LIBADD = $(libffi_la_LIBADD)
-libffi_convenience_la_DEPENDENCIES = $(libffi_la_DEPENDENCIES)
 nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
 
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/libtool-ldflags $(LDFLAGS))
@@ -122,38 +249,10 @@
 AM_CFLAGS += -DFFI_DEBUG
 endif
 
-if LIBFFI_BUILD_VERSIONED_SHLIB
-if LIBFFI_BUILD_VERSIONED_SHLIB_GNU
-libffi_version_script = -Wl,--version-script,libffi.map
-libffi_version_dep = libffi.map
-endif
-if LIBFFI_BUILD_VERSIONED_SHLIB_SUN
-libffi_version_script = -Wl,-M,libffi.map-sun
-libffi_version_dep = libffi.map-sun
-libffi.map-sun : libffi.map $(top_srcdir)/make_sunver.pl \
-		 $(libffi_la_OBJECTS) $(libffi_la_LIBADD)
-	perl $(top_srcdir)/make_sunver.pl libffi.map \
-	 `echo $(libffi_la_OBJECTS) $(libffi_la_LIBADD) | \
-	    sed 's,\([^/        ]*\)\.l\([ao]\),.libs/\1.\2,g'` \
-	 > $@ || (rm -f $@ ; exit 1)
-endif
-else
-libffi_version_script =
-libffi_version_dep =
-endif
-libffi_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
-
-libffi.map: $(top_srcdir)/libffi.map.in
-	$(COMPILE) -D$(TARGET) -E -x assembler-with-cpp -o $@ $<
-
-libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS)
-libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep)
+libffi_la_LDFLAGS = -no-undefined -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
 
 AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
 AM_CCASFLAGS = $(AM_CPPFLAGS)
 
 dist-hook:
-	d=`(cd $(distdir); pwd)`; (cd doc; make pdf; cp *.pdf $$d/doc)
 	if [ -d $(top_srcdir)/.git ] ; then (cd $(top_srcdir); git log --no-decorate) ; else echo 'See git log for history.' ; fi > $(distdir)/ChangeLog
-	s=`awk '/was released on/{ print NR; exit}' $(top_srcdir)/README.md`; tail -n +$$(($$s-1)) $(top_srcdir)/README.md > $(distdir)/README.md
-
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..a66fab4
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,21 @@
+libffi - Copyright (c) 1996-2014  Anthony Green, Red Hat, Inc and others.
+See source files for details.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
deleted file mode 100644
index 3d6ce44..0000000
--- a/README.md
+++ /dev/null
@@ -1,477 +0,0 @@
-Status
-======
-
-[![Build Status](https://travis-ci.org/libffi/libffi.svg?branch=master)](https://travis-ci.org/libffi/libffi)
-[![Build status](https://ci.appveyor.com/api/projects/status/8lko9vagbx4w2kxq?svg=true)](https://ci.appveyor.com/project/atgreen/libffi)
-
-libffi-3.3 was released on November 23, 2019.  Check the libffi web
-page for updates: <URL:http://sourceware.org/libffi/>.
-
-
-What is libffi?
-===============
-
-Compilers for high level languages generate code that follow certain
-conventions. These conventions are necessary, in part, for separate
-compilation to work. One such convention is the "calling
-convention". The "calling convention" is essentially a set of
-assumptions made by the compiler about where function arguments will
-be found on entry to a function. A "calling convention" also specifies
-where the return value for a function is found.
-
-Some programs may not know at the time of compilation what arguments
-are to be passed to a function. For instance, an interpreter may be
-told at run-time about the number and types of arguments used to call
-a given function. Libffi can be used in such programs to provide a
-bridge from the interpreter program to compiled code.
-
-The libffi library provides a portable, high level programming
-interface to various calling conventions. This allows a programmer to
-call any function specified by a call interface description at run
-time.  
-
-FFI stands for Foreign Function Interface.  A foreign function
-interface is the popular name for the interface that allows code
-written in one language to call code written in another language. The
-libffi library really only provides the lowest, machine dependent
-layer of a fully featured foreign function interface. A layer must
-exist above libffi that handles type conversions for values passed
-between the two languages.
-
-
-Supported Platforms
-===================
-
-Libffi has been ported to many different platforms.
-
-At the time of release, the following basic configurations have been
-tested:
-
-| Architecture    | Operating System | Compiler                |
-| --------------- | ---------------- | ----------------------- |
-| AArch64 (ARM64) | iOS              | Clang                   |
-| AArch64         | Linux            | GCC                     |
-| AArch64         | Windows          | MSVC                    |
-| Alpha           | Linux            | GCC                     |
-| Alpha           | Tru64            | GCC                     |
-| ARC             | Linux            | GCC                     |
-| ARM             | Linux            | GCC                     |
-| ARM             | iOS              | GCC                     |
-| ARM             | Windows          | MSVC                    |
-| AVR32           | Linux            | GCC                     |
-| Blackfin        | uClinux          | GCC                     |
-| HPPA            | HPUX             | GCC                     |
-| IA-64           | Linux            | GCC                     |
-| M68K            | FreeMiNT         | GCC                     |
-| M68K            | Linux            | GCC                     |
-| M68K            | RTEMS            | GCC                     |
-| M88K            | OpenBSD/mvme88k  | GCC                     |
-| Meta            | Linux            | GCC                     |
-| MicroBlaze      | Linux            | GCC                     |
-| MIPS            | IRIX             | GCC                     |
-| MIPS            | Linux            | GCC                     |
-| MIPS            | RTEMS            | GCC                     |
-| MIPS64          | Linux            | GCC                     |
-| Moxie           | Bare metal       | GCC                     |
-| Nios II         | Linux            | GCC                     |
-| OpenRISC        | Linux            | GCC                     |
-| PowerPC 32-bit  | AIX              | IBM XL C                |
-| PowerPC 64-bit  | AIX              | IBM XL C                |
-| PowerPC         | AMIGA            | GCC                     |
-| PowerPC         | Linux            | GCC                     |
-| PowerPC         | Mac OSX          | GCC                     |
-| PowerPC         | FreeBSD          | GCC                     |
-| PowerPC 64-bit  | FreeBSD          | GCC                     |
-| PowerPC 64-bit  | Linux ELFv1      | GCC                     |
-| PowerPC 64-bit  | Linux ELFv2      | GCC                     |
-| RISC-V 32-bit   | Linux            | GCC                     |
-| RISC-V 64-bit   | Linux            | GCC                     |
-| S390            | Linux            | GCC                     |
-| S390X           | Linux            | GCC                     |
-| SPARC           | Linux            | GCC                     |
-| SPARC           | Solaris          | GCC                     |
-| SPARC           | Solaris          | Oracle Solaris Studio C |
-| SPARC64         | Linux            | GCC                     |
-| SPARC64         | FreeBSD          | GCC                     |
-| SPARC64         | Solaris          | Oracle Solaris Studio C |
-| TILE-Gx/TILEPro | Linux            | GCC                     |
-| VAX             | OpenBSD/vax      | GCC                     |
-| X86             | FreeBSD          | GCC                     |
-| X86             | GNU HURD         | GCC                     |
-| X86             | Interix          | GCC                     |
-| X86             | kFreeBSD         | GCC                     |
-| X86             | Linux            | GCC                     |
-| X86             | Mac OSX          | GCC                     |
-| X86             | OpenBSD          | GCC                     |
-| X86             | OS/2             | GCC                     |
-| X86             | Solaris          | GCC                     |
-| X86             | Solaris          | Oracle Solaris Studio C |
-| X86             | Windows/Cygwin   | GCC                     |
-| X86             | Windows/MingW    | GCC                     |
-| X86-64          | FreeBSD          | GCC                     |
-| X86-64          | Linux            | GCC                     |
-| X86-64          | Linux/x32        | GCC                     |
-| X86-64          | OpenBSD          | GCC                     |
-| X86-64          | Solaris          | Oracle Solaris Studio C |
-| X86-64          | Windows/Cygwin   | GCC                     |
-| X86-64          | Windows/MingW    | GCC                     |
-| X86-64          | Mac OSX          | GCC                     |
-| Xtensa          | Linux            | GCC                     |
-
-Please send additional platform test results to
-libffi-discuss@sourceware.org.
-
-Installing libffi
-=================
-
-First you must configure the distribution for your particular
-system. Go to the directory you wish to build libffi in and run the
-"configure" program found in the root directory of the libffi source
-distribution.  Note that building libffi requires a C99 compatible
-compiler.
-
-If you're building libffi directly from git hosted sources, configure
-won't exist yet; run ./autogen.sh first.  This will require that you
-install autoconf, automake and libtool.
-
-You may want to tell configure where to install the libffi library and
-header files. To do that, use the ``--prefix`` configure switch.  Libffi
-will install under /usr/local by default. 
-
-If you want to enable extra run-time debugging checks use the the
-``--enable-debug`` configure switch. This is useful when your program dies
-mysteriously while using libffi. 
-
-Another useful configure switch is ``--enable-purify-safety``. Using this
-will add some extra code which will suppress certain warnings when you
-are using Purify with libffi. Only use this switch when using 
-Purify, as it will slow down the library.
-
-If you don't want to build documentation, use the ``--disable-docs``
-configure switch.
-
-It's also possible to build libffi on Windows platforms with
-Microsoft's Visual C++ compiler.  In this case, use the msvcc.sh
-wrapper script during configuration like so:
-
-    path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP="cl -nologo -EP" CPPFLAGS="-DFFI_BUILDING_DLL"
-
-For 64-bit Windows builds, use ``CC="path/to/msvcc.sh -m64"`` and
-``CXX="path/to/msvcc.sh -m64"``.  You may also need to specify
-``--build`` appropriately.
-
-It is also possible to build libffi on Windows platforms with the LLVM
-project's clang-cl compiler, like below:
-
-    path/to/configure CC="path/to/msvcc.sh -clang-cl" CXX="path/to/msvcc.sh -clang-cl" LD=link CPP="clang-cl -EP" 
-
-When building with MSVC under a MingW environment, you may need to
-remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath'
-command.  ('cygpath' is not present in MingW, and is not required when
-using MingW-style paths.)
-
-To build static library for ARM64 with MSVC using visual studio solution, msvc_build folder have
-   aarch64/Ffi_staticLib.sln
-   required header files in aarch64/aarch64_include/
-
-
-SPARC Solaris builds require the use of the GNU assembler and linker.
-Point ``AS`` and ``LD`` environment variables at those tool prior to
-configuration.
-
-For iOS builds, the ``libffi.xcodeproj`` Xcode project is available.
-
-Configure has many other options. Use ``configure --help`` to see them all.
-
-Once configure has finished, type "make". Note that you must be using
-GNU make.  You can ftp GNU make from ftp.gnu.org:/pub/gnu/make .
-
-To ensure that libffi is working as advertised, type "make check".
-This will require that you have DejaGNU installed.
-
-To install the library and header files, type ``make install``.
-
-
-History
-=======
-
-See the git log for details at http://github.com/libffi/libffi.
-
-    3.3 Nov-23-19
-        Add RISC-V support.
-        New API in support of GO closures.
-        Add IEEE754 binary128 long double support for 64-bit Power
-        Default to Microsoft's 64 bit long double ABI with Visual C++.
-        GNU compiler uses 80 bits (128 in memory) FFI_GNUW64 ABI.
-        Add Windows on ARM64 (WOA) support.
-        Add Windows 32-bit ARM support.
-        Raw java (gcj) API deprecated.
-	Add pre-built PDF documentation to source distribution.
-        Many new tests cases and bug fixes.
-        
-    3.2.1 Nov-12-14
-        Build fix for non-iOS AArch64 targets.
-    
-    3.2 Nov-11-14
-        Add C99 Complex Type support (currently only supported on
-          s390).
-        Add support for PASCAL and REGISTER calling conventions on x86
-          Windows/Linux.
-        Add OpenRISC and Cygwin-64 support.
-        Bug fixes.
-    
-    3.1 May-19-14
-        Add AArch64 (ARM64) iOS support.
-        Add Nios II support.
-        Add m88k and DEC VAX support.
-        Add support for stdcall, thiscall, and fastcall on non-Windows
-          32-bit x86 targets such as Linux.
-        Various Android, MIPS N32, x86, FreeBSD and UltraSPARC IIi
-          fixes.
-        Make the testsuite more robust: eliminate several spurious
-          failures, and respect the $CC and $CXX environment variables.
-        Archive off the manually maintained ChangeLog in favor of git
-          log.
-    
-    3.0.13 Mar-17-13
-        Add Meta support.
-        Add missing Moxie bits.
-        Fix stack alignment bug on 32-bit x86.
-        Build fix for m68000 targets.
-        Build fix for soft-float Power targets.
-        Fix the install dir location for some platforms when building
-          with GCC (OS X, Solaris).
-        Fix Cygwin regression.
-    
-    3.0.12 Feb-11-13
-        Add Moxie support.
-        Add AArch64 support.
-        Add Blackfin support.
-        Add TILE-Gx/TILEPro support.
-        Add MicroBlaze support.
-        Add Xtensa support.
-        Add support for PaX enabled kernels with MPROTECT.
-        Add support for native vendor compilers on
-          Solaris and AIX.
-        Work around LLVM/GCC interoperability issue on x86_64.
-    
-    3.0.11 Apr-11-12
-        Lots of build fixes.
-        Add support for variadic functions (ffi_prep_cif_var).
-        Add Linux/x32 support.
-        Add thiscall, fastcall and MSVC cdecl support on Windows.
-        Add Amiga and newer MacOS support.
-        Add m68k FreeMiNT support.
-        Integration with iOS' xcode build tools.
-        Fix Octeon and MC68881 support.
-        Fix code pessimizations.
-    
-    3.0.10 Aug-23-11
-        Add support for Apple's iOS.
-        Add support for ARM VFP ABI.
-        Add RTEMS support for MIPS and M68K.
-        Fix instruction cache clearing problems on
-          ARM and SPARC.
-        Fix the N64 build on mips-sgi-irix6.5.
-        Enable builds with Microsoft's compiler.
-        Enable x86 builds with Oracle's Solaris compiler.
-        Fix support for calling code compiled with Oracle's Sparc
-          Solaris compiler.
-        Testsuite fixes for Tru64 Unix.
-        Additional platform support.
-    
-    3.0.9 Dec-31-09
-        Add AVR32 and win64 ports.  Add ARM softfp support.
-        Many fixes for AIX, Solaris, HP-UX, *BSD.
-        Several PowerPC and x86-64 bug fixes.
-        Build DLL for windows.
-    
-    3.0.8 Dec-19-08
-        Add *BSD, BeOS, and PA-Linux support.
-    
-    3.0.7 Nov-11-08
-        Fix for ppc FreeBSD.
-        (thanks to Andreas Tobler)
-    
-    3.0.6 Jul-17-08
-        Fix for closures on sh.
-        Mark the sh/sh64 stack as non-executable.
-        (both thanks to Kaz Kojima)
-    
-    3.0.5 Apr-3-08
-        Fix libffi.pc file.
-        Fix #define ARM for IcedTea users.
-        Fix x86 closure bug.
-    
-    3.0.4 Feb-24-08
-        Fix x86 OpenBSD configury.
-    
-    3.0.3 Feb-22-08
-        Enable x86 OpenBSD thanks to Thomas Heller, and
-          x86-64 FreeBSD thanks to Björn König and Andreas Tobler.
-        Clean up test instruction in README.
-    
-    3.0.2 Feb-21-08
-        Improved x86 FreeBSD support.
-        Thanks to Björn König.
-    
-    3.0.1 Feb-15-08
-        Fix instruction cache flushing bug on MIPS.
-        Thanks to David Daney.
-    
-    3.0.0 Feb-15-08
-        Many changes, mostly thanks to the GCC project.
-        Cygnus Solutions is now Red Hat.
-    
-      [10 years go by...]
-    
-    1.20 Oct-5-98
-        Raffaele Sena produces ARM port.
-    
-    1.19 Oct-5-98
-        Fixed x86 long double and long long return support.
-        m68k bug fixes from Andreas Schwab.
-        Patch for DU assembler compatibility for the Alpha from Richard
-          Henderson.
-    
-    1.18 Apr-17-98
-        Bug fixes and MIPS configuration changes.
-    
-    1.17 Feb-24-98
-        Bug fixes and m68k port from Andreas Schwab. PowerPC port from
-        Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
-    
-    1.16 Feb-11-98
-        Richard Henderson produces Alpha port.
-    
-    1.15 Dec-4-97
-        Fixed an n32 ABI bug. New libtool, auto* support.
-    
-    1.14 May-13-97
-        libtool is now used to generate shared and static libraries.
-        Fixed a minor portability problem reported by Russ McManus
-        <mcmanr@eq.gs.com>.
-    
-    1.13 Dec-2-96
-        Added --enable-purify-safety to keep Purify from complaining
-          about certain low level code.
-        Sparc fix for calling functions with < 6 args.
-        Linux x86 a.out fix.
-    
-    1.12 Nov-22-96
-        Added missing ffi_type_void, needed for supporting void return 
-          types. Fixed test case for non MIPS machines. Cygnus Support 
-          is now Cygnus Solutions. 
-    
-    1.11 Oct-30-96
-        Added notes about GNU make.
-    
-    1.10 Oct-29-96
-        Added configuration fix for non GNU compilers.
-    
-    1.09 Oct-29-96
-        Added --enable-debug configure switch. Clean-ups based on LCLint 
-        feedback. ffi_mips.h is always installed. Many configuration 
-        fixes. Fixed ffitest.c for sparc builds.
-    
-    1.08 Oct-15-96
-        Fixed n32 problem. Many clean-ups.
-    
-    1.07 Oct-14-96
-        Gordon Irlam rewrites v8.S again. Bug fixes.
-    
-    1.06 Oct-14-96
-        Gordon Irlam improved the sparc port. 
-    
-    1.05 Oct-14-96
-        Interface changes based on feedback.
-    
-    1.04 Oct-11-96
-        Sparc port complete (modulo struct passing bug).
-    
-    1.03 Oct-10-96
-        Passing struct args, and returning struct values works for
-        all architectures/calling conventions. Expanded tests.
-    
-    1.02 Oct-9-96
-        Added SGI n32 support. Fixed bugs in both o32 and Linux support.
-        Added "make test".
-    
-    1.01 Oct-8-96
-        Fixed float passing bug in mips version. Restructured some
-        of the code. Builds cleanly with SGI tools.
-    
-    1.00 Oct-7-96
-        First release. No public announcement.
-
-Authors & Credits
-=================
-
-libffi was originally written by Anthony Green <green@moxielogic.com>.
-
-The developers of the GNU Compiler Collection project have made
-innumerable valuable contributions.  See the ChangeLog file for
-details.
-
-Some of the ideas behind libffi were inspired by Gianni Mariani's free
-gencall library for Silicon Graphics machines.
-
-The closure mechanism was designed and implemented by Kresten Krab
-Thorup.
-
-Major processor architecture ports were contributed by the following
-developers:
-
-    aarch64             Marcus Shawcroft, James Greenhalgh
-    alpha               Richard Henderson
-    arc                 Hackers at Synopsis
-    arm                 Raffaele Sena
-    avr32               Bradley Smith
-    blackfin            Alexandre Keunecke I. de Mendonca
-    cris                Simon Posnjak, Hans-Peter Nilsson
-    frv                 Anthony Green
-    ia64                Hans Boehm
-    m32r                Kazuhiro Inaoka
-    m68k                Andreas Schwab
-    m88k                Miod Vallat
-    metag               Hackers at Imagination Technologies
-    microblaze          Nathan Rossi
-    mips                Anthony Green, Casey Marshall
-    mips64              David Daney
-    moxie               Anthony Green
-    nios ii             Sandra Loosemore
-    openrisc            Sebastian Macke
-    pa                  Randolph Chung, Dave Anglin, Andreas Tobler
-    powerpc             Geoffrey Keating, Andreas Tobler,
-                        David Edelsohn, John Hornkvist
-    powerpc64           Jakub Jelinek
-    riscv               Michael Knyszek, Andrew Waterman, Stef O'Rear
-    s390                Gerhard Tonn, Ulrich Weigand
-    sh                  Kaz Kojima
-    sh64                Kaz Kojima
-    sparc               Anthony Green, Gordon Irlam
-    tile-gx/tilepro     Walter Lee
-    vax                 Miod Vallat
-    x86                 Anthony Green, Jon Beniston
-    x86-64              Bo Thorsen
-    xtensa              Chris Zankel
-
-Jesper Skov and Andrew Haley both did more than their fair share of
-stepping through the code and tracking down bugs.
-
-Thanks also to Tom Tromey for bug fixes, documentation and
-configuration help.
-
-Thanks to Jim Blandy, who provided some useful feedback on the libffi
-interface.
-
-Andreas Tobler has done a tremendous amount of work on the testsuite.
-
-Alex Oliva solved the executable page problem for SElinux.
-
-The list above is almost certainly incomplete and inaccurate.  I'm
-happy to make corrections or additions upon request.
-
-If you have a problem, or have found a bug, please send a note to the
-author at green@moxielogic.com, or the project mailing list at
-libffi-discuss@sourceware.org.
diff --git a/acinclude.m4 b/acinclude.m4
index 1a70efb..3e8f8ba 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -90,390 +90,3 @@
 	    [Define if mmap with MAP_ANON(YMOUS) works.])
 fi
 ])
-
-dnl ----------------------------------------------------------------------
-dnl This whole bit snagged from libstdc++-v3, via libatomic.
-
-dnl
-dnl LIBFFI_ENABLE
-dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING)
-dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, permit a|b|c)
-dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, SHELL-CODE-HANDLER)
-dnl
-dnl See docs/html/17_intro/configury.html#enable for documentation.
-dnl
-m4_define([LIBFFI_ENABLE],[dnl
-m4_define([_g_switch],[--enable-$1])dnl
-m4_define([_g_help],[AC_HELP_STRING(_g_switch$3,[$4 @<:@default=$2@:>@])])dnl
- AC_ARG_ENABLE($1,_g_help,
-  m4_bmatch([$5],
-   [^permit ],
-     [[
-      case "$enableval" in
-       m4_bpatsubst([$5],[permit ])) ;;
-       *) AC_MSG_ERROR(Unknown argument to enable/disable $1) ;;
-          dnl Idea for future:  generate a URL pointing to
-          dnl "onlinedocs/configopts.html#whatever"
-      esac
-     ]],
-   [^$],
-     [[
-      case "$enableval" in
-       yes|no) ;;
-       *) AC_MSG_ERROR(Argument to enable/disable $1 must be yes or no) ;;
-      esac
-     ]],
-   [[$5]]),
-  [enable_]m4_bpatsubst([$1],-,_)[=][$2])
-m4_undefine([_g_switch])dnl
-m4_undefine([_g_help])dnl
-])
-
-dnl
-dnl If GNU ld is in use, check to see if tricky linker opts can be used.  If
-dnl the native linker is in use, all variables will be defined to something
-dnl safe (like an empty string).
-dnl
-dnl Defines:
-dnl  SECTION_LDFLAGS='-Wl,--gc-sections' if possible
-dnl  OPT_LDFLAGS='-Wl,-O1' if possible
-dnl  LD (as a side effect of testing)
-dnl Sets:
-dnl  with_gnu_ld
-dnl  libat_ld_is_gold (possibly)
-dnl  libat_gnu_ld_version (possibly)
-dnl
-dnl The last will be a single integer, e.g., version 1.23.45.0.67.89 will
-dnl set libat_gnu_ld_version to 12345.  Zeros cause problems.
-dnl
-AC_DEFUN([LIBFFI_CHECK_LINKER_FEATURES], [
-  # If we're not using GNU ld, then there's no point in even trying these
-  # tests.  Check for that first.  We should have already tested for gld
-  # by now (in libtool), but require it now just to be safe...
-  test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
-  test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
-  AC_REQUIRE([AC_PROG_LD])
-  AC_REQUIRE([AC_PROG_AWK])
-
-  # The name set by libtool depends on the version of libtool.  Shame on us
-  # for depending on an impl detail, but c'est la vie.  Older versions used
-  # ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
-  # top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
-  # makes sense).  We'll test with_gnu_ld everywhere else, so if that isn't
-  # set (hence we're using an older libtool), then set it.
-  if test x${with_gnu_ld+set} != xset; then
-    if test x${ac_cv_prog_gnu_ld+set} != xset; then
-      # We got through "ac_require(ac_prog_ld)" and still not set?  Huh?
-      with_gnu_ld=no
-    else
-      with_gnu_ld=$ac_cv_prog_gnu_ld
-    fi
-  fi
-
-  # Start by getting the version number.  I think the libtool test already
-  # does some of this, but throws away the result.
-  libat_ld_is_gold=no
-  if $LD --version 2>/dev/null | grep 'GNU gold'> /dev/null 2>&1; then
-    libat_ld_is_gold=yes
-  fi
-  changequote(,)
-  ldver=`$LD --version 2>/dev/null |
-         sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
-  changequote([,])
-  libat_gnu_ld_version=`echo $ldver | \
-         $AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
-
-  # Set --gc-sections.
-  if test "$with_gnu_ld" = "notbroken"; then
-    # GNU ld it is!  Joy and bunny rabbits!
-
-    # All these tests are for C++; save the language and the compiler flags.
-    # Need to do this so that g++ won't try to link in libstdc++
-    ac_test_CFLAGS="${CFLAGS+set}"
-    ac_save_CFLAGS="$CFLAGS"
-    CFLAGS='-x c++  -Wl,--gc-sections'
-
-    # Check for -Wl,--gc-sections
-    # XXX This test is broken at the moment, as symbols required for linking
-    # are now in libsupc++ (not built yet).  In addition, this test has
-    # cored on solaris in the past.  In addition, --gc-sections doesn't
-    # really work at the moment (keeps on discarding used sections, first
-    # .eh_frame and now some of the glibc sections for iconv).
-    # Bzzzzt.  Thanks for playing, maybe next time.
-    AC_MSG_CHECKING([for ld that supports -Wl,--gc-sections])
-    AC_TRY_RUN([
-     int main(void)
-     {
-       try { throw 1; }
-       catch (...) { };
-       return 0;
-     }
-    ], [ac_sectionLDflags=yes],[ac_sectionLDflags=no], [ac_sectionLDflags=yes])
-    if test "$ac_test_CFLAGS" = set; then
-      CFLAGS="$ac_save_CFLAGS"
-    else
-      # this is the suspicious part
-      CFLAGS=''
-    fi
-    if test "$ac_sectionLDflags" = "yes"; then
-      SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
-    fi
-    AC_MSG_RESULT($ac_sectionLDflags)
-  fi
-
-  # Set linker optimization flags.
-  if test x"$with_gnu_ld" = x"yes"; then
-    OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
-  fi
-
-  AC_SUBST(SECTION_LDFLAGS)
-  AC_SUBST(OPT_LDFLAGS)
-])
-
-
-dnl
-dnl If GNU ld is in use, check to see if tricky linker opts can be used.  If
-dnl the native linker is in use, all variables will be defined to something
-dnl safe (like an empty string).
-dnl
-dnl Defines:
-dnl  SECTION_LDFLAGS='-Wl,--gc-sections' if possible
-dnl  OPT_LDFLAGS='-Wl,-O1' if possible
-dnl  LD (as a side effect of testing)
-dnl Sets:
-dnl  with_gnu_ld
-dnl  libat_ld_is_gold (possibly)
-dnl  libat_gnu_ld_version (possibly)
-dnl
-dnl The last will be a single integer, e.g., version 1.23.45.0.67.89 will
-dnl set libat_gnu_ld_version to 12345.  Zeros cause problems.
-dnl
-AC_DEFUN([LIBFFI_CHECK_LINKER_FEATURES], [
-  # If we're not using GNU ld, then there's no point in even trying these
-  # tests.  Check for that first.  We should have already tested for gld
-  # by now (in libtool), but require it now just to be safe...
-  test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
-  test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
-  AC_REQUIRE([AC_PROG_LD])
-  AC_REQUIRE([AC_PROG_AWK])
-
-  # The name set by libtool depends on the version of libtool.  Shame on us
-  # for depending on an impl detail, but c'est la vie.  Older versions used
-  # ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
-  # top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
-  # makes sense).  We'll test with_gnu_ld everywhere else, so if that isn't
-  # set (hence we're using an older libtool), then set it.
-  if test x${with_gnu_ld+set} != xset; then
-    if test x${ac_cv_prog_gnu_ld+set} != xset; then
-      # We got through "ac_require(ac_prog_ld)" and still not set?  Huh?
-      with_gnu_ld=no
-    else
-      with_gnu_ld=$ac_cv_prog_gnu_ld
-    fi
-  fi
-
-  # Start by getting the version number.  I think the libtool test already
-  # does some of this, but throws away the result.
-  libat_ld_is_gold=no
-  if $LD --version 2>/dev/null | grep 'GNU gold'> /dev/null 2>&1; then
-    libat_ld_is_gold=yes
-  fi
-  libat_ld_is_lld=no
-  if $LD --version 2>/dev/null | grep 'LLD '> /dev/null 2>&1; then
-    libat_ld_is_lld=yes
-  fi
-  changequote(,)
-  ldver=`$LD --version 2>/dev/null |
-         sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
-  changequote([,])
-  libat_gnu_ld_version=`echo $ldver | \
-         $AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
-
-  # Set --gc-sections.
-  if test "$with_gnu_ld" = "notbroken"; then
-    # GNU ld it is!  Joy and bunny rabbits!
-
-    # All these tests are for C++; save the language and the compiler flags.
-    # Need to do this so that g++ won't try to link in libstdc++
-    ac_test_CFLAGS="${CFLAGS+set}"
-    ac_save_CFLAGS="$CFLAGS"
-    CFLAGS='-x c++  -Wl,--gc-sections'
-
-    # Check for -Wl,--gc-sections
-    # XXX This test is broken at the moment, as symbols required for linking
-    # are now in libsupc++ (not built yet).  In addition, this test has
-    # cored on solaris in the past.  In addition, --gc-sections doesn't
-    # really work at the moment (keeps on discarding used sections, first
-    # .eh_frame and now some of the glibc sections for iconv).
-    # Bzzzzt.  Thanks for playing, maybe next time.
-    AC_MSG_CHECKING([for ld that supports -Wl,--gc-sections])
-    AC_TRY_RUN([
-     int main(void)
-     {
-       try { throw 1; }
-       catch (...) { };
-       return 0;
-     }
-    ], [ac_sectionLDflags=yes],[ac_sectionLDflags=no], [ac_sectionLDflags=yes])
-    if test "$ac_test_CFLAGS" = set; then
-      CFLAGS="$ac_save_CFLAGS"
-    else
-      # this is the suspicious part
-      CFLAGS=''
-    fi
-    if test "$ac_sectionLDflags" = "yes"; then
-      SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
-    fi
-    AC_MSG_RESULT($ac_sectionLDflags)
-  fi
-
-  # Set linker optimization flags.
-  if test x"$with_gnu_ld" = x"yes"; then
-    OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
-  fi
-
-  AC_SUBST(SECTION_LDFLAGS)
-  AC_SUBST(OPT_LDFLAGS)
-])
-
-
-dnl
-dnl Add version tags to symbols in shared library (or not), additionally
-dnl marking other symbols as private/local (or not).
-dnl
-dnl --enable-symvers=style adds a version script to the linker call when
-dnl       creating the shared library.  The choice of version script is
-dnl       controlled by 'style'.
-dnl --disable-symvers does not.
-dnl  +  Usage:  LIBFFI_ENABLE_SYMVERS[(DEFAULT)]
-dnl       Where DEFAULT is either 'yes' or 'no'.  Passing `yes' tries to
-dnl       choose a default style based on linker characteristics.  Passing
-dnl       'no' disables versioning.
-dnl
-AC_DEFUN([LIBFFI_ENABLE_SYMVERS], [
-
-LIBFFI_ENABLE(symvers,yes,[=STYLE],
-  [enables symbol versioning of the shared library],
-  [permit yes|no|gnu*|sun])
-
-# If we never went through the LIBFFI_CHECK_LINKER_FEATURES macro, then we
-# don't know enough about $LD to do tricks...
-AC_REQUIRE([LIBFFI_CHECK_LINKER_FEATURES])
-
-# Turn a 'yes' into a suitable default.
-if test x$enable_symvers = xyes ; then
-  # FIXME  The following test is too strict, in theory.
-  if test $enable_shared = no || test "x$LD" = x; then
-    enable_symvers=no
-  else
-    if test $with_gnu_ld = yes ; then
-      enable_symvers=gnu
-    else
-      case ${target_os} in
-        # Sun symbol versioning exists since Solaris 2.5.
-        solaris2.[[5-9]]* | solaris2.1[[0-9]]*)
-          enable_symvers=sun ;;
-        *)
-          enable_symvers=no ;;
-      esac
-    fi
-  fi
-fi
-
-# Check if 'sun' was requested on non-Solaris 2 platforms.
-if test x$enable_symvers = xsun ; then
-  case ${target_os} in
-    solaris2*)
-      # All fine.
-      ;;
-    *)
-      # Unlikely to work.
-      AC_MSG_WARN([=== You have requested Sun symbol versioning, but])
-      AC_MSG_WARN([=== you are not targetting Solaris 2.])
-      AC_MSG_WARN([=== Symbol versioning will be disabled.])
-      enable_symvers=no
-      ;;
-  esac
-fi
-
-# Check to see if libgcc_s exists, indicating that shared libgcc is possible.
-if test $enable_symvers != no; then
-  AC_MSG_CHECKING([for shared libgcc])
-  ac_save_CFLAGS="$CFLAGS"
-  CFLAGS=' -lgcc_s'
-  AC_TRY_LINK(, [return 0;], libat_shared_libgcc=yes, libat_shared_libgcc=no)
-  CFLAGS="$ac_save_CFLAGS"
-  if test $libat_shared_libgcc = no; then
-    cat > conftest.c <<EOF
-int main (void) { return 0; }
-EOF
-changequote(,)dnl
-    libat_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
-			     -shared -shared-libgcc -o conftest.so \
-			     conftest.c -v 2>&1 >/dev/null \
-			     | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
-changequote([,])dnl
-    rm -f conftest.c conftest.so
-    if test x${libat_libgcc_s_suffix+set} = xset; then
-      CFLAGS=" -lgcc_s$libat_libgcc_s_suffix"
-      AC_TRY_LINK(, [return 0;], libat_shared_libgcc=yes)
-      CFLAGS="$ac_save_CFLAGS"
-    fi
-  fi
-  AC_MSG_RESULT($libat_shared_libgcc)
-fi
-
-# For GNU ld, we need at least this version.  The format is described in
-# LIBFFI_CHECK_LINKER_FEATURES above.
-libat_min_gnu_ld_version=21400
-# XXXXXXXXXXX libat_gnu_ld_version=21390
-
-# Check to see if unspecified "yes" value can win, given results above.
-# Change "yes" into either "no" or a style name.
-if test $enable_symvers != no && test $libat_shared_libgcc = yes; then
-  if test $with_gnu_ld = yes; then
-    if test $libat_gnu_ld_version -ge $libat_min_gnu_ld_version ; then
-      enable_symvers=gnu
-    elif test $libat_ld_is_gold = yes ; then
-      enable_symvers=gnu
-    elif test $libat_ld_is_lld = yes ; then
-      enable_symvers=gnu
-    else
-      # The right tools, the right setup, but too old.  Fallbacks?
-      AC_MSG_WARN(=== Linker version $libat_gnu_ld_version is too old for)
-      AC_MSG_WARN(=== full symbol versioning support in this release of GCC.)
-      AC_MSG_WARN(=== You would need to upgrade your binutils to version)
-      AC_MSG_WARN(=== $libat_min_gnu_ld_version or later and rebuild GCC.)
-      if test $libat_gnu_ld_version -ge 21200 ; then
-        # Globbing fix is present, proper block support is not.
-        dnl AC_MSG_WARN([=== Dude, you are soooo close.  Maybe we can fake it.])
-        dnl enable_symvers=???
-        AC_MSG_WARN([=== Symbol versioning will be disabled.])
-        enable_symvers=no
-      else
-        # 2.11 or older.
-        AC_MSG_WARN([=== Symbol versioning will be disabled.])
-        enable_symvers=no
-      fi
-    fi
-  elif test $enable_symvers = sun; then
-    : All interesting versions of Sun ld support sun style symbol versioning.
-  else
-    # just fail for now
-    AC_MSG_WARN([=== You have requested some kind of symbol versioning, but])
-    AC_MSG_WARN([=== either you are not using a supported linker, or you are])
-    AC_MSG_WARN([=== not building a shared libgcc_s (which is required).])
-    AC_MSG_WARN([=== Symbol versioning will be disabled.])
-    enable_symvers=no
-  fi
-fi
-if test $enable_symvers = gnu; then
-  AC_DEFINE(LIBFFI_GNU_SYMBOL_VERSIONING, 1,
-	    [Define to 1 if GNU symbol versioning is used for libatomic.])
-fi
-
-AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB, test $enable_symvers != no)
-AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB_GNU, test $enable_symvers = gnu)
-AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB_SUN, test $enable_symvers = sun)
-AC_MSG_NOTICE(versioning on shared library symbols is $enable_symvers)
-])
diff --git a/autogen.sh b/autogen.sh
index fb014a3..d270b98 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,2 +1,2 @@
 #!/bin/sh
-exec autoreconf -v -i
+exec autoreconf -v -f -i
diff --git a/config.guess b/config.guess
deleted file mode 100644
index faa63aa..0000000
--- a/config.guess
+++ /dev/null
@@ -1,1466 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-#   Copyright 1992-2017 Free Software Foundation, Inc.
-
-timestamp='2017-05-11'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program.  This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-#
-# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
-#
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
-#
-# Please send patches to <config-patches@gnu.org>.
-
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
-  -h, --help         print this help, then exit
-  -t, --time-stamp   print date of last modification, then exit
-  -v, --version      print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright 1992-2017 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions.  There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
-  case $1 in
-    --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
-    --version | -v )
-       echo "$version" ; exit ;;
-    --help | --h* | -h )
-       echo "$usage"; exit ;;
-    -- )     # Stop option processing
-       shift; break ;;
-    - )	# Use stdin as input.
-       break ;;
-    -* )
-       echo "$me: invalid option $1$help" >&2
-       exit 1 ;;
-    * )
-       break ;;
-  esac
-done
-
-if test $# != 0; then
-  echo "$me: too many arguments$help" >&2
-  exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int x;" > $dummy.c ;
-	for c in cc gcc c89 c99 ; do
-	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
-	     CC_FOR_BUILD="$c"; break ;
-	  fi ;
-	done ;
-	if test x"$CC_FOR_BUILD" = x ; then
-	  CC_FOR_BUILD=no_compiler_found ;
-	fi
-	;;
- ,,*)   CC_FOR_BUILD=$CC ;;
- ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
-	PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-case "${UNAME_SYSTEM}" in
-Linux|GNU|GNU/*)
-	# If the system lacks a compiler, then just pick glibc.
-	# We could probably try harder.
-	LIBC=gnu
-
-	eval $set_cc_for_build
-	cat <<-EOF > $dummy.c
-	#include <features.h>
-	#if defined(__UCLIBC__)
-	LIBC=uclibc
-	#elif defined(__dietlibc__)
-	LIBC=dietlibc
-	#else
-	LIBC=gnu
-	#endif
-	EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
-	;;
-esac
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
-    *:NetBSD:*:*)
-	# NetBSD (nbsd) targets should (where applicable) match one or
-	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
-	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
-	# switched to ELF, *-*-netbsd* would select the old
-	# object file format.  This provides both forward
-	# compatibility and a consistent mechanism for selecting the
-	# object file format.
-	#
-	# Note: NetBSD doesn't particularly care about the vendor
-	# portion of the name.  We always set it to "unknown".
-	sysctl="sysctl -n hw.machine_arch"
-	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
-	    /sbin/$sysctl 2>/dev/null || \
-	    /usr/sbin/$sysctl 2>/dev/null || \
-	    echo unknown)`
-	case "${UNAME_MACHINE_ARCH}" in
-	    armeb) machine=armeb-unknown ;;
-	    arm*) machine=arm-unknown ;;
-	    sh3el) machine=shl-unknown ;;
-	    sh3eb) machine=sh-unknown ;;
-	    sh5el) machine=sh5le-unknown ;;
-	    earmv*)
-		arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
-		endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
-		machine=${arch}${endian}-unknown
-		;;
-	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
-	esac
-	# The Operating System including object format, if it has switched
-	# to ELF recently (or will in the future) and ABI.
-	case "${UNAME_MACHINE_ARCH}" in
-	    earm*)
-		os=netbsdelf
-		;;
-	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-		eval $set_cc_for_build
-		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
-			| grep -q __ELF__
-		then
-		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
-		    # Return netbsd for either.  FIX?
-		    os=netbsd
-		else
-		    os=netbsdelf
-		fi
-		;;
-	    *)
-		os=netbsd
-		;;
-	esac
-	# Determine ABI tags.
-	case "${UNAME_MACHINE_ARCH}" in
-	    earm*)
-		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
-		abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
-		;;
-	esac
-	# The OS release
-	# Debian GNU/NetBSD machines have a different userland, and
-	# thus, need a distinct triplet. However, they do not need
-	# kernel version information, so it can be replaced with a
-	# suitable tag, in the style of linux-gnu.
-	case "${UNAME_VERSION}" in
-	    Debian*)
-		release='-gnu'
-		;;
-	    *)
-		release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
-		;;
-	esac
-	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
-	# contains redundant information, the shorter form:
-	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "${machine}-${os}${release}${abi}"
-	exit ;;
-    *:Bitrig:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
-	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
-	exit ;;
-    *:OpenBSD:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
-	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
-	exit ;;
-    *:LibertyBSD:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
-	echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
-	exit ;;
-    *:ekkoBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
-	exit ;;
-    *:SolidBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
-	exit ;;
-    macppc:MirBSD:*:*)
-	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
-	exit ;;
-    *:MirBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
-	exit ;;
-    *:Sortix:*:*)
-	echo ${UNAME_MACHINE}-unknown-sortix
-	exit ;;
-    alpha:OSF1:*:*)
-	case $UNAME_RELEASE in
-	*4.0)
-		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
-		;;
-	*5.*)
-		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
-		;;
-	esac
-	# According to Compaq, /usr/sbin/psrinfo has been available on
-	# OSF/1 and Tru64 systems produced since 1995.  I hope that
-	# covers most systems running today.  This code pipes the CPU
-	# types through head -n 1, so we only detect the type of CPU 0.
-	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
-	case "$ALPHA_CPU_TYPE" in
-	    "EV4 (21064)")
-		UNAME_MACHINE=alpha ;;
-	    "EV4.5 (21064)")
-		UNAME_MACHINE=alpha ;;
-	    "LCA4 (21066/21068)")
-		UNAME_MACHINE=alpha ;;
-	    "EV5 (21164)")
-		UNAME_MACHINE=alphaev5 ;;
-	    "EV5.6 (21164A)")
-		UNAME_MACHINE=alphaev56 ;;
-	    "EV5.6 (21164PC)")
-		UNAME_MACHINE=alphapca56 ;;
-	    "EV5.7 (21164PC)")
-		UNAME_MACHINE=alphapca57 ;;
-	    "EV6 (21264)")
-		UNAME_MACHINE=alphaev6 ;;
-	    "EV6.7 (21264A)")
-		UNAME_MACHINE=alphaev67 ;;
-	    "EV6.8CB (21264C)")
-		UNAME_MACHINE=alphaev68 ;;
-	    "EV6.8AL (21264B)")
-		UNAME_MACHINE=alphaev68 ;;
-	    "EV6.8CX (21264D)")
-		UNAME_MACHINE=alphaev68 ;;
-	    "EV6.9A (21264/EV69A)")
-		UNAME_MACHINE=alphaev69 ;;
-	    "EV7 (21364)")
-		UNAME_MACHINE=alphaev7 ;;
-	    "EV7.9 (21364A)")
-		UNAME_MACHINE=alphaev79 ;;
-	esac
-	# A Pn.n version is a patched version.
-	# A Vn.n version is a released version.
-	# A Tn.n version is a released field test version.
-	# A Xn.n version is an unreleased experimental baselevel.
-	# 1.2 uses "1.2" for uname -r.
-	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
-	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
-	exitcode=$?
-	trap '' 0
-	exit $exitcode ;;
-    Alpha\ *:Windows_NT*:*)
-	# How do we know it's Interix rather than the generic POSIX subsystem?
-	# Should we change UNAME_MACHINE based on the output of uname instead
-	# of the specific Alpha model?
-	echo alpha-pc-interix
-	exit ;;
-    21064:Windows_NT:50:3)
-	echo alpha-dec-winnt3.5
-	exit ;;
-    Amiga*:UNIX_System_V:4.0:*)
-	echo m68k-unknown-sysv4
-	exit ;;
-    *:[Aa]miga[Oo][Ss]:*:*)
-	echo ${UNAME_MACHINE}-unknown-amigaos
-	exit ;;
-    *:[Mm]orph[Oo][Ss]:*:*)
-	echo ${UNAME_MACHINE}-unknown-morphos
-	exit ;;
-    *:OS/390:*:*)
-	echo i370-ibm-openedition
-	exit ;;
-    *:z/VM:*:*)
-	echo s390-ibm-zvmoe
-	exit ;;
-    *:OS400:*:*)
-	echo powerpc-ibm-os400
-	exit ;;
-    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
-	echo arm-acorn-riscix${UNAME_RELEASE}
-	exit ;;
-    arm*:riscos:*:*|arm*:RISCOS:*:*)
-	echo arm-unknown-riscos
-	exit ;;
-    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
-	echo hppa1.1-hitachi-hiuxmpp
-	exit ;;
-    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
-	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
-	if test "`(/bin/universe) 2>/dev/null`" = att ; then
-		echo pyramid-pyramid-sysv3
-	else
-		echo pyramid-pyramid-bsd
-	fi
-	exit ;;
-    NILE*:*:*:dcosx)
-	echo pyramid-pyramid-svr4
-	exit ;;
-    DRS?6000:unix:4.0:6*)
-	echo sparc-icl-nx6
-	exit ;;
-    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
-	case `/usr/bin/uname -p` in
-	    sparc) echo sparc-icl-nx7; exit ;;
-	esac ;;
-    s390x:SunOS:*:*)
-	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
-    sun4H:SunOS:5.*:*)
-	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
-    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
-    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
-	echo i386-pc-auroraux${UNAME_RELEASE}
-	exit ;;
-    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-	eval $set_cc_for_build
-	SUN_ARCH=i386
-	# If there is a compiler, see if it is configured for 64-bit objects.
-	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
-	# This test works for both compilers.
-	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
-	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		grep IS_64BIT_ARCH >/dev/null
-	    then
-		SUN_ARCH=x86_64
-	    fi
-	fi
-	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
-    sun4*:SunOS:6*:*)
-	# According to config.sub, this is the proper way to canonicalize
-	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
-	# it's likely to be more like Solaris than SunOS4.
-	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
-    sun4*:SunOS:*:*)
-	case "`/usr/bin/arch -k`" in
-	    Series*|S4*)
-		UNAME_RELEASE=`uname -v`
-		;;
-	esac
-	# Japanese Language versions have a version number like `4.1.3-JL'.
-	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
-	exit ;;
-    sun3*:SunOS:*:*)
-	echo m68k-sun-sunos${UNAME_RELEASE}
-	exit ;;
-    sun*:*:4.2BSD:*)
-	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
-	test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
-	case "`/bin/arch`" in
-	    sun3)
-		echo m68k-sun-sunos${UNAME_RELEASE}
-		;;
-	    sun4)
-		echo sparc-sun-sunos${UNAME_RELEASE}
-		;;
-	esac
-	exit ;;
-    aushp:SunOS:*:*)
-	echo sparc-auspex-sunos${UNAME_RELEASE}
-	exit ;;
-    # The situation for MiNT is a little confusing.  The machine name
-    # can be virtually everything (everything which is not
-    # "atarist" or "atariste" at least should have a processor
-    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
-    # to the lowercase version "mint" (or "freemint").  Finally
-    # the system name "TOS" denotes a system which is actually not
-    # MiNT.  But MiNT is downward compatible to TOS, so this should
-    # be no problem.
-    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-	echo m68k-atari-mint${UNAME_RELEASE}
-	exit ;;
-    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
-	echo m68k-atari-mint${UNAME_RELEASE}
-	exit ;;
-    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-	echo m68k-atari-mint${UNAME_RELEASE}
-	exit ;;
-    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-	echo m68k-milan-mint${UNAME_RELEASE}
-	exit ;;
-    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-	echo m68k-hades-mint${UNAME_RELEASE}
-	exit ;;
-    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-	echo m68k-unknown-mint${UNAME_RELEASE}
-	exit ;;
-    m68k:machten:*:*)
-	echo m68k-apple-machten${UNAME_RELEASE}
-	exit ;;
-    powerpc:machten:*:*)
-	echo powerpc-apple-machten${UNAME_RELEASE}
-	exit ;;
-    RISC*:Mach:*:*)
-	echo mips-dec-mach_bsd4.3
-	exit ;;
-    RISC*:ULTRIX:*:*)
-	echo mips-dec-ultrix${UNAME_RELEASE}
-	exit ;;
-    VAX*:ULTRIX*:*:*)
-	echo vax-dec-ultrix${UNAME_RELEASE}
-	exit ;;
-    2020:CLIX:*:* | 2430:CLIX:*:*)
-	echo clipper-intergraph-clix${UNAME_RELEASE}
-	exit ;;
-    mips:*:*:UMIPS | mips:*:*:RISCos)
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h>  /* for printf() prototype */
-	int main (int argc, char *argv[]) {
-#else
-	int main (argc, argv) int argc; char *argv[]; {
-#endif
-	#if defined (host_mips) && defined (MIPSEB)
-	#if defined (SYSTYPE_SYSV)
-	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
-	#endif
-	#if defined (SYSTYPE_SVR4)
-	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
-	#endif
-	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
-	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
-	#endif
-	#endif
-	  exit (-1);
-	}
-EOF
-	$CC_FOR_BUILD -o $dummy $dummy.c &&
-	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
-	  SYSTEM_NAME=`$dummy $dummyarg` &&
-	    { echo "$SYSTEM_NAME"; exit; }
-	echo mips-mips-riscos${UNAME_RELEASE}
-	exit ;;
-    Motorola:PowerMAX_OS:*:*)
-	echo powerpc-motorola-powermax
-	exit ;;
-    Motorola:*:4.3:PL8-*)
-	echo powerpc-harris-powermax
-	exit ;;
-    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
-	echo powerpc-harris-powermax
-	exit ;;
-    Night_Hawk:Power_UNIX:*:*)
-	echo powerpc-harris-powerunix
-	exit ;;
-    m88k:CX/UX:7*:*)
-	echo m88k-harris-cxux7
-	exit ;;
-    m88k:*:4*:R4*)
-	echo m88k-motorola-sysv4
-	exit ;;
-    m88k:*:3*:R3*)
-	echo m88k-motorola-sysv3
-	exit ;;
-    AViiON:dgux:*:*)
-	# DG/UX returns AViiON for all architectures
-	UNAME_PROCESSOR=`/usr/bin/uname -p`
-	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
-	then
-	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
-	       [ ${TARGET_BINARY_INTERFACE}x = x ]
-	    then
-		echo m88k-dg-dgux${UNAME_RELEASE}
-	    else
-		echo m88k-dg-dguxbcs${UNAME_RELEASE}
-	    fi
-	else
-	    echo i586-dg-dgux${UNAME_RELEASE}
-	fi
-	exit ;;
-    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
-	echo m88k-dolphin-sysv3
-	exit ;;
-    M88*:*:R3*:*)
-	# Delta 88k system running SVR3
-	echo m88k-motorola-sysv3
-	exit ;;
-    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
-	echo m88k-tektronix-sysv3
-	exit ;;
-    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
-	echo m68k-tektronix-bsd
-	exit ;;
-    *:IRIX*:*:*)
-	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
-	exit ;;
-    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
-	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
-	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
-    i*86:AIX:*:*)
-	echo i386-ibm-aix
-	exit ;;
-    ia64:AIX:*:*)
-	if [ -x /usr/bin/oslevel ] ; then
-		IBM_REV=`/usr/bin/oslevel`
-	else
-		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
-	fi
-	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
-	exit ;;
-    *:AIX:2:3)
-	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-		eval $set_cc_for_build
-		sed 's/^		//' << EOF >$dummy.c
-		#include <sys/systemcfg.h>
-
-		main()
-			{
-			if (!__power_pc())
-				exit(1);
-			puts("powerpc-ibm-aix3.2.5");
-			exit(0);
-			}
-EOF
-		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
-		then
-			echo "$SYSTEM_NAME"
-		else
-			echo rs6000-ibm-aix3.2.5
-		fi
-	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
-		echo rs6000-ibm-aix3.2.4
-	else
-		echo rs6000-ibm-aix3.2
-	fi
-	exit ;;
-    *:AIX:*:[4567])
-	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
-	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
-		IBM_ARCH=rs6000
-	else
-		IBM_ARCH=powerpc
-	fi
-	if [ -x /usr/bin/lslpp ] ; then
-		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
-			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
-	else
-		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
-	fi
-	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
-	exit ;;
-    *:AIX:*:*)
-	echo rs6000-ibm-aix
-	exit ;;
-    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
-	echo romp-ibm-bsd4.4
-	exit ;;
-    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
-	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
-	exit ;;                             # report: romp-ibm BSD 4.3
-    *:BOSX:*:*)
-	echo rs6000-bull-bosx
-	exit ;;
-    DPX/2?00:B.O.S.:*:*)
-	echo m68k-bull-sysv3
-	exit ;;
-    9000/[34]??:4.3bsd:1.*:*)
-	echo m68k-hp-bsd
-	exit ;;
-    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
-	echo m68k-hp-bsd4.4
-	exit ;;
-    9000/[34678]??:HP-UX:*:*)
-	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-	case "${UNAME_MACHINE}" in
-	    9000/31? )            HP_ARCH=m68000 ;;
-	    9000/[34]?? )         HP_ARCH=m68k ;;
-	    9000/[678][0-9][0-9])
-		if [ -x /usr/bin/getconf ]; then
-		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
-		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-		    case "${sc_cpu_version}" in
-		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
-		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
-		      532)                      # CPU_PA_RISC2_0
-			case "${sc_kernel_bits}" in
-			  32) HP_ARCH=hppa2.0n ;;
-			  64) HP_ARCH=hppa2.0w ;;
-			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
-			esac ;;
-		    esac
-		fi
-		if [ "${HP_ARCH}" = "" ]; then
-		    eval $set_cc_for_build
-		    sed 's/^		//' << EOF >$dummy.c
-
-		#define _HPUX_SOURCE
-		#include <stdlib.h>
-		#include <unistd.h>
-
-		int main ()
-		{
-		#if defined(_SC_KERNEL_BITS)
-		    long bits = sysconf(_SC_KERNEL_BITS);
-		#endif
-		    long cpu  = sysconf (_SC_CPU_VERSION);
-
-		    switch (cpu)
-			{
-			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
-			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
-			case CPU_PA_RISC2_0:
-		#if defined(_SC_KERNEL_BITS)
-			    switch (bits)
-				{
-				case 64: puts ("hppa2.0w"); break;
-				case 32: puts ("hppa2.0n"); break;
-				default: puts ("hppa2.0"); break;
-				} break;
-		#else  /* !defined(_SC_KERNEL_BITS) */
-			    puts ("hppa2.0"); break;
-		#endif
-			default: puts ("hppa1.0"); break;
-			}
-		    exit (0);
-		}
-EOF
-		    (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
-		    test -z "$HP_ARCH" && HP_ARCH=hppa
-		fi ;;
-	esac
-	if [ ${HP_ARCH} = hppa2.0w ]
-	then
-	    eval $set_cc_for_build
-
-	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
-	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
-	    # generating 64-bit code.  GNU and HP use different nomenclature:
-	    #
-	    # $ CC_FOR_BUILD=cc ./config.guess
-	    # => hppa2.0w-hp-hpux11.23
-	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
-	    # => hppa64-hp-hpux11.23
-
-	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
-		grep -q __LP64__
-	    then
-		HP_ARCH=hppa2.0w
-	    else
-		HP_ARCH=hppa64
-	    fi
-	fi
-	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
-	exit ;;
-    ia64:HP-UX:*:*)
-	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-	echo ia64-hp-hpux${HPUX_REV}
-	exit ;;
-    3050*:HI-UX:*:*)
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
-	#include <unistd.h>
-	int
-	main ()
-	{
-	  long cpu = sysconf (_SC_CPU_VERSION);
-	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
-	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
-	     results, however.  */
-	  if (CPU_IS_PA_RISC (cpu))
-	    {
-	      switch (cpu)
-		{
-		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
-		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
-		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
-		  default: puts ("hppa-hitachi-hiuxwe2"); break;
-		}
-	    }
-	  else if (CPU_IS_HP_MC68K (cpu))
-	    puts ("m68k-hitachi-hiuxwe2");
-	  else puts ("unknown-hitachi-hiuxwe2");
-	  exit (0);
-	}
-EOF
-	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
-		{ echo "$SYSTEM_NAME"; exit; }
-	echo unknown-hitachi-hiuxwe2
-	exit ;;
-    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
-	echo hppa1.1-hp-bsd
-	exit ;;
-    9000/8??:4.3bsd:*:*)
-	echo hppa1.0-hp-bsd
-	exit ;;
-    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
-	echo hppa1.0-hp-mpeix
-	exit ;;
-    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
-	echo hppa1.1-hp-osf
-	exit ;;
-    hp8??:OSF1:*:*)
-	echo hppa1.0-hp-osf
-	exit ;;
-    i*86:OSF1:*:*)
-	if [ -x /usr/sbin/sysversion ] ; then
-	    echo ${UNAME_MACHINE}-unknown-osf1mk
-	else
-	    echo ${UNAME_MACHINE}-unknown-osf1
-	fi
-	exit ;;
-    parisc*:Lites*:*:*)
-	echo hppa1.1-hp-lites
-	exit ;;
-    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
-	echo c1-convex-bsd
-	exit ;;
-    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
-	if getsysinfo -f scalar_acc
-	then echo c32-convex-bsd
-	else echo c2-convex-bsd
-	fi
-	exit ;;
-    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
-	echo c34-convex-bsd
-	exit ;;
-    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
-	echo c38-convex-bsd
-	exit ;;
-    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
-	echo c4-convex-bsd
-	exit ;;
-    CRAY*Y-MP:*:*:*)
-	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
-    CRAY*[A-Z]90:*:*:*)
-	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
-	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-	      -e 's/\.[^.]*$/.X/'
-	exit ;;
-    CRAY*TS:*:*:*)
-	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
-    CRAY*T3E:*:*:*)
-	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
-    CRAY*SV1:*:*:*)
-	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
-    *:UNICOS/mp:*:*)
-	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
-    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
-	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
-	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
-	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
-	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-	exit ;;
-    5000:UNIX_System_V:4.*:*)
-	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
-	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
-	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-	exit ;;
-    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
-	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
-	exit ;;
-    sparc*:BSD/OS:*:*)
-	echo sparc-unknown-bsdi${UNAME_RELEASE}
-	exit ;;
-    *:BSD/OS:*:*)
-	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
-	exit ;;
-    *:FreeBSD:*:*)
-	UNAME_PROCESSOR=`/usr/bin/uname -p`
-	case ${UNAME_PROCESSOR} in
-	    amd64)
-		UNAME_PROCESSOR=x86_64 ;;
-	    i386)
-		UNAME_PROCESSOR=i586 ;;
-	esac
-	echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
-	exit ;;
-    i*:CYGWIN*:*)
-	echo ${UNAME_MACHINE}-pc-cygwin
-	exit ;;
-    *:MINGW64*:*)
-	echo ${UNAME_MACHINE}-pc-mingw64
-	exit ;;
-    *:MINGW*:*)
-	echo ${UNAME_MACHINE}-pc-mingw32
-	exit ;;
-    *:MSYS*:*)
-	echo ${UNAME_MACHINE}-pc-msys
-	exit ;;
-    i*:windows32*:*)
-	# uname -m includes "-pc" on this system.
-	echo ${UNAME_MACHINE}-mingw32
-	exit ;;
-    i*:PW*:*)
-	echo ${UNAME_MACHINE}-pc-pw32
-	exit ;;
-    *:Interix*:*)
-	case ${UNAME_MACHINE} in
-	    x86)
-		echo i586-pc-interix${UNAME_RELEASE}
-		exit ;;
-	    authenticamd | genuineintel | EM64T)
-		echo x86_64-unknown-interix${UNAME_RELEASE}
-		exit ;;
-	    IA64)
-		echo ia64-unknown-interix${UNAME_RELEASE}
-		exit ;;
-	esac ;;
-    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
-	echo i${UNAME_MACHINE}-pc-mks
-	exit ;;
-    8664:Windows_NT:*)
-	echo x86_64-pc-mks
-	exit ;;
-    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
-	# How do we know it's Interix rather than the generic POSIX subsystem?
-	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
-	# UNAME_MACHINE based on the output of uname instead of i386?
-	echo i586-pc-interix
-	exit ;;
-    i*:UWIN*:*)
-	echo ${UNAME_MACHINE}-pc-uwin
-	exit ;;
-    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
-	echo x86_64-unknown-cygwin
-	exit ;;
-    p*:CYGWIN*:*)
-	echo powerpcle-unknown-cygwin
-	exit ;;
-    prep*:SunOS:5.*:*)
-	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
-    *:GNU:*:*)
-	# the GNU system
-	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
-	exit ;;
-    *:GNU/*:*:*)
-	# other systems with GNU libc and userland
-	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
-	exit ;;
-    i*86:Minix:*:*)
-	echo ${UNAME_MACHINE}-pc-minix
-	exit ;;
-    aarch64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    aarch64_be:Linux:*:*)
-	UNAME_MACHINE=aarch64_be
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    alpha:Linux:*:*)
-	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
-	  EV5)   UNAME_MACHINE=alphaev5 ;;
-	  EV56)  UNAME_MACHINE=alphaev56 ;;
-	  PCA56) UNAME_MACHINE=alphapca56 ;;
-	  PCA57) UNAME_MACHINE=alphapca56 ;;
-	  EV6)   UNAME_MACHINE=alphaev6 ;;
-	  EV67)  UNAME_MACHINE=alphaev67 ;;
-	  EV68*) UNAME_MACHINE=alphaev68 ;;
-	esac
-	objdump --private-headers /bin/sh | grep -q ld.so.1
-	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    arc:Linux:*:* | arceb:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    arm*:Linux:*:*)
-	eval $set_cc_for_build
-	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
-	    | grep -q __ARM_EABI__
-	then
-	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	else
-	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
-		| grep -q __ARM_PCS_VFP
-	    then
-		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
-	    else
-		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
-	    fi
-	fi
-	exit ;;
-    avr32*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    cris:Linux:*:*)
-	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
-	exit ;;
-    crisv32:Linux:*:*)
-	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
-	exit ;;
-    e2k:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    frv:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    hexagon:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    i*86:Linux:*:*)
-	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
-	exit ;;
-    ia64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    k1om:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    m32r*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    m68*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    mips:Linux:*:* | mips64:Linux:*:*)
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
-	#undef CPU
-	#undef ${UNAME_MACHINE}
-	#undef ${UNAME_MACHINE}el
-	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=${UNAME_MACHINE}el
-	#else
-	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=${UNAME_MACHINE}
-	#else
-	CPU=
-	#endif
-	#endif
-EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
-	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
-	;;
-    mips64el:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    openrisc*:Linux:*:*)
-	echo or1k-unknown-linux-${LIBC}
-	exit ;;
-    or32:Linux:*:* | or1k*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    padre:Linux:*:*)
-	echo sparc-unknown-linux-${LIBC}
-	exit ;;
-    parisc64:Linux:*:* | hppa64:Linux:*:*)
-	echo hppa64-unknown-linux-${LIBC}
-	exit ;;
-    parisc:Linux:*:* | hppa:Linux:*:*)
-	# Look for CPU level
-	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
-	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
-	  *)    echo hppa-unknown-linux-${LIBC} ;;
-	esac
-	exit ;;
-    ppc64:Linux:*:*)
-	echo powerpc64-unknown-linux-${LIBC}
-	exit ;;
-    ppc:Linux:*:*)
-	echo powerpc-unknown-linux-${LIBC}
-	exit ;;
-    ppc64le:Linux:*:*)
-	echo powerpc64le-unknown-linux-${LIBC}
-	exit ;;
-    ppcle:Linux:*:*)
-	echo powerpcle-unknown-linux-${LIBC}
-	exit ;;
-    riscv32:Linux:*:* | riscv64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    s390:Linux:*:* | s390x:Linux:*:*)
-	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
-	exit ;;
-    sh64*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    sh*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    sparc:Linux:*:* | sparc64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    tile*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    vax:Linux:*:*)
-	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
-	exit ;;
-    x86_64:Linux:*:*)
-	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
-	exit ;;
-    xtensa*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
-    i*86:DYNIX/ptx:4*:*)
-	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
-	# earlier versions are messed up and put the nodename in both
-	# sysname and nodename.
-	echo i386-sequent-sysv4
-	exit ;;
-    i*86:UNIX_SV:4.2MP:2.*)
-	# Unixware is an offshoot of SVR4, but it has its own version
-	# number series starting with 2...
-	# I am not positive that other SVR4 systems won't match this,
-	# I just have to hope.  -- rms.
-	# Use sysv4.2uw... so that sysv4* matches it.
-	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
-	exit ;;
-    i*86:OS/2:*:*)
-	# If we were able to find `uname', then EMX Unix compatibility
-	# is probably installed.
-	echo ${UNAME_MACHINE}-pc-os2-emx
-	exit ;;
-    i*86:XTS-300:*:STOP)
-	echo ${UNAME_MACHINE}-unknown-stop
-	exit ;;
-    i*86:atheos:*:*)
-	echo ${UNAME_MACHINE}-unknown-atheos
-	exit ;;
-    i*86:syllable:*:*)
-	echo ${UNAME_MACHINE}-pc-syllable
-	exit ;;
-    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
-	echo i386-unknown-lynxos${UNAME_RELEASE}
-	exit ;;
-    i*86:*DOS:*:*)
-	echo ${UNAME_MACHINE}-pc-msdosdjgpp
-	exit ;;
-    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
-	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
-	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
-		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
-	else
-		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
-	fi
-	exit ;;
-    i*86:*:5:[678]*)
-	# UnixWare 7.x, OpenUNIX and OpenServer 6.
-	case `/bin/uname -X | grep "^Machine"` in
-	    *486*)	     UNAME_MACHINE=i486 ;;
-	    *Pentium)	     UNAME_MACHINE=i586 ;;
-	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
-	esac
-	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
-	exit ;;
-    i*86:*:3.2:*)
-	if test -f /usr/options/cb.name; then
-		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
-		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
-	elif /bin/uname -X 2>/dev/null >/dev/null ; then
-		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
-		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
-		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
-			&& UNAME_MACHINE=i586
-		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
-			&& UNAME_MACHINE=i686
-		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
-			&& UNAME_MACHINE=i686
-		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
-	else
-		echo ${UNAME_MACHINE}-pc-sysv32
-	fi
-	exit ;;
-    pc:*:*:*)
-	# Left here for compatibility:
-	# uname -m prints for DJGPP always 'pc', but it prints nothing about
-	# the processor, so we play safe by assuming i586.
-	# Note: whatever this is, it MUST be the same as what config.sub
-	# prints for the "djgpp" host, or else GDB configure will decide that
-	# this is a cross-build.
-	echo i586-pc-msdosdjgpp
-	exit ;;
-    Intel:Mach:3*:*)
-	echo i386-pc-mach3
-	exit ;;
-    paragon:*:*:*)
-	echo i860-intel-osf1
-	exit ;;
-    i860:*:4.*:*) # i860-SVR4
-	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
-	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
-	else # Add other i860-SVR4 vendors below as they are discovered.
-	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
-	fi
-	exit ;;
-    mini*:CTIX:SYS*5:*)
-	# "miniframe"
-	echo m68010-convergent-sysv
-	exit ;;
-    mc68k:UNIX:SYSTEM5:3.51m)
-	echo m68k-convergent-sysv
-	exit ;;
-    M680?0:D-NIX:5.3:*)
-	echo m68k-diab-dnix
-	exit ;;
-    M68*:*:R3V[5678]*:*)
-	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
-    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
-	OS_REL=''
-	test -r /etc/.relid \
-	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
-	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
-	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
-    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
-	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-	  && { echo i486-ncr-sysv4; exit; } ;;
-    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
-	OS_REL='.3'
-	test -r /etc/.relid \
-	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
-	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
-	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
-	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
-	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
-    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
-	echo m68k-unknown-lynxos${UNAME_RELEASE}
-	exit ;;
-    mc68030:UNIX_System_V:4.*:*)
-	echo m68k-atari-sysv4
-	exit ;;
-    TSUNAMI:LynxOS:2.*:*)
-	echo sparc-unknown-lynxos${UNAME_RELEASE}
-	exit ;;
-    rs6000:LynxOS:2.*:*)
-	echo rs6000-unknown-lynxos${UNAME_RELEASE}
-	exit ;;
-    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
-	echo powerpc-unknown-lynxos${UNAME_RELEASE}
-	exit ;;
-    SM[BE]S:UNIX_SV:*:*)
-	echo mips-dde-sysv${UNAME_RELEASE}
-	exit ;;
-    RM*:ReliantUNIX-*:*:*)
-	echo mips-sni-sysv4
-	exit ;;
-    RM*:SINIX-*:*:*)
-	echo mips-sni-sysv4
-	exit ;;
-    *:SINIX-*:*:*)
-	if uname -p 2>/dev/null >/dev/null ; then
-		UNAME_MACHINE=`(uname -p) 2>/dev/null`
-		echo ${UNAME_MACHINE}-sni-sysv4
-	else
-		echo ns32k-sni-sysv
-	fi
-	exit ;;
-    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-			# says <Richard.M.Bartel@ccMail.Census.GOV>
-	echo i586-unisys-sysv4
-	exit ;;
-    *:UNIX_System_V:4*:FTX*)
-	# From Gerald Hewes <hewes@openmarket.com>.
-	# How about differentiating between stratus architectures? -djm
-	echo hppa1.1-stratus-sysv4
-	exit ;;
-    *:*:*:FTX*)
-	# From seanf@swdc.stratus.com.
-	echo i860-stratus-sysv4
-	exit ;;
-    i*86:VOS:*:*)
-	# From Paul.Green@stratus.com.
-	echo ${UNAME_MACHINE}-stratus-vos
-	exit ;;
-    *:VOS:*:*)
-	# From Paul.Green@stratus.com.
-	echo hppa1.1-stratus-vos
-	exit ;;
-    mc68*:A/UX:*:*)
-	echo m68k-apple-aux${UNAME_RELEASE}
-	exit ;;
-    news*:NEWS-OS:6*:*)
-	echo mips-sony-newsos6
-	exit ;;
-    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
-	if [ -d /usr/nec ]; then
-		echo mips-nec-sysv${UNAME_RELEASE}
-	else
-		echo mips-unknown-sysv${UNAME_RELEASE}
-	fi
-	exit ;;
-    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
-	echo powerpc-be-beos
-	exit ;;
-    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
-	echo powerpc-apple-beos
-	exit ;;
-    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
-	echo i586-pc-beos
-	exit ;;
-    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
-	echo i586-pc-haiku
-	exit ;;
-    x86_64:Haiku:*:*)
-	echo x86_64-unknown-haiku
-	exit ;;
-    SX-4:SUPER-UX:*:*)
-	echo sx4-nec-superux${UNAME_RELEASE}
-	exit ;;
-    SX-5:SUPER-UX:*:*)
-	echo sx5-nec-superux${UNAME_RELEASE}
-	exit ;;
-    SX-6:SUPER-UX:*:*)
-	echo sx6-nec-superux${UNAME_RELEASE}
-	exit ;;
-    SX-7:SUPER-UX:*:*)
-	echo sx7-nec-superux${UNAME_RELEASE}
-	exit ;;
-    SX-8:SUPER-UX:*:*)
-	echo sx8-nec-superux${UNAME_RELEASE}
-	exit ;;
-    SX-8R:SUPER-UX:*:*)
-	echo sx8r-nec-superux${UNAME_RELEASE}
-	exit ;;
-    SX-ACE:SUPER-UX:*:*)
-	echo sxace-nec-superux${UNAME_RELEASE}
-	exit ;;
-    Power*:Rhapsody:*:*)
-	echo powerpc-apple-rhapsody${UNAME_RELEASE}
-	exit ;;
-    *:Rhapsody:*:*)
-	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
-	exit ;;
-    *:Darwin:*:*)
-	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-	eval $set_cc_for_build
-	if test "$UNAME_PROCESSOR" = unknown ; then
-	    UNAME_PROCESSOR=powerpc
-	fi
-	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
-	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
-		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		    (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		    grep IS_64BIT_ARCH >/dev/null
-		then
-		    case $UNAME_PROCESSOR in
-			i386) UNAME_PROCESSOR=x86_64 ;;
-			powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		    esac
-		fi
-	    fi
-	elif test "$UNAME_PROCESSOR" = i386 ; then
-	    # Avoid executing cc on OS X 10.9, as it ships with a stub
-	    # that puts up a graphical alert prompting to install
-	    # developer tools.  Any system running Mac OS X 10.7 or
-	    # later (Darwin 11 and later) is required to have a 64-bit
-	    # processor. This is not true of the ARM version of Darwin
-	    # that Apple uses in portable devices.
-	    UNAME_PROCESSOR=x86_64
-	fi
-	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
-	exit ;;
-    *:procnto*:*:* | *:QNX:[0123456789]*:*)
-	UNAME_PROCESSOR=`uname -p`
-	if test "$UNAME_PROCESSOR" = x86; then
-		UNAME_PROCESSOR=i386
-		UNAME_MACHINE=pc
-	fi
-	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
-	exit ;;
-    *:QNX:*:4*)
-	echo i386-pc-qnx
-	exit ;;
-    NEO-*:NONSTOP_KERNEL:*:*)
-	echo neo-tandem-nsk${UNAME_RELEASE}
-	exit ;;
-    NSE-*:NONSTOP_KERNEL:*:*)
-	echo nse-tandem-nsk${UNAME_RELEASE}
-	exit ;;
-    NSR-*:NONSTOP_KERNEL:*:*)
-	echo nsr-tandem-nsk${UNAME_RELEASE}
-	exit ;;
-    NSX-*:NONSTOP_KERNEL:*:*)
-	echo nsx-tandem-nsk${UNAME_RELEASE}
-	exit ;;
-    *:NonStop-UX:*:*)
-	echo mips-compaq-nonstopux
-	exit ;;
-    BS2000:POSIX*:*:*)
-	echo bs2000-siemens-sysv
-	exit ;;
-    DS/*:UNIX_System_V:*:*)
-	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
-	exit ;;
-    *:Plan9:*:*)
-	# "uname -m" is not consistent, so use $cputype instead. 386
-	# is converted to i386 for consistency with other x86
-	# operating systems.
-	if test "$cputype" = 386; then
-	    UNAME_MACHINE=i386
-	else
-	    UNAME_MACHINE="$cputype"
-	fi
-	echo ${UNAME_MACHINE}-unknown-plan9
-	exit ;;
-    *:TOPS-10:*:*)
-	echo pdp10-unknown-tops10
-	exit ;;
-    *:TENEX:*:*)
-	echo pdp10-unknown-tenex
-	exit ;;
-    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
-	echo pdp10-dec-tops20
-	exit ;;
-    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
-	echo pdp10-xkl-tops20
-	exit ;;
-    *:TOPS-20:*:*)
-	echo pdp10-unknown-tops20
-	exit ;;
-    *:ITS:*:*)
-	echo pdp10-unknown-its
-	exit ;;
-    SEI:*:*:SEIUX)
-	echo mips-sei-seiux${UNAME_RELEASE}
-	exit ;;
-    *:DragonFly:*:*)
-	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
-	exit ;;
-    *:*VMS:*:*)
-	UNAME_MACHINE=`(uname -p) 2>/dev/null`
-	case "${UNAME_MACHINE}" in
-	    A*) echo alpha-dec-vms ; exit ;;
-	    I*) echo ia64-dec-vms ; exit ;;
-	    V*) echo vax-dec-vms ; exit ;;
-	esac ;;
-    *:XENIX:*:SysV)
-	echo i386-pc-xenix
-	exit ;;
-    i*86:skyos:*:*)
-	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
-	exit ;;
-    i*86:rdos:*:*)
-	echo ${UNAME_MACHINE}-pc-rdos
-	exit ;;
-    i*86:AROS:*:*)
-	echo ${UNAME_MACHINE}-pc-aros
-	exit ;;
-    x86_64:VMkernel:*:*)
-	echo ${UNAME_MACHINE}-unknown-esx
-	exit ;;
-    amd64:Isilon\ OneFS:*:*)
-	echo x86_64-unknown-onefs
-	exit ;;
-esac
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script (version $timestamp), has failed to recognize the
-operating system you are using. If your script is old, overwrite
-config.guess and config.sub with the latest versions from:
-
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
-and
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
-
-If $0 has already been updated, send the following data and any
-information you think might be pertinent to config-patches@gnu.org to
-provide the necessary information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo               = `(hostinfo) 2>/dev/null`
-/bin/universe          = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch              = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM  = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/config.sub b/config.sub
deleted file mode 100644
index 40ea5df..0000000
--- a/config.sub
+++ /dev/null
@@ -1,1836 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-#   Copyright 1992-2017 Free Software Foundation, Inc.
-
-timestamp='2017-04-02'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that
-# program.  This Exception is an additional permission under section 7
-# of the GNU General Public License, version 3 ("GPLv3").
-
-
-# Please send patches to <config-patches@gnu.org>.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support.  The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
-  -h, --help         print this help, then exit
-  -t, --time-stamp   print date of last modification, then exit
-  -v, --version      print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright 1992-2017 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions.  There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
-  case $1 in
-    --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
-    --version | -v )
-       echo "$version" ; exit ;;
-    --help | --h* | -h )
-       echo "$usage"; exit ;;
-    -- )     # Stop option processing
-       shift; break ;;
-    - )	# Use stdin as input.
-       break ;;
-    -* )
-       echo "$me: invalid option $1$help"
-       exit 1 ;;
-
-    *local*)
-       # First pass through any local machine types.
-       echo $1
-       exit ;;
-
-    * )
-       break ;;
-  esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
-    exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
-    exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
-  kopensolaris*-gnu* | cloudabi*-eabi* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  android-linux)
-    os=-linux-android
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
-    ;;
-  *)
-    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-    if [ $basic_machine != $1 ]
-    then os=`echo $1 | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-	-sun*os*)
-		# Prevent following clause from handling this invalid input.
-		;;
-	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple | -axis | -knuth | -cray | -microblaze*)
-		os=
-		basic_machine=$1
-		;;
-	-bluegene*)
-		os=-cnk
-		;;
-	-sim | -cisco | -oki | -wec | -winbond)
-		os=
-		basic_machine=$1
-		;;
-	-scout)
-		;;
-	-wrs)
-		os=-vxworks
-		basic_machine=$1
-		;;
-	-chorusos*)
-		os=-chorusos
-		basic_machine=$1
-		;;
-	-chorusrdb)
-		os=-chorusrdb
-		basic_machine=$1
-		;;
-	-hiux*)
-		os=-hiuxwe2
-		;;
-	-sco6)
-		os=-sco5v6
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5)
-		os=-sco3.2v5
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco4)
-		os=-sco3.2v4
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2.[4-9]*)
-		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2v[4-9]*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5v6*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco*)
-		os=-sco3.2v2
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-udk*)
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-isc)
-		os=-isc2.2
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-clix*)
-		basic_machine=clipper-intergraph
-		;;
-	-isc*)
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-lynx*178)
-		os=-lynxos178
-		;;
-	-lynx*5)
-		os=-lynxos5
-		;;
-	-lynx*)
-		os=-lynxos
-		;;
-	-ptx*)
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
-		;;
-	-windowsnt*)
-		os=`echo $os | sed -e 's/windowsnt/winnt/'`
-		;;
-	-psos*)
-		os=-psos
-		;;
-	-mint | -mint[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
-		;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
-	# Recognize the basic CPU types without company name.
-	# Some are omitted here because they have special meanings below.
-	1750a | 580 \
-	| a29k \
-	| aarch64 | aarch64_be \
-	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-	| am33_2.0 \
-	| arc | arceb \
-	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
-	| avr | avr32 \
-	| ba \
-	| be32 | be64 \
-	| bfin \
-	| c4x | c8051 | clipper \
-	| d10v | d30v | dlx | dsp16xx \
-	| e2k | epiphany \
-	| fido | fr30 | frv | ft32 \
-	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-	| hexagon \
-	| i370 | i860 | i960 | ia16 | ia64 \
-	| ip2k | iq2000 \
-	| k1om \
-	| le32 | le64 \
-	| lm32 \
-	| m32c | m32r | m32rle | m68000 | m68k | m88k \
-	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
-	| mips | mipsbe | mipseb | mipsel | mipsle \
-	| mips16 \
-	| mips64 | mips64el \
-	| mips64octeon | mips64octeonel \
-	| mips64orion | mips64orionel \
-	| mips64r5900 | mips64r5900el \
-	| mips64vr | mips64vrel \
-	| mips64vr4100 | mips64vr4100el \
-	| mips64vr4300 | mips64vr4300el \
-	| mips64vr5000 | mips64vr5000el \
-	| mips64vr5900 | mips64vr5900el \
-	| mipsisa32 | mipsisa32el \
-	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa32r6 | mipsisa32r6el \
-	| mipsisa64 | mipsisa64el \
-	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64r6 | mipsisa64r6el \
-	| mipsisa64sb1 | mipsisa64sb1el \
-	| mipsisa64sr71k | mipsisa64sr71kel \
-	| mipsr5900 | mipsr5900el \
-	| mipstx39 | mipstx39el \
-	| mn10200 | mn10300 \
-	| moxie \
-	| mt \
-	| msp430 \
-	| nds32 | nds32le | nds32be \
-	| nios | nios2 | nios2eb | nios2el \
-	| ns16k | ns32k \
-	| open8 | or1k | or1knd | or32 \
-	| pdp10 | pdp11 | pj | pjl \
-	| powerpc | powerpc64 | powerpc64le | powerpcle \
-	| pru \
-	| pyramid \
-	| riscv32 | riscv64 \
-	| rl78 | rx \
-	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-	| sh64 | sh64le \
-	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-	| spu \
-	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
-	| ubicom32 \
-	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| visium \
-	| wasm32 \
-	| we32k \
-	| x86 | xc16x | xstormy16 | xtensa \
-	| z8k | z80)
-		basic_machine=$basic_machine-unknown
-		;;
-	c54x)
-		basic_machine=tic54x-unknown
-		;;
-	c55x)
-		basic_machine=tic55x-unknown
-		;;
-	c6x)
-		basic_machine=tic6x-unknown
-		;;
-	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
-		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-		basic_machine=$basic_machine-unknown
-		os=-none
-		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
-		;;
-	ms1)
-		basic_machine=mt-unknown
-		;;
-
-	strongarm | thumb | xscale)
-		basic_machine=arm-unknown
-		;;
-	xgate)
-		basic_machine=$basic_machine-unknown
-		os=-none
-		;;
-	xscaleeb)
-		basic_machine=armeb-unknown
-		;;
-
-	xscaleel)
-		basic_machine=armel-unknown
-		;;
-
-	# We use `pc' rather than `unknown'
-	# because (1) that's what they normally are, and
-	# (2) the word "unknown" tends to confuse beginning users.
-	i*86 | x86_64)
-	  basic_machine=$basic_machine-pc
-	  ;;
-	# Object if more than one company name word.
-	*-*-*)
-		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-		exit 1
-		;;
-	# Recognize the basic CPU types with company name.
-	580-* \
-	| a29k-* \
-	| aarch64-* | aarch64_be-* \
-	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
-	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-	| avr-* | avr32-* \
-	| ba-* \
-	| be32-* | be64-* \
-	| bfin-* | bs2000-* \
-	| c[123]* | c30-* | [cjt]90-* | c4x-* \
-	| c8051-* | clipper-* | craynv-* | cydra-* \
-	| d10v-* | d30v-* | dlx-* \
-	| e2k-* | elxsi-* \
-	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-	| h8300-* | h8500-* \
-	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-	| hexagon-* \
-	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
-	| ip2k-* | iq2000-* \
-	| k1om-* \
-	| le32-* | le64-* \
-	| lm32-* \
-	| m32c-* | m32r-* | m32rle-* \
-	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-	| microblaze-* | microblazeel-* \
-	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-	| mips16-* \
-	| mips64-* | mips64el-* \
-	| mips64octeon-* | mips64octeonel-* \
-	| mips64orion-* | mips64orionel-* \
-	| mips64r5900-* | mips64r5900el-* \
-	| mips64vr-* | mips64vrel-* \
-	| mips64vr4100-* | mips64vr4100el-* \
-	| mips64vr4300-* | mips64vr4300el-* \
-	| mips64vr5000-* | mips64vr5000el-* \
-	| mips64vr5900-* | mips64vr5900el-* \
-	| mipsisa32-* | mipsisa32el-* \
-	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa32r6-* | mipsisa32r6el-* \
-	| mipsisa64-* | mipsisa64el-* \
-	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64r6-* | mipsisa64r6el-* \
-	| mipsisa64sb1-* | mipsisa64sb1el-* \
-	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
-	| mipsr5900-* | mipsr5900el-* \
-	| mipstx39-* | mipstx39el-* \
-	| mmix-* \
-	| mt-* \
-	| msp430-* \
-	| nds32-* | nds32le-* | nds32be-* \
-	| nios-* | nios2-* | nios2eb-* | nios2el-* \
-	| none-* | np1-* | ns16k-* | ns32k-* \
-	| open8-* \
-	| or1k*-* \
-	| orion-* \
-	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
-	| pru-* \
-	| pyramid-* \
-	| riscv32-* | riscv64-* \
-	| rl78-* | romp-* | rs6000-* | rx-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
-	| tahoe-* \
-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-	| tile*-* \
-	| tron-* \
-	| ubicom32-* \
-	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
-	| vax-* \
-	| visium-* \
-	| wasm32-* \
-	| we32k-* \
-	| x86-* | x86_64-* | xc16x-* | xps100-* \
-	| xstormy16-* | xtensa*-* \
-	| ymp-* \
-	| z8k-* | z80-*)
-		;;
-	# Recognize the basic CPU types without company name, with glob match.
-	xtensa*)
-		basic_machine=$basic_machine-unknown
-		;;
-	# Recognize the various machine names and aliases which stand
-	# for a CPU type and a company and sometimes even an OS.
-	386bsd)
-		basic_machine=i386-unknown
-		os=-bsd
-		;;
-	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-		basic_machine=m68000-att
-		;;
-	3b*)
-		basic_machine=we32k-att
-		;;
-	a29khif)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	abacus)
-		basic_machine=abacus-unknown
-		;;
-	adobe68k)
-		basic_machine=m68010-adobe
-		os=-scout
-		;;
-	alliant | fx80)
-		basic_machine=fx80-alliant
-		;;
-	altos | altos3068)
-		basic_machine=m68k-altos
-		;;
-	am29k)
-		basic_machine=a29k-none
-		os=-bsd
-		;;
-	amd64)
-		basic_machine=x86_64-pc
-		;;
-	amd64-*)
-		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	amdahl)
-		basic_machine=580-amdahl
-		os=-sysv
-		;;
-	amiga | amiga-*)
-		basic_machine=m68k-unknown
-		;;
-	amigaos | amigados)
-		basic_machine=m68k-unknown
-		os=-amigaos
-		;;
-	amigaunix | amix)
-		basic_machine=m68k-unknown
-		os=-sysv4
-		;;
-	apollo68)
-		basic_machine=m68k-apollo
-		os=-sysv
-		;;
-	apollo68bsd)
-		basic_machine=m68k-apollo
-		os=-bsd
-		;;
-	aros)
-		basic_machine=i386-pc
-		os=-aros
-		;;
-	asmjs)
-		basic_machine=asmjs-unknown
-		;;
-	aux)
-		basic_machine=m68k-apple
-		os=-aux
-		;;
-	balance)
-		basic_machine=ns32k-sequent
-		os=-dynix
-		;;
-	blackfin)
-		basic_machine=bfin-unknown
-		os=-linux
-		;;
-	blackfin-*)
-		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	bluegene*)
-		basic_machine=powerpc-ibm
-		os=-cnk
-		;;
-	c54x-*)
-		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	c55x-*)
-		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	c6x-*)
-		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	c90)
-		basic_machine=c90-cray
-		os=-unicos
-		;;
-	cegcc)
-		basic_machine=arm-unknown
-		os=-cegcc
-		;;
-	convex-c1)
-		basic_machine=c1-convex
-		os=-bsd
-		;;
-	convex-c2)
-		basic_machine=c2-convex
-		os=-bsd
-		;;
-	convex-c32)
-		basic_machine=c32-convex
-		os=-bsd
-		;;
-	convex-c34)
-		basic_machine=c34-convex
-		os=-bsd
-		;;
-	convex-c38)
-		basic_machine=c38-convex
-		os=-bsd
-		;;
-	cray | j90)
-		basic_machine=j90-cray
-		os=-unicos
-		;;
-	craynv)
-		basic_machine=craynv-cray
-		os=-unicosmp
-		;;
-	cr16 | cr16-*)
-		basic_machine=cr16-unknown
-		os=-elf
-		;;
-	crds | unos)
-		basic_machine=m68k-crds
-		;;
-	crisv32 | crisv32-* | etraxfs*)
-		basic_machine=crisv32-axis
-		;;
-	cris | cris-* | etrax*)
-		basic_machine=cris-axis
-		;;
-	crx)
-		basic_machine=crx-unknown
-		os=-elf
-		;;
-	da30 | da30-*)
-		basic_machine=m68k-da30
-		;;
-	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-		basic_machine=mips-dec
-		;;
-	decsystem10* | dec10*)
-		basic_machine=pdp10-dec
-		os=-tops10
-		;;
-	decsystem20* | dec20*)
-		basic_machine=pdp10-dec
-		os=-tops20
-		;;
-	delta | 3300 | motorola-3300 | motorola-delta \
-	      | 3300-motorola | delta-motorola)
-		basic_machine=m68k-motorola
-		;;
-	delta88)
-		basic_machine=m88k-motorola
-		os=-sysv3
-		;;
-	dicos)
-		basic_machine=i686-pc
-		os=-dicos
-		;;
-	djgpp)
-		basic_machine=i586-pc
-		os=-msdosdjgpp
-		;;
-	dpx20 | dpx20-*)
-		basic_machine=rs6000-bull
-		os=-bosx
-		;;
-	dpx2* | dpx2*-bull)
-		basic_machine=m68k-bull
-		os=-sysv3
-		;;
-	e500v[12])
-		basic_machine=powerpc-unknown
-		os=$os"spe"
-		;;
-	e500v[12]-*)
-		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
-		os=$os"spe"
-		;;
-	ebmon29k)
-		basic_machine=a29k-amd
-		os=-ebmon
-		;;
-	elxsi)
-		basic_machine=elxsi-elxsi
-		os=-bsd
-		;;
-	encore | umax | mmax)
-		basic_machine=ns32k-encore
-		;;
-	es1800 | OSE68k | ose68k | ose | OSE)
-		basic_machine=m68k-ericsson
-		os=-ose
-		;;
-	fx2800)
-		basic_machine=i860-alliant
-		;;
-	genix)
-		basic_machine=ns32k-ns
-		;;
-	gmicro)
-		basic_machine=tron-gmicro
-		os=-sysv
-		;;
-	go32)
-		basic_machine=i386-pc
-		os=-go32
-		;;
-	h3050r* | hiux*)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
-		;;
-	h8300hms)
-		basic_machine=h8300-hitachi
-		os=-hms
-		;;
-	h8300xray)
-		basic_machine=h8300-hitachi
-		os=-xray
-		;;
-	h8500hms)
-		basic_machine=h8500-hitachi
-		os=-hms
-		;;
-	harris)
-		basic_machine=m88k-harris
-		os=-sysv3
-		;;
-	hp300-*)
-		basic_machine=m68k-hp
-		;;
-	hp300bsd)
-		basic_machine=m68k-hp
-		os=-bsd
-		;;
-	hp300hpux)
-		basic_machine=m68k-hp
-		os=-hpux
-		;;
-	hp3k9[0-9][0-9] | hp9[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hp9k2[0-9][0-9] | hp9k31[0-9])
-		basic_machine=m68000-hp
-		;;
-	hp9k3[2-9][0-9])
-		basic_machine=m68k-hp
-		;;
-	hp9k6[0-9][0-9] | hp6[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hp9k7[0-79][0-9] | hp7[0-79][0-9])
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k78[0-9] | hp78[0-9])
-		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
-		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[0-9][13679] | hp8[0-9][13679])
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[0-9][0-9] | hp8[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hppa-next)
-		os=-nextstep3
-		;;
-	hppaosf)
-		basic_machine=hppa1.1-hp
-		os=-osf
-		;;
-	hppro)
-		basic_machine=hppa1.1-hp
-		os=-proelf
-		;;
-	i370-ibm* | ibm*)
-		basic_machine=i370-ibm
-		;;
-	i*86v32)
-		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-		os=-sysv32
-		;;
-	i*86v4*)
-		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-		os=-sysv4
-		;;
-	i*86v)
-		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-		os=-sysv
-		;;
-	i*86sol2)
-		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-		os=-solaris2
-		;;
-	i386mach)
-		basic_machine=i386-mach
-		os=-mach
-		;;
-	i386-vsta | vsta)
-		basic_machine=i386-unknown
-		os=-vsta
-		;;
-	iris | iris4d)
-		basic_machine=mips-sgi
-		case $os in
-		    -irix*)
-			;;
-		    *)
-			os=-irix4
-			;;
-		esac
-		;;
-	isi68 | isi)
-		basic_machine=m68k-isi
-		os=-sysv
-		;;
-	leon-*|leon[3-9]-*)
-		basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
-		;;
-	m68knommu)
-		basic_machine=m68k-unknown
-		os=-linux
-		;;
-	m68knommu-*)
-		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	m88k-omron*)
-		basic_machine=m88k-omron
-		;;
-	magnum | m3230)
-		basic_machine=mips-mips
-		os=-sysv
-		;;
-	merlin)
-		basic_machine=ns32k-utek
-		os=-sysv
-		;;
-	microblaze*)
-		basic_machine=microblaze-xilinx
-		;;
-	mingw64)
-		basic_machine=x86_64-pc
-		os=-mingw64
-		;;
-	mingw32)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	mingw32ce)
-		basic_machine=arm-unknown
-		os=-mingw32ce
-		;;
-	miniframe)
-		basic_machine=m68000-convergent
-		;;
-	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
-		;;
-	mips3*-*)
-		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
-		;;
-	mips3*)
-		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
-		;;
-	monitor)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	morphos)
-		basic_machine=powerpc-unknown
-		os=-morphos
-		;;
-	moxiebox)
-		basic_machine=moxie-unknown
-		os=-moxiebox
-		;;
-	msdos)
-		basic_machine=i386-pc
-		os=-msdos
-		;;
-	ms1-*)
-		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
-		;;
-	msys)
-		basic_machine=i686-pc
-		os=-msys
-		;;
-	mvs)
-		basic_machine=i370-ibm
-		os=-mvs
-		;;
-	nacl)
-		basic_machine=le32-unknown
-		os=-nacl
-		;;
-	ncr3000)
-		basic_machine=i486-ncr
-		os=-sysv4
-		;;
-	netbsd386)
-		basic_machine=i386-unknown
-		os=-netbsd
-		;;
-	netwinder)
-		basic_machine=armv4l-rebel
-		os=-linux
-		;;
-	news | news700 | news800 | news900)
-		basic_machine=m68k-sony
-		os=-newsos
-		;;
-	news1000)
-		basic_machine=m68030-sony
-		os=-newsos
-		;;
-	news-3600 | risc-news)
-		basic_machine=mips-sony
-		os=-newsos
-		;;
-	necv70)
-		basic_machine=v70-nec
-		os=-sysv
-		;;
-	next | m*-next )
-		basic_machine=m68k-next
-		case $os in
-		    -nextstep* )
-			;;
-		    -ns2*)
-		      os=-nextstep2
-			;;
-		    *)
-		      os=-nextstep3
-			;;
-		esac
-		;;
-	nh3000)
-		basic_machine=m68k-harris
-		os=-cxux
-		;;
-	nh[45]000)
-		basic_machine=m88k-harris
-		os=-cxux
-		;;
-	nindy960)
-		basic_machine=i960-intel
-		os=-nindy
-		;;
-	mon960)
-		basic_machine=i960-intel
-		os=-mon960
-		;;
-	nonstopux)
-		basic_machine=mips-compaq
-		os=-nonstopux
-		;;
-	np1)
-		basic_machine=np1-gould
-		;;
-	neo-tandem)
-		basic_machine=neo-tandem
-		;;
-	nse-tandem)
-		basic_machine=nse-tandem
-		;;
-	nsr-tandem)
-		basic_machine=nsr-tandem
-		;;
-	nsx-tandem)
-		basic_machine=nsx-tandem
-		;;
-	op50n-* | op60c-*)
-		basic_machine=hppa1.1-oki
-		os=-proelf
-		;;
-	openrisc | openrisc-*)
-		basic_machine=or32-unknown
-		;;
-	os400)
-		basic_machine=powerpc-ibm
-		os=-os400
-		;;
-	OSE68000 | ose68000)
-		basic_machine=m68000-ericsson
-		os=-ose
-		;;
-	os68k)
-		basic_machine=m68k-none
-		os=-os68k
-		;;
-	pa-hitachi)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
-		;;
-	paragon)
-		basic_machine=i860-intel
-		os=-osf
-		;;
-	parisc)
-		basic_machine=hppa-unknown
-		os=-linux
-		;;
-	parisc-*)
-		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	pbd)
-		basic_machine=sparc-tti
-		;;
-	pbb)
-		basic_machine=m68k-tti
-		;;
-	pc532 | pc532-*)
-		basic_machine=ns32k-pc532
-		;;
-	pc98)
-		basic_machine=i386-pc
-		;;
-	pc98-*)
-		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	pentium | p5 | k5 | k6 | nexgen | viac3)
-		basic_machine=i586-pc
-		;;
-	pentiumpro | p6 | 6x86 | athlon | athlon_*)
-		basic_machine=i686-pc
-		;;
-	pentiumii | pentium2 | pentiumiii | pentium3)
-		basic_machine=i686-pc
-		;;
-	pentium4)
-		basic_machine=i786-pc
-		;;
-	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	pentiumpro-* | p6-* | 6x86-* | athlon-*)
-		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	pentium4-*)
-		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	pn)
-		basic_machine=pn-gould
-		;;
-	power)	basic_machine=power-ibm
-		;;
-	ppc | ppcbe)	basic_machine=powerpc-unknown
-		;;
-	ppc-* | ppcbe-*)
-		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	ppcle | powerpclittle)
-		basic_machine=powerpcle-unknown
-		;;
-	ppcle-* | powerpclittle-*)
-		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	ppc64)	basic_machine=powerpc64-unknown
-		;;
-	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	ppc64le | powerpc64little)
-		basic_machine=powerpc64le-unknown
-		;;
-	ppc64le-* | powerpc64little-*)
-		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	ps2)
-		basic_machine=i386-ibm
-		;;
-	pw32)
-		basic_machine=i586-unknown
-		os=-pw32
-		;;
-	rdos | rdos64)
-		basic_machine=x86_64-pc
-		os=-rdos
-		;;
-	rdos32)
-		basic_machine=i386-pc
-		os=-rdos
-		;;
-	rom68k)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	rm[46]00)
-		basic_machine=mips-siemens
-		;;
-	rtpc | rtpc-*)
-		basic_machine=romp-ibm
-		;;
-	s390 | s390-*)
-		basic_machine=s390-ibm
-		;;
-	s390x | s390x-*)
-		basic_machine=s390x-ibm
-		;;
-	sa29200)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	sb1)
-		basic_machine=mipsisa64sb1-unknown
-		;;
-	sb1el)
-		basic_machine=mipsisa64sb1el-unknown
-		;;
-	sde)
-		basic_machine=mipsisa32-sde
-		os=-elf
-		;;
-	sei)
-		basic_machine=mips-sei
-		os=-seiux
-		;;
-	sequent)
-		basic_machine=i386-sequent
-		;;
-	sh)
-		basic_machine=sh-hitachi
-		os=-hms
-		;;
-	sh5el)
-		basic_machine=sh5le-unknown
-		;;
-	sh64)
-		basic_machine=sh64-unknown
-		;;
-	sparclite-wrs | simso-wrs)
-		basic_machine=sparclite-wrs
-		os=-vxworks
-		;;
-	sps7)
-		basic_machine=m68k-bull
-		os=-sysv2
-		;;
-	spur)
-		basic_machine=spur-unknown
-		;;
-	st2000)
-		basic_machine=m68k-tandem
-		;;
-	stratus)
-		basic_machine=i860-stratus
-		os=-sysv4
-		;;
-	strongarm-* | thumb-*)
-		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	sun2)
-		basic_machine=m68000-sun
-		;;
-	sun2os3)
-		basic_machine=m68000-sun
-		os=-sunos3
-		;;
-	sun2os4)
-		basic_machine=m68000-sun
-		os=-sunos4
-		;;
-	sun3os3)
-		basic_machine=m68k-sun
-		os=-sunos3
-		;;
-	sun3os4)
-		basic_machine=m68k-sun
-		os=-sunos4
-		;;
-	sun4os3)
-		basic_machine=sparc-sun
-		os=-sunos3
-		;;
-	sun4os4)
-		basic_machine=sparc-sun
-		os=-sunos4
-		;;
-	sun4sol2)
-		basic_machine=sparc-sun
-		os=-solaris2
-		;;
-	sun3 | sun3-*)
-		basic_machine=m68k-sun
-		;;
-	sun4)
-		basic_machine=sparc-sun
-		;;
-	sun386 | sun386i | roadrunner)
-		basic_machine=i386-sun
-		;;
-	sv1)
-		basic_machine=sv1-cray
-		os=-unicos
-		;;
-	symmetry)
-		basic_machine=i386-sequent
-		os=-dynix
-		;;
-	t3e)
-		basic_machine=alphaev5-cray
-		os=-unicos
-		;;
-	t90)
-		basic_machine=t90-cray
-		os=-unicos
-		;;
-	tile*)
-		basic_machine=$basic_machine-unknown
-		os=-linux-gnu
-		;;
-	tx39)
-		basic_machine=mipstx39-unknown
-		;;
-	tx39el)
-		basic_machine=mipstx39el-unknown
-		;;
-	toad1)
-		basic_machine=pdp10-xkl
-		os=-tops20
-		;;
-	tower | tower-32)
-		basic_machine=m68k-ncr
-		;;
-	tpf)
-		basic_machine=s390x-ibm
-		os=-tpf
-		;;
-	udi29k)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	ultra3)
-		basic_machine=a29k-nyu
-		os=-sym1
-		;;
-	v810 | necv810)
-		basic_machine=v810-nec
-		os=-none
-		;;
-	vaxv)
-		basic_machine=vax-dec
-		os=-sysv
-		;;
-	vms)
-		basic_machine=vax-dec
-		os=-vms
-		;;
-	vpp*|vx|vx-*)
-		basic_machine=f301-fujitsu
-		;;
-	vxworks960)
-		basic_machine=i960-wrs
-		os=-vxworks
-		;;
-	vxworks68)
-		basic_machine=m68k-wrs
-		os=-vxworks
-		;;
-	vxworks29k)
-		basic_machine=a29k-wrs
-		os=-vxworks
-		;;
-	wasm32)
-		basic_machine=wasm32-unknown
-		;;
-	w65*)
-		basic_machine=w65-wdc
-		os=-none
-		;;
-	w89k-*)
-		basic_machine=hppa1.1-winbond
-		os=-proelf
-		;;
-	xbox)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	xps | xps100)
-		basic_machine=xps100-honeywell
-		;;
-	xscale-* | xscalee[bl]-*)
-		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
-		;;
-	ymp)
-		basic_machine=ymp-cray
-		os=-unicos
-		;;
-	z8k-*-coff)
-		basic_machine=z8k-unknown
-		os=-sim
-		;;
-	z80-*-coff)
-		basic_machine=z80-unknown
-		os=-sim
-		;;
-	none)
-		basic_machine=none-none
-		os=-none
-		;;
-
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-	w89k)
-		basic_machine=hppa1.1-winbond
-		;;
-	op50n)
-		basic_machine=hppa1.1-oki
-		;;
-	op60c)
-		basic_machine=hppa1.1-oki
-		;;
-	romp)
-		basic_machine=romp-ibm
-		;;
-	mmix)
-		basic_machine=mmix-knuth
-		;;
-	rs6000)
-		basic_machine=rs6000-ibm
-		;;
-	vax)
-		basic_machine=vax-dec
-		;;
-	pdp10)
-		# there are many clones, so DEC is not a safe bet
-		basic_machine=pdp10-unknown
-		;;
-	pdp11)
-		basic_machine=pdp11-dec
-		;;
-	we32k)
-		basic_machine=we32k-att
-		;;
-	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-		basic_machine=sh-unknown
-		;;
-	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
-		basic_machine=sparc-sun
-		;;
-	cydra)
-		basic_machine=cydra-cydrome
-		;;
-	orion)
-		basic_machine=orion-highlevel
-		;;
-	orion105)
-		basic_machine=clipper-highlevel
-		;;
-	mac | mpw | mac-mpw)
-		basic_machine=m68k-apple
-		;;
-	pmac | pmac-mpw)
-		basic_machine=powerpc-apple
-		;;
-	*-unknown)
-		# Make sure to match an already-canonicalized machine name.
-		;;
-	*)
-		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-		exit 1
-		;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-	*-digital*)
-		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
-		;;
-	*-commodore*)
-		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
-		;;
-	*)
-		;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
-	# First match some system type aliases
-	# that might get confused with valid system types.
-	# -solaris* is a basic system type, with this one exception.
-	-auroraux)
-		os=-auroraux
-		;;
-	-solaris1 | -solaris1.*)
-		os=`echo $os | sed -e 's|solaris1|sunos4|'`
-		;;
-	-solaris)
-		os=-solaris2
-		;;
-	-svr4*)
-		os=-sysv4
-		;;
-	-unixware*)
-		os=-sysv4.2uw
-		;;
-	-gnu/linux*)
-		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
-		;;
-	# First accept the basic system types.
-	# The portable systems comes first.
-	# Each alternative MUST END IN A *, to match a version number.
-	# -sysv* is not here because it comes later, after sysvr4.
-	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-	      | -sym* | -kopensolaris* | -plan9* \
-	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* | -cloudabi* | -sortix* \
-	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
-	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
-	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
-	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
-	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
-	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
-	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
-	      | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
-	# Remember, each alternative MUST END IN *, to match a version number.
-		;;
-	-qnx*)
-		case $basic_machine in
-		    x86-* | i*86-*)
-			;;
-		    *)
-			os=-nto$os
-			;;
-		esac
-		;;
-	-nto-qnx*)
-		;;
-	-nto*)
-		os=`echo $os | sed -e 's|nto|nto-qnx|'`
-		;;
-	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
-	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
-		;;
-	-mac*)
-		os=`echo $os | sed -e 's|mac|macos|'`
-		;;
-	-linux-dietlibc)
-		os=-linux-dietlibc
-		;;
-	-linux*)
-		os=`echo $os | sed -e 's|linux|linux-gnu|'`
-		;;
-	-sunos5*)
-		os=`echo $os | sed -e 's|sunos5|solaris2|'`
-		;;
-	-sunos6*)
-		os=`echo $os | sed -e 's|sunos6|solaris3|'`
-		;;
-	-opened*)
-		os=-openedition
-		;;
-	-os400*)
-		os=-os400
-		;;
-	-wince*)
-		os=-wince
-		;;
-	-osfrose*)
-		os=-osfrose
-		;;
-	-osf*)
-		os=-osf
-		;;
-	-utek*)
-		os=-bsd
-		;;
-	-dynix*)
-		os=-bsd
-		;;
-	-acis*)
-		os=-aos
-		;;
-	-atheos*)
-		os=-atheos
-		;;
-	-syllable*)
-		os=-syllable
-		;;
-	-386bsd)
-		os=-bsd
-		;;
-	-ctix* | -uts*)
-		os=-sysv
-		;;
-	-nova*)
-		os=-rtmk-nova
-		;;
-	-ns2 )
-		os=-nextstep2
-		;;
-	-nsk*)
-		os=-nsk
-		;;
-	# Preserve the version number of sinix5.
-	-sinix5.*)
-		os=`echo $os | sed -e 's|sinix|sysv|'`
-		;;
-	-sinix*)
-		os=-sysv4
-		;;
-	-tpf*)
-		os=-tpf
-		;;
-	-triton*)
-		os=-sysv3
-		;;
-	-oss*)
-		os=-sysv3
-		;;
-	-svr4)
-		os=-sysv4
-		;;
-	-svr3)
-		os=-sysv3
-		;;
-	-sysvr4)
-		os=-sysv4
-		;;
-	# This must come after -sysvr4.
-	-sysv*)
-		;;
-	-ose*)
-		os=-ose
-		;;
-	-es1800*)
-		os=-ose
-		;;
-	-xenix)
-		os=-xenix
-		;;
-	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-		os=-mint
-		;;
-	-aros*)
-		os=-aros
-		;;
-	-zvmoe)
-		os=-zvmoe
-		;;
-	-dicos*)
-		os=-dicos
-		;;
-	-nacl*)
-		;;
-	-ios)
-		;;
-	-none)
-		;;
-	*)
-		# Get rid of the `-' at the beginning of $os.
-		os=`echo $os | sed 's/[^-]*-//'`
-		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
-		exit 1
-		;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system.  Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
-	score-*)
-		os=-elf
-		;;
-	spu-*)
-		os=-elf
-		;;
-	*-acorn)
-		os=-riscix1.2
-		;;
-	arm*-rebel)
-		os=-linux
-		;;
-	arm*-semi)
-		os=-aout
-		;;
-	c4x-* | tic4x-*)
-		os=-coff
-		;;
-	c8051-*)
-		os=-elf
-		;;
-	hexagon-*)
-		os=-elf
-		;;
-	tic54x-*)
-		os=-coff
-		;;
-	tic55x-*)
-		os=-coff
-		;;
-	tic6x-*)
-		os=-coff
-		;;
-	# This must come before the *-dec entry.
-	pdp10-*)
-		os=-tops20
-		;;
-	pdp11-*)
-		os=-none
-		;;
-	*-dec | vax-*)
-		os=-ultrix4.2
-		;;
-	m68*-apollo)
-		os=-domain
-		;;
-	i386-sun)
-		os=-sunos4.0.2
-		;;
-	m68000-sun)
-		os=-sunos3
-		;;
-	m68*-cisco)
-		os=-aout
-		;;
-	mep-*)
-		os=-elf
-		;;
-	mips*-cisco)
-		os=-elf
-		;;
-	mips*-*)
-		os=-elf
-		;;
-	or32-*)
-		os=-coff
-		;;
-	*-tti)	# must be before sparc entry or we get the wrong os.
-		os=-sysv3
-		;;
-	sparc-* | *-sun)
-		os=-sunos4.1.1
-		;;
-	pru-*)
-		os=-elf
-		;;
-	*-be)
-		os=-beos
-		;;
-	*-haiku)
-		os=-haiku
-		;;
-	*-ibm)
-		os=-aix
-		;;
-	*-knuth)
-		os=-mmixware
-		;;
-	*-wec)
-		os=-proelf
-		;;
-	*-winbond)
-		os=-proelf
-		;;
-	*-oki)
-		os=-proelf
-		;;
-	*-hp)
-		os=-hpux
-		;;
-	*-hitachi)
-		os=-hiux
-		;;
-	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-		os=-sysv
-		;;
-	*-cbm)
-		os=-amigaos
-		;;
-	*-dg)
-		os=-dgux
-		;;
-	*-dolphin)
-		os=-sysv3
-		;;
-	m68k-ccur)
-		os=-rtu
-		;;
-	m88k-omron*)
-		os=-luna
-		;;
-	*-next )
-		os=-nextstep
-		;;
-	*-sequent)
-		os=-ptx
-		;;
-	*-crds)
-		os=-unos
-		;;
-	*-ns)
-		os=-genix
-		;;
-	i370-*)
-		os=-mvs
-		;;
-	*-next)
-		os=-nextstep3
-		;;
-	*-gould)
-		os=-sysv
-		;;
-	*-highlevel)
-		os=-bsd
-		;;
-	*-encore)
-		os=-bsd
-		;;
-	*-sgi)
-		os=-irix
-		;;
-	*-siemens)
-		os=-sysv4
-		;;
-	*-masscomp)
-		os=-rtu
-		;;
-	f30[01]-fujitsu | f700-fujitsu)
-		os=-uxpv
-		;;
-	*-rom68k)
-		os=-coff
-		;;
-	*-*bug)
-		os=-coff
-		;;
-	*-apple)
-		os=-macos
-		;;
-	*-atari*)
-		os=-mint
-		;;
-	*)
-		os=-none
-		;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-	*-unknown)
-		case $os in
-			-riscix*)
-				vendor=acorn
-				;;
-			-sunos*)
-				vendor=sun
-				;;
-			-cnk*|-aix*)
-				vendor=ibm
-				;;
-			-beos*)
-				vendor=be
-				;;
-			-hpux*)
-				vendor=hp
-				;;
-			-mpeix*)
-				vendor=hp
-				;;
-			-hiux*)
-				vendor=hitachi
-				;;
-			-unos*)
-				vendor=crds
-				;;
-			-dgux*)
-				vendor=dg
-				;;
-			-luna*)
-				vendor=omron
-				;;
-			-genix*)
-				vendor=ns
-				;;
-			-mvs* | -opened*)
-				vendor=ibm
-				;;
-			-os400*)
-				vendor=ibm
-				;;
-			-ptx*)
-				vendor=sequent
-				;;
-			-tpf*)
-				vendor=ibm
-				;;
-			-vxsim* | -vxworks* | -windiss*)
-				vendor=wrs
-				;;
-			-aux*)
-				vendor=apple
-				;;
-			-hms*)
-				vendor=hitachi
-				;;
-			-mpw* | -macos*)
-				vendor=apple
-				;;
-			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-				vendor=atari
-				;;
-			-vos*)
-				vendor=stratus
-				;;
-		esac
-		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
-		;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/configure.ac b/configure.ac
index b764368..a7bf5ee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 
 AC_PREREQ(2.68)
 
-AC_INIT([libffi], [3.3], [http://github.com/libffi/libffi/issues])
+AC_INIT([libffi], [3.2.1], [http://github.com/atgreen/libffi/issues])
 AC_CONFIG_HEADERS([fficonfig.h])
 
 AC_CANONICAL_SYSTEM
@@ -72,16 +72,272 @@
 
 TARGETDIR="unknown"
 HAVE_LONG_DOUBLE_VARIANT=0
+case "$host" in
+  aarch64*-*-*)
+	TARGET=AARCH64; TARGETDIR=aarch64
+	;;
 
-. ${srcdir}/configure.host
+  alpha*-*-*)
+	TARGET=ALPHA; TARGETDIR=alpha;
+	# Support 128-bit long double, changeable via command-line switch.
+	HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
+	;;
 
-if test -n "${UNSUPPORTED}"; then
-  AC_MSG_ERROR(["libffi has not been ported to $host."])
-fi
+  arc*-*-*)
+	TARGET=ARC; TARGETDIR=arc
+	;;
+
+  arm*-*-*)
+	TARGET=ARM; TARGETDIR=arm
+	;;
+
+  amd64-*-freebsd* | amd64-*-openbsd*)
+	TARGET=X86_64; TARGETDIR=x86
+  	;;
+
+  amd64-*-freebsd*)
+	TARGET=X86_64; TARGETDIR=x86
+  	;;
+
+  amd64-*-freebsd*)
+	TARGET=X86_64; TARGETDIR=x86
+	;;
+
+  avr32*-*-*)
+	TARGET=AVR32; TARGETDIR=avr32
+	;;
+
+  bfin*)
+  	TARGET=BFIN; TARGETDIR=bfin
+  	;;
+
+  cris-*-*)
+	TARGET=LIBFFI_CRIS; TARGETDIR=cris
+	;;
+
+  frv-*-*)
+	TARGET=FRV; TARGETDIR=frv
+	;;
+
+  hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
+	TARGET=PA_LINUX; TARGETDIR=pa
+	;;
+  hppa*64-*-hpux*)
+	TARGET=PA64_HPUX; TARGETDIR=pa
+	;;
+  hppa*-*-hpux*)
+	TARGET=PA_HPUX; TARGETDIR=pa
+	;;
+
+  i?86-*-freebsd* | i?86-*-openbsd*)
+	TARGET=X86_FREEBSD; TARGETDIR=x86
+	;;
+  i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*)
+	TARGET=X86_WIN32; TARGETDIR=x86
+	# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
+	# We must also check with_cross_host to decide if this is a native
+	# or cross-build and select where to install dlls appropriately.
+	if test -n "$with_cross_host" &&
+	   test x"$with_cross_host" != x"no"; then
+	  AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
+	else
+	  AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
+	fi
+	;;
+  i?86-*-darwin*)
+	TARGET=X86_DARWIN; TARGETDIR=x86
+	;;
+  i?86-*-solaris2.1[[0-9]]*)
+	TARGETDIR=x86
+	if test $ac_cv_sizeof_size_t = 4; then
+	  TARGET=X86; 
+	else
+	  TARGET=X86_64; 
+	fi	  
+	;;
+
+  x86_64-*-darwin*)
+	TARGET=X86_DARWIN; TARGETDIR=x86
+	;;
+
+  x86_64-*-cygwin* | x86_64-*-mingw*)
+	TARGET=X86_WIN64; TARGETDIR=x86
+	# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
+	# We must also check with_cross_host to decide if this is a native
+	# or cross-build and select where to install dlls appropriately.
+	if test -n "$with_cross_host" &&
+	   test x"$with_cross_host" != x"no"; then
+	  AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
+	else
+	  AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
+	fi
+	;;
+
+  i?86-*-* | x86_64-*-*)
+	TARGETDIR=x86
+	if test $ac_cv_sizeof_size_t = 4; then
+	  case "$host" in
+	    *-gnux32)
+	      TARGET=X86_64
+	      ;;
+	    *)
+	      TARGET=X86
+	      ;;
+          esac	
+	else
+	  TARGET=X86_64; 
+	fi	  
+	;;
+
+  ia64*-*-*)
+	TARGET=IA64; TARGETDIR=ia64
+	;;
+
+  m32r*-*-*)
+	TARGET=M32R; TARGETDIR=m32r
+	;;
+
+  m68k-*-*)
+	TARGET=M68K; TARGETDIR=m68k
+	;;
+
+  m88k-*-*)
+	TARGET=M88K; TARGETDIR=m88k
+	;;
+
+  microblaze*-*-*)
+	TARGET=MICROBLAZE; TARGETDIR=microblaze
+	;;
+
+  moxie-*-*)
+	TARGET=MOXIE; TARGETDIR=moxie
+	;;
+
+  metag-*-*)
+	TARGET=METAG; TARGETDIR=metag
+	;;
+
+  mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
+	TARGET=MIPS; TARGETDIR=mips
+	;;
+  mips*-*linux* | mips*-*-openbsd*)
+	# Support 128-bit long double for NewABI.
+	HAVE_LONG_DOUBLE='defined(__mips64)'
+	TARGET=MIPS; TARGETDIR=mips
+	;;
+
+  nios2*-linux*)
+	TARGET=NIOS2; TARGETDIR=nios2
+	;;
+
+  or1k*-linux*)
+	TARGET=OR1K; TARGETDIR=or1k
+	;;
+
+  powerpc*-*-linux* | powerpc-*-sysv*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	HAVE_LONG_DOUBLE_VARIANT=1
+	;;
+  powerpc-*-amigaos*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc-*-beos*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc-*-darwin* | powerpc64-*-darwin*)
+	TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
+	;;
+  powerpc-*-aix* | rs6000-*-aix*)
+	TARGET=POWERPC_AIX; TARGETDIR=powerpc
+	;;
+  powerpc-*-freebsd* | powerpc-*-openbsd*)
+	TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
+	HAVE_LONG_DOUBLE_VARIANT=1
+	;;
+  powerpc64-*-freebsd*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc*-*-rtems*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+
+  s390-*-* | s390x-*-*)
+	TARGET=S390; TARGETDIR=s390
+	;;
+
+  sh-*-* | sh[[34]]*-*-*)
+	TARGET=SH; TARGETDIR=sh
+	;;
+  sh64-*-* | sh5*-*-*)
+	TARGET=SH64; TARGETDIR=sh64
+	;;
+
+  sparc*-*-*)
+	TARGET=SPARC; TARGETDIR=sparc
+	;;
+
+  tile*-*)
+        TARGET=TILE; TARGETDIR=tile
+        ;;
+
+  vax-*-*)
+	TARGET=VAX; TARGETDIR=vax
+	;;
+
+  xtensa*-*)
+	TARGET=XTENSA; TARGETDIR=xtensa
+	;;
+
+esac
 
 AC_SUBST(AM_RUNTESTFLAGS)
 AC_SUBST(AM_LTLDFLAGS)
 
+if test $TARGETDIR = unknown; then
+  AC_MSG_ERROR(["libffi has not been ported to $host."])
+fi
+
+AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
+AM_CONDITIONAL(BFIN, test x$TARGET = xBFIN)
+AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
+AM_CONDITIONAL(X86, test x$TARGET = xX86)
+AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
+AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
+AM_CONDITIONAL(X86_WIN64, test x$TARGET = xX86_WIN64)
+AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
+AM_CONDITIONAL(X86_DARWIN32, test x$TARGET = xX86_DARWIN && test $ac_cv_sizeof_size_t = 4)
+AM_CONDITIONAL(X86_DARWIN64, test x$TARGET = xX86_DARWIN && test $ac_cv_sizeof_size_t = 8)
+AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
+AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
+AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
+AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
+AM_CONDITIONAL(M88K, test x$TARGET = xM88K)
+AM_CONDITIONAL(MICROBLAZE, test x$TARGET = xMICROBLAZE)
+AM_CONDITIONAL(METAG, test x$TARGET = xMETAG)
+AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
+AM_CONDITIONAL(NIOS2, test x$TARGET = xNIOS2)
+AM_CONDITIONAL(OR1K, test x$TARGET = xOR1K)
+AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
+AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
+AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
+AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
+AM_CONDITIONAL(AARCH64, test x$TARGET = xAARCH64)
+AM_CONDITIONAL(ARC, test x$TARGET = xARC)
+AM_CONDITIONAL(ARM, test x$TARGET = xARM)
+AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
+AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
+AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
+AM_CONDITIONAL(S390, test x$TARGET = xS390)
+AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
+AM_CONDITIONAL(SH, test x$TARGET = xSH)
+AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
+AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
+AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
+AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
+AM_CONDITIONAL(TILE, test x$TARGET = xTILE)
+AM_CONDITIONAL(VAX, test x$TARGET = xVAX)
+AM_CONDITIONAL(XTENSA, test x$TARGET = xXTENSA)
+
 AC_HEADER_STDC
 AC_CHECK_FUNCS(memcpy)
 AC_FUNC_ALLOCA
@@ -111,8 +367,7 @@
 
 GCC_AS_CFI_PSEUDO_OP
 
-case "$TARGET" in
-  SPARC)
+if test x$TARGET = xSPARC; then
     AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
 	libffi_cv_as_sparc_ua_pcrel, [
 	save_CFLAGS="$CFLAGS"
@@ -141,9 +396,9 @@
        AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
 	       [Define if your assembler supports .register.])
     fi
-    ;;
+fi
 
-  X86*)
+if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
     AC_CACHE_CHECK([assembler supports pc related relocs],
 	libffi_cv_as_x86_pcrel, [
 	libffi_cv_as_x86_pcrel=no
@@ -156,25 +411,33 @@
 	AC_DEFINE(HAVE_AS_X86_PCREL, 1,
 		  [Define if your assembler supports PC relative relocs.])
     fi
-    ;;
 
-  S390)
-    AC_CACHE_CHECK([compiler uses zarch features],
-	libffi_cv_as_s390_zarch, [
-	libffi_cv_as_s390_zarch=no
-	echo 'void foo(void) { bar(); bar(); }' > conftest.c
-	if $CC $CFLAGS -S conftest.c > /dev/null 2>&1; then
-	    if grep -q brasl conftest.s; then
-	        libffi_cv_as_s390_zarch=yes
-	    fi
-	fi
-	])
-    if test "x$libffi_cv_as_s390_zarch" = xyes; then
-	AC_DEFINE(HAVE_AS_S390_ZARCH, 1,
-		  [Define if the compiler uses zarch features.])
+    AC_CACHE_CHECK([assembler .ascii pseudo-op support],
+       libffi_cv_as_ascii_pseudo_op, [
+       libffi_cv_as_ascii_pseudo_op=unknown
+       # Check if we have .ascii
+       AC_TRY_COMPILE(,[asm (".ascii \\"string\\"");],
+		       [libffi_cv_as_ascii_pseudo_op=yes],
+		       [libffi_cv_as_ascii_pseudo_op=no])
+    ])
+    if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
+       AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
+	       [Define if your assembler supports .ascii.])
     fi
-    ;;
-esac
+
+    AC_CACHE_CHECK([assembler .string pseudo-op support],
+       libffi_cv_as_string_pseudo_op, [
+       libffi_cv_as_string_pseudo_op=unknown
+       # Check if we have .string
+       AC_TRY_COMPILE(,[asm (".string \\"string\\"");],
+		       [libffi_cv_as_string_pseudo_op=yes],
+		       [libffi_cv_as_string_pseudo_op=no])
+    ])
+    if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
+       AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
+	       [Define if your assembler supports .string.])
+    fi
+fi
 
 # On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC.
 AC_ARG_ENABLE(pax_emutramp,
@@ -191,13 +454,13 @@
 
 FFI_EXEC_TRAMPOLINE_TABLE=0
 case "$target" in
-     *arm*-apple-* | aarch64-apple-*)
+     *arm*-apple-darwin*)
        FFI_EXEC_TRAMPOLINE_TABLE=1
        AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,
                  [Cannot use PROT_EXEC on this target, so, we revert to
                    alternative means])
      ;;
-     *-apple-* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris* | *-linux-android*)
+     *-apple-darwin1* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*)
        AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
                  [Cannot use malloc on this target, so, we revert to
                    alternative means])
@@ -245,13 +508,11 @@
   	if $CC $CFLAGS -c -fpic -fexceptions -o conftest.o conftest.c > /dev/null 2>&1; then
 	    objdump -h conftest.o > conftest.dump 2>&1
 	    libffi_eh_frame_line=`grep -n eh_frame conftest.dump | cut -d: -f 1`
-	    if test "x$libffi_eh_frame_line" != "x"; then
-	        libffi_test_line=`expr $libffi_eh_frame_line + 1`p
-	        sed -n $libffi_test_line conftest.dump > conftest.line
-	        if grep READONLY conftest.line > /dev/null; then
-	            libffi_cv_ro_eh_frame=yes
-	        fi
-	    fi
+	    libffi_test_line=`expr $libffi_eh_frame_line + 1`p
+	    sed -n $libffi_test_line conftest.dump > conftest.line
+  	    if grep READONLY conftest.line > /dev/null; then
+  		libffi_cv_ro_eh_frame=yes
+  	    fi
   	fi
   	rm -f conftest.*
       ])
@@ -270,7 +531,7 @@
   	echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1  ; }' > conftest.c
   	libffi_cv_hidden_visibility_attribute=no
   	if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
-  	    if egrep '(\.hidden|\.private_extern).*foo' conftest.s >/dev/null; then
+  	    if grep '\.hidden.*foo' conftest.s >/dev/null; then
   		libffi_cv_hidden_visibility_attribute=yes
   	    fi
   	fi
@@ -282,21 +543,10 @@
   fi
 fi
 
-AC_ARG_ENABLE(docs,
-              AC_HELP_STRING([--disable-docs],
-                             [Disable building of docs (default: no)]),
-              [enable_docs=no],
-              [enable_docs=yes])
-AM_CONDITIONAL(BUILD_DOCS, [test x$enable_docs = xyes])
-
 AH_BOTTOM([
 #ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
 #ifdef LIBFFI_ASM
-#ifdef __APPLE__
-#define FFI_HIDDEN(name) .private_extern name
-#else
 #define FFI_HIDDEN(name) .hidden name
-#endif
 #else
 #define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
 #endif
@@ -312,14 +562,6 @@
 AC_SUBST(TARGET)
 AC_SUBST(TARGETDIR)
 
-changequote(<,>)
-TARGET_OBJ=
-for i in $SOURCES; do
-  TARGET_OBJ="${TARGET_OBJ} src/${TARGETDIR}/"`echo $i | sed 's/[cS]$/lo/'`
-done
-changequote([,])
-AC_SUBST(TARGET_OBJ)
-
 AC_SUBST(SHELL)
 
 AC_ARG_ENABLE(debug,
@@ -348,47 +590,36 @@
     AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
   fi)
 
-AC_ARG_ENABLE(multi-os-directory,
-[  --disable-multi-os-directory
-                          disable use of gcc --print-multi-os-directory to change the library installation directory])
-                          
 # These variables are only ever used when we cross-build to X86_WIN32.
 # And we only support this with GCC, so...
 if test "x$GCC" = "xyes"; then
   if test -n "$with_cross_host" &&
      test x"$with_cross_host" != x"no"; then
-    toolexecdir='${exec_prefix}'/'$(target_alias)'
-    toolexeclibdir='${toolexecdir}'/lib
+    toolexecdir="${exec_prefix}"/'$(target_alias)'
+    toolexeclibdir="${toolexecdir}"/lib
   else
-    toolexecdir='${libdir}'/gcc-lib/'$(target_alias)'
-    toolexeclibdir='${libdir}'
+    toolexecdir="${libdir}"/gcc-lib/'$(target_alias)'
+    toolexeclibdir="${libdir}"
   fi
-  if test x"$enable_multi_os_directory" != x"no"; then
-    multi_os_directory=`$CC $CFLAGS -print-multi-os-directory`
-    case $multi_os_directory in
-      .) ;; # Avoid trailing /.
-      ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
-    esac
-  fi
+  multi_os_directory=`$CC $CFLAGS -print-multi-os-directory`
+  case $multi_os_directory in
+    .) ;; # Avoid trailing /.
+    ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+  esac
   AC_SUBST(toolexecdir)
 else
-  toolexeclibdir='${libdir}'
+  toolexeclibdir="${libdir}"
 fi
 AC_SUBST(toolexeclibdir)
 
-# Check linker support.
-LIBFFI_ENABLE_SYMVERS
-
 AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
 AC_CONFIG_COMMANDS(src, [
 test -d src || mkdir src
 test -d src/$TARGETDIR || mkdir src/$TARGETDIR
 ], [TARGETDIR="$TARGETDIR"])
 
-AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile doc/Makefile libffi.pc)
+AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
+
+AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc)
 
 AC_OUTPUT
-
-# Copy this file instead of using AC_CONFIG_LINK in order to support
-# compiling with MSVC, which won't understand cygwin style symlinks.
-cp ${srcdir}/src/$TARGETDIR/ffitarget.h include/ffitarget.h
diff --git a/configure.host b/configure.host
deleted file mode 100644
index 9a72cda..0000000
--- a/configure.host
+++ /dev/null
@@ -1,303 +0,0 @@
-# configure.host
-#
-# This shell script handles all host based configuration for libffi.
-#
-
-# THIS TABLE IS SORTED.  KEEP IT THAT WAY.
-# Most of the time we can define all the variables all at once...
-case "${host}" in
-  aarch64*-*-cygwin* | aarch64*-*-mingw* | aarch64*-*-win* )
-	TARGET=ARM_WIN64; TARGETDIR=aarch64
-	MSVC=1
-	;;
-
-  aarch64*-*-*)
-	TARGET=AARCH64; TARGETDIR=aarch64
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  alpha*-*-*)
-	TARGET=ALPHA; TARGETDIR=alpha;
-	# Support 128-bit long double, changeable via command-line switch.
-	HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
-	SOURCES="ffi.c osf.S"
-	;;
-
-  arc*-*-*)
-	TARGET=ARC; TARGETDIR=arc
-	SOURCES="ffi.c arcompact.S"
-	;;
-
-  arm*-*-cygwin* | arm*-*-mingw* | arm*-*-win* )
-	TARGET=ARM_WIN32; TARGETDIR=arm
-	MSVC=1
-	;;
-
-  arm*-*-*)
-	TARGET=ARM; TARGETDIR=arm
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  avr32*-*-*)
-	TARGET=AVR32; TARGETDIR=avr32
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  bfin*)
-	TARGET=BFIN; TARGETDIR=bfin
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  cris-*-*)
-	TARGET=LIBFFI_CRIS; TARGETDIR=cris
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  frv-*-*)
-	TARGET=FRV; TARGETDIR=frv
-	SOURCES="ffi.c eabi.S"
-	;;
-
-  hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
-	TARGET=PA_LINUX; TARGETDIR=pa
-	SOURCES="ffi.c linux.S"
-	;;
-  hppa*64-*-hpux*)
-	TARGET=PA64_HPUX; TARGETDIR=pa
-	;;
-  hppa*-*-hpux*)
-	TARGET=PA_HPUX; TARGETDIR=pa
-	SOURCES="ffi.c hpux32.S"
-	;;
-
-  i?86-*-freebsd* | i?86-*-openbsd*)
-	TARGET=X86_FREEBSD; TARGETDIR=x86
-	;;
-
-  i?86-*-cygwin* | i?86-*-mingw* | i?86-*-win* | i?86-*-os2* | i?86-*-interix* \
-  | x86_64-*-cygwin* | x86_64-*-mingw* | x86_64-*-win* )
-	TARGETDIR=x86
-	if test $ac_cv_sizeof_size_t = 4; then
-	  TARGET=X86_WIN32
-	else
-	  TARGET=X86_WIN64
-	fi
-	if test "${ax_cv_c_compiler_vendor}" = "microsoft"; then
-	  MSVC=1
-	fi
-	# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
-	# We must also check with_cross_host to decide if this is a native
-	# or cross-build and select where to install dlls appropriately.
-	if test -n "$with_cross_host" &&
-	   test x"$with_cross_host" != x"no"; then
-	  AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
-	else
-	  AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
-	fi
-	;;
-
-  i?86-*-darwin* | x86_64-*-darwin* | i?86-*-ios | x86_64-*-ios)
-	TARGETDIR=x86
-	if test $ac_cv_sizeof_size_t = 4; then
-	  TARGET=X86_DARWIN
-	else
-	  TARGET=X86_64
-	fi
-	;;
-
-  i?86-*-* | x86_64-*-* | amd64-*)
-	TARGETDIR=x86
-	if test $ac_cv_sizeof_size_t = 4; then
-	  case "$host" in
-	    x86_64-*x32|x86_64-x32-*)
-	      TARGET_X32=yes
-	      TARGET=X86_64
-	      ;;
-	    *)
-	      echo 'int foo (void) { return __x86_64__; }' > conftest.c
-	      if $CC $CFLAGS -Werror -S conftest.c -o conftest.s > /dev/null 2>&1; then
-		TARGET_X32=yes
-		TARGET=X86_64
-	      else
-		TARGET=X86;
-	      fi
-	      rm -f conftest.*
-	      ;;
-          esac
-	else
-	  TARGET=X86_64;
-	fi
-	;;
-
-  ia64*-*-*)
-	TARGET=IA64; TARGETDIR=ia64
-	SOURCES="ffi.c unix.S"
-	;;
-
-  m32r*-*-*)
-	TARGET=M32R; TARGETDIR=m32r
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  m68k-*-*)
-	TARGET=M68K; TARGETDIR=m68k
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  m88k-*-*)
-	TARGET=M88K; TARGETDIR=m88k
-	SOURCES="ffi.c obsd.S"
-	;;
-
-  microblaze*-*-*)
-	TARGET=MICROBLAZE; TARGETDIR=microblaze
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  moxie-*-*)
-	TARGET=MOXIE; TARGETDIR=moxie
-	SOURCES="ffi.c eabi.S"
-	;;
-
-  metag-*-*)
-	TARGET=METAG; TARGETDIR=metag
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
-	TARGET=MIPS; TARGETDIR=mips
-	;;
-  mips*-*linux* | mips*-*-openbsd*)
-	# Support 128-bit long double for NewABI.
-	HAVE_LONG_DOUBLE='defined(__mips64)'
-	TARGET=MIPS; TARGETDIR=mips
-	;;
-
-  nios2*-linux*)
-	TARGET=NIOS2; TARGETDIR=nios2
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  or1k*-*-*)
-	TARGET=OR1K; TARGETDIR=or1k
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  powerpc*-*-linux* | powerpc-*-sysv*)
-	TARGET=POWERPC; TARGETDIR=powerpc
-	HAVE_LONG_DOUBLE_VARIANT=1
-	;;
-  powerpc-*-amigaos*)
-	TARGET=POWERPC; TARGETDIR=powerpc
-	;;
-  powerpc-*-beos*)
-	TARGET=POWERPC; TARGETDIR=powerpc
-	;;
-  powerpc-*-darwin* | powerpc64-*-darwin*)
-	TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
-	;;
-  powerpc-*-aix* | rs6000-*-aix*)
-	TARGET=POWERPC_AIX; TARGETDIR=powerpc
-	;;
-  powerpc-*-freebsd* | powerpc-*-openbsd* | powerpc-*-netbsd*)
-	TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
-	HAVE_LONG_DOUBLE_VARIANT=1
-	;;
-  powerpc64-*-freebsd*)
-	TARGET=POWERPC; TARGETDIR=powerpc
-	;;
-  powerpc*-*-rtems*)
-	TARGET=POWERPC; TARGETDIR=powerpc
-	;;
-
-  riscv*-*)
-	TARGET=RISCV; TARGETDIR=riscv
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  s390-*-* | s390x-*-*)
-	TARGET=S390; TARGETDIR=s390
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  sh-*-* | sh[34]*-*-*)
-	TARGET=SH; TARGETDIR=sh
-	SOURCES="ffi.c sysv.S"
-	;;
-  sh64-*-* | sh5*-*-*)
-	TARGET=SH64; TARGETDIR=sh64
-	SOURCES="ffi.c sysv.S"
-	;;
-
-  sparc*-*-*)
-	TARGET=SPARC; TARGETDIR=sparc
-	SOURCES="ffi.c ffi64.c v8.S v9.S"
-	;;
-
-  tile*-*)
-        TARGET=TILE; TARGETDIR=tile
-	SOURCES="ffi.c tile.S"
-        ;;
-
-  vax-*-*)
-	TARGET=VAX; TARGETDIR=vax
-	SOURCES="ffi.c elfbsd.S"
-	;;
-
-  xtensa*-*)
-	TARGET=XTENSA; TARGETDIR=xtensa
-	SOURCES="ffi.c sysv.S"
-	;;
-esac
-
-# ... but some of the cases above share configury.
-case "${TARGET}" in
-  ARM_WIN32)
-	SOURCES="ffi.c sysv_msvc_arm32.S"
-	;;
-  ARM_WIN64)
-	SOURCES="ffi.c win64_armasm.S"
-	;;
-  MIPS)
-	SOURCES="ffi.c o32.S n32.S"
-	;;
-  POWERPC)
-	SOURCES="ffi.c ffi_sysv.c ffi_linux64.c sysv.S ppc_closure.S"
-	SOURCES="${SOURCES} linux64.S linux64_closure.S"
-	;;
-  POWERPC_AIX)
-	SOURCES="ffi_darwin.c aix.S aix_closure.S"
-	;;
-  POWERPC_DARWIN)
-	SOURCES="ffi_darwin.c darwin.S darwin_closure.S"
-	;;
-  POWERPC_FREEBSD)
-	SOURCES="ffi.c ffi_sysv.c sysv.S ppc_closure.S"
-	;;
-  X86 | X86_DARWIN | X86_FREEBSD | X86_WIN32)
-	if test "$MSVC" = 1; then
-		SOURCES="ffi.c sysv_intel.S"
-	else
-		SOURCES="ffi.c sysv.S"
-	fi
-	;;
-  X86_64)
-	if test x"$TARGET_X32" = xyes; then
-		SOURCES="ffi64.c unix64.S"
-	else
-		SOURCES="ffi64.c unix64.S ffiw64.c win64.S"
-	fi
-	;;
-  X86_WIN64)
-	if test "$MSVC" = 1; then
-		SOURCES="ffiw64.c win64_intel.S"
-	else
-		SOURCES="ffiw64.c win64.S"
-	fi
-	;;
-esac
-
-# If we failed to configure SOURCES, we can't do anything.
-if test -z "${SOURCES}"; then
-  UNSUPPORTED=1
-fi
diff --git a/doc/Makefile.am b/doc/Makefile.am
deleted file mode 100644
index 43b650a..0000000
--- a/doc/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-## Process this with automake to create Makefile.in
-
-info_TEXINFOS = libffi.texi
diff --git a/doc/libffi.texi b/doc/libffi.texi
index bd30593..b1c9bc3 100644
--- a/doc/libffi.texi
+++ b/doc/libffi.texi
@@ -1,8 +1,7 @@
 \input texinfo   @c -*-texinfo-*-
 @c %**start of header
 @setfilename libffi.info
-@include version.texi
-@settitle libffi: the portable foreign function interface library
+@settitle libffi
 @setchapternewpage off
 @c %**end of header
 
@@ -13,43 +12,32 @@
 @syncodeindex pg cp
 @syncodeindex tp cp
 
+@include version.texi
+
 @copying
 
-This manual is for libffi, a portable foreign function interface
+This manual is for Libffi, a portable foreign-function interface
 library.
 
-Copyright @copyright{} 2008--2019 Anthony Green and Red Hat, Inc.
+Copyright @copyright{} 2008, 2010, 2011 Red Hat, Inc.
 
-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:
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.  A copy of the license is included in the
+section entitled ``GNU General Public License''.
 
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
+@end quotation
 @end copying
 
 @dircategory Development
 @direntry
-* libffi: (libffi).             Portable foreign function interface library.
+* libffi: (libffi).             Portable foreign-function interface library.
 @end direntry
 
 @titlepage
-@title libffi: a foreign function interface library
-@subtitle For Version @value{VERSION} of libffi
-@author Anthony Green
+@title Libffi
 @page
 @vskip 0pt plus 1filll
 @insertcopying
@@ -119,7 +107,6 @@
 * Multiple ABIs::               Different passing styles on one platform.
 * The Closure API::             Writing a generic function.
 * Closure Example::             A closure example.
-* Thread Safety::               Thread safety.
 @end menu
 
 
@@ -165,16 +152,16 @@
 @code{ffi_prep_cif_var} must be used instead of @code{ffi_prep_cif}.
 
 @findex ffi_prep_cif_var
-@defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nfixedargs}, unsigned int @var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
+@defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi var{abi}, unsigned int @var{nfixedargs}, unsigned int var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
 This initializes @var{cif} according to the given parameters for
-a call to a variadic function.  In general its operation is the
+a call to a variadic function.  In general it's operation is the
 same as for @code{ffi_prep_cif} except that:
 
 @var{nfixedargs} is the number of fixed arguments, prior to any
 variadic arguments.  It must be greater than zero.
 
 @var{ntotalargs} the total number of arguments, including variadic
-and fixed arguments.  @var{argtypes} must have this many elements.
+and fixed arguments.
 
 Note that, different cif's must be prepped for calls to the same
 function when different numbers of arguments are passed.
@@ -185,10 +172,6 @@
 
 @end defun
 
-Note that the resulting @code{ffi_cif} holds pointers to all the
-@code{ffi_type} objects that were used during initialization.  You
-must ensure that these type objects have a lifetime at least as long
-as that of the @code{ffi_cif}.
 
 To call a function using an initialized @code{ffi_cif}, use the
 @code{ffi_call} function:
@@ -207,29 +190,12 @@
 @code{void} (using @code{ffi_type_void}), then @var{rvalue} is
 ignored.
 
-In most situations, @samp{libffi} will handle promotion according to
-the ABI.  However, for historical reasons, there is a special case
-with return values that must be handled by your code.  In particular,
-for integral (not @code{struct}) types that are narrower than the
-system register size, the return value will be widened by
-@samp{libffi}.  @samp{libffi} provides a type, @code{ffi_arg}, that
-can be used as the return type.  For example, if the CIF was defined
-with a return type of @code{char}, @samp{libffi} will try to store a
-full @code{ffi_arg} into the return value.
-
 @var{avalues} is a vector of @code{void *} pointers that point to the
 memory locations holding the argument values for a call.  If @var{cif}
 declares that the function has no arguments (i.e., @var{nargs} was 0),
 then @var{avalues} is ignored.  Note that argument values may be
 modified by the callee (for instance, structs passed by value); the
 burden of copying pass-by-value arguments is placed on the caller.
-
-Note that while the return value must be register-sized, arguments
-should exactly match their declared type.  For example, if an argument
-is a @code{short}, then the entry in @var{avalues} should point to an
-object declared as @code{short}; but if the return type is
-@code{short}, then @var{rvalue} should point to an object declared as
-a larger type -- usually @code{ffi_arg}.
 @end defun
 
 
@@ -280,8 +246,6 @@
 @menu
 * Primitive Types::             Built-in types.
 * Structures::                  Structure types.
-* Size and Alignment::          Size and alignment of types.
-* Arrays Unions Enums::         Arrays, unions, and enumerations.
 * Type Example::                Structure type example.
 * Complex::                     Complex types.
 * Complex Type Example::        Complex type example.
@@ -406,7 +370,8 @@
 @node Structures
 @subsection Structures
 
-@samp{libffi} is perfectly happy passing structures back and forth.
+Although @samp{libffi} has no special support for unions or
+bit-fields, it is perfectly happy passing structures back and forth.
 You must first describe the structure to @samp{libffi} by creating a
 new @code{ffi_type} object for it.
 
@@ -426,166 +391,9 @@
 @item ffi_type **elements
 This is a @samp{NULL}-terminated array of pointers to @code{ffi_type}
 objects.  There is one element per field of the struct.
-
-Note that @samp{libffi} has no special support for bit-fields.  You
-must manage these manually.
 @end table
 @end deftp
 
-The @code{size} and @code{alignment} fields will be filled in by
-@code{ffi_prep_cif} or @code{ffi_prep_cif_var}, as needed.
-
-@node Size and Alignment
-@subsection Size and Alignment
-
-@code{libffi} will set the @code{size} and @code{alignment} fields of
-an @code{ffi_type} object for you.  It does so using its knowledge of
-the ABI.
-
-You might expect that you can simply read these fields for a type that
-has been laid out by @code{libffi}.  However, there are some caveats.
-
-@itemize @bullet
-@item
-The size or alignment of some of the built-in types may vary depending
-on the chosen ABI.
-
-@item
-The size and alignment of a new structure type will not be set by
-@code{libffi} until it has been passed to @code{ffi_prep_cif} or
-@code{ffi_get_struct_offsets}.
-
-@item
-A structure type cannot be shared across ABIs.  Instead each ABI needs
-its own copy of the structure type.
-@end itemize
-
-So, before examining these fields, it is safest to pass the
-@code{ffi_type} object to @code{ffi_prep_cif} or
-@code{ffi_get_struct_offsets} first.  This function will do all the
-needed setup.
-
-@example
-ffi_type *desired_type;
-ffi_abi desired_abi;
-@dots{}
-ffi_cif cif;
-if (ffi_prep_cif (&cif, desired_abi, 0, desired_type, NULL) == FFI_OK)
-  @{
-    size_t size = desired_type->size;
-    unsigned short alignment = desired_type->alignment;
-  @}
-@end example
-
-@code{libffi} also provides a way to get the offsets of the members of
-a structure.
-
-@findex ffi_get_struct_offsets
-@defun ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets)
-Compute the offset of each element of the given structure type.
-@var{abi} is the ABI to use; this is needed because in some cases the
-layout depends on the ABI.
-
-@var{offsets} is an out parameter.  The caller is responsible for
-providing enough space for all the results to be written -- one
-element per element type in @var{struct_type}.  If @var{offsets} is
-@code{NULL}, then the type will be laid out but not otherwise
-modified.  This can be useful for accessing the type's size or layout,
-as mentioned above.
-
-This function returns @code{FFI_OK} on success; @code{FFI_BAD_ABI} if
-@var{abi} is invalid; or @code{FFI_BAD_TYPEDEF} if @var{struct_type}
-is invalid in some way.  Note that only @code{FFI_STRUCT} types are
-valid here.
-@end defun
-
-@node Arrays Unions Enums
-@subsection Arrays, Unions, and Enumerations
-
-@subsubsection Arrays
-
-@samp{libffi} does not have direct support for arrays or unions.
-However, they can be emulated using structures.
-
-To emulate an array, simply create an @code{ffi_type} using
-@code{FFI_TYPE_STRUCT} with as many members as there are elements in
-the array.
-
-@example
-ffi_type array_type;
-ffi_type **elements
-int i;
-
-elements = malloc ((n + 1) * sizeof (ffi_type *));
-for (i = 0; i < n; ++i)
-  elements[i] = array_element_type;
-elements[n] = NULL;
-
-array_type.size = array_type.alignment = 0;
-array_type.type = FFI_TYPE_STRUCT;
-array_type.elements = elements;
-@end example
-
-Note that arrays cannot be passed or returned by value in C --
-structure types created like this should only be used to refer to
-members of real @code{FFI_TYPE_STRUCT} objects.
-
-However, a phony array type like this will not cause any errors from
-@samp{libffi} if you use it as an argument or return type.  This may
-be confusing.
-
-@subsubsection Unions
-
-A union can also be emulated using @code{FFI_TYPE_STRUCT}.  In this
-case, however, you must make sure that the size and alignment match
-the real requirements of the union.
-
-One simple way to do this is to ensue that each element type is laid
-out.  Then, give the new structure type a single element; the size of
-the largest element; and the largest alignment seen as well.
-
-This example uses the @code{ffi_prep_cif} trick to ensure that each
-element type is laid out.
-
-@example
-ffi_abi desired_abi;
-ffi_type union_type;
-ffi_type **union_elements;
-
-int i;
-ffi_type element_types[2];
-
-element_types[1] = NULL;
-
-union_type.size = union_type.alignment = 0;
-union_type.type = FFI_TYPE_STRUCT;
-union_type.elements = element_types;
-
-for (i = 0; union_elements[i]; ++i)
-  @{
-    ffi_cif cif;
-    if (ffi_prep_cif (&cif, desired_abi, 0, union_elements[i], NULL) == FFI_OK)
-      @{
-        if (union_elements[i]->size > union_type.size)
-          @{
-            union_type.size = union_elements[i];
-            size = union_elements[i]->size;
-          @}
-        if (union_elements[i]->alignment > union_type.alignment)
-          union_type.alignment = union_elements[i]->alignment;
-      @}
-  @}
-@end example
-
-@subsubsection Enumerations
-
-@code{libffi} does not have any special support for C @code{enum}s.
-Although any given @code{enum} is implemented using a specific
-underlying integral type, exactly which type will be used cannot be
-determined by @code{libffi} -- it may depend on the values in the
-enumeration or on compiler flags such as @option{-fshort-enums}.
-@xref{Structures unions enumerations and bit-fields implementation, , , gcc},
-for more information about how GCC handles enumerations.
 
 @node Type Example
 @subsection Type Example
@@ -822,47 +630,30 @@
 
 @findex ffi_prep_closure_loc
 @defun ffi_status ffi_prep_closure_loc (ffi_closure *@var{closure}, ffi_cif *@var{cif}, void (*@var{fun}) (ffi_cif *@var{cif}, void *@var{ret}, void **@var{args}, void *@var{user_data}), void *@var{user_data}, void *@var{codeloc})
-Prepare a closure function.  The arguments to
-@code{ffi_prep_closure_loc} are:
+Prepare a closure function.
 
-@table @var
-@item closure
-The address of a @code{ffi_closure} object; this is the writable
-address returned by @code{ffi_closure_alloc}.
+@var{closure} is the address of a @code{ffi_closure} object; this is
+the writable address returned by @code{ffi_closure_alloc}.
 
-@item cif
-The @code{ffi_cif} describing the function parameters.  Note that this
-object, and the types to which it refers, must be kept alive until the
-closure itself is freed.
+@var{cif} is the @code{ffi_cif} describing the function parameters.
 
-@item user_data
-An arbitrary datum that is passed, uninterpreted, to your closure
-function.
+@var{user_data} is an arbitrary datum that is passed, uninterpreted,
+to your closure function.
 
-@item codeloc
-The executable address returned by @code{ffi_closure_alloc}.
+@var{codeloc} is the executable address returned by
+@code{ffi_closure_alloc}.
 
-@item fun
-The function which will be called when the closure is invoked.  It is
-called with the arguments:
-
+@var{fun} is the function which will be called when the closure is
+invoked.  It is called with the arguments:
 @table @var
 @item cif
 The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}.
 
 @item ret
 A pointer to the memory used for the function's return value.
-
-If the function is declared as returning @code{void}, then this value
-is garbage and should not be used.
-
-Otherwise, @var{fun} must fill the object to which this points,
-following the same special promotion behavior as @code{ffi_call}.
-That is, in most cases, @var{ret} points to an object of exactly the
-size of the type specified when @var{cif} was constructed.  However,
-integral types narrower than the system register size are widened.  In
-these cases your program may assume that @var{ret} points to an
-@code{ffi_arg} object.
+@var{fun} must fill this, unless the function is declared as returning
+@code{void}.
+@c FIXME: is this NULL for void-returning functions?
 
 @item args
 A vector of pointers to memory holding the arguments to the function.
@@ -871,10 +662,10 @@
 The same @var{user_data} that was passed to
 @code{ffi_prep_closure_loc}.
 @end table
-@end table
 
 @code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything
-went ok, and one of the other @code{ffi_status} values on error.
+went ok, and something else on error.
+@c FIXME: what?
 
 After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc}
 to the appropriate pointer-to-function type.
@@ -942,28 +733,6 @@
 
 @end example
 
-@node Thread Safety
-@section Thread Safety
-
-@code{libffi} is not completely thread-safe.  However, many parts are,
-and if you follow some simple rules, you can use it safely in a
-multi-threaded program.
-
-@itemize @bullet
-@item
-@code{ffi_prep_cif} may modify the @code{ffi_type} objects passed to
-it.  It is best to ensure that only a single thread prepares a given
-@code{ffi_cif} at a time.
-
-@item
-On some platforms, @code{ffi_prep_cif} may modify the size and
-alignment of some types, depending on the chosen ABI.  On these
-platforms, if you switch between ABIs, you must ensure that there is
-only one call to @code{ffi_prep_cif} at a time.
-
-Currently the only affected platform is PowerPC and the only affected
-type is @code{long double}.
-@end itemize
 
 @node Missing Features
 @chapter Missing Features
@@ -979,11 +748,15 @@
 There is no support for bit fields in structures.
 
 @item
-The ``raw'' API is undocumented.
-@c anything else?
+The closure API is
+
+@c FIXME: ...
 
 @item
-The Go API is undocumented.
+The ``raw'' API is undocumented.
+@c argument promotion?
+@c unions?
+@c anything else?
 @end itemize
 
 Note that variadic support is very new and tested on a relatively
diff --git a/doc/version.texi b/doc/version.texi
index d9d5094..ccef70f 100644
--- a/doc/version.texi
+++ b/doc/version.texi
@@ -1,4 +1,4 @@
-@set UPDATED 22 November 2019
-@set UPDATED-MONTH November 2019
-@set EDITION 3.3
-@set VERSION 3.3
+@set UPDATED 8 November 2014
+@set UPDATED-MONTH November 2014
+@set EDITION 3.2.1
+@set VERSION 3.2.1
diff --git a/generate-darwin-source-and-headers.py b/generate-darwin-source-and-headers.py
index f7fc414..964e861 100644
--- a/generate-darwin-source-and-headers.py
+++ b/generate-darwin-source-and-headers.py
@@ -14,12 +14,12 @@
     sdk = 'iphonesimulator'
     arch = 'i386'
     triple = 'i386-apple-darwin11'
-    version_min = '-miphoneos-version-min=7.0'
+    version_min = '-miphoneos-version-min=5.1.1'
 
     prefix = "#ifdef __i386__\n\n"
     suffix = "\n\n#endif"
     src_dir = 'x86'
-    src_files = ['sysv.S', 'ffi.c', 'internal.h']
+    src_files = ['darwin.S', 'win32.S', 'ffi.c']
 
 
 class simulator64_platform(Platform):
@@ -32,7 +32,7 @@
     prefix = "#ifdef __x86_64__\n\n"
     suffix = "\n\n#endif"
     src_dir = 'x86'
-    src_files = ['unix64.S', 'ffi64.c', 'ffiw64.c', 'win64.S', 'internal64.h', 'asmnames.h']
+    src_files = ['darwin64.S', 'ffi64.c']
 
 
 class device_platform(Platform):
@@ -40,12 +40,12 @@
     sdk = 'iphoneos'
     arch = 'armv7'
     triple = 'arm-apple-darwin11'
-    version_min = '-miphoneos-version-min=7.0'
+    version_min = '-miphoneos-version-min=5.1.1'
 
     prefix = "#ifdef __arm__\n\n"
     suffix = "\n\n#endif"
     src_dir = 'arm'
-    src_files = ['sysv.S', 'ffi.c', 'internal.h']
+    src_files = ['sysv.S', 'trampoline.S', 'ffi.c']
 
 
 class device64_platform(Platform):
@@ -58,7 +58,7 @@
     prefix = "#ifdef __arm64__\n\n"
     suffix = "\n\n#endif"
     src_dir = 'aarch64'
-    src_files = ['sysv.S', 'ffi.c', 'internal.h']
+    src_files = ['sysv.S', 'ffi.c']
 
 
 class desktop32_platform(Platform):
@@ -68,7 +68,7 @@
     triple = 'i386-apple-darwin10'
     version_min = '-mmacosx-version-min=10.6'
     src_dir = 'x86'
-    src_files = ['sysv.S', 'ffi.c', 'internal.h']
+    src_files = ['darwin.S', 'win32.S', 'ffi.c']
 
     prefix = "#ifdef __i386__\n\n"
     suffix = "\n\n#endif"
@@ -84,14 +84,16 @@
     prefix = "#ifdef __x86_64__\n\n"
     suffix = "\n\n#endif"
     src_dir = 'x86'
-    src_files = ['unix64.S', 'ffi64.c', 'ffiw64.c', 'win64.S', 'internal64.h', 'asmnames.h']
+    src_files = ['darwin64.S', 'ffi64.c']
 
 
 def mkdir_p(path):
     try:
         os.makedirs(path)
     except OSError as exc:  # Python >2.5
-        if exc.errno != errno.EEXIST:
+        if exc.errno == errno.EEXIST:
+            pass
+        else:
             raise
 
 
@@ -100,11 +102,8 @@
     out_filename = filename
 
     if file_suffix:
-        if filename in ['internal64.h', 'asmnames.h', 'internal.h']:
-            out_filename = filename
-        else:
-            split_name = os.path.splitext(filename)
-            out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
+        split_name = os.path.splitext(filename)
+        out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
 
     with open(os.path.join(src_dir, filename)) as in_file:
         with open(os.path.join(dst_dir, out_filename), 'w') as out_file:
@@ -163,11 +162,18 @@
             platform_headers[filename].add((platform.prefix, platform.arch, platform.suffix))
 
 
+def make_tramp():
+    with open('src/arm/trampoline.S', 'w') as tramp_out:
+        p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out)
+        p.wait()
+
+
 def generate_source_and_headers(generate_osx=True, generate_ios=True):
     copy_files('src', 'darwin_common/src', pattern='*.c')
     copy_files('include', 'darwin_common/include', pattern='*.h')
 
     if generate_ios:
+        make_tramp()
         copy_src_platform_files(simulator_platform)
         copy_src_platform_files(simulator64_platform)
         copy_src_platform_files(device_platform)
diff --git a/include/Makefile.am b/include/Makefile.am
index c59df9f..fd28024 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -3,7 +3,7 @@
 AUTOMAKE_OPTIONS=foreign
 
 DISTCLEANFILES=ffitarget.h
-noinst_HEADERS=ffi_common.h ffi_cfi.h
-EXTRA_DIST=ffi.h.in
+EXTRA_DIST=ffi.h.in ffi_common.h
 
-nodist_include_HEADERS = ffi.h ffitarget.h
+includesdir = $(libdir)/@PACKAGE_NAME@-@PACKAGE_VERSION@/include
+nodist_includes_HEADERS = ffi.h ffitarget.h
diff --git a/include/ffi.h.in b/include/ffi.h.in
index 71cc05c..f403ae0 100644
--- a/include/ffi.h.in
+++ b/include/ffi.h.in
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------*-C-*-
-   libffi @VERSION@ - Copyright (c) 2011, 2014, 2019 Anthony Green
+   libffi @VERSION@ - Copyright (c) 2011, 2014 Anthony Green
                     - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
 
    Permission is hereby granted, free of charge, to any person
@@ -25,14 +25,23 @@
    ----------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------
-   Most of the API is documented in doc/libffi.texi.
+   The basic API is described in the README file.
 
-   The raw API is designed to bypass some of the argument packing and
-   unpacking on architectures for which it can be avoided.  Routines
-   are provided to emulate the raw API if the underlying platform
-   doesn't allow faster implementation.
+   The raw API is designed to bypass some of the argument packing
+   and unpacking on architectures for which it can be avoided.
 
-   More details on the raw API can be found in:
+   The closure API allows interpreted functions to be packaged up
+   inside a C function pointer, so that they can be called as C functions,
+   with no understanding on the client side that they are interpreted.
+   It can also be used in other cases in which it is necessary to package
+   up a user specified parameter and a function pointer as a single
+   function pointer.
+
+   The closure API must be implemented in order to get its functionality,
+   e.g. for use by gij.  Routines are provided to emulate the raw API
+   if the underlying platform doesn't allow faster implementation.
+
+   More details on the raw and cloure API can be found in:
 
    http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
 
@@ -97,8 +106,8 @@
 # endif
 #endif
 
-/* The closure code assumes that this works on pointers, i.e. a size_t
-   can hold a pointer.  */
+/* The closure code assumes that this works on pointers, i.e. a size_t	*/
+/* can hold a pointer.							*/
 
 typedef struct _ffi_type
 {
@@ -108,32 +117,6 @@
   struct _ffi_type **elements;
 } ffi_type;
 
-/* Need minimal decorations for DLLs to work on Windows.  GCC has
-   autoimport and autoexport.  Always mark externally visible symbols
-   as dllimport for MSVC clients, even if it means an extra indirection
-   when using the static version of the library.
-   Besides, as a workaround, they can define FFI_BUILDING if they
-   *know* they are going to link with the static library.  */
-#if defined _MSC_VER
-# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
-#  define FFI_API __declspec(dllexport)
-# elif !defined FFI_BUILDING  /* Importing libffi.DLL */
-#  define FFI_API __declspec(dllimport)
-# else                        /* Building/linking static library */
-#  define FFI_API
-# endif
-#else
-# define FFI_API
-#endif
-
-/* The externally visible type declarations also need the MSVC DLL
-   decorations, or they will not be exported from the object file.  */
-#if defined LIBFFI_HIDE_BASIC_TYPES
-# define FFI_EXTERN FFI_API
-#else
-# define FFI_EXTERN extern FFI_API
-#endif
-
 #ifndef LIBFFI_HIDE_BASIC_TYPES
 #if SCHAR_MAX == 127
 # define ffi_type_uchar                ffi_type_uint8
@@ -183,7 +166,21 @@
  #error "long size not supported"
 #endif
 
-/* These are defined in types.c.  */
+/* Need minimal decorations for DLLs to works on Windows. */
+/* GCC has autoimport and autoexport.  Rely on Libtool to */
+/* help MSVC export from a DLL, but always declare data   */
+/* to be imported for MSVC clients.  This costs an extra  */
+/* indirection for MSVC clients using the static version  */
+/* of the library, but don't worry about that.  Besides,  */
+/* as a workaround, they can define FFI_BUILDING if they  */
+/* *know* they are going to link with the static library. */
+#if defined _MSC_VER && !defined FFI_BUILDING
+#define FFI_EXTERN extern __declspec(dllimport)
+#else
+#define FFI_EXTERN extern
+#endif
+
+/* These are defined in types.c */
 FFI_EXTERN ffi_type ffi_type_void;
 FFI_EXTERN ffi_type ffi_type_uint8;
 FFI_EXTERN ffi_type ffi_type_sint8;
@@ -220,6 +217,8 @@
   FFI_BAD_ABI
 } ffi_status;
 
+typedef unsigned FFI_TYPE;
+
 typedef struct {
   ffi_abi abi;
   unsigned nargs;
@@ -232,6 +231,20 @@
 #endif
 } ffi_cif;
 
+#if @HAVE_LONG_DOUBLE_VARIANT@
+/* Used to adjust size/alignment of ffi types.  */
+void ffi_prep_types (ffi_abi abi);
+#endif
+
+/* Used internally, but overridden by some architectures */
+ffi_status ffi_prep_cif_core(ffi_cif *cif,
+			     ffi_abi abi,
+			     unsigned int isvariadic,
+			     unsigned int nfixedargs,
+			     unsigned int ntotalargs,
+			     ffi_type *rtype,
+			     ffi_type **atypes);
+
 /* ---- Definitions for the raw API -------------------------------------- */
 
 #ifndef FFI_SIZEOF_ARG
@@ -269,34 +282,27 @@
 #endif
 
 
-FFI_API 
 void ffi_raw_call (ffi_cif *cif,
 		   void (*fn)(void),
 		   void *rvalue,
 		   ffi_raw *avalue);
 
-FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
-FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
-FFI_API size_t ffi_raw_size (ffi_cif *cif);
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
 
-/* This is analogous to the raw API, except it uses Java parameter
-   packing, even on 64-bit machines.  I.e. on 64-bit machines longs
-   and doubles are followed by an empty 64-bit word.  */
+/* This is analogous to the raw API, except it uses Java parameter	*/
+/* packing, even on 64-bit machines.  I.e. on 64-bit machines		*/
+/* longs and doubles are followed by an empty 64-bit word.		*/
 
-#if !FFI_NATIVE_RAW_API
-FFI_API
 void ffi_java_raw_call (ffi_cif *cif,
 			void (*fn)(void),
 			void *rvalue,
-			ffi_java_raw *avalue) __attribute__((deprecated));
-#endif
+			ffi_java_raw *avalue);
 
-FFI_API
-void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated));
-FFI_API
-void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated));
-FFI_API
-size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated));
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
 
 /* ---- Definitions for closures ----------------------------------------- */
 
@@ -315,34 +321,25 @@
   ffi_cif   *cif;
   void     (*fun)(ffi_cif*,void*,void**,void*);
   void      *user_data;
-} ffi_closure
 #ifdef __GNUC__
-    __attribute__((aligned (8)))
-#endif
-    ;
-
-#ifndef __GNUC__
+} ffi_closure __attribute__((aligned (8)));
+#else
+} ffi_closure;
 # ifdef __sgi
 #  pragma pack 0
 # endif
 #endif
 
-FFI_API void *ffi_closure_alloc (size_t size, void **code);
-FFI_API void ffi_closure_free (void *);
+void *ffi_closure_alloc (size_t size, void **code);
+void ffi_closure_free (void *);
 
-FFI_API ffi_status
+ffi_status
 ffi_prep_closure (ffi_closure*,
 		  ffi_cif *,
 		  void (*fun)(ffi_cif*,void*,void**,void*),
-		  void *user_data)
-#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
-  __attribute__((deprecated ("use ffi_prep_closure_loc instead")))
-#elif defined(__GNUC__) && __GNUC__ >= 3
-  __attribute__((deprecated))
-#endif
-  ;
+		  void *user_data);
 
-FFI_API ffi_status
+ffi_status
 ffi_prep_closure_loc (ffi_closure*,
 		      ffi_cif *,
 		      void (*fun)(ffi_cif*,void*,void**,void*),
@@ -363,9 +360,9 @@
 
 #if !FFI_NATIVE_RAW_API
 
-  /* If this is enabled, then a raw closure has the same layout 
+  /* if this is enabled, then a raw closure has the same layout 
      as a regular closure.  We use this to install an intermediate 
-     handler to do the transaltion, void** -> ffi_raw*.  */
+     handler to do the transaltion, void** -> ffi_raw*. */
 
   void     (*translate_args)(ffi_cif*,void*,void**,void*);
   void      *this_closure;
@@ -389,9 +386,9 @@
 
 #if !FFI_NATIVE_RAW_API
 
-  /* If this is enabled, then a raw closure has the same layout 
+  /* if this is enabled, then a raw closure has the same layout 
      as a regular closure.  We use this to install an intermediate 
-     handler to do the translation, void** -> ffi_raw*.  */
+     handler to do the transaltion, void** -> ffi_raw*. */
 
   void     (*translate_args)(ffi_cif*,void*,void**,void*);
   void      *this_closure;
@@ -403,62 +400,42 @@
 
 } ffi_java_raw_closure;
 
-FFI_API ffi_status
+ffi_status
 ffi_prep_raw_closure (ffi_raw_closure*,
 		      ffi_cif *cif,
 		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
 		      void *user_data);
 
-FFI_API ffi_status
+ffi_status
 ffi_prep_raw_closure_loc (ffi_raw_closure*,
 			  ffi_cif *cif,
 			  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
 			  void *user_data,
 			  void *codeloc);
 
-#if !FFI_NATIVE_RAW_API
-FFI_API ffi_status
+ffi_status
 ffi_prep_java_raw_closure (ffi_java_raw_closure*,
 		           ffi_cif *cif,
 		           void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
-		           void *user_data) __attribute__((deprecated));
+		           void *user_data);
 
-FFI_API ffi_status
+ffi_status
 ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
 			       ffi_cif *cif,
 			       void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
 			       void *user_data,
-			       void *codeloc) __attribute__((deprecated));
-#endif
+			       void *codeloc);
 
 #endif /* FFI_CLOSURES */
 
-#if FFI_GO_CLOSURES
-
-typedef struct {
-  void      *tramp;
-  ffi_cif   *cif;
-  void     (*fun)(ffi_cif*,void*,void**,void*);
-} ffi_go_closure;
-
-FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
-				void (*fun)(ffi_cif*,void*,void**,void*));
-
-FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
-		  void **avalue, void *closure);
-
-#endif /* FFI_GO_CLOSURES */
-
 /* ---- Public interface definition -------------------------------------- */
 
-FFI_API 
 ffi_status ffi_prep_cif(ffi_cif *cif,
 			ffi_abi abi,
 			unsigned int nargs,
 			ffi_type *rtype,
 			ffi_type **atypes);
 
-FFI_API
 ffi_status ffi_prep_cif_var(ffi_cif *cif,
 			    ffi_abi abi,
 			    unsigned int nfixedargs,
@@ -466,17 +443,12 @@
 			    ffi_type *rtype,
 			    ffi_type **atypes);
 
-FFI_API
 void ffi_call(ffi_cif *cif,
 	      void (*fn)(void),
 	      void *rvalue,
 	      void **avalue);
 
-FFI_API
-ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
-				   size_t *offsets);
-
-/* Useful for eliminating compiler warnings.  */
+/* Useful for eliminating compiler warnings */
 #define FFI_FN(f) ((void (*)(void))f)
 
 /* ---- Definitions shared with assembly code ---------------------------- */
@@ -505,7 +477,7 @@
 #define FFI_TYPE_POINTER    14
 #define FFI_TYPE_COMPLEX    15
 
-/* This should always refer to the last type code (for sanity checks).  */
+/* This should always refer to the last type code (for sanity checks) */
 #define FFI_TYPE_LAST       FFI_TYPE_COMPLEX
 
 #ifdef __cplusplus
diff --git a/include/ffi_cfi.h b/include/ffi_cfi.h
deleted file mode 100644
index 244ce57..0000000
--- a/include/ffi_cfi.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -----------------------------------------------------------------------
-   ffi_cfi.h - Copyright (c) 2014  Red Hat, Inc.
-
-   Conditionally assemble cfi directives. Only necessary for building libffi.
-   ----------------------------------------------------------------------- */
-
-#ifndef FFI_CFI_H
-#define FFI_CFI_H
-
-#ifdef HAVE_AS_CFI_PSEUDO_OP
-
-# define cfi_startproc			.cfi_startproc
-# define cfi_endproc			.cfi_endproc
-# define cfi_def_cfa(reg, off)		.cfi_def_cfa reg, off
-# define cfi_def_cfa_register(reg)	.cfi_def_cfa_register reg
-# define cfi_def_cfa_offset(off)	.cfi_def_cfa_offset off
-# define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off
-# define cfi_offset(reg, off)		.cfi_offset reg, off
-# define cfi_rel_offset(reg, off)	.cfi_rel_offset reg, off
-# define cfi_register(r1, r2)		.cfi_register r1, r2
-# define cfi_return_column(reg)		.cfi_return_column reg
-# define cfi_restore(reg)		.cfi_restore reg
-# define cfi_same_value(reg)		.cfi_same_value reg
-# define cfi_undefined(reg)		.cfi_undefined reg
-# define cfi_remember_state		.cfi_remember_state
-# define cfi_restore_state		.cfi_restore_state
-# define cfi_window_save		.cfi_window_save
-# define cfi_personality(enc, exp)	.cfi_personality enc, exp
-# define cfi_lsda(enc, exp)		.cfi_lsda enc, exp
-# define cfi_escape(...)		.cfi_escape __VA_ARGS__
-
-#else
-
-# define cfi_startproc
-# define cfi_endproc
-# define cfi_def_cfa(reg, off)
-# define cfi_def_cfa_register(reg)
-# define cfi_def_cfa_offset(off)
-# define cfi_adjust_cfa_offset(off)
-# define cfi_offset(reg, off)
-# define cfi_rel_offset(reg, off)
-# define cfi_register(r1, r2)
-# define cfi_return_column(reg)
-# define cfi_restore(reg)
-# define cfi_same_value(reg)
-# define cfi_undefined(reg)
-# define cfi_remember_state
-# define cfi_restore_state
-# define cfi_window_save
-# define cfi_personality(enc, exp)
-# define cfi_lsda(enc, exp)
-# define cfi_escape(...)
-
-#endif /* HAVE_AS_CFI_PSEUDO_OP */
-#endif /* FFI_CFI_H */
diff --git a/include/ffi_common.h b/include/ffi_common.h
index 76b9dd6..37f5a9e 100644
--- a/include/ffi_common.h
+++ b/include/ffi_common.h
@@ -74,35 +74,14 @@
 #define FFI_ASSERT_VALID_TYPE(x)
 #endif
 
-/* v cast to size_t and aligned up to a multiple of a */
-#define FFI_ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
-/* v cast to size_t and aligned down to a multiple of a */
-#define FFI_ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
+#define ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
+#define ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
 
 /* Perform machine dependent cif processing */
 ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
 ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
 	 unsigned int nfixedargs, unsigned int ntotalargs);
 
-
-#if HAVE_LONG_DOUBLE_VARIANT
-/* Used to adjust size/alignment of ffi types.  */
-void ffi_prep_types (ffi_abi abi);
-#endif
-
-/* Used internally, but overridden by some architectures */
-ffi_status ffi_prep_cif_core(ffi_cif *cif,
-			     ffi_abi abi,
-			     unsigned int isvariadic,
-			     unsigned int nfixedargs,
-			     unsigned int ntotalargs,
-			     ffi_type *rtype,
-			     ffi_type **atypes);
-
-/* Translate a data pointer to a code pointer.  Needed for closures on
-   some targets.  */
-void *ffi_data_to_code_pointer (void *data) FFI_HIDDEN;
-
 /* Extended cif, used in callback from assembly routine */
 typedef struct
 {
diff --git a/libffi.map.in b/libffi.map.in
deleted file mode 100644
index 5553ab0..0000000
--- a/libffi.map.in
+++ /dev/null
@@ -1,80 +0,0 @@
-#define LIBFFI_ASM
-#define LIBFFI_H
-#include <fficonfig.h>
-#include <ffitarget.h>
-
-/* These version numbers correspond to the libtool-version abi numbers,
-   not to the libffi release numbers.  */
-
-LIBFFI_BASE_7.0 {
-  global:
-	/* Exported data variables.  */
-	ffi_type_void;
-	ffi_type_uint8;
-	ffi_type_sint8;
-	ffi_type_uint16;
-	ffi_type_sint16;
-	ffi_type_uint32;
-	ffi_type_sint32;
-	ffi_type_uint64;
-	ffi_type_sint64;
-	ffi_type_float;
-	ffi_type_double;
-	ffi_type_longdouble;
-	ffi_type_pointer;
-
-	/* Exported functions.  */
-	ffi_call;
-	ffi_prep_cif;
-	ffi_prep_cif_var;
-
-	ffi_raw_call;
-	ffi_ptrarray_to_raw;
-	ffi_raw_to_ptrarray;
-	ffi_raw_size;
-
-	ffi_java_raw_call;
-	ffi_java_ptrarray_to_raw;
-	ffi_java_raw_to_ptrarray;
-	ffi_java_raw_size;
-
-  local:
-	*;
-};
-
-LIBFFI_BASE_7.1 {
-  global:
-	ffi_get_struct_offsets;
-} LIBFFI_BASE_7.0;
-
-#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
-LIBFFI_COMPLEX_7.0 {
-  global:
-	/* Exported data variables.  */
-	ffi_type_complex_float;
-	ffi_type_complex_double;
-	ffi_type_complex_longdouble;
-} LIBFFI_BASE_7.0;
-#endif
-
-#if FFI_CLOSURES
-LIBFFI_CLOSURE_7.0 {
-  global:
-	ffi_closure_alloc;
-	ffi_closure_free;
-	ffi_prep_closure;
-	ffi_prep_closure_loc;
-	ffi_prep_raw_closure;
-	ffi_prep_raw_closure_loc;
-	ffi_prep_java_raw_closure;
-	ffi_prep_java_raw_closure_loc;
-} LIBFFI_BASE_7.0;
-#endif
-
-#if FFI_GO_CLOSURES
-LIBFFI_GO_CLOSURE_7.0 {
-  global:
-	ffi_call_go;
-	ffi_prep_go_closure;
-} LIBFFI_CLOSURE_7.0;
-#endif
diff --git a/libffi.pc.in b/libffi.pc.in
index 6fad83b..edf6fde 100644
--- a/libffi.pc.in
+++ b/libffi.pc.in
@@ -2,7 +2,7 @@
 exec_prefix=@exec_prefix@
 libdir=@libdir@
 toolexeclibdir=@toolexeclibdir@
-includedir=@includedir@
+includedir=${libdir}/@PACKAGE_NAME@-@PACKAGE_VERSION@/include
 
 Name: @PACKAGE_NAME@
 Description: Library supporting Foreign Function Interfaces
diff --git a/libffi.xcodeproj/project.pbxproj b/libffi.xcodeproj/project.pbxproj
index 9a107b4..1cf396f 100644
--- a/libffi.xcodeproj/project.pbxproj
+++ b/libffi.xcodeproj/project.pbxproj
@@ -7,10 +7,6 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		43B5D3F81D35473200D1E1FD /* ffiw64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = 43B5D3F71D35473200D1E1FD /* ffiw64_x86_64.c */; };
-		43B5D3FA1D3547CE00D1E1FD /* win64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 43B5D3F91D3547CE00D1E1FD /* win64_x86_64.S */; };
-		43E9A5C71D352C1500926A8F /* sysv_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = 43E9A5C51D352C1500926A8F /* sysv_i386.S */; };
-		43E9A5C81D352C1500926A8F /* unix64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 43E9A5C61D352C1500926A8F /* unix64_x86_64.S */; };
 		DBFA714A187F1D8600A76262 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; };
 		DBFA714B187F1D8600A76262 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA713F187F1D8600A76262 /* ffi_common.h */; };
 		DBFA714C187F1D8600A76262 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7140187F1D8600A76262 /* fficonfig.h */; };
@@ -27,6 +23,9 @@
 		DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716D187F1D9B00A76262 /* sysv_arm64.S */; };
 		DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716F187F1D9B00A76262 /* ffi_armv7.c */; };
 		DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7170187F1D9B00A76262 /* sysv_armv7.S */; };
+		DBFA717B187F1D9B00A76262 /* trampoline_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */; };
+		DBFA717C187F1D9B00A76262 /* darwin64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */; };
+		DBFA717D187F1D9B00A76262 /* darwin_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7174187F1D9B00A76262 /* darwin_i386.S */; };
 		DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */; };
 		DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7176187F1D9B00A76262 /* ffi_i386.c */; };
 		DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7182187F1DA100A76262 /* ffi_i386.h */; };
@@ -35,117 +34,25 @@
 		DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */; };
 		DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7186187F1DA100A76262 /* ffitarget_i386.h */; };
 		DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */; };
-		DBFA7194187F1DA100A76262 /* unix64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718A187F1DA100A76262 /* unix64_x86_64.S */; };
-		DBFA7195187F1DA100A76262 /* sysv_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718B187F1DA100A76262 /* sysv_i386.S */; };
+		DBFA7194187F1DA100A76262 /* darwin64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */; };
+		DBFA7195187F1DA100A76262 /* darwin_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718B187F1DA100A76262 /* darwin_i386.S */; };
 		DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */; };
 		DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718D187F1DA100A76262 /* ffi_i386.c */; };
-		FDB52FB31F6144FA00AA92E6 /* unix64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 43E9A5C61D352C1500926A8F /* unix64_x86_64.S */; };
-		FDB52FB41F6144FA00AA92E6 /* sysv_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = 43E9A5C51D352C1500926A8F /* sysv_i386.S */; };
-		FDB52FB51F6144FA00AA92E6 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */; };
-		FDB52FB61F6144FA00AA92E6 /* ffi_armv7.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716F187F1D9B00A76262 /* ffi_armv7.c */; };
-		FDB52FB71F6144FA00AA92E6 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; };
-		FDB52FB81F6144FA00AA92E6 /* sysv_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7170187F1D9B00A76262 /* sysv_armv7.S */; };
-		FDB52FB91F6144FA00AA92E6 /* ffiw64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = 43B5D3F71D35473200D1E1FD /* ffiw64_x86_64.c */; };
-		FDB52FBA1F6144FA00AA92E6 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; };
-		FDB52FBB1F6144FA00AA92E6 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7176187F1D9B00A76262 /* ffi_i386.c */; };
-		FDB52FBC1F6144FA00AA92E6 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; };
-		FDB52FBD1F6144FA00AA92E6 /* sysv_arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716D187F1D9B00A76262 /* sysv_arm64.S */; };
-		FDB52FBE1F6144FA00AA92E6 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; };
-		FDB52FBF1F6144FA00AA92E6 /* ffi_arm64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716C187F1D9B00A76262 /* ffi_arm64.c */; };
-		FDB52FC01F6144FA00AA92E6 /* win64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 43B5D3F91D3547CE00D1E1FD /* win64_x86_64.S */; };
-		FDB52FD01F614A8B00AA92E6 /* ffi.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; };
-		FDB52FD11F614AA700AA92E6 /* ffi_arm64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA715E187F1D9B00A76262 /* ffi_arm64.h */; };
-		FDB52FD21F614AAB00AA92E6 /* ffi_armv7.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA715F187F1D9B00A76262 /* ffi_armv7.h */; };
-		FDB52FD31F614AB000AA92E6 /* ffi_i386.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7160187F1D9B00A76262 /* ffi_i386.h */; };
-		FDB52FD41F614AB500AA92E6 /* ffi_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */; };
-		FDB52FD51F614AE200AA92E6 /* ffi.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; };
-		FDB52FD61F614AEA00AA92E6 /* ffi_arm64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA715E187F1D9B00A76262 /* ffi_arm64.h */; };
-		FDB52FD71F614AED00AA92E6 /* ffi_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */; };
-		FDB52FD81F614B8700AA92E6 /* ffitarget.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7141187F1D8600A76262 /* ffitarget.h */; };
-		FDB52FD91F614B8E00AA92E6 /* ffitarget_arm64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */; };
-		FDB52FDA1F614B9300AA92E6 /* ffitarget_armv7.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */; };
-		FDB52FDB1F614B9700AA92E6 /* ffitarget_i386.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */; };
-		FDB52FDD1F614BA900AA92E6 /* ffitarget_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */; };
-		FDB52FDE1F6155E300AA92E6 /* ffitarget.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7141187F1D8600A76262 /* ffitarget.h */; };
-		FDB52FDF1F6155EA00AA92E6 /* ffitarget_arm64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */; };
-		FDB52FE01F6155EF00AA92E6 /* ffitarget_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */; };
-		FDB52FE21F6156FA00AA92E6 /* ffi.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; };
-		FDB52FE31F61571A00AA92E6 /* ffi_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7183187F1DA100A76262 /* ffi_x86_64.h */; };
-		FDB52FE41F61571D00AA92E6 /* ffitarget.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7141187F1D8600A76262 /* ffitarget.h */; };
-		FDB52FE61F61573100AA92E6 /* ffitarget_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */; };
-		FDDB2F411F5D66E200EF414E /* ffiw64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = FDDB2F3F1F5D666900EF414E /* ffiw64_x86_64.c */; };
-		FDDB2F461F5D691E00EF414E /* win64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = FDDB2F441F5D68C900EF414E /* win64_x86_64.S */; };
-		FDDB2F4A1F5D846400EF414E /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */; };
-		FDDB2F4B1F5D846400EF414E /* sysv_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718B187F1DA100A76262 /* sysv_i386.S */; };
-		FDDB2F4C1F5D846400EF414E /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; };
-		FDDB2F4D1F5D846400EF414E /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718D187F1DA100A76262 /* ffi_i386.c */; };
-		FDDB2F4E1F5D846400EF414E /* ffiw64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = FDDB2F3F1F5D666900EF414E /* ffiw64_x86_64.c */; };
-		FDDB2F4F1F5D846400EF414E /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; };
-		FDDB2F501F5D846400EF414E /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; };
-		FDDB2F511F5D846400EF414E /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; };
-		FDDB2F521F5D846400EF414E /* unix64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718A187F1DA100A76262 /* unix64_x86_64.S */; };
-		FDDB2F531F5D846400EF414E /* win64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = FDDB2F441F5D68C900EF414E /* win64_x86_64.S */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXCopyFilesBuildPhase section */
 		DB13B1641849DF1E0010F42D /* CopyFiles */ = {
 			isa = PBXCopyFilesBuildPhase;
-			buildActionMask = 12;
+			buildActionMask = 8;
 			dstPath = "include/$(PRODUCT_NAME)";
 			dstSubfolderSpec = 16;
 			files = (
-				FDB52FD01F614A8B00AA92E6 /* ffi.h in CopyFiles */,
-				FDB52FD11F614AA700AA92E6 /* ffi_arm64.h in CopyFiles */,
-				FDB52FD21F614AAB00AA92E6 /* ffi_armv7.h in CopyFiles */,
-				FDB52FD31F614AB000AA92E6 /* ffi_i386.h in CopyFiles */,
-				FDB52FD41F614AB500AA92E6 /* ffi_x86_64.h in CopyFiles */,
-				FDB52FD81F614B8700AA92E6 /* ffitarget.h in CopyFiles */,
-				FDB52FD91F614B8E00AA92E6 /* ffitarget_arm64.h in CopyFiles */,
-				FDB52FDA1F614B9300AA92E6 /* ffitarget_armv7.h in CopyFiles */,
-				FDB52FDB1F614B9700AA92E6 /* ffitarget_i386.h in CopyFiles */,
-				FDB52FDD1F614BA900AA92E6 /* ffitarget_x86_64.h in CopyFiles */,
 			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		FDB52FC11F6144FA00AA92E6 /* CopyFiles */ = {
-			isa = PBXCopyFilesBuildPhase;
-			buildActionMask = 12;
-			dstPath = "include/$(PRODUCT_NAME)";
-			dstSubfolderSpec = 16;
-			files = (
-				FDB52FD51F614AE200AA92E6 /* ffi.h in CopyFiles */,
-				FDB52FD61F614AEA00AA92E6 /* ffi_arm64.h in CopyFiles */,
-				FDB52FD71F614AED00AA92E6 /* ffi_x86_64.h in CopyFiles */,
-				FDB52FDE1F6155E300AA92E6 /* ffitarget.h in CopyFiles */,
-				FDB52FDF1F6155EA00AA92E6 /* ffitarget_arm64.h in CopyFiles */,
-				FDB52FE01F6155EF00AA92E6 /* ffitarget_x86_64.h in CopyFiles */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		FDB52FE11F6156E000AA92E6 /* CopyFiles */ = {
-			isa = PBXCopyFilesBuildPhase;
-			buildActionMask = 2147483647;
-			dstPath = "include/$(PRODUCT_NAME)";
-			dstSubfolderSpec = 16;
-			files = (
-				FDB52FE21F6156FA00AA92E6 /* ffi.h in CopyFiles */,
-				FDB52FE31F61571A00AA92E6 /* ffi_x86_64.h in CopyFiles */,
-				FDB52FE41F61571D00AA92E6 /* ffitarget.h in CopyFiles */,
-				FDB52FE61F61573100AA92E6 /* ffitarget_x86_64.h in CopyFiles */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
+			runOnlyForDeploymentPostprocessing = 1;
 		};
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
-		43B5D3F71D35473200D1E1FD /* ffiw64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffiw64_x86_64.c; sourceTree = "<group>"; };
-		43B5D3F91D3547CE00D1E1FD /* win64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = win64_x86_64.S; sourceTree = "<group>"; };
-		43E9A5C51D352C1500926A8F /* sysv_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_i386.S; sourceTree = "<group>"; };
-		43E9A5C61D352C1500926A8F /* unix64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = unix64_x86_64.S; sourceTree = "<group>"; };
-		43E9A5DA1D35373600926A8F /* internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
-		43E9A5DB1D35374400926A8F /* internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
-		43E9A5DC1D35375400926A8F /* internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
-		43E9A5DD1D35375400926A8F /* internal64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal64.h; sourceTree = "<group>"; };
 		DB13B1661849DF1E0010F42D /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		DB13B1911849DF510010F42D /* ffi.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ffi.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		DBFA713E187F1D8600A76262 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = "<group>"; };
@@ -169,10 +76,13 @@
 		DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_armv7.h; sourceTree = "<group>"; };
 		DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = "<group>"; };
 		DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = "<group>"; };
-		DBFA716C187F1D9B00A76262 /* ffi_arm64.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.c; path = ffi_arm64.c; sourceTree = "<group>"; };
+		DBFA716C187F1D9B00A76262 /* ffi_arm64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_arm64.c; sourceTree = "<group>"; };
 		DBFA716D187F1D9B00A76262 /* sysv_arm64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_arm64.S; sourceTree = "<group>"; };
-		DBFA716F187F1D9B00A76262 /* ffi_armv7.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.c; path = ffi_armv7.c; sourceTree = "<group>"; };
+		DBFA716F187F1D9B00A76262 /* ffi_armv7.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_armv7.c; sourceTree = "<group>"; };
 		DBFA7170187F1D9B00A76262 /* sysv_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_armv7.S; sourceTree = "<group>"; };
+		DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = trampoline_armv7.S; sourceTree = "<group>"; };
+		DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64_x86_64.S; sourceTree = "<group>"; };
+		DBFA7174187F1D9B00A76262 /* darwin_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin_i386.S; sourceTree = "<group>"; };
 		DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = "<group>"; };
 		DBFA7176187F1D9B00A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = "<group>"; };
 		DBFA7182187F1DA100A76262 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = "<group>"; };
@@ -181,17 +91,10 @@
 		DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = "<group>"; };
 		DBFA7186187F1DA100A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = "<group>"; };
 		DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = "<group>"; };
-		DBFA718A187F1DA100A76262 /* unix64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = unix64_x86_64.S; sourceTree = "<group>"; };
-		DBFA718B187F1DA100A76262 /* sysv_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_i386.S; sourceTree = "<group>"; };
-		DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = "<group>"; };
+		DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64_x86_64.S; sourceTree = "<group>"; };
+		DBFA718B187F1DA100A76262 /* darwin_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin_i386.S; sourceTree = "<group>"; };
+		DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = "<group>"; };
 		DBFA718D187F1DA100A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = "<group>"; };
-		FDB52FC51F6144FA00AA92E6 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
-		FDDB2F3E1F5D61BC00EF414E /* asmnames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = asmnames.h; sourceTree = "<group>"; };
-		FDDB2F3F1F5D666900EF414E /* ffiw64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffiw64_x86_64.c; sourceTree = "<group>"; };
-		FDDB2F421F5D68C900EF414E /* internal64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal64.h; sourceTree = "<group>"; };
-		FDDB2F431F5D68C900EF414E /* internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
-		FDDB2F441F5D68C900EF414E /* win64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = win64_x86_64.S; sourceTree = "<group>"; };
-		FDDB2F621F5D846400EF414E /* libffi.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
 /* End PBXFileReference section */
 
 /* Begin PBXGroup section */
@@ -210,8 +113,6 @@
 			children = (
 				DB13B1661849DF1E0010F42D /* libffi.a */,
 				DB13B1911849DF510010F42D /* ffi.dylib */,
-				FDDB2F621F5D846400EF414E /* libffi.a */,
-				FDB52FC51F6144FA00AA92E6 /* libffi.a */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -222,7 +123,7 @@
 				DBFA713D187F1D8600A76262 /* include */,
 				DBFA7142187F1D8600A76262 /* src */,
 			);
-			path = darwin_common;
+			path = "darwin_common";
 			sourceTree = "<group>";
 		};
 		DBFA713D187F1D8600A76262 /* include */ = {
@@ -254,7 +155,7 @@
 				DBFA715D187F1D9B00A76262 /* include */,
 				DBFA716A187F1D9B00A76262 /* src */,
 			);
-			path = darwin_ios;
+			path = "darwin_ios";
 			sourceTree = "<group>";
 		};
 		DBFA715D187F1D9B00A76262 /* include */ = {
@@ -289,7 +190,6 @@
 		DBFA716B187F1D9B00A76262 /* aarch64 */ = {
 			isa = PBXGroup;
 			children = (
-				43E9A5DA1D35373600926A8F /* internal.h */,
 				DBFA716C187F1D9B00A76262 /* ffi_arm64.c */,
 				DBFA716D187F1D9B00A76262 /* sysv_arm64.S */,
 			);
@@ -299,9 +199,9 @@
 		DBFA716E187F1D9B00A76262 /* arm */ = {
 			isa = PBXGroup;
 			children = (
-				43E9A5DB1D35374400926A8F /* internal.h */,
 				DBFA716F187F1D9B00A76262 /* ffi_armv7.c */,
 				DBFA7170187F1D9B00A76262 /* sysv_armv7.S */,
+				DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */,
 			);
 			path = arm;
 			sourceTree = "<group>";
@@ -309,14 +209,10 @@
 		DBFA7172187F1D9B00A76262 /* x86 */ = {
 			isa = PBXGroup;
 			children = (
-				43E9A5DC1D35375400926A8F /* internal.h */,
-				43E9A5DD1D35375400926A8F /* internal64.h */,
+				DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */,
+				DBFA7174187F1D9B00A76262 /* darwin_i386.S */,
 				DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */,
-				43B5D3F71D35473200D1E1FD /* ffiw64_x86_64.c */,
 				DBFA7176187F1D9B00A76262 /* ffi_i386.c */,
-				43E9A5C51D352C1500926A8F /* sysv_i386.S */,
-				43E9A5C61D352C1500926A8F /* unix64_x86_64.S */,
-				43B5D3F91D3547CE00D1E1FD /* win64_x86_64.S */,
 			);
 			path = x86;
 			sourceTree = "<group>";
@@ -327,7 +223,7 @@
 				DBFA7181187F1DA100A76262 /* include */,
 				DBFA7188187F1DA100A76262 /* src */,
 			);
-			path = darwin_osx;
+			path = "darwin_osx";
 			sourceTree = "<group>";
 		};
 		DBFA7181187F1DA100A76262 /* include */ = {
@@ -354,15 +250,10 @@
 		DBFA7189187F1DA100A76262 /* x86 */ = {
 			isa = PBXGroup;
 			children = (
-				FDDB2F431F5D68C900EF414E /* internal.h */,
-				FDDB2F421F5D68C900EF414E /* internal64.h */,
-				FDDB2F3E1F5D61BC00EF414E /* asmnames.h */,
+				DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */,
+				DBFA718B187F1DA100A76262 /* darwin_i386.S */,
 				DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */,
-				FDDB2F3F1F5D666900EF414E /* ffiw64_x86_64.c */,
 				DBFA718D187F1DA100A76262 /* ffi_i386.c */,
-				DBFA718B187F1DA100A76262 /* sysv_i386.S */,
-				DBFA718A187F1DA100A76262 /* unix64_x86_64.S */,
-				FDDB2F441F5D68C900EF414E /* win64_x86_64.S */,
 			);
 			path = x86;
 			sourceTree = "<group>";
@@ -394,7 +285,7 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = DB13B18B1849DF1E0010F42D /* Build configuration list for PBXNativeTarget "libffi-iOS" */;
 			buildPhases = (
-				43B5D3FB1D35480D00D1E1FD /* Run Script */,
+				DB13B3051849E01C0010F42D /* ShellScript */,
 				DB13B1621849DF1E0010F42D /* Sources */,
 				DB13B1641849DF1E0010F42D /* CopyFiles */,
 			);
@@ -424,47 +315,13 @@
 			productReference = DB13B1911849DF510010F42D /* ffi.dylib */;
 			productType = "com.apple.product-type.library.dynamic";
 		};
-		FDB52FB01F6144FA00AA92E6 /* libffi-tvOS */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = FDB52FC21F6144FA00AA92E6 /* Build configuration list for PBXNativeTarget "libffi-tvOS" */;
-			buildPhases = (
-				FDB52FB11F6144FA00AA92E6 /* Run Script */,
-				FDB52FB21F6144FA00AA92E6 /* Sources */,
-				FDB52FC11F6144FA00AA92E6 /* CopyFiles */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = "libffi-tvOS";
-			productName = ffi;
-			productReference = FDB52FC51F6144FA00AA92E6 /* libffi.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-		FDDB2F471F5D846400EF414E /* libffi-static-Mac */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = FDDB2F5F1F5D846400EF414E /* Build configuration list for PBXNativeTarget "libffi-static-Mac" */;
-			buildPhases = (
-				FDDB2F481F5D846400EF414E /* ShellScript */,
-				FDDB2F491F5D846400EF414E /* Sources */,
-				FDB52FE11F6156E000AA92E6 /* CopyFiles */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = "libffi-static-Mac";
-			productName = ffi;
-			productReference = FDDB2F621F5D846400EF414E /* libffi.a */;
-			productType = "com.apple.product-type.library.dynamic";
-		};
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
 		DB13B15C1849DEB70010F42D /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 0830;
+				LastUpgradeCheck = 0510;
 			};
 			buildConfigurationList = DB13B15F1849DEB70010F42D /* Build configuration list for PBXProject "libffi" */;
 			compatibilityVersion = "Xcode 3.2";
@@ -479,27 +336,24 @@
 			projectRoot = "";
 			targets = (
 				DB13B1651849DF1E0010F42D /* libffi-iOS */,
-				FDB52FB01F6144FA00AA92E6 /* libffi-tvOS */,
 				DB13B1901849DF510010F42D /* libffi-Mac */,
-				FDDB2F471F5D846400EF414E /* libffi-static-Mac */,
 			);
 		};
 /* End PBXProject section */
 
 /* Begin PBXShellScriptBuildPhase section */
-		43B5D3FB1D35480D00D1E1FD /* Run Script */ = {
+		DB13B3051849E01C0010F42D /* ShellScript */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Run Script";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "if [ ! -f \"./compile\" ]\nthen\nautoreconf -i -f -v\nif [ -f \"../ltmain.sh\" ]\nthen\necho \"fixing ltmain.sh for some reason\"\nmv ../ltmain.sh ./\nautoreconf -i -f -v\nfi\n/usr/bin/python generate-darwin-source-and-headers.py --only-ios\nfi";
+			shellScript = "/usr/bin/python generate-darwin-source-and-headers.py --only-ios";
 		};
 		DB13B3061849E0490010F42D /* ShellScript */ = {
 			isa = PBXShellScriptBuildPhase;
@@ -512,34 +366,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "if [ ! -f \"./compile\" ]\nthen\nautoreconf -i -f -v\nif [ -f \"../ltmain.sh\" ]\nthen\necho \"fixing ltmain.sh for some reason\"\nmv ../ltmain.sh ./\nautoreconf -i -f -v\nfi\n/usr/bin/python generate-darwin-source-and-headers.py --only-osx\nfi";
-		};
-		FDB52FB11F6144FA00AA92E6 /* Run Script */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			name = "Run Script";
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "if [ ! -f \"./compile\" ]\nthen\nautoreconf -i -f -v\nif [ -f \"../ltmain.sh\" ]\nthen\necho \"fixing ltmain.sh for some reason\"\nmv ../ltmain.sh ./\nautoreconf -i -f -v\nfi\n/usr/bin/python generate-darwin-source-and-headers.py --only-ios\nfi";
-		};
-		FDDB2F481F5D846400EF414E /* ShellScript */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "if [ ! -f \"./compile\" ]\nthen\nautoreconf -i -f -v\nif [ -f \"../ltmain.sh\" ]\nthen\necho \"fixing ltmain.sh for some reason\"\nmv ../ltmain.sh ./\nautoreconf -i -f -v\nfi\n/usr/bin/python generate-darwin-source-and-headers.py --only-osx\nfi";
+			shellScript = "/usr/bin/python generate-darwin-source-and-headers.py --only-osx";
 		};
 /* End PBXShellScriptBuildPhase section */
 
@@ -548,20 +375,19 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				43E9A5C81D352C1500926A8F /* unix64_x86_64.S in Sources */,
-				43E9A5C71D352C1500926A8F /* sysv_i386.S in Sources */,
 				DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */,
 				DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */,
+				DBFA717B187F1D9B00A76262 /* trampoline_armv7.S in Sources */,
 				DBFA714E187F1D8600A76262 /* closures.c in Sources */,
 				DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */,
-				43B5D3F81D35473200D1E1FD /* ffiw64_x86_64.c in Sources */,
+				DBFA717D187F1D9B00A76262 /* darwin_i386.S in Sources */,
 				DBFA7156187F1D8600A76262 /* prep_cif.c in Sources */,
 				DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */,
 				DBFA7158187F1D8600A76262 /* raw_api.c in Sources */,
 				DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */,
+				DBFA717C187F1D9B00A76262 /* darwin64_x86_64.S in Sources */,
 				DBFA715A187F1D8600A76262 /* types.c in Sources */,
 				DBFA7177187F1D9B00A76262 /* ffi_arm64.c in Sources */,
-				43B5D3FA1D3547CE00D1E1FD /* win64_x86_64.S in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -570,53 +396,13 @@
 			buildActionMask = 2147483647;
 			files = (
 				DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */,
-				DBFA7195187F1DA100A76262 /* sysv_i386.S in Sources */,
+				DBFA7195187F1DA100A76262 /* darwin_i386.S in Sources */,
 				DBFA7157187F1D8600A76262 /* prep_cif.c in Sources */,
 				DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */,
-				FDDB2F411F5D66E200EF414E /* ffiw64_x86_64.c in Sources */,
 				DBFA715B187F1D8600A76262 /* types.c in Sources */,
 				DBFA7159187F1D8600A76262 /* raw_api.c in Sources */,
 				DBFA714F187F1D8600A76262 /* closures.c in Sources */,
-				DBFA7194187F1DA100A76262 /* unix64_x86_64.S in Sources */,
-				FDDB2F461F5D691E00EF414E /* win64_x86_64.S in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		FDB52FB21F6144FA00AA92E6 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				FDB52FB31F6144FA00AA92E6 /* unix64_x86_64.S in Sources */,
-				FDB52FB41F6144FA00AA92E6 /* sysv_i386.S in Sources */,
-				FDB52FB51F6144FA00AA92E6 /* ffi64_x86_64.c in Sources */,
-				FDB52FB61F6144FA00AA92E6 /* ffi_armv7.c in Sources */,
-				FDB52FB71F6144FA00AA92E6 /* closures.c in Sources */,
-				FDB52FB81F6144FA00AA92E6 /* sysv_armv7.S in Sources */,
-				FDB52FB91F6144FA00AA92E6 /* ffiw64_x86_64.c in Sources */,
-				FDB52FBA1F6144FA00AA92E6 /* prep_cif.c in Sources */,
-				FDB52FBB1F6144FA00AA92E6 /* ffi_i386.c in Sources */,
-				FDB52FBC1F6144FA00AA92E6 /* raw_api.c in Sources */,
-				FDB52FBD1F6144FA00AA92E6 /* sysv_arm64.S in Sources */,
-				FDB52FBE1F6144FA00AA92E6 /* types.c in Sources */,
-				FDB52FBF1F6144FA00AA92E6 /* ffi_arm64.c in Sources */,
-				FDB52FC01F6144FA00AA92E6 /* win64_x86_64.S in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		FDDB2F491F5D846400EF414E /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				FDDB2F4A1F5D846400EF414E /* ffi64_x86_64.c in Sources */,
-				FDDB2F4B1F5D846400EF414E /* sysv_i386.S in Sources */,
-				FDDB2F4C1F5D846400EF414E /* prep_cif.c in Sources */,
-				FDDB2F4D1F5D846400EF414E /* ffi_i386.c in Sources */,
-				FDDB2F4E1F5D846400EF414E /* ffiw64_x86_64.c in Sources */,
-				FDDB2F4F1F5D846400EF414E /* types.c in Sources */,
-				FDDB2F501F5D846400EF414E /* raw_api.c in Sources */,
-				FDDB2F511F5D846400EF414E /* closures.c in Sources */,
-				FDDB2F521F5D846400EF414E /* unix64_x86_64.S in Sources */,
-				FDDB2F531F5D846400EF414E /* win64_x86_64.S in Sources */,
+				DBFA7194187F1DA100A76262 /* darwin64_x86_64.S in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -626,27 +412,9 @@
 		DB13B1601849DEB70010F42D /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				CLANG_WARN_BOOL_CONVERSION = YES;
-				CLANG_WARN_CONSTANT_CONVERSION = YES;
-				CLANG_WARN_EMPTY_BODY = YES;
-				CLANG_WARN_ENUM_CONVERSION = YES;
-				CLANG_WARN_INFINITE_RECURSION = YES;
-				CLANG_WARN_INT_CONVERSION = YES;
-				CLANG_WARN_SUSPICIOUS_MOVE = YES;
-				CLANG_WARN_UNREACHABLE_CODE = YES;
-				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				ENABLE_STRICT_OBJC_MSGSEND = YES;
-				ENABLE_TESTABILITY = YES;
-				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNDECLARED_SELECTOR = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES;
-				GCC_WARN_UNUSED_FUNCTION = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
-					darwin_common/include,
+					"darwin_common/include",
 				);
 				ONLY_ACTIVE_ARCH = YES;
 			};
@@ -655,26 +423,9 @@
 		DB13B1611849DEB70010F42D /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				CLANG_WARN_BOOL_CONVERSION = YES;
-				CLANG_WARN_CONSTANT_CONVERSION = YES;
-				CLANG_WARN_EMPTY_BODY = YES;
-				CLANG_WARN_ENUM_CONVERSION = YES;
-				CLANG_WARN_INFINITE_RECURSION = YES;
-				CLANG_WARN_INT_CONVERSION = YES;
-				CLANG_WARN_SUSPICIOUS_MOVE = YES;
-				CLANG_WARN_UNREACHABLE_CODE = YES;
-				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				ENABLE_STRICT_OBJC_MSGSEND = YES;
-				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNDECLARED_SELECTOR = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES;
-				GCC_WARN_UNUSED_FUNCTION = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
-					darwin_common/include,
+					"darwin_common/include",
 				);
 			};
 			name = Release;
@@ -683,6 +434,11 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_CONSTANT_CONVERSION = YES;
 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
@@ -693,11 +449,14 @@
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
 				DSTROOT = /tmp/ffi.dst;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"DEBUG=1",
 					"$(inherited)",
 				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
@@ -706,13 +465,14 @@
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
-					darwin_ios/include,
+					"darwin_ios/include",
 				);
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+				"IPHONEOS_DEPLOYMENT_TARGET[arch=arm64]" = 7.0;
+				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_NAME = ffi;
 				SDKROOT = iphoneos;
 				SKIP_INSTALL = YES;
-				VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64";
 			};
 			name = Debug;
 		};
@@ -720,6 +480,11 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_CONSTANT_CONVERSION = YES;
 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
@@ -731,6 +496,7 @@
 				COPY_PHASE_STRIP = YES;
 				DSTROOT = /tmp/ffi.dst;
 				ENABLE_NS_ASSERTIONS = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
@@ -739,14 +505,15 @@
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
-					darwin_ios/include,
+					"darwin_ios/include",
 				);
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+				"IPHONEOS_DEPLOYMENT_TARGET[arch=arm64]" = 7.0;
+				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_NAME = ffi;
 				SDKROOT = iphoneos;
 				SKIP_INSTALL = YES;
 				VALIDATE_PRODUCT = YES;
-				VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64";
 			};
 			name = Release;
 		};
@@ -765,7 +532,6 @@
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				COMBINE_HIDPI_IMAGES = YES;
 				COPY_PHASE_STRIP = NO;
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
@@ -786,7 +552,7 @@
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
-					darwin_osx/include,
+					"darwin_osx/include",
 				);
 				MACOSX_DEPLOYMENT_TARGET = 10.6;
 				ONLY_ACTIVE_ARCH = YES;
@@ -811,7 +577,6 @@
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				COMBINE_HIDPI_IMAGES = YES;
 				COPY_PHASE_STRIP = YES;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DYLIB_COMPATIBILITY_VERSION = 1;
@@ -827,7 +592,7 @@
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
 					"$(inherited)",
-					darwin_osx/include,
+					"darwin_osx/include",
 				);
 				MACOSX_DEPLOYMENT_TARGET = 10.6;
 				OTHER_LDFLAGS = "-Wl,-no_compact_unwind";
@@ -836,159 +601,6 @@
 			};
 			name = Release;
 		};
-		FDB52FC31F6144FA00AA92E6 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				CLANG_WARN_BOOL_CONVERSION = YES;
-				CLANG_WARN_CONSTANT_CONVERSION = YES;
-				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
-				CLANG_WARN_EMPTY_BODY = YES;
-				CLANG_WARN_ENUM_CONVERSION = YES;
-				CLANG_WARN_INT_CONVERSION = YES;
-				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
-				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				COPY_PHASE_STRIP = NO;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"DEBUG=1",
-					"$(inherited)",
-				);
-				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
-				GCC_WARN_UNDECLARED_SELECTOR = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
-				GCC_WARN_UNUSED_FUNCTION = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = (
-					"$(inherited)",
-					darwin_ios/include,
-				);
-				PRODUCT_NAME = ffi;
-				SDKROOT = appletvos;
-				SKIP_INSTALL = YES;
-				TVOS_DEPLOYMENT_TARGET = 9.0;
-			};
-			name = Debug;
-		};
-		FDB52FC41F6144FA00AA92E6 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				CLANG_WARN_BOOL_CONVERSION = YES;
-				CLANG_WARN_CONSTANT_CONVERSION = YES;
-				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
-				CLANG_WARN_EMPTY_BODY = YES;
-				CLANG_WARN_ENUM_CONVERSION = YES;
-				CLANG_WARN_INT_CONVERSION = YES;
-				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
-				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				COPY_PHASE_STRIP = YES;
-				ENABLE_NS_ASSERTIONS = NO;
-				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
-				GCC_WARN_UNDECLARED_SELECTOR = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
-				GCC_WARN_UNUSED_FUNCTION = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = (
-					"$(inherited)",
-					darwin_ios/include,
-				);
-				PRODUCT_NAME = ffi;
-				SDKROOT = appletvos;
-				SKIP_INSTALL = YES;
-				TVOS_DEPLOYMENT_TARGET = 9.0;
-				VALIDATE_PRODUCT = YES;
-			};
-			name = Release;
-		};
-		FDDB2F601F5D846400EF414E /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
-				CLANG_CXX_LIBRARY = "libc++";
-				CLANG_ENABLE_OBJC_ARC = YES;
-				CLANG_WARN_BOOL_CONVERSION = YES;
-				CLANG_WARN_CONSTANT_CONVERSION = YES;
-				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
-				CLANG_WARN_EMPTY_BODY = YES;
-				CLANG_WARN_ENUM_CONVERSION = YES;
-				CLANG_WARN_INT_CONVERSION = YES;
-				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
-				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				COMBINE_HIDPI_IMAGES = YES;
-				COPY_PHASE_STRIP = NO;
-				EXECUTABLE_EXTENSION = a;
-				EXECUTABLE_PREFIX = lib;
-				GCC_C_LANGUAGE_STANDARD = gnu99;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"DEBUG=1",
-					"$(inherited)",
-				);
-				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
-				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
-				GCC_WARN_UNDECLARED_SELECTOR = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
-				GCC_WARN_UNUSED_FUNCTION = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = (
-					"$(inherited)",
-					darwin_osx/include,
-				);
-				MACH_O_TYPE = staticlib;
-				MACOSX_DEPLOYMENT_TARGET = 10.6;
-				ONLY_ACTIVE_ARCH = YES;
-				PRODUCT_NAME = ffi;
-				SDKROOT = macosx;
-			};
-			name = Debug;
-		};
-		FDDB2F611F5D846400EF414E /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
-				CLANG_CXX_LIBRARY = "libc++";
-				CLANG_ENABLE_OBJC_ARC = YES;
-				CLANG_WARN_BOOL_CONVERSION = YES;
-				CLANG_WARN_CONSTANT_CONVERSION = YES;
-				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
-				CLANG_WARN_EMPTY_BODY = YES;
-				CLANG_WARN_ENUM_CONVERSION = YES;
-				CLANG_WARN_INT_CONVERSION = YES;
-				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
-				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				COMBINE_HIDPI_IMAGES = YES;
-				COPY_PHASE_STRIP = YES;
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				ENABLE_NS_ASSERTIONS = NO;
-				EXECUTABLE_EXTENSION = a;
-				EXECUTABLE_PREFIX = lib;
-				GCC_C_LANGUAGE_STANDARD = gnu99;
-				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
-				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
-				GCC_WARN_UNDECLARED_SELECTOR = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
-				GCC_WARN_UNUSED_FUNCTION = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = (
-					"$(inherited)",
-					darwin_osx/include,
-				);
-				MACH_O_TYPE = staticlib;
-				MACOSX_DEPLOYMENT_TARGET = 10.6;
-				PRODUCT_NAME = ffi;
-				SDKROOT = macosx;
-			};
-			name = Release;
-		};
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
@@ -1019,24 +631,6 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
-		FDB52FC21F6144FA00AA92E6 /* Build configuration list for PBXNativeTarget "libffi-tvOS" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FDB52FC31F6144FA00AA92E6 /* Debug */,
-				FDB52FC41F6144FA00AA92E6 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		FDDB2F5F1F5D846400EF414E /* Build configuration list for PBXNativeTarget "libffi-static-Mac" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FDDB2F601F5D846400EF414E /* Debug */,
-				FDDB2F611F5D846400EF414E /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
 /* End XCConfigurationList section */
 	};
 	rootObject = DB13B15C1849DEB70010F42D /* Project object */;
diff --git a/libtool-version b/libtool-version
index e4f5aa2..149a51a 100644
--- a/libtool-version
+++ b/libtool-version
@@ -26,4 +26,4 @@
 #    release, then set age to 0.
 #
 # CURRENT:REVISION:AGE
-8:0:1
+6:4:0
diff --git a/linux-arm/fficonfig.h b/linux-arm/fficonfig.h
index 4bc40c8..1055e03 100644
--- a/linux-arm/fficonfig.h
+++ b/linux-arm/fficonfig.h
@@ -41,7 +41,7 @@
 #define HAVE_DLFCN_H 1
 
 /* Define if __attribute__((visibility("hidden"))) is supported. */
-#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
+#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #define HAVE_INTTYPES_H 1
@@ -146,11 +146,7 @@
 
 #ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
 #ifdef LIBFFI_ASM
-#ifdef __APPLE__
-#define FFI_HIDDEN(name) .private_extern name
-#else
 #define FFI_HIDDEN(name) .hidden name
-#endif
 #else
 #define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
 #endif
diff --git a/linux-arm64/fficonfig.h b/linux-arm64/fficonfig.h
index 4bc40c8..1055e03 100644
--- a/linux-arm64/fficonfig.h
+++ b/linux-arm64/fficonfig.h
@@ -41,7 +41,7 @@
 #define HAVE_DLFCN_H 1
 
 /* Define if __attribute__((visibility("hidden"))) is supported. */
-#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
+#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #define HAVE_INTTYPES_H 1
@@ -146,11 +146,7 @@
 
 #ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
 #ifdef LIBFFI_ASM
-#ifdef __APPLE__
-#define FFI_HIDDEN(name) .private_extern name
-#else
 #define FFI_HIDDEN(name) .hidden name
-#endif
 #else
 #define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
 #endif
diff --git a/linux-x86/ffi.h b/linux-x86/ffi.h
index f11ee39..5717a82 100644
--- a/linux-x86/ffi.h
+++ b/linux-x86/ffi.h
@@ -15,7 +15,7 @@
  */
 #ifndef LIBFFI_H
 
-#define X86_64 1
+#define X86 1
 #define CONF_HAVE_LONG_DOUBLE 1
 
 #define LIBFFI_H
diff --git a/linux-x86/fficonfig.h b/linux-x86/fficonfig.h
index 5b3aa8b..939ef31 100644
--- a/linux-x86/fficonfig.h
+++ b/linux-x86/fficonfig.h
@@ -9,7 +9,7 @@
 #undef C_ALLOCA
 
 /* Define to the flags needed for the .section .eh_frame directive. */
-#define EH_FRAME_FLAGS "a"
+#define EH_FRAME_FLAGS "aw"
 
 /* Define this if you want extra debugging. */
 #undef FFI_DEBUG
@@ -41,7 +41,7 @@
 #define HAVE_DLFCN_H 1
 
 /* Define if __attribute__((visibility("hidden"))) is supported. */
-#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
+#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #define HAVE_INTTYPES_H 1
@@ -68,7 +68,7 @@
 #define HAVE_MMAP_FILE 1
 
 /* Define if .eh_frame sections should be read-only. */
-#define HAVE_RO_EH_FRAME 1
+#undef HAVE_RO_EH_FRAME
 
 /* Define to 1 if you have the <stdint.h> header file. */
 #define HAVE_STDINT_H 1
@@ -146,11 +146,7 @@
 
 #ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
 #ifdef LIBFFI_ASM
-#ifdef __APPLE__
-#define FFI_HIDDEN(name) .private_extern name
-#else
 #define FFI_HIDDEN(name) .hidden name
-#endif
 #else
 #define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
 #endif
diff --git a/m4/asmcfi.m4 b/m4/asmcfi.m4
index 3e28602..dbf73a0 100644
--- a/m4/asmcfi.m4
+++ b/m4/asmcfi.m4
@@ -2,7 +2,7 @@
 [AC_CACHE_CHECK([assembler .cfi pseudo-op support],
     gcc_cv_as_cfi_pseudo_op, [
     gcc_cv_as_cfi_pseudo_op=unknown
-    AC_TRY_COMPILE([asm (".cfi_sections\n\t.cfi_startproc\n\t.cfi_endproc");],,
+    AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
 		   [gcc_cv_as_cfi_pseudo_op=yes],
 		   [gcc_cv_as_cfi_pseudo_op=no])
  ])
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
index dd6d8b6..1d38b76 100644
--- a/m4/ax_append_flag.m4
+++ b/m4/ax_append_flag.m4
@@ -1,5 +1,5 @@
 # ===========================================================================
-#      https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+#      http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
 # ===========================================================================
 #
 # SYNOPSIS
@@ -23,28 +23,47 @@
 #   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
 #   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
 #
-#   Copying and distribution of this file, with or without modification, are
-#   permitted in any medium without royalty provided the copyright notice
-#   and this notice are preserved.  This file is offered as-is, without any
-#   warranty.
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
 
-#serial 8
+#serial 2
 
 AC_DEFUN([AX_APPEND_FLAG],
-[dnl
-AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
-AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
-AS_VAR_SET_IF(FLAGS,[
-  AS_CASE([" AS_VAR_GET(FLAGS) "],
-    [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
-    [
-     AS_VAR_APPEND(FLAGS,[" $1"])
-     AC_RUN_LOG([: FLAGS="$FLAGS"])
-    ])
-  ],
-  [
-  AS_VAR_SET(FLAGS,[$1])
-  AC_RUN_LOG([: FLAGS="$FLAGS"])
-  ])
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl
+AS_VAR_SET_IF(FLAGS,
+  [case " AS_VAR_GET(FLAGS) " in
+    *" $1 "*)
+      AC_RUN_LOG([: FLAGS already contains $1])
+      ;;
+    *)
+      AC_RUN_LOG([: FLAGS="$FLAGS $1"])
+      AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"])
+      ;;
+   esac],
+  [AS_VAR_SET(FLAGS,["$1"])])
 AS_VAR_POPDEF([FLAGS])dnl
 ])dnl AX_APPEND_FLAG
diff --git a/m4/ax_cc_maxopt.m4 b/m4/ax_cc_maxopt.m4
index 9e7f1ee..62e3b53 100644
--- a/m4/ax_cc_maxopt.m4
+++ b/m4/ax_cc_maxopt.m4
@@ -1,5 +1,5 @@
 # ===========================================================================
-#       https://www.gnu.org/software/autoconf-archive/ax_cc_maxopt.html
+#       http://www.gnu.org/software/autoconf-archive/ax_cc_maxopt.html
 # ===========================================================================
 #
 # SYNOPSIS
@@ -40,7 +40,7 @@
 #   Public License for more details.
 #
 #   You should have received a copy of the GNU General Public License along
-#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 #   As a special exception, the respective Autoconf Macro's copyright owner
 #   gives unlimited permission to copy, distribute and modify the configure
@@ -55,7 +55,7 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 17
+#serial 13
 
 AC_DEFUN([AX_CC_MAXOPT],
 [
@@ -115,19 +115,11 @@
 	      AX_GCC_X86_CPUID(0)
               AX_GCC_X86_CPUID(1)
 	      case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG
-                *:756e6547:6c65746e:49656e69) # Intel
+                *:756e6547:*:*) # Intel
                   case $ax_cv_gcc_x86_cpuid_1 in
-		    *0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) icc_flags="-xK" ;;
-		    *0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) icc_flags="-xSSE2 -xB -xK" ;;
-		    *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) icc_flags="-xSSE3 -xP -xO -xB -xK" ;;
-		    *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) icc_flags="-xSSSE3 -xT -xB -xK" ;;
-		    *1?6[[7d]]?:*:*:*) icc_flags="-xSSE4.1 -xS -xT -xB -xK" ;;
-		    *1?6[[aef]]?:*:*:*|*2?6[[5cef]]?:*:*:*) icc_flags="-xSSE4.2 -xS -xT -xB -xK" ;;
-		    *2?6[[ad]]?:*:*:*) icc_flags="-xAVX -SSE4.2 -xS -xT -xB -xK" ;;
-		    *3?6[[ae]]?:*:*:*) icc_flags="-xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;
-		    *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) icc_flags="-xCORE-AVX2 -xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;
-		    *000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) icc_flags="-xSSE3 -xP -xO -xN -xW -xK" ;;
-		    *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) icc_flags="-xSSE2 -xN -xW -xK" ;;
+                    *6a?:*[[234]]:*:*|*6[[789b]]?:*:*:*) icc_flags="-xK";;
+                    *f3[[347]]:*:*:*|*f4[1347]:*:*:*) icc_flags="-xP -xN -xW -xK";;
+                    *f??:*:*:*) icc_flags="-xN -xW -xK";;
                   esac ;;
               esac ;;
           esac
@@ -149,7 +141,7 @@
      CFLAGS="-O3 -fomit-frame-pointer"
 
      # -malign-double for x86 systems
-     # libffi local change -- don't align double, as it changes the ABI
+     # LIBFFI -- DON'T DO THIS - CHANGES ABI
      # AX_CHECK_COMPILE_FLAG(-malign-double, CFLAGS="$CFLAGS -malign-double")
 
      #  -fstrict-aliasing for gcc-2.95+
@@ -161,11 +153,6 @@
 
      AX_GCC_ARCHFLAG($acx_maxopt_portable)
      ;;
-
-    microsoft)
-     # default optimization flags for MSVC opt builds
-     CFLAGS="-O2"
-     ;;
   esac
 
   if test -z "$CFLAGS"; then
diff --git a/m4/ax_cflags_warn_all.m4 b/m4/ax_cflags_warn_all.m4
index 094577e..0fa3e18 100644
--- a/m4/ax_cflags_warn_all.m4
+++ b/m4/ax_cflags_warn_all.m4
@@ -1,5 +1,5 @@
 # ===========================================================================
-#    https://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
+#    http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
 # ===========================================================================
 #
 # SYNOPSIS
@@ -43,7 +43,7 @@
 #   Public License for more details.
 #
 #   You should have received a copy of the GNU General Public License along
-#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 #   As a special exception, the respective Autoconf Macro's copyright owner
 #   gives unlimited permission to copy, distribute and modify the configure
@@ -58,7 +58,7 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 16
+#serial 14
 
 AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
 AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
@@ -84,7 +84,7 @@
 FLAGS="$ac_save_[]FLAGS"
 ])
 AS_VAR_POPDEF([FLAGS])dnl
-AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
+AC_REQUIRE([AX_APPEND_FLAG])
 case ".$VAR" in
      .ok|.ok,*) m4_ifvaln($3,$3) ;;
    .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
index bd753b3..c3a8d69 100644
--- a/m4/ax_check_compile_flag.m4
+++ b/m4/ax_check_compile_flag.m4
@@ -1,10 +1,10 @@
 # ===========================================================================
-#  https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+#   http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
 # ===========================================================================
 #
 # SYNOPSIS
 #
-#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
 #
 # DESCRIPTION
 #
@@ -19,8 +19,6 @@
 #   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
 #   force the compiler to issue an error when a bad flag is given.
 #
-#   INPUT gives an alternative input source to AC_COMPILE_IFELSE.
-#
 #   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
 #   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
 #
@@ -29,24 +27,45 @@
 #   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
 #   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
 #
-#   Copying and distribution of this file, with or without modification, are
-#   permitted in any medium without royalty provided the copyright notice
-#   and this notice are preserved.  This file is offered as-is, without any
-#   warranty.
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
 
-#serial 6
+#serial 2
 
 AC_DEFUN([AX_CHECK_COMPILE_FLAG],
-[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
 AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
 AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
   ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
   _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
-  AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
     [AS_VAR_SET(CACHEVAR,[yes])],
     [AS_VAR_SET(CACHEVAR,[no])])
   _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
-AS_VAR_IF(CACHEVAR,yes,
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
   [m4_default([$2], :)],
   [m4_default([$3], :)])
 AS_VAR_POPDEF([CACHEVAR])dnl
diff --git a/m4/ax_compiler_vendor.m4 b/m4/ax_compiler_vendor.m4
index 73efdb0..73e32ea 100644
--- a/m4/ax_compiler_vendor.m4
+++ b/m4/ax_compiler_vendor.m4
@@ -1,5 +1,5 @@
 # ===========================================================================
-#    https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html
+#    http://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html
 # ===========================================================================
 #
 # SYNOPSIS
@@ -29,7 +29,7 @@
 #   Public License for more details.
 #
 #   You should have received a copy of the GNU General Public License along
-#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 #   As a special exception, the respective Autoconf Macro's copyright owner
 #   gives unlimited permission to copy, distribute and modify the configure
@@ -44,25 +44,22 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 17
+#serial 11
 
 AC_DEFUN([AX_COMPILER_VENDOR],
 [AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
-  dnl Please add if possible support to ax_compiler_version.m4
   [# note: don't check for gcc first since some other compilers define __GNUC__
   vendors="intel:     __ICC,__ECC,__INTEL_COMPILER
            ibm:       __xlc__,__xlC__,__IBMC__,__IBMCPP__
            pathscale: __PATHCC__,__PATHSCALE__
            clang:     __clang__
-           cray:      _CRAYC
-           fujitsu:   __FUJITSU
-           sdcc:      SDCC, __SDCC
            gnu:       __GNUC__
            sun:       __SUNPRO_C,__SUNPRO_CC
            hp:        __HP_cc,__HP_aCC
            dec:       __DECC,__DECCXX,__DECC_VER,__DECCXX_VER
-           borland:   __BORLANDC__,__CODEGEARC__,__TURBOC__
+           borland:   __BORLANDC__,__TURBOC__
            comeau:    __COMO__
+           cray:      _CRAYC
            kai:       __KCC
            lcc:       __LCC__
            sgi:       __sgi,sgi
@@ -70,7 +67,6 @@
            metrowerks: __MWERKS__
            watcom:    __WATCOMC__
            portland:  __PGI
-	   tcc:       __TINYC__
            unknown:   UNKNOWN"
   for ventest in $vendors; do
     case $ventest in
diff --git a/m4/ax_configure_args.m4 b/m4/ax_configure_args.m4
index 9237efe..0726b1b 100644
--- a/m4/ax_configure_args.m4
+++ b/m4/ax_configure_args.m4
@@ -1,5 +1,5 @@
 # ===========================================================================
-#    https://www.gnu.org/software/autoconf-archive/ax_configure_args.html
+#     http://www.gnu.org/software/autoconf-archive/ax_configure_args.html
 # ===========================================================================
 #
 # SYNOPSIS
@@ -15,7 +15,7 @@
 #   to rely on eval'ing $ac_configure_args however some old autoconf
 #   versions do not provide that. To ensure maximum portability of autoconf
 #   extension macros this helper can be AC_REQUIRE'd so that
-#   $ac_configure_args will always be present.
+#   $ac_configure_args will alsways be present.
 #
 #   Sadly, the traditional "exec $SHELL" of the enable_builddir macros is
 #   spoiled now and must be replaced by "eval + exit $?".
@@ -31,15 +31,36 @@
 #
 #   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
 #
-#   Copying and distribution of this file, with or without modification, are
-#   permitted in any medium without royalty provided the copyright notice
-#   and this notice are preserved.  This file is offered as-is, without any
-#   warranty.
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
 
-#serial 14
+#serial 9
 
 AC_DEFUN([AX_CONFIGURE_ARGS],[
-   # [$]@ is unusable in 2.60+ but earlier autoconf had no ac_configure_args
+   # [$]@ is unsable in 2.60+ but earlier autoconf had no ac_configure_args
    if test "${ac_configure_args+set}" != "set" ; then
       ac_configure_args=
       for ac_arg in ${1+"[$]@"}; do
diff --git a/m4/ax_enable_builddir.m4 b/m4/ax_enable_builddir.m4
index 710384d..3cb2093 100644
--- a/m4/ax_enable_builddir.m4
+++ b/m4/ax_enable_builddir.m4
@@ -1,5 +1,5 @@
 # ===========================================================================
-#    https://www.gnu.org/software/autoconf-archive/ax_enable_builddir.html
+#    http://www.gnu.org/software/autoconf-archive/ax_enable_builddir.html
 # ===========================================================================
 #
 # SYNOPSIS
@@ -24,7 +24,7 @@
 #   toplevel builddir Makefile. It just copies the variables and
 #   rule-targets, each extended with a default rule-execution that recurses
 #   into the build directory of the current "HOST". You can override the
-#   auto-detection through `config.guess` and build-time of course, as in
+#   auto-dection through `config.guess` and build-time of course, as in
 #
 #     make HOST=i386-mingw-cross
 #
@@ -42,7 +42,7 @@
 #   into. Usually, the last one is the only one used. However, almost all
 #   targets have an additional "*-all" rule which makes the script to
 #   recurse into _all_ variants of the current HOST (!!) setting. The "-all"
-#   suffix can be overridden for the macro as well.
+#   suffix can be overriden for the macro as well.
 #
 #   a special rule is only given for things like "dist" that will copy the
 #   tarball from the builddir to the sourcedir (or $(PUB)) for reason of
@@ -64,7 +64,7 @@
 #   Public License for more details.
 #
 #   You should have received a copy of the GNU General Public License along
-#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 #   As a special exception, the respective Autoconf Macro's copyright owner
 #   gives unlimited permission to copy, distribute and modify the configure
@@ -79,11 +79,10 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 30
+#serial 23
 
 AC_DEFUN([AX_ENABLE_BUILDDIR],[
 AC_REQUIRE([AC_CANONICAL_HOST])[]dnl
-AC_REQUIRE([AC_CANONICAL_TARGET])[]dnl
 AC_REQUIRE([AX_CONFIGURE_ARGS])[]dnl
 AC_REQUIRE([AM_AUX_DIR_EXPAND])[]dnl
 AC_BEFORE([$0],[AM_INIT_AUTOMAKE])dnl
@@ -122,7 +121,7 @@
       test -f $srcdir/$cache_file  && mv $srcdir/$cache_file  .
       AC_MSG_RESULT(....exec $SHELL $srcdir/[$]0 "--srcdir=$srcdir" "--enable-builddir=$SUB" ${1+"[$]@"})
       case "[$]0" in # restart
-       [[\\/]]* | ?:[[\\/]]*) # Absolute name
+       [[\\/]]* | ?:[[\\/]]*) # Asbolute name
          eval $SHELL "'[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;
        *) eval $SHELL "'$srcdir/[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;
       esac ; exit $?
diff --git a/m4/ax_gcc_archflag.m4 b/m4/ax_gcc_archflag.m4
index c52b9b2..aab2661 100644
--- a/m4/ax_gcc_archflag.m4
+++ b/m4/ax_gcc_archflag.m4
@@ -1,5 +1,5 @@
 # ===========================================================================
-#     https://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html
+#      http://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html
 # ===========================================================================
 #
 # SYNOPSIS
@@ -36,8 +36,7 @@
 #
 #   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
 #   Copyright (c) 2008 Matteo Frigo
-#   Copyright (c) 2014 Tsukasa Oi
-#   Copyright (c) 2017-2018 Alexey Kopytov
+#   Copyright (c) 2012 Tsukasa Oi
 #
 #   This program is free software: you can redistribute it and/or modify it
 #   under the terms of the GNU General Public License as published by the
@@ -50,7 +49,7 @@
 #   Public License for more details.
 #
 #   You should have received a copy of the GNU General Public License along
-#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 #   As a special exception, the respective Autoconf Macro's copyright owner
 #   gives unlimited permission to copy, distribute and modify the configure
@@ -65,13 +64,11 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 22
+#serial 11
 
 AC_DEFUN([AX_GCC_ARCHFLAG],
 [AC_REQUIRE([AC_PROG_CC])
 AC_REQUIRE([AC_CANONICAL_HOST])
-AC_REQUIRE([AC_PROG_SED])
-AC_REQUIRE([AX_COMPILER_VENDOR])
 
 AC_ARG_WITH(gcc-arch, [AS_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],
 	ax_gcc_arch=$withval, ax_gcc_arch=yes)
@@ -88,70 +85,63 @@
 ax_gcc_arch=""
 if test "$cross_compiling" = no; then
 case $host_cpu in
-  i[[3456]]86*|x86_64*|amd64*) # use cpuid codes
+  i[[3456]]86*|x86_64*) # use cpuid codes
      AX_GCC_X86_CPUID(0)
      AX_GCC_X86_CPUID(1)
      case $ax_cv_gcc_x86_cpuid_0 in
-       *:756e6547:6c65746e:49656e69) # Intel
+       *:756e6547:*:*) # Intel
           case $ax_cv_gcc_x86_cpuid_1 in
-	    *5[[4578]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
-	    *5[[123]]?:*:*:*) ax_gcc_arch=pentium ;;
-	    *0?61?:*:*:*|?61?:*:*:*|61?:*:*:*) ax_gcc_arch=pentiumpro ;;
-	    *0?6[[356]]?:*:*:*|?6[[356]]?:*:*:*|6[[356]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
-	    *0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
-	    *0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
-	    *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) ax_gcc_arch="yonah pentium-m pentium3 pentiumpro" ;;
-	    *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;;
-	    *1?6[[7d]]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;;
-	    *1?6[[aef]]?:*:*:*|*2?6e?:*:*:*) ax_gcc_arch="nehalem corei7 core2 pentium-m pentium3 pentiumpro" ;;
-	    *2?6[[5cf]]?:*:*:*) ax_gcc_arch="westmere corei7 core2 pentium-m pentium3 pentiumpro" ;;
-	    *2?6[[ad]]?:*:*:*) ax_gcc_arch="sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
-	    *3?6[[ae]]?:*:*:*) ax_gcc_arch="ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
-	    *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) ax_gcc_arch="haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
-	    *3?6d?:*:*:*|*4?6[[7f]]?:*:*:*|*5?66?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
-	    *1?6c?:*:*:*|*2?6[[67]]?:*:*:*|*3?6[[56]]?:*:*:*) ax_gcc_arch="bonnell atom core2 pentium-m pentium3 pentiumpro" ;;
-	    *3?67?:*:*:*|*[[45]]?6[[ad]]?:*:*:*) ax_gcc_arch="silvermont atom core2 pentium-m pentium3 pentiumpro" ;;
-	    *000?f[[012]]?:*:*:*|?f[[012]]?:*:*:*|f[[012]]?:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;;
-	    *000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) ax_gcc_arch="nocona prescott pentium4 pentiumpro" ;;
-	    # fallback
+	    *5[[48]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
 	    *5??:*:*:*) ax_gcc_arch=pentium ;;
-	    *??6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;;
-	    *6??:*:*:*) ax_gcc_arch=pentiumpro ;;
-	    *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;;
+	    *0?6[[3456]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
+	    *0?6a?:*[[01]]:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
+	    *0?6a?:*[[234]]:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
+	    *0?6[[9de]]?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
+	    *0?6[[78b]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
+	    *0?6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;;
+	    *1?6[[7d]]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;;
+	    *1?6[[aef]]?:*:*:*|*2?6[[5cef]]?:*:*:*) ax_gcc_arch="corei7 core2 pentium-m pentium3 pentiumpro" ;;
+	    *1?6c?:*:*:*|*[[23]]?66?:*:*:*) ax_gcc_arch="atom core2 pentium-m pentium3 pentiumpro" ;;
+	    *2?6[[ad]]?:*:*:*) ax_gcc_arch="corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
+	    *0?6??:*:*:*) ax_gcc_arch=pentiumpro ;;
+	    *6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;;
+	    ?000?f3[[347]]:*:*:*|?000?f4[1347]:*:*:*|?000?f6?:*:*:*)
+		case $host_cpu in
+	          x86_64*) ax_gcc_arch="nocona pentium4 pentiumpro" ;;
+	          *) ax_gcc_arch="prescott pentium4 pentiumpro" ;;
+	        esac ;;
+	    ?000?f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro";;
           esac ;;
-       *:68747541:444d4163:69746e65) # AMD
+       *:68747541:*:*) # AMD
           case $ax_cv_gcc_x86_cpuid_1 in
 	    *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;
-	    *5[[8]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
-	    *5[[9d]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;
+	    *5[[8d]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
+	    *5[[9]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;
+	    *60?:*:*:*) ax_gcc_arch=k7 ;;
 	    *6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;;
 	    *6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;
-	    *6[[678a]]?:*:*:*) ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;
-	    *000?f[[4578bcef]]?:*:*:*|?f[[4578bcef]]?:*:*:*|f[[4578bcef]]?:*:*:*|*001?f[[4578bcf]]?:*:*:*|1?f[[4578bcf]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;
-	    *002?f[[13457bcf]]?:*:*:*|2?f[[13457bcf]]?:*:*:*|*004?f[[138bcf]]?:*:*:*|4?f[[138bcf]]?:*:*:*|*005?f[[df]]?:*:*:*|5?f[[df]]?:*:*:*|*006?f[[8bcf]]?:*:*:*|6?f[[8bcf]]?:*:*:*|*007?f[[cf]]?:*:*:*|7?f[[cf]]?:*:*:*|*00c?f1?:*:*:*|c?f1?:*:*:*|*020?f3?:*:*:*|20?f3?:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;;
-	    *010?f[[245689a]]?:*:*:*|10?f[[245689a]]?:*:*:*|*030?f1?:*:*:*|30?f1?:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;;
-	    *050?f[[12]]?:*:*:*|50?f[[12]]?:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;
-	    *060?f1?:*:*:*|60?f1?:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;
-	    *060?f2?:*:*:*|60?f2?:*:*:*|*061?f[[03]]?:*:*:*|61?f[[03]]?:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;;
-	    *063?f0?:*:*:*|63?f0?:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;;
-	    *07[[03]]?f0?:*:*:*|7[[03]]?f0?:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;;
-	    # fallback
-	    *0[[13]]??f??:*:*:*|[[13]]??f??:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;;
-	    *020?f??:*:*:*|20?f??:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;;
-	    *05??f??:*:*:*|5??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;
-	    *060?f??:*:*:*|60?f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;
-	    *061?f??:*:*:*|61?f??:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;;
-	    *06??f??:*:*:*|6??f??:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;;
-	    *070?f??:*:*:*|70?f??:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;;
-	    *???f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;;
+	    *67?:*:*:*) ax_gcc_arch="athlon-4 athlon k7" ;;
+	    *6[[68a]]?:*:*:*)
+	       AX_GCC_X86_CPUID(0x80000006) # L2 cache size
+	       case $ax_cv_gcc_x86_cpuid_0x80000006 in
+                 *:*:*[[1-9a-f]]??????:*) # (L2 = ecx >> 16) >= 256
+			ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;
+                 *) ax_gcc_arch="athlon-4 athlon k7" ;;
+	       esac ;;
+	    ?00??f[[4cef8b]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;
+	    ?00??f5?:*:*:*) ax_gcc_arch="opteron k8" ;;
+	    ?00??f7?:*:*:*) ax_gcc_arch="athlon-fx opteron k8" ;;
+	    ?00??f??:*:*:*) ax_gcc_arch="k8" ;;
+	    ?05??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;
+	    ?06??f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;
+	    *f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;;
           esac ;;
-	*:746e6543:736c7561:48727561) # IDT / VIA (Centaur)
+	*:746e6543:*:*) # IDT
 	   case $ax_cv_gcc_x86_cpuid_1 in
 	     *54?:*:*:*) ax_gcc_arch=winchip-c6 ;;
-	     *5[[89]]?:*:*:*) ax_gcc_arch=winchip2 ;;
-	     *66?:*:*:*) ax_gcc_arch=winchip2 ;;
+	     *58?:*:*:*) ax_gcc_arch=winchip2 ;;
 	     *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;;
-	     *6[[9adf]]?:*:*:*) ax_gcc_arch="c3-2 c3" ;;
+	     *69?:*:*:*) ax_gcc_arch="c3-2 c3" ;;
 	   esac ;;
      esac
      if test x"$ax_gcc_arch" = x; then # fallback
@@ -165,7 +155,7 @@
   sparc*)
      AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])
      cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null`
-     cputype=`echo "$cputype" | tr -d ' -' | $SED 's/SPARCIIi/SPARCII/' |tr $as_cr_LETTERS $as_cr_letters`
+     cputype=`echo "$cputype" | tr -d ' -' | sed 's/SPARCIIi/SPARCII/' | tr $as_cr_LETTERS $as_cr_letters`
      case $cputype in
          *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;
          *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;
@@ -187,8 +177,8 @@
   alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;
 
   powerpc*)
-     cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | $SED 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`
-     cputype=`echo $cputype | $SED -e 's/ppc//g;s/ *//g'`
+     cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | sed 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`
+     cputype=`echo $cputype | sed -e 's/ppc//g;s/ *//g'`
      case $cputype in
        *750*) ax_gcc_arch="750 G3" ;;
        *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;;
@@ -198,58 +188,26 @@
        *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;
        *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;
        603ev|8240) ax_gcc_arch="$cputype 603e 603";;
-       *POWER7*) ax_gcc_arch="power7";;
-       *POWER8*) ax_gcc_arch="power8";;
-       *POWER9*) ax_gcc_arch="power9";;
-       *POWER10*) ax_gcc_arch="power10";;
        *) ax_gcc_arch=$cputype ;;
      esac
      ax_gcc_arch="$ax_gcc_arch powerpc"
      ;;
-  aarch64)
-     cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`
-     cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`
-     cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`
-     case $cpuimpl in
-       0x42) case $cpuarch in
-               8) case $cpuvar in
-                    0x0) ax_gcc_arch="thunderx2t99 vulcan armv8.1-a armv8-a+lse armv8-a native" ;;
-                  esac
-                  ;;
-             esac
-             ;;
-       0x43) case $cpuarch in
-               8) case $cpuvar in
-                    0x0) ax_gcc_arch="thunderx armv8-a native" ;;
-                    0x1) ax_gcc_arch="thunderx+lse armv8.1-a armv8-a+lse armv8-a native" ;;
-                  esac
-                  ;;
-             esac
-             ;;
-      esac
-      ;;
 esac
 fi # not cross-compiling
 fi # guess arch
 
 if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then
-if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code
-  flag_prefixes="-mtune="
-  if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then flag_prefixes="-march="; fi
-  # -mcpu=$arch and m$arch generate nonportable code on every arch except
-  # x86.  And some other arches (e.g. Alpha) don't accept -mtune.  Grrr.
-  case $host_cpu in i*86|x86_64*|amd64*) flag_prefixes="$flag_prefixes -mcpu= -m";; esac
-else
-  flag_prefixes="-march= -mcpu= -m"
-fi
-for flag_prefix in $flag_prefixes; do
-  for arch in $ax_gcc_arch; do
-    flag="$flag_prefix$arch"
-    AX_CHECK_COMPILE_FLAG($flag, [if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then
-      if test "x[]m4_default([$1],yes)" = xyes; then
-	if test "x$flag" = "x-march=$arch"; then flag=-mtune=$arch; fi
-      fi
-    fi; ax_cv_gcc_archflag=$flag; break])
+for arch in $ax_gcc_arch; do
+  if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code
+    flags="-mtune=$arch"
+    # -mcpu=$arch and m$arch generate nonportable code on every arch except
+    # x86.  And some other arches (e.g. Alpha) don't accept -mtune.  Grrr.
+    case $host_cpu in i*86|x86_64*) flags="$flags -mcpu=$arch -m$arch";; esac
+  else
+    flags="-march=$arch -mcpu=$arch -m$arch"
+  fi
+  for flag in $flags; do
+    AX_CHECK_COMPILE_FLAG($flag, [ax_cv_gcc_archflag=$flag; break])
   done
   test "x$ax_cv_gcc_archflag" = xunknown || break
 done
diff --git a/m4/ax_gcc_x86_cpuid.m4 b/m4/ax_gcc_x86_cpuid.m4
index df95465..7d46fee 100644
--- a/m4/ax_gcc_x86_cpuid.m4
+++ b/m4/ax_gcc_x86_cpuid.m4
@@ -1,19 +1,17 @@
 # ===========================================================================
-#     https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html
+#     http://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html
 # ===========================================================================
 #
 # SYNOPSIS
 #
 #   AX_GCC_X86_CPUID(OP)
-#   AX_GCC_X86_CPUID_COUNT(OP, COUNT)
 #
 # DESCRIPTION
 #
 #   On Pentium and later x86 processors, with gcc or a compiler that has a
 #   compatible syntax for inline assembly instructions, run a small program
 #   that executes the cpuid instruction with input OP. This can be used to
-#   detect the CPU type. AX_GCC_X86_CPUID_COUNT takes an additional COUNT
-#   parameter that gets passed into register ECX before calling cpuid.
+#   detect the CPU type.
 #
 #   On output, the values of the eax, ebx, ecx, and edx registers are stored
 #   as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable
@@ -30,7 +28,6 @@
 #
 #   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
 #   Copyright (c) 2008 Matteo Frigo
-#   Copyright (c) 2015 Michael Petch <mpetch@capp-sysware.com>
 #
 #   This program is free software: you can redistribute it and/or modify it
 #   under the terms of the GNU General Public License as published by the
@@ -43,7 +40,7 @@
 #   Public License for more details.
 #
 #   You should have received a copy of the GNU General Public License along
-#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 #   As a special exception, the respective Autoconf Macro's copyright owner
 #   gives unlimited permission to copy, distribute and modify the configure
@@ -58,25 +55,18 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 10
+#serial 7
 
 AC_DEFUN([AX_GCC_X86_CPUID],
-[AX_GCC_X86_CPUID_COUNT($1, 0)
-])
-
-AC_DEFUN([AX_GCC_X86_CPUID_COUNT],
 [AC_REQUIRE([AC_PROG_CC])
 AC_LANG_PUSH([C])
 AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
  [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
-     int op = $1, level = $2, eax, ebx, ecx, edx;
+     int op = $1, eax, ebx, ecx, edx;
      FILE *f;
-      __asm__ __volatile__ ("xchg %%ebx, %1\n"
-        "cpuid\n"
-        "xchg %%ebx, %1\n"
-        : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
-        : "a" (op), "2" (level));
-
+      __asm__("cpuid"
+        : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+        : "a" (op));
      f = fopen("conftest_cpuid", "w"); if (!f) return 1;
      fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
      fclose(f);
diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4
deleted file mode 100644
index 17c3eab..0000000
--- a/m4/ax_require_defined.m4
+++ /dev/null
@@ -1,37 +0,0 @@
-# ===========================================================================
-#    https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-#   AX_REQUIRE_DEFINED(MACRO)
-#
-# DESCRIPTION
-#
-#   AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
-#   been defined and thus are available for use.  This avoids random issues
-#   where a macro isn't expanded.  Instead the configure script emits a
-#   non-fatal:
-#
-#     ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
-#
-#   It's like AC_REQUIRE except it doesn't expand the required macro.
-#
-#   Here's an example:
-#
-#     AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
-#
-# LICENSE
-#
-#   Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
-#
-#   Copying and distribution of this file, with or without modification, are
-#   permitted in any medium without royalty provided the copyright notice
-#   and this notice are preserved. This file is offered as-is, without any
-#   warranty.
-
-#serial 2
-
-AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
-  m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
-])dnl AX_REQUIRE_DEFINED
diff --git a/make_sunver.pl b/make_sunver.pl
deleted file mode 100644
index 8a90b1f..0000000
--- a/make_sunver.pl
+++ /dev/null
@@ -1,333 +0,0 @@
-#!/usr/bin/perl -w
-
-# make_sunver.pl
-#
-# This script takes at least two arguments, a GNU style version script and
-# a list of object and archive files, and generates a corresponding Sun
-# style version script as follows:
-#
-# Each glob pattern, C++ mangled pattern or literal in the input script is
-# matched against all global symbols in the input objects, emitting those
-# that matched (or nothing if no match was found).
-# A comment with the original pattern and its type is left in the output
-# file to make it easy to understand the matches.
-#
-# It uses elfdump when present (native), GNU readelf otherwise.
-# It depends on the GNU version of c++filt, since it must understand the
-# GNU mangling style.
-
-use FileHandle;
-use IPC::Open2;
-
-# Enforce C locale.
-$ENV{'LC_ALL'} = "C";
-$ENV{'LANG'} = "C";
-
-# Input version script, GNU style.
-my $symvers = shift;
-
-##########
-# Get all the symbols from the library, match them, and add them to a hash.
-
-my %sym_hash = ();
-
-# List of objects and archives to process.
-my @OBJECTS = ();
-
-# List of shared objects to omit from processing.
-my @SHAREDOBJS = ();
-
-# Filter out those input archives that have corresponding shared objects to
-# avoid adding all symbols matched in the archive to the output map.
-foreach $file (@ARGV) {
-    if (($so = $file) =~ s/\.a$/.so/ && -e $so) {
-	printf STDERR "omitted $file -> $so\n";
-	push (@SHAREDOBJS, $so);
-    } else {
-	push (@OBJECTS, $file);
-    }
-}
-
-# We need to detect and ignore hidden symbols.  Solaris nm can only detect
-# this in the harder to parse default output format, and GNU nm not at all,
-# so use elfdump -s in the native case and GNU readelf -s otherwise.
-# GNU objdump -t cannot be used since it produces a variable number of
-# columns.
-
-# The path to elfdump.
-my $elfdump = "/usr/ccs/bin/elfdump";
-
-if (-f $elfdump) {
-    open ELFDUMP,$elfdump.' -s '.(join ' ',@OBJECTS).'|' or die $!;
-    my $skip_arsym = 0;
-
-    while (<ELFDUMP>) {
-	chomp;
-
-	# Ignore empty lines.
-	if (/^$/) {
-	    # End of archive symbol table, stop skipping.
-	    $skip_arsym = 0 if $skip_arsym;
-	    next;
-	}
-
-	# Keep skipping until end of archive symbol table.
-	next if ($skip_arsym);
-
-	# Ignore object name header for individual objects and archives.
-	next if (/:$/);
-
-	# Ignore table header lines.
-	next if (/^Symbol Table Section:/);
-	next if (/index.*value.*size/);
-
-	# Start of archive symbol table: start skipping.
-	if (/^Symbol Table: \(archive/) {
-	    $skip_arsym = 1;
-	    next;
-	}
-
-	# Split table.
-	(undef, undef, undef, undef, $bind, $oth, undef, $shndx, $name) = split;
-
-	# Error out for unknown input.
-	die "unknown input line:\n$_" unless defined($bind);
-
-	# Ignore local symbols.
-	next if ($bind eq "LOCL");
-	# Ignore hidden symbols.
-	next if ($oth eq "H");
-	# Ignore undefined symbols.
-	next if ($shndx eq "UNDEF");
-	# Error out for unhandled cases.
-	if ($bind !~ /^(GLOB|WEAK)/ or $oth ne "D") {
-	    die "unhandled symbol:\n$_";
-	}
-
-	# Remember symbol.
-	$sym_hash{$name}++;
-    }
-    close ELFDUMP or die "$elfdump error";
-} else {
-    open READELF, 'readelf -s -W '.(join ' ',@OBJECTS).'|' or die $!;
-    # Process each symbol.
-    while (<READELF>) {
-	chomp;
-
-	# Ignore empty lines.
-	next if (/^$/);
-
-	# Ignore object name header.
-	next if (/^File: .*$/);
-
-	# Ignore table header lines.
-	next if (/^Symbol table.*contains.*:/);
-	next if (/Num:.*Value.*Size/);
-
-	# Split table.
-	(undef, undef, undef, undef, $bind, $vis, $ndx, $name) = split;
-
-	# Error out for unknown input.
-	die "unknown input line:\n$_" unless defined($bind);
-
-	# Ignore local symbols.
-	next if ($bind eq "LOCAL");
-	# Ignore hidden symbols.
-	next if ($vis eq "HIDDEN");
-	# Ignore undefined symbols.
-	next if ($ndx eq "UND");
-	# Error out for unhandled cases.
-	if ($bind !~ /^(GLOBAL|WEAK)/ or $vis ne "DEFAULT") {
-	    die "unhandled symbol:\n$_";
-	}
-
-	# Remember symbol.
-	$sym_hash{$name}++;
-    }
-    close READELF or die "readelf error";
-}
-
-##########
-# The various types of glob patterns.
-#
-# A glob pattern that is to be applied to the demangled name: 'cxx'.
-# A glob patterns that applies directly to the name in the .o files: 'glob'.
-# This pattern is ignored; used for local variables (usually just '*'): 'ign'.
-
-# The type of the current pattern.
-my $glob = 'glob';
-
-# We're currently inside `extern "C++"', which Sun ld doesn't understand.
-my $in_extern = 0;
-
-# The c++filt command to use.  This *must* be GNU c++filt; the Sun Studio
-# c++filt doesn't handle the GNU mangling style.
-my $cxxfilt = $ENV{'CXXFILT'} || "c++filt";
-
-# The current version name.
-my $current_version = "";
-
-# Was there any attempt to match a symbol to this version?
-my $matches_attempted;
-
-# The number of versions which matched this symbol.
-my $matched_symbols;
-
-open F,$symvers or die $!;
-
-# Print information about generating this file
-print "# This file was generated by make_sunver.pl.  DO NOT EDIT!\n";
-print "# It was generated by:\n";
-printf "# %s %s %s\n", $0, $symvers, (join ' ',@ARGV);
-printf "# Omitted archives with corresponding shared libraries: %s\n",
-    (join ' ', @SHAREDOBJS) if $#SHAREDOBJS >= 0;
-print "#\n\n";
-
-while (<F>) {
-    # Lines of the form '};'
-    if (/^([ \t]*)(\}[ \t]*;[ \t]*)$/) {
-	$glob = 'glob';
-	if ($in_extern) {
-	    $in_extern--;
-	    print "$1##$2\n";
-	} else {
-	    print;
-	}
-	next;
-    }
-
-    # Lines of the form '} SOME_VERSION_NAME_1.0;'
-    if (/^[ \t]*\}[ \tA-Z0-9_.a-z]+;[ \t]*$/) {
-	$glob = 'glob';
-	# We tried to match symbols agains this version, but none matched.
-	# Emit dummy hidden symbol to avoid marking this version WEAK.
-	if ($matches_attempted && $matched_symbols == 0) {
-	    print "  hidden:\n";
-	    print "    .force_WEAK_off_$current_version = DATA S0x0 V0x0;\n";
-	}
-	print; next;
-    }
-
-    # Comment and blank lines
-    if (/^[ \t]*\#/) { print; next; }
-    if (/^[ \t]*$/) { print; next; }
-
-    # Lines of the form '{'
-    if (/^([ \t]*){$/) {
-	if ($in_extern) {
-	    print "$1##{\n";
-	} else {
-	    print;
-	}
-	next;
-    }
-
-    # Lines of the form 'SOME_VERSION_NAME_1.1 {'
-    if (/^([A-Z0-9_.]+)[ \t]+{$/) {
-	# Record version name.
-	$current_version = $1;
-	# Reset match attempts, #matched symbols for this version.
-	$matches_attempted = 0;
-	$matched_symbols = 0;
-	print;
-	next;
-    }
-
-    # Ignore 'global:'
-    if (/^[ \t]*global:$/) { print; next; }
-
-    # After 'local:', globs should be ignored, they won't be exported.
-    if (/^[ \t]*local:$/) {
-	$glob = 'ign';
-	print;
-	next;
-    }
-
-    # After 'extern "C++"', globs are C++ patterns
-    if (/^([ \t]*)(extern \"C\+\+\"[ \t]*)$/) {
-	$in_extern++;
-	$glob = 'cxx';
-	# Need to comment, Sun ld cannot handle this.
-	print "$1##$2\n"; next;
-    }
-
-    # Chomp newline now we're done with passing through the input file.
-    chomp;
-
-    # Catch globs.  Note that '{}' is not allowed in globs by this script,
-    # so only '*' and '[]' are available.
-    if (/^([ \t]*)([^ \t;{}#]+);?[ \t]*$/) {
-	my $ws = $1;
-	my $ptn = $2;
-	# Turn the glob into a regex by replacing '*' with '.*', '?' with '.'.
-	# Keep $ptn so we can still print the original form.
-	($pattern = $ptn) =~ s/\*/\.\*/g;
-	$pattern =~ s/\?/\./g;
-
-	if ($glob eq 'ign') {
-	    # We're in a local: * section; just continue.
-	    print "$_\n";
-	    next;
-	}
-
-	# Print the glob commented for human readers.
-	print "$ws##$ptn ($glob)\n";
-	# We tried to match a symbol to this version.
-	$matches_attempted++;
-
-	if ($glob eq 'glob') {
-	    my %ptn_syms = ();
-
-	    # Match ptn against symbols in %sym_hash.
-	    foreach my $sym (keys %sym_hash) {
-		# Maybe it matches one of the patterns based on the symbol in
-		# the .o file.
-		$ptn_syms{$sym}++ if ($sym =~ /^$pattern$/);
-	    }
-
-	    foreach my $sym (sort keys(%ptn_syms)) {
-		$matched_symbols++;
-		print "$ws$sym;\n";
-	    }
-	} elsif ($glob eq 'cxx') {
-	    my %dem_syms = ();
-
-	    # Verify that we're actually using GNU c++filt.  Other versions
-	    # most likely cannot handle GNU style symbol mangling.
-	    my $cxxout = `$cxxfilt --version 2>&1`;
-	    $cxxout =~ m/GNU/ or die "$0 requires GNU c++filt to function";
-
-	    # Talk to c++filt through a pair of file descriptors.
-	    # Need to start a fresh instance per pattern, otherwise the
-	    # process grows to 500+ MB.
-	    my $pid = open2(*FILTIN, *FILTOUT, $cxxfilt) or die $!;
-
-	    # Match ptn against symbols in %sym_hash.
-	    foreach my $sym (keys %sym_hash) {
-		# No?  Well, maybe its demangled form matches one of those
-		# patterns.
-		printf FILTOUT "%s\n",$sym;
-		my $dem = <FILTIN>;
-		chomp $dem;
-		$dem_syms{$sym}++ if ($dem =~ /^$pattern$/);
-	    }
-
-	    close FILTOUT or die "c++filt error";
-	    close FILTIN or die "c++filt error";
-	    # Need to wait for the c++filt process to avoid lots of zombies.
-	    waitpid $pid, 0;
-
-	    foreach my $sym (sort keys(%dem_syms)) {
-		$matched_symbols++;
-		print "$ws$sym;\n";
-	    }
-	} else {
-	    # No?  Well, then ignore it.
-	}
-	next;
-    }
-    # Important sanity check.  This script can't handle lots of formats
-    # that GNU ld can, so be sure to error out if one is seen!
-    die "strange line `$_'";
-}
-close F;
diff --git a/msvc_build/aarch64/Ffi_staticLib.sln b/msvc_build/aarch64/Ffi_staticLib.sln
deleted file mode 100644
index d9119df..0000000
--- a/msvc_build/aarch64/Ffi_staticLib.sln
+++ /dev/null
@@ -1,33 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.28302.56
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ffi_staticLib_arm64", "Ffi_staticLib.vcxproj", "{115502C0-BE05-4767-BF19-5C87D805FAD6}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|ARM64 = Debug|ARM64
-		Debug|x64 = Debug|x64
-		Debug|x86 = Debug|x86
-		Release|ARM64 = Release|ARM64
-		Release|x64 = Release|x64
-		Release|x86 = Release|x86
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|ARM64.ActiveCfg = Debug|ARM64
-		{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|ARM64.Build.0 = Debug|ARM64
-		{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|x64.ActiveCfg = Debug|ARM64
-		{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|x86.ActiveCfg = Debug|ARM64
-		{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|ARM64.ActiveCfg = Release|ARM64
-		{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|ARM64.Build.0 = Release|ARM64
-		{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|x64.ActiveCfg = Release|ARM64
-		{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|x86.ActiveCfg = Release|ARM64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-		SolutionGuid = {241C54C7-20DD-4897-9376-E6B6D1B43BD5}
-	EndGlobalSection
-EndGlobal
diff --git a/msvc_build/aarch64/Ffi_staticLib.vcxproj b/msvc_build/aarch64/Ffi_staticLib.vcxproj
deleted file mode 100644
index 3187699..0000000
--- a/msvc_build/aarch64/Ffi_staticLib.vcxproj
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|ARM64">
-      <Configuration>Debug</Configuration>
-      <Platform>ARM64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|ARM64">
-      <Configuration>Release</Configuration>
-      <Platform>ARM64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <VCProjectVersion>15.0</VCProjectVersion>
-    <ProjectGuid>{115502C0-BE05-4767-BF19-5C87D805FAD6}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>FfistaticLib</RootNamespace>
-    <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
-    <ProjectName>Ffi_staticLib_arm64</ProjectName>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v141</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v141</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="Shared">
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <SDLCheck>true</SDLCheck>
-      <PreprocessorDefinitions>FFI_BUILDING_DLL;_DEBUG;_LIB;USE_DL_PREFIX;ARM64;_M_ARM64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <ConformanceMode>true</ConformanceMode>
-      <AdditionalIncludeDirectories>..\..\include;.\aarch64_include;..\..\src\aarch64;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
-      <BrowseInformation>true</BrowseInformation>
-      <OmitFramePointers>
-      </OmitFramePointers>
-      <WholeProgramOptimization>false</WholeProgramOptimization>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
-      <PreprocessorDefinitions>FFI_BUILDING_DLL;USE_DL_PREFIX;ARM64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <ConformanceMode>true</ConformanceMode>
-      <AdditionalIncludeDirectories>..\..\include;.\aarch64_include;..\..\src\aarch64;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <OmitFramePointers>true</OmitFramePointers>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <AdditionalUsingDirectories>..\..\src;..\..\src\aarch64;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClInclude Include=".\aarch64_include\ffi.h" />
-    <ClInclude Include=".\aarch64_include\fficonfig.h" />
-    <ClInclude Include="..\..\src\aarch64\ffitarget.h" />
-    <ClInclude Include="..\include\ffi_cfi.h" />
-    <ClInclude Include="..\include\ffi_common.h" />
-    <ClInclude Include="..\..\src\aarch64\internal.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\src\closures.c" />
-    <ClCompile Include="..\..\src\dlmalloc.c" />
-    <ClCompile Include="..\..\src\aarch64\ffi.c" />
-    <ClCompile Include="..\..\src\prep_cif.c" />
-    <ClCompile Include="..\..\src\types.c" />
-  </ItemGroup>
-  <!--ItemGroup>
-    <Object Include="..\..\..\..\Downloads\libffi-master-win64\src\aarch64\win64_armasm.obj" />
-  </ItemGroup-->
-  <ItemGroup>
-    <CustomBuild Include="..\..\src\aarch64\win64_armasm.S">
-      <!--ExcludedFromBuild Condition="'$(Platform)'!='ARM64'">true</ExcludedFromBuild -->
-      <Command>
-        cl /FA /EP /nologo /I"..\..\include" /I".\aarch64_include" /I"..\..\src\aarch64" "%(FullPath)" &gt; $(IntDir)win64_armasm.i
-        armasm64 $(IntDir)win64_armasm.i /I"src\" /I"..\..\include" /I"..\..\src\aarch64" -o "$(IntDir)win64_armasm.obj"
-      </Command>
-      <Outputs>win64_armasm.obj;%(Outputs)</Outputs>
-    </CustomBuild>
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters b/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters
deleted file mode 100644
index 1f8c6e1..0000000
--- a/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\include\ffi.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\include\ffi_cfi.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\include\ffi_common.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\include\fficonfig.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\include\ffitarget.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\include\internal.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="src\closures.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\dlmalloc.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\ffi.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\prep_cif.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\types.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <CustomBuild Include="src\win64_armasm.S" />
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/msvc_build/aarch64/Ffi_staticLib.vcxproj.user b/msvc_build/aarch64/Ffi_staticLib.vcxproj.user
deleted file mode 100644
index be25078..0000000
--- a/msvc_build/aarch64/Ffi_staticLib.vcxproj.user
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup />
-</Project>
\ No newline at end of file
diff --git a/msvc_build/aarch64/aarch64_include/ffi.h b/msvc_build/aarch64/aarch64_include/ffi.h
deleted file mode 100644
index 02f26a2..0000000
--- a/msvc_build/aarch64/aarch64_include/ffi.h
+++ /dev/null
@@ -1,511 +0,0 @@
-/* -----------------------------------------------------------------*-C-*-
-   libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green
-                    - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
-
-   Permission is hereby granted, free of charge, to any person
-   obtaining a copy of this software and associated documentation
-   files (the ``Software''), to deal in the Software without
-   restriction, including without limitation the rights to use, copy,
-   modify, merge, publish, distribute, sublicense, and/or sell copies
-   of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be
-   included in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-   DEALINGS IN THE SOFTWARE.
-
-   ----------------------------------------------------------------------- */
-
-/* -------------------------------------------------------------------
-   Most of the API is documented in doc/libffi.texi.
-
-   The raw API is designed to bypass some of the argument packing and
-   unpacking on architectures for which it can be avoided.  Routines
-   are provided to emulate the raw API if the underlying platform
-   doesn't allow faster implementation.
-
-   More details on the raw API can be found in:
-
-   http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
-
-   and
-
-   http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-   -------------------------------------------------------------------- */
-
-#ifndef LIBFFI_H
-#define LIBFFI_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Specify which architecture libffi is configured for. */
-#ifndef AARCH64
-#define AARCH64
-#endif
-
-/* ---- System configuration information --------------------------------- */
-
-#include <ffitarget.h>
-
-#ifndef LIBFFI_ASM
-
-#if defined(_MSC_VER) && !defined(__clang__)
-#define __attribute__(X)
-#endif
-
-#include <stddef.h>
-#include <limits.h>
-
-/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
-   But we can find it either under the correct ANSI name, or under GNU
-   C's internal name.  */
-
-#define FFI_64_BIT_MAX 9223372036854775807
-
-#ifdef LONG_LONG_MAX
-# define FFI_LONG_LONG_MAX LONG_LONG_MAX
-#else
-# ifdef LLONG_MAX
-#  define FFI_LONG_LONG_MAX LLONG_MAX
-#  ifdef _AIX52 /* or newer has C99 LLONG_MAX */
-#   undef FFI_64_BIT_MAX
-#   define FFI_64_BIT_MAX 9223372036854775807LL
-#  endif /* _AIX52 or newer */
-# else
-#  ifdef __GNUC__
-#   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
-#  endif
-#  ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
-#   ifndef __PPC64__
-#    if defined (__IBMC__) || defined (__IBMCPP__)
-#     define FFI_LONG_LONG_MAX LONGLONG_MAX
-#    endif
-#   endif /* __PPC64__ */
-#   undef  FFI_64_BIT_MAX
-#   define FFI_64_BIT_MAX 9223372036854775807LL
-#  endif
-# endif
-#endif
-
-/* The closure code assumes that this works on pointers, i.e. a size_t
-   can hold a pointer.  */
-
-typedef struct _ffi_type
-{
-  size_t size;
-  unsigned short alignment;
-  unsigned short type;
-  struct _ffi_type **elements;
-} ffi_type;
-
-/* Need minimal decorations for DLLs to work on Windows.  GCC has
-   autoimport and autoexport.  Always mark externally visible symbols
-   as dllimport for MSVC clients, even if it means an extra indirection
-   when using the static version of the library.
-   Besides, as a workaround, they can define FFI_BUILDING if they
-   *know* they are going to link with the static library.  */
-#if defined _MSC_VER
-# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
-#  define FFI_API __declspec(dllexport)
-# elif !defined FFI_BUILDING  /* Importing libffi.DLL */
-#  define FFI_API __declspec(dllimport)
-# else                        /* Building/linking static library */
-#  define FFI_API
-# endif
-#else
-# define FFI_API
-#endif
-
-/* The externally visible type declarations also need the MSVC DLL
-   decorations, or they will not be exported from the object file.  */
-#if defined LIBFFI_HIDE_BASIC_TYPES
-# define FFI_EXTERN FFI_API
-#else
-# define FFI_EXTERN extern FFI_API
-#endif
-
-#ifndef LIBFFI_HIDE_BASIC_TYPES
-#if SCHAR_MAX == 127
-# define ffi_type_uchar                ffi_type_uint8
-# define ffi_type_schar                ffi_type_sint8
-#else
- #error "char size not supported"
-#endif
-
-#if SHRT_MAX == 32767
-# define ffi_type_ushort       ffi_type_uint16
-# define ffi_type_sshort       ffi_type_sint16
-#elif SHRT_MAX == 2147483647
-# define ffi_type_ushort       ffi_type_uint32
-# define ffi_type_sshort       ffi_type_sint32
-#else
- #error "short size not supported"
-#endif
-
-#if INT_MAX == 32767
-# define ffi_type_uint         ffi_type_uint16
-# define ffi_type_sint         ffi_type_sint16
-#elif INT_MAX == 2147483647
-# define ffi_type_uint         ffi_type_uint32
-# define ffi_type_sint         ffi_type_sint32
-#elif INT_MAX == 9223372036854775807
-# define ffi_type_uint         ffi_type_uint64
-# define ffi_type_sint         ffi_type_sint64
-#else
- #error "int size not supported"
-#endif
-
-#if LONG_MAX == 2147483647
-# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
- #error "no 64-bit data type supported"
-# endif
-#elif LONG_MAX != FFI_64_BIT_MAX
- #error "long size not supported"
-#endif
-
-#if LONG_MAX == 2147483647
-# define ffi_type_ulong        ffi_type_uint32
-# define ffi_type_slong        ffi_type_sint32
-#elif LONG_MAX == FFI_64_BIT_MAX
-# define ffi_type_ulong        ffi_type_uint64
-# define ffi_type_slong        ffi_type_sint64
-#else
- #error "long size not supported"
-#endif
-
-/* These are defined in types.c.  */
-FFI_EXTERN ffi_type ffi_type_void;
-FFI_EXTERN ffi_type ffi_type_uint8;
-FFI_EXTERN ffi_type ffi_type_sint8;
-FFI_EXTERN ffi_type ffi_type_uint16;
-FFI_EXTERN ffi_type ffi_type_sint16;
-FFI_EXTERN ffi_type ffi_type_uint32;
-FFI_EXTERN ffi_type ffi_type_sint32;
-FFI_EXTERN ffi_type ffi_type_uint64;
-FFI_EXTERN ffi_type ffi_type_sint64;
-FFI_EXTERN ffi_type ffi_type_float;
-FFI_EXTERN ffi_type ffi_type_double;
-FFI_EXTERN ffi_type ffi_type_pointer;
-
-#ifndef _M_ARM64
-FFI_EXTERN ffi_type ffi_type_longdouble;
-#else
-#define ffi_type_longdouble ffi_type_double
-#endif
-
-#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
-FFI_EXTERN ffi_type ffi_type_complex_float;
-FFI_EXTERN ffi_type ffi_type_complex_double;
-#if 1
-FFI_EXTERN ffi_type ffi_type_complex_longdouble;
-#else
-#define ffi_type_complex_longdouble ffi_type_complex_double
-#endif
-#endif
-#endif /* LIBFFI_HIDE_BASIC_TYPES */
-
-typedef enum {
-  FFI_OK = 0,
-  FFI_BAD_TYPEDEF,
-  FFI_BAD_ABI
-} ffi_status;
-
-typedef struct {
-  ffi_abi abi;
-  unsigned nargs;
-  ffi_type **arg_types;
-  ffi_type *rtype;
-  unsigned bytes;
-  unsigned flags;
-#ifdef FFI_EXTRA_CIF_FIELDS
-  FFI_EXTRA_CIF_FIELDS;
-#endif
-} ffi_cif;
-
-/* ---- Definitions for the raw API -------------------------------------- */
-
-#ifndef FFI_SIZEOF_ARG
-# if LONG_MAX == 2147483647
-#  define FFI_SIZEOF_ARG        4
-# elif LONG_MAX == FFI_64_BIT_MAX
-#  define FFI_SIZEOF_ARG        8
-# endif
-#endif
-
-#ifndef FFI_SIZEOF_JAVA_RAW
-#  define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
-#endif
-
-typedef union {
-  ffi_sarg  sint;
-  ffi_arg   uint;
-  float	    flt;
-  char      data[FFI_SIZEOF_ARG];
-  void*     ptr;
-} ffi_raw;
-
-#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
-/* This is a special case for mips64/n32 ABI (and perhaps others) where
-   sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8.  */
-typedef union {
-  signed int	sint;
-  unsigned int	uint;
-  float		flt;
-  char		data[FFI_SIZEOF_JAVA_RAW];
-  void*		ptr;
-} ffi_java_raw;
-#else
-typedef ffi_raw ffi_java_raw;
-#endif
-
-
-FFI_API 
-void ffi_raw_call (ffi_cif *cif,
-		   void (*fn)(void),
-		   void *rvalue,
-		   ffi_raw *avalue);
-
-FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
-FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
-FFI_API size_t ffi_raw_size (ffi_cif *cif);
-
-/* This is analogous to the raw API, except it uses Java parameter
-   packing, even on 64-bit machines.  I.e. on 64-bit machines longs
-   and doubles are followed by an empty 64-bit word.  */
-
-FFI_API
-void ffi_java_raw_call (ffi_cif *cif,
-			void (*fn)(void),
-			void *rvalue,
-			ffi_java_raw *avalue);
-
-FFI_API
-void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
-FFI_API
-void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
-FFI_API
-size_t ffi_java_raw_size (ffi_cif *cif);
-
-/* ---- Definitions for closures ----------------------------------------- */
-
-#if FFI_CLOSURES
-
-#ifdef _MSC_VER
-__declspec(align(8))
-#endif
-typedef struct {
-#if 0
-  void *trampoline_table;
-  void *trampoline_table_entry;
-#else
-  char tramp[FFI_TRAMPOLINE_SIZE];
-#endif
-  ffi_cif   *cif;
-  void     (*fun)(ffi_cif*,void*,void**,void*);
-  void      *user_data;
-} ffi_closure
-#ifdef __GNUC__
-    __attribute__((aligned (8)))
-#endif
-    ;
-
-#ifndef __GNUC__
-# ifdef __sgi
-#  pragma pack 0
-# endif
-#endif
-
-FFI_API void *ffi_closure_alloc (size_t size, void **code);
-FFI_API void ffi_closure_free (void *);
-
-FFI_API ffi_status
-ffi_prep_closure (ffi_closure*,
-		  ffi_cif *,
-		  void (*fun)(ffi_cif*,void*,void**,void*),
-		  void *user_data)
-#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
-  __attribute__((deprecated ("use ffi_prep_closure_loc instead")))
-#elif defined(__GNUC__) && __GNUC__ >= 3
-  __attribute__((deprecated))
-#endif
-  ;
-
-FFI_API ffi_status
-ffi_prep_closure_loc (ffi_closure*,
-		      ffi_cif *,
-		      void (*fun)(ffi_cif*,void*,void**,void*),
-		      void *user_data,
-		      void*codeloc);
-
-#ifdef __sgi
-# pragma pack 8
-#endif
-typedef struct {
-#if 0
-  void *trampoline_table;
-  void *trampoline_table_entry;
-#else
-  char tramp[FFI_TRAMPOLINE_SIZE];
-#endif
-  ffi_cif   *cif;
-
-#if !FFI_NATIVE_RAW_API
-
-  /* If this is enabled, then a raw closure has the same layout 
-     as a regular closure.  We use this to install an intermediate 
-     handler to do the transaltion, void** -> ffi_raw*.  */
-
-  void     (*translate_args)(ffi_cif*,void*,void**,void*);
-  void      *this_closure;
-
-#endif
-
-  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
-  void      *user_data;
-
-} ffi_raw_closure;
-
-typedef struct {
-#if 0
-  void *trampoline_table;
-  void *trampoline_table_entry;
-#else
-  char tramp[FFI_TRAMPOLINE_SIZE];
-#endif
-
-  ffi_cif   *cif;
-
-#if !FFI_NATIVE_RAW_API
-
-  /* If this is enabled, then a raw closure has the same layout 
-     as a regular closure.  We use this to install an intermediate 
-     handler to do the translation, void** -> ffi_raw*.  */
-
-  void     (*translate_args)(ffi_cif*,void*,void**,void*);
-  void      *this_closure;
-
-#endif
-
-  void     (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
-  void      *user_data;
-
-} ffi_java_raw_closure;
-
-FFI_API ffi_status
-ffi_prep_raw_closure (ffi_raw_closure*,
-		      ffi_cif *cif,
-		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
-		      void *user_data);
-
-FFI_API ffi_status
-ffi_prep_raw_closure_loc (ffi_raw_closure*,
-			  ffi_cif *cif,
-			  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
-			  void *user_data,
-			  void *codeloc);
-
-FFI_API ffi_status
-ffi_prep_java_raw_closure (ffi_java_raw_closure*,
-		           ffi_cif *cif,
-		           void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
-		           void *user_data);
-
-FFI_API ffi_status
-ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
-			       ffi_cif *cif,
-			       void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
-			       void *user_data,
-			       void *codeloc);
-
-#endif /* FFI_CLOSURES */
-
-#if FFI_GO_CLOSURES
-
-typedef struct {
-  void      *tramp;
-  ffi_cif   *cif;
-  void     (*fun)(ffi_cif*,void*,void**,void*);
-} ffi_go_closure;
-
-FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
-				void (*fun)(ffi_cif*,void*,void**,void*));
-
-FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
-		  void **avalue, void *closure);
-
-#endif /* FFI_GO_CLOSURES */
-
-/* ---- Public interface definition -------------------------------------- */
-
-FFI_API 
-ffi_status ffi_prep_cif(ffi_cif *cif,
-			ffi_abi abi,
-			unsigned int nargs,
-			ffi_type *rtype,
-			ffi_type **atypes);
-
-FFI_API
-ffi_status ffi_prep_cif_var(ffi_cif *cif,
-			    ffi_abi abi,
-			    unsigned int nfixedargs,
-			    unsigned int ntotalargs,
-			    ffi_type *rtype,
-			    ffi_type **atypes);
-
-FFI_API
-void ffi_call(ffi_cif *cif,
-	      void (*fn)(void),
-	      void *rvalue,
-	      void **avalue);
-
-FFI_API
-ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
-				   size_t *offsets);
-
-/* Useful for eliminating compiler warnings.  */
-#define FFI_FN(f) ((void (*)(void))f)
-
-/* ---- Definitions shared with assembly code ---------------------------- */
-
-#endif
-
-/* If these change, update src/mips/ffitarget.h. */
-#define FFI_TYPE_VOID       0    
-#define FFI_TYPE_INT        1
-#define FFI_TYPE_FLOAT      2    
-#define FFI_TYPE_DOUBLE     3
-#ifndef _M_ARM64
-#define FFI_TYPE_LONGDOUBLE 4
-#else
-#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
-#endif
-#define FFI_TYPE_UINT8      5   
-#define FFI_TYPE_SINT8      6
-#define FFI_TYPE_UINT16     7 
-#define FFI_TYPE_SINT16     8
-#define FFI_TYPE_UINT32     9
-#define FFI_TYPE_SINT32     10
-#define FFI_TYPE_UINT64     11
-#define FFI_TYPE_SINT64     12
-#define FFI_TYPE_STRUCT     13
-#define FFI_TYPE_POINTER    14
-#define FFI_TYPE_COMPLEX    15
-/* This should always refer to the last type code (for sanity checks).  */
-#define FFI_TYPE_LAST   FFI_TYPE_COMPLEX
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/msvc_build/aarch64/aarch64_include/fficonfig.h b/msvc_build/aarch64/aarch64_include/fficonfig.h
deleted file mode 100644
index b3d89b0..0000000
--- a/msvc_build/aarch64/aarch64_include/fficonfig.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/* fficonfig.h.  Generated from fficonfig.h.in by configure.  */
-/* fficonfig.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define if building universal (internal helper macro) */
-/* #undef AC_APPLE_UNIVERSAL_BUILD */
-
-/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
-   systems. This function is required for `alloca.c' support on those systems.
-   */
-/* #undef CRAY_STACKSEG_END */
-
-/* Define to 1 if using `alloca.c'. */
-/* #undef C_ALLOCA */
-
-/* Define to the flags needed for the .section .eh_frame directive. */
-#define EH_FRAME_FLAGS "a"
-
-/* Define this if you want extra debugging. */
-/* #undef FFI_DEBUG */
-
-/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
-/* #undef FFI_EXEC_TRAMPOLINE_TABLE */
-
-/* Define this if you want to enable pax emulated trampolines */
-/* #undef FFI_MMAP_EXEC_EMUTRAMP_PAX */
-
-/* Cannot use malloc on this target, so, we revert to alternative means */
-/* #undef FFI_MMAP_EXEC_WRIT */
-
-/* Define this if you do not want support for the raw API. */
-/* #undef FFI_NO_RAW_API */
-
-/* Define this if you do not want support for aggregate types. */
-/* #undef FFI_NO_STRUCTS */
-
-/* Define to 1 if you have `alloca', as a function or macro. */
-#define HAVE_ALLOCA 1
-
-/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
-   */
-/*#define HAVE_ALLOCA_H 1 */
-
-/* Define if your assembler supports .cfi_* directives. */
-#define HAVE_AS_CFI_PSEUDO_OP 1
-
-/* Define if your assembler supports .register. */
-/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
-
-/* Define if the compiler uses zarch features. */
-/* #undef HAVE_AS_S390_ZARCH */
-
-/* Define if your assembler and linker support unaligned PC relative relocs.
-   */
-/* #undef HAVE_AS_SPARC_UA_PCREL */
-
-/* Define if your assembler supports unwind section type. */
-/* #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE */
-
-/* Define if your assembler supports PC relative relocs. */
-/* #undef HAVE_AS_X86_PCREL */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define if __attribute__((visibility("hidden"))) is supported. */
-#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define if you have the long double type and it is bigger than a double */
-#define HAVE_LONG_DOUBLE 1
-
-/* Define if you support more than one size of the long double type */
-/* #undef HAVE_LONG_DOUBLE_VARIANT */
-
-/* Define to 1 if you have the `memcpy' function. */
-#define HAVE_MEMCPY 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `mkostemp' function. */
-#define HAVE_MKOSTEMP 1
-
-/* Define to 1 if you have the `mmap' function. */
-#define HAVE_MMAP 1
-
-/* Define if mmap with MAP_ANON(YMOUS) works. */
-#define HAVE_MMAP_ANON 1
-
-/* Define if mmap of /dev/zero works. */
-#define HAVE_MMAP_DEV_ZERO 1
-
-/* Define if read-only mmap of a plain file works. */
-#define HAVE_MMAP_FILE 1
-
-/* Define if .eh_frame sections should be read-only. */
-#define HAVE_RO_EH_FRAME 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-//#define HAVE_STDLIB_H 0
-#define LACKS_STDLIB_H 1
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/mman.h> header file. */
-#define HAVE_SYS_MMAN_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if GNU symbol versioning is used for libatomic. */
-#define LIBFFI_GNU_SYMBOL_VERSIONING 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
-#define LT_OBJDIR ".libs/"
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-/* #undef NO_MINUS_C_MINUS_O */
-
-/* Name of package */
-#define PACKAGE "libffi"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "libffi"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libffi 3.3-rc0"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "libffi"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "3.3-rc0"
-
-/* The size of `double', as computed by sizeof. */
-#define SIZEOF_DOUBLE 8
-
-/* The size of `long double', as computed by sizeof. */
-#define SIZEOF_LONG_DOUBLE 8
-
-/* The size of `size_t', as computed by sizeof. */
-#define SIZEOF_SIZE_T 8
-
-/* If using the C implementation of alloca, define if you know the
-   direction of stack growth for your system; otherwise it will be
-   automatically deduced at runtime.
-	STACK_DIRECTION > 0 => grows toward higher addresses
-	STACK_DIRECTION < 0 => grows toward lower addresses
-	STACK_DIRECTION = 0 => direction of growth unknown */
-/* #undef STACK_DIRECTION */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define if symbols are underscored. */
-/* #undef SYMBOL_UNDERSCORE */
-
-/* Define this if you are using Purify and want to suppress spurious messages.
-   */
-/* #undef USING_PURIFY */
-
-/* Version number of package */
-#define VERSION "3.3-rc0"
-
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
-   significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-#  define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-/* #  undef WORDS_BIGENDIAN */
-# endif
-#endif
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-
-#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
-#ifdef LIBFFI_ASM
-#ifdef __APPLE__
-#define FFI_HIDDEN(name) .private_extern name
-#else
-#define FFI_HIDDEN(name) .hidden name
-#endif
-#else
-#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
-#endif
-#else
-#ifdef LIBFFI_ASM
-#define FFI_HIDDEN(name)
-#else
-#define FFI_HIDDEN
-#endif
-#endif
-
diff --git a/msvcc.sh b/msvcc.sh
index 97facd6..65fbfef 100755
--- a/msvcc.sh
+++ b/msvcc.sh
@@ -44,29 +44,17 @@
 
 args_orig=$@
 args="-nologo -W3"
-linkargs=
 static_crt=
 debug_crt=
 cl="cl"
 ml="ml"
 safeseh="-safeseh"
 output=
-libpaths=
-libversion=7
-verbose=
 
 while [ $# -gt 0 ]
 do
   case $1
   in
-    --verbose)
-      verbose=1
-      shift 1
-    ;;
-    --version)
-      args="-help"
-      shift 1
-    ;;
     -fexceptions)
       # Don't enable exceptions for now.
       #args="$args -EHac"
@@ -80,18 +68,9 @@
       safeseh=
       shift 1
     ;;
-    -marm)
-      ml='armasm'
-      safeseh=
-      shift 1
-    ;;
-    -marm64)
-      ml='armasm64'
-      safeseh=
-      shift 1
-    ;;
     -clang-cl)
       cl="clang-cl"
+      safeseh=
       shift 1
     ;;
     -O0)
@@ -165,44 +144,13 @@
       shift 1
     ;;
     -I)
-      p=$(cygpath -m $2)
-      args="$args -I$p"
-      includes="$includes -I$p"
+      args="$args -I$2"
+      includes="$includes -I$2"
       shift 2
     ;;
     -I*)
-      p=$(cygpath -m ${1#-I})
-      args="$args -I$p"
-      includes="$includes -I$p"
-      shift 1
-    ;;
-    -L)
-      p=$(cygpath -m $2)
-      linkargs="$linkargs -LIBPATH:$p"
-      shift 2
-    ;;
-    -L*)
-      p=$(cygpath -m ${1#-L})
-      linkargs="$linkargs -LIBPATH:$p"
-      shift 1
-    ;;
-    -link)
-      # add next argument verbatim to linker args
-      linkargs="$linkargs $2"
-      shift 2
-      ;;
-    -l*)
-      case $1
-      in
-        -lffi)
-          linkargs="$linkargs lib${1#-l}-${libversion}.lib"
-          ;;
-        *)
-          # ignore other libraries like -lm, hope they are
-          # covered by MSVCRT
-          # linkargs="$linkargs ${1#-l}.lib"
-          ;;
-      esac
+      args="$args $1"
+      includes="$includes $1"
       shift 1
     ;;
     -W|-Wextra)
@@ -218,15 +166,6 @@
       # libffi tests -pedantic with -Wall, so drop it also.
       shift 1
     ;;
-    -warn)
-      # ignore -warn all from libtool as well.
-      if test "$2" = "all"; then
-        shift 2
-      else
-        args="$args -warn"
-        shift 1
-      fi
-    ;;
     -Werror)
       args="$args -WX"
       shift 1
@@ -247,7 +186,6 @@
       else
         output="-Fe$2"
       fi
-      armasm_output="-o $2"
       if [ -n "$assembly" ]; then
         args="$args $output"
       else
@@ -272,16 +210,11 @@
   esac
 done
 
-if [ -n "$linkargs" ]; then
-
-    # If -Zi is specified, certain optimizations are implicitly disabled
-    # by MSVC. Add back those optimizations if this is an optimized build.
-    # NOTE: These arguments must come after all others.
-    if [ -n "$opt" ]; then
-	linkargs="$linkargs -OPT:REF -OPT:ICF -INCREMENTAL:NO"
-    fi
-
-    args="$args -link $linkargs"
+# If -Zi is specified, certain optimizations are implicitly disabled
+# by MSVC. Add back those optimizations if this is an optimized build.
+# NOTE: These arguments must come after all others.
+if [ -n "$opt" ]; then
+    args="$args -link -OPT:REF -OPT:ICF -INCREMENTAL:NO"
 fi
 
 if [ -n "$static_crt" ]; then
@@ -299,33 +232,12 @@
       outdir="."
     fi
     ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
-
-    if [ $ml = "armasm" ]; then
-      defines="$defines -D_M_ARM"
-    fi
-
-    if [ $ml = "armasm64" ]; then
-      defines="$defines -D_M_ARM64"
-    fi
-
-    if test -n "$verbose"; then
-      echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
-    fi
-
+    echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
     "$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
     output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
-    if [ $ml = "armasm" ]; then
-      args="-nologo -g -oldit $armasm_output $ppsrc -errorReport:prompt"
-    elif [ $ml = "armasm64" ]; then
-      args="-nologo -g $armasm_output $ppsrc -errorReport:prompt"
-    else
-      args="-nologo $safeseh $single $output $ppsrc"
-    fi
+    args="-nologo $safeseh $single $output $ppsrc"
 
-    if test -n "$verbose"; then
-      echo "$ml $args"
-    fi
-
+    echo "$ml $args"
     eval "\"$ml\" $args"
     result=$?
 
@@ -333,21 +245,13 @@
     #mv *.obj $outdir
 else
     args="$md $args"
-
-    if test -n "$verbose"; then
-      echo "$cl $args"
-    fi
+    echo "$cl $args"
     # Return an error code of 1 if an invalid command line parameter is passed
-    # instead of just ignoring it. Any output that is not a warning or an
-    # error is filtered so this command behaves more like gcc. cl.exe prints
-    # the name of the compiled file otherwise, which breaks the dejagnu checks
-    # for excess warnings and errors.
+    # instead of just ignoring it.
     eval "(\"$cl\" $args 2>&1 1>&3 | \
-          awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1 | \
-          awk '/warning|error/'"
+          awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1"
     result=$?
 fi
 
 exit $result
 
-# vim: noai:ts=4:sw=4
diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c
index 1ebf43c..cdb7816 100644
--- a/src/aarch64/ffi.c
+++ b/src/aarch64/ffi.c
@@ -19,28 +19,24 @@
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 
-#if defined(__aarch64__) || defined(__arm64__)|| defined (_M_ARM64)
 #include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <fficonfig.h>
+
 #include <ffi.h>
 #include <ffi_common.h>
-#include "internal.h"
-#ifdef _M_ARM64
-#include <windows.h> /* FlushInstructionCache */
+
+#include <stdlib.h>
+
+/* Stack alignment requirement in bytes */
+#if defined (__APPLE__)
+#define AARCH64_STACK_ALIGN 1
+#else
+#define AARCH64_STACK_ALIGN 16
 #endif
 
-/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
-   all further uses in this file will refer to the 128-bit type.  */
-#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
-# if FFI_TYPE_LONGDOUBLE != 4
-#  error FFI_TYPE_LONGDOUBLE out of date
-# endif
-#else
-# undef FFI_TYPE_LONGDOUBLE
-# define FFI_TYPE_LONGDOUBLE 4
-#endif
+#define N_X_ARG_REG 8
+#define N_V_ARG_REG 8
+
+#define AARCH64_FFI_WITH_V (1 << AARCH64_FFI_WITH_V_BIT)
 
 union _d
 {
@@ -48,196 +44,360 @@
   UINT32 s[2];
 };
 
-struct _v
-{
-  union _d d[2] __attribute__((aligned(16)));
-};
-
 struct call_context
 {
-  struct _v v[N_V_ARG_REG];
-  UINT64 x[N_X_ARG_REG];
+  UINT64 x [AARCH64_N_XREG];
+  struct
+  {
+    union _d d[2];
+  } v [AARCH64_N_VREG];
 };
 
-#if FFI_EXEC_TRAMPOLINE_TABLE
-
-#ifdef __MACH__
-#include <mach/vm_param.h>
-#endif
-
-#else
-
 #if defined (__clang__) && defined (__APPLE__)
-extern void sys_icache_invalidate (void *start, size_t len);
+extern void
+sys_icache_invalidate (void *start, size_t len);
 #endif
 
 static inline void
 ffi_clear_cache (void *start, void *end)
 {
 #if defined (__clang__) && defined (__APPLE__)
-  sys_icache_invalidate (start, (char *)end - (char *)start);
+	sys_icache_invalidate (start, (char *)end - (char *)start);
 #elif defined (__GNUC__)
-  __builtin___clear_cache (start, end);
-#elif defined (_M_ARM64)
-  FlushInstructionCache(GetCurrentProcess(), start, (char*)end - (char*)start);
+	__builtin___clear_cache (start, end);
 #else
 #error "Missing builtin to flush instruction cache"
 #endif
 }
 
+static void *
+get_x_addr (struct call_context *context, unsigned n)
+{
+  return &context->x[n];
+}
+
+static void *
+get_s_addr (struct call_context *context, unsigned n)
+{
+#if defined __AARCH64EB__
+  return &context->v[n].d[1].s[1];
+#else
+  return &context->v[n].d[0].s[0];
 #endif
-
-/* A subroutine of is_vfp_type.  Given a structure type, return the type code
-   of the first non-structure element.  Recurse for structure elements.
-   Return -1 if the structure is in fact empty, i.e. no nested elements.  */
-
-static int
-is_hfa0 (const ffi_type *ty)
-{
-  ffi_type **elements = ty->elements;
-  int i, ret = -1;
-
-  if (elements != NULL)
-    for (i = 0; elements[i]; ++i)
-      {
-        ret = elements[i]->type;
-        if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX)
-          {
-            ret = is_hfa0 (elements[i]);
-            if (ret < 0)
-              continue;
-          }
-        break;
-      }
-
-  return ret;
 }
 
-/* A subroutine of is_vfp_type.  Given a structure type, return true if all
-   of the non-structure elements are the same as CANDIDATE.  */
-
-static int
-is_hfa1 (const ffi_type *ty, int candidate)
+static void *
+get_d_addr (struct call_context *context, unsigned n)
 {
-  ffi_type **elements = ty->elements;
-  int i;
-
-  if (elements != NULL)
-    for (i = 0; elements[i]; ++i)
-      {
-        int t = elements[i]->type;
-        if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
-          {
-            if (!is_hfa1 (elements[i], candidate))
-              return 0;
-          }
-        else if (t != candidate)
-          return 0;
-      }
-
-  return 1;
+#if defined __AARCH64EB__
+  return &context->v[n].d[1];
+#else
+  return &context->v[n].d[0];
+#endif
 }
 
-/* Determine if TY may be allocated to the FP registers.  This is both an
-   fp scalar type as well as an homogenous floating point aggregate (HFA).
-   That is, a structure consisting of 1 to 4 members of all the same type,
-   where that type is an fp scalar.
-
-   Returns non-zero iff TY is an HFA.  The result is the AARCH64_RET_*
-   constant for the type.  */
-
-static int
-is_vfp_type (const ffi_type *ty)
+static void *
+get_v_addr (struct call_context *context, unsigned n)
 {
-  ffi_type **elements;
-  int candidate, i;
-  size_t size, ele_count;
+  return &context->v[n];
+}
 
-  /* Quickest tests first.  */
-  candidate = ty->type;
-  switch (candidate)
+/* Return the memory location at which a basic type would reside
+   were it to have been stored in register n.  */
+
+static void *
+get_basic_type_addr (unsigned short type, struct call_context *context,
+		     unsigned n)
+{
+  switch (type)
     {
-    default:
-      return 0;
     case FFI_TYPE_FLOAT:
+      return get_s_addr (context, n);
     case FFI_TYPE_DOUBLE:
+      return get_d_addr (context, n);
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
     case FFI_TYPE_LONGDOUBLE:
-      ele_count = 1;
-      goto done;
-    case FFI_TYPE_COMPLEX:
-      candidate = ty->elements[0]->type;
-      switch (candidate)
+      return get_v_addr (context, n);
+#endif
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_INT:
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      return get_x_addr (context, n);
+    case FFI_TYPE_VOID:
+      return NULL;
+    default:
+      FFI_ASSERT (0);
+      return NULL;
+    }
+}
+
+/* Return the alignment width for each of the basic types.  */
+
+static size_t
+get_basic_type_alignment (unsigned short type)
+{
+  switch (type)
+    {
+    case FFI_TYPE_FLOAT:
+#if defined (__APPLE__)
+      return sizeof (UINT32);
+#endif
+    case FFI_TYPE_DOUBLE:
+      return sizeof (UINT64);
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+      return sizeof (long double);
+#endif
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT8:
+#if defined (__APPLE__)
+	  return sizeof (UINT8);
+#endif
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_SINT16:
+#if defined (__APPLE__)
+	  return sizeof (UINT16);
+#endif
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_INT:
+    case FFI_TYPE_SINT32:
+#if defined (__APPLE__)
+	  return sizeof (UINT32);
+#endif
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      return sizeof (UINT64);
+
+    default:
+      FFI_ASSERT (0);
+      return 0;
+    }
+}
+
+/* Return the size in bytes for each of the basic types.  */
+
+static size_t
+get_basic_type_size (unsigned short type)
+{
+  switch (type)
+    {
+    case FFI_TYPE_FLOAT:
+      return sizeof (UINT32);
+    case FFI_TYPE_DOUBLE:
+      return sizeof (UINT64);
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+      return sizeof (long double);
+#endif
+    case FFI_TYPE_UINT8:
+      return sizeof (UINT8);
+    case FFI_TYPE_SINT8:
+      return sizeof (SINT8);
+    case FFI_TYPE_UINT16:
+      return sizeof (UINT16);
+    case FFI_TYPE_SINT16:
+      return sizeof (SINT16);
+    case FFI_TYPE_UINT32:
+      return sizeof (UINT32);
+    case FFI_TYPE_INT:
+    case FFI_TYPE_SINT32:
+      return sizeof (SINT32);
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_UINT64:
+      return sizeof (UINT64);
+    case FFI_TYPE_SINT64:
+      return sizeof (SINT64);
+
+    default:
+      FFI_ASSERT (0);
+      return 0;
+    }
+}
+
+extern void
+ffi_call_SYSV (unsigned (*)(struct call_context *context, unsigned char *,
+			    extended_cif *),
+               struct call_context *context,
+               extended_cif *,
+               size_t,
+               void (*fn)(void));
+
+extern void
+ffi_closure_SYSV (ffi_closure *);
+
+/* Test for an FFI floating point representation.  */
+
+static unsigned
+is_floating_type (unsigned short type)
+{
+  return (type == FFI_TYPE_FLOAT || type == FFI_TYPE_DOUBLE
+	  || type == FFI_TYPE_LONGDOUBLE);
+}
+
+/* Test for a homogeneous structure.  */
+
+static unsigned short
+get_homogeneous_type (ffi_type *ty)
+{
+  if (ty->type == FFI_TYPE_STRUCT && ty->elements)
+    {
+      unsigned i;
+      unsigned short candidate_type
+	= get_homogeneous_type (ty->elements[0]);
+      for (i =1; ty->elements[i]; i++)
 	{
-	case FFI_TYPE_FLOAT:
-	case FFI_TYPE_DOUBLE:
-	case FFI_TYPE_LONGDOUBLE:
-	  ele_count = 2;
-	  goto done;
+	  unsigned short iteration_type = 0;
+	  /* If we have a nested struct, we must find its homogeneous type.
+	     If that fits with our candidate type, we are still
+	     homogeneous.  */
+	  if (ty->elements[i]->type == FFI_TYPE_STRUCT
+	      && ty->elements[i]->elements)
+	    {
+	      iteration_type = get_homogeneous_type (ty->elements[i]);
+	    }
+	  else
+	    {
+	      iteration_type = ty->elements[i]->type;
+	    }
+
+	  /* If we are not homogeneous, return FFI_TYPE_STRUCT.  */
+	  if (candidate_type != iteration_type)
+	    return FFI_TYPE_STRUCT;
 	}
-      return 0;
-    case FFI_TYPE_STRUCT:
-      break;
+      return candidate_type;
     }
 
-  /* No HFA types are smaller than 4 bytes, or larger than 64 bytes.  */
-  size = ty->size;
-  if (size < 4 || size > 64)
-    return 0;
+  /* Base case, we have no more levels of nesting, so we
+     are a basic type, and so, trivially homogeneous in that type.  */
+  return ty->type;
+}
 
-  /* Find the type of the first non-structure member.  */
-  elements = ty->elements;
-  candidate = elements[0]->type;
-  if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX)
+/* Determine the number of elements within a STRUCT.
+
+   Note, we must handle nested structs.
+
+   If ty is not a STRUCT this function will return 0.  */
+
+static unsigned
+element_count (ffi_type *ty)
+{
+  if (ty->type == FFI_TYPE_STRUCT && ty->elements)
     {
-      for (i = 0; ; ++i)
-        {
-          candidate = is_hfa0 (elements[i]);
-          if (candidate >= 0)
-            break;
-        }
+      unsigned n;
+      unsigned elems = 0;
+      for (n = 0; ty->elements[n]; n++)
+	{
+	  if (ty->elements[n]->type == FFI_TYPE_STRUCT
+	      && ty->elements[n]->elements)
+	    elems += element_count (ty->elements[n]);
+	  else
+	    elems++;
+	}
+      return elems;
     }
+  return 0;
+}
 
-  /* If the first member is not a floating point type, it's not an HFA.
-     Also quickly re-check the size of the structure.  */
-  switch (candidate)
+/* Test for a homogeneous floating point aggregate.
+
+   A homogeneous floating point aggregate is a homogeneous aggregate of
+   a half- single- or double- precision floating point type with one
+   to four elements.  Note that this includes nested structs of the
+   basic type.  */
+
+static int
+is_hfa (ffi_type *ty)
+{
+  if (ty->type == FFI_TYPE_STRUCT
+      && ty->elements[0]
+      && is_floating_type (get_homogeneous_type (ty)))
     {
+      unsigned n = element_count (ty);
+      return n >= 1 && n <= 4;
+    }
+  return 0;
+}
+
+/* Test if an ffi_type is a candidate for passing in a register.
+
+   This test does not check that sufficient registers of the
+   appropriate class are actually available, merely that IFF
+   sufficient registers are available then the argument will be passed
+   in register(s).
+
+   Note that an ffi_type that is deemed to be a register candidate
+   will always be returned in registers.
+
+   Returns 1 if a register candidate else 0.  */
+
+static int
+is_register_candidate (ffi_type *ty)
+{
+  switch (ty->type)
+    {
+    case FFI_TYPE_VOID:
     case FFI_TYPE_FLOAT:
-      ele_count = size / sizeof(float);
-      if (size != ele_count * sizeof(float))
-        return 0;
-      break;
     case FFI_TYPE_DOUBLE:
-      ele_count = size / sizeof(double);
-      if (size != ele_count * sizeof(double))
-        return 0;
-      break;
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
     case FFI_TYPE_LONGDOUBLE:
-      ele_count = size / sizeof(long double);
-      if (size != ele_count * sizeof(long double))
-        return 0;
-      break;
-    default:
-      return 0;
-    }
-  if (ele_count > 4)
-    return 0;
+#endif
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_INT:
+    case FFI_TYPE_SINT64:
+      return 1;
 
-  /* Finally, make sure that all scalar elements are the same type.  */
-  for (i = 0; elements[i]; ++i)
-    {
-      int t = elements[i]->type;
-      if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
+    case FFI_TYPE_STRUCT:
+      if (is_hfa (ty))
         {
-          if (!is_hfa1 (elements[i], candidate))
-            return 0;
+          return 1;
         }
-      else if (t != candidate)
-        return 0;
+      else if (ty->size > 16)
+        {
+          /* Too large. Will be replaced with a pointer to memory. The
+             pointer MAY be passed in a register, but the value will
+             not. This test specifically fails since the argument will
+             never be passed by value in registers. */
+          return 0;
+        }
+      else
+        {
+          /* Might be passed in registers depending on the number of
+             registers required. */
+          return (ty->size + 7) / 8 < N_X_ARG_REG;
+        }
+      break;
+
+    default:
+      FFI_ASSERT (0);
+      break;
     }
 
-  /* All tests succeeded.  Encode the result.  */
- done:
-  return candidate * 4 + (4 - (int)ele_count);
+  return 0;
+}
+
+/* Test if an ffi_type argument or result is a candidate for a vector
+   register.  */
+
+static int
+is_v_register_candidate (ffi_type *ty)
+{
+  return is_floating_type (ty->type)
+	   || (ty->type == FFI_TYPE_STRUCT && is_hfa (ty));
 }
 
 /* Representation of the procedure call argument marshalling
@@ -259,291 +419,369 @@
 
 /* Initialize a procedure call argument marshalling state.  */
 static void
-arg_init (struct arg_state *state)
+arg_init (struct arg_state *state, size_t call_frame_size)
 {
   state->ngrn = 0;
   state->nsrn = 0;
   state->nsaa = 0;
+
 #if defined (__APPLE__)
   state->allocating_variadic = 0;
 #endif
 }
 
+/* Return the number of available consecutive core argument
+   registers.  */
+
+static unsigned
+available_x (struct arg_state *state)
+{
+  return N_X_ARG_REG - state->ngrn;
+}
+
+/* Return the number of available consecutive vector argument
+   registers.  */
+
+static unsigned
+available_v (struct arg_state *state)
+{
+  return N_V_ARG_REG - state->nsrn;
+}
+
+static void *
+allocate_to_x (struct call_context *context, struct arg_state *state)
+{
+  FFI_ASSERT (state->ngrn < N_X_ARG_REG);
+  return get_x_addr (context, (state->ngrn)++);
+}
+
+static void *
+allocate_to_s (struct call_context *context, struct arg_state *state)
+{
+  FFI_ASSERT (state->nsrn < N_V_ARG_REG);
+  return get_s_addr (context, (state->nsrn)++);
+}
+
+static void *
+allocate_to_d (struct call_context *context, struct arg_state *state)
+{
+  FFI_ASSERT (state->nsrn < N_V_ARG_REG);
+  return get_d_addr (context, (state->nsrn)++);
+}
+
+static void *
+allocate_to_v (struct call_context *context, struct arg_state *state)
+{
+  FFI_ASSERT (state->nsrn < N_V_ARG_REG);
+  return get_v_addr (context, (state->nsrn)++);
+}
+
 /* Allocate an aligned slot on the stack and return a pointer to it.  */
 static void *
-allocate_to_stack (struct arg_state *state, void *stack,
-		   size_t alignment, size_t size)
+allocate_to_stack (struct arg_state *state, void *stack, size_t alignment,
+		   size_t size)
 {
-  size_t nsaa = state->nsaa;
+  void *allocation;
 
   /* Round up the NSAA to the larger of 8 or the natural
      alignment of the argument's type.  */
+  state->nsaa = ALIGN (state->nsaa, alignment);
+  state->nsaa = ALIGN (state->nsaa, alignment);
 #if defined (__APPLE__)
-  if (state->allocating_variadic && alignment < 8)
-    alignment = 8;
+  if (state->allocating_variadic)
+    state->nsaa = ALIGN (state->nsaa, 8);
 #else
-  if (alignment < 8)
-    alignment = 8;
+  state->nsaa = ALIGN (state->nsaa, 8);
 #endif
-    
-  nsaa = FFI_ALIGN (nsaa, alignment);
-  state->nsaa = nsaa + size;
 
-  return (char *)stack + nsaa;
+  allocation = stack + state->nsaa;
+
+  state->nsaa += size;
+  return allocation;
 }
 
-static ffi_arg
-extend_integer_type (void *source, int type)
+static void
+copy_basic_type (void *dest, void *source, unsigned short type)
 {
+  /* This is necessary to ensure that basic types are copied
+     sign extended to 64-bits as libffi expects.  */
   switch (type)
     {
+    case FFI_TYPE_FLOAT:
+      *(float *) dest = *(float *) source;
+      break;
+    case FFI_TYPE_DOUBLE:
+      *(double *) dest = *(double *) source;
+      break;
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+      *(long double *) dest = *(long double *) source;
+      break;
+#endif
     case FFI_TYPE_UINT8:
-      return *(UINT8 *) source;
+      *(ffi_arg *) dest = *(UINT8 *) source;
+      break;
     case FFI_TYPE_SINT8:
-      return *(SINT8 *) source;
+      *(ffi_sarg *) dest = *(SINT8 *) source;
+      break;
     case FFI_TYPE_UINT16:
-      return *(UINT16 *) source;
+      *(ffi_arg *) dest = *(UINT16 *) source;
+      break;
     case FFI_TYPE_SINT16:
-      return *(SINT16 *) source;
+      *(ffi_sarg *) dest = *(SINT16 *) source;
+      break;
     case FFI_TYPE_UINT32:
-      return *(UINT32 *) source;
+      *(ffi_arg *) dest = *(UINT32 *) source;
+      break;
     case FFI_TYPE_INT:
     case FFI_TYPE_SINT32:
-      return *(SINT32 *) source;
-    case FFI_TYPE_UINT64:
-    case FFI_TYPE_SINT64:
-      return *(UINT64 *) source;
+      *(ffi_sarg *) dest = *(SINT32 *) source;
       break;
     case FFI_TYPE_POINTER:
-      return *(uintptr_t *) source;
+    case FFI_TYPE_UINT64:
+      *(ffi_arg *) dest = *(UINT64 *) source;
+      break;
+    case FFI_TYPE_SINT64:
+      *(ffi_sarg *) dest = *(SINT64 *) source;
+      break;
+    case FFI_TYPE_VOID:
+      break;
+
     default:
-      abort();
+      FFI_ASSERT (0);
     }
 }
 
-#if defined(_MSC_VER)
-void extend_hfa_type (void *dest, void *src, int h);
-#else
 static void
-extend_hfa_type (void *dest, void *src, int h)
+copy_hfa_to_reg_or_stack (void *memory,
+			  ffi_type *ty,
+			  struct call_context *context,
+			  unsigned char *stack,
+			  struct arg_state *state)
 {
-  ssize_t f = h - AARCH64_RET_S4;
-  void *x0;
-
-  asm volatile (
-	"adr	%0, 0f\n"
-"	add	%0, %0, %1\n"
-"	br	%0\n"
-"0:	ldp	s16, s17, [%3]\n"	/* S4 */
-"	ldp	s18, s19, [%3, #8]\n"
-"	b	4f\n"
-"	ldp	s16, s17, [%3]\n"	/* S3 */
-"	ldr	s18, [%3, #8]\n"
-"	b	3f\n"
-"	ldp	s16, s17, [%3]\n"	/* S2 */
-"	b	2f\n"
-"	nop\n"
-"	ldr	s16, [%3]\n"		/* S1 */
-"	b	1f\n"
-"	nop\n"
-"	ldp	d16, d17, [%3]\n"	/* D4 */
-"	ldp	d18, d19, [%3, #16]\n"
-"	b	4f\n"
-"	ldp	d16, d17, [%3]\n"	/* D3 */
-"	ldr	d18, [%3, #16]\n"
-"	b	3f\n"
-"	ldp	d16, d17, [%3]\n"	/* D2 */
-"	b	2f\n"
-"	nop\n"
-"	ldr	d16, [%3]\n"		/* D1 */
-"	b	1f\n"
-"	nop\n"
-"	ldp	q16, q17, [%3]\n"	/* Q4 */
-"	ldp	q18, q19, [%3, #32]\n"
-"	b	4f\n"
-"	ldp	q16, q17, [%3]\n"	/* Q3 */
-"	ldr	q18, [%3, #32]\n"
-"	b	3f\n"
-"	ldp	q16, q17, [%3]\n"	/* Q2 */
-"	b	2f\n"
-"	nop\n"
-"	ldr	q16, [%3]\n"		/* Q1 */
-"	b	1f\n"
-"4:	str	q19, [%2, #48]\n"
-"3:	str	q18, [%2, #32]\n"
-"2:	str	q17, [%2, #16]\n"
-"1:	str	q16, [%2]"
-    : "=&r"(x0)
-    : "r"(f * 12), "r"(dest), "r"(src)
-    : "memory", "v16", "v17", "v18", "v19");
-}
-#endif
-
-#if defined(_MSC_VER)
-void* compress_hfa_type (void *dest, void *src, int h);
-#else
-static void *
-compress_hfa_type (void *dest, void *reg, int h)
-{
-  switch (h)
+  unsigned elems = element_count (ty);
+  if (available_v (state) < elems)
     {
-    case AARCH64_RET_S1:
-      if (dest == reg)
-	{
-#ifdef __AARCH64EB__
-	  dest += 12;
-#endif
-	}
-      else
-	*(float *)dest = *(float *)reg;
-      break;
-    case AARCH64_RET_S2:
-      asm ("ldp q16, q17, [%1]\n\t"
-	   "st2 { v16.s, v17.s }[0], [%0]"
-	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17");
-      break;
-    case AARCH64_RET_S3:
-      asm ("ldp q16, q17, [%1]\n\t"
-	   "ldr q18, [%1, #32]\n\t"
-	   "st3 { v16.s, v17.s, v18.s }[0], [%0]"
-	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18");
-      break;
-    case AARCH64_RET_S4:
-      asm ("ldp q16, q17, [%1]\n\t"
-	   "ldp q18, q19, [%1, #32]\n\t"
-	   "st4 { v16.s, v17.s, v18.s, v19.s }[0], [%0]"
-	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18", "v19");
-      break;
-
-    case AARCH64_RET_D1:
-      if (dest == reg)
-	{
-#ifdef __AARCH64EB__
-	  dest += 8;
-#endif
-	}
-      else
-	*(double *)dest = *(double *)reg;
-      break;
-    case AARCH64_RET_D2:
-      asm ("ldp q16, q17, [%1]\n\t"
-	   "st2 { v16.d, v17.d }[0], [%0]"
-	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17");
-      break;
-    case AARCH64_RET_D3:
-      asm ("ldp q16, q17, [%1]\n\t"
-	   "ldr q18, [%1, #32]\n\t"
-	   "st3 { v16.d, v17.d, v18.d }[0], [%0]"
-	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18");
-      break;
-    case AARCH64_RET_D4:
-      asm ("ldp q16, q17, [%1]\n\t"
-	   "ldp q18, q19, [%1, #32]\n\t"
-	   "st4 { v16.d, v17.d, v18.d, v19.d }[0], [%0]"
-	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18", "v19");
-      break;
-
-    default:
-      if (dest != reg)
-	return memcpy (dest, reg, 16 * (4 - (h & 3)));
-      break;
+      /* There are insufficient V registers. Further V register allocations
+	 are prevented, the NSAA is adjusted (by allocate_to_stack ())
+	 and the argument is copied to memory at the adjusted NSAA.  */
+      state->nsrn = N_V_ARG_REG;
+      memcpy (allocate_to_stack (state, stack, ty->alignment, ty->size),
+	      memory,
+	      ty->size);
     }
-  return dest;
+  else
+    {
+      int i;
+      unsigned short type = get_homogeneous_type (ty);
+      for (i = 0; i < elems; i++)
+	{
+	  void *reg = allocate_to_v (context, state);
+	  copy_basic_type (reg, memory, type);
+	  memory += get_basic_type_size (type);
+	}
+    }
 }
-#endif
 
 /* Either allocate an appropriate register for the argument type, or if
    none are available, allocate a stack slot and return a pointer
    to the allocated space.  */
 
 static void *
-allocate_int_to_reg_or_stack (struct call_context *context,
-			      struct arg_state *state,
-			      void *stack, size_t size)
+allocate_to_register_or_stack (struct call_context *context,
+			       unsigned char *stack,
+			       struct arg_state *state,
+			       unsigned short type)
 {
-  if (state->ngrn < N_X_ARG_REG)
-    return &context->x[state->ngrn++];
-
-  state->ngrn = N_X_ARG_REG;
-  return allocate_to_stack (state, stack, size, size);
-}
-
-ffi_status FFI_HIDDEN
-ffi_prep_cif_machdep (ffi_cif *cif)
-{
-  ffi_type *rtype = cif->rtype;
-  size_t bytes = cif->bytes;
-  int flags, i, n;
-
-  switch (rtype->type)
+  size_t alignment = get_basic_type_alignment (type);
+  size_t size = alignment;
+  switch (type)
     {
-    case FFI_TYPE_VOID:
-      flags = AARCH64_RET_VOID;
-      break;
-    case FFI_TYPE_UINT8:
-      flags = AARCH64_RET_UINT8;
-      break;
-    case FFI_TYPE_UINT16:
-      flags = AARCH64_RET_UINT16;
-      break;
-    case FFI_TYPE_UINT32:
-      flags = AARCH64_RET_UINT32;
-      break;
-    case FFI_TYPE_SINT8:
-      flags = AARCH64_RET_SINT8;
-      break;
-    case FFI_TYPE_SINT16:
-      flags = AARCH64_RET_SINT16;
-      break;
-    case FFI_TYPE_INT:
-    case FFI_TYPE_SINT32:
-      flags = AARCH64_RET_SINT32;
-      break;
-    case FFI_TYPE_SINT64:
-    case FFI_TYPE_UINT64:
-      flags = AARCH64_RET_INT64;
-      break;
-    case FFI_TYPE_POINTER:
-      flags = (sizeof(void *) == 4 ? AARCH64_RET_UINT32 : AARCH64_RET_INT64);
-      break;
-
     case FFI_TYPE_FLOAT:
+      /* This is the only case for which the allocated stack size
+	 should not match the alignment of the type.  */
+      size = sizeof (UINT32);
+      /* Fall through.  */
     case FFI_TYPE_DOUBLE:
-    case FFI_TYPE_LONGDOUBLE:
-    case FFI_TYPE_STRUCT:
-    case FFI_TYPE_COMPLEX:
-      flags = is_vfp_type (rtype);
-      if (flags == 0)
-	{
-	  size_t s = rtype->size;
-	  if (s > 16)
-	    {
-	      flags = AARCH64_RET_VOID | AARCH64_RET_IN_MEM;
-	      bytes += 8;
-	    }
-	  else if (s == 16)
-	    flags = AARCH64_RET_INT128;
-	  else if (s == 8)
-	    flags = AARCH64_RET_INT64;
-	  else
-	    flags = AARCH64_RET_INT128 | AARCH64_RET_NEED_COPY;
-	}
+      if (state->nsrn < N_V_ARG_REG)
+	return allocate_to_d (context, state);
+      state->nsrn = N_V_ARG_REG;
       break;
-
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+      if (state->nsrn < N_V_ARG_REG)
+	return allocate_to_v (context, state);
+      state->nsrn = N_V_ARG_REG;
+      break;
+#endif
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_INT:
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      if (state->ngrn < N_X_ARG_REG)
+	return allocate_to_x (context, state);
+      state->ngrn = N_X_ARG_REG;
+      break;
     default:
-      abort();
+      FFI_ASSERT (0);
     }
 
-  for (i = 0, n = cif->nargs; i < n; i++)
-    if (is_vfp_type (cif->arg_types[i]))
-      {
-	flags |= AARCH64_FLAG_ARG_V;
-	break;
-      }
+    return allocate_to_stack (state, stack, alignment, size);
+}
 
+/* Copy a value to an appropriate register, or if none are
+   available, to the stack.  */
+
+static void
+copy_to_register_or_stack (struct call_context *context,
+			   unsigned char *stack,
+			   struct arg_state *state,
+			   void *value,
+			   unsigned short type)
+{
+  copy_basic_type (
+	  allocate_to_register_or_stack (context, stack, state, type),
+	  value,
+	  type);
+}
+
+/* Marshall the arguments from FFI representation to procedure call
+   context and stack.  */
+
+static unsigned
+aarch64_prep_args (struct call_context *context, unsigned char *stack,
+		   extended_cif *ecif)
+{
+  int i;
+  struct arg_state state;
+
+  arg_init (&state, ALIGN(ecif->cif->bytes, 16));
+
+  for (i = 0; i < ecif->cif->nargs; i++)
+    {
+      ffi_type *ty = ecif->cif->arg_types[i];
+      switch (ty->type)
+	{
+	case FFI_TYPE_VOID:
+	  FFI_ASSERT (0);
+	  break;
+
+	/* If the argument is a basic type the argument is allocated to an
+	   appropriate register, or if none are available, to the stack.  */
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_INT:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_POINTER:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	  copy_to_register_or_stack (context, stack, &state,
+				     ecif->avalue[i], ty->type);
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  if (is_hfa (ty))
+	    {
+	      copy_hfa_to_reg_or_stack (ecif->avalue[i], ty, context,
+					stack, &state);
+	    }
+	  else if (ty->size > 16)
+	    {
+	      /* If the argument is a composite type that is larger than 16
+		 bytes, then the argument has been copied to memory, and
+		 the argument is replaced by a pointer to the copy.  */
+
+	      copy_to_register_or_stack (context, stack, &state,
+					 &(ecif->avalue[i]), FFI_TYPE_POINTER);
+	    }
+	  else if (available_x (&state) >= (ty->size + 7) / 8)
+	    {
+	      /* If the argument is a composite type and the size in
+		 double-words is not more than the number of available
+		 X registers, then the argument is copied into consecutive
+		 X registers.  */
+	      int j;
+	      for (j = 0; j < (ty->size + 7) / 8; j++)
+		{
+		  memcpy (allocate_to_x (context, &state),
+			  &(((UINT64 *) ecif->avalue[i])[j]),
+			  sizeof (UINT64));
+		}
+	    }
+	  else
+	    {
+	      /* Otherwise, there are insufficient X registers. Further X
+		 register allocations are prevented, the NSAA is adjusted
+		 (by allocate_to_stack ()) and the argument is copied to
+		 memory at the adjusted NSAA.  */
+	      state.ngrn = N_X_ARG_REG;
+
+	      memcpy (allocate_to_stack (&state, stack, ty->alignment,
+					 ty->size), ecif->avalue + i, ty->size);
+	    }
+	  break;
+
+	default:
+	  FFI_ASSERT (0);
+	  break;
+	}
+
+#if defined (__APPLE__)
+      if (i + 1 == ecif->cif->aarch64_nfixedargs)
+	{
+	  state.ngrn = N_X_ARG_REG;
+	  state.nsrn = N_V_ARG_REG;
+
+	  state.allocating_variadic = 1;
+	}
+#endif
+    }
+
+  return ecif->cif->aarch64_flags;
+}
+
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
   /* Round the stack up to a multiple of the stack alignment requirement. */
-  cif->bytes = (unsigned) FFI_ALIGN(bytes, 16);
-  cif->flags = flags;
+  cif->bytes =
+    (cif->bytes + (AARCH64_STACK_ALIGN - 1)) & ~ (AARCH64_STACK_ALIGN - 1);
+
+  /* Initialize our flags. We are interested if this CIF will touch a
+     vector register, if so we will enable context save and load to
+     those registers, otherwise not. This is intended to be friendly
+     to lazy float context switching in the kernel.  */
+  cif->aarch64_flags = 0;
+
+  if (is_v_register_candidate (cif->rtype))
+    {
+      cif->aarch64_flags |= AARCH64_FFI_WITH_V;
+    }
+  else
+    {
+      int i;
+      for (i = 0; i < cif->nargs; i++)
+        if (is_v_register_candidate (cif->arg_types[i]))
+          {
+            cif->aarch64_flags |= AARCH64_FFI_WITH_V;
+            break;
+          }
+    }
+
 #if defined (__APPLE__)
   cif->aarch64_nfixedargs = 0;
 #endif
@@ -552,226 +790,142 @@
 }
 
 #if defined (__APPLE__)
+
 /* Perform Apple-specific cif processing for variadic calls */
-ffi_status FFI_HIDDEN
-ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,
-			 unsigned int ntotalargs)
+ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
+				    unsigned int nfixedargs,
+				    unsigned int ntotalargs)
 {
-  ffi_status status = ffi_prep_cif_machdep (cif);
+  ffi_status status;
+
+  status = ffi_prep_cif_machdep (cif);
+
   cif->aarch64_nfixedargs = nfixedargs;
+
   return status;
 }
-#endif /* __APPLE__ */
 
-extern void ffi_call_SYSV (struct call_context *context, void *frame,
-			   void (*fn)(void), void *rvalue, int flags,
-			   void *closure) FFI_HIDDEN;
+#endif
 
 /* Call a function with the provided arguments and capture the return
    value.  */
-static void
-ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
-	      void **avalue, void *closure)
+void
+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
-  struct call_context *context;
-  void *stack, *frame, *rvalue;
-  struct arg_state state;
-  size_t stack_bytes, rtype_size, rsize;
-  int i, nargs, flags;
-  ffi_type *rtype;
+  extended_cif ecif;
 
-  flags = cif->flags;
-  rtype = cif->rtype;
-  rtype_size = rtype->size;
-  stack_bytes = cif->bytes;
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  ecif.rvalue = rvalue;
 
-  /* If the target function returns a structure via hidden pointer,
-     then we cannot allow a null rvalue.  Otherwise, mash a null
-     rvalue to void return type.  */
-  rsize = 0;
-  if (flags & AARCH64_RET_IN_MEM)
+  switch (cif->abi)
     {
-      if (orig_rvalue == NULL)
-	rsize = rtype_size;
-    }
-  else if (orig_rvalue == NULL)
-    flags &= AARCH64_FLAG_ARG_V;
-  else if (flags & AARCH64_RET_NEED_COPY)
-    rsize = 16;
+    case FFI_SYSV:
+      {
+        struct call_context context;
+	size_t stack_bytes;
 
-  /* Allocate consectutive stack for everything we'll need.  */
-  context = alloca (sizeof(struct call_context) + stack_bytes + 32 + rsize);
-  stack = context + 1;
-  frame = (void*)((uintptr_t)stack + (uintptr_t)stack_bytes);
-  rvalue = (rsize ? (void*)((uintptr_t)frame + 32) : orig_rvalue);
+	/* Figure out the total amount of stack space we need, the
+	   above call frame space needs to be 16 bytes aligned to
+	   ensure correct alignment of the first object inserted in
+	   that space hence the ALIGN applied to cif->bytes.*/
+	stack_bytes = ALIGN(cif->bytes, 16);
 
-  arg_init (&state);
-  for (i = 0, nargs = cif->nargs; i < nargs; i++)
-    {
-      ffi_type *ty = cif->arg_types[i];
-      size_t s = ty->size;
-      void *a = avalue[i];
-      int h, t;
-
-      t = ty->type;
-      switch (t)
-	{
-	case FFI_TYPE_VOID:
-	  FFI_ASSERT (0);
-	  break;
-
-	/* If the argument is a basic type the argument is allocated to an
-	   appropriate register, or if none are available, to the stack.  */
-	case FFI_TYPE_INT:
-	case FFI_TYPE_UINT8:
-	case FFI_TYPE_SINT8:
-	case FFI_TYPE_UINT16:
-	case FFI_TYPE_SINT16:
-	case FFI_TYPE_UINT32:
-	case FFI_TYPE_SINT32:
-	case FFI_TYPE_UINT64:
-	case FFI_TYPE_SINT64:
-	case FFI_TYPE_POINTER:
-	do_pointer:
-	  {
-	    ffi_arg ext = extend_integer_type (a, t);
-	    if (state.ngrn < N_X_ARG_REG)
-	      context->x[state.ngrn++] = ext;
-	    else
-	      {
-		void *d = allocate_to_stack (&state, stack, ty->alignment, s);
-		state.ngrn = N_X_ARG_REG;
-		/* Note that the default abi extends each argument
-		   to a full 64-bit slot, while the iOS abi allocates
-		   only enough space. */
-#ifdef __APPLE__
-		memcpy(d, a, s);
-#else
-		*(ffi_arg *)d = ext;
+	memset (&context, 0, sizeof (context));
+        if (is_register_candidate (cif->rtype))
+          {
+            ffi_call_SYSV (aarch64_prep_args, &context, &ecif, stack_bytes, fn);
+            switch (cif->rtype->type)
+              {
+              case FFI_TYPE_VOID:
+              case FFI_TYPE_FLOAT:
+              case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+              case FFI_TYPE_LONGDOUBLE:
 #endif
-	      }
-	  }
-	  break;
+              case FFI_TYPE_UINT8:
+              case FFI_TYPE_SINT8:
+              case FFI_TYPE_UINT16:
+              case FFI_TYPE_SINT16:
+              case FFI_TYPE_UINT32:
+              case FFI_TYPE_SINT32:
+              case FFI_TYPE_POINTER:
+              case FFI_TYPE_UINT64:
+              case FFI_TYPE_INT:
+              case FFI_TYPE_SINT64:
+		{
+		  void *addr = get_basic_type_addr (cif->rtype->type,
+						    &context, 0);
+		  copy_basic_type (rvalue, addr, cif->rtype->type);
+		  break;
+		}
 
-	case FFI_TYPE_FLOAT:
-	case FFI_TYPE_DOUBLE:
-	case FFI_TYPE_LONGDOUBLE:
-	case FFI_TYPE_STRUCT:
-	case FFI_TYPE_COMPLEX:
-	  {
-	    void *dest;
-
-	    h = is_vfp_type (ty);
-	    if (h)
-	      {
-		int elems = 4 - (h & 3);
-#ifdef _M_ARM64 /* for handling armasm calling convention */
-                if (cif->is_variadic)
+              case FFI_TYPE_STRUCT:
+                if (is_hfa (cif->rtype))
+		  {
+		    int j;
+		    unsigned short type = get_homogeneous_type (cif->rtype);
+		    unsigned elems = element_count (cif->rtype);
+		    for (j = 0; j < elems; j++)
+		      {
+			void *reg = get_basic_type_addr (type, &context, j);
+			copy_basic_type (rvalue, reg, type);
+			rvalue += get_basic_type_size (type);
+		      }
+		  }
+                else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG)
                   {
-                    if (state.ngrn + elems <= N_X_ARG_REG)
-                      {
-                        dest = &context->x[state.ngrn];
-                        state.ngrn += elems;
-                        extend_hfa_type(dest, a, h);
-                        break;
-                      }
-                    state.nsrn = N_X_ARG_REG;
-                    dest = allocate_to_stack(&state, stack, ty->alignment, s);
+                    size_t size = ALIGN (cif->rtype->size, sizeof (UINT64));
+                    memcpy (rvalue, get_x_addr (&context, 0), size);
                   }
                 else
                   {
-#endif /* for handling armasm calling convention */
-	        if (state.nsrn + elems <= N_V_ARG_REG)
-		  {
-		    dest = &context->v[state.nsrn];
-		    state.nsrn += elems;
-		    extend_hfa_type (dest, a, h);
-		    break;
-		  }
-		state.nsrn = N_V_ARG_REG;
-		dest = allocate_to_stack (&state, stack, ty->alignment, s);
-#ifdef _M_ARM64 /* for handling armasm calling convention */
-	      }
-#endif /* for handling armasm calling convention */
-	      }
-	    else if (s > 16)
-	      {
-		/* If the argument is a composite type that is larger than 16
-		   bytes, then the argument has been copied to memory, and
-		   the argument is replaced by a pointer to the copy.  */
-		a = &avalue[i];
-		t = FFI_TYPE_POINTER;
-		s = sizeof (void *);
-		goto do_pointer;
-	      }
-	    else
-	      {
-		size_t n = (s + 7) / 8;
-		if (state.ngrn + n <= N_X_ARG_REG)
-		  {
-		    /* If the argument is a composite type and the size in
-		       double-words is not more than the number of available
-		       X registers, then the argument is copied into
-		       consecutive X registers.  */
-		    dest = &context->x[state.ngrn];
-                    state.ngrn += (unsigned int)n;
-		  }
-		else
-		  {
-		    /* Otherwise, there are insufficient X registers. Further
-		       X register allocations are prevented, the NSAA is
-		       adjusted and the argument is copied to memory at the
-		       adjusted NSAA.  */
-		    state.ngrn = N_X_ARG_REG;
-		    dest = allocate_to_stack (&state, stack, ty->alignment, s);
-		  }
-		}
-	      memcpy (dest, a, s);
-	    }
-	  break;
+                    FFI_ASSERT (0);
+                  }
+                break;
 
-	default:
-	  abort();
-	}
+              default:
+                FFI_ASSERT (0);
+                break;
+              }
+          }
+        else
+          {
+            memcpy (get_x_addr (&context, 8), &rvalue, sizeof (UINT64));
+            ffi_call_SYSV (aarch64_prep_args, &context, &ecif,
+			   stack_bytes, fn);
+          }
+        break;
+      }
 
-#if defined (__APPLE__)
-      if (i + 1 == cif->aarch64_nfixedargs)
-	{
-	  state.ngrn = N_X_ARG_REG;
-	  state.nsrn = N_V_ARG_REG;
-	  state.allocating_variadic = 1;
-	}
-#endif
+    default:
+      FFI_ASSERT (0);
+      break;
     }
-
-  ffi_call_SYSV (context, frame, fn, rvalue, flags, closure);
-
-  if (flags & AARCH64_RET_NEED_COPY)
-    memcpy (orig_rvalue, rvalue, rtype_size);
 }
 
-void
-ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, NULL);
-}
-
-#ifdef FFI_GO_CLOSURES
-void
-ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,
-	     void **avalue, void *closure)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, closure);
-}
-#endif /* FFI_GO_CLOSURES */
+static unsigned char trampoline [] =
+{ 0x70, 0x00, 0x00, 0x58,	/* ldr	x16, 1f	*/
+  0x91, 0x00, 0x00, 0x10,	/* adr	x17, 2f	*/
+  0x00, 0x02, 0x1f, 0xd6	/* br	x16	*/
+};
 
 /* Build a trampoline.  */
 
-extern void ffi_closure_SYSV (void) FFI_HIDDEN;
-extern void ffi_closure_SYSV_V (void) FFI_HIDDEN;
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,FLAGS)			\
+  ({unsigned char *__tramp = (unsigned char*)(TRAMP);			\
+    UINT64  __fun = (UINT64)(FUN);					\
+    UINT64  __ctx = (UINT64)(CTX);					\
+    UINT64  __flags = (UINT64)(FLAGS);					\
+    memcpy (__tramp, trampoline, sizeof (trampoline));			\
+    memcpy (__tramp + 12, &__fun, sizeof (__fun));			\
+    memcpy (__tramp + 20, &__ctx, sizeof (__ctx));			\
+    memcpy (__tramp + 28, &__flags, sizeof (__flags));			\
+    ffi_clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE);		\
+  })
 
 ffi_status
-ffi_prep_closure_loc (ffi_closure *closure,
+ffi_prep_closure_loc (ffi_closure* closure,
                       ffi_cif* cif,
                       void (*fun)(ffi_cif*,void*,void**,void*),
                       void *user_data,
@@ -780,77 +934,16 @@
   if (cif->abi != FFI_SYSV)
     return FFI_BAD_ABI;
 
-  void (*start)(void);
-  
-  if (cif->flags & AARCH64_FLAG_ARG_V)
-    start = ffi_closure_SYSV_V;
-  else
-    start = ffi_closure_SYSV;
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV, codeloc,
+		       cif->aarch64_flags);
 
-#if FFI_EXEC_TRAMPOLINE_TABLE
-#ifdef __MACH__
-  void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);
-  config[0] = closure;
-  config[1] = start;
-#endif
-#else
-  static const unsigned char trampoline[16] = {
-    0x90, 0x00, 0x00, 0x58,	/* ldr	x16, tramp+16	*/
-    0xf1, 0xff, 0xff, 0x10,	/* adr	x17, tramp+0	*/
-    0x00, 0x02, 0x1f, 0xd6	/* br	x16		*/
-  };
-  char *tramp = closure->tramp;
-  
-  memcpy (tramp, trampoline, sizeof(trampoline));
-  
-  *(UINT64 *)(tramp + 16) = (uintptr_t)start;
-
-  ffi_clear_cache(tramp, tramp + FFI_TRAMPOLINE_SIZE);
-
-  /* Also flush the cache for code mapping.  */
-#ifdef _M_ARM64
-  // Not using dlmalloc.c for Windows ARM64 builds
-  // so calling ffi_data_to_code_pointer() isn't necessary
-  unsigned char *tramp_code = tramp;
-  #else
-  unsigned char *tramp_code = ffi_data_to_code_pointer (tramp);
-  #endif
-  ffi_clear_cache (tramp_code, tramp_code + FFI_TRAMPOLINE_SIZE);
-#endif
-
-  closure->cif = cif;
-  closure->fun = fun;
+  closure->cif  = cif;
   closure->user_data = user_data;
+  closure->fun  = fun;
 
   return FFI_OK;
 }
 
-#ifdef FFI_GO_CLOSURES
-extern void ffi_go_closure_SYSV (void) FFI_HIDDEN;
-extern void ffi_go_closure_SYSV_V (void) FFI_HIDDEN;
-
-ffi_status
-ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif* cif,
-                     void (*fun)(ffi_cif*,void*,void**,void*))
-{
-  void (*start)(void);
-
-  if (cif->abi != FFI_SYSV)
-    return FFI_BAD_ABI;
-
-  if (cif->flags & AARCH64_FLAG_ARG_V)
-    start = ffi_go_closure_SYSV_V;
-  else
-    start = ffi_go_closure_SYSV;
-
-  closure->tramp = start;
-  closure->cif = cif;
-  closure->fun = fun;
-
-  return FFI_OK;
-}
-#endif /* FFI_GO_CLOSURES */
-
 /* Primary handler to setup and invoke a function within a closure.
 
    A closure when invoked enters via the assembler wrapper
@@ -867,143 +960,220 @@
    descriptors, invokes the wrapped function, then marshalls the return
    value back into the call context.  */
 
-int FFI_HIDDEN
-ffi_closure_SYSV_inner (ffi_cif *cif,
-			void (*fun)(ffi_cif*,void*,void**,void*),
-			void *user_data,
-			struct call_context *context,
-			void *stack, void *rvalue, void *struct_rvalue)
+void FFI_HIDDEN
+ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
+			void *stack)
 {
+  ffi_cif *cif = closure->cif;
   void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
-  int i, h, nargs, flags;
+  void *rvalue = NULL;
+  int i;
   struct arg_state state;
 
-  arg_init (&state);
+  arg_init (&state, ALIGN(cif->bytes, 16));
 
-  for (i = 0, nargs = cif->nargs; i < nargs; i++)
+  for (i = 0; i < cif->nargs; i++)
     {
       ffi_type *ty = cif->arg_types[i];
-      int t = ty->type;
-      size_t n, s = ty->size;
 
-      switch (t)
+      switch (ty->type)
 	{
 	case FFI_TYPE_VOID:
 	  FFI_ASSERT (0);
 	  break;
 
-	case FFI_TYPE_INT:
 	case FFI_TYPE_UINT8:
 	case FFI_TYPE_SINT8:
 	case FFI_TYPE_UINT16:
 	case FFI_TYPE_SINT16:
 	case FFI_TYPE_UINT32:
 	case FFI_TYPE_SINT32:
+	case FFI_TYPE_INT:
+	case FFI_TYPE_POINTER:
 	case FFI_TYPE_UINT64:
 	case FFI_TYPE_SINT64:
-	case FFI_TYPE_POINTER:
-	  avalue[i] = allocate_int_to_reg_or_stack (context, &state, stack, s);
+	case  FFI_TYPE_FLOAT:
+	case  FFI_TYPE_DOUBLE:
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+	case  FFI_TYPE_LONGDOUBLE:
+	  avalue[i] = allocate_to_register_or_stack (context, stack,
+						     &state, ty->type);
+	  break;
+#endif
+
+	case FFI_TYPE_STRUCT:
+	  if (is_hfa (ty))
+	    {
+	      unsigned n = element_count (ty);
+	      if (available_v (&state) < n)
+		{
+		  state.nsrn = N_V_ARG_REG;
+		  avalue[i] = allocate_to_stack (&state, stack, ty->alignment,
+						 ty->size);
+		}
+	      else
+		{
+		  switch (get_homogeneous_type (ty))
+		    {
+		    case FFI_TYPE_FLOAT:
+		      {
+			/* Eeek! We need a pointer to the structure,
+			   however the homogeneous float elements are
+			   being passed in individual S registers,
+			   therefore the structure is not represented as
+			   a contiguous sequence of bytes in our saved
+			   register context. We need to fake up a copy
+			   of the structure laid out in memory
+			   correctly. The fake can be tossed once the
+			   closure function has returned hence alloca()
+			   is sufficient. */
+			int j;
+			UINT32 *p = avalue[i] = alloca (ty->size);
+			for (j = 0; j < element_count (ty); j++)
+			  memcpy (&p[j],
+				  allocate_to_s (context, &state),
+				  sizeof (*p));
+			break;
+		      }
+
+		    case FFI_TYPE_DOUBLE:
+		      {
+			/* Eeek! We need a pointer to the structure,
+			   however the homogeneous float elements are
+			   being passed in individual S registers,
+			   therefore the structure is not represented as
+			   a contiguous sequence of bytes in our saved
+			   register context. We need to fake up a copy
+			   of the structure laid out in memory
+			   correctly. The fake can be tossed once the
+			   closure function has returned hence alloca()
+			   is sufficient. */
+			int j;
+			UINT64 *p = avalue[i] = alloca (ty->size);
+			for (j = 0; j < element_count (ty); j++)
+			  memcpy (&p[j],
+				  allocate_to_d (context, &state),
+				  sizeof (*p));
+			break;
+		      }
+
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+		    case FFI_TYPE_LONGDOUBLE:
+			  memcpy (&avalue[i],
+				  allocate_to_v (context, &state),
+				  sizeof (*avalue));
+		      break;
+#endif
+
+		    default:
+		      FFI_ASSERT (0);
+		      break;
+		    }
+		}
+	    }
+	  else if (ty->size > 16)
+	    {
+	      /* Replace Composite type of size greater than 16 with a
+		 pointer.  */
+	      memcpy (&avalue[i],
+		      allocate_to_register_or_stack (context, stack,
+						     &state, FFI_TYPE_POINTER),
+		      sizeof (avalue[i]));
+	    }
+	  else if (available_x (&state) >= (ty->size + 7) / 8)
+	    {
+	      avalue[i] = get_x_addr (context, state.ngrn);
+	      state.ngrn += (ty->size + 7) / 8;
+	    }
+	  else
+	    {
+	      state.ngrn = N_X_ARG_REG;
+
+	      avalue[i] = allocate_to_stack (&state, stack, ty->alignment,
+					     ty->size);
+	    }
 	  break;
 
-	case FFI_TYPE_FLOAT:
-	case FFI_TYPE_DOUBLE:
-	case FFI_TYPE_LONGDOUBLE:
-	case FFI_TYPE_STRUCT:
-	case FFI_TYPE_COMPLEX:
-	  h = is_vfp_type (ty);
-	  if (h)
+	default:
+	  FFI_ASSERT (0);
+	  break;
+	}
+    }
+
+  /* Figure out where the return value will be passed, either in
+     registers or in a memory block allocated by the caller and passed
+     in x8.  */
+
+  if (is_register_candidate (cif->rtype))
+    {
+      /* Register candidates are *always* returned in registers. */
+
+      /* Allocate a scratchpad for the return value, we will let the
+         callee scrible the result into the scratch pad then move the
+         contents into the appropriate return value location for the
+         call convention.  */
+      rvalue = alloca (cif->rtype->size);
+      (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+      /* Copy the return value into the call context so that it is returned
+         as expected to our caller.  */
+      switch (cif->rtype->type)
+        {
+        case FFI_TYPE_VOID:
+          break;
+
+        case FFI_TYPE_UINT8:
+        case FFI_TYPE_UINT16:
+        case FFI_TYPE_UINT32:
+        case FFI_TYPE_POINTER:
+        case FFI_TYPE_UINT64:
+        case FFI_TYPE_SINT8:
+        case FFI_TYPE_SINT16:
+        case FFI_TYPE_INT:
+        case FFI_TYPE_SINT32:
+        case FFI_TYPE_SINT64:
+        case FFI_TYPE_FLOAT:
+        case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+        case FFI_TYPE_LONGDOUBLE:
+#endif
+	  {
+	    void *addr = get_basic_type_addr (cif->rtype->type, context, 0);
+	    copy_basic_type (addr, rvalue, cif->rtype->type);
+            break;
+	  }
+        case FFI_TYPE_STRUCT:
+          if (is_hfa (cif->rtype))
 	    {
-	      n = 4 - (h & 3);
-#ifdef _M_ARM64  /* for handling armasm calling convention */
-              if (cif->is_variadic)
-                {
-                  if (state.ngrn + n <= N_X_ARG_REG)
-                    {
-                      void *reg = &context->x[state.ngrn];
-                      state.ngrn += (unsigned int)n;
-    
-                      /* Eeek! We need a pointer to the structure, however the
-                       homogeneous float elements are being passed in individual
-                       registers, therefore for float and double the structure
-                       is not represented as a contiguous sequence of bytes in
-                       our saved register context.  We don't need the original
-                       contents of the register storage, so we reformat the
-                       structure into the same memory.  */
-                      avalue[i] = compress_hfa_type(reg, reg, h);
-                    }
-                  else
-                    {
-                      state.ngrn = N_X_ARG_REG;
-                      state.nsrn = N_V_ARG_REG;
-                      avalue[i] = allocate_to_stack(&state, stack,
-                             ty->alignment, s);
-                    }
-                }
-              else
-                {
-#endif  /* for handling armasm calling convention */
-                  if (state.nsrn + n <= N_V_ARG_REG)
-                    {
-                      void *reg = &context->v[state.nsrn];
-                      state.nsrn += (unsigned int)n;
-                      avalue[i] = compress_hfa_type(reg, reg, h);
-                    }
-                  else
-                    {
-                      state.nsrn = N_V_ARG_REG;
-                      avalue[i] = allocate_to_stack(&state, stack,
-                                                   ty->alignment, s);
-                    }
-#ifdef _M_ARM64  /* for handling armasm calling convention */
-                }
-#endif  /* for handling armasm calling convention */
-            }
-          else if (s > 16)
+	      int j;
+	      unsigned short type = get_homogeneous_type (cif->rtype);
+	      unsigned elems = element_count (cif->rtype);
+	      for (j = 0; j < elems; j++)
+		{
+		  void *reg = get_basic_type_addr (type, context, j);
+		  copy_basic_type (reg, rvalue, type);
+		  rvalue += get_basic_type_size (type);
+		}
+	    }
+          else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG)
             {
-              /* Replace Composite type of size greater than 16 with a
-                  pointer.  */
-              avalue[i] = *(void **)
-              allocate_int_to_reg_or_stack (context, &state, stack,
-                                         sizeof (void *));
+              size_t size = ALIGN (cif->rtype->size, sizeof (UINT64)) ;
+              memcpy (get_x_addr (context, 0), rvalue, size);
             }
           else
             {
-              n = (s + 7) / 8;
-              if (state.ngrn + n <= N_X_ARG_REG)
-                {
-                  avalue[i] = &context->x[state.ngrn];
-                  state.ngrn += (unsigned int)n;
-                }
-              else
-                {
-                  state.ngrn = N_X_ARG_REG;
-                  avalue[i] = allocate_to_stack(&state, stack,
-                                           ty->alignment, s);
-                }
+              FFI_ASSERT (0);
             }
           break;
-
         default:
-          abort();
-      }
-
-#if defined (__APPLE__)
-      if (i + 1 == cif->aarch64_nfixedargs)
-	{
-	  state.ngrn = N_X_ARG_REG;
-	  state.nsrn = N_V_ARG_REG;
-	  state.allocating_variadic = 1;
-	}
-#endif
+          FFI_ASSERT (0);
+          break;
+        }
     }
-
-  flags = cif->flags;
-  if (flags & AARCH64_RET_IN_MEM)
-    rvalue = struct_rvalue;
-
-  fun (cif, rvalue, avalue, user_data);
-
-  return flags;
+  else
+    {
+      memcpy (&rvalue, get_x_addr (context, 8), sizeof (UINT64));
+      (closure->fun) (cif, rvalue, avalue, closure->user_data);
+    }
 }
 
-#endif /* (__aarch64__) || defined(__arm64__)|| defined (_M_ARM64)*/
diff --git a/src/aarch64/ffitarget.h b/src/aarch64/ffitarget.h
index ecb6d2d..4bbced2 100644
--- a/src/aarch64/ffitarget.h
+++ b/src/aarch64/ffitarget.h
@@ -27,19 +27,8 @@
 #endif
 
 #ifndef LIBFFI_ASM
-#ifdef __ILP32__
-#define FFI_SIZEOF_ARG 8
-#define FFI_SIZEOF_JAVA_RAW  4
-typedef unsigned long long ffi_arg;
-typedef signed long long ffi_sarg;
-#elif defined(_M_ARM64)
-#define FFI_SIZEOF_ARG 8
-typedef unsigned long long ffi_arg;
-typedef signed long long ffi_sarg;
-#else
 typedef unsigned long ffi_arg;
 typedef signed long ffi_sarg;
-#endif
 
 typedef enum ffi_abi
   {
@@ -53,40 +42,22 @@
 /* ---- Definitions for closures ----------------------------------------- */
 
 #define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 36
 #define FFI_NATIVE_RAW_API 0
 
-#if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
-
-#ifdef __MACH__
-#define FFI_TRAMPOLINE_SIZE 16
-#define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
-#else
-#error "No trampoline table implementation"
-#endif
-
-#else
-#define FFI_TRAMPOLINE_SIZE 24
-#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
-#endif
-
-#ifdef _M_ARM64
-#define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
-#endif
-
 /* ---- Internal ---- */
 
 #if defined (__APPLE__)
 #define FFI_TARGET_SPECIFIC_VARIADIC
-#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
-#elif !defined(_M_ARM64)
-/* iOS and Windows reserve x18 for the system.  Disable Go closures until
-   a new static chain is chosen.  */
-#define FFI_GO_CLOSURES 1
+#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags; unsigned aarch64_nfixedargs
+#else
+#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags
 #endif
 
-#ifndef _M_ARM64
-/* No complex type on Windows */
-#define FFI_TARGET_HAS_COMPLEX_TYPE
-#endif
+#define AARCH64_FFI_WITH_V_BIT 0
+
+#define AARCH64_N_XREG 32
+#define AARCH64_N_VREG 32
+#define AARCH64_CALL_CONTEXT_SIZE (AARCH64_N_XREG * 8 + AARCH64_N_VREG * 16)
 
 #endif
diff --git a/src/aarch64/internal.h b/src/aarch64/internal.h
deleted file mode 100644
index 9c3e077..0000000
--- a/src/aarch64/internal.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-``Software''), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
-
-#define AARCH64_RET_VOID	0
-#define AARCH64_RET_INT64	1
-#define AARCH64_RET_INT128	2
-
-#define AARCH64_RET_UNUSED3	3
-#define AARCH64_RET_UNUSED4	4
-#define AARCH64_RET_UNUSED5	5
-#define AARCH64_RET_UNUSED6	6
-#define AARCH64_RET_UNUSED7	7
-
-/* Note that FFI_TYPE_FLOAT == 2, _DOUBLE == 3, _LONGDOUBLE == 4,
-   so _S4 through _Q1 are layed out as (TYPE * 4) + (4 - COUNT).  */
-#define AARCH64_RET_S4		8
-#define AARCH64_RET_S3		9
-#define AARCH64_RET_S2		10
-#define AARCH64_RET_S1		11
-
-#define AARCH64_RET_D4		12
-#define AARCH64_RET_D3		13
-#define AARCH64_RET_D2		14
-#define AARCH64_RET_D1		15
-
-#define AARCH64_RET_Q4		16
-#define AARCH64_RET_Q3		17
-#define AARCH64_RET_Q2		18
-#define AARCH64_RET_Q1		19
-
-/* Note that each of the sub-64-bit integers gets two entries.  */
-#define AARCH64_RET_UINT8	20
-#define AARCH64_RET_UINT16	22
-#define AARCH64_RET_UINT32	24
-
-#define AARCH64_RET_SINT8	26
-#define AARCH64_RET_SINT16	28
-#define AARCH64_RET_SINT32	30
-
-#define AARCH64_RET_MASK	31
-
-#define AARCH64_RET_IN_MEM	(1 << 5)
-#define AARCH64_RET_NEED_COPY	(1 << 6)
-
-#define AARCH64_FLAG_ARG_V_BIT	7
-#define AARCH64_FLAG_ARG_V	(1 << AARCH64_FLAG_ARG_V_BIT)
-
-#define N_X_ARG_REG		8
-#define N_V_ARG_REG		8
-#define CALL_CONTEXT_SIZE	(N_V_ARG_REG * 16 + N_X_ARG_REG * 8)
diff --git a/src/aarch64/sysv.S b/src/aarch64/sysv.S
index 6761ee1..169eab8 100644
--- a/src/aarch64/sysv.S
+++ b/src/aarch64/sysv.S
@@ -19,12 +19,9 @@
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 
-#if defined(__aarch64__) || defined(__arm64__)
 #define LIBFFI_ASM
 #include <fficonfig.h>
 #include <ffi.h>
-#include <ffi_cfi.h>
-#include "internal.h"
 
 #ifdef HAVE_MACHINE_ASM_H
 #include <machine/asm.h>
@@ -40,401 +37,297 @@
 #endif
 #endif
 
-#ifdef __AARCH64EB__
-# define BE(X)	X
-#else
-# define BE(X)	0
+#define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off
+#define cfi_rel_offset(reg, off)	.cfi_rel_offset reg, off
+#define cfi_restore(reg)		.cfi_restore reg
+#define cfi_def_cfa_register(reg)	.cfi_def_cfa_register reg
+
+        .text
+        .globl CNAME(ffi_call_SYSV)
+#ifdef __ELF__
+        .type CNAME(ffi_call_SYSV), #function
+#endif
+#ifdef __APPLE__
+        .align 2
 #endif
 
-#ifdef __ILP32__
-#define PTR_REG(n)      w##n
-#else
-#define PTR_REG(n)      x##n
-#endif
+/* ffi_call_SYSV()
 
-#ifdef __ILP32__
-#define PTR_SIZE	4
-#else
-#define PTR_SIZE	8
-#endif
+   Create a stack frame, setup an argument context, call the callee
+   and extract the result.
 
-	.text
-	.align 4
+   The maximum required argument stack size is provided,
+   ffi_call_SYSV() allocates that stack space then calls the
+   prepare_fn to populate register context and stack.  The
+   argument passing registers are loaded from the register
+   context and the callee called, on return the register passing
+   register are saved back to the context.  Our caller will
+   extract the return value from the final state of the saved
+   register context.
 
-/* ffi_call_SYSV
-   extern void ffi_call_SYSV (void *stack, void *frame,
-			      void (*fn)(void), void *rvalue,
-			      int flags, void *closure);
+   Prototype:
+
+   extern unsigned
+   ffi_call_SYSV (void (*)(struct call_context *context, unsigned char *,
+			   extended_cif *),
+                  struct call_context *context,
+                  extended_cif *,
+                  size_t required_stack_size,
+                  void (*fn)(void));
 
    Therefore on entry we have:
 
-   x0 stack
-   x1 frame
-   x2 fn
-   x3 rvalue
-   x4 flags
-   x5 closure
-*/
+   x0 prepare_fn
+   x1 &context
+   x2 &ecif
+   x3 bytes
+   x4 fn
 
-	cfi_startproc
+   This function uses the following stack frame layout:
+
+   ==
+                saved x30(lr)
+   x29(fp)->    saved x29(fp)
+                saved x24
+                saved x23
+                saved x22
+   sp'    ->    saved x21
+                ...
+   sp     ->    (constructed callee stack arguments)
+   ==
+
+   Voila! */
+
+#define ffi_call_SYSV_FS (8 * 4)
+
+        .cfi_startproc
 CNAME(ffi_call_SYSV):
-	/* Use a stack frame allocated by our caller.  */
-	cfi_def_cfa(x1, 32);
-	stp	x29, x30, [x1]
-	mov	x29, x1
-	mov	sp, x0
-	cfi_def_cfa_register(x29)
-	cfi_rel_offset (x29, 0)
-	cfi_rel_offset (x30, 8)
+        stp     x29, x30, [sp, #-16]!
+	cfi_adjust_cfa_offset (16)
+        cfi_rel_offset (x29, 0)
+        cfi_rel_offset (x30, 8)
 
-	mov	x9, x2			/* save fn */
-	mov	x8, x3			/* install structure return */
-#ifdef FFI_GO_CLOSURES
-	mov	x18, x5			/* install static chain */
-#endif
-	stp	x3, x4, [x29, #16]	/* save rvalue and flags */
+        mov     x29, sp
+	cfi_def_cfa_register (x29)
+        sub     sp, sp, #ffi_call_SYSV_FS
 
-	/* Load the vector argument passing registers, if necessary.  */
-	tbz	w4, #AARCH64_FLAG_ARG_V_BIT, 1f
-	ldp     q0, q1, [sp, #0]
-	ldp     q2, q3, [sp, #32]
-	ldp     q4, q5, [sp, #64]
-	ldp     q6, q7, [sp, #96]
+        stp     x21, x22, [sp, #0]
+        cfi_rel_offset (x21, 0 - ffi_call_SYSV_FS)
+        cfi_rel_offset (x22, 8 - ffi_call_SYSV_FS)
+
+        stp     x23, x24, [sp, #16]
+        cfi_rel_offset (x23, 16 - ffi_call_SYSV_FS)
+        cfi_rel_offset (x24, 24 - ffi_call_SYSV_FS)
+
+        mov     x21, x1
+        mov     x22, x2
+        mov     x24, x4
+
+        /* Allocate the stack space for the actual arguments, many
+           arguments will be passed in registers, but we assume
+           worst case and allocate sufficient stack for ALL of
+           the arguments.  */
+        sub     sp, sp, x3
+
+        /* unsigned (*prepare_fn) (struct call_context *context,
+				   unsigned char *stack, extended_cif *ecif);
+	 */
+        mov     x23, x0
+        mov     x0, x1
+        mov     x1, sp
+        /* x2 already in place */
+        blr     x23
+
+        /* Preserve the flags returned.  */
+        mov     x23, x0
+
+        /* Figure out if we should touch the vector registers.  */
+        tbz     x23, #AARCH64_FFI_WITH_V_BIT, 1f
+
+        /* Load the vector argument passing registers.  */
+        ldp     q0, q1, [x21, #8*32 +  0]
+        ldp     q2, q3, [x21, #8*32 + 32]
+        ldp     q4, q5, [x21, #8*32 + 64]
+        ldp     q6, q7, [x21, #8*32 + 96]
 1:
-	/* Load the core argument passing registers, including
-	   the structure return pointer.  */
-	ldp     x0, x1, [sp, #16*N_V_ARG_REG + 0]
-	ldp     x2, x3, [sp, #16*N_V_ARG_REG + 16]
-	ldp     x4, x5, [sp, #16*N_V_ARG_REG + 32]
-	ldp     x6, x7, [sp, #16*N_V_ARG_REG + 48]
+        /* Load the core argument passing registers.  */
+        ldp     x0, x1, [x21,  #0]
+        ldp     x2, x3, [x21, #16]
+        ldp     x4, x5, [x21, #32]
+        ldp     x6, x7, [x21, #48]
 
-	/* Deallocate the context, leaving the stacked arguments.  */
-	add	sp, sp, #CALL_CONTEXT_SIZE
+        /* Don't forget x8 which may be holding the address of a return buffer.
+	 */
+        ldr     x8,     [x21, #8*8]
 
-	blr     x9			/* call fn */
+        blr     x24
 
-	ldp	x3, x4, [x29, #16]	/* reload rvalue and flags */
+        /* Save the core argument passing registers.  */
+        stp     x0, x1, [x21,  #0]
+        stp     x2, x3, [x21, #16]
+        stp     x4, x5, [x21, #32]
+        stp     x6, x7, [x21, #48]
 
-	/* Partially deconstruct the stack frame.  */
-	mov     sp, x29
+        /* Note nothing useful ever comes back in x8!  */
+
+        /* Figure out if we should touch the vector registers.  */
+        tbz     x23, #AARCH64_FFI_WITH_V_BIT, 1f
+
+        /* Save the vector argument passing registers.  */
+        stp     q0, q1, [x21, #8*32 + 0]
+        stp     q2, q3, [x21, #8*32 + 32]
+        stp     q4, q5, [x21, #8*32 + 64]
+        stp     q6, q7, [x21, #8*32 + 96]
+1:
+        /* All done, unwind our stack frame.  */
+        ldp     x21, x22, [x29,  # - ffi_call_SYSV_FS]
+        cfi_restore (x21)
+        cfi_restore (x22)
+
+        ldp     x23, x24, [x29,  # - ffi_call_SYSV_FS + 16]
+        cfi_restore (x23)
+        cfi_restore (x24)
+
+        mov     sp, x29
 	cfi_def_cfa_register (sp)
-	ldp     x29, x30, [x29]
 
-	/* Save the return value as directed.  */
-	adr	x5, 0f
-	and	w4, w4, #AARCH64_RET_MASK
-	add	x5, x5, x4, lsl #3
-	br	x5
+        ldp     x29, x30, [sp], #16
+	cfi_adjust_cfa_offset (-16)
+        cfi_restore (x29)
+        cfi_restore (x30)
 
-	/* Note that each table entry is 2 insns, and thus 8 bytes.
-	   For integer data, note that we're storing into ffi_arg
-	   and therefore we want to extend to 64 bits; these types
-	   have two consecutive entries allocated for them.  */
-	.align	4
-0:	ret				/* VOID */
-	nop
-1:	str	x0, [x3]		/* INT64 */
-	ret
-2:	stp	x0, x1, [x3]		/* INT128 */
-	ret
-3:	brk	#1000			/* UNUSED */
-	ret
-4:	brk	#1000			/* UNUSED */
-	ret
-5:	brk	#1000			/* UNUSED */
-	ret
-6:	brk	#1000			/* UNUSED */
-	ret
-7:	brk	#1000			/* UNUSED */
-	ret
-8:	st4	{ v0.s, v1.s, v2.s, v3.s }[0], [x3]	/* S4 */
-	ret
-9:	st3	{ v0.s, v1.s, v2.s }[0], [x3]	/* S3 */
-	ret
-10:	stp	s0, s1, [x3]		/* S2 */
-	ret
-11:	str	s0, [x3]		/* S1 */
-	ret
-12:	st4	{ v0.d, v1.d, v2.d, v3.d }[0], [x3]	/* D4 */
-	ret
-13:	st3	{ v0.d, v1.d, v2.d }[0], [x3]	/* D3 */
-	ret
-14:	stp	d0, d1, [x3]		/* D2 */
-	ret
-15:	str	d0, [x3]		/* D1 */
-	ret
-16:	str	q3, [x3, #48]		/* Q4 */
-	nop
-17:	str	q2, [x3, #32]		/* Q3 */
-	nop
-18:	stp	q0, q1, [x3]		/* Q2 */
-	ret
-19:	str	q0, [x3]		/* Q1 */
-	ret
-20:	uxtb	w0, w0			/* UINT8 */
-	str	x0, [x3]
-21:	ret				/* reserved */
-	nop
-22:	uxth	w0, w0			/* UINT16 */
-	str	x0, [x3]
-23:	ret				/* reserved */
-	nop
-24:	mov	w0, w0			/* UINT32 */
-	str	x0, [x3]
-25:	ret				/* reserved */
-	nop
-26:	sxtb	x0, w0			/* SINT8 */
-	str	x0, [x3]
-27:	ret				/* reserved */
-	nop
-28:	sxth	x0, w0			/* SINT16 */
-	str	x0, [x3]
-29:	ret				/* reserved */
-	nop
-30:	sxtw	x0, w0			/* SINT32 */
-	str	x0, [x3]
-31:	ret				/* reserved */
-	nop
+        ret
 
-	cfi_endproc
-
-	.globl	CNAME(ffi_call_SYSV)
-	FFI_HIDDEN(CNAME(ffi_call_SYSV))
+        .cfi_endproc
 #ifdef __ELF__
-	.type	CNAME(ffi_call_SYSV), #function
-	.size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV)
+        .size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV)
 #endif
 
+#define ffi_closure_SYSV_FS (8 * 2 + AARCH64_CALL_CONTEXT_SIZE)
+
 /* ffi_closure_SYSV
 
    Closure invocation glue. This is the low level code invoked directly by
    the closure trampoline to setup and call a closure.
 
-   On entry x17 points to a struct ffi_closure, x16 has been clobbered
+   On entry x17 points to a struct trampoline_data, x16 has been clobbered
    all other registers are preserved.
 
    We allocate a call context and save the argument passing registers,
    then invoked the generic C ffi_closure_SYSV_inner() function to do all
    the real work, on return we load the result passing registers back from
    the call context.
-*/
 
-#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64)
+   On entry
 
-	.align 4
-CNAME(ffi_closure_SYSV_V):
-	cfi_startproc
-	stp     x29, x30, [sp, #-ffi_closure_SYSV_FS]!
-	cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
-	cfi_rel_offset (x29, 0)
-	cfi_rel_offset (x30, 8)
+   extern void
+   ffi_closure_SYSV (struct trampoline_data *);
 
-	/* Save the argument passing vector registers.  */
-	stp     q0, q1, [sp, #16 + 0]
-	stp     q2, q3, [sp, #16 + 32]
-	stp     q4, q5, [sp, #16 + 64]
-	stp     q6, q7, [sp, #16 + 96]
-	b	0f
-	cfi_endproc
+   struct trampoline_data
+   {
+        UINT64 *ffi_closure;
+        UINT64 flags;
+   };
 
-	.globl	CNAME(ffi_closure_SYSV_V)
-	FFI_HIDDEN(CNAME(ffi_closure_SYSV_V))
-#ifdef __ELF__
-	.type	CNAME(ffi_closure_SYSV_V), #function
-	.size	CNAME(ffi_closure_SYSV_V), . - CNAME(ffi_closure_SYSV_V)
+   This function uses the following stack frame layout:
+
+   ==
+                saved x30(lr)
+   x29(fp)->    saved x29(fp)
+                saved x22
+                saved x21
+                ...
+   sp     ->    call_context
+   ==
+
+   Voila!  */
+
+        .text
+        .globl CNAME(ffi_closure_SYSV)
+#ifdef __APPLE__
+        .align 2
 #endif
-
-	.align	4
-	cfi_startproc
+        .cfi_startproc
 CNAME(ffi_closure_SYSV):
-	stp     x29, x30, [sp, #-ffi_closure_SYSV_FS]!
-	cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
-	cfi_rel_offset (x29, 0)
-	cfi_rel_offset (x30, 8)
-0:
-	mov     x29, sp
+        stp     x29, x30, [sp, #-16]!
+	cfi_adjust_cfa_offset (16)
+        cfi_rel_offset (x29, 0)
+        cfi_rel_offset (x30, 8)
 
-	/* Save the argument passing core registers.  */
-	stp     x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
-	stp     x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
-	stp     x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
-	stp     x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
+        mov     x29, sp
+        cfi_def_cfa_register (x29)
 
-	/* Load ffi_closure_inner arguments.  */
-	ldp	PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET]	/* load cif, fn */
-	ldr	PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2]	/* load user_data */
-.Ldo_closure:
-	add	x3, sp, #16				/* load context */
-	add	x4, sp, #ffi_closure_SYSV_FS		/* load stack */
-	add	x5, sp, #16+CALL_CONTEXT_SIZE		/* load rvalue */
-	mov	x6, x8					/* load struct_rval */
-	bl      CNAME(ffi_closure_SYSV_inner)
+        sub     sp, sp, #ffi_closure_SYSV_FS
 
-	/* Load the return value as directed.  */
-	adr	x1, 0f
-	and	w0, w0, #AARCH64_RET_MASK
-	add	x1, x1, x0, lsl #3
-	add	x3, sp, #16+CALL_CONTEXT_SIZE
-	br	x1
+        stp     x21, x22, [x29, #-16]
+        cfi_rel_offset (x21, -16)
+        cfi_rel_offset (x22, -8)
 
-	/* Note that each table entry is 2 insns, and thus 8 bytes.  */
-	.align	4
-0:	b	99f			/* VOID */
-	nop
-1:	ldr	x0, [x3]		/* INT64 */
-	b	99f
-2:	ldp	x0, x1, [x3]		/* INT128 */
-	b	99f
-3:	brk	#1000			/* UNUSED */
-	nop
-4:	brk	#1000			/* UNUSED */
-	nop
-5:	brk	#1000			/* UNUSED */
-	nop
-6:	brk	#1000			/* UNUSED */
-	nop
-7:	brk	#1000			/* UNUSED */
-	nop
-8:	ldr	s3, [x3, #12]		/* S4 */
-	nop
-9:	ldr	s2, [x3, #8]		/* S3 */
-	nop
-10:	ldp	s0, s1, [x3]		/* S2 */
-	b	99f
-11:	ldr	s0, [x3]		/* S1 */
-	b	99f
-12:	ldr	d3, [x3, #24]		/* D4 */
-	nop
-13:	ldr	d2, [x3, #16]		/* D3 */
-	nop
-14:	ldp	d0, d1, [x3]		/* D2 */
-	b	99f
-15:	ldr	d0, [x3]		/* D1 */
-	b	99f
-16:	ldr	q3, [x3, #48]		/* Q4 */
-	nop
-17:	ldr	q2, [x3, #32]		/* Q3 */
-	nop
-18:	ldp	q0, q1, [x3]		/* Q2 */
-	b	99f
-19:	ldr	q0, [x3]		/* Q1 */
-	b	99f
-20:	ldrb	w0, [x3, #BE(7)]	/* UINT8 */
-	b	99f
-21:	brk	#1000			/* reserved */
-	nop
-22:	ldrh	w0, [x3, #BE(6)]	/* UINT16 */
-	b	99f
-23:	brk	#1000			/* reserved */
-	nop
-24:	ldr	w0, [x3, #BE(4)]	/* UINT32 */
-	b	99f
-25:	brk	#1000			/* reserved */
-	nop
-26:	ldrsb	x0, [x3, #BE(7)]	/* SINT8 */
-	b	99f
-27:	brk	#1000			/* reserved */
-	nop
-28:	ldrsh	x0, [x3, #BE(6)]	/* SINT16 */
-	b	99f
-29:	brk	#1000			/* reserved */
-	nop
-30:	ldrsw	x0, [x3, #BE(4)]	/* SINT32 */
-	nop
-31:					/* reserved */
-99:	ldp     x29, x30, [sp], #ffi_closure_SYSV_FS
-	cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS)
-	cfi_restore (x29)
-	cfi_restore (x30)
-	ret
-	cfi_endproc
+        /* Load x21 with &call_context.  */
+        mov     x21, sp
+        /* Preserve our struct trampoline_data *  */
+        mov     x22, x17
 
-	.globl	CNAME(ffi_closure_SYSV)
-	FFI_HIDDEN(CNAME(ffi_closure_SYSV))
+        /* Save the rest of the argument passing registers.  */
+        stp     x0, x1, [x21, #0]
+        stp     x2, x3, [x21, #16]
+        stp     x4, x5, [x21, #32]
+        stp     x6, x7, [x21, #48]
+        /* Don't forget we may have been given a result scratch pad address.
+	 */
+        str     x8,     [x21, #64]
+
+        /* Figure out if we should touch the vector registers.  */
+        ldr     x0, [x22, #8]
+        tbz     x0, #AARCH64_FFI_WITH_V_BIT, 1f
+
+        /* Save the argument passing vector registers.  */
+        stp     q0, q1, [x21, #8*32 + 0]
+        stp     q2, q3, [x21, #8*32 + 32]
+        stp     q4, q5, [x21, #8*32 + 64]
+        stp     q6, q7, [x21, #8*32 + 96]
+1:
+        /* Load &ffi_closure..  */
+        ldr     x0, [x22, #0]
+        mov     x1, x21
+        /* Compute the location of the stack at the point that the
+           trampoline was called.  */
+        add     x2, x29, #16
+
+        bl      CNAME(ffi_closure_SYSV_inner)
+
+        /* Figure out if we should touch the vector registers.  */
+        ldr     x0, [x22, #8]
+        tbz     x0, #AARCH64_FFI_WITH_V_BIT, 1f
+
+        /* Load the result passing vector registers.  */
+        ldp     q0, q1, [x21, #8*32 + 0]
+        ldp     q2, q3, [x21, #8*32 + 32]
+        ldp     q4, q5, [x21, #8*32 + 64]
+        ldp     q6, q7, [x21, #8*32 + 96]
+1:
+        /* Load the result passing core registers.  */
+        ldp     x0, x1, [x21,  #0]
+        ldp     x2, x3, [x21, #16]
+        ldp     x4, x5, [x21, #32]
+        ldp     x6, x7, [x21, #48]
+        /* Note nothing useful is returned in x8.  */
+
+        /* We are done, unwind our frame.  */
+        ldp     x21, x22, [x29,  #-16]
+        cfi_restore (x21)
+        cfi_restore (x22)
+
+        mov     sp, x29
+        cfi_def_cfa_register (sp)
+
+        ldp     x29, x30, [sp], #16
+	cfi_adjust_cfa_offset (-16)
+        cfi_restore (x29)
+        cfi_restore (x30)
+
+        ret
+        .cfi_endproc
 #ifdef __ELF__
-	.type	CNAME(ffi_closure_SYSV), #function
-	.size	CNAME(ffi_closure_SYSV), . - CNAME(ffi_closure_SYSV)
+        .size CNAME(ffi_closure_SYSV), .-CNAME(ffi_closure_SYSV)
 #endif
-
-#if FFI_EXEC_TRAMPOLINE_TABLE
-
-#ifdef __MACH__
-#include <mach/machine/vm_param.h>
-    .align PAGE_MAX_SHIFT
-CNAME(ffi_closure_trampoline_table_page):
-    .rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
-    adr x16, -PAGE_MAX_SIZE
-    ldp x17, x16, [x16]
-    br x16
-	nop		/* each entry in the trampoline config page is 2*sizeof(void*) so the trampoline itself cannot be smaller that 16 bytes */
-    .endr
-
-    .globl CNAME(ffi_closure_trampoline_table_page)
-    FFI_HIDDEN(CNAME(ffi_closure_trampoline_table_page))
-    #ifdef __ELF__
-    	.type	CNAME(ffi_closure_trampoline_table_page), #function
-    	.size	CNAME(ffi_closure_trampoline_table_page), . - CNAME(ffi_closure_trampoline_table_page)
-    #endif
-#endif
-
-#endif /* FFI_EXEC_TRAMPOLINE_TABLE */
-
-#ifdef FFI_GO_CLOSURES
-	.align 4
-CNAME(ffi_go_closure_SYSV_V):
-	cfi_startproc
-	stp     x29, x30, [sp, #-ffi_closure_SYSV_FS]!
-	cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
-	cfi_rel_offset (x29, 0)
-	cfi_rel_offset (x30, 8)
-
-	/* Save the argument passing vector registers.  */
-	stp     q0, q1, [sp, #16 + 0]
-	stp     q2, q3, [sp, #16 + 32]
-	stp     q4, q5, [sp, #16 + 64]
-	stp     q6, q7, [sp, #16 + 96]
-	b	0f
-	cfi_endproc
-
-	.globl	CNAME(ffi_go_closure_SYSV_V)
-	FFI_HIDDEN(CNAME(ffi_go_closure_SYSV_V))
-#ifdef __ELF__
-	.type	CNAME(ffi_go_closure_SYSV_V), #function
-	.size	CNAME(ffi_go_closure_SYSV_V), . - CNAME(ffi_go_closure_SYSV_V)
-#endif
-
-	.align	4
-	cfi_startproc
-CNAME(ffi_go_closure_SYSV):
-	stp     x29, x30, [sp, #-ffi_closure_SYSV_FS]!
-	cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
-	cfi_rel_offset (x29, 0)
-	cfi_rel_offset (x30, 8)
-0:
-	mov     x29, sp
-
-	/* Save the argument passing core registers.  */
-	stp     x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
-	stp     x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
-	stp     x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
-	stp     x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
-
-	/* Load ffi_closure_inner arguments.  */
-	ldp	PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */
-	mov	x2, x18					/* load user_data */
-	b	.Ldo_closure
-	cfi_endproc
-
-	.globl	CNAME(ffi_go_closure_SYSV)
-	FFI_HIDDEN(CNAME(ffi_go_closure_SYSV))
-#ifdef __ELF__
-	.type	CNAME(ffi_go_closure_SYSV), #function
-	.size	CNAME(ffi_go_closure_SYSV), . - CNAME(ffi_go_closure_SYSV)
-#endif
-#endif /* FFI_GO_CLOSURES */
-#endif /* __arm64__ */
-
-#if defined __ELF__ && defined __linux__
-	.section .note.GNU-stack,"",%progbits
-#endif
-
diff --git a/src/aarch64/win64_armasm.S b/src/aarch64/win64_armasm.S
deleted file mode 100644
index a79f8a8..0000000
--- a/src/aarch64/win64_armasm.S
+++ /dev/null
@@ -1,506 +0,0 @@
-/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-``Software''), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
-
-#define LIBFFI_ASM
-#include <fficonfig.h>
-#include <ffi.h>
-#include <ffi_cfi.h>
-#include "internal.h"
-
-	OPT	2 /*disable listing */
-/* For some macros to add unwind information */
-#include "ksarm64.h"
-	OPT	1 /*re-enable listing */
-
-#define BE(X)	0
-#define PTR_REG(n)      x##n
-#define PTR_SIZE	8
-
-	IMPORT ffi_closure_SYSV_inner
-	EXPORT	ffi_call_SYSV
-	EXPORT	ffi_closure_SYSV_V
-	EXPORT	ffi_closure_SYSV
-	EXPORT	extend_hfa_type
-	EXPORT	compress_hfa_type
-#ifdef FFI_GO_CLOSURES
-	EXPORT	ffi_go_closure_SYSV_V
-	EXPORT	ffi_go_closure_SYSV
-#endif
-
-	TEXTAREA, ALLIGN=8
-
-/* ffi_call_SYSV
-   extern void ffi_call_SYSV (void *stack, void *frame,
-			      void (*fn)(void), void *rvalue,
-			      int flags, void *closure);
-   Therefore on entry we have:
-   x0 stack
-   x1 frame
-   x2 fn
-   x3 rvalue
-   x4 flags
-   x5 closure
-*/
-
-	NESTED_ENTRY ffi_call_SYSV_fake
-
-	/* For unwind information, Windows has to store fp and lr  */
-	PROLOG_SAVE_REG_PAIR	x29, x30, #-32!
-
-	ALTERNATE_ENTRY ffi_call_SYSV
-	/* Use a stack frame allocated by our caller. */
-	stp	x29, x30, [x1]
-	mov	x29, x1
-	mov	sp, x0
-
-	mov	x9, x2			/* save fn */
-	mov	x8, x3			/* install structure return */
-#ifdef FFI_GO_CLOSURES
-	/*mov	x18, x5			install static chain */
-#endif
-	stp	x3, x4, [x29, #16]	/* save rvalue and flags */
-	
-	/* Load the vector argument passing registers, if necessary.  */
-	tbz	x4, #AARCH64_FLAG_ARG_V_BIT, ffi_call_SYSV_L1
-	ldp	q0, q1, [sp, #0]
-	ldp	q2, q3, [sp, #32]
-	ldp	q4, q5, [sp, #64]
-	ldp	q6, q7, [sp, #96]
-
-ffi_call_SYSV_L1
-	/* Load the core argument passing registers, including
-	   the structure return pointer.  */
-	ldp     x0, x1, [sp, #16*N_V_ARG_REG + 0]
-	ldp     x2, x3, [sp, #16*N_V_ARG_REG + 16]
-	ldp     x4, x5, [sp, #16*N_V_ARG_REG + 32]
-	ldp     x6, x7, [sp, #16*N_V_ARG_REG + 48]
-
-	/* Deallocate the context, leaving the stacked arguments.  */
-	add	sp, sp, #CALL_CONTEXT_SIZE	
-
-	blr     x9			/* call fn */
-
-	ldp	x3, x4, [x29, #16]	/* reload rvalue and flags */
-
-	/* Partially deconstruct the stack frame. */
-	mov     sp, x29 
-	ldp     x29, x30, [x29]
-
-	/* Save the return value as directed.  */
-	adr	x5, ffi_call_SYSV_return
-	and	w4, w4, #AARCH64_RET_MASK
-	add	x5, x5, x4, lsl #3
-	br	x5
-	
-	/* Note that each table entry is 2 insns, and thus 8 bytes.
-	   For integer data, note that we're storing into ffi_arg
-	   and therefore we want to extend to 64 bits; these types
-	   have two consecutive entries allocated for them.  */
-	ALIGN 4
-ffi_call_SYSV_return
-	ret				/* VOID */
-	nop
-	str	x0, [x3]		/* INT64 */
-	ret
-	stp	x0, x1, [x3]		/* INT128 */
-	ret
-	brk	#1000			/* UNUSED */
-	ret
-	brk	#1000			/* UNUSED */
-	ret
-	brk	#1000			/* UNUSED */
-	ret
-	brk	#1000			/* UNUSED */
-	ret
-	brk	#1000			/* UNUSED */
-	ret
-	st4	{ v0.s, v1.s, v2.s, v3.s }[0], [x3]	/* S4 */
-	ret
-	st3	{ v0.s, v1.s, v2.s }[0], [x3]	/* S3 */
-	ret
-	stp	s0, s1, [x3]		/* S2 */
-	ret
-	str	s0, [x3]		/* S1 */
-	ret
-	st4	{ v0.d, v1.d, v2.d, v3.d }[0], [x3]	/* D4 */
-	ret
-	st3	{ v0.d, v1.d, v2.d }[0], [x3]	/* D3 */
-	ret
-	stp	d0, d1, [x3]		/* D2 */
-	ret
-	str	d0, [x3]		/* D1 */
-	ret
-	str	q3, [x3, #48]		/* Q4 */
-	nop
-	str	q2, [x3, #32]		/* Q3 */
-	nop
-	stp	q0, q1, [x3]		/* Q2 */
-	ret
-	str	q0, [x3]		/* Q1 */
-	ret
-	uxtb	w0, w0			/* UINT8 */
-	str	x0, [x3]
-	ret				/* reserved */
-	nop
-	uxth	w0, w0			/* UINT16 */
-	str	x0, [x3]
-	ret				/* reserved */
-	nop
-	mov	w0, w0			/* UINT32 */
-	str	x0, [x3]
-	ret				/* reserved */
-	nop
-	sxtb	x0, w0			/* SINT8 */
-	str	x0, [x3]
-	ret				/* reserved */
-	nop
-	sxth	x0, w0			/* SINT16 */
-	str	x0, [x3]
-	ret				/* reserved */
-	nop
-	sxtw	x0, w0			/* SINT32 */
-	str	x0, [x3]
-	ret				/* reserved */
-	nop
-	
-	
-	NESTED_END ffi_call_SYSV_fake
-	
-
-/* ffi_closure_SYSV
-   Closure invocation glue. This is the low level code invoked directly by
-   the closure trampoline to setup and call a closure.
-   On entry x17 points to a struct ffi_closure, x16 has been clobbered
-   all other registers are preserved.
-   We allocate a call context and save the argument passing registers,
-   then invoked the generic C ffi_closure_SYSV_inner() function to do all
-   the real work, on return we load the result passing registers back from
-   the call context.
-*/
-
-#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64)
-
-	NESTED_ENTRY	ffi_closure_SYSV_V
-	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!
-
-	/* Save the argument passing vector registers.  */
-	stp	q0, q1, [sp, #16 + 0]
-	stp	q2, q3, [sp, #16 + 32]
-	stp	q4, q5, [sp, #16 + 64]
-	stp	q6, q7, [sp, #16 + 96]
-
-	b	ffi_closure_SYSV_save_argument
-	NESTED_END	ffi_closure_SYSV_V
-
-	NESTED_ENTRY	ffi_closure_SYSV
-	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!
-
-ffi_closure_SYSV_save_argument
-	/* Save the argument passing core registers.  */
-	stp     x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
-	stp     x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
-	stp     x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
-	stp     x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
-
-	/* Load ffi_closure_inner arguments.  */
-	ldp	PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET]	/* load cif, fn */
-	ldr	PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2]	/* load user_data */
-
-do_closure
-	add	x3, sp, #16							/* load context */
-	add	x4, sp, #ffi_closure_SYSV_FS		/* load stack */
-	add	x5, sp, #16+CALL_CONTEXT_SIZE		/* load rvalue */
-	mov	x6, x8					/* load struct_rval */
-
-	bl	ffi_closure_SYSV_inner
-
-	/* Load the return value as directed.  */
-	adr	x1, ffi_closure_SYSV_return_base
-	and	w0, w0, #AARCH64_RET_MASK
-	add	x1, x1, x0, lsl #3
-	add	x3, sp, #16+CALL_CONTEXT_SIZE
-	br	x1
-
-	/* Note that each table entry is 2 insns, and thus 8 bytes.  */
-	ALIGN	8
-ffi_closure_SYSV_return_base
-	b	ffi_closure_SYSV_epilog			/* VOID */
-	nop
-	ldr	x0, [x3]		/* INT64 */
-	b	ffi_closure_SYSV_epilog
-	ldp	x0, x1, [x3]		/* INT128 */
-	b	ffi_closure_SYSV_epilog
-	brk	#1000			/* UNUSED */
-	nop
-	brk	#1000			/* UNUSED */
-	nop
-	brk	#1000			/* UNUSED */
-	nop
-	brk	#1000			/* UNUSED */
-	nop
-	brk	#1000			/* UNUSED */
-	nop
-	ldr	s3, [x3, #12]		/* S4 */
-	nop
-	ldr	s2, [x3, #8]		/* S3 */
-	nop
-	ldp	s0, s1, [x3]		/* S2 */
-	b	ffi_closure_SYSV_epilog
-	ldr	s0, [x3]		/* S1 */
-	b	ffi_closure_SYSV_epilog
-	ldr	d3, [x3, #24]		/* D4 */
-	nop
-	ldr	d2, [x3, #16]		/* D3 */
-	nop
-	ldp	d0, d1, [x3]		/* D2 */
-	b	ffi_closure_SYSV_epilog
-	ldr	d0, [x3]		/* D1 */
-	b	ffi_closure_SYSV_epilog
-	ldr	q3, [x3, #48]		/* Q4 */
-	nop
-	ldr	q2, [x3, #32]		/* Q3 */
-	nop
-	ldp	q0, q1, [x3]		/* Q2 */
-	b	ffi_closure_SYSV_epilog
-	ldr	q0, [x3]		/* Q1 */
-	b	ffi_closure_SYSV_epilog
-	ldrb	w0, [x3, #BE(7)]	/* UINT8 */
-	b	ffi_closure_SYSV_epilog
-	brk	#1000			/* reserved */
-	nop
-	ldrh	w0, [x3, #BE(6)]	/* UINT16 */
-	b	ffi_closure_SYSV_epilog
-	brk	#1000			/* reserved */
-	nop
-	ldr	w0, [x3, #BE(4)]	/* UINT32 */
-	b	ffi_closure_SYSV_epilog
-	brk	#1000			/* reserved */
-	nop
-	ldrsb	x0, [x3, #BE(7)]	/* SINT8 */
-	b	ffi_closure_SYSV_epilog
-	brk	#1000			/* reserved */
-	nop
-	ldrsh	x0, [x3, #BE(6)]	/* SINT16 */
-	b	ffi_closure_SYSV_epilog
-	brk	#1000			/* reserved */
-	nop
-	ldrsw	x0, [x3, #BE(4)]	/* SINT32 */
-	nop
-					/* reserved */
-
-ffi_closure_SYSV_epilog
-	EPILOG_RESTORE_REG_PAIR	x29, x30, #ffi_closure_SYSV_FS!
-	EPILOG_RETURN
-	NESTED_END	ffi_closure_SYSV
-
-
-#ifdef FFI_GO_CLOSURES
-	NESTED_ENTRY	ffi_go_closure_SYSV_V
-	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!
-
-	/* Save the argument passing vector registers.  */
-	stp	q0, q1, [sp, #16 + 0]
-	stp	q2, q3, [sp, #16 + 32]
-	stp	q4, q5, [sp, #16 + 64]
-	stp	q6, q7, [sp, #16 + 96]
-	b	ffi_go_closure_SYSV_save_argument
-	NESTED_END	ffi_go_closure_SYSV_V
-
-	NESTED_ENTRY	ffi_go_closure_SYSV
-	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!
-
-ffi_go_closure_SYSV_save_argument
-	/* Save the argument passing core registers.  */
-	stp     x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
-	stp     x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
-	stp     x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
-	stp     x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
-
-	/* Load ffi_closure_inner arguments.  */
-	ldp	PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */
-	mov	x2, x18					/* load user_data */
-	b	do_closure
-	NESTED_END	ffi_go_closure_SYSV
-
-#endif /* FFI_GO_CLOSURES */
-
-
-/* void extend_hfa_type (void *dest, void *src, int h) */
-
-	LEAF_ENTRY	extend_hfa_type
-
-	adr	x3, extend_hfa_type_jump_base
-	and	w2, w2, #AARCH64_RET_MASK
-	sub	x2, x2, #AARCH64_RET_S4
-	add	x3, x3, x2, lsl #4
-	br	x3
-
-	ALIGN	4
-extend_hfa_type_jump_base
-	ldp	s16, s17, [x1]		/* S4 */
-	ldp	s18, s19, [x1, #8]
-	b	extend_hfa_type_store_4
-	nop
-
-	ldp	s16, s17, [x1]		/* S3 */
-	ldr	s18, [x1, #8]
-	b	extend_hfa_type_store_3
-	nop
-
-	ldp	s16, s17, [x1]		/* S2 */
-	b	extend_hfa_type_store_2
-	nop
-	nop
-
-	ldr	s16, [x1]		/* S1 */
-	b	extend_hfa_type_store_1
-	nop
-	nop
-
-	ldp	d16, d17, [x1]		/* D4 */
-	ldp	d18, d19, [x1, #16]
-	b       extend_hfa_type_store_4
-	nop
-
-	ldp     d16, d17, [x1]		/* D3 */
-	ldr     d18, [x1, #16]
-	b	extend_hfa_type_store_3
-	nop
-
-	ldp	d16, d17, [x1]		/* D2 */
-	b	extend_hfa_type_store_2
-	nop
-	nop
-
-	ldr	d16, [x1]		/* D1 */
-	b	extend_hfa_type_store_1
-	nop
-	nop
-
-	ldp	q16, q17, [x1]		/* Q4 */
-	ldp	q18, q19, [x1, #16]
-	b	extend_hfa_type_store_4
-	nop
-
-	ldp	q16, q17, [x1]		/* Q3 */
-	ldr	q18, [x1, #16]
-	b	extend_hfa_type_store_3
-	nop
-
-	ldp	q16, q17, [x1]		/* Q2 */
-	b	extend_hfa_type_store_2
-	nop
-	nop
-
-	ldr	q16, [x1]		/* Q1 */
-	b	extend_hfa_type_store_1
-
-extend_hfa_type_store_4
-	str	q19, [x0, #48]
-extend_hfa_type_store_3
-	str	q18, [x0, #32]
-extend_hfa_type_store_2
-	str	q17, [x0, #16]
-extend_hfa_type_store_1
-	str	q16, [x0]
-	ret
-
-	LEAF_END	extend_hfa_type
-
-
-/* void compress_hfa_type (void *dest, void *reg, int h) */
-
-	LEAF_ENTRY	compress_hfa_type
-
-	adr	x3, compress_hfa_type_jump_base
-	and	w2, w2, #AARCH64_RET_MASK
-	sub	x2, x2, #AARCH64_RET_S4
-	add	x3, x3, x2, lsl #4
-	br	x3
-
-	ALIGN	4
-compress_hfa_type_jump_base
-	ldp	q16, q17, [x1]		/* S4 */
-	ldp	q18, q19, [x1, #32]
-	st4	{ v16.s, v17.s, v18.s, v19.s }[0], [x0]
-	ret
-
-	ldp	q16, q17, [x1]		/* S3 */
-	ldr	q18, [x1, #32]
-	st3	{ v16.s, v17.s, v18.s }[0], [x0]
-	ret
-
-	ldp	q16, q17, [x1]		/* S2 */
-	st2	{ v16.s, v17.s }[0], [x0]
-	ret
-	nop
-
-	ldr	q16, [x1]		/* S1 */
-	st1	{ v16.s }[0], [x0]
-	ret
-	nop
-
-	ldp	q16, q17, [x1]		/* D4 */
-	ldp	q18, q19, [x1, #32]
-	st4	{ v16.d, v17.d, v18.d, v19.d }[0], [x0]
-	ret
-
-	ldp	q16, q17, [x1]		/* D3 */
-	ldr	q18, [x1, #32]
-	st3	{ v16.d, v17.d, v18.d }[0], [x0]
-	ret
-
-	ldp	q16, q17, [x1]		/* D2 */
-	st2	{ v16.d, v17.d }[0], [x0]
-	ret
-	nop
-
-	ldr	q16, [x1]		/* D1 */
-	st1	{ v16.d }[0], [x0]
-	ret
-	nop
-
-	ldp	q16, q17, [x1]		/* Q4 */
-	ldp	q18, q19, [x1, #32]
-	b	compress_hfa_type_store_q4
-	nop
-
-	ldp	q16, q17, [x1]		/* Q3 */
-	ldr	q18, [x1, #32]
-	b	compress_hfa_type_store_q3
-	nop
-
-	ldp	q16, q17, [x1]		/* Q2 */
-	stp	q16, q17, [x0]
-	ret
-	nop
-
-	ldr	q16, [x1]		/* Q1 */
-	str	q16, [x0]
-	ret
-
-compress_hfa_type_store_q4
-	str	q19, [x0, #48]
-compress_hfa_type_store_q3
-	str	q18, [x0, #32]
-	stp	q16, q17, [x0]
-	ret
-
-	LEAF_END	compress_hfa_type
-
-	END
\ No newline at end of file
diff --git a/src/alpha/ffi.c b/src/alpha/ffi.c
index 7a95e97..192f691 100644
--- a/src/alpha/ffi.c
+++ b/src/alpha/ffi.c
@@ -1,8 +1,8 @@
 /* -----------------------------------------------------------------------
    ffi.c - Copyright (c) 2012  Anthony Green
-	   Copyright (c) 1998, 2001, 2007, 2008  Red Hat, Inc.
-
-   Alpha Foreign Function Interface
+           Copyright (c) 1998, 2001, 2007, 2008  Red Hat, Inc.
+   
+   Alpha Foreign Function Interface 
 
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
@@ -28,7 +28,6 @@
 #include <ffi.h>
 #include <ffi_common.h>
 #include <stdlib.h>
-#include "internal.h"
 
 /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
    all further uses in this file will refer to the 128-bit type.  */
@@ -41,286 +40,135 @@
 # define FFI_TYPE_LONGDOUBLE 4
 #endif
 
-extern void ffi_call_osf(void *stack, void *frame, unsigned flags,
-			 void *raddr, void (*fn)(void), void *closure)
-	FFI_HIDDEN;
+extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void))
+  FFI_HIDDEN;
 extern void ffi_closure_osf(void) FFI_HIDDEN;
-extern void ffi_go_closure_osf(void) FFI_HIDDEN;
 
-/* Promote a float value to its in-register double representation.
-   Unlike actually casting to double, this does not trap on NaN.  */
-static inline UINT64 lds(void *ptr)
-{
-  UINT64 ret;
-  asm("lds %0,%1" : "=f"(ret) : "m"(*(UINT32 *)ptr));
-  return ret;
-}
 
-/* And the reverse.  */
-static inline void sts(void *ptr, UINT64 val)
-{
-  asm("sts %1,%0" : "=m"(*(UINT32 *)ptr) : "f"(val));
-}
-
-ffi_status FFI_HIDDEN
+ffi_status
 ffi_prep_cif_machdep(ffi_cif *cif)
 {
-  size_t bytes = 0;
-  int flags, i, avn;
-  ffi_type *rtype, *itype;
-
-  if (cif->abi != FFI_OSF)
-    return FFI_BAD_ABI;
-
-  /* Compute the size of the argument area.  */
-  for (i = 0, avn = cif->nargs; i < avn; i++)
-    {
-      itype = cif->arg_types[i];
-      switch (itype->type)
-	{
-	case FFI_TYPE_INT:
-	case FFI_TYPE_SINT8:
-	case FFI_TYPE_UINT8:
-	case FFI_TYPE_SINT16:
-	case FFI_TYPE_UINT16:
-	case FFI_TYPE_SINT32:
-	case FFI_TYPE_UINT32:
-	case FFI_TYPE_SINT64:
-	case FFI_TYPE_UINT64:
-	case FFI_TYPE_POINTER:
-	case FFI_TYPE_FLOAT:
-	case FFI_TYPE_DOUBLE:
-	case FFI_TYPE_LONGDOUBLE:
-	  /* All take one 8 byte slot.  */
-	  bytes += 8;
-	  break;
-
-	case FFI_TYPE_VOID:
-	case FFI_TYPE_STRUCT:
-	  /* Passed by value in N slots.  */
-	  bytes += FFI_ALIGN(itype->size, FFI_SIZEOF_ARG);
-	  break;
-
-	case FFI_TYPE_COMPLEX:
-	  /* _Complex long double passed by reference; others in 2 slots.  */
-	  if (itype->elements[0]->type == FFI_TYPE_LONGDOUBLE)
-	    bytes += 8;
-	  else
-	    bytes += 16;
-	  break;
-
-	default:
-	  abort();
-	}
-    }
+  /* Adjust cif->bytes to represent a minimum 6 words for the temporary
+     register argument loading area.  */
+  if (cif->bytes < 6*FFI_SIZEOF_ARG)
+    cif->bytes = 6*FFI_SIZEOF_ARG;
 
   /* Set the return type flag */
-  rtype = cif->rtype;
-  switch (rtype->type)
+  switch (cif->rtype->type)
     {
-    case FFI_TYPE_VOID:
-      flags = ALPHA_FLAGS(ALPHA_ST_VOID, ALPHA_LD_VOID);
-      break;
-    case FFI_TYPE_INT:
-    case FFI_TYPE_UINT32:
-    case FFI_TYPE_SINT32:
-      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT32);
-      break;
-    case FFI_TYPE_FLOAT:
-      flags = ALPHA_FLAGS(ALPHA_ST_FLOAT, ALPHA_LD_FLOAT);
-      break;
-    case FFI_TYPE_DOUBLE:
-      flags = ALPHA_FLAGS(ALPHA_ST_DOUBLE, ALPHA_LD_DOUBLE);
-      break;
-    case FFI_TYPE_UINT8:
-      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT8);
-      break;
-    case FFI_TYPE_SINT8:
-      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT8);
-      break;
-    case FFI_TYPE_UINT16:
-      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT16);
-      break;
-    case FFI_TYPE_SINT16:
-      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT16);
-      break;
-    case FFI_TYPE_UINT64:
-    case FFI_TYPE_SINT64:
-    case FFI_TYPE_POINTER:
-      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT64);
-      break;
-    case FFI_TYPE_LONGDOUBLE:
     case FFI_TYPE_STRUCT:
-      /* Passed in memory, with a hidden pointer.  */
-      flags = ALPHA_RET_IN_MEM;
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+      cif->flags = cif->rtype->type;
       break;
-    case FFI_TYPE_COMPLEX:
-      itype = rtype->elements[0];
-      switch (itype->type)
-	{
-	case FFI_TYPE_FLOAT:
-	  flags = ALPHA_FLAGS(ALPHA_ST_CPLXF, ALPHA_LD_CPLXF);
-	  break;
-	case FFI_TYPE_DOUBLE:
-	  flags = ALPHA_FLAGS(ALPHA_ST_CPLXD, ALPHA_LD_CPLXD);
-	  break;
-	default:
-	  if (rtype->size <= 8)
-	    flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT64);
-	  else
-	    flags = ALPHA_RET_IN_MEM;
-	  break;
-	}
+
+    case FFI_TYPE_LONGDOUBLE:
+      /* 128-bit long double is returned in memory, like a struct.  */
+      cif->flags = FFI_TYPE_STRUCT;
       break;
+
     default:
-      abort();
+      cif->flags = FFI_TYPE_INT;
+      break;
     }
-  cif->flags = flags;
-
-  /* Include the hidden structure pointer in args requirement.  */
-  if (flags == ALPHA_RET_IN_MEM)
-    bytes += 8;
-  /* Minimum size is 6 slots, so that ffi_call_osf can pop them.  */
-  if (bytes < 6*8)
-    bytes = 6*8;
-  cif->bytes = bytes;
-
+  
   return FFI_OK;
 }
 
-static unsigned long
-extend_basic_type(void *valp, int type, int argn)
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
-  switch (type)
-    {
-    case FFI_TYPE_SINT8:
-      return *(SINT8 *)valp;
-    case FFI_TYPE_UINT8:
-      return *(UINT8 *)valp;
-    case FFI_TYPE_SINT16:
-      return *(SINT16 *)valp;
-    case FFI_TYPE_UINT16:
-      return *(UINT16 *)valp;
-
-    case FFI_TYPE_FLOAT:
-      if (argn < 6)
-	return lds(valp);
-      /* FALLTHRU */
-
-    case FFI_TYPE_INT:
-    case FFI_TYPE_SINT32:
-    case FFI_TYPE_UINT32:
-      /* Note that unsigned 32-bit quantities are sign extended.  */
-      return *(SINT32 *)valp;
-
-    case FFI_TYPE_SINT64:
-    case FFI_TYPE_UINT64:
-    case FFI_TYPE_POINTER:
-    case FFI_TYPE_DOUBLE:
-      return *(UINT64 *)valp;
-
-    default:
-      abort();
-    }
-}
-
-static void
-ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	      void **avalue, void *closure)
-{
-  unsigned long *argp;
-  long i, avn, argn, flags = cif->flags;
+  unsigned long *stack, *argp;
+  long i, avn;
   ffi_type **arg_types;
-  void *frame;
-
+  
   /* 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 && flags == ALPHA_RET_IN_MEM)
+  if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
     rvalue = alloca(cif->rtype->size);
 
   /* Allocate the space for the arguments, plus 4 words of temp
      space for ffi_call_osf.  */
-  argp = frame = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);
-  frame += cif->bytes;
+  argp = stack = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);
 
-  argn = 0;
-  if (flags == ALPHA_RET_IN_MEM)
-    argp[argn++] = (unsigned long)rvalue;
+  if (cif->flags == FFI_TYPE_STRUCT)
+    *(void **) argp++ = rvalue;
 
+  i = 0;
   avn = cif->nargs;
   arg_types = cif->arg_types;
 
-  for (i = 0, avn = cif->nargs; i < avn; i++)
+  while (i < avn)
     {
-      ffi_type *ty = arg_types[i];
-      void *valp = avalue[i];
-      int type = ty->type;
-      size_t size;
+      size_t size = (*arg_types)->size;
 
-      switch (type)
+      switch ((*arg_types)->type)
 	{
-	case FFI_TYPE_INT:
 	case FFI_TYPE_SINT8:
+	  *(SINT64 *) argp = *(SINT8 *)(* avalue);
+	  break;
+		  
 	case FFI_TYPE_UINT8:
+	  *(SINT64 *) argp = *(UINT8 *)(* avalue);
+	  break;
+		  
 	case FFI_TYPE_SINT16:
+	  *(SINT64 *) argp = *(SINT16 *)(* avalue);
+	  break;
+		  
 	case FFI_TYPE_UINT16:
+	  *(SINT64 *) argp = *(UINT16 *)(* avalue);
+	  break;
+		  
 	case FFI_TYPE_SINT32:
 	case FFI_TYPE_UINT32:
+	  /* Note that unsigned 32-bit quantities are sign extended.  */
+	  *(SINT64 *) argp = *(SINT32 *)(* avalue);
+	  break;
+		  
 	case FFI_TYPE_SINT64:
 	case FFI_TYPE_UINT64:
 	case FFI_TYPE_POINTER:
+	  *(UINT64 *) argp = *(UINT64 *)(* avalue);
+	  break;
+
 	case FFI_TYPE_FLOAT:
+	  if (argp - stack < 6)
+	    {
+	      /* Note the conversion -- all the fp regs are loaded as
+		 doubles.  The in-register format is the same.  */
+	      *(double *) argp = *(float *)(* avalue);
+	    }
+	  else
+	    *(float *) argp = *(float *)(* avalue);
+	  break;
+
 	case FFI_TYPE_DOUBLE:
-	  argp[argn] = extend_basic_type(valp, type, argn);
-	  argn++;
+	  *(double *) argp = *(double *)(* avalue);
 	  break;
 
 	case FFI_TYPE_LONGDOUBLE:
-	by_reference:
-	  /* Note that 128-bit long double is passed by reference.  */
-	  argp[argn++] = (unsigned long)valp;
+	  /* 128-bit long double is passed by reference.  */
+	  *(long double **) argp = (long double *)(* avalue);
+	  size = sizeof (long double *);
 	  break;
 
-	case FFI_TYPE_VOID:
 	case FFI_TYPE_STRUCT:
-	  size = ty->size;
-	  memcpy(argp + argn, valp, size);
-	  argn += FFI_ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
-	  break;
-
-	case FFI_TYPE_COMPLEX:
-	  type = ty->elements[0]->type;
-	  if (type == FFI_TYPE_LONGDOUBLE)
-	    goto by_reference;
-
-	  /* Most complex types passed as two separate arguments.  */
-	  size = ty->elements[0]->size;
-	  argp[argn] = extend_basic_type(valp, type, argn);
-	  argp[argn + 1] = extend_basic_type(valp + size, type, argn + 1);
-	  argn += 2;
+	  memcpy(argp, *avalue, (*arg_types)->size);
 	  break;
 
 	default:
-	  abort();
+	  FFI_ASSERT(0);
 	}
+
+      argp += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+      i++, arg_types++, avalue++;
     }
 
-  flags = (flags >> ALPHA_ST_SHIFT) & 0xff;
-  ffi_call_osf(argp, frame, flags, rvalue, fn, closure);
+  ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn);
 }
 
-void
-ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
-{
-  ffi_call_int(cif, fn, rvalue, avalue, NULL);
-}
-
-void
-ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	     void **avalue, void *closure)
-{
-  ffi_call_int(cif, fn, rvalue, avalue, closure);
-}
 
 ffi_status
 ffi_prep_closure_loc (ffi_closure* closure,
@@ -356,56 +204,39 @@
   return FFI_OK;
 }
 
-ffi_status
-ffi_prep_go_closure (ffi_go_closure* closure,
-		     ffi_cif* cif,
-		     void (*fun)(ffi_cif*, void*, void**, void*))
-{
-  if (cif->abi != FFI_OSF)
-    return FFI_BAD_ABI;
-
-  closure->tramp = (void *)ffi_go_closure_osf;
-  closure->cif = cif;
-  closure->fun = fun;
-
-  return FFI_OK;
-}
 
 long FFI_HIDDEN
-ffi_closure_osf_inner (ffi_cif *cif,
-		       void (*fun)(ffi_cif*, void*, void**, void*),
-		       void *user_data,
-		       void *rvalue, unsigned long *argp)
+ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
 {
+  ffi_cif *cif;
   void **avalue;
   ffi_type **arg_types;
-  long i, avn, argn, flags;
+  long i, avn, argn;
 
+  cif = closure->cif;
   avalue = alloca(cif->nargs * sizeof(void *));
-  flags = cif->flags;
+
   argn = 0;
 
   /* Copy the caller's structure return address to that the closure
      returns the data directly to the caller.  */
-  if (flags == ALPHA_RET_IN_MEM)
+  if (cif->flags == FFI_TYPE_STRUCT)
     {
       rvalue = (void *) argp[0];
       argn = 1;
     }
 
+  i = 0;
+  avn = cif->nargs;
   arg_types = cif->arg_types;
-
+  
   /* Grab the addresses of the arguments from the stack frame.  */
-  for (i = 0, avn = cif->nargs; i < avn; i++)
+  while (i < avn)
     {
-      ffi_type *ty = arg_types[i];
-      int type = ty->type;
-      void *valp = &argp[argn];
-      size_t size;
+      size_t size = arg_types[i]->size;
 
-      switch (type)
+      switch (arg_types[i]->type)
 	{
-	case FFI_TYPE_INT:
 	case FFI_TYPE_SINT8:
 	case FFI_TYPE_UINT8:
 	case FFI_TYPE_SINT16:
@@ -415,107 +246,43 @@
 	case FFI_TYPE_SINT64:
 	case FFI_TYPE_UINT64:
 	case FFI_TYPE_POINTER:
-	  argn += 1;
-	  break;
-
-	case FFI_TYPE_VOID:
 	case FFI_TYPE_STRUCT:
-	  size = ty->size;
-	  argn += FFI_ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	  avalue[i] = &argp[argn];
 	  break;
 
 	case FFI_TYPE_FLOAT:
-	  /* Floats coming from registers need conversion from double
-	     back to float format.  */
 	  if (argn < 6)
 	    {
-	      valp = &argp[argn - 6];
-	      sts(valp, argp[argn - 6]);
+	      /* Floats coming from registers need conversion from double
+	         back to float format.  */
+	      *(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
+	      avalue[i] = &argp[argn - 6];
 	    }
-	  argn += 1;
+	  else
+	    avalue[i] = &argp[argn];
 	  break;
 
 	case FFI_TYPE_DOUBLE:
-	  if (argn < 6)
-	    valp = &argp[argn - 6];
-	  argn += 1;
+	  avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
 	  break;
 
 	case FFI_TYPE_LONGDOUBLE:
-	by_reference:
 	  /* 128-bit long double is passed by reference.  */
-	  valp = (void *)argp[argn];
-	  argn += 1;
-	  break;
-
-	case FFI_TYPE_COMPLEX:
-	  type = ty->elements[0]->type;
-	  switch (type)
-	    {
-	    case FFI_TYPE_SINT64:
-	    case FFI_TYPE_UINT64:
-	      /* Passed as separate arguments, but they wind up sequential.  */
-	      break;
-
-	    case FFI_TYPE_INT:
-	    case FFI_TYPE_SINT8:
-	    case FFI_TYPE_UINT8:
-	    case FFI_TYPE_SINT16:
-	    case FFI_TYPE_UINT16:
-	    case FFI_TYPE_SINT32:
-	    case FFI_TYPE_UINT32:
-	      /* Passed as separate arguments.  Disjoint, but there's room
-		 enough in one slot to hold the pair.  */
-	      size = ty->elements[0]->size;
-	      memcpy(valp + size, valp + 8, size);
-	      break;
-
-	    case FFI_TYPE_FLOAT:
-	      /* Passed as separate arguments.  Disjoint, and each piece
-		 may need conversion back to float.  */
-	      if (argn < 6)
-		{
-		  valp = &argp[argn - 6];
-		  sts(valp, argp[argn - 6]);
-		}
-	      if (argn + 1 < 6)
-		sts(valp + 4, argp[argn + 1 - 6]);
-	      else
-		*(UINT32 *)(valp + 4) = argp[argn + 1];
-	      break;
-
-	    case FFI_TYPE_DOUBLE:
-	      /* Passed as separate arguments.  Only disjoint if one part
-		 is in fp regs and the other is on the stack.  */
-	      if (argn < 5)
-		valp = &argp[argn - 6];
-	      else if (argn == 5)
-		{
-		  valp = alloca(16);
-		  ((UINT64 *)valp)[0] = argp[5 - 6];
-		  ((UINT64 *)valp)[1] = argp[6];
-		}
-	      break;
-
-	    case FFI_TYPE_LONGDOUBLE:
-	      goto by_reference;
-
-	    default:
-	      abort();
-	    }
-	  argn += 2;
+	  avalue[i] = (long double *) argp[argn];
+	  size = sizeof (long double *);
 	  break;
 
 	default:
 	  abort ();
 	}
 
-      avalue[i] = valp;
+      argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+      i++;
     }
 
   /* Invoke the closure.  */
-  fun (cif, rvalue, avalue, user_data);
+  closure->fun (cif, rvalue, avalue, closure->user_data);
 
   /* Tell ffi_closure_osf how to perform return type promotions.  */
-  return (flags >> ALPHA_LD_SHIFT) & 0xff;
+  return cif->rtype->type;
 }
diff --git a/src/alpha/ffitarget.h b/src/alpha/ffitarget.h
index a02dbd0..af145bc 100644
--- a/src/alpha/ffitarget.h
+++ b/src/alpha/ffitarget.h
@@ -44,13 +44,9 @@
 } ffi_abi;
 #endif
 
-#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
-#define FFI_TARGET_HAS_COMPLEX_TYPE
-
 /* ---- Definitions for closures ----------------------------------------- */
 
 #define FFI_CLOSURES 1
-#define FFI_GO_CLOSURES 1
 #define FFI_TRAMPOLINE_SIZE 24
 #define FFI_NATIVE_RAW_API 0
 
diff --git a/src/alpha/internal.h b/src/alpha/internal.h
deleted file mode 100644
index 44da192..0000000
--- a/src/alpha/internal.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#define ALPHA_ST_VOID	0
-#define ALPHA_ST_INT	1
-#define ALPHA_ST_FLOAT	2
-#define ALPHA_ST_DOUBLE	3
-#define ALPHA_ST_CPLXF	4
-#define ALPHA_ST_CPLXD	5
-
-#define ALPHA_LD_VOID	0
-#define ALPHA_LD_INT64	1
-#define ALPHA_LD_INT32	2
-#define ALPHA_LD_UINT16	3
-#define ALPHA_LD_SINT16	4
-#define ALPHA_LD_UINT8	5
-#define ALPHA_LD_SINT8	6
-#define ALPHA_LD_FLOAT	7
-#define ALPHA_LD_DOUBLE	8
-#define ALPHA_LD_CPLXF	9
-#define ALPHA_LD_CPLXD	10
-
-#define ALPHA_ST_SHIFT		0
-#define ALPHA_LD_SHIFT		8
-#define ALPHA_RET_IN_MEM	0x10000
-#define ALPHA_FLAGS(S, L)	(((L) << ALPHA_LD_SHIFT) | (S))
diff --git a/src/alpha/osf.S b/src/alpha/osf.S
index b031828..6b9f4df 100644
--- a/src/alpha/osf.S
+++ b/src/alpha/osf.S
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------
-   osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat
-
-   Alpha/OSF Foreign Function Interface
+   osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011 Red Hat
+   
+   Alpha/OSF Foreign Function Interface 
 
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
@@ -24,49 +24,40 @@
    DEALINGS IN THE SOFTWARE.
    ----------------------------------------------------------------------- */
 
-#define LIBFFI_ASM
+#define LIBFFI_ASM	
 #include <fficonfig.h>
 #include <ffi.h>
-#include <ffi_cfi.h>
-#include "internal.h"
 
 	.arch ev6
 	.text
 
-/* Aid in building a direct addressed jump table, 4 insns per entry.  */
-.macro E index
-	.align	4
-	.org	99b + \index * 16
-.endm
+/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
+		 void *raddr, void (*fnaddr)(void));
 
-/* ffi_call_osf (void *stack, void *frame, unsigned flags,
-		 void *raddr, void (*fnaddr)(void), void *closure)
-
-   Bit o trickiness here -- FRAME is the base of the stack frame
+   Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
    for this function.  This has been allocated by ffi_call.  We also
    deallocate some of the stack that has been alloca'd.  */
 
-	.align	4
+	.align	3
 	.globl	ffi_call_osf
 	.ent	ffi_call_osf
 	FFI_HIDDEN(ffi_call_osf)
 
 ffi_call_osf:
-	cfi_startproc
-	cfi_def_cfa($17, 32)
+	.frame	$15, 32, $26, 0
+	.mask   0x4008000, -32
+$LFB1:
+	addq	$16,$17,$1
 	mov	$16, $30
-	stq	$26, 0($17)
-	stq	$15, 8($17)
-	mov	$17, $15
+	stq	$26, 0($1)
+	stq	$15, 8($1)
+	stq	$18, 16($1)
+	mov	$1, $15
+$LCFI1:
 	.prologue 0
-	cfi_def_cfa_register($15)
-	cfi_rel_offset($26, 0)
-	cfi_rel_offset($15, 8)
 
-	stq	$18, 16($17)		# save flags into frame
-	stq	$19, 24($17)		# save rvalue into frame
-	mov	$20, $27		# fn into place for call
-	mov	$21, $1			# closure into static chain
+	stq	$19, 24($1)
+	mov	$20, $27
 
 	# Load up all of the (potential) argument registers.
 	ldq	$16, 0($30)
@@ -86,197 +77,311 @@
 	lda	$30, 48($30)
 
 	jsr	$26, ($27), 0
-0:
-	ldah	$29, 0($26)		!gpdisp!1
-	ldq	$2, 24($15)		# reload rvalue
-	lda	$29, 0($29)		!gpdisp!1
-	ldq	$3, 16($15)		# reload flags
-	lda	$1, 99f-0b($26)
+	ldgp	$29, 0($26)
+
+	# If the return value pointer is NULL, assume no return value.
+	ldq	$19, 24($15)
+	ldq	$18, 16($15)
 	ldq	$26, 0($15)
+$LCFI2:
+	beq	$19, $noretval
+
+	# Store the return value out in the proper type.
+	cmpeq	$18, FFI_TYPE_INT, $1
+	bne	$1, $retint
+	cmpeq	$18, FFI_TYPE_FLOAT, $2
+	bne	$2, $retfloat
+	cmpeq	$18, FFI_TYPE_DOUBLE, $3
+	bne	$3, $retdouble
+
+	.align	3
+$noretval:
 	ldq	$15, 8($15)
-	cfi_restore($26)
-	cfi_restore($15)
-	cfi_def_cfa($sp, 0)
-	cmoveq	$2, ALPHA_ST_VOID, $3	# mash null rvalue to void
-	addq	$3, $3, $3
-	s8addq	$3, $1, $1		# 99f + stcode * 16
-	jmp	$31, ($1), $st_int
+	ret
 
 	.align	4
-99:
-E ALPHA_ST_VOID
-	ret
-E ALPHA_ST_INT
-$st_int:
-	stq	$0, 0($2)
-	ret
-E ALPHA_ST_FLOAT
-	sts	$f0, 0($2)
-	ret
-E ALPHA_ST_DOUBLE
-	stt	$f0, 0($2)
-	ret
-E ALPHA_ST_CPLXF
-	sts	$f0, 0($2)
-	sts	$f1, 4($2)
-	ret
-E ALPHA_ST_CPLXD
-	stt	$f0, 0($2)
-	stt	$f1, 8($2)
+$retint:
+	stq	$0, 0($19)
+	nop
+	ldq	$15, 8($15)
 	ret
 
-	cfi_endproc
+	.align	4
+$retfloat:
+	sts	$f0, 0($19)
+	nop
+	ldq	$15, 8($15)
+	ret
+
+	.align	4
+$retdouble:
+	stt	$f0, 0($19)
+	nop
+	ldq	$15, 8($15)
+	ret
+$LFE1:
+
 	.end	ffi_call_osf
 
 /* ffi_closure_osf(...)
 
    Receives the closure argument in $1.   */
 
-#define CLOSURE_FS	(16*8)
-
-	.align	4
-	.globl	ffi_go_closure_osf
-	.ent	ffi_go_closure_osf
-	FFI_HIDDEN(ffi_go_closure_osf)
-
-ffi_go_closure_osf:
-	cfi_startproc
-	ldgp	$29, 0($27)
-	subq	$30, CLOSURE_FS, $30
-	cfi_adjust_cfa_offset(CLOSURE_FS)
-	stq	$26, 0($30)
-	.prologue 1
-	cfi_rel_offset($26, 0)
-
-	stq	$16, 10*8($30)
-	stq	$17, 11*8($30)
-	stq	$18, 12*8($30)
-
-	ldq	$16, 8($1)			# load cif
-	ldq	$17, 16($1)			# load fun
-	mov	$1, $18				# closure is user_data
-	br	$do_closure
-
-	cfi_endproc
-	.end	ffi_go_closure_osf
-
-	.align	4
+	.align	3
 	.globl	ffi_closure_osf
 	.ent	ffi_closure_osf
 	FFI_HIDDEN(ffi_closure_osf)
 
 ffi_closure_osf:
-	cfi_startproc
+	.frame	$30, 16*8, $26, 0
+	.mask	0x4000000, -16*8
+$LFB2:
 	ldgp	$29, 0($27)
-	subq	$30, CLOSURE_FS, $30
-	cfi_adjust_cfa_offset(CLOSURE_FS)
+	subq	$30, 16*8, $30
+$LCFI5:
 	stq	$26, 0($30)
+$LCFI6:
 	.prologue 1
-	cfi_rel_offset($26, 0)
 
 	# Store all of the potential argument registers in va_list format.
-	stq	$16, 10*8($30)
-	stq	$17, 11*8($30)
-	stq	$18, 12*8($30)
-
-	ldq	$16, 24($1)			# load cif
-	ldq	$17, 32($1)			# load fun
-	ldq	$18, 40($1)			# load user_data
-
-$do_closure:
-	stq	$19, 13*8($30)
-	stq	$20, 14*8($30)
-	stq	$21, 15*8($30)
 	stt	$f16, 4*8($30)
 	stt	$f17, 5*8($30)
 	stt	$f18, 6*8($30)
 	stt	$f19, 7*8($30)
 	stt	$f20, 8*8($30)
 	stt	$f21, 9*8($30)
+	stq	$16, 10*8($30)
+	stq	$17, 11*8($30)
+	stq	$18, 12*8($30)
+	stq	$19, 13*8($30)
+	stq	$20, 14*8($30)
+	stq	$21, 15*8($30)
 
 	# Call ffi_closure_osf_inner to do the bulk of the work.
-	lda	$19, 2*8($30)
-	lda	$20, 10*8($30)
+	mov	$1, $16
+	lda	$17, 2*8($30)
+	lda	$18, 10*8($30)
 	jsr	$26, ffi_closure_osf_inner
-0:
-	ldah	$29, 0($26)			!gpdisp!2
-	lda	$2, 99f-0b($26)
-	s4addq	$0, 0, $1			# ldcode * 4
-	ldq	$0, 16($30)			# preload return value
-	s4addq	$1, $2, $1			# 99f + ldcode * 16
-	lda	$29, 0($29)			!gpdisp!2
+	ldgp	$29, 0($26)
 	ldq	$26, 0($30)
-	cfi_restore($26)
+
+	# Load up the return value in the proper type.
+	lda	$1, $load_table
+	s4addq	$0, $1, $1
+	ldl	$1, 0($1)
+	addq	$1, $29, $1
 	jmp	$31, ($1), $load_32
 
-.macro epilogue
-	addq	$30, CLOSURE_FS, $30
-	cfi_adjust_cfa_offset(-CLOSURE_FS)
+	.align 4
+$load_none:
+	addq	$30, 16*8, $30
 	ret
-	.align	4
-	cfi_adjust_cfa_offset(CLOSURE_FS)
-.endm
 
 	.align 4
-99:
-E ALPHA_LD_VOID
-	epilogue
+$load_float:
+	lds	$f0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
 
-E ALPHA_LD_INT64
-	epilogue
+	.align 4
+$load_double:
+	ldt	$f0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
 
-E ALPHA_LD_INT32
-$load_32:
-	sextl	$0, $0
-	epilogue
-
-E ALPHA_LD_UINT16
-	zapnot	$0, 3, $0
-	epilogue
-
-E ALPHA_LD_SINT16
+	.align 4
+$load_u8:
 #ifdef __alpha_bwx__
-	sextw	$0, $0
+	ldbu	$0, 16($30)
+	nop
 #else
-	sll	$0, 48, $0
-	sra	$0, 48, $0
+	ldq	$0, 16($30)
+	and	$0, 255, $0
 #endif
-	epilogue
+	addq	$30, 16*8, $30
+	ret
 
-E ALPHA_LD_UINT8
-	and	$0, 0xff, $0
-	epilogue
-
-E ALPHA_LD_SINT8
+	.align 4
+$load_s8:
 #ifdef __alpha_bwx__
+	ldbu	$0, 16($30)
 	sextb	$0, $0
 #else
+	ldq	$0, 16($30)
 	sll	$0, 56, $0
 	sra	$0, 56, $0
 #endif
-	epilogue
+	addq	$30, 16*8, $30
+	ret
 
-E ALPHA_LD_FLOAT
-	lds	$f0, 16($sp)
-	epilogue
+	.align 4
+$load_u16:
+#ifdef __alpha_bwx__
+	ldwu	$0, 16($30)
+	nop
+#else
+	ldq	$0, 16($30)
+	zapnot	$0, 3, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
 
-E ALPHA_LD_DOUBLE
-	ldt	$f0, 16($sp)
-	epilogue
+	.align 4
+$load_s16:
+#ifdef __alpha_bwx__
+	ldwu	$0, 16($30)
+	sextw	$0, $0
+#else
+	ldq	$0, 16($30)
+	sll	$0, 48, $0
+	sra	$0, 48, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
 
-E ALPHA_LD_CPLXF
-	lds	$f0, 16($sp)
-	lds	$f1, 20($sp)
-	epilogue
+	.align 4
+$load_32:
+	ldl	$0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
 
-E ALPHA_LD_CPLXD
-	ldt	$f0, 16($sp)
-	ldt	$f1, 24($sp)
-	epilogue
+	.align 4
+$load_64:
+	ldq	$0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
+$LFE2:
 
-	cfi_endproc
 	.end	ffi_closure_osf
 
+#ifdef __ELF__
+.section .rodata
+#else
+.rdata
+#endif
+$load_table:
+	.gprel32 $load_none	# FFI_TYPE_VOID
+	.gprel32 $load_32	# FFI_TYPE_INT
+	.gprel32 $load_float	# FFI_TYPE_FLOAT
+	.gprel32 $load_double	# FFI_TYPE_DOUBLE
+	.gprel32 $load_none	# FFI_TYPE_LONGDOUBLE
+	.gprel32 $load_u8	# FFI_TYPE_UINT8
+	.gprel32 $load_s8	# FFI_TYPE_SINT8
+	.gprel32 $load_u16	# FFI_TYPE_UINT16
+	.gprel32 $load_s16	# FFI_TYPE_SINT16
+	.gprel32 $load_32	# FFI_TYPE_UINT32
+	.gprel32 $load_32	# FFI_TYPE_SINT32
+	.gprel32 $load_64	# FFI_TYPE_UINT64
+	.gprel32 $load_64	# FFI_TYPE_SINT64
+	.gprel32 $load_none	# FFI_TYPE_STRUCT
+	.gprel32 $load_64	# FFI_TYPE_POINTER
+
+/* Assert that the table above is in sync with ffi.h.  */
+
+#if	   FFI_TYPE_FLOAT != 2		\
+	|| FFI_TYPE_DOUBLE != 3		\
+	|| FFI_TYPE_UINT8 != 5		\
+	|| FFI_TYPE_SINT8 != 6		\
+	|| FFI_TYPE_UINT16 != 7		\
+	|| FFI_TYPE_SINT16 != 8		\
+	|| FFI_TYPE_UINT32 != 9		\
+	|| FFI_TYPE_SINT32 != 10	\
+	|| FFI_TYPE_UINT64 != 11	\
+	|| FFI_TYPE_SINT64 != 12	\
+	|| FFI_TYPE_STRUCT != 13	\
+	|| FFI_TYPE_POINTER != 14	\
+	|| FFI_TYPE_LAST != 14
+#error "osf.S out of sync with ffi.h"
+#endif
+
+#ifdef __ELF__
+# define UA_SI		.4byte
+# define FDE_ENCODING	0x1b	/* pcrel sdata4 */
+# define FDE_ENCODE(X)	.4byte X-.
+# define FDE_ARANGE(X)	.4byte X
+#elif defined __osf__
+# define UA_SI		.align 0; .long
+# define FDE_ENCODING	0x50	/* aligned absolute */
+# define FDE_ENCODE(X)	.align 3; .quad X
+# define FDE_ARANGE(X)	.align 0; .quad X
+#endif
+
+#ifdef __ELF__
+	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
+#elif defined __osf__
+	.data
+	.align 3
+	.globl _GLOBAL__F_ffi_call_osf
+_GLOBAL__F_ffi_call_osf:
+#endif
+__FRAME_BEGIN__:
+	UA_SI	$LECIE1-$LSCIE1	# Length of Common Information Entry
+$LSCIE1:
+	UA_SI	0x0		# CIE Identifier Tag
+	.byte	0x1		# CIE Version
+	.ascii "zR\0"		# CIE Augmentation
+	.byte	0x1		# uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x78		# sleb128 -8; CIE Data Alignment Factor
+	.byte	26		# CIE RA Column
+	.byte	0x1		# uleb128 0x1; Augmentation size
+	.byte	FDE_ENCODING	# FDE Encoding
+	.byte	0xc		# DW_CFA_def_cfa
+	.byte	30		# uleb128 column 30
+	.byte	0		# uleb128 offset 0
+	.align 3
+$LECIE1:
+$LSFDE1:
+	UA_SI	$LEFDE1-$LASFDE1		# FDE Length
+$LASFDE1:
+	UA_SI	$LASFDE1-__FRAME_BEGIN__	# FDE CIE offset
+	FDE_ENCODE($LFB1)			# FDE initial location
+	FDE_ARANGE($LFE1-$LFB1)			# FDE address range
+	.byte	0x0		# uleb128 0x0; Augmentation size
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	UA_SI	$LCFI1-$LFB1
+	.byte	0x9a		# DW_CFA_offset, column 26
+	.byte	4		# uleb128 4*-8
+	.byte	0x8f		# DW_CFA_offset, column 15
+	.byte	0x3		# uleb128 3*-8
+	.byte	0xc		# DW_CFA_def_cfa
+	.byte	15		# uleb128 column 15
+	.byte	32		# uleb128 offset 32
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	UA_SI	$LCFI2-$LCFI1
+	.byte	0xda		# DW_CFA_restore, column 26
+	.align 3
+$LEFDE1:
+
+$LSFDE3:
+	UA_SI	$LEFDE3-$LASFDE3		# FDE Length
+$LASFDE3:
+	UA_SI	$LASFDE3-__FRAME_BEGIN__	# FDE CIE offset
+	FDE_ENCODE($LFB2)			# FDE initial location
+	FDE_ARANGE($LFE2-$LFB2)			# FDE address range
+	.byte	0x0		# uleb128 0x0; Augmentation size
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	UA_SI	$LCFI5-$LFB2
+	.byte	0xe		# DW_CFA_def_cfa_offset
+	.byte	0x80,0x1	# uleb128 128
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	UA_SI	$LCFI6-$LCFI5
+	.byte	0x9a		# DW_CFA_offset, column 26
+	.byte	16		# uleb128 offset 16*-8
+	.align 3
+$LEFDE3:
+#if defined __osf__
+	.align 0
+	.long	0		# End of Table
+#endif
+
 #if defined __ELF__ && defined __linux__
 	.section	.note.GNU-stack,"",@progbits
 #endif
diff --git a/src/arc/ffi.c b/src/arc/ffi.c
index 4d10b21..32f82a7 100644
--- a/src/arc/ffi.c
+++ b/src/arc/ffi.c
@@ -46,10 +46,12 @@
 ffi_prep_args (char *stack, extended_cif * ecif)
 {
   unsigned int i;
+  int tmp;
   void **p_argv;
   char *argp;
   ffi_type **p_arg;
 
+  tmp = 0;
   argp = stack;
 
   if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
@@ -71,7 +73,7 @@
 
       /* Align if necessary.  */
       if ((alignment - 1) & (unsigned) argp)
-	argp = (char *) FFI_ALIGN (argp, alignment);
+	argp = (char *) ALIGN (argp, alignment);
 
       z = (*p_arg)->size;
       if (z < sizeof (int))
@@ -223,7 +225,7 @@
 
       /* Align if necessary.  */
       if ((alignment - 1) & (unsigned) argp)
-	argp = (char *) FFI_ALIGN (argp, alignment);
+	argp = (char *) ALIGN (argp, alignment);
 
       z = (*p_argt)->size;
       *p_argv = (void *) argp;
diff --git a/src/arm/ffi.c b/src/arm/ffi.c
index 4e27071..6691ab5 100644
--- a/src/arm/ffi.c
+++ b/src/arm/ffi.c
@@ -28,778 +28,856 @@
    DEALINGS IN THE SOFTWARE.
    ----------------------------------------------------------------------- */
 
-#if defined(__arm__) || defined(_M_ARM)
-#include <fficonfig.h>
 #include <ffi.h>
 #include <ffi_common.h>
-#include <stdint.h>
+
 #include <stdlib.h>
-#include "internal.h"
-
-#if defined(_MSC_VER) && defined(_M_ARM)
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-#if FFI_EXEC_TRAMPOLINE_TABLE
-
-#ifdef __MACH__
-#include <mach/machine/vm_param.h>
-#endif
-
-#else
-#ifndef _M_ARM
-extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN;
-#else
-extern unsigned int ffi_arm_trampoline[3] FFI_HIDDEN;
-#endif
-#endif
 
 /* Forward declares. */
-static int vfp_type_p (const ffi_type *);
+static int vfp_type_p (ffi_type *);
 static void layout_vfp_args (ffi_cif *);
 
-static void *
-ffi_align (ffi_type *ty, void *p)
+int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space);
+int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space);
+
+static char* ffi_align(ffi_type **p_arg, char *argp)
 {
   /* Align if necessary */
-  size_t alignment;
-#ifdef _WIN32_WCE
-  alignment = 4;
-#else
-  alignment = ty->alignment;
+  register size_t alignment = (*p_arg)->alignment;
   if (alignment < 4)
+  {
     alignment = 4;
+  }
+#ifdef _WIN32_WCE
+  if (alignment > 4)
+  {
+    alignment = 4;
+  }
 #endif
-  return (void *) FFI_ALIGN (p, alignment);
+  if ((alignment - 1) & (unsigned) argp)
+  {
+    argp = (char *) ALIGN(argp, alignment);
+  }
+
+  if ((*p_arg)->type == FFI_TYPE_STRUCT)
+  {
+    argp = (char *) ALIGN(argp, 4);
+  }
+  return argp;
 }
 
-static size_t
-ffi_put_arg (ffi_type *ty, void *src, void *dst)
+static size_t ffi_put_arg(ffi_type **arg_type, void **arg, char *stack)
 {
-  size_t z = ty->size;
-
-  switch (ty->type)
+	register char* argp = stack;
+	register ffi_type **p_arg = arg_type;
+	register void **p_argv = arg;
+	register size_t z = (*p_arg)->size;
+  if (z < sizeof(int))
     {
-    case FFI_TYPE_SINT8:
-      *(UINT32 *)dst = *(SINT8 *)src;
-      break;
-    case FFI_TYPE_UINT8:
-      *(UINT32 *)dst = *(UINT8 *)src;
-      break;
-    case FFI_TYPE_SINT16:
-      *(UINT32 *)dst = *(SINT16 *)src;
-      break;
-    case FFI_TYPE_UINT16:
-      *(UINT32 *)dst = *(UINT16 *)src;
-      break;
-
-    case FFI_TYPE_INT:
-    case FFI_TYPE_SINT32:
-    case FFI_TYPE_UINT32:
-    case FFI_TYPE_POINTER:
-#ifndef _MSC_VER
-    case FFI_TYPE_FLOAT:
-#endif
-      *(UINT32 *)dst = *(UINT32 *)src;
-      break;
-
-#ifdef _MSC_VER
-    // casting a float* to a UINT32* doesn't work on Windows
-    case FFI_TYPE_FLOAT:
-        *(uintptr_t *)dst = 0;
-        *(float *)dst = *(float *)src;
+		z = sizeof(int);
+		switch ((*p_arg)->type)
+      {
+      case FFI_TYPE_SINT8:
+        *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
         break;
-#endif
+        
+      case FFI_TYPE_UINT8:
+        *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+        break;
+        
+      case FFI_TYPE_SINT16:
+        *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+        break;
+        
+      case FFI_TYPE_UINT16:
+        *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+        break;
+        
+      case FFI_TYPE_STRUCT:
+        memcpy(argp, *p_argv, (*p_arg)->size);
+        break;
 
-    case FFI_TYPE_SINT64:
-    case FFI_TYPE_UINT64:
-    case FFI_TYPE_DOUBLE:
-      *(UINT64 *)dst = *(UINT64 *)src;
-      break;
-
-    case FFI_TYPE_STRUCT:
-    case FFI_TYPE_COMPLEX:
-      memcpy (dst, src, z);
-      break;
-
-    default:
-      abort();
+      default:
+        FFI_ASSERT(0);
+      }
     }
-
-  return FFI_ALIGN (z, 4);
+  else if (z == sizeof(int))
+    {
+		if ((*p_arg)->type == FFI_TYPE_FLOAT)
+			*(float *) argp = *(float *)(* p_argv);
+		else
+			*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+    }
+	else if (z == sizeof(double) && (*p_arg)->type == FFI_TYPE_DOUBLE)
+		{
+			*(double *) argp = *(double *)(* p_argv);
+		}
+  else
+    {
+      memcpy(argp, *p_argv, z);
+    }
+  return z;
 }
-
-/* ffi_prep_args is called once stack space has been allocated
-   for the function's arguments.
-
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments
+   
    The vfp_space parameter is the load area for VFP regs, the return
    value is cif->vfp_used (word bitset of VFP regs used for passing
    arguments). These are only used for the VFP hard-float ABI.
 */
-static void
-ffi_prep_args_SYSV (ffi_cif *cif, int flags, void *rvalue,
-		    void **avalue, char *argp)
+int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space)
 {
-  ffi_type **arg_types = cif->arg_types;
-  int i, n;
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+  argp = stack;
+  
 
-  if (flags == ARM_TYPE_STRUCT)
+  if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
+    *(void **) argp = ecif->rvalue;
+    argp += 4;
+  }
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0);
+       i--, p_arg++, p_argv++)
     {
-      *(void **) argp = rvalue;
-      argp += 4;
+    argp = ffi_align(p_arg, argp);
+    argp += ffi_put_arg(p_arg, p_argv, argp);
     }
 
-  for (i = 0, n = cif->nargs; i < n; i++)
-    {
-      ffi_type *ty = arg_types[i];
-      argp = ffi_align (ty, argp);
-      argp += ffi_put_arg (ty, avalue[i], argp);
-    }
+  return 0;
 }
 
-static void
-ffi_prep_args_VFP (ffi_cif *cif, int flags, void *rvalue,
-                   void **avalue, char *stack, char *vfp_space)
+int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
 {
-  ffi_type **arg_types = cif->arg_types;
-  int i, n, vi = 0;
-  char *argp, *regp, *eo_regp;
+  register unsigned int i, vi = 0;
+  register void **p_argv;
+  register char *argp, *regp, *eo_regp;
+  register ffi_type **p_arg;
   char stack_used = 0;
   char done_with_regs = 0;
+  char is_vfp_type;
 
-  /* The first 4 words on the stack are used for values
-     passed in core registers.  */
+  // make sure we are using FFI_VFP
+  FFI_ASSERT(ecif->cif->abi == FFI_VFP);
+
+  /* the first 4 words on the stack are used for values passed in core
+   * registers. */
   regp = stack;
   eo_regp = argp = regp + 16;
+  
 
-  /* If the function returns an FFI_TYPE_STRUCT in memory,
-     that address is passed in r0 to the function.  */
-  if (flags == ARM_TYPE_STRUCT)
-    {
-      *(void **) regp = rvalue;
-      regp += 4;
-    }
+  /* if the function returns an FFI_TYPE_STRUCT in memory, that address is
+   * passed in r0 to the function */
+  if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
+    *(void **) regp = ecif->rvalue;
+    regp += 4;
+  }
 
-  for (i = 0, n = cif->nargs; i < n; i++)
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0);
+       i--, p_arg++, p_argv++)
     {
-      ffi_type *ty = arg_types[i];
-      void *a = avalue[i];
-      int is_vfp_type = vfp_type_p (ty);
+      is_vfp_type = vfp_type_p (*p_arg);
 
       /* Allocated in VFP registers. */
-      if (vi < cif->vfp_nargs && is_vfp_type)
-	{
-	  char *vfp_slot = vfp_space + cif->vfp_args[vi++] * 4;
-	  ffi_put_arg (ty, a, vfp_slot);
-	  continue;
-	}
+      if(vi < ecif->cif->vfp_nargs && is_vfp_type)
+        {
+          char *vfp_slot = (char *)(vfp_space + ecif->cif->vfp_args[vi++]);
+          ffi_put_arg(p_arg, p_argv, vfp_slot);
+          continue;
+        }
       /* Try allocating in core registers. */
       else if (!done_with_regs && !is_vfp_type)
-	{
-	  char *tregp = ffi_align (ty, regp);
-	  size_t size = ty->size;
-	  size = (size < 4) ? 4 : size;	// pad
-	  /* Check if there is space left in the aligned register
-	     area to place the argument.  */
-	  if (tregp + size <= eo_regp)
-	    {
-	      regp = tregp + ffi_put_arg (ty, a, tregp);
-	      done_with_regs = (regp == argp);
-	      // ensure we did not write into the stack area
-	      FFI_ASSERT (regp <= argp);
-	      continue;
-	    }
-	  /* In case there are no arguments in the stack area yet,
-	     the argument is passed in the remaining core registers
-	     and on the stack.  */
-	  else if (!stack_used)
-	    {
-	      stack_used = 1;
-	      done_with_regs = 1;
-	      argp = tregp + ffi_put_arg (ty, a, tregp);
-	      FFI_ASSERT (eo_regp < argp);
-	      continue;
-	    }
-	}
+        {
+          char *tregp = ffi_align(p_arg, regp);
+          size_t size = (*p_arg)->size; 
+          size = (size < 4)? 4 : size; // pad
+          /* Check if there is space left in the aligned register area to place
+           * the argument */
+          if(tregp + size <= eo_regp)
+            {
+              regp = tregp + ffi_put_arg(p_arg, p_argv, tregp);
+              done_with_regs = (regp == argp);
+              // ensure we did not write into the stack area
+              FFI_ASSERT(regp <= argp);
+              continue;
+            }
+          /* In case there are no arguments in the stack area yet, 
+          the argument is passed in the remaining core registers and on the
+          stack. */
+          else if (!stack_used) 
+            {
+              stack_used = 1;
+              done_with_regs = 1;
+              argp = tregp + ffi_put_arg(p_arg, p_argv, tregp);
+              FFI_ASSERT(eo_regp < argp);
+              continue;
+            }
+        }
       /* Base case, arguments are passed on the stack */
       stack_used = 1;
-      argp = ffi_align (ty, argp);
-      argp += ffi_put_arg (ty, a, argp);
+      argp = ffi_align(p_arg, argp);
+      argp += ffi_put_arg(p_arg, p_argv, argp);
     }
+  /* Indicate the VFP registers used. */
+  return ecif->cif->vfp_used;
 }
 
 /* Perform machine dependent cif processing */
-ffi_status FFI_HIDDEN
-ffi_prep_cif_machdep (ffi_cif *cif)
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 {
-  int flags = 0, cabi = cif->abi;
-  size_t bytes = cif->bytes;
-
-  /* Map out the register placements of VFP register args.  The VFP
-     hard-float calling conventions are slightly more sophisticated
-     than the base calling conventions, so we do it here instead of
-     in ffi_prep_args(). */
-  if (cabi == FFI_VFP)
-    layout_vfp_args (cif);
+  int type_code;
+  /* Round the stack up to a multiple of 8 bytes.  This isn't needed 
+     everywhere, but it is on some platforms, and it doesn't harm anything
+     when it isn't needed.  */
+  cif->bytes = (cif->bytes + 7) & ~7;
 
   /* Set the return type flag */
   switch (cif->rtype->type)
     {
     case FFI_TYPE_VOID:
-      flags = ARM_TYPE_VOID;
-      break;
-
-    case FFI_TYPE_INT:
-    case FFI_TYPE_UINT8:
-    case FFI_TYPE_SINT8:
-    case FFI_TYPE_UINT16:
-    case FFI_TYPE_SINT16:
-    case FFI_TYPE_UINT32:
-    case FFI_TYPE_SINT32:
-    case FFI_TYPE_POINTER:
-      flags = ARM_TYPE_INT;
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+      cif->flags = (unsigned) cif->rtype->type;
       break;
 
     case FFI_TYPE_SINT64:
     case FFI_TYPE_UINT64:
-      flags = ARM_TYPE_INT64;
-      break;
-
-    case FFI_TYPE_FLOAT:
-      flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_S : ARM_TYPE_INT);
-      break;
-    case FFI_TYPE_DOUBLE:
-      flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_D : ARM_TYPE_INT64);
+      cif->flags = (unsigned) FFI_TYPE_SINT64;
       break;
 
     case FFI_TYPE_STRUCT:
-    case FFI_TYPE_COMPLEX:
-      if (cabi == FFI_VFP)
+      if (cif->abi == FFI_VFP
+	  && (type_code = vfp_type_p (cif->rtype)) != 0)
 	{
-	  int h = vfp_type_p (cif->rtype);
-
-	  flags = ARM_TYPE_VFP_N;
-	  if (h == 0x100 + FFI_TYPE_FLOAT)
-	    flags = ARM_TYPE_VFP_S;
-	  if (h == 0x100 + FFI_TYPE_DOUBLE)
-	    flags = ARM_TYPE_VFP_D;
-	  if (h != 0)
-	      break;
+	  /* A Composite Type passed in VFP registers, either
+	     FFI_TYPE_STRUCT_VFP_FLOAT or FFI_TYPE_STRUCT_VFP_DOUBLE. */
+	  cif->flags = (unsigned) type_code;
 	}
-
-      /* A Composite Type not larger than 4 bytes is returned in r0.
-	 A Composite Type larger than 4 bytes, or whose size cannot
-	 be determined statically ... is stored in memory at an
-	 address passed [in r0].  */
-      if (cif->rtype->size <= 4)
-	flags = ARM_TYPE_INT;
+      else if (cif->rtype->size <= 4)
+	/* A Composite Type not larger than 4 bytes is returned in r0.  */
+	cif->flags = (unsigned)FFI_TYPE_INT;
       else
-	{
-	  flags = ARM_TYPE_STRUCT;
-	  bytes += 4;
-	}
+	/* A Composite Type larger than 4 bytes, or whose size cannot
+	   be determined statically ... is stored in memory at an
+	   address passed [in r0].  */
+	cif->flags = (unsigned)FFI_TYPE_STRUCT;
       break;
 
     default:
-      abort();
+      cif->flags = FFI_TYPE_INT;
+      break;
     }
 
-  /* Round the stack up to a multiple of 8 bytes.  This isn't needed
-     everywhere, but it is on some platforms, and it doesn't harm anything
-     when it isn't needed.  */
-  bytes = FFI_ALIGN (bytes, 8);
-
-  /* Minimum stack space is the 4 register arguments that we pop.  */
-  if (bytes < 4*4)
-    bytes = 4*4;
-
-  cif->bytes = bytes;
-  cif->flags = flags;
+  /* Map out the register placements of VFP register args.
+     The VFP hard-float calling conventions are slightly more sophisticated than
+     the base calling conventions, so we do it here instead of in ffi_prep_args(). */
+  if (cif->abi == FFI_VFP)
+    layout_vfp_args (cif);
 
   return FFI_OK;
 }
 
 /* Perform machine dependent cif processing for variadic calls */
-ffi_status FFI_HIDDEN
-ffi_prep_cif_machdep_var (ffi_cif * cif,
-			  unsigned int nfixedargs, unsigned int ntotalargs)
+ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
+				    unsigned int nfixedargs,
+				    unsigned int ntotalargs)
 {
   /* VFP variadic calls actually use the SYSV ABI */
   if (cif->abi == FFI_VFP)
-    cif->abi = FFI_SYSV;
+	cif->abi = FFI_SYSV;
 
-  return ffi_prep_cif_machdep (cif);
+  return ffi_prep_cif_machdep(cif);
 }
 
-/* Prototypes for assembly functions, in sysv.S.  */
+/* Prototypes for assembly functions, in sysv.S */
+extern void ffi_call_SYSV (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
+extern void ffi_call_VFP (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
 
-struct call_frame
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
-  void *fp;
-  void *lr;
-  void *rvalue;
-  int flags;
-  void *closure;
-};
+  extended_cif ecif;
 
-extern void ffi_call_SYSV (void *stack, struct call_frame *,
-			   void (*fn) (void)) FFI_HIDDEN;
-extern void ffi_call_VFP (void *vfp_space, struct call_frame *,
-			   void (*fn) (void), unsigned vfp_used) FFI_HIDDEN;
+  int small_struct = (cif->flags == FFI_TYPE_INT 
+		      && cif->rtype->type == FFI_TYPE_STRUCT);
+  int vfp_struct = (cif->flags == FFI_TYPE_STRUCT_VFP_FLOAT
+		    || cif->flags == FFI_TYPE_STRUCT_VFP_DOUBLE);
 
-static void
-ffi_call_int (ffi_cif * cif, void (*fn) (void), void *rvalue,
-	      void **avalue, void *closure)
-{
-  int flags = cif->flags;
-  ffi_type *rtype = cif->rtype;
-  size_t bytes, rsize, vfp_size;
-  char *stack, *vfp_space, *new_rvalue;
-  struct call_frame *frame;
+  unsigned int temp;
+  
+  ecif.cif = cif;
+  ecif.avalue = avalue;
 
-  rsize = 0;
-  if (rvalue == NULL)
+  /* 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->flags == FFI_TYPE_STRUCT))
     {
-      /* If the return value is a struct and we don't have a return
-	 value address then we need to make one.  Otherwise the return
-	 value is in registers and we can ignore them.  */
-      if (flags == ARM_TYPE_STRUCT)
-	rsize = rtype->size;
-      else
-	flags = ARM_TYPE_VOID;
+      ecif.rvalue = alloca(cif->rtype->size);
     }
-  else if (flags == ARM_TYPE_VFP_N)
+  else if (small_struct)
+    ecif.rvalue = &temp;
+  else if (vfp_struct)
     {
       /* Largest case is double x 4. */
-      rsize = 32;
-    }
-  else if (flags == ARM_TYPE_INT && rtype->type == FFI_TYPE_STRUCT)
-    rsize = 4;
-
-  /* Largest case.  */
-  vfp_size = (cif->abi == FFI_VFP && cif->vfp_used ? 8*8: 0);
-
-  bytes = cif->bytes;
-  stack = alloca (vfp_size + bytes + sizeof(struct call_frame) + rsize);
-
-  vfp_space = NULL;
-  if (vfp_size)
-    {
-      vfp_space = stack;
-      stack += vfp_size;
-    }
-
-  frame = (struct call_frame *)(stack + bytes);
-
-  new_rvalue = rvalue;
-  if (rsize)
-    new_rvalue = (void *)(frame + 1);
-
-  frame->rvalue = new_rvalue;
-  frame->flags = flags;
-  frame->closure = closure;
-
-  if (vfp_space)
-    {
-      ffi_prep_args_VFP (cif, flags, new_rvalue, avalue, stack, vfp_space);
-      ffi_call_VFP (vfp_space, frame, fn, cif->vfp_used);
+      ecif.rvalue = alloca(32);
     }
   else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi) 
     {
-      ffi_prep_args_SYSV (cif, flags, new_rvalue, avalue, stack);
-      ffi_call_SYSV (stack, frame, fn);
+    case FFI_SYSV:
+      ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
+      break;
+
+    case FFI_VFP:
+#ifdef __ARM_EABI__
+      ffi_call_VFP (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
+      break;
+#endif
+
+    default:
+      FFI_ASSERT(0);
+      break;
     }
-
-  if (rvalue && rvalue != new_rvalue)
-    memcpy (rvalue, new_rvalue, rtype->size);
-}
-
-void
-ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, NULL);
-}
-
-void
-ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,
-	     void **avalue, void *closure)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, closure);
-}
-
-static void *
-ffi_prep_incoming_args_SYSV (ffi_cif *cif, void *rvalue,
-			     char *argp, void **avalue)
-{
-  ffi_type **arg_types = cif->arg_types;
-  int i, n;
-
-  if (cif->flags == ARM_TYPE_STRUCT)
+  if (small_struct)
     {
-      rvalue = *(void **) argp;
-      argp += 4;
+      FFI_ASSERT(rvalue != NULL);
+      memcpy (rvalue, &temp, cif->rtype->size);
     }
+    
+  else if (vfp_struct)
+    {
+      FFI_ASSERT(rvalue != NULL);
+      memcpy (rvalue, ecif.rvalue, cif->rtype->size);
+    }
+    
+}
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+					 void** args, ffi_cif* cif, float *vfp_stack);
+
+static void ffi_prep_incoming_args_VFP (char *stack, void **ret,
+					 void** args, ffi_cif* cif, float *vfp_stack);
+
+void ffi_closure_SYSV (ffi_closure *);
+
+void ffi_closure_VFP (ffi_closure *);
+
+/* This function is jumped to by the trampoline */
+
+unsigned int FFI_HIDDEN
+ffi_closure_inner (ffi_closure *closure, 
+		   void **respp, void *args, void *vfp_args)
+{
+  // our various things...
+  ffi_cif       *cif;
+  void         **arg_area;
+
+  cif         = closure->cif;
+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
+
+  /* this call will initialize ARG_AREA, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will re-set RESP to point to the
+   * structure return address.  */
+  if (cif->abi == FFI_VFP)
+    ffi_prep_incoming_args_VFP(args, respp, arg_area, cif, vfp_args);
   else
-    {
-      if (cif->rtype->size && cif->rtype->size < 4)
-        *(uint32_t *) rvalue = 0;
-    }
+    ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args);
 
-  for (i = 0, n = cif->nargs; i < n; i++)
-    {
-      ffi_type *ty = arg_types[i];
-      size_t z = ty->size;
+  (closure->fun) (cif, *respp, arg_area, closure->user_data);
 
-      argp = ffi_align (ty, argp);
-      avalue[i] = (void *) argp;
+  return cif->flags;
+}
+
+/*@-exportheader@*/
+static void 
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+			    void **avalue, ffi_cif *cif,
+			    /* Used only under VFP hard-float ABI. */
+			    float *vfp_stack)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if ( cif->flags == FFI_TYPE_STRUCT ) {
+    *rvalue = *(void **) argp;
+    argp += 4;
+  }
+
+  p_argv = avalue;
+
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+    {
+      size_t z;
+
+      argp = ffi_align(p_arg, argp);
+
+      z = (*p_arg)->size;
+
+      /* because we're little endian, this is what it turns into.   */
+
+      *p_argv = (void*) argp;
+
+      p_argv++;
       argp += z;
     }
-
-  return rvalue;
+  
+  return;
 }
 
-static void *
-ffi_prep_incoming_args_VFP (ffi_cif *cif, void *rvalue, char *stack,
-			    char *vfp_space, void **avalue)
+/*@-exportheader@*/
+static void 
+ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
+			    void **avalue, ffi_cif *cif,
+			    /* Used only under VFP hard-float ABI. */
+			    float *vfp_stack)
+/*@=exportheader@*/
 {
-  ffi_type **arg_types = cif->arg_types;
-  int i, n, vi = 0;
-  char *argp, *regp, *eo_regp;
+  register unsigned int i, vi = 0;
+  register void **p_argv;
+  register char *argp, *regp, *eo_regp;
+  register ffi_type **p_arg;
   char done_with_regs = 0;
   char stack_used = 0;
+  char is_vfp_type;
 
+  FFI_ASSERT(cif->abi == FFI_VFP);
   regp = stack;
   eo_regp = argp = regp + 16;
 
-  if (cif->flags == ARM_TYPE_STRUCT)
+  if ( cif->flags == FFI_TYPE_STRUCT ) {
+    *rvalue = *(void **) regp;
+    regp += 4;
+  }
+
+  p_argv = avalue;
+
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
     {
-      rvalue = *(void **) regp;
-      regp += 4;
+    size_t z;
+    is_vfp_type = vfp_type_p (*p_arg); 
+
+    if(vi < cif->vfp_nargs && is_vfp_type)
+      {
+        *p_argv++ = (void*)(vfp_stack + cif->vfp_args[vi++]);
+        continue;
+      }
+    else if (!done_with_regs && !is_vfp_type)
+      {
+        char* tregp = ffi_align(p_arg, regp);
+
+        z = (*p_arg)->size; 
+        z = (z < 4)? 4 : z; // pad
+        
+        /* if the arguments either fits into the registers or uses registers
+         * and stack, while we haven't read other things from the stack */
+        if(tregp + z <= eo_regp || !stack_used) 
+          {
+          /* because we're little endian, this is what it turns into. */
+          *p_argv = (void*) tregp;
+
+          p_argv++;
+          regp = tregp + z;
+          // if we read past the last core register, make sure we have not read
+          // from the stack before and continue reading after regp
+          if(regp > eo_regp)
+            {
+            if(stack_used)
+              {
+                abort(); // we should never read past the end of the register
+                         // are if the stack is already in use
+              }
+            argp = regp;
+            }
+          if(regp >= eo_regp)
+            {
+            done_with_regs = 1;
+            stack_used = 1;
+            }
+          continue;
+          }
+      }
+    stack_used = 1;
+
+    argp = ffi_align(p_arg, argp);
+
+    z = (*p_arg)->size;
+
+    /* because we're little endian, this is what it turns into.   */
+
+    *p_argv = (void*) argp;
+
+    p_argv++;
+    argp += z;
     }
-
-  for (i = 0, n = cif->nargs; i < n; i++)
-    {
-      ffi_type *ty = arg_types[i];
-      int is_vfp_type = vfp_type_p (ty);
-      size_t z = ty->size;
-
-      if (vi < cif->vfp_nargs && is_vfp_type)
-	{
-	  avalue[i] = vfp_space + cif->vfp_args[vi++] * 4;
-	  continue;
-	}
-      else if (!done_with_regs && !is_vfp_type)
-	{
-	  char *tregp = ffi_align (ty, regp);
-
-	  z = (z < 4) ? 4 : z;	// pad
-
-	  /* If the arguments either fits into the registers or uses registers
-	     and stack, while we haven't read other things from the stack */
-	  if (tregp + z <= eo_regp || !stack_used)
-	    {
-	      /* Because we're little endian, this is what it turns into.  */
-	      avalue[i] = (void *) tregp;
-	      regp = tregp + z;
-
-	      /* If we read past the last core register, make sure we
-		 have not read from the stack before and continue
-		 reading after regp.  */
-	      if (regp > eo_regp)
-		{
-		  FFI_ASSERT (!stack_used);
-		  argp = regp;
-		}
-	      if (regp >= eo_regp)
-		{
-		  done_with_regs = 1;
-		  stack_used = 1;
-		}
-	      continue;
-	    }
-	}
-
-      stack_used = 1;
-      argp = ffi_align (ty, argp);
-      avalue[i] = (void *) argp;
-      argp += z;
-    }
-
-  return rvalue;
+  
+  return;
 }
 
-struct closure_frame
-{
-  char vfp_space[8*8] __attribute__((aligned(8)));
-  char result[8*4];
-  char argp[];
+/* How to make a trampoline.  */
+
+extern unsigned int ffi_arm_trampoline[3];
+
+#if FFI_EXEC_TRAMPOLINE_TABLE
+
+#include <mach/mach.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void *ffi_closure_trampoline_table_page;
+
+typedef struct ffi_trampoline_table ffi_trampoline_table;
+typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry;
+
+struct ffi_trampoline_table {
+  /* contiguous writable and executable pages */
+  vm_address_t config_page;
+  vm_address_t trampoline_page;
+
+  /* free list tracking */
+  uint16_t free_count;
+  ffi_trampoline_table_entry *free_list;
+  ffi_trampoline_table_entry *free_list_pool;
+
+  ffi_trampoline_table *prev;
+  ffi_trampoline_table *next;
 };
 
-int FFI_HIDDEN
-ffi_closure_inner_SYSV (ffi_cif *cif,
-		        void (*fun) (ffi_cif *, void *, void **, void *),
-		        void *user_data,
-		        struct closure_frame *frame)
+struct ffi_trampoline_table_entry {
+  void *(*trampoline)();
+  ffi_trampoline_table_entry *next;
+};
+
+/* Override the standard architecture trampoline size */
+// XXX TODO - Fix
+#undef FFI_TRAMPOLINE_SIZE
+#define FFI_TRAMPOLINE_SIZE 12
+
+/* The trampoline configuration is placed at 4080 bytes prior to the trampoline's entry point */
+#define FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc) ((void **) (((uint8_t *) codeloc) - 4080));
+
+/* The first 16 bytes of the config page are unused, as they are unaddressable from the trampoline page. */
+#define FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET 16
+
+/* Total number of trampolines that fit in one trampoline table */
+#define FFI_TRAMPOLINE_COUNT ((PAGE_SIZE - FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET) / FFI_TRAMPOLINE_SIZE)
+
+static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER;
+static ffi_trampoline_table *ffi_trampoline_tables = NULL;
+
+static ffi_trampoline_table *
+ffi_trampoline_table_alloc ()
 {
-  void **avalue = (void **) alloca (cif->nargs * sizeof (void *));
-  void *rvalue = ffi_prep_incoming_args_SYSV (cif, frame->result,
-					      frame->argp, avalue);
-  fun (cif, rvalue, avalue, user_data);
-  return cif->flags;
+  ffi_trampoline_table *table = NULL;
+
+  /* Loop until we can allocate two contiguous pages */
+  while (table == NULL) {
+    vm_address_t config_page = 0x0;
+    kern_return_t kt;
+
+    /* Try to allocate two pages */
+    kt = vm_allocate (mach_task_self (), &config_page, PAGE_SIZE*2, VM_FLAGS_ANYWHERE);
+    if (kt != KERN_SUCCESS) {
+      fprintf(stderr, "vm_allocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
+      break;
+    }
+
+    /* Now drop the second half of the allocation to make room for the trampoline table */
+    vm_address_t trampoline_page = config_page+PAGE_SIZE;
+    kt = vm_deallocate (mach_task_self (), trampoline_page, PAGE_SIZE);
+    if (kt != KERN_SUCCESS) {
+      fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
+      break;
+    }
+
+    /* Remap the trampoline table to directly follow the config page */
+    vm_prot_t cur_prot;
+    vm_prot_t max_prot;
+
+    kt = vm_remap (mach_task_self (), &trampoline_page, PAGE_SIZE, 0x0, FALSE, mach_task_self (), (vm_address_t) &ffi_closure_trampoline_table_page, FALSE, &cur_prot, &max_prot, VM_INHERIT_SHARE);
+
+    /* If we lost access to the destination trampoline page, drop our config allocation mapping and retry */
+    if (kt != KERN_SUCCESS) {
+      /* Log unexpected failures */
+      if (kt != KERN_NO_SPACE) {
+        fprintf(stderr, "vm_remap() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
+      }
+
+      vm_deallocate (mach_task_self (), config_page, PAGE_SIZE);
+      continue;
+    }
+
+    /* We have valid trampoline and config pages */
+    table = calloc (1, sizeof(ffi_trampoline_table));
+    table->free_count = FFI_TRAMPOLINE_COUNT;
+    table->config_page = config_page;
+    table->trampoline_page = trampoline_page;
+
+    /* Create and initialize the free list */
+    table->free_list_pool = calloc(FFI_TRAMPOLINE_COUNT, sizeof(ffi_trampoline_table_entry));
+
+    uint16_t i;
+    for (i = 0; i < table->free_count; i++) {
+      ffi_trampoline_table_entry *entry = &table->free_list_pool[i];
+      entry->trampoline = (void *) (table->trampoline_page + (i * FFI_TRAMPOLINE_SIZE));
+
+      if (i < table->free_count - 1)
+        entry->next = &table->free_list_pool[i+1];
+    }
+
+    table->free_list = table->free_list_pool;
+  }
+
+  return table;
 }
 
-int FFI_HIDDEN
-ffi_closure_inner_VFP (ffi_cif *cif,
-		       void (*fun) (ffi_cif *, void *, void **, void *),
-		       void *user_data,
-		       struct closure_frame *frame)
+void *
+ffi_closure_alloc (size_t size, void **code)
 {
-  void **avalue = (void **) alloca (cif->nargs * sizeof (void *));
-  void *rvalue = ffi_prep_incoming_args_VFP (cif, frame->result, frame->argp,
-					     frame->vfp_space, avalue);
-  fun (cif, rvalue, avalue, user_data);
-  return cif->flags;
+  /* Create the closure */
+  ffi_closure *closure = malloc(size);
+  if (closure == NULL)
+    return NULL;
+
+  pthread_mutex_lock(&ffi_trampoline_lock);
+
+  /* Check for an active trampoline table with available entries. */
+  ffi_trampoline_table *table = ffi_trampoline_tables;
+  if (table == NULL || table->free_list == NULL) {
+    table = ffi_trampoline_table_alloc ();
+    if (table == NULL) {
+      free(closure);
+      return NULL;
+    }
+
+    /* Insert the new table at the top of the list */
+    table->next = ffi_trampoline_tables;
+    if (table->next != NULL)
+        table->next->prev = table;
+
+    ffi_trampoline_tables = table;
+  }
+
+  /* Claim the free entry */
+  ffi_trampoline_table_entry *entry = ffi_trampoline_tables->free_list;
+  ffi_trampoline_tables->free_list = entry->next;
+  ffi_trampoline_tables->free_count--;
+  entry->next = NULL;
+
+  pthread_mutex_unlock(&ffi_trampoline_lock);
+
+  /* Initialize the return values */
+  *code = entry->trampoline;
+  closure->trampoline_table = table;
+  closure->trampoline_table_entry = entry;
+
+  return closure;
 }
 
-void ffi_closure_SYSV (void) FFI_HIDDEN;
-void ffi_closure_VFP (void) FFI_HIDDEN;
-void ffi_go_closure_SYSV (void) FFI_HIDDEN;
-void ffi_go_closure_VFP (void) FFI_HIDDEN;
+void
+ffi_closure_free (void *ptr)
+{
+  ffi_closure *closure = ptr;
+
+  pthread_mutex_lock(&ffi_trampoline_lock);
+
+  /* Fetch the table and entry references */
+  ffi_trampoline_table *table = closure->trampoline_table;
+  ffi_trampoline_table_entry *entry = closure->trampoline_table_entry;
+
+  /* Return the entry to the free list */
+  entry->next = table->free_list;
+  table->free_list = entry;
+  table->free_count++;
+
+  /* If all trampolines within this table are free, and at least one other table exists, deallocate
+   * the table */
+  if (table->free_count == FFI_TRAMPOLINE_COUNT && ffi_trampoline_tables != table) {
+    /* Remove from the list */
+    if (table->prev != NULL)
+      table->prev->next = table->next;
+
+    if (table->next != NULL)
+      table->next->prev = table->prev;
+
+    /* Deallocate pages */
+    kern_return_t kt;
+    kt = vm_deallocate (mach_task_self (), table->config_page, PAGE_SIZE);
+    if (kt != KERN_SUCCESS)
+      fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
+
+    kt = vm_deallocate (mach_task_self (), table->trampoline_page, PAGE_SIZE);
+    if (kt != KERN_SUCCESS)
+      fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
+
+    /* Deallocate free list */
+    free (table->free_list_pool);
+    free (table);
+  } else if (ffi_trampoline_tables != table) {
+    /* Otherwise, bump this table to the top of the list */
+    table->prev = NULL;
+    table->next = ffi_trampoline_tables;
+    if (ffi_trampoline_tables != NULL)
+      ffi_trampoline_tables->prev = table;
+
+    ffi_trampoline_tables = table;
+  }
+
+  pthread_mutex_unlock (&ffi_trampoline_lock);
+
+  /* Free the closure */
+  free (closure);
+}
+
+#else
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX)				\
+({ unsigned char *__tramp = (unsigned char*)(TRAMP);			\
+   unsigned int  __fun = (unsigned int)(FUN);				\
+   unsigned int  __ctx = (unsigned int)(CTX);				\
+   unsigned char *insns = (unsigned char *)(CTX);                       \
+   memcpy (__tramp, ffi_arm_trampoline, sizeof ffi_arm_trampoline);     \
+   *(unsigned int*) &__tramp[12] = __ctx;				\
+   *(unsigned int*) &__tramp[16] = __fun;				\
+   __clear_cache((&__tramp[0]), (&__tramp[19])); /* Clear data mapping.  */ \
+   __clear_cache(insns, insns + 3 * sizeof (unsigned int));             \
+                                                 /* Clear instruction   \
+                                                    mapping.  */        \
+ })
+
+#endif
 
 /* the cif must already be prep'ed */
 
 ffi_status
-ffi_prep_closure_loc (ffi_closure * closure,
-		      ffi_cif * cif,
-		      void (*fun) (ffi_cif *, void *, void **, void *),
-		      void *user_data, void *codeloc)
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*,void*,void**,void*),
+		      void *user_data,
+		      void *codeloc)
 {
-  void (*closure_func) (void) = ffi_closure_SYSV;
+  void (*closure_func)(ffi_closure*) = NULL;
 
-  if (cif->abi == FFI_VFP)
-    {
-      /* We only need take the vfp path if there are vfp arguments.  */
-      if (cif->vfp_used)
-	closure_func = ffi_closure_VFP;
-    }
-  else if (cif->abi != FFI_SYSV)
+  if (cif->abi == FFI_SYSV)
+    closure_func = &ffi_closure_SYSV;
+#ifdef __ARM_EABI__
+  else if (cif->abi == FFI_VFP)
+    closure_func = &ffi_closure_VFP;
+#endif
+  else
     return FFI_BAD_ABI;
 
 #if FFI_EXEC_TRAMPOLINE_TABLE
-  void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);
+  void **config = FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc);
   config[0] = closure;
   config[1] = closure_func;
 #else
-
-#ifndef _M_ARM
-  memcpy(closure->tramp, ffi_arm_trampoline, 8);
-#else
-  // cast away function type so MSVC doesn't set the lower bit of the function pointer
-  memcpy(closure->tramp, (void*)((uintptr_t)ffi_arm_trampoline & 0xFFFFFFFE), FFI_TRAMPOLINE_CLOSURE_OFFSET);
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
+		       closure_func,  \
+		       codeloc);
 #endif
 
-#if defined (__QNX__)
-  msync(closure->tramp, 8, 0x1000000);	/* clear data map */
-  msync(codeloc, 8, 0x1000000);	/* clear insn map */
-#elif defined(_MSC_VER)
-  FlushInstructionCache(GetCurrentProcess(), closure->tramp, FFI_TRAMPOLINE_SIZE);
-#else
-  __clear_cache(closure->tramp, closure->tramp + 8);	/* clear data map */
-  __clear_cache(codeloc, codeloc + 8);			/* clear insn map */
-#endif
-#ifdef _M_ARM
-  *(void(**)(void))(closure->tramp + FFI_TRAMPOLINE_CLOSURE_FUNCTION) = closure_func;
-#else
-  *(void (**)(void))(closure->tramp + 8) = closure_func;
-#endif
-#endif
-
-  closure->cif = cif;
-  closure->fun = fun;
+  closure->cif  = cif;
   closure->user_data = user_data;
-
-  return FFI_OK;
-}
-
-ffi_status
-ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
-		     void (*fun) (ffi_cif *, void *, void **, void *))
-{
-  void (*closure_func) (void) = ffi_go_closure_SYSV;
-
-  if (cif->abi == FFI_VFP)
-    {
-      /* We only need take the vfp path if there are vfp arguments.  */
-      if (cif->vfp_used)
-	closure_func = ffi_go_closure_VFP;
-    }
-  else if (cif->abi != FFI_SYSV)
-    return FFI_BAD_ABI;
-
-  closure->tramp = closure_func;
-  closure->cif = cif;
-  closure->fun = fun;
+  closure->fun  = fun;
 
   return FFI_OK;
 }
 
 /* Below are routines for VFP hard-float support. */
 
-/* A subroutine of vfp_type_p.  Given a structure type, return the type code
-   of the first non-structure element.  Recurse for structure elements.
-   Return -1 if the structure is in fact empty, i.e. no nested elements.  */
-
-static int
-is_hfa0 (const ffi_type *ty)
+static int rec_vfp_type_p (ffi_type *t, int *elt, int *elnum)
 {
-  ffi_type **elements = ty->elements;
-  int i, ret = -1;
-
-  if (elements != NULL)
-    for (i = 0; elements[i]; ++i)
-      {
-        ret = elements[i]->type;
-        if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX)
-          {
-            ret = is_hfa0 (elements[i]);
-            if (ret < 0)
-              continue;
-          }
-        break;
-      }
-
-  return ret;
-}
-
-/* A subroutine of vfp_type_p.  Given a structure type, return true if all
-   of the non-structure elements are the same as CANDIDATE.  */
-
-static int
-is_hfa1 (const ffi_type *ty, int candidate)
-{
-  ffi_type **elements = ty->elements;
-  int i;
-
-  if (elements != NULL)
-    for (i = 0; elements[i]; ++i)
-      {
-        int t = elements[i]->type;
-        if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
-          {
-            if (!is_hfa1 (elements[i], candidate))
-              return 0;
-          }
-        else if (t != candidate)
-          return 0;
-      }
-
-  return 1;
-}
-
-/* Determine if TY is an homogenous floating point aggregate (HFA).
-   That is, a structure consisting of 1 to 4 members of all the same type,
-   where that type is a floating point scalar.
-
-   Returns non-zero iff TY is an HFA.  The result is an encoded value where
-   bits 0-7 contain the type code, and bits 8-10 contain the element count.  */
-
-static int
-vfp_type_p (const ffi_type *ty)
-{
-  ffi_type **elements;
-  int candidate, i;
-  size_t size, ele_count;
-
-  /* Quickest tests first.  */
-  candidate = ty->type;
-  switch (ty->type)
-    {
-    default:
-      return 0;
-    case FFI_TYPE_FLOAT:
-    case FFI_TYPE_DOUBLE:
-      ele_count = 1;
-      goto done;
-    case FFI_TYPE_COMPLEX:
-      candidate = ty->elements[0]->type;
-      if (candidate != FFI_TYPE_FLOAT && candidate != FFI_TYPE_DOUBLE)
-	return 0;
-      ele_count = 2;
-      goto done;
-    case FFI_TYPE_STRUCT:
-      break;
-    }
-
-  /* No HFA types are smaller than 4 bytes, or larger than 32 bytes.  */
-  size = ty->size;
-  if (size < 4 || size > 32)
-    return 0;
-
-  /* Find the type of the first non-structure member.  */
-  elements = ty->elements;
-  candidate = elements[0]->type;
-  if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX)
-    {
-      for (i = 0; ; ++i)
-        {
-          candidate = is_hfa0 (elements[i]);
-          if (candidate >= 0)
-            break;
-        }
-    }
-
-  /* If the first member is not a floating point type, it's not an HFA.
-     Also quickly re-check the size of the structure.  */
-  switch (candidate)
+  switch (t->type)
     {
     case FFI_TYPE_FLOAT:
-      ele_count = size / sizeof(float);
-      if (size != ele_count * sizeof(float))
-        return 0;
-      break;
     case FFI_TYPE_DOUBLE:
-      ele_count = size / sizeof(double);
-      if (size != ele_count * sizeof(double))
-        return 0;
-      break;
-    default:
-      return 0;
-    }
-  if (ele_count > 4)
-    return 0;
+      *elt = (int) t->type;
+      *elnum = 1;
+      return 1;
 
-  /* Finally, make sure that all scalar elements are the same type.  */
-  for (i = 0; elements[i]; ++i)
-    {
-      int t = elements[i]->type;
-      if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
-        {
-          if (!is_hfa1 (elements[i], candidate))
-            return 0;
-        }
-      else if (t != candidate)
-        return 0;
-    }
+    case FFI_TYPE_STRUCT_VFP_FLOAT:
+      *elt = FFI_TYPE_FLOAT;
+      *elnum = t->size / sizeof (float);
+      return 1;
 
-  /* All tests succeeded.  Encode the result.  */
- done:
-  return (ele_count << 8) | candidate;
+    case FFI_TYPE_STRUCT_VFP_DOUBLE:
+      *elt = FFI_TYPE_DOUBLE;
+      *elnum = t->size / sizeof (double);
+      return 1;
+
+    case FFI_TYPE_STRUCT:;
+      {
+	int base_elt = 0, total_elnum = 0;
+	ffi_type **el = t->elements;
+	while (*el)
+	  {
+	    int el_elt = 0, el_elnum = 0;
+	    if (! rec_vfp_type_p (*el, &el_elt, &el_elnum)
+		|| (base_elt && base_elt != el_elt)
+		|| total_elnum + el_elnum > 4)
+	      return 0;
+	    base_elt = el_elt;
+	    total_elnum += el_elnum;
+	    el++;
+	  }
+	*elnum = total_elnum;
+	*elt = base_elt;
+	return 1;
+      }
+    default: ;
+    }
+  return 0;
 }
 
-static int
-place_vfp_arg (ffi_cif *cif, int h)
+static int vfp_type_p (ffi_type *t)
 {
-  unsigned short reg = cif->vfp_reg_free;
-  int align = 1, nregs = h >> 8;
+  int elt, elnum;
+  if (rec_vfp_type_p (t, &elt, &elnum))
+    {
+      if (t->type == FFI_TYPE_STRUCT)
+	{
+	  if (elnum == 1)
+	    t->type = elt;
+	  else
+	    t->type = (elt == FFI_TYPE_FLOAT
+		       ? FFI_TYPE_STRUCT_VFP_FLOAT
+		       : FFI_TYPE_STRUCT_VFP_DOUBLE);
+	}
+      return (int) t->type;
+    }
+  return 0;
+}
 
-  if ((h & 0xff) == FFI_TYPE_DOUBLE)
-    align = 2, nregs *= 2;
-
+static int place_vfp_arg (ffi_cif *cif, ffi_type *t)
+{
+  short reg = cif->vfp_reg_free;
+  int nregs = t->size / sizeof (float);
+  int align = ((t->type == FFI_TYPE_STRUCT_VFP_FLOAT
+		|| t->type == FFI_TYPE_FLOAT) ? 1 : 2);
   /* Align register number. */
   if ((reg & 1) && align == 2)
     reg++;
-
   while (reg + nregs <= 16)
     {
       int s, new_used = 0;
@@ -814,7 +892,7 @@
 	}
       /* Found regs to allocate. */
       cif->vfp_used |= new_used;
-      cif->vfp_args[cif->vfp_nargs++] = (signed char)reg;
+      cif->vfp_args[cif->vfp_nargs++] = reg;
 
       /* Update vfp_reg_free. */
       if (cif->vfp_used & (1 << cif->vfp_reg_free))
@@ -825,7 +903,7 @@
 	  cif->vfp_reg_free = reg;
 	}
       return 0;
-    next_reg:;
+    next_reg: ;
     }
   // done, mark all regs as used
   cif->vfp_reg_free = 16;
@@ -833,22 +911,21 @@
   return 1;
 }
 
-static void
-layout_vfp_args (ffi_cif * cif)
+static void layout_vfp_args (ffi_cif *cif)
 {
-  unsigned int i;
+  int i;
   /* Init VFP fields */
   cif->vfp_used = 0;
   cif->vfp_nargs = 0;
   cif->vfp_reg_free = 0;
-  memset (cif->vfp_args, -1, 16);	/* Init to -1. */
+  memset (cif->vfp_args, -1, 16); /* Init to -1. */
 
   for (i = 0; i < cif->nargs; i++)
     {
-      int h = vfp_type_p (cif->arg_types[i]);
-      if (h && place_vfp_arg (cif, h) == 1)
-	break;
+      ffi_type *t = cif->arg_types[i];
+      if (vfp_type_p (t) && place_vfp_arg (cif, t) == 1)
+        {
+          break;
+        }
     }
 }
-
-#endif /* __arm__ or _M_ARM */
diff --git a/src/arm/ffitarget.h b/src/arm/ffitarget.h
index cb57b84..26d494d 100644
--- a/src/arm/ffitarget.h
+++ b/src/arm/ffitarget.h
@@ -43,7 +43,7 @@
   FFI_SYSV,
   FFI_VFP,
   FFI_LAST_ABI,
-#if defined(__ARM_PCS_VFP) || defined(_M_ARM)
+#ifdef __ARM_PCS_VFP
   FFI_DEFAULT_ABI = FFI_VFP,
 #else
   FFI_DEFAULT_ABI = FFI_SYSV,
@@ -53,37 +53,19 @@
 
 #define FFI_EXTRA_CIF_FIELDS			\
   int vfp_used;					\
-  unsigned short vfp_reg_free, vfp_nargs;	\
+  short vfp_reg_free, vfp_nargs;		\
   signed char vfp_args[16]			\
 
+/* Internally used. */
+#define FFI_TYPE_STRUCT_VFP_FLOAT  (FFI_TYPE_LAST + 1)
+#define FFI_TYPE_STRUCT_VFP_DOUBLE (FFI_TYPE_LAST + 2)
+
 #define FFI_TARGET_SPECIFIC_VARIADIC
-#ifndef _M_ARM
-#define FFI_TARGET_HAS_COMPLEX_TYPE
-#endif
 
 /* ---- Definitions for closures ----------------------------------------- */
 
 #define FFI_CLOSURES 1
-#define FFI_GO_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 20
 #define FFI_NATIVE_RAW_API 0
 
-#if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
-
-#ifdef __MACH__
-#define FFI_TRAMPOLINE_SIZE 12
-#define FFI_TRAMPOLINE_CLOSURE_OFFSET 8
-#else
-#error "No trampoline table implementation"
-#endif
-
-#else
-#ifdef _MSC_VER
-#define FFI_TRAMPOLINE_SIZE 16
-#define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12
-#else
-#define FFI_TRAMPOLINE_SIZE 12
-#endif
-#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
-#endif
-
 #endif
diff --git a/src/arm/internal.h b/src/arm/internal.h
deleted file mode 100644
index 6cf0b2a..0000000
--- a/src/arm/internal.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#define ARM_TYPE_VFP_S	0
-#define ARM_TYPE_VFP_D	1
-#define ARM_TYPE_VFP_N	2
-#define ARM_TYPE_INT64	3
-#define ARM_TYPE_INT	4
-#define ARM_TYPE_VOID	5
-#define ARM_TYPE_STRUCT	6
diff --git a/src/arm/sysv.S b/src/arm/sysv.S
index 63180a4..fcdfd56 100644
--- a/src/arm/sysv.S
+++ b/src/arm/sysv.S
@@ -1,8 +1,8 @@
 /* -----------------------------------------------------------------------
    sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
 	    Copyright (c) 2011 Plausible Labs Cooperative, Inc.
-
-   ARM Foreign Function Interface
+   
+   ARM Foreign Function Interface 
 
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
@@ -25,360 +25,466 @@
    DEALINGS IN THE SOFTWARE.
    ----------------------------------------------------------------------- */
 
-#ifdef __arm__
-#define LIBFFI_ASM
+#define LIBFFI_ASM	
 #include <fficonfig.h>
 #include <ffi.h>
-#include <ffi_cfi.h>
-#include "internal.h"
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+#ifdef __USER_LABEL_PREFIX__
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
 
-/* GCC 4.8 provides __ARM_ARCH; construct it otherwise.  */
-#ifndef __ARM_ARCH
-# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
-     || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
-     || defined(__ARM_ARCH_7EM__)
-#  define __ARM_ARCH 7
-# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+/* Use the right prefix for global labels.  */
+#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+#else
+#define CNAME(x) x
+#endif
+#ifdef __APPLE__
+#define ENTRY(x) .globl _##x; _##x:
+#else
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif /* __APPLE__ */
+#endif
+
+#ifdef __ELF__
+#define LSYM(x) .x
+#else
+#define LSYM(x) x
+#endif
+
+/* Use the SOFTFP return value ABI on Mac OS X, as per the iOS ABI
+  Function Call Guide */
+#ifdef __APPLE__
+#define __SOFTFP__
+#endif
+
+/* We need a better way of testing for this, but for now, this is all 
+   we can do.  */
+@ This selects the minimum architecture level required.
+#define __ARM_ARCH__ 3
+
+#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 4
+#endif
+        
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+	|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
+	|| defined(__ARM_ARCH_5TEJ__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 5
+#endif
+
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
         || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
         || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
 	|| defined(__ARM_ARCH_6M__)
-#  define __ARM_ARCH 6
-# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
-	|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
-	|| defined(__ARM_ARCH_5TEJ__)
-#  define __ARM_ARCH 5
-# else
-#  define __ARM_ARCH 4
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 6
+#endif
+
+#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+        || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+	|| defined(__ARM_ARCH_7EM__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 7
+#endif
+
+#if __ARM_ARCH__ >= 5
+# define call_reg(x)	blx	x
+#elif defined (__ARM_ARCH_4T__)
+# define call_reg(x)	mov	lr, pc ; bx	x
+# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
+#  define __INTERWORKING__
 # endif
+#else
+# define call_reg(x)	mov	lr, pc ; mov	pc, x
 #endif
 
 /* Conditionally compile unwinder directives.  */
 #ifdef __ARM_EABI__
-# define UNWIND(...)	__VA_ARGS__
+#define UNWIND
 #else
-# define UNWIND(...)
+#define UNWIND @
+#endif	
+
+.syntax unified
+
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+#define ARM_FUNC_START(name) \
+	.text; \
+	.align 2; \
+	.thumb; \
+	.thumb_func; \
+	ENTRY(name); \
+	bx pc; \
+	nop; \
+	.arm; \
+	UNWIND .fnstart; \
+_L__##name:
+#else
+#define ARM_FUNC_START(name) \
+	.text; \
+	.align 2; \
+	.arm; \
+	ENTRY(name); \
+	UNWIND .fnstart
 #endif
 
-#if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__ARM_EABI__)
-	.cfi_sections	.debug_frame
-#endif
-
-#define CONCAT(a, b)	CONCAT2(a, b)
-#define CONCAT2(a, b)	a ## b
-
-#ifdef __USER_LABEL_PREFIX__
-# define CNAME(X)	CONCAT (__USER_LABEL_PREFIX__, X)
+.macro	RETLDM	regs=, cond=, dirn=ia
+#if defined (__INTERWORKING__)
+	.ifc "\regs",""
+	ldr\cond	lr, [sp], #4
+	.else
+	ldm\cond\dirn	sp!, {\regs, lr}
+	.endif
+	bx\cond	lr
 #else
-# define CNAME(X)	X
-#endif
-#ifdef __ELF__
-# define SIZE(X)	.size CNAME(X), . - CNAME(X)
-# define TYPE(X, Y)	.type CNAME(X), Y
-#else
-# define SIZE(X)
-# define TYPE(X, Y)
-#endif
-
-#define ARM_FUNC_START_LOCAL(name)	\
-	.align	3;			\
-	TYPE(CNAME(name), %function);	\
-	CNAME(name):
-
-#define ARM_FUNC_START(name)		\
-	.globl CNAME(name);		\
-	FFI_HIDDEN(CNAME(name));	\
-	ARM_FUNC_START_LOCAL(name)
-
-#define ARM_FUNC_END(name) \
-	SIZE(name)
-
-/* Aid in defining a jump table with 8 bytes between entries.  */
-/* ??? The clang assembler doesn't handle .if with symbolic expressions.  */
-#ifdef __clang__
-# define E(index)
-#else
-# define E(index)				\
-	.if . - 0b - 8*index;			\
-	.error "type table out of sync";	\
+	.ifc "\regs",""
+	ldr\cond	pc, [sp], #4
+	.else
+	ldm\cond\dirn	sp!, {\regs, pc}
 	.endif
 #endif
+.endm
 
-	.text
-	.syntax unified
-	.arm
+	@ r0:   ffi_prep_args
+	@ r1:   &ecif
+	@ r2:   cif->bytes
+	@ r3:   fig->flags
+	@ sp+0: ecif.rvalue
 
-#ifndef __clang__
-	/* We require interworking on LDM, which implies ARMv5T,
-	   which implies the existance of BLX.  */
- 	.arch	armv5t
-#endif
-
-	/* Note that we use STC and LDC to encode VFP instructions,
-	   so that we do not need ".fpu vfp", nor get that added to
-	   the object file attributes.  These will not be executed
-	   unless the FFI_VFP abi is used.  */
-
-	@ r0:   stack
-	@ r1:   frame
-	@ r2:   fn
-	@ r3:	vfp_used
-
-ARM_FUNC_START(ffi_call_VFP)
-	UNWIND(.fnstart)
-	cfi_startproc
-
-	cmp	r3, #3			@ load only d0 if possible
-#ifdef __clang__
-	vldrle d0, [sp]
-	vldmgt sp, {d0-d7}
-#else
-	ldcle	p11, cr0, [r0]		@ vldrle d0, [sp]
-	ldcgt	p11, cr0, [r0], {16}	@ vldmgt sp, {d0-d7}
-#endif
-	add	r0, r0, #64		@ discard the vfp register args
-	/* FALLTHRU */
-ARM_FUNC_END(ffi_call_VFP)
-
+	@ This assumes we are using gas.
 ARM_FUNC_START(ffi_call_SYSV)
-	stm	r1, {fp, lr}
-	mov	fp, r1
+	@ Save registers
+        stmfd	sp!, {r0-r3, fp, lr}
+	UNWIND .save	{r0-r3, fp, lr}
+	mov	fp, sp
 
-	@ This is a bit of a lie wrt the origin of the unwind info, but
-	@ now we've got the usual frame pointer and two saved registers.
-	UNWIND(.save {fp,lr})
-	UNWIND(.setfp fp, sp)
-	cfi_def_cfa(fp, 8)
-	cfi_rel_offset(fp, 0)
-	cfi_rel_offset(lr, 4)
+	UNWIND .setfp	fp, sp
 
-	mov	sp, r0		@ install the stack pointer
-	mov	lr, r2		@ move the fn pointer out of the way
-	ldr	ip, [fp, #16]	@ install the static chain
-	ldmia	sp!, {r0-r3}	@ move first 4 parameters in registers.
-	blx	lr		@ call fn
+	@ Make room for all of the new args.
+	sub	sp, fp, r2
+
+	@ Place all of the ffi_prep_args in position
+	mov	r0, sp
+	@     r1 already set
+
+	@ Call ffi_prep_args(stack, &ecif)
+	bl	CNAME(ffi_prep_args_SYSV)
+
+	@ move first 4 parameters in registers
+	ldmia	sp, {r0-r3}
+
+	@ and adjust stack
+	sub	lr, fp, sp	@ cif->bytes == fp - sp
+	ldr	ip, [fp]	@ load fn() in advance
+	cmp	lr, #16
+	movhs	lr, #16
+	add	sp, sp, lr
+
+	@ call (fn) (...)
+	call_reg(ip)
+	
+	@ Remove the space we pushed for the args
+	mov	sp, fp
 
 	@ Load r2 with the pointer to storage for the return value
-	@ Load r3 with the return type code
-	ldr	r2, [fp, #8]
-	ldr	r3, [fp, #12]
+	ldr	r2, [sp, #24]
 
-	@ Deallocate the stack with the arguments.
-	mov	sp, fp
-	cfi_def_cfa_register(sp)
+	@ Load r3 with the return type code 
+	ldr	r3, [sp, #12]
 
-	@ Store values stored in registers.
-	.align	3
-	add	pc, pc, r3, lsl #3
-	nop
-0:
-E(ARM_TYPE_VFP_S)
-#ifdef __clang__
-	vstr s0, [r2]
-#else
-	stc	p10, cr0, [r2]		@ vstr s0, [r2]
-#endif
-	pop	{fp,pc}
-E(ARM_TYPE_VFP_D)
-#ifdef __clang__
-	vstr d0, [r2]
-#else
-	stc	p11, cr0, [r2]		@ vstr d0, [r2]
-#endif
-	pop	{fp,pc}
-E(ARM_TYPE_VFP_N)
-#ifdef __clang__
-	vstm r2, {d0-d3}
-#else
-	stc	p11, cr0, [r2], {8}	@ vstm r2, {d0-d3}
-#endif
-	pop	{fp,pc}
-E(ARM_TYPE_INT64)
-	str	r1, [r2, #4]
-	nop
-E(ARM_TYPE_INT)
-	str	r0, [r2]
-	pop	{fp,pc}
-E(ARM_TYPE_VOID)
-	pop	{fp,pc}
-	nop
-E(ARM_TYPE_STRUCT)
-	pop	{fp,pc}
+	@ If the return value pointer is NULL, assume no return value.
+	cmp	r2, #0
+	beq	LSYM(Lepilogue)
 
-	cfi_endproc
-	UNWIND(.fnend)
-ARM_FUNC_END(ffi_call_SYSV)
+@ return INT
+	cmp	r3, #FFI_TYPE_INT
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+	cmpne	r3, #FFI_TYPE_FLOAT
+#endif
+	streq	r0, [r2]
+	beq	LSYM(Lepilogue)
+
+	@ return INT64
+	cmp	r3, #FFI_TYPE_SINT64
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+	cmpne	r3, #FFI_TYPE_DOUBLE
+#endif
+	stmiaeq	r2, {r0, r1}
+
+#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
+	beq	LSYM(Lepilogue)
+
+@ return FLOAT
+	cmp	r3, #FFI_TYPE_FLOAT
+	stfeqs	f0, [r2]
+	beq	LSYM(Lepilogue)
+
+@ return DOUBLE or LONGDOUBLE
+	cmp	r3, #FFI_TYPE_DOUBLE
+	stfeqd	f0, [r2]
+#endif
+
+LSYM(Lepilogue):
+#if defined (__INTERWORKING__)
+	ldmia   sp!, {r0-r3,fp, lr}
+	bx	lr
+#else
+	ldmia   sp!, {r0-r3,fp, pc}
+#endif
+
+.ffi_call_SYSV_end:
+	UNWIND .fnend
+#ifdef __ELF__
+        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+#endif
 
 
 /*
-	int ffi_closure_inner_* (cif, fun, user_data, frame)
+	unsigned int FFI_HIDDEN
+	ffi_closure_inner (closure, respp, args)
+	     ffi_closure *closure;
+	     void **respp;
+  	     void *args;
 */
 
-ARM_FUNC_START(ffi_go_closure_SYSV)
-	cfi_startproc
-	stmdb	sp!, {r0-r3}			@ save argument regs
-	cfi_adjust_cfa_offset(16)
-	ldr	r0, [ip, #4]			@ load cif
-	ldr	r1, [ip, #8]			@ load fun
-	mov	r2, ip				@ load user_data
-	b	0f
-	cfi_endproc
-ARM_FUNC_END(ffi_go_closure_SYSV)
-
 ARM_FUNC_START(ffi_closure_SYSV)
-	UNWIND(.fnstart)
-	cfi_startproc
-	stmdb	sp!, {r0-r3}			@ save argument regs
-	cfi_adjust_cfa_offset(16)
+	UNWIND .pad #16
+	add	ip, sp, #16
+	stmfd	sp!, {ip, lr}
+	UNWIND .save	{r0, lr}
+	add	r2, sp, #8
+	UNWIND .pad #16
+	sub	sp, sp, #16
+	str	sp, [sp, #8]
+	add	r1, sp, #8
+	bl	CNAME(ffi_closure_inner)
+	cmp	r0, #FFI_TYPE_INT
+	beq	.Lretint
 
-#if FFI_EXEC_TRAMPOLINE_TABLE
-	ldr ip, [ip]				@ ip points to the config page, dereference to get the ffi_closure*
+	cmp	r0, #FFI_TYPE_FLOAT
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+	beq	.Lretint
+#else
+	beq	.Lretfloat
 #endif
-	ldr	r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET]	@ load cif
-	ldr	r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4]  @ load fun
-	ldr	r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8]  @ load user_data
-0:
-	add	ip, sp, #16			@ compute entry sp
-	sub	sp, sp, #64+32			@ allocate frame
-	cfi_adjust_cfa_offset(64+32)
-	stmdb	sp!, {ip,lr}
 
-	/* Remember that EABI unwind info only applies at call sites.
-	   We need do nothing except note the save of the stack pointer
-	   and the link registers.  */
-	UNWIND(.save {sp,lr})
-	cfi_adjust_cfa_offset(8)
-	cfi_rel_offset(lr, 4)
+	cmp	r0, #FFI_TYPE_DOUBLE
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+	beq	.Lretlonglong
+#else
+	beq	.Lretdouble
+#endif
 
-	add	r3, sp, #8			@ load frame
-	bl	CNAME(ffi_closure_inner_SYSV)
+	cmp	r0, #FFI_TYPE_LONGDOUBLE
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+	beq	.Lretlonglong
+#else
+	beq	.Lretlongdouble
+#endif
 
-	@ Load values returned in registers.
-	add	r2, sp, #8+64			@ load result
-	adr	r3, CNAME(ffi_closure_ret)
-	add	pc, r3, r0, lsl #3
-	cfi_endproc
-	UNWIND(.fnend)
-ARM_FUNC_END(ffi_closure_SYSV)
+	cmp	r0, #FFI_TYPE_SINT64
+	beq	.Lretlonglong
+.Lclosure_epilogue:
+	add	sp, sp, #16
+	ldmfd	sp, {sp, pc}
+.Lretint:
+	ldr	r0, [sp]
+	b	.Lclosure_epilogue
+.Lretlonglong:
+	ldr	r0, [sp]
+	ldr	r1, [sp, #4]
+	b	.Lclosure_epilogue
 
-ARM_FUNC_START(ffi_go_closure_VFP)
-	cfi_startproc
-	stmdb	sp!, {r0-r3}			@ save argument regs
-	cfi_adjust_cfa_offset(16)
-	ldr	r0, [ip, #4]			@ load cif
-	ldr	r1, [ip, #8]			@ load fun
-	mov	r2, ip				@ load user_data
-	b	0f
-	cfi_endproc
-ARM_FUNC_END(ffi_go_closure_VFP)
+#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
+.Lretfloat:
+	ldfs	f0, [sp]
+	b	.Lclosure_epilogue
+.Lretdouble:
+	ldfd	f0, [sp]
+	b	.Lclosure_epilogue
+.Lretlongdouble:
+	ldfd	f0, [sp]
+	b	.Lclosure_epilogue
+#endif
+
+.ffi_closure_SYSV_end:
+	UNWIND .fnend
+#ifdef __ELF__
+        .size    CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+#endif
+
+
+/* Below are VFP hard-float ABI call and closure implementations.
+   Add VFP FPU directive here. This is only compiled into the library
+   under EABI.  */
+#ifdef __ARM_EABI__
+	.fpu	vfp
+
+	@ r0:   fn
+	@ r1:   &ecif
+	@ r2:   cif->bytes
+	@ r3:   fig->flags
+	@ sp+0: ecif.rvalue
+
+ARM_FUNC_START(ffi_call_VFP)
+	@ Save registers
+        stmfd	sp!, {r0-r3, fp, lr}
+	UNWIND .save	{r0-r3, fp, lr}
+	mov	fp, sp
+	UNWIND .setfp	fp, sp
+
+	@ Make room for all of the new args.
+	sub	sp, sp, r2
+
+	@ Make room for loading VFP args
+	sub	sp, sp, #64
+
+	@ Place all of the ffi_prep_args in position
+	mov	r0, sp
+	@     r1 already set
+	sub	r2, fp, #64   @ VFP scratch space
+
+	@ Call ffi_prep_args(stack, &ecif, vfp_space)
+	bl	CNAME(ffi_prep_args_VFP)
+
+	@ Load VFP register args if needed
+	cmp	r0, #0
+	mov	ip, fp
+	beq	LSYM(Lbase_args)
+
+	@ Load only d0 if possible
+	cmp	r0, #3
+	sub	ip, fp, #64
+	flddle	d0, [ip]
+	vldmiagt	ip, {d0-d7}
+
+LSYM(Lbase_args):
+	@ move first 4 parameters in registers
+	ldmia	sp, {r0-r3}
+
+	@ and adjust stack
+	sub	lr, ip, sp	@ cif->bytes == (fp - 64) - sp
+	ldr	ip, [fp]	@ load fn() in advance
+        cmp	lr, #16
+	movhs	lr, #16
+        add	sp, sp, lr
+
+	@ call (fn) (...)
+	call_reg(ip)
+
+	@ Remove the space we pushed for the args
+	mov	sp, fp
+
+	@ Load r2 with the pointer to storage for
+	@ the return value
+	ldr	r2, [sp, #24]
+
+	@ Load r3 with the return type code 
+	ldr	r3, [sp, #12]
+
+	@ If the return value pointer is NULL,
+	@ assume no return value.
+	cmp	r2, #0
+	beq	LSYM(Lepilogue_vfp)
+
+	cmp	r3, #FFI_TYPE_INT
+	streq	r0, [r2]
+	beq	LSYM(Lepilogue_vfp)
+
+	cmp	r3, #FFI_TYPE_SINT64
+	stmiaeq	r2, {r0, r1}
+	beq	LSYM(Lepilogue_vfp)
+
+	cmp	r3, #FFI_TYPE_FLOAT
+	fstseq	s0, [r2]
+	beq	LSYM(Lepilogue_vfp)
+	
+	cmp	r3, #FFI_TYPE_DOUBLE
+	fstdeq	d0, [r2]
+	beq	LSYM(Lepilogue_vfp)
+
+	cmp	r3, #FFI_TYPE_STRUCT_VFP_FLOAT
+	cmpne	r3, #FFI_TYPE_STRUCT_VFP_DOUBLE
+	vstmiaeq	r2, {d0-d3}
+
+LSYM(Lepilogue_vfp):
+	RETLDM	"r0-r3,fp"
+
+.ffi_call_VFP_end:
+	UNWIND .fnend
+        .size    CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP)
+
 
 ARM_FUNC_START(ffi_closure_VFP)
-	UNWIND(.fnstart)
-	cfi_startproc
-	stmdb	sp!, {r0-r3}			@ save argument regs
-	cfi_adjust_cfa_offset(16)
+	vpush	{d0-d7}
+	@ r0-r3, then d0-d7
+	UNWIND .pad #80
+	add	ip, sp, #80
+	stmfd	sp!, {ip, lr}
+	UNWIND .save	{r0, lr}
+	add	r2, sp, #72
+	add	r3, sp, #8
+	UNWIND .pad #72
+	sub	sp, sp, #72
+	str	sp, [sp, #64]
+	add	r1, sp, #64
+	bl	CNAME(ffi_closure_inner)
 
-#if FFI_EXEC_TRAMPOLINE_TABLE
-	ldr ip, [ip]				@ ip points to the config page, dereference to get the ffi_closure*
-#endif
-	ldr	r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET]	@ load cif
-	ldr	r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4]  @ load fun
-	ldr	r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8]  @ load user_data
-0:
-	add	ip, sp, #16
-	sub	sp, sp, #64+32			@ allocate frame
-	cfi_adjust_cfa_offset(64+32)
-#ifdef __clang__
-	vstm sp, {d0-d7}
-#else
-	stc	p11, cr0, [sp], {16}		@ vstm sp, {d0-d7}
-#endif
-	stmdb	sp!, {ip,lr}
+	cmp	r0, #FFI_TYPE_INT
+	beq	.Lretint_vfp
 
-	/* See above.  */
-	UNWIND(.save {sp,lr})
-	cfi_adjust_cfa_offset(8)
-	cfi_rel_offset(lr, 4)
+	cmp	r0, #FFI_TYPE_FLOAT
+	beq	.Lretfloat_vfp
 
-	add	r3, sp, #8			@ load frame
-	bl	CNAME(ffi_closure_inner_VFP)
+	cmp	r0, #FFI_TYPE_DOUBLE
+	cmpne	r0, #FFI_TYPE_LONGDOUBLE
+	beq	.Lretdouble_vfp
 
-	@ Load values returned in registers.
-	add	r2, sp, #8+64			@ load result
-	adr	r3, CNAME(ffi_closure_ret)
-	add	pc, r3, r0, lsl #3
-	cfi_endproc
-	UNWIND(.fnend)
-ARM_FUNC_END(ffi_closure_VFP)
+	cmp	r0, #FFI_TYPE_SINT64
+	beq	.Lretlonglong_vfp
 
-/* Load values returned in registers for both closure entry points.
-   Note that we use LDM with SP in the register set.  This is deprecated
-   by ARM, but not yet unpredictable.  */
+	cmp	r0, #FFI_TYPE_STRUCT_VFP_FLOAT
+	beq	.Lretfloat_struct_vfp
 
-ARM_FUNC_START_LOCAL(ffi_closure_ret)
-	cfi_startproc
-	cfi_rel_offset(sp, 0)
-	cfi_rel_offset(lr, 4)
-0:
-E(ARM_TYPE_VFP_S)
-#ifdef __clang__
-	vldr s0, [r2]
-#else
-	ldc	p10, cr0, [r2]			@ vldr s0, [r2]
-#endif
-	ldm	sp, {sp,pc}
-E(ARM_TYPE_VFP_D)
-#ifdef __clang__
-	vldr d0, [r2]
-#else
-	ldc	p11, cr0, [r2]			@ vldr d0, [r2]
-#endif
-	ldm	sp, {sp,pc}
-E(ARM_TYPE_VFP_N)
-#ifdef __clang__
-	vldm r2, {d0-d3}
-#else
-	ldc	p11, cr0, [r2], {8}		@ vldm r2, {d0-d3}
-#endif
-	ldm	sp, {sp,pc}
-E(ARM_TYPE_INT64)
-	ldr	r1, [r2, #4]
-	nop
-E(ARM_TYPE_INT)
-	ldr	r0, [r2]
-	ldm	sp, {sp,pc}
-E(ARM_TYPE_VOID)
-	ldm	sp, {sp,pc}
-	nop
-E(ARM_TYPE_STRUCT)
-	ldm	sp, {sp,pc}
-	cfi_endproc
-ARM_FUNC_END(ffi_closure_ret)
+	cmp	r0, #FFI_TYPE_STRUCT_VFP_DOUBLE
+	beq	.Lretdouble_struct_vfp
+	
+.Lclosure_epilogue_vfp:
+	add	sp, sp, #72
+	ldmfd	sp, {sp, pc}
 
-#if FFI_EXEC_TRAMPOLINE_TABLE
+.Lretfloat_vfp:
+	flds	s0, [sp]
+	b	.Lclosure_epilogue_vfp
+.Lretdouble_vfp:
+	fldd	d0, [sp]
+	b	.Lclosure_epilogue_vfp
+.Lretint_vfp:
+	ldr	r0, [sp]
+	b	.Lclosure_epilogue_vfp
+.Lretlonglong_vfp:
+	ldmia	sp, {r0, r1}
+	b	.Lclosure_epilogue_vfp
+.Lretfloat_struct_vfp:
+	vldmia	sp, {d0-d1}
+	b	.Lclosure_epilogue_vfp
+.Lretdouble_struct_vfp:
+	vldmia	sp, {d0-d3}
+	b	.Lclosure_epilogue_vfp
 
-#ifdef __MACH__
-#include <mach/machine/vm_param.h>
-
-.align	PAGE_MAX_SHIFT
-ARM_FUNC_START(ffi_closure_trampoline_table_page)
-.rept	PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
-	adr ip, #-PAGE_MAX_SIZE   @ the config page is PAGE_MAX_SIZE behind the trampoline page
-	sub ip, #8				  @ account for pc bias
-	ldr	pc, [ip, #4]		  @ jump to ffi_closure_SYSV or ffi_closure_VFP
-.endr
-ARM_FUNC_END(ffi_closure_trampoline_table_page)
+.ffi_closure_VFP_end:
+	UNWIND .fnend
+        .size    CNAME(ffi_closure_VFP),.ffi_closure_VFP_end-CNAME(ffi_closure_VFP)
 #endif
 
-#else
-
-ARM_FUNC_START(ffi_arm_trampoline)
-0:	adr	ip, 0b
-	ldr	pc, 1f
-1:	.long	0
-ARM_FUNC_END(ffi_arm_trampoline)
-
-#endif /* FFI_EXEC_TRAMPOLINE_TABLE */
-#endif /* __arm__ */
+ENTRY(ffi_arm_trampoline)
+	stmfd sp!, {r0-r3}
+	ldr r0, [pc]
+	ldr pc, [pc]
 
 #if defined __ELF__ && defined __linux__
 	.section	.note.GNU-stack,"",%progbits
diff --git a/src/arm/sysv_msvc_arm32.S b/src/arm/sysv_msvc_arm32.S
deleted file mode 100644
index 5c99d02..0000000
--- a/src/arm/sysv_msvc_arm32.S
+++ /dev/null
@@ -1,311 +0,0 @@
-/* -----------------------------------------------------------------------
-   sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
-        Copyright (c) 2011 Plausible Labs Cooperative, Inc.
-        Copyright (c) 2019 Microsoft Corporation.
-
-   ARM Foreign Function Interface
-
-   Permission is hereby granted, free of charge, to any person obtaining
-   a copy of this software and associated documentation files (the
-   ``Software''), to deal in the Software without restriction, including
-   without limitation the rights to use, copy, modify, merge, publish,
-   distribute, sublicense, and/or sell copies of the Software, and to
-   permit persons to whom the Software is furnished to do so, subject to
-   the following conditions:
-
-   The above copyright notice and this permission notice shall be included
-   in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-   DEALINGS IN THE SOFTWARE.
-   ----------------------------------------------------------------------- */
-
-#define LIBFFI_ASM
-#include <fficonfig.h>
-#include <ffi.h>
-#include <ffi_cfi.h>
-#include "internal.h"
-#include "ksarm.h"
-
-
-        ; 8 byte aligned AREA to support 8 byte aligned jump tables
-        MACRO
-        NESTED_ENTRY_FFI $FuncName, $AreaName, $ExceptHandler
-
-        ; compute the function's labels
-        __DeriveFunctionLabels $FuncName
-
-        ; determine the area we will put the function into
-__FuncArea   SETS    "|.text|"
-        IF "$AreaName" != ""
-__FuncArea   SETS    "$AreaName"
-        ENDIF
-
-        ; set up the exception handler itself
-__FuncExceptionHandler SETS ""
-        IF "$ExceptHandler" != ""
-__FuncExceptionHandler SETS    "|$ExceptHandler|"
-        ENDIF
-
-        ; switch to the specified area, jump tables require 8 byte alignment
-        AREA    $__FuncArea,CODE,CODEALIGN,ALIGN=3,READONLY
-
-        ; export the function name
-        __ExportProc $FuncName
-
-        ; flush any pending literal pool stuff
-        ROUT
-
-        ; reset the state of the unwind code tracking
-        __ResetUnwindState
-
-        MEND
-
-;        MACRO
-;        TABLE_ENTRY $Type, $Table
-;$Type_$Table
-;        MEND
-
-#define E(index,table) return_##index##_##table
-
-    ; r0:   stack
-    ; r1:   frame
-    ; r2:   fn
-    ; r3:   vfp_used
-
-    ; fake entry point exists only to generate exists only to 
-    ; generate .pdata for exception unwinding
-    NESTED_ENTRY_FFI ffi_call_VFP_fake
-    PROLOG_PUSH  {r11, lr}          ; save fp and lr for unwind
-
-    ALTERNATE_ENTRY ffi_call_VFP
-    cmp    r3, #3                   ; load only d0 if possible
-    vldrle d0, [r0]
-    vldmgt r0, {d0-d7}
-    add    r0, r0, #64              ; discard the vfp register args
-    b ffi_call_SYSV
-    NESTED_END ffi_call_VFP_fake
-
-    ; fake entry point exists only to generate exists only to 
-    ; generate .pdata for exception unwinding
-    NESTED_ENTRY_FFI ffi_call_SYSV_fake
-    PROLOG_PUSH  {r11, lr}          ; save fp and lr for unwind
-
-    ALTERNATE_ENTRY ffi_call_SYSV
-    stm    r1, {fp, lr}
-    mov    fp, r1
-
-    mov    sp, r0                   ; install the stack pointer
-    mov    lr, r2                   ; move the fn pointer out of the way
-    ldr    ip, [fp, #16]            ; install the static chain
-    ldmia  sp!, {r0-r3}             ; move first 4 parameters in registers.
-    blx    lr                       ; call fn
-
-    ; Load r2 with the pointer to storage for the return value
-    ; Load r3 with the return type code
-    ldr    r2, [fp, #8]
-    ldr    r3, [fp, #12]
-
-    ; Deallocate the stack with the arguments.
-    mov    sp, fp
-
-    ; Store values stored in registers.
-    ALIGN 8
-    lsl     r3, #3
-    add     r3, r3, pc
-    add     r3, #8
-    mov     pc, r3
-
-
-E(ARM_TYPE_VFP_S, ffi_call)
-    ALIGN 8
-    vstr s0, [r2]
-    pop    {fp,pc}
-E(ARM_TYPE_VFP_D, ffi_call)
-    ALIGN 8
-    vstr d0, [r2]
-    pop    {fp,pc}
-E(ARM_TYPE_VFP_N, ffi_call)
-    ALIGN 8
-    vstm r2, {d0-d3}
-    pop    {fp,pc}
-E(ARM_TYPE_INT64, ffi_call)
-    ALIGN 8
-    str    r1, [r2, #4]
-    nop
-E(ARM_TYPE_INT, ffi_call)
-    ALIGN 8
-    str    r0, [r2]
-    pop    {fp,pc}
-E(ARM_TYPE_VOID, ffi_call)
-    ALIGN 8
-    pop    {fp,pc}
-    nop
-E(ARM_TYPE_STRUCT, ffi_call)
-    ALIGN 8
-    cmp r3, #ARM_TYPE_STRUCT
-    pop    {fp,pc}
-    NESTED_END ffi_call_SYSV_fake
-
-    IMPORT |ffi_closure_inner_SYSV|
-    /*
-    int ffi_closure_inner_SYSV
-    (
-        cif,        ; r0
-        fun,        ; r1
-        user_data,  ; r2
-        frame       ; r3
-    )
-    */
-
-    NESTED_ENTRY_FFI ffi_go_closure_SYSV
-    stmdb   sp!, {r0-r3}            ; save argument regs
-    ldr     r0, [ip, #4]            ; load cif
-    ldr     r1, [ip, #8]            ; load fun
-    mov     r2, ip                  ; load user_data
-    b       ffi_go_closure_SYSV_0
-    NESTED_END ffi_go_closure_SYSV
-
-    ; r3:    ffi_closure
-
-    ; fake entry point exists only to generate exists only to 
-    ; generate .pdata for exception unwinding
-    NESTED_ENTRY_FFI ffi_closure_SYSV_fake  
-    PROLOG_PUSH  {r11, lr}          ; save fp and lr for unwind
-    ALTERNATE_ENTRY ffi_closure_SYSV
-    ldmfd   sp!, {ip,r0}            ; restore fp (r0 is used for stack alignment)
-    stmdb   sp!, {r0-r3}            ; save argument regs
-
-    ldr     r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET]    ; ffi_closure->cif
-    ldr     r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4]  ; ffi_closure->fun
-    ldr     r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8]  ; ffi_closure->user_data
-
-    ALTERNATE_ENTRY ffi_go_closure_SYSV_0
-    add     ip, sp, #16             ; compute entry sp
-
-    sub     sp, sp, #64+32          ; allocate frame parameter (sizeof(vfp_space) = 64, sizeof(result) = 32)
-    mov     r3, sp                  ; set frame parameter
-    stmdb   sp!, {ip,lr}
-
-    bl      ffi_closure_inner_SYSV  ; call the Python closure
-
-                                    ; Load values returned in registers.
-    add     r2, sp, #64+8           ; address of closure_frame->result
-    bl      ffi_closure_ret         ; move result to correct register or memory for type
-
-    ldmfd   sp!, {ip,lr}
-    mov     sp, ip                  ; restore stack pointer
-    mov     pc, lr
-    NESTED_END ffi_closure_SYSV_fake
-
-    IMPORT |ffi_closure_inner_VFP|
-    /*
-    int ffi_closure_inner_VFP
-    (
-        cif,        ; r0
-        fun,        ; r1
-        user_data,  ; r2
-        frame       ; r3
-    )
-    */
-
-    NESTED_ENTRY_FFI ffi_go_closure_VFP
-    stmdb   sp!, {r0-r3}			; save argument regs
-    ldr	r0, [ip, #4]			; load cif
-    ldr	r1, [ip, #8]			; load fun
-    mov	r2, ip				; load user_data
-    b	ffi_go_closure_VFP_0
-    NESTED_END ffi_go_closure_VFP
-
-    ; fake entry point exists only to generate exists only to 
-    ; generate .pdata for exception unwinding
-    ; r3:    closure
-    NESTED_ENTRY_FFI ffi_closure_VFP_fake
-    PROLOG_PUSH  {r11, lr}          ; save fp and lr for unwind
-
-    ALTERNATE_ENTRY ffi_closure_VFP
-    ldmfd   sp!, {ip,r0}            ; restore fp (r0 is used for stack alignment)
-    stmdb   sp!, {r0-r3}            ; save argument regs
-
-    ldr     r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET]    ; load cif
-    ldr     r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4]  ; load fun
-    ldr     r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8]  ; load user_data
-
-    ALTERNATE_ENTRY ffi_go_closure_VFP_0
-    add     ip, sp, #16             ; compute entry sp
-    sub     sp, sp, #32             ; save space for closure_frame->result
-    vstmdb  sp!, {d0-d7}            ; push closure_frame->vfp_space
-
-    mov     r3, sp                  ; save closure_frame
-    stmdb   sp!, {ip,lr}
-
-    bl      ffi_closure_inner_VFP
-
-    ; Load values returned in registers.
-    add     r2, sp, #64+8           ; load result
-    bl      ffi_closure_ret
-    ldmfd   sp!, {ip,lr}
-    mov     sp, ip                  ; restore stack pointer
-    mov     pc, lr
-    NESTED_END ffi_closure_VFP_fake
-
-/* Load values returned in registers for both closure entry points.
-   Note that we use LDM with SP in the register set.  This is deprecated
-   by ARM, but not yet unpredictable.  */
-
-    NESTED_ENTRY_FFI ffi_closure_ret
-    stmdb sp!, {fp,lr}
-
-    ALIGN 8
-    lsl     r0, #3
-    add     r0, r0, pc
-    add     r0, #8
-    mov     pc, r0
-
-E(ARM_TYPE_VFP_S, ffi_closure)
-    ALIGN 8
-    vldr s0, [r2]
-    b call_epilogue
-E(ARM_TYPE_VFP_D, ffi_closure)
-    ALIGN 8
-    vldr d0, [r2]
-    b call_epilogue
-E(ARM_TYPE_VFP_N, ffi_closure)
-    ALIGN 8
-    vldm r2, {d0-d3}
-    b call_epilogue
-E(ARM_TYPE_INT64, ffi_closure)
-    ALIGN 8
-    ldr    r1, [r2, #4]
-    nop
-E(ARM_TYPE_INT, ffi_closure)
-    ALIGN 8
-    ldr    r0, [r2]
-    b call_epilogue
-E(ARM_TYPE_VOID, ffi_closure)
-    ALIGN 8
-    b call_epilogue
-    nop
-E(ARM_TYPE_STRUCT, ffi_closure)
-    ALIGN 8
-    b call_epilogue
-call_epilogue
-    ldmfd sp!, {fp,pc}
-    NESTED_END ffi_closure_ret
-
-    AREA |.trampoline|, DATA, THUMB, READONLY
-    EXPORT |ffi_arm_trampoline|
-|ffi_arm_trampoline| DATA
-thisproc    adr    ip, thisproc
-            stmdb  sp!, {ip, r0}
-            ldr    pc, [pc, #0]
-            DCD    0
-            ;ENDP
-
-    END
\ No newline at end of file
diff --git a/src/closures.c b/src/closures.c
index 5120021..721ff00 100644
--- a/src/closures.c
+++ b/src/closures.c
@@ -1,6 +1,5 @@
 /* -----------------------------------------------------------------------
-   closures.c - Copyright (c) 2019 Anthony Green
-                Copyright (c) 2007, 2009, 2010 Red Hat, Inc.
+   closures.c - Copyright (c) 2007, 2009, 2010  Red Hat, Inc.
                 Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
                 Copyright (c) 2011 Plausible Labs Cooperative, Inc.
 
@@ -31,88 +30,11 @@
 #define _GNU_SOURCE 1
 #endif
 
-#include <fficonfig.h>
 #include <ffi.h>
 #include <ffi_common.h>
 
-#ifdef __NetBSD__
-#include <sys/param.h>
-#endif
-
-#if __NetBSD_Version__ - 0 >= 799007200
-/* NetBSD with PROT_MPROTECT */
-#include <sys/mman.h>
-
-#include <stddef.h>
-#include <unistd.h>
-
-static const size_t overhead =
-  (sizeof(max_align_t) > sizeof(void *) + sizeof(size_t)) ?
-    sizeof(max_align_t)
-    : sizeof(void *) + sizeof(size_t);
-
-#define ADD_TO_POINTER(p, d) ((void *)((uintptr_t)(p) + (d)))
-
-void *
-ffi_closure_alloc (size_t size, void **code)
-{
-  static size_t page_size;
-  size_t rounded_size;
-  void *codeseg, *dataseg;
-  int prot;
-
-  /* Expect that PAX mprotect is active and a separate code mapping is necessary. */
-  if (!code)
-    return NULL;
-
-  /* Obtain system page size. */
-  if (!page_size)
-    page_size = sysconf(_SC_PAGESIZE);
-
-  /* Round allocation size up to the next page, keeping in mind the size field and pointer to code map. */
-  rounded_size = (size + overhead + page_size - 1) & ~(page_size - 1);
-
-  /* Primary mapping is RW, but request permission to switch to PROT_EXEC later. */
-  prot = PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC);
-  dataseg = mmap(NULL, rounded_size, prot, MAP_ANON | MAP_PRIVATE, -1, 0);
-  if (dataseg == MAP_FAILED)
-    return NULL;
-
-  /* Create secondary mapping and switch it to RX. */
-  codeseg = mremap(dataseg, rounded_size, NULL, rounded_size, MAP_REMAPDUP);
-  if (codeseg == MAP_FAILED) {
-    munmap(dataseg, rounded_size);
-    return NULL;
-  }
-  if (mprotect(codeseg, rounded_size, PROT_READ | PROT_EXEC) == -1) {
-    munmap(codeseg, rounded_size);
-    munmap(dataseg, rounded_size);
-    return NULL;
-  }
-
-  /* Remember allocation size and location of the secondary mapping for ffi_closure_free. */
-  memcpy(dataseg, &rounded_size, sizeof(rounded_size));
-  memcpy(ADD_TO_POINTER(dataseg, sizeof(size_t)), &codeseg, sizeof(void *));
-  *code = ADD_TO_POINTER(codeseg, overhead);
-  return ADD_TO_POINTER(dataseg, overhead);
-}
-
-void
-ffi_closure_free (void *ptr)
-{
-  void *codeseg, *dataseg;
-  size_t rounded_size;
-
-  dataseg = ADD_TO_POINTER(ptr, -overhead);
-  memcpy(&rounded_size, dataseg, sizeof(rounded_size));
-  memcpy(&codeseg, ADD_TO_POINTER(dataseg, sizeof(size_t)), sizeof(void *));
-  munmap(dataseg, rounded_size);
-  munmap(codeseg, rounded_size);
-}
-#else /* !NetBSD with PROT_MPROTECT */
-
 #if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
-# if __linux__ && !defined(__ANDROID__)
+# if __gnu_linux__ && !defined(__ANDROID__)
 /* This macro indicates it may be forbidden to map anonymous memory
    with both write and execute permission.  Code compiled when this
    option is defined will attempt to map such pages once, but if it
@@ -123,7 +45,7 @@
 #  define FFI_MMAP_EXEC_WRIT 1
 #  define HAVE_MNTENT 1
 # endif
-# if defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)
+# if defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)
 /* Windows systems may have Data Execution Protection (DEP) enabled, 
    which requires the use of VirtualMalloc/VirtualFree to alloc/free
    executable memory. */
@@ -132,7 +54,7 @@
 #endif
 
 #if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
-# if defined(__linux__) && !defined(__ANDROID__)
+# ifdef __linux__
 /* When defined to 1 check for SELinux and if SELinux is active,
    don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
    might cause audit messages.  */
@@ -142,216 +64,11 @@
 
 #if FFI_CLOSURES
 
-#if FFI_EXEC_TRAMPOLINE_TABLE
-
-#ifdef __MACH__
-
-#include <mach/mach.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-extern void *ffi_closure_trampoline_table_page;
-
-typedef struct ffi_trampoline_table ffi_trampoline_table;
-typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry;
-
-struct ffi_trampoline_table
-{
-  /* contiguous writable and executable pages */
-  vm_address_t config_page;
-  vm_address_t trampoline_page;
-
-  /* free list tracking */
-  uint16_t free_count;
-  ffi_trampoline_table_entry *free_list;
-  ffi_trampoline_table_entry *free_list_pool;
-
-  ffi_trampoline_table *prev;
-  ffi_trampoline_table *next;
-};
-
-struct ffi_trampoline_table_entry
-{
-  void *(*trampoline) (void);
-  ffi_trampoline_table_entry *next;
-};
-
-/* Total number of trampolines that fit in one trampoline table */
-#define FFI_TRAMPOLINE_COUNT (PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE)
-
-static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER;
-static ffi_trampoline_table *ffi_trampoline_tables = NULL;
-
-static ffi_trampoline_table *
-ffi_trampoline_table_alloc (void)
-{
-  ffi_trampoline_table *table;
-  vm_address_t config_page;
-  vm_address_t trampoline_page;
-  vm_address_t trampoline_page_template;
-  vm_prot_t cur_prot;
-  vm_prot_t max_prot;
-  kern_return_t kt;
-  uint16_t i;
-
-  /* Allocate two pages -- a config page and a placeholder page */
-  config_page = 0x0;
-  kt = vm_allocate (mach_task_self (), &config_page, PAGE_MAX_SIZE * 2,
-		    VM_FLAGS_ANYWHERE);
-  if (kt != KERN_SUCCESS)
-    return NULL;
-
-  /* Remap the trampoline table on top of the placeholder page */
-  trampoline_page = config_page + PAGE_MAX_SIZE;
-  trampoline_page_template = (vm_address_t)&ffi_closure_trampoline_table_page;
-#ifdef __arm__
-  /* ffi_closure_trampoline_table_page can be thumb-biased on some ARM archs */
-  trampoline_page_template &= ~1UL;
-#endif
-  kt = vm_remap (mach_task_self (), &trampoline_page, PAGE_MAX_SIZE, 0x0,
-		 VM_FLAGS_OVERWRITE, mach_task_self (), trampoline_page_template,
-		 FALSE, &cur_prot, &max_prot, VM_INHERIT_SHARE);
-  if (kt != KERN_SUCCESS)
-    {
-      vm_deallocate (mach_task_self (), config_page, PAGE_MAX_SIZE * 2);
-      return NULL;
-    }
-
-  /* We have valid trampoline and config pages */
-  table = calloc (1, sizeof (ffi_trampoline_table));
-  table->free_count = FFI_TRAMPOLINE_COUNT;
-  table->config_page = config_page;
-  table->trampoline_page = trampoline_page;
-
-  /* Create and initialize the free list */
-  table->free_list_pool =
-    calloc (FFI_TRAMPOLINE_COUNT, sizeof (ffi_trampoline_table_entry));
-
-  for (i = 0; i < table->free_count; i++)
-    {
-      ffi_trampoline_table_entry *entry = &table->free_list_pool[i];
-      entry->trampoline =
-	(void *) (table->trampoline_page + (i * FFI_TRAMPOLINE_SIZE));
-
-      if (i < table->free_count - 1)
-	entry->next = &table->free_list_pool[i + 1];
-    }
-
-  table->free_list = table->free_list_pool;
-
-  return table;
-}
-
-static void
-ffi_trampoline_table_free (ffi_trampoline_table *table)
-{
-  /* Remove from the list */
-  if (table->prev != NULL)
-    table->prev->next = table->next;
-
-  if (table->next != NULL)
-    table->next->prev = table->prev;
-
-  /* Deallocate pages */
-  vm_deallocate (mach_task_self (), table->config_page, PAGE_MAX_SIZE * 2);
-
-  /* Deallocate free list */
-  free (table->free_list_pool);
-  free (table);
-}
-
-void *
-ffi_closure_alloc (size_t size, void **code)
-{
-  /* Create the closure */
-  ffi_closure *closure = malloc (size);
-  if (closure == NULL)
-    return NULL;
-
-  pthread_mutex_lock (&ffi_trampoline_lock);
-
-  /* Check for an active trampoline table with available entries. */
-  ffi_trampoline_table *table = ffi_trampoline_tables;
-  if (table == NULL || table->free_list == NULL)
-    {
-      table = ffi_trampoline_table_alloc ();
-      if (table == NULL)
-	{
-	  pthread_mutex_unlock (&ffi_trampoline_lock);
-	  free (closure);
-	  return NULL;
-	}
-
-      /* Insert the new table at the top of the list */
-      table->next = ffi_trampoline_tables;
-      if (table->next != NULL)
-	table->next->prev = table;
-
-      ffi_trampoline_tables = table;
-    }
-
-  /* Claim the free entry */
-  ffi_trampoline_table_entry *entry = ffi_trampoline_tables->free_list;
-  ffi_trampoline_tables->free_list = entry->next;
-  ffi_trampoline_tables->free_count--;
-  entry->next = NULL;
-
-  pthread_mutex_unlock (&ffi_trampoline_lock);
-
-  /* Initialize the return values */
-  *code = entry->trampoline;
-  closure->trampoline_table = table;
-  closure->trampoline_table_entry = entry;
-
-  return closure;
-}
-
-void
-ffi_closure_free (void *ptr)
-{
-  ffi_closure *closure = ptr;
-
-  pthread_mutex_lock (&ffi_trampoline_lock);
-
-  /* Fetch the table and entry references */
-  ffi_trampoline_table *table = closure->trampoline_table;
-  ffi_trampoline_table_entry *entry = closure->trampoline_table_entry;
-
-  /* Return the entry to the free list */
-  entry->next = table->free_list;
-  table->free_list = entry;
-  table->free_count++;
-
-  /* If all trampolines within this table are free, and at least one other table exists, deallocate
-   * the table */
-  if (table->free_count == FFI_TRAMPOLINE_COUNT
-      && ffi_trampoline_tables != table)
-    {
-      ffi_trampoline_table_free (table);
-    }
-  else if (ffi_trampoline_tables != table)
-    {
-      /* Otherwise, bump this table to the top of the list */
-      table->prev = NULL;
-      table->next = ffi_trampoline_tables;
-      if (ffi_trampoline_tables != NULL)
-	ffi_trampoline_tables->prev = table;
-
-      ffi_trampoline_tables = table;
-    }
-
-  pthread_mutex_unlock (&ffi_trampoline_lock);
-
-  /* Free the closure */
-  free (closure);
-}
-
-#endif
+# if FFI_EXEC_TRAMPOLINE_TABLE
 
 // Per-target implementation; It's unclear what can reasonable be shared between two OS/architecture implementations.
 
-#elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */
+# elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */
 
 #define USE_LOCKS 1
 #define USE_DL_PREFIX 1
@@ -377,6 +94,14 @@
 /* Don't allocate more than a page unless needed.  */
 #define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)
 
+#if FFI_CLOSURE_TEST
+/* Don't release single pages, to avoid a worst-case scenario of
+   continuously allocating and releasing single pages, but release
+   pairs of pages, which should do just as well given that allocations
+   are likely to be small.  */
+#define DEFAULT_TRIM_THRESHOLD ((size_t)malloc_getpagesize)
+#endif
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -386,7 +111,7 @@
 #endif
 #include <string.h>
 #include <stdio.h>
-#if !defined(X86_WIN32) && !defined(X86_WIN64) && !defined(_M_ARM64)
+#if !defined(X86_WIN32) && !defined(X86_WIN64)
 #ifdef HAVE_MNTENT
 #include <mntent.h>
 #endif /* HAVE_MNTENT */
@@ -512,7 +237,7 @@
 static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
 static void dlmalloc_stats(void) MAYBE_UNUSED;
 
-#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
+#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
 /* Use these for mmap and munmap within dlmalloc.c.  */
 static void *dlmmap(void *, size_t, int, int, int, off_t);
 static int dlmunmap(void *, size_t);
@@ -526,7 +251,7 @@
 #undef mmap
 #undef munmap
 
-#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
+#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
 
 /* A mutex used to synchronize access to *exec* variables in this file.  */
 static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -583,7 +308,7 @@
   }
 #endif
 
-  lendir = (int) strlen (dir);
+  lendir = strlen (dir);
   tempname = __builtin_alloca (lendir + sizeof (suffix));
 
   if (!tempname)
@@ -724,36 +449,6 @@
   return fd;
 }
 
-/* We need to allocate space in a file that will be backing a writable
-   mapping.  Several problems exist with the usual approaches:
-   - fallocate() is Linux-only
-   - posix_fallocate() is not available on all platforms
-   - ftruncate() does not allocate space on filesystems with sparse files
-   Failure to allocate the space will cause SIGBUS to be thrown when
-   the mapping is subsequently written to.  */
-static int
-allocate_space (int fd, off_t offset, off_t len)
-{
-  static size_t page_size;
-
-  /* Obtain system page size. */
-  if (!page_size)
-    page_size = sysconf(_SC_PAGESIZE);
-
-  unsigned char buf[page_size];
-  memset (buf, 0, page_size);
-
-  while (len > 0)
-    {
-      off_t to_write = (len < page_size) ? len : page_size;
-      if (write (fd, buf, to_write) < to_write)
-        return -1;
-      len -= to_write;
-    }
-
-  return 0;
-}
-
 /* Map in a chunk of memory from the temporary exec file into separate
    locations in the virtual memory address space, one writable and one
    executable.  Returns the address of the writable portion, after
@@ -775,7 +470,7 @@
 
   offset = execsize;
 
-  if (allocate_space (execfd, offset, length))
+  if (ftruncate (execfd, offset + length))
     return MFAIL;
 
   flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
@@ -790,13 +485,7 @@
 	  close (execfd);
 	  goto retry_open;
 	}
-      if (ftruncate (execfd, offset) != 0)
-      {
-        /* Fixme : Error logs can be added here. Returning an error for
-         * ftruncte() will not add any advantage as it is being
-         * validating in the error case. */
-      }
-
+      ftruncate (execfd, offset);
       return MFAIL;
     }
   else if (!offset
@@ -808,12 +497,7 @@
   if (start == MFAIL)
     {
       munmap (ptr, length);
-      if (ftruncate (execfd, offset) != 0)
-      {
-        /* Fixme : Error logs can be added here. Returning an error for
-         * ftruncte() will not add any advantage as it is being
-         * validating in the error case. */
-      }
+      ftruncate (execfd, offset);
       return start;
     }
 
@@ -837,6 +521,10 @@
 	  && flags == (MAP_PRIVATE | MAP_ANONYMOUS)
 	  && fd == -1 && offset == 0);
 
+#if FFI_CLOSURE_TEST
+  printf ("mapping in %zi\n", length);
+#endif
+
   if (execfd == -1 && is_emutramp_enabled ())
     {
       ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);
@@ -882,6 +570,10 @@
   msegmentptr seg = segment_holding (gm, start);
   void *code;
 
+#if FFI_CLOSURE_TEST
+  printf ("unmapping %zi\n", length);
+#endif
+
   if (seg && (code = add_segment_exec_offset (start, seg)) != start)
     {
       int ret = munmap (code, length);
@@ -908,7 +600,7 @@
 }
 #endif
 
-#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
+#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
 
 /* Allocate a chunk of memory with the given size.  Returns a pointer
    to the writable address, and sets *CODE to the executable
@@ -933,20 +625,6 @@
   return ptr;
 }
 
-void *
-ffi_data_to_code_pointer (void *data)
-{
-  msegmentptr seg = segment_holding (gm, data);
-  /* We expect closures to be allocated with ffi_closure_alloc(), in
-     which case seg will be non-NULL.  However, some users take on the
-     burden of managing this memory themselves, in which case this
-     we'll just return data. */
-  if (seg)
-    return add_segment_exec_offset (data, seg);
-  else
-    return data;
-}
-
 /* Release a chunk of memory allocated with ffi_closure_alloc.  If
    FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
    writable or the executable address given.  Otherwise, only the
@@ -964,6 +642,26 @@
   dlfree (ptr);
 }
 
+
+#if FFI_CLOSURE_TEST
+/* Do some internal sanity testing to make sure allocation and
+   deallocation of pages are working as intended.  */
+int main ()
+{
+  void *p[3];
+#define GET(idx, len) do { p[idx] = dlmalloc (len); printf ("allocated %zi for p[%i]\n", (len), (idx)); } while (0)
+#define PUT(idx) do { printf ("freeing p[%i]\n", (idx)); dlfree (p[idx]); } while (0)
+  GET (0, malloc_getpagesize / 2);
+  GET (1, 2 * malloc_getpagesize - 64 * sizeof (void*));
+  PUT (1);
+  GET (1, 2 * malloc_getpagesize);
+  GET (2, malloc_getpagesize / 2);
+  PUT (1);
+  PUT (0);
+  PUT (2);
+  return 0;
+}
+#endif /* FFI_CLOSURE_TEST */
 # else /* ! FFI_MMAP_EXEC_WRIT */
 
 /* On many systems, memory returned by malloc is writable and
@@ -986,13 +684,5 @@
   free (ptr);
 }
 
-void *
-ffi_data_to_code_pointer (void *data)
-{
-  return data;
-}
-
 # endif /* ! FFI_MMAP_EXEC_WRIT */
 #endif /* FFI_CLOSURES */
-
-#endif /* NetBSD with PROT_MPROTECT */
diff --git a/src/cris/ffi.c b/src/cris/ffi.c
index 9011fde..aaca5b1 100644
--- a/src/cris/ffi.c
+++ b/src/cris/ffi.c
@@ -29,7 +29,7 @@
 #include <ffi.h>
 #include <ffi_common.h>
 
-#define STACK_ARG_SIZE(x) FFI_ALIGN(x, FFI_SIZEOF_ARG)
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
 
 static ffi_status
 initialize_aggregate_packed_struct (ffi_type * arg)
@@ -190,7 +190,7 @@
       FFI_ASSERT_VALID_TYPE (*ptr);
 
       if (((*ptr)->alignment - 1) & bytes)
-	bytes = FFI_ALIGN (bytes, (*ptr)->alignment);
+	bytes = ALIGN (bytes, (*ptr)->alignment);
       if ((*ptr)->type == FFI_TYPE_STRUCT)
 	{
 	  if ((*ptr)->size > 8)
diff --git a/src/dlmalloc.c b/src/dlmalloc.c
index d63dd36..8725b4f 100644
--- a/src/dlmalloc.c
+++ b/src/dlmalloc.c
@@ -438,11 +438,6 @@
 
 */
 
-#if defined __linux__ && !defined _GNU_SOURCE
-/* mremap() on Linux requires this via sys/mman.h */
-#define _GNU_SOURCE 1
-#endif
-
 #ifndef WIN32
 #ifdef _WIN32
 #define WIN32 1
@@ -2296,7 +2291,7 @@
 #define treebin_at(M,i)     (&((M)->treebins[i]))
 
 /* assign tree index for size S to variable I */
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && defined(i386)
 #define compute_tree_index(S, I)\
 {\
   size_t X = S >> TREEBIN_SHIFT;\
@@ -2361,7 +2356,7 @@
 
 /* index corresponding to given bit */
 
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && defined(i386)
 #define compute_bit2idx(X, I)\
 {\
   unsigned int J;\
diff --git a/src/frv/ffi.c b/src/frv/ffi.c
index ed1c65a..5698c89 100644
--- a/src/frv/ffi.c
+++ b/src/frv/ffi.c
@@ -107,7 +107,7 @@
       count += z;
     }
 
-  return (stack + ((count > 24) ? 24 : FFI_ALIGN_DOWN(count, 8)));
+  return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
 }
 
 /* Perform machine dependent cif processing */
@@ -118,7 +118,7 @@
   else
     cif->flags = cif->rtype->size;
 
-  cif->bytes = FFI_ALIGN (cif->bytes, 8);
+  cif->bytes = ALIGN (cif->bytes, 8);
 
   return FFI_OK;
 }
diff --git a/src/ia64/ffi.c b/src/ia64/ffi.c
index b1d04c3..b77a836 100644
--- a/src/ia64/ffi.c
+++ b/src/ia64/ffi.c
@@ -220,8 +220,8 @@
 
 /* Perform machine dependent cif processing. */
 
-static ffi_status
-ffi_prep_cif_machdep_core(ffi_cif *cif)
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
 {
   int flags;
 
@@ -271,22 +271,6 @@
   return FFI_OK;
 }
 
-ffi_status
-ffi_prep_cif_machdep(ffi_cif *cif)
-{
-  cif->nfixedargs = cif->nargs;
-  return ffi_prep_cif_machdep_core(cif);
-}
-
-ffi_status
-ffi_prep_cif_machdep_var(ffi_cif *cif,
-			 unsigned int nfixedargs,
-			 unsigned int ntotalargs MAYBE_UNUSED)
-{
-  cif->nfixedargs = nfixedargs;
-  return ffi_prep_cif_machdep_core(cif);
-}
-
 extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(void), UINT64);
 
 void
@@ -470,11 +454,10 @@
   ffi_cif *cif;
   void **avalue;
   ffi_type **p_arg;
-  long i, avn, gpcount, fpcount, nfixedargs;
+  long i, avn, gpcount, fpcount;
 
   cif = closure->cif;
   avn = cif->nargs;
-  nfixedargs = cif->nfixedargs;
   avalue = alloca (avn * sizeof (void *));
 
   /* If the structure return value is passed in memory get that location
@@ -485,7 +468,6 @@
   gpcount = fpcount = 0;
   for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
     {
-      int named = i < nfixedargs;
       switch ((*p_arg)->type)
 	{
 	case FFI_TYPE_SINT8:
@@ -509,7 +491,7 @@
 	  break;
 
 	case FFI_TYPE_FLOAT:
-	  if (named && gpcount < 8 && fpcount < 8)
+	  if (gpcount < 8 && fpcount < 8)
 	    {
 	      fpreg *addr = &stack->fp_regs[fpcount++];
 	      float result;
@@ -523,7 +505,7 @@
 	  break;
 
 	case FFI_TYPE_DOUBLE:
-	  if (named && gpcount < 8 && fpcount < 8)
+	  if (gpcount < 8 && fpcount < 8)
 	    {
 	      fpreg *addr = &stack->fp_regs[fpcount++];
 	      double result;
@@ -539,7 +521,7 @@
 	case FFI_TYPE_LONGDOUBLE:
 	  if (gpcount & 1)
 	    gpcount++;
-	  if (LDBL_MANT_DIG == 64 && named && gpcount < 8 && fpcount < 8)
+	  if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
 	    {
 	      fpreg *addr = &stack->fp_regs[fpcount++];
 	      __float80 result;
diff --git a/src/ia64/ffitarget.h b/src/ia64/ffitarget.h
index fd5b9a0..e68cea6 100644
--- a/src/ia64/ffitarget.h
+++ b/src/ia64/ffitarget.h
@@ -50,7 +50,6 @@
 #define FFI_TRAMPOLINE_SIZE 24  /* Really the following struct, which 	*/
 				/* can be interpreted as a C function	*/
 				/* descriptor:				*/
-#define FFI_TARGET_SPECIFIC_VARIADIC 1
-#define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
 
 #endif
+
diff --git a/src/ia64/unix.S b/src/ia64/unix.S
index e2547e0..4d2a86d 100644
--- a/src/ia64/unix.S
+++ b/src/ia64/unix.S
@@ -175,6 +175,7 @@
 	;;
 
 .Lst_small_struct:
+	add	sp = -16, sp
 	cmp.lt	p6, p0 = 8, in3
 	cmp.lt	p7, p0 = 16, in3
 	cmp.lt	p8, p0 = 24, in3
@@ -190,12 +191,6 @@
 (p8)	st8	[r18] = r11
 	mov	out1 = sp
 	mov	out2 = in3
-	;;
-	// ia64 software calling convention requires
-	// top 16 bytes of stack to be scratch space
-	// PLT resolver uses that scratch space at
-	// 'memcpy' symbol reolution time
-	add	sp = -16, sp
 	br.call.sptk.many b0 = memcpy#
 	;;
 	mov	ar.pfs = loc0
@@ -534,7 +529,6 @@
 	data8	@pcrel(.Lst_int64)		// FFI_TYPE_SINT64
 	data8	@pcrel(.Lst_void)		// FFI_TYPE_STRUCT
 	data8	@pcrel(.Lst_int64)		// FFI_TYPE_POINTER
-	data8	@pcrel(.Lst_void)		// FFI_TYPE_COMPLEX (not implemented)
 	data8 	@pcrel(.Lst_small_struct)	// FFI_IA64_TYPE_SMALL_STRUCT
 	data8	@pcrel(.Lst_hfa_float)		// FFI_IA64_TYPE_HFA_FLOAT
 	data8	@pcrel(.Lst_hfa_double)		// FFI_IA64_TYPE_HFA_DOUBLE
@@ -556,7 +550,6 @@
 	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT64
 	data8	@pcrel(.Lld_void)		// FFI_TYPE_STRUCT
 	data8	@pcrel(.Lld_int)		// FFI_TYPE_POINTER
-	data8	@pcrel(.Lld_void)		// FFI_TYPE_COMPLEX (not implemented)
 	data8 	@pcrel(.Lld_small_struct)	// FFI_IA64_TYPE_SMALL_STRUCT
 	data8	@pcrel(.Lld_hfa_float)		// FFI_IA64_TYPE_HFA_FLOAT
 	data8	@pcrel(.Lld_hfa_double)		// FFI_IA64_TYPE_HFA_DOUBLE
diff --git a/src/java_raw_api.c b/src/java_raw_api.c
index 114d3e4..127123d 100644
--- a/src/java_raw_api.c
+++ b/src/java_raw_api.c
@@ -114,7 +114,7 @@
 	default:
 	  *args = raw;
 	  raw +=
-	    FFI_ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
+	    ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
 	}
     }
 
@@ -142,7 +142,7 @@
 #else /* FFI_SIZEOF_JAVA_RAW != 8 */
 	*args = (void*) raw;
 	raw +=
-	  FFI_ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
+	  ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
 #endif /* FFI_SIZEOF_JAVA_RAW == 8 */
     }
 
@@ -234,7 +234,7 @@
 #else
 	  memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
 	  raw +=
-	    FFI_ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
+	    ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
 #endif
 	}
     }
diff --git a/src/m32r/ffi.c b/src/m32r/ffi.c
index ab8fc4e..3000063 100644
--- a/src/m32r/ffi.c
+++ b/src/m32r/ffi.c
@@ -61,7 +61,7 @@
 
       /* Align if necessary.  */
       if (((*p_arg)->alignment - 1) & (unsigned) argp)
-	argp = (char *) FFI_ALIGN (argp, (*p_arg)->alignment);
+	argp = (char *) ALIGN (argp, (*p_arg)->alignment);
 
       if (avn != 0) 
 	{
diff --git a/src/m68k/ffi.c b/src/m68k/ffi.c
index 0330184..0dee938 100644
--- a/src/m68k/ffi.c
+++ b/src/m68k/ffi.c
@@ -105,7 +105,7 @@
 
 	  /* Align if necessary.  */
 	  if ((sizeof(int) - 1) & z)
-	    z = FFI_ALIGN(z, sizeof(int));
+	    z = ALIGN(z, sizeof(int));
 	}
 
       p_argv++;
@@ -297,7 +297,7 @@
 
 	  /* Align if necessary */
 	  if ((sizeof(int) - 1) & z)
-	    z = FFI_ALIGN(z, sizeof(int));
+	    z = ALIGN(z, sizeof(int));
 	}
 
       p_argv++;
diff --git a/src/m68k/sysv.S b/src/m68k/sysv.S
index ea40f11..ec2b14f 100644
--- a/src/m68k/sysv.S
+++ b/src/m68k/sysv.S
@@ -3,7 +3,7 @@
    sysv.S - Copyright (c) 2012 Alan Hourihane
 	    Copyright (c) 1998, 2012 Andreas Schwab
 	    Copyright (c) 2008 Red Hat, Inc.
-	    Copyright (c) 2012, 2016 Thorsten Glaser
+	    Copyright (c) 2012 Thorsten Glaser
 
    m68k Foreign Function Interface
 
@@ -72,15 +72,6 @@
 	pea	4(%sp)
 #if !defined __PIC__
 	jsr	CALLFUNC(ffi_prep_args)
-#elif defined(__uClinux__) && defined(__ID_SHARED_LIBRARY__)
-	move.l  _current_shared_library_a5_offset_(%a5),%a0
-	move.l  CALLFUNC(ffi_prep_args@GOT)(%a0),%a0
-	jsr     (%a0)
-#elif defined(__mcoldfire__) && !defined(__mcfisab__) && !defined(__mcfisac__)
-	move.l  #_GLOBAL_OFFSET_TABLE_@GOTPC,%a0
-	lea     (-6,%pc,%a0),%a0
-	move.l  CALLFUNC(ffi_prep_args@GOT)(%a0),%a0
-	jsr     (%a0)
 #else
 	bsr.l	CALLFUNC(ffi_prep_args@PLTPC)
 #endif
@@ -224,15 +215,6 @@
 	move.l	%a0,-(%sp)
 #if !defined __PIC__
 	jsr	CALLFUNC(ffi_closure_SYSV_inner)
-#elif defined(__uClinux__) && defined(__ID_SHARED_LIBRARY__)
-	move.l  _current_shared_library_a5_offset_(%a5),%a0
-	move.l  CALLFUNC(ffi_closure_SYSV_inner@GOT)(%a0),%a0
-	jsr     (%a0)
-#elif defined(__mcoldfire__) && !defined(__mcfisab__) && !defined(__mcfisac__)
-	move.l  #_GLOBAL_OFFSET_TABLE_@GOTPC,%a0
-	lea     (-6,%pc,%a0),%a0
-	move.l  CALLFUNC(ffi_closure_SYSV_inner@GOT)(%a0),%a0
-	jsr     (%a0)
 #else
 	bsr.l	CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
 #endif
@@ -335,15 +317,6 @@
 	move.l	%a0,-(%sp)
 #if !defined __PIC__
 	jsr	CALLFUNC(ffi_closure_SYSV_inner)
-#elif defined(__uClinux__) && defined(__ID_SHARED_LIBRARY__)
-	move.l  _current_shared_library_a5_offset_(%a5),%a0
-	move.l  CALLFUNC(ffi_closure_SYSV_inner@GOT)(%a0),%a0
-	jsr     (%a0)
-#elif defined(__mcoldfire__) && !defined(__mcfisab__) && !defined(__mcfisac__)
-	move.l  #_GLOBAL_OFFSET_TABLE_@GOTPC,%a0
-	lea     (-6,%pc,%a0),%a0
-	move.l  CALLFUNC(ffi_closure_SYSV_inner@GOT)(%a0),%a0
-	jsr     (%a0)
 #else
 	bsr.l	CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
 #endif
diff --git a/src/m88k/ffi.c b/src/m88k/ffi.c
index 57b344f..68df494 100644
--- a/src/m88k/ffi.c
+++ b/src/m88k/ffi.c
@@ -134,7 +134,7 @@
       /* Enforce proper stack alignment of 64-bit types */
       if (argp == stackp && a > sizeof (int))
 	{
-	  stackp = (char *) FFI_ALIGN(stackp, a);
+	  stackp = (char *) ALIGN(stackp, a);
 	  argp = stackp;
 	}
 
@@ -177,7 +177,7 @@
 
       /* Align if necessary.  */
       if ((sizeof (int) - 1) & z)
-	z = FFI_ALIGN(z, sizeof (int));
+	z = ALIGN(z, sizeof (int));
 
       p_argv++;
 
@@ -320,7 +320,7 @@
       /* Enforce proper stack alignment of 64-bit types */
       if (argp == stackp && a > sizeof (int))
 	{
-	  stackp = (char *) FFI_ALIGN(stackp, a);
+	  stackp = (char *) ALIGN(stackp, a);
 	  argp = stackp;
 	}
 
@@ -331,7 +331,7 @@
 
       /* Align if necessary */
       if ((sizeof (int) - 1) & z)
-	z = FFI_ALIGN(z, sizeof (int));
+	z = ALIGN(z, sizeof (int));
 
       p_argv++;
 
diff --git a/src/metag/ffi.c b/src/metag/ffi.c
index 3aecb0b..46b383e 100644
--- a/src/metag/ffi.c
+++ b/src/metag/ffi.c
@@ -61,7 +61,7 @@
 		argp -= z;
 
 		/* Align if necessary */
-		argp = (char *) FFI_ALIGN_DOWN(FFI_ALIGN_DOWN(argp, (*p_arg)->alignment), 4);
+		argp = (char *) ALIGN_DOWN(ALIGN_DOWN(argp, (*p_arg)->alignment), 4);
 
 		if (z < sizeof(int)) {
 			z = sizeof(int);
@@ -93,7 +93,7 @@
 
 	/* return the size of the arguments to be passed in registers,
 	   padded to an 8 byte boundary to preserve stack alignment */
-	return FFI_ALIGN(MIN(stack - argp, 6*4), 8);
+	return ALIGN(MIN(stack - argp, 6*4), 8);
 }
 
 /* Perform machine dependent cif processing */
@@ -112,20 +112,20 @@
 
 		/* Add any padding if necessary */
 		if (((*ptr)->alignment - 1) & bytes)
-			bytes = FFI_ALIGN(bytes, (*ptr)->alignment);
+			bytes = ALIGN(bytes, (*ptr)->alignment);
 
-		bytes += FFI_ALIGN((*ptr)->size, 4);
+		bytes += ALIGN((*ptr)->size, 4);
 	}
 
 	/* Ensure arg space is aligned to an 8-byte boundary */
-	bytes = FFI_ALIGN(bytes, 8);
+	bytes = ALIGN(bytes, 8);
 
 	/* Make space for the return structure pointer */
 	if (cif->rtype->type == FFI_TYPE_STRUCT) {
 		bytes += sizeof(void*);
 
 		/* Ensure stack is aligned to an 8-byte boundary */
-		bytes = FFI_ALIGN(bytes, 8);
+		bytes = ALIGN(bytes, 8);
 	}
 
 	cif->bytes = bytes;
@@ -319,7 +319,7 @@
 		if (alignment < 4)
 			alignment = 4;
 		if ((alignment - 1) & (unsigned)argp)
-			argp = (char *) FFI_ALIGN(argp, alignment);
+			argp = (char *) ALIGN(argp, alignment);
 
 		z = (*p_arg)->size;
 		*p_argv = (void*) argp;
diff --git a/src/microblaze/ffi.c b/src/microblaze/ffi.c
index df6e33c..ea962ea 100644
--- a/src/microblaze/ffi.c
+++ b/src/microblaze/ffi.c
@@ -35,7 +35,7 @@
 
 #define WORD_SIZE			sizeof(unsigned int)
 #define ARGS_REGISTER_SIZE	(WORD_SIZE * 6)
-#define WORD_FFI_ALIGN(x)		FFI_ALIGN(x, WORD_SIZE)
+#define WORD_ALIGN(x)		ALIGN(x, WORD_SIZE)
 
 /* ffi_prep_args is called by the assembly routine once stack space
    has been allocated for the function's arguments */
@@ -46,12 +46,12 @@
 	void** p_argv;
 	void* stack_args_p = stack;
 
+	p_argv = ecif->avalue;
+
 	if (ecif == NULL || ecif->cif == NULL) {
 		return; /* no description to prepare */
 	}
 
-	p_argv = ecif->avalue;
-
 	if ((ecif->cif->rtype != NULL) &&
 			(ecif->cif->rtype->type == FFI_TYPE_STRUCT))
 	{
@@ -74,7 +74,7 @@
 		int type = (*p_arg)->type;
 		void* value = p_argv[i];
 		char* addr = stack_args_p;
-		int aligned_size = WORD_FFI_ALIGN(size);
+		int aligned_size = WORD_ALIGN(size);
 
 		/* force word alignment on the stack */
 		stack_args_p += aligned_size;
@@ -259,7 +259,7 @@
 				avalue[i] = ptr;
 				break;
 		}
-		ptr += WORD_FFI_ALIGN(arg_types[i]->size);
+		ptr += WORD_ALIGN(arg_types[i]->size);
 	}
 
 	/* set the return type info passed back to the wrapper */
diff --git a/src/mips/ffi.c b/src/mips/ffi.c
index 057b046..5d0dd70 100644
--- a/src/mips/ffi.c
+++ b/src/mips/ffi.c
@@ -29,7 +29,6 @@
 #include <ffi.h>
 #include <ffi_common.h>
 
-#include <stdint.h>
 #include <stdlib.h>
 
 #ifdef __GNUC__
@@ -117,7 +116,7 @@
       
       if ((a - 1) & (unsigned long) argp)
 	{
-	  argp = (char *) FFI_ALIGN(argp, a);
+	  argp = (char *) ALIGN(argp, a);
 	  FIX_ARGP;
 	}
 
@@ -248,7 +247,7 @@
   while ((e = arg->elements[index]))
     {
       /* Align this object.  */
-      *loc = FFI_ALIGN(*loc, e->alignment);
+      *loc = ALIGN(*loc, e->alignment);
       if (e->type == FFI_TYPE_DOUBLE)
 	{
           /* Already aligned to FFI_SIZEOF_ARG.  */
@@ -263,7 +262,7 @@
       index++;
     }
   /* Next Argument register at alignment of FFI_SIZEOF_ARG.  */
-  *arg_reg = FFI_ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+  *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
 
   return flags;
 }
@@ -323,10 +322,9 @@
 #endif
 
 /* Perform machine dependent cif processing */
-static ffi_status ffi_prep_cif_machdep_int(ffi_cif *cif, unsigned nfixedargs)
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 {
   cif->flags = 0;
-  cif->mips_nfixedargs = nfixedargs;
 
 #ifdef FFI_MIPS_O32
   /* Set the flags necessary for O32 processing.  FFI_O32_SOFT_FLOAT
@@ -335,7 +333,7 @@
 
   if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
     {
-      if (cif->nargs > 0 && cif->nargs == nfixedargs)
+      if (cif->nargs > 0)
 	{
 	  switch ((cif->arg_types)[0]->type)
 	    {
@@ -452,9 +450,7 @@
     while (count-- > 0 && arg_reg < 8)
       {
 	type = (cif->arg_types)[index]->type;
-
-	// Pass variadic arguments in integer registers even if they're floats
-	if (soft_float || index >= nfixedargs)
+	if (soft_float)
 	  {
 	    switch (type)
 	      {
@@ -478,9 +474,9 @@
 	    break;
           case FFI_TYPE_LONGDOUBLE:
             /* Align it.  */
-            arg_reg = FFI_ALIGN(arg_reg, 2);
+            arg_reg = ALIGN(arg_reg, 2);
             /* Treat it as two adjacent doubles.  */
-	    if (soft_float || index >= nfixedargs)
+	    if (soft_float) 
 	      {
 		arg_reg += 2;
 	      }
@@ -497,7 +493,7 @@
 
 	  case FFI_TYPE_STRUCT:
             loc = arg_reg * FFI_SIZEOF_ARG;
-	    cif->flags += calc_n32_struct_flags(soft_float || index >= nfixedargs,
+	    cif->flags += calc_n32_struct_flags(soft_float,
 						(cif->arg_types)[index],
 						&loc, &arg_reg);
 	    break;
@@ -582,30 +578,17 @@
   return FFI_OK;
 }
 
-ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
-{
-    return ffi_prep_cif_machdep_int(cif, cif->nargs);
-}
-
-ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
-                                    unsigned nfixedargs,
-                                    unsigned ntotalargs MAYBE_UNUSED)
-{
-    return ffi_prep_cif_machdep_int(cif, nfixedargs);
-}
-
 /* Low level routine for calling O32 functions */
 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), 
 			extended_cif *, unsigned, 
-			unsigned, unsigned *, void (*)(void), void *closure);
+			unsigned, unsigned *, void (*)(void));
 
 /* Low level routine for calling N32 functions */
 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), 
 			extended_cif *, unsigned, 
-			unsigned, void *, void (*)(void), void *closure);
+			unsigned, void *, void (*)(void));
 
-void ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue, 
-	      void **avalue, void *closure)
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
   extended_cif ecif;
 
@@ -627,7 +610,7 @@
     case FFI_O32:
     case FFI_O32_SOFT_FLOAT:
       ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, 
-		   cif->flags, ecif.rvalue, fn, closure);
+		   cif->flags, ecif.rvalue, fn);
       break;
 #endif
 
@@ -659,7 +642,7 @@
 #endif
 	  }
         ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
-                     cif->flags, rvalue_copy, fn, closure);
+                     cif->flags, rvalue_copy, fn);
         if (copy_rvalue)
           memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
       }
@@ -672,27 +655,11 @@
     }
 }
 
-void
-ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, NULL);
-}
-
-void
-ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	     void **avalue, void *closure)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, closure);
-}
-
-
 #if FFI_CLOSURES
 #if defined(FFI_MIPS_O32)
 extern void ffi_closure_O32(void);
-extern void ffi_go_closure_O32(void);
 #else
 extern void ffi_closure_N32(void);
-extern void ffi_go_closure_N32(void);
 #endif /* FFI_MIPS_O32 */
 
 ffi_status
@@ -731,11 +698,7 @@
   /* lui  $12,high(codeloc) */
   tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
   /* jr   $25          */
-#if !defined(__mips_isa_rev) || (__mips_isa_rev<6)
   tramp[3] = 0x03200008;
-#else
-  tramp[3] = 0x03200009;
-#endif
   /* ori  $12,low(codeloc)  */
   tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
 #else
@@ -763,11 +726,7 @@
   /* ori  $25,low(fn)  */
   tramp[10] = 0x37390000 | ((unsigned long)fn  & 0xffff);
   /* jr   $25          */
-#if !defined(__mips_isa_rev) || (__mips_isa_rev<6)
   tramp[11] = 0x03200008;
-#else
-  tramp[11] = 0x03200009;
-#endif
   /* ori  $12,low(codeloc)  */
   tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
 
@@ -803,28 +762,27 @@
  * Based on the similar routine for sparc.
  */
 int
-ffi_closure_mips_inner_O32 (ffi_cif *cif,
-                            void (*fun)(ffi_cif*, void*, void**, void*),
-			    void *user_data,
+ffi_closure_mips_inner_O32 (ffi_closure *closure,
 			    void *rvalue, ffi_arg *ar,
 			    double *fpr)
 {
+  ffi_cif *cif;
   void **avaluep;
   ffi_arg *avalue;
   ffi_type **arg_types;
   int i, avn, argn, seen_int;
 
+  cif = closure->cif;
   avalue = alloca (cif->nargs * sizeof (ffi_arg));
   avaluep = alloca (cif->nargs * sizeof (ffi_arg));
 
-  seen_int = (cif->abi == FFI_O32_SOFT_FLOAT) || (cif->mips_nfixedargs != cif->nargs);
+  seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
   argn = 0;
 
   if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
     {
-      rvalue = (void *)(uintptr_t)ar[0];
+      rvalue = (void *)(UINT32)ar[0];
       argn = 1;
-      seen_int = 1;
     }
 
   i = 0;
@@ -833,8 +791,6 @@
 
   while (i < avn)
     {
-      if (arg_types[i]->alignment == 8 && (argn & 0x1))
-        argn++;
       if (i < 2 && !seen_int &&
 	  (arg_types[i]->type == FFI_TYPE_FLOAT ||
 	   arg_types[i]->type == FFI_TYPE_DOUBLE ||
@@ -849,6 +805,8 @@
 	}
       else
 	{
+	  if (arg_types[i]->alignment == 8 && (argn & 0x1))
+	    argn++;
 	  switch (arg_types[i]->type)
 	    {
 	      case FFI_TYPE_SINT8:
@@ -877,12 +835,12 @@
 	    }
 	  seen_int = 1;
 	}
-      argn += FFI_ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+      argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
       i++;
     }
 
   /* Invoke the closure. */
-  fun(cif, rvalue, avaluep, user_data);
+  (closure->fun) (cif, rvalue, avaluep, closure->user_data);
 
   if (cif->abi == FFI_O32_SOFT_FLOAT)
     {
@@ -918,7 +876,7 @@
       char *argp;
       char *fpp;
 
-      o = FFI_ALIGN(offset, elt_type->alignment);
+      o = ALIGN(offset, elt_type->alignment);
       arg_offset += o - offset;
       offset = o;
       argn += arg_offset / sizeof(ffi_arg);
@@ -958,12 +916,11 @@
  *
  */
 int
-ffi_closure_mips_inner_N32 (ffi_cif *cif, 
-			    void (*fun)(ffi_cif*, void*, void**, void*),
-                            void *user_data,
+ffi_closure_mips_inner_N32 (ffi_closure *closure,
 			    void *rvalue, ffi_arg *ar,
 			    ffi_arg *fpr)
 {
+  ffi_cif *cif;
   void **avaluep;
   ffi_arg *avalue;
   ffi_type **arg_types;
@@ -971,6 +928,7 @@
   int soft_float;
   ffi_arg *argp;
 
+  cif = closure->cif;
   soft_float = cif->abi == FFI_N64_SOFT_FLOAT
     || cif->abi == FFI_N32_SOFT_FLOAT;
   avalue = alloca (cif->nargs * sizeof (ffi_arg));
@@ -998,10 +956,10 @@
 	  || arg_types[i]->type == FFI_TYPE_DOUBLE
 	  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE)
         {
-          argp = (argn >= 8 || i >= cif->mips_nfixedargs || soft_float) ? ar + argn : fpr + argn;
-          if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((uintptr_t)argp & (arg_types[i]->alignment-1)))
+          argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
+          if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1)))
             {
-              argp=(ffi_arg*)FFI_ALIGN(argp,arg_types[i]->alignment);
+              argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment);
               argn++;
             }
 #if defined(__MIPSEB__) || defined(_MIPSEB)
@@ -1016,7 +974,7 @@
           unsigned type = arg_types[i]->type;
 
           if (arg_types[i]->alignment > sizeof(ffi_arg))
-            argn = FFI_ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
+            argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
 
           argp = ar + argn;
 
@@ -1067,7 +1025,7 @@
                      it was passed in registers.  */
                   avaluep[i] = alloca(arg_types[i]->size);
                   copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
-                                  argn, 0, ar, fpr, i >= cif->mips_nfixedargs || soft_float);
+                                  argn, 0, ar, fpr, soft_float);
 
                   break;
                 }
@@ -1077,54 +1035,16 @@
               break;
             }
         }
-      argn += FFI_ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
+      argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
       i++;
     }
 
   /* Invoke the closure. */
-  fun (cif, rvalue, avaluep, user_data);
+  (closure->fun) (cif, rvalue, avaluep, closure->user_data);
 
   return cif->flags >> (FFI_FLAG_BITS * 8);
 }
 
 #endif /* FFI_MIPS_N32 */
 
-#if defined(FFI_MIPS_O32)
-extern void ffi_closure_O32(void);
-extern void ffi_go_closure_O32(void);
-#else
-extern void ffi_closure_N32(void);
-extern void ffi_go_closure_N32(void);
-#endif /* FFI_MIPS_O32 */
-
-ffi_status
-ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
-		     void (*fun)(ffi_cif*,void*,void**,void*))
-{
-  void * fn;
-
-#if defined(FFI_MIPS_O32)
-  if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT)
-    return FFI_BAD_ABI;
-  fn = ffi_go_closure_O32;
-#else
-#if _MIPS_SIM ==_ABIN32
-  if (cif->abi != FFI_N32
-      && cif->abi != FFI_N32_SOFT_FLOAT)
-    return FFI_BAD_ABI;
-#else
-  if (cif->abi != FFI_N64
-      && cif->abi != FFI_N64_SOFT_FLOAT)
-    return FFI_BAD_ABI;
-#endif
-  fn = ffi_go_closure_N32;
-#endif /* FFI_MIPS_O32 */
-
-  closure->tramp = (void *)fn;
-  closure->cif = cif;
-  closure->fun = fun;
-
-  return FFI_OK;
-}
-
 #endif /* FFI_CLOSURES */
diff --git a/src/mips/ffitarget.h b/src/mips/ffitarget.h
index fffdb97..717d659 100644
--- a/src/mips/ffitarget.h
+++ b/src/mips/ffitarget.h
@@ -32,7 +32,7 @@
 #error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
 #endif
 
-#ifdef __linux__
+#ifdef linux
 # include <asm/sgidefs.h>
 #elif defined(__rtems__)
 /*
@@ -224,21 +224,24 @@
 #endif
 } ffi_abi;
 
-#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag; unsigned mips_nfixedargs
-#define FFI_TARGET_SPECIFIC_VARIADIC
+#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag
 #endif /* !LIBFFI_ASM */
 
 /* ---- Definitions for closures ----------------------------------------- */
 
+#if defined(FFI_MIPS_O32)
 #define FFI_CLOSURES 1
-#define FFI_GO_CLOSURES 1
-#define FFI_NATIVE_RAW_API 0
-
-#if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
-# define FFI_TRAMPOLINE_SIZE 20
+#define FFI_TRAMPOLINE_SIZE 20
 #else
-# define FFI_TRAMPOLINE_SIZE 56
+/* N32/N64. */
+# define FFI_CLOSURES 1
+#if _MIPS_SIM==_ABI64
+#define FFI_TRAMPOLINE_SIZE 52
+#else
+#define FFI_TRAMPOLINE_SIZE 20
 #endif
+#endif /* FFI_MIPS_O32 */
+#define FFI_NATIVE_RAW_API 0
 
 #endif
 
diff --git a/src/mips/n32.S b/src/mips/n32.S
index 1a940b6..c6985d3 100644
--- a/src/mips/n32.S
+++ b/src/mips/n32.S
@@ -37,43 +37,36 @@
 #define flags	 a3
 #define raddr    a4
 #define fn       a5
-#define closure  a6
 
-/* Note: to keep stack 16 byte aligned we need even number slots 
-   used 9 slots here
-*/
-#define SIZEOF_FRAME	( 10 * FFI_SIZEOF_ARG )
+#define SIZEOF_FRAME	( 8 * FFI_SIZEOF_ARG )
 
 #ifdef __GNUC__
 	.abicalls
 #endif
-#if !defined(__mips_isa_rev) || (__mips_isa_rev<6)
 	.set mips4
-#endif
 	.text
 	.align	2
 	.globl	ffi_call_N32
 	.ent	ffi_call_N32
 ffi_call_N32:	
-.LFB0:
+.LFB3:
 	.frame	$fp, SIZEOF_FRAME, ra
 	.mask	0xc0000000,-FFI_SIZEOF_ARG
 	.fmask	0x00000000,0
 
 	# Prologue
 	SUBU	$sp, SIZEOF_FRAME			# Frame size
-.LCFI00:
+.LCFI0:
 	REG_S	$fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp)	# Save frame pointer
 	REG_S	ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp)	# Save return address
-.LCFI01:
+.LCFI1:
 	move	$fp, $sp
-.LCFI02:
+.LCFI3:
 	move	t9, callback	# callback function pointer
 	REG_S	bytes, 2*FFI_SIZEOF_ARG($fp) # bytes
 	REG_S	flags, 3*FFI_SIZEOF_ARG($fp) # flags
 	REG_S	raddr, 4*FFI_SIZEOF_ARG($fp) # raddr
 	REG_S	fn,    5*FFI_SIZEOF_ARG($fp) # fn
-	REG_S	closure, 6*FFI_SIZEOF_ARG($fp) # closure
 
 	# Allocate at least 4 words in the argstack
 	move	v0, bytes
@@ -114,16 +107,6 @@
 
 	REG_L	t6, 3*FFI_SIZEOF_ARG($fp)  # load the flags word into t6.
 
-#ifdef __mips_soft_float
-	REG_L	a0, 0*FFI_SIZEOF_ARG(t9)
-	REG_L	a1, 1*FFI_SIZEOF_ARG(t9)
-	REG_L	a2, 2*FFI_SIZEOF_ARG(t9)
-	REG_L	a3, 3*FFI_SIZEOF_ARG(t9)
-	REG_L	a4, 4*FFI_SIZEOF_ARG(t9)
-	REG_L	a5, 5*FFI_SIZEOF_ARG(t9)
-	REG_L	a6, 6*FFI_SIZEOF_ARG(t9)
-	REG_L	a7, 7*FFI_SIZEOF_ARG(t9)
-#else
 	and	t4, t6, ((1<<FFI_FLAG_BITS)-1)
 	REG_L	a0, 0*FFI_SIZEOF_ARG(t9)
 	beqz	t4, arg1_next
@@ -210,15 +193,11 @@
 arg8_doublep:	
  	l.d	$f19, 7*FFI_SIZEOF_ARG(t9)	
 arg8_next:	
-#endif
 
 callit:		
 	# Load the function pointer
 	REG_L	t9, 5*FFI_SIZEOF_ARG($fp)
 
-	# install the static chain(t7=$15)
-	REG_L	t7, 6*FFI_SIZEOF_ARG($fp)
-
 	# If the return value pointer is NULL, assume no return value.
 	REG_L	t5, 4*FFI_SIZEOF_ARG($fp)
 	beqz	t5, noretval
@@ -235,7 +214,6 @@
 	b	epilogue
 
 retfloat:
-#ifndef __mips_soft_float
 	bne     t6, FFI_TYPE_FLOAT, retdouble
 	jal	t9
 	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
@@ -294,7 +272,6 @@
 	s.s	$f0, 0(t4)
 	s.d	$f2, 8(t4)
 	b	epilogue
-#endif
 
 retstruct_d_soft:
 	bne	t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft
@@ -369,7 +346,7 @@
 	ADDU	$sp, SIZEOF_FRAME		      # Fix stack pointer
 	j	ra
 
-.LFE0:
+.LFE3:
 	.end	ffi_call_N32
 
 /* ffi_closure_N32. Expects address of the passed-in ffi_closure in t0
@@ -429,41 +406,6 @@
 #define GP_OFF2		(0  * FFI_SIZEOF_ARG)
 
 	.align	2
-	.globl	ffi_go_closure_N32
-	.ent	ffi_go_closure_N32
-ffi_go_closure_N32:
-.LFB1:
-	.frame	$sp, SIZEOF_FRAME2, ra
-	.mask	0x90000000,-(SIZEOF_FRAME2 - RA_OFF2)
-	.fmask	0x00000000,0
-	SUBU	$sp, SIZEOF_FRAME2
-.LCFI10:
-	.cpsetup t9, GP_OFF2, ffi_go_closure_N32
-	REG_S	ra, RA_OFF2($sp)	# Save return address
-.LCFI11:
-
-	REG_S	a0, A0_OFF2($sp)
-	REG_S	a1, A1_OFF2($sp)
-	REG_S	a2, A2_OFF2($sp)
-	REG_S	a3, A3_OFF2($sp)
-	REG_S	a4, A4_OFF2($sp)
-	REG_S	a5, A5_OFF2($sp)
-
-	# Call ffi_closure_mips_inner_N32 to do the real work.
-	LA	t9, ffi_closure_mips_inner_N32
-	REG_L	a0, 8($15)   # cif
-	REG_L	a1, 16($15) # fun
-	move	a2, t7                     # userdata=closure
-	ADDU	a3, $sp, V0_OFF2           # rvalue
-	ADDU	a4, $sp, A0_OFF2           # ar
-	ADDU	a5, $sp, F12_OFF2          # fpr
-
-	b	$do_closure
-
-.LFE1:	
-	.end	ffi_go_closure_N32
-
-	.align	2
 	.globl	ffi_closure_N32
 	.ent	ffi_closure_N32
 ffi_closure_N32:
@@ -472,33 +414,21 @@
 	.mask	0x90000000,-(SIZEOF_FRAME2 - RA_OFF2)
 	.fmask	0x00000000,0
 	SUBU	$sp, SIZEOF_FRAME2
-.LCFI20:
+.LCFI5:
 	.cpsetup t9, GP_OFF2, ffi_closure_N32
 	REG_S	ra, RA_OFF2($sp)	# Save return address
-.LCFI21:
+.LCFI6:
+	# Store all possible argument registers. If there are more than
+	# fit in registers, then they were stored on the stack.
 	REG_S	a0, A0_OFF2($sp)
 	REG_S	a1, A1_OFF2($sp)
 	REG_S	a2, A2_OFF2($sp)
 	REG_S	a3, A3_OFF2($sp)
 	REG_S	a4, A4_OFF2($sp)
 	REG_S	a5, A5_OFF2($sp)
-
-	# Call ffi_closure_mips_inner_N32 to do the real work.
-	LA	t9, ffi_closure_mips_inner_N32
-	REG_L	a0, 56($12)   # cif
-	REG_L	a1, 64($12)   # fun
-	REG_L	a2, 72($12) # user_data
-	ADDU	a3, $sp, V0_OFF2
-	ADDU	a4, $sp, A0_OFF2
-	ADDU	a5, $sp, F12_OFF2
-
-$do_closure:
-	# Store all possible argument registers. If there are more than
-	# fit in registers, then they were stored on the stack.
 	REG_S	a6, A6_OFF2($sp)
 	REG_S	a7, A7_OFF2($sp)
 
-#ifndef __mips_soft_float
 	# Store all possible float/double registers.
 	s.d	$f12, F12_OFF2($sp)
 	s.d	$f13, F13_OFF2($sp)
@@ -508,8 +438,13 @@
 	s.d	$f17, F17_OFF2($sp)
 	s.d	$f18, F18_OFF2($sp)
 	s.d	$f19, F19_OFF2($sp)
-#endif
 
+	# Call ffi_closure_mips_inner_N32 to do the real work.
+	LA	t9, ffi_closure_mips_inner_N32
+	move	a0, $12	 # Pointer to the ffi_closure
+	ADDU	a1, $sp, V0_OFF2
+	ADDU	a2, $sp, A0_OFF2
+	ADDU	a3, $sp, F12_OFF2
 	jalr	t9
 
 	# Return flags are in v0
@@ -523,7 +458,6 @@
 	b	cls_epilogue
 
 cls_retfloat:
-#ifndef __mips_soft_float
 	bne     v0, FFI_TYPE_FLOAT, cls_retdouble
 	l.s	$f0, V0_OFF2($sp)
 	b	cls_epilogue
@@ -566,7 +500,6 @@
 	l.s	$f0, V0_OFF2($sp)
 	l.d	$f2, V1_OFF2($sp)
 	b	cls_epilogue
-#endif
 	
 cls_retstruct_small2:	
 	REG_L	v0, V0_OFF2($sp)
@@ -598,66 +531,46 @@
         .align  EH_FRAME_ALIGN
 .LECIE1:
 
-.LSFDE0:
-        .4byte  .LEFDE0-.LASFDE0	# length.
-.LASFDE0:
-        .4byte  .LASFDE0-.Lframe1	# CIE_pointer.
-        FDE_ADDR_BYTES  .LFB0		# initial_location.
-        FDE_ADDR_BYTES  .LFE0-.LFB0	# address_range.
+.LSFDE1:
+        .4byte  .LEFDE1-.LASFDE1	# length.
+.LASFDE1:
+        .4byte  .LASFDE1-.Lframe1	# CIE_pointer.
+        FDE_ADDR_BYTES  .LFB3		# initial_location.
+        FDE_ADDR_BYTES  .LFE3-.LFB3	# address_range.
         .byte   0x4			# DW_CFA_advance_loc4
-        .4byte  .LCFI00-.LFB0		# to .LCFI00
+        .4byte  .LCFI0-.LFB3		# to .LCFI0
         .byte   0xe			# DW_CFA_def_cfa_offset
         .uleb128 SIZEOF_FRAME		# adjust stack.by SIZEOF_FRAME
         .byte   0x4			# DW_CFA_advance_loc4
-        .4byte  .LCFI01-.LCFI00		# to .LCFI01
+        .4byte  .LCFI1-.LCFI0		# to .LCFI1
         .byte   0x9e			# DW_CFA_offset of $fp
         .uleb128 2*FFI_SIZEOF_ARG/4	# 
         .byte   0x9f			# DW_CFA_offset of ra
         .uleb128 1*FFI_SIZEOF_ARG/4	# 
         .byte   0x4			# DW_CFA_advance_loc4
-        .4byte  .LCFI02-.LCFI01		# to .LCFI02
+        .4byte  .LCFI3-.LCFI1		# to .LCFI3
         .byte   0xd			# DW_CFA_def_cfa_register
         .uleb128 0x1e			# in $fp
         .align  EH_FRAME_ALIGN
-.LEFDE0:
-
-.LSFDE1:
-	.4byte	.LEFDE1-.LASFDE1	# length
-.LASFDE1:
-	.4byte	.LASFDE1-.Lframe1	# CIE_pointer.
-	FDE_ADDR_BYTES	.LFB1		# initial_location.
-	FDE_ADDR_BYTES	.LFE1-.LFB1	# address_range.
-	.byte	0x4			# DW_CFA_advance_loc4
-	.4byte	.LCFI10-.LFB1		# to .LCFI10
-	.byte	0xe			# DW_CFA_def_cfa_offset
-	.uleb128 SIZEOF_FRAME2		# adjust stack.by SIZEOF_FRAME
-	.byte	0x4			# DW_CFA_advance_loc4
-	.4byte	.LCFI11-.LCFI10		# to .LCFI11
-	.byte	0x9c			# DW_CFA_offset of $gp ($28)
-	.uleb128 (SIZEOF_FRAME2 - GP_OFF2)/4
-	.byte	0x9f			# DW_CFA_offset of ra ($31)
-	.uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4
-	.align	EH_FRAME_ALIGN
 .LEFDE1:
-
-.LSFDE2:
-	.4byte	.LEFDE2-.LASFDE2	# length
-.LASFDE2:
-	.4byte	.LASFDE2-.Lframe1	# CIE_pointer.
+.LSFDE3:
+	.4byte	.LEFDE3-.LASFDE3	# length
+.LASFDE3:
+	.4byte	.LASFDE3-.Lframe1	# CIE_pointer.
 	FDE_ADDR_BYTES	.LFB2		# initial_location.
 	FDE_ADDR_BYTES	.LFE2-.LFB2	# address_range.
 	.byte	0x4			# DW_CFA_advance_loc4
-	.4byte	.LCFI20-.LFB2		# to .LCFI20
+	.4byte	.LCFI5-.LFB2		# to .LCFI5
 	.byte	0xe			# DW_CFA_def_cfa_offset
 	.uleb128 SIZEOF_FRAME2		# adjust stack.by SIZEOF_FRAME
 	.byte	0x4			# DW_CFA_advance_loc4
-	.4byte	.LCFI21-.LCFI20		# to .LCFI21
+	.4byte	.LCFI6-.LCFI5		# to .LCFI6
 	.byte	0x9c			# DW_CFA_offset of $gp ($28)
 	.uleb128 (SIZEOF_FRAME2 - GP_OFF2)/4
 	.byte	0x9f			# DW_CFA_offset of ra ($31)
 	.uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4
 	.align	EH_FRAME_ALIGN
-.LEFDE2:
+.LEFDE3:
 #endif /* __GNUC__ */	
 	
 #endif
diff --git a/src/mips/o32.S b/src/mips/o32.S
index 44e74cb..eb27981 100644
--- a/src/mips/o32.S
+++ b/src/mips/o32.S
@@ -50,14 +50,14 @@
 $LFB0:
 	# Prologue
 	SUBU	$sp, SIZEOF_FRAME	# Frame size
-$LCFI00:
+$LCFI0:
 	REG_S	$fp, FP_OFF($sp)	# Save frame pointer
-$LCFI01:
+$LCFI1:
 	REG_S	ra, RA_OFF($sp)		# Save return address
-$LCFI02:
+$LCFI2:
 	move	$fp, $sp
 
-$LCFI03:
+$LCFI3:
 	move	t9, callback		# callback function pointer
 	REG_S	flags, A3_OFF($fp)	# flags
 
@@ -82,16 +82,13 @@
 		
 	ADDU	$sp, 4 * FFI_SIZEOF_ARG		# adjust $sp to new args
 
-#ifndef __mips_soft_float
 	bnez	t0, pass_d			# make it quick for int
-#endif
 	REG_L	a0, 0*FFI_SIZEOF_ARG($sp)	# just go ahead and load the
 	REG_L	a1, 1*FFI_SIZEOF_ARG($sp)	# four regs.
 	REG_L	a2, 2*FFI_SIZEOF_ARG($sp)
 	REG_L	a3, 3*FFI_SIZEOF_ARG($sp)
 	b	call_it
 
-#ifndef __mips_soft_float
 pass_d:
 	bne	t0, FFI_ARGS_D, pass_f
 	l.d	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
@@ -133,12 +130,8 @@
  #	bne	t0, FFI_ARGS_F_D, call_it
 	l.s	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
 	l.d	$f14, 2*FFI_SIZEOF_ARG($sp)	# passing double and float
-#endif
 
 call_it:	
-	# Load the static chain pointer
-	REG_L	t7, SIZEOF_FRAME + 6*FFI_SIZEOF_ARG($fp)
-
 	# Load the function pointer
 	REG_L	t9, SIZEOF_FRAME + 5*FFI_SIZEOF_ARG($fp)
 
@@ -165,23 +158,14 @@
 	bne     t2, FFI_TYPE_FLOAT, retdouble
 	jalr	t9
 	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
-#ifndef __mips_soft_float
 	s.s	$f0, 0(t0)
-#else
-	REG_S	v0, 0(t0)
-#endif
 	b	epilogue
 
 retdouble:	
 	bne	t2, FFI_TYPE_DOUBLE, noretval
 	jalr	t9
 	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
-#ifndef __mips_soft_float
 	s.d	$f0, 0(t0)
-#else
-	REG_S	v1, 4(t0)
-	REG_S	v0, 0(t0)
-#endif
 	b	epilogue
 	
 noretval:	
@@ -220,15 +204,13 @@
 	-8 - f14 (le low, be high)
 	-9 - f12 (le high, be low)
        -10 - f12 (le low, be high)
-       -11 - Called function a5 save
-       -12 - Called function a4 save
-       -13 - Called function a3 save
-       -14 - Called function a2 save
-       -15 - Called function a1 save
-       -16 - Called function a0 save, our sp and fp point here
+       -11 - Called function a3 save
+       -12 - Called function a2 save
+       -13 - Called function a1 save
+       -14 - Called function a0 save, our sp and fp point here
 	 */
 	
-#define SIZEOF_FRAME2	(16 * FFI_SIZEOF_ARG)
+#define SIZEOF_FRAME2	(14 * FFI_SIZEOF_ARG)
 #define A3_OFF2		(SIZEOF_FRAME2 + 3 * FFI_SIZEOF_ARG)
 #define A2_OFF2		(SIZEOF_FRAME2 + 2 * FFI_SIZEOF_ARG)
 #define A1_OFF2		(SIZEOF_FRAME2 + 1 * FFI_SIZEOF_ARG)
@@ -243,15 +225,12 @@
 #define FA_1_0_OFF2	(SIZEOF_FRAME2 - 8 * FFI_SIZEOF_ARG)
 #define FA_0_1_OFF2	(SIZEOF_FRAME2 - 9 * FFI_SIZEOF_ARG)
 #define FA_0_0_OFF2	(SIZEOF_FRAME2 - 10 * FFI_SIZEOF_ARG)
-#define CALLED_A5_OFF2  (SIZEOF_FRAME2 - 11 * FFI_SIZEOF_ARG)
-#define CALLED_A4_OFF2  (SIZEOF_FRAME2 - 12 * FFI_SIZEOF_ARG)
 
 	.text
-
 	.align	2
-	.globl	ffi_go_closure_O32
-	.ent	ffi_go_closure_O32
-ffi_go_closure_O32:
+	.globl	ffi_closure_O32
+	.ent	ffi_closure_O32
+ffi_closure_O32:
 $LFB1:
 	# Prologue
 	.frame	$fp, SIZEOF_FRAME2, ra
@@ -260,69 +239,14 @@
 	.set	reorder
 	SUBU	$sp, SIZEOF_FRAME2
 	.cprestore GP_OFF2
-$LCFI10:
-
+$LCFI4:
 	REG_S	$16, S0_OFF2($sp)	 # Save s0
 	REG_S	$fp, FP_OFF2($sp)	 # Save frame pointer
 	REG_S	ra, RA_OFF2($sp)	 # Save return address
-$LCFI11:
-
-	move	$fp, $sp
-$LCFI12:
-
-	REG_S	a0, A0_OFF2($fp)
-	REG_S	a1, A1_OFF2($fp)
-	REG_S	a2, A2_OFF2($fp)
-	REG_S	a3, A3_OFF2($fp)
-
-	# Load ABI enum to s0
-	REG_L	$16, 4($15)	# cif 
-	REG_L	$16, 0($16)	# abi is first member.
-
-	li	$13, 1		# FFI_O32
-	bne	$16, $13, 1f	# Skip fp save if FFI_O32_SOFT_FLOAT
-	
-	# Store all possible float/double registers.
-	s.d	$f12, FA_0_0_OFF2($fp)
-	s.d	$f14, FA_1_0_OFF2($fp)
-1:
-	# prepare arguments for ffi_closure_mips_inner_O32
-	REG_L	a0, 4($15)	 # cif 
-	REG_L	a1, 8($15)	 # fun
-	move	a2, $15		 # user_data = go closure
-	addu	a3, $fp, V0_OFF2 # rvalue
-
-	addu	t9, $fp, A0_OFF2 # ar
-	REG_S   t9, CALLED_A4_OFF2($fp)
-
-	addu	t9, $fp, FA_0_0_OFF2 #fpr
-	REG_S   t9, CALLED_A5_OFF2($fp)
-
-	b $do_closure
-
-$LFE1:
-	.end ffi_go_closure_O32
-
-	.align	2
-	.globl	ffi_closure_O32
-	.ent	ffi_closure_O32
-ffi_closure_O32:
-$LFB2:
-	# Prologue
-	.frame	$fp, SIZEOF_FRAME2, ra
-	.set	noreorder
-	.cpload	t9
-	.set	reorder
-	SUBU	$sp, SIZEOF_FRAME2
-	.cprestore GP_OFF2
-$LCFI20:
-	REG_S	$16, S0_OFF2($sp)	 # Save s0
-	REG_S	$fp, FP_OFF2($sp)	 # Save frame pointer
-	REG_S	ra, RA_OFF2($sp)	 # Save return address
-$LCFI21:
+$LCFI6:
 	move	$fp, $sp
 
-$LCFI22:
+$LCFI7:
 	# Store all possible argument registers. If there are more than
 	# four arguments, then they are stored above where we put a3.
 	REG_S	a0, A0_OFF2($fp)
@@ -337,27 +261,16 @@
 	li	$13, 1		# FFI_O32
 	bne	$16, $13, 1f	# Skip fp save if FFI_O32_SOFT_FLOAT
 	
-#ifndef __mips_soft_float
 	# Store all possible float/double registers.
 	s.d	$f12, FA_0_0_OFF2($fp)
 	s.d	$f14, FA_1_0_OFF2($fp)
-#endif
 1:	
-	# prepare arguments for ffi_closure_mips_inner_O32
-	REG_L	a0, 20($12)	 # cif pointer follows tramp.
-	REG_L	a1, 24($12)	 # fun
-	REG_L	a2, 28($12)	 # user_data
-	addu	a3, $fp, V0_OFF2 # rvalue
-
-	addu	t9, $fp, A0_OFF2 # ar
-	REG_S   t9, CALLED_A4_OFF2($fp)
-
-	addu	t9, $fp, FA_0_0_OFF2 #fpr
-	REG_S   t9, CALLED_A5_OFF2($fp)
-
-$do_closure:
-	la	t9, ffi_closure_mips_inner_O32
 	# Call ffi_closure_mips_inner_O32 to do the work.
+	la	t9, ffi_closure_mips_inner_O32
+	move	a0, $12	 # Pointer to the ffi_closure
+	addu	a1, $fp, V0_OFF2
+	addu	a2, $fp, A0_OFF2
+	addu	a3, $fp, FA_0_0_OFF2
 	jalr	t9
 
 	# Load the return value into the appropriate register.
@@ -368,7 +281,6 @@
 	li	$13, 1		# FFI_O32
 	bne	$16, $13, 1f	# Skip fp restore if FFI_O32_SOFT_FLOAT
 
-#ifndef __mips_soft_float
 	li	$9, FFI_TYPE_FLOAT
 	l.s	$f0, V0_OFF2($fp)
 	beq	$8, $9, closure_done
@@ -376,7 +288,6 @@
 	li	$9, FFI_TYPE_DOUBLE
 	l.d	$f0, V0_OFF2($fp)
 	beq	$8, $9, closure_done
-#endif
 1:	
 	REG_L	$3, V1_OFF2($fp)
 	REG_L	$2, V0_OFF2($fp)
@@ -389,7 +300,7 @@
 	REG_L	ra,  RA_OFF2($sp)	 # Restore return address
 	ADDU	$sp, SIZEOF_FRAME2
 	j	ra
-$LFE2:
+$LFE1:
 	.end	ffi_closure_O32
 
 /* DWARF-2 unwind info. */
@@ -411,7 +322,6 @@
 	.uleb128 0x0
 	.align	2
 $LECIE0:
-
 $LSFDE0:
 	.4byte	$LEFDE0-$LASFDE0	 # FDE Length
 $LASFDE0:
@@ -420,11 +330,11 @@
 	.4byte	$LFE0-$LFB0	 # FDE address range
 	.uleb128 0x0	 # Augmentation size
 	.byte	0x4	 # DW_CFA_advance_loc4
-	.4byte	$LCFI00-$LFB0
+	.4byte	$LCFI0-$LFB0
 	.byte	0xe	 # DW_CFA_def_cfa_offset
 	.uleb128 0x18
 	.byte	0x4	 # DW_CFA_advance_loc4
-	.4byte	$LCFI01-$LCFI00
+	.4byte	$LCFI2-$LCFI0
 	.byte	0x11	 # DW_CFA_offset_extended_sf
 	.uleb128 0x1e	 # $fp
 	.sleb128 -2	 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)
@@ -432,13 +342,12 @@
 	.uleb128 0x1f	 # $ra
 	.sleb128 -1	 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
 	.byte	0x4	 # DW_CFA_advance_loc4
-	.4byte	$LCFI02-$LCFI01
+	.4byte	$LCFI3-$LCFI2
 	.byte	0xc	 # DW_CFA_def_cfa
 	.uleb128 0x1e
 	.uleb128 0x18
 	.align	2
 $LEFDE0:
-
 $LSFDE1:
 	.4byte	$LEFDE1-$LASFDE1	 # FDE Length
 $LASFDE1:
@@ -447,11 +356,11 @@
 	.4byte	$LFE1-$LFB1	 # FDE address range
 	.uleb128 0x0	 # Augmentation size
 	.byte	0x4	 # DW_CFA_advance_loc4
-	.4byte	$LCFI10-$LFB1
+	.4byte	$LCFI4-$LFB1
 	.byte	0xe	 # DW_CFA_def_cfa_offset
-	.uleb128 SIZEOF_FRAME2
+	.uleb128 0x38
 	.byte	0x4	 # DW_CFA_advance_loc4
-	.4byte	$LCFI11-$LCFI10
+	.4byte	$LCFI6-$LCFI4
 	.byte	0x11	 # DW_CFA_offset_extended_sf
 	.uleb128 0x10	 # $16
 	.sleb128 -3	 # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp)
@@ -462,41 +371,11 @@
 	.uleb128 0x1f	 # $ra
 	.sleb128 -1	 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
 	.byte	0x4	 # DW_CFA_advance_loc4
-	.4byte	$LCFI12-$LCFI11
+	.4byte	$LCFI7-$LCFI6
 	.byte	0xc	 # DW_CFA_def_cfa
 	.uleb128 0x1e
-	.uleb128 SIZEOF_FRAME2
+	.uleb128 0x38
 	.align	2
 $LEFDE1:
 
-$LSFDE2:
-	.4byte	$LEFDE2-$LASFDE2	 # FDE Length
-$LASFDE2:
-	.4byte	$LASFDE2-$Lframe0	 # 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	$LCFI20-$LFB2
-	.byte	0xe	 # DW_CFA_def_cfa_offset
-	.uleb128 SIZEOF_FRAME2
-	.byte	0x4	 # DW_CFA_advance_loc4
-	.4byte	$LCFI21-$LCFI20
-	.byte	0x11	 # DW_CFA_offset_extended_sf
-	.uleb128 0x10	 # $16
-	.sleb128 -3	 # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp)
-	.byte	0x11	 # DW_CFA_offset_extended_sf
-	.uleb128 0x1e	 # $fp
-	.sleb128 -2	 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)
-	.byte	0x11	 # DW_CFA_offset_extended_sf
-	.uleb128 0x1f	 # $ra
-	.sleb128 -1	 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
-	.byte	0x4	 # DW_CFA_advance_loc4
-	.4byte	$LCFI22-$LCFI21
-	.byte	0xc	 # DW_CFA_def_cfa
-	.uleb128 0x1e
-	.uleb128 SIZEOF_FRAME2
-	.align	2
-$LEFDE2:
-
 #endif
diff --git a/src/moxie/eabi.S b/src/moxie/eabi.S
index 10cfb04..ac7aceb 100644
--- a/src/moxie/eabi.S
+++ b/src/moxie/eabi.S
@@ -59,7 +59,7 @@
 	mov 	$r6, $r4 /* Save result buffer */
 	mov	$r7, $r5 /* Save the target fn */
 	mov	$r8, $r3 /* Save the flags */
-	sub	$sp, $r2 /* Allocate stack space */
+	sub.l	$sp, $r2 /* Allocate stack space */
 	mov	$r0, $sp /* We can stomp over $r0 */
 	/* $r1 is already set up */
 	jsra 	ffi_prep_args
diff --git a/src/moxie/ffi.c b/src/moxie/ffi.c
index 16d2bb3..540a042 100644
--- a/src/moxie/ffi.c
+++ b/src/moxie/ffi.c
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------
-   ffi.c - Copyright (C) 2012, 2013, 2018  Anthony Green
+   ffi.c - Copyright (C) 2012, 2013  Anthony Green
    
    Moxie Foreign Function Interface 
 
@@ -100,7 +100,7 @@
       count += z;
     }
 
-  return (stack + ((count > 24) ? 24 : FFI_ALIGN_DOWN(count, 8)));
+  return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
 }
 
 /* Perform machine dependent cif processing */
@@ -111,7 +111,7 @@
   else
     cif->flags = cif->rtype->size;
 
-  cif->bytes = FFI_ALIGN (cif->bytes, 8);
+  cif->bytes = ALIGN (cif->bytes, 8);
 
   return FFI_OK;
 }
@@ -159,7 +159,7 @@
 		       unsigned arg4, unsigned arg5, unsigned arg6)
 {
   /* This function is called by a trampoline.  The trampoline stows a
-     pointer to the ffi_closure object in $r12.  We must save this
+     pointer to the ffi_closure object in $r7.  We must save this
      pointer in a place that will persist while we do our work.  */
   register ffi_closure *creg __asm__ ("$r12");
   ffi_closure *closure = creg;
@@ -215,18 +215,7 @@
 	  break;
 	default:
 	  /* This is an 8-byte value.  */
-	  if (ptr == (char *) &register_args[5])
-	    {
-	      /* The value is split across two locations */
-	      unsigned *ip = alloca(8);
-	      avalue[i] = ip;
-	      ip[0] = *(unsigned *) ptr;
-	      ip[1] = *(unsigned *) stack_args;
-	    }
-	  else
-	    {
-	      avalue[i] = ptr;
-	    }
+	  avalue[i] = ptr;
 	  ptr += 4;
 	  break;
 	}
@@ -234,10 +223,8 @@
 
       /* If we've handled more arguments than fit in registers,
 	 start looking at the those passed on the stack.  */
-      if (ptr == (char *) &register_args[6])
+      if (ptr == &register_args[6])
 	ptr = stack_args;
-      else if (ptr == (char *) &register_args[7])
-	ptr = stack_args + 4;
     }
 
   /* Invoke the closure.  */
@@ -270,7 +257,7 @@
 
   fn = (unsigned long) ffi_closure_eabi;
 
-  tramp[0] = 0x01e0; /* ldi.l $r12, .... */
+  tramp[0] = 0x01e0; /* ldi.l $r7, .... */
   tramp[1] = cls >> 16;
   tramp[2] = cls & 0xffff;
   tramp[3] = 0x1a00; /* jmpa .... */
diff --git a/src/nios2/ffi.c b/src/nios2/ffi.c
index 721080d..2efa033 100644
--- a/src/nios2/ffi.c
+++ b/src/nios2/ffi.c
@@ -101,7 +101,7 @@
 
       /* Align argp as appropriate for the argument type.  */
       if ((alignment - 1) & (unsigned) argp)
-	argp = (char *) FFI_ALIGN (argp, alignment);
+	argp = (char *) ALIGN (argp, alignment);
 
       /* Copy the argument, promoting integral types smaller than a
 	 word to word size.  */
@@ -230,7 +230,7 @@
 
       /* Align argp as appropriate for the argument type.  */
       if ((alignment - 1) & (unsigned) argp)
-	argp = (char *) FFI_ALIGN (argp, alignment);
+	argp = (char *) ALIGN (argp, alignment);
 
       /* Arguments smaller than an int are promoted to int.  */
       if (size < sizeof (int))
diff --git a/src/pa/linux.S b/src/pa/linux.S
index ab04c75..f11ae76 100644
--- a/src/pa/linux.S
+++ b/src/pa/linux.S
@@ -297,18 +297,10 @@
 .LSCIE1:
 	.word   0x0     ;# CIE Identifier Tag
 	.byte   0x1     ;# CIE Version
-#ifdef __PIC__
-	.ascii  "zR\0"  ;# CIE Augmentation: 'z' - data, 'R' - DW_EH_PE_... data
-#else
 	.ascii "\0"     ;# CIE Augmentation
-#endif
 	.uleb128 0x1    ;# CIE Code Alignment Factor
 	.sleb128 4      ;# CIE Data Alignment Factor
 	.byte   0x2     ;# CIE RA Column
-#ifdef __PIC__
-	.uleb128 0x1    ;# Augmentation size
-	.byte	0x1b    ;# FDE Encoding (DW_EH_PE_pcrel|DW_EH_PE_sdata4)
-#endif
 	.byte   0xc     ;# DW_CFA_def_cfa
 	.uleb128 0x1e
 	.uleb128 0x0
@@ -318,15 +310,9 @@
 	.word   .LEFDE1-.LASFDE1        ;# FDE Length
 .LASFDE1:
 	.word   .LASFDE1-.Lframe1       ;# FDE CIE offset
-#ifdef __PIC__
-	.word	.LFB1-. ;# FDE initial location
-#else
-	.word	.LFB1   ;# FDE initial location
-#endif
+	.word   .LFB1   ;# FDE initial location
 	.word   .LFE1-.LFB1     ;# FDE address range
-#ifdef __PIC__
-	.uleb128 0x0	;# Augmentation size: no data
-#endif
+
 	.byte   0x4     ;# DW_CFA_advance_loc4
 	.word   .LCFI11-.LFB1
 	.byte	0x83	;# DW_CFA_offset, column 0x3
@@ -352,15 +338,8 @@
 	.word   .LEFDE2-.LASFDE2        ;# FDE Length
 .LASFDE2:
 	.word   .LASFDE2-.Lframe1       ;# FDE CIE offset
-#ifdef __PIC__
-	.word   .LFB2-. ;# FDE initial location
-#else
 	.word   .LFB2   ;# FDE initial location
-#endif
 	.word   .LFE2-.LFB2     ;# FDE address range
-#ifdef __PIC__
-	.uleb128 0x0	;# Augmentation size: no data
-#endif
 	.byte   0x4     ;# DW_CFA_advance_loc4
 	.word   .LCFI21-.LFB2
 	.byte   0x83    ;# DW_CFA_offset, column 0x3
diff --git a/src/powerpc/aix.S b/src/powerpc/aix.S
index 7ba5415..349e78c 100644
--- a/src/powerpc/aix.S
+++ b/src/powerpc/aix.S
@@ -106,10 +106,6 @@
 	.llong .ffi_call_AIX, TOC[tc0], 0
 	.csect .text[PR]
 .ffi_call_AIX:
-	.function .ffi_call_AIX,.ffi_call_AIX,16,044,LFE..0-LFB..0
-	.bf __LINE__
-	.line 1
-LFB..0:
 	/* Save registers we use.  */
 	mflr	r0
 
@@ -119,10 +115,8 @@
 	std	r31, -8(r1)
 
 	std	r0, 16(r1)
-LCFI..0:
 	mr	r28, r1		/* our AP.  */
 	stdux	r1, r1, r4
-LCFI..1:
 
 	/* Save arguments over call...  */
 	mr	r31, r5	/* flags, */
@@ -208,16 +202,12 @@
 L(float_return_value):
 	stfs	f1, 0(r30)
 	b	L(done_return_value)
-LFE..0:
+
 #else /* ! __64BIT__ */
 	
 	.long .ffi_call_AIX, TOC[tc0], 0
 	.csect .text[PR]
 .ffi_call_AIX:
-	.function .ffi_call_AIX,.ffi_call_AIX,16,044,LFE..0-LFB..0
-	.bf __LINE__
-	.line 1
-LFB..0:
 	/* Save registers we use.  */
 	mflr	r0
 
@@ -227,10 +217,8 @@
 	stw	r31, -4(r1)
 
 	stw	r0, 8(r1)
-LCFI..0:
 	mr	r28, r1		/* out AP.  */
 	stwux	r1, r1, r4
-LCFI..1:
 
 	/* Save arguments over call...  */
 	mr	r31, r5	/* flags, */
@@ -316,144 +304,11 @@
 L(float_return_value):
 	stfs	f1, 0(r30)
 	b	L(done_return_value)
-LFE..0:
 #endif
-	.ef __LINE__
 	.long 0
 	.byte 0,0,0,1,128,4,0,0
 /* END(ffi_call_AIX) */
 
-	/* void ffi_call_go_AIX(extended_cif *ecif, unsigned long bytes,
-	 *		        unsigned int flags, unsigned int *rvalue,
-	 *		        void (*fn)(),
-	 *		        void (*prep_args)(extended_cif*, unsigned *const),
-	 *                      void *closure);
-	 * r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args, r9=closure
-	 */
-
-.csect .text[PR]
-	.align 2
-	.globl ffi_call_go_AIX
-	.globl .ffi_call_go_AIX
-.csect ffi_call_go_AIX[DS]
-ffi_call_go_AIX:
-#ifdef __64BIT__
-	.llong .ffi_call_go_AIX, TOC[tc0], 0
-	.csect .text[PR]
-.ffi_call_go_AIX:
-	.function .ffi_call_go_AIX,.ffi_call_go_AIX,16,044,LFE..1-LFB..1
-	.bf __LINE__
-	.line 1
-LFB..1:
-	/* Save registers we use.  */
-	mflr	r0
-
-	std	r28,-32(r1)
-	std	r29,-24(r1)
-	std	r30,-16(r1)
-	std	r31, -8(r1)
-
-	std	r9, 8(r1)	/* closure, saved in cr field. */
-	std	r0, 16(r1)
-LCFI..2:
-	mr	r28, r1		/* our AP.  */
-	stdux	r1, r1, r4
-LCFI..3:
-
-	/* Save arguments over call...  */
-	mr	r31, r5	/* flags, */
-	mr	r30, r6	/* rvalue, */
-	mr	r29, r7	/* function address,  */
-	std	r2, 40(r1)
-
-	/* Call ffi_prep_args.  */
-	mr	r4, r1
-	bl	.ffi_prep_args
-	nop
-
-	/* Now do the call.  */
-	ld	r0, 0(r29)
-	ld	r2, 8(r29)
-	ld      r11, 8(r28)	/* closure */
-	/* Set up cr1 with bits 4-7 of the flags.  */
-	mtcrf	0x40, r31
-	mtctr	r0
-	/* Load all those argument registers.  */
-	/* We have set up a nice stack frame, just load it into registers. */
-	ld	r3, 40+(1*8)(r1)
-	ld	r4, 40+(2*8)(r1)
-	ld	r5, 40+(3*8)(r1)
-	ld	r6, 40+(4*8)(r1)
-	nop
-	ld	r7, 40+(5*8)(r1)
-	ld	r8, 40+(6*8)(r1)
-	ld	r9, 40+(7*8)(r1)
-	ld	r10,40+(8*8)(r1)
-
-	b	L1
-LFE..1:
-#else /* ! __64BIT__ */
-	
-	.long .ffi_call_go_AIX, TOC[tc0], 0
-	.csect .text[PR]
-.ffi_call_go_AIX:
-	.function .ffi_call_go_AIX,.ffi_call_go_AIX,16,044,LFE..1-LFB..1
-	.bf __LINE__
-	.line 1
-	/* Save registers we use.  */
-LFB..1:
-	mflr	r0
-
-	stw	r28,-16(r1)
-	stw	r29,-12(r1)
-	stw	r30, -8(r1)
-	stw	r31, -4(r1)
-
-	stw	r9, 4(r1)	/* closure, saved in cr field.  */
-	stw	r0, 8(r1)
-LCFI..2:
-	mr	r28, r1		/* out AP.  */
-	stwux	r1, r1, r4
-LCFI..3:
-
-	/* Save arguments over call...  */
-	mr	r31, r5	/* flags, */
-	mr	r30, r6	/* rvalue, */
-	mr	r29, r7	/* function address, */
-	stw	r2, 20(r1)
-
-	/* Call ffi_prep_args.  */
-	mr	r4, r1
-	bl	.ffi_prep_args
-	nop
-
-	/* Now do the call.  */
-	lwz	r0, 0(r29)
-	lwz	r2, 4(r29)
-	lwz	r11, 4(r28)	/* closure */
-	/* Set up cr1 with bits 4-7 of the flags.  */
-	mtcrf	0x40, r31
-	mtctr	r0
-	/* Load all those argument registers.  */
-	/* We have set up a nice stack frame, just load it into registers. */
-	lwz	r3, 20+(1*4)(r1)
-	lwz	r4, 20+(2*4)(r1)
-	lwz	r5, 20+(3*4)(r1)
-	lwz	r6, 20+(4*4)(r1)
-	nop
-	lwz	r7, 20+(5*4)(r1)
-	lwz	r8, 20+(6*4)(r1)
-	lwz	r9, 20+(7*4)(r1)
-	lwz	r10,20+(8*4)(r1)
-
-	b	L1
-LFE..1:
-#endif
-	.ef __LINE__
-	.long 0
-	.byte 0,0,0,1,128,4,0,0
-/* END(ffi_call_go_AIX) */
-
 .csect .text[PR]
 	.align 2
 	.globl ffi_call_DARWIN
@@ -471,96 +326,3 @@
 	.long 0
 	.byte 0,0,0,0,0,0,0,0
 /* END(ffi_call_DARWIN) */
-
-/* EH frame stuff.  */
-
-#define LR_REGNO		0x41		/* Link Register (65), see rs6000.md */
-#ifdef __64BIT__
-#define PTRSIZE			8
-#define LOG2_PTRSIZE		3
-#define FDE_ENCODING		0x1c		/* DW_EH_PE_pcrel|DW_EH_PE_sdata8 */
-#define EH_DATA_ALIGN_FACT	0x78		/* LEB128 -8 */
-#else
-#define PTRSIZE			4
-#define LOG2_PTRSIZE		2
-#define FDE_ENCODING		0x1b		/* DW_EH_PE_pcrel|DW_EH_PE_sdata4 */
-#define EH_DATA_ALIGN_FACT	0x7c		/* LEB128 -4 */
-#endif
-	.csect	_unwind.ro_[RO],4
-	.align	LOG2_PTRSIZE
-	.globl	_GLOBAL__F_libffi_src_powerpc_aix
-_GLOBAL__F_libffi_src_powerpc_aix:
-Lframe..1:
-	.vbyte	4,LECIE..1-LSCIE..1	/* CIE Length */
-LSCIE..1:
-	.vbyte	4,0			/* CIE Identifier Tag */
-	.byte	0x3			/* CIE Version */
-	.byte	"zR"			/* CIE Augmentation */
-	.byte	0
-	.byte	0x1			/* uleb128 0x1; CIE Code Alignment Factor */
-	.byte	EH_DATA_ALIGN_FACT	/* leb128 -4/-8; CIE Data Alignment Factor */
-	.byte	0x41			/* CIE RA Column */
-	.byte	0x1			/* uleb128 0x1; Augmentation size */
-	.byte	FDE_ENCODING		/* FDE Encoding (pcrel|sdata4/8) */
-	.byte	0xc			/* DW_CFA_def_cfa */
-	.byte	0x1			/*     uleb128 0x1; Register r1 */
-	.byte	0			/*     uleb128 0x0; Offset 0 */
-	.align	LOG2_PTRSIZE
-LECIE..1:
-LSFDE..1:
-	.vbyte	4,LEFDE..1-LASFDE..1	/* FDE Length */
-LASFDE..1:
-	.vbyte	4,LASFDE..1-Lframe..1	/* FDE CIE offset */
-	.vbyte	PTRSIZE,LFB..0-$	/* FDE initial location */
-	.vbyte	PTRSIZE,LFE..0-LFB..0	/* FDE address range */
-	.byte   0			/* uleb128 0x0; Augmentation size */
-	.byte	0x4			/* DW_CFA_advance_loc4 */
-	.vbyte	4,LCFI..0-LFB..0
-	.byte	0x11			/* DW_CFA_def_offset_extended_sf */
-	.byte	LR_REGNO		/*     uleb128 LR_REGNO; Register LR */
-	.byte	0x7e			/*     leb128 -2; Offset -2 (8/16) */
-	.byte	0x9f			/* DW_CFA_offset Register r31 */
-	.byte	0x1			/*     uleb128 0x1; Offset 1 (-4/-8) */
-	.byte	0x9e			/* DW_CFA_offset Register r30 */
-	.byte	0x2			/*     uleb128 0x2; Offset 2 (-8/-16) */
-	.byte	0x9d			/* DW_CFA_offset Register r29 */
-	.byte	0x3			/*     uleb128 0x3; Offset 3 (-12/-24) */
-	.byte	0x9c			/* DW_CFA_offset Register r28 */
-	.byte	0x4			/*     uleb128 0x4; Offset 4 (-16/-32) */
-	.byte	0x4			/* DW_CFA_advance_loc4 */
-	.vbyte	4,LCFI..1-LCFI..0
-	.byte	0xd			/* DW_CFA_def_cfa_register */
-	.byte	0x1c			/*     uleb128 28; Register r28 */
-	.align	LOG2_PTRSIZE
-LEFDE..1:
-LSFDE..2:
-	.vbyte	4,LEFDE..2-LASFDE..2	/* FDE Length */
-LASFDE..2:
-	.vbyte	4,LASFDE..2-Lframe..1	/* FDE CIE offset */
-	.vbyte	PTRSIZE,LFB..1-$	/* FDE initial location */
-	.vbyte	PTRSIZE,LFE..1-LFB..1	/* FDE address range */
-	.byte   0			/* uleb128 0x0; Augmentation size */
-	.byte	0x4			/* DW_CFA_advance_loc4 */
-	.vbyte	4,LCFI..2-LFB..1
-	.byte	0x11			/* DW_CFA_def_offset_extended_sf */
-	.byte	LR_REGNO		/*     uleb128 LR_REGNO; Register LR */
-	.byte	0x7e			/*     leb128 -2; Offset -2 (8/16) */
-	.byte	0x9f			/* DW_CFA_offset Register r31 */
-	.byte	0x1			/*     uleb128 0x1; Offset 1 (-4/-8) */
-	.byte	0x9e			/* DW_CFA_offset Register r30 */
-	.byte	0x2			/*     uleb128 0x2; Offset 2 (-8/-16) */
-	.byte	0x9d			/* DW_CFA_offset Register r29 */
-	.byte	0x3			/*     uleb128 0x3; Offset 3 (-12/-24) */
-	.byte	0x9c			/* DW_CFA_offset Register r28 */
-	.byte	0x4			/*     uleb128 0x4; Offset 4 (-16/-32) */
-	.byte	0x4			/* DW_CFA_advance_loc4 */
-	.vbyte	4,LCFI..3-LCFI..2
-	.byte	0xd			/* DW_CFA_def_cfa_register */
-	.byte	0x1c			/*     uleb128 28; Register r28 */
-	.align	LOG2_PTRSIZE
-LEFDE..2:
-	.vbyte	4,0			/* End of FDEs */
-
-	.csect	.text[PR]
-	.ref	_GLOBAL__F_libffi_src_powerpc_aix	/* Prevents garbage collection by AIX linker */
-
diff --git a/src/powerpc/aix_closure.S b/src/powerpc/aix_closure.S
index 132c785..aabd3c3 100644
--- a/src/powerpc/aix_closure.S
+++ b/src/powerpc/aix_closure.S
@@ -80,7 +80,6 @@
 	.set f21,21
 
 	.extern .ffi_closure_helper_DARWIN
-	.extern .ffi_go_closure_helper_DARWIN
 
 #define LIBFFI_ASM
 #define JUMPTARGET(name) name
@@ -102,10 +101,6 @@
 	.llong .ffi_closure_ASM, TOC[tc0], 0
 	.csect .text[PR]
 .ffi_closure_ASM:
-	.function .ffi_closure_ASM,.ffi_closure_ASM,16,044,LFE..0-LFB..0
-	.bf __LINE__
-	.line 1
-LFB..0:
 /* we want to build up an area for the parameters passed */
 /* in registers (both floating point and integer) */
 
@@ -122,7 +117,8 @@
 	std   r9, 48+(6*8)(r1)
 	std   r10, 48+(7*8)(r1)
 	std   r0, 16(r1)	/* save the return address */
-LCFI..0:
+
+
 	/* 48  Bytes (Linkage Area) */
 	/* 64  Bytes (params) */
 	/* 16  Bytes (result) */
@@ -132,7 +128,6 @@
 
 	stdu  r1, -240(r1)	/* skip over caller save area
 				   keep stack aligned to 16  */
-LCFI..1:
 
 	/* next save fpr 1 to fpr 13 (aligned to 8) */
 	stfd  f1, 128+(0*8)(r1)
@@ -166,8 +161,6 @@
 	bl .ffi_closure_helper_DARWIN
 	nop
 
-.Ldoneclosure:
-
 	/* now r3 contains the return type */
 	/* so use it to look up in a table */
 	/* so we know how to deal with each type */
@@ -277,17 +270,12 @@
 	mtlr r0
 	addi r1, r1, 240
 	blr
-LFE..0:
 
 #else /* ! __64BIT__ */
 	
 	.long .ffi_closure_ASM, TOC[tc0], 0
 	.csect .text[PR]
 .ffi_closure_ASM:
-	.function .ffi_closure_ASM,.ffi_closure_ASM,16,044,LFE..0-LFB..0
-	.bf __LINE__
-	.line 1
-LFB..0:
 /* we want to build up an area for the parameters passed */
 /* in registers (both floating point and integer) */
 
@@ -304,7 +292,7 @@
 	stw   r9, 24+(6*4)(r1)
 	stw   r10, 24+(7*4)(r1)
 	stw   r0, 8(r1)
-LCFI..0:
+
 	/* 24 Bytes (Linkage Area) */
 	/* 32 Bytes (params) */
 	/* 16  Bytes (result) */
@@ -313,7 +301,6 @@
 
 	stwu  r1, -176(r1)	/* skip over caller save area
 				   keep stack aligned to 16  */
-LCFI..1:
 
 	/* next save fpr 1 to fpr 13 (aligned to 8) */
 	stfd  f1, 72+(0*8)(r1)
@@ -347,8 +334,6 @@
 	bl .ffi_closure_helper_DARWIN
 	nop
 
-.Ldoneclosure:
-
 	/* now r3 contains the return type */
 	/* so use it to look up in a table */
 	/* so we know how to deal with each type */
@@ -458,237 +443,5 @@
 L..finish:
 	addi r1, r1, 176
 	blr
-LFE..0:
 #endif
-	.ef __LINE__
 /* END(ffi_closure_ASM) */
-
-
-.csect .text[PR]
-	.align 2
-	.globl ffi_go_closure_ASM
-	.globl .ffi_go_closure_ASM
-.csect ffi_go_closure_ASM[DS]
-ffi_go_closure_ASM:
-#ifdef __64BIT__
-	.llong .ffi_go_closure_ASM, TOC[tc0], 0
-	.csect .text[PR]
-.ffi_go_closure_ASM:
-	.function .ffi_go_closure_ASM,.ffi_go_closure_ASM,16,044,LFE..1-LFB..1
-	.bf __LINE__
-	.line 1
-LFB..1:
-/* we want to build up an area for the parameters passed */
-/* in registers (both floating point and integer) */
-
-	/* we store gpr 3 to gpr 10 (aligned to 4)
-	in the parents outgoing area  */
-	std   r3, 48+(0*8)(r1)
-	std   r4, 48+(1*8)(r1)
-	std   r5, 48+(2*8)(r1)
-	std   r6, 48+(3*8)(r1)
-	mflr  r0
-
-	std   r7, 48+(4*8)(r1)
-	std   r8, 48+(5*8)(r1)
-	std   r9, 48+(6*8)(r1)
-	std   r10, 48+(7*8)(r1)
-	std   r0, 16(r1)	/* save the return address */
-LCFI..2:
-	/* 48  Bytes (Linkage Area) */
-	/* 64  Bytes (params) */
-	/* 16  Bytes (result) */
-	/* 104 Bytes (13*8 from FPR) */
-	/* 8   Bytes (alignment) */
-	/* 240 Bytes */
-
-	stdu  r1, -240(r1)	/* skip over caller save area
-				   keep stack aligned to 16  */
-LCFI..3:
-
-	/* next save fpr 1 to fpr 13 (aligned to 8) */
-	stfd  f1, 128+(0*8)(r1)
-	stfd  f2, 128+(1*8)(r1)
-	stfd  f3, 128+(2*8)(r1)
-	stfd  f4, 128+(3*8)(r1)
-	stfd  f5, 128+(4*8)(r1)
-	stfd  f6, 128+(5*8)(r1)
-	stfd  f7, 128+(6*8)(r1)
-	stfd  f8, 128+(7*8)(r1)
-	stfd  f9, 128+(8*8)(r1)
-	stfd  f10, 128+(9*8)(r1)
-	stfd  f11, 128+(10*8)(r1)
-	stfd  f12, 128+(11*8)(r1)
-	stfd  f13, 128+(12*8)(r1)
-
-	/* set up registers for the routine that actually does the work */
-	mr r3, r11	/* go closure */
-
-	/* now load up the pointer to the result storage */
-	addi r4, r1, 112
-
-	/* now load up the pointer to the saved gpr registers */
-	addi r5, r1, 288
-
-	/* now load up the pointer to the saved fpr registers */
-	addi r6, r1, 128
-
-	/* make the call */
-	bl .ffi_go_closure_helper_DARWIN
-	nop
-
-	b .Ldoneclosure
-LFE..1:
-
-#else /* ! __64BIT__ */
-	
-	.long .ffi_go_closure_ASM, TOC[tc0], 0
-	.csect .text[PR]
-.ffi_go_closure_ASM:
-	.function .ffi_go_closure_ASM,.ffi_go_closure_ASM,16,044,LFE..1-LFB..1
-	.bf __LINE__
-	.line 1
-LFB..1:
-/* we want to build up an area for the parameters passed */
-/* in registers (both floating point and integer) */
-
-	/* we store gpr 3 to gpr 10 (aligned to 4)
-	in the parents outgoing area  */
-	stw   r3, 24+(0*4)(r1)
-	stw   r4, 24+(1*4)(r1)
-	stw   r5, 24+(2*4)(r1)
-	stw   r6, 24+(3*4)(r1)
-	mflr  r0
-
-	stw   r7, 24+(4*4)(r1)
-	stw   r8, 24+(5*4)(r1)
-	stw   r9, 24+(6*4)(r1)
-	stw   r10, 24+(7*4)(r1)
-	stw   r0, 8(r1)
-LCFI..2:
-	/* 24 Bytes (Linkage Area) */
-	/* 32 Bytes (params) */
-	/* 16  Bytes (result) */
-	/* 104 Bytes (13*8 from FPR) */
-	/* 176 Bytes */
-
-	stwu  r1, -176(r1)	/* skip over caller save area
-				   keep stack aligned to 16  */
-LCFI..3:
-
-	/* next save fpr 1 to fpr 13 (aligned to 8) */
-	stfd  f1, 72+(0*8)(r1)
-	stfd  f2, 72+(1*8)(r1)
-	stfd  f3, 72+(2*8)(r1)
-	stfd  f4, 72+(3*8)(r1)
-	stfd  f5, 72+(4*8)(r1)
-	stfd  f6, 72+(5*8)(r1)
-	stfd  f7, 72+(6*8)(r1)
-	stfd  f8, 72+(7*8)(r1)
-	stfd  f9, 72+(8*8)(r1)
-	stfd  f10, 72+(9*8)(r1)
-	stfd  f11, 72+(10*8)(r1)
-	stfd  f12, 72+(11*8)(r1)
-	stfd  f13, 72+(12*8)(r1)
-
-	/* set up registers for the routine that actually does the work */
-	mr   r3, 11	/* go closure */
-
-	/* now load up the pointer to the result storage */
-	addi r4, r1, 56
-
-	/* now load up the pointer to the saved gpr registers */
-	addi r5, r1, 200
-
-	/* now load up the pointer to the saved fpr registers */
-	addi r6, r1, 72
-
-	/* make the call */
-	bl .ffi_go_closure_helper_DARWIN
-	nop
-
-	b    .Ldoneclosure
-LFE..1:
-#endif
-	.ef __LINE__
-/* END(ffi_go_closure_ASM) */
-
-/* EH frame stuff.  */
-
-#define LR_REGNO		0x41		/* Link Register (65), see rs6000.md */
-#ifdef __64BIT__
-#define PTRSIZE			8
-#define LOG2_PTRSIZE		3
-#define CFA_OFFSET		0xf0,0x01	/* LEB128 240 */
-#define FDE_ENCODING		0x1c		/* DW_EH_PE_pcrel|DW_EH_PE_sdata8 */
-#define EH_DATA_ALIGN_FACT	0x78		/* LEB128 -8 */
-#else
-#define PTRSIZE			4
-#define LOG2_PTRSIZE		2
-#define CFA_OFFSET		0xb0,0x01	/* LEB128 176 */
-#define FDE_ENCODING		0x1b		/* DW_EH_PE_pcrel|DW_EH_PE_sdata4 */
-#define EH_DATA_ALIGN_FACT	0x7c		/* LEB128 -4 */
-#endif
-
-	.csect	_unwind.ro_[RO],4
-	.align	LOG2_PTRSIZE
-	.globl	_GLOBAL__F_libffi_src_powerpc_aix_closure
-_GLOBAL__F_libffi_src_powerpc_aix_closure:
-Lframe..1:
-	.vbyte	4,LECIE..1-LSCIE..1	/* CIE Length */
-LSCIE..1:
-	.vbyte	4,0			/* CIE Identifier Tag */
-	.byte	0x3			/* CIE Version */
-	.byte	"zR"			/* CIE Augmentation */
-	.byte	0
-	.byte	0x1			/* uleb128 0x1; CIE Code Alignment Factor */
-	.byte	EH_DATA_ALIGN_FACT	/* leb128 -4/-8; CIE Data Alignment Factor */
-	.byte	LR_REGNO		/* CIE RA Column */
-	.byte	0x1			/* uleb128 0x1; Augmentation size */
-	.byte	FDE_ENCODING		/* FDE Encoding (pcrel|sdata4/8) */
-	.byte	0xc			/* DW_CFA_def_cfa */
-	.byte	0x1			/*     uleb128 0x1; Register r1 */
-	.byte	0			/*     uleb128 0x0; Offset 0 */
-	.align	LOG2_PTRSIZE
-LECIE..1:
-LSFDE..1:
-	.vbyte	4,LEFDE..1-LASFDE..1	/* FDE Length */
-LASFDE..1:
-	.vbyte	4,LASFDE..1-Lframe..1	/* FDE CIE offset */
-	.vbyte	PTRSIZE,LFB..0-$	/* FDE initial location */
-	.vbyte	PTRSIZE,LFE..0-LFB..0	/* FDE address range */
-	.byte	0			/* uleb128 0x0; Augmentation size */
-	.byte	0x4			/* DW_CFA_advance_loc4 */
-	.vbyte	4,LCFI..1-LCFI..0
-	.byte	0xe			/* DW_CFA_def_cfa_offset */
-	.byte	CFA_OFFSET		/*     uleb128 176/240 */
-	.byte	0x4			/* DW_CFA_advance_loc4 */
-	.vbyte	4,LCFI..0-LFB..0
-	.byte	0x11			/* DW_CFA_offset_extended_sf */
-	.byte	LR_REGNO		/*     uleb128 LR_REGNO; Register LR */
-	.byte	0x7e			/*     leb128 -2; Offset -2 (8/16) */
-	.align	LOG2_PTRSIZE
-LEFDE..1:
-LSFDE..2:
-	.vbyte	4,LEFDE..2-LASFDE..2	/* FDE Length */
-LASFDE..2:
-	.vbyte	4,LASFDE..2-Lframe..1	/* FDE CIE offset */
-	.vbyte	PTRSIZE,LFB..1-$	/* FDE initial location */
-	.vbyte	PTRSIZE,LFE..1-LFB..1	/* FDE address range */
-	.byte	0			/* uleb128 0x0; Augmentation size */
-	.byte	0x4			/* DW_CFA_advance_loc4 */
-	.vbyte	4,LCFI..3-LCFI..2
-	.byte	0xe			/* DW_CFA_def_cfa_offset */
-	.byte	CFA_OFFSET		/*     uleb128 176/240 */
-	.byte	0x4			/* DW_CFA_advance_loc4 */
-	.vbyte	4,LCFI..2-LFB..1
-	.byte	0x11			/* DW_CFA_offset_extended_sf */
-	.byte	LR_REGNO		/*     uleb128 LR_REGNO; Register LR */
-	.byte	0x7e			/*     leb128 -2; Offset -2 (8/16) */
-	.align	LOG2_PTRSIZE
-LEFDE..2:
-	.vbyte	4,0			/* End of FDEs */
-
-	.csect	.text[PR]
-	.ref	_GLOBAL__F_libffi_src_powerpc_aix_closure	/* Prevents garbage collection by AIX linker */
-
diff --git a/src/powerpc/asm.h b/src/powerpc/asm.h
index 27b22f6..994f62d 100644
--- a/src/powerpc/asm.h
+++ b/src/powerpc/asm.h
@@ -93,7 +93,7 @@
 /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
    past a 2^align boundary.  */
 #ifdef PROF
-#define EFFI_ALIGN(name, alignt, words)					      \
+#define EALIGN(name, alignt, words)					      \
   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
   .align ALIGNARG(2);							      \
@@ -104,7 +104,7 @@
   EALIGN_W_##words;							      \
   0:
 #else /* PROF */
-#define EFFI_ALIGN(name, alignt, words)					      \
+#define EALIGN(name, alignt, words)					      \
   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
   .align ALIGNARG(alignt);						      \
diff --git a/src/powerpc/darwin_closure.S b/src/powerpc/darwin_closure.S
index 3121e6a..c7734d4 100644
--- a/src/powerpc/darwin_closure.S
+++ b/src/powerpc/darwin_closure.S
@@ -353,7 +353,7 @@
 	bgt	Lstructend		; not a special small case
 	b	Lsmallstruct		; see if we need more.
 #else
-	cmpwi	0,r0,4
+	cmpi	0,r0,4
 	bgt	Lfinish		; not by value
 	lg	r3,0(r5)
 	b	Lfinish
@@ -494,8 +494,8 @@
 LASFDE1:
 	.long	LASFDE1-EH_frame1	; FDE CIE offset
 	.g_long	Lstartcode-.	; FDE initial location
-	.set	L$set$2,LFE1-Lstartcode
-	.g_long	L$set$2	; FDE address range
+	.set	L$set$3,LFE1-Lstartcode
+	.g_long	L$set$3	; FDE address range
 	.byte   0x0     ; uleb128 0x0; Augmentation size
 	.byte	0x4	; DW_CFA_advance_loc4
 	.set	L$set$3,LCFI1-LCFI0
diff --git a/src/powerpc/ffi.c b/src/powerpc/ffi.c
index a19bcbb..efb441b 100644
--- a/src/powerpc/ffi.c
+++ b/src/powerpc/ffi.c
@@ -70,12 +70,8 @@
 #endif
 }
 
-static void
-ffi_call_int (ffi_cif *cif,
-	      void (*fn) (void),
-	      void *rvalue,
-	      void **avalue,
-	      void *closure)
+void
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
   /* The final SYSV ABI says that structures smaller or equal 8 bytes
      are returned in r3/r4.  A draft ABI used by linux instead returns
@@ -85,9 +81,8 @@
      can write r3 and r4 to memory without worrying about struct size.
    
      For ELFv2 ABI, use a bounce buffer for homogeneous structs too,
-     for similar reasons. This bounce buffer must be aligned to 16
-     bytes for use with homogeneous structs of vectors (float128).  */
-  float128 smst_buffer[8];
+     for similar reasons.  */
+  unsigned long smst_buffer[8];
   extended_cif ecif;
 
   ecif.cif = cif;
@@ -102,10 +97,9 @@
     ecif.rvalue = alloca (cif->rtype->size);
 
 #ifdef POWERPC64
-  ffi_call_LINUX64 (&ecif, fn, ecif.rvalue, cif->flags, closure,
-		    -(long) cif->bytes);
+  ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
 #else
-  ffi_call_SYSV (&ecif, fn, ecif.rvalue, cif->flags, closure, -cif->bytes);
+  ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
 #endif
 
   /* Check for a bounce-buffered return value */
@@ -122,9 +116,8 @@
 # endif
 	/* The SYSV ABI returns a structure of up to 8 bytes in size
 	   left-padded in r3/r4, and the ELFv2 ABI similarly returns a
-	   structure of up to 8 bytes in size left-padded in r3. But
-	   note that a structure of a single float is not paddded.  */
-	if (rsize <= 8 && (cif->flags & FLAG_RETURNS_FP) == 0)
+	   structure of up to 8 bytes in size left-padded in r3.  */
+	if (rsize <= 8)
 	  memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize);
 	else
 #endif
@@ -132,18 +125,6 @@
     }
 }
 
-void
-ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, NULL);
-}
-
-void
-ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,
-	     void *closure)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, closure);
-}
 
 ffi_status
 ffi_prep_closure_loc (ffi_closure *closure,
@@ -158,18 +139,3 @@
   return ffi_prep_closure_loc_sysv (closure, cif, fun, user_data, codeloc);
 #endif
 }
-
-ffi_status
-ffi_prep_go_closure (ffi_go_closure *closure,
-		     ffi_cif *cif,
-		     void (*fun) (ffi_cif *, void *, void **, void *))
-{
-#ifdef POWERPC64
-  closure->tramp = ffi_go_closure_linux64;
-#else
-  closure->tramp = ffi_go_closure_sysv;
-#endif
-  closure->cif = cif;
-  closure->fun = fun;
-  return FFI_OK;
-}
diff --git a/src/powerpc/ffi_darwin.c b/src/powerpc/ffi_darwin.c
index 61a18c4..cf6fb6d 100644
--- a/src/powerpc/ffi_darwin.c
+++ b/src/powerpc/ffi_darwin.c
@@ -33,7 +33,6 @@
 #include <stdlib.h>
 
 extern void ffi_closure_ASM (void);
-extern void ffi_go_closure_ASM (void);
 
 enum {
   /* The assembly depends on these exact flags.  
@@ -256,7 +255,7 @@
 	case FFI_TYPE_STRUCT:
 	  size_al = (*ptr)->size;
 #if defined(POWERPC_DARWIN64)
-	  next_arg = (unsigned long *)FFI_ALIGN((char *)next_arg, (*ptr)->alignment);
+	  next_arg = (unsigned long *)ALIGN((char *)next_arg, (*ptr)->alignment);
 	  darwin64_pass_struct_by_value (*ptr, (char *) *p_argv, 
 					 (unsigned) size_al,
 					 (unsigned int *) &fparg_count,
@@ -267,7 +266,7 @@
 	  /* If the first member of the struct is a double, then include enough
 	     padding in the struct size to align it to double-word.  */
 	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
-	    size_al = FFI_ALIGN((*ptr)->size, 8);
+	    size_al = ALIGN((*ptr)->size, 8);
 
 #  if defined(POWERPC64) 
 	  FFI_ASSERT (abi != FFI_DARWIN);
@@ -353,7 +352,7 @@
       ffi_type *p = s->elements[i];
       /* Find the start of this item (0 for the first one).  */
       if (i > 0)
-        struct_offset = FFI_ALIGN(struct_offset, p->alignment);
+        struct_offset = ALIGN(struct_offset, p->alignment);
 
       item_base = src + struct_offset;
 
@@ -437,7 +436,7 @@
       ffi_type *p = s->elements[i];
       /* Find the start of this item (0 for the first one).  */
       if (i > 0)
-        struct_offset = FFI_ALIGN(struct_offset, p->alignment);
+        struct_offset = ALIGN(struct_offset, p->alignment);
       item_base = src + struct_offset;
 
       switch (p->type)
@@ -528,7 +527,7 @@
       ffi_type *p = s->elements[i];
       /* Find the start of this item (0 for the first one).  */
       if (i > 0)
-        struct_offset = FFI_ALIGN(struct_offset, p->alignment);
+        struct_offset = ALIGN(struct_offset, p->alignment);
       item_base = dest + struct_offset;
 
       switch (p->type)
@@ -605,10 +604,10 @@
 	align = 4;
 #endif
       /* Pad, if necessary, before adding the current item.  */
-      s->size = FFI_ALIGN(s->size, align) + p->size;
+      s->size = ALIGN(s->size, align) + p->size;
     }
   
-  s->size = FFI_ALIGN(s->size, s->alignment);
+  s->size = ALIGN(s->size, s->alignment);
   
   /* This should not be necessary on m64, but harmless.  */
   if (s->elements[0]->type == FFI_TYPE_UINT64
@@ -641,10 +640,10 @@
       align = p->alignment;
       if (i != 0 && p->type == FFI_TYPE_DOUBLE)
 	align = 4;
-      s->size = FFI_ALIGN(s->size, align) + p->size;
+      s->size = ALIGN(s->size, align) + p->size;
     }
   
-  s->size = FFI_ALIGN(s->size, s->alignment);
+  s->size = ALIGN(s->size, s->alignment);
   
   if (s->elements[0]->type == FFI_TYPE_UINT64
       || s->elements[0]->type == FFI_TYPE_SINT64
@@ -810,9 +809,9 @@
 	     16-byte-aligned.  */
 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
 #if defined (POWERPC64)
-	    intarg_count = FFI_ALIGN(intarg_count, 2);
+	    intarg_count = ALIGN(intarg_count, 2);
 #else
-	    intarg_count = FFI_ALIGN(intarg_count, 4);
+	    intarg_count = ALIGN(intarg_count, 4);
 #endif
 	  break;
 #endif
@@ -839,7 +838,7 @@
 #if defined(POWERPC_DARWIN64)
 	  align_words = (*ptr)->alignment >> 3;
 	  if (align_words)
-	    intarg_count = FFI_ALIGN(intarg_count, align_words);
+	    intarg_count = ALIGN(intarg_count, align_words);
 	  /* Base size of the struct.  */
 	  intarg_count += (size_al + 7) / 8;
 	  /* If 16 bytes then don't worry about floats.  */
@@ -849,11 +848,11 @@
 #else
 	  align_words = (*ptr)->alignment >> 2;
 	  if (align_words)
-	    intarg_count = FFI_ALIGN(intarg_count, align_words);
+	    intarg_count = ALIGN(intarg_count, align_words);
 	  /* If the first member of the struct is a double, then align
 	     the struct to double-word. 
 	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
-	    size_al = FFI_ALIGN((*ptr)->size, 8); */
+	    size_al = ALIGN((*ptr)->size, 8); */
 #  ifdef POWERPC64
 	  intarg_count += (size_al + 7) / 8;
 #  else
@@ -898,7 +897,7 @@
     bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
 
   /* The stack space allocated needs to be a multiple of 16 bytes.  */
-  bytes = FFI_ALIGN(bytes, 16) ;
+  bytes = ALIGN(bytes, 16) ;
 
   cif->flags = flags;
   cif->bytes = bytes;
@@ -909,9 +908,6 @@
 extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,
 			 void (*fn)(void), void (*fn2)(void));
 
-extern void ffi_call_go_AIX(extended_cif *, long, unsigned, unsigned *,
-			    void (*fn)(void), void (*fn2)(void), void *closure);
-
 extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,
 			    void (*fn)(void), void (*fn2)(void), ffi_type*);
 
@@ -950,38 +946,6 @@
     }
 }
 
-void
-ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,
-	     void *closure)
-{
-  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_AIX:
-      ffi_call_go_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
-		      FFI_FN(ffi_prep_args), closure);
-      break;
-    default:
-      FFI_ASSERT(0);
-      break;
-    }
-}
-
 static void flush_icache(char *);
 static void flush_range(char *, int);
 
@@ -1110,30 +1074,6 @@
   return FFI_OK;
 }
 
-ffi_status
-ffi_prep_go_closure (ffi_go_closure* closure,
-		     ffi_cif* cif,
-		     void (*fun)(ffi_cif*, void*, void**, void*))
-{
-  switch (cif->abi)
-    {
-      case FFI_AIX:
-
-        FFI_ASSERT (cif->abi == FFI_AIX);
-
-        closure->tramp = (void *)ffi_go_closure_ASM;
-        closure->cif = cif;
-        closure->fun = fun;
-        return FFI_OK;
-      
-      // For now, ffi_prep_go_closure is only implemented for AIX, not for Darwin
-      default:
-        return FFI_BAD_ABI;
-        break;
-    }
-  return FFI_OK;
-}
-
 static void
 flush_icache(char *addr)
 {
@@ -1168,10 +1108,6 @@
 ffi_closure_helper_DARWIN (ffi_closure *, void *,
 			   unsigned long *, ffi_dblfl *);
 
-ffi_type *
-ffi_go_closure_helper_DARWIN (ffi_go_closure*, void *,
-			      unsigned long *, ffi_dblfl *);
-
 /* Basically the trampoline invokes ffi_closure_ASM, and on
    entry, r11 holds the address of the closure.
    After storing the registers that could possibly contain
@@ -1179,10 +1115,8 @@
    up space for a return value, ffi_closure_ASM invokes the
    following helper function to do most of the work.  */
 
-static ffi_type *
-ffi_closure_helper_common (ffi_cif* cif,
-			   void (*fun)(ffi_cif*, void*, void**, void*),
-			   void *user_data, void *rvalue,
+ffi_type *
+ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
 			   unsigned long *pgr, ffi_dblfl *pfr)
 {
   /* rvalue is the pointer to space for return value in closure assembly
@@ -1200,12 +1134,14 @@
   void **          avalue;
   ffi_type **      arg_types;
   long             i, avn;
+  ffi_cif *        cif;
   ffi_dblfl *      end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
   unsigned         size_al;
 #if defined(POWERPC_DARWIN64)
   unsigned 	   fpsused = 0;
 #endif
 
+  cif = closure->cif;
   avalue = alloca (cif->nargs * sizeof(void *));
 
   if (cif->rtype->type == FFI_TYPE_STRUCT)
@@ -1272,7 +1208,7 @@
 	case FFI_TYPE_STRUCT:
 	  size_al = arg_types[i]->size;
 #if defined(POWERPC_DARWIN64)
-	  pgr = (unsigned long *)FFI_ALIGN((char *)pgr, arg_types[i]->alignment);
+	  pgr = (unsigned long *)ALIGN((char *)pgr, arg_types[i]->alignment);
 	  if (size_al < 3 || size_al == 4)
 	    {
 	      avalue[i] = ((char *)pgr)+8-size_al;
@@ -1297,7 +1233,7 @@
 	  /* If the first member of the struct is a double, then align
 	     the struct to double-word.  */
 	  if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
-	    size_al = FFI_ALIGN(arg_types[i]->size, 8);
+	    size_al = ALIGN(arg_types[i]->size, 8);
 #  if defined(POWERPC64)
 	  FFI_ASSERT (cif->abi != FFI_DARWIN);
 	  avalue[i] = pgr;
@@ -1416,25 +1352,8 @@
       i++;
     }
 
-  (fun) (cif, rvalue, avalue, user_data);
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
   /* Tell ffi_closure_ASM to perform return type promotions.  */
   return cif->rtype;
 }
-
-ffi_type *
-ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
-			   unsigned long *pgr, ffi_dblfl *pfr)
-{
-  return ffi_closure_helper_common (closure->cif, closure->fun,
-				    closure->user_data, rvalue, pgr, pfr);
-}
-
-ffi_type *
-ffi_go_closure_helper_DARWIN (ffi_go_closure *closure, void *rvalue,
-			      unsigned long *pgr, ffi_dblfl *pfr)
-{
-  return ffi_closure_helper_common (closure->cif, closure->fun,
-				    closure, rvalue, pgr, pfr);
-}
-
diff --git a/src/powerpc/ffi_linux64.c b/src/powerpc/ffi_linux64.c
index de0d033..b087af8 100644
--- a/src/powerpc/ffi_linux64.c
+++ b/src/powerpc/ffi_linux64.c
@@ -38,8 +38,7 @@
 /* About the LINUX64 ABI.  */
 enum {
   NUM_GPR_ARG_REGISTERS64 = 8,
-  NUM_FPR_ARG_REGISTERS64 = 13,
-  NUM_VEC_ARG_REGISTERS64 = 12,
+  NUM_FPR_ARG_REGISTERS64 = 13
 };
 enum { ASM_NEEDS_REGISTERS64 = 4 };
 
@@ -63,32 +62,12 @@
 #endif
 
 
+#if _CALL_ELF == 2
 static unsigned int
-discover_homogeneous_aggregate (ffi_abi abi,
-                                const ffi_type *t,
-                                unsigned int *elnum)
+discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum)
 {
   switch (t->type)
     {
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-    case FFI_TYPE_LONGDOUBLE:
-      /* 64-bit long doubles are equivalent to doubles. */
-      if ((abi & FFI_LINUX_LONG_DOUBLE_128) == 0)
-        {
-          *elnum = 1;
-          return FFI_TYPE_DOUBLE;
-        }
-      /* IBM extended precision values use unaligned pairs
-         of FPRs, but according to the ABI must be considered
-         distinct from doubles. They are also limited to a
-         maximum of four members in a homogeneous aggregate. */
-      else if ((abi & FFI_LINUX_LONG_DOUBLE_IEEE128) == 0)
-        {
-          *elnum = 2;
-          return FFI_TYPE_LONGDOUBLE;
-        }
-      /* Fall through. */
-#endif
     case FFI_TYPE_FLOAT:
     case FFI_TYPE_DOUBLE:
       *elnum = 1;
@@ -101,19 +80,14 @@
 	while (*el)
 	  {
 	    unsigned int el_elt, el_elnum = 0;
-	    el_elt = discover_homogeneous_aggregate (abi, *el, &el_elnum);
+	    el_elt = discover_homogeneous_aggregate (*el, &el_elnum);
 	    if (el_elt == 0
 		|| (base_elt && base_elt != el_elt))
 	      return 0;
 	    base_elt = el_elt;
 	    total_elnum += el_elnum;
-#if _CALL_ELF == 2
 	    if (total_elnum > 8)
 	      return 0;
-#else
-	    if (total_elnum > 1)
-	      return 0;
-#endif
 	    el++;
 	  }
 	*elnum = total_elnum;
@@ -124,6 +98,7 @@
       return 0;
     }
 }
+#endif
 
 
 /* Perform machine dependent cif processing */
@@ -132,23 +107,15 @@
 {
   ffi_type **ptr;
   unsigned bytes;
-  unsigned i, fparg_count = 0, intarg_count = 0, vecarg_count = 0;
+  unsigned i, fparg_count = 0, intarg_count = 0;
   unsigned flags = cif->flags;
-  unsigned elt, elnum, rtype;
+#if _CALL_ELF == 2
+  unsigned int elt, elnum;
+#endif
 
 #if FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE
-  /* If compiled without long double support... */
-  if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0 ||
-      (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
-    return FFI_BAD_ABI;
-#elif !defined(__VEC__)
-  /* If compiled without vector register support (used by assembly)... */
-  if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
-    return FFI_BAD_ABI;
-#else
-  /* If the IEEE128 flag is set, but long double is only 64 bits wide... */
-  if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) == 0 &&
-      (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
+  /* If compiled without long double support..  */
+  if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0)
     return FFI_BAD_ABI;
 #endif
 
@@ -170,19 +137,10 @@
 #endif
 
   /* Return value handling.  */
-  rtype = cif->rtype->type;
-#if _CALL_ELF == 2
-homogeneous:
-#endif
-  switch (rtype)
+  switch (cif->rtype->type)
     {
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
     case FFI_TYPE_LONGDOUBLE:
-      if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
-        {
-          flags |= FLAG_RETURNS_VEC;
-          break;
-        }
       if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0)
 	flags |= FLAG_RETURNS_128BITS;
       /* Fall through.  */
@@ -199,24 +157,24 @@
       /* Fall through.  */
     case FFI_TYPE_UINT64:
     case FFI_TYPE_SINT64:
-    case FFI_TYPE_POINTER:
       flags |= FLAG_RETURNS_64BITS;
       break;
 
     case FFI_TYPE_STRUCT:
 #if _CALL_ELF == 2
-      elt = discover_homogeneous_aggregate (cif->abi, cif->rtype, &elnum);
+      elt = discover_homogeneous_aggregate (cif->rtype, &elnum);
       if (elt)
-        {
-          flags |= FLAG_RETURNS_SMST;
-          rtype = elt;
-          goto homogeneous;
-        }
+	{
+	  if (elt == FFI_TYPE_DOUBLE)
+	    flags |= FLAG_RETURNS_64BITS;
+	  flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST;
+	  break;
+	}
       if (cif->rtype->size <= 16)
-        {
-          flags |= FLAG_RETURNS_SMST;
-          break;
-        }
+	{
+	  flags |= FLAG_RETURNS_SMST;
+	  break;
+	}
 #endif
       intarg_count++;
       flags |= FLAG_RETVAL_REFERENCE;
@@ -238,15 +196,6 @@
 	{
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 	case FFI_TYPE_LONGDOUBLE:
-          if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
-            {
-              vecarg_count++;
-              /* Align to 16 bytes, plus the 16-byte argument. */
-              intarg_count = (intarg_count + 3) & ~0x1;
-              if (vecarg_count > NUM_VEC_ARG_REGISTERS64)
-                flags |= FLAG_ARG_NEEDS_PSAVE;
-              break;
-            }
 	  if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0)
 	    {
 	      fparg_count++;
@@ -270,21 +219,11 @@
 		align = 16;
 	      align = align / 8;
 	      if (align > 1)
-		intarg_count = FFI_ALIGN (intarg_count, align);
+		intarg_count = ALIGN (intarg_count, align);
 	    }
 	  intarg_count += ((*ptr)->size + 7) / 8;
-	  elt = discover_homogeneous_aggregate (cif->abi, *ptr, &elnum);
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-          if (elt == FFI_TYPE_LONGDOUBLE &&
-              (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
-            {
-              vecarg_count += elnum;
-              if (vecarg_count > NUM_VEC_ARG_REGISTERS64)
-                flags |= FLAG_ARG_NEEDS_PSAVE;
-              break;
-            }
-	  else
-#endif
+#if _CALL_ELF == 2
+	  elt = discover_homogeneous_aggregate (*ptr, &elnum);
 	  if (elt)
 	    {
 	      fparg_count += elnum;
@@ -292,6 +231,7 @@
 		flags |= FLAG_ARG_NEEDS_PSAVE;
 	    }
 	  else
+#endif
 	    {
 	      if (intarg_count > NUM_GPR_ARG_REGISTERS64)
 		flags |= FLAG_ARG_NEEDS_PSAVE;
@@ -323,17 +263,10 @@
     flags |= FLAG_FP_ARGUMENTS;
   if (intarg_count > 4)
     flags |= FLAG_4_GPR_ARGUMENTS;
-  if (vecarg_count != 0)
-    flags |= FLAG_VEC_ARGUMENTS;
 
   /* Space for the FPR registers, if needed.  */
   if (fparg_count != 0)
     bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
-  /* Space for the vector registers, if needed, aligned to 16 bytes. */
-  if (vecarg_count != 0) {
-    bytes = (bytes + 15) & ~0xF;
-    bytes += NUM_VEC_ARG_REGISTERS64 * sizeof (float128);
-  }
 
   /* Stack space.  */
 #if _CALL_ELF == 2
@@ -416,8 +349,6 @@
    |--------------------------------------------| |
    |   FPR registers f1-f13 (optional)	13*8	| |
    |--------------------------------------------| |
-   |   VEC registers v2-v13 (optional)  12*16   | |
-   |--------------------------------------------| |
    |   Parameter save area		        | |
    |--------------------------------------------| |
    |   TOC save area			8	| |
@@ -447,7 +378,6 @@
     unsigned long *ul;
     float *f;
     double *d;
-    float128 *f128;
     size_t p;
   } valp;
 
@@ -461,16 +391,11 @@
   valp rest;
   valp next_arg;
 
-  /* 'fpr_base' points at the space for f1, and grows upwards as
+  /* 'fpr_base' points at the space for fpr3, and grows upwards as
      we use FPR registers.  */
   valp fpr_base;
   unsigned int fparg_count;
 
-  /* 'vec_base' points at the space for v2, and grows upwards as
-     we use vector registers.  */
-  valp vec_base;
-  unsigned int vecarg_count;
-
   unsigned int i, words, nargs, nfixedargs;
   ffi_type **ptr;
   double double_tmp;
@@ -487,7 +412,6 @@
     unsigned long **ul;
     float **f;
     double **d;
-    float128 **f128;
   } p_argv;
   unsigned long gprvalue;
   unsigned long align;
@@ -502,21 +426,11 @@
 #endif
   fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
   fparg_count = 0;
-  /* Place the vector args below the FPRs, if used, else the GPRs. */
-  if (ecif->cif->flags & FLAG_FP_ARGUMENTS)
-    vec_base.p = fpr_base.p & ~0xF;
-  else
-    vec_base.p = gpr_base.p;
-  vec_base.f128 -= NUM_VEC_ARG_REGISTERS64;
-  vecarg_count = 0;
   next_arg.ul = gpr_base.ul;
 
   /* Check that everything starts aligned properly.  */
   FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
   FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
-  FFI_ASSERT (((unsigned long) gpr_base.c & 0xF) == 0);
-  FFI_ASSERT (((unsigned long) gpr_end.c  & 0xF) == 0);
-  FFI_ASSERT (((unsigned long) vec_base.c & 0xF) == 0);
   FFI_ASSERT ((bytes & 0xF) == 0);
 
   /* Deal with return values that are actually pass-by-reference.  */
@@ -535,28 +449,14 @@
        i < nargs;
        i++, ptr++, p_argv.v++)
     {
+#if _CALL_ELF == 2
       unsigned int elt, elnum;
+#endif
 
       switch ((*ptr)->type)
 	{
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 	case FFI_TYPE_LONGDOUBLE:
-          if ((ecif->cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
-            {
-              next_arg.p = FFI_ALIGN (next_arg.p, 16);
-              if (next_arg.ul == gpr_end.ul)
-                next_arg.ul = rest.ul;
-              if (vecarg_count < NUM_VEC_ARG_REGISTERS64 && i < nfixedargs)
-                *vec_base.f128++ = **p_argv.f128;
-              else
-                *next_arg.f128 = **p_argv.f128;
-              if (++next_arg.f128 == gpr_end.f128)
-                next_arg.f128 = rest.f128;
-              vecarg_count++;
-              FFI_ASSERT (__LDBL_MANT_DIG__ == 113);
-              FFI_ASSERT (flags & FLAG_VEC_ARGUMENTS);
-              break;
-            }
 	  if ((ecif->cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0)
 	    {
 	      double_tmp = (*p_argv.d)[0];
@@ -594,9 +494,6 @@
 	  /* Fall through.  */
 #endif
 	case FFI_TYPE_DOUBLE:
-#if _CALL_ELF != 2
-	do_double:
-#endif
 	  double_tmp = **p_argv.d;
 	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
 	    {
@@ -615,32 +512,17 @@
 	  break;
 
 	case FFI_TYPE_FLOAT:
-#if _CALL_ELF != 2
-	do_float:
-#endif
 	  double_tmp = **p_argv.f;
 	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
 	    {
 	      *fpr_base.d++ = double_tmp;
 #if _CALL_ELF != 2
 	      if ((flags & FLAG_COMPAT) != 0)
-		{
-# ifndef __LITTLE_ENDIAN__
-		  next_arg.f[1] = (float) double_tmp;
-# else
-		  next_arg.f[0] = (float) double_tmp;
-# endif
-		}
+		*next_arg.f = (float) double_tmp;
 #endif
 	    }
 	  else
-	    {
-# ifndef __LITTLE_ENDIAN__
-	      next_arg.f[1] = (float) double_tmp;
-# else
-	      next_arg.f[0] = (float) double_tmp;
-# endif
-	    }
+	    *next_arg.f = (float) double_tmp;
 	  if (++next_arg.ul == gpr_end.ul)
 	    next_arg.ul = rest.ul;
 	  fparg_count++;
@@ -654,43 +536,19 @@
 	      if (align > 16)
 		align = 16;
 	      if (align > 1)
-                {
-                  next_arg.p = FFI_ALIGN (next_arg.p, align);
-                  if (next_arg.ul == gpr_end.ul)
-                    next_arg.ul = rest.ul;
-                }
+		next_arg.p = ALIGN (next_arg.p, align);
 	    }
-	  elt = discover_homogeneous_aggregate (ecif->cif->abi, *ptr, &elnum);
+#if _CALL_ELF == 2
+	  elt = discover_homogeneous_aggregate (*ptr, &elnum);
 	  if (elt)
 	    {
-#if _CALL_ELF == 2
 	      union {
 		void *v;
 		float *f;
 		double *d;
-		float128 *f128;
 	      } arg;
 
 	      arg.v = *p_argv.v;
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-              if (elt == FFI_TYPE_LONGDOUBLE &&
-                  (ecif->cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
-                {
-                  do
-                    {
-                      if (vecarg_count < NUM_VEC_ARG_REGISTERS64
-                          && i < nfixedargs)
-                        *vec_base.f128++ = *arg.f128++;
-                      else
-                        *next_arg.f128 = *arg.f128++;
-                      if (++next_arg.f128 == gpr_end.f128)
-                        next_arg.f128 = rest.f128;
-                      vecarg_count++;
-                    }
-                  while (--elnum != 0);
-                }
-              else
-#endif
 	      if (elt == FFI_TYPE_FLOAT)
 		{
 		  do
@@ -706,9 +564,11 @@
 		      fparg_count++;
 		    }
 		  while (--elnum != 0);
-		  if ((next_arg.p & 7) != 0)
-                    if (++next_arg.f == gpr_end.f)
-                      next_arg.f = rest.f;
+		  if ((next_arg.p & 3) != 0)
+		    {
+		      if (++next_arg.f == gpr_end.f)
+			next_arg.f = rest.f;
+		    }
 		}
 	      else
 		do
@@ -723,14 +583,9 @@
 		    fparg_count++;
 		  }
 		while (--elnum != 0);
-#else
-	      if (elt == FFI_TYPE_FLOAT)
-		goto do_float;
-	      else
-		goto do_double;
-#endif
 	    }
 	  else
+#endif
 	    {
 	      words = ((*ptr)->size + 7) / 8;
 	      if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
@@ -812,8 +667,7 @@
 }
 #endif
 
-
-ffi_status FFI_HIDDEN
+ffi_status
 ffi_prep_closure_loc_linux64 (ffi_closure *closure,
 			      ffi_cif *cif,
 			      void (*fun) (ffi_cif *, void *, void **, void *),
@@ -834,17 +688,17 @@
 				/* 2:	.quad	context		*/
   *(void **) &tramp[4] = (void *) ffi_closure_LINUX64;
   *(void **) &tramp[6] = codeloc;
-  flush_icache ((char *) tramp, (char *) codeloc, 4 * 4);
+  flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
 #else
   void **tramp = (void **) &closure->tramp[0];
 
   if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI)
     return FFI_BAD_ABI;
 
-  /* Copy function address and TOC from ffi_closure_LINUX64 OPD.  */
-  memcpy (&tramp[0], (void **) ffi_closure_LINUX64, sizeof (void *));
+  /* Copy function address and TOC from ffi_closure_LINUX64.  */
+  memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
+  tramp[2] = tramp[1];
   tramp[1] = codeloc;
-  memcpy (&tramp[2], (void **) ffi_closure_LINUX64 + 1, sizeof (void *));
 #endif
 
   closure->cif = cif;
@@ -856,27 +710,22 @@
 
 
 int FFI_HIDDEN
-ffi_closure_helper_LINUX64 (ffi_cif *cif,
-			    void (*fun) (ffi_cif *, void *, void **, void *),
-			    void *user_data,
-			    void *rvalue,
-			    unsigned long *pst,
-                            ffi_dblfl *pfr,
-                            float128 *pvec)
+ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
+			    unsigned long *pst, ffi_dblfl *pfr)
 {
   /* rvalue is the pointer to space for return value in closure assembly */
   /* pst is the pointer to parameter save area
      (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
   /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
-  /* pvec is the pointer to where v2-v13 are stored in ffi_closure_LINUX64 */
 
   void **avalue;
   ffi_type **arg_types;
   unsigned long i, avn, nfixedargs;
+  ffi_cif *cif;
   ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
-  float128 *end_pvec = pvec + NUM_VEC_ARG_REGISTERS64;
   unsigned long align;
 
+  cif = closure->cif;
   avalue = alloca (cif->nargs * sizeof (void *));
 
   /* Copy the caller's structure return value address so that the
@@ -942,18 +791,19 @@
 	      if (align > 16)
 		align = 16;
 	      if (align > 1)
-		pst = (unsigned long *) FFI_ALIGN ((size_t) pst, align);
+		pst = (unsigned long *) ALIGN ((size_t) pst, align);
 	    }
-	  elt = discover_homogeneous_aggregate (cif->abi, arg_types[i], &elnum);
+	  elt = 0;
+#if _CALL_ELF == 2
+	  elt = discover_homogeneous_aggregate (arg_types[i], &elnum);
+#endif
 	  if (elt)
 	    {
-#if _CALL_ELF == 2
 	      union {
 		void *v;
 		unsigned long *ul;
 		float *f;
 		double *d;
-		float128 *f128;
 		size_t p;
 	      } to, from;
 
@@ -961,17 +811,6 @@
 		 aggregate size is not greater than the space taken by
 		 the registers so store back to the register/parameter
 		 save arrays.  */
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-              if (elt == FFI_TYPE_LONGDOUBLE &&
-                  (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
-                {
-                  if (pvec + elnum <= end_pvec)
-                    to.v = pvec;
-                  else
-                    to.v = pst;
-                }
-              else
-#endif
 	      if (pfr + elnum <= end_pfr)
 		to.v = pfr;
 	      else
@@ -979,23 +818,6 @@
 
 	      avalue[i] = to.v;
 	      from.ul = pst;
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-              if (elt == FFI_TYPE_LONGDOUBLE &&
-                  (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
-                {
-                  do
-                    {
-                      if (pvec < end_pvec && i < nfixedargs)
-                        *to.f128 = *pvec++;
-                      else
-                        *to.f128 = *from.f128;
-                      to.f128++;
-                      from.f128++;
-                    }
-                  while (--elnum != 0);
-                }
-              else
-#endif
 	      if (elt == FFI_TYPE_FLOAT)
 		{
 		  do
@@ -1028,12 +850,6 @@
 		    }
 		  while (--elnum != 0);
 		}
-#else
-	      if (elt == FFI_TYPE_FLOAT)
-		goto do_float;
-	      else
-		goto do_double;
-#endif
 	    }
 	  else
 	    {
@@ -1051,18 +867,7 @@
 
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 	case FFI_TYPE_LONGDOUBLE:
-          if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)
-            {
-              if (((unsigned long) pst & 0xF) != 0)
-                ++pst;
-              if (pvec < end_pvec && i < nfixedargs)
-                avalue[i] = pvec++;
-              else
-                avalue[i] = pst;
-              pst += 2;
-              break;
-            }
-          else if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0)
+	  if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0)
 	    {
 	      if (pfr + 1 < end_pfr && i + 1 < nfixedargs)
 		{
@@ -1086,9 +891,6 @@
 	  /* Fall through.  */
 #endif
 	case FFI_TYPE_DOUBLE:
-#if _CALL_ELF != 2
-	do_double:
-#endif
 	  /* On the outgoing stack all values are aligned to 8 */
 	  /* there are 13 64bit floating point registers */
 
@@ -1103,9 +905,6 @@
 	  break;
 
 	case FFI_TYPE_FLOAT:
-#if _CALL_ELF != 2
-	do_float:
-#endif
 	  if (pfr < end_pfr && i < nfixedargs)
 	    {
 	      /* Float values are stored as doubles in the
@@ -1115,13 +914,7 @@
 	      pfr++;
 	    }
 	  else
-	    {
-#ifndef __LITTLE_ENDIAN__
-	      avalue[i] = (char *) pst + 4;
-#else
-	      avalue[i] = pst;
-#endif
-	    }
+	    avalue[i] = pst;
 	  pst++;
 	  break;
 
@@ -1132,22 +925,19 @@
       i++;
     }
 
-  (*fun) (cif, rvalue, avalue, user_data);
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
   /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
   if ((cif->flags & FLAG_RETURNS_SMST) != 0)
     {
-      if ((cif->flags & (FLAG_RETURNS_FP | FLAG_RETURNS_VEC)) == 0)
+      if ((cif->flags & FLAG_RETURNS_FP) == 0)
 	return FFI_V2_TYPE_SMALL_STRUCT + cif->rtype->size - 1;
-      else if ((cif->flags & FLAG_RETURNS_VEC) != 0)
-        return FFI_V2_TYPE_VECTOR_HOMOG;
       else if ((cif->flags & FLAG_RETURNS_64BITS) != 0)
 	return FFI_V2_TYPE_DOUBLE_HOMOG;
       else
 	return FFI_V2_TYPE_FLOAT_HOMOG;
     }
-  if ((cif->flags & FLAG_RETURNS_VEC) != 0)
-    return FFI_V2_TYPE_VECTOR;
   return cif->rtype->type;
 }
 #endif
diff --git a/src/powerpc/ffi_powerpc.h b/src/powerpc/ffi_powerpc.h
index 5ee2a70..2e61653 100644
--- a/src/powerpc/ffi_powerpc.h
+++ b/src/powerpc/ffi_powerpc.h
@@ -31,24 +31,22 @@
 enum {
   /* The assembly depends on these exact flags.  */
   /* These go in cr7 */
-  FLAG_RETURNS_SMST     = 1 << (31-31), /* Used for FFI_SYSV small structs.  */
+  FLAG_RETURNS_SMST	= 1 << (31-31), /* Used for FFI_SYSV small structs.  */
   FLAG_RETURNS_NOTHING  = 1 << (31-30),
   FLAG_RETURNS_FP       = 1 << (31-29),
-  FLAG_RETURNS_VEC      = 1 << (31-28),
+  FLAG_RETURNS_64BITS   = 1 << (31-28),
 
-  /* These go in cr6 */
-  FLAG_RETURNS_64BITS   = 1 << (31-27),
-  FLAG_RETURNS_128BITS  = 1 << (31-26),
+  /* This goes in cr6 */
+  FLAG_RETURNS_128BITS  = 1 << (31-27),
 
-  FLAG_COMPAT           = 1 << (31- 8), /* Not used by assembly */
+  FLAG_COMPAT		= 1 << (31- 8), /* Not used by assembly */
 
   /* These go in cr1 */
   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7), /* Used by sysv code */
   FLAG_ARG_NEEDS_PSAVE  = FLAG_ARG_NEEDS_COPY, /* Used by linux64 code */
   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
   FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
-  FLAG_RETVAL_REFERENCE = 1 << (31- 4),
-  FLAG_VEC_ARGUMENTS    = 1 << (31- 3),
+  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
 };
 
 typedef union
@@ -57,49 +55,23 @@
   double d;
 } ffi_dblfl;
 
-#if defined(__FLOAT128_TYPE__)
-typedef _Float128 float128;
-#elif defined(__FLOAT128__)
-typedef __float128 float128;
-#else
-typedef __int128 float128;
-#endif
-
 void FFI_HIDDEN ffi_closure_SYSV (void);
-void FFI_HIDDEN ffi_go_closure_sysv (void);
-void FFI_HIDDEN ffi_call_SYSV(extended_cif *, void (*)(void), void *,
-			      unsigned, void *, int);
+void FFI_HIDDEN ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
+			      void (*)(void));
 
 void FFI_HIDDEN ffi_prep_types_sysv (ffi_abi);
 ffi_status FFI_HIDDEN ffi_prep_cif_sysv (ffi_cif *);
-ffi_status FFI_HIDDEN ffi_prep_closure_loc_sysv (ffi_closure *,
-						 ffi_cif *,
-						 void (*) (ffi_cif *, void *,
-							   void **, void *),
-						 void *, void *);
-int FFI_HIDDEN ffi_closure_helper_SYSV (ffi_cif *,
-					void (*) (ffi_cif *, void *,
-						  void **, void *),
-					void *, void *, unsigned long *,
+int FFI_HIDDEN ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
 					ffi_dblfl *, unsigned long *);
 
-void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, void (*) (void), void *,
-				 unsigned long, void *, long);
+void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long, unsigned long,
+				 unsigned long *, void (*)(void));
 void FFI_HIDDEN ffi_closure_LINUX64 (void);
-void FFI_HIDDEN ffi_go_closure_linux64 (void);
 
 void FFI_HIDDEN ffi_prep_types_linux64 (ffi_abi);
 ffi_status FFI_HIDDEN ffi_prep_cif_linux64 (ffi_cif *);
 ffi_status FFI_HIDDEN ffi_prep_cif_linux64_var (ffi_cif *, unsigned int,
 						unsigned int);
 void FFI_HIDDEN ffi_prep_args64 (extended_cif *, unsigned long *const);
-ffi_status FFI_HIDDEN ffi_prep_closure_loc_linux64 (ffi_closure *, ffi_cif *,
-						    void (*) (ffi_cif *, void *,
-							      void **, void *),
-						    void *, void *);
-int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_cif *,
-					   void (*) (ffi_cif *, void *,
-						     void **, void *),
-					   void *, void *,
-					   unsigned long *, ffi_dblfl *,
-					   float128 *);
+int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
+					   unsigned long *, ffi_dblfl *);
diff --git a/src/powerpc/ffi_sysv.c b/src/powerpc/ffi_sysv.c
index 4078e75..fbe85fe 100644
--- a/src/powerpc/ffi_sysv.c
+++ b/src/powerpc/ffi_sysv.c
@@ -36,7 +36,7 @@
 
 
 /* About the SYSV ABI.  */
-#define ASM_NEEDS_REGISTERS 6
+#define ASM_NEEDS_REGISTERS 4
 #define NUM_GPR_ARG_REGISTERS 8
 #define NUM_FPR_ARG_REGISTERS 8
 
@@ -93,7 +93,7 @@
 {
   ffi_type **ptr;
   unsigned bytes;
-  unsigned i, fpr_count = 0, gpr_count = 0, stack_count = 0;
+  unsigned i, fparg_count = 0, intarg_count = 0;
   unsigned flags = cif->flags;
   unsigned struct_copy_size = 0;
   unsigned type = cif->rtype->type;
@@ -155,7 +155,7 @@
 	  flags |= FLAG_RETURNS_SMST;
 	  break;
 	}
-      gpr_count++;
+      intarg_count++;
       flags |= FLAG_RETVAL_REFERENCE;
       /* Fall through.  */
     case FFI_TYPE_VOID:
@@ -182,41 +182,24 @@
 	{
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 	case FFI_TYPE_LONGDOUBLE:
-	  if (fpr_count >= NUM_FPR_ARG_REGISTERS - 1)
-	    {
-	      fpr_count = NUM_FPR_ARG_REGISTERS;
-	      /* 8-byte align long doubles.  */
-	      stack_count += stack_count & 1;
-	      stack_count += 4;
-	    }
-	  else
-	    fpr_count += 2;
-#ifdef __NO_FPRS__
-	  return FFI_BAD_ABI;
+	  fparg_count++;
+	  /* Fall thru */
 #endif
-	  break;
-#endif
-
 	case FFI_TYPE_DOUBLE:
-	  if (fpr_count >= NUM_FPR_ARG_REGISTERS)
-	    {
-	      /* 8-byte align doubles.  */
-	      stack_count += stack_count & 1;
-	      stack_count += 2;
-	    }
-	  else
-	    fpr_count += 1;
+	  fparg_count++;
+	  /* If this FP arg is going on the stack, it must be
+	     8-byte-aligned.  */
+	  if (fparg_count > NUM_FPR_ARG_REGISTERS
+	      && intarg_count >= NUM_GPR_ARG_REGISTERS
+	      && intarg_count % 2 != 0)
+	    intarg_count++;
 #ifdef __NO_FPRS__
 	  return FFI_BAD_ABI;
 #endif
 	  break;
 
 	case FFI_TYPE_FLOAT:
-	  if (fpr_count >= NUM_FPR_ARG_REGISTERS)
-	    /* Yes, we don't follow the ABI, but neither does gcc.  */
-	    stack_count += 1;
-	  else
-	    fpr_count += 1;
+	  fparg_count++;
 #ifdef __NO_FPRS__
 	  return FFI_BAD_ABI;
 #endif
@@ -225,13 +208,11 @@
 	case FFI_TYPE_UINT128:
 	  /* A long double in FFI_LINUX_SOFT_FLOAT can use only a set
 	     of four consecutive gprs. If we do not have enough, we
-	     have to adjust the gpr_count value.  */
-	  if (gpr_count >= NUM_GPR_ARG_REGISTERS - 3)
-	    gpr_count = NUM_GPR_ARG_REGISTERS;
-	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)
-	    stack_count += 4;
-	  else
-	    gpr_count += 4;
+	     have to adjust the intarg_count value.  */
+	  if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
+	      && intarg_count < NUM_GPR_ARG_REGISTERS)
+	    intarg_count = NUM_GPR_ARG_REGISTERS;
+	  intarg_count += 4;
 	  break;
 
 	case FFI_TYPE_UINT64:
@@ -244,14 +225,10 @@
 	     Also, only certain register pairs can be used for
 	     passing long long int -- specifically (r3,r4), (r5,r6),
 	     (r7,r8), (r9,r10).  */
-	  gpr_count += gpr_count & 1;
-	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)
-	    {
-	      stack_count += stack_count & 1;
-	      stack_count += 2;
-	    }
-	  else
-	    gpr_count += 2;
+	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1
+	      || intarg_count % 2 != 0)
+	    intarg_count++;
+	  intarg_count += 2;
 	  break;
 
 	case FFI_TYPE_STRUCT:
@@ -272,10 +249,7 @@
 	case FFI_TYPE_SINT8:
 	  /* Everything else is passed as a 4-byte word in a GPR, either
 	     the object itself or a pointer to it.  */
-	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)
-	    stack_count += 1;
-	  else
-	    gpr_count += 1;
+	  intarg_count++;
 	  break;
 
 	default:
@@ -283,19 +257,22 @@
 	}
     }
 
-  if (fpr_count != 0)
+  if (fparg_count != 0)
     flags |= FLAG_FP_ARGUMENTS;
-  if (gpr_count > 4)
+  if (intarg_count > 4)
     flags |= FLAG_4_GPR_ARGUMENTS;
   if (struct_copy_size != 0)
     flags |= FLAG_ARG_NEEDS_COPY;
 
   /* Space for the FPR registers, if needed.  */
-  if (fpr_count != 0)
+  if (fparg_count != 0)
     bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
 
   /* Stack space.  */
-  bytes += stack_count * sizeof (int);
+  if (intarg_count > NUM_GPR_ARG_REGISTERS)
+    bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
+  if (fparg_count > NUM_FPR_ARG_REGISTERS)
+    bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
 
   /* The stack space allocated needs to be a multiple of 16 bytes.  */
   bytes = (bytes + 15) & ~0xF;
@@ -390,13 +367,13 @@
   /* 'gpr_base' points at the space for gpr3, and grows upwards as
      we use GPR registers.  */
   valp gpr_base;
-  valp gpr_end;
+  int intarg_count;
 
 #ifndef __NO_FPRS__
   /* 'fpr_base' points at the space for fpr1, and grows upwards as
      we use FPR registers.  */
   valp fpr_base;
-  valp fpr_end;
+  int fparg_count;
 #endif
 
   /* 'copy_space' grows down as we put structures in it.  It should
@@ -428,11 +405,11 @@
   unsigned gprvalue;
 
   stacktop.c = (char *) stack + bytes;
-  gpr_end.u = stacktop.u - ASM_NEEDS_REGISTERS;
-  gpr_base.u = gpr_end.u - NUM_GPR_ARG_REGISTERS;
+  gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
+  intarg_count = 0;
 #ifndef __NO_FPRS__
-  fpr_end.d = gpr_base.d;
-  fpr_base.d = fpr_end.d - NUM_FPR_ARG_REGISTERS;
+  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
+  fparg_count = 0;
   copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
 #else
   copy_space.c = gpr_base.c;
@@ -448,7 +425,10 @@
 
   /* Deal with return values that are actually pass-by-reference.  */
   if (flags & FLAG_RETVAL_REFERENCE)
-    *gpr_base.u++ = (unsigned) (char *) ecif->rvalue;
+    {
+      *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
+      intarg_count++;
+    }
 
   /* Now for the arguments.  */
   p_argv.v = ecif->avalue;
@@ -468,11 +448,14 @@
 	case FFI_TYPE_LONGDOUBLE:
 	  double_tmp = (*p_argv.d)[0];
 
-	  if (fpr_base.d >= fpr_end.d - 1)
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
 	    {
-	      fpr_base.d = fpr_end.d;
-	      if (((next_arg.u - stack) & 1) != 0)
-		next_arg.u += 1;
+	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
+		  && intarg_count % 2 != 0)
+		{
+		  intarg_count++;
+		  next_arg.u++;
+		}
 	      *next_arg.d = double_tmp;
 	      next_arg.u += 2;
 	      double_tmp = (*p_argv.d)[1];
@@ -485,33 +468,42 @@
 	      double_tmp = (*p_argv.d)[1];
 	      *fpr_base.d++ = double_tmp;
 	    }
+
+	  fparg_count += 2;
 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
 	  break;
 # endif
 	case FFI_TYPE_DOUBLE:
 	  double_tmp = **p_argv.d;
 
-	  if (fpr_base.d >= fpr_end.d)
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
 	    {
-	      if (((next_arg.u - stack) & 1) != 0)
-		next_arg.u += 1;
+	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
+		  && intarg_count % 2 != 0)
+		{
+		  intarg_count++;
+		  next_arg.u++;
+		}
 	      *next_arg.d = double_tmp;
 	      next_arg.u += 2;
 	    }
 	  else
 	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
 	  break;
 
 	case FFI_TYPE_FLOAT:
 	  double_tmp = **p_argv.f;
-	  if (fpr_base.d >= fpr_end.d)
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
 	    {
 	      *next_arg.f = (float) double_tmp;
 	      next_arg.u += 1;
+	      intarg_count++;
 	    }
 	  else
 	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
 	  break;
 #endif /* have FPRs */
@@ -521,34 +513,42 @@
 	     is passed in four consecutive GPRs if available.  A maximum of 2
 	     long doubles can be passed in gprs.  If we do not have 4 GPRs
 	     left, the long double is passed on the stack, 4-byte aligned.  */
-	  if (gpr_base.u >= gpr_end.u - 3)
-	    {
-	      unsigned int ii;
-	      gpr_base.u = gpr_end.u;
-	      for (ii = 0; ii < 4; ii++)
-		{
-		  unsigned int int_tmp = (*p_argv.ui)[ii];
-		  *next_arg.u++ = int_tmp;
-		}
-	    }
-	  else
-	    {
-	      unsigned int ii;
-	      for (ii = 0; ii < 4; ii++)
-		{
-		  unsigned int int_tmp = (*p_argv.ui)[ii];
-		  *gpr_base.u++ = int_tmp;
-		}
-	    }
-	  break;
+	  {
+	    unsigned int int_tmp;
+	    unsigned int ii;
+	    if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
+	      {
+		if (intarg_count < NUM_GPR_ARG_REGISTERS)
+		  intarg_count = NUM_GPR_ARG_REGISTERS;
+		for (ii = 0; ii < 4; ii++)
+		  {
+		    int_tmp = (*p_argv.ui)[ii];
+		    *next_arg.u++ = int_tmp;
+		  }
+	      }
+	    else
+	      {
+		for (ii = 0; ii < 4; ii++)
+		  {
+		    int_tmp = (*p_argv.ui)[ii];
+		    *gpr_base.u++ = int_tmp;
+		  }
+	      }
+	    intarg_count += 4;
+	    break;
+	  }
 
 	case FFI_TYPE_UINT64:
 	case FFI_TYPE_SINT64:
-	  if (gpr_base.u >= gpr_end.u - 1)
+	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
+	    intarg_count++;
+	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
 	    {
-	      gpr_base.u = gpr_end.u;
-	      if (((next_arg.u - stack) & 1) != 0)
-		next_arg.u++;
+	      if (intarg_count % 2 != 0)
+		{
+		  intarg_count++;
+		  next_arg.u++;
+		}
 	      *next_arg.ll = **p_argv.ll;
 	      next_arg.u += 2;
 	    }
@@ -559,10 +559,14 @@
 		 (r5,r6), (r7,r8), (r9,r10).  If next arg is long long
 		 but not correct starting register of pair then skip
 		 until the proper starting register.  */
-	      if (((gpr_end.u - gpr_base.u) & 1) != 0)
-		gpr_base.u++;
+	      if (intarg_count % 2 != 0)
+		{
+		  intarg_count ++;
+		  gpr_base.u++;
+		}
 	      *gpr_base.ll++ = **p_argv.ll;
 	    }
+	  intarg_count += 2;
 	  break;
 
 	case FFI_TYPE_STRUCT:
@@ -597,22 +601,29 @@
 	  gprvalue = **p_argv.ui;
 
 	putgpr:
-	  if (gpr_base.u >= gpr_end.u)
+	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
 	    *next_arg.u++ = gprvalue;
 	  else
 	    *gpr_base.u++ = gprvalue;
+	  intarg_count++;
 	  break;
 	}
     }
 
   /* Check that we didn't overrun the stack...  */
   FFI_ASSERT (copy_space.c >= next_arg.c);
-  FFI_ASSERT (gpr_base.u <= gpr_end.u);
+  FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
+  /* The assert below is testing that the number of integer arguments agrees
+     with the number found in ffi_prep_cif_machdep().  However, intarg_count
+     is incremented whenever we place an FP arg on the stack, so account for
+     that before our assert test.  */
 #ifndef __NO_FPRS__
-  FFI_ASSERT (fpr_base.u <= fpr_end.u);
+  if (fparg_count > NUM_FPR_ARG_REGISTERS)
+    intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS;
+  FFI_ASSERT (fpr_base.u
+	      <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
 #endif
-  FFI_ASSERT (((flags & FLAG_4_GPR_ARGUMENTS) != 0)
-	      == (gpr_end.u - gpr_base.u < 4));
+  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
 }
 
 #define MIN_CACHE_LINE_SIZE 8
@@ -643,18 +654,18 @@
 
   tramp = (unsigned int *) &closure->tramp[0];
   tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
-  tramp[1] = 0x429f0005;  /*   bcl     20,31,.+4 */
-  tramp[2] = 0x7d6802a6;  /*   mflr    r11 */
-  tramp[3] = 0x7c0803a6;  /*   mtlr    r0 */
-  tramp[4] = 0x800b0018;  /*   lwz     r0,24(r11) */
-  tramp[5] = 0x816b001c;  /*   lwz     r11,28(r11) */
-  tramp[6] = 0x7c0903a6;  /*   mtctr   r0 */
-  tramp[7] = 0x4e800420;  /*   bctr */
-  *(void **) &tramp[8] = (void *) ffi_closure_SYSV; /* function */
-  *(void **) &tramp[9] = codeloc;                   /* context */
+  tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
+  tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
+  tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
+  tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
+  tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
+  tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
+  tramp[9] = 0x4e800420;  /*   bctr */
+  *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
+  *(void **) &tramp[3] = codeloc;                   /* context */
 
   /* Flush the icache.  */
-  flush_icache ((char *)tramp, (char *)codeloc, 8 * 4);
+  flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
 
   closure->cif = cif;
   closure->fun = fun;
@@ -671,12 +682,8 @@
    following helper function to do most of the work.  */
 
 int
-ffi_closure_helper_SYSV (ffi_cif *cif,
-			 void (*fun) (ffi_cif *, void *, void **, void *),
-			 void *user_data,
-			 void *rvalue,
-			 unsigned long *pgr,
-			 ffi_dblfl *pfr,
+ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
+			 unsigned long *pgr, ffi_dblfl *pfr,
 			 unsigned long *pst)
 {
   /* rvalue is the pointer to space for return value in closure assembly */
@@ -692,6 +699,7 @@
 #endif
   long             ng = 0;   /* number of general registers already used */
 
+  ffi_cif *cif = closure->cif;
   unsigned       size     = cif->rtype->size;
   unsigned short rtypenum = cif->rtype->type;
 
@@ -907,7 +915,7 @@
     i++;
   }
 
-  (*fun) (cif, rvalue, avalue, user_data);
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
   /* Tell ffi_closure_SYSV how to perform return type promotions.
      Because the FFI_SYSV ABI returns the structures <= 8 bytes in
diff --git a/src/powerpc/ffitarget.h b/src/powerpc/ffitarget.h
index 7fb9a93..b47b0f5 100644
--- a/src/powerpc/ffitarget.h
+++ b/src/powerpc/ffitarget.h
@@ -91,19 +91,15 @@
   /* This and following bits can reuse FFI_COMPAT values.  */
   FFI_LINUX_STRUCT_ALIGN = 1,
   FFI_LINUX_LONG_DOUBLE_128 = 2,
-  FFI_LINUX_LONG_DOUBLE_IEEE128 = 4,
   FFI_DEFAULT_ABI = (FFI_LINUX
 #  ifdef __STRUCT_PARM_ALIGN__
 		     | FFI_LINUX_STRUCT_ALIGN
 #  endif
 #  ifdef __LONG_DOUBLE_128__
 		     | FFI_LINUX_LONG_DOUBLE_128
-#   ifdef __LONG_DOUBLE_IEEE128__
-		     | FFI_LINUX_LONG_DOUBLE_IEEE128
-#   endif
 #  endif
 		     ),
-  FFI_LAST_ABI = 16
+  FFI_LAST_ABI = 12
 
 # else
   /* This bit, always set in new code, must not be set in any of the
@@ -142,40 +138,23 @@
 #define FFI_CLOSURES 1
 #define FFI_NATIVE_RAW_API 0
 #if defined (POWERPC) || defined (POWERPC_FREEBSD)
-# define FFI_GO_CLOSURES 1
 # define FFI_TARGET_SPECIFIC_VARIADIC 1
 # define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
 #endif
-#if defined (POWERPC_AIX)
-# define FFI_GO_CLOSURES 1
-#endif
 
-/* ppc_closure.S and linux64_closure.S expect this.  */
-#define FFI_PPC_TYPE_LAST FFI_TYPE_POINTER
-
-/* We define additional types below.  If generic types are added that
-   must be supported by powerpc libffi then it is likely that
-   FFI_PPC_TYPE_LAST needs increasing *and* the jump tables in
-   ppc_closure.S and linux64_closure.S be extended.  */
-
-#if !(FFI_TYPE_LAST == FFI_PPC_TYPE_LAST		\
-      || (FFI_TYPE_LAST == FFI_TYPE_COMPLEX		\
-	  && !defined FFI_TARGET_HAS_COMPLEX_TYPE))
-# error "You likely have a broken powerpc libffi"
-#endif
+/* For additional types like the below, take care about the order in
+   ppc_closures.S. They must follow after the FFI_TYPE_LAST.  */
 
 /* Needed for soft-float long-double-128 support.  */
-#define FFI_TYPE_UINT128 (FFI_PPC_TYPE_LAST + 1)
+#define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1)
 
 /* Needed for FFI_SYSV small structure returns.  */
-#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 2)
+#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
 
 /* Used by ELFv2 for homogenous structure returns.  */
-#define FFI_V2_TYPE_VECTOR		(FFI_PPC_TYPE_LAST + 1)
-#define FFI_V2_TYPE_VECTOR_HOMOG	(FFI_PPC_TYPE_LAST + 2)
-#define FFI_V2_TYPE_FLOAT_HOMOG		(FFI_PPC_TYPE_LAST + 3)
-#define FFI_V2_TYPE_DOUBLE_HOMOG	(FFI_PPC_TYPE_LAST + 4)
-#define FFI_V2_TYPE_SMALL_STRUCT	(FFI_PPC_TYPE_LAST + 5)
+#define FFI_V2_TYPE_FLOAT_HOMOG		(FFI_TYPE_LAST + 1)
+#define FFI_V2_TYPE_DOUBLE_HOMOG	(FFI_TYPE_LAST + 2)
+#define FFI_V2_TYPE_SMALL_STRUCT	(FFI_TYPE_LAST + 3)
 
 #if _CALL_ELF == 2
 # define FFI_TRAMPOLINE_SIZE 32
diff --git a/src/powerpc/linux64.S b/src/powerpc/linux64.S
index c99889c..d2acb70 100644
--- a/src/powerpc/linux64.S
+++ b/src/powerpc/linux64.S
@@ -32,9 +32,8 @@
 #ifdef POWERPC64
 	.hidden	ffi_call_LINUX64
 	.globl	ffi_call_LINUX64
-	.text
-	.cfi_startproc
 # if _CALL_ELF == 2
+	.text
 ffi_call_LINUX64:
 	addis	%r2, %r12, .TOC.-ffi_call_LINUX64@ha
 	addi	%r2, %r2, .TOC.-ffi_call_LINUX64@l
@@ -58,26 +57,20 @@
 .ffi_call_LINUX64:
 #  endif
 # endif
+.LFB1:
 	mflr	%r0
 	std	%r28, -32(%r1)
 	std	%r29, -24(%r1)
 	std	%r30, -16(%r1)
 	std	%r31, -8(%r1)
-	std	%r7, 8(%r1)	/* closure, saved in cr field.  */
 	std	%r0, 16(%r1)
 
 	mr	%r28, %r1	/* our AP.  */
-	.cfi_def_cfa_register 28
-	.cfi_offset 65, 16
-	.cfi_offset 31, -8
-	.cfi_offset 30, -16
-	.cfi_offset 29, -24
-	.cfi_offset 28, -32
-
-	stdux	%r1, %r1, %r8
-	mr	%r31, %r6	/* flags, */
-	mr	%r30, %r5	/* rvalue, */
-	mr	%r29, %r4	/* function address.  */
+.LCFI0:
+	stdux	%r1, %r1, %r4
+	mr	%r31, %r5	/* flags, */
+	mr	%r30, %r6	/* rvalue, */
+	mr	%r29, %r7	/* function address.  */
 /* Save toc pointer, not for the ffi_prep_args64 call, but for the later
    bctrl function call.  */
 # if _CALL_ELF == 2
@@ -99,74 +92,44 @@
 # else
 	ld	%r12, 0(%r29)
 	ld	%r2, 8(%r29)
+	ld	%r11, 16(%r29)
 # endif
 	/* Now do the call.  */
-	/* Set up cr1 with bits 3-7 of the flags.  */
-	mtcrf	0xc0, %r31
+	/* Set up cr1 with bits 4-7 of the flags.  */
+	mtcrf	0x40, %r31
 
 	/* Get the address to call into CTR.  */
 	mtctr	%r12
 	/* Load all those argument registers.  */
-	addi	%r29, %r28, -32-(8*8)
-	ld	%r3,  (0*8)(%r29)
-	ld	%r4,  (1*8)(%r29)
-	ld	%r5,  (2*8)(%r29)
-	ld	%r6,  (3*8)(%r29)
+	ld	%r3, -32-(8*8)(%r28)
+	ld	%r4, -32-(7*8)(%r28)
+	ld	%r5, -32-(6*8)(%r28)
+	ld	%r6, -32-(5*8)(%r28)
 	bf-	5, 1f
-	ld	%r7,  (4*8)(%r29)
-	ld	%r8,  (5*8)(%r29)
-	ld	%r9,  (6*8)(%r29)
-	ld	%r10, (7*8)(%r29)
+	ld	%r7, -32-(4*8)(%r28)
+	ld	%r8, -32-(3*8)(%r28)
+	ld	%r9, -32-(2*8)(%r28)
+	ld	%r10, -32-(1*8)(%r28)
 1:
 
 	/* Load all the FP registers.  */
 	bf-	6, 2f
-	addi	%r29, %r29, -(14*8)
-	lfd	%f1,  ( 1*8)(%r29)
-	lfd	%f2,  ( 2*8)(%r29)
-	lfd	%f3,  ( 3*8)(%r29)
-	lfd	%f4,  ( 4*8)(%r29)
-	lfd	%f5,  ( 5*8)(%r29)
-	lfd	%f6,  ( 6*8)(%r29)
-	lfd	%f7,  ( 7*8)(%r29)
-	lfd	%f8,  ( 8*8)(%r29)
-	lfd	%f9,  ( 9*8)(%r29)
-	lfd	%f10, (10*8)(%r29)
-	lfd	%f11, (11*8)(%r29)
-	lfd	%f12, (12*8)(%r29)
-	lfd	%f13, (13*8)(%r29)
+	lfd	%f1, -32-(21*8)(%r28)
+	lfd	%f2, -32-(20*8)(%r28)
+	lfd	%f3, -32-(19*8)(%r28)
+	lfd	%f4, -32-(18*8)(%r28)
+	lfd	%f5, -32-(17*8)(%r28)
+	lfd	%f6, -32-(16*8)(%r28)
+	lfd	%f7, -32-(15*8)(%r28)
+	lfd	%f8, -32-(14*8)(%r28)
+	lfd	%f9, -32-(13*8)(%r28)
+	lfd	%f10, -32-(12*8)(%r28)
+	lfd	%f11, -32-(11*8)(%r28)
+	lfd	%f12, -32-(10*8)(%r28)
+	lfd	%f13, -32-(9*8)(%r28)
 2:
 
-	/* Load all the vector registers.  */
-	bf-	3, 3f
-	addi	%r29, %r29, -16
-	lvx	%v13, 0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v12, 0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v11, 0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v10, 0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v9,  0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v8,  0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v7,  0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v6,  0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v5,  0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v4,  0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v3,  0, %r29
-	addi	%r29, %r29, -16
-	lvx	%v2,  0, %r29
-3:
-
 	/* Make the call.  */
-	ld	%r11, 8(%r28)
 	bctrl
 
 	/* This must follow the call immediately, the unwinder
@@ -182,14 +145,12 @@
 	bt	31, .Lstruct_return_value
 	bt	30, .Ldone_return_value
 	bt	29, .Lfp_return_value
-	bt	28, .Lvec_return_value
 	std	%r3, 0(%r30)
 	/* Fall through...  */
 
 .Ldone_return_value:
 	/* Restore the registers we used and return.  */
 	mr	%r1, %r28
-	.cfi_def_cfa_register 1
 	ld	%r0, 16(%r28)
 	ld	%r28, -32(%r28)
 	mtlr	%r0
@@ -198,16 +159,11 @@
 	ld	%r31, -8(%r1)
 	blr
 
-.Lvec_return_value:
-	stvx	%v2, 0, %r30
-	b	.Ldone_return_value
-
 .Lfp_return_value:
-	.cfi_def_cfa_register 28
-	mtcrf	0x02, %r31 /* cr6  */
-	bf	27, .Lfloat_return_value
+	bf	28, .Lfloat_return_value
 	stfd	%f1, 0(%r30)
-	bf	26, .Ldone_return_value
+	mtcrf	0x02, %r31 /* cr6  */
+	bf	27, .Ldone_return_value
 	stfd	%f2, 8(%r30)
 	b	.Ldone_return_value
 .Lfloat_return_value:
@@ -215,9 +171,8 @@
 	b	.Ldone_return_value
 
 .Lstruct_return_value:
-	bf	29, .Lvec_homog_or_small_struct
-	mtcrf	0x02, %r31 /* cr6  */
-	bf	27, .Lfloat_homog_return_value
+	bf	29, .Lsmall_struct
+	bf	28, .Lfloat_homog_return_value
 	stfd	%f1, 0(%r30)
 	stfd	%f2, 8(%r30)
 	stfd	%f3, 16(%r30)
@@ -239,43 +194,66 @@
 	stfs	%f8, 28(%r30)
 	b	.Ldone_return_value
 
-.Lvec_homog_or_small_struct:
-	bf	28, .Lsmall_struct
-	stvx	%v2, 0, %r30
-	addi	%r30, %r30, 16
-	stvx	%v3, 0, %r30
-	addi	%r30, %r30, 16
-	stvx	%v4, 0, %r30
-	addi	%r30, %r30, 16
-	stvx	%v5, 0, %r30
-	addi	%r30, %r30, 16
-	stvx	%v6, 0, %r30
-	addi	%r30, %r30, 16
-	stvx	%v7, 0, %r30
-	addi	%r30, %r30, 16
-	stvx	%v8, 0, %r30
-	addi	%r30, %r30, 16
-	stvx	%v9, 0, %r30
-	b	.Ldone_return_value
-
 .Lsmall_struct:
 	std	%r3, 0(%r30)
 	std	%r4, 8(%r30)
 	b	.Ldone_return_value
 
-	.cfi_endproc
+.LFE1:
+	.long	0
+	.byte	0,12,0,1,128,4,0,0
 # if _CALL_ELF == 2
 	.size	ffi_call_LINUX64,.-ffi_call_LINUX64
 # else
 #  ifdef _CALL_LINUX
 	.size	ffi_call_LINUX64,.-.L.ffi_call_LINUX64
 #  else
-	.long	0
-	.byte	0,12,0,1,128,4,0,0
 	.size	.ffi_call_LINUX64,.-.ffi_call_LINUX64
 #  endif
 # endif
 
+	.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	0x41	 # CIE RA Column
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x14	 # FDE Encoding (pcrel udata8)
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1
+	.uleb128 0x0
+	.align 3
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	 # FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
+	.8byte	.LFB1-.	 # FDE initial location
+	.8byte	.LFE1-.LFB1	 # FDE address range
+	.uleb128 0x0	 # Augmentation size
+	.byte	0x2	 # DW_CFA_advance_loc1
+	.byte	.LCFI0-.LFB1
+	.byte	0xd	 # DW_CFA_def_cfa_register
+	.uleb128 0x1c
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x41
+	.sleb128 -2
+	.byte	0x9f	 # DW_CFA_offset, column 0x1f
+	.uleb128 0x1
+	.byte	0x9e	 # DW_CFA_offset, column 0x1e
+	.uleb128 0x2
+	.byte	0x9d	 # DW_CFA_offset, column 0x1d
+	.uleb128 0x3
+	.byte	0x9c	 # DW_CFA_offset, column 0x1c
+	.uleb128 0x4
+	.align 3
+.LEFDE1:
+
 #endif
 
 #if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2
diff --git a/src/powerpc/linux64_closure.S b/src/powerpc/linux64_closure.S
index d67e4bb..97421a4 100644
--- a/src/powerpc/linux64_closure.S
+++ b/src/powerpc/linux64_closure.S
@@ -33,9 +33,8 @@
 #ifdef POWERPC64
 	FFI_HIDDEN (ffi_closure_LINUX64)
 	.globl  ffi_closure_LINUX64
-	.text
-	.cfi_startproc
 # if _CALL_ELF == 2
+	.text
 ffi_closure_LINUX64:
 	addis	%r2, %r12, .TOC.-ffi_closure_LINUX64@ha
 	addi	%r2, %r2, .TOC.-ffi_closure_LINUX64@l
@@ -61,15 +60,9 @@
 # endif
 
 # if _CALL_ELF == 2
-#  ifdef __VEC__
-#   32 byte special reg save area + 64 byte parm save area
-#   + 128 byte retval area + 13*8 fpr save area + 12*16 vec save area + round to 16
-#   define STACKFRAME 528
-#  else
-#   32 byte special reg save area + 64 byte parm save area
-#   + 64 byte retval area + 13*8 fpr save area + round to 16
-#   define STACKFRAME 272
-#  endif
+#  32 byte special reg save area + 64 byte parm save area
+#  + 64 byte retval area + 13*8 fpr save area + round to 16
+#  define STACKFRAME 272
 #  define PARMSAVE 32
 #  define RETVAL PARMSAVE+64
 # else
@@ -80,18 +73,20 @@
 #  define RETVAL PARMSAVE+64
 # endif
 
+.LFB1:
 # if _CALL_ELF == 2
 	ld	%r12, FFI_TRAMPOLINE_SIZE(%r11)		# closure->cif
 	mflr	%r0
 	lwz	%r12, 28(%r12)				# cif->flags
 	mtcrf	0x40, %r12
 	addi	%r12, %r1, PARMSAVE
-	bt	7, 0f
+	bt	7, .Lparmsave
 	# Our caller has not allocated a parameter save area.
 	# We need to allocate one here and use it to pass gprs to
 	# ffi_closure_helper_LINUX64.
 	addi	%r12, %r1, -STACKFRAME+PARMSAVE
-0:
+.Lparmsave:
+	std	%r0, 16(%r1)
 	# Save general regs into parm save area
 	std	%r3, 0(%r12)
 	std	%r4, 8(%r12)
@@ -103,11 +98,11 @@
 	std	%r10, 56(%r12)
 
 	# load up the pointer to the parm save area
-	mr	%r7, %r12
+	mr	%r5, %r12
 # else
 	# copy r2 to r11 and load TOC into r2
 	mr	%r11, %r2
-	ld	%r2, 16(%r2)
+	ld	%r2, 16(%r11)
 
 	mflr	%r0
 	# Save general regs into parm save area
@@ -121,19 +116,12 @@
 	std	%r9, PARMSAVE+48(%r1)
 	std	%r10, PARMSAVE+56(%r1)
 
-	# load up the pointer to the parm save area
-	addi	%r7, %r1, PARMSAVE
-# endif
 	std	%r0, 16(%r1)
 
-	# closure->cif
-	ld	%r3, FFI_TRAMPOLINE_SIZE(%r11)
-	# closure->fun
-	ld	%r4, FFI_TRAMPOLINE_SIZE+8(%r11)
-	# closure->user_data
-	ld	%r5, FFI_TRAMPOLINE_SIZE+16(%r11)
+	# load up the pointer to the parm save area
+	addi	%r5, %r1, PARMSAVE
+# endif
 
-.Ldoclosure:
 	# next save fpr 1 to fpr 13
 	stfd	%f1, -104+(0*8)(%r1)
 	stfd	%f2, -104+(1*8)(%r1)
@@ -149,44 +137,17 @@
 	stfd	%f12, -104+(11*8)(%r1)
 	stfd	%f13, -104+(12*8)(%r1)
 
-	# load up the pointer to the saved fpr registers
-	addi	%r8, %r1, -104
-
-# ifdef __VEC__
-	# load up the pointer to the saved vector registers
-	# 8 bytes padding for 16-byte alignment at -112(%r1)
-	addi	%r9, %r8, -24
-	stvx	%v13, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v12, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v11, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v10, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v9, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v8, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v7, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v6, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v5, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v4, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v3, 0, %r9
-	addi	%r9, %r9, -16
-	stvx	%v2, 0, %r9
-# endif
+	# load up the pointer to the saved fpr registers */
+	addi	%r6, %r1, -104
 
 	# load up the pointer to the result storage
-	addi	%r6, %r1, -STACKFRAME+RETVAL
+	addi	%r4, %r1, -STACKFRAME+RETVAL
 
 	stdu	%r1, -STACKFRAME(%r1)
-	.cfi_def_cfa_offset STACKFRAME
-	.cfi_offset 65, 16
+.LCFI0:
+
+	# get the context pointer from the trampoline
+	mr	%r3, %r11
 
 	# make the call
 # if defined _CALL_LINUX || _CALL_ELF == 2
@@ -221,9 +182,7 @@
 # case FFI_TYPE_VOID
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 	nop
 # case FFI_TYPE_INT
 # ifdef __LITTLE_ENDIAN__
@@ -233,23 +192,17 @@
 # endif
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 # case FFI_TYPE_FLOAT
 	lfs %f1, RETVAL+0(%r1)
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 # case FFI_TYPE_DOUBLE
 	lfd %f1, RETVAL+0(%r1)
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 # case FFI_TYPE_LONGDOUBLE
 	lfd %f1, RETVAL+0(%r1)
 	mtlr %r0
@@ -263,9 +216,7 @@
 # endif
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 # case FFI_TYPE_SINT8
 # ifdef __LITTLE_ENDIAN__
 	lbz %r3, RETVAL+0(%r1)
@@ -284,9 +235,7 @@
 	mtlr %r0
 .Lfinish:
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 # case FFI_TYPE_SINT16
 # ifdef __LITTLE_ENDIAN__
 	lha %r3, RETVAL+0(%r1)
@@ -295,9 +244,7 @@
 # endif
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 # case FFI_TYPE_UINT32
 # ifdef __LITTLE_ENDIAN__
 	lwz %r3, RETVAL+0(%r1)
@@ -306,9 +253,7 @@
 # endif
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 # case FFI_TYPE_SINT32
 # ifdef __LITTLE_ENDIAN__
 	lwa %r3, RETVAL+0(%r1)
@@ -317,47 +262,27 @@
 # endif
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 # case FFI_TYPE_UINT64
 	ld %r3, RETVAL+0(%r1)
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 # case FFI_TYPE_SINT64
 	ld %r3, RETVAL+0(%r1)
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 # case FFI_TYPE_STRUCT
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 	nop
 # case FFI_TYPE_POINTER
 	ld %r3, RETVAL+0(%r1)
 	mtlr %r0
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
-# case FFI_V2_TYPE_VECTOR
-	addi %r3, %r1, RETVAL
-	lvx %v2, 0, %r3
-	mtlr %r0
-	b .Lfinish
-# case FFI_V2_TYPE_VECTOR_HOMOG
-	addi %r3, %r1, RETVAL
-	lvx %v2, 0, %r3
-	addi %r3, %r3, 16
-	b .Lmorevector
 # case FFI_V2_TYPE_FLOAT_HOMOG
 	lfs %f1, RETVAL+0(%r1)
 	lfs %f2, RETVAL+4(%r1)
@@ -374,28 +299,7 @@
 	lfd %f7, RETVAL+48(%r1)
 	lfd %f8, RETVAL+56(%r1)
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
-.Lmorevector:
-	lvx %v3, 0, %r3
-	addi %r3, %r3, 16
-	lvx %v4, 0, %r3
-	addi %r3, %r3, 16
-	lvx %v5, 0, %r3
-	mtlr %r0
-	addi %r3, %r3, 16
-	lvx %v6, 0, %r3
-	addi %r3, %r3, 16
-	lvx %v7, 0, %r3
-	addi %r3, %r3, 16
-	lvx %v8, 0, %r3
-	addi %r3, %r3, 16
-	lvx %v9, 0, %r3
-	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
-	blr
-	.cfi_def_cfa_offset STACKFRAME
 .Lmorefloat:
 	lfs %f4, RETVAL+12(%r1)
 	mtlr %r0
@@ -404,16 +308,13 @@
 	lfs %f7, RETVAL+24(%r1)
 	lfs %f8, RETVAL+28(%r1)
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 .Lsmall:
 # ifdef __LITTLE_ENDIAN__
 	ld %r3,RETVAL+0(%r1)
 	mtlr %r0
 	ld %r4,RETVAL+8(%r1)
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
 # else
 	# A struct smaller than a dword is returned in the low bits of r3
@@ -427,124 +328,63 @@
 	mtlr %r0
 	ld %r4,RETVAL+8(%r1)
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset STACKFRAME
 .Lsmalldown:
 	addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7
 	mtlr %r0
 	sldi %r5, %r5, 3
 	addi %r1, %r1, STACKFRAME
-	.cfi_def_cfa_offset 0
 	srd %r3, %r3, %r5
 	blr
 # endif
 
-	.cfi_endproc
+.LFE1:
+	.long	0
+	.byte	0,12,0,1,128,0,0,0
 # if _CALL_ELF == 2
 	.size	ffi_closure_LINUX64,.-ffi_closure_LINUX64
 # else
 #  ifdef _CALL_LINUX
 	.size	ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64
 #  else
-	.long	0
-	.byte	0,12,0,1,128,0,0,0
 	.size	.ffi_closure_LINUX64,.-.ffi_closure_LINUX64
 #  endif
 # endif
 
+	.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	0x41	 # CIE RA Column
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x14	 # FDE Encoding (pcrel udata8)
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1
+	.uleb128 0x0
+	.align 3
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	 # FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
+	.8byte	.LFB1-.	 # FDE initial location
+	.8byte	.LFE1-.LFB1	 # FDE address range
+	.uleb128 0x0	 # Augmentation size
+	.byte	0x2	 # DW_CFA_advance_loc1
+	.byte	.LCFI0-.LFB1
+	.byte	0xe	 # DW_CFA_def_cfa_offset
+	.uleb128 STACKFRAME
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x41
+	.sleb128 -2
+	.align 3
+.LEFDE1:
 
-	FFI_HIDDEN (ffi_go_closure_linux64)
-	.globl  ffi_go_closure_linux64
-	.text
-	.cfi_startproc
-# if _CALL_ELF == 2
-ffi_go_closure_linux64:
-	addis	%r2, %r12, .TOC.-ffi_go_closure_linux64@ha
-	addi	%r2, %r2, .TOC.-ffi_go_closure_linux64@l
-	.localentry ffi_go_closure_linux64, . - ffi_go_closure_linux64
-# else
-	.section        ".opd","aw"
-	.align  3
-ffi_go_closure_linux64:
-#  ifdef _CALL_LINUX
-	.quad   .L.ffi_go_closure_linux64,.TOC.@tocbase,0
-	.type   ffi_go_closure_linux64,@function
-	.text
-.L.ffi_go_closure_linux64:
-#  else
-	FFI_HIDDEN (.ffi_go_closure_linux64)
-	.globl  .ffi_go_closure_linux64
-	.quad   .ffi_go_closure_linux64,.TOC.@tocbase,0
-	.size   ffi_go_closure_linux64,24
-	.type   .ffi_go_closure_linux64,@function
-	.text
-.ffi_go_closure_linux64:
-#  endif
-# endif
-
-# if _CALL_ELF == 2
-	ld	%r12, 8(%r11)				# closure->cif
-	mflr	%r0
-	lwz	%r12, 28(%r12)				# cif->flags
-	mtcrf	0x40, %r12
-	addi	%r12, %r1, PARMSAVE
-	bt	7, 0f
-	# Our caller has not allocated a parameter save area.
-	# We need to allocate one here and use it to pass gprs to
-	# ffi_closure_helper_LINUX64.
-	addi	%r12, %r1, -STACKFRAME+PARMSAVE
-0:
-	# Save general regs into parm save area
-	std	%r3, 0(%r12)
-	std	%r4, 8(%r12)
-	std	%r5, 16(%r12)
-	std	%r6, 24(%r12)
-	std	%r7, 32(%r12)
-	std	%r8, 40(%r12)
-	std	%r9, 48(%r12)
-	std	%r10, 56(%r12)
-
-	# load up the pointer to the parm save area
-	mr	%r7, %r12
-# else
-	mflr	%r0
-	# Save general regs into parm save area
-	# This is the parameter save area set up by our caller.
-	std	%r3, PARMSAVE+0(%r1)
-	std	%r4, PARMSAVE+8(%r1)
-	std	%r5, PARMSAVE+16(%r1)
-	std	%r6, PARMSAVE+24(%r1)
-	std	%r7, PARMSAVE+32(%r1)
-	std	%r8, PARMSAVE+40(%r1)
-	std	%r9, PARMSAVE+48(%r1)
-	std	%r10, PARMSAVE+56(%r1)
-
-	# load up the pointer to the parm save area
-	addi	%r7, %r1, PARMSAVE
-# endif
-	std	%r0, 16(%r1)
-
-	# closure->cif
-	ld	%r3, 8(%r11)
-	# closure->fun
-	ld	%r4, 16(%r11)
-	# user_data
-	mr	%r5, %r11
-	b	.Ldoclosure
-
-	.cfi_endproc
-# if _CALL_ELF == 2
-	.size	ffi_go_closure_linux64,.-ffi_go_closure_linux64
-# else
-#  ifdef _CALL_LINUX
-	.size	ffi_go_closure_linux64,.-.L.ffi_go_closure_linux64
-#  else
-	.long	0
-	.byte	0,12,0,1,128,0,0,0
-	.size	.ffi_go_closure_linux64,.-.ffi_go_closure_linux64
-#  endif
-# endif
 #endif
 
 #if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2
diff --git a/src/powerpc/ppc_closure.S b/src/powerpc/ppc_closure.S
index b6d209d..075922c 100644
--- a/src/powerpc/ppc_closure.S
+++ b/src/powerpc/ppc_closure.S
@@ -33,14 +33,13 @@
 
 #ifndef POWERPC64
 
-FFI_HIDDEN(ffi_closure_SYSV)
 ENTRY(ffi_closure_SYSV)
-	.cfi_startproc
+.LFB1:
 	stwu %r1,-144(%r1)
-	.cfi_def_cfa_offset 144
+.LCFI0:
 	mflr %r0
+.LCFI1:
 	stw %r0,148(%r1)
-	.cfi_offset 65, 4
 
 # we want to build up an areas for the parameters passed
 # in registers (both floating point and integer)
@@ -49,17 +48,6 @@
 	stw   %r3, 16(%r1)
 	stw   %r4, 20(%r1)
 	stw   %r5, 24(%r1)
-
-	# set up registers for the routine that does the work
-
-	# closure->cif
-	lwz %r3,FFI_TRAMPOLINE_SIZE(%r11)
-	# closure->fun
-	lwz %r4,FFI_TRAMPOLINE_SIZE+4(%r11)
-	# closure->user_data
-	lwz %r5,FFI_TRAMPOLINE_SIZE+8(%r11)
-
-.Ldoclosure:
 	stw   %r6, 28(%r1)
 	stw   %r7, 32(%r1)
 	stw   %r8, 36(%r1)
@@ -78,18 +66,23 @@
 	stfd  %f8, 104(%r1)
 #endif
 
-	# pointer to the result storage
-	addi %r6,%r1,112
+	# set up registers for the routine that actually does the work
+	# get the context pointer from the trampoline
+	mr %r3,%r11
 
-	# pointer to the saved gpr registers
-	addi %r7,%r1,16
+	# now load up the pointer to the result storage
+	addi %r4,%r1,112
 
-	# pointer to the saved fpr registers
-	addi %r8,%r1,48
+	# now load up the pointer to the saved gpr registers
+	addi %r5,%r1,16
 
-	# pointer to the outgoing parameter save area in the previous frame
+	# now load up the pointer to the saved fpr registers */
+	addi %r6,%r1,48
+
+	# now load up the pointer to the outgoing parameter
+	# stack in the previous frame
 	# i.e. the previous frame pointer + 8
-	addi %r9,%r1,152
+	addi %r7,%r1,152
 
 	# make the call
 	bl ffi_closure_helper_SYSV@local
@@ -108,6 +101,7 @@
 	add %r3,%r3,%r4		# add contents of table to table address
 	mtctr %r3
 	bctr			# jump to it
+.LFE1:
 
 # Each of the ret_typeX code fragments has to be exactly 16 bytes long
 # (4 instructions). For cache effectiveness we align to a 16 byte boundary
@@ -117,9 +111,7 @@
 .Lret_type0:
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 	nop
 
 # case FFI_TYPE_INT
@@ -127,33 +119,31 @@
 	mtlr %r0
 .Lfinish:
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_TYPE_FLOAT
 #ifndef __NO_FPRS__
 	lfs %f1,112+0(%r1)
-#else
-	nop
-#endif
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
+#else
+	nop
+	nop
+	nop
+#endif
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_TYPE_DOUBLE
 #ifndef __NO_FPRS__
 	lfd %f1,112+0(%r1)
-#else
-	nop
-#endif
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
+#else
+	nop
+	nop
+	nop
+#endif
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_TYPE_LONGDOUBLE
 #ifndef __NO_FPRS__
@@ -162,12 +152,10 @@
 	mtlr %r0
 	b .Lfinish
 #else
-	mtlr %r0
-	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
-	blr
-	.cfi_def_cfa_offset 144
 	nop
+	nop
+	nop
+	blr
 #endif
 
 # case FFI_TYPE_UINT8
@@ -178,9 +166,7 @@
 #endif
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_TYPE_SINT8
 #ifdef __LITTLE_ENDIAN__
@@ -200,9 +186,7 @@
 #endif
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_TYPE_SINT16
 #ifdef __LITTLE_ENDIAN__
@@ -212,25 +196,19 @@
 #endif
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_TYPE_UINT32
 	lwz %r3,112+0(%r1)
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_TYPE_SINT32
 	lwz %r3,112+0(%r1)
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_TYPE_UINT64
 	lwz %r3,112+0(%r1)
@@ -247,18 +225,14 @@
 # case FFI_TYPE_STRUCT
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 	nop
 
 # case FFI_TYPE_POINTER
 	lwz %r3,112+0(%r1)
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_TYPE_UINT128
 	lwz %r3,112+0(%r1)
@@ -271,26 +245,20 @@
 	lbz %r3,112+0(%r1)
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
 	lhz %r3,112+0(%r1)
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
 	lwz %r3,112+0(%r1)
 #ifdef __LITTLE_ENDIAN__
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 #else
 	srwi %r3,%r3,8
 	mtlr %r0
@@ -301,9 +269,7 @@
 	lwz %r3,112+0(%r1)
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
 	lwz %r3,112+0(%r1)
@@ -353,43 +319,64 @@
 	or %r4,%r6,%r4
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_def_cfa_offset 144
 #endif
 
 .Luint128:
 	lwz %r6,112+12(%r1)
 	mtlr %r0
 	addi %r1,%r1,144
-	.cfi_def_cfa_offset 0
 	blr
-	.cfi_endproc
+	
 END(ffi_closure_SYSV)
 
-
-FFI_HIDDEN(ffi_go_closure_sysv)
-ENTRY(ffi_go_closure_sysv)
-	.cfi_startproc
-	stwu %r1,-144(%r1)
-	.cfi_def_cfa_offset 144
-	mflr %r0
-	stw %r0,148(%r1)
-	.cfi_offset 65, 4
-
-	stw   %r3, 16(%r1)
-	stw   %r4, 20(%r1)
-	stw   %r5, 24(%r1)
-
-	# closure->cif
-	lwz %r3,4(%r11)
-	# closure->fun
-	lwz %r4,8(%r11)
-	# user_data
-	mr %r5,%r11
-	b .Ldoclosure
-	.cfi_endproc
-END(ffi_go_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
+#if defined _RELOCATABLE || defined __PIC__
+	.ascii "zR\0"	 # CIE Augmentation
+#else
+	.ascii "\0"	 # CIE Augmentation
+#endif
+	.uleb128 0x1	 # CIE Code Alignment Factor
+	.sleb128 -4	 # CIE Data Alignment Factor
+	.byte	0x41	 # CIE RA Column
+#if defined _RELOCATABLE || defined __PIC__
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x1b	 # FDE Encoding (pcrel sdata4)
+#endif
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1
+	.uleb128 0x0
+	.align 2
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	 # FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
+#if defined _RELOCATABLE || defined __PIC__
+	.4byte	.LFB1-.	 # FDE initial location
+#else
+	.4byte	.LFB1	 # FDE initial location
+#endif
+	.4byte	.LFE1-.LFB1	 # FDE address range
+#if defined _RELOCATABLE || defined __PIC__
+	.uleb128 0x0	 # Augmentation size
+#endif
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	.LCFI0-.LFB1
+	.byte	0xe	 # DW_CFA_def_cfa_offset
+	.uleb128 144
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	.LCFI1-.LCFI0
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x41
+	.sleb128 -1
+	.align 2
+.LEFDE1:
 
 #if defined __ELF__ && defined __linux__
 	.section	.note.GNU-stack,"",@progbits
diff --git a/src/powerpc/sysv.S b/src/powerpc/sysv.S
index 1474ce7..fed2380 100644
--- a/src/powerpc/sysv.S
+++ b/src/powerpc/sysv.S
@@ -31,35 +31,34 @@
 #include <powerpc/asm.h>
 
 #ifndef POWERPC64
-FFI_HIDDEN(ffi_call_SYSV)
+	.globl ffi_prep_args_SYSV
 ENTRY(ffi_call_SYSV)
-	.cfi_startproc
+.LFB1:
 	/* Save the old stack pointer as AP.  */
-	mr	%r10,%r1
-	.cfi_def_cfa_register 10
+	mr	%r8,%r1
 
+.LCFI0:
 	/* Allocate the stack space we need.  */
-	stwux	%r1,%r1,%r8
+	stwux	%r1,%r1,%r4
 	/* Save registers we use.  */
 	mflr	%r9
-	stw	%r28,-16(%r10)
-	stw	%r29,-12(%r10)
-	stw	%r30, -8(%r10)
-	stw	%r31, -4(%r10)
-	stw	%r9,   4(%r10)
-	.cfi_offset 65, 4
-	.cfi_offset 31, -4
-	.cfi_offset 30, -8
-	.cfi_offset 29, -12
-	.cfi_offset 28, -16
+	stw	%r28,-16(%r8)
+.LCFI1:
+	stw	%r29,-12(%r8)
+.LCFI2:
+	stw	%r30, -8(%r8)
+.LCFI3:
+	stw	%r31, -4(%r8)
+.LCFI4:
+	stw	%r9,   4(%r8)
+.LCFI5:
 
 	/* Save arguments over call...  */
-	stw	%r7,   -20(%r10)	/* closure, */
-	mr	%r31,%r6		/* flags, */
-	mr	%r30,%r5		/* rvalue, */
-	mr	%r29,%r4		/* function address, */
-	mr	%r28,%r10		/* our AP. */
-	.cfi_def_cfa_register 28
+	mr	%r31,%r5	/* flags, */
+	mr	%r30,%r6	/* rvalue, */
+	mr	%r29,%r7	/* function address, */
+	mr	%r28,%r8	/* our AP. */
+.LCFI6:
 
 	/* Call ffi_prep_args_SYSV.  */
 	mr	%r4,%r1
@@ -71,36 +70,35 @@
 	/* Get the address to call into CTR.  */
 	mtctr	%r29
 	/* Load all those argument registers.  */
-	lwz	%r3,-24-(8*4)(%r28)
-	lwz	%r4,-24-(7*4)(%r28)
-	lwz	%r5,-24-(6*4)(%r28)
-	lwz	%r6,-24-(5*4)(%r28)
+	lwz	%r3,-16-(8*4)(%r28)
+	lwz	%r4,-16-(7*4)(%r28)
+	lwz	%r5,-16-(6*4)(%r28)
+	lwz	%r6,-16-(5*4)(%r28)
 	bf-	5,1f
 	nop
-	lwz	%r7,-24-(4*4)(%r28)
-	lwz	%r8,-24-(3*4)(%r28)
-	lwz	%r9,-24-(2*4)(%r28)
-	lwz	%r10,-24-(1*4)(%r28)
+	lwz	%r7,-16-(4*4)(%r28)
+	lwz	%r8,-16-(3*4)(%r28)
+	lwz	%r9,-16-(2*4)(%r28)
+	lwz	%r10,-16-(1*4)(%r28)
 	nop
 1:
 
 #ifndef __NO_FPRS__
 	/* Load all the FP registers.  */
 	bf-	6,2f
-	lfd	%f1,-24-(8*4)-(8*8)(%r28)
-	lfd	%f2,-24-(8*4)-(7*8)(%r28)
-	lfd	%f3,-24-(8*4)-(6*8)(%r28)
-	lfd	%f4,-24-(8*4)-(5*8)(%r28)
+	lfd	%f1,-16-(8*4)-(8*8)(%r28)
+	lfd	%f2,-16-(8*4)-(7*8)(%r28)
+	lfd	%f3,-16-(8*4)-(6*8)(%r28)
+	lfd	%f4,-16-(8*4)-(5*8)(%r28)
 	nop
-	lfd	%f5,-24-(8*4)-(4*8)(%r28)
-	lfd	%f6,-24-(8*4)-(3*8)(%r28)
-	lfd	%f7,-24-(8*4)-(2*8)(%r28)
-	lfd	%f8,-24-(8*4)-(1*8)(%r28)
+	lfd	%f5,-16-(8*4)-(4*8)(%r28)
+	lfd	%f6,-16-(8*4)-(3*8)(%r28)
+	lfd	%f7,-16-(8*4)-(2*8)(%r28)
+	lfd	%f8,-16-(8*4)-(1*8)(%r28)
 #endif
 2:
 
 	/* Make the call.  */
-	lwz	%r11, -20(%r28)
 	bctrl
 
 	/* Now, deal with the return value.  */
@@ -127,24 +125,11 @@
 	lwz	%r30, -8(%r28)
 	lwz	%r29,-12(%r28)
 	lwz	%r28,-16(%r28)
-	.cfi_remember_state
-	/* At this point we don't have a cfa register.  Say all our
-	   saved regs have been restored.  */
-	.cfi_same_value 65
-	.cfi_same_value 31
-	.cfi_same_value 30
-	.cfi_same_value 29
-	.cfi_same_value 28
-	/* Hopefully this works..  */
-	.cfi_def_cfa_register 1
-	.cfi_offset 1, 0
 	lwz	%r1,0(%r1)
-	.cfi_same_value 1
 	blr
 
 #ifndef __NO_FPRS__
 L(fp_return_value):
-	.cfi_restore_state
 	bf	28,L(float_return_value)
 	stfd	%f1,0(%r30)
 	mtcrf   0x02,%r31 /* cr6  */
@@ -165,10 +150,70 @@
 	stw %r3, 0(%r30)
 	stw %r4, 4(%r30)
 	b L(done_return_value)
-	.cfi_endproc
 
+.LFE1:
 END(ffi_call_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 */
+#if defined _RELOCATABLE || defined __PIC__
+      .ascii	"zR\0"   /*  CIE Augmentation */
+#else
+      .ascii	"\0"	 /*  CIE Augmentation */
+#endif
+      .uleb128  0x1      /*  CIE Code Alignment Factor */
+      .sleb128  -4	 /*  CIE Data Alignment Factor */
+      .byte     0x41     /*  CIE RA Column */
+#if defined _RELOCATABLE || defined __PIC__
+      .uleb128  0x1      /*  Augmentation size */
+      .byte	0x1b	 /*  FDE Encoding (pcrel sdata4) */
+#endif
+      .byte     0xc      /*  DW_CFA_def_cfa */
+      .uleb128  0x1
+      .uleb128  0x0
+      .align 2
+.LECIE1:
+.LSFDE1:
+      .4byte    .LEFDE1-.LASFDE1         /*  FDE Length */
+.LASFDE1:
+      .4byte    .LASFDE1-.Lframe1         /*  FDE CIE offset */
+#if defined _RELOCATABLE || defined __PIC__
+      .4byte    .LFB1-.  /*  FDE initial location */
+#else
+      .4byte    .LFB1    /*  FDE initial location */
+#endif
+      .4byte    .LFE1-.LFB1      /*  FDE address range */
+#if defined _RELOCATABLE || defined __PIC__
+      .uleb128  0x0	 /*  Augmentation size */
+#endif
+      .byte     0x4      /*  DW_CFA_advance_loc4 */
+      .4byte    .LCFI0-.LFB1
+      .byte     0xd      /*  DW_CFA_def_cfa_register */
+      .uleb128  0x08
+      .byte     0x4      /*  DW_CFA_advance_loc4 */
+      .4byte    .LCFI5-.LCFI0
+      .byte     0x11     /*  DW_CFA_offset_extended_sf */
+      .uleb128  0x41
+      .sleb128  -1
+      .byte     0x9f     /*  DW_CFA_offset, column 0x1f */
+      .uleb128  0x1
+      .byte     0x9e     /*  DW_CFA_offset, column 0x1e */
+      .uleb128  0x2
+      .byte     0x9d     /*  DW_CFA_offset, column 0x1d */
+      .uleb128  0x3
+      .byte     0x9c     /*  DW_CFA_offset, column 0x1c */
+      .uleb128  0x4
+      .byte     0x4      /*  DW_CFA_advance_loc4 */
+      .4byte    .LCFI6-.LCFI5
+      .byte     0xd      /*  DW_CFA_def_cfa_register */
+      .uleb128  0x1c
+      .align 2
+.LEFDE1:
+
 #if defined __ELF__ && defined __linux__
 	.section	.note.GNU-stack,"",@progbits
 #endif
diff --git a/src/prep_cif.c b/src/prep_cif.c
index 06c6544..be5eae3 100644
--- a/src/prep_cif.c
+++ b/src/prep_cif.c
@@ -29,12 +29,12 @@
 
 /* Round up to FFI_SIZEOF_ARG. */
 
-#define STACK_ARG_SIZE(x) FFI_ALIGN(x, FFI_SIZEOF_ARG)
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
 
 /* Perform machine independent initialization of aggregate type
    specifications. */
 
-static ffi_status initialize_aggregate(ffi_type *arg, size_t *offsets)
+static ffi_status initialize_aggregate(ffi_type *arg)
 {
   ffi_type **ptr;
 
@@ -52,15 +52,13 @@
   while ((*ptr) != NULL)
     {
       if (UNLIKELY(((*ptr)->size == 0)
-		    && (initialize_aggregate((*ptr), NULL) != FFI_OK)))
+		    && (initialize_aggregate((*ptr)) != FFI_OK)))
 	return FFI_BAD_TYPEDEF;
 
       /* Perform a sanity check on the argument type */
       FFI_ASSERT_VALID_TYPE(*ptr);
 
-      arg->size = FFI_ALIGN(arg->size, (*ptr)->alignment);
-      if (offsets)
-	*offsets++ = arg->size;
+      arg->size = ALIGN(arg->size, (*ptr)->alignment);
       arg->size += (*ptr)->size;
 
       arg->alignment = (arg->alignment > (*ptr)->alignment) ?
@@ -76,7 +74,7 @@
      struct A { long a; char b; }; struct B { struct A x; char y; };
      should find y at an offset of 2*sizeof(long) and result in a
      total size of 3*sizeof(long).  */
-  arg->size = FFI_ALIGN (arg->size, arg->alignment);
+  arg->size = ALIGN (arg->size, arg->alignment);
 
   /* On some targets, the ABI defines that structures have an additional
      alignment beyond the "natural" one based on their elements.  */
@@ -129,16 +127,13 @@
   cif->rtype = rtype;
 
   cif->flags = 0;
-#ifdef _M_ARM64
-  cif->is_variadic = isvariadic;
-#endif
+
 #if HAVE_LONG_DOUBLE_VARIANT
   ffi_prep_types (abi);
 #endif
 
   /* Initialize the return type if necessary */
-  if ((cif->rtype->size == 0)
-      && (initialize_aggregate(cif->rtype, NULL) != FFI_OK))
+  if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
     return FFI_BAD_TYPEDEF;
 
 #ifndef FFI_TARGET_HAS_COMPLEX_TYPE
@@ -152,6 +147,9 @@
 #if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
   /* Make space for the return structure pointer */
   if (cif->rtype->type == FFI_TYPE_STRUCT
+#ifdef SPARC
+      && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
 #ifdef TILE
       && (cif->rtype->size > 10 * FFI_SIZEOF_ARG)
 #endif
@@ -169,8 +167,7 @@
     {
 
       /* Initialize any uninitialized aggregate type definitions */
-      if (((*ptr)->size == 0)
-	  && (initialize_aggregate((*ptr), NULL) != FFI_OK))
+      if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
 	return FFI_BAD_TYPEDEF;
 
 #ifndef FFI_TARGET_HAS_COMPLEX_TYPE
@@ -182,10 +179,18 @@
       FFI_ASSERT_VALID_TYPE(*ptr);
 
 #if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
+#ifdef SPARC
+      if (((*ptr)->type == FFI_TYPE_STRUCT
+	   && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+	  || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+	      && cif->abi != FFI_V9))
+	bytes += sizeof(void*);
+      else
+#endif
 	{
 	  /* Add any padding if necessary */
 	  if (((*ptr)->alignment - 1) & bytes)
-	    bytes = (unsigned)FFI_ALIGN(bytes, (*ptr)->alignment);
+	    bytes = (unsigned)ALIGN(bytes, (*ptr)->alignment);
 
 #ifdef TILE
 	  if (bytes < 10 * FFI_SIZEOF_ARG &&
@@ -201,7 +206,7 @@
 	    bytes = 6*4;
 #endif
 
-	  bytes += (unsigned int)STACK_ARG_SIZE((*ptr)->size);
+	  bytes += STACK_ARG_SIZE((*ptr)->size);
 	}
 #endif
     }
@@ -246,18 +251,3 @@
 }
 
 #endif
-
-ffi_status
-ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets)
-{
-  if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
-    return FFI_BAD_ABI;
-  if (struct_type->type != FFI_TYPE_STRUCT)
-    return FFI_BAD_TYPEDEF;
-
-#if HAVE_LONG_DOUBLE_VARIANT
-  ffi_prep_types (abi);
-#endif
-
-  return initialize_aggregate(struct_type, offsets);
-}
diff --git a/src/raw_api.c b/src/raw_api.c
index be15611..276cb22 100644
--- a/src/raw_api.c
+++ b/src/raw_api.c
@@ -43,10 +43,10 @@
     {
 #if !FFI_NO_STRUCTS
       if ((*at)->type == FFI_TYPE_STRUCT)
-	result += FFI_ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
+	result += ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
       else
 #endif
-	result += FFI_ALIGN ((*at)->size, FFI_SIZEOF_ARG);
+	result += ALIGN ((*at)->size, FFI_SIZEOF_ARG);
     }
 
   return result;
@@ -98,7 +98,7 @@
 	  
 	default:
 	  *args = raw;
-	  raw += FFI_ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	  raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
 	}
     }
 
@@ -123,7 +123,7 @@
       else
 	{
 	  *args = (void*) raw;
-	  raw += FFI_ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
+	  raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
 	}
     }
 
@@ -186,7 +186,7 @@
 
 	default:
 	  memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
-	  raw += FFI_ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	  raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
 	}
     }
 }
diff --git a/src/riscv/ffi.c b/src/riscv/ffi.c
deleted file mode 100644
index c910858..0000000
--- a/src/riscv/ffi.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 2015 Michael Knyszek <mknyszek@berkeley.edu>
-                         2015 Andrew Waterman <waterman@cs.berkeley.edu>
-                         2018 Stef O'Rear <sorear2@gmail.com>
-   Based on MIPS N32/64 port
-
-   RISC-V Foreign Function Interface
-
-   Permission is hereby granted, free of charge, to any person obtaining
-   a copy of this software and associated documentation files (the
-   ``Software''), to deal in the Software without restriction, including
-   without limitation the rights to use, copy, modify, merge, publish,
-   distribute, sublicense, and/or sell copies of the Software, and to
-   permit persons to whom the Software is furnished to do so, subject to
-   the following conditions:
-
-   The above copyright notice and this permission notice shall be included
-   in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-   DEALINGS IN THE SOFTWARE.
-   ----------------------------------------------------------------------- */
-
-#include <ffi.h>
-#include <ffi_common.h>
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#if __riscv_float_abi_double
-#define ABI_FLEN 64
-#define ABI_FLOAT double
-#elif __riscv_float_abi_single
-#define ABI_FLEN 32
-#define ABI_FLOAT float
-#endif
-
-#define NARGREG 8
-#define STKALIGN 16
-#define MAXCOPYARG (2 * sizeof(double))
-
-typedef struct call_context
-{
-#if ABI_FLEN
-    ABI_FLOAT fa[8];
-#endif
-    size_t a[8];
-    /* used by the assembly code to in-place construct its own stack frame */
-    char frame[16];
-} call_context;
-
-typedef struct call_builder
-{
-    call_context *aregs;
-    int used_integer;
-    int used_float;
-    size_t *used_stack;
-} call_builder;
-
-/* integer (not pointer) less than ABI XLEN */
-/* FFI_TYPE_INT does not appear to be used */
-#if __SIZEOF_POINTER__ == 8
-#define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT64)
-#else
-#define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT32)
-#endif
-
-#if ABI_FLEN
-typedef struct {
-    char as_elements, type1, offset2, type2;
-} float_struct_info;
-
-#if ABI_FLEN >= 64
-#define IS_FLOAT(type) ((type) >= FFI_TYPE_FLOAT && (type) <= FFI_TYPE_DOUBLE)
-#else
-#define IS_FLOAT(type) ((type) == FFI_TYPE_FLOAT)
-#endif
-
-static ffi_type **flatten_struct(ffi_type *in, ffi_type **out, ffi_type **out_end) {
-    int i;
-    if (out == out_end) return out;
-    if (in->type != FFI_TYPE_STRUCT) {
-        *(out++) = in;
-    } else {
-        for (i = 0; in->elements[i]; i++)
-            out = flatten_struct(in->elements[i], out, out_end);
-    }
-    return out;
-}
-
-/* Structs with at most two fields after flattening, one of which is of
-   floating point type, are passed in multiple registers if sufficient
-   registers are available. */
-static float_struct_info struct_passed_as_elements(call_builder *cb, ffi_type *top) {
-    float_struct_info ret = {0, 0, 0, 0};
-    ffi_type *fields[3];
-    int num_floats, num_ints;
-    int num_fields = flatten_struct(top, fields, fields + 3) - fields;
-
-    if (num_fields == 1) {
-        if (IS_FLOAT(fields[0]->type)) {
-            ret.as_elements = 1;
-            ret.type1 = fields[0]->type;
-        }
-    } else if (num_fields == 2) {
-        num_floats = IS_FLOAT(fields[0]->type) + IS_FLOAT(fields[1]->type);
-        num_ints = IS_INT(fields[0]->type) + IS_INT(fields[1]->type);
-        if (num_floats == 0 || num_floats + num_ints != 2)
-            return ret;
-        if (cb->used_float + num_floats > NARGREG || cb->used_integer + (2 - num_floats) > NARGREG)
-            return ret;
-        if (!IS_FLOAT(fields[0]->type) && !IS_FLOAT(fields[1]->type))
-            return ret;
-
-        ret.type1 = fields[0]->type;
-        ret.type2 = fields[1]->type;
-        ret.offset2 = FFI_ALIGN(fields[0]->size, fields[1]->alignment);
-        ret.as_elements = 1;
-    }
-
-    return ret;
-}
-#endif
-
-/* allocates a single register, float register, or XLEN-sized stack slot to a datum */
-static void marshal_atom(call_builder *cb, int type, void *data) {
-    size_t value = 0;
-    switch (type) {
-        case FFI_TYPE_UINT8: value = *(uint8_t *)data; break;
-        case FFI_TYPE_SINT8: value = *(int8_t *)data; break;
-        case FFI_TYPE_UINT16: value = *(uint16_t *)data; break;
-        case FFI_TYPE_SINT16: value = *(int16_t *)data; break;
-        /* 32-bit quantities are always sign-extended in the ABI */
-        case FFI_TYPE_UINT32: value = *(int32_t *)data; break;
-        case FFI_TYPE_SINT32: value = *(int32_t *)data; break;
-#if __SIZEOF_POINTER__ == 8
-        case FFI_TYPE_UINT64: value = *(uint64_t *)data; break;
-        case FFI_TYPE_SINT64: value = *(int64_t *)data; break;
-#endif
-        case FFI_TYPE_POINTER: value = *(size_t *)data; break;
-
-        /* float values may be recoded in an implementation-defined way
-           by hardware conforming to 2.1 or earlier, so use asm to
-           reinterpret floats as doubles */
-#if ABI_FLEN >= 32
-        case FFI_TYPE_FLOAT:
-            asm("" : "=f"(cb->aregs->fa[cb->used_float++]) : "0"(*(float *)data));
-            return;
-#endif
-#if ABI_FLEN >= 64
-        case FFI_TYPE_DOUBLE:
-            asm("" : "=f"(cb->aregs->fa[cb->used_float++]) : "0"(*(double *)data));
-            return;
-#endif
-        default: FFI_ASSERT(0); break;
-    }
-
-    if (cb->used_integer == NARGREG) {
-        *cb->used_stack++ = value;
-    } else {
-        cb->aregs->a[cb->used_integer++] = value;
-    }
-}
-
-static void unmarshal_atom(call_builder *cb, int type, void *data) {
-    size_t value;
-    switch (type) {
-#if ABI_FLEN >= 32
-        case FFI_TYPE_FLOAT:
-            asm("" : "=f"(*(float *)data) : "0"(cb->aregs->fa[cb->used_float++]));
-            return;
-#endif
-#if ABI_FLEN >= 64
-        case FFI_TYPE_DOUBLE:
-            asm("" : "=f"(*(double *)data) : "0"(cb->aregs->fa[cb->used_float++]));
-            return;
-#endif
-    }
-
-    if (cb->used_integer == NARGREG) {
-        value = *cb->used_stack++;
-    } else {
-        value = cb->aregs->a[cb->used_integer++];
-    }
-
-    switch (type) {
-        case FFI_TYPE_UINT8: *(uint8_t *)data = value; break;
-        case FFI_TYPE_SINT8: *(uint8_t *)data = value; break;
-        case FFI_TYPE_UINT16: *(uint16_t *)data = value; break;
-        case FFI_TYPE_SINT16: *(uint16_t *)data = value; break;
-        case FFI_TYPE_UINT32: *(uint32_t *)data = value; break;
-        case FFI_TYPE_SINT32: *(uint32_t *)data = value; break;
-#if __SIZEOF_POINTER__ == 8
-        case FFI_TYPE_UINT64: *(uint64_t *)data = value; break;
-        case FFI_TYPE_SINT64: *(uint64_t *)data = value; break;
-#endif
-        case FFI_TYPE_POINTER: *(size_t *)data = value; break;
-        default: FFI_ASSERT(0); break;
-    }
-}
-
-/* adds an argument to a call, or a not by reference return value */
-static void marshal(call_builder *cb, ffi_type *type, int var, void *data) {
-    size_t realign[2];
-
-#if ABI_FLEN
-    if (!var && type->type == FFI_TYPE_STRUCT) {
-        float_struct_info fsi = struct_passed_as_elements(cb, type);
-        if (fsi.as_elements) {
-            marshal_atom(cb, fsi.type1, data);
-            if (fsi.offset2)
-                marshal_atom(cb, fsi.type2, ((char*)data) + fsi.offset2);
-            return;
-        }
-    }
-
-    if (!var && cb->used_float < NARGREG && IS_FLOAT(type->type)) {
-        marshal_atom(cb, type->type, data);
-        return;
-    }
-#endif
-
-    if (type->size > 2 * __SIZEOF_POINTER__) {
-        /* pass by reference */
-        marshal_atom(cb, FFI_TYPE_POINTER, &data);
-    } else if (IS_INT(type->type) || type->type == FFI_TYPE_POINTER) {
-        marshal_atom(cb, type->type, data);
-    } else {
-        /* overlong integers, soft-float floats, and structs without special
-           float handling are treated identically from this point on */
-
-        /* variadics are aligned even in registers */
-        if (type->alignment > __SIZEOF_POINTER__) {
-            if (var)
-                cb->used_integer = FFI_ALIGN(cb->used_integer, 2);
-            cb->used_stack = (size_t *)FFI_ALIGN(cb->used_stack, 2*__SIZEOF_POINTER__);
-        }
-
-        memcpy(realign, data, type->size);
-        if (type->size > 0)
-            marshal_atom(cb, FFI_TYPE_POINTER, realign);
-        if (type->size > __SIZEOF_POINTER__)
-            marshal_atom(cb, FFI_TYPE_POINTER, realign + 1);
-    }
-}
-
-/* for arguments passed by reference returns the pointer, otherwise the arg is copied (up to MAXCOPYARG bytes) */
-static void *unmarshal(call_builder *cb, ffi_type *type, int var, void *data) {
-    size_t realign[2];
-    void *pointer;
-
-#if ABI_FLEN
-    if (!var && type->type == FFI_TYPE_STRUCT) {
-        float_struct_info fsi = struct_passed_as_elements(cb, type);
-        if (fsi.as_elements) {
-            unmarshal_atom(cb, fsi.type1, data);
-            if (fsi.offset2)
-                unmarshal_atom(cb, fsi.type2, ((char*)data) + fsi.offset2);
-            return data;
-        }
-    }
-
-    if (!var && cb->used_float < NARGREG && IS_FLOAT(type->type)) {
-        unmarshal_atom(cb, type->type, data);
-        return data;
-    }
-#endif
-
-    if (type->size > 2 * __SIZEOF_POINTER__) {
-        /* pass by reference */
-        unmarshal_atom(cb, FFI_TYPE_POINTER, (char*)&pointer);
-        return pointer;
-    } else if (IS_INT(type->type) || type->type == FFI_TYPE_POINTER) {
-        unmarshal_atom(cb, type->type, data);
-        return data;
-    } else {
-        /* overlong integers, soft-float floats, and structs without special
-           float handling are treated identically from this point on */
-
-        /* variadics are aligned even in registers */
-        if (type->alignment > __SIZEOF_POINTER__) {
-            if (var)
-                cb->used_integer = FFI_ALIGN(cb->used_integer, 2);
-            cb->used_stack = (size_t *)FFI_ALIGN(cb->used_stack, 2*__SIZEOF_POINTER__);
-        }
-
-        if (type->size > 0)
-            unmarshal_atom(cb, FFI_TYPE_POINTER, realign);
-        if (type->size > __SIZEOF_POINTER__)
-            unmarshal_atom(cb, FFI_TYPE_POINTER, realign + 1);
-        memcpy(data, realign, type->size);
-        return data;
-    }
-}
-
-static int passed_by_ref(call_builder *cb, ffi_type *type, int var) {
-#if ABI_FLEN
-    if (!var && type->type == FFI_TYPE_STRUCT) {
-        float_struct_info fsi = struct_passed_as_elements(cb, type);
-        if (fsi.as_elements) return 0;
-    }
-#endif
-
-    return type->size > 2 * __SIZEOF_POINTER__;
-}
-
-/* Perform machine dependent cif processing */
-ffi_status ffi_prep_cif_machdep(ffi_cif *cif) {
-    cif->riscv_nfixedargs = cif->nargs;
-    return FFI_OK;
-}
-
-/* Perform machine dependent cif processing when we have a variadic function */
-
-ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs, unsigned int ntotalargs) {
-    cif->riscv_nfixedargs = nfixedargs;
-    return FFI_OK;
-}
-
-/* Low level routine for calling functions */
-extern void ffi_call_asm (void *stack, struct call_context *regs,
-			  void (*fn) (void), void *closure) FFI_HIDDEN;
-
-static void
-ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,
-	      void *closure)
-{
-    /* this is a conservative estimate, assuming a complex return value and
-       that all remaining arguments are long long / __int128 */
-    size_t arg_bytes = cif->nargs <= 3 ? 0 :
-        FFI_ALIGN(2 * sizeof(size_t) * (cif->nargs - 3), STKALIGN);
-    size_t rval_bytes = 0;
-    if (rvalue == NULL && cif->rtype->size > 2*__SIZEOF_POINTER__)
-        rval_bytes = FFI_ALIGN(cif->rtype->size, STKALIGN);
-    size_t alloc_size = arg_bytes + rval_bytes + sizeof(call_context);
-
-    /* the assembly code will deallocate all stack data at lower addresses
-       than the argument region, so we need to allocate the frame and the
-       return value after the arguments in a single allocation */
-    size_t alloc_base;
-    /* Argument region must be 16-byte aligned */
-    if (_Alignof(max_align_t) >= STKALIGN) {
-        /* since sizeof long double is normally 16, the compiler will
-           guarantee alloca alignment to at least that much */
-        alloc_base = (size_t)alloca(alloc_size);
-    } else {
-        alloc_base = FFI_ALIGN(alloca(alloc_size + STKALIGN - 1), STKALIGN);
-    }
-
-    if (rval_bytes)
-        rvalue = (void*)(alloc_base + arg_bytes);
-
-    call_builder cb;
-    cb.used_float = cb.used_integer = 0;
-    cb.aregs = (call_context*)(alloc_base + arg_bytes + rval_bytes);
-    cb.used_stack = (void*)alloc_base;
-
-    int return_by_ref = passed_by_ref(&cb, cif->rtype, 0);
-    if (return_by_ref)
-        marshal(&cb, &ffi_type_pointer, 0, &rvalue);
-
-    int i;
-    for (i = 0; i < cif->nargs; i++)
-        marshal(&cb, cif->arg_types[i], i >= cif->riscv_nfixedargs, avalue[i]);
-
-    ffi_call_asm ((void *) alloc_base, cb.aregs, fn, closure);
-
-    cb.used_float = cb.used_integer = 0;
-    if (!return_by_ref && rvalue)
-        unmarshal(&cb, cif->rtype, 0, rvalue);
-}
-
-void
-ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
-{
-  ffi_call_int(cif, fn, rvalue, avalue, NULL);
-}
-
-void
-ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,
-	     void **avalue, void *closure)
-{
-  ffi_call_int(cif, fn, rvalue, avalue, closure);
-}
-
-extern void ffi_closure_asm(void) FFI_HIDDEN;
-
-ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data, void *codeloc)
-{
-    uint32_t *tramp = (uint32_t *) &closure->tramp[0];
-    uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm;
-
-    if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)
-        return FFI_BAD_ABI;
-
-    /* we will call ffi_closure_inner with codeloc, not closure, but as long
-       as the memory is readable it should work */
-
-    tramp[0] = 0x00000317; /* auipc t1, 0 (i.e. t0 <- codeloc) */
-#if __SIZEOF_POINTER__ == 8
-    tramp[1] = 0x01033383; /* ld t2, 16(t1) */
-#else
-    tramp[1] = 0x01032383; /* lw t2, 16(t1) */
-#endif
-    tramp[2] = 0x00038067; /* jr t2 */
-    tramp[3] = 0x00000013; /* nop */
-    tramp[4] = fn;
-    tramp[5] = fn >> 32;
-
-    closure->cif = cif;
-    closure->fun = fun;
-    closure->user_data = user_data;
-
-    __builtin___clear_cache(codeloc, codeloc + FFI_TRAMPOLINE_SIZE);
-
-    return FFI_OK;
-}
-
-extern void ffi_go_closure_asm (void) FFI_HIDDEN;
-
-ffi_status
-ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
-		     void (*fun) (ffi_cif *, void *, void **, void *))
-{
-  if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)
-    return FFI_BAD_ABI;
-
-  closure->tramp = (void *) ffi_go_closure_asm;
-  closure->cif = cif;
-  closure->fun = fun;
-
-  return FFI_OK;
-}
-
-/* Called by the assembly code with aregs pointing to saved argument registers
-   and stack pointing to the stacked arguments.  Return values passed in
-   registers will be reloaded from aregs. */
-void FFI_HIDDEN
-ffi_closure_inner (ffi_cif *cif,
-		   void (*fun) (ffi_cif *, void *, void **, void *),
-		   void *user_data,
-		   size_t *stack, call_context *aregs)
-{
-    void **avalue = alloca(cif->nargs * sizeof(void*));
-    /* storage for arguments which will be copied by unmarshal().  We could
-       theoretically avoid the copies in many cases and use at most 128 bytes
-       of memory, but allocating disjoint storage for each argument is
-       simpler. */
-    char *astorage = alloca(cif->nargs * MAXCOPYARG);
-    void *rvalue;
-    call_builder cb;
-    int return_by_ref;
-    int i;
-
-    cb.aregs = aregs;
-    cb.used_integer = cb.used_float = 0;
-    cb.used_stack = stack;
-
-    return_by_ref = passed_by_ref(&cb, cif->rtype, 0);
-    if (return_by_ref)
-        unmarshal(&cb, &ffi_type_pointer, 0, &rvalue);
-    else
-        rvalue = alloca(cif->rtype->size);
-
-    for (i = 0; i < cif->nargs; i++)
-        avalue[i] = unmarshal(&cb, cif->arg_types[i],
-            i >= cif->riscv_nfixedargs, astorage + i*MAXCOPYARG);
-
-    fun (cif, rvalue, avalue, user_data);
-
-    if (!return_by_ref && cif->rtype->type != FFI_TYPE_VOID) {
-        cb.used_integer = cb.used_float = 0;
-        marshal(&cb, cif->rtype, 0, rvalue);
-    }
-}
diff --git a/src/riscv/ffitarget.h b/src/riscv/ffitarget.h
deleted file mode 100644
index 75e6462..0000000
--- a/src/riscv/ffitarget.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -----------------------------------------------------------------*-C-*-
-   ffitarget.h - 2014 Michael Knyszek
-
-   Target configuration macros for RISC-V.
-
-   Permission is hereby granted, free of charge, to any person obtaining
-   a copy of this software and associated documentation files (the
-   ``Software''), to deal in the Software without restriction, including
-   without limitation the rights to use, copy, modify, merge, publish,
-   distribute, sublicense, and/or sell copies of the Software, and to
-   permit persons to whom the Software is furnished to do so, subject to
-   the following conditions:
-
-   The above copyright notice and this permission notice shall be included
-   in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-   DEALINGS IN THE SOFTWARE.
-
-   ----------------------------------------------------------------------- */
-
-#ifndef LIBFFI_TARGET_H
-#define LIBFFI_TARGET_H
-
-#ifndef LIBFFI_H
-#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
-#endif
-
-#ifndef __riscv
-#error "libffi was configured for a RISC-V target but this does not appear to be a RISC-V compiler."
-#endif
-
-#ifndef LIBFFI_ASM
-
-typedef unsigned long ffi_arg;
-typedef   signed long ffi_sarg;
-
-/* FFI_UNUSED_NN and riscv_unused are to maintain ABI compatibility with a
-   distributed Berkeley patch from 2014, and can be removed at SONAME bump */
-typedef enum ffi_abi {
-    FFI_FIRST_ABI = 0,
-    FFI_SYSV,
-    FFI_UNUSED_1,
-    FFI_UNUSED_2,
-    FFI_UNUSED_3,
-    FFI_LAST_ABI,
-
-    FFI_DEFAULT_ABI = FFI_SYSV
-} ffi_abi;
-
-#endif /* LIBFFI_ASM */
-
-/* ---- Definitions for closures ----------------------------------------- */
-
-#define FFI_CLOSURES 1
-#define FFI_GO_CLOSURES 1
-#define FFI_TRAMPOLINE_SIZE 24
-#define FFI_NATIVE_RAW_API 0
-#define FFI_EXTRA_CIF_FIELDS unsigned riscv_nfixedargs; unsigned riscv_unused;
-#define FFI_TARGET_SPECIFIC_VARIADIC
-
-#endif
-
diff --git a/src/riscv/sysv.S b/src/riscv/sysv.S
deleted file mode 100644
index 522d0b0..0000000
--- a/src/riscv/sysv.S
+++ /dev/null
@@ -1,293 +0,0 @@
-/* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 2015 Michael Knyszek <mknyszek@berkeley.edu>
-                         2015 Andrew Waterman <waterman@cs.berkeley.edu>
-                         2018 Stef O'Rear <sorear2@gmail.com>
-
-   RISC-V Foreign Function Interface
-
-   Permission is hereby granted, free of charge, to any person obtaining
-   a copy of this software and associated documentation files (the
-   ``Software''), to deal in the Software without restriction, including
-   without limitation the rights to use, copy, modify, merge, publish,
-   distribute, sublicense, and/or sell copies of the Software, and to
-   permit persons to whom the Software is furnished to do so, subject to
-   the following conditions:
-
-   The above copyright notice and this permission notice shall be included
-   in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-   DEALINGS IN THE SOFTWARE.
-   ----------------------------------------------------------------------- */
-
-#define LIBFFI_ASM
-#include <fficonfig.h>
-#include <ffi.h>
-
-/* Define aliases so that we can handle all ABIs uniformly */
-
-#if __SIZEOF_POINTER__ == 8
-#define PTRS 8
-#define LARG ld
-#define SARG sd
-#else
-#define PTRS 4
-#define LARG lw
-#define SARG sw
-#endif
-
-#if __riscv_float_abi_double
-#define FLTS 8
-#define FLARG fld
-#define FSARG fsd
-#elif __riscv_float_abi_single
-#define FLTS 4
-#define FLARG flw
-#define FSARG fsw
-#else
-#define FLTS 0
-#endif
-
-#define fp s0
-
-    .text
-    .globl  ffi_call_asm
-    .type   ffi_call_asm, @function
-    .hidden ffi_call_asm
-/*
-  struct call_context {
-      floatreg fa[8];
-      intreg a[8];
-      intreg pad[rv32 ? 2 : 0];
-      intreg save_fp, save_ra;
-  }
-  void ffi_call_asm (size_t *stackargs, struct call_context *regargs,
-                     void (*fn) (void), void *closure);
-*/
-
-#define FRAME_LEN (8 * FLTS + 8 * PTRS + 16)
-
-ffi_call_asm:
-    .cfi_startproc
-
-    /*
-      We are NOT going to set up an ordinary stack frame.  In order to pass
-      the stacked args to the called function, we adjust our stack pointer to
-      a0, which is in the _caller's_ alloca area.  We establish our own stack
-      frame at the end of the call_context.
-
-      Anything below the arguments will be freed at this point, although we
-      preserve the call_context so that it can be read back in the caller.
-    */
-
-    .cfi_def_cfa 11, FRAME_LEN # interim CFA based on a1
-    SARG    fp, FRAME_LEN - 2*PTRS(a1)
-    .cfi_offset 8, -2*PTRS
-    SARG    ra, FRAME_LEN - 1*PTRS(a1)
-    .cfi_offset 1, -1*PTRS
-
-    addi    fp, a1, FRAME_LEN
-    mv      sp, a0
-    .cfi_def_cfa 8, 0 # our frame is fully set up
-
-    # Load arguments
-    mv      t1, a2
-    mv      t2, a3
-
-#if FLTS
-    FLARG   fa0, -FRAME_LEN+0*FLTS(fp)
-    FLARG   fa1, -FRAME_LEN+1*FLTS(fp)
-    FLARG   fa2, -FRAME_LEN+2*FLTS(fp)
-    FLARG   fa3, -FRAME_LEN+3*FLTS(fp)
-    FLARG   fa4, -FRAME_LEN+4*FLTS(fp)
-    FLARG   fa5, -FRAME_LEN+5*FLTS(fp)
-    FLARG   fa6, -FRAME_LEN+6*FLTS(fp)
-    FLARG   fa7, -FRAME_LEN+7*FLTS(fp)
-#endif
-
-    LARG    a0, -FRAME_LEN+8*FLTS+0*PTRS(fp)
-    LARG    a1, -FRAME_LEN+8*FLTS+1*PTRS(fp)
-    LARG    a2, -FRAME_LEN+8*FLTS+2*PTRS(fp)
-    LARG    a3, -FRAME_LEN+8*FLTS+3*PTRS(fp)
-    LARG    a4, -FRAME_LEN+8*FLTS+4*PTRS(fp)
-    LARG    a5, -FRAME_LEN+8*FLTS+5*PTRS(fp)
-    LARG    a6, -FRAME_LEN+8*FLTS+6*PTRS(fp)
-    LARG    a7, -FRAME_LEN+8*FLTS+7*PTRS(fp)
-
-    /* Call */
-    jalr    t1
-
-    /* Save return values - only a0/a1 (fa0/fa1) are used */
-#if FLTS
-    FSARG   fa0, -FRAME_LEN+0*FLTS(fp)
-    FSARG   fa1, -FRAME_LEN+1*FLTS(fp)
-#endif
-
-    SARG    a0, -FRAME_LEN+8*FLTS+0*PTRS(fp)
-    SARG    a1, -FRAME_LEN+8*FLTS+1*PTRS(fp)
-
-    /* Restore and return */
-    addi    sp, fp, -FRAME_LEN
-    .cfi_def_cfa 2, FRAME_LEN
-    LARG    ra, -1*PTRS(fp)
-    .cfi_restore 1
-    LARG    fp, -2*PTRS(fp)
-    .cfi_restore 8
-    ret
-    .cfi_endproc
-    .size   ffi_call_asm, .-ffi_call_asm
-
-
-/*
-  ffi_closure_asm. Expects address of the passed-in ffi_closure in t1.
-  void ffi_closure_inner (ffi_cif *cif,
-		          void (*fun) (ffi_cif *, void *, void **, void *),
-		          void *user_data,
-		          size_t *stackargs, struct call_context *regargs)
-*/
-
-    .globl ffi_closure_asm
-    .hidden ffi_closure_asm
-    .type ffi_closure_asm, @function
-ffi_closure_asm:
-    .cfi_startproc
-
-    addi    sp,  sp, -FRAME_LEN
-    .cfi_def_cfa_offset FRAME_LEN
-
-    /* make a frame */
-    SARG    fp, FRAME_LEN - 2*PTRS(sp)
-    .cfi_offset 8, -2*PTRS
-    SARG    ra, FRAME_LEN - 1*PTRS(sp)
-    .cfi_offset 1, -1*PTRS
-    addi    fp, sp, FRAME_LEN
-
-    /* save arguments */
-#if FLTS
-    FSARG   fa0, 0*FLTS(sp)
-    FSARG   fa1, 1*FLTS(sp)
-    FSARG   fa2, 2*FLTS(sp)
-    FSARG   fa3, 3*FLTS(sp)
-    FSARG   fa4, 4*FLTS(sp)
-    FSARG   fa5, 5*FLTS(sp)
-    FSARG   fa6, 6*FLTS(sp)
-    FSARG   fa7, 7*FLTS(sp)
-#endif
-
-    SARG    a0, 8*FLTS+0*PTRS(sp)
-    SARG    a1, 8*FLTS+1*PTRS(sp)
-    SARG    a2, 8*FLTS+2*PTRS(sp)
-    SARG    a3, 8*FLTS+3*PTRS(sp)
-    SARG    a4, 8*FLTS+4*PTRS(sp)
-    SARG    a5, 8*FLTS+5*PTRS(sp)
-    SARG    a6, 8*FLTS+6*PTRS(sp)
-    SARG    a7, 8*FLTS+7*PTRS(sp)
-
-    /* enter C */
-    LARG    a0, FFI_TRAMPOLINE_SIZE+0*PTRS(t1)
-    LARG    a1, FFI_TRAMPOLINE_SIZE+1*PTRS(t1)
-    LARG    a2, FFI_TRAMPOLINE_SIZE+2*PTRS(t1)
-    addi    a3, sp, FRAME_LEN
-    mv      a4, sp
-
-    call    ffi_closure_inner
-
-    /* return values */
-#if FLTS
-    FLARG   fa0, 0*FLTS(sp)
-    FLARG   fa1, 1*FLTS(sp)
-#endif
-
-    LARG    a0, 8*FLTS+0*PTRS(sp)
-    LARG    a1, 8*FLTS+1*PTRS(sp)
-
-    /* restore and return */
-    LARG    ra, FRAME_LEN-1*PTRS(sp)
-    .cfi_restore 1
-    LARG    fp, FRAME_LEN-2*PTRS(sp)
-    .cfi_restore 8
-    addi    sp, sp, FRAME_LEN
-    .cfi_def_cfa_offset 0
-    ret
-    .cfi_endproc
-    .size ffi_closure_asm, .-ffi_closure_asm
-
-/*
-  ffi_go_closure_asm.  Expects address of the passed-in ffi_go_closure in t2.
-  void ffi_closure_inner (ffi_cif *cif,
-		          void (*fun) (ffi_cif *, void *, void **, void *),
-		          void *user_data,
-		          size_t *stackargs, struct call_context *regargs)
-*/
-
-    .globl ffi_go_closure_asm
-    .hidden ffi_go_closure_asm
-    .type ffi_go_closure_asm, @function
-ffi_go_closure_asm:
-    .cfi_startproc
-
-    addi    sp,  sp, -FRAME_LEN
-    .cfi_def_cfa_offset FRAME_LEN
-
-    /* make a frame */
-    SARG    fp, FRAME_LEN - 2*PTRS(sp)
-    .cfi_offset 8, -2*PTRS
-    SARG    ra, FRAME_LEN - 1*PTRS(sp)
-    .cfi_offset 1, -1*PTRS
-    addi    fp, sp, FRAME_LEN
-
-    /* save arguments */
-#if FLTS
-    FSARG   fa0, 0*FLTS(sp)
-    FSARG   fa1, 1*FLTS(sp)
-    FSARG   fa2, 2*FLTS(sp)
-    FSARG   fa3, 3*FLTS(sp)
-    FSARG   fa4, 4*FLTS(sp)
-    FSARG   fa5, 5*FLTS(sp)
-    FSARG   fa6, 6*FLTS(sp)
-    FSARG   fa7, 7*FLTS(sp)
-#endif
-
-    SARG    a0, 8*FLTS+0*PTRS(sp)
-    SARG    a1, 8*FLTS+1*PTRS(sp)
-    SARG    a2, 8*FLTS+2*PTRS(sp)
-    SARG    a3, 8*FLTS+3*PTRS(sp)
-    SARG    a4, 8*FLTS+4*PTRS(sp)
-    SARG    a5, 8*FLTS+5*PTRS(sp)
-    SARG    a6, 8*FLTS+6*PTRS(sp)
-    SARG    a7, 8*FLTS+7*PTRS(sp)
-
-    /* enter C */
-    LARG    a0, 1*PTRS(t2)
-    LARG    a1, 2*PTRS(t2)
-    mv      a2, t2
-    addi    a3, sp, FRAME_LEN
-    mv      a4, sp
-
-    call    ffi_closure_inner
-
-    /* return values */
-#if FLTS
-    FLARG   fa0, 0*FLTS(sp)
-    FLARG   fa1, 1*FLTS(sp)
-#endif
-
-    LARG    a0, 8*FLTS+0*PTRS(sp)
-    LARG    a1, 8*FLTS+1*PTRS(sp)
-
-    /* restore and return */
-    LARG    ra, FRAME_LEN-1*PTRS(sp)
-    .cfi_restore 1
-    LARG    fp, FRAME_LEN-2*PTRS(sp)
-    .cfi_restore 8
-    addi    sp, sp, FRAME_LEN
-    .cfi_def_cfa_offset 0
-    ret
-    .cfi_endproc
-    .size ffi_go_closure_asm, .-ffi_go_closure_asm
diff --git a/src/s390/ffi.c b/src/s390/ffi.c
index 4035b6e..520ec7c 100644
--- a/src/s390/ffi.c
+++ b/src/s390/ffi.c
@@ -1,9 +1,9 @@
 /* -----------------------------------------------------------------------
    ffi.c - Copyright (c) 2000, 2007 Software AG
            Copyright (c) 2008 Red Hat, Inc
-
+ 
    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
@@ -11,10 +11,10 @@
    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.
@@ -27,23 +27,24 @@
 /*                          Includes                                  */
 /*                          --------                                  */
 /*====================================================================*/
-
+ 
 #include <ffi.h>
 #include <ffi_common.h>
-#include <stdint.h>
-#include "internal.h"
-
+ 
+#include <stdlib.h>
+#include <stdio.h>
+ 
 /*====================== End of Includes =============================*/
-
+ 
 /*====================================================================*/
 /*                           Defines                                  */
 /*                           -------                                  */
 /*====================================================================*/
 
-/* Maximum number of GPRs available for argument passing.  */
+/* Maximum number of GPRs available for argument passing.  */ 
 #define MAX_GPRARGS 5
 
-/* Maximum number of FPRs available for argument passing.  */
+/* Maximum number of FPRs available for argument passing.  */ 
 #ifdef __s390x__
 #define MAX_FPRARGS 4
 #else
@@ -53,30 +54,47 @@
 /* Round to multiple of 16.  */
 #define ROUND_SIZE(size) (((size) + 15) & ~15)
 
-/*===================== End of Defines ===============================*/
+/* 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 *);
+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                                 */
 /*                          ---------                                 */
 /*====================================================================*/
-
-struct call_frame
-{
-  void *back_chain;
-  void *eos;
-  unsigned long gpr_args[5];
-  unsigned long gpr_save[9];
-  unsigned long long fpr_args[4];
-};
-
-extern void FFI_HIDDEN ffi_call_SYSV(struct call_frame *, unsigned, void *,
-			             void (*fn)(void), void *);
+ 
+extern void ffi_call_SYSV(unsigned,
+			  extended_cif *,
+			  void (*)(unsigned char *, extended_cif *),
+			  unsigned,
+			  void *,
+			  void (*fn)(void));
 
 extern void ffi_closure_SYSV(void);
-extern void ffi_go_closure_SYSV(void);
-
+ 
 /*====================== End of Externals ============================*/
-
+ 
 /*====================================================================*/
 /*                                                                    */
 /* Name     - ffi_check_struct_type.                                  */
@@ -85,7 +103,7 @@
 /*            general purpose or floating point register.             */
 /*                                                                    */
 /*====================================================================*/
-
+ 
 static int
 ffi_check_struct_type (ffi_type *arg)
 {
@@ -93,7 +111,7 @@
 
   /* 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
+  while (arg->type == FFI_TYPE_STRUCT 
          && arg->elements[0] && !arg->elements[1])
     arg = arg->elements[0];
 
@@ -126,9 +144,193 @@
   /* 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;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+      /* 16-byte long double is passed like a struct.  */
+      if (type == FFI_TYPE_LONGDOUBLE)
+	type = FFI_TYPE_STRUCT;
+#endif
+
+      /* Check how a structure type is passed.  */
+      if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
+	{
+	  if (type == FFI_TYPE_COMPLEX)
+	    type = FFI_TYPE_POINTER;
+	  else
+	    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;
+	    }
+	}
+
+      /* Now handle all primitive int/pointer/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_POINTER:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = (unsigned long)*(unsigned char **) arg;
+	    else
+	      p_ov[n_ov++] = (unsigned long)*(unsigned char **) 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.                                   */
@@ -136,8 +338,8 @@
 /* Function - Perform machine dependent CIF processing.               */
 /*                                                                    */
 /*====================================================================*/
-
-ffi_status FFI_HIDDEN
+ 
+ffi_status
 ffi_prep_cif_machdep(ffi_cif *cif)
 {
   size_t struct_size = 0;
@@ -148,7 +350,7 @@
   ffi_type **ptr;
   int i;
 
-  /* Determine return value handling.  */
+  /* Determine return value handling.  */ 
 
   switch (cif->rtype->type)
     {
@@ -162,7 +364,7 @@
       case FFI_TYPE_COMPLEX:
 	cif->flags = FFI390_RET_STRUCT;
 	n_gpr++;  /* We need one GPR to pass the pointer.  */
-	break;
+	break; 
 
       /* Floating point values are returned in fpr 0.  */
       case FFI_TYPE_FLOAT:
@@ -201,14 +403,14 @@
 	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++)
@@ -236,7 +438,7 @@
 	}
 
       /* Now handle all primitive int/float data types.  */
-      switch (type)
+      switch (type) 
 	{
 	  /* The first MAX_FPRARGS floating point arguments
 	     go in FPRs, the rest overflow to the stack.  */
@@ -247,7 +449,7 @@
 	    else
 	      n_ov += sizeof (double) / sizeof (long);
 	    break;
-
+	
 	  case FFI_TYPE_FLOAT:
 	    if (n_fpr < MAX_FPRARGS)
 	      n_fpr++;
@@ -257,9 +459,9 @@
 
 	  /* 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
+	     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:
@@ -275,7 +477,7 @@
 	  /* Everything else is passed in GPRs (until MAX_GPRARGS
 	     have been used) or overflows to the stack.  */
 
-	  default:
+	  default: 
 	    if (n_gpr < MAX_GPRARGS)
 	      n_gpr++;
 	    else
@@ -288,12 +490,12 @@
      and temporary structure copies.  */
 
   cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
-
+ 
   return FFI_OK;
 }
-
+ 
 /*======================== End of Routine ============================*/
-
+ 
 /*====================================================================*/
 /*                                                                    */
 /* Name     - ffi_call.                                               */
@@ -301,195 +503,42 @@
 /* Function - Call the FFI routine.                                   */
 /*                                                                    */
 /*====================================================================*/
-
-static void
-ffi_call_int(ffi_cif *cif,
-	     void (*fn)(void),
-	     void *rvalue,
-	     void **avalue,
-	     void *closure)
+ 
+void
+ffi_call(ffi_cif *cif,
+	 void (*fn)(void),
+	 void *rvalue,
+	 void **avalue)
 {
   int ret_type = cif->flags;
-  size_t rsize = 0, bytes = cif->bytes;
-  unsigned char *stack, *p_struct;
-  struct call_frame *frame;
-  unsigned long *p_ov, *p_gpr;
-  unsigned long long *p_fpr;
-  int n_fpr, n_gpr, n_ov, i, n;
-  ffi_type **arg_types;
-
-  FFI_ASSERT (cif->abi == FFI_SYSV);
+  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_IN_MEM)
-	rsize = cif->rtype->size;
+      if (ret_type == FFI390_RET_STRUCT)
+	ecif.rvalue = alloca (cif->rtype->size);
       else
 	ret_type = FFI390_RET_VOID;
-    }
+    } 
 
-  /* The stack space will be filled with those areas:
-
-	dummy structure return		    (highest addresses)
-	  FPR argument register save area
-	  GPR argument register save area
-	stack frame for ffi_call_SYSV
-	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.
-
-     Note that we're going to create the stack frame for both
-     ffi_call_SYSV _and_ the target function right here.  This
-     works because we don't make any function calls with more
-     than 5 arguments (indeed only memcpy and ffi_call_SYSV),
-     and thus we don't have any stacked outgoing parameters.  */
-
-  stack = alloca (bytes + sizeof(struct call_frame) + rsize);
-  frame = (struct call_frame *)(stack + bytes);
-  if (rsize)
-    rvalue = frame + 1;
-
-  /* Link the new frame back to the one from this function.  */
-  frame->back_chain = __builtin_frame_address (0);
-
-  /* Fill in all of the argument stuff.  */
-  p_ov = (unsigned long *)stack;
-  p_struct = (unsigned char *)frame;
-  p_gpr = frame->gpr_args;
-  p_fpr = frame->fpr_args;
-  n_fpr = n_gpr = n_ov = 0;
-
-  /* If we returning a structure then we set the first parameter register
-     to the address of where we are returning this structure.  */
-  if (cif->flags & FFI390_RET_IN_MEM)
-    p_gpr[n_gpr++] = (uintptr_t) rvalue;
-
-  /* Now for the arguments.  */
-  arg_types = cif->arg_types;
-  for (i = 0, n = cif->nargs; i < n; ++i)
+  switch (cif->abi)
     {
-      ffi_type *ty = arg_types[i];
-      void *arg = avalue[i];
-      int type = ty->type;
-      ffi_arg val;
-
-    restart:
-      switch (type)
-	{
-	case FFI_TYPE_SINT8:
-	  val = *(SINT8 *)arg;
-	  goto do_int;
-	case FFI_TYPE_UINT8:
-	  val = *(UINT8 *)arg;
-	  goto do_int;
-	case FFI_TYPE_SINT16:
-	  val = *(SINT16 *)arg;
-	  goto do_int;
-	case FFI_TYPE_UINT16:
-	  val = *(UINT16 *)arg;
-	  goto do_int;
-	case FFI_TYPE_INT:
-	case FFI_TYPE_SINT32:
-	  val = *(SINT32 *)arg;
-	  goto do_int;
-	case FFI_TYPE_UINT32:
-	  val = *(UINT32 *)arg;
-	  goto do_int;
-	case FFI_TYPE_POINTER:
-	  val = *(uintptr_t *)arg;
-	do_int:
-	  *(n_gpr < MAX_GPRARGS ? p_gpr + n_gpr++ : p_ov + n_ov++) = val;
-	  break;
-
-	case FFI_TYPE_UINT64:
-	case FFI_TYPE_SINT64:
-#ifdef __s390x__
-	  val = *(UINT64 *)arg;
-	  goto do_int;
-#else
-	  if (n_gpr == MAX_GPRARGS-1)
-	    n_gpr = MAX_GPRARGS;
-	  if (n_gpr < MAX_GPRARGS)
-	    p_gpr[n_gpr++] = ((UINT32 *) arg)[0],
-	    p_gpr[n_gpr++] = ((UINT32 *) arg)[1];
-	  else
-	    p_ov[n_ov++] = ((UINT32 *) arg)[0],
-	    p_ov[n_ov++] = ((UINT32 *) arg)[1];
-#endif
-	  break;
-
-	case FFI_TYPE_DOUBLE:
-	  if (n_fpr < MAX_FPRARGS)
-	    p_fpr[n_fpr++] = *(UINT64 *) arg;
-	  else
-	    {
-#ifdef __s390x__
-	      p_ov[n_ov++] = *(UINT64 *) arg;
-#else
-	      p_ov[n_ov++] = ((UINT32 *) arg)[0],
-	      p_ov[n_ov++] = ((UINT32 *) arg)[1];
-#endif
-	    }
-	  break;
-
-	case FFI_TYPE_FLOAT:
-	  val = *(UINT32 *)arg;
-	  if (n_fpr < MAX_FPRARGS)
-	    p_fpr[n_fpr++] = (UINT64)val << 32;
-	  else
-	    p_ov[n_ov++] = val;
-	  break;
-
-	case FFI_TYPE_STRUCT:
-          /* Check how a structure type is passed.  */
-	  type = ffi_check_struct_type (ty);
-	  /* Some structures are passed via a type they contain.  */
-	  if (type != FFI_TYPE_POINTER)
-	    goto restart;
-	  /* ... otherwise, passed by reference.  fallthru.  */
-
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-	case FFI_TYPE_LONGDOUBLE:
-	  /* 16-byte long double is passed via reference.  */
-#endif
-	case FFI_TYPE_COMPLEX:
-	  /* Complex types are passed via reference.  */
-	  p_struct -= ROUND_SIZE (ty->size);
-	  memcpy (p_struct, arg, ty->size);
-	  val = (uintptr_t)p_struct;
-	  goto do_int;
-
-	default:
-	  FFI_ASSERT (0);
-	  break;
-        }
+      case FFI_SYSV:
+        ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
+		       ret_type, ecif.rvalue, fn);
+        break;
+ 
+      default:
+        FFI_ASSERT (0);
+        break;
     }
-
-  ffi_call_SYSV (frame, ret_type & FFI360_RET_MASK, rvalue, fn, closure);
 }
-
-void
-ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
-{
-  ffi_call_int(cif, fn, rvalue, avalue, NULL);
-}
-
-void
-ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	     void **avalue, void *closure)
-{
-  ffi_call_int(cif, fn, rvalue, avalue, closure);
-}
-
+ 
 /*======================== End of Routine ============================*/
 
 /*====================================================================*/
@@ -499,11 +548,9 @@
 /* Function - Call a FFI closure target function.                     */
 /*                                                                    */
 /*====================================================================*/
-
-void FFI_HIDDEN
-ffi_closure_helper_SYSV (ffi_cif *cif,
-			 void (*fun)(ffi_cif*,void*,void**,void*),
-			 void *user_data,
+ 
+void
+ffi_closure_helper_SYSV (ffi_closure *closure,
 			 unsigned long *p_gpr,
 			 unsigned long long *p_fpr,
 			 unsigned long *p_ov)
@@ -522,16 +569,21 @@
   int i;
 
   /* Allocate buffer for argument list pointers.  */
-  p_arg = avalue = alloca (cif->nargs * sizeof (void *));
 
-  /* If we returning a structure, pass the structure address
-     directly to the target function.  Otherwise, have the target
+  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 (cif->flags & FFI390_RET_IN_MEM)
+
+  if (closure->cif->flags == FFI390_RET_STRUCT)
     rvalue = (void *) p_gpr[n_gpr++];
 
   /* Now for the arguments.  */
-  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, p_arg++, ptr++)
+
+  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;
@@ -550,7 +602,7 @@
 	  else
 	    type = ffi_check_struct_type (*ptr);
 
-	  /* If we pass the struct via pointer, remember to
+	  /* If we pass the struct via pointer, remember to 
 	     retrieve the pointer later.  */
 	  if (type == FFI_TYPE_POINTER)
 	    deref_struct_pointer = 1;
@@ -558,32 +610,30 @@
 
       /* Pointers are passed like UINTs of the same size.  */
       if (type == FFI_TYPE_POINTER)
-	{
 #ifdef __s390x__
-	  type = FFI_TYPE_UINT64;
+	type = FFI_TYPE_UINT64;
 #else
-	  type = FFI_TYPE_UINT32;
+	type = FFI_TYPE_UINT32;
 #endif
-	}
 
       /* Now handle all primitive int/float data types.  */
-      switch (type)
+      switch (type) 
 	{
 	  case FFI_TYPE_DOUBLE:
 	    if (n_fpr < MAX_FPRARGS)
 	      *p_arg = &p_fpr[n_fpr++];
 	    else
-	      *p_arg = &p_ov[n_ov],
+	      *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__
@@ -600,7 +650,7 @@
 	      *p_arg = &p_ov[n_ov], n_ov += 2;
 #endif
 	    break;
-
+ 
 	  case FFI_TYPE_INT:
 	  case FFI_TYPE_UINT32:
 	  case FFI_TYPE_SINT32:
@@ -609,7 +659,7 @@
 	    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)
@@ -625,7 +675,7 @@
 	    else
 	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
 	    break;
-
+ 
 	  default:
 	    FFI_ASSERT (0);
 	    break;
@@ -639,10 +689,10 @@
 
 
   /* Call the target function.  */
-  (fun) (cif, rvalue, avalue, user_data);
+  (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
 
   /* Convert the return value.  */
-  switch (cif->rtype->type)
+  switch (closure->cif->rtype->type)
     {
       /* Void is easy, and so is struct.  */
       case FFI_TYPE_VOID:
@@ -693,7 +743,7 @@
         break;
     }
 }
-
+ 
 /*======================== End of Routine ============================*/
 
 /*====================================================================*/
@@ -703,7 +753,7 @@
 /* Function - Prepare a FFI closure.                                  */
 /*                                                                    */
 /*====================================================================*/
-
+ 
 ffi_status
 ffi_prep_closure_loc (ffi_closure *closure,
 		      ffi_cif *cif,
@@ -711,46 +761,32 @@
 		      void *user_data,
 		      void *codeloc)
 {
-  static unsigned short const template[] = {
-    0x0d10,			/* basr %r1,0 */
-#ifndef __s390x__
-    0x9801, 0x1006,		/* lm %r0,%r1,6(%r1) */
-#else
-    0xeb01, 0x100e, 0x0004,	/* lmg %r0,%r1,14(%r1) */
-#endif
-    0x07f1			/* br %r1 */
-  };
-
-  unsigned long *tramp = (unsigned long *)&closure->tramp;
-
   if (cif->abi != FFI_SYSV)
     return FFI_BAD_ABI;
 
-  memcpy (tramp, template, sizeof(template));
-  tramp[2] = (unsigned long)codeloc;
-  tramp[3] = (unsigned long)&ffi_closure_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)codeloc;
+  *(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)codeloc;
+  *(long  *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
+#endif 
+ 
   closure->cif = cif;
-  closure->fun = fun;
   closure->user_data = user_data;
-
+  closure->fun = fun;
+ 
   return FFI_OK;
 }
 
 /*======================== End of Routine ============================*/
-
-/* Build a Go language closure.  */
-
-ffi_status
-ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
-		     void (*fun)(ffi_cif*,void*,void**,void*))
-{
-  if (cif->abi != FFI_SYSV)
-    return FFI_BAD_ABI;
-
-  closure->tramp = ffi_go_closure_SYSV;
-  closure->cif = cif;
-  closure->fun = fun;
-
-  return FFI_OK;
-}
+ 
diff --git a/src/s390/ffitarget.h b/src/s390/ffitarget.h
index d8a4ee4..0e4868a 100644
--- a/src/s390/ffitarget.h
+++ b/src/s390/ffitarget.h
@@ -58,7 +58,6 @@
 /* ---- Definitions for closures ----------------------------------------- */
 
 #define FFI_CLOSURES 1
-#define FFI_GO_CLOSURES 1
 #ifdef S390X
 #define FFI_TRAMPOLINE_SIZE 32
 #else
diff --git a/src/s390/internal.h b/src/s390/internal.h
deleted file mode 100644
index b875578..0000000
--- a/src/s390/internal.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* If these values change, sysv.S must be adapted!  */
-#define FFI390_RET_DOUBLE	0
-#define FFI390_RET_FLOAT	1
-#define FFI390_RET_INT64	2
-#define FFI390_RET_INT32	3
-#define FFI390_RET_VOID		4
-
-#define FFI360_RET_MASK		7
-#define FFI390_RET_IN_MEM	8
-
-#define FFI390_RET_STRUCT	(FFI390_RET_VOID | FFI390_RET_IN_MEM)
diff --git a/src/s390/sysv.S b/src/s390/sysv.S
index c4b5006..4731a31 100644
--- a/src/s390/sysv.S
+++ b/src/s390/sysv.S
@@ -1,9 +1,9 @@
 /* -----------------------------------------------------------------------
    sysv.S - Copyright (c) 2000 Software AG
             Copyright (c) 2008 Red Hat, Inc.
-
+ 
    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
@@ -11,10 +11,10 @@
    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
@@ -29,296 +29,405 @@
 #include <fficonfig.h>
 #include <ffi.h>
 
-	.text
-
 #ifndef __s390x__
+ 
+.text
 
-	# r2:	frame
-	# r3:	ret_type
-	# r4:	ret_addr
-	# r5:	fun
-	# r6:	closure
-
+	# r2:	cif->bytes
+	# r3:	&ecif
+	# r4:	ffi_prep_args
+	# r5:	ret_type
+	# r6:	ecif.rvalue
+	# ov:	fn 
+ 
 	# This assumes we are using gas.
-	.balign	8
 	.globl	ffi_call_SYSV
-	FFI_HIDDEN(ffi_call_SYSV)
 	.type	ffi_call_SYSV,%function
 ffi_call_SYSV:
-	.cfi_startproc
-	st	%r6,44(%r2)			# Save registers
-	stm	%r12,%r14,48(%r2)
-	lr	%r13,%r2			# Install frame pointer
-	.cfi_rel_offset r6, 44
-	.cfi_rel_offset r12, 48
-	.cfi_rel_offset r13, 52
-	.cfi_rel_offset r14, 56
-	.cfi_def_cfa_register r13
-	st	%r2,0(%r15)			# Set up back chain
-	sla	%r3,3				# ret_type *= 8
-	lr	%r12,%r4			# Save ret_addr
-	lr	%r1,%r5				# Save fun
-	lr	%r0,%r6				# Install static chain
+.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:
 
-	# Set return address, so that there is only one indirect jump.
-#ifdef HAVE_AS_S390_ZARCH
-	larl	%r14,.Ltable
-	ar	%r14,%r3
-#else
-	basr	%r14,0
-0:	la	%r14,.Ltable-0b(%r14,%r3)
-#endif
+	la	%r2,96(%r15)			# Save area
+						# r3 already holds &ecif
+	basr	%r14,%r4			# Call ffi_prep_args
 
-	lm	%r2,%r6,8(%r13)			# Load arguments
-	ld	%f0,64(%r13)
-	ld	%f2,72(%r13)
-	br	%r1				# ... and call function
+	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
 
-	.balign	8
+.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:
-# FFI390_RET_DOUBLE
-	std	%f0,0(%r12)
-	j	.Ldone
+	.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
 
-	.balign	8
-# FFI390_RET_FLOAT
-	ste	%f0,0(%r12)
-	j	.Ldone
-
-	.balign	8
-# FFI390_RET_INT64
-	st	%r3,4(%r12)
-	nop
-	# fallthru
-
-	.balign	8
-# FFI390_RET_INT32
-	st	%r2,0(%r12)
-	nop
-	# fallthru
-
-	.balign	8
-# FFI390_RET_VOID
-.Ldone:
-	l	%r14,56(%r13)
-	l	%r12,48(%r13)
-	l	%r6,44(%r13)
-	l	%r13,52(%r13)
-	.cfi_restore 14
-	.cfi_restore 13
-	.cfi_restore 12
-	.cfi_restore 6
-	.cfi_def_cfa r15, 96
-	br	%r14
-	.cfi_endproc
-	.size	 ffi_call_SYSV,.-ffi_call_SYSV
+.LFE1: 
+.ffi_call_SYSV_end:
+	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
 
 
-	.balign	8
-	.globl	ffi_go_closure_SYSV
-	FFI_HIDDEN(ffi_go_closure_SYSV)
-	.type	ffi_go_closure_SYSV,%function
-ffi_go_closure_SYSV:
-	.cfi_startproc
-	stm	%r2,%r6,8(%r15)			# Save arguments
-	lr	%r4,%r0				# Load closure -> user_data
-	l	%r2,4(%r4)			#   ->cif
-	l	%r3,8(%r4)			#   ->fun
-	j	.Ldoclosure
-	.cfi_endproc
-
-	.balign	8
 	.globl	ffi_closure_SYSV
-	FFI_HIDDEN(ffi_closure_SYSV)
 	.type	ffi_closure_SYSV,%function
 ffi_closure_SYSV:
-	.cfi_startproc
-	stm	%r2,%r6,8(%r15)			# Save arguments
-	lr	%r4,%r0				# Closure
-	l	%r2,16(%r4)			#   ->cif
-	l	%r3,20(%r4)			#   ->fun
-	l	%r4,24(%r4)			#   ->user_data
-.Ldoclosure:
+.LFB2:
 	stm	%r12,%r15,48(%r15)		# Save registers
-	lr	%r12,%r15
-	.cfi_def_cfa_register r12
-	.cfi_rel_offset r6, 24
-	.cfi_rel_offset r12, 48
-	.cfi_rel_offset r13, 52
-	.cfi_rel_offset r14, 56
-	.cfi_rel_offset r15, 60
-#ifndef HAVE_AS_S390_ZARCH
+.LCFI10:
 	basr	%r13,0				# Set up base register
 .Lcbase:
-	l	%r1,.Lchelper-.Lcbase(%r13)	# Get helper function
-#endif
-	ahi	%r15,-96-8			# Set up stack frame
-	st	%r12,0(%r15)			# Set up back chain
+	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
 
-	std	%f0,64(%r12)			# Save fp arguments
-	std	%f2,72(%r12)
+	bas	%r14,0(%r12,%r13)		# Call helper
 
-	la	%r5,96(%r12)			# Overflow
-	st	%r5,96(%r15)
-	la	%r6,64(%r12)			# FPRs
-	la	%r5,8(%r12)			# GPRs
-#ifdef HAVE_AS_S390_ZARCH
-	brasl	%r14,ffi_closure_helper_SYSV
-#else
-	bas	%r14,0(%r1,%r13)		# Call helper
-#endif
+	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
 
-	lr	%r15,%r12
-	.cfi_def_cfa_register r15
-	lm	%r12,%r14,48(%r12)		# Restore saved registers
-	l	%r6,24(%r15)
-	ld	%f0,64(%r15)			# Load return registers
-	lm	%r2,%r3,8(%r15)
-	br	%r14
-	.cfi_endproc
-
-#ifndef HAVE_AS_S390_ZARCH
 	.align 4
 .Lchelper:
 	.long	ffi_closure_helper_SYSV-.Lcbase
-#endif
 
-	.size	 ffi_closure_SYSV,.-ffi_closure_SYSV
+.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
-
-	# r2:	frame
-	# r3:	ret_type
-	# r4:	ret_addr
-	# r5:	fun
-	# r6:	closure
-
+ 
+.text
+ 
+	# r2:	cif->bytes
+	# r3:	&ecif
+	# r4:	ffi_prep_args
+	# r5:	ret_type
+	# r6:	ecif.rvalue
+	# ov:	fn 
+ 
 	# This assumes we are using gas.
-	.balign	8
 	.globl	ffi_call_SYSV
-	FFI_HIDDEN(ffi_call_SYSV)
 	.type	ffi_call_SYSV,%function
 ffi_call_SYSV:
-	.cfi_startproc
-	stg	%r6,88(%r2)			# Save registers
-	stmg	%r12,%r14,96(%r2)
-	lgr	%r13,%r2			# Install frame pointer
-	.cfi_rel_offset r6, 88
-	.cfi_rel_offset r12, 96
-	.cfi_rel_offset r13, 104
-	.cfi_rel_offset r14, 112
-	.cfi_def_cfa_register r13
-	stg	%r2,0(%r15)			# Set up back chain
-	larl	%r14,.Ltable			# Set up return address
-	slag	%r3,%r3,3			# ret_type *= 8
-	lgr	%r12,%r4			# Save ret_addr
-	lgr	%r1,%r5				# Save fun
-	lgr	%r0,%r6				# Install static chain
-	agr	%r14,%r3
-	lmg	%r2,%r6,16(%r13)		# Load arguments
-	ld	%f0,128(%r13)
-	ld	%f2,136(%r13)
-	ld	%f4,144(%r13)
-	ld	%f6,152(%r13)
-	br	%r1				# ... and call function
+.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:
 
-	.balign	8
+	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:
-# FFI390_RET_DOUBLE
-	std	%f0,0(%r12)
-	j	.Ldone
+	.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
 
-	.balign	8
-# FFI390_RET_DOUBLE
-	ste	%f0,0(%r12)
-	j	.Ldone
-
-	.balign	8
-# FFI390_RET_INT64
-	stg	%r2,0(%r12)
-
-	.balign	8
-# FFI390_RET_INT32
-	# Never used, as we always store type ffi_arg.
-	# But the stg above is 6 bytes and we cannot
-	# jump around this case, so fall through.
-	nop
-	nop
-
-	.balign	8
-# FFI390_RET_VOID
-.Ldone:
-	lg	%r14,112(%r13)
-	lg	%r12,96(%r13)
-	lg	%r6,88(%r13)
-	lg	%r13,104(%r13)
-	.cfi_restore r14
-	.cfi_restore r13
-	.cfi_restore r12
-	.cfi_restore r6
-	.cfi_def_cfa r15, 160
-	br	%r14
-	.cfi_endproc
-	.size	 ffi_call_SYSV,.-ffi_call_SYSV
+.LFE1: 
+.ffi_call_SYSV_end:
+	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
 
 
-	.balign	8
-	.globl	ffi_go_closure_SYSV
-	FFI_HIDDEN(ffi_go_closure_SYSV)
-	.type	ffi_go_closure_SYSV,%function
-ffi_go_closure_SYSV:
-	.cfi_startproc
-	stmg	%r2,%r6,16(%r15)		# Save arguments
-	lgr	%r4,%r0				# Load closure -> user_data
-	lg	%r2,8(%r4)			#   ->cif
-	lg	%r3,16(%r4)			#   ->fun
-	j	.Ldoclosure
-	.cfi_endproc
-	.size	 ffi_go_closure_SYSV,.-ffi_go_closure_SYSV
-
-
-	.balign	8
 	.globl	ffi_closure_SYSV
-	FFI_HIDDEN(ffi_closure_SYSV)
 	.type	ffi_closure_SYSV,%function
 ffi_closure_SYSV:
-	.cfi_startproc
+.LFB2:
+	stmg	%r14,%r15,112(%r15)		# Save registers
+.LCFI10:
 	stmg	%r2,%r6,16(%r15)		# Save arguments
-	lgr	%r4,%r0				# Load closure
-	lg	%r2,32(%r4)			#   ->cif
-	lg	%r3,40(%r4)			#   ->fun
-	lg	%r4,48(%r4)			#   ->user_data
-.Ldoclosure:
-	stmg	%r13,%r15,104(%r15)		# Save registers
-	lgr	%r13,%r15
-	.cfi_def_cfa_register r13
-	.cfi_rel_offset r6, 48
-	.cfi_rel_offset r13, 104
-	.cfi_rel_offset r14, 112
-	.cfi_rel_offset r15, 120
-	aghi	%r15,-160-16			# Set up stack frame
-	stg	%r13,0(%r15)			# Set up back chain
+	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
 
-	std	%f0,128(%r13)			# Save fp arguments
-	std	%f2,136(%r13)
-	std	%f4,144(%r13)
-	std	%f6,152(%r13)
-	la	%r5,160(%r13)			# Overflow
-	stg	%r5,160(%r15)
-	la	%r6,128(%r13)			# FPRs
-	la	%r5,16(%r13)			# GPRs
 	brasl	%r14,ffi_closure_helper_SYSV	# Call helper
 
-	lgr	%r15,%r13
-	.cfi_def_cfa_register r15
-	lmg	%r13,%r14,104(%r13)		# Restore saved registers
-	lg	%r6,48(%r15)
-	ld	%f0,128(%r15)			# Load return registers
-	lg	%r2,16(%r15)
+	lg	%r14,160+112(%r15)
+	ld	%f0,160+128(%r15)		# Load return registers
+	lg	%r2,160+16(%r15)
+	la	%r15,160(%r15)
 	br	%r14
-	.cfi_endproc
-	.size	 ffi_closure_SYSV,.-ffi_closure_SYSV
-#endif /* !s390x */
+.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
 
 #if defined __ELF__ && defined __linux__
 	.section	.note.GNU-stack,"",@progbits
diff --git a/src/sparc/ffi.c b/src/sparc/ffi.c
index 9e406d0..9f0fded 100644
--- a/src/sparc/ffi.c
+++ b/src/sparc/ffi.c
@@ -27,442 +27,655 @@
 
 #include <ffi.h>
 #include <ffi_common.h>
+
 #include <stdlib.h>
-#include "internal.h"
 
-#ifndef SPARC64
 
-/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
-   all further uses in this file will refer to the 128-bit type.  */
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-# if FFI_TYPE_LONGDOUBLE != 4
-#  error FFI_TYPE_LONGDOUBLE out of date
-# endif
-#else
-# undef FFI_TYPE_LONGDOUBLE
-# define FFI_TYPE_LONGDOUBLE 4
-#endif
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
 
-/* Perform machine dependent cif processing */
-ffi_status FFI_HIDDEN
-ffi_prep_cif_machdep(ffi_cif *cif)
+void ffi_prep_args_v8(char *stack, extended_cif *ecif)
 {
-  ffi_type *rtype = cif->rtype;
-  int rtt = rtype->type;
-  size_t bytes;
-  int i, n, flags;
-
-  /* Set the return type flag */
-  switch (rtt)
-    {
-    case FFI_TYPE_VOID:
-      flags = SPARC_RET_VOID;
-      break;
-    case FFI_TYPE_FLOAT:
-      flags = SPARC_RET_F_1;
-      break;
-    case FFI_TYPE_DOUBLE:
-      flags = SPARC_RET_F_2;
-      break;
-    case FFI_TYPE_LONGDOUBLE:
-    case FFI_TYPE_STRUCT:
-      flags = (rtype->size & 0xfff) << SPARC_SIZEMASK_SHIFT;
-      flags |= SPARC_RET_STRUCT;
-      break;
-    case FFI_TYPE_SINT8:
-      flags = SPARC_RET_SINT8;
-      break;
-    case FFI_TYPE_UINT8:
-      flags = SPARC_RET_UINT8;
-      break;
-    case FFI_TYPE_SINT16:
-      flags = SPARC_RET_SINT16;
-      break;
-    case FFI_TYPE_UINT16:
-      flags = SPARC_RET_UINT16;
-      break;
-    case FFI_TYPE_INT:
-    case FFI_TYPE_SINT32:
-    case FFI_TYPE_UINT32:
-    case FFI_TYPE_POINTER:
-      flags = SPARC_RET_UINT32;
-      break;
-    case FFI_TYPE_SINT64:
-    case FFI_TYPE_UINT64:
-      flags = SPARC_RET_INT64;
-      break;
-    case FFI_TYPE_COMPLEX:
-      rtt = rtype->elements[0]->type;
-      switch (rtt)
-	{
-	case FFI_TYPE_FLOAT:
-	  flags = SPARC_RET_F_2;
-	  break;
-	case FFI_TYPE_DOUBLE:
-	  flags = SPARC_RET_F_4;
-	  break;
-	case FFI_TYPE_LONGDOUBLE:
-	  flags = SPARC_RET_F_8;
-	  break;
-	case FFI_TYPE_SINT64:
-	case FFI_TYPE_UINT64:
-	  flags = SPARC_RET_INT128;
-	  break;
-	case FFI_TYPE_INT:
-	case FFI_TYPE_SINT32:
-	case FFI_TYPE_UINT32:
-	  flags = SPARC_RET_INT64;
-	  break;
-	case FFI_TYPE_SINT16:
-	case FFI_TYPE_UINT16:
-	  flags = SP_V8_RET_CPLX16;
-	  break;
-	case FFI_TYPE_SINT8:
-	case FFI_TYPE_UINT8:
-	  flags = SP_V8_RET_CPLX8;
-	  break;
-	default:
-	  abort();
-	}
-      break;
-    default:
-      abort();
-    }
-  cif->flags = flags;
-
-  bytes = 0;
-  for (i = 0, n = cif->nargs; i < n; ++i)
-    {
-      ffi_type *ty = cif->arg_types[i];
-      size_t z = ty->size;
-      int tt = ty->type;
-
-      switch (tt)
-	{
-	case FFI_TYPE_STRUCT:
-	case FFI_TYPE_LONGDOUBLE:
-	by_reference:
-	  /* Passed by reference.  */
-	  z = 4;
-	  break;
-
-	case FFI_TYPE_COMPLEX:
-	  tt = ty->elements[0]->type;
-	  if (tt == FFI_TYPE_FLOAT || z > 8)
-	    goto by_reference;
-	  /* FALLTHRU */
-
-	default:
-	  z = FFI_ALIGN(z, 4);
-	}
-      bytes += z;
-    }
-
-  /* Sparc call frames require that space is allocated for 6 args,
-     even if they aren't used. Make that space if necessary.  */
-  if (bytes < 6 * 4)
-    bytes = 6 * 4;
-
-  /* The ABI always requires space for the struct return pointer.  */
-  bytes += 4;
-
-  /* The stack must be 2 word aligned, so round bytes up appropriately. */
-  bytes = FFI_ALIGN(bytes, 2 * 4);
-
-  /* Include the call frame to prep_args.  */
-  bytes += 4*16 + 4*8;
-  cif->bytes = bytes;
-
-  return FFI_OK;
-}
-
-extern void ffi_call_v8(ffi_cif *cif, void (*fn)(void), void *rvalue,
-			void **avalue, size_t bytes, void *closure) FFI_HIDDEN;
-
-int FFI_HIDDEN
-ffi_prep_args_v8(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue)
-{
+  int i;
+  void **p_argv;
+  char *argp;
   ffi_type **p_arg;
-  int flags = cif->flags;
-  int i, nargs;
 
-  if (rvalue == NULL)
-    {
-      if ((flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT)
-	{
-	  /* Since we pass the pointer to the callee, we need a value.
-	     We allowed for this space in ffi_call, before ffi_call_v8
-	     alloca'd the space.  */
-	  rvalue = (char *)argp + cif->bytes;
-	}
-      else
-	{
-	  /* Otherwise, we can ignore the return value.  */
-	  flags = SPARC_RET_VOID;
-	}
-    }
+  /* Skip 16 words for the window save area */
+  argp = stack + 16*sizeof(int);
 
-  /* This could only really be done when we are returning a structure.
-     However, the space is reserved so we can do it unconditionally.  */
-  *argp++ = (unsigned long)rvalue;
+  /* This should only really be done when we are returning a structure,
+     however, it's faster just to do it all the time...
+
+  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
+  *(int *) argp = (long)ecif->rvalue;
+
+  /* And 1 word for the  structure return value. */
+  argp += sizeof(int);
 
 #ifdef USING_PURIFY
-  /* Purify will probably complain in our assembly routine,
-     unless we zero out this memory. */
-  memset(argp, 0, 6*4);
+  /* Purify will probably complain in our assembly routine, unless we
+     zero out this memory. */
+
+  ((int*)argp)[0] = 0;
+  ((int*)argp)[1] = 0;
+  ((int*)argp)[2] = 0;
+  ((int*)argp)[3] = 0;
+  ((int*)argp)[4] = 0;
+  ((int*)argp)[5] = 0;
 #endif
 
-  p_arg = cif->arg_types;
-  for (i = 0, nargs = cif->nargs; i < nargs; i++)
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
     {
-      ffi_type *ty = p_arg[i];
-      void *a = avalue[i];
-      int tt = ty->type;
       size_t z;
 
-      switch (tt)
-	{
-	case FFI_TYPE_STRUCT:
-	case FFI_TYPE_LONGDOUBLE:
-	by_reference:
-	  *argp++ = (unsigned long)a;
-	  break;
-
-	case FFI_TYPE_DOUBLE:
-	case FFI_TYPE_UINT64:
-	case FFI_TYPE_SINT64:
-	  memcpy(argp, a, 8);
-	  argp += 2;
-	  break;
-
-	case FFI_TYPE_INT:
-	case FFI_TYPE_FLOAT:
-	case FFI_TYPE_UINT32:
-	case FFI_TYPE_SINT32:
-	case FFI_TYPE_POINTER:
-	  *argp++ = *(unsigned *)a;
-	  break;
-
-	case FFI_TYPE_UINT8:
-	  *argp++ = *(UINT8 *)a;
-	  break;
-	case FFI_TYPE_SINT8:
-	  *argp++ = *(SINT8 *)a;
-	  break;
-	case FFI_TYPE_UINT16:
-	  *argp++ = *(UINT16 *)a;
-	  break;
-	case FFI_TYPE_SINT16:
-	  *argp++ = *(SINT16 *)a;
-	  break;
-
-        case FFI_TYPE_COMPLEX:
-	  tt = ty->elements[0]->type;
-	  z = ty->size;
-	  if (tt == FFI_TYPE_FLOAT || z > 8)
-	    goto by_reference;
-	  if (z < 4)
+	  if ((*p_arg)->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	      || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
+#endif
+	      )
 	    {
-	      memcpy((char *)argp + 4 - z, a, z);
-	      argp++;
+	      *(unsigned int *) argp = (unsigned long)(* p_argv);
+	      z = sizeof(int);
 	    }
 	  else
 	    {
-	      memcpy(argp, a, z);
-	      argp += z / 4;
-	    }
-	  break;
+	      z = (*p_arg)->size;
+	      if (z < sizeof(int))
+		{
+		  z = sizeof(int);
+		  switch ((*p_arg)->type)
+		    {
+		    case FFI_TYPE_SINT8:
+		      *(signed int *) argp = *(SINT8 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_UINT8:
+		      *(unsigned int *) argp = *(UINT8 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_SINT16:
+		      *(signed int *) argp = *(SINT16 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_UINT16:
+		      *(unsigned int *) argp = *(UINT16 *)(* p_argv);
+		      break;
 
+		    default:
+		      FFI_ASSERT(0);
+		    }
+		}
+	      else
+		{
+		  memcpy(argp, *p_argv, z);
+		}
+	    }
+	  p_argv++;
+	  argp += z;
+    }
+  
+  return;
+}
+
+int ffi_prep_args_v9(char *stack, extended_cif *ecif)
+{
+  int i, ret = 0;
+  int tmp;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  tmp = 0;
+
+  /* Skip 16 words for the window save area */
+  argp = stack + 16*sizeof(long long);
+
+#ifdef USING_PURIFY
+  /* Purify will probably complain in our assembly routine, unless we
+     zero out this memory. */
+
+  ((long long*)argp)[0] = 0;
+  ((long long*)argp)[1] = 0;
+  ((long long*)argp)[2] = 0;
+  ((long long*)argp)[3] = 0;
+  ((long long*)argp)[4] = 0;
+  ((long long*)argp)[5] = 0;
+#endif
+
+  p_argv = ecif->avalue;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
+      ecif->cif->rtype->size > 32)
+    {
+      *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
+      argp += sizeof(long long);
+      tmp = 1;
+    }
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
+       i++, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_STRUCT:
+	  if (z > 16)
+	    {
+	      /* For structures larger than 16 bytes we pass reference.  */
+	      *(unsigned long long *) argp = (unsigned long)* p_argv;
+	      argp += sizeof(long long);
+	      tmp++;
+	      p_argv++;
+	      continue;
+	    }
+	  /* FALLTHROUGH */
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	  ret = 1; /* We should promote into FP regs as well as integer.  */
+	  break;
+	}
+      if (z < sizeof(long long))
+	{
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed long long *) argp = *(SINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT8:
+	      *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT16:
+	      *(signed long long *) argp = *(SINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT16:
+	      *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT32:
+	      *(signed long long *) argp = *(SINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT32:
+	      *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_FLOAT:
+	      *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
+	      break;
+
+	    case FFI_TYPE_STRUCT:
+	      memcpy(argp, *p_argv, z);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  z = sizeof(long long);
+	  tmp++;
+	}
+      else if (z == sizeof(long long))
+	{
+	  memcpy(argp, *p_argv, z);
+	  z = sizeof(long long);
+	  tmp++;
+	}
+      else
+	{
+	  if ((tmp & 1) && (*p_arg)->alignment > 8)
+	    {
+	      tmp++;
+	      argp += sizeof(long long);
+	    }
+	  memcpy(argp, *p_argv, z);
+	  z = 2 * sizeof(long long);
+	  tmp += 2;
+	}
+      p_argv++;
+      argp += z;
+    }
+
+  return ret;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int wordsize;
+
+  if (cif->abi != FFI_V9)
+    {
+      wordsize = 4;
+
+      /* If we are returning a struct, this will already have been added.
+	 Otherwise we need to add it because it's always got to be there! */
+
+      if (cif->rtype->type != FFI_TYPE_STRUCT)
+	cif->bytes += wordsize;
+
+      /* sparc call frames require that space is allocated for 6 args,
+	 even if they aren't used. Make that space if necessary. */
+  
+      if (cif->bytes < 4*6+4)
+	cif->bytes = 4*6+4;
+    }
+  else
+    {
+      wordsize = 8;
+
+      /* sparc call frames require that space is allocated for 6 args,
+	 even if they aren't used. Make that space if necessary. */
+  
+      if (cif->bytes < 8*6)
+	cif->bytes = 8*6;
+    }
+
+  /* Adjust cif->bytes. to include 16 words for the window save area,
+     and maybe the struct/union return pointer area, */
+
+  cif->bytes += 16 * wordsize;
+
+  /* The stack must be 2 word aligned, so round bytes up
+     appropriately. */
+
+  cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+#endif
+      cif->flags = cif->rtype->type;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      if (cif->abi == FFI_V9 && cif->rtype->size > 32)
+	cif->flags = FFI_TYPE_VOID;
+      else
+	cif->flags = FFI_TYPE_STRUCT;
+      break;
+
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT16:
+      if (cif->abi == FFI_V9)
+	cif->flags = FFI_TYPE_INT;
+      else
+	cif->flags = cif->rtype->type;
+      break;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      if (cif->abi == FFI_V9)
+	cif->flags = FFI_TYPE_INT;
+      else
+	cif->flags = FFI_TYPE_SINT64;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+  return FFI_OK;
+}
+
+int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
+{
+  ffi_type **ptr = &arg->elements[0];
+
+  while (*ptr != NULL)
+    {
+      if (off & ((*ptr)->alignment - 1))
+	off = ALIGN(off, (*ptr)->alignment);
+
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_STRUCT:
+	  off = ffi_v9_layout_struct(*ptr, off, ret, intg, flt);
+	  off = ALIGN(off, FFI_SIZEOF_ARG);
+	  break;
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	  memmove(ret + off, flt + off, (*ptr)->size);
+	  off += (*ptr)->size;
+	  break;
 	default:
-	  abort();
+	  memmove(ret + off, intg + off, (*ptr)->size);
+	  off += (*ptr)->size;
+	  break;
+	}
+      ptr++;
+    }
+  return off;
+}
+
+
+#ifdef SPARC64
+extern int ffi_call_v9(void *, extended_cif *, unsigned, 
+		       unsigned, unsigned *, void (*fn)(void));
+#else
+extern int ffi_call_v8(void *, extended_cif *, unsigned, 
+		       unsigned, unsigned *, void (*fn)(void));
+#endif
+
+#ifndef __GNUC__
+void ffi_flush_icache (void *, size_t);
+#endif
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+  void *rval = rvalue;
+
+  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		        */
+
+  ecif.rvalue = rvalue;
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      if (cif->rtype->size <= 32)
+	rval = alloca(64);
+      else
+	{
+	  rval = NULL;
+	  if (rvalue == NULL)
+	    ecif.rvalue = alloca(cif->rtype->size);
 	}
     }
 
-  return flags;
-}
-
-static void
-ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	      void **avalue, void *closure)
-{
-  size_t bytes = cif->bytes;
-
-  FFI_ASSERT (cif->abi == FFI_V8);
-
-  /* If we've not got a return value, we need to create one if we've
-     got to pass the return value to the callee.  Otherwise ignore it.  */
-  if (rvalue == NULL
-      && (cif->flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT)
-    bytes += FFI_ALIGN (cif->rtype->size, 8);
-
-  ffi_call_v8(cif, fn, rvalue, avalue, -bytes, closure);
-}
-
-void
-ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, NULL);
-}
-
-void
-ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	     void **avalue, void *closure)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, closure);
-}
-
-#ifdef __GNUC__
-static inline void
-ffi_flush_icache (void *p)
-{
-  /* SPARC v8 requires 5 instructions for flush to be visible */
-  asm volatile ("iflush	%0; iflush %0+8; nop; nop; nop; nop; nop"
-		: : "r" (p) : "memory");
-}
+  switch (cif->abi) 
+    {
+    case FFI_V8:
+#ifdef SPARC64
+      /* We don't yet support calling 32bit code from 64bit */
+      FFI_ASSERT(0);
 #else
-extern void ffi_flush_icache (void *) FFI_HIDDEN;
+      if (rvalue && (cif->rtype->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  || cif->flags == FFI_TYPE_LONGDOUBLE
+#endif
+	  ))
+	{
+	  /* For v8, we need an "unimp" with size of returning struct */
+	  /* behind "call", so we alloc some executable space for it. */
+	  /* l7 is used, we need to make sure v8.S doesn't use %l7.   */
+	  unsigned int *call_struct = NULL;
+	  ffi_closure_alloc(32, (void **)&call_struct);
+	  if (call_struct)
+	    {
+	      unsigned long f = (unsigned long)fn;
+	      call_struct[0] = 0xae10001f;		 /* mov   %i7, %l7	 */
+	      call_struct[1] = 0xbe10000f;		 /* mov   %o7, %i7	 */
+	      call_struct[2] = 0x03000000 | f >> 10;     /* sethi %hi(fn), %g1	 */
+	      call_struct[3] = 0x9fc06000 | (f & 0x3ff); /* jmp %g1+%lo(fn), %o7 */
+	      call_struct[4] = 0x01000000;		 /* nop			 */
+	      if (cif->rtype->size < 0x7f)
+		call_struct[5] = cif->rtype->size;	 /* unimp		 */
+	      else
+		call_struct[5] = 0x01000000;	     	 /* nop			 */
+	      call_struct[6] = 0x81c7e008;		 /* ret			 */
+	      call_struct[7] = 0xbe100017;		 /* mov   %l7, %i7	 */
+#ifdef __GNUC__
+	      asm volatile ("iflush %0; iflush %0+8; iflush %0+16; iflush %0+24" : :
+			    "r" (call_struct) : "memory");
+	      /* SPARC v8 requires 5 instructions for flush to be visible */
+	      asm volatile ("nop; nop; nop; nop; nop");
+#else
+	      ffi_flush_icache (call_struct, 32);
+#endif
+	      ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
+			  cif->flags, rvalue, call_struct);
+	      ffi_closure_free(call_struct);
+	    }
+	  else
+	    {
+	      ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
+			  cif->flags, rvalue, fn);
+	    }
+	}
+      else
+	{
+	  ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
+		      cif->flags, rvalue, fn);
+	}
+#endif
+      break;
+    case FFI_V9:
+#ifdef SPARC64
+      ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes,
+		  cif->flags, rval, fn);
+      if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
+	ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
+#else
+      /* And vice versa */
+      FFI_ASSERT(0);
+#endif
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+
+#ifdef SPARC64
+extern void ffi_closure_v9(void);
+#else
+extern void ffi_closure_v8(void);
 #endif
 
-extern void ffi_closure_v8(void) FFI_HIDDEN;
-extern void ffi_go_closure_v8(void) FFI_HIDDEN;
-
 ffi_status
-ffi_prep_closure_loc (ffi_closure *closure,
-		      ffi_cif *cif,
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
 		      void (*fun)(ffi_cif*, void*, void**, void*),
 		      void *user_data,
 		      void *codeloc)
 {
   unsigned int *tramp = (unsigned int *) &closure->tramp[0];
-  unsigned long ctx = (unsigned long) closure;
-  unsigned long fn = (unsigned long) ffi_closure_v8;
-
+  unsigned long fn;
+#ifdef SPARC64
+  /* Trampoline address is equal to the closure address.  We take advantage
+     of that to reduce the trampoline size by 8 bytes. */
+  if (cif->abi != FFI_V9)
+    return FFI_BAD_ABI;
+  fn = (unsigned long) ffi_closure_v9;
+  tramp[0] = 0x83414000;	/* rd	%pc, %g1	*/
+  tramp[1] = 0xca586010;	/* ldx	[%g1+16], %g5	*/
+  tramp[2] = 0x81c14000;	/* jmp	%g5		*/
+  tramp[3] = 0x01000000;	/* nop			*/
+  *((unsigned long *) &tramp[4]) = fn;
+#else
+  unsigned long ctx = (unsigned long) codeloc;
   if (cif->abi != FFI_V8)
     return FFI_BAD_ABI;
-
+  fn = (unsigned long) ffi_closure_v8;
   tramp[0] = 0x03000000 | fn >> 10;	/* sethi %hi(fn), %g1	*/
   tramp[1] = 0x05000000 | ctx >> 10;	/* sethi %hi(ctx), %g2	*/
   tramp[2] = 0x81c06000 | (fn & 0x3ff);	/* jmp   %g1+%lo(fn)	*/
   tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or    %g2, %lo(ctx)	*/
+#endif
 
   closure->cif = cif;
   closure->fun = fun;
   closure->user_data = user_data;
 
-  ffi_flush_icache (closure);
+  /* Flush the Icache.  closure is 8 bytes aligned.  */
+#ifdef __GNUC__
+#ifdef SPARC64
+  asm volatile ("flush	%0; flush %0+8" : : "r" (closure) : "memory");
+#else
+  asm volatile ("iflush	%0; iflush %0+8" : : "r" (closure) : "memory");
+  /* SPARC v8 requires 5 instructions for flush to be visible */
+  asm volatile ("nop; nop; nop; nop; nop");
+#endif
+#else
+  ffi_flush_icache (closure, 16);
+#endif
 
   return FFI_OK;
 }
 
-ffi_status
-ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
-		     void (*fun)(ffi_cif*, void*, void**, void*))
+int
+ffi_closure_sparc_inner_v8(ffi_closure *closure,
+  void *rvalue, unsigned long *gpr, unsigned long *scratch)
 {
-  if (cif->abi != FFI_V8)
-    return FFI_BAD_ABI;
-
-  closure->tramp = ffi_go_closure_v8;
-  closure->cif = cif;
-  closure->fun = fun;
-
-  return FFI_OK;
-}
-
-int FFI_HIDDEN
-ffi_closure_sparc_inner_v8(ffi_cif *cif, 
-			   void (*fun)(ffi_cif*, void*, void**, void*),
-			   void *user_data, void *rvalue,
-			   unsigned long *argp)
-{
+  ffi_cif *cif;
   ffi_type **arg_types;
   void **avalue;
-  int i, nargs, flags;
+  int i, argn;
 
+  cif = closure->cif;
   arg_types = cif->arg_types;
-  nargs = cif->nargs;
-  flags = cif->flags;
-  avalue = alloca(nargs * sizeof(void *));
+  avalue = alloca(cif->nargs * sizeof(void *));
 
   /* Copy the caller's structure return address so that the closure
-     returns the data directly to the caller.  Also install it so we
-     can return the address in %o0.  */
-  if ((flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT)
-    {
-      void *new_rvalue = (void *)*argp;
-      *(void **)rvalue = new_rvalue;
-      rvalue = new_rvalue;
-    }
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE  
+      || cif->flags == FFI_TYPE_LONGDOUBLE
+#endif
+     )
+    rvalue = (void *) gpr[0];
 
   /* Always skip the structure return address.  */
-  argp++;
+  argn = 1;
 
   /* Grab the addresses of the arguments from the stack frame.  */
-  for (i = 0; i < nargs; i++)
+  for (i = 0; i < cif->nargs; i++)
     {
-      ffi_type *ty = arg_types[i];
-      int tt = ty->type;
-      void *a = argp;
-      size_t z;
-
-      switch (tt)
+      if (arg_types[i]->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+         )
 	{
-	case FFI_TYPE_STRUCT:
-	case FFI_TYPE_LONGDOUBLE:
-	by_reference:
 	  /* Straight copy of invisible reference.  */
-	  a = (void *)*argp;
-	  break;
-
-	case FFI_TYPE_DOUBLE:
-	case FFI_TYPE_SINT64:
-	case FFI_TYPE_UINT64:
-	  if ((unsigned long)a & 7)
-	    {
-	      /* Align on a 8-byte boundary.  */
-	      UINT64 *tmp = alloca(8);
-	      *tmp = ((UINT64)argp[0] << 32) | argp[1];
-	      a = tmp;
-	    }
-	  argp++;
-	  break;
-
-	case FFI_TYPE_INT:
-	case FFI_TYPE_FLOAT:
-	case FFI_TYPE_UINT32:
-	case FFI_TYPE_SINT32:
-	case FFI_TYPE_POINTER:
-	  break;
-        case FFI_TYPE_UINT16:
-        case FFI_TYPE_SINT16:
-	  a += 2;
-	  break;
-        case FFI_TYPE_UINT8:
-        case FFI_TYPE_SINT8:
-	  a += 3;
-	  break;
-
-        case FFI_TYPE_COMPLEX:
-	  tt = ty->elements[0]->type;
-	  z = ty->size;
-	  if (tt == FFI_TYPE_FLOAT || z > 8)
-	    goto by_reference;
-	  if (z < 4)
-	    a += 4 - z;
-	  else if (z > 4)
-	    argp++;
-	  break;
-
-	default:
-	  abort();
+	  avalue[i] = (void *)gpr[argn++];
 	}
-      argp++;
-      avalue[i] = a;
+      else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
+	       || arg_types[i]->type == FFI_TYPE_SINT64
+	       || arg_types[i]->type == FFI_TYPE_UINT64)
+	       /* gpr is 8-byte aligned.  */
+	       && (argn % 2) != 0)
+	{
+	  /* Align on a 8-byte boundary.  */
+	  scratch[0] = gpr[argn];
+	  scratch[1] = gpr[argn+1];
+	  avalue[i] = scratch;
+	  scratch -= 2;
+	  argn += 2;
+	}
+      else
+	{
+	  /* Always right-justify.  */
+	  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	  avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+	}
     }
 
   /* Invoke the closure.  */
-  fun (cif, rvalue, avalue, user_data);
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
   /* Tell ffi_closure_sparc how to perform return type promotions.  */
-  return flags;
+  return cif->rtype->type;
 }
-#endif /* !SPARC64 */
+
+int
+ffi_closure_sparc_inner_v9(ffi_closure *closure,
+  void *rvalue, unsigned long *gpr, double *fpr)
+{
+  ffi_cif *cif;
+  ffi_type **arg_types;
+  void **avalue;
+  int i, argn, fp_slot_max;
+
+  cif = closure->cif;
+  arg_types = cif->arg_types;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  /* Copy the caller's structure return address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_VOID
+      && cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) gpr[0];
+      /* Skip the structure return address.  */
+      argn = 1;
+    }
+  else
+    argn = 0;
+
+  fp_slot_max = 16 - argn;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0; i < cif->nargs; i++)
+    {
+      if (arg_types[i]->type == FFI_TYPE_STRUCT)
+	{
+	  if (arg_types[i]->size > 16)
+	    {
+	      /* Straight copy of invisible reference.  */
+	      avalue[i] = (void *)gpr[argn++];
+	    }
+	  else
+	    {
+	      /* Left-justify.  */
+	      ffi_v9_layout_struct(arg_types[i],
+				   0,
+				   (char *) &gpr[argn],
+				   (char *) &gpr[argn],
+				   (char *) &fpr[argn]);
+	      avalue[i] = &gpr[argn];
+	      argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	    }
+	}
+      else
+	{
+	  /* Right-justify.  */
+	  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+
+	  /* Align on a 16-byte boundary.  */
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  if (arg_types[i]->type == FFI_TYPE_LONGDOUBLE && (argn % 2) != 0)
+	    argn++;
+#endif
+	  if (i < fp_slot_max
+	      && (arg_types[i]->type == FFI_TYPE_FLOAT
+		  || arg_types[i]->type == FFI_TYPE_DOUBLE
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+		  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+		  ))
+	    avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
+	  else
+	    avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+	}
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_sparc how to perform return type promotions.  */
+  return cif->rtype->type;
+}
diff --git a/src/sparc/ffi64.c b/src/sparc/ffi64.c
deleted file mode 100644
index 9e04061..0000000
--- a/src/sparc/ffi64.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 2011, 2013 Anthony Green
-           Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc.
-
-   SPARC Foreign Function Interface
-
-   Permission is hereby granted, free of charge, to any person obtaining
-   a copy of this software and associated documentation files (the
-   ``Software''), to deal in the Software without restriction, including
-   without limitation the rights to use, copy, modify, merge, publish,
-   distribute, sublicense, and/or sell copies of the Software, and to
-   permit persons to whom the Software is furnished to do so, subject to
-   the following conditions:
-
-   The above copyright notice and this permission notice shall be included
-   in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-   DEALINGS IN THE SOFTWARE.
-   ----------------------------------------------------------------------- */
-
-#include <ffi.h>
-#include <ffi_common.h>
-#include <stdlib.h>
-#include "internal.h"
-
-/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
-   all further uses in this file will refer to the 128-bit type.  */
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-# if FFI_TYPE_LONGDOUBLE != 4
-#  error FFI_TYPE_LONGDOUBLE out of date
-# endif
-#else
-# undef FFI_TYPE_LONGDOUBLE
-# define FFI_TYPE_LONGDOUBLE 4
-#endif
-
-#ifdef SPARC64
-
-/* Flatten the contents of a structure to the parts that are passed in
-   floating point registers.  The return is a bit mask wherein bit N
-   set means bytes [4*n, 4*n+3] are passed in %fN.
-
-   We encode both the (running) size (maximum 32) and mask (maxumum 255)
-   into one integer.  The size is placed in the low byte, so that align
-   and addition work correctly.  The mask is placed in the second byte.  */
-
-static int
-ffi_struct_float_mask (ffi_type *outer_type, int size_mask)
-{
-  ffi_type **elts;
-  ffi_type *t;
-
-  if (outer_type->type == FFI_TYPE_COMPLEX)
-    {
-      int m = 0, tt = outer_type->elements[0]->type;
-      size_t z = outer_type->size;
-
-      if (tt == FFI_TYPE_FLOAT
-	  || tt == FFI_TYPE_DOUBLE
-	  || tt == FFI_TYPE_LONGDOUBLE)
-        m = (1 << (z / 4)) - 1;
-      return (m << 8) | z;
-    }
-  FFI_ASSERT (outer_type->type == FFI_TYPE_STRUCT);
-
-  for (elts = outer_type->elements; (t = *elts) != NULL; elts++)
-    {
-      size_t z = t->size;
-      int o, m, tt;
-
-      size_mask = FFI_ALIGN(size_mask, t->alignment);
-      switch (t->type)
-	{
-	case FFI_TYPE_STRUCT:
-	  size_mask = ffi_struct_float_mask (t, size_mask);
-	  continue;
-	case FFI_TYPE_COMPLEX:
-	  tt = t->elements[0]->type;
-	  if (tt != FFI_TYPE_FLOAT
-	      && tt != FFI_TYPE_DOUBLE
-	      && tt != FFI_TYPE_LONGDOUBLE)
-	    break;
-	  /* FALLTHRU */
-	case FFI_TYPE_FLOAT:
-	case FFI_TYPE_DOUBLE:
-	case FFI_TYPE_LONGDOUBLE:
-	  m = (1 << (z / 4)) - 1;	/* compute mask for type */
-	  o = (size_mask >> 2) & 0x3f;	/* extract word offset */
-	  size_mask |= m << (o + 8);	/* insert mask into place */
-	  break;
-	}
-      size_mask += z;
-    }
-
-  size_mask = FFI_ALIGN(size_mask, outer_type->alignment);
-  FFI_ASSERT ((size_mask & 0xff) == outer_type->size);
-
-  return size_mask;
-}
-
-/* Merge floating point data into integer data.  If the structure is
-   entirely floating point, simply return a pointer to the fp data.  */
-
-static void *
-ffi_struct_float_merge (int size_mask, void *vi, void *vf)
-{
-  int size = size_mask & 0xff;
-  int mask = size_mask >> 8;
-  int n = size >> 2;
-
-  if (mask == 0)
-    return vi;
-  else if (mask == (1 << n) - 1)
-    return vf;
-  else
-    {
-      unsigned int *wi = vi, *wf = vf;
-      int i;
-
-      for (i = 0; i < n; ++i)
-	if ((mask >> i) & 1)
-	  wi[i] = wf[i];
-
-      return vi;
-    }
-}
-
-/* Similar, but place the data into VD in the end.  */
-
-void FFI_HIDDEN
-ffi_struct_float_copy (int size_mask, void *vd, void *vi, void *vf)
-{
-  int size = size_mask & 0xff;
-  int mask = size_mask >> 8;
-  int n = size >> 2;
-
-  if (mask == 0)
-    ;
-  else if (mask == (1 << n) - 1)
-    vi = vf;
-  else
-    {
-      unsigned int *wd = vd, *wi = vi, *wf = vf;
-      int i;
-
-      for (i = 0; i < n; ++i)
-	wd[i] = ((mask >> i) & 1 ? wf : wi)[i];
-      return;
-    }
-  memcpy (vd, vi, size);
-}
-
-/* Perform machine dependent cif processing */
-
-static ffi_status
-ffi_prep_cif_machdep_core(ffi_cif *cif)
-{
-  ffi_type *rtype = cif->rtype;
-  int rtt = rtype->type;
-  size_t bytes = 0;
-  int i, n, flags;
-
-  /* Set the return type flag */
-  switch (rtt)
-    {
-    case FFI_TYPE_VOID:
-      flags = SPARC_RET_VOID;
-      break;
-    case FFI_TYPE_FLOAT:
-      flags = SPARC_RET_F_1;
-      break;
-    case FFI_TYPE_DOUBLE:
-      flags = SPARC_RET_F_2;
-      break;
-    case FFI_TYPE_LONGDOUBLE:
-      flags = SPARC_RET_F_4;
-      break;
-
-    case FFI_TYPE_COMPLEX:
-    case FFI_TYPE_STRUCT:
-      if (rtype->size > 32)
-	{
-	  flags = SPARC_RET_VOID | SPARC_FLAG_RET_IN_MEM;
-	  bytes = 8;
-	}
-      else
-	{
-	  int size_mask = ffi_struct_float_mask (rtype, 0);
-	  int word_size = (size_mask >> 2) & 0x3f;
-	  int all_mask = (1 << word_size) - 1;
-	  int fp_mask = size_mask >> 8;
-
-	  flags = (size_mask << SPARC_SIZEMASK_SHIFT) | SPARC_RET_STRUCT;
-
-	  /* For special cases of all-int or all-fp, we can return
-	     the value directly without popping through a struct copy.  */
-	  if (fp_mask == 0)
-	    {
-	      if (rtype->alignment >= 8)
-		{
-		  if (rtype->size == 8)
-		    flags = SPARC_RET_INT64;
-		  else if (rtype->size == 16)
-		    flags = SPARC_RET_INT128;
-		}
-	    }
-	  else if (fp_mask == all_mask)
-	    switch (word_size)
-	      {
-	      case 1: flags = SPARC_RET_F_1; break;
-	      case 2: flags = SPARC_RET_F_2; break;
-	      case 3: flags = SP_V9_RET_F_3; break;
-	      case 4: flags = SPARC_RET_F_4; break;
-	      /* 5 word structures skipped; handled via RET_STRUCT.  */
-	      case 6: flags = SPARC_RET_F_6; break;
-	      /* 7 word structures skipped; handled via RET_STRUCT.  */
-	      case 8: flags = SPARC_RET_F_8; break;
-	      }
-	}
-      break;
-
-    case FFI_TYPE_SINT8:
-      flags = SPARC_RET_SINT8;
-      break;
-    case FFI_TYPE_UINT8:
-      flags = SPARC_RET_UINT8;
-      break;
-    case FFI_TYPE_SINT16:
-      flags = SPARC_RET_SINT16;
-      break;
-    case FFI_TYPE_UINT16:
-      flags = SPARC_RET_UINT16;
-      break;
-    case FFI_TYPE_INT:
-    case FFI_TYPE_SINT32:
-      flags = SP_V9_RET_SINT32;
-      break;
-    case FFI_TYPE_UINT32:
-      flags = SPARC_RET_UINT32;
-      break;
-    case FFI_TYPE_SINT64:
-    case FFI_TYPE_UINT64:
-    case FFI_TYPE_POINTER:
-      flags = SPARC_RET_INT64;
-      break;
-
-    default:
-      abort();
-    }
-
-  bytes = 0;
-  for (i = 0, n = cif->nargs; i < n; ++i)
-    {
-      ffi_type *ty = cif->arg_types[i];
-      size_t z = ty->size;
-      size_t a = ty->alignment;
-
-      switch (ty->type)
-	{
-	case FFI_TYPE_COMPLEX:
-	case FFI_TYPE_STRUCT:
-	  /* Large structs passed by reference.  */
-	  if (z > 16)
-	    {
-	      a = z = 8;
-	      break;
-	    }
-	  /* Small structs may be passed in integer or fp regs or both.  */
-	  if (bytes >= 16*8)
-	    break;
-	  if ((ffi_struct_float_mask (ty, 0) & 0xff00) == 0)
-	    break;
-	  /* FALLTHRU */
-	case FFI_TYPE_FLOAT:
-	case FFI_TYPE_DOUBLE:
-	case FFI_TYPE_LONGDOUBLE:
-	  flags |= SPARC_FLAG_FP_ARGS;
-	  break;
-	}
-      bytes = FFI_ALIGN(bytes, a);
-      bytes += FFI_ALIGN(z, 8);
-    }
-
-  /* Sparc call frames require that space is allocated for 6 args,
-     even if they aren't used. Make that space if necessary. */
-  if (bytes < 6 * 8)
-    bytes = 6 * 8;
-
-  /* The stack must be 2 word aligned, so round bytes up appropriately. */
-  bytes = FFI_ALIGN(bytes, 16);
-
-  /* Include the call frame to prep_args.  */
-  bytes += 8*16 + 8*8;
-
-  cif->bytes = bytes;
-  cif->flags = flags;
-  return FFI_OK;
-}
-
-ffi_status FFI_HIDDEN
-ffi_prep_cif_machdep(ffi_cif *cif)
-{
-  cif->nfixedargs = cif->nargs;
-  return ffi_prep_cif_machdep_core(cif);
-}
-
-ffi_status FFI_HIDDEN
-ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned nfixedargs, unsigned ntotalargs)
-{
-  cif->nfixedargs = nfixedargs;
-  return ffi_prep_cif_machdep_core(cif);
-}
-
-extern void ffi_call_v9(ffi_cif *cif, void (*fn)(void), void *rvalue,
-			void **avalue, size_t bytes, void *closure) FFI_HIDDEN;
-
-/* ffi_prep_args is called by the assembly routine once stack space
-   has been allocated for the function's arguments */
-
-int FFI_HIDDEN
-ffi_prep_args_v9(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue)
-{
-  ffi_type **p_arg;
-  int flags = cif->flags;
-  int i, nargs;
-
-  if (rvalue == NULL)
-    {
-      if (flags & SPARC_FLAG_RET_IN_MEM)
-	{
-	  /* Since we pass the pointer to the callee, we need a value.
-	     We allowed for this space in ffi_call, before ffi_call_v8
-	     alloca'd the space.  */
-	  rvalue = (char *)argp + cif->bytes;
-	}
-      else
-	{
-	  /* Otherwise, we can ignore the return value.  */
-	  flags = SPARC_RET_VOID;
-	}
-    }
-
-#ifdef USING_PURIFY
-  /* Purify will probably complain in our assembly routine,
-     unless we zero out this memory. */
-  memset(argp, 0, 6*8);
-#endif
-
-  if (flags & SPARC_FLAG_RET_IN_MEM)
-    *argp++ = (unsigned long)rvalue;
-
-  p_arg = cif->arg_types;
-  for (i = 0, nargs = cif->nargs; i < nargs; i++)
-    {
-      ffi_type *ty = p_arg[i];
-      void *a = avalue[i];
-      size_t z;
-
-      switch (ty->type)
-	{
-	case FFI_TYPE_SINT8:
-	  *argp++ = *(SINT8 *)a;
-	  break;
-	case FFI_TYPE_UINT8:
-	  *argp++ = *(UINT8 *)a;
-	  break;
-	case FFI_TYPE_SINT16:
-	  *argp++ = *(SINT16 *)a;
-	  break;
-	case FFI_TYPE_UINT16:
-	  *argp++ = *(UINT16 *)a;
-	  break;
-	case FFI_TYPE_INT:
-	case FFI_TYPE_SINT32:
-	  *argp++ = *(SINT32 *)a;
-	  break;
-	case FFI_TYPE_UINT32:
-	case FFI_TYPE_FLOAT:
-	  *argp++ = *(UINT32 *)a;
-	  break;
-	case FFI_TYPE_SINT64:
-	case FFI_TYPE_UINT64:
-	case FFI_TYPE_POINTER:
-	case FFI_TYPE_DOUBLE:
-	  *argp++ = *(UINT64 *)a;
-	  break;
-
-	case FFI_TYPE_LONGDOUBLE:
-	case FFI_TYPE_COMPLEX:
-	case FFI_TYPE_STRUCT:
-	  z = ty->size;
-	  if (z > 16)
-	    {
-	      /* For structures larger than 16 bytes we pass reference.  */
-	      *argp++ = (unsigned long)a;
-	      break;
-	    }
-	  if (((unsigned long)argp & 15) && ty->alignment > 8)
-	    argp++;
-	  memcpy(argp, a, z);
-	  argp += FFI_ALIGN(z, 8) / 8;
-	  break;
-
-	default:
-	  abort();
-	}
-    }
-
-  return flags;
-}
-
-static void
-ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue,
-	     void **avalue, void *closure)
-{
-  size_t bytes = cif->bytes;
-
-  FFI_ASSERT (cif->abi == FFI_V9);
-
-  if (rvalue == NULL && (cif->flags & SPARC_FLAG_RET_IN_MEM))
-    bytes += FFI_ALIGN (cif->rtype->size, 16);
-
-  ffi_call_v9(cif, fn, rvalue, avalue, -bytes, closure);
-}
-
-void
-ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
-{
-  ffi_call_int(cif, fn, rvalue, avalue, NULL);
-}
-
-void
-ffi_call_go(ffi_cif *cif, void (*fn)(void), void *rvalue,
-	    void **avalue, void *closure)
-{
-  ffi_call_int(cif, fn, rvalue, avalue, closure);
-}
-
-#ifdef __GNUC__
-static inline void
-ffi_flush_icache (void *p)
-{
-  asm volatile ("flush	%0; flush %0+8" : : "r" (p) : "memory");
-}
-#else
-extern void ffi_flush_icache (void *) FFI_HIDDEN;
-#endif
-
-extern void ffi_closure_v9(void) FFI_HIDDEN;
-extern void ffi_go_closure_v9(void) FFI_HIDDEN;
-
-ffi_status
-ffi_prep_closure_loc (ffi_closure* closure,
-		      ffi_cif* cif,
-		      void (*fun)(ffi_cif*, void*, void**, void*),
-		      void *user_data,
-		      void *codeloc)
-{
-  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
-  unsigned long fn;
-
-  if (cif->abi != FFI_V9)
-    return FFI_BAD_ABI;
-
-  /* Trampoline address is equal to the closure address.  We take advantage
-     of that to reduce the trampoline size by 8 bytes. */
-  fn = (unsigned long) ffi_closure_v9;
-  tramp[0] = 0x83414000;	/* rd	%pc, %g1	*/
-  tramp[1] = 0xca586010;	/* ldx	[%g1+16], %g5	*/
-  tramp[2] = 0x81c14000;	/* jmp	%g5		*/
-  tramp[3] = 0x01000000;	/* nop			*/
-  *((unsigned long *) &tramp[4]) = fn;
-
-  closure->cif = cif;
-  closure->fun = fun;
-  closure->user_data = user_data;
-
-  ffi_flush_icache (closure);
-
-  return FFI_OK;
-}
-
-ffi_status
-ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
-		     void (*fun)(ffi_cif*, void*, void**, void*))
-{
-  if (cif->abi != FFI_V9)
-    return FFI_BAD_ABI;
-
-  closure->tramp = ffi_go_closure_v9;
-  closure->cif = cif;
-  closure->fun = fun;
-
-  return FFI_OK;
-}
-
-int FFI_HIDDEN
-ffi_closure_sparc_inner_v9(ffi_cif *cif,
-			   void (*fun)(ffi_cif*, void*, void**, void*),
-			   void *user_data, void *rvalue,
-			   unsigned long *gpr, unsigned long *fpr)
-{
-  ffi_type **arg_types;
-  void **avalue;
-  int i, argn, argx, nargs, flags, nfixedargs;
-
-  arg_types = cif->arg_types;
-  nargs = cif->nargs;
-  flags = cif->flags;
-  nfixedargs = cif->nfixedargs;
-
-  avalue = alloca(nargs * sizeof(void *));
-
-  /* Copy the caller's structure return address so that the closure
-     returns the data directly to the caller.  */
-  if (flags & SPARC_FLAG_RET_IN_MEM)
-    {
-      rvalue = (void *) gpr[0];
-      /* Skip the structure return address.  */
-      argn = 1;
-    }
-  else
-    argn = 0;
-
-  /* Grab the addresses of the arguments from the stack frame.  */
-  for (i = 0; i < nargs; i++, argn = argx)
-    {
-      int named = i < nfixedargs;
-      ffi_type *ty = arg_types[i];
-      void *a = &gpr[argn];
-      size_t z;
-
-      argx = argn + 1;
-      switch (ty->type)
-	{
-	case FFI_TYPE_COMPLEX:
-	case FFI_TYPE_STRUCT:
-	  z = ty->size;
-	  if (z > 16)
-	    a = *(void **)a;
-	  else
-	    {
-	      argx = argn + FFI_ALIGN (z, 8) / 8;
-	      if (named && argn < 16)
-		{
-		  int size_mask = ffi_struct_float_mask (ty, 0);
-		  int argn_mask = (0xffff00 >> argn) & 0xff00;
-
-		  /* Eliminate fp registers off the end.  */
-		  size_mask = (size_mask & 0xff) | (size_mask & argn_mask);
-		  a = ffi_struct_float_merge (size_mask, gpr+argn, fpr+argn);
-		}
-	    }
-	  break;
-
-	case FFI_TYPE_LONGDOUBLE:
-	  argn = FFI_ALIGN (argn, 2);
-	  a = (named && argn < 16 ? fpr : gpr) + argn;
-	  argx = argn + 2;
-	  break;
-	case FFI_TYPE_DOUBLE:
-	  if (named && argn < 16)
-	    a = fpr + argn;
-	  break;
-	case FFI_TYPE_FLOAT:
-	  if (named && argn < 16)
-	    a = fpr + argn;
-	  a += 4;
-	  break;
-
-	case FFI_TYPE_UINT64:
-	case FFI_TYPE_SINT64:
-	case FFI_TYPE_POINTER:
-	  break;
-	case FFI_TYPE_INT:
-	case FFI_TYPE_UINT32:
-	case FFI_TYPE_SINT32:
-	  a += 4;
-	  break;
-        case FFI_TYPE_UINT16:
-        case FFI_TYPE_SINT16:
-	  a += 6;
-	  break;
-        case FFI_TYPE_UINT8:
-        case FFI_TYPE_SINT8:
-	  a += 7;
-	  break;
-
-	default:
-	  abort();
-	}
-      avalue[i] = a;
-    }
-
-  /* Invoke the closure.  */
-  fun (cif, rvalue, avalue, user_data);
-
-  /* Tell ffi_closure_sparc how to perform return type promotions.  */
-  return flags;
-}
-#endif /* SPARC64 */
diff --git a/src/sparc/ffitarget.h b/src/sparc/ffitarget.h
index 2f4cd9a..d89f787 100644
--- a/src/sparc/ffitarget.h
+++ b/src/sparc/ffitarget.h
@@ -46,29 +46,21 @@
 
 typedef enum ffi_abi {
   FFI_FIRST_ABI = 0,
-#ifdef SPARC64
-  FFI_V9,
-  FFI_DEFAULT_ABI = FFI_V9,
-#else
   FFI_V8,
-  FFI_DEFAULT_ABI = FFI_V8,
-#endif
-  FFI_LAST_ABI
-} ffi_abi;
-#endif
-
-#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 1
-#define FFI_TARGET_HAS_COMPLEX_TYPE 1
-
+  FFI_V8PLUS,
+  FFI_V9,
+  FFI_LAST_ABI,
 #ifdef SPARC64
-# define FFI_TARGET_SPECIFIC_VARIADIC 1
-# define FFI_EXTRA_CIF_FIELDS  unsigned int nfixedargs
+  FFI_DEFAULT_ABI = FFI_V9
+#else
+  FFI_DEFAULT_ABI = FFI_V8
+#endif
+} ffi_abi;
 #endif
 
 /* ---- Definitions for closures ----------------------------------------- */
 
 #define FFI_CLOSURES 1
-#define FFI_GO_CLOSURES 1
 #define FFI_NATIVE_RAW_API 0
 
 #ifdef SPARC64
diff --git a/src/sparc/internal.h b/src/sparc/internal.h
deleted file mode 100644
index 0a66472..0000000
--- a/src/sparc/internal.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#define SPARC_RET_VOID		0
-#define SPARC_RET_STRUCT	1
-#define SPARC_RET_UINT8		2
-#define SPARC_RET_SINT8		3
-#define SPARC_RET_UINT16	4
-#define SPARC_RET_SINT16	5
-#define SPARC_RET_UINT32	6
-#define SP_V9_RET_SINT32	7	/* v9 only */
-#define SP_V8_RET_CPLX16	7	/* v8 only */
-#define SPARC_RET_INT64		8
-#define SPARC_RET_INT128	9
-
-/* Note that F_7 is missing, and is handled by SPARC_RET_STRUCT.  */
-#define SPARC_RET_F_8		10
-#define SPARC_RET_F_6		11
-#define SPARC_RET_F_4		12
-#define SPARC_RET_F_2		13
-#define SP_V9_RET_F_3		14	/* v9 only */
-#define SP_V8_RET_CPLX8		14	/* v8 only */
-#define SPARC_RET_F_1		15
-
-#define SPARC_FLAG_RET_MASK	15
-#define SPARC_FLAG_RET_IN_MEM	32
-#define SPARC_FLAG_FP_ARGS	64
-
-#define SPARC_SIZEMASK_SHIFT	8
diff --git a/src/sparc/v8.S b/src/sparc/v8.S
index a2e4908..6bf7ac0 100644
--- a/src/sparc/v8.S
+++ b/src/sparc/v8.S
@@ -1,8 +1,8 @@
 /* -----------------------------------------------------------------------
    v8.S - Copyright (c) 2013  The Written Word, Inc.
 	  Copyright (c) 1996, 1997, 2003, 2004, 2008  Red Hat, Inc.
-
-   SPARC Foreign Function Interface
+   
+   SPARC Foreign Function Interface 
 
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
@@ -25,253 +25,179 @@
    DEALINGS IN THE SOFTWARE.
    ----------------------------------------------------------------------- */
 
-#define LIBFFI_ASM
+#define LIBFFI_ASM	
 #include <fficonfig.h>
 #include <ffi.h>
-#include "internal.h"
 
-#ifndef SPARC64
+#define STACKFRAME 96		/* Minimum stack framesize for SPARC */
+#define ARGS (64+4)		/* Offset of register area in frame */
 
-#define C2(X, Y)  X ## Y
-#define C1(X, Y)  C2(X, Y)
-
-#ifdef __USER_LABEL_PREFIX__
-# define C(Y)	C1(__USER_LABEL_PREFIX__, Y)
-#else
-# define C(Y)	Y
-#endif
-#define L(Y)	C1(.L, Y)
-
+#ifndef __GNUC__	
 	.text
-
-#ifndef __GNUC__
         .align 8
-	.globl	C(ffi_flush_icache)
-	.type	C(ffi_flush_icache),#function
-	FFI_HIDDEN(C(ffi_flush_icache))
+.globl ffi_flush_icache
+.globl _ffi_flush_icache
 
-C(ffi_flush_icache):
+ffi_flush_icache:
+_ffi_flush_icache:	
+        add %o0, %o1, %o2
+#ifdef SPARC64	
+1:	flush %o0
+#else	
 1:	iflush %o0
-	iflush %o+8
+#endif
+	add %o0, 8, %o0
+	cmp %o0, %o2
+	blt 1b
 	nop
 	nop
 	nop
 	nop
 	nop
 	retl
-	 nop
-	.size	C(ffi_flush_icache), . - C(ffi_flush_icache)
+	nop
+.ffi_flush_icache_end:
+	.size	ffi_flush_icache,.ffi_flush_icache_end-ffi_flush_icache
 #endif
 
-#if defined(__sun__) && defined(__svr4__)
-# define E(INDEX)	.align 16
-#else
-# define E(INDEX)	.align 16; .org 2b + INDEX * 16
-#endif
-
+	.text
         .align 8
-	.globl	C(ffi_call_v8)
-	.type	C(ffi_call_v8),#function
-	FFI_HIDDEN(C(ffi_call_v8))
+.globl ffi_call_v8
+.globl _ffi_call_v8
+	
+ffi_call_v8:
+_ffi_call_v8:
+.LLFB1:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI0:
+	
+	sub	%sp, %i2, %sp	! alloca() space in stack for frame to set up
+	add	%sp, STACKFRAME, %l0	! %l0 has start of 
+					! frame to set up
 
-C(ffi_call_v8):
-.LUW0:
-	! Allocate a stack frame sized by ffi_call.
-	save	%sp, %o4, %sp
-.LUW1:
-	mov	%i0, %o0		! copy cif
-	add	%sp, 64+32, %o1		! load args area
-	mov	%i2, %o2		! copy rvalue
-	call	C(ffi_prep_args_v8)
-	 mov	%i3, %o3		! copy avalue
+	mov	%l0, %o0	! call routine to set up frame
+	call	%i0
+	mov	%i1, %o1	! (delay)
 
-	add	%sp, 32, %sp		! deallocate prep frame
-	and	%o0, SPARC_FLAG_RET_MASK, %l0	! save return type
-	srl	%o0, SPARC_SIZEMASK_SHIFT, %l1	! save return size
-	ld	[%sp+64+4], %o0		! load all argument registers
-	ld	[%sp+64+8], %o1
-	ld	[%sp+64+12], %o2
-	ld	[%sp+64+16], %o3
-	cmp	%l0, SPARC_RET_STRUCT	! struct return needs an unimp 4
-	ld	[%sp+64+20], %o4
-	be	8f
-	 ld	[%sp+64+24], %o5
+	ld	[%l0+ARGS], %o0	! call foreign function
+	ld	[%l0+ARGS+4], %o1
+	ld	[%l0+ARGS+8], %o2
+	ld	[%l0+ARGS+12], %o3
+	ld	[%l0+ARGS+16], %o4
+	ld	[%l0+ARGS+20], %o5
+	call	%i5
+	mov	%l0, %sp	! (delay) switch to frame
+	nop			! STRUCT returning functions skip 12 instead of 8 bytes
 
-	! Call foreign function
-	call	%i1
-	 mov	%i5, %g2		! load static chain
-
-0:	call	1f		! load pc in %o7
-	 sll	%l0, 4, %l0
-1:	add	%o7, %l0, %o7	! o7 = 0b + ret_type*16
-	jmp	%o7+(2f-0b)
-	 nop
-
-	! Note that each entry is 4 insns, enforced by the E macro.
-	.align	16
-2:
-E(SPARC_RET_VOID)
-	ret
-	 restore
-E(SPARC_RET_STRUCT)
-	unimp
-E(SPARC_RET_UINT8)
-	and	%o0, 0xff, %o0
-	st	%o0, [%i2]
-	ret
-	 restore
-E(SPARC_RET_SINT8)
-	sll	%o0, 24, %o0
-	b	7f
-	 sra	%o0, 24, %o0
-E(SPARC_RET_UINT16)
-	sll	%o0, 16, %o0
-	b	7f
-	 srl	%o0, 16, %o0
-E(SPARC_RET_SINT16)
-	sll	%o0, 16, %o0
-	b	7f
-	 sra	%o0, 16, %o0
-E(SPARC_RET_UINT32)
-7:	st	%o0, [%i2]
-	ret
-	 restore
-E(SP_V8_RET_CPLX16)
-	sth	%o0, [%i2+2]
-	b	9f
-	 srl	%o0, 16, %o0
-E(SPARC_RET_INT64)
-	st	%o0, [%i2]
-	st	%o1, [%i2+4]
-	ret
-	 restore
-E(SPARC_RET_INT128)
-	std	%o0, [%i2]
-	std	%o2, [%i2+8]
-	ret
-	 restore
-E(SPARC_RET_F_8)
-	st	%f7, [%i2+7*4]
+	! If the return value pointer is NULL, assume no return value.
+	tst	%i4
+	bz	done
 	nop
-	st	%f6, [%i2+6*4]
-	nop
-E(SPARC_RET_F_6)
-	st	%f5, [%i2+5*4]
-	nop
-	st	%f4, [%i2+4*4]
-	nop
-E(SPARC_RET_F_4)
-	st	%f3, [%i2+3*4]
-	nop
-	st	%f2, [%i2+2*4]
-	nop
-E(SPARC_RET_F_2)
-	st	%f1, [%i2+4]
-	st	%f0, [%i2]
+
+	cmp	%i3, FFI_TYPE_INT
+	be,a	done
+	st	%o0, [%i4]	! (delay)
+
+	cmp	%i3, FFI_TYPE_FLOAT
+	be,a	done
+	st	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_DOUBLE
+	be,a	double
+	st	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_SINT8
+	be,a	sint8
+	sll	%o0, 24, %o0	! (delay)
+
+	cmp	%i3, FFI_TYPE_UINT8
+	be,a	uint8
+	sll	%o0, 24, %o0	! (delay)
+
+	cmp	%i3, FFI_TYPE_SINT16
+	be,a	sint16
+	sll	%o0, 16, %o0	! (delay)
+
+	cmp	%i3, FFI_TYPE_UINT16
+	be,a	uint16
+	sll	%o0, 16, %o0	! (delay)
+
+	cmp	%i3, FFI_TYPE_SINT64
+	be,a	longlong
+	st	%o0, [%i4+0]	! (delay)
+done:
 	ret
-	 restore
-E(SP_V8_RET_CPLX8)
-	stb	%o0, [%i2+1]
-	b	0f
-	 srl	%o0, 8, %o0
-E(SPARC_RET_F_1)
-	st	%f0, [%i2]
+	restore
+
+double:
+	st	%f1, [%i4+4]
 	ret
-	 restore
+	restore
 
-	.align	8
-9:	sth	%o0, [%i2]
+sint8:
+	sra	%o0, 24, %o0
+	st	%o0, [%i4+0]
 	ret
-	 restore
-	.align	8
-0:	stb	%o0, [%i2]
+	restore
+
+uint8:
+	srl	%o0, 24, %o0
+	st	%o0, [%i4+0]
 	ret
-	 restore
+	restore
 
-	! Struct returning functions expect and skip the unimp here.
-	! To make it worse, conforming callees examine the unimp and
-	! make sure the low 12 bits of the unimp match the size of
-	! the struct being returned.
-	.align	8
-8:	call	1f				! load pc in %o7
-	 sll	%l1, 2, %l0			! size * 4
-1:	sll	%l1, 4, %l1			! size * 16
-	add	%l0, %l1, %l0			! size * 20
-	add	%o7, %l0, %o7			! o7 = 8b + size*20
-	jmp	%o7+(2f-8b)
-	 mov	%i5, %g2			! load static chain
-2:
+sint16:
+	sra	%o0, 16, %o0
+	st	%o0, [%i4+0]
+	ret
+	restore
 
-/* The Sun assembler doesn't understand .rept 0x1000.  */
-#define rept1			\
-	call	%i1;		\
-	 nop;			\
-	unimp	(. - 2b) / 20;	\
-	ret;			\
-	 restore
+uint16:
+	srl	%o0, 16, %o0
+	st	%o0, [%i4+0]
+	ret
+	restore
 
-#define rept16				\
-	rept1; rept1; rept1; rept1;	\
-	rept1; rept1; rept1; rept1;	\
-	rept1; rept1; rept1; rept1;	\
-	rept1; rept1; rept1; rept1
+longlong:
+	st	%o1, [%i4+4]
+	ret
+	restore
+.LLFE1:
 
-#define rept256				\
-	rept16; rept16; rept16; rept16;	\
-	rept16; rept16; rept16; rept16;	\
-	rept16; rept16; rept16; rept16;	\
-	rept16; rept16; rept16; rept16
-
-	rept256; rept256; rept256; rept256
-	rept256; rept256; rept256; rept256
-	rept256; rept256; rept256; rept256
-	rept256; rept256; rept256; rept256
-
-.LUW2:
-	.size	C(ffi_call_v8),. - C(ffi_call_v8)
+.ffi_call_v8_end:
+	.size	ffi_call_v8,.ffi_call_v8_end-ffi_call_v8
 
 
-/* 16*4 register window + 1*4 struct return + 6*4 args backing store
-   + 8*4 return storage + 1*4 alignment.  */
-#define	STACKFRAME	(16*4 + 4 + 6*4 + 8*4 + 4)
+#undef STACKFRAME
+#define	STACKFRAME	104	/* 16*4 register window +
+				   1*4 struct return +	
+				   6*4 args backing store +
+				   3*4 locals */
 
 /* ffi_closure_v8(...)
 
    Receives the closure argument in %g2.   */
 
+	.text
+	.align 8
+	.globl ffi_closure_v8
+
+ffi_closure_v8:
 #ifdef HAVE_AS_REGISTER_PSEUDO_OP
-	.register	%g2, #scratch
+		.register	%g2, #scratch
 #endif
+.LLFB2:
+	! Reserve frame space for all arguments in case
+	! we need to align them on a 8-byte boundary.
+	ld	[%g2+FFI_TRAMPOLINE_SIZE], %g1
+	ld	[%g1+4], %g1
+	sll	%g1, 3, %g1
+	add	%g1, STACKFRAME, %g1
+	! %g1 == STACKFRAME + 8*nargs
+	neg	%g1
+	save	%sp, %g1, %sp
+.LLCFI1:
 
-	.align 8
-	.globl	C(ffi_go_closure_v8)
-	.type	C(ffi_go_closure_v8),#function
-	FFI_HIDDEN(C(ffi_go_closure_v8))
-
-C(ffi_go_closure_v8):
-.LUW3:
-	save	%sp, -STACKFRAME, %sp
-.LUW4:
-	ld	[%g2+4], %o0			! load cif
-	ld	[%g2+8], %o1			! load fun
-	b	0f
-	 mov	%g2, %o2			! load user_data
-.LUW5:
-	.size	C(ffi_go_closure_v8), . - C(ffi_go_closure_v8)
-
-	.align 8
-	.globl	C(ffi_closure_v8)
-	.type	C(ffi_closure_v8),#function
-	FFI_HIDDEN(C(ffi_closure_v8))
-
-C(ffi_closure_v8):
-.LUW6:
-	save	%sp, -STACKFRAME, %sp
-.LUW7:
-	ld	[%g2+FFI_TRAMPOLINE_SIZE], %o0		! load cif
-	ld	[%g2+FFI_TRAMPOLINE_SIZE+4], %o1	! load fun
-	ld	[%g2+FFI_TRAMPOLINE_SIZE+8], %o2	! load user_data
-0:
 	! Store all of the potential argument registers in va_list format.
 	st	%i0, [%fp+68+0]
 	st	%i1, [%fp+68+4]
@@ -281,163 +207,140 @@
 	st	%i5, [%fp+68+20]
 
 	! Call ffi_closure_sparc_inner to do the bulk of the work.
-	add	%fp, -8*4, %o3
+	mov	%g2, %o0
+	add	%fp, -8, %o1
+	add	%fp,  64, %o2
 	call	ffi_closure_sparc_inner_v8
-	 add	%fp,  64, %o4
+	 add	%fp, -16, %o3
 
-0:	call	1f
-	 and	%o0, SPARC_FLAG_RET_MASK, %o0
-1:	sll	%o0, 4, %o0	! o0 = o0 * 16
-	add	%o7, %o0, %o7	! o7 = 0b + o0*16
-	jmp	%o7+(2f-0b)
-	 add	%fp, -8*4, %i2
-	 
-	! Note that each entry is 4 insns, enforced by the E macro.
-	.align	16
-2:
-E(SPARC_RET_VOID)
-	ret
+	! Load up the return value in the proper type.
+	! See ffi_prep_cif_machdep for the list of cases.
+	cmp	%o0, FFI_TYPE_VOID
+	be	done1
+
+	cmp	%o0, FFI_TYPE_INT
+	be	done1
+	 ld	[%fp-8], %i0
+
+	cmp	%o0, FFI_TYPE_FLOAT
+	be,a	done1
+	 ld	[%fp-8], %f0
+
+	cmp	%o0, FFI_TYPE_DOUBLE
+	be,a	done1
+	 ldd	[%fp-8], %f0
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	cmp	%o0, FFI_TYPE_LONGDOUBLE
+	be	done2
+#endif
+
+	cmp	%o0, FFI_TYPE_STRUCT
+	be	done2
+
+	cmp	%o0, FFI_TYPE_SINT64
+	be,a	done1
+	 ldd	[%fp-8], %i0
+
+	cmp	%o0, FFI_TYPE_UINT64
+	be,a	done1
+	 ldd	[%fp-8], %i0
+
+	ld	[%fp-8], %i0
+done1:
+	jmp	%i7+8
 	 restore
-E(SPARC_RET_STRUCT)
-	ld	[%i2], %i0
+done2:
+	! Skip 'unimp'.
 	jmp	%i7+12
 	 restore
-E(SPARC_RET_UINT8)
-	ldub	[%i2+3], %i0
-	ret
-	 restore
-E(SPARC_RET_SINT8)
-	ldsb	[%i2+3], %i0
-	ret
-	 restore
-E(SPARC_RET_UINT16)
-	lduh	[%i2+2], %i0
-	ret
-	 restore
-E(SPARC_RET_SINT16)
-	ldsh	[%i2+2], %i0
-	ret
-	 restore
-E(SPARC_RET_UINT32)
-	ld	[%i2], %i0
-	ret
-	 restore
-E(SP_V8_RET_CPLX16)
-	ld	[%i2], %i0
-	ret
-	 restore
-E(SPARC_RET_INT64)
-	ldd	[%i2], %i0
-	ret
-	 restore
-E(SPARC_RET_INT128)
-	ldd	[%i2], %i0
-	ldd	[%i2+8], %i2
-	ret
-	 restore
-E(SPARC_RET_F_8)
-	ld	[%i2+7*4], %f7
-	nop
-	ld	[%i2+6*4], %f6
-	nop
-E(SPARC_RET_F_6)
-	ld	[%i2+5*4], %f5
-	nop
-	ld	[%i2+4*4], %f4
-	nop
-E(SPARC_RET_F_4)
-	ld	[%i2+3*4], %f3
-	nop
-	ld	[%i2+2*4], %f2
-	nop
-E(SPARC_RET_F_2)
-	ldd	[%i2], %f0
-	ret
-	 restore
-E(SP_V8_RET_CPLX8)
-	lduh	[%i2], %i0
-	ret
-	 restore
-E(SPARC_RET_F_1)
-	ld	[%i2], %f0
-	ret
-	 restore
+.LLFE2:
 
-.LUW8:
-	.size	C(ffi_closure_v8), . - C(ffi_closure_v8)
+.ffi_closure_v8_end:
+	.size	ffi_closure_v8,.ffi_closure_v8_end-ffi_closure_v8
+
+#ifdef SPARC64
+#define WS 8
+#define nword	xword
+#define uanword	uaxword
+#else
+#define WS 4
+#define nword	long
+#define uanword	uaword
+#endif
 
 #ifdef HAVE_RO_EH_FRAME
-        .section        ".eh_frame",#alloc
+	.section	".eh_frame",#alloc
 #else
-        .section        ".eh_frame",#alloc,#write
+	.section	".eh_frame",#alloc,#write
 #endif
-
+.LLframe1:
+	.uaword	.LLECIE1-.LLSCIE1	! Length of Common Information Entry
+.LLSCIE1:
+	.uaword	0x0	! CIE Identifier Tag
+	.byte	0x1	! CIE Version
+	.ascii "zR\0"	! CIE Augmentation
+	.byte	0x1	! uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x80-WS	! sleb128 -WS; CIE Data Alignment Factor
+	.byte	0xf	! CIE RA Column
+	.byte	0x1	! uleb128 0x1; Augmentation size
 #ifdef HAVE_AS_SPARC_UA_PCREL
-# define FDE_ADDR(X)	%r_disp32(X)
+	.byte	0x1b	! FDE Encoding (pcrel sdata4)
 #else
-# define FDE_ADDR(X)	X
+	.byte	0x50	! FDE Encoding (aligned absolute)
 #endif
-
-	.align 4
-.LCIE:
-	.long	.LECIE - .LSCIE		! CIE Length
-.LSCIE:
-	.long	0			! CIE Identifier Tag
-	.byte	1			! CIE Version
-	.ascii	"zR\0"			! CIE Augmentation
-	.byte	4			! CIE Code Alignment Factor
-	.byte	0x7c			! CIE Data Alignment Factor
-	.byte	15			! CIE RA Column
-	.byte	1			! Augmentation size
+	.byte	0xc	! DW_CFA_def_cfa
+	.byte	0xe	! uleb128 0xe
+	.byte	0x0	! uleb128 0x0
+	.align	WS
+.LLECIE1:
+.LLSFDE1:
+	.uaword	.LLEFDE1-.LLASFDE1	! FDE Length
+.LLASFDE1:
+	.uaword	.LLASFDE1-.LLframe1	! FDE CIE offset
 #ifdef HAVE_AS_SPARC_UA_PCREL
-	.byte	0x1b			! FDE Encoding (pcrel sdata4)
+	.uaword	%r_disp32(.LLFB1)
+	.uaword	.LLFE1-.LLFB1	! FDE address range
 #else
-	.byte	0x50			! FDE Encoding (aligned absolute)
+	.align	WS
+	.nword	.LLFB1
+	.uanword .LLFE1-.LLFB1	! FDE address range
 #endif
-	.byte	0xc, 14, 0		! DW_CFA_def_cfa, %o6, offset 0
-	.align	4
-.LECIE:
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI0-.LLFB1
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align	WS
+.LLEFDE1:
+.LLSFDE2:
+	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
+.LLASFDE2:
+	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB2)
+	.uaword	.LLFE2-.LLFB2	! FDE address range
+#else
+	.align	WS
+	.nword	.LLFB2
+	.uanword .LLFE2-.LLFB2	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI1-.LLFB2
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align	WS
+.LLEFDE2:
 
-	.long	.LEFDE1 - .LSFDE1	! FDE Length
-.LSFDE1:
-	.long	.LSFDE1 - .LCIE		! FDE CIE offset
-	.long	FDE_ADDR(.LUW0)		! Initial location
-	.long	.LUW2 - .LUW0		! Address range
-	.byte	0			! Augmentation size
-	.byte	0x40+1			! DW_CFA_advance_loc 4
-	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6
-	.byte	0x2d			! DW_CFA_GNU_window_save
-	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7
-	.align	4
-.LEFDE1:
-
-	.long	.LEFDE2 - .LSFDE2	! FDE Length
-.LSFDE2:
-	.long	.LSFDE2 - .LCIE		! FDE CIE offset
-	.long	FDE_ADDR(.LUW3)		! Initial location
-	.long	.LUW5 - .LUW3		! Address range
-	.byte	0			! Augmentation size
-	.byte	0x40+1			! DW_CFA_advance_loc 4
-	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6
-	.byte	0x2d			! DW_CFA_GNU_window_save
-	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7
-	.align	4
-.LEFDE2:
-
-	.long	.LEFDE3 - .LSFDE3	! FDE Length
-.LSFDE3:
-	.long	.LSFDE3 - .LCIE		! FDE CIE offset
-	.long	FDE_ADDR(.LUW6)		! Initial location
-	.long	.LUW8 - .LUW6		! Address range
-	.byte	0			! Augmentation size
-	.byte	0x40+1			! DW_CFA_advance_loc 4
-	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6
-	.byte	0x2d			! DW_CFA_GNU_window_save
-	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7
-	.align	4
-.LEFDE3:
-
-#endif /* !SPARC64 */
 #if defined __ELF__ && defined __linux__
 	.section	.note.GNU-stack,"",@progbits
 #endif
diff --git a/src/sparc/v9.S b/src/sparc/v9.S
index 55f8f43..bf31a2b 100644
--- a/src/sparc/v9.S
+++ b/src/sparc/v9.S
@@ -27,176 +27,105 @@
 #define LIBFFI_ASM	
 #include <fficonfig.h>
 #include <ffi.h>
-#include "internal.h"
 
 #ifdef SPARC64
+/* Only compile this in for 64bit builds, because otherwise the object file
+   will have inproper architecture due to used instructions.  */
 
-#define C2(X, Y)  X ## Y
-#define C1(X, Y)  C2(X, Y)
-
-#ifdef __USER_LABEL_PREFIX__
-# define C(Y)	C1(__USER_LABEL_PREFIX__, Y)
-#else
-# define C(Y)	Y
-#endif
-#define L(Y)	C1(.L, Y)
-
-#if defined(__sun__) && defined(__svr4__)
-# define E(INDEX)	.align 16
-#else
-# define E(INDEX)	.align 16; .org 2b + INDEX * 16
-#endif
-
+#define STACKFRAME 176		/* Minimum stack framesize for SPARC 64-bit */
 #define STACK_BIAS 2047
+#define ARGS (128)		/* Offset of register area in frame */
 
-	.text
+.text
         .align 8
-	.globl	C(ffi_call_v9)
-	.type	C(ffi_call_v9),#function
-	FFI_HIDDEN(C(ffi_call_v9))
+.globl ffi_call_v9
+.globl _ffi_call_v9
 
-C(ffi_call_v9):
-.LUW0:
-	save	%sp, %o4, %sp
-.LUW1:
-	mov	%i0, %o0			! copy cif
-	add	%sp, STACK_BIAS+128+48, %o1	! load args area
-	mov	%i2, %o2			! copy rvalue
-	call	C(ffi_prep_args_v9)
-	 mov	%i3, %o3			! copy avalue
+ffi_call_v9:
+_ffi_call_v9:
+.LLFB1:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI0:
+	
+	sub	%sp, %i2, %sp	! alloca() space in stack for frame to set up
+	add	%sp, STACKFRAME+STACK_BIAS, %l0	! %l0 has start of 
+						! frame to set up
 
-	andcc	%o0, SPARC_FLAG_FP_ARGS, %g0	! need fp regs?
-	add	%sp, 48, %sp			! deallocate prep frame
-	be,pt	%xcc, 1f
-	 mov	%o0, %l0			! save flags
+	mov	%l0, %o0	! call routine to set up frame
+	call	%i0
+	 mov	%i1, %o1	! (delay)
+	brz,pt	%o0, 1f
+	 ldx	[%l0+ARGS], %o0	! call foreign function
 
-	ldd	[%sp+STACK_BIAS+128], %f0	! load all fp arg regs
-	ldd	[%sp+STACK_BIAS+128+8], %f2
-	ldd	[%sp+STACK_BIAS+128+16], %f4
-	ldd	[%sp+STACK_BIAS+128+24], %f6
-	ldd	[%sp+STACK_BIAS+128+32], %f8
-	ldd	[%sp+STACK_BIAS+128+40], %f10
-	ldd	[%sp+STACK_BIAS+128+48], %f12
-	ldd	[%sp+STACK_BIAS+128+56], %f14
-	ldd	[%sp+STACK_BIAS+128+64], %f16
-	ldd	[%sp+STACK_BIAS+128+72], %f18
-	ldd	[%sp+STACK_BIAS+128+80], %f20
-	ldd	[%sp+STACK_BIAS+128+88], %f22
-	ldd	[%sp+STACK_BIAS+128+96], %f24
-	ldd	[%sp+STACK_BIAS+128+104], %f26
-	ldd	[%sp+STACK_BIAS+128+112], %f28
-	ldd	[%sp+STACK_BIAS+128+120], %f30
+	ldd	[%l0+ARGS], %f0
+	ldd	[%l0+ARGS+8], %f2
+	ldd	[%l0+ARGS+16], %f4
+	ldd	[%l0+ARGS+24], %f6
+	ldd	[%l0+ARGS+32], %f8
+	ldd	[%l0+ARGS+40], %f10
+	ldd	[%l0+ARGS+48], %f12
+	ldd	[%l0+ARGS+56], %f14
+	ldd	[%l0+ARGS+64], %f16
+	ldd	[%l0+ARGS+72], %f18
+	ldd	[%l0+ARGS+80], %f20
+	ldd	[%l0+ARGS+88], %f22
+	ldd	[%l0+ARGS+96], %f24
+	ldd	[%l0+ARGS+104], %f26
+	ldd	[%l0+ARGS+112], %f28
+	ldd	[%l0+ARGS+120], %f30
 
-1:	ldx	[%sp+STACK_BIAS+128], %o0	! load all int arg regs
-	ldx	[%sp+STACK_BIAS+128+8], %o1
-	ldx	[%sp+STACK_BIAS+128+16], %o2
-	ldx	[%sp+STACK_BIAS+128+24], %o3
-	ldx	[%sp+STACK_BIAS+128+32], %o4
-	ldx	[%sp+STACK_BIAS+128+40], %o5
-	call	%i1
-	 mov	%i5, %g5			! load static chain
+1:	ldx	[%l0+ARGS+8], %o1
+	ldx	[%l0+ARGS+16], %o2
+	ldx	[%l0+ARGS+24], %o3
+	ldx	[%l0+ARGS+32], %o4
+	ldx	[%l0+ARGS+40], %o5
+	call	%i5
+	 sub	%l0, STACK_BIAS, %sp	! (delay) switch to frame
 
-0:	call	1f		! load pc in %o7
-	 and	%l0, SPARC_FLAG_RET_MASK, %l1
-1:	sll	%l1, 4, %l1
-	add	%o7, %l1, %o7	! o7 = 0b + ret_type*16
-	jmp	%o7+(2f-0b)
+	! If the return value pointer is NULL, assume no return value.
+	brz,pn	%i4, done
 	 nop
 
-	.align	16
-2:
-E(SPARC_RET_VOID)
-	return	%i7+8
-	 nop
-E(SPARC_RET_STRUCT)
-	add	%sp, STACK_BIAS-64+128+48, %l2
-	sub	%sp, 64, %sp
-	b	8f
-	 stx	%o0, [%l2]
-E(SPARC_RET_UINT8)
-	and	%o0, 0xff, %i0
-	return	%i7+8
-	  stx	%o0, [%o2]
-E(SPARC_RET_SINT8)
-	sll	%o0, 24, %o0
-	sra	%o0, 24, %i0
-	return	%i7+8
-	 stx	%o0, [%o2]
-E(SPARC_RET_UINT16)
-	sll	%o0, 16, %o0
-	srl	%o0, 16, %i0
-	return	%i7+8
-	 stx	%o0, [%o2]
-E(SPARC_RET_SINT16)
-	sll	%o0, 16, %o0
-	sra	%o0, 16, %i0
-	return	%i7+8
-	 stx	%o0, [%o2]
-E(SPARC_RET_UINT32)
-	srl	%o0, 0, %i0
-	return	%i7+8
-	 stx	%o0, [%o2]
-E(SP_V9_RET_SINT32)
-	sra	%o0, 0, %i0
-	return	%i7+8
-	 stx	%o0, [%o2]
-E(SPARC_RET_INT64)
-	stx	%o0, [%i2]
-	return	%i7+8
-	 nop
-E(SPARC_RET_INT128)
-	stx	%o0, [%i2]
-	stx	%o1, [%i2+8]
-	return	%i7+8
-	 nop
-E(SPARC_RET_F_8)
-	st	%f7, [%i2+7*4]
-	nop
-	st	%f6, [%i2+6*4]
-	nop
-E(SPARC_RET_F_6)
-	st	%f5, [%i2+5*4]
-	nop
-	st	%f4, [%i2+4*4]
-	nop
-E(SPARC_RET_F_4)
-	std	%f2, [%i2+2*4]
-	return	%i7+8
-	 std	%f0, [%o2]
-E(SPARC_RET_F_2)
-	return	%i7+8
-	 std	%f0, [%o2]
-E(SP_V9_RET_F_3)
-	st	%f2, [%i2+2*4]
-	nop
-	st	%f1, [%i2+1*4]
-	nop
-E(SPARC_RET_F_1)
-	return	%i7+8
-	 st	%f0, [%o2]
+	cmp	%i3, FFI_TYPE_INT
+	be,a,pt	%icc, done
+	 stx	%o0, [%i4+0]	! (delay)
 
-	! Finish the SPARC_RET_STRUCT sequence.
-	.align	8
-8:	stx	%o1, [%l2+8]
-	stx	%o2, [%l2+16]
-	stx	%o3, [%l2+24]
-	std	%f0, [%l2+32]
-	std	%f2, [%l2+40]
-	std	%f4, [%l2+48]
-	std	%f6, [%l2+56]
+	cmp	%i3, FFI_TYPE_FLOAT
+	be,a,pn	%icc, done
+	 st	%f0, [%i4+0]	! (delay)
 
-	! Copy the structure into place.
-	srl	%l0, SPARC_SIZEMASK_SHIFT, %o0	! load size_mask
-	mov	%i2, %o1			! load dst
-	mov	%l2, %o2			! load src_gp
-	call	C(ffi_struct_float_copy)
-	 add	%l2, 32, %o3			! load src_fp
+	cmp	%i3, FFI_TYPE_DOUBLE
+	be,a,pn	%icc, done
+	 std	%f0, [%i4+0]	! (delay)
 
-	return	%i7+8
+	cmp	%i3, FFI_TYPE_STRUCT
+	be,pn	%icc, dostruct
+
+	cmp	%i3, FFI_TYPE_LONGDOUBLE
+	bne,pt	%icc, done
 	 nop
+	std	%f0, [%i4+0]
+	std	%f2, [%i4+8]
 
-.LUW2:
-	.size	C(ffi_call_v9), . - C(ffi_call_v9)
+done:	ret
+	 restore
+
+dostruct:
+	/* This will not work correctly for unions. */
+	stx	%o0, [%i4+0]
+	stx	%o1, [%i4+8]
+	stx	%o2, [%i4+16]
+	stx	%o3, [%i4+24]
+	std	%f0, [%i4+32]
+	std	%f2, [%i4+40]
+	std	%f4, [%i4+48]
+	std	%f6, [%i4+56]
+	ret
+	 restore
+.LLFE1:
+
+.ffi_call_v9_end:
+	.size	ffi_call_v9,.ffi_call_v9_end-ffi_call_v9
 
 
 #undef STACKFRAME
@@ -209,36 +138,15 @@
 
    Receives the closure argument in %g1.   */
 
+	.text
 	.align 8
-	.globl	C(ffi_go_closure_v9)
-	.type	C(ffi_go_closure_v9),#function
-	FFI_HIDDEN(C(ffi_go_closure_v9))
+	.globl ffi_closure_v9
 
-C(ffi_go_closure_v9):
-.LUW3:
+ffi_closure_v9:
+.LLFB2:
 	save	%sp, -STACKFRAME, %sp
-.LUW4:
-	ldx	[%g5+8], %o0
-	ldx	[%g5+16], %o1
-	b	0f
-	 mov	%g5, %o2
+.LLCFI1:
 
-.LUW5:
-	.size	C(ffi_go_closure_v9), . - C(ffi_go_closure_v9)
-
-	.align 8
-	.globl	C(ffi_closure_v9)
-	.type	C(ffi_closure_v9),#function
-	FFI_HIDDEN(C(ffi_closure_v9))
-
-C(ffi_closure_v9):
-.LUW6:
-	save	%sp, -STACKFRAME, %sp
-.LUW7:
-	ldx	[%g1+FFI_TRAMPOLINE_SIZE], %o0
-	ldx	[%g1+FFI_TRAMPOLINE_SIZE+8], %o1
-	ldx	[%g1+FFI_TRAMPOLINE_SIZE+16], %o2
-0:
 	! Store all of the potential argument registers in va_list format.
 	stx	%i0, [FP+128+0]
 	stx	%i1, [FP+128+8]
@@ -266,175 +174,134 @@
 	std     %f30, [FP-8]
 
 	! Call ffi_closure_sparc_inner to do the bulk of the work.
-	add	%fp, STACK_BIAS-160, %o3
-	add	%fp, STACK_BIAS+128, %o4
-	call	C(ffi_closure_sparc_inner_v9)
-	 add	%fp, STACK_BIAS-128, %o5
+	mov	%g1, %o0
+	add	%fp, STACK_BIAS-160, %o1
+	add	%fp, STACK_BIAS+128, %o2
+	call	ffi_closure_sparc_inner_v9
+	 add	%fp, STACK_BIAS-128, %o3
 
-0:	call	1f		! load pc in %o7
-	 and	%o0, SPARC_FLAG_RET_MASK, %o0
-1:	sll	%o0, 4, %o0	! o2 = i2 * 16
-	add	%o7, %o0, %o7	! o7 = 0b + i2*16
-	jmp	%o7+(2f-0b)
-	 nop
+	! Load up the return value in the proper type.
+	! See ffi_prep_cif_machdep for the list of cases.
+	cmp	%o0, FFI_TYPE_VOID
+	be,pn	%icc, done1
 
-	! Note that we cannot load the data in the delay slot of
-	! the return insn because the data is in the stack frame
-	! that is deallocated by the return.
-	.align	16
-2:
-E(SPARC_RET_VOID)
-	return	%i7+8
-	 nop
-E(SPARC_RET_STRUCT)
-	ldx	[FP-160], %i0
-	ldd	[FP-160], %f0
-	b	8f
-	 ldx	[FP-152], %i1
-E(SPARC_RET_UINT8)
-	ldub	[FP-160+7], %i0
-	return	%i7+8
-	 nop
-E(SPARC_RET_SINT8)
-	ldsb	[FP-160+7], %i0
-	return	%i7+8
-	 nop
-E(SPARC_RET_UINT16)
-	lduh	[FP-160+6], %i0
-	return	%i7+8
-	 nop
-E(SPARC_RET_SINT16)
-	ldsh	[FP-160+6], %i0
-	return	%i7+8
-	 nop
-E(SPARC_RET_UINT32)
-	lduw	[FP-160+4], %i0
-	return	%i7+8
-	 nop
-E(SP_V9_RET_SINT32)
-	ldsw	[FP-160+4], %i0
-	return	%i7+8
-	 nop
-E(SPARC_RET_INT64)
-	ldx	[FP-160], %i0
-	return	%i7+8
-	 nop
-E(SPARC_RET_INT128)
-	ldx	[FP-160], %i0
-	ldx	[FP-160+8], %i1
-	return	%i7+8
-	 nop
-E(SPARC_RET_F_8)
-	ld	[FP-160+7*4], %f7
-	nop
-	ld	[FP-160+6*4], %f6
-	nop
-E(SPARC_RET_F_6)
-	ld	[FP-160+5*4], %f5
-	nop
-	ld	[FP-160+4*4], %f4
-	nop
-E(SPARC_RET_F_4)
-	ldd	[FP-160], %f0
-	ldd	[FP-160+8], %f2
-	return	%i7+8
-	 nop
-E(SPARC_RET_F_2)
-	ldd	[FP-160], %f0
-	return	%i7+8
-	 nop
-E(SP_V9_RET_F_3)
-	ld	[FP-160+2*4], %f2
-	nop
-	ld	[FP-160+1*4], %f1
-	nop
-E(SPARC_RET_F_1)
-	ld	[FP-160], %f0
-	return	%i7+8
-	 nop
+	cmp	%o0, FFI_TYPE_INT
+	be,pn	%icc, integer
 
-	! Finish the SPARC_RET_STRUCT sequence.
-	.align	8
-8:	ldd	[FP-152], %f2
+	cmp	%o0, FFI_TYPE_FLOAT
+	be,a,pn	%icc, done1
+	 ld	[FP-160], %f0
+
+	cmp	%o0, FFI_TYPE_DOUBLE
+	be,a,pn	%icc, done1
+	 ldd	[FP-160], %f0
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	cmp	%o0, FFI_TYPE_LONGDOUBLE
+	be,a,pn	%icc, longdouble1
+	 ldd	[FP-160], %f0
+#endif
+
+	! FFI_TYPE_STRUCT
+	ldx	[FP-152], %i1
 	ldx	[FP-144], %i2
-	ldd	[FP-144], %f4
 	ldx	[FP-136], %i3
+	ldd	[FP-160], %f0
+	ldd	[FP-152], %f2
+	ldd	[FP-144], %f4
 	ldd	[FP-136], %f6
-	return	%i7+8
-	 nop
 
-.LUW8:
-	.size	C(ffi_closure_v9), . - C(ffi_closure_v9)
+integer:
+	ldx	[FP-160], %i0
+
+done1:
+	ret
+	 restore
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+longdouble1:
+	ldd	[FP-152], %f2
+	ret
+	 restore
+#endif
+.LLFE2:
+
+.ffi_closure_v9_end:
+	.size	ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
 
 #ifdef HAVE_RO_EH_FRAME
-        .section        ".eh_frame",#alloc
+	.section	".eh_frame",#alloc
 #else
-        .section        ".eh_frame",#alloc,#write
+	.section	".eh_frame",#alloc,#write
 #endif
-
+.LLframe1:
+	.uaword	.LLECIE1-.LLSCIE1	! Length of Common Information Entry
+.LLSCIE1:
+	.uaword	0x0	! CIE Identifier Tag
+	.byte	0x1	! CIE Version
+	.ascii "zR\0"	! CIE Augmentation
+	.byte	0x1	! uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x78	! sleb128 -8; CIE Data Alignment Factor
+	.byte	0xf	! CIE RA Column
+	.byte	0x1	! uleb128 0x1; Augmentation size
 #ifdef HAVE_AS_SPARC_UA_PCREL
-# define FDE_RANGE(B, E)  .long %r_disp32(B), E - B
+	.byte	0x1b	! FDE Encoding (pcrel sdata4)
 #else
-# define FDE_RANGE(B, E)  .align 8; .xword B, E - B
+	.byte	0x50	! FDE Encoding (aligned absolute)
 #endif
-
+	.byte	0xc	! DW_CFA_def_cfa
+	.byte	0xe	! uleb128 0xe
+	.byte	0xff,0xf	! uleb128 0x7ff
 	.align 8
-.LCIE:
-	.long	.LECIE - .LSCIE		! CIE Length
-.LSCIE:
-	.long	0			! CIE Identifier Tag
-	.byte	1			! CIE Version
-	.ascii	"zR\0"			! CIE Augmentation
-	.byte	4			! CIE Code Alignment Factor
-	.byte	0x78			! CIE Data Alignment Factor
-	.byte	15			! CIE RA Column
-	.byte	1			! Augmentation size
+.LLECIE1:
+.LLSFDE1:
+	.uaword	.LLEFDE1-.LLASFDE1	! FDE Length
+.LLASFDE1:
+	.uaword	.LLASFDE1-.LLframe1	! FDE CIE offset
 #ifdef HAVE_AS_SPARC_UA_PCREL
-	.byte	0x1b			! FDE Encoding (pcrel sdata4)
+	.uaword	%r_disp32(.LLFB1)
+	.uaword	.LLFE1-.LLFB1		! FDE address range
 #else
-	.byte	0x50			! FDE Encoding (aligned absolute)
+	.align 8
+	.xword	.LLFB1
+	.uaxword	.LLFE1-.LLFB1	! FDE address range
 #endif
-	.byte	0xc, 14, 0xff, 0xf	! DW_CFA_def_cfa, %o6, offset 0x7ff
-	.align	8
-.LECIE:
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI0-.LLFB1
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align 8
+.LLEFDE1:
+.LLSFDE2:
+	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
+.LLASFDE2:
+	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB2)
+	.uaword	.LLFE2-.LLFB2		! FDE address range
+#else
+	.align 8
+	.xword	.LLFB2
+	.uaxword	.LLFE2-.LLFB2	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI1-.LLFB2
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align 8
+.LLEFDE2:
+#endif
 
-	.long	.LEFDE1 - .LSFDE1	! FDE Length
-.LSFDE1:
-	.long	.LSFDE1 - .LCIE		! FDE CIE offset
-	FDE_RANGE(.LUW0, .LUW2)
-	.byte	0			! Augmentation size
-	.byte	0x40+1			! DW_CFA_advance_loc 4
-	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6
-	.byte	0x2d			! DW_CFA_GNU_window_save
-	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7
-	.align	8
-.LEFDE1:
-
-	.long	.LEFDE2 - .LSFDE2	! FDE Length
-.LSFDE2:
-	.long	.LSFDE2 - .LCIE		! FDE CIE offset
-	FDE_RANGE(.LUW3, .LUW5)
-	.byte	0			! Augmentation size
-	.byte	0x40+1			! DW_CFA_advance_loc 4
-	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6
-	.byte	0x2d			! DW_CFA_GNU_window_save
-	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7
-	.align	8
-.LEFDE2:
-
-	.long	.LEFDE3 - .LSFDE3	! FDE Length
-.LSFDE3:
-	.long	.LSFDE3 - .LCIE		! FDE CIE offset
-	FDE_RANGE(.LUW6, .LUW8)
-	.byte	0			! Augmentation size
-	.byte	0x40+1			! DW_CFA_advance_loc 4
-	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6
-	.byte	0x2d			! DW_CFA_GNU_window_save
-	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7
-	.align	8
-.LEFDE3:
-
-#endif /* SPARC64 */
 #ifdef __linux__
 	.section	.note.GNU-stack,"",@progbits
 #endif
diff --git a/src/types.c b/src/types.c
index 9ec27f6..7e80aec 100644
--- a/src/types.c
+++ b/src/types.c
@@ -38,7 +38,6 @@
   char c;					\
   type x;					\
 };						\
-FFI_EXTERN					\
 maybe_const ffi_type ffi_type_##name = {	\
   sizeof(type),					\
   offsetof(struct struct_align_##name, x),	\
@@ -53,7 +52,6 @@
   char c;						\
   _Complex type x;					\
 };							\
-FFI_EXTERN						\
 maybe_const ffi_type ffi_type_complex_##name = {	\
   sizeof(_Complex type),				\
   offsetof(struct struct_align_complex_##name, x),	\
@@ -62,7 +60,7 @@
 }
 
 /* Size and alignment are fake here. They must not be 0. */
-FFI_EXTERN const ffi_type ffi_type_void = {
+const ffi_type ffi_type_void = {
   1, 1, FFI_TYPE_VOID, NULL
 };
 
diff --git a/src/vax/ffi.c b/src/vax/ffi.c
index e52caec..f4d6bbb 100644
--- a/src/vax/ffi.c
+++ b/src/vax/ffi.c
@@ -108,7 +108,7 @@
 
 	  /* Align if necessary.  */
 	  if ((sizeof(int) - 1) & z)
-	    z = FFI_ALIGN(z, sizeof(int));
+	    z = ALIGN(z, sizeof(int));
 	}
 
       p_argv++;
@@ -215,7 +215,7 @@
 
       /* Align if necessary */
       if ((sizeof (int) - 1) & z)
-	z = FFI_ALIGN(z, sizeof (int));
+	z = ALIGN(z, sizeof (int));
 
       p_argv++;
       stackp += z;
diff --git a/src/x86/asmnames.h b/src/x86/asmnames.h
deleted file mode 100644
index 7551021..0000000
--- a/src/x86/asmnames.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef ASMNAMES_H
-#define ASMNAMES_H
-
-#define C2(X, Y)  X ## Y
-#define C1(X, Y)  C2(X, Y)
-#ifdef __USER_LABEL_PREFIX__
-# define C(X)     C1(__USER_LABEL_PREFIX__, X)
-#else
-# define C(X)     X
-#endif
-
-#ifdef __APPLE__
-# define L(X)     C1(L, X)
-#else
-# define L(X)     C1(.L, X)
-#endif
-
-#if defined(__ELF__) && defined(__PIC__)
-# define PLT(X)	  X@PLT
-#else
-# define PLT(X)	  X
-#endif
-
-#ifdef __ELF__
-# define ENDF(X)  .type	X,@function; .size X, . - X
-#else
-# define ENDF(X)
-#endif
-
-#endif /* ASMNAMES_H */
diff --git a/src/x86/darwin.S b/src/x86/darwin.S
new file mode 100644
index 0000000..8f0f070
--- /dev/null
+++ b/src/x86/darwin.S
@@ -0,0 +1,444 @@
+/* -----------------------------------------------------------------------
+   darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005  Red Hat, Inc.
+	Copyright (C) 2008  Free Software Foundation, Inc.
+
+   X86 Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   -----------------------------------------------------------------------
+   */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl _ffi_prep_args
+
+	.align 4
+.globl _ffi_call_SYSV
+
+_ffi_call_SYSV:
+.LFB1:
+        pushl %ebp
+.LCFI0:
+        movl  %esp,%ebp
+.LCFI1:
+        subl $8,%esp
+	/* Make room for all of the new args.  */
+	movl  16(%ebp),%ecx
+	subl  %ecx,%esp
+
+	movl  %esp,%eax
+
+	/* Place all of the ffi_prep_args in position  */
+	subl  $8,%esp
+	pushl 12(%ebp)
+	pushl %eax
+	call  *8(%ebp)
+
+	/* Return stack to previous state and call the function  */
+	addl  $16,%esp	
+
+	call  *28(%ebp)
+
+	/* Load %ecx with the return type code  */
+	movl  20(%ebp),%ecx	
+
+	/* Protect %esi.  We're going to pop it in the epilogue.  */
+	pushl %esi
+
+	/* If the return value pointer is NULL, assume no return value.  */
+	cmpl  $0,24(%ebp)
+	jne  0f
+
+	/* Even if there is no space for the return value, we are 
+	   obliged to handle floating-point values.  */
+	cmpl  $FFI_TYPE_FLOAT,%ecx
+	jne   noretval
+	fstp  %st(0)
+
+	jmp   epilogue
+0:
+	.align 4
+	call 1f
+.Lstore_table:
+	.long   noretval-.Lstore_table		/* FFI_TYPE_VOID */
+	.long   retint-.Lstore_table		/* FFI_TYPE_INT */
+	.long   retfloat-.Lstore_table		/* FFI_TYPE_FLOAT */
+	.long   retdouble-.Lstore_table		/* FFI_TYPE_DOUBLE */
+	.long   retlongdouble-.Lstore_table     /* FFI_TYPE_LONGDOUBLE */
+	.long   retuint8-.Lstore_table		/* FFI_TYPE_UINT8 */
+	.long   retsint8-.Lstore_table		/* FFI_TYPE_SINT8 */
+	.long   retuint16-.Lstore_table		/* FFI_TYPE_UINT16 */
+	.long   retsint16-.Lstore_table		/* FFI_TYPE_SINT16 */
+	.long   retint-.Lstore_table		/* FFI_TYPE_UINT32 */
+	.long   retint-.Lstore_table		/* FFI_TYPE_SINT32 */
+	.long   retint64-.Lstore_table		/* FFI_TYPE_UINT64 */
+	.long   retint64-.Lstore_table		/* FFI_TYPE_SINT64 */
+	.long   retstruct-.Lstore_table		/* FFI_TYPE_STRUCT */
+	.long   retint-.Lstore_table		/* FFI_TYPE_POINTER */
+	.long   retstruct1b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_1B */
+	.long   retstruct2b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_2B */
+1:
+	pop  %esi
+	add  (%esi, %ecx, 4), %esi
+	jmp  *%esi
+
+	/* Sign/zero extend as appropriate.  */
+retsint8:
+	movsbl  %al, %eax
+	jmp  retint
+
+retsint16:
+	movswl  %ax, %eax
+	jmp  retint
+
+retuint8:
+	movzbl  %al, %eax
+	jmp  retint
+
+retuint16:
+	movzwl  %ax, %eax
+	jmp  retint
+
+retfloat:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	fstps (%ecx)
+	jmp   epilogue
+
+retdouble:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	fstpl (%ecx)
+	jmp   epilogue
+
+retlongdouble:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	fstpt (%ecx)
+	jmp   epilogue
+
+retint64:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	movl  %eax,0(%ecx)
+	movl  %edx,4(%ecx)
+	jmp   epilogue
+
+retstruct1b:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	movb  %al,0(%ecx)
+	jmp   epilogue
+
+retstruct2b:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	movw  %ax,0(%ecx)
+	jmp   epilogue
+
+retint:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	movl  %eax,0(%ecx)
+
+retstruct:
+	/* Nothing to do!  */
+
+noretval:
+epilogue:
+	popl %esi
+	movl %ebp,%esp
+	popl %ebp
+	ret
+
+.LFE1:
+.ffi_call_SYSV_end:
+
+	.align	4
+FFI_HIDDEN (ffi_closure_SYSV)
+.globl _ffi_closure_SYSV
+
+_ffi_closure_SYSV:
+.LFB2:
+	pushl	%ebp
+.LCFI2:
+	movl	%esp, %ebp
+.LCFI3:
+	subl	$40, %esp
+	leal	-24(%ebp), %edx
+	movl	%edx, -12(%ebp)	/* resp */
+	leal	8(%ebp), %edx
+	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
+	leal	-12(%ebp), %edx
+	movl	%edx, (%esp)	/* &resp */
+	movl	%ebx, 8(%esp)
+.LCFI7:
+	call	L_ffi_closure_SYSV_inner$stub
+	movl	8(%esp), %ebx
+	movl	-12(%ebp), %ecx
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lcls_retint
+
+	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
+	cmpl	$FFI_TYPE_UINT64, %eax
+	jge	0f
+	cmpl	$FFI_TYPE_UINT8, %eax
+	jge	.Lcls_retint
+
+0:	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lcls_retllong
+	cmpl	$FFI_TYPE_SMALL_STRUCT_1B, %eax
+	je	.Lcls_retstruct1b
+	cmpl	$FFI_TYPE_SMALL_STRUCT_2B, %eax
+	je	.Lcls_retstruct2b
+	cmpl	$FFI_TYPE_STRUCT, %eax
+	je	.Lcls_retstruct
+.Lcls_epilogue:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret
+.Lcls_retint:
+	movl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retfloat:
+	flds	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retdouble:
+	fldl	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retldouble:
+	fldt	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retllong:
+	movl	(%ecx), %eax
+	movl	4(%ecx), %edx
+	jmp	.Lcls_epilogue
+.Lcls_retstruct1b:
+	movsbl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retstruct2b:
+	movswl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retstruct:
+	lea -8(%ebp),%esp
+	movl	%ebp, %esp
+	popl	%ebp
+	ret $4
+.LFE2:
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+	.align	4
+FFI_HIDDEN (ffi_closure_raw_SYSV)
+.globl _ffi_closure_raw_SYSV
+
+_ffi_closure_raw_SYSV:
+.LFB3:
+	pushl	%ebp
+.LCFI4:
+	movl	%esp, %ebp
+.LCFI5:
+	pushl	%esi
+.LCFI6:
+	subl	$36, %esp
+	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
+	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+	movl	%edx, 12(%esp)	/* user_data */
+	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
+	movl	%edx, 8(%esp)	/* raw_args */
+	leal	-24(%ebp), %edx
+	movl	%edx, 4(%esp)	/* &res */
+	movl	%esi, (%esp)	/* cif */
+	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
+	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lrcls_retint
+
+	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
+	cmpl	$FFI_TYPE_UINT64, %eax
+	jge	0f
+	cmpl	$FFI_TYPE_UINT8, %eax
+	jge	.Lrcls_retint
+0:
+	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lrcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lrcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lrcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lrcls_retllong
+.Lrcls_epilogue:
+	addl	$36, %esp
+	popl	%esi
+	popl	%ebp
+	ret
+.Lrcls_retint:
+	movl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+.Lrcls_retfloat:
+	flds	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retdouble:
+	fldl	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retldouble:
+	fldt	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retllong:
+	movl	-24(%ebp), %eax
+	movl	-20(%ebp), %edx
+	jmp	.Lrcls_epilogue
+.LFE3:
+#endif
+
+.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
+L_ffi_closure_SYSV_inner$stub:
+	.indirect_symbol _ffi_closure_SYSV_inner
+	hlt ; hlt ; hlt ; hlt ; hlt
+
+
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+	.set	L$set$0,LECIE1-LSCIE1
+	.long	L$set$0
+LSCIE1:
+	.long	0x0
+	.byte	0x1
+	.ascii "zR\0"
+	.byte	0x1
+	.byte	0x7c
+	.byte	0x8
+	.byte	0x1
+	.byte	0x10
+	.byte	0xc
+	.byte	0x5
+	.byte	0x4
+	.byte	0x88
+	.byte	0x1
+	.align 2
+LECIE1:
+.globl _ffi_call_SYSV.eh
+_ffi_call_SYSV.eh:
+LSFDE1:
+	.set	L$set$1,LEFDE1-LASFDE1
+	.long	L$set$1
+LASFDE1:
+	.long	LASFDE1-EH_frame1
+	.long	.LFB1-.
+	.set L$set$2,.LFE1-.LFB1
+	.long L$set$2
+	.byte	0x0
+	.byte	0x4
+	.set L$set$3,.LCFI0-.LFB1
+	.long L$set$3
+	.byte	0xe
+	.byte	0x8
+	.byte	0x84
+	.byte	0x2
+	.byte	0x4
+	.set L$set$4,.LCFI1-.LCFI0
+	.long L$set$4
+	.byte	0xd
+	.byte	0x4
+	.align 2
+LEFDE1:
+.globl _ffi_closure_SYSV.eh
+_ffi_closure_SYSV.eh:
+LSFDE2:
+	.set	L$set$5,LEFDE2-LASFDE2
+	.long	L$set$5
+LASFDE2:
+	.long	LASFDE2-EH_frame1
+	.long	.LFB2-.
+	.set L$set$6,.LFE2-.LFB2
+	.long L$set$6
+	.byte	0x0
+	.byte	0x4
+	.set L$set$7,.LCFI2-.LFB2
+	.long L$set$7
+	.byte	0xe
+	.byte	0x8
+	.byte	0x84
+	.byte	0x2
+	.byte	0x4
+	.set L$set$8,.LCFI3-.LCFI2
+	.long L$set$8
+	.byte	0xd
+	.byte	0x4
+	.align 2
+LEFDE2:
+
+#if !FFI_NO_RAW_API
+
+.globl _ffi_closure_raw_SYSV.eh
+_ffi_closure_raw_SYSV.eh:
+LSFDE3:
+	.set	L$set$10,LEFDE3-LASFDE3
+	.long	L$set$10
+LASFDE3:
+	.long	LASFDE3-EH_frame1
+	.long	.LFB3-.
+	.set L$set$11,.LFE3-.LFB3
+	.long L$set$11
+	.byte	0x0
+	.byte	0x4
+	.set L$set$12,.LCFI4-.LFB3
+	.long L$set$12
+	.byte	0xe
+	.byte	0x8
+	.byte	0x84
+	.byte	0x2
+	.byte	0x4
+	.set L$set$13,.LCFI5-.LCFI4
+	.long L$set$13
+	.byte	0xd
+	.byte	0x4
+	.byte	0x4
+	.set L$set$14,.LCFI6-.LCFI5
+	.long L$set$14
+	.byte	0x85
+	.byte	0x3
+	.align 2
+LEFDE3:
+
+#endif
+
+#endif /* ifndef __x86_64__ */
diff --git a/src/x86/darwin64.S b/src/x86/darwin64.S
new file mode 100644
index 0000000..2f7394e
--- /dev/null
+++ b/src/x86/darwin64.S
@@ -0,0 +1,416 @@
+/* -----------------------------------------------------------------------
+   darwin64.S - Copyright (c) 2006 Free Software Foundation, Inc.
+	        Copyright (c) 2008 Red Hat, Inc.
+   derived from unix64.S
+
+   x86-64 Foreign Function Interface for Darwin.
+
+   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.
+   ----------------------------------------------------------------------- */
+
+#ifdef __x86_64__
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.file "darwin64.S"
+.text
+
+/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
+		    void *raddr, void (*fnaddr)(void));
+
+   Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
+   for this function.  This has been allocated by ffi_call.  We also
+   deallocate some of the stack that has been alloca'd.  */
+
+	.align	3
+	.globl	_ffi_call_unix64
+
+_ffi_call_unix64:
+LUW0:
+	movq	(%rsp), %r10		/* Load return address.  */
+	leaq	(%rdi, %rsi), %rax	/* Find local stack base.  */
+	movq	%rdx, (%rax)		/* Save flags.  */
+	movq	%rcx, 8(%rax)		/* Save raddr.  */
+	movq	%rbp, 16(%rax)		/* Save old frame pointer.  */
+	movq	%r10, 24(%rax)		/* Relocate return address.  */
+	movq	%rax, %rbp		/* Finalize local stack frame.  */
+LUW1:
+	movq	%rdi, %r10		/* Save a copy of the register area. */
+	movq	%r8, %r11		/* Save a copy of the target fn.  */
+	movl	%r9d, %eax		/* Set number of SSE registers.  */
+
+	/* Load up all argument registers.  */
+	movq	(%r10), %rdi
+	movq	8(%r10), %rsi
+	movq	16(%r10), %rdx
+	movq	24(%r10), %rcx
+	movq	32(%r10), %r8
+	movq	40(%r10), %r9
+	testl	%eax, %eax
+	jnz	Lload_sse
+Lret_from_load_sse:
+
+	/* Deallocate the reg arg area.  */
+	leaq	176(%r10), %rsp
+
+	/* Call the user function.  */
+	call	*%r11
+
+	/* Deallocate stack arg area; local stack frame in redzone.  */
+	leaq	24(%rbp), %rsp
+
+	movq	0(%rbp), %rcx		/* Reload flags.  */
+	movq	8(%rbp), %rdi		/* Reload raddr.  */
+	movq	16(%rbp), %rbp		/* Reload old frame pointer.  */
+LUW2:
+
+	/* The first byte of the flags contains the FFI_TYPE.  */
+	movzbl	%cl, %r10d
+	leaq	Lstore_table(%rip), %r11
+	movslq	(%r11, %r10, 4), %r10
+	addq	%r11, %r10
+	jmp	*%r10
+
+Lstore_table:
+	.long	Lst_void-Lstore_table		/* FFI_TYPE_VOID */
+	.long	Lst_sint32-Lstore_table		/* FFI_TYPE_INT */
+	.long	Lst_float-Lstore_table		/* FFI_TYPE_FLOAT */
+	.long	Lst_double-Lstore_table		/* FFI_TYPE_DOUBLE */
+	.long	Lst_ldouble-Lstore_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	Lst_uint8-Lstore_table		/* FFI_TYPE_UINT8 */
+	.long	Lst_sint8-Lstore_table		/* FFI_TYPE_SINT8 */
+	.long	Lst_uint16-Lstore_table		/* FFI_TYPE_UINT16 */
+	.long	Lst_sint16-Lstore_table		/* FFI_TYPE_SINT16 */
+	.long	Lst_uint32-Lstore_table		/* FFI_TYPE_UINT32 */
+	.long	Lst_sint32-Lstore_table		/* FFI_TYPE_SINT32 */
+	.long	Lst_int64-Lstore_table		/* FFI_TYPE_UINT64 */
+	.long	Lst_int64-Lstore_table		/* FFI_TYPE_SINT64 */
+	.long	Lst_struct-Lstore_table		/* FFI_TYPE_STRUCT */
+	.long	Lst_int64-Lstore_table		/* FFI_TYPE_POINTER */
+
+	.text
+	.align	3
+Lst_void:
+	ret
+	.align	3
+Lst_uint8:
+	movzbq	%al, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align	3
+Lst_sint8:
+	movsbq	%al, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align	3
+Lst_uint16:
+	movzwq	%ax, %rax
+	movq	%rax, (%rdi)
+	.align	3
+Lst_sint16:
+	movswq	%ax, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align	3
+Lst_uint32:
+	movl	%eax, %eax
+	movq	%rax, (%rdi)
+	.align	3
+Lst_sint32:
+	cltq
+	movq	%rax, (%rdi)
+	ret
+	.align	3
+Lst_int64:
+	movq	%rax, (%rdi)
+	ret
+	.align	3
+Lst_float:
+	movss	%xmm0, (%rdi)
+	ret
+	.align	3
+Lst_double:
+	movsd	%xmm0, (%rdi)
+	ret
+Lst_ldouble:
+	fstpt	(%rdi)
+	ret
+	.align	3
+Lst_struct:
+	leaq	-20(%rsp), %rsi		/* Scratch area in redzone.  */
+
+	/* We have to locate the values now, and since we don't want to
+	   write too much data into the user's return value, we spill the
+	   value to a 16 byte scratch area first.  Bits 8, 9, and 10
+	   control where the values are located.  Only one of the three
+	   bits will be set; see ffi_prep_cif_machdep for the pattern.  */
+	movd	%xmm0, %r10
+	movd	%xmm1, %r11
+	testl	$0x100, %ecx
+	cmovnz	%rax, %rdx
+	cmovnz	%r10, %rax
+	testl	$0x200, %ecx
+	cmovnz	%r10, %rdx
+	testl	$0x400, %ecx
+	cmovnz	%r10, %rax
+	cmovnz	%r11, %rdx
+	movq	%rax, (%rsi)
+	movq	%rdx, 8(%rsi)
+
+	/* Bits 12-31 contain the true size of the structure.  Copy from
+	   the scratch area to the true destination.  */
+	shrl	$12, %ecx
+	rep movsb
+	ret
+
+	/* Many times we can avoid loading any SSE registers at all.
+	   It's not worth an indirect jump to load the exact set of
+	   SSE registers needed; zero or all is a good compromise.  */
+	.align	3
+LUW3:
+Lload_sse:
+	movdqa	48(%r10), %xmm0
+	movdqa	64(%r10), %xmm1
+	movdqa	80(%r10), %xmm2
+	movdqa	96(%r10), %xmm3
+	movdqa	112(%r10), %xmm4
+	movdqa	128(%r10), %xmm5
+	movdqa	144(%r10), %xmm6
+	movdqa	160(%r10), %xmm7
+	jmp	Lret_from_load_sse
+
+LUW4:
+	.align	3
+	.globl	_ffi_closure_unix64
+
+_ffi_closure_unix64:
+LUW5:
+	/* The carry flag is set by the trampoline iff SSE registers
+	   are used.  Don't clobber it before the branch instruction.  */
+	leaq    -200(%rsp), %rsp
+LUW6:
+	movq	%rdi, (%rsp)
+	movq    %rsi, 8(%rsp)
+	movq    %rdx, 16(%rsp)
+	movq    %rcx, 24(%rsp)
+	movq    %r8, 32(%rsp)
+	movq    %r9, 40(%rsp)
+	jc      Lsave_sse
+Lret_from_save_sse:
+
+	movq	%r10, %rdi
+	leaq	176(%rsp), %rsi
+	movq	%rsp, %rdx
+	leaq	208(%rsp), %rcx
+	call	_ffi_closure_unix64_inner
+
+	/* Deallocate stack frame early; return value is now in redzone.  */
+	addq	$200, %rsp
+LUW7:
+
+	/* The first byte of the return value contains the FFI_TYPE.  */
+	movzbl	%al, %r10d
+	leaq	Lload_table(%rip), %r11
+	movslq	(%r11, %r10, 4), %r10
+	addq	%r11, %r10
+	jmp	*%r10
+
+Lload_table:
+	.long	Lld_void-Lload_table		/* FFI_TYPE_VOID */
+	.long	Lld_int32-Lload_table		/* FFI_TYPE_INT */
+	.long	Lld_float-Lload_table		/* FFI_TYPE_FLOAT */
+	.long	Lld_double-Lload_table		/* FFI_TYPE_DOUBLE */
+	.long	Lld_ldouble-Lload_table		/* FFI_TYPE_LONGDOUBLE */
+	.long	Lld_int8-Lload_table		/* FFI_TYPE_UINT8 */
+	.long	Lld_int8-Lload_table		/* FFI_TYPE_SINT8 */
+	.long	Lld_int16-Lload_table		/* FFI_TYPE_UINT16 */
+	.long	Lld_int16-Lload_table		/* FFI_TYPE_SINT16 */
+	.long	Lld_int32-Lload_table		/* FFI_TYPE_UINT32 */
+	.long	Lld_int32-Lload_table		/* FFI_TYPE_SINT32 */
+	.long	Lld_int64-Lload_table		/* FFI_TYPE_UINT64 */
+	.long	Lld_int64-Lload_table		/* FFI_TYPE_SINT64 */
+	.long	Lld_struct-Lload_table		/* FFI_TYPE_STRUCT */
+	.long	Lld_int64-Lload_table		/* FFI_TYPE_POINTER */
+
+	.text
+	.align	3
+Lld_void:
+	ret
+	.align	3
+Lld_int8:
+	movzbl	-24(%rsp), %eax
+	ret
+	.align	3
+Lld_int16:
+	movzwl	-24(%rsp), %eax
+	ret
+	.align	3
+Lld_int32:
+	movl	-24(%rsp), %eax
+	ret
+	.align	3
+Lld_int64:
+	movq	-24(%rsp), %rax
+	ret
+	.align	3
+Lld_float:
+	movss	-24(%rsp), %xmm0
+	ret
+	.align	3
+Lld_double:
+	movsd	-24(%rsp), %xmm0
+	ret
+	.align	3
+Lld_ldouble:
+	fldt	-24(%rsp)
+	ret
+	.align	3
+Lld_struct:
+	/* There are four possibilities here, %rax/%rdx, %xmm0/%rax,
+	   %rax/%xmm0, %xmm0/%xmm1.  We collapse two by always loading
+	   both rdx and xmm1 with the second word.  For the remaining,
+	   bit 8 set means xmm0 gets the second word, and bit 9 means
+	   that rax gets the second word.  */
+	movq	-24(%rsp), %rcx
+	movq	-16(%rsp), %rdx
+	movq	-16(%rsp), %xmm1
+	testl	$0x100, %eax
+	cmovnz	%rdx, %rcx
+	movd	%rcx, %xmm0
+	testl	$0x200, %eax
+	movq	-24(%rsp), %rax
+	cmovnz	%rdx, %rax
+	ret
+
+	/* See the comment above Lload_sse; the same logic applies here.  */
+	.align	3
+LUW8:
+Lsave_sse:
+	movdqa	%xmm0, 48(%rsp)
+	movdqa	%xmm1, 64(%rsp)
+	movdqa	%xmm2, 80(%rsp)
+	movdqa	%xmm3, 96(%rsp)
+	movdqa	%xmm4, 112(%rsp)
+	movdqa	%xmm5, 128(%rsp)
+	movdqa	%xmm6, 144(%rsp)
+	movdqa	%xmm7, 160(%rsp)
+	jmp	Lret_from_save_sse
+
+LUW9:
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+	.set	L$set$0,LECIE1-LSCIE1		/* CIE Length */
+	.long	L$set$0
+LSCIE1:
+	.long	0x0		/* CIE Identifier Tag */
+	.byte	0x1		/* CIE Version */
+	.ascii	"zR\0"		/* CIE Augmentation */
+	.byte	0x1		/* uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x78		/* sleb128 -8; CIE Data Alignment Factor */
+	.byte	0x10		/* CIE RA Column */
+	.byte	0x1		/* uleb128 0x1; Augmentation size */
+	.byte	0x10		/* FDE Encoding (pcrel sdata4) */
+	.byte	0xc		/* DW_CFA_def_cfa, %rsp offset 8 */
+	.byte	0x7		/* uleb128 0x7 */
+	.byte	0x8		/* uleb128 0x8 */
+	.byte	0x90		/* DW_CFA_offset, column 0x10 */
+	.byte	0x1
+	.align	3
+LECIE1:
+	.globl _ffi_call_unix64.eh
+_ffi_call_unix64.eh:
+LSFDE1:
+	.set	L$set$1,LEFDE1-LASFDE1	/* FDE Length */
+	.long	L$set$1
+LASFDE1:
+	.long	LASFDE1-EH_frame1	/* FDE CIE offset */
+	.quad	LUW0-.			/* FDE initial location */
+	.set	L$set$2,LUW4-LUW0	/* FDE address range */
+	.quad	L$set$2
+	.byte	0x0			/* Augmentation size */
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$3,LUW1-LUW0
+	.long	L$set$3
+
+	/* New stack frame based off rbp.  This is a itty bit of unwind
+	   trickery in that the CFA *has* changed.  There is no easy way
+	   to describe it correctly on entry to the function.  Fortunately,
+	   it doesn't matter too much since at all points we can correctly
+	   unwind back to ffi_call.  Note that the location to which we
+	   moved the return address is (the new) CFA-8, so from the
+	   perspective of the unwind info, it hasn't moved.  */
+	.byte	0xc			/* DW_CFA_def_cfa, %rbp offset 32 */
+	.byte	0x6
+	.byte	0x20
+	.byte	0x80+6			/* DW_CFA_offset, %rbp offset 2*-8 */
+	.byte	0x2
+	.byte	0xa			/* DW_CFA_remember_state */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$4,LUW2-LUW1
+	.long	L$set$4
+	.byte	0xc			/* DW_CFA_def_cfa, %rsp offset 8 */
+	.byte	0x7
+	.byte	0x8
+	.byte	0xc0+6			/* DW_CFA_restore, %rbp */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$5,LUW3-LUW2
+	.long	L$set$5
+	.byte	0xb			/* DW_CFA_restore_state */
+
+	.align	3
+LEFDE1:
+	.globl _ffi_closure_unix64.eh
+_ffi_closure_unix64.eh:
+LSFDE3:
+	.set	L$set$6,LEFDE3-LASFDE3	/* FDE Length */
+	.long	L$set$6
+LASFDE3:
+	.long	LASFDE3-EH_frame1	/* FDE CIE offset */
+	.quad	LUW5-.			/* FDE initial location */
+	.set	L$set$7,LUW9-LUW5	/* FDE address range */
+	.quad	L$set$7
+	.byte	0x0			/* Augmentation size */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$8,LUW6-LUW5
+	.long	L$set$8
+	.byte	0xe			/* DW_CFA_def_cfa_offset */
+	.byte	208,1			/* uleb128 208 */
+	.byte	0xa			/* DW_CFA_remember_state */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$9,LUW7-LUW6
+	.long	L$set$9
+	.byte	0xe			/* DW_CFA_def_cfa_offset */
+	.byte	0x8
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$10,LUW8-LUW7
+	.long	L$set$10
+	.byte	0xb			/* DW_CFA_restore_state */
+
+	.align	3
+LEFDE3:
+	.subsections_via_symbols
+
+#endif /* __x86_64__ */
diff --git a/src/x86/ffi.c b/src/x86/ffi.c
index 9a59218..006c95d 100644
--- a/src/x86/ffi.c
+++ b/src/x86/ffi.c
@@ -1,6 +1,5 @@
 /* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 2017  Anthony Green
-           Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008  Red Hat, Inc.
+   ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008  Red Hat, Inc.
            Copyright (c) 2002  Ranjit Mathew
            Copyright (c) 2002  Bo Thorsen
            Copyright (c) 2002  Roger Sayle
@@ -29,503 +28,694 @@
    DEALINGS IN THE SOFTWARE.
    ----------------------------------------------------------------------- */
 
-#if defined(__i386__) || defined(_M_IX86)
+#if !defined(__x86_64__) || defined(_WIN64) || defined(__CYGWIN__)
+
+#ifdef _WIN64
+#include <windows.h>
+#endif
+
 #include <ffi.h>
 #include <ffi_common.h>
-#include <stdint.h>
+
 #include <stdlib.h>
-#include "internal.h"
 
-/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
-   all further uses in this file will refer to the 80-bit type.  */
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-# if FFI_TYPE_LONGDOUBLE != 4
-#  error FFI_TYPE_LONGDOUBLE out of date
-# endif
-#else
-# undef FFI_TYPE_LONGDOUBLE
-# define FFI_TYPE_LONGDOUBLE 4
-#endif
 
-#if defined(__GNUC__) && !defined(__declspec)
-# define __declspec(x)  __attribute__((x))
-#endif
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
 
-#if defined(_MSC_VER) && defined(_M_IX86)
-/* Stack is not 16-byte aligned on Windows.  */
-#define STACK_ALIGN(bytes) (bytes)
-#else
-#define STACK_ALIGN(bytes) FFI_ALIGN (bytes, 16)
-#endif
-
-/* Perform machine dependent cif processing.  */
-ffi_status FFI_HIDDEN
-ffi_prep_cif_machdep(ffi_cif *cif)
+unsigned int ffi_prep_args(char *stack, extended_cif *ecif);
+unsigned int ffi_prep_args(char *stack, extended_cif *ecif)
 {
-  size_t bytes = 0;
-  int i, n, flags, cabi = cif->abi;
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+#ifndef X86_WIN64
+  const int cabi = ecif->cif->abi;
+  const int dir = (cabi == FFI_PASCAL || cabi == FFI_REGISTER) ? -1 : +1;
+  unsigned int stack_args_count = 0;
+  void *p_stack_data[3];
+  char *argp2 = stack;
+#else
+  #define dir 1
+#endif
 
-  switch (cabi)
+  argp = stack;
+
+  if ((ecif->cif->flags == FFI_TYPE_STRUCT
+       || ecif->cif->flags == FFI_TYPE_MS_STRUCT)
+#ifdef X86_WIN64
+      && ((ecif->cif->rtype->size & (1 | 2 | 4 | 8)) == 0)
+#endif
+      )
     {
-    case FFI_SYSV:
-    case FFI_STDCALL:
-    case FFI_THISCALL:
-    case FFI_FASTCALL:
-    case FFI_MS_CDECL:
-    case FFI_PASCAL:
-    case FFI_REGISTER:
-      break;
-    default:
-      return FFI_BAD_ABI;
+#ifndef X86_WIN64
+      /* For fastcall/thiscall/register this is first register-passed
+         argument.  */
+      if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL || cabi == FFI_REGISTER)
+        {
+          p_stack_data[stack_args_count] = argp;
+          ++stack_args_count;
+        }
+#endif
+
+      *(void **) argp = ecif->rvalue;
+      argp += sizeof(void*);
     }
 
+  p_arg  = ecif->cif->arg_types;
+  p_argv = ecif->avalue;
+  if (dir < 0)
+    {
+      const int nargs = ecif->cif->nargs - 1;
+      if (nargs > 0)
+      {
+        p_arg  += nargs;
+        p_argv += nargs;
+      }
+    }
+
+  for (i = ecif->cif->nargs;
+       i != 0;
+       i--, p_arg += dir, p_argv += dir)
+    {
+      /* Align if necessary */
+      if ((sizeof(void*) - 1) & (size_t) argp)
+        argp = (char *) ALIGN(argp, sizeof(void*));
+
+      size_t z = (*p_arg)->size;
+
+#ifdef X86_WIN64
+      if (z > FFI_SIZEOF_ARG
+          || ((*p_arg)->type == FFI_TYPE_STRUCT
+              && (z & (1 | 2 | 4 | 8)) == 0)
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+          || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
+#endif
+          )
+        {
+          z = FFI_SIZEOF_ARG;
+          *(void **)argp = *p_argv;
+        }
+      else if ((*p_arg)->type == FFI_TYPE_FLOAT)
+        {
+          memcpy(argp, *p_argv, z);
+        }
+      else
+#endif
+      if (z < FFI_SIZEOF_ARG)
+        {
+          z = FFI_SIZEOF_ARG;
+          switch ((*p_arg)->type)
+            {
+            case FFI_TYPE_SINT8:
+              *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_UINT8:
+              *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_SINT16:
+              *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_UINT16:
+              *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_SINT32:
+              *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_UINT32:
+              *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_STRUCT:
+              *(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
+              break;
+
+            default:
+              FFI_ASSERT(0);
+            }
+        }
+      else
+        {
+          memcpy(argp, *p_argv, z);
+        }
+
+#ifndef X86_WIN64
+    /* For thiscall/fastcall/register convention register-passed arguments
+       are the first two none-floating-point arguments with a size
+       smaller or equal to sizeof (void*).  */
+    if ((z == FFI_SIZEOF_ARG)
+        && ((cabi == FFI_REGISTER)
+          || (cabi == FFI_THISCALL && stack_args_count < 1)
+          || (cabi == FFI_FASTCALL && stack_args_count < 2))
+        && ((*p_arg)->type != FFI_TYPE_FLOAT && (*p_arg)->type != FFI_TYPE_STRUCT)
+       )
+      {
+        if (dir < 0 && stack_args_count > 2)
+          {
+            /* Iterating arguments backwards, so first register-passed argument
+               will be passed last. Shift temporary values to make place. */
+            p_stack_data[0] = p_stack_data[1];
+            p_stack_data[1] = p_stack_data[2];
+            stack_args_count = 2;
+          }
+
+        p_stack_data[stack_args_count] = argp;
+        ++stack_args_count;
+      }
+#endif
+
+#ifdef X86_WIN64
+      argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
+#else
+      argp += z;
+#endif
+    }
+
+#ifndef X86_WIN64
+  /* We need to move the register-passed arguments for thiscall/fastcall/register
+     on top of stack, so that those can be moved to registers by call-handler.  */
+  if (stack_args_count > 0)
+    {
+      if (dir < 0 && stack_args_count > 1)
+        {
+          /* Reverse order if iterating arguments backwards */
+          ffi_arg tmp = *(ffi_arg*) p_stack_data[0];
+          *(ffi_arg*) p_stack_data[0] = *(ffi_arg*) p_stack_data[stack_args_count - 1];
+          *(ffi_arg*) p_stack_data[stack_args_count - 1] = tmp;
+        }
+      
+      int i;
+      for (i = 0; i < stack_args_count; i++)
+        {
+          if (p_stack_data[i] != argp2)
+            {
+              ffi_arg tmp = *(ffi_arg*) p_stack_data[i];
+              memmove (argp2 + FFI_SIZEOF_ARG, argp2, (size_t) ((char*) p_stack_data[i] - (char*)argp2));
+              *(ffi_arg *) argp2 = tmp;
+            }
+
+          argp2 += FFI_SIZEOF_ARG;
+        }
+    }
+
+    return stack_args_count;
+#endif
+    return 0;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  unsigned int i;
+  ffi_type **ptr;
+
+  /* Set the return type flag */
   switch (cif->rtype->type)
     {
     case FFI_TYPE_VOID:
-      flags = X86_RET_VOID;
-      break;
-    case FFI_TYPE_FLOAT:
-      flags = X86_RET_FLOAT;
-      break;
-    case FFI_TYPE_DOUBLE:
-      flags = X86_RET_DOUBLE;
-      break;
-    case FFI_TYPE_LONGDOUBLE:
-      flags = X86_RET_LDOUBLE;
-      break;
     case FFI_TYPE_UINT8:
-      flags = X86_RET_UINT8;
-      break;
     case FFI_TYPE_UINT16:
-      flags = X86_RET_UINT16;
-      break;
     case FFI_TYPE_SINT8:
-      flags = X86_RET_SINT8;
-      break;
     case FFI_TYPE_SINT16:
-      flags = X86_RET_SINT16;
-      break;
-    case FFI_TYPE_INT:
-    case FFI_TYPE_SINT32:
+#ifdef X86_WIN64
     case FFI_TYPE_UINT32:
-    case FFI_TYPE_POINTER:
-      flags = X86_RET_INT32;
-      break;
+    case FFI_TYPE_SINT32:
+#endif
     case FFI_TYPE_SINT64:
-    case FFI_TYPE_UINT64:
-      flags = X86_RET_INT64;
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+#ifndef X86_WIN64
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+#endif
+#endif
+      cif->flags = (unsigned) cif->rtype->type;
       break;
+
+    case FFI_TYPE_UINT64:
+#ifdef X86_WIN64
+    case FFI_TYPE_POINTER:
+#endif
+      cif->flags = FFI_TYPE_SINT64;
+      break;
+
     case FFI_TYPE_STRUCT:
 #ifndef X86
-      /* ??? This should be a different ABI rather than an ifdef.  */
       if (cif->rtype->size == 1)
-	flags = X86_RET_STRUCT_1B;
+        {
+          cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
+        }
       else if (cif->rtype->size == 2)
-	flags = X86_RET_STRUCT_2B;
+        {
+          cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
+        }
       else if (cif->rtype->size == 4)
-	flags = X86_RET_INT32;
+        {
+#ifdef X86_WIN64
+          cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
+#else
+          cif->flags = FFI_TYPE_INT; /* same as int type */
+#endif
+        }
       else if (cif->rtype->size == 8)
-	flags = X86_RET_INT64;
+        {
+          cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
+        }
       else
 #endif
-	{
-	do_struct:
-	  switch (cabi)
-	    {
-	    case FFI_THISCALL:
-	    case FFI_FASTCALL:
-	    case FFI_STDCALL:
-	    case FFI_MS_CDECL:
-	      flags = X86_RET_STRUCTARG;
-	      break;
-	    default:
-	      flags = X86_RET_STRUCTPOP;
-	      break;
-	    }
-	  /* Allocate space for return value pointer.  */
-	  bytes += FFI_ALIGN (sizeof(void*), FFI_SIZEOF_ARG);
-	}
+        {
+#ifdef X86_WIN32
+          if (cif->abi == FFI_MS_CDECL)
+            cif->flags = FFI_TYPE_MS_STRUCT;
+          else
+#endif
+            cif->flags = FFI_TYPE_STRUCT;
+          /* allocate space for return value pointer */
+          cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
+        }
       break;
-    case FFI_TYPE_COMPLEX:
-      switch (cif->rtype->elements[0]->type)
-	{
-	case FFI_TYPE_DOUBLE:
-	case FFI_TYPE_LONGDOUBLE:
-	case FFI_TYPE_SINT64:
-	case FFI_TYPE_UINT64:
-	  goto do_struct;
-	case FFI_TYPE_FLOAT:
-	case FFI_TYPE_INT:
-	case FFI_TYPE_SINT32:
-	case FFI_TYPE_UINT32:
-	  flags = X86_RET_INT64;
-	  break;
-	case FFI_TYPE_SINT16:
-	case FFI_TYPE_UINT16:
-	  flags = X86_RET_INT32;
-	  break;
-	case FFI_TYPE_SINT8:
-	case FFI_TYPE_UINT8:
-	  flags = X86_RET_STRUCT_2B;
-	  break;
-	default:
-	  return FFI_BAD_TYPEDEF;
-	}
-      break;
+
     default:
-      return FFI_BAD_TYPEDEF;
+#ifdef X86_WIN64
+      cif->flags = FFI_TYPE_SINT64;
+      break;
+    case FFI_TYPE_INT:
+      cif->flags = FFI_TYPE_SINT32;
+#else
+      cif->flags = FFI_TYPE_INT;
+#endif
+      break;
     }
-  cif->flags = flags;
 
-  for (i = 0, n = cif->nargs; i < n; i++)
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
     {
-      ffi_type *t = cif->arg_types[i];
-
-      bytes = FFI_ALIGN (bytes, t->alignment);
-      bytes += FFI_ALIGN (t->size, FFI_SIZEOF_ARG);
+      if (((*ptr)->alignment - 1) & cif->bytes)
+        cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
+      cif->bytes += (unsigned)ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
     }
-  cif->bytes = bytes;
+
+#ifdef X86_WIN64
+  /* ensure space for storing four registers */
+  cif->bytes += 4 * FFI_SIZEOF_ARG;
+#endif
+
+#ifndef X86_WIN32
+#ifndef X86_WIN64
+  if (cif->abi == FFI_SYSV || cif->abi == FFI_UNIX64)
+#endif
+    cif->bytes = (cif->bytes + 15) & ~0xF;
+#endif
 
   return FFI_OK;
 }
 
-static ffi_arg
-extend_basic_type(void *arg, int type)
-{
-  switch (type)
-    {
-    case FFI_TYPE_SINT8:
-      return *(SINT8 *)arg;
-    case FFI_TYPE_UINT8:
-      return *(UINT8 *)arg;
-    case FFI_TYPE_SINT16:
-      return *(SINT16 *)arg;
-    case FFI_TYPE_UINT16:
-      return *(UINT16 *)arg;
-
-    case FFI_TYPE_SINT32:
-    case FFI_TYPE_UINT32:
-    case FFI_TYPE_POINTER:
-    case FFI_TYPE_FLOAT:
-      return *(UINT32 *)arg;
-
-    default:
-      abort();
-    }
-}
-
-struct call_frame
-{
-  void *ebp;		/* 0 */
-  void *retaddr;	/* 4 */
-  void (*fn)(void);	/* 8 */
-  int flags;		/* 12 */
-  void *rvalue;		/* 16 */
-  unsigned regs[3];	/* 20-28 */
-};
-
-struct abi_params
-{
-  int dir;		/* parameter growth direction */
-  int static_chain;	/* the static chain register used by gcc */
-  int nregs;		/* number of register parameters */
-  int regs[3];
-};
-
-static const struct abi_params abi_params[FFI_LAST_ABI] = {
-  [FFI_SYSV] = { 1, R_ECX, 0 },
-  [FFI_THISCALL] = { 1, R_EAX, 1, { R_ECX } },
-  [FFI_FASTCALL] = { 1, R_EAX, 2, { R_ECX, R_EDX } },
-  [FFI_STDCALL] = { 1, R_ECX, 0 },
-  [FFI_PASCAL] = { -1, R_ECX, 0 },
-  /* ??? No defined static chain; gcc does not support REGISTER.  */
-  [FFI_REGISTER] = { -1, R_ECX, 3, { R_EAX, R_EDX, R_ECX } },
-  [FFI_MS_CDECL] = { 1, R_ECX, 0 }
-};
-
-#ifdef HAVE_FASTCALL
-  #ifdef _MSC_VER
-    #define FFI_DECLARE_FASTCALL __fastcall
-  #else
-    #define FFI_DECLARE_FASTCALL __declspec(fastcall)
-  #endif
+#ifdef X86_WIN64
+extern int
+ffi_call_win64(unsigned int (*)(char *, extended_cif *), extended_cif *,
+               unsigned, unsigned, unsigned *, void (*fn)(void));
 #else
-  #define FFI_DECLARE_FASTCALL
+extern void
+ffi_call_win32(unsigned int (*)(char *, extended_cif *), extended_cif *,
+               unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
+                          unsigned, unsigned, unsigned *, void (*fn)(void));
 #endif
 
-extern void FFI_DECLARE_FASTCALL ffi_call_i386(struct call_frame *, char *) FFI_HIDDEN;
-
-static void
-ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	      void **avalue, void *closure)
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
-  size_t rsize, bytes;
-  struct call_frame *frame;
-  char *stack, *argp;
-  ffi_type **arg_types;
-  int flags, cabi, i, n, dir, narg_reg;
-  const struct abi_params *pabi;
+  extended_cif ecif;
 
-  flags = cif->flags;
-  cabi = cif->abi;
-  pabi = &abi_params[cabi];
-  dir = pabi->dir;
+  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                     */
 
-  rsize = 0;
-  if (rvalue == NULL)
+#ifdef X86_WIN64
+  if (rvalue == NULL
+      && cif->flags == FFI_TYPE_STRUCT
+      && ((cif->rtype->size & (1 | 2 | 4 | 8)) == 0))
     {
-      switch (flags)
-	{
-	case X86_RET_FLOAT:
-	case X86_RET_DOUBLE:
-	case X86_RET_LDOUBLE:
-	case X86_RET_STRUCTPOP:
-	case X86_RET_STRUCTARG:
-	  /* The float cases need to pop the 387 stack.
-	     The struct cases need to pass a valid pointer to the callee.  */
-	  rsize = cif->rtype->size;
-	  break;
-	default:
-	  /* We can pretend that the callee returns nothing.  */
-	  flags = X86_RET_VOID;
-	  break;
-	}
+      ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
     }
-
-  bytes = STACK_ALIGN (cif->bytes);
-  stack = alloca(bytes + sizeof(*frame) + rsize);
-  argp = (dir < 0 ? stack + bytes : stack);
-  frame = (struct call_frame *)(stack + bytes);
-  if (rsize)
-    rvalue = frame + 1;
-
-  frame->fn = fn;
-  frame->flags = flags;
-  frame->rvalue = rvalue;
-  frame->regs[pabi->static_chain] = (unsigned)closure;
-
-  narg_reg = 0;
-  switch (flags)
+#else
+  if (rvalue == NULL
+      && (cif->flags == FFI_TYPE_STRUCT
+          || cif->flags == FFI_TYPE_MS_STRUCT))
     {
-    case X86_RET_STRUCTARG:
-      /* The pointer is passed as the first argument.  */
-      if (pabi->nregs > 0)
-	{
-	  frame->regs[pabi->regs[0]] = (unsigned)rvalue;
-	  narg_reg = 1;
-	  break;
-	}
-      /* fallthru */
-    case X86_RET_STRUCTPOP:
-      *(void **)argp = rvalue;
-      argp += sizeof(void *);
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+#endif
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+#ifdef X86_WIN64
+    case FFI_WIN64:
+      ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
+                     cif->flags, ecif.rvalue, fn);
+      break;
+#else
+#ifndef X86_WIN32
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
+                    fn);
+      break;
+#else
+    case FFI_SYSV:
+    case FFI_MS_CDECL:
+#endif
+    case FFI_STDCALL:
+    case FFI_THISCALL:
+    case FFI_FASTCALL:
+    case FFI_PASCAL:
+    case FFI_REGISTER:
+      ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
+                     ecif.rvalue, fn);
+      break;
+#endif
+    default:
+      FFI_ASSERT(0);
       break;
     }
-
-  arg_types = cif->arg_types;
-  for (i = 0, n = cif->nargs; i < n; i++)
-    {
-      ffi_type *ty = arg_types[i];
-      void *valp = avalue[i];
-      size_t z = ty->size;
-      int t = ty->type;
-
-      if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
-        {
-	  ffi_arg val = extend_basic_type (valp, t);
-
-	  if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
-	    frame->regs[pabi->regs[narg_reg++]] = val;
-	  else if (dir < 0)
-	    {
-	      argp -= 4;
-	      *(ffi_arg *)argp = val;
-	    }
-	  else
-	    {
-	      *(ffi_arg *)argp = val;
-	      argp += 4;
-	    }
-	}
-      else
-	{
-	  size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
-	  size_t align = FFI_SIZEOF_ARG;
-
-	  /* Issue 434: For thiscall and fastcall, if the paramter passed
-	     as 64-bit integer or struct, all following integer paramters
-	     will be passed on stack.  */
-	  if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
-	      && (t == FFI_TYPE_SINT64
-		  || t == FFI_TYPE_UINT64
-		  || t == FFI_TYPE_STRUCT))
-	    narg_reg = 2;
-
-	  /* Alignment rules for arguments are quite complex.  Vectors and
-	     structures with 16 byte alignment get it.  Note that long double
-	     on Darwin does have 16 byte alignment, and does not get this
-	     alignment if passed directly; a structure with a long double
-	     inside, however, would get 16 byte alignment.  Since libffi does
-	     not support vectors, we need non concern ourselves with other
-	     cases.  */
-	  if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
-	    align = 16;
-	    
-	  if (dir < 0)
-	    {
-	      /* ??? These reverse argument ABIs are probably too old
-		 to have cared about alignment.  Someone should check.  */
-	      argp -= za;
-	      memcpy (argp, valp, z);
-	    }
-	  else
-	    {
-	      argp = (char *)FFI_ALIGN (argp, align);
-	      memcpy (argp, valp, z);
-	      argp += za;
-	    }
-	}
-    }
-  FFI_ASSERT (dir > 0 || argp == stack);
-
-  ffi_call_i386 (frame, stack);
 }
 
-void
-ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, NULL);
-}
-
-void
-ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	     void **avalue, void *closure)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, closure);
-}
 
 /** private members **/
 
-void FFI_HIDDEN ffi_closure_i386(void);
-void FFI_HIDDEN ffi_closure_STDCALL(void);
-void FFI_HIDDEN ffi_closure_REGISTER(void);
+/* The following __attribute__((regparm(1))) decorations will have no effect
+   on MSVC or SUNPRO_C -- standard conventions apply. */
+static unsigned int ffi_prep_incoming_args (char *stack, void **ret,
+                                            void** args, ffi_cif* cif);
+void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
+     __attribute__ ((regparm(1)));
+unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
+     __attribute__ ((regparm(1)));
+unsigned int FFI_HIDDEN ffi_closure_WIN32_inner (ffi_closure *, void **, void *)
+     __attribute__ ((regparm(1)));
+void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
+     __attribute__ ((regparm(1)));
+#ifdef X86_WIN32
+void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
+     __attribute__ ((regparm(1)));
+#endif
+#ifndef X86_WIN64
+void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *);
+void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *);
+void FFI_HIDDEN ffi_closure_FASTCALL (ffi_closure *);
+void FFI_HIDDEN ffi_closure_REGISTER (ffi_closure *);
+#else
+void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
+#endif
 
-struct closure_frame
-{
-  unsigned rettemp[4];				/* 0 */
-  unsigned regs[3];				/* 16-24 */
-  ffi_cif *cif;					/* 28 */
-  void (*fun)(ffi_cif*,void*,void**,void*);	/* 32 */
-  void *user_data;				/* 36 */
-};
+/* This function is jumped to by the trampoline */
 
-int FFI_HIDDEN FFI_DECLARE_FASTCALL
-ffi_closure_inner (struct closure_frame *frame, char *stack)
-{
-  ffi_cif *cif = frame->cif;
-  int cabi, i, n, flags, dir, narg_reg;
-  const struct abi_params *pabi;
-  ffi_type **arg_types;
-  char *argp;
-  void *rvalue;
-  void **avalue;
+#ifdef X86_WIN64
+void * FFI_HIDDEN
+ffi_closure_win64_inner (ffi_closure *closure, void *args) {
+  ffi_cif       *cif;
+  void         **arg_area;
+  void          *result;
+  void          *resp = &result;
 
-  cabi = cif->abi;
-  flags = cif->flags;
-  narg_reg = 0;
-  rvalue = frame->rettemp;
-  pabi = &abi_params[cabi];
-  dir = pabi->dir;
-  argp = (dir < 0 ? stack + STACK_ALIGN (cif->bytes) : stack);
+  cif         = closure->cif;
+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
 
-  switch (flags)
-    {
-    case X86_RET_STRUCTARG:
-      if (pabi->nregs > 0)
-	{
-	  rvalue = (void *)frame->regs[pabi->regs[0]];
-	  narg_reg = 1;
-	  frame->rettemp[0] = (unsigned)rvalue;
-	  break;
-	}
-      /* fallthru */
-    case X86_RET_STRUCTPOP:
-      rvalue = *(void **)argp;
-      argp += sizeof(void *);
-      frame->rettemp[0] = (unsigned)rvalue;
-      break;
-    }
+  /* this call will initialize ARG_AREA, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will change RESP to point to the
+   * structure return address.  */
 
-  n = cif->nargs;
-  avalue = alloca(sizeof(void *) * n);
+  ffi_prep_incoming_args(args, &resp, arg_area, cif);
+  
+  (closure->fun) (cif, resp, arg_area, closure->user_data);
 
-  arg_types = cif->arg_types;
-  for (i = 0; i < n; ++i)
-    {
-      ffi_type *ty = arg_types[i];
-      size_t z = ty->size;
-      int t = ty->type;
-      void *valp;
-
-      if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
-	{
-	  if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
-	    valp = &frame->regs[pabi->regs[narg_reg++]];
-	  else if (dir < 0)
-	    {
-	      argp -= 4;
-	      valp = argp;
-	    }
-	  else
-	    {
-	      valp = argp;
-	      argp += 4;
-	    }
-	}
-      else
-	{
-	  size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
-	  size_t align = FFI_SIZEOF_ARG;
-
-	  /* See the comment in ffi_call_int.  */
-	  if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
-	    align = 16;
-
-	  /* Issue 434: For thiscall and fastcall, if the paramter passed
-	     as 64-bit integer or struct, all following integer paramters
-	     will be passed on stack.  */
-	  if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
-	      && (t == FFI_TYPE_SINT64
-		  || t == FFI_TYPE_UINT64
-		  || t == FFI_TYPE_STRUCT))
-	    narg_reg = 2;
-
-	  if (dir < 0)
-	    {
-	      /* ??? These reverse argument ABIs are probably too old
-		 to have cared about alignment.  Someone should check.  */
-	      argp -= za;
-	      valp = argp;
-	    }
-	  else
-	    {
-	      argp = (char *)FFI_ALIGN (argp, align);
-	      valp = argp;
-	      argp += za;
-	    }
-	}
-
-      avalue[i] = valp;
-    }
-
-  frame->fun (cif, rvalue, avalue, frame->user_data);
-
-  if (cabi == FFI_STDCALL)
-    return flags + (cif->bytes << X86_RET_POP_SHIFT);
-  else
-    return flags;
+  /* The result is returned in rax.  This does the right thing for
+     result types except for floats; we have to 'mov xmm0, rax' in the
+     caller to correct this.
+     TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
+  */
+  return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
 }
 
+#else
+unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
+ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
+{
+  /* our various things...  */
+  ffi_cif       *cif;
+  void         **arg_area;
+
+  cif         = closure->cif;
+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
+
+  /* this call will initialize ARG_AREA, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will change RESP to point to the
+   * structure return address.  */
+
+  ffi_prep_incoming_args(args, respp, arg_area, cif);
+
+  (closure->fun) (cif, *respp, arg_area, closure->user_data);
+
+  return cif->flags;
+}
+
+unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
+ffi_closure_WIN32_inner (ffi_closure *closure, void **respp, void *args)
+{
+  /* our various things...  */
+  ffi_cif       *cif;
+  void         **arg_area;
+  unsigned int   ret;
+
+  cif         = closure->cif;
+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
+
+  /* this call will initialize ARG_AREA, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will change RESP to point to the
+   * structure return address.  */
+
+  ret = ffi_prep_incoming_args(args, respp, arg_area, cif);
+
+  (closure->fun) (cif, *respp, arg_area, closure->user_data);
+
+  return ret;
+}
+#endif /* !X86_WIN64 */
+
+static unsigned int
+ffi_prep_incoming_args(char *stack, void **rvalue, void **avalue,
+                       ffi_cif *cif)
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+#ifndef X86_WIN64
+  const int cabi = cif->abi;
+  const int dir = (cabi == FFI_PASCAL || cabi == FFI_REGISTER) ? -1 : +1;
+  const unsigned int max_stack_count = (cabi == FFI_THISCALL) ? 1
+                                     : (cabi == FFI_FASTCALL) ? 2
+                                     : (cabi == FFI_REGISTER) ? 3
+                                     : 0;
+  unsigned int passed_regs = 0;
+  void *p_stack_data[3] = { stack - 1 };
+#else
+  #define dir 1
+#endif
+
+  argp = stack;
+#ifndef X86_WIN64
+  argp += max_stack_count * FFI_SIZEOF_ARG;
+#endif
+
+  if ((cif->flags == FFI_TYPE_STRUCT
+       || cif->flags == FFI_TYPE_MS_STRUCT)
+#ifdef X86_WIN64
+      && ((cif->rtype->size & (1 | 2 | 4 | 8)) == 0)
+#endif
+      )
+    {
+#ifndef X86_WIN64
+      if (passed_regs < max_stack_count)
+        {
+          *rvalue = *(void**) (stack + (passed_regs*FFI_SIZEOF_ARG));
+          ++passed_regs;
+        }
+      else
+#endif
+        {
+          *rvalue = *(void **) argp;
+          argp += sizeof(void *);
+        }
+    }
+
+#ifndef X86_WIN64
+  /* Do register arguments first  */
+  for (i = 0, p_arg = cif->arg_types; 
+       i < cif->nargs && passed_regs < max_stack_count;
+       i++, p_arg++)
+    {
+      if ((*p_arg)->type == FFI_TYPE_FLOAT
+         || (*p_arg)->type == FFI_TYPE_STRUCT)
+        continue;
+
+      size_t sz = (*p_arg)->size;
+      if(sz == 0 || sz > FFI_SIZEOF_ARG)
+        continue;
+
+      p_stack_data[passed_regs] = avalue + i;
+      avalue[i] = stack + (passed_regs*FFI_SIZEOF_ARG);
+      ++passed_regs;
+    }
+#endif
+
+  p_arg = cif->arg_types;
+  p_argv = avalue;
+  if (dir < 0)
+    {
+      const int nargs = cif->nargs - 1;
+      if (nargs > 0)
+      {
+        p_arg  += nargs;
+        p_argv += nargs;
+      }
+    }
+
+  for (i = cif->nargs;
+       i != 0;
+       i--, p_arg += dir, p_argv += dir)
+    {
+      /* Align if necessary */
+      if ((sizeof(void*) - 1) & (size_t) argp)
+        argp = (char *) ALIGN(argp, sizeof(void*));
+
+      size_t z = (*p_arg)->size;
+
+#ifdef X86_WIN64
+      if (z > FFI_SIZEOF_ARG
+          || ((*p_arg)->type == FFI_TYPE_STRUCT
+              && (z & (1 | 2 | 4 | 8)) == 0)
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+          || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
+#endif
+          )
+        {
+          z = FFI_SIZEOF_ARG;
+          *p_argv = *(void **)argp;
+        }
+      else
+#else
+      if (passed_regs > 0
+          && z <= FFI_SIZEOF_ARG
+          && (p_argv == p_stack_data[0]
+            || p_argv == p_stack_data[1]
+            || p_argv == p_stack_data[2]))
+        {
+          /* Already assigned a register value */
+          continue;
+        }
+      else
+#endif
+        {
+          /* because we're little endian, this is what it turns into.   */
+          *p_argv = (void*) argp;
+        }
+
+#ifdef X86_WIN64
+      argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
+#else
+      argp += z;
+#endif
+    }
+
+  return (size_t)argp - (size_t)stack;
+}
+
+#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   void*  __fun = (void*)(FUN); \
+   void*  __ctx = (void*)(CTX); \
+   *(unsigned char*) &__tramp[0] = 0x41; \
+   *(unsigned char*) &__tramp[1] = 0xbb; \
+   *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
+   *(unsigned char*) &__tramp[6] = 0x48; \
+   *(unsigned char*) &__tramp[7] = 0xb8; \
+   *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
+   *(unsigned char *)  &__tramp[16] = 0x49; \
+   *(unsigned char *)  &__tramp[17] = 0xba; \
+   *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
+   *(unsigned char *)  &__tramp[26] = 0x41; \
+   *(unsigned char *)  &__tramp[27] = 0xff; \
+   *(unsigned char *)  &__tramp[28] = 0xe2; /* jmp %r10 */ \
+ }
+
+/* How to make a trampoline.  Derived from gcc/config/i386/i386.c. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   unsigned int  __fun = (unsigned int)(FUN); \
+   unsigned int  __ctx = (unsigned int)(CTX); \
+   unsigned int  __dis = __fun - (__ctx + 10);  \
+   *(unsigned char*) &__tramp[0] = 0xb8; \
+   *(unsigned int*)  &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
+   *(unsigned char*) &__tramp[5] = 0xe9; \
+   *(unsigned int*)  &__tramp[6] = __dis; /* jmp __fun  */ \
+ }
+
+#define FFI_INIT_TRAMPOLINE_RAW_THISCALL(TRAMP,FUN,CTX,SIZE) \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   unsigned int  __fun = (unsigned int)(FUN); \
+   unsigned int  __ctx = (unsigned int)(CTX); \
+   unsigned int  __dis = __fun - (__ctx + 49);  \
+   unsigned short __size = (unsigned short)(SIZE); \
+   *(unsigned int *) &__tramp[0] = 0x8324048b;      /* mov (%esp), %eax */ \
+   *(unsigned int *) &__tramp[4] = 0x4c890cec;      /* sub $12, %esp */ \
+   *(unsigned int *) &__tramp[8] = 0x04890424;      /* mov %ecx, 4(%esp) */ \
+   *(unsigned char*) &__tramp[12] = 0x24;           /* mov %eax, (%esp) */ \
+   *(unsigned char*) &__tramp[13] = 0xb8; \
+   *(unsigned int *) &__tramp[14] = __size;         /* mov __size, %eax */ \
+   *(unsigned int *) &__tramp[18] = 0x08244c8d;     /* lea 8(%esp), %ecx */ \
+   *(unsigned int *) &__tramp[22] = 0x4802e8c1;     /* shr $2, %eax ; dec %eax */ \
+   *(unsigned short*) &__tramp[26] = 0x0b74;        /* jz 1f */ \
+   *(unsigned int *) &__tramp[28] = 0x8908518b;     /* 2b: mov 8(%ecx), %edx */ \
+   *(unsigned int *) &__tramp[32] = 0x04c18311;     /* mov %edx, (%ecx) ; add $4, %ecx */ \
+   *(unsigned char*) &__tramp[36] = 0x48;           /* dec %eax */ \
+   *(unsigned short*) &__tramp[37] = 0xf575;        /* jnz 2b ; 1f: */ \
+   *(unsigned char*) &__tramp[39] = 0xb8; \
+   *(unsigned int*)  &__tramp[40] = __ctx;          /* movl __ctx, %eax */ \
+   *(unsigned char *)  &__tramp[44] = 0xe8; \
+   *(unsigned int*)  &__tramp[45] = __dis;          /* call __fun  */ \
+   *(unsigned char*)  &__tramp[49] = 0xc2;          /* ret  */ \
+   *(unsigned short*)  &__tramp[50] = (__size + 8); /* ret (__size + 8)  */ \
+ }
+
+#define FFI_INIT_TRAMPOLINE_WIN32(TRAMP,FUN,CTX)  \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   unsigned int  __fun = (unsigned int)(FUN); \
+   unsigned int  __ctx = (unsigned int)(CTX); \
+   unsigned int  __dis = __fun - (__ctx + 10); \
+   *(unsigned char*) &__tramp[0] = 0x68; \
+   *(unsigned int*)  &__tramp[1] = __ctx; /* push __ctx */ \
+   *(unsigned char*) &__tramp[5] = 0xe9; \
+   *(unsigned int*)  &__tramp[6] = __dis; /* jmp __fun  */ \
+ }
+
+/* the cif must already be prep'ed */
+
 ffi_status
 ffi_prep_closure_loc (ffi_closure* closure,
                       ffi_cif* cif,
@@ -533,77 +723,65 @@
                       void *user_data,
                       void *codeloc)
 {
-  char *tramp = closure->tramp;
-  void (*dest)(void);
-  int op = 0xb8;  /* movl imm, %eax */
-
-  switch (cif->abi)
+#ifdef X86_WIN64
+#define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
+#define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
+  if (cif->abi == FFI_WIN64) 
     {
-    case FFI_SYSV:
-    case FFI_THISCALL:
-    case FFI_FASTCALL:
-    case FFI_MS_CDECL:
-      dest = ffi_closure_i386;
-      break;
-    case FFI_STDCALL:
-    case FFI_PASCAL:
-      dest = ffi_closure_STDCALL;
-      break;
-    case FFI_REGISTER:
-      dest = ffi_closure_REGISTER;
-      op = 0x68;  /* pushl imm */
-      break;
-    default:
+      int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
+      FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
+                                 &ffi_closure_win64,
+                                 codeloc, mask);
+      /* make sure we can execute here */
+    }
+#else
+  if (cif->abi == FFI_SYSV)
+    {
+      FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+                           &ffi_closure_SYSV,
+                           (void*)codeloc);
+    }
+  else if (cif->abi == FFI_REGISTER)
+    {
+      FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
+                                   &ffi_closure_REGISTER,
+                                   (void*)codeloc);
+    }
+  else if (cif->abi == FFI_FASTCALL)
+    {
+      FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
+                                   &ffi_closure_FASTCALL,
+                                   (void*)codeloc);
+    }
+  else if (cif->abi == FFI_THISCALL)
+    {
+      FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
+                                   &ffi_closure_THISCALL,
+                                   (void*)codeloc);
+    }
+  else if (cif->abi == FFI_STDCALL || cif->abi == FFI_PASCAL)
+    {
+      FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
+                                   &ffi_closure_STDCALL,
+                                   (void*)codeloc);
+    }
+#ifdef X86_WIN32
+  else if (cif->abi == FFI_MS_CDECL)
+    {
+      FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+                           &ffi_closure_SYSV,
+                           (void*)codeloc);
+    }
+#endif /* X86_WIN32 */
+#endif /* !X86_WIN64 */
+  else
+    {
       return FFI_BAD_ABI;
     }
-
-  /* movl or pushl immediate.  */
-  tramp[0] = op;
-  *(void **)(tramp + 1) = codeloc;
-
-  /* jmp dest */
-  tramp[5] = 0xe9;
-  *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
-
-  closure->cif = cif;
-  closure->fun = fun;
+    
+  closure->cif  = cif;
   closure->user_data = user_data;
-
-  return FFI_OK;
-}
-
-void FFI_HIDDEN ffi_go_closure_EAX(void);
-void FFI_HIDDEN ffi_go_closure_ECX(void);
-void FFI_HIDDEN ffi_go_closure_STDCALL(void);
-
-ffi_status
-ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
-		     void (*fun)(ffi_cif*,void*,void**,void*))
-{
-  void (*dest)(void);
-
-  switch (cif->abi)
-    {
-    case FFI_SYSV:
-    case FFI_MS_CDECL:
-      dest = ffi_go_closure_ECX;
-      break;
-    case FFI_THISCALL:
-    case FFI_FASTCALL:
-      dest = ffi_go_closure_EAX;
-      break;
-    case FFI_STDCALL:
-    case FFI_PASCAL:
-      dest = ffi_go_closure_STDCALL;
-      break;
-    case FFI_REGISTER:
-    default:
-      return FFI_BAD_ABI;
-    }
-
-  closure->tramp = dest;
-  closure->cif = cif;
-  closure->fun = fun;
+  closure->fun  = fun;
 
   return FFI_OK;
 }
@@ -612,150 +790,142 @@
 
 #if !FFI_NO_RAW_API
 
-void FFI_HIDDEN ffi_closure_raw_SYSV(void);
-void FFI_HIDDEN ffi_closure_raw_THISCALL(void);
-
 ffi_status
-ffi_prep_raw_closure_loc (ffi_raw_closure *closure,
-                          ffi_cif *cif,
+ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
+                          ffi_cif* cif,
                           void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
                           void *user_data,
                           void *codeloc)
 {
-  char *tramp = closure->tramp;
-  void (*dest)(void);
   int i;
 
-  /* We currently don't support certain kinds of arguments for raw
+  if (cif->abi != FFI_SYSV
+#ifdef X86_WIN32
+      && cif->abi != FFI_THISCALL
+#endif
+     )
+    return FFI_BAD_ABI;
+
+  /* we currently don't support certain kinds of arguments for raw
      closures.  This should be implemented by a separate assembly
      language routine, since it would require argument processing,
      something we don't do now for performance.  */
+
   for (i = cif->nargs-1; i >= 0; i--)
-    switch (cif->arg_types[i]->type)
-      {
-      case FFI_TYPE_STRUCT:
-      case FFI_TYPE_LONGDOUBLE:
-	return FFI_BAD_TYPEDEF;
-      }
-
-  switch (cif->abi)
     {
-    case FFI_THISCALL:
-      dest = ffi_closure_raw_THISCALL;
-      break;
-    case FFI_SYSV:
-      dest = ffi_closure_raw_SYSV;
-      break;
-    default:
-      return FFI_BAD_ABI;
+      FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
+      FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
     }
-
-  /* movl imm, %eax.  */
-  tramp[0] = 0xb8;
-  *(void **)(tramp + 1) = codeloc;
-
-  /* jmp dest */
-  tramp[5] = 0xe9;
-  *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
-
-  closure->cif = cif;
-  closure->fun = fun;
+  
+#ifdef X86_WIN32
+  if (cif->abi == FFI_SYSV)
+    {
+#endif
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
+                       codeloc);
+#ifdef X86_WIN32
+    }
+  else if (cif->abi == FFI_THISCALL)
+    {
+      FFI_INIT_TRAMPOLINE_RAW_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL, codeloc, cif->bytes);
+    }
+#endif
+  closure->cif  = cif;
   closure->user_data = user_data;
+  closure->fun  = fun;
 
   return FFI_OK;
 }
 
-void
-ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
+static unsigned int 
+ffi_prep_args_raw(char *stack, extended_cif *ecif)
 {
-  size_t rsize, bytes;
-  struct call_frame *frame;
-  char *stack, *argp;
-  ffi_type **arg_types;
-  int flags, cabi, i, n, narg_reg;
-  const struct abi_params *pabi;
+  const ffi_cif *cif = ecif->cif;
+  unsigned int i, passed_regs = 0;
+  
+#ifndef X86_WIN64
+  const unsigned int abi = cif->abi;
+  const unsigned int max_regs = (abi == FFI_THISCALL) ? 1
+                              : (abi == FFI_FASTCALL) ? 2
+                              : (abi == FFI_REGISTER) ? 3
+                              : 0;
 
-  flags = cif->flags;
-  cabi = cif->abi;
-  pabi = &abi_params[cabi];
-
-  rsize = 0;
-  if (rvalue == NULL)
+  if (cif->flags == FFI_TYPE_STRUCT)
+    ++passed_regs;
+  
+  for (i = 0; i < cif->nargs && passed_regs <= max_regs; i++)
     {
-      switch (flags)
-	{
-	case X86_RET_FLOAT:
-	case X86_RET_DOUBLE:
-	case X86_RET_LDOUBLE:
-	case X86_RET_STRUCTPOP:
-	case X86_RET_STRUCTARG:
-	  /* The float cases need to pop the 387 stack.
-	     The struct cases need to pass a valid pointer to the callee.  */
-	  rsize = cif->rtype->size;
-	  break;
-	default:
-	  /* We can pretend that the callee returns nothing.  */
-	  flags = X86_RET_VOID;
-	  break;
-	}
+      if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
+         || cif->arg_types[i]->type == FFI_TYPE_STRUCT)
+        continue;
+
+      size_t sz = cif->arg_types[i]->size;
+      if (sz == 0 || sz > FFI_SIZEOF_ARG)
+        continue;
+
+      ++passed_regs;
     }
+#endif
 
-  bytes = STACK_ALIGN (cif->bytes);
-  argp = stack =
-      (void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);
-  frame = (struct call_frame *)(stack + bytes);
-  if (rsize)
-    rvalue = frame + 1;
+  memcpy (stack, ecif->avalue, cif->bytes);
+  return passed_regs;
+}
 
-  frame->fn = fn;
-  frame->flags = flags;
-  frame->rvalue = rvalue;
+/* we borrow this routine from libffi (it must be changed, though, to
+ * actually call the function passed in the first argument.  as of
+ * libffi-1.20, this is not the case.)
+ */
 
-  narg_reg = 0;
-  switch (flags)
+void
+ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
+{
+  extended_cif ecif;
+  void **avalue = (void **)fake_avalue;
+
+  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->flags == FFI_TYPE_STRUCT
+          || cif->flags == FFI_TYPE_MS_STRUCT))
     {
-    case X86_RET_STRUCTARG:
-      /* The pointer is passed as the first argument.  */
-      if (pabi->nregs > 0)
-	{
-	  frame->regs[pabi->regs[0]] = (unsigned)rvalue;
-	  narg_reg = 1;
-	  break;
-	}
-      /* fallthru */
-    case X86_RET_STRUCTPOP:
-      *(void **)argp = rvalue;
-      argp += sizeof(void *);
-      bytes -= sizeof(void *);
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+#ifndef X86_WIN32
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
+                    ecif.rvalue, fn);
+      break;
+#else
+    case FFI_SYSV:
+    case FFI_MS_CDECL:
+#endif
+#ifndef X86_WIN64
+    case FFI_STDCALL:
+    case FFI_THISCALL:
+    case FFI_FASTCALL:
+    case FFI_PASCAL:
+    case FFI_REGISTER:
+      ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
+                     ecif.rvalue, fn);
+      break;
+#endif
+    default:
+      FFI_ASSERT(0);
       break;
     }
-
-  arg_types = cif->arg_types;
-  for (i = 0, n = cif->nargs; narg_reg < pabi->nregs && i < n; i++)
-    {
-      ffi_type *ty = arg_types[i];
-      size_t z = ty->size;
-      int t = ty->type;
-
-      if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT && t != FFI_TYPE_FLOAT)
-	{
-	  ffi_arg val = extend_basic_type (avalue, t);
-	  frame->regs[pabi->regs[narg_reg++]] = val;
-	  z = FFI_SIZEOF_ARG;
-	}
-      else
-	{
-	  memcpy (argp, avalue, z);
-	  z = FFI_ALIGN (z, FFI_SIZEOF_ARG);
-	  argp += z;
-	}
-      avalue += z;
-      bytes -= z;
-    }
-  if (i < n)
-    memcpy (argp, avalue, bytes);
-
-  ffi_call_i386 (frame, stack);
 }
-#endif /* !FFI_NO_RAW_API */
-#endif /* __i386__ */
+
+#endif
+
+#endif /* !__x86_64__  || X86_WIN64 */
+
diff --git a/src/x86/ffi64.c b/src/x86/ffi64.c
index dec331c..5a5e043 100644
--- a/src/x86/ffi64.c
+++ b/src/x86/ffi64.c
@@ -1,6 +1,6 @@
 /* -----------------------------------------------------------------------
-   ffi64.c - Copyright (c) 2011, 2018  Anthony Green
-             Copyright (c) 2013  The Written Word, Inc.
+   ffi64.c - Copyright (c) 2013  The Written Word, Inc.
+             Copyright (c) 2011  Anthony Green
              Copyright (c) 2008, 2010  Red Hat, Inc.
              Copyright (c) 2002, 2007  Bo Thorsen <bo@suse.de>
 
@@ -32,8 +32,6 @@
 
 #include <stdlib.h>
 #include <stdarg.h>
-#include <stdint.h>
-#include "internal64.h"
 
 #ifdef __x86_64__
 
@@ -64,12 +62,10 @@
   /* Registers for argument passing.  */
   UINT64 gpr[MAX_GPR_REGS];
   union big_int_union sse[MAX_SSE_REGS];
-  UINT64 rax;	/* ssecount */
-  UINT64 r10;	/* static chain */
 };
 
 extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
-			     void *raddr, void (*fnaddr)(void)) FFI_HIDDEN;
+			     void *raddr, void (*fnaddr)(void), unsigned ssecount);
 
 /* All reference to register classes here is identical to the code in
    gcc/config/i386/i386.c. Do *not* change one without the other.  */
@@ -171,7 +167,6 @@
     case FFI_TYPE_UINT64:
     case FFI_TYPE_SINT64:
     case FFI_TYPE_POINTER:
-    do_integer:
       {
 	size_t size = byte_offset + type->size;
 
@@ -193,7 +188,7 @@
 	  }
 	else if (size <= 16)
 	  {
-	    classes[0] = classes[1] = X86_64_INTEGER_CLASS;
+	    classes[0] = classes[1] = X86_64_INTEGERSI_CLASS;
 	    return 2;
 	  }
 	else
@@ -219,7 +214,7 @@
 	const size_t UNITS_PER_WORD = 8;
 	size_t words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 	ffi_type **ptr;
-	unsigned int i;
+	int i;
 	enum x86_64_reg_class subclasses[MAX_CLASSES];
 
 	/* If the struct is larger than 32 bytes, pass it on the stack.  */
@@ -233,7 +228,6 @@
 	   signalize memory class, so handle it as special case.  */
 	if (!words)
 	  {
-    case FFI_TYPE_VOID:
 	    classes[0] = X86_64_NO_CLASS;
 	    return 1;
 	  }
@@ -243,7 +237,7 @@
 	  {
 	    size_t num;
 
-	    byte_offset = FFI_ALIGN (byte_offset, (*ptr)->alignment);
+	    byte_offset = ALIGN (byte_offset, (*ptr)->alignment);
 
 	    num = classify_argument (*ptr, subclasses, byte_offset % 8);
 	    if (num == 0)
@@ -282,7 +276,7 @@
 
 	    /* The X86_64_SSEUP_CLASS should be always preceded by
 	       X86_64_SSE_CLASS or X86_64_SSEUP_CLASS.  */
-	    if (i > 1 && classes[i] == X86_64_SSEUP_CLASS
+	    if (classes[i] == X86_64_SSEUP_CLASS
 		&& classes[i - 1] != X86_64_SSE_CLASS
 		&& classes[i - 1] != X86_64_SSEUP_CLASS)
 	      {
@@ -293,7 +287,7 @@
 
 	    /*  If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
 		everything should be passed in memory.  */
-	    if (i > 1 && classes[i] == X86_64_X87UP_CLASS
+	    if (classes[i] == X86_64_X87UP_CLASS
 		&& (classes[i - 1] != X86_64_X87_CLASS))
 	      {
 		/* The first one should never be X86_64_X87UP_CLASS.  */
@@ -303,42 +297,11 @@
 	  }
 	return words;
       }
-    case FFI_TYPE_COMPLEX:
-      {
-	ffi_type *inner = type->elements[0];
-	switch (inner->type)
-	  {
-	  case FFI_TYPE_INT:
-	  case FFI_TYPE_UINT8:
-	  case FFI_TYPE_SINT8:
-	  case FFI_TYPE_UINT16:
-	  case FFI_TYPE_SINT16:
-	  case FFI_TYPE_UINT32:
-	  case FFI_TYPE_SINT32:
-	  case FFI_TYPE_UINT64:
-	  case FFI_TYPE_SINT64:
-	    goto do_integer;
 
-	  case FFI_TYPE_FLOAT:
-	    classes[0] = X86_64_SSE_CLASS;
-	    if (byte_offset % 8)
-	      {
-		classes[1] = X86_64_SSESF_CLASS;
-		return 2;
-	      }
-	    return 1;
-	  case FFI_TYPE_DOUBLE:
-	    classes[0] = classes[1] = X86_64_SSEDF_CLASS;
-	    return 2;
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-	  case FFI_TYPE_LONGDOUBLE:
-	    classes[0] = X86_64_COMPLEX_X87_CLASS;
-	    return 1;
-#endif
-	  }
-      }
+    default:
+      FFI_ASSERT(0);
     }
-  abort();
+  return 0; /* Never reached.  */
 }
 
 /* Examine the argument and return set number of register required in each
@@ -350,8 +313,7 @@
 		  _Bool in_return, int *pngpr, int *pnsse)
 {
   size_t n;
-  unsigned int i;
-  int ngpr, nsse;
+  int i, ngpr, nsse;
 
   n = classify_argument (type, classes, 0);
   if (n == 0)
@@ -389,74 +351,18 @@
 
 /* Perform machine dependent cif processing.  */
 
-#ifndef __ILP32__
-extern ffi_status
-ffi_prep_cif_machdep_efi64(ffi_cif *cif);
-#endif
-
-ffi_status FFI_HIDDEN
+ffi_status
 ffi_prep_cif_machdep (ffi_cif *cif)
 {
-  int gprcount, ssecount, i, avn, ngpr, nsse;
-  unsigned flags;
+  int gprcount, ssecount, i, avn, ngpr, nsse, flags;
   enum x86_64_reg_class classes[MAX_CLASSES];
-  size_t bytes, n, rtype_size;
-  ffi_type *rtype;
-
-#ifndef __ILP32__
-  if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
-    return ffi_prep_cif_machdep_efi64(cif);
-#endif
-  if (cif->abi != FFI_UNIX64)
-    return FFI_BAD_ABI;
+  size_t bytes, n;
 
   gprcount = ssecount = 0;
 
-  rtype = cif->rtype;
-  rtype_size = rtype->size;
-  switch (rtype->type)
+  flags = cif->rtype->type;
+  if (flags != FFI_TYPE_VOID)
     {
-    case FFI_TYPE_VOID:
-      flags = UNIX64_RET_VOID;
-      break;
-    case FFI_TYPE_UINT8:
-      flags = UNIX64_RET_UINT8;
-      break;
-    case FFI_TYPE_SINT8:
-      flags = UNIX64_RET_SINT8;
-      break;
-    case FFI_TYPE_UINT16:
-      flags = UNIX64_RET_UINT16;
-      break;
-    case FFI_TYPE_SINT16:
-      flags = UNIX64_RET_SINT16;
-      break;
-    case FFI_TYPE_UINT32:
-      flags = UNIX64_RET_UINT32;
-      break;
-    case FFI_TYPE_INT:
-    case FFI_TYPE_SINT32:
-      flags = UNIX64_RET_SINT32;
-      break;
-    case FFI_TYPE_UINT64:
-    case FFI_TYPE_SINT64:
-      flags = UNIX64_RET_INT64;
-      break;
-    case FFI_TYPE_POINTER:
-      flags = (sizeof(void *) == 4 ? UNIX64_RET_UINT32 : UNIX64_RET_INT64);
-      break;
-    case FFI_TYPE_FLOAT:
-      flags = UNIX64_RET_XMM32;
-      break;
-    case FFI_TYPE_DOUBLE:
-      flags = UNIX64_RET_XMM64;
-      break;
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-    case FFI_TYPE_LONGDOUBLE:
-      flags = UNIX64_RET_X87;
-      break;
-#endif
-    case FFI_TYPE_STRUCT:
       n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
       if (n == 0)
 	{
@@ -464,62 +370,22 @@
 	     memory is the first argument.  Allocate a register for it.  */
 	  gprcount++;
 	  /* We don't have to do anything in asm for the return.  */
-	  flags = UNIX64_RET_VOID | UNIX64_FLAG_RET_IN_MEM;
+	  flags = FFI_TYPE_VOID;
 	}
-      else
+      else if (flags == FFI_TYPE_STRUCT)
 	{
+	  /* Mark which registers the result appears in.  */
 	  _Bool sse0 = SSE_CLASS_P (classes[0]);
-
-	  if (rtype_size == 4 && sse0)
-	    flags = UNIX64_RET_XMM32;
-	  else if (rtype_size == 8)
-	    flags = sse0 ? UNIX64_RET_XMM64 : UNIX64_RET_INT64;
-	  else
-	    {
-	      _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
-	      if (sse0 && sse1)
-		flags = UNIX64_RET_ST_XMM0_XMM1;
-	      else if (sse0)
-		flags = UNIX64_RET_ST_XMM0_RAX;
-	      else if (sse1)
-		flags = UNIX64_RET_ST_RAX_XMM0;
-	      else
-		flags = UNIX64_RET_ST_RAX_RDX;
-	      flags |= rtype_size << UNIX64_SIZE_SHIFT;
-	    }
+	  _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
+	  if (sse0 && !sse1)
+	    flags |= 1 << 8;
+	  else if (!sse0 && sse1)
+	    flags |= 1 << 9;
+	  else if (sse0 && sse1)
+	    flags |= 1 << 10;
+	  /* Mark the true size of the structure.  */
+	  flags |= cif->rtype->size << 12;
 	}
-      break;
-    case FFI_TYPE_COMPLEX:
-      switch (rtype->elements[0]->type)
-	{
-	case FFI_TYPE_UINT8:
-	case FFI_TYPE_SINT8:
-	case FFI_TYPE_UINT16:
-	case FFI_TYPE_SINT16:
-	case FFI_TYPE_INT:
-	case FFI_TYPE_UINT32:
-	case FFI_TYPE_SINT32:
-	case FFI_TYPE_UINT64:
-	case FFI_TYPE_SINT64:
-	  flags = UNIX64_RET_ST_RAX_RDX | ((unsigned) rtype_size << UNIX64_SIZE_SHIFT);
-	  break;
-	case FFI_TYPE_FLOAT:
-	  flags = UNIX64_RET_XMM64;
-	  break;
-	case FFI_TYPE_DOUBLE:
-	  flags = UNIX64_RET_ST_XMM0_XMM1 | (16 << UNIX64_SIZE_SHIFT);
-	  break;
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-	case FFI_TYPE_LONGDOUBLE:
-	  flags = UNIX64_RET_X87_2;
-	  break;
-#endif
-	default:
-	  return FFI_BAD_TYPEDEF;
-	}
-      break;
-    default:
-      return FFI_BAD_TYPEDEF;
     }
 
   /* Go over all arguments and determine the way they should be passed.
@@ -536,7 +402,7 @@
 	  if (align < 8)
 	    align = 8;
 
-	  bytes = FFI_ALIGN (bytes, align);
+	  bytes = ALIGN (bytes, align);
 	  bytes += cif->arg_types[i]->size;
 	}
       else
@@ -546,50 +412,44 @@
 	}
     }
   if (ssecount)
-    flags |= UNIX64_FLAG_XMM_ARGS;
-
+    flags |= 1 << 11;
   cif->flags = flags;
-  cif->bytes = (unsigned) FFI_ALIGN (bytes, 8);
+  cif->bytes = (unsigned)ALIGN (bytes, 8);
 
   return FFI_OK;
 }
 
-static void
-ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	      void **avalue, void *closure)
+void
+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
   enum x86_64_reg_class classes[MAX_CLASSES];
   char *stack, *argp;
   ffi_type **arg_types;
-  int gprcount, ssecount, ngpr, nsse, i, avn, flags;
+  int gprcount, ssecount, ngpr, nsse, i, avn;
+  _Bool ret_in_memory;
   struct register_args *reg_args;
 
   /* Can't call 32-bit mode from 64-bit mode.  */
   FFI_ASSERT (cif->abi == FFI_UNIX64);
 
   /* If the return value is a struct and we don't have a return value
-     address then we need to make one.  Otherwise we can ignore it.  */
-  flags = cif->flags;
-  if (rvalue == NULL)
-    {
-      if (flags & UNIX64_FLAG_RET_IN_MEM)
-	rvalue = alloca (cif->rtype->size);
-      else
-	flags = UNIX64_RET_VOID;
-    }
+     address then we need to make one.  Note the setting of flags to
+     VOID above in ffi_prep_cif_machdep.  */
+  ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
+		   && (cif->flags & 0xff) == FFI_TYPE_VOID);
+  if (rvalue == NULL && ret_in_memory)
+    rvalue = alloca (cif->rtype->size);
 
   /* Allocate the space for the arguments, plus 4 words of temp space.  */
   stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
   reg_args = (struct register_args *) stack;
   argp = stack + sizeof (struct register_args);
 
-  reg_args->r10 = (uintptr_t) closure;
-
   gprcount = ssecount = 0;
 
   /* If the return value is passed in memory, add the pointer as the
      first integer argument.  */
-  if (flags & UNIX64_FLAG_RET_IN_MEM)
+  if (ret_in_memory)
     reg_args->gpr[gprcount++] = (unsigned long) rvalue;
 
   avn = cif->nargs;
@@ -611,7 +471,7 @@
 	    align = 8;
 
 	  /* Pass this argument in memory.  */
-	  argp = (void *) FFI_ALIGN (argp, align);
+	  argp = (void *) ALIGN (argp, align);
 	  memcpy (argp, avalue[i], size);
 	  argp += size;
 	}
@@ -619,15 +479,12 @@
 	{
 	  /* The argument is passed entirely in registers.  */
 	  char *a = (char *) avalue[i];
-	  unsigned int j;
+	  int j;
 
 	  for (j = 0; j < n; j++, a += 8, size -= 8)
 	    {
 	      switch (classes[j])
 		{
-		case X86_64_NO_CLASS:
-		case X86_64_SSEUP_CLASS:
-		  break;
 		case X86_64_INTEGER_CLASS:
 		case X86_64_INTEGERSI_CLASS:
 		  /* Sign-extend integer arguments passed in general
@@ -637,26 +494,26 @@
 		  switch (arg_types[i]->type)
 		    {
 		    case FFI_TYPE_SINT8:
-		      reg_args->gpr[gprcount] = (SINT64) *((SINT8 *) a);
+		      *(SINT64 *)&reg_args->gpr[gprcount] = (SINT64) *((SINT8 *) a);
 		      break;
 		    case FFI_TYPE_SINT16:
-		      reg_args->gpr[gprcount] = (SINT64) *((SINT16 *) a);
+		      *(SINT64 *)&reg_args->gpr[gprcount] = (SINT64) *((SINT16 *) a);
 		      break;
 		    case FFI_TYPE_SINT32:
-		      reg_args->gpr[gprcount] = (SINT64) *((SINT32 *) a);
+		      *(SINT64 *)&reg_args->gpr[gprcount] = (SINT64) *((SINT32 *) a);
 		      break;
 		    default:
 		      reg_args->gpr[gprcount] = 0;
-		      memcpy (&reg_args->gpr[gprcount], a, size);
+		      memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
 		    }
 		  gprcount++;
 		  break;
 		case X86_64_SSE_CLASS:
 		case X86_64_SSEDF_CLASS:
-		  memcpy (&reg_args->sse[ssecount++].i64, a, sizeof(UINT64));
+		  reg_args->sse[ssecount++].i64 = *(UINT64 *) a;
 		  break;
 		case X86_64_SSESF_CLASS:
-		  memcpy (&reg_args->sse[ssecount++].i32, a, sizeof(UINT32));
+		  reg_args->sse[ssecount++].i32 = *(UINT32 *) a;
 		  break;
 		default:
 		  abort();
@@ -664,62 +521,13 @@
 	    }
 	}
     }
-  reg_args->rax = ssecount;
 
   ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
-		   flags, rvalue, fn);
-}
-
-#ifndef __ILP32__
-extern void
-ffi_call_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);
-#endif
-
-void
-ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
-{
-#ifndef __ILP32__
-  if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
-    {
-      ffi_call_efi64(cif, fn, rvalue, avalue);
-      return;
-    }
-#endif
-  ffi_call_int (cif, fn, rvalue, avalue, NULL);
-}
-
-#ifndef __ILP32__
-extern void
-ffi_call_go_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue,
-		  void **avalue, void *closure);
-#endif
-
-void
-ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	     void **avalue, void *closure)
-{
-#ifndef __ILP32__
-  if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
-    {
-      ffi_call_go_efi64(cif, fn, rvalue, avalue, closure);
-      return;
-    }
-#endif
-  ffi_call_int (cif, fn, rvalue, avalue, closure);
+		   cif->flags, rvalue, fn, ssecount);
 }
 
 
-extern void ffi_closure_unix64(void) FFI_HIDDEN;
-extern void ffi_closure_unix64_sse(void) FFI_HIDDEN;
-
-#ifndef __ILP32__
-extern ffi_status
-ffi_prep_closure_loc_efi64(ffi_closure* closure,
-			   ffi_cif* cif,
-			   void (*fun)(ffi_cif*, void*, void**, void*),
-			   void *user_data,
-			   void *codeloc);
-#endif
+extern void ffi_closure_unix64(void);
 
 ffi_status
 ffi_prep_closure_loc (ffi_closure* closure,
@@ -728,31 +536,29 @@
 		      void *user_data,
 		      void *codeloc)
 {
-  static const unsigned char trampoline[16] = {
-    /* leaq  -0x7(%rip),%r10   # 0x0  */
-    0x4c, 0x8d, 0x15, 0xf9, 0xff, 0xff, 0xff,
-    /* jmpq  *0x3(%rip)        # 0x10 */
-    0xff, 0x25, 0x03, 0x00, 0x00, 0x00,
-    /* nopl  (%rax) */
-    0x0f, 0x1f, 0x00
-  };
-  void (*dest)(void);
-  char *tramp = closure->tramp;
+  volatile unsigned short *tramp;
 
-#ifndef __ILP32__
-  if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
-    return ffi_prep_closure_loc_efi64(closure, cif, fun, user_data, codeloc);
-#endif
-  if (cif->abi != FFI_UNIX64)
-    return FFI_BAD_ABI;
+  /* Sanity check on the cif ABI.  */
+  {
+    int abi = cif->abi;
+    if (UNLIKELY (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)))
+      return FFI_BAD_ABI;
+  }
 
-  if (cif->flags & UNIX64_FLAG_XMM_ARGS)
-    dest = ffi_closure_unix64_sse;
-  else
-    dest = ffi_closure_unix64;
+  tramp = (volatile unsigned short *) &closure->tramp[0];
 
-  memcpy (tramp, trampoline, sizeof(trampoline));
-  *(UINT64 *)(tramp + 16) = (uintptr_t)dest;
+  tramp[0] = 0xbb49;		/* mov <code>, %r11	*/
+  *((unsigned long long * volatile) &tramp[1])
+    = (unsigned long) ffi_closure_unix64;
+  tramp[5] = 0xba49;		/* mov <data>, %r10	*/
+  *((unsigned long long * volatile) &tramp[6])
+    = (unsigned long) codeloc;
+
+  /* Set the carry bit iff the function uses any sse registers.
+     This is clc or stc, together with the first byte of the jmp.  */
+  tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
+
+  tramp[11] = 0xe3ff;			/* jmp *%r11    */
 
   closure->cif = cif;
   closure->fun = fun;
@@ -761,36 +567,49 @@
   return FFI_OK;
 }
 
-int FFI_HIDDEN
-ffi_closure_unix64_inner(ffi_cif *cif,
-			 void (*fun)(ffi_cif*, void*, void**, void*),
-			 void *user_data,
-			 void *rvalue,
-			 struct register_args *reg_args,
-			 char *argp)
+int
+ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
+			 struct register_args *reg_args, char *argp)
 {
+  ffi_cif *cif;
   void **avalue;
   ffi_type **arg_types;
   long i, avn;
   int gprcount, ssecount, ngpr, nsse;
-  int flags;
+  int ret;
 
-  avn = cif->nargs;
-  flags = cif->flags;
-  avalue = alloca(avn * sizeof(void *));
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
   gprcount = ssecount = 0;
 
-  if (flags & UNIX64_FLAG_RET_IN_MEM)
+  ret = cif->rtype->type;
+  if (ret != FFI_TYPE_VOID)
     {
-      /* On return, %rax will contain the address that was passed
-	 by the caller in %rdi.  */
-      void *r = (void *)(uintptr_t)reg_args->gpr[gprcount++];
-      *(void **)rvalue = r;
-      rvalue = r;
-      flags = (sizeof(void *) == 4 ? UNIX64_RET_UINT32 : UNIX64_RET_INT64);
+      enum x86_64_reg_class classes[MAX_CLASSES];
+      size_t n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
+      if (n == 0)
+	{
+	  /* The return value goes in memory.  Arrange for the closure
+	     return value to go directly back to the original caller.  */
+	  rvalue = (void *) (unsigned long) reg_args->gpr[gprcount++];
+	  /* We don't have to do anything in asm for the return.  */
+	  ret = FFI_TYPE_VOID;
+	}
+      else if (ret == FFI_TYPE_STRUCT && n == 2)
+	{
+	  /* Mark which register the second word of the structure goes in.  */
+	  _Bool sse0 = SSE_CLASS_P (classes[0]);
+	  _Bool sse1 = SSE_CLASS_P (classes[1]);
+	  if (!sse0 && sse1)
+	    ret |= 1 << 8;
+	  else if (sse0 && !sse1)
+	    ret |= 1 << 9;
+	}
     }
 
+  avn = cif->nargs;
   arg_types = cif->arg_types;
+
   for (i = 0; i < avn; ++i)
     {
       enum x86_64_reg_class classes[MAX_CLASSES];
@@ -808,7 +627,7 @@
 	    align = 8;
 
 	  /* Pass this argument in memory.  */
-	  argp = (void *) FFI_ALIGN (argp, align);
+	  argp = (void *) ALIGN (argp, align);
 	  avalue[i] = argp;
 	  argp += arg_types[i]->size;
 	}
@@ -834,7 +653,7 @@
       else
 	{
 	  char *a = alloca (16);
-	  unsigned int j;
+	  int j;
 
 	  avalue[i] = a;
 	  for (j = 0; j < n; j++, a += 8)
@@ -848,39 +667,10 @@
     }
 
   /* Invoke the closure.  */
-  fun (cif, rvalue, avalue, user_data);
+  closure->fun (cif, rvalue, avalue, closure->user_data);
 
   /* Tell assembly how to perform return type promotions.  */
-  return flags;
-}
-
-extern void ffi_go_closure_unix64(void) FFI_HIDDEN;
-extern void ffi_go_closure_unix64_sse(void) FFI_HIDDEN;
-
-#ifndef __ILP32__
-extern ffi_status
-ffi_prep_go_closure_efi64(ffi_go_closure* closure, ffi_cif* cif,
-			  void (*fun)(ffi_cif*, void*, void**, void*));
-#endif
-
-ffi_status
-ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
-		     void (*fun)(ffi_cif*, void*, void**, void*))
-{
-#ifndef __ILP32__
-  if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
-    return ffi_prep_go_closure_efi64(closure, cif, fun);
-#endif
-  if (cif->abi != FFI_UNIX64)
-    return FFI_BAD_ABI;
-
-  closure->tramp = (cif->flags & UNIX64_FLAG_XMM_ARGS
-		    ? ffi_go_closure_unix64_sse
-		    : ffi_go_closure_unix64);
-  closure->cif = cif;
-  closure->fun = fun;
-
-  return FFI_OK;
+  return ret;
 }
 
 #endif /* __x86_64__ */
diff --git a/src/x86/ffitarget.h b/src/x86/ffitarget.h
index 85ccedf..a236677 100644
--- a/src/x86/ffitarget.h
+++ b/src/x86/ffitarget.h
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------*-C-*-
-   ffitarget.h - Copyright (c) 2012, 2014, 2018  Anthony Green
+   ffitarget.h - Copyright (c) 2012, 2014  Anthony Green
                  Copyright (c) 1996-2003, 2010  Red Hat, Inc.
                  Copyright (C) 2008  Free Software Foundation, Inc.
 
@@ -50,9 +50,7 @@
 #endif
 
 #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
-#ifndef _MSC_VER
 #define FFI_TARGET_HAS_COMPLEX_TYPE
-#endif
 
 /* ---- Generic type definitions ----------------------------------------- */
 
@@ -78,69 +76,74 @@
 #endif
 
 typedef enum ffi_abi {
-#if defined(X86_WIN64)
   FFI_FIRST_ABI = 0,
-  FFI_WIN64,            /* sizeof(long double) == 8  - microsoft compilers */
-  FFI_GNUW64,           /* sizeof(long double) == 16 - GNU compilers */
-  FFI_LAST_ABI,
-#ifdef __GNUC__
-  FFI_DEFAULT_ABI = FFI_GNUW64
-#else  
-  FFI_DEFAULT_ABI = FFI_WIN64
-#endif  
 
-#elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
-  FFI_FIRST_ABI = 1,
-  FFI_UNIX64,
-  FFI_WIN64,
-  FFI_EFI64 = FFI_WIN64,
-  FFI_GNUW64,
+  /* ---- Intel x86 Win32 ---------- */
+#ifdef X86_WIN32
+  FFI_SYSV,
+  FFI_STDCALL,
+  FFI_THISCALL,
+  FFI_FASTCALL,
+  FFI_MS_CDECL,
+  FFI_PASCAL,
+  FFI_REGISTER,
   FFI_LAST_ABI,
-  FFI_DEFAULT_ABI = FFI_UNIX64
-
-#elif defined(X86_WIN32)
-  FFI_FIRST_ABI = 0,
-  FFI_SYSV      = 1,
-  FFI_STDCALL   = 2,
-  FFI_THISCALL  = 3,
-  FFI_FASTCALL  = 4,
-  FFI_MS_CDECL  = 5,
-  FFI_PASCAL    = 6,
-  FFI_REGISTER  = 7,
-  FFI_LAST_ABI,
+#ifdef _MSC_VER
   FFI_DEFAULT_ABI = FFI_MS_CDECL
 #else
-  FFI_FIRST_ABI = 0,
-  FFI_SYSV      = 1,
-  FFI_THISCALL  = 3,
-  FFI_FASTCALL  = 4,
-  FFI_STDCALL   = 5,
-  FFI_PASCAL    = 6,
-  FFI_REGISTER  = 7,
-  FFI_MS_CDECL  = 8,
-  FFI_LAST_ABI,
   FFI_DEFAULT_ABI = FFI_SYSV
 #endif
+
+#elif defined(X86_WIN64)
+  FFI_WIN64,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_WIN64
+
+#else
+  /* ---- Intel x86 and AMD x86-64 - */
+  FFI_SYSV,
+  FFI_UNIX64,   /* Unix variants all use the same ABI for x86-64  */
+  FFI_THISCALL,
+  FFI_FASTCALL,
+  FFI_STDCALL,
+  FFI_PASCAL,
+  FFI_REGISTER,
+  FFI_LAST_ABI,
+#if defined(__i386__) || defined(__i386)
+  FFI_DEFAULT_ABI = FFI_SYSV
+#else
+  FFI_DEFAULT_ABI = FFI_UNIX64
+#endif
+#endif
 } ffi_abi;
 #endif
 
 /* ---- Definitions for closures ----------------------------------------- */
 
 #define FFI_CLOSURES 1
-#define FFI_GO_CLOSURES 1
-
 #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
 #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
 #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
 #define FFI_TYPE_MS_STRUCT       (FFI_TYPE_LAST + 4)
 
-#if defined (X86_64) || defined(X86_WIN64) \
-    || (defined (__x86_64__) && defined (X86_DARWIN))
-# define FFI_TRAMPOLINE_SIZE 24
-# define FFI_NATIVE_RAW_API 0
+#if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
 #else
-# define FFI_TRAMPOLINE_SIZE 12
-# define FFI_NATIVE_RAW_API 1  /* x86 has native raw api support */
+#ifdef X86_WIN32
+#define FFI_TRAMPOLINE_SIZE 52
+#else
+#ifdef X86_WIN64
+#define FFI_TRAMPOLINE_SIZE 29
+#define FFI_NATIVE_RAW_API 0
+#define FFI_NO_RAW_API 1
+#else
+#define FFI_TRAMPOLINE_SIZE 10
+#endif
+#endif
+#ifndef X86_WIN64
+#define FFI_NATIVE_RAW_API 1  /* x86 has native raw api support */
+#endif
 #endif
 
 #endif
diff --git a/src/x86/ffiw64.c b/src/x86/ffiw64.c
deleted file mode 100644
index b68f69c..0000000
--- a/src/x86/ffiw64.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/* -----------------------------------------------------------------------
-   ffiw64.c - Copyright (c) 2018 Anthony Green
-              Copyright (c) 2014 Red Hat, Inc.
-
-   x86 win64 Foreign Function Interface
-
-   Permission is hereby granted, free of charge, to any person obtaining
-   a copy of this software and associated documentation files (the
-   ``Software''), to deal in the Software without restriction, including
-   without limitation the rights to use, copy, modify, merge, publish,
-   distribute, sublicense, and/or sell copies of the Software, and to
-   permit persons to whom the Software is furnished to do so, subject to
-   the following conditions:
-
-   The above copyright notice and this permission notice shall be included
-   in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-   DEALINGS IN THE SOFTWARE.
-   ----------------------------------------------------------------------- */
-
-#if defined(__x86_64__) || defined(_M_AMD64)
-#include <ffi.h>
-#include <ffi_common.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#ifdef X86_WIN64
-#define EFI64(name) name
-#else
-#define EFI64(name) FFI_HIDDEN name##_efi64
-#endif
-
-struct win64_call_frame
-{
-  UINT64 rbp;		/* 0 */
-  UINT64 retaddr;	/* 8 */
-  UINT64 fn;		/* 16 */
-  UINT64 flags;		/* 24 */
-  UINT64 rvalue;	/* 32 */
-};
-
-extern void ffi_call_win64 (void *stack, struct win64_call_frame *,
-			    void *closure) FFI_HIDDEN;
-
-ffi_status FFI_HIDDEN
-EFI64(ffi_prep_cif_machdep)(ffi_cif *cif)
-{
-  int flags, n;
-
-  switch (cif->abi)
-    {
-    case FFI_WIN64:
-    case FFI_GNUW64:
-      break;
-    default:
-      return FFI_BAD_ABI;
-    }
-
-  flags = cif->rtype->type;
-  switch (flags)
-    {
-    default:
-      break;
-    case FFI_TYPE_LONGDOUBLE:
-      /* GCC returns long double values by reference, like a struct */
-      if (cif->abi == FFI_GNUW64)
-	flags = FFI_TYPE_STRUCT;
-      break;
-    case FFI_TYPE_COMPLEX:
-      flags = FFI_TYPE_STRUCT;
-      /* FALLTHRU */
-    case FFI_TYPE_STRUCT:
-      switch (cif->rtype->size)
-	{
-	case 8:
-	  flags = FFI_TYPE_UINT64;
-	  break;
-	case 4:
-	  flags = FFI_TYPE_SMALL_STRUCT_4B;
-	  break;
-	case 2:
-	  flags = FFI_TYPE_SMALL_STRUCT_2B;
-	  break;
-	case 1:
-	  flags = FFI_TYPE_SMALL_STRUCT_1B;
-	  break;
-	}
-      break;
-    }
-  cif->flags = flags;
-
-  /* Each argument either fits in a register, an 8 byte slot, or is
-     passed by reference with the pointer in the 8 byte slot.  */
-  n = cif->nargs;
-  n += (flags == FFI_TYPE_STRUCT);
-  if (n < 4)
-    n = 4;
-  cif->bytes = n * 8;
-
-  return FFI_OK;
-}
-
-static void
-ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
-	      void **avalue, void *closure)
-{
-  int i, j, n, flags;
-  UINT64 *stack;
-  size_t rsize;
-  struct win64_call_frame *frame;
-
-  FFI_ASSERT(cif->abi == FFI_GNUW64 || cif->abi == FFI_WIN64);
-
-  flags = cif->flags;
-  rsize = 0;
-
-  /* If we have no return value for a structure, we need to create one.
-     Otherwise we can ignore the return type entirely.  */
-  if (rvalue == NULL)
-    {
-      if (flags == FFI_TYPE_STRUCT)
-	rsize = cif->rtype->size;
-      else
-	flags = FFI_TYPE_VOID;
-    }
-
-  stack = alloca(cif->bytes + sizeof(struct win64_call_frame) + rsize);
-  frame = (struct win64_call_frame *)((char *)stack + cif->bytes);
-  if (rsize)
-    rvalue = frame + 1;
-
-  frame->fn = (uintptr_t)fn;
-  frame->flags = flags;
-  frame->rvalue = (uintptr_t)rvalue;
-
-  j = 0;
-  if (flags == FFI_TYPE_STRUCT)
-    {
-      stack[0] = (uintptr_t)rvalue;
-      j = 1;
-    }
-
-  for (i = 0, n = cif->nargs; i < n; ++i, ++j)
-    {
-      switch (cif->arg_types[i]->size)
-	{
-	case 8:
-	  stack[j] = *(UINT64 *)avalue[i];
-	  break;
-	case 4:
-	  stack[j] = *(UINT32 *)avalue[i];
-	  break;
-	case 2:
-	  stack[j] = *(UINT16 *)avalue[i];
-	  break;
-	case 1:
-	  stack[j] = *(UINT8 *)avalue[i];
-	  break;
-	default:
-	  stack[j] = (uintptr_t)avalue[i];
-	  break;
-	}
-    }
-
-  ffi_call_win64 (stack, frame, closure);
-}
-
-void
-EFI64(ffi_call)(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, NULL);
-}
-
-void
-EFI64(ffi_call_go)(ffi_cif *cif, void (*fn)(void), void *rvalue,
-	     void **avalue, void *closure)
-{
-  ffi_call_int (cif, fn, rvalue, avalue, closure);
-}
-
-
-extern void ffi_closure_win64(void) FFI_HIDDEN;
-extern void ffi_go_closure_win64(void) FFI_HIDDEN;
-
-ffi_status
-EFI64(ffi_prep_closure_loc)(ffi_closure* closure,
-		      ffi_cif* cif,
-		      void (*fun)(ffi_cif*, void*, void**, void*),
-		      void *user_data,
-		      void *codeloc)
-{
-  static const unsigned char trampoline[16] = {
-    /* leaq  -0x7(%rip),%r10   # 0x0  */
-    0x4c, 0x8d, 0x15, 0xf9, 0xff, 0xff, 0xff,
-    /* jmpq  *0x3(%rip)        # 0x10 */
-    0xff, 0x25, 0x03, 0x00, 0x00, 0x00,
-    /* nopl  (%rax) */
-    0x0f, 0x1f, 0x00
-  };
-  char *tramp = closure->tramp;
-
-  switch (cif->abi)
-    {
-    case FFI_WIN64:
-    case FFI_GNUW64:
-      break;
-    default:
-      return FFI_BAD_ABI;
-    }
-
-  memcpy (tramp, trampoline, sizeof(trampoline));
-  *(UINT64 *)(tramp + 16) = (uintptr_t)ffi_closure_win64;
-
-  closure->cif = cif;
-  closure->fun = fun;
-  closure->user_data = user_data;
-
-  return FFI_OK;
-}
-
-ffi_status
-EFI64(ffi_prep_go_closure)(ffi_go_closure* closure, ffi_cif* cif,
-		     void (*fun)(ffi_cif*, void*, void**, void*))
-{
-  switch (cif->abi)
-    {
-    case FFI_WIN64:
-    case FFI_GNUW64:
-      break;
-    default:
-      return FFI_BAD_ABI;
-    }
-
-  closure->tramp = ffi_go_closure_win64;
-  closure->cif = cif;
-  closure->fun = fun;
-
-  return FFI_OK;
-}
-
-struct win64_closure_frame
-{
-  UINT64 rvalue[2];
-  UINT64 fargs[4];
-  UINT64 retaddr;
-  UINT64 args[];
-};
-
-/* Force the inner function to use the MS ABI.  When compiling on win64
-   this is a nop.  When compiling on unix, this simplifies the assembly,
-   and places the burden of saving the extra call-saved registers on
-   the compiler.  */
-int FFI_HIDDEN __attribute__((ms_abi))
-ffi_closure_win64_inner(ffi_cif *cif,
-			void (*fun)(ffi_cif*, void*, void**, void*),
-			void *user_data,
-			struct win64_closure_frame *frame)
-{
-  void **avalue;
-  void *rvalue;
-  int i, n, nreg, flags;
-
-  avalue = alloca(cif->nargs * sizeof(void *));
-  rvalue = frame->rvalue;
-  nreg = 0;
-
-  /* When returning a structure, the address is in the first argument.
-     We must also be prepared to return the same address in eax, so
-     install that address in the frame and pretend we return a pointer.  */
-  flags = cif->flags;
-  if (flags == FFI_TYPE_STRUCT)
-    {
-      rvalue = (void *)(uintptr_t)frame->args[0];
-      frame->rvalue[0] = frame->args[0];
-      nreg = 1;
-    }
-
-  for (i = 0, n = cif->nargs; i < n; ++i, ++nreg)
-    {
-      size_t size = cif->arg_types[i]->size;
-      size_t type = cif->arg_types[i]->type;
-      void *a;
-
-      if (type == FFI_TYPE_DOUBLE || type == FFI_TYPE_FLOAT)
-	{
-	  if (nreg < 4)
-	    a = &frame->fargs[nreg];
-	  else
-	    a = &frame->args[nreg];
-	}
-      else if (size == 1 || size == 2 || size == 4 || size == 8)
-	a = &frame->args[nreg];
-      else
-	a = (void *)(uintptr_t)frame->args[nreg];
-
-      avalue[i] = a;
-    }
-
-  /* Invoke the closure.  */
-  fun (cif, rvalue, avalue, user_data);
-  return flags;
-}
-
-#endif /* __x86_64__ */
diff --git a/src/x86/internal.h b/src/x86/internal.h
deleted file mode 100644
index 09771ba..0000000
--- a/src/x86/internal.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#define X86_RET_FLOAT		0
-#define X86_RET_DOUBLE		1
-#define X86_RET_LDOUBLE		2
-#define X86_RET_SINT8		3
-#define X86_RET_SINT16		4
-#define X86_RET_UINT8		5
-#define X86_RET_UINT16		6
-#define X86_RET_INT64		7
-#define X86_RET_INT32		8
-#define X86_RET_VOID		9
-#define X86_RET_STRUCTPOP	10
-#define X86_RET_STRUCTARG       11
-#define X86_RET_STRUCT_1B	12
-#define X86_RET_STRUCT_2B	13
-#define X86_RET_UNUSED14	14
-#define X86_RET_UNUSED15	15
-
-#define X86_RET_TYPE_MASK	15
-#define X86_RET_POP_SHIFT	4
-
-#define R_EAX	0
-#define R_EDX	1
-#define R_ECX	2
-
-#ifdef __PCC__
-# define HAVE_FASTCALL 0
-#else
-# define HAVE_FASTCALL 1
-#endif
diff --git a/src/x86/internal64.h b/src/x86/internal64.h
deleted file mode 100644
index 512e955..0000000
--- a/src/x86/internal64.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#define UNIX64_RET_VOID		0
-#define UNIX64_RET_UINT8	1
-#define UNIX64_RET_UINT16	2
-#define UNIX64_RET_UINT32	3
-#define UNIX64_RET_SINT8	4
-#define UNIX64_RET_SINT16	5
-#define UNIX64_RET_SINT32	6
-#define UNIX64_RET_INT64	7
-#define UNIX64_RET_XMM32	8
-#define UNIX64_RET_XMM64	9
-#define UNIX64_RET_X87		10
-#define UNIX64_RET_X87_2	11
-#define UNIX64_RET_ST_XMM0_RAX	12
-#define UNIX64_RET_ST_RAX_XMM0	13
-#define UNIX64_RET_ST_XMM0_XMM1	14
-#define UNIX64_RET_ST_RAX_RDX	15
-
-#define UNIX64_RET_LAST		15
-
-#define UNIX64_FLAG_RET_IN_MEM	(1 << 10)
-#define UNIX64_FLAG_XMM_ARGS	(1 << 11)
-#define UNIX64_SIZE_SHIFT	12
diff --git a/src/x86/sysv.S b/src/x86/sysv.S
index 7c9598c..3bd5477 100644
--- a/src/x86/sysv.S
+++ b/src/x86/sysv.S
@@ -1,7 +1,6 @@
 /* -----------------------------------------------------------------------
-   sysv.S - Copyright (c) 2017  Anthony Green
-          - Copyright (c) 2013  The Written Word, Inc.
-          - Copyright (c) 1996,1998,2001-2003,2005,2008,2010  Red Hat, Inc.
+   sysv.S - Copyright (c) 2013  The Written Word, Inc.
+	  - Copyright (c) 1996,1998,2001-2003,2005,2008,2010  Red Hat, Inc.
    
    X86 Foreign Function Interface 
 
@@ -26,1103 +25,458 @@
    DEALINGS IN THE SOFTWARE.
    ----------------------------------------------------------------------- */
 
-#ifdef __i386__
-#ifndef _MSC_VER
+#ifndef __x86_64__
 
 #define LIBFFI_ASM	
 #include <fficonfig.h>
 #include <ffi.h>
-#include "internal.h"
 
-#define C2(X, Y)  X ## Y
-#define C1(X, Y)  C2(X, Y)
-#ifdef __USER_LABEL_PREFIX__
-# define C(X)     C1(__USER_LABEL_PREFIX__, X)
+.text
+
+.globl ffi_prep_args
+
+	.align 4
+.globl ffi_call_SYSV
+        .type    ffi_call_SYSV,@function
+
+ffi_call_SYSV:
+.LFB1:
+        pushl %ebp
+.LCFI0:
+        movl  %esp,%ebp
+.LCFI1:
+	/* Make room for all of the new args.  */
+	movl  16(%ebp),%ecx
+	subl  %ecx,%esp
+
+        /* Align the stack pointer to 16-bytes */
+        andl  $0xfffffff0, %esp
+
+	movl  %esp,%eax
+
+	/* Place all of the ffi_prep_args in position  */
+	pushl 12(%ebp)
+	pushl %eax
+	call  *8(%ebp)
+
+	/* Return stack to previous state and call the function  */
+	addl  $8,%esp	
+
+	call  *28(%ebp)
+
+	/* Load %ecx with the return type code  */
+	movl  20(%ebp),%ecx	
+
+	/* Protect %esi.  We're going to pop it in the epilogue.  */
+	pushl %esi
+
+	/* If the return value pointer is NULL, assume no return value.  */
+	cmpl  $0,24(%ebp)
+	jne  0f
+
+	/* Even if there is no space for the return value, we are 
+	   obliged to handle floating-point values.  */
+	cmpl  $FFI_TYPE_FLOAT,%ecx
+	jne   noretval
+	fstp  %st(0)
+
+        jmp   epilogue
+
+0:
+	call  1f
+
+.Lstore_table:
+	.long	noretval-.Lstore_table	/* FFI_TYPE_VOID */
+	.long	retint-.Lstore_table	/* FFI_TYPE_INT */
+	.long	retfloat-.Lstore_table	/* FFI_TYPE_FLOAT */
+	.long	retdouble-.Lstore_table	/* FFI_TYPE_DOUBLE */
+	.long	retlongdouble-.Lstore_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	retuint8-.Lstore_table	/* FFI_TYPE_UINT8 */
+	.long	retsint8-.Lstore_table	/* FFI_TYPE_SINT8 */
+	.long	retuint16-.Lstore_table	/* FFI_TYPE_UINT16 */
+	.long	retsint16-.Lstore_table	/* FFI_TYPE_SINT16 */
+	.long	retint-.Lstore_table	/* FFI_TYPE_UINT32 */
+	.long	retint-.Lstore_table	/* FFI_TYPE_SINT32 */
+	.long	retint64-.Lstore_table	/* FFI_TYPE_UINT64 */
+	.long	retint64-.Lstore_table	/* FFI_TYPE_SINT64 */
+	.long	retstruct-.Lstore_table	/* FFI_TYPE_STRUCT */
+	.long	retint-.Lstore_table	/* FFI_TYPE_POINTER */
+
+1:
+	pop  %esi
+	add  (%esi, %ecx, 4), %esi
+	jmp  *%esi
+
+	/* Sign/zero extend as appropriate.  */
+retsint8:
+	movsbl  %al, %eax
+	jmp  retint
+
+retsint16:
+	movswl  %ax, %eax
+	jmp  retint
+
+retuint8:
+	movzbl  %al, %eax
+	jmp  retint
+
+retuint16:
+	movzwl  %ax, %eax
+	jmp  retint
+
+retfloat:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstps (%ecx)
+	jmp   epilogue
+
+retdouble:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstpl (%ecx)
+	jmp   epilogue
+
+retlongdouble:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstpt (%ecx)
+	jmp   epilogue
+	
+retint64:	
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movl  %eax,0(%ecx)
+	movl  %edx,4(%ecx)
+	jmp   epilogue
+	
+retint:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movl  %eax,0(%ecx)
+
+retstruct:
+	/* Nothing to do!  */
+
+noretval:
+epilogue:
+        popl %esi
+        movl %ebp,%esp
+        popl %ebp
+        ret
+.LFE1:
+.ffi_call_SYSV_end:
+        .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+	.align	4
+FFI_HIDDEN (ffi_closure_SYSV)
+.globl ffi_closure_SYSV
+	.type	ffi_closure_SYSV, @function
+
+ffi_closure_SYSV:
+.LFB2:
+	pushl	%ebp
+.LCFI2:
+	movl	%esp, %ebp
+.LCFI3:
+	subl	$40, %esp
+	leal	-24(%ebp), %edx
+	movl	%edx, -12(%ebp)	/* resp */
+	leal	8(%ebp), %edx
+#ifdef __SUNPRO_C
+	/* The SUNPRO compiler doesn't support GCC's regparm function
+  	   attribute, so we have to pass all three arguments to
+	   ffi_closure_SYSV_inner on the stack.  */
+	movl	%edx, 8(%esp)	/* args = __builtin_dwarf_cfa () */
+	leal	-12(%ebp), %edx
+	movl	%edx, 4(%esp)	/* &resp */
+	movl    %eax, (%esp)    /* closure */
 #else
-# define C(X)     X
+	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
+	leal	-12(%ebp), %edx
+	movl	%edx, (%esp)	/* &resp */
 #endif
-
-#ifdef X86_DARWIN
-# define L(X)     C1(L, X)
+#if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
+	call	ffi_closure_SYSV_inner
 #else
-# define L(X)     C1(.L, X)
+	movl	%ebx, 8(%esp)
+.LCFI7:
+	call	1f
+1:	popl	%ebx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+	call	ffi_closure_SYSV_inner@PLT
+	movl	8(%esp), %ebx
 #endif
+	movl	-12(%ebp), %ecx
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lcls_retint
 
-#ifdef __ELF__
-# define ENDF(X)  .type	X,@function; .size X, . - X
-#else
-# define ENDF(X)
-#endif
-
-/* Handle win32 fastcall name mangling.  */
-#ifdef X86_WIN32
-# define ffi_call_i386		@ffi_call_i386@8
-# define ffi_closure_inner	@ffi_closure_inner@8
-#else
-# define ffi_call_i386		C(ffi_call_i386)
-# define ffi_closure_inner	C(ffi_closure_inner)
-#endif
-
-/* This macro allows the safe creation of jump tables without an
-   actual table.  The entry points into the table are all 8 bytes.
-   The use of ORG asserts that we're at the correct location.  */
-/* ??? The clang assembler doesn't handle .org with symbolic expressions.  */
-#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
-# define E(BASE, X)	.balign 8
-#else
-# define E(BASE, X)	.balign 8; .org BASE + X * 8
-#endif
-
-	.text
-	.balign	16
-	.globl	ffi_call_i386
-	FFI_HIDDEN(ffi_call_i386)
-
-/* This is declared as
-
-   void ffi_call_i386(struct call_frame *frame, char *argp)
-        __attribute__((fastcall));
-
-   Thus the arguments are present in
-
-        ecx: frame
-        edx: argp
-*/
-
-ffi_call_i386:
-L(UW0):
-	# cfi_startproc
-#if !HAVE_FASTCALL
-	movl	4(%esp), %ecx
-	movl	8(%esp), %edx
-#endif
-	movl	(%esp), %eax		/* move the return address */
-	movl	%ebp, (%ecx)		/* store %ebp into local frame */
-	movl	%eax, 4(%ecx)		/* store retaddr into local frame */
-
-	/* New stack frame based off ebp.  This is a itty bit of unwind
-	   trickery in that the CFA *has* changed.  There is no easy way
-	   to describe it correctly on entry to the function.  Fortunately,
-	   it doesn't matter too much since at all points we can correctly
-	   unwind back to ffi_call.  Note that the location to which we
-	   moved the return address is (the new) CFA-4, so from the
-	   perspective of the unwind info, it hasn't moved.  */
-	movl	%ecx, %ebp
-L(UW1):
-	# cfi_def_cfa(%ebp, 8)
-	# cfi_rel_offset(%ebp, 0)
-
-	movl	%edx, %esp		/* set outgoing argument stack */
-	movl	20+R_EAX*4(%ebp), %eax	/* set register arguments */
-	movl	20+R_EDX*4(%ebp), %edx
-	movl	20+R_ECX*4(%ebp), %ecx
-
-	call	*8(%ebp)
-
-	movl	12(%ebp), %ecx		/* load return type code */
-	movl	%ebx, 8(%ebp)		/* preserve %ebx */
-L(UW2):
-	# cfi_rel_offset(%ebx, 8)
-
-	andl	$X86_RET_TYPE_MASK, %ecx
-#ifdef __PIC__
-	call	C(__x86.get_pc_thunk.bx)
-L(pc1):
-	leal	L(store_table)-L(pc1)(%ebx, %ecx, 8), %ebx
-#else
-	leal	L(store_table)(,%ecx, 8), %ebx
-#endif
-	movl	16(%ebp), %ecx		/* load result address */
-	jmp	*%ebx
-
-	.balign	8
-L(store_table):
-E(L(store_table), X86_RET_FLOAT)
-	fstps	(%ecx)
-	jmp	L(e1)
-E(L(store_table), X86_RET_DOUBLE)
-	fstpl	(%ecx)
-	jmp	L(e1)
-E(L(store_table), X86_RET_LDOUBLE)
-	fstpt	(%ecx)
-	jmp	L(e1)
-E(L(store_table), X86_RET_SINT8)
-	movsbl	%al, %eax
-	mov	%eax, (%ecx)
-	jmp	L(e1)
-E(L(store_table), X86_RET_SINT16)
-	movswl	%ax, %eax
-	mov	%eax, (%ecx)
-	jmp	L(e1)
-E(L(store_table), X86_RET_UINT8)
-	movzbl	%al, %eax
-	mov	%eax, (%ecx)
-	jmp	L(e1)
-E(L(store_table), X86_RET_UINT16)
-	movzwl	%ax, %eax
-	mov	%eax, (%ecx)
-	jmp	L(e1)
-E(L(store_table), X86_RET_INT64)
-	movl	%edx, 4(%ecx)
-	/* fallthru */
-E(L(store_table), X86_RET_INT32)
-	movl	%eax, (%ecx)
-	/* fallthru */
-E(L(store_table), X86_RET_VOID)
-L(e1):
-	movl	8(%ebp), %ebx
+	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
+	cmpl	$FFI_TYPE_UINT64, %eax
+	jge	0f
+	cmpl	$FFI_TYPE_UINT8, %eax
+	jge	.Lcls_retint
+	
+0:	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lcls_retllong
+	cmpl	$FFI_TYPE_STRUCT, %eax
+	je	.Lcls_retstruct
+.Lcls_epilogue:
 	movl	%ebp, %esp
 	popl	%ebp
-L(UW3):
-	# cfi_remember_state
-	# cfi_def_cfa(%esp, 4)
-	# cfi_restore(%ebx)
-	# cfi_restore(%ebp)
 	ret
-L(UW4):
-	# cfi_restore_state
+.Lcls_retint:
+	movl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retfloat:
+	flds	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retdouble:
+	fldl	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retldouble:
+	fldt	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retllong:
+	movl	(%ecx), %eax
+	movl	4(%ecx), %edx
+	jmp	.Lcls_epilogue
+.Lcls_retstruct:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret	$4
+.LFE2:
+	.size	ffi_closure_SYSV, .-ffi_closure_SYSV
 
-E(L(store_table), X86_RET_STRUCTPOP)
-	jmp	L(e1)
-E(L(store_table), X86_RET_STRUCTARG)
-	jmp	L(e1)
-E(L(store_table), X86_RET_STRUCT_1B)
-	movb	%al, (%ecx)
-	jmp	L(e1)
-E(L(store_table), X86_RET_STRUCT_2B)
-	movw	%ax, (%ecx)
-	jmp	L(e1)
+#if !FFI_NO_RAW_API
 
-	/* Fill out the table so that bad values are predictable.  */
-E(L(store_table), X86_RET_UNUSED14)
-	ud2
-E(L(store_table), X86_RET_UNUSED15)
-	ud2
-
-L(UW5):
-	# cfi_endproc
-ENDF(ffi_call_i386)
-
-/* The inner helper is declared as
-
-   void ffi_closure_inner(struct closure_frame *frame, char *argp)
-	__attribute_((fastcall))
-
-   Thus the arguments are placed in
-
-	ecx:	frame
-	edx:	argp
-*/
-
-/* Macros to help setting up the closure_data structure.  */
-
-#if HAVE_FASTCALL
-# define closure_FS	(40 + 4)
-# define closure_CF	0
+/* Precalculate for e.g. the Solaris 10/x86 assembler.  */
+#if FFI_TRAMPOLINE_SIZE == 10
+#define RAW_CLOSURE_CIF_OFFSET 12
+#define RAW_CLOSURE_FUN_OFFSET 16
+#define RAW_CLOSURE_USER_DATA_OFFSET 20
+#elif FFI_TRAMPOLINE_SIZE == 24
+#define RAW_CLOSURE_CIF_OFFSET 24
+#define RAW_CLOSURE_FUN_OFFSET 28
+#define RAW_CLOSURE_USER_DATA_OFFSET 32
 #else
-# define closure_FS	(8 + 40 + 12)
-# define closure_CF	8
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#endif
+#define CIF_FLAGS_OFFSET 20
+
+	.align	4
+FFI_HIDDEN (ffi_closure_raw_SYSV)
+.globl ffi_closure_raw_SYSV
+	.type	ffi_closure_raw_SYSV, @function
+
+ffi_closure_raw_SYSV:
+.LFB3:
+	pushl	%ebp
+.LCFI4:
+	movl	%esp, %ebp
+.LCFI5:
+	pushl	%esi
+.LCFI6:
+	subl	$36, %esp
+	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
+	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+	movl	%edx, 12(%esp)	/* user_data */
+	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
+	movl	%edx, 8(%esp)	/* raw_args */
+	leal	-24(%ebp), %edx
+	movl	%edx, 4(%esp)	/* &res */
+	movl	%esi, (%esp)	/* cif */
+	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
+	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lrcls_retint
+
+	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
+	cmpl	$FFI_TYPE_UINT64, %eax
+	jge	0f
+	cmpl	$FFI_TYPE_UINT8, %eax
+	jge	.Lrcls_retint
+0:
+	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lrcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lrcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lrcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lrcls_retllong
+.Lrcls_epilogue:
+	addl	$36, %esp
+	popl	%esi
+	popl	%ebp
+	ret
+.Lrcls_retint:
+	movl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+.Lrcls_retfloat:
+	flds	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retdouble:
+	fldl	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retldouble:
+	fldt	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retllong:
+	movl	-24(%ebp), %eax
+	movl	-20(%ebp), %edx
+	jmp	.Lrcls_epilogue
+.LFE3:
+	.size	ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
 #endif
 
-#define FFI_CLOSURE_SAVE_REGS		\
-	movl	%eax, closure_CF+16+R_EAX*4(%esp);	\
-	movl	%edx, closure_CF+16+R_EDX*4(%esp);	\
-	movl	%ecx, closure_CF+16+R_ECX*4(%esp)
+#if defined __GNUC__
+/* Only emit dwarf unwind info when building with GNU toolchain.  */
 
-#define FFI_CLOSURE_COPY_TRAMP_DATA					\
-	movl	FFI_TRAMPOLINE_SIZE(%eax), %edx;	/* copy cif */	\
-	movl	FFI_TRAMPOLINE_SIZE+4(%eax), %ecx;	/* copy fun */	\
-	movl	FFI_TRAMPOLINE_SIZE+8(%eax), %eax;	/* copy user_data */ \
-	movl	%edx, closure_CF+28(%esp);				\
-	movl	%ecx, closure_CF+32(%esp);				\
-	movl	%eax, closure_CF+36(%esp)
-
-#if HAVE_FASTCALL
-# define FFI_CLOSURE_PREP_CALL						\
-	movl	%esp, %ecx;			/* load closure_data */	\
-	leal	closure_FS+4(%esp), %edx;	/* load incoming stack */
-#else
-# define FFI_CLOSURE_PREP_CALL						\
-	leal	closure_CF(%esp), %ecx;		/* load closure_data */	\
-	leal	closure_FS+4(%esp), %edx;	/* load incoming stack */ \
-	movl	%ecx, (%esp);						\
-	movl	%edx, 4(%esp)
-#endif
-
-#define FFI_CLOSURE_CALL_INNER(UWN) \
-	call	ffi_closure_inner
-
-#define FFI_CLOSURE_MASK_AND_JUMP(N, UW)				\
-	andl	$X86_RET_TYPE_MASK, %eax;				\
-	leal	L(C1(load_table,N))(, %eax, 8), %edx;			\
-	movl	closure_CF(%esp), %eax;		/* optimiztic load */	\
-	jmp	*%edx
-
-#ifdef __PIC__
-# if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
-#  undef FFI_CLOSURE_MASK_AND_JUMP
-#  define FFI_CLOSURE_MASK_AND_JUMP(N, UW)				\
-	andl	$X86_RET_TYPE_MASK, %eax;				\
-	call	C(__x86.get_pc_thunk.dx);				\
-L(C1(pc,N)):								\
-	leal	L(C1(load_table,N))-L(C1(pc,N))(%edx, %eax, 8), %edx;	\
-	movl	closure_CF(%esp), %eax;		/* optimiztic load */	\
-	jmp	*%edx
+#if defined __PIC__
+# if defined __sun__ && defined __svr4__
+/* 32-bit Solaris 2/x86 uses datarel encoding for PIC.  GNU ld before 2.22
+   doesn't correctly sort .eh_frame_hdr with mixed encodings, so match this.  */
+#  define FDE_ENCODING		0x30	/* datarel */
+#  define FDE_ENCODE(X)		X@GOTOFF
 # else
-#  define FFI_CLOSURE_CALL_INNER_SAVE_EBX
-#  undef FFI_CLOSURE_CALL_INNER
-#  define FFI_CLOSURE_CALL_INNER(UWN)					\
-	movl	%ebx, 40(%esp);			/* save ebx */		\
-L(C1(UW,UWN)):								\
-	/* cfi_rel_offset(%ebx, 40); */					\
-	call	C(__x86.get_pc_thunk.bx);	/* load got register */	\
-	addl	$C(_GLOBAL_OFFSET_TABLE_), %ebx;			\
-	call	ffi_closure_inner@PLT
-#  undef FFI_CLOSURE_MASK_AND_JUMP
-#  define FFI_CLOSURE_MASK_AND_JUMP(N, UWN)				\
-	andl	$X86_RET_TYPE_MASK, %eax;				\
-	leal	L(C1(load_table,N))@GOTOFF(%ebx, %eax, 8), %edx;	\
-	movl	40(%esp), %ebx;			/* restore ebx */	\
-L(C1(UW,UWN)):								\
-	/* cfi_restore(%ebx); */					\
-	movl	closure_CF(%esp), %eax;		/* optimiztic load */	\
-	jmp	*%edx
-# endif /* DARWIN || HIDDEN */
-#endif /* __PIC__ */
+#  define FDE_ENCODING		0x1b	/* pcrel sdata4 */
+#  if defined HAVE_AS_X86_PCREL
+#   define FDE_ENCODE(X)	X-.
+#  else
+#   define FDE_ENCODE(X)	X@rel
+#  endif
+# endif
+#else
+# define FDE_ENCODING		0	/* absolute */
+# define FDE_ENCODE(X)		X
+#endif
 
-	.balign	16
-	.globl	C(ffi_go_closure_EAX)
-	FFI_HIDDEN(C(ffi_go_closure_EAX))
-C(ffi_go_closure_EAX):
-L(UW6):
-	# cfi_startproc
-	subl	$closure_FS, %esp
-L(UW7):
-	# cfi_def_cfa_offset(closure_FS + 4)
-	FFI_CLOSURE_SAVE_REGS
-	movl	4(%eax), %edx			/* copy cif */
-	movl	8(%eax), %ecx			/* copy fun */
-	movl	%edx, closure_CF+28(%esp)
-	movl	%ecx, closure_CF+32(%esp)
-	movl	%eax, closure_CF+36(%esp)	/* closure is user_data */
-	jmp	L(do_closure_i386)
-L(UW8):
-	# cfi_endproc
-ENDF(C(ffi_go_closure_EAX))
-
-	.balign	16
-	.globl	C(ffi_go_closure_ECX)
-	FFI_HIDDEN(C(ffi_go_closure_ECX))
-C(ffi_go_closure_ECX):
-L(UW9):
-	# cfi_startproc
-	subl	$closure_FS, %esp
-L(UW10):
-	# cfi_def_cfa_offset(closure_FS + 4)
-	FFI_CLOSURE_SAVE_REGS
-	movl	4(%ecx), %edx			/* copy cif */
-	movl	8(%ecx), %eax			/* copy fun */
-	movl	%edx, closure_CF+28(%esp)
-	movl	%eax, closure_CF+32(%esp)
-	movl	%ecx, closure_CF+36(%esp)	/* closure is user_data */
-	jmp	L(do_closure_i386)
-L(UW11):
-	# cfi_endproc
-ENDF(C(ffi_go_closure_ECX))
-
-/* The closure entry points are reached from the ffi_closure trampoline.
-   On entry, %eax contains the address of the ffi_closure.  */
-
-	.balign	16
-	.globl	C(ffi_closure_i386)
-	FFI_HIDDEN(C(ffi_closure_i386))
-
-C(ffi_closure_i386):
-L(UW12):
-	# cfi_startproc
-	subl	$closure_FS, %esp
-L(UW13):
-	# cfi_def_cfa_offset(closure_FS + 4)
-
-	FFI_CLOSURE_SAVE_REGS
-	FFI_CLOSURE_COPY_TRAMP_DATA
-
-	/* Entry point from preceeding Go closures.  */
-L(do_closure_i386):
-
-	FFI_CLOSURE_PREP_CALL
-	FFI_CLOSURE_CALL_INNER(14)
-	FFI_CLOSURE_MASK_AND_JUMP(2, 15)
-
-	.balign	8
-L(load_table2):
-E(L(load_table2), X86_RET_FLOAT)
-	flds	closure_CF(%esp)
-	jmp	L(e2)
-E(L(load_table2), X86_RET_DOUBLE)
-	fldl	closure_CF(%esp)
-	jmp	L(e2)
-E(L(load_table2), X86_RET_LDOUBLE)
-	fldt	closure_CF(%esp)
-	jmp	L(e2)
-E(L(load_table2), X86_RET_SINT8)
-	movsbl	%al, %eax
-	jmp	L(e2)
-E(L(load_table2), X86_RET_SINT16)
-	movswl	%ax, %eax
-	jmp	L(e2)
-E(L(load_table2), X86_RET_UINT8)
-	movzbl	%al, %eax
-	jmp	L(e2)
-E(L(load_table2), X86_RET_UINT16)
-	movzwl	%ax, %eax
-	jmp	L(e2)
-E(L(load_table2), X86_RET_INT64)
-	movl	closure_CF+4(%esp), %edx
-	jmp	L(e2)
-E(L(load_table2), X86_RET_INT32)
-	nop
-	/* fallthru */
-E(L(load_table2), X86_RET_VOID)
-L(e2):
-	addl	$closure_FS, %esp
-L(UW16):
-	# cfi_adjust_cfa_offset(-closure_FS)
-	ret
-L(UW17):
-	# cfi_adjust_cfa_offset(closure_FS)
-E(L(load_table2), X86_RET_STRUCTPOP)
-	addl	$closure_FS, %esp
-L(UW18):
-	# cfi_adjust_cfa_offset(-closure_FS)
-	ret	$4
-L(UW19):
-	# cfi_adjust_cfa_offset(closure_FS)
-E(L(load_table2), X86_RET_STRUCTARG)
-	jmp	L(e2)
-E(L(load_table2), X86_RET_STRUCT_1B)
-	movzbl	%al, %eax
-	jmp	L(e2)
-E(L(load_table2), X86_RET_STRUCT_2B)
-	movzwl	%ax, %eax
-	jmp	L(e2)
-
-	/* Fill out the table so that bad values are predictable.  */
-E(L(load_table2), X86_RET_UNUSED14)
-	ud2
-E(L(load_table2), X86_RET_UNUSED15)
-	ud2
-
-L(UW20):
-	# cfi_endproc
-ENDF(C(ffi_closure_i386))
-
-	.balign	16
-	.globl	C(ffi_go_closure_STDCALL)
-	FFI_HIDDEN(C(ffi_go_closure_STDCALL))
-C(ffi_go_closure_STDCALL):
-L(UW21):
-	# cfi_startproc
-	subl	$closure_FS, %esp
-L(UW22):
-	# cfi_def_cfa_offset(closure_FS + 4)
-	FFI_CLOSURE_SAVE_REGS
-	movl	4(%ecx), %edx			/* copy cif */
-	movl	8(%ecx), %eax			/* copy fun */
-	movl	%edx, closure_CF+28(%esp)
-	movl	%eax, closure_CF+32(%esp)
-	movl	%ecx, closure_CF+36(%esp)	/* closure is user_data */
-	jmp	L(do_closure_STDCALL)
-L(UW23):
-	# cfi_endproc
-ENDF(C(ffi_go_closure_STDCALL))
-
-/* For REGISTER, we have no available parameter registers, and so we
-   enter here having pushed the closure onto the stack.  */
-
-	.balign	16
-	.globl	C(ffi_closure_REGISTER)
-	FFI_HIDDEN(C(ffi_closure_REGISTER))
-C(ffi_closure_REGISTER):
-L(UW24):
-	# cfi_startproc
-	# cfi_def_cfa(%esp, 8)
-	# cfi_offset(%eip, -8)
-	subl	$closure_FS-4, %esp
-L(UW25):
-	# cfi_def_cfa_offset(closure_FS + 4)
-	FFI_CLOSURE_SAVE_REGS
-	movl	closure_FS-4(%esp), %ecx	/* load retaddr */
-	movl	closure_FS(%esp), %eax		/* load closure */
-	movl	%ecx, closure_FS(%esp)		/* move retaddr */
-	jmp	L(do_closure_REGISTER)
-L(UW26):
-	# cfi_endproc
-ENDF(C(ffi_closure_REGISTER))
-
-/* For STDCALL (and others), we need to pop N bytes of arguments off
-   the stack following the closure.  The amount needing to be popped
-   is returned to us from ffi_closure_inner.  */
-
-	.balign	16
-	.globl	C(ffi_closure_STDCALL)
-	FFI_HIDDEN(C(ffi_closure_STDCALL))
-C(ffi_closure_STDCALL):
-L(UW27):
-	# cfi_startproc
-	subl	$closure_FS, %esp
-L(UW28):
-	# cfi_def_cfa_offset(closure_FS + 4)
-
-	FFI_CLOSURE_SAVE_REGS
-
-	/* Entry point from ffi_closure_REGISTER.  */
-L(do_closure_REGISTER):
-
-	FFI_CLOSURE_COPY_TRAMP_DATA
-
-	/* Entry point from preceeding Go closure.  */
-L(do_closure_STDCALL):
-
-	FFI_CLOSURE_PREP_CALL
-	FFI_CLOSURE_CALL_INNER(29)
-
-	movl	%eax, %ecx
-	shrl	$X86_RET_POP_SHIFT, %ecx	/* isolate pop count */
-	leal	closure_FS(%esp, %ecx), %ecx	/* compute popped esp */
-	movl	closure_FS(%esp), %edx		/* move return address */
-	movl	%edx, (%ecx)
-
-	/* From this point on, the value of %esp upon return is %ecx+4,
-	   and we've copied the return address to %ecx to make return easy.
-	   There's no point in representing this in the unwind info, as
-	   there is always a window between the mov and the ret which
-	   will be wrong from one point of view or another.  */
-
-	FFI_CLOSURE_MASK_AND_JUMP(3, 30)
-
-	.balign	8
-L(load_table3):
-E(L(load_table3), X86_RET_FLOAT)
-	flds    closure_CF(%esp)
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_DOUBLE)
-	fldl    closure_CF(%esp)
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_LDOUBLE)
-	fldt    closure_CF(%esp)
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_SINT8)
-	movsbl  %al, %eax
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_SINT16)
-	movswl  %ax, %eax
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_UINT8)
-	movzbl  %al, %eax
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_UINT16)
-	movzwl  %ax, %eax
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_INT64)
-	movl	closure_CF+4(%esp), %edx
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_INT32)
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_VOID)
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_STRUCTPOP)
-	movl    %ecx, %esp
-	ret
-E(L(load_table3), X86_RET_STRUCTARG)
-	movl	%ecx, %esp
-	ret
-E(L(load_table3), X86_RET_STRUCT_1B)
-	movzbl	%al, %eax
-	movl	%ecx, %esp
-	ret
-E(L(load_table3), X86_RET_STRUCT_2B)
-	movzwl	%ax, %eax
-	movl	%ecx, %esp
-	ret
-
-	/* Fill out the table so that bad values are predictable.  */
-E(L(load_table3), X86_RET_UNUSED14)
-	ud2
-E(L(load_table3), X86_RET_UNUSED15)
-	ud2
-
-L(UW31):
-	# cfi_endproc
-ENDF(C(ffi_closure_STDCALL))
+	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
+.LSCIE1:
+	.long	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+#ifdef HAVE_AS_ASCII_PSEUDO_OP
+#ifdef __PIC__
+	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.ascii "\0"	/* CIE Augmentation */
+#endif
+#elif defined HAVE_AS_STRING_PSEUDO_OP
+#ifdef __PIC__
+	.string "zR"	/* CIE Augmentation */
+#else
+	.string ""	/* CIE Augmentation */
+#endif
+#else
+#error missing .ascii/.string
+#endif
+	.byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
+	.byte	0x8	/* CIE RA Column */
+#ifdef __PIC__
+	.byte	0x1	/* .uleb128 0x1; Augmentation size */
+	.byte	FDE_ENCODING
+#endif
+	.byte	0xc	/* DW_CFA_def_cfa */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x88	/* DW_CFA_offset, column 0x8 */
+	.byte	0x1	/* .uleb128 0x1 */
+	.align 4
+.LECIE1:
+.LSFDE1:
+	.long	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
+	.long	FDE_ENCODE(.LFB1)	/* FDE initial location */
+	.long	.LFE1-.LFB1		/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI0-.LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI1-.LCFI0
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+	.align 4
+.LEFDE1:
+.LSFDE2:
+	.long	.LEFDE2-.LASFDE2	/* FDE Length */
+.LASFDE2:
+	.long	.LASFDE2-.Lframe1	/* FDE CIE offset */
+	.long	FDE_ENCODE(.LFB2)	/* FDE initial location */
+	.long	.LFE2-.LFB2		/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI2-.LFB2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+#if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI7-.LCFI3
+	.byte	0x83	/* DW_CFA_offset, column 0x3 */
+	.byte	0xa	/* .uleb128 0xa */
+#endif
+	.align 4
+.LEFDE2:
 
 #if !FFI_NO_RAW_API
 
-#define raw_closure_S_FS	(16+16+12)
-
-	.balign	16
-	.globl	C(ffi_closure_raw_SYSV)
-	FFI_HIDDEN(C(ffi_closure_raw_SYSV))
-C(ffi_closure_raw_SYSV):
-L(UW32):
-	# cfi_startproc
-	subl	$raw_closure_S_FS, %esp
-L(UW33):
-	# cfi_def_cfa_offset(raw_closure_S_FS + 4)
-	movl	%ebx, raw_closure_S_FS-4(%esp)
-L(UW34):
-	# cfi_rel_offset(%ebx, raw_closure_S_FS-4)
-
-	movl	FFI_TRAMPOLINE_SIZE+8(%eax), %edx	/* load cl->user_data */
-	movl	%edx, 12(%esp)
-	leal	raw_closure_S_FS+4(%esp), %edx		/* load raw_args */
-	movl	%edx, 8(%esp)
-	leal	16(%esp), %edx				/* load &res */
-	movl	%edx, 4(%esp)
-	movl	FFI_TRAMPOLINE_SIZE(%eax), %ebx		/* load cl->cif */
-	movl	%ebx, (%esp)
-	call	*FFI_TRAMPOLINE_SIZE+4(%eax)		/* call cl->fun */
-
-	movl	20(%ebx), %eax				/* load cif->flags */
-	andl	$X86_RET_TYPE_MASK, %eax
+.LSFDE3:
+	.long	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
+	.long	FDE_ENCODE(.LFB3)	/* FDE initial location */
+	.long	.LFE3-.LFB3		/* FDE address range */
 #ifdef __PIC__
-	call	C(__x86.get_pc_thunk.bx)
-L(pc4):
-	leal	L(load_table4)-L(pc4)(%ebx, %eax, 8), %ecx
-#else
-	leal	L(load_table4)(,%eax, 8), %ecx
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
 #endif
-	movl	raw_closure_S_FS-4(%esp), %ebx
-L(UW35):
-	# cfi_restore(%ebx)
-	movl	16(%esp), %eax				/* Optimistic load */
-	jmp	*%ecx
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI4-.LFB3
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI5-.LCFI4
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI6-.LCFI5
+	.byte	0x86	/* DW_CFA_offset, column 0x6 */
+	.byte	0x3	/* .uleb128 0x3 */
+	.align 4
+.LEFDE3:
 
-	.balign	8
-L(load_table4):
-E(L(load_table4), X86_RET_FLOAT)
-	flds	16(%esp)
-	jmp	L(e4)
-E(L(load_table4), X86_RET_DOUBLE)
-	fldl	16(%esp)
-	jmp	L(e4)
-E(L(load_table4), X86_RET_LDOUBLE)
-	fldt	16(%esp)
-	jmp	L(e4)
-E(L(load_table4), X86_RET_SINT8)
-	movsbl	%al, %eax
-	jmp	L(e4)
-E(L(load_table4), X86_RET_SINT16)
-	movswl	%ax, %eax
-	jmp	L(e4)
-E(L(load_table4), X86_RET_UINT8)
-	movzbl	%al, %eax
-	jmp	L(e4)
-E(L(load_table4), X86_RET_UINT16)
-	movzwl	%ax, %eax
-	jmp	L(e4)
-E(L(load_table4), X86_RET_INT64)
-	movl	16+4(%esp), %edx
-	jmp	L(e4)
-E(L(load_table4), X86_RET_INT32)
-	nop
-	/* fallthru */
-E(L(load_table4), X86_RET_VOID)
-L(e4):
-	addl	$raw_closure_S_FS, %esp
-L(UW36):
-	# cfi_adjust_cfa_offset(-raw_closure_S_FS)
-	ret
-L(UW37):
-	# cfi_adjust_cfa_offset(raw_closure_S_FS)
-E(L(load_table4), X86_RET_STRUCTPOP)
-	addl	$raw_closure_S_FS, %esp
-L(UW38):
-	# cfi_adjust_cfa_offset(-raw_closure_S_FS)
-	ret	$4
-L(UW39):
-	# cfi_adjust_cfa_offset(raw_closure_S_FS)
-E(L(load_table4), X86_RET_STRUCTARG)
-	jmp	L(e4)
-E(L(load_table4), X86_RET_STRUCT_1B)
-	movzbl	%al, %eax
-	jmp	L(e4)
-E(L(load_table4), X86_RET_STRUCT_2B)
-	movzwl	%ax, %eax
-	jmp	L(e4)
-
-	/* Fill out the table so that bad values are predictable.  */
-E(L(load_table4), X86_RET_UNUSED14)
-	ud2
-E(L(load_table4), X86_RET_UNUSED15)
-	ud2
-
-L(UW40):
-	# cfi_endproc
-ENDF(C(ffi_closure_raw_SYSV))
-
-#define raw_closure_T_FS	(16+16+8)
-
-	.balign	16
-	.globl	C(ffi_closure_raw_THISCALL)
-	FFI_HIDDEN(C(ffi_closure_raw_THISCALL))
-C(ffi_closure_raw_THISCALL):
-L(UW41):
-	# cfi_startproc
-	/* Rearrange the stack such that %ecx is the first argument.
-	   This means moving the return address.  */
-	popl	%edx
-L(UW42):
-	# cfi_def_cfa_offset(0)
-	# cfi_register(%eip, %edx)
-	pushl	%ecx
-L(UW43):
-	# cfi_adjust_cfa_offset(4)
-	pushl	%edx
-L(UW44):
-	# cfi_adjust_cfa_offset(4)
-	# cfi_rel_offset(%eip, 0)
-	subl	$raw_closure_T_FS, %esp
-L(UW45):
-	# cfi_adjust_cfa_offset(raw_closure_T_FS)
-	movl	%ebx, raw_closure_T_FS-4(%esp)
-L(UW46):
-	# cfi_rel_offset(%ebx, raw_closure_T_FS-4)
-
-	movl	FFI_TRAMPOLINE_SIZE+8(%eax), %edx	/* load cl->user_data */
-	movl	%edx, 12(%esp)
-	leal	raw_closure_T_FS+4(%esp), %edx		/* load raw_args */
-	movl	%edx, 8(%esp)
-	leal	16(%esp), %edx				/* load &res */
-	movl	%edx, 4(%esp)
-	movl	FFI_TRAMPOLINE_SIZE(%eax), %ebx		/* load cl->cif */
-	movl	%ebx, (%esp)
-	call	*FFI_TRAMPOLINE_SIZE+4(%eax)		/* call cl->fun */
-
-	movl	20(%ebx), %eax				/* load cif->flags */
-	andl	$X86_RET_TYPE_MASK, %eax
-#ifdef __PIC__
-	call	C(__x86.get_pc_thunk.bx)
-L(pc5):
-	leal	L(load_table5)-L(pc5)(%ebx, %eax, 8), %ecx
-#else
-	leal	L(load_table5)(,%eax, 8), %ecx
 #endif
-	movl	raw_closure_T_FS-4(%esp), %ebx
-L(UW47):
-	# cfi_restore(%ebx)
-	movl	16(%esp), %eax				/* Optimistic load */
-	jmp	*%ecx
-
-	.balign	8
-L(load_table5):
-E(L(load_table5), X86_RET_FLOAT)
-	flds	16(%esp)
-	jmp	L(e5)
-E(L(load_table5), X86_RET_DOUBLE)
-	fldl	16(%esp)
-	jmp	L(e5)
-E(L(load_table5), X86_RET_LDOUBLE)
-	fldt	16(%esp)
-	jmp	L(e5)
-E(L(load_table5), X86_RET_SINT8)
-	movsbl	%al, %eax
-	jmp	L(e5)
-E(L(load_table5), X86_RET_SINT16)
-	movswl	%ax, %eax
-	jmp	L(e5)
-E(L(load_table5), X86_RET_UINT8)
-	movzbl	%al, %eax
-	jmp	L(e5)
-E(L(load_table5), X86_RET_UINT16)
-	movzwl	%ax, %eax
-	jmp	L(e5)
-E(L(load_table5), X86_RET_INT64)
-	movl	16+4(%esp), %edx
-	jmp	L(e5)
-E(L(load_table5), X86_RET_INT32)
-	nop
-	/* fallthru */
-E(L(load_table5), X86_RET_VOID)
-L(e5):
-	addl	$raw_closure_T_FS, %esp
-L(UW48):
-	# cfi_adjust_cfa_offset(-raw_closure_T_FS)
-	/* Remove the extra %ecx argument we pushed.  */
-	ret	$4
-L(UW49):
-	# cfi_adjust_cfa_offset(raw_closure_T_FS)
-E(L(load_table5), X86_RET_STRUCTPOP)
-	addl	$raw_closure_T_FS, %esp
-L(UW50):
-	# cfi_adjust_cfa_offset(-raw_closure_T_FS)
-	ret	$8
-L(UW51):
-	# cfi_adjust_cfa_offset(raw_closure_T_FS)
-E(L(load_table5), X86_RET_STRUCTARG)
-	jmp	L(e5)
-E(L(load_table5), X86_RET_STRUCT_1B)
-	movzbl	%al, %eax
-	jmp	L(e5)
-E(L(load_table5), X86_RET_STRUCT_2B)
-	movzwl	%ax, %eax
-	jmp	L(e5)
-
-	/* Fill out the table so that bad values are predictable.  */
-E(L(load_table5), X86_RET_UNUSED14)
-	ud2
-E(L(load_table5), X86_RET_UNUSED15)
-	ud2
-
-L(UW52):
-	# cfi_endproc
-ENDF(C(ffi_closure_raw_THISCALL))
-
-#endif /* !FFI_NO_RAW_API */
-
-#ifdef X86_DARWIN
-# define COMDAT(X)							\
-        .section __TEXT,__text,coalesced,pure_instructions;		\
-        .weak_definition X;						\
-        FFI_HIDDEN(X)
-#elif defined __ELF__ && !(defined(__sun__) && defined(__svr4__))
-# define COMDAT(X)							\
-	.section .text.X,"axG",@progbits,X,comdat;			\
-	.globl	X;							\
-	FFI_HIDDEN(X)
-#else
-# define COMDAT(X)
 #endif
 
-#if defined(__PIC__)
-	COMDAT(C(__x86.get_pc_thunk.bx))
-C(__x86.get_pc_thunk.bx):
-	movl	(%esp), %ebx
-	ret
-ENDF(C(__x86.get_pc_thunk.bx))
-# if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
-	COMDAT(C(__x86.get_pc_thunk.dx))
-C(__x86.get_pc_thunk.dx):
-	movl	(%esp), %edx
-	ret
-ENDF(C(__x86.get_pc_thunk.dx))
-#endif /* DARWIN || HIDDEN */
-#endif /* __PIC__ */
-
-/* Sadly, OSX cctools-as doesn't understand .cfi directives at all.  */
-
-#ifdef __APPLE__
-.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
-EHFrame0:
-#elif defined(X86_WIN32)
-.section .eh_frame,"r"
-#elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)
-.section .eh_frame,EH_FRAME_FLAGS,@unwind
-#else
-.section .eh_frame,EH_FRAME_FLAGS,@progbits
-#endif
-
-#ifdef HAVE_AS_X86_PCREL
-# define PCREL(X)	X - .
-#else
-# define PCREL(X)	X@rel
-#endif
-
-/* Simplify advancing between labels.  Assume DW_CFA_advance_loc1 fits.  */
-#define ADV(N, P)	.byte 2, L(N)-L(P)
-
-	.balign 4
-L(CIE):
-	.set	L(set0),L(ECIE)-L(SCIE)
-	.long	L(set0)			/* CIE Length */
-L(SCIE):
-	.long	0			/* CIE Identifier Tag */
-	.byte	1			/* CIE Version */
-	.ascii	"zR\0"			/* CIE Augmentation */
-	.byte	1			/* CIE Code Alignment Factor */
-	.byte	0x7c			/* CIE Data Alignment Factor */
-	.byte	0x8			/* CIE RA Column */
-	.byte	1			/* Augmentation size */
-	.byte	0x1b			/* FDE Encoding (pcrel sdata4) */
-	.byte	0xc, 4, 4		/* DW_CFA_def_cfa, %esp offset 4 */
-	.byte	0x80+8, 1		/* DW_CFA_offset, %eip offset 1*-4 */
-	.balign 4
-L(ECIE):
-
-	.set	L(set1),L(EFDE1)-L(SFDE1)
-	.long	L(set1)			/* FDE Length */
-L(SFDE1):
-	.long	L(SFDE1)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW0))		/* Initial location */
-	.long	L(UW5)-L(UW0)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW1, UW0)
-	.byte	0xc, 5, 8		/* DW_CFA_def_cfa, %ebp 8 */
-	.byte	0x80+5, 2		/* DW_CFA_offset, %ebp 2*-4 */
-	ADV(UW2, UW1)
-	.byte	0x80+3, 0		/* DW_CFA_offset, %ebx 0*-4 */
-	ADV(UW3, UW2)
-	.byte	0xa			/* DW_CFA_remember_state */
-	.byte	0xc, 4, 4		/* DW_CFA_def_cfa, %esp 4 */
-	.byte	0xc0+3			/* DW_CFA_restore, %ebx */
-	.byte	0xc0+5			/* DW_CFA_restore, %ebp */
-	ADV(UW4, UW3)
-	.byte	0xb			/* DW_CFA_restore_state */
-	.balign	4
-L(EFDE1):
-
-	.set	L(set2),L(EFDE2)-L(SFDE2)
-	.long	L(set2)			/* FDE Length */
-L(SFDE2):
-	.long	L(SFDE2)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW6))		/* Initial location */
-	.long	L(UW8)-L(UW6)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW7, UW6)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE2):
-
-	.set	L(set3),L(EFDE3)-L(SFDE3)
-	.long	L(set3)			/* FDE Length */
-L(SFDE3):
-	.long	L(SFDE3)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW9))		/* Initial location */
-	.long	L(UW11)-L(UW9)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW10, UW9)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE3):
-
-	.set	L(set4),L(EFDE4)-L(SFDE4)
-	.long	L(set4)			/* FDE Length */
-L(SFDE4):
-	.long	L(SFDE4)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW12))		/* Initial location */
-	.long	L(UW20)-L(UW12)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW13, UW12)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX
-	ADV(UW14, UW13)
-	.byte	0x80+3, (40-(closure_FS+4))/-4  /* DW_CFA_offset %ebx */
-	ADV(UW15, UW14)
-	.byte	0xc0+3			/* DW_CFA_restore %ebx */
-	ADV(UW16, UW15)
-#else
-	ADV(UW16, UW13)
-#endif
-	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
-	ADV(UW17, UW16)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	ADV(UW18, UW17)
-	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
-	ADV(UW19, UW18)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE4):
-
-	.set	L(set5),L(EFDE5)-L(SFDE5)
-	.long	L(set5)			/* FDE Length */
-L(SFDE5):
-	.long	L(SFDE5)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW21))		/* Initial location */
-	.long	L(UW23)-L(UW21)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW22, UW21)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE5):
-
-	.set	L(set6),L(EFDE6)-L(SFDE6)
-	.long	L(set6)			/* FDE Length */
-L(SFDE6):
-	.long	L(SFDE6)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW24))		/* Initial location */
-	.long	L(UW26)-L(UW24)		/* Address range */
-	.byte	0			/* Augmentation size */
-	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
-	.byte	0x80+8, 2		/* DW_CFA_offset %eip, 2*-4 */
-	ADV(UW25, UW24)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE6):
-
-	.set	L(set7),L(EFDE7)-L(SFDE7)
-	.long	L(set7)			/* FDE Length */
-L(SFDE7):
-	.long	L(SFDE7)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW27))		/* Initial location */
-	.long	L(UW31)-L(UW27)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW28, UW27)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX
-	ADV(UW29, UW28)
-	.byte	0x80+3, (40-(closure_FS+4))/-4  /* DW_CFA_offset %ebx */
-	ADV(UW30, UW29)
-	.byte	0xc0+3			/* DW_CFA_restore %ebx */
-#endif
-	.balign	4
-L(EFDE7):
-
-#if !FFI_NO_RAW_API
-	.set	L(set8),L(EFDE8)-L(SFDE8)
-	.long	L(set8)			/* FDE Length */
-L(SFDE8):
-	.long	L(SFDE8)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW32))		/* Initial location */
-	.long	L(UW40)-L(UW32)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW33, UW32)
-	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */
-	ADV(UW34, UW33)
-	.byte	0x80+3, 2		/* DW_CFA_offset %ebx 2*-4 */
-	ADV(UW35, UW34)
-	.byte	0xc0+3			/* DW_CFA_restore %ebx */
-	ADV(UW36, UW35)
-	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
-	ADV(UW37, UW36)
-	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */
-	ADV(UW38, UW37)
-	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
-	ADV(UW39, UW38)
-	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE8):
-
-	.set	L(set9),L(EFDE9)-L(SFDE9)
-	.long	L(set9)			/* FDE Length */
-L(SFDE9):
-	.long	L(SFDE9)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW41))		/* Initial location */
-	.long	L(UW52)-L(UW41)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW42, UW41)
-	.byte	0xe, 0			/* DW_CFA_def_cfa_offset */
-	.byte	0x9, 8, 2		/* DW_CFA_register %eip, %edx */
-	ADV(UW43, UW42)
-	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
-	ADV(UW44, UW43)
-	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
-	.byte	0x80+8, 2		/* DW_CFA_offset %eip 2*-4 */
-	ADV(UW45, UW44)
-	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */
-	ADV(UW46, UW45)
-	.byte	0x80+3, 3		/* DW_CFA_offset %ebx 3*-4 */
-	ADV(UW47, UW46)
-	.byte	0xc0+3			/* DW_CFA_restore %ebx */
-	ADV(UW48, UW47)
-	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
-	ADV(UW49, UW48)
-	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */
-	ADV(UW50, UW49)
-	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
-	ADV(UW51, UW50)
-	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE9):
-#endif /* !FFI_NO_RAW_API */
-
-#ifdef _WIN32
-	.def	 @feat.00;
-	.scl	3;
-	.type	0;
-	.endef
-	.globl	@feat.00
-@feat.00 = 1
-#endif
-
-#ifdef __APPLE__
-    .subsections_via_symbols
-    .section __LD,__compact_unwind,regular,debug
-
-    /* compact unwind for ffi_call_i386 */
-    .long    C(ffi_call_i386)
-    .set     L1,L(UW5)-L(UW0)
-    .long    L1
-    .long    0x04000000 /* use dwarf unwind info */
-    .long    0
-    .long    0
-
-    /* compact unwind for ffi_go_closure_EAX */
-    .long    C(ffi_go_closure_EAX)
-    .set     L2,L(UW8)-L(UW6)
-    .long    L2
-    .long    0x04000000 /* use dwarf unwind info */
-    .long    0
-    .long    0
-
-    /* compact unwind for ffi_go_closure_ECX */
-    .long    C(ffi_go_closure_ECX)
-    .set     L3,L(UW11)-L(UW9)
-    .long    L3
-    .long    0x04000000 /* use dwarf unwind info */
-    .long    0
-    .long    0
-
-    /* compact unwind for ffi_closure_i386 */
-    .long    C(ffi_closure_i386)
-    .set     L4,L(UW20)-L(UW12)
-    .long    L4
-    .long    0x04000000 /* use dwarf unwind info */
-    .long    0
-    .long    0
-
-    /* compact unwind for ffi_go_closure_STDCALL */
-    .long    C(ffi_go_closure_STDCALL)
-    .set     L5,L(UW23)-L(UW21)
-    .long    L5
-    .long    0x04000000 /* use dwarf unwind info */
-    .long    0
-    .long    0
-
-    /* compact unwind for ffi_closure_REGISTER */
-    .long    C(ffi_closure_REGISTER)
-    .set     L6,L(UW26)-L(UW24)
-    .long    L6
-    .long    0x04000000 /* use dwarf unwind info */
-    .long    0
-    .long    0
-
-    /* compact unwind for ffi_closure_STDCALL */
-    .long    C(ffi_closure_STDCALL)
-    .set     L7,L(UW31)-L(UW27)
-    .long    L7
-    .long    0x04000000 /* use dwarf unwind info */
-    .long    0
-    .long    0
-
-    /* compact unwind for ffi_closure_raw_SYSV */
-    .long    C(ffi_closure_raw_SYSV)
-    .set     L8,L(UW40)-L(UW32)
-    .long    L8
-    .long    0x04000000 /* use dwarf unwind info */
-    .long    0
-    .long    0
-
-    /* compact unwind for ffi_closure_raw_THISCALL */
-    .long    C(ffi_closure_raw_THISCALL)
-    .set     L9,L(UW52)-L(UW41)
-    .long    L9
-    .long    0x04000000 /* use dwarf unwind info */
-    .long    0
-    .long    0
-#endif /* __APPLE__ */
-
-#endif /* ifndef _MSC_VER */
-#endif /* ifdef __i386__ */
+#endif /* ifndef __x86_64__ */
 
 #if defined __ELF__ && defined __linux__
 	.section	.note.GNU-stack,"",@progbits
diff --git a/src/x86/sysv_intel.S b/src/x86/sysv_intel.S
deleted file mode 100644
index 3cafd71..0000000
--- a/src/x86/sysv_intel.S
+++ /dev/null
@@ -1,995 +0,0 @@
-/* -----------------------------------------------------------------------
-   sysv.S - Copyright (c) 2017  Anthony Green
-          - Copyright (c) 2013  The Written Word, Inc.
-          - Copyright (c) 1996,1998,2001-2003,2005,2008,2010  Red Hat, Inc.
-   
-   X86 Foreign Function Interface 
-
-   Permission is hereby granted, free of charge, to any person obtaining
-   a copy of this software and associated documentation files (the
-   ``Software''), to deal in the Software without restriction, including
-   without limitation the rights to use, copy, modify, merge, publish,
-   distribute, sublicense, and/or sell copies of the Software, and to
-   permit persons to whom the Software is furnished to do so, subject to
-   the following conditions:
-
-   The above copyright notice and this permission notice shall be included
-   in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-   DEALINGS IN THE SOFTWARE.
-   ----------------------------------------------------------------------- */
-
-#ifndef __x86_64__
-#ifdef _MSC_VER
-
-#define LIBFFI_ASM	
-#include <fficonfig.h>
-#include <ffi.h>
-#include <ffi_cfi.h>
-#include "internal.h" 
-
-#define C2(X, Y)  X ## Y
-#define C1(X, Y)  C2(X, Y)
-#define L(X)     C1(L, X)
-# define ENDF(X) X ENDP
-
-/* This macro allows the safe creation of jump tables without an
-   actual table.  The entry points into the table are all 8 bytes.
-   The use of ORG asserts that we're at the correct location.  */
-/* ??? The clang assembler doesn't handle .org with symbolic expressions.  */
-#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
-# define E(BASE, X)	ALIGN 8
-#else
-# define E(BASE, X)	ALIGN 8; ORG BASE + X * 8
-#endif
-
-    .686P
-    .MODEL FLAT
-
-EXTRN	@ffi_closure_inner@8:PROC
-_TEXT SEGMENT
-
-/* This is declared as
-
-   void ffi_call_i386(struct call_frame *frame, char *argp)
-        __attribute__((fastcall));
-
-   Thus the arguments are present in
-
-        ecx: frame
-        edx: argp
-*/
-
-ALIGN 16
-PUBLIC @ffi_call_i386@8
-@ffi_call_i386@8 PROC
-L(UW0):
-	cfi_startproc
- #if !HAVE_FASTCALL
-	mov	    ecx, [esp+4]
-	mov 	edx, [esp+8]
- #endif
-	mov	    eax, [esp]		/* move the return address */
-	mov	    [ecx], ebp		/* store ebp into local frame */
-	mov 	[ecx+4], eax	/* store retaddr into local frame */
-
-	/* New stack frame based off ebp.  This is a itty bit of unwind
-	   trickery in that the CFA *has* changed.  There is no easy way
-	   to describe it correctly on entry to the function.  Fortunately,
-	   it doesn't matter too much since at all points we can correctly
-	   unwind back to ffi_call.  Note that the location to which we
-	   moved the return address is (the new) CFA-4, so from the
-	   perspective of the unwind info, it hasn't moved.  */
-	mov 	ebp, ecx
-L(UW1):
-	// cfi_def_cfa(%ebp, 8)
-	// cfi_rel_offset(%ebp, 0)
-
-	mov 	esp, edx		/* set outgoing argument stack */
-	mov 	eax, [20+R_EAX*4+ebp]	/* set register arguments */
-	mov 	edx, [20+R_EDX*4+ebp]
-	mov	    ecx, [20+R_ECX*4+ebp]
-
-	call	dword ptr [ebp+8]
-
-	mov	    ecx, [12+ebp]		/* load return type code */
-	mov 	[ebp+8], ebx		/* preserve %ebx */
-L(UW2):
-	// cfi_rel_offset(%ebx, 8)
-
-	and 	ecx, X86_RET_TYPE_MASK
-	lea 	ebx, [L(store_table) + ecx * 8]
-	mov 	ecx, [ebp+16]		/* load result address */
-	jmp	    ebx
-
-	ALIGN	8
-L(store_table):
-E(L(store_table), X86_RET_FLOAT)
-	fstp	DWORD PTR [ecx]
-	jmp	L(e1)
-E(L(store_table), X86_RET_DOUBLE)
-	fstp	QWORD PTR [ecx]
-	jmp	L(e1)
-E(L(store_table), X86_RET_LDOUBLE)
-	fstp	QWORD PTR [ecx]
-	jmp	L(e1)
-E(L(store_table), X86_RET_SINT8)
-	movsx	eax, al
-	mov	[ecx], eax
-	jmp	L(e1)
-E(L(store_table), X86_RET_SINT16)
-	movsx	eax, ax
-	mov	[ecx], eax
-	jmp	L(e1)
-E(L(store_table), X86_RET_UINT8)
-	movzx	eax, al
-	mov	[ecx], eax
-	jmp	L(e1)
-E(L(store_table), X86_RET_UINT16)
-	movzx	eax, ax
-	mov	[ecx], eax
-	jmp	L(e1)
-E(L(store_table), X86_RET_INT64)
-	mov	[ecx+4], edx
-	/* fallthru */
-E(L(store_table), X86_RET_int 32)
-	mov	[ecx], eax
-	/* fallthru */
-E(L(store_table), X86_RET_VOID)
-L(e1):
-	mov	    ebx, [ebp+8]
-	mov	    esp, ebp
-	pop 	ebp
-L(UW3):
-	// cfi_remember_state
-	// cfi_def_cfa(%esp, 4)
-	// cfi_restore(%ebx)
-	// cfi_restore(%ebp)
-	ret
-L(UW4):
-	// cfi_restore_state
-
-E(L(store_table), X86_RET_STRUCTPOP)
-	jmp	    L(e1)
-E(L(store_table), X86_RET_STRUCTARG)
-	jmp	    L(e1)
-E(L(store_table), X86_RET_STRUCT_1B)
-	mov 	[ecx], al
-	jmp	    L(e1)
-E(L(store_table), X86_RET_STRUCT_2B)
-	mov 	[ecx], ax
-	jmp	    L(e1)
-
-	/* Fill out the table so that bad values are predictable.  */
-E(L(store_table), X86_RET_UNUSED14)
-	int 3
-E(L(store_table), X86_RET_UNUSED15)
-	int 3
-
-L(UW5):
-	// cfi_endproc
-ENDF(@ffi_call_i386@8)
-
-/* The inner helper is declared as
-
-   void ffi_closure_inner(struct closure_frame *frame, char *argp)
-	__attribute_((fastcall))
-
-   Thus the arguments are placed in
-
-	ecx:	frame
-	edx:	argp
-*/
-
-/* Macros to help setting up the closure_data structure.  */
-
-#if HAVE_FASTCALL
-# define closure_FS	(40 + 4)
-# define closure_CF	0
-#else
-# define closure_FS	(8 + 40 + 12)
-# define closure_CF	8
-#endif
-
-FFI_CLOSURE_SAVE_REGS MACRO
-	mov 	[esp + closure_CF+16+R_EAX*4], eax
-	mov 	[esp + closure_CF+16+R_EDX*4], edx
-	mov 	[esp + closure_CF+16+R_ECX*4], ecx
-ENDM
-
-FFI_CLOSURE_COPY_TRAMP_DATA MACRO
-	mov 	edx, [eax+FFI_TRAMPOLINE_SIZE]      /* copy cif */
-	mov 	ecx, [eax+FFI_TRAMPOLINE_SIZE+4]    /* copy fun */
-	mov 	eax, [eax+FFI_TRAMPOLINE_SIZE+8];   /* copy user_data */
-	mov 	[esp+closure_CF+28], edx
-	mov 	[esp+closure_CF+32], ecx
-	mov 	[esp+closure_CF+36], eax
-ENDM
-
-#if HAVE_FASTCALL
-FFI_CLOSURE_PREP_CALL MACRO
-	mov	    ecx, esp                    /* load closure_data */
-	lea 	edx, [esp+closure_FS+4]     /* load incoming stack */
-ENDM
-#else
-FFI_CLOSURE_PREP_CALL MACRO
-	lea 	ecx, [esp+closure_CF]       /* load closure_data */
-	lea 	edx, [esp+closure_FS+4]     /* load incoming stack */
-	mov 	[esp], ecx
-	mov 	[esp+4], edx
-ENDM
-#endif
-
-FFI_CLOSURE_CALL_INNER MACRO UWN
-	call	@ffi_closure_inner@8
-ENDM
-
-FFI_CLOSURE_MASK_AND_JUMP MACRO LABEL
-	and	    eax, X86_RET_TYPE_MASK
-	lea 	edx, [LABEL+eax*8]
-	mov 	eax, [esp+closure_CF]       /* optimiztic load */
-	jmp	    edx
-ENDM
-
-ALIGN 16
-PUBLIC ffi_go_closure_EAX
-ffi_go_closure_EAX PROC C
-L(UW6):
-	// cfi_startproc
-	sub	esp, closure_FS
-L(UW7):
-	// cfi_def_cfa_offset(closure_FS + 4)
-	FFI_CLOSURE_SAVE_REGS
-	mov     edx, [eax+4]			/* copy cif */
-	mov 	ecx, [eax +8]			/* copy fun */
-	mov 	[esp+closure_CF+28], edx
-	mov 	[esp+closure_CF+32], ecx
-	mov 	[esp+closure_CF+36], eax	/* closure is user_data */
-	jmp	L(do_closure_i386)
-L(UW8):
-	// cfi_endproc
-ENDF(ffi_go_closure_EAX)
-
-ALIGN 16
-PUBLIC ffi_go_closure_ECX
-ffi_go_closure_ECX PROC C
-L(UW9):
-	// cfi_startproc
-	sub 	esp, closure_FS
-L(UW10):
-	// cfi_def_cfa_offset(closure_FS + 4)
-	FFI_CLOSURE_SAVE_REGS
-	mov 	edx, [ecx+4]			/* copy cif */
-	mov 	eax, [ecx+8]			/* copy fun */
-	mov 	[esp+closure_CF+28], edx
-	mov 	[esp+closure_CF+32], eax
-	mov 	[esp+closure_CF+36], ecx	/* closure is user_data */
-	jmp	L(do_closure_i386)
-L(UW11):
-	// cfi_endproc
-ENDF(ffi_go_closure_ECX)
-
-/* The closure entry points are reached from the ffi_closure trampoline.
-   On entry, %eax contains the address of the ffi_closure.  */
-
-ALIGN 16
-PUBLIC ffi_closure_i386
-ffi_closure_i386 PROC C
-L(UW12):
-	// cfi_startproc
-	sub	    esp, closure_FS
-L(UW13):
-	// cfi_def_cfa_offset(closure_FS + 4)
-
-	FFI_CLOSURE_SAVE_REGS
-	FFI_CLOSURE_COPY_TRAMP_DATA
-
-	/* Entry point from preceeding Go closures.  */
-L(do_closure_i386)::
-
-	FFI_CLOSURE_PREP_CALL
-	FFI_CLOSURE_CALL_INNER(14)
-	FFI_CLOSURE_MASK_AND_JUMP L(C1(load_table,2))
-
-    ALIGN 8
-L(load_table2):
-E(L(load_table2), X86_RET_FLOAT)
-	fld 	dword ptr [esp+closure_CF]
-	jmp	L(e2)
-E(L(load_table2), X86_RET_DOUBLE)
-	fld 	qword ptr [esp+closure_CF]
-	jmp	L(e2)
-E(L(load_table2), X86_RET_LDOUBLE)
-	fld 	qword ptr [esp+closure_CF]
-	jmp	L(e2)
-E(L(load_table2), X86_RET_SINT8)
-	movsx	eax, al
-	jmp	L(e2)
-E(L(load_table2), X86_RET_SINT16)
-	movsx	eax, ax
-	jmp	L(e2)
-E(L(load_table2), X86_RET_UINT8)
-	movzx	eax, al
-	jmp	L(e2)
-E(L(load_table2), X86_RET_UINT16)
-	movzx	eax, ax
-	jmp	L(e2)
-E(L(load_table2), X86_RET_INT64)
-	mov 	edx, [esp+closure_CF+4]
-	jmp	L(e2)
-E(L(load_table2), X86_RET_INT32)
-	nop
-	/* fallthru */
-E(L(load_table2), X86_RET_VOID)
-L(e2):
-	add 	esp, closure_FS
-L(UW16):
-	// cfi_adjust_cfa_offset(-closure_FS)
-	ret
-L(UW17):
-	// cfi_adjust_cfa_offset(closure_FS)
-E(L(load_table2), X86_RET_STRUCTPOP)
-	add 	esp, closure_FS
-L(UW18):
-	// cfi_adjust_cfa_offset(-closure_FS)
-	ret	4
-L(UW19):
-	// cfi_adjust_cfa_offset(closure_FS)
-E(L(load_table2), X86_RET_STRUCTARG)
-	jmp	L(e2)
-E(L(load_table2), X86_RET_STRUCT_1B)
-	movzx	eax, al
-	jmp	L(e2)
-E(L(load_table2), X86_RET_STRUCT_2B)
-	movzx	eax, ax
-	jmp	L(e2)
-
-	/* Fill out the table so that bad values are predictable.  */
-E(L(load_table2), X86_RET_UNUSED14)
-	int 3
-E(L(load_table2), X86_RET_UNUSED15)
-	int 3
-
-L(UW20):
-	// cfi_endproc
-ENDF(ffi_closure_i386)
-
-ALIGN 16
-PUBLIC	ffi_go_closure_STDCALL
-ffi_go_closure_STDCALL PROC C
-L(UW21):
-	// cfi_startproc
-	sub 	esp, closure_FS
-L(UW22):
-	// cfi_def_cfa_offset(closure_FS + 4)
-	FFI_CLOSURE_SAVE_REGS
-	mov 	edx, [ecx+4]			/* copy cif */
-	mov 	eax, [ecx+8]			/* copy fun */
-	mov 	[esp+closure_CF+28], edx
-	mov 	[esp+closure_CF+32], eax
-	mov 	[esp+closure_CF+36], ecx	/* closure is user_data */
-	jmp	L(do_closure_STDCALL)
-L(UW23):
-	// cfi_endproc
-ENDF(ffi_go_closure_STDCALL)
-
-/* For REGISTER, we have no available parameter registers, and so we
-   enter here having pushed the closure onto the stack.  */
-
-ALIGN 16
-PUBLIC ffi_closure_REGISTER
-ffi_closure_REGISTER PROC C
-L(UW24):
-	// cfi_startproc
-	// cfi_def_cfa(%esp, 8)
-	// cfi_offset(%eip, -8)
-	sub 	esp, closure_FS-4
-L(UW25):
-	// cfi_def_cfa_offset(closure_FS + 4)
-	FFI_CLOSURE_SAVE_REGS
-	mov	ecx, [esp+closure_FS-4] 	/* load retaddr */
-	mov	eax, [esp+closure_FS]		/* load closure */
-	mov	[esp+closure_FS], ecx		/* move retaddr */
-	jmp	L(do_closure_REGISTER)
-L(UW26):
-	// cfi_endproc
-ENDF(ffi_closure_REGISTER)
-
-/* For STDCALL (and others), we need to pop N bytes of arguments off
-   the stack following the closure.  The amount needing to be popped
-   is returned to us from ffi_closure_inner.  */
-
-ALIGN 16
-PUBLIC ffi_closure_STDCALL
-ffi_closure_STDCALL PROC C
-L(UW27):
-	// cfi_startproc
-	sub 	esp, closure_FS
-L(UW28):
-	// cfi_def_cfa_offset(closure_FS + 4)
-
-	FFI_CLOSURE_SAVE_REGS
-
-	/* Entry point from ffi_closure_REGISTER.  */
-L(do_closure_REGISTER)::
-
-	FFI_CLOSURE_COPY_TRAMP_DATA
-
-	/* Entry point from preceeding Go closure.  */
-L(do_closure_STDCALL)::
-
-	FFI_CLOSURE_PREP_CALL
-	FFI_CLOSURE_CALL_INNER(29)
-
-	mov 	ecx, eax
-	shr 	ecx, X86_RET_POP_SHIFT	    /* isolate pop count */
-	lea 	ecx, [esp+closure_FS+ecx]	/* compute popped esp */
-	mov 	edx, [esp+closure_FS]		/* move return address */
-	mov 	[ecx], edx
-
-	/* From this point on, the value of %esp upon return is %ecx+4,
-	   and we've copied the return address to %ecx to make return easy.
-	   There's no point in representing this in the unwind info, as
-	   there is always a window between the mov and the ret which
-	   will be wrong from one point of view or another.  */
-
-	FFI_CLOSURE_MASK_AND_JUMP  L(C1(load_table,3))
-
-    ALIGN 8
-L(load_table3):
-E(L(load_table3), X86_RET_FLOAT)
-	fld    DWORD PTR [esp+closure_CF]
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_DOUBLE)
-	fld    QWORD PTR [esp+closure_CF]
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_LDOUBLE)
-	fld    QWORD PTR [esp+closure_CF]
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_SINT8)
-	movsx   eax, al
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_SINT16)
-	movsx   eax, ax
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_UINT8)
-	movzx   eax, al
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_UINT16)
-	movzx   eax, ax
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_INT64)
-	mov 	edx, [esp+closure_CF+4]
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_int 32)
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_VOID)
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_STRUCTPOP)
-	mov     esp, ecx
-	ret
-E(L(load_table3), X86_RET_STRUCTARG)
-	mov 	esp, ecx
-	ret
-E(L(load_table3), X86_RET_STRUCT_1B)
-	movzx	eax, al
-	mov 	esp, ecx
-	ret
-E(L(load_table3), X86_RET_STRUCT_2B)
-	movzx	eax, ax
-	mov 	esp, ecx
-	ret
-
-	/* Fill out the table so that bad values are predictable.  */
-E(L(load_table3), X86_RET_UNUSED14)
-	int 3
-E(L(load_table3), X86_RET_UNUSED15)
-	int 3
-
-L(UW31):
-	// cfi_endproc
-ENDF(ffi_closure_STDCALL)
-
-#if !FFI_NO_RAW_API
-
-#define raw_closure_S_FS	(16+16+12)
-
-ALIGN 16
-PUBLIC ffi_closure_raw_SYSV
-ffi_closure_raw_SYSV PROC C
-L(UW32):
-	// cfi_startproc
-	sub 	esp, raw_closure_S_FS
-L(UW33):
-	// cfi_def_cfa_offset(raw_closure_S_FS + 4)
-	mov 	[esp+raw_closure_S_FS-4], ebx
-L(UW34):
-	// cfi_rel_offset(%ebx, raw_closure_S_FS-4)
-
-	mov 	edx, [eax+FFI_TRAMPOLINE_SIZE+8]	/* load cl->user_data */
-	mov 	[esp+12], edx
-	lea 	edx, [esp+raw_closure_S_FS+4]		/* load raw_args */
-	mov 	[esp+8], edx
-	lea 	edx, [esp+16]				/* load &res */
-	mov 	[esp+4], edx
-	mov 	ebx, [eax+FFI_TRAMPOLINE_SIZE]		/* load cl->cif */
-	mov 	[esp], ebx
-	call	DWORD PTR [eax+FFI_TRAMPOLINE_SIZE+4]		/* call cl->fun */
-
-	mov 	eax, [ebx+20]			/* load cif->flags */
-	and 	eax, X86_RET_TYPE_MASK
-// #ifdef __PIC__
-// 	call	__x86.get_pc_thunk.bx
-// L(pc4):
-// 	lea 	ecx, L(load_table4)-L(pc4)(%ebx, %eax, 8), %ecx
-// #else
-	lea 	ecx, [L(load_table4)+eax+8]
-// #endif
-	mov 	ebx, [esp+raw_closure_S_FS-4]
-L(UW35):
-	// cfi_restore(%ebx)
-	mov 	eax, [esp+16]				/* Optimistic load */
-	jmp	    dword ptr [ecx]
-
-	ALIGN 8
-L(load_table4):
-E(L(load_table4), X86_RET_FLOAT)
-	fld 	DWORD PTR [esp +16]
-	jmp	L(e4)
-E(L(load_table4), X86_RET_DOUBLE)
-	fld 	QWORD PTR [esp +16]
-	jmp	L(e4)
-E(L(load_table4), X86_RET_LDOUBLE)
-	fld 	QWORD PTR [esp +16]
-	jmp	L(e4)
-E(L(load_table4), X86_RET_SINT8)
-	movsx	eax, al
-	jmp	L(e4)
-E(L(load_table4), X86_RET_SINT16)
-	movsx	eax, ax
-	jmp	L(e4)
-E(L(load_table4), X86_RET_UINT8)
-	movzx	eax, al
-	jmp	L(e4)
-E(L(load_table4), X86_RET_UINT16)
-	movzx	eax, ax
-	jmp	L(e4)
-E(L(load_table4), X86_RET_INT64)
-	mov 	edx, [esp+16+4]
-	jmp	L(e4)
-E(L(load_table4), X86_RET_int 32)
-	nop
-	/* fallthru */
-E(L(load_table4), X86_RET_VOID)
-L(e4):
-	add 	esp, raw_closure_S_FS
-L(UW36):
-	// cfi_adjust_cfa_offset(-raw_closure_S_FS)
-	ret
-L(UW37):
-	// cfi_adjust_cfa_offset(raw_closure_S_FS)
-E(L(load_table4), X86_RET_STRUCTPOP)
-	add 	esp, raw_closure_S_FS
-L(UW38):
-	// cfi_adjust_cfa_offset(-raw_closure_S_FS)
-	ret	4
-L(UW39):
-	// cfi_adjust_cfa_offset(raw_closure_S_FS)
-E(L(load_table4), X86_RET_STRUCTARG)
-	jmp	L(e4)
-E(L(load_table4), X86_RET_STRUCT_1B)
-	movzx	eax, al
-	jmp	L(e4)
-E(L(load_table4), X86_RET_STRUCT_2B)
-	movzx	eax, ax
-	jmp	L(e4)
-
-	/* Fill out the table so that bad values are predictable.  */
-E(L(load_table4), X86_RET_UNUSED14)
-	int 3
-E(L(load_table4), X86_RET_UNUSED15)
-	int 3
-
-L(UW40):
-	// cfi_endproc
-ENDF(ffi_closure_raw_SYSV)
-
-#define raw_closure_T_FS	(16+16+8)
-
-ALIGN 16
-PUBLIC ffi_closure_raw_THISCALL
-ffi_closure_raw_THISCALL PROC C
-L(UW41):
-	// cfi_startproc
-	/* Rearrange the stack such that %ecx is the first argument.
-	   This means moving the return address.  */
-	pop 	edx
-L(UW42):
-	// cfi_def_cfa_offset(0)
-	// cfi_register(%eip, %edx)
-	push	ecx
-L(UW43):
-	// cfi_adjust_cfa_offset(4)
-	push 	edx
-L(UW44):
-	// cfi_adjust_cfa_offset(4)
-	// cfi_rel_offset(%eip, 0)
-	sub 	esp, raw_closure_T_FS
-L(UW45):
-	// cfi_adjust_cfa_offset(raw_closure_T_FS)
-	mov 	[esp+raw_closure_T_FS-4], ebx
-L(UW46):
-	// cfi_rel_offset(%ebx, raw_closure_T_FS-4)
-
-	mov 	edx, [eax+FFI_TRAMPOLINE_SIZE+8]	/* load cl->user_data */
-	mov 	[esp+12], edx
-	lea 	edx, [esp+raw_closure_T_FS+4]		/* load raw_args */
-	mov 	[esp+8], edx
-	lea 	edx, [esp+16]				/* load &res */
-	mov 	[esp+4], edx
-	mov 	ebx, [eax+FFI_TRAMPOLINE_SIZE]		/* load cl->cif */
-	mov 	[esp], ebx
-	call	DWORD PTR [eax+FFI_TRAMPOLINE_SIZE+4]		/* call cl->fun */
-
-	mov 	eax, [ebx+20]				/* load cif->flags */
-	and 	eax, X86_RET_TYPE_MASK
-// #ifdef __PIC__
-// 	call	__x86.get_pc_thunk.bx
-// L(pc5):
-// 	leal	L(load_table5)-L(pc5)(%ebx, %eax, 8), %ecx
-// #else
-	lea 	ecx, [L(load_table5)+eax*8]
-//#endif
-	mov 	ebx, [esp+raw_closure_T_FS-4]
-L(UW47):
-	// cfi_restore(%ebx)
-	mov 	eax, [esp+16]				/* Optimistic load */
-	jmp	    DWORD PTR [ecx]
-
-	AlIGN 4
-L(load_table5):
-E(L(load_table5), X86_RET_FLOAT)
-	fld	DWORD PTR [esp +16]
-	jmp	L(e5)
-E(L(load_table5), X86_RET_DOUBLE)
-	fld	QWORD PTR [esp +16]
-	jmp	L(e5)
-E(L(load_table5), X86_RET_LDOUBLE)
-	fld	QWORD PTR [esp+16]
-	jmp	L(e5)
-E(L(load_table5), X86_RET_SINT8)
-	movsx	eax, al
-	jmp	L(e5)
-E(L(load_table5), X86_RET_SINT16)
-	movsx	eax, ax
-	jmp	L(e5)
-E(L(load_table5), X86_RET_UINT8)
-	movzx	eax, al
-	jmp	L(e5)
-E(L(load_table5), X86_RET_UINT16)
-	movzx	eax, ax
-	jmp	L(e5)
-E(L(load_table5), X86_RET_INT64)
-	mov 	edx, [esp+16+4]
-	jmp	L(e5)
-E(L(load_table5), X86_RET_int 32)
-	nop
-	/* fallthru */
-E(L(load_table5), X86_RET_VOID)
-L(e5):
-	add 	esp, raw_closure_T_FS
-L(UW48):
-	// cfi_adjust_cfa_offset(-raw_closure_T_FS)
-	/* Remove the extra %ecx argument we pushed.  */
-	ret	4
-L(UW49):
-	// cfi_adjust_cfa_offset(raw_closure_T_FS)
-E(L(load_table5), X86_RET_STRUCTPOP)
-	add 	esp, raw_closure_T_FS
-L(UW50):
-	// cfi_adjust_cfa_offset(-raw_closure_T_FS)
-	ret	8
-L(UW51):
-	// cfi_adjust_cfa_offset(raw_closure_T_FS)
-E(L(load_table5), X86_RET_STRUCTARG)
-	jmp	L(e5)
-E(L(load_table5), X86_RET_STRUCT_1B)
-	movzx	eax, al
-	jmp	L(e5)
-E(L(load_table5), X86_RET_STRUCT_2B)
-	movzx	eax, ax
-	jmp	L(e5)
-
-	/* Fill out the table so that bad values are predictable.  */
-E(L(load_table5), X86_RET_UNUSED14)
-	int 3
-E(L(load_table5), X86_RET_UNUSED15)
-	int 3
-
-L(UW52):
-	// cfi_endproc
-ENDF(ffi_closure_raw_THISCALL)
-
-#endif /* !FFI_NO_RAW_API */
-
-#ifdef X86_DARWIN
-# define COMDAT(X)							\
-        .section __TEXT,__text,coalesced,pure_instructions;		\
-        .weak_definition X;						\
-        FFI_HIDDEN(X)
-#elif defined __ELF__ && !(defined(__sun__) && defined(__svr4__))
-# define COMDAT(X)							\
-	.section .text.X,"axG",@progbits,X,comdat;			\
-	PUBLIC	X;							\
-	FFI_HIDDEN(X)
-#else
-# define COMDAT(X)
-#endif
-
-// #if defined(__PIC__)
-// 	COMDAT(C(__x86.get_pc_thunk.bx))
-// C(__x86.get_pc_thunk.bx):
-// 	movl	(%esp), %ebx
-// 	ret
-// ENDF(C(__x86.get_pc_thunk.bx))
-// # if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
-// 	COMDAT(C(__x86.get_pc_thunk.dx))
-// C(__x86.get_pc_thunk.dx):
-// 	movl	(%esp), %edx
-// 	ret
-// ENDF(C(__x86.get_pc_thunk.dx))
-// #endif /* DARWIN || HIDDEN */
-// #endif /* __PIC__ */
-
-#if 0
-/* Sadly, OSX cctools-as doesn't understand .cfi directives at all.  */
-
-#ifdef __APPLE__
-.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
-EHFrame0:
-#elif defined(X86_WIN32)
-.section .eh_frame,"r"
-#elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)
-.section .eh_frame,EH_FRAME_FLAGS,@unwind
-#else
-.section .eh_frame,EH_FRAME_FLAGS,@progbits
-#endif
-
-#ifdef HAVE_AS_X86_PCREL
-# define PCREL(X)	X - .
-#else
-# define PCREL(X)	X@rel
-#endif
-
-/* Simplify advancing between labels.  Assume DW_CFA_advance_loc1 fits.  */
-#define ADV(N, P)	.byte 2, L(N)-L(P)
-
-	.balign 4
-L(CIE):
-	.set	L(set0),L(ECIE)-L(SCIE)
-	.long	L(set0)			/* CIE Length */
-L(SCIE):
-	.long	0			/* CIE Identifier Tag */
-	.byte	1			/* CIE Version */
-	.ascii	"zR\0"			/* CIE Augmentation */
-	.byte	1			/* CIE Code Alignment Factor */
-	.byte	0x7c			/* CIE Data Alignment Factor */
-	.byte	0x8			/* CIE RA Column */
-	.byte	1			/* Augmentation size */
-	.byte	0x1b			/* FDE Encoding (pcrel sdata4) */
-	.byte	0xc, 4, 4		/* DW_CFA_def_cfa, %esp offset 4 */
-	.byte	0x80+8, 1		/* DW_CFA_offset, %eip offset 1*-4 */
-	.balign 4
-L(ECIE):
-
-	.set	L(set1),L(EFDE1)-L(SFDE1)
-	.long	L(set1)			/* FDE Length */
-L(SFDE1):
-	.long	L(SFDE1)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW0))		/* Initial location */
-	.long	L(UW5)-L(UW0)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW1, UW0)
-	.byte	0xc, 5, 8		/* DW_CFA_def_cfa, %ebp 8 */
-	.byte	0x80+5, 2		/* DW_CFA_offset, %ebp 2*-4 */
-	ADV(UW2, UW1)
-	.byte	0x80+3, 0		/* DW_CFA_offset, %ebx 0*-4 */
-	ADV(UW3, UW2)
-	.byte	0xa			/* DW_CFA_remember_state */
-	.byte	0xc, 4, 4		/* DW_CFA_def_cfa, %esp 4 */
-	.byte	0xc0+3			/* DW_CFA_restore, %ebx */
-	.byte	0xc0+5			/* DW_CFA_restore, %ebp */
-	ADV(UW4, UW3)
-	.byte	0xb			/* DW_CFA_restore_state */
-	.balign	4
-L(EFDE1):
-
-	.set	L(set2),L(EFDE2)-L(SFDE2)
-	.long	L(set2)			/* FDE Length */
-L(SFDE2):
-	.long	L(SFDE2)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW6))		/* Initial location */
-	.long	L(UW8)-L(UW6)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW7, UW6)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE2):
-
-	.set	L(set3),L(EFDE3)-L(SFDE3)
-	.long	L(set3)			/* FDE Length */
-L(SFDE3):
-	.long	L(SFDE3)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW9))		/* Initial location */
-	.long	L(UW11)-L(UW9)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW10, UW9)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE3):
-
-	.set	L(set4),L(EFDE4)-L(SFDE4)
-	.long	L(set4)			/* FDE Length */
-L(SFDE4):
-	.long	L(SFDE4)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW12))		/* Initial location */
-	.long	L(UW20)-L(UW12)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW13, UW12)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX
-	ADV(UW14, UW13)
-	.byte	0x80+3, (40-(closure_FS+4))/-4  /* DW_CFA_offset %ebx */
-	ADV(UW15, UW14)
-	.byte	0xc0+3			/* DW_CFA_restore %ebx */
-	ADV(UW16, UW15)
-#else
-	ADV(UW16, UW13)
-#endif
-	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
-	ADV(UW17, UW16)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	ADV(UW18, UW17)
-	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
-	ADV(UW19, UW18)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE4):
-
-	.set	L(set5),L(EFDE5)-L(SFDE5)
-	.long	L(set5)			/* FDE Length */
-L(SFDE5):
-	.long	L(SFDE5)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW21))		/* Initial location */
-	.long	L(UW23)-L(UW21)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW22, UW21)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE5):
-
-	.set	L(set6),L(EFDE6)-L(SFDE6)
-	.long	L(set6)			/* FDE Length */
-L(SFDE6):
-	.long	L(SFDE6)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW24))		/* Initial location */
-	.long	L(UW26)-L(UW24)		/* Address range */
-	.byte	0			/* Augmentation size */
-	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
-	.byte	0x80+8, 2		/* DW_CFA_offset %eip, 2*-4 */
-	ADV(UW25, UW24)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE6):
-
-	.set	L(set7),L(EFDE7)-L(SFDE7)
-	.long	L(set7)			/* FDE Length */
-L(SFDE7):
-	.long	L(SFDE7)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW27))		/* Initial location */
-	.long	L(UW31)-L(UW27)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW28, UW27)
-	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */
-#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX
-	ADV(UW29, UW28)
-	.byte	0x80+3, (40-(closure_FS+4))/-4  /* DW_CFA_offset %ebx */
-	ADV(UW30, UW29)
-	.byte	0xc0+3			/* DW_CFA_restore %ebx */
-#endif
-	.balign	4
-L(EFDE7):
-
-#if !FFI_NO_RAW_API
-	.set	L(set8),L(EFDE8)-L(SFDE8)
-	.long	L(set8)			/* FDE Length */
-L(SFDE8):
-	.long	L(SFDE8)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW32))		/* Initial location */
-	.long	L(UW40)-L(UW32)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW33, UW32)
-	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */
-	ADV(UW34, UW33)
-	.byte	0x80+3, 2		/* DW_CFA_offset %ebx 2*-4 */
-	ADV(UW35, UW34)
-	.byte	0xc0+3			/* DW_CFA_restore %ebx */
-	ADV(UW36, UW35)
-	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
-	ADV(UW37, UW36)
-	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */
-	ADV(UW38, UW37)
-	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
-	ADV(UW39, UW38)
-	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE8):
-
-	.set	L(set9),L(EFDE9)-L(SFDE9)
-	.long	L(set9)			/* FDE Length */
-L(SFDE9):
-	.long	L(SFDE9)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW41))		/* Initial location */
-	.long	L(UW52)-L(UW41)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW42, UW41)
-	.byte	0xe, 0			/* DW_CFA_def_cfa_offset */
-	.byte	0x9, 8, 2		/* DW_CFA_register %eip, %edx */
-	ADV(UW43, UW42)
-	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */
-	ADV(UW44, UW43)
-	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
-	.byte	0x80+8, 2		/* DW_CFA_offset %eip 2*-4 */
-	ADV(UW45, UW44)
-	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */
-	ADV(UW46, UW45)
-	.byte	0x80+3, 3		/* DW_CFA_offset %ebx 3*-4 */
-	ADV(UW47, UW46)
-	.byte	0xc0+3			/* DW_CFA_restore %ebx */
-	ADV(UW48, UW47)
-	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
-	ADV(UW49, UW48)
-	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */
-	ADV(UW50, UW49)
-	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */
-	ADV(UW51, UW50)
-	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */
-	.balign	4
-L(EFDE9):
-#endif /* !FFI_NO_RAW_API */
-
-#ifdef _WIN32
-	.def	 @feat.00;
-	.scl	3;
-	.type	0;
-	.endef
-	PUBLIC	@feat.00
-@feat.00 = 1
-#endif
-
-#endif /* ifndef _MSC_VER */
-#endif /* ifndef __x86_64__ */
-
-#if defined __ELF__ && defined __linux__
-	.section	.note.GNU-stack,"",@progbits
-#endif
-#endif
-
-END
\ No newline at end of file
diff --git a/src/x86/unix64.S b/src/x86/unix64.S
index 41563f5..dcd6bc7 100644
--- a/src/x86/unix64.S
+++ b/src/x86/unix64.S
@@ -30,20 +30,8 @@
 #define LIBFFI_ASM	
 #include <fficonfig.h>
 #include <ffi.h>
-#include "internal64.h"
-#include "asmnames.h"
 
-	.text
-
-/* This macro allows the safe creation of jump tables without an
-   actual table.  The entry points into the table are all 8 bytes.
-   The use of ORG asserts that we're at the correct location.  */
-/* ??? The clang assembler doesn't handle .org with symbolic expressions.  */
-#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
-# define E(BASE, X)	.balign 8
-#else
-# define E(BASE, X)	.balign 8; .org BASE + X * 8
-#endif
+.text
 
 /* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
 	            void *raddr, void (*fnaddr)(void));
@@ -52,12 +40,12 @@
    for this function.  This has been allocated by ffi_call.  We also
    deallocate some of the stack that has been alloca'd.  */
 
-	.balign	8
-	.globl	C(ffi_call_unix64)
-	FFI_HIDDEN(C(ffi_call_unix64))
+	.align	2
+	.globl	ffi_call_unix64
+	.type	ffi_call_unix64,@function
 
-C(ffi_call_unix64):
-L(UW0):
+ffi_call_unix64:
+.LUW0:
 	movq	(%rsp), %r10		/* Load return address.  */
 	leaq	(%rdi, %rsi), %rax	/* Find local stack base.  */
 	movq	%rdx, (%rax)		/* Save flags.  */
@@ -65,37 +53,24 @@
 	movq	%rbp, 16(%rax)		/* Save old frame pointer.  */
 	movq	%r10, 24(%rax)		/* Relocate return address.  */
 	movq	%rax, %rbp		/* Finalize local stack frame.  */
-
-	/* New stack frame based off rbp.  This is a itty bit of unwind
-	   trickery in that the CFA *has* changed.  There is no easy way
-	   to describe it correctly on entry to the function.  Fortunately,
-	   it doesn't matter too much since at all points we can correctly
-	   unwind back to ffi_call.  Note that the location to which we
-	   moved the return address is (the new) CFA-8, so from the
-	   perspective of the unwind info, it hasn't moved.  */
-L(UW1):
-	/* cfi_def_cfa(%rbp, 32) */
-	/* cfi_rel_offset(%rbp, 16) */
-
+.LUW1:
 	movq	%rdi, %r10		/* Save a copy of the register area. */
 	movq	%r8, %r11		/* Save a copy of the target fn.  */
 	movl	%r9d, %eax		/* Set number of SSE registers.  */
 
 	/* Load up all argument registers.  */
 	movq	(%r10), %rdi
-	movq	0x08(%r10), %rsi
-	movq	0x10(%r10), %rdx
-	movq	0x18(%r10), %rcx
-	movq	0x20(%r10), %r8
-	movq	0x28(%r10), %r9
-	movl	0xb0(%r10), %eax
+	movq	8(%r10), %rsi
+	movq	16(%r10), %rdx
+	movq	24(%r10), %rcx
+	movq	32(%r10), %r8
+	movq	40(%r10), %r9
 	testl	%eax, %eax
-	jnz	L(load_sse)
-L(ret_from_load_sse):
+	jnz	.Lload_sse
+.Lret_from_load_sse:
 
-	/* Deallocate the reg arg area, except for r10, then load via pop.  */
-	leaq	0xb8(%r10), %rsp
-	popq	%r10
+	/* Deallocate the reg arg area.  */
+	leaq	176(%r10), %rsp
 
 	/* Call the user function.  */
 	call	*%r11
@@ -106,461 +81,352 @@
 	movq	0(%rbp), %rcx		/* Reload flags.  */
 	movq	8(%rbp), %rdi		/* Reload raddr.  */
 	movq	16(%rbp), %rbp		/* Reload old frame pointer.  */
-L(UW2):
-	/* cfi_remember_state */
-	/* cfi_def_cfa(%rsp, 8) */
-	/* cfi_restore(%rbp) */
+.LUW2:
 
 	/* The first byte of the flags contains the FFI_TYPE.  */
-	cmpb	$UNIX64_RET_LAST, %cl
 	movzbl	%cl, %r10d
-	leaq	L(store_table)(%rip), %r11
-	ja	L(sa)
-	leaq	(%r11, %r10, 8), %r10
-
-	/* Prep for the structure cases: scratch area in redzone.  */
-	leaq	-20(%rsp), %rsi
+	leaq	.Lstore_table(%rip), %r11
+	movslq	(%r11, %r10, 4), %r10
+	addq	%r11, %r10
 	jmp	*%r10
 
-	.balign	8
-L(store_table):
-E(L(store_table), UNIX64_RET_VOID)
+.Lstore_table:
+	.long	.Lst_void-.Lstore_table		/* FFI_TYPE_VOID */
+	.long	.Lst_sint32-.Lstore_table	/* FFI_TYPE_INT */
+	.long	.Lst_float-.Lstore_table	/* FFI_TYPE_FLOAT */
+	.long	.Lst_double-.Lstore_table	/* FFI_TYPE_DOUBLE */
+	.long	.Lst_ldouble-.Lstore_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	.Lst_uint8-.Lstore_table	/* FFI_TYPE_UINT8 */
+	.long	.Lst_sint8-.Lstore_table	/* FFI_TYPE_SINT8 */
+	.long	.Lst_uint16-.Lstore_table	/* FFI_TYPE_UINT16 */
+	.long	.Lst_sint16-.Lstore_table	/* FFI_TYPE_SINT16 */
+	.long	.Lst_uint32-.Lstore_table	/* FFI_TYPE_UINT32 */
+	.long	.Lst_sint32-.Lstore_table	/* FFI_TYPE_SINT32 */
+	.long	.Lst_int64-.Lstore_table	/* FFI_TYPE_UINT64 */
+	.long	.Lst_int64-.Lstore_table	/* FFI_TYPE_SINT64 */
+	.long	.Lst_struct-.Lstore_table	/* FFI_TYPE_STRUCT */
+	.long	.Lst_int64-.Lstore_table	/* FFI_TYPE_POINTER */
+
+	.align 2
+.Lst_void:
 	ret
-E(L(store_table), UNIX64_RET_UINT8)
-	movzbl	%al, %eax
+	.align 2
+
+.Lst_uint8:
+	movzbq	%al, %rax
 	movq	%rax, (%rdi)
 	ret
-E(L(store_table), UNIX64_RET_UINT16)
-	movzwl	%ax, %eax
-	movq	%rax, (%rdi)
-	ret
-E(L(store_table), UNIX64_RET_UINT32)
-	movl	%eax, %eax
-	movq	%rax, (%rdi)
-	ret
-E(L(store_table), UNIX64_RET_SINT8)
+	.align 2
+.Lst_sint8:
 	movsbq	%al, %rax
 	movq	%rax, (%rdi)
 	ret
-E(L(store_table), UNIX64_RET_SINT16)
+	.align 2
+.Lst_uint16:
+	movzwq	%ax, %rax
+	movq	%rax, (%rdi)
+	.align 2
+.Lst_sint16:
 	movswq	%ax, %rax
 	movq	%rax, (%rdi)
 	ret
-E(L(store_table), UNIX64_RET_SINT32)
+	.align 2
+.Lst_uint32:
+	movl	%eax, %eax
+	movq	%rax, (%rdi)
+	.align 2
+.Lst_sint32:
 	cltq
 	movq	%rax, (%rdi)
 	ret
-E(L(store_table), UNIX64_RET_INT64)
+	.align 2
+.Lst_int64:
 	movq	%rax, (%rdi)
 	ret
-E(L(store_table), UNIX64_RET_XMM32)
-	movd	%xmm0, (%rdi)
+
+	.align 2
+.Lst_float:
+	movss	%xmm0, (%rdi)
 	ret
-E(L(store_table), UNIX64_RET_XMM64)
-	movq	%xmm0, (%rdi)
+	.align 2
+.Lst_double:
+	movsd	%xmm0, (%rdi)
 	ret
-E(L(store_table), UNIX64_RET_X87)
+.Lst_ldouble:
 	fstpt	(%rdi)
 	ret
-E(L(store_table), UNIX64_RET_X87_2)
-	fstpt	(%rdi)
-	fstpt	16(%rdi)
-	ret
-E(L(store_table), UNIX64_RET_ST_XMM0_RAX)
-	movq	%rax, 8(%rsi)
-	jmp	L(s3)
-E(L(store_table), UNIX64_RET_ST_RAX_XMM0)
-	movq	%xmm0, 8(%rsi)
-	jmp	L(s2)
-E(L(store_table), UNIX64_RET_ST_XMM0_XMM1)
-	movq	%xmm1, 8(%rsi)
-	jmp	L(s3)
-E(L(store_table), UNIX64_RET_ST_RAX_RDX)
-	movq	%rdx, 8(%rsi)
-L(s2):
-	movq	%rax, (%rsi)
-	shrl	$UNIX64_SIZE_SHIFT, %ecx
-	rep movsb
-	ret
-	.balign 8
-L(s3):
-	movq	%xmm0, (%rsi)
-	shrl	$UNIX64_SIZE_SHIFT, %ecx
-	rep movsb
-	ret
 
-L(sa):	call	PLT(C(abort))
+	.align 2
+.Lst_struct:
+	leaq	-20(%rsp), %rsi		/* Scratch area in redzone.  */
+
+	/* We have to locate the values now, and since we don't want to
+	   write too much data into the user's return value, we spill the
+	   value to a 16 byte scratch area first.  Bits 8, 9, and 10
+	   control where the values are located.  Only one of the three
+	   bits will be set; see ffi_prep_cif_machdep for the pattern.  */
+	movd	%xmm0, %r10
+	movd	%xmm1, %r11
+	testl	$0x100, %ecx
+	cmovnz	%rax, %rdx
+	cmovnz	%r10, %rax
+	testl	$0x200, %ecx
+	cmovnz	%r10, %rdx
+	testl	$0x400, %ecx
+	cmovnz	%r10, %rax
+	cmovnz	%r11, %rdx
+	movq	%rax, (%rsi)
+	movq	%rdx, 8(%rsi)
+
+	/* Bits 12-31 contain the true size of the structure.  Copy from
+	   the scratch area to the true destination.  */
+	shrl	$12, %ecx
+	rep movsb
+	ret
 
 	/* Many times we can avoid loading any SSE registers at all.
 	   It's not worth an indirect jump to load the exact set of
 	   SSE registers needed; zero or all is a good compromise.  */
-	.balign 2
-L(UW3):
-	/* cfi_restore_state */
-L(load_sse):
-	movdqa	0x30(%r10), %xmm0
-	movdqa	0x40(%r10), %xmm1
-	movdqa	0x50(%r10), %xmm2
-	movdqa	0x60(%r10), %xmm3
-	movdqa	0x70(%r10), %xmm4
-	movdqa	0x80(%r10), %xmm5
-	movdqa	0x90(%r10), %xmm6
-	movdqa	0xa0(%r10), %xmm7
-	jmp	L(ret_from_load_sse)
+	.align 2
+.LUW3:
+.Lload_sse:
+	movdqa	48(%r10), %xmm0
+	movdqa	64(%r10), %xmm1
+	movdqa	80(%r10), %xmm2
+	movdqa	96(%r10), %xmm3
+	movdqa	112(%r10), %xmm4
+	movdqa	128(%r10), %xmm5
+	movdqa	144(%r10), %xmm6
+	movdqa	160(%r10), %xmm7
+	jmp	.Lret_from_load_sse
 
-L(UW4):
-ENDF(C(ffi_call_unix64))
+.LUW4:
+	.size    ffi_call_unix64,.-ffi_call_unix64
 
-/* 6 general registers, 8 vector registers,
-   32 bytes of rvalue, 8 bytes of alignment.  */
-#define ffi_closure_OFS_G	0
-#define ffi_closure_OFS_V	(6*8)
-#define ffi_closure_OFS_RVALUE	(ffi_closure_OFS_V + 8*16)
-#define ffi_closure_FS		(ffi_closure_OFS_RVALUE + 32 + 8)
+	.align	2
+	.globl ffi_closure_unix64
+	.type	ffi_closure_unix64,@function
 
-/* The location of rvalue within the red zone after deallocating the frame.  */
-#define ffi_closure_RED_RVALUE	(ffi_closure_OFS_RVALUE - ffi_closure_FS)
+ffi_closure_unix64:
+.LUW5:
+	/* The carry flag is set by the trampoline iff SSE registers
+	   are used.  Don't clobber it before the branch instruction.  */
+	leaq    -200(%rsp), %rsp
+.LUW6:
+	movq	%rdi, (%rsp)
+	movq    %rsi, 8(%rsp)
+	movq    %rdx, 16(%rsp)
+	movq    %rcx, 24(%rsp)
+	movq    %r8, 32(%rsp)
+	movq    %r9, 40(%rsp)
+	jc      .Lsave_sse
+.Lret_from_save_sse:
 
-	.balign	2
-	.globl	C(ffi_closure_unix64_sse)
-	FFI_HIDDEN(C(ffi_closure_unix64_sse))
-
-C(ffi_closure_unix64_sse):
-L(UW5):
-	subq	$ffi_closure_FS, %rsp
-L(UW6):
-	/* cfi_adjust_cfa_offset(ffi_closure_FS) */
-
-	movdqa	%xmm0, ffi_closure_OFS_V+0x00(%rsp)
-	movdqa	%xmm1, ffi_closure_OFS_V+0x10(%rsp)
-	movdqa	%xmm2, ffi_closure_OFS_V+0x20(%rsp)
-	movdqa	%xmm3, ffi_closure_OFS_V+0x30(%rsp)
-	movdqa	%xmm4, ffi_closure_OFS_V+0x40(%rsp)
-	movdqa	%xmm5, ffi_closure_OFS_V+0x50(%rsp)
-	movdqa	%xmm6, ffi_closure_OFS_V+0x60(%rsp)
-	movdqa	%xmm7, ffi_closure_OFS_V+0x70(%rsp)
-	jmp	L(sse_entry1)
-
-L(UW7):
-ENDF(C(ffi_closure_unix64_sse))
-
-	.balign	2
-	.globl	C(ffi_closure_unix64)
-	FFI_HIDDEN(C(ffi_closure_unix64))
-
-C(ffi_closure_unix64):
-L(UW8):
-	subq	$ffi_closure_FS, %rsp
-L(UW9):
-	/* cfi_adjust_cfa_offset(ffi_closure_FS) */
-L(sse_entry1):
-	movq	%rdi, ffi_closure_OFS_G+0x00(%rsp)
-	movq    %rsi, ffi_closure_OFS_G+0x08(%rsp)
-	movq    %rdx, ffi_closure_OFS_G+0x10(%rsp)
-	movq    %rcx, ffi_closure_OFS_G+0x18(%rsp)
-	movq    %r8,  ffi_closure_OFS_G+0x20(%rsp)
-	movq    %r9,  ffi_closure_OFS_G+0x28(%rsp)
-
-#ifdef __ILP32__
-	movl	FFI_TRAMPOLINE_SIZE(%r10), %edi		/* Load cif */
-	movl	FFI_TRAMPOLINE_SIZE+4(%r10), %esi	/* Load fun */
-	movl	FFI_TRAMPOLINE_SIZE+8(%r10), %edx	/* Load user_data */
-#else
-	movq	FFI_TRAMPOLINE_SIZE(%r10), %rdi		/* Load cif */
-	movq	FFI_TRAMPOLINE_SIZE+8(%r10), %rsi	/* Load fun */
-	movq	FFI_TRAMPOLINE_SIZE+16(%r10), %rdx	/* Load user_data */
-#endif
-L(do_closure):
-	leaq	ffi_closure_OFS_RVALUE(%rsp), %rcx	/* Load rvalue */
-	movq	%rsp, %r8				/* Load reg_args */
-	leaq	ffi_closure_FS+8(%rsp), %r9		/* Load argp */
-	call	PLT(C(ffi_closure_unix64_inner))
+	movq	%r10, %rdi
+	leaq	176(%rsp), %rsi
+	movq	%rsp, %rdx
+	leaq	208(%rsp), %rcx
+	call	ffi_closure_unix64_inner@PLT
 
 	/* Deallocate stack frame early; return value is now in redzone.  */
-	addq	$ffi_closure_FS, %rsp
-L(UW10):
-	/* cfi_adjust_cfa_offset(-ffi_closure_FS) */
+	addq	$200, %rsp
+.LUW7:
 
 	/* The first byte of the return value contains the FFI_TYPE.  */
-	cmpb	$UNIX64_RET_LAST, %al
 	movzbl	%al, %r10d
-	leaq	L(load_table)(%rip), %r11
-	ja	L(la)
-	leaq	(%r11, %r10, 8), %r10
-	leaq	ffi_closure_RED_RVALUE(%rsp), %rsi
+	leaq	.Lload_table(%rip), %r11
+	movslq	(%r11, %r10, 4), %r10
+	addq	%r11, %r10
 	jmp	*%r10
 
-	.balign	8
-L(load_table):
-E(L(load_table), UNIX64_RET_VOID)
-	ret
-E(L(load_table), UNIX64_RET_UINT8)
-	movzbl	(%rsi), %eax
-	ret
-E(L(load_table), UNIX64_RET_UINT16)
-	movzwl	(%rsi), %eax
-	ret
-E(L(load_table), UNIX64_RET_UINT32)
-	movl	(%rsi), %eax
-	ret
-E(L(load_table), UNIX64_RET_SINT8)
-	movsbl	(%rsi), %eax
-	ret
-E(L(load_table), UNIX64_RET_SINT16)
-	movswl	(%rsi), %eax
-	ret
-E(L(load_table), UNIX64_RET_SINT32)
-	movl	(%rsi), %eax
-	ret
-E(L(load_table), UNIX64_RET_INT64)
-	movq	(%rsi), %rax
-	ret
-E(L(load_table), UNIX64_RET_XMM32)
-	movd	(%rsi), %xmm0
-	ret
-E(L(load_table), UNIX64_RET_XMM64)
-	movq	(%rsi), %xmm0
-	ret
-E(L(load_table), UNIX64_RET_X87)
-	fldt	(%rsi)
-	ret
-E(L(load_table), UNIX64_RET_X87_2)
-	fldt	16(%rsi)
-	fldt	(%rsi)
-	ret
-E(L(load_table), UNIX64_RET_ST_XMM0_RAX)
-	movq	8(%rsi), %rax
-	jmp	L(l3)
-E(L(load_table), UNIX64_RET_ST_RAX_XMM0)
-	movq	8(%rsi), %xmm0
-	jmp	L(l2)
-E(L(load_table), UNIX64_RET_ST_XMM0_XMM1)
-	movq	8(%rsi), %xmm1
-	jmp	L(l3)
-E(L(load_table), UNIX64_RET_ST_RAX_RDX)
-	movq	8(%rsi), %rdx
-L(l2):
-	movq	(%rsi), %rax
-	ret
-	.balign	8
-L(l3):
-	movq	(%rsi), %xmm0
+.Lload_table:
+	.long	.Lld_void-.Lload_table		/* FFI_TYPE_VOID */
+	.long	.Lld_int32-.Lload_table		/* FFI_TYPE_INT */
+	.long	.Lld_float-.Lload_table		/* FFI_TYPE_FLOAT */
+	.long	.Lld_double-.Lload_table	/* FFI_TYPE_DOUBLE */
+	.long	.Lld_ldouble-.Lload_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	.Lld_int8-.Lload_table		/* FFI_TYPE_UINT8 */
+	.long	.Lld_int8-.Lload_table		/* FFI_TYPE_SINT8 */
+	.long	.Lld_int16-.Lload_table		/* FFI_TYPE_UINT16 */
+	.long	.Lld_int16-.Lload_table		/* FFI_TYPE_SINT16 */
+	.long	.Lld_int32-.Lload_table		/* FFI_TYPE_UINT32 */
+	.long	.Lld_int32-.Lload_table		/* FFI_TYPE_SINT32 */
+	.long	.Lld_int64-.Lload_table		/* FFI_TYPE_UINT64 */
+	.long	.Lld_int64-.Lload_table		/* FFI_TYPE_SINT64 */
+	.long	.Lld_struct-.Lload_table	/* FFI_TYPE_STRUCT */
+	.long	.Lld_int64-.Lload_table		/* FFI_TYPE_POINTER */
+
+	.align 2
+.Lld_void:
 	ret
 
-L(la):	call	PLT(C(abort))
+	.align 2
+.Lld_int8:
+	movzbl	-24(%rsp), %eax
+	ret
+	.align 2
+.Lld_int16:
+	movzwl	-24(%rsp), %eax
+	ret
+	.align 2
+.Lld_int32:
+	movl	-24(%rsp), %eax
+	ret
+	.align 2
+.Lld_int64:
+	movq	-24(%rsp), %rax
+	ret
 
-L(UW11):
-ENDF(C(ffi_closure_unix64))
+	.align 2
+.Lld_float:
+	movss	-24(%rsp), %xmm0
+	ret
+	.align 2
+.Lld_double:
+	movsd	-24(%rsp), %xmm0
+	ret
+	.align 2
+.Lld_ldouble:
+	fldt	-24(%rsp)
+	ret
 
-	.balign	2
-	.globl	C(ffi_go_closure_unix64_sse)
-	FFI_HIDDEN(C(ffi_go_closure_unix64_sse))
+	.align 2
+.Lld_struct:
+	/* There are four possibilities here, %rax/%rdx, %xmm0/%rax,
+	   %rax/%xmm0, %xmm0/%xmm1.  We collapse two by always loading
+	   both rdx and xmm1 with the second word.  For the remaining,
+	   bit 8 set means xmm0 gets the second word, and bit 9 means
+	   that rax gets the second word.  */
+	movq	-24(%rsp), %rcx
+	movq	-16(%rsp), %rdx
+	movq	-16(%rsp), %xmm1
+	testl	$0x100, %eax
+	cmovnz	%rdx, %rcx
+	movd	%rcx, %xmm0
+	testl	$0x200, %eax
+	movq	-24(%rsp), %rax
+	cmovnz	%rdx, %rax
+	ret
 
-C(ffi_go_closure_unix64_sse):
-L(UW12):
-	subq	$ffi_closure_FS, %rsp
-L(UW13):
-	/* cfi_adjust_cfa_offset(ffi_closure_FS) */
+	/* See the comment above .Lload_sse; the same logic applies here.  */
+	.align 2
+.LUW8:
+.Lsave_sse:
+	movdqa	%xmm0, 48(%rsp)
+	movdqa	%xmm1, 64(%rsp)
+	movdqa	%xmm2, 80(%rsp)
+	movdqa	%xmm3, 96(%rsp)
+	movdqa	%xmm4, 112(%rsp)
+	movdqa	%xmm5, 128(%rsp)
+	movdqa	%xmm6, 144(%rsp)
+	movdqa	%xmm7, 160(%rsp)
+	jmp	.Lret_from_save_sse
 
-	movdqa	%xmm0, ffi_closure_OFS_V+0x00(%rsp)
-	movdqa	%xmm1, ffi_closure_OFS_V+0x10(%rsp)
-	movdqa	%xmm2, ffi_closure_OFS_V+0x20(%rsp)
-	movdqa	%xmm3, ffi_closure_OFS_V+0x30(%rsp)
-	movdqa	%xmm4, ffi_closure_OFS_V+0x40(%rsp)
-	movdqa	%xmm5, ffi_closure_OFS_V+0x50(%rsp)
-	movdqa	%xmm6, ffi_closure_OFS_V+0x60(%rsp)
-	movdqa	%xmm7, ffi_closure_OFS_V+0x70(%rsp)
-	jmp	L(sse_entry2)
+.LUW9:
+	.size	ffi_closure_unix64,.-ffi_closure_unix64
 
-L(UW14):
-ENDF(C(ffi_go_closure_unix64_sse))
+#ifdef __GNUC__
+/* Only emit DWARF unwind info when building with the GNU toolchain.  */
 
-	.balign	2
-	.globl	C(ffi_go_closure_unix64)
-	FFI_HIDDEN(C(ffi_go_closure_unix64))
-
-C(ffi_go_closure_unix64):
-L(UW15):
-	subq	$ffi_closure_FS, %rsp
-L(UW16):
-	/* cfi_adjust_cfa_offset(ffi_closure_FS) */
-L(sse_entry2):
-	movq	%rdi, ffi_closure_OFS_G+0x00(%rsp)
-	movq    %rsi, ffi_closure_OFS_G+0x08(%rsp)
-	movq    %rdx, ffi_closure_OFS_G+0x10(%rsp)
-	movq    %rcx, ffi_closure_OFS_G+0x18(%rsp)
-	movq    %r8,  ffi_closure_OFS_G+0x20(%rsp)
-	movq    %r9,  ffi_closure_OFS_G+0x28(%rsp)
-
-#ifdef __ILP32__
-	movl	4(%r10), %edi		/* Load cif */
-	movl	8(%r10), %esi		/* Load fun */
-	movl	%r10d, %edx		/* Load closure (user_data) */
+#ifdef HAVE_AS_X86_64_UNWIND_SECTION_TYPE
+	.section	.eh_frame,"a",@unwind
 #else
-	movq	8(%r10), %rdi		/* Load cif */
-	movq	16(%r10), %rsi		/* Load fun */
-	movq	%r10, %rdx		/* Load closure (user_data) */
+	.section	.eh_frame,"a",@progbits
 #endif
-	jmp	L(do_closure)
-
-L(UW17):
-ENDF(C(ffi_go_closure_unix64))
-
-/* Sadly, OSX cctools-as doesn't understand .cfi directives at all.  */
-
-#ifdef __APPLE__
-.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
-EHFrame0:
-#elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)
-.section .eh_frame,"a",@unwind
-#else
-.section .eh_frame,"a",@progbits
-#endif
-
-#ifdef HAVE_AS_X86_PCREL
-# define PCREL(X)	X - .
-#else
-# define PCREL(X)	X@rel
-#endif
-
-/* Simplify advancing between labels.  Assume DW_CFA_advance_loc1 fits.  */
-#define ADV(N, P)	.byte 2, L(N)-L(P)
-
-	.balign 8
-L(CIE):
-	.set	L(set0),L(ECIE)-L(SCIE)
-	.long	L(set0)			/* CIE Length */
-L(SCIE):
+.Lframe1:
+	.long	.LECIE1-.LSCIE1		/* CIE Length */
+.LSCIE1:
 	.long	0			/* CIE Identifier Tag */
 	.byte	1			/* CIE Version */
-	.ascii	"zR\0"			/* CIE Augmentation */
-	.byte	1			/* CIE Code Alignment Factor */
-	.byte	0x78			/* CIE Data Alignment Factor */
+	.ascii "zR\0"			/* CIE Augmentation */
+	.uleb128 1			/* CIE Code Alignment Factor */
+	.sleb128 -8			/* CIE Data Alignment Factor */
 	.byte	0x10			/* CIE RA Column */
-	.byte	1			/* Augmentation size */
+	.uleb128 1			/* Augmentation size */
 	.byte	0x1b			/* FDE Encoding (pcrel sdata4) */
-	.byte	0xc, 7, 8		/* DW_CFA_def_cfa, %rsp offset 8 */
-	.byte	0x80+16, 1		/* DW_CFA_offset, %rip offset 1*-8 */
-	.balign 8
-L(ECIE):
-
-	.set	L(set1),L(EFDE1)-L(SFDE1)
-	.long	L(set1)			/* FDE Length */
-L(SFDE1):
-	.long	L(SFDE1)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW0))		/* Initial location */
-	.long	L(UW4)-L(UW0)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW1, UW0)
-	.byte	0xc, 6, 32		/* DW_CFA_def_cfa, %rbp 32 */
-	.byte	0x80+6, 2		/* DW_CFA_offset, %rbp 2*-8 */
-	ADV(UW2, UW1)
-	.byte	0xa			/* DW_CFA_remember_state */
-	.byte	0xc, 7, 8		/* DW_CFA_def_cfa, %rsp 8 */
-	.byte	0xc0+6			/* DW_CFA_restore, %rbp */
-	ADV(UW3, UW2)
-	.byte	0xb			/* DW_CFA_restore_state */
-	.balign	8
-L(EFDE1):
-
-	.set	L(set2),L(EFDE2)-L(SFDE2)
-	.long	L(set2)			/* FDE Length */
-L(SFDE2):
-	.long	L(SFDE2)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW5))		/* Initial location */
-	.long	L(UW7)-L(UW5)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW6, UW5)
-	.byte	0xe			/* DW_CFA_def_cfa_offset */
-	.byte	ffi_closure_FS + 8, 1	/* uleb128, assuming 128 <= FS < 255 */
-	.balign	8
-L(EFDE2):
-
-	.set	L(set3),L(EFDE3)-L(SFDE3)
-	.long	L(set3)			/* FDE Length */
-L(SFDE3):
-	.long	L(SFDE3)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW8))		/* Initial location */
-	.long	L(UW11)-L(UW8)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW9, UW8)
-	.byte	0xe			/* DW_CFA_def_cfa_offset */
-	.byte	ffi_closure_FS + 8, 1	/* uleb128, assuming 128 <= FS < 255 */
-	ADV(UW10, UW9)
-	.byte	0xe, 8			/* DW_CFA_def_cfa_offset 8 */
-L(EFDE3):
-
-	.set	L(set4),L(EFDE4)-L(SFDE4)
-	.long	L(set4)			/* FDE Length */
-L(SFDE4):
-	.long	L(SFDE4)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW12))		/* Initial location */
-	.long	L(UW14)-L(UW12)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW13, UW12)
-	.byte	0xe			/* DW_CFA_def_cfa_offset */
-	.byte	ffi_closure_FS + 8, 1	/* uleb128, assuming 128 <= FS < 255 */
-	.balign	8
-L(EFDE4):
-
-	.set	L(set5),L(EFDE5)-L(SFDE5)
-	.long	L(set5)			/* FDE Length */
-L(SFDE5):
-	.long	L(SFDE5)-L(CIE)		/* FDE CIE offset */
-	.long	PCREL(L(UW15))		/* Initial location */
-	.long	L(UW17)-L(UW15)		/* Address range */
-	.byte	0			/* Augmentation size */
-	ADV(UW16, UW15)
-	.byte	0xe			/* DW_CFA_def_cfa_offset */
-	.byte	ffi_closure_FS + 8, 1	/* uleb128, assuming 128 <= FS < 255 */
-	.balign	8
-L(EFDE5):
-#ifdef __APPLE__
-	.subsections_via_symbols
-	.section __LD,__compact_unwind,regular,debug
-
-	/* compact unwind for ffi_call_unix64 */
-	.quad    C(ffi_call_unix64)
-	.set     L1,L(UW4)-L(UW0)
-	.long    L1
-	.long    0x04000000 /* use dwarf unwind info */
-	.quad    0
-	.quad    0
-
-	/* compact unwind for ffi_closure_unix64_sse */
-	.quad    C(ffi_closure_unix64_sse)
-	.set     L2,L(UW7)-L(UW5)
-	.long    L2
-	.long    0x04000000 /* use dwarf unwind info */
-	.quad    0
-	.quad    0
-
-	/* compact unwind for ffi_closure_unix64 */
-	.quad    C(ffi_closure_unix64)
-	.set     L3,L(UW11)-L(UW8)
-	.long    L3
-	.long    0x04000000 /* use dwarf unwind info */
-	.quad    0
-	.quad    0
-
-	/* compact unwind for ffi_go_closure_unix64_sse */
-	.quad    C(ffi_go_closure_unix64_sse)
-	.set     L4,L(UW14)-L(UW12)
-	.long    L4
-	.long    0x04000000 /* use dwarf unwind info */
-	.quad    0
-	.quad    0
-
-	/* compact unwind for ffi_go_closure_unix64 */
-	.quad    C(ffi_go_closure_unix64)
-	.set     L5,L(UW17)-L(UW15)
-	.long    L5
-	.long    0x04000000 /* use dwarf unwind info */
-	.quad    0
-	.quad    0
+	.byte	0xc			/* DW_CFA_def_cfa, %rsp offset 8 */
+	.uleb128 7
+	.uleb128 8
+	.byte	0x80+16			/* DW_CFA_offset, %rip offset 1*-8 */
+	.uleb128 1
+	.align 8
+.LECIE1:
+.LSFDE1:
+	.long	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
+#if HAVE_AS_X86_PCREL
+	.long	.LUW0-.			/* FDE initial location */
+#else
+	.long	.LUW0@rel
 #endif
+	.long	.LUW4-.LUW0		/* FDE address range */
+	.uleb128 0x0			/* Augmentation size */
 
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW1-.LUW0
+
+	/* New stack frame based off rbp.  This is a itty bit of unwind
+	   trickery in that the CFA *has* changed.  There is no easy way
+	   to describe it correctly on entry to the function.  Fortunately,
+	   it doesn't matter too much since at all points we can correctly
+	   unwind back to ffi_call.  Note that the location to which we
+	   moved the return address is (the new) CFA-8, so from the
+	   perspective of the unwind info, it hasn't moved.  */
+	.byte	0xc			/* DW_CFA_def_cfa, %rbp offset 32 */
+	.uleb128 6
+	.uleb128 32
+	.byte	0x80+6			/* DW_CFA_offset, %rbp offset 2*-8 */
+	.uleb128 2
+	.byte	0xa			/* DW_CFA_remember_state */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW2-.LUW1
+	.byte	0xc			/* DW_CFA_def_cfa, %rsp offset 8 */
+	.uleb128 7
+	.uleb128 8
+	.byte	0xc0+6			/* DW_CFA_restore, %rbp */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW3-.LUW2
+	.byte	0xb			/* DW_CFA_restore_state */
+
+	.align 8
+.LEFDE1:
+.LSFDE3:
+	.long	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
+#if HAVE_AS_X86_PCREL
+	.long	.LUW5-.			/* FDE initial location */
+#else
+	.long	.LUW5@rel
+#endif
+	.long	.LUW9-.LUW5		/* FDE address range */
+	.uleb128 0x0			/* Augmentation size */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW6-.LUW5
+	.byte	0xe			/* DW_CFA_def_cfa_offset */
+	.uleb128 208
+	.byte	0xa			/* DW_CFA_remember_state */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW7-.LUW6
+	.byte	0xe			/* DW_CFA_def_cfa_offset */
+	.uleb128 8
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW8-.LUW7
+	.byte	0xb			/* DW_CFA_restore_state */
+
+	.align 8
+.LEFDE3:
+
+#endif /* __GNUC__ */
+	
 #endif /* __x86_64__ */
+
 #if defined __ELF__ && defined __linux__
 	.section	.note.GNU-stack,"",@progbits
 #endif
diff --git a/src/x86/win32.S b/src/x86/win32.S
new file mode 100644
index 0000000..3680bf5
--- /dev/null
+++ b/src/x86/win32.S
@@ -0,0 +1,1351 @@
+/* -----------------------------------------------------------------------
+   win32.S - Copyright (c) 2014  Anthony Green
+             Copyright (c) 1996, 1998, 2001, 2002, 2009  Red Hat, Inc.
+             Copyright (c) 2001  John Beniton
+             Copyright (c) 2002  Ranjit Mathew
+             Copyright (c) 2009  Daniel Witte
+
+
+   X86 Foreign Function Interface
+ 
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+ 
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+ 
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   -----------------------------------------------------------------------
+   */
+ 
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#define CIF_BYTES_OFFSET 16
+#define CIF_FLAGS_OFFSET 20
+
+#ifdef _MSC_VER
+
+#define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
+
+.386
+.MODEL FLAT, C
+
+EXTRN ffi_closure_SYSV_inner:NEAR
+EXTRN ffi_closure_WIN32_inner:NEAR
+
+_TEXT SEGMENT
+
+ffi_call_win32 PROC NEAR,
+    ffi_prep_args : NEAR PTR DWORD,
+    ecif          : NEAR PTR DWORD,
+    cif_abi       : DWORD,
+    cif_bytes     : DWORD,
+    cif_flags     : DWORD,
+    rvalue        : NEAR PTR DWORD,
+    fn            : NEAR PTR DWORD
+
+        ;; Make room for all of the new args.
+        mov  ecx, cif_bytes
+        sub  esp, ecx
+
+        mov  eax, esp
+
+        ;; Call ffi_prep_args
+        push ecif
+        push eax
+        call ffi_prep_args
+        add  esp, 8
+
+        ;; Prepare registers
+        ;; EAX stores the number of register arguments
+        cmp  eax, 0
+        je   fun
+        cmp  eax, 3
+        jl   prepr_two_cmp
+        
+        mov  ecx, esp
+        add  esp, 12
+        mov  eax, DWORD PTR [ecx+8]
+        jmp  prepr_two
+prepr_two_cmp:
+        cmp  eax, 2
+        jl   prepr_one_prep
+        mov  ecx, esp
+        add  esp, 8
+prepr_two:
+        mov  edx, DWORD PTR [ecx+4]
+        jmp  prepr_one
+prepr_one_prep:
+        mov  ecx, esp
+        add  esp, 4
+prepr_one:
+        mov  ecx, DWORD PTR [ecx]
+        cmp  cif_abi, 7 ;; FFI_REGISTER
+        jne  fun
+
+        xchg ecx, eax
+
+fun:
+        ;; Call function
+        call fn
+
+        ;; Load ecx with the return type code
+        mov  ecx, cif_flags
+
+        ;; If the return value pointer is NULL, assume no return value.
+        cmp  rvalue, 0
+        jne  ca_jumptable
+
+        ;; Even if there is no space for the return value, we are
+        ;; obliged to handle floating-point values.
+        cmp  ecx, FFI_TYPE_FLOAT
+        jne  ca_epilogue
+        fstp st(0)
+
+        jmp  ca_epilogue
+
+ca_jumptable:
+        jmp  [ca_jumpdata + 4 * ecx]
+ca_jumpdata:
+        ;; Do not insert anything here between label and jump table.
+        dd offset ca_epilogue       ;; FFI_TYPE_VOID
+        dd offset ca_retint         ;; FFI_TYPE_INT
+        dd offset ca_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset ca_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset ca_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset ca_retuint8       ;; FFI_TYPE_UINT8
+        dd offset ca_retsint8       ;; FFI_TYPE_SINT8
+        dd offset ca_retuint16      ;; FFI_TYPE_UINT16
+        dd offset ca_retsint16      ;; FFI_TYPE_SINT16
+        dd offset ca_retint         ;; FFI_TYPE_UINT32
+        dd offset ca_retint         ;; FFI_TYPE_SINT32
+        dd offset ca_retint64       ;; FFI_TYPE_UINT64
+        dd offset ca_retint64       ;; FFI_TYPE_SINT64
+        dd offset ca_epilogue       ;; FFI_TYPE_STRUCT
+        dd offset ca_retint         ;; FFI_TYPE_POINTER
+        dd offset ca_retstruct1b    ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset ca_retstruct2b    ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset ca_epilogue       ;; FFI_TYPE_MS_STRUCT
+
+        /* Sign/zero extend as appropriate.  */
+ca_retuint8:
+        movzx eax, al
+        jmp   ca_retint
+
+ca_retsint8:
+        movsx eax, al
+        jmp   ca_retint
+
+ca_retuint16:
+        movzx eax, ax
+        jmp   ca_retint
+
+ca_retsint16:
+        movsx eax, ax
+        jmp   ca_retint
+
+ca_retint:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], eax
+        jmp   ca_epilogue
+
+ca_retint64:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], eax
+        mov   [ecx + 4], edx
+        jmp   ca_epilogue
+
+ca_retfloat:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        fstp  DWORD PTR [ecx]
+        jmp   ca_epilogue
+
+ca_retdouble:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        fstp  QWORD PTR [ecx]
+        jmp   ca_epilogue
+
+ca_retlongdouble:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        fstp  TBYTE PTR [ecx]
+        jmp   ca_epilogue
+
+ca_retstruct1b:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], al
+        jmp   ca_epilogue
+
+ca_retstruct2b:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], ax
+        jmp   ca_epilogue
+
+ca_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_call_win32 ENDP
+
+ffi_closure_THISCALL PROC NEAR
+        ;; Insert the register argument on the stack as the first argument
+        xchg	DWORD PTR [esp+4], ecx
+        xchg	DWORD PTR [esp], ecx
+        push	ecx
+        jmp	ffi_closure_STDCALL
+ffi_closure_THISCALL ENDP
+
+ffi_closure_FASTCALL PROC NEAR
+        ;; Insert the 2 register arguments on the stack as the first argument
+        xchg	DWORD PTR [esp+4], edx
+        xchg	DWORD PTR [esp], ecx
+        push	edx
+        push	ecx
+        jmp	ffi_closure_STDCALL
+ffi_closure_FASTCALL ENDP
+
+ffi_closure_REGISTER PROC NEAR
+        ;; Insert the 3 register arguments on the stack as the first argument
+        push	eax
+        xchg	DWORD PTR [esp+8], ecx
+        xchg	DWORD PTR [esp+4], edx
+        push	ecx
+        push	edx
+        jmp	ffi_closure_STDCALL
+ffi_closure_REGISTER ENDP
+
+ffi_closure_SYSV PROC NEAR FORCEFRAME
+    ;; the ffi_closure ctx is passed in eax by the trampoline.
+
+        sub  esp, 40
+        lea  edx, [ebp - 24]
+        mov  [ebp - 12], edx         ;; resp
+        lea  edx, [ebp + 8]
+stub::
+        mov  [esp + 8], edx          ;; args
+        lea  edx, [ebp - 12]
+        mov  [esp + 4], edx          ;; &resp
+        mov  [esp], eax              ;; closure
+        call ffi_closure_SYSV_inner
+        mov  ecx, [ebp - 12]
+
+cs_jumptable:
+        jmp  [cs_jumpdata + 4 * eax]
+cs_jumpdata:
+        ;; Do not insert anything here between the label and jump table.
+        dd offset cs_epilogue       ;; FFI_TYPE_VOID
+        dd offset cs_retint         ;; FFI_TYPE_INT
+        dd offset cs_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset cs_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset cs_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset cs_retuint8       ;; FFI_TYPE_UINT8
+        dd offset cs_retsint8       ;; FFI_TYPE_SINT8
+        dd offset cs_retuint16      ;; FFI_TYPE_UINT16
+        dd offset cs_retsint16      ;; FFI_TYPE_SINT16
+        dd offset cs_retint         ;; FFI_TYPE_UINT32
+        dd offset cs_retint         ;; FFI_TYPE_SINT32
+        dd offset cs_retint64       ;; FFI_TYPE_UINT64
+        dd offset cs_retint64       ;; FFI_TYPE_SINT64
+        dd offset cs_retstruct      ;; FFI_TYPE_STRUCT
+        dd offset cs_retint         ;; FFI_TYPE_POINTER
+        dd offset cs_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cs_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cs_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset cs_retmsstruct    ;; FFI_TYPE_MS_STRUCT
+
+cs_retuint8:
+        movzx eax, BYTE PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retsint8:
+        movsx eax, BYTE PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retuint16:
+        movzx eax, WORD PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retsint16:
+        movsx eax, WORD PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retint:
+        mov   eax, [ecx]
+        jmp   cs_epilogue
+
+cs_retint64:
+        mov   eax, [ecx + 0]
+        mov   edx, [ecx + 4]
+        jmp   cs_epilogue
+
+cs_retfloat:
+        fld   DWORD PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retdouble:
+        fld   QWORD PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retlongdouble:
+        fld   TBYTE PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retstruct:
+        ;; Caller expects us to pop struct return value pointer hidden arg.
+        ;; Epilogue code is autogenerated.
+        ret	4
+
+cs_retmsstruct:
+        ;; Caller expects us to return a pointer to the real return value.
+        mov   eax, ecx
+        ;; Caller doesn't expects us to pop struct return value pointer hidden arg.
+        jmp   cs_epilogue
+
+cs_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_closure_SYSV ENDP
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+
+ffi_closure_raw_THISCALL PROC NEAR USES esi FORCEFRAME
+        sub esp, 36
+        mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
+        mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
+        mov [esp + 12], edx
+        lea edx, [ebp + 12]
+        jmp stubraw
+ffi_closure_raw_THISCALL ENDP
+
+ffi_closure_raw_SYSV PROC NEAR USES esi FORCEFRAME
+    ;; the ffi_closure ctx is passed in eax by the trampoline.
+
+        sub  esp, 40
+        mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
+        mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
+        mov  [esp + 12], edx                            ;; user_data
+        lea  edx, [ebp + 8]
+stubraw::
+        mov  [esp + 8], edx                             ;; raw_args
+        lea  edx, [ebp - 24]
+        mov  [esp + 4], edx                             ;; &res
+        mov  [esp], esi                                 ;; cif
+        call DWORD PTR [eax + RAW_CLOSURE_FUN_OFFSET]   ;; closure->fun
+        mov  eax, [esi + CIF_FLAGS_OFFSET]              ;; cif->flags
+        lea  ecx, [ebp - 24]
+
+cr_jumptable:
+        jmp  [cr_jumpdata + 4 * eax]
+cr_jumpdata:
+        ;; Do not insert anything here between the label and jump table.
+        dd offset cr_epilogue       ;; FFI_TYPE_VOID
+        dd offset cr_retint         ;; FFI_TYPE_INT
+        dd offset cr_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset cr_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset cr_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset cr_retuint8       ;; FFI_TYPE_UINT8
+        dd offset cr_retsint8       ;; FFI_TYPE_SINT8
+        dd offset cr_retuint16      ;; FFI_TYPE_UINT16
+        dd offset cr_retsint16      ;; FFI_TYPE_SINT16
+        dd offset cr_retint         ;; FFI_TYPE_UINT32
+        dd offset cr_retint         ;; FFI_TYPE_SINT32
+        dd offset cr_retint64       ;; FFI_TYPE_UINT64
+        dd offset cr_retint64       ;; FFI_TYPE_SINT64
+        dd offset cr_epilogue       ;; FFI_TYPE_STRUCT
+        dd offset cr_retint         ;; FFI_TYPE_POINTER
+        dd offset cr_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cr_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cr_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset cr_epilogue       ;; FFI_TYPE_MS_STRUCT
+
+cr_retuint8:
+        movzx eax, BYTE PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retsint8:
+        movsx eax, BYTE PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retuint16:
+        movzx eax, WORD PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retsint16:
+        movsx eax, WORD PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retint:
+        mov   eax, [ecx]
+        jmp   cr_epilogue
+
+cr_retint64:
+        mov   eax, [ecx + 0]
+        mov   edx, [ecx + 4]
+        jmp   cr_epilogue
+
+cr_retfloat:
+        fld   DWORD PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retdouble:
+        fld   QWORD PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retlongdouble:
+        fld   TBYTE PTR [ecx]
+        jmp   cr_epilogue
+
+cr_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_closure_raw_SYSV ENDP
+
+#endif /* !FFI_NO_RAW_API */
+
+ffi_closure_STDCALL PROC NEAR FORCEFRAME
+        mov  eax, [esp] ;; the ffi_closure ctx passed by the trampoline.
+
+        sub  esp, 40
+        lea  edx, [ebp - 24]
+        mov  [ebp - 12], edx         ;; resp
+        lea  edx, [ebp + 12]         ;; account for stub return address on stack
+        mov  [esp + 8], edx          ;; args
+        lea  edx, [ebp - 12]
+        mov  [esp + 4], edx          ;; &resp
+        mov  [esp], eax              ;; closure
+        call ffi_closure_WIN32_inner
+        mov  ecx, [ebp - 12]
+
+        xchg [ebp + 4], eax          ;;xchg size of stack parameters and ffi_closure ctx
+        mov  eax, DWORD PTR [eax + CLOSURE_CIF_OFFSET]
+        mov  eax, DWORD PTR [eax + CIF_FLAGS_OFFSET]
+
+cd_jumptable:
+        jmp  [cd_jumpdata + 4 * eax]
+cd_jumpdata:
+        ;; Do not insert anything here between the label and jump table.
+        dd offset cd_epilogue       ;; FFI_TYPE_VOID
+        dd offset cd_retint         ;; FFI_TYPE_INT
+        dd offset cd_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset cd_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset cd_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset cd_retuint8       ;; FFI_TYPE_UINT8
+        dd offset cd_retsint8       ;; FFI_TYPE_SINT8
+        dd offset cd_retuint16      ;; FFI_TYPE_UINT16
+        dd offset cd_retsint16      ;; FFI_TYPE_SINT16
+        dd offset cd_retint         ;; FFI_TYPE_UINT32
+        dd offset cd_retint         ;; FFI_TYPE_SINT32
+        dd offset cd_retint64       ;; FFI_TYPE_UINT64
+        dd offset cd_retint64       ;; FFI_TYPE_SINT64
+        dd offset cd_epilogue       ;; FFI_TYPE_STRUCT
+        dd offset cd_retint         ;; FFI_TYPE_POINTER
+        dd offset cd_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cd_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cd_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+
+cd_retuint8:
+        movzx eax, BYTE PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retsint8:
+        movsx eax, BYTE PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retuint16:
+        movzx eax, WORD PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retsint16:
+        movsx eax, WORD PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retint:
+        mov   eax, [ecx]
+        jmp   cd_epilogue
+
+cd_retint64:
+        mov   eax, [ecx + 0]
+        mov   edx, [ecx + 4]
+        jmp   cd_epilogue
+
+cd_retfloat:
+        fld   DWORD PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retdouble:
+        fld   QWORD PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retlongdouble:
+        fld   TBYTE PTR [ecx]
+        jmp   cd_epilogue
+
+cd_epilogue:
+        mov   esp, ebp
+        pop   ebp
+        mov   ecx, [esp + 4]  ;; Return address
+        add   esp, [esp]      ;; Parameters stack size
+        add   esp, 8
+        jmp   ecx
+ffi_closure_STDCALL ENDP
+
+_TEXT ENDS
+END
+
+#else
+
+#define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+
+#if defined(SYMBOL_UNDERSCORE)
+#define USCORE_SYMBOL(x) _##x
+#else
+#define USCORE_SYMBOL(x) x
+#endif
+        .text
+ 
+        # This assumes we are using gas.
+        .balign 16
+FFI_HIDDEN(ffi_call_win32)
+        .globl	USCORE_SYMBOL(ffi_call_win32)
+#if defined(X86_WIN32) && !defined(__OS2__)
+        .def	_ffi_call_win32;	.scl	2;	.type	32;	.endef
+#endif
+USCORE_SYMBOL(ffi_call_win32):
+.LFB1:
+        pushl %ebp
+.LCFI0:
+        movl  %esp,%ebp
+.LCFI1:
+        # Make room for all of the new args.
+        movl  20(%ebp),%ecx                                                     
+        subl  %ecx,%esp
+ 
+        movl  %esp,%eax
+ 
+        # Call ffi_prep_args
+        pushl 12(%ebp)
+        pushl %eax
+        call  *8(%ebp)
+        addl  $8,%esp
+
+        # Prepare registers
+        # EAX stores the number of register arguments
+        cmpl  $0, %eax
+        je    .fun
+        cmpl  $3, %eax
+        jl    .prepr_two_cmp
+        
+        movl  %esp, %ecx
+        addl  $12, %esp
+        movl  8(%ecx), %eax
+        jmp   .prepr_two
+.prepr_two_cmp:
+        cmpl  $2, %eax
+        jl    .prepr_one_prep
+        movl  %esp, %ecx
+        addl  $8, %esp
+.prepr_two:
+        movl  4(%ecx), %edx
+        jmp   .prepr_one
+.prepr_one_prep:
+        movl  %esp, %ecx
+        addl  $4, %esp
+.prepr_one:
+        movl  (%ecx), %ecx
+        cmpl  $7, 16(%ebp) # FFI_REGISTER
+        jne   .fun
+
+        xchgl %eax, %ecx
+        
+.fun:
+        # FIXME: Align the stack to a 128-bit boundary to avoid
+        # potential performance hits.
+
+        # Call function
+        call  *32(%ebp)
+ 
+        # stdcall functions pop arguments off the stack themselves
+
+        # Load %ecx with the return type code
+        movl  24(%ebp),%ecx
+ 
+        # If the return value pointer is NULL, assume no return value.
+        cmpl  $0,28(%ebp)
+        jne   0f
+ 
+        # Even if there is no space for the return value, we are
+        # obliged to handle floating-point values.
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   .Lnoretval
+        fstp  %st(0)
+ 
+        jmp   .Lepilogue
+
+0:
+        call 1f
+        # Do not insert anything here between the call and the jump table.
+.Lstore_table:
+        .long	.Lnoretval-.Lstore_table	/* FFI_TYPE_VOID */
+        .long	.Lretint-.Lstore_table		/* FFI_TYPE_INT */
+        .long	.Lretfloat-.Lstore_table	/* FFI_TYPE_FLOAT */
+        .long	.Lretdouble-.Lstore_table	/* FFI_TYPE_DOUBLE */
+        .long	.Lretlongdouble-.Lstore_table	/* FFI_TYPE_LONGDOUBLE */
+        .long	.Lretuint8-.Lstore_table	/* FFI_TYPE_UINT8 */
+        .long	.Lretsint8-.Lstore_table	/* FFI_TYPE_SINT8 */
+        .long	.Lretuint16-.Lstore_table	/* FFI_TYPE_UINT16 */
+        .long	.Lretsint16-.Lstore_table	/* FFI_TYPE_SINT16 */
+        .long	.Lretint-.Lstore_table		/* FFI_TYPE_UINT32 */
+        .long	.Lretint-.Lstore_table		/* FFI_TYPE_SINT32 */
+        .long	.Lretint64-.Lstore_table	/* FFI_TYPE_UINT64 */
+        .long	.Lretint64-.Lstore_table	/* FFI_TYPE_SINT64 */
+        .long	.Lretstruct-.Lstore_table	/* FFI_TYPE_STRUCT */
+        .long	.Lretint-.Lstore_table		/* FFI_TYPE_POINTER */
+        .long	.Lretstruct1b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_1B */
+        .long	.Lretstruct2b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_2B */
+        .long	.Lretstruct4b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_4B */
+        .long	.Lretstruct-.Lstore_table	/* FFI_TYPE_MS_STRUCT */
+1:
+        shl	$2, %ecx
+        add	(%esp),%ecx
+        mov	(%ecx),%ecx
+        add	(%esp),%ecx
+        add	$4, %esp
+        jmp	*%ecx
+
+        /* Sign/zero extend as appropriate.  */
+.Lretsint8:
+        movsbl	%al, %eax
+        jmp	.Lretint
+
+.Lretsint16:
+        movswl	%ax, %eax
+        jmp	.Lretint
+
+.Lretuint8:
+        movzbl	%al, %eax
+        jmp	.Lretint
+
+.Lretuint16:
+        movzwl	%ax, %eax
+        jmp	.Lretint
+
+.Lretint:
+        # Load %ecx with the pointer to storage for the return value
+        movl  28(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        jmp   .Lepilogue
+ 
+.Lretfloat:
+         # Load %ecx with the pointer to storage for the return value
+        movl  28(%ebp),%ecx
+        fstps (%ecx)
+        jmp   .Lepilogue
+ 
+.Lretdouble:
+        # Load %ecx with the pointer to storage for the return value
+        movl  28(%ebp),%ecx
+        fstpl (%ecx)
+        jmp   .Lepilogue
+ 
+.Lretlongdouble:
+        # Load %ecx with the pointer to storage for the return value
+        movl  28(%ebp),%ecx
+        fstpt (%ecx)
+        jmp   .Lepilogue
+ 
+.Lretint64:
+        # Load %ecx with the pointer to storage for the return value
+        movl  28(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        movl  %edx,4(%ecx)
+        jmp   .Lepilogue
+
+.Lretstruct1b:
+        # Load %ecx with the pointer to storage for the return value
+        movl  28(%ebp),%ecx
+        movb  %al,0(%ecx)
+        jmp   .Lepilogue
+ 
+.Lretstruct2b:
+        # Load %ecx with the pointer to storage for the return value
+        movl  28(%ebp),%ecx
+        movw  %ax,0(%ecx)
+        jmp   .Lepilogue
+
+.Lretstruct4b:
+        # Load %ecx with the pointer to storage for the return value
+        movl  28(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        jmp   .Lepilogue
+
+.Lretstruct:
+        # Nothing to do!
+ 
+.Lnoretval:
+.Lepilogue:
+        movl %ebp,%esp
+        popl %ebp
+        ret
+.ffi_call_win32_end:
+        .balign 16
+FFI_HIDDEN(ffi_closure_THISCALL)
+        .globl	USCORE_SYMBOL(ffi_closure_THISCALL)
+#if defined(X86_WIN32) && !defined(__OS2__)
+        .def	_ffi_closure_THISCALL;	.scl	2;	.type	32;	.endef
+#endif
+USCORE_SYMBOL(ffi_closure_THISCALL):
+        /* Insert the register argument on the stack as the first argument */
+        xchg	%ecx, 4(%esp)
+        xchg	%ecx, (%esp)
+        push	%ecx
+        jmp	.ffi_closure_STDCALL_internal
+
+        .balign 16
+FFI_HIDDEN(ffi_closure_FASTCALL)
+        .globl	USCORE_SYMBOL(ffi_closure_FASTCALL)
+#if defined(X86_WIN32) && !defined(__OS2__)
+        .def	_ffi_closure_FASTCALL;	.scl	2;	.type	32;	.endef
+#endif
+USCORE_SYMBOL(ffi_closure_FASTCALL):
+        /* Insert the 2 register arguments on the stack as the first two arguments */
+        xchg	%edx, 4(%esp)
+        xchg	%ecx, (%esp)
+        push	%edx
+        push	%ecx
+        jmp	.ffi_closure_STDCALL_internal
+FFI_HIDDEN(ffi_closure_REGISTER)
+        .globl	USCORE_SYMBOL(ffi_closure_REGISTER)
+#if defined(X86_WIN32) && !defined(__OS2__)
+        .def	_ffi_closure_REGISTER;	.scl	2;	.type	32;	.endef
+#endif
+USCORE_SYMBOL(ffi_closure_REGISTER):
+        /* Insert the 3 register arguments on the stack as the first two arguments */
+        push	%eax
+        xchg	%ecx, 8(%esp)
+        xchg	%edx, 4(%esp)
+        push	%ecx
+        push	%edx
+        jmp	.ffi_closure_STDCALL_internal
+
+.LFE1:
+        # This assumes we are using gas.
+        .balign 16
+FFI_HIDDEN(ffi_closure_SYSV)
+#if defined(X86_WIN32)
+        .globl	USCORE_SYMBOL(ffi_closure_SYSV)
+#if defined(X86_WIN32) && !defined(__OS2__)
+        .def	_ffi_closure_SYSV;	.scl	2;	.type	32;	.endef
+#endif
+USCORE_SYMBOL(ffi_closure_SYSV):
+#endif
+.LFB3:
+        pushl	%ebp
+.LCFI4:
+        movl	%esp, %ebp
+.LCFI5:
+        subl	$40, %esp
+        leal	-24(%ebp), %edx
+        movl	%edx, -12(%ebp)	/* resp */
+        leal	8(%ebp), %edx
+        movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
+        leal	-12(%ebp), %edx
+        movl	%edx, (%esp)	/* &resp */
+#if defined(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE) || !defined(__PIC__)
+        call	USCORE_SYMBOL(ffi_closure_SYSV_inner)
+#elif defined(X86_DARWIN)
+        calll	L_ffi_closure_SYSV_inner$stub
+#else
+        movl	%ebx, 8(%esp)
+        call	1f
+1:      popl	%ebx
+        addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+        call	ffi_closure_SYSV_inner@PLT
+        movl	8(%esp), %ebx
+#endif
+        movl	-12(%ebp), %ecx
+
+0:
+        call	1f
+        # Do not insert anything here between the call and the jump table.
+.Lcls_store_table:
+        .long	.Lcls_noretval-.Lcls_store_table	/* FFI_TYPE_VOID */
+        .long	.Lcls_retint-.Lcls_store_table		/* FFI_TYPE_INT */
+        .long	.Lcls_retfloat-.Lcls_store_table	/* FFI_TYPE_FLOAT */
+        .long	.Lcls_retdouble-.Lcls_store_table	/* FFI_TYPE_DOUBLE */
+        .long	.Lcls_retldouble-.Lcls_store_table	/* FFI_TYPE_LONGDOUBLE */
+        .long	.Lcls_retuint8-.Lcls_store_table	/* FFI_TYPE_UINT8 */
+        .long	.Lcls_retsint8-.Lcls_store_table	/* FFI_TYPE_SINT8 */
+        .long	.Lcls_retuint16-.Lcls_store_table	/* FFI_TYPE_UINT16 */
+        .long	.Lcls_retsint16-.Lcls_store_table	/* FFI_TYPE_SINT16 */
+        .long	.Lcls_retint-.Lcls_store_table		/* FFI_TYPE_UINT32 */
+        .long	.Lcls_retint-.Lcls_store_table		/* FFI_TYPE_SINT32 */
+        .long	.Lcls_retllong-.Lcls_store_table	/* FFI_TYPE_UINT64 */
+        .long	.Lcls_retllong-.Lcls_store_table	/* FFI_TYPE_SINT64 */
+        .long	.Lcls_retstruct-.Lcls_store_table	/* FFI_TYPE_STRUCT */
+        .long	.Lcls_retint-.Lcls_store_table		/* FFI_TYPE_POINTER */
+        .long	.Lcls_retstruct1-.Lcls_store_table	/* FFI_TYPE_SMALL_STRUCT_1B */
+        .long	.Lcls_retstruct2-.Lcls_store_table	/* FFI_TYPE_SMALL_STRUCT_2B */
+        .long	.Lcls_retstruct4-.Lcls_store_table	/* FFI_TYPE_SMALL_STRUCT_4B */
+        .long	.Lcls_retmsstruct-.Lcls_store_table	/* FFI_TYPE_MS_STRUCT */
+
+1:
+        shl	$2, %eax
+        add	(%esp),%eax
+        mov	(%eax),%eax
+        add	(%esp),%eax
+        add	$4, %esp
+        jmp	*%eax
+
+        /* Sign/zero extend as appropriate.  */
+.Lcls_retsint8:
+        movsbl	(%ecx), %eax
+        jmp	.Lcls_epilogue
+
+.Lcls_retsint16:
+        movswl	(%ecx), %eax
+        jmp	.Lcls_epilogue
+
+.Lcls_retuint8:
+        movzbl	(%ecx), %eax
+        jmp	.Lcls_epilogue
+
+.Lcls_retuint16:
+        movzwl	(%ecx), %eax
+        jmp	.Lcls_epilogue
+
+.Lcls_retint:
+        movl	(%ecx), %eax
+        jmp	.Lcls_epilogue
+
+.Lcls_retfloat:
+        flds	(%ecx)
+        jmp	.Lcls_epilogue
+
+.Lcls_retdouble:
+        fldl	(%ecx)
+        jmp	.Lcls_epilogue
+
+.Lcls_retldouble:
+        fldt	(%ecx)
+        jmp	.Lcls_epilogue
+
+.Lcls_retllong:
+        movl	(%ecx), %eax
+        movl	4(%ecx), %edx
+        jmp	.Lcls_epilogue
+
+.Lcls_retstruct1:
+        movsbl	(%ecx), %eax
+        jmp	.Lcls_epilogue
+
+.Lcls_retstruct2:
+        movswl	(%ecx), %eax
+        jmp	.Lcls_epilogue
+
+.Lcls_retstruct4:
+        movl	(%ecx), %eax
+        jmp	.Lcls_epilogue
+
+.Lcls_retstruct:
+        # Caller expects us to pop struct return value pointer hidden arg.
+        movl	%ebp, %esp
+        popl	%ebp
+        ret	$0x4
+
+.Lcls_retmsstruct:
+        # Caller expects us to return a pointer to the real return value.
+        mov	%ecx, %eax
+        # Caller doesn't expects us to pop struct return value pointer hidden arg.
+        jmp	.Lcls_epilogue
+
+.Lcls_noretval:
+.Lcls_epilogue:
+        movl	%ebp, %esp
+        popl	%ebp
+        ret
+.ffi_closure_SYSV_end:
+.LFE3:
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+
+#ifdef X86_WIN32
+        .balign 16
+FFI_HIDDEN(ffi_closure_raw_THISCALL)
+        .globl	USCORE_SYMBOL(ffi_closure_raw_THISCALL)
+#if defined(X86_WIN32) && !defined(__OS2__)
+        .def	_ffi_closure_raw_THISCALL;	.scl	2;	.type	32;	.endef
+#endif
+USCORE_SYMBOL(ffi_closure_raw_THISCALL):
+        pushl	%ebp
+        movl	%esp, %ebp
+        pushl	%esi
+        subl	$36, %esp
+        movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
+        movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+        movl	%edx, 12(%esp)	/* user_data */
+        leal	12(%ebp), %edx	/* __builtin_dwarf_cfa () */
+        jmp	.stubraw
+#endif /* X86_WIN32 */
+
+        # This assumes we are using gas.
+        .balign 16
+#if defined(X86_WIN32)
+        .globl	USCORE_SYMBOL(ffi_closure_raw_SYSV)
+#if defined(X86_WIN32) && !defined(__OS2__)
+        .def	_ffi_closure_raw_SYSV;	.scl	2;	.type	32;	.endef
+#endif
+USCORE_SYMBOL(ffi_closure_raw_SYSV):
+#endif /* defined(X86_WIN32) */
+.LFB4:
+        pushl	%ebp
+.LCFI6:
+        movl	%esp, %ebp
+.LCFI7:
+        pushl	%esi
+.LCFI8:
+        subl	$36, %esp
+        movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
+        movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+        movl	%edx, 12(%esp)	/* user_data */
+        leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
+.stubraw:
+        movl	%edx, 8(%esp)	/* raw_args */
+        leal	-24(%ebp), %edx
+        movl	%edx, 4(%esp)	/* &res */
+        movl	%esi, (%esp)	/* cif */
+        call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
+        movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
+0:
+        call	1f
+        # Do not insert anything here between the call and the jump table.
+.Lrcls_store_table:
+        .long	.Lrcls_noretval-.Lrcls_store_table	/* FFI_TYPE_VOID */
+        .long	.Lrcls_retint-.Lrcls_store_table	/* FFI_TYPE_INT */
+        .long	.Lrcls_retfloat-.Lrcls_store_table	/* FFI_TYPE_FLOAT */
+        .long	.Lrcls_retdouble-.Lrcls_store_table	/* FFI_TYPE_DOUBLE */
+        .long	.Lrcls_retldouble-.Lrcls_store_table	/* FFI_TYPE_LONGDOUBLE */
+        .long	.Lrcls_retuint8-.Lrcls_store_table	/* FFI_TYPE_UINT8 */
+        .long	.Lrcls_retsint8-.Lrcls_store_table	/* FFI_TYPE_SINT8 */
+        .long	.Lrcls_retuint16-.Lrcls_store_table	/* FFI_TYPE_UINT16 */
+        .long	.Lrcls_retsint16-.Lrcls_store_table	/* FFI_TYPE_SINT16 */
+        .long	.Lrcls_retint-.Lrcls_store_table	/* FFI_TYPE_UINT32 */
+        .long	.Lrcls_retint-.Lrcls_store_table	/* FFI_TYPE_SINT32 */
+        .long	.Lrcls_retllong-.Lrcls_store_table	/* FFI_TYPE_UINT64 */
+        .long	.Lrcls_retllong-.Lrcls_store_table	/* FFI_TYPE_SINT64 */
+        .long	.Lrcls_retstruct-.Lrcls_store_table	/* FFI_TYPE_STRUCT */
+        .long	.Lrcls_retint-.Lrcls_store_table	/* FFI_TYPE_POINTER */
+        .long	.Lrcls_retstruct1-.Lrcls_store_table	/* FFI_TYPE_SMALL_STRUCT_1B */
+        .long	.Lrcls_retstruct2-.Lrcls_store_table	/* FFI_TYPE_SMALL_STRUCT_2B */
+        .long	.Lrcls_retstruct4-.Lrcls_store_table	/* FFI_TYPE_SMALL_STRUCT_4B */
+        .long	.Lrcls_retstruct-.Lrcls_store_table	/* FFI_TYPE_MS_STRUCT */
+1:
+        shl	$2, %eax
+        add	(%esp),%eax
+        mov	(%eax),%eax
+        add	(%esp),%eax
+        add	$4, %esp
+        jmp	*%eax
+
+        /* Sign/zero extend as appropriate.  */
+.Lrcls_retsint8:
+        movsbl	-24(%ebp), %eax
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retsint16:
+        movswl	-24(%ebp), %eax
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retuint8:
+        movzbl	-24(%ebp), %eax
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retuint16:
+        movzwl	-24(%ebp), %eax
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retint:
+        movl	-24(%ebp), %eax
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retfloat:
+        flds	-24(%ebp)
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retdouble:
+        fldl	-24(%ebp)
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retldouble:
+        fldt	-24(%ebp)
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retllong:
+        movl	-24(%ebp), %eax
+        movl	-20(%ebp), %edx
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retstruct1:
+        movsbl	-24(%ebp), %eax
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retstruct2:
+        movswl	-24(%ebp), %eax
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retstruct4:
+        movl	-24(%ebp), %eax
+        jmp	.Lrcls_epilogue
+
+.Lrcls_retstruct:
+        # Nothing to do!
+
+.Lrcls_noretval:
+.Lrcls_epilogue:
+        addl	$36, %esp
+        popl	%esi
+        popl	%ebp
+        ret
+.ffi_closure_raw_SYSV_end:
+.LFE4:
+
+#endif /* !FFI_NO_RAW_API */
+
+        # This assumes we are using gas.
+        .balign	16
+FFI_HIDDEN(ffi_closure_STDCALL)
+        .globl	USCORE_SYMBOL(ffi_closure_STDCALL)
+#if defined(X86_WIN32) && !defined(__OS2__)
+        .def	_ffi_closure_STDCALL;	.scl	2;	.type	32;	.endef
+#endif
+USCORE_SYMBOL(ffi_closure_STDCALL):
+.ffi_closure_STDCALL_internal:
+        /* ffi_closure ctx is at top of the stack */
+        movl	(%esp), %eax
+.LFB5:
+        pushl	%ebp
+.LCFI9:
+        movl	%esp, %ebp
+.LCFI10:
+        subl	$40, %esp
+        leal	-24(%ebp), %edx
+        movl	%edx, -12(%ebp)	/* resp */
+        leal	12(%ebp), %edx  /* account for stub return address on stack */
+        movl	%edx, 4(%esp)	/* args */
+        leal	-12(%ebp), %edx
+        movl	%edx, (%esp)	/* &resp */
+#if defined(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE) || !defined(__PIC__)
+        call	USCORE_SYMBOL(ffi_closure_WIN32_inner)
+#elif defined(X86_DARWIN)
+        calll	L_ffi_closure_WIN32_inner$stub
+#else
+        movl	%ebx, 8(%esp)
+        call	1f
+1:      popl	%ebx
+        addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+        call	ffi_closure_WIN32_inner@PLT
+        movl	8(%esp), %ebx
+#endif
+        movl	-12(%ebp), %ecx
+0:
+        xchgl	4(%ebp), %eax /* xchg size of stack parameters and ffi_closure ctx */
+        movl	CLOSURE_CIF_OFFSET(%eax), %eax
+        movl	CIF_FLAGS_OFFSET(%eax), %eax
+
+        call	1f
+        # Do not insert anything here between the call and the jump table.
+.Lscls_store_table:
+        .long	.Lscls_noretval-.Lscls_store_table	/* FFI_TYPE_VOID */
+        .long	.Lscls_retint-.Lscls_store_table	/* FFI_TYPE_INT */
+        .long	.Lscls_retfloat-.Lscls_store_table	/* FFI_TYPE_FLOAT */
+        .long	.Lscls_retdouble-.Lscls_store_table	/* FFI_TYPE_DOUBLE */
+        .long	.Lscls_retldouble-.Lscls_store_table	/* FFI_TYPE_LONGDOUBLE */
+        .long	.Lscls_retuint8-.Lscls_store_table	/* FFI_TYPE_UINT8 */
+        .long	.Lscls_retsint8-.Lscls_store_table	/* FFI_TYPE_SINT8 */
+        .long	.Lscls_retuint16-.Lscls_store_table	/* FFI_TYPE_UINT16 */
+        .long	.Lscls_retsint16-.Lscls_store_table	/* FFI_TYPE_SINT16 */
+        .long	.Lscls_retint-.Lscls_store_table	/* FFI_TYPE_UINT32 */
+        .long	.Lscls_retint-.Lscls_store_table	/* FFI_TYPE_SINT32 */
+        .long	.Lscls_retllong-.Lscls_store_table	/* FFI_TYPE_UINT64 */
+        .long	.Lscls_retllong-.Lscls_store_table	/* FFI_TYPE_SINT64 */
+        .long	.Lscls_retstruct-.Lscls_store_table	/* FFI_TYPE_STRUCT */
+        .long	.Lscls_retint-.Lscls_store_table	/* FFI_TYPE_POINTER */
+        .long	.Lscls_retstruct1-.Lscls_store_table	/* FFI_TYPE_SMALL_STRUCT_1B */
+        .long	.Lscls_retstruct2-.Lscls_store_table	/* FFI_TYPE_SMALL_STRUCT_2B */
+        .long	.Lscls_retstruct4-.Lscls_store_table	/* FFI_TYPE_SMALL_STRUCT_4B */
+1:
+        shl	$2, %eax
+        add	(%esp),%eax
+        mov	(%eax),%eax
+        add	(%esp),%eax
+        add	$4, %esp
+        jmp	*%eax
+
+        /* Sign/zero extend as appropriate.  */
+.Lscls_retsint8:
+        movsbl	(%ecx), %eax
+        jmp	.Lscls_epilogue
+
+.Lscls_retsint16:
+        movswl	(%ecx), %eax
+        jmp	.Lscls_epilogue
+
+.Lscls_retuint8:
+        movzbl	(%ecx), %eax
+        jmp	.Lscls_epilogue
+
+.Lscls_retuint16:
+        movzwl	(%ecx), %eax
+        jmp	.Lscls_epilogue
+
+.Lscls_retint:
+        movl	(%ecx), %eax
+        jmp	.Lscls_epilogue
+
+.Lscls_retfloat:
+        flds	(%ecx)
+        jmp	.Lscls_epilogue
+
+.Lscls_retdouble:
+        fldl	(%ecx)
+        jmp	.Lscls_epilogue
+
+.Lscls_retldouble:
+        fldt	(%ecx)
+        jmp	.Lscls_epilogue
+
+.Lscls_retllong:
+        movl	(%ecx), %eax
+        movl	4(%ecx), %edx
+        jmp	.Lscls_epilogue
+
+.Lscls_retstruct1:
+        movsbl	(%ecx), %eax
+        jmp	.Lscls_epilogue
+
+.Lscls_retstruct2:
+        movswl	(%ecx), %eax
+        jmp	.Lscls_epilogue
+
+.Lscls_retstruct4:
+        movl	(%ecx), %eax
+        jmp	.Lscls_epilogue
+
+.Lscls_retstruct:
+        # Nothing to do!
+
+.Lscls_noretval:
+.Lscls_epilogue:
+        movl	%ebp, %esp
+        popl	%ebp
+        movl	4(%esp), %ecx /* Return address */
+        addl	(%esp), %esp  /* Parameters stack size */
+        addl	$8, %esp
+        jmp	*%ecx
+.ffi_closure_STDCALL_end:
+.LFE5:
+
+#if defined(X86_DARWIN)
+.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
+L_ffi_closure_SYSV_inner$stub:
+        .indirect_symbol _ffi_closure_SYSV_inner
+        hlt ; hlt ; hlt ; hlt ; hlt
+L_ffi_closure_WIN32_inner$stub:
+        .indirect_symbol _ffi_closure_WIN32_inner
+        hlt ; hlt ; hlt ; hlt ; hlt
+#endif
+
+#if defined(X86_WIN32) && !defined(__OS2__)
+        .section	.eh_frame,"w"
+#endif
+.Lframe1:
+.LSCIE1:
+        .long	.LECIE1-.LASCIE1  /* Length of Common Information Entry */
+.LASCIE1:
+        .long	0x0	/* CIE Identifier Tag */
+        .byte	0x1	/* CIE Version */
+#ifdef __PIC__
+        .ascii "zR\0"	/* CIE Augmentation */
+#else
+        .ascii "\0"	/* CIE Augmentation */
+#endif
+        .byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
+        .byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
+        .byte	0x8	/* CIE RA Column */
+#ifdef __PIC__
+        .byte	0x1	/* .uleb128 0x1; Augmentation size */
+        .byte	0x1b	/* FDE Encoding (pcrel sdata4) */
+#endif
+        .byte	0xc	/* DW_CFA_def_cfa CFA = r4 + 4 = 4(%esp) */
+        .byte	0x4	/* .uleb128 0x4 */
+        .byte	0x4	/* .uleb128 0x4 */
+        .byte	0x88	/* DW_CFA_offset, column 0x8 %eip at CFA + 1 * -4 */
+        .byte	0x1	/* .uleb128 0x1 */
+        .align 4
+.LECIE1:
+
+.LSFDE1:
+        .long	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+        .long	.LASFDE1-.Lframe1	/* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+        .long	.LFB1-.	/* FDE initial location */
+#else
+        .long	.LFB1
+#endif
+        .long	.LFE1-.LFB1	/* FDE address range */
+#ifdef __PIC__
+        .byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+        /* DW_CFA_xxx CFI instructions go here.  */
+
+        .byte	0x4	/* DW_CFA_advance_loc4 */
+        .long	.LCFI0-.LFB1
+        .byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+        .byte	0x8	/* .uleb128 0x8 */
+        .byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+        .byte	0x2	/* .uleb128 0x2 */
+
+        .byte	0x4	/* DW_CFA_advance_loc4 */
+        .long	.LCFI1-.LCFI0
+        .byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+        .byte	0x5	/* .uleb128 0x5 */
+
+        /* End of DW_CFA_xxx CFI instructions.  */
+        .align 4
+.LEFDE1:
+
+.LSFDE3:
+        .long	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+        .long	.LASFDE3-.Lframe1	/* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+        .long	.LFB3-.	/* FDE initial location */
+#else
+        .long	.LFB3
+#endif
+        .long	.LFE3-.LFB3	/* FDE address range */
+#ifdef __PIC__
+        .byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+        /* DW_CFA_xxx CFI instructions go here.  */
+
+        .byte	0x4	/* DW_CFA_advance_loc4 */
+        .long	.LCFI4-.LFB3
+        .byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+        .byte	0x8	/* .uleb128 0x8 */
+        .byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+        .byte	0x2	/* .uleb128 0x2 */
+
+        .byte	0x4	/* DW_CFA_advance_loc4 */
+        .long	.LCFI5-.LCFI4
+        .byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+        .byte	0x5	/* .uleb128 0x5 */
+
+        /* End of DW_CFA_xxx CFI instructions.  */
+        .align 4
+.LEFDE3:
+
+#if !FFI_NO_RAW_API
+
+.LSFDE4:
+        .long	.LEFDE4-.LASFDE4	/* FDE Length */
+.LASFDE4:
+        .long	.LASFDE4-.Lframe1	/* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+        .long	.LFB4-.	/* FDE initial location */
+#else
+        .long	.LFB4
+#endif
+        .long	.LFE4-.LFB4	/* FDE address range */
+#ifdef __PIC__
+        .byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+        /* DW_CFA_xxx CFI instructions go here.  */
+
+        .byte	0x4	/* DW_CFA_advance_loc4 */
+        .long	.LCFI6-.LFB4
+        .byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+        .byte	0x8	/* .uleb128 0x8 */
+        .byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+        .byte	0x2	/* .uleb128 0x2 */
+
+        .byte	0x4	/* DW_CFA_advance_loc4 */
+        .long	.LCFI7-.LCFI6
+        .byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+        .byte	0x5	/* .uleb128 0x5 */
+
+        .byte	0x4	/* DW_CFA_advance_loc4 */
+        .long	.LCFI8-.LCFI7
+        .byte	0x86	/* DW_CFA_offset, column 0x6 %esi at CFA + 3 * -4 */
+        .byte	0x3	/* .uleb128 0x3 */
+
+        /* End of DW_CFA_xxx CFI instructions.  */
+        .align 4
+.LEFDE4:
+
+#endif /* !FFI_NO_RAW_API */
+
+.LSFDE5:
+        .long	.LEFDE5-.LASFDE5	/* FDE Length */
+.LASFDE5:
+        .long	.LASFDE5-.Lframe1	/* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+        .long	.LFB5-.	/* FDE initial location */
+#else
+        .long	.LFB5
+#endif
+        .long	.LFE5-.LFB5	/* FDE address range */
+#ifdef __PIC__
+        .byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+        /* DW_CFA_xxx CFI instructions go here.  */
+
+        .byte	0x4	/* DW_CFA_advance_loc4 */
+        .long	.LCFI9-.LFB5
+        .byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+        .byte	0x8	/* .uleb128 0x8 */
+        .byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+        .byte	0x2	/* .uleb128 0x2 */
+
+        .byte	0x4	/* DW_CFA_advance_loc4 */
+        .long	.LCFI10-.LCFI9
+        .byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+        .byte	0x5	/* .uleb128 0x5 */
+
+        /* End of DW_CFA_xxx CFI instructions.  */
+        .align 4
+.LEFDE5:
+
+#endif /* !_MSC_VER */
+
+#if defined __ELF__ && defined __linux__
+        .section	.note.GNU-stack,"",@progbits
+#endif
diff --git a/src/x86/win64.S b/src/x86/win64.S
index 2c334c8..687f97c 100644
--- a/src/x86/win64.S
+++ b/src/x86/win64.S
@@ -1,237 +1,520 @@
-#ifdef __x86_64__
 #define LIBFFI_ASM
 #include <fficonfig.h>
 #include <ffi.h>
-#include <ffi_cfi.h>
-#include "asmnames.h"
 
-#if defined(HAVE_AS_CFI_PSEUDO_OP)
-        .cfi_sections   .debug_frame
-#endif
+/* Constants for ffi_call_win64 */
+#define STACK 0
+#define PREP_ARGS_FN 32
+#define ECIF 40
+#define CIF_BYTES 48
+#define CIF_FLAGS 56
+#define RVALUE 64
+#define FN 72
 
-#ifdef X86_WIN64
-#define SEH(...) __VA_ARGS__
-#define arg0	%rcx
-#define arg1	%rdx
-#define arg2	%r8
-#define arg3	%r9
+/* ffi_call_win64 (void (*prep_args_fn)(char *, extended_cif *),
+		   extended_cif *ecif, unsigned bytes, unsigned flags,
+		   unsigned *rvalue, void (*fn)());
+ */
+
+#ifdef _MSC_VER
+PUBLIC	ffi_call_win64
+
+EXTRN	__chkstk:NEAR
+EXTRN	ffi_closure_win64_inner:NEAR
+
+_TEXT	SEGMENT
+
+;;; ffi_closure_win64 will be called with these registers set:
+;;;    rax points to 'closure'
+;;;    r11 contains a bit mask that specifies which of the
+;;;    first four parameters are float or double
+;;;
+;;; It must move the parameters passed in registers to their stack location,
+;;; call ffi_closure_win64_inner for the actual work, then return the result.
+;;;
+ffi_closure_win64 PROC FRAME
+	;; copy register arguments onto stack
+	test	r11, 1
+	jne	first_is_float
+	mov	QWORD PTR [rsp+8], rcx
+	jmp	second
+first_is_float:
+	movlpd	QWORD PTR [rsp+8], xmm0
+
+second:
+	test	r11, 2
+	jne	second_is_float
+	mov	QWORD PTR [rsp+16], rdx
+	jmp	third
+second_is_float:
+	movlpd	QWORD PTR [rsp+16], xmm1
+
+third:
+	test	r11, 4
+	jne	third_is_float
+	mov	QWORD PTR [rsp+24], r8
+	jmp	fourth
+third_is_float:
+	movlpd	QWORD PTR [rsp+24], xmm2
+
+fourth:
+	test	r11, 8
+	jne	fourth_is_float
+	mov	QWORD PTR [rsp+32], r9
+	jmp	done
+fourth_is_float:
+	movlpd	QWORD PTR [rsp+32], xmm3
+
+done:
+	.ALLOCSTACK 40
+	sub	rsp, 40
+	.ENDPROLOG
+	mov	rcx, rax	; context is first parameter
+	mov	rdx, rsp	; stack is second parameter
+	add	rdx, 48		; point to start of arguments
+	mov	rax, ffi_closure_win64_inner
+	call	rax		; call the real closure function
+	add	rsp, 40
+	movd	xmm0, rax	; If the closure returned a float,
+				; ffi_closure_win64_inner wrote it to rax
+	ret	0
+ffi_closure_win64 ENDP
+
+ffi_call_win64 PROC FRAME
+	;; copy registers onto stack
+	mov	QWORD PTR [rsp+32], r9
+	mov	QWORD PTR [rsp+24], r8
+	mov	QWORD PTR [rsp+16], rdx
+	mov	QWORD PTR [rsp+8], rcx
+	.PUSHREG rbp
+	push	rbp
+	.ALLOCSTACK 48
+	sub	rsp, 48					; 00000030H
+	.SETFRAME rbp, 32
+	lea	rbp, QWORD PTR [rsp+32]
+	.ENDPROLOG
+
+	mov	eax, DWORD PTR CIF_BYTES[rbp]
+	add	rax, 15
+	and	rax, -16
+	call	__chkstk
+	sub	rsp, rax
+	lea	rax, QWORD PTR [rsp+32]
+	mov	QWORD PTR STACK[rbp], rax
+
+	mov	rdx, QWORD PTR ECIF[rbp]
+	mov	rcx, QWORD PTR STACK[rbp]
+	call	QWORD PTR PREP_ARGS_FN[rbp]
+
+	mov	rsp, QWORD PTR STACK[rbp]
+
+	movlpd	xmm3, QWORD PTR [rsp+24]
+	movd	r9, xmm3
+
+	movlpd	xmm2, QWORD PTR [rsp+16]
+	movd	r8, xmm2
+
+	movlpd	xmm1, QWORD PTR [rsp+8]
+	movd	rdx, xmm1
+
+	movlpd	xmm0, QWORD PTR [rsp]
+	movd	rcx, xmm0
+
+	call	QWORD PTR FN[rbp]
+ret_struct4b$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_4B
+ 	jne	ret_struct2b$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	mov	DWORD PTR [rcx], eax
+	jmp	ret_void$
+
+ret_struct2b$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_2B
+ 	jne	ret_struct1b$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	mov	WORD PTR [rcx], ax
+	jmp	ret_void$
+
+ret_struct1b$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_1B
+ 	jne	ret_uint8$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	mov	BYTE PTR [rcx], al
+	jmp	ret_void$
+
+ret_uint8$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT8
+ 	jne	ret_sint8$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	movzx   rax, al
+	mov	QWORD PTR [rcx], rax
+	jmp	ret_void$
+
+ret_sint8$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT8
+ 	jne	ret_uint16$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	movsx   rax, al
+	mov	QWORD PTR [rcx], rax
+	jmp	ret_void$
+
+ret_uint16$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT16
+ 	jne	ret_sint16$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	movzx   rax, ax
+	mov	QWORD PTR [rcx], rax
+	jmp	SHORT ret_void$
+
+ret_sint16$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT16
+ 	jne	ret_uint32$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	movsx   rax, ax
+	mov	QWORD PTR [rcx], rax
+	jmp	SHORT ret_void$
+
+ret_uint32$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT32
+ 	jne	ret_sint32$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	mov     eax, eax
+	mov	QWORD PTR [rcx], rax
+	jmp	SHORT ret_void$
+
+ret_sint32$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT32
+ 	jne	ret_float$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	cdqe
+	mov	QWORD PTR [rcx], rax
+	jmp	SHORT ret_void$
+
+ret_float$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_FLOAT
+ 	jne	SHORT ret_double$
+
+ 	mov	rax, QWORD PTR RVALUE[rbp]
+ 	movss	DWORD PTR [rax], xmm0
+ 	jmp	SHORT ret_void$
+
+ret_double$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_DOUBLE
+ 	jne	SHORT ret_uint64$
+
+ 	mov	rax, QWORD PTR RVALUE[rbp]
+ 	movlpd	QWORD PTR [rax], xmm0
+ 	jmp	SHORT ret_void$
+
+ret_uint64$:
+  	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT64
+  	jne	SHORT ret_sint64$
+
+ 	mov	rcx, QWORD PTR RVALUE[rbp]
+ 	mov	QWORD PTR [rcx], rax
+ 	jmp	SHORT ret_void$
+
+ret_sint64$:
+  	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT64
+  	jne	SHORT ret_pointer$
+
+ 	mov	rcx, QWORD PTR RVALUE[rbp]
+ 	mov	QWORD PTR [rcx], rax
+ 	jmp	SHORT ret_void$
+
+ret_pointer$:
+  	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_POINTER
+  	jne	SHORT ret_int$
+
+ 	mov	rcx, QWORD PTR RVALUE[rbp]
+ 	mov	QWORD PTR [rcx], rax
+ 	jmp	SHORT ret_void$
+
+ret_int$:
+  	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_INT
+  	jne	SHORT ret_void$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	cdqe
+	mov	QWORD PTR [rcx], rax
+ 	jmp	SHORT ret_void$
+
+ret_void$:
+	xor	rax, rax
+
+	lea	rsp, QWORD PTR [rbp+16]
+	pop	rbp
+	ret	0
+ffi_call_win64 ENDP
+_TEXT	ENDS
+END
+
 #else
-#define SEH(...)
-#define arg0	%rdi
-#define arg1	%rsi
-#define arg2	%rdx
-#define arg3	%rcx
-#endif
 
-/* This macro allows the safe creation of jump tables without an
-   actual table.  The entry points into the table are all 8 bytes.
-   The use of ORG asserts that we're at the correct location.  */
-/* ??? The clang assembler doesn't handle .org with symbolic expressions.  */
-#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
-# define E(BASE, X)	.balign 8
+#ifdef SYMBOL_UNDERSCORE
+#define SYMBOL_NAME(name) _##name
 #else
-# define E(BASE, X)	.balign 8; .org BASE + X * 8
+#define SYMBOL_NAME(name) name
 #endif
 
-	.text
+.text
 
-/* ffi_call_win64 (void *stack, struct win64_call_frame *frame, void *r10)
+.extern SYMBOL_NAME(ffi_closure_win64_inner)
 
-   Bit o trickiness here -- FRAME is the base of the stack frame
-   for this function.  This has been allocated by ffi_call.  We also
-   deallocate some of the stack that has been alloca'd.  */
+# ffi_closure_win64 will be called with these registers set:
+#    rax points to 'closure'
+#    r11 contains a bit mask that specifies which of the
+#    first four parameters are float or double
+#
+# It must move the parameters passed in registers to their stack location,
+# call ffi_closure_win64_inner for the actual work, then return the result.
+#
+	.balign 16
+	.globl SYMBOL_NAME(ffi_closure_win64)
+	.seh_proc SYMBOL_NAME(ffi_closure_win64)
+SYMBOL_NAME(ffi_closure_win64):
+	# copy register arguments onto stack
+	test	$1,%r11
+	jne	.Lfirst_is_float
+	mov	%rcx, 8(%rsp)
+	jmp	.Lsecond
+.Lfirst_is_float:
+	movlpd	%xmm0, 8(%rsp)
 
-	.align	8
-	.globl	C(ffi_call_win64)
-	FFI_HIDDEN(C(ffi_call_win64))
+.Lsecond:
+	test	$2, %r11
+	jne	.Lsecond_is_float
+	mov	%rdx, 16(%rsp)
+	jmp	.Lthird
+.Lsecond_is_float:
+	movlpd	%xmm1, 16(%rsp)
 
-	SEH(.seh_proc ffi_call_win64)
-C(ffi_call_win64):
-	cfi_startproc
-	/* Set up the local stack frame and install it in rbp/rsp.  */
-	movq	(%rsp), %rax
-	movq	%rbp, (arg1)
-	movq	%rax, 8(arg1)
-	movq	arg1, %rbp
-	cfi_def_cfa(%rbp, 16)
-	cfi_rel_offset(%rbp, 0)
-	SEH(.seh_pushreg %rbp)
-	SEH(.seh_setframe %rbp, 0)
-	SEH(.seh_endprologue)
-	movq	arg0, %rsp
+.Lthird:
+	test	$4, %r11
+	jne	.Lthird_is_float
+	mov	%r8,24(%rsp)
+	jmp	.Lfourth
+.Lthird_is_float:
+	movlpd	%xmm2, 24(%rsp)
 
-	movq	arg2, %r10
+.Lfourth:
+	test	$8, %r11
+	jne	.Lfourth_is_float
+	mov	%r9, 32(%rsp)
+	jmp	.Ldone
+.Lfourth_is_float:
+	movlpd	%xmm3, 32(%rsp)
 
-	/* Load all slots into both general and xmm registers.  */
-	movq	(%rsp), %rcx
-	movsd	(%rsp), %xmm0
-	movq	8(%rsp), %rdx
-	movsd	8(%rsp), %xmm1
-	movq	16(%rsp), %r8
-	movsd	16(%rsp), %xmm2
-	movq	24(%rsp), %r9
-	movsd	24(%rsp), %xmm3
+.Ldone:
+	.seh_stackalloc 40
+	sub	$40, %rsp
+	.seh_endprologue
+	mov	%rax, %rcx	# context is first parameter
+	mov	%rsp, %rdx	# stack is second parameter
+	add	$48, %rdx	# point to start of arguments
+	leaq	SYMBOL_NAME(ffi_closure_win64_inner)(%rip), %rax
+	callq	*%rax		# call the real closure function
+	add	$40, %rsp
+	movq	%rax, %xmm0	# If the closure returned a float,
+				# ffi_closure_win64_inner wrote it to rax
+	retq
+	.seh_endproc
 
-	call	*16(%rbp)
+	.balign 16
+	.globl	SYMBOL_NAME(ffi_call_win64)
+	.seh_proc SYMBOL_NAME(ffi_call_win64)
+SYMBOL_NAME(ffi_call_win64):
+	# copy registers onto stack
+	mov	%r9,32(%rsp)
+	mov	%r8,24(%rsp)
+	mov	%rdx,16(%rsp)
+	mov	%rcx,8(%rsp)
+	.seh_pushreg rbp
+	push	%rbp
+	.seh_stackalloc 48
+	sub	$48,%rsp
+	.seh_setframe rbp, 32
+	lea	32(%rsp),%rbp
+	.seh_endprologue
 
-	movl	24(%rbp), %ecx
-	movq	32(%rbp), %r8
-	leaq	0f(%rip), %r10
-	cmpl	$FFI_TYPE_SMALL_STRUCT_4B, %ecx
-	leaq	(%r10, %rcx, 8), %r10
-	ja	99f
-	jmp	*%r10
+	mov	CIF_BYTES(%rbp),%eax
+	add	$15, %rax
+	and	$-16, %rax
+	cmpq	$0x1000, %rax
+	jb	Lch_done
+Lch_probe:
+	subq	$0x1000,%rsp
+	orl	$0x0, (%rsp)
+	subq	$0x1000,%rax
+	cmpq	$0x1000,%rax
+	ja	Lch_probe
+Lch_done:
+	subq	%rax, %rsp
+	orl	$0x0, (%rsp)
+	lea	32(%rsp), %rax
+	mov	%rax, STACK(%rbp)
 
-/* Below, we're space constrained most of the time.  Thus we eschew the
-   modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes).  */
-.macro epilogue
-	leaveq
-	cfi_remember_state
-	cfi_def_cfa(%rsp, 8)
-	cfi_restore(%rbp)
-	ret
-	cfi_restore_state
-.endm
+	mov	ECIF(%rbp), %rdx
+	mov	STACK(%rbp), %rcx
+	callq	*PREP_ARGS_FN(%rbp)
 
-	.align	8
-0:
-E(0b, FFI_TYPE_VOID)
-	epilogue
-E(0b, FFI_TYPE_INT)
-	movslq	%eax, %rax
-	movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_FLOAT)
-	movss	%xmm0, (%r8)
-	epilogue
-E(0b, FFI_TYPE_DOUBLE)
-	movsd	%xmm0, (%r8)
-	epilogue
-E(0b, FFI_TYPE_LONGDOUBLE)
-	call	PLT(C(abort))
-E(0b, FFI_TYPE_UINT8)
-	movzbl	%al, %eax
-	movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SINT8)
-	movsbq	%al, %rax
-	jmp	98f
-E(0b, FFI_TYPE_UINT16)
-	movzwl	%ax, %eax
-	movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SINT16)
-	movswq	%ax, %rax
-	jmp	98f
-E(0b, FFI_TYPE_UINT32)
-	movl	%eax, %eax
-	movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SINT32)
-	movslq	%eax, %rax
-	movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_UINT64)
-98:	movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SINT64)
-	movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_STRUCT)
-	epilogue
-E(0b, FFI_TYPE_POINTER)
-	movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_COMPLEX)
-	call	PLT(C(abort))
-E(0b, FFI_TYPE_SMALL_STRUCT_1B)
-	movb	%al, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SMALL_STRUCT_2B)
-	movw	%ax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SMALL_STRUCT_4B)
-	movl	%eax, (%r8)
-	epilogue
+	mov	STACK(%rbp), %rsp
 
-	.align	8
-99:	call	PLT(C(abort))
+	movlpd	24(%rsp), %xmm3
+	movd	%xmm3, %r9
 
-	epilogue
+	movlpd	16(%rsp), %xmm2
+	movd	%xmm2, %r8
 
-	cfi_endproc
-	SEH(.seh_endproc)
+	movlpd	8(%rsp), %xmm1
+	movd	%xmm1, %rdx
 
+	movlpd	(%rsp), %xmm0
+	movd	%xmm0, %rcx
 
-/* 32 bytes of outgoing register stack space, 8 bytes of alignment,
-   16 bytes of result, 32 bytes of xmm registers.  */
-#define ffi_clo_FS	(32+8+16+32)
-#define ffi_clo_OFF_R	(32+8)
-#define ffi_clo_OFF_X	(32+8+16)
+	callq	*FN(%rbp)
+.Lret_struct4b:
+ 	cmpl	$FFI_TYPE_SMALL_STRUCT_4B, CIF_FLAGS(%rbp)
+ 	jne .Lret_struct2b
 
-	.align	8
-	.globl	C(ffi_go_closure_win64)
-	FFI_HIDDEN(C(ffi_go_closure_win64))
+	mov	RVALUE(%rbp), %rcx
+	mov	%eax, (%rcx)
+	jmp	.Lret_void
 
-	SEH(.seh_proc ffi_go_closure_win64)
-C(ffi_go_closure_win64):
-	cfi_startproc
-	/* Save all integer arguments into the incoming reg stack space.  */
-	movq	%rcx, 8(%rsp)
-	movq	%rdx, 16(%rsp)
-	movq	%r8, 24(%rsp)
-	movq	%r9, 32(%rsp)
+.Lret_struct2b:
+	cmpl	$FFI_TYPE_SMALL_STRUCT_2B, CIF_FLAGS(%rbp)
+	jne .Lret_struct1b
 
-	movq	8(%r10), %rcx			/* load cif */
-	movq	16(%r10), %rdx			/* load fun */
-	movq	%r10, %r8			/* closure is user_data */
-	jmp	0f
-	cfi_endproc
-	SEH(.seh_endproc)
+	mov	RVALUE(%rbp), %rcx
+	mov	%ax, (%rcx)
+	jmp .Lret_void
 
-	.align	8
-	.globl	C(ffi_closure_win64)
-	FFI_HIDDEN(C(ffi_closure_win64))
+.Lret_struct1b:
+	cmpl	$FFI_TYPE_SMALL_STRUCT_1B, CIF_FLAGS(%rbp)
+	jne .Lret_uint8
 
-	SEH(.seh_proc ffi_closure_win64)
-C(ffi_closure_win64):
-	cfi_startproc
-	/* Save all integer arguments into the incoming reg stack space.  */
-	movq	%rcx, 8(%rsp)
-	movq	%rdx, 16(%rsp)
-	movq	%r8, 24(%rsp)
-	movq	%r9, 32(%rsp)
+	mov	RVALUE(%rbp), %rcx
+	mov	%al, (%rcx)
+	jmp .Lret_void
 
-	movq	FFI_TRAMPOLINE_SIZE(%r10), %rcx		/* load cif */
-	movq	FFI_TRAMPOLINE_SIZE+8(%r10), %rdx	/* load fun */
-	movq	FFI_TRAMPOLINE_SIZE+16(%r10), %r8	/* load user_data */
-0:
-	subq	$ffi_clo_FS, %rsp
-	cfi_adjust_cfa_offset(ffi_clo_FS)
-	SEH(.seh_stackalloc ffi_clo_FS)
-	SEH(.seh_endprologue)
+.Lret_uint8:
+	cmpl	$FFI_TYPE_UINT8, CIF_FLAGS(%rbp)
+	jne .Lret_sint8
 
-	/* Save all sse arguments into the stack frame.  */
-	movsd	%xmm0, ffi_clo_OFF_X(%rsp)
-	movsd	%xmm1, ffi_clo_OFF_X+8(%rsp)
-	movsd	%xmm2, ffi_clo_OFF_X+16(%rsp)
-	movsd	%xmm3, ffi_clo_OFF_X+24(%rsp)
+	mov     RVALUE(%rbp), %rcx
+	movzbq  %al, %rax
+	movq    %rax, (%rcx)
+	jmp .Lret_void
 
-	leaq	ffi_clo_OFF_R(%rsp), %r9
-	call	PLT(C(ffi_closure_win64_inner))
+.Lret_sint8:
+	cmpl	$FFI_TYPE_SINT8, CIF_FLAGS(%rbp)
+	jne .Lret_uint16
 
-	/* Load the result into both possible result registers.  */
-	movq    ffi_clo_OFF_R(%rsp), %rax
-	movsd   ffi_clo_OFF_R(%rsp), %xmm0
+	mov     RVALUE(%rbp), %rcx
+	movsbq  %al, %rax
+	movq    %rax, (%rcx)
+	jmp .Lret_void
 
-	addq	$ffi_clo_FS, %rsp
-	cfi_adjust_cfa_offset(-ffi_clo_FS)
-	ret
+.Lret_uint16:
+	cmpl	$FFI_TYPE_UINT16, CIF_FLAGS(%rbp)
+	jne .Lret_sint16
 
-	cfi_endproc
-	SEH(.seh_endproc)
-#endif /* __x86_64__ */
+	mov     RVALUE(%rbp), %rcx
+	movzwq  %ax, %rax
+	movq    %rax, (%rcx)
+	jmp .Lret_void
 
-#if defined __ELF__ && defined __linux__
-	.section	.note.GNU-stack,"",@progbits
-#endif
+.Lret_sint16:
+	cmpl	$FFI_TYPE_SINT16, CIF_FLAGS(%rbp)
+	jne .Lret_uint32
+
+	mov     RVALUE(%rbp), %rcx
+	movswq  %ax, %rax
+	movq    %rax, (%rcx)
+	jmp .Lret_void
+
+.Lret_uint32:
+	cmpl	$FFI_TYPE_UINT32, CIF_FLAGS(%rbp)
+	jne .Lret_sint32
+
+	mov     RVALUE(%rbp), %rcx
+	movl    %eax, %eax
+	movq    %rax, (%rcx)
+	jmp .Lret_void
+
+.Lret_sint32:
+ 	cmpl	$FFI_TYPE_SINT32, CIF_FLAGS(%rbp)
+ 	jne	.Lret_float
+
+	mov	RVALUE(%rbp), %rcx
+	cltq
+	movq	%rax, (%rcx)
+	jmp	.Lret_void
+
+.Lret_float:
+ 	cmpl	$FFI_TYPE_FLOAT, CIF_FLAGS(%rbp)
+ 	jne	.Lret_double
+
+ 	mov	RVALUE(%rbp), %rax
+ 	movss	%xmm0, (%rax)
+ 	jmp	.Lret_void
+
+.Lret_double:
+ 	cmpl	$FFI_TYPE_DOUBLE, CIF_FLAGS(%rbp)
+ 	jne	.Lret_uint64
+
+ 	mov	RVALUE(%rbp), %rax
+ 	movlpd	%xmm0, (%rax)
+ 	jmp	.Lret_void
+
+.Lret_uint64:
+  	cmpl	$FFI_TYPE_UINT64, CIF_FLAGS(%rbp)
+ 	jne	.Lret_sint64
+
+ 	mov	RVALUE(%rbp), %rcx
+ 	mov	%rax, (%rcx)
+ 	jmp	.Lret_void
+
+.Lret_sint64:
+  	cmpl	$FFI_TYPE_SINT64, CIF_FLAGS(%rbp)
+  	jne	.Lret_pointer
+
+ 	mov	RVALUE(%rbp), %rcx
+ 	mov	%rax, (%rcx)
+ 	jmp	.Lret_void
+
+.Lret_pointer:
+  	cmpl	$FFI_TYPE_POINTER, CIF_FLAGS(%rbp)
+  	jne	.Lret_int
+
+ 	mov	RVALUE(%rbp), %rcx
+ 	mov	%rax, (%rcx)
+ 	jmp	.Lret_void
+
+.Lret_int:
+  	cmpl	$FFI_TYPE_INT, CIF_FLAGS(%rbp)
+  	jne	.Lret_void
+
+	mov	RVALUE(%rbp), %rcx
+	cltq
+	movq	%rax, (%rcx)
+	jmp	.Lret_void
+
+.Lret_void:
+	xor	%rax, %rax
+
+	lea	16(%rbp), %rsp
+	pop	%rbp
+	retq
+	.seh_endproc
+#endif /* !_MSC_VER */
+
diff --git a/src/x86/win64_intel.S b/src/x86/win64_intel.S
deleted file mode 100644
index 7df78b3..0000000
--- a/src/x86/win64_intel.S
+++ /dev/null
@@ -1,237 +0,0 @@
-#define LIBFFI_ASM
-#include <fficonfig.h>
-#include <ffi.h>
-#include <ffi_cfi.h>
-#include "asmnames.h"
-
-#if defined(HAVE_AS_CFI_PSEUDO_OP)
-        .cfi_sections   .debug_frame
-#endif
-
-#ifdef X86_WIN64
-#define SEH(...) __VA_ARGS__
-#define arg0	rcx
-#define arg1	rdx
-#define arg2	r8
-#define arg3	r9
-#else
-#define SEH(...)
-#define arg0	rdi
-#define arg1	rsi
-#define arg2	rdx
-#define arg3	rcx
-#endif
-
-/* This macro allows the safe creation of jump tables without an
-   actual table.  The entry points into the table are all 8 bytes.
-   The use of ORG asserts that we're at the correct location.  */
-/* ??? The clang assembler doesn't handle .org with symbolic expressions.  */
-#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
-# define E(BASE, X)	ALIGN 8
-#else
-# define E(BASE, X)	ALIGN 8; ORG BASE + X * 8
-#endif
-
-	.CODE
-	extern PLT(C(abort)):near
-	extern C(ffi_closure_win64_inner):near
-
-/* ffi_call_win64 (void *stack, struct win64_call_frame *frame, void *r10)
-
-   Bit o trickiness here -- FRAME is the base of the stack frame
-   for this function.  This has been allocated by ffi_call.  We also
-   deallocate some of the stack that has been alloca'd.  */
-
-	ALIGN	8
-	PUBLIC	C(ffi_call_win64)
-
-	; SEH(.safesh ffi_call_win64)
-C(ffi_call_win64) proc SEH(frame)
-	cfi_startproc
-	/* Set up the local stack frame and install it in rbp/rsp.  */
-	mov	RAX, [RSP] ; 	movq	(%rsp), %rax
-	mov [arg1], RBP ; movq	%rbp, (arg1)
-	mov [arg1 + 8], RAX;	movq	%rax, 8(arg1)
-	mov	 RBP, arg1; movq	arg1, %rbp
-	cfi_def_cfa(rbp, 16)
-	cfi_rel_offset(rbp, 0)
-	SEH(.pushreg rbp)
-	SEH(.setframe rbp, 0)
-	SEH(.endprolog)
-	mov	RSP, arg0 ;	movq	arg0, %rsp
-
-	mov	R10, arg2 ; movq	arg2, %r10
-
-	/* Load all slots into both general and xmm registers.  */
-	mov	RCX, [RSP] ;	movq	(%rsp), %rcx
-	movsd XMM0, qword ptr [RSP] ; movsd	(%rsp), %xmm0
-	mov	RDX, [RSP + 8] ;movq	8(%rsp), %rdx
-	movsd XMM1, qword ptr [RSP + 8];	movsd	8(%rsp), %xmm1
-	mov R8, [RSP + 16] ; movq	16(%rsp), %r8
-	movsd	XMM2, qword ptr [RSP + 16] ; movsd	16(%rsp), %xmm2
-	mov	R9, [RSP + 24] ; movq	24(%rsp), %r9
-	movsd	XMM3, qword ptr [RSP + 24] ;movsd	24(%rsp), %xmm3
-
-	CALL qword ptr [RBP + 16] ; call	*16(%rbp)
-
-	mov	 ECX, [RBP + 24] ; movl	24(%rbp), %ecx
-	mov	R8, [RBP + 32] ; movq	32(%rbp), %r8
-	LEA	R10, ffi_call_win64_tab ; leaq	0f(%rip), %r10
-	CMP	ECX, FFI_TYPE_SMALL_STRUCT_4B ; cmpl	$FFI_TYPE_SMALL_STRUCT_4B, %ecx
-	LEA	R10, [R10 + RCX*8] ; leaq	(%r10, %rcx, 8), %r10
-	JA	L99 ; ja	99f
-	JMP	R10 ; jmp	*%r10
-
-/* Below, we're space constrained most of the time.  Thus we eschew the
-   modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes).  */
-epilogue macro
-	LEAVE
-	cfi_remember_state
-	cfi_def_cfa(rsp, 8)
-	cfi_restore(rbp)
-	RET
-	cfi_restore_state
-endm
-
-	ALIGN 8
-ffi_call_win64_tab LABEL NEAR
-E(0b, FFI_TYPE_VOID)
-	epilogue
-E(0b, FFI_TYPE_INT)
-	movsxd rax, eax ; movslq	%eax, %rax
-	mov qword ptr [r8], rax; movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_FLOAT)
-	movss dword ptr [r8], xmm0 ; movss	%xmm0, (%r8)
-	epilogue
-E(0b, FFI_TYPE_DOUBLE)
-	movsd qword ptr[r8], xmm0; movsd	%xmm0, (%r8)
-	epilogue
-E(0b, FFI_TYPE_LONGDOUBLE)
-	call	PLT(C(abort))
-E(0b, FFI_TYPE_UINT8)
-	movzx eax, al ;movzbl	%al, %eax
-	mov qword ptr[r8], rax; movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SINT8)
-	movsx rax, al ; movsbq	%al, %rax
-	jmp	L98
-E(0b, FFI_TYPE_UINT16)
-	movzx eax, ax ; movzwl	%ax, %eax
-	mov qword ptr[r8], rax; movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SINT16)
-	movsx rax, ax; movswq	%ax, %rax
-	jmp	L98
-E(0b, FFI_TYPE_UINT32)
-	mov eax, eax; movl	%eax, %eax
-	mov qword ptr[r8], rax ; movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SINT32)
-	movsxd rax, eax; movslq	%eax, %rax
-	mov qword ptr [r8], rax; movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_UINT64)
-L98 LABEL near
-	mov qword ptr [r8], rax ; movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SINT64)
-	mov qword ptr [r8], rax;movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_STRUCT)
-	epilogue
-E(0b, FFI_TYPE_POINTER)
-	mov qword ptr [r8], rax ;movq	%rax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_COMPLEX)
-	call	PLT(C(abort))
-E(0b, FFI_TYPE_SMALL_STRUCT_1B)
-	mov byte ptr [r8], al ; movb	%al, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SMALL_STRUCT_2B)
-	mov word ptr [r8], ax ; movw	%ax, (%r8)
-	epilogue
-E(0b, FFI_TYPE_SMALL_STRUCT_4B)
-	mov dword ptr [r8], eax ; movl	%eax, (%r8)
-	epilogue
-
-	align	8
-L99 LABEL near
-	call	PLT(C(abort))
-
-	epilogue
-
-	cfi_endproc
-	C(ffi_call_win64) endp
-
-
-/* 32 bytes of outgoing register stack space, 8 bytes of alignment,
-   16 bytes of result, 32 bytes of xmm registers.  */
-#define ffi_clo_FS	(32+8+16+32)
-#define ffi_clo_OFF_R	(32+8)
-#define ffi_clo_OFF_X	(32+8+16)
-
-	align	8
-	PUBLIC	C(ffi_go_closure_win64)
-
-C(ffi_go_closure_win64) proc
-	cfi_startproc
-	/* Save all integer arguments into the incoming reg stack space.  */
-	mov qword ptr [rsp + 8], rcx; movq	%rcx, 8(%rsp)
-	mov qword ptr [rsp + 16], rdx; movq	%rdx, 16(%rsp)
-	mov qword ptr [rsp + 24], r8; movq	%r8, 24(%rsp)
-	mov qword ptr [rsp + 32], r9 ;movq	%r9, 32(%rsp)
-
-	mov rcx, qword ptr [r10 + 8]; movq	8(%r10), %rcx			/* load cif */
-	mov rdx, qword ptr [r10 + 16];  movq	16(%r10), %rdx			/* load fun */
-	mov r8, r10 ; movq	%r10, %r8			/* closure is user_data */
-	jmp	ffi_closure_win64_2
-	cfi_endproc
-	C(ffi_go_closure_win64) endp
-
-	align	8
-	
-PUBLIC C(ffi_closure_win64)
-C(ffi_closure_win64) PROC FRAME
-	cfi_startproc
-	/* Save all integer arguments into the incoming reg stack space.  */
-	mov qword ptr [rsp + 8], rcx; movq	%rcx, 8(%rsp)
-	mov qword ptr [rsp + 16], rdx;	movq	%rdx, 16(%rsp)
-	mov qword ptr [rsp + 24], r8; 	movq	%r8, 24(%rsp)
-	mov qword ptr [rsp + 32], r9;	movq	%r9, 32(%rsp)
-
-	mov rcx, qword ptr [FFI_TRAMPOLINE_SIZE + r10]	;movq	FFI_TRAMPOLINE_SIZE(%r10), %rcx		/* load cif */
-	mov rdx, qword ptr [FFI_TRAMPOLINE_SIZE + 8 + r10] ;	movq	FFI_TRAMPOLINE_SIZE+8(%r10), %rdx	/* load fun */
-	mov r8, qword ptr [FFI_TRAMPOLINE_SIZE+16+r10] ;movq	FFI_TRAMPOLINE_SIZE+16(%r10), %r8	/* load user_data */
-ffi_closure_win64_2 LABEL near
-	sub rsp, ffi_clo_FS ;subq	$ffi_clo_FS, %rsp
-	cfi_adjust_cfa_offset(ffi_clo_FS)
-	SEH(.allocstack ffi_clo_FS)
-	SEH(.endprolog)
-
-	/* Save all sse arguments into the stack frame.  */
-	movsd qword ptr [ffi_clo_OFF_X + rsp], xmm0	; movsd	%xmm0, ffi_clo_OFF_X(%rsp)
-	movsd qword ptr [ffi_clo_OFF_X+8+rsp], xmm1 ; movsd	%xmm1, ffi_clo_OFF_X+8(%rsp)
-	movsd qword ptr [ffi_clo_OFF_X+16+rsp], xmm2 ; movsd %xmm2, ffi_clo_OFF_X+16(%rsp)
-	movsd qword ptr [ffi_clo_OFF_X+24+rsp], xmm3 ; movsd %xmm3, ffi_clo_OFF_X+24(%rsp)
-
-	lea	r9, [ffi_clo_OFF_R + rsp] ; leaq	ffi_clo_OFF_R(%rsp), %r9
-	call C(ffi_closure_win64_inner)
-
-	/* Load the result into both possible result registers.  */
-	
-	mov rax, qword ptr [ffi_clo_OFF_R + rsp] ;movq    ffi_clo_OFF_R(%rsp), %rax
-	movsd xmm0, qword ptr [rsp + ffi_clo_OFF_R] ;movsd   ffi_clo_OFF_R(%rsp), %xmm0
-
-	add rsp, ffi_clo_FS ;addq	$ffi_clo_FS, %rsp
-	cfi_adjust_cfa_offset(-ffi_clo_FS)
-	ret
-
-	cfi_endproc
-	C(ffi_closure_win64) endp
-
-#if defined __ELF__ && defined __linux__
-	.section	.note.GNU-stack,"",@progbits
-#endif
-_text ends
-end
\ No newline at end of file
diff --git a/src/xtensa/ffi.c b/src/xtensa/ffi.c
index 9a0575f..fd94daf 100644
--- a/src/xtensa/ffi.c
+++ b/src/xtensa/ffi.c
@@ -89,7 +89,7 @@
   /* Round the stack up to a full 4 register frame, just in case
      (we use this size in movsp). This way, it's also a  multiple of
      8 bytes for 64-bit arguments.  */
-  cif->bytes = FFI_ALIGN(cif->bytes, 16);
+  cif->bytes = ALIGN(cif->bytes, 16);
 
   return FFI_OK;
 }
@@ -205,7 +205,7 @@
 
   if (flags == FFI_TYPE_STRUCT && (rsize <= 16 || rvalue == NULL))
   {
-    alloc = alloca(FFI_ALIGN(rsize, 4));
+    alloc = alloca(ALIGN(rsize, 4));
     ecif.rvalue = alloc;
   }
   else
diff --git a/src/xtensa/sysv.S b/src/xtensa/sysv.S
index e942179..64e6a09 100644
--- a/src/xtensa/sysv.S
+++ b/src/xtensa/sysv.S
@@ -169,13 +169,8 @@
 
 	entry	a1, 16
 
-1:	
-#if XCHAL_DCACHE_SIZE
-	dhwbi	a2, 0
-#endif
-#if XCHAL_ICACHE_SIZE
+1:	dhwbi	a2, 0
 	ihi	a2, 0
-#endif
 	addi	a2, a2, 4
 	blt	a2, a3, 1b
 
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index bcfea57..da10465 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -6,117 +6,80 @@
 
 CLEANFILES = *.exe core* *.log *.sum
 
-EXTRA_DIST = lib/target-libpath.exp lib/libffi.exp lib/wrapper.exp \
-libffi.call/strlen4.c libffi.call/struct10.c libffi.call/many_mixed.c \
-libffi.call/float.c libffi.call/struct5.c libffi.call/return_fl3.c \
-libffi.call/return_fl1.c libffi.call/call.exp libffi.call/pyobjc-tc.c \
-libffi.call/float_va.c libffi.call/struct8.c libffi.call/pr1172638.c \
-libffi.call/return_sc.c libffi.call/va_struct1.c \
-libffi.call/align_stdcall.c libffi.call/struct9.c libffi.call/va_1.c \
-libffi.call/va_struct2.c libffi.call/return_fl2.c \
-libffi.call/align_mixed.c libffi.call/ffitest.h libffi.call/struct4.c \
-libffi.call/return_ldl.c libffi.call/float3.c libffi.call/return_sl.c \
-libffi.call/return_dbl1.c libffi.call/err_bad_typedef.c \
-libffi.call/return_ll1.c libffi.call/return_dbl2.c \
-libffi.call/negint.c libffi.closures/nested_struct3.c \
-libffi.call/struct2.c libffi.call/struct3.c libffi.call/return_fl.c \
-libffi.call/offsets.c libffi.call/struct7.c libffi.call/va_struct3.c \
-libffi.call/float1.c libffi.call/uninitialized.c libffi.call/many2.c \
-libffi.call/struct6.c libffi.call/strlen2.c libffi.call/float2.c \
-libffi.call/return_ul.c libffi.call/struct1.c libffi.call/strlen3.c \
-libffi.call/return_dbl.c libffi.call/float4.c libffi.call/many.c \
-libffi.call/strlen.c libffi.call/return_uc.c libffi.call/many_double.c \
-libffi.call/return_ll.c libffi.call/promotion.c \
-libffi.complex/complex_defs_longdouble.inc \
-libffi.complex/cls_align_complex_float.c \
-libffi.complex/cls_complex_va_float.c \
-libffi.complex/cls_complex_struct_float.c \
-libffi.complex/return_complex2_longdouble.c \
-libffi.complex/cls_complex_float.c \
-libffi.complex/return_complex_longdouble.c \
-libffi.complex/return_complex2_float.c libffi.complex/cls_complex.inc \
-libffi.complex/cls_complex_va_longdouble.c \
-libffi.complex/return_complex_double.c \
-libffi.complex/return_complex.inc libffi.complex/many_complex.inc \
-libffi.complex/complex_float.c libffi.complex/cls_align_complex.inc \
-libffi.complex/return_complex2_double.c \
-libffi.complex/many_complex_float.c libffi.complex/ffitest.h \
-libffi.complex/return_complex1_double.c \
-libffi.complex/cls_complex_struct_longdouble.c \
-libffi.complex/complex_defs_double.inc \
-libffi.complex/cls_complex_va_double.c \
-libffi.complex/many_complex_double.c \
-libffi.complex/return_complex2.inc \
-libffi.complex/return_complex1_float.c \
-libffi.complex/complex_longdouble.c \
-libffi.complex/complex_defs_float.inc \
-libffi.complex/cls_complex_double.c \
-libffi.complex/cls_align_complex_double.c \
-libffi.complex/cls_align_complex_longdouble.c \
-libffi.complex/complex_double.c libffi.complex/cls_complex_va.inc \
-libffi.complex/many_complex_longdouble.c libffi.complex/complex.inc \
-libffi.complex/return_complex1_longdouble.c \
-libffi.complex/complex_int.c libffi.complex/cls_complex_longdouble.c \
-libffi.complex/cls_complex_struct_double.c \
-libffi.complex/return_complex1.inc libffi.complex/complex.exp \
-libffi.complex/cls_complex_struct.inc \
-libffi.complex/return_complex_float.c libffi.go/closure1.c \
-libffi.go/aa-direct.c libffi.go/ffitest.h libffi.go/go.exp \
-libffi.go/static-chain.h libffi.bhaible/bhaible.exp \
-libffi.bhaible/test-call.c libffi.bhaible/alignof.h \
-libffi.bhaible/testcases.c libffi.bhaible/test-callback.c \
-libffi.bhaible/Makefile libffi.bhaible/README config/default.exp \
-libffi.closures/cls_multi_sshort.c \
-libffi.closures/cls_align_longdouble_split2.c \
-libffi.closures/cls_1_1byte.c libffi.closures/cls_uint_va.c \
-libffi.closures/cls_3_1byte.c libffi.closures/cls_many_mixed_args.c \
-libffi.closures/cls_20byte1.c libffi.closures/cls_pointer_stack.c \
-libffi.closures/cls_align_float.c libffi.closures/cls_5_1_byte.c \
-libffi.closures/cls_9byte1.c libffi.closures/cls_align_uint32.c \
-libffi.closures/stret_medium.c libffi.closures/cls_3byte1.c \
-libffi.closures/cls_align_uint64.c libffi.closures/cls_longdouble_va.c \
-libffi.closures/cls_align_pointer.c libffi.closures/cls_19byte.c \
-libffi.closures/cls_ushort.c libffi.closures/cls_align_sint32.c \
-libffi.closures/cls_ulonglong.c libffi.closures/cls_struct_va1.c \
-libffi.closures/cls_9byte2.c libffi.closures/closure_fn5.c \
-libffi.closures/cls_5byte.c libffi.closures/cls_3float.c \
-libffi.closures/closure.exp libffi.closures/cls_schar.c \
-libffi.closures/closure_fn4.c libffi.closures/cls_uchar_va.c \
-libffi.closures/closure_fn0.c libffi.closures/huge_struct.c \
-libffi.closures/cls_ushort_va.c \
-libffi.closures/cls_64byte.c libffi.closures/cls_longdouble.c \
-libffi.closures/cls_ulong_va.c libffi.closures/cls_6_1_byte.c \
-libffi.closures/cls_align_uint16.c libffi.closures/closure_fn2.c \
-libffi.closures/unwindtest_ffi_call.cc \
-libffi.closures/cls_multi_ushortchar.c libffi.closures/cls_8byte.c \
-libffi.closures/ffitest.h libffi.closures/nested_struct8.c \
-libffi.closures/cls_pointer.c libffi.closures/nested_struct2.c \
-libffi.closures/nested_struct.c libffi.closures/cls_multi_schar.c \
-libffi.closures/cls_align_longdouble_split.c \
-libffi.closures/cls_uchar.c libffi.closures/nested_struct9.c \
-libffi.closures/cls_float.c libffi.closures/stret_medium2.c \
-libffi.closures/closure_loc_fn0.c libffi.closures/cls_6byte.c \
-libffi.closures/closure_simple.c libffi.closures/cls_align_double.c \
-libffi.closures/cls_multi_uchar.c libffi.closures/cls_4_1byte.c \
-libffi.closures/closure_fn3.c libffi.closures/cls_align_sint64.c \
-libffi.closures/nested_struct1.c libffi.closures/unwindtest.cc \
-libffi.closures/nested_struct5.c libffi.closures/cls_multi_ushort.c \
-libffi.closures/nested_struct11.c \
-libffi.closures/cls_multi_sshortchar.c \
-libffi.closures/cls_align_longdouble.c \
-libffi.closures/cls_dbls_struct.c \
-libffi.closures/cls_many_mixed_float_double.c \
-libffi.closures/stret_large.c libffi.closures/stret_large2.c \
-libffi.closures/cls_align_sint16.c libffi.closures/cls_2byte.c \
-libffi.closures/nested_struct4.c libffi.closures/problem1.c \
-libffi.closures/testclosure.c libffi.closures/nested_struct6.c \
-libffi.closures/cls_4byte.c libffi.closures/cls_24byte.c \
-libffi.closures/nested_struct10.c libffi.closures/cls_uint.c \
-libffi.closures/cls_12byte.c libffi.closures/cls_sint.c \
-libffi.closures/cls_7_1_byte.c libffi.closures/cls_sshort.c \
-libffi.closures/cls_16byte.c libffi.closures/nested_struct7.c \
-libffi.closures/cls_double_va.c libffi.closures/cls_3byte2.c \
-libffi.closures/cls_double.c libffi.closures/cls_7byte.c \
-libffi.closures/closure_fn6.c libffi.closures/closure_fn1.c \
-libffi.closures/cls_20byte.c libffi.closures/cls_18byte.c \
-libffi.closures/err_bad_abi.c
+EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c		\
+libffi.call/cls_align_longdouble_split.c				\
+libffi.call/closure_loc_fn0.c libffi.call/cls_schar.c			\
+libffi.call/closure_fn1.c \
+libffi.call/return_ul.c libffi.call/cls_align_double.c			\
+libffi.call/return_fl2.c libffi.call/cls_1_1byte.c			\
+libffi.call/cls_64byte.c libffi.call/nested_struct7.c			\
+libffi.call/cls_align_sint32.c libffi.call/nested_struct2.c		\
+libffi.call/ffitest.h libffi.call/nested_struct4.c			\
+libffi.call/cls_multi_ushort.c libffi.call/struct3.c			\
+libffi.call/cls_3byte1.c libffi.call/cls_16byte.c			\
+libffi.call/struct8.c libffi.call/nested_struct8.c			\
+libffi.call/cls_multi_sshort.c libffi.call/cls_3byte2.c			\
+libffi.call/cls_pointer.c			\
+libffi.call/err_bad_typedef.c libffi.call/cls_4_1byte.c			\
+libffi.call/cls_9byte2.c libffi.call/cls_multi_schar.c			\
+libffi.call/stret_medium2.c libffi.call/cls_5_1_byte.c			\
+libffi.call/call.exp libffi.call/cls_double.c				\
+libffi.call/cls_align_sint16.c libffi.call/cls_uint.c			\
+libffi.call/return_ll1.c libffi.call/nested_struct3.c			\
+libffi.call/cls_20byte1.c libffi.call/closure_fn4.c			\
+libffi.call/cls_uchar.c libffi.call/struct2.c libffi.call/cls_7byte.c	\
+libffi.call/strlen.c libffi.call/many.c libffi.call/testclosure.c	\
+libffi.call/return_fl.c libffi.call/struct5.c				\
+libffi.call/cls_12byte.c libffi.call/cls_multi_sshortchar.c		\
+libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c	\
+libffi.call/return_fl3.c libffi.call/stret_medium.c			\
+libffi.call/nested_struct6.c libffi.call/closure_fn3.c			\
+libffi.call/float3.c libffi.call/many2.c				\
+libffi.call/closure_simple.c libffi.call/cls_align_uint16.c		\
+libffi.call/cls_9byte1.c libffi.call/closure_fn6.c			\
+libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c		\
+libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c		\
+libffi.call/cls_sshort.c \
+libffi.call/nested_struct.c libffi.call/cls_20byte.c			\
+libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c		\
+libffi.call/return_uc.c \
+libffi.call/cls_18byte.c libffi.call/cls_8byte.c			\
+libffi.call/promotion.c \
+libffi.call/return_dbl.c libffi.call/cls_24byte.c			\
+libffi.call/struct4.c libffi.call/cls_6byte.c				\
+libffi.call/cls_align_uint32.c libffi.call/float.c			\
+libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c	\
+libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c			\
+libffi.call/cls_align_float.c libffi.call/return_fl1.c			\
+libffi.call/nested_struct10.c libffi.call/nested_struct5.c		\
+libffi.call/cls_align_sint64.c		\
+libffi.call/stret_large2.c libffi.call/return_sl.c			\
+libffi.call/closure_fn0.c libffi.call/cls_5byte.c			\
+libffi.call/cls_2byte.c libffi.call/float2.c				\
+libffi.call/cls_dbls_struct.c libffi.call/cls_sint.c			\
+libffi.call/stret_large.c libffi.call/cls_ulonglong.c			\
+libffi.call/cls_ushort.c libffi.call/nested_struct1.c			\
+libffi.call/err_bad_abi.c libffi.call/cls_longdouble_va.c		\
+libffi.call/cls_float.c libffi.call/cls_pointer_stack.c		\
+libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c		\
+libffi.call/struct1.c libffi.call/nested_struct9.c			\
+libffi.call/huge_struct.c libffi.call/problem1.c			\
+libffi.call/float4.c \
+libffi.call/return_ldl.c \
+libffi.call/closure_fn5.c \
+libffi.call/struct6.c libffi.call/return_ll.c libffi.call/struct9.c	\
+libffi.call/return_sc.c libffi.call/struct7.c				\
+libffi.call/cls_align_uint64.c libffi.call/cls_4byte.c			\
+libffi.call/cls_6_1_byte.c			\
+libffi.call/cls_7_1_byte.c libffi.call/unwindtest.cc			\
+libffi.call/unwindtest_ffi_call.cc	\
+lib/wrapper.exp lib/target-libpath.exp	\
+lib/libffi.exp libffi.call/cls_struct_va1.c				\
+libffi.call/cls_uchar_va.c libffi.call/cls_uint_va.c			\
+libffi.call/cls_ulong_va.c libffi.call/cls_ushort_va.c			\
+libffi.call/nested_struct11.c libffi.call/uninitialized.c		\
+libffi.call/va_1.c libffi.call/va_struct1.c libffi.call/va_struct2.c	\
+libffi.call/va_struct3.c \
+libffi.call/strlen2.c \
+libffi.call/strlen3.c \
+libffi.call/strlen4.c
diff --git a/testsuite/lib/libffi.exp b/testsuite/lib/libffi.exp
index c02adf9..5051d31 100644
--- a/testsuite/lib/libffi.exp
+++ b/testsuite/lib/libffi.exp
@@ -1,4 +1,4 @@
-#   Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011, 2014, 2019 Free Software Foundation, Inc.
+#   Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011, 2014 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -24,178 +24,6 @@
 load_gcc_lib target-libpath.exp
 load_gcc_lib wrapper.exp
 
-# Return 1 if the target matches the effective target 'arg', 0 otherwise.
-# This can be used with any check_* proc that takes no argument and
-# returns only 1 or 0.  It could be used with check_* procs that take
-# arguments with keywords that pass particular arguments.
-
-proc is-effective-target { arg } {
-    global et_index
-    set selected 0
-    if { ![info exists et_index] } {
-	# Initialize the effective target index that is used in some
-	# check_effective_target_* procs.
-	set et_index 0
-    }
-    if { [info procs check_effective_target_${arg}] != [list] } {
-	set selected [check_effective_target_${arg}]
-    } else {
-	error "unknown effective target keyword `$arg'" 
-    }
-    verbose "is-effective-target: $arg $selected" 2
-    return $selected
-}
-
-proc is-effective-target-keyword { arg } {
-    if { [info procs check_effective_target_${arg}] != [list] } {
-	return 1
-    } else {
-	return 0
-    }
-}
-
-# Intercept the call to the DejaGnu version of dg-process-target to
-# support use of an effective-target keyword in place of a list of
-# target triplets to xfail or skip a test.
-#
-# The argument to dg-process-target is the keyword "target" or "xfail"
-# followed by a selector:
-#    target-triplet-1 ...
-#    effective-target-keyword
-#    selector-expression
-#
-# For a target list the result is "S" if the target is selected, "N" otherwise.
-# For an xfail list the result is "F" if the target is affected, "P" otherwise.
-
-# In contexts that allow either "target" or "xfail" the argument can be
-#    target selector1 xfail selector2
-# which returns "N" if selector1 is not selected, otherwise the result of
-# "xfail selector2".
-#
-# A selector expression appears within curly braces and uses a single logical
-# operator: !, &&, or ||.  An operand is another selector expression, an
-# effective-target keyword, or a list of target triplets within quotes or
-# curly braces.
-
-if { [info procs saved-dg-process-target] == [list] } {
-    rename dg-process-target saved-dg-process-target
-
-    # Evaluate an operand within a selector expression.
-    proc selector_opd { op } {
-	set selector "target"
-	lappend selector $op
-	set answer [ expr { [dg-process-target $selector] == "S" } ]
-	verbose "selector_opd: `$op' $answer" 2
-	return $answer
-    }
-
-    # Evaluate a target triplet list within a selector expression.
-    # Unlike other operands, this needs to be expanded from a list to
-    # the same string as "target".
-    proc selector_list { op } {
-	set selector "target [join $op]"
-	set answer [ expr { [dg-process-target $selector] == "S" } ]
-	verbose "selector_list: `$op' $answer" 2
-	return $answer
-    }
-
-    # Evaluate a selector expression.
-    proc selector_expression { exp } {
-	if { [llength $exp] == 2 } {
-	    if [string match "!" [lindex $exp 0]] {
-		set op1 [lindex $exp 1]
-		set answer [expr { ! [selector_opd $op1] }]
-	    } else {
-		# Assume it's a list of target triplets.
-		set answer [selector_list $exp]
-	    }
-	} elseif { [llength $exp] == 3 } {
-	    set op1 [lindex $exp 0]
-	    set opr [lindex $exp 1]
-	    set op2 [lindex $exp 2]
-	    if [string match "&&" $opr] {
-		set answer [expr { [selector_opd $op1] && [selector_opd $op2] }]
-	    } elseif [string match "||" $opr] {
-		set answer [expr { [selector_opd $op1] || [selector_opd $op2] }]
-	    } else {
-		# Assume it's a list of target triplets.
-		set answer [selector_list $exp]
-	    }
-	} else {
-	    # Assume it's a list of target triplets.
-	    set answer [selector_list $exp]
-	}
-
-	verbose "selector_expression: `$exp' $answer" 2
-	return $answer
-    }
-
-    # Evaluate "target selector" or "xfail selector".
-
-    proc dg-process-target-1 { args } {
-	verbose "dg-process-target-1: `$args'" 2
-
-	# Extract the 'what' keyword from the argument list.
-	set selector [string trim [lindex $args 0]]
-	if [regexp "^xfail " $selector] {
-	    set what "xfail"
-	} elseif [regexp "^target " $selector] {
-	    set what "target"
-	} else {
-	    error "syntax error in target selector \"$selector\""
-	}
-
-	# Extract the rest of the list, which might be a keyword.
-	regsub "^${what}" $selector "" rest
-	set rest [string trim $rest]
-
-	if [is-effective-target-keyword $rest] {
-	    # The selector is an effective target keyword.
-	    if [is-effective-target $rest] {
-		return [expr { $what == "xfail" ? "F" : "S" }]
-	    } else {
-		return [expr { $what == "xfail" ? "P" : "N" }]
-	    }
-	}
-
-	if [string match "{*}" $rest] {
-	    if [selector_expression [lindex $rest 0]] {
-		return [expr { $what == "xfail" ? "F" : "S" }]
-	    } else {
-		return [expr { $what == "xfail" ? "P" : "N" }]
-	    }
-	}
-
-	# The selector is not an effective-target keyword, so process
-	# the list of target triplets.
-	return [saved-dg-process-target $selector]
-    }
-
-    # Intercept calls to the DejaGnu function.  In addition to
-    # processing "target selector" or "xfail selector", handle
-    # "target selector1 xfail selector2".
-
-    proc dg-process-target { args } {
-	verbose "replacement dg-process-target: `$args'" 2
-
-	set selector [string trim [lindex $args 0]]
-
-	# If the argument list contains both 'target' and 'xfail',
-	# process 'target' and, if that succeeds, process 'xfail'.
-	if [regexp "^target .* xfail .*" $selector] {
-	    set xfail_index [string first "xfail" $selector]
-	    set xfail_selector [string range $selector $xfail_index end]
-	    set target_selector [string range $selector 0 [expr $xfail_index-1]]
-	    set target_selector [string trim $target_selector]
-	    if { [dg-process-target-1 $target_selector] == "N" } {
-		return "N"
-	    }
-	    return [dg-process-target-1 $xfail_selector]
-	    
-	}
-	return [dg-process-target-1 $selector]
-    }
-}
 
 # Define libffi callbacks for dg.exp.
 
@@ -261,12 +89,6 @@
     return [libffi-dg-test-1 target_compile $prog $do_what $extra_tool_flags]
 }
 
-proc libffi-dg-prune { target_triplet text } {
-    # We get this with some qemu emulated systems (eg. ppc64le-linux-gnu)
-    regsub -all "(^|\n)\[^\n\]*unable to perform all requested operations" $text "" text
-    return $text
-}
-
 proc libffi-init { args } {
     global gluefile wrap_flags;
     global srcdir
@@ -278,42 +100,46 @@
     global libffi_link_flags
     global tool_root_dir
     global ld_library_path
-    global compiler_vendor
 
-    if ![info exists blddirffi] {
-	set blddirffi [pwd]/..
-    }
+    global using_gcc
 
+    set blddirffi [pwd]/.. 
     verbose "libffi $blddirffi"
 
-    # Which compiler are we building with?
-    set tmp [grep "$blddirffi/config.log" "^ax_cv_c_compiler_vendor.*$"]
-    regexp -- {^[^=]*=(.*)$} $tmp nil compiler_vendor
+    # Are we building with GCC?
+    set tmp [grep ../config.status "GCC='yes'"]
+    if { [string match $tmp "GCC='yes'"] } {
 
-    if { [string match $compiler_vendor "gnu"] } {
-        set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
-        if {$gccdir != ""} {
-	    set gccdir [file dirname $gccdir]
-        }
-        verbose "gccdir $gccdir"
+      set using_gcc "yes"
 
-        set ld_library_path "."
-        append ld_library_path ":${gccdir}"
+    set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
+    if {$gccdir != ""} {
+	set gccdir [file dirname $gccdir]
+    }
+    verbose "gccdir $gccdir"
 
-        set compiler "${gccdir}/xgcc"
-        if { [is_remote host] == 0 && [which $compiler] != 0 } {
-	    foreach i "[exec $compiler --print-multi-lib]" {
-	        set mldir ""
-	        regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
-	        set mldir [string trimright $mldir "\;@"]
-	        if { "$mldir" == "." } {
-		    continue
-	        }
-	        if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
-		    append ld_library_path ":${gccdir}/${mldir}"
-	        }
+    set ld_library_path "."
+    append ld_library_path ":${gccdir}"
+
+    set compiler "${gccdir}/xgcc"
+    if { [is_remote host] == 0 && [which $compiler] != 0 } {
+	foreach i "[exec $compiler --print-multi-lib]" {
+	    set mldir ""
+	    regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
+	    set mldir [string trimright $mldir "\;@"]
+	    if { "$mldir" == "." } {
+		continue
 	    }
-        }
+	    if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
+		append ld_library_path ":${gccdir}/${mldir}"
+	    }
+	}
+    }
+ 
+    } else {
+
+      set using_gcc "no"
+
     }
 
     # add the library path for libffi.
@@ -353,7 +179,7 @@
     global libffi_link_flags
     global libffi_include
     global target_triplet
-    global compiler_vendor
+
 
     if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } {
 	lappend options "libs=${gluefile}"
@@ -363,7 +189,7 @@
     # TOOL_OPTIONS must come first, so that it doesn't override testcase
     # specific options.
     if [info exists TOOL_OPTIONS] {
-	lappend  options "additional_flags=$TOOL_OPTIONS"
+	lappend  options [concat "additional_flags=$TOOL_OPTIONS" $options];
     }
 
     # search for ffi_mips.h in srcdir, too
@@ -396,38 +222,14 @@
 	lappend options "libs= -lpthread"
     }
 
-    # this may be required for g++, but just confused clang.
     if { [string match "*.cc" $source] } {
-        lappend options "c++"
-    }
-
-    if { [string match "arc*-*-linux*" $target_triplet] } {
-	lappend options "libs= -lpthread"
+	lappend options "c++"
     }
 
     verbose "options: $options"
     return [target_compile $source $dest $type $options]
 }
 
-# TEST should be a preprocessor condition.  Returns true if it holds.
-proc libffi_feature_test { test } {
-    set src "ffitest[pid].c"
-
-    set f [open $src "w"]
-    puts $f "#include <ffi.h>"
-    puts $f $test
-    puts $f "/* OK */"
-    puts $f "#else"
-    puts $f "# error Failed $test"
-    puts $f "#endif"
-    close $f
-
-    set lines [libffi_target_compile $src /dev/null assembly ""]
-    file delete $src
-
-    return [string match "" $lines]
-}
-
 # Utility routines.
 
 #
@@ -476,54 +278,25 @@
 }
 
 proc run-many-tests { testcases extra_flags } {
-    global compiler_vendor
-    global env
-    switch $compiler_vendor {
-      "clang" {
-        set common "-W -Wall"
-        if [info exists env(LIBFFI_TEST_OPTIMIZATION)] {
-	  set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ]
-        } else { 
-          set optimizations { "-O0" "-O2" }
-        }
-      }
-      "gnu" {
+    global using_gcc
+    if { [string match $using_gcc "yes"] } {
         set common "-W -Wall -Wno-psabi"
-        if [info exists env(LIBFFI_TEST_OPTIMIZATION)] {
-	  set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ]
-        } else { 
-          set optimizations { "-O0" "-O2" }
-        }
-      }
-      default {
+        set optimizations { "-O0" "-O2" "-O3" "-Os" "-O2 -fomit-frame-pointer" }
+    } else {
         # Assume we are using the vendor compiler.
         set common ""
-        if [info exists env(LIBFFI_TEST_OPTIMIZATION)] {
-	  set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ]
-        } else { 
-          set optimizations { "" }
-        }
-      }
+        set optimizations { "" }
     }
 
-    info exists env(LD_LIBRARY_PATH)
-
     set targetabis { "" }
-    if [string match $compiler_vendor "gnu"] {
-        if [libffi_feature_test "#ifdef __i386__"] {
+    if [string match $using_gcc "yes"] {
+        if [istarget "i?86-*-*"] {
             set targetabis {
                 ""
                 "-DABI_NUM=FFI_STDCALL -DABI_ATTR=__STDCALL__"
                 "-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__"
                 "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__"
             }
-        } elseif { [istarget "x86_64-*-*"] \
-		   && [libffi_feature_test "#if !defined __ILP32__  \
-						&& !defined __i386__"] } {
-            set targetabis {
-                ""
-                "-DABI_NUM=FFI_GNUW64 -DABI_ATTR=__MSABI__"
-            }
         }
     }
 
diff --git a/testsuite/libffi.bhaible/Makefile b/testsuite/libffi.bhaible/Makefile
deleted file mode 100644
index 3322de9..0000000
--- a/testsuite/libffi.bhaible/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-CC = gcc
-CFLAGS = -O2 -Wall
-prefix =
-includedir = $(prefix)/include
-libdir = $(prefix)/lib
-CPPFLAGS = -I$(includedir)
-LDFLAGS = -L$(libdir) -Wl,-rpath,$(libdir)
-
-all: check-call check-callback
-
-test-call: test-call.c testcases.c
-	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o test-call test-call.c -lffi
-
-test-callback: test-callback.c testcases.c
-	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o test-callback test-callback.c -lffi
-
-check-call: test-call
-	./test-call > test-call.out
-	LC_ALL=C uniq -u < test-call.out > failed-call
-	test '!' -s failed-call
-
-check-callback: test-callback
-	./test-callback > test-callback.out
-	LC_ALL=C uniq -u < test-callback.out > failed-callback
-	test '!' -s failed-callback
-
-clean:
-	rm -f test-call test-callback test-call.out test-callback.out failed-call failed-callback
diff --git a/testsuite/libffi.bhaible/README b/testsuite/libffi.bhaible/README
deleted file mode 100644
index be8540b..0000000
--- a/testsuite/libffi.bhaible/README
+++ /dev/null
@@ -1,78 +0,0 @@
-This package contains a test suite for libffi.
-
-This test suite can be compiled with a C compiler. No need for 'expect'
-or some other package that is often not installed.
-
-The test suite consists of 81 C functions, each with a different signature.
-* test-call verifies that calling each function directly produces the same
-  results as calling the function indirectly through 'ffi_call'.
-* test-callback verifies that calling each function directly produces the same
-  results as calling a function that is a callback (object build by
-  'ffi_prep_closure_loc') and simulates the original function.
-
-Each direct or indirect invocation should produce one line of output to
-stdout. A correct output consists of paired lines, such as
-
-void f(void):
-void f(void):
-int f(void):->99
-int f(void):->99
-int f(int):(1)->2
-int f(int):(1)->2
-int f(2*int):(1,2)->3
-int f(2*int):(1,2)->3
-...
-
-The Makefile then creates two files:
-* failed-call, which consists of the non-paired lines of output of
-  'test-call',
-* failed-callback, which consists of the non-paired lines of output of
-  'test-callback'.
-
-The test suite passes if both failed-call and failed-callback come out
-as empty.
-
-
-How to use the test suite
--------------------------
-
-1. Modify the Makefile's variables
-   prefix = the directory in which libffi was installed
-   CC = the C compiler, often with options such as "-m32" or "-m64"
-        that enforce a certain ABI,
-   CFLAGS = optimization options (need to change them only for non-GCC
-            compilers)
-2. Run "make". If it fails already in "test-call", run also
-   "make check-callback".
-3. If this failed, inspect the output files.
-
-
-How to interpret the results
-----------------------------
-
-The failed-call and failed-callback files consist of paired lines:
-The first line is the result of the direct invocation.
-The second line is the result of invocation through libffi.
-
-For example, this output
-
-uchar f(uchar,ushort,uint,ulong):(97,2,3,4)->255
-uchar f(uchar,ushort,uint,ulong):(97,2,3,4)->0
-
-indicates that the arguments were passed correctly, but the return
-value came out wrong.
-
-And this output
-
-float f(17*float,3*int,L):(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,6,7,8,561,1105,1729,2465,2821,6601)->15319.1
-float f(17*float,3*int,L):(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,-140443648,10,268042216,-72537980,-140443648,-140443648,-140443648,-140443648,-140443648)->-6.47158e+08
-
-indicates that integer arguments that come after 17 floating-point arguments
-were not passed correctly.
-
-
-Credits
--------
-
-The test suite is based on the one of GNU libffcall-2.0.
-Authors: Bill Triggs, Bruno Haible
diff --git a/testsuite/libffi.bhaible/alignof.h b/testsuite/libffi.bhaible/alignof.h
deleted file mode 100644
index 00604a5..0000000
--- a/testsuite/libffi.bhaible/alignof.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Determine alignment of types.
-   Copyright (C) 2003-2004, 2006, 2009-2017 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
-
-#ifndef _ALIGNOF_H
-#define _ALIGNOF_H
-
-#include <stddef.h>
-
-/* alignof_slot (TYPE)
-   Determine the alignment of a structure slot (field) of a given type,
-   at compile time.  Note that the result depends on the ABI.
-   This is the same as alignof (TYPE) and _Alignof (TYPE), defined in
-   <stdalign.h> if __alignof_is_defined is 1.
-   Note: The result cannot be used as a value for an 'enum' constant,
-   due to bugs in HP-UX 10.20 cc and AIX 3.2.5 xlc.  */
-#if defined __cplusplus
-  template <class type> struct alignof_helper { char __slot1; type __slot2; };
-# define alignof_slot(type) offsetof (alignof_helper<type>, __slot2)
-#else
-# define alignof_slot(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
-#endif
-
-/* alignof_type (TYPE)
-   Determine the good alignment of an object of the given type at compile time.
-   Note that this is not necessarily the same as alignof_slot(type).
-   For example, with GNU C on x86 platforms: alignof_type(double) = 8, but
-   - when -malign-double is not specified:  alignof_slot(double) = 4,
-   - when -malign-double is specified:      alignof_slot(double) = 8.
-   Note: The result cannot be used as a value for an 'enum' constant,
-   due to bugs in HP-UX 10.20 cc and AIX 3.2.5 xlc.  */
-#if defined __GNUC__ || defined __IBM__ALIGNOF__
-# define alignof_type __alignof__
-#else
-# define alignof_type alignof_slot
-#endif
-
-#endif /* _ALIGNOF_H */
diff --git a/testsuite/libffi.bhaible/bhaible.exp b/testsuite/libffi.bhaible/bhaible.exp
deleted file mode 100644
index 44aebc5..0000000
--- a/testsuite/libffi.bhaible/bhaible.exp
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2003, 2006, 2009, 2010, 2014, 2018 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-dg-init
-libffi-init
-
-global srcdir subdir
-global compiler_vendor
-
-# The conversion of this testsuite into a dejagnu compatible testsuite
-# was done in a pretty lazy fashion, and requires the use of compiler
-# flags to disable warnings for now.
-if { [string match $compiler_vendor "gnu"] } {
-    set warning_options "-Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized";
-}
-if { [string match $compiler_vendor "microsoft"] } {
-    # -wd4996  suggest use of vsprintf_s instead of vsprintf
-    # -wd4116  unnamed type definition
-    # -wd4101  unreferenced local variable
-    # -wd4244  warning about implicit double to float conversion
-    set warning_options "-wd4996 -wd4116 -wd4101 -wd4244";
-}
-if { ![string match $compiler_vendor "microsoft"] && ![string match $compiler_vendor "gnu"] } {
-    set warning_options "-Wno-unused-variable -Wno-unused-parameter -Wno-uninitialized";
-}
-
-
-set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/test-call.c]]
-
-for {set i 1} {$i < 82} {incr i} {
-    run-many-tests $tlist [format "-DDGTEST=%d %s" $i $warning_options]
-}
-
-set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/test-callback.c]]
-
-for {set i 1} {$i < 81} {incr i} {
-    if { [libffi_feature_test "#if FFI_CLOSURES"] } {
-        run-many-tests $tlist [format "-DDGTEST=%d %s" $i $warning_options]
-    } else {
-        foreach test $tlist {
-            unsupported [format "%s -DDGTEST=%d %s" $test $i $warning_options]
-        }
-    }
-}
-
-dg-finish
-
-# Local Variables:
-# tcl-indent-level:4
-# End:
diff --git a/testsuite/libffi.bhaible/test-call.c b/testsuite/libffi.bhaible/test-call.c
deleted file mode 100644
index 01a8a21..0000000
--- a/testsuite/libffi.bhaible/test-call.c
+++ /dev/null
@@ -1,1745 +0,0 @@
-/**
-  Copyright 1993 Bill Triggs <Bill.Triggs@inrialpes.fr>
-  Copyright 1995-2017 Bruno Haible <bruno@clisp.org>
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-**/
-
-/* { dg-do run } */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ffi.h>
-#include "alignof.h"
-#include <stdarg.h>
-
-/* libffi testsuite local changes -------------------------------- */
-#ifdef DGTEST
-/* Redefine exit(1) as a test failure */
-#define exit(V) (void)((V) ? (abort(), 1) : exit(0))
-int count = 0;
-char rbuf1[2048];
-char rbuf2[2048];
-int _fprintf(FILE *stream, const char *format, ...)
-{
-  va_list args;
-  va_start(args, format);
-
-  switch (count++)
-    {
-    case 0:
-    case 1:
-      vsprintf(&rbuf1[strlen(rbuf1)], format, args);
-      break;
-    case 2:
-      printf("%s", rbuf1);
-      vsprintf(rbuf2, format, args);
-      break;
-    case 3:
-      vsprintf(&rbuf2[strlen(rbuf2)], format, args);
-      printf("%s", rbuf2);
-      if (strcmp (rbuf1, rbuf2)) abort();
-      break;
-    }
-
-  va_end(args);
-
-  return 0;
-}
-#define fprintf _fprintf
-#endif
-/* --------------------------------------------------------------- */
-
-#include "testcases.c"
-
-#ifndef ABI_NUM
-#define ABI_NUM FFI_DEFAULT_ABI
-#endif
-
-/* Definitions that ought to be part of libffi. */
-static ffi_type ffi_type_char;
-#define ffi_type_slonglong ffi_type_sint64
-#define ffi_type_ulonglong ffi_type_uint64
-
-/* libffi does not support arrays inside structs. */
-#define SKIP_EXTRA_STRUCTS
-
-#define FFI_PREP_CIF(cif,argtypes,rettype) \
-  if (ffi_prep_cif(&(cif),ABI_NUM,sizeof(argtypes)/sizeof(argtypes[0]),&rettype,argtypes) != FFI_OK) abort()
-#define FFI_PREP_CIF_NOARGS(cif,rettype) \
-  if (ffi_prep_cif(&(cif),ABI_NUM,0,&rettype,NULL) != FFI_OK) abort()
-#define FFI_CALL(cif,fn,args,retaddr) \
-  ffi_call(&(cif),(void(*)(void))(fn),retaddr,args)
-
-long clear_traces_i (long a, long b, long c, long d, long e, long f, long g, long h,
-                     long i, long j, long k, long l, long m, long n, long o, long p)
-{ return 0; }
-float clear_traces_f (float a, float b, float c, float d, float e, float f, float g,
-                      float h, float i, float j, float k, float l, float m, float n,
-                      float o, float p)
-{ return 0.0; }
-double clear_traces_d (double a, double b, double c, double d, double e, double f, double g,
-                       double h, double i, double j, double k, double l, double m, double n,
-                       double o, double p)
-{ return 0.0; }
-J clear_traces_J (void)
-{ J j; j.l1 = j.l2 = 0; return j; }
-void clear_traces (void)
-{ clear_traces_i(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
-  clear_traces_f(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
-  clear_traces_d(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
-  clear_traces_J();
-}
-
-void
-  void_tests (void)
-{
-#if (!defined(DGTEST)) || DGTEST == 1  
-  v_v();
-  clear_traces();
-  {
-    ffi_cif cif;
-    FFI_PREP_CIF_NOARGS(cif,ffi_type_void);
-    {
-      FFI_CALL(cif,v_v,NULL,NULL);
-    }
-  }
-#endif  
-  return;
-}
-void
-  int_tests (void)
-{
-  int ir;
-  ffi_arg retvalue;
-#if (!defined(DGTEST)) || DGTEST == 2
-  ir = i_v();
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-  ir = 0; clear_traces();
-  {
-    ffi_cif cif;
-    FFI_PREP_CIF_NOARGS(cif,ffi_type_sint);
-    {
-      FFI_CALL(cif,i_v,NULL,&retvalue);
-      ir = retvalue;
-    }
-  }
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 3
-  ir = i_i(i1);
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-  ir = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
-    {
-      /*const*/ void* args[] = { &i1 };
-      FFI_CALL(cif,i_i,args,&retvalue);
-      ir = retvalue;
-    }
-  }
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 4
-  ir = i_i2(i1,i2);
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-  ir = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
-    {
-      /*const*/ void* args[] = { &i1, &i2 };
-      FFI_CALL(cif,i_i2,args,&retvalue);
-      ir = retvalue;
-    }
-  }
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 5
-  ir = i_i4(i1,i2,i3,i4);
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-  ir = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
-    {
-      /*const*/ void* args[] = { &i1, &i2, &i3, &i4 };
-      FFI_CALL(cif,i_i4,args,&retvalue);
-      ir = retvalue;
-    }
-  }
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 6
-  ir = i_i8(i1,i2,i3,i4,i5,i6,i7,i8);
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-  ir = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
-    {
-      /*const*/ void* args[] = { &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8 };
-      FFI_CALL(cif,i_i8,args,&retvalue);
-      ir = retvalue;
-    }
-  }
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 7
-  ir = i_i16(i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16);
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-  ir = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
-    {
-      /*const*/ void* args[] = { &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9, &i10, &i11, &i12, &i13, &i14, &i15, &i16 };
-      FFI_CALL(cif,i_i16,args,&retvalue);
-      ir = retvalue;
-    }
-  }
-  fprintf(out,"->%d\n",ir);
-  fflush(out);
-#endif
-
-  return;
-}
-void
-  float_tests (void)
-{
-  float fr;
-
-#if (!defined(DGTEST)) || DGTEST == 8
-  fr = f_f(f1);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1 };
-      FFI_CALL(cif,f_f,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 9
-  fr = f_f2(f1,f2);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2 };
-      FFI_CALL(cif,f_f2,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 10
-  fr = f_f4(f1,f2,f3,f4);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &f4 };
-      FFI_CALL(cif,f_f4,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 11
-  fr = f_f8(f1,f2,f3,f4,f5,f6,f7,f8);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8 };
-      FFI_CALL(cif,f_f8,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 12
-  fr = f_f16(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9, &f10, &f11, &f12, &f13, &f14, &f15, &f16 };
-      FFI_CALL(cif,f_f16,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 13
-  fr = f_f24(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20,f21,f22,f23,f24);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9, &f10, &f11, &f12, &f13, &f14, &f15, &f16, &f17, &f18, &f19, &f20, &f21, &f22, &f23, &f24 };
-      FFI_CALL(cif,f_f24,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-}
-void
-  double_tests (void)
-{
-  double dr;
-
-#if (!defined(DGTEST)) || DGTEST == 14
-  
-  dr = d_d(d1);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1 };
-      FFI_CALL(cif,d_d,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 15
-  dr = d_d2(d1,d2);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2 };
-      FFI_CALL(cif,d_d2,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 16
-  dr = d_d4(d1,d2,d3,d4);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &d3, &d4 };
-      FFI_CALL(cif,d_d4,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 17
-  dr = d_d8(d1,d2,d3,d4,d5,d6,d7,d8);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8 };
-      FFI_CALL(cif,d_d8,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 18
-  dr = d_d16(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &d13, &d14, &d15, &d16 };
-      FFI_CALL(cif,d_d16,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif  
-  return;
-}
-void
-  pointer_tests (void)
-{
-  void* vpr;
-
-#if (!defined(DGTEST)) || DGTEST == 19
-  vpr = vp_vpdpcpsp(&uc1,&d2,str3,&I4);
-  fprintf(out,"->0x%p\n",vpr);
-  fflush(out);
-  vpr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_pointer, &ffi_type_pointer, &ffi_type_pointer, &ffi_type_pointer };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_pointer);
-    {
-      void* puc1 = &uc1;
-      void* pd2 = &d2;
-      void* pstr3 = str3;
-      void* pI4 = &I4;
-      /*const*/ void* args[] = { &puc1, &pd2, &pstr3, &pI4 };
-      FFI_CALL(cif,vp_vpdpcpsp,args,&vpr);
-    }
-  }
-  fprintf(out,"->0x%p\n",vpr);
-  fflush(out);
-#endif  
-  return;
-}
-void
-  mixed_number_tests (void)
-{
-  uchar ucr;
-  ushort usr;
-  float fr;
-  double dr;
-  long long llr;
-
-  /* Unsigned types.
-   */
-#if (!defined(DGTEST)) || DGTEST == 20
-  ucr = uc_ucsil(uc1, us2, ui3, ul4);
-  fprintf(out,"->%u\n",ucr);
-  fflush(out);
-  ucr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_uchar, &ffi_type_ushort, &ffi_type_uint, &ffi_type_ulong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_uchar);
-    {
-      ffi_arg r;
-      /*const*/ void* args[] = { &uc1, &us2, &ui3, &ul4 };
-      FFI_CALL(cif,uc_ucsil,args,&r);
-      ucr = (uchar) r;
-    }
-  }
-  fprintf(out,"->%u\n",ucr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 21
-  /* Mixed int & float types.
-   */
-  dr = d_iidd(i1,i2,d3,d4);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_double, &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &i1, &i2, &d3, &d4 };
-      FFI_CALL(cif,d_iidd,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 22
-  dr = d_iiidi(i1,i2,i3,d4,i5);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_double, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &i1, &i2, &i3, &d4, &i5 };
-      FFI_CALL(cif,d_iiidi,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 23
-  dr = d_idid(i1,d2,i3,d4);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_double, &ffi_type_sint, &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &i1, &d2, &i3, &d4 };
-      FFI_CALL(cif,d_idid,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 24
-  dr = d_fdi(f1,d2,i3);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_double, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &f1, &d2, &i3 };
-      FFI_CALL(cif,d_fdi,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 25
-  usr = us_cdcd(c1,d2,c3,d4);
-  fprintf(out,"->%u\n",usr);
-  fflush(out);
-  usr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_char, &ffi_type_double, &ffi_type_char, &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_ushort);
-    {
-      ffi_arg rint;
-      /*const*/ void* args[] = { &c1, &d2, &c3, &d4 };
-      FFI_CALL(cif,us_cdcd,args,&rint);
-      usr = (ushort) rint;
-    }
-  }
-  fprintf(out,"->%u\n",usr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 26
-  /* Long long types.
-   */
-  llr = ll_iiilli(i1,i2,i3,ll1,i13);
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-  llr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_slonglong, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-    {
-      /*const*/ void* args[] = { &i1, &i2, &i3, &ll1, &i13 };
-      FFI_CALL(cif,ll_iiilli,args,&llr);
-    }
-  }
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 27
-  llr = ll_flli(f13,ll1,i13);
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-  llr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_slonglong, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-    {
-      /*const*/ void* args[] = { &f13, &ll1, &i13 };
-      FFI_CALL(cif,ll_flli,args,&llr);
-    }
-  }
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 28
-  fr = f_fi(f1,i9);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &i9 };
-      FFI_CALL(cif,f_fi,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 29
-  fr = f_f2i(f1,f2,i9);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &i9 };
-      FFI_CALL(cif,f_f2i,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 30
-  fr = f_f3i(f1,f2,f3,i9);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &i9 };
-      FFI_CALL(cif,f_f3i,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 31
-  fr = f_f4i(f1,f2,f3,f4,i9);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &i9 };
-      FFI_CALL(cif,f_f4i,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 32
-  fr = f_f7i(f1,f2,f3,f4,f5,f6,f7,i9);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &i9 };
-      FFI_CALL(cif,f_f7i,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 33
-  fr = f_f8i(f1,f2,f3,f4,f5,f6,f7,f8,i9);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &i9 };
-      FFI_CALL(cif,f_f8i,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 34
-  fr = f_f12i(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,i9);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9, &f10, &f11, &f12, &i9 };
-      FFI_CALL(cif,f_f12i,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 35
-  fr = f_f13i(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,i9);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9, &f10, &f11, &f12, &f13, &i9 };
-      FFI_CALL(cif,f_f13i,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 36
-  dr = d_di(d1,i9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &i9 };
-      FFI_CALL(cif,d_di,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 37
-  dr = d_d2i(d1,d2,i9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &i9 };
-      FFI_CALL(cif,d_d2i,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 38
-  dr = d_d3i(d1,d2,d3,i9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &d3, &i9 };
-      FFI_CALL(cif,d_d3i,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 39
-  dr = d_d4i(d1,d2,d3,d4,i9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &i9 };
-      FFI_CALL(cif,d_d4i,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 40
-  dr = d_d7i(d1,d2,d3,d4,d5,d6,d7,i9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &i9 };
-      FFI_CALL(cif,d_d7i,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 41
-  dr = d_d8i(d1,d2,d3,d4,d5,d6,d7,d8,i9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &i9 };
-      FFI_CALL(cif,d_d8i,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 42
-  dr = d_d12i(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,i9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &i9 };
-      FFI_CALL(cif,d_d12i,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 43
-  dr = d_d13i(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,i9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &d13, &i9 };
-      FFI_CALL(cif,d_d13i,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif  
-  return;
-}
-void
-  small_structure_return_tests (void)
-{
-#if (!defined(DGTEST)) || DGTEST == 44
-  {
-    Size1 r = S1_v();
-    fprintf(out,"->{%c}\n",r.x1);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    {
-      ffi_type* ffi_type_Size1_elements[] = { &ffi_type_char, NULL };
-      ffi_type ffi_type_Size1;
-      ffi_type_Size1.type = FFI_TYPE_STRUCT;
-      ffi_type_Size1.size = sizeof(Size1);
-      ffi_type_Size1.alignment = alignof_slot(Size1);
-      ffi_type_Size1.elements = ffi_type_Size1_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size1);
-      {
-        FFI_CALL(cif,S1_v,NULL,&r);
-      }
-    }
-    fprintf(out,"->{%c}\n",r.x1);
-    fflush(out);
-  }
-#endif
-#if (!defined(DGTEST)) || DGTEST == 45
-  {
-    Size2 r = S2_v();
-    fprintf(out,"->{%c%c}\n",r.x1,r.x2);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    {
-      ffi_type* ffi_type_Size2_elements[] = { &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size2;
-      ffi_type_Size2.type = FFI_TYPE_STRUCT;
-      ffi_type_Size2.size = sizeof(Size2);
-      ffi_type_Size2.alignment = alignof_slot(Size2);
-      ffi_type_Size2.elements = ffi_type_Size2_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size2);
-      {
-        FFI_CALL(cif,S2_v,NULL,&r);
-      }
-    }
-    fprintf(out,"->{%c%c}\n",r.x1,r.x2);
-    fflush(out);
-  }
-#endif
-#if (!defined(DGTEST)) || DGTEST == 46
-  {
-    Size3 r = S3_v();
-    fprintf(out,"->{%c%c%c}\n",r.x1,r.x2,r.x3);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    {
-      ffi_type* ffi_type_Size3_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size3;
-      ffi_type_Size3.type = FFI_TYPE_STRUCT;
-      ffi_type_Size3.size = sizeof(Size3);
-      ffi_type_Size3.alignment = alignof_slot(Size3);
-      ffi_type_Size3.elements = ffi_type_Size3_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size3);
-      {
-        FFI_CALL(cif,S3_v,NULL,&r);
-      }
-    }
-    fprintf(out,"->{%c%c%c}\n",r.x1,r.x2,r.x3);
-    fflush(out);
-  }
-#endif
-#if (!defined(DGTEST)) || DGTEST == 47
-  {
-    Size4 r = S4_v();
-    fprintf(out,"->{%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    {
-      ffi_type* ffi_type_Size4_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size4;
-      ffi_type_Size4.type = FFI_TYPE_STRUCT;
-      ffi_type_Size4.size = sizeof(Size4);
-      ffi_type_Size4.alignment = alignof_slot(Size4);
-      ffi_type_Size4.elements = ffi_type_Size4_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size4);
-      {
-        FFI_CALL(cif,S4_v,NULL,&r);
-      }
-    }
-    fprintf(out,"->{%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4);
-    fflush(out);
-  }
-#endif
-#if (!defined(DGTEST)) || DGTEST == 48
-  {
-    Size7 r = S7_v();
-    fprintf(out,"->{%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    {
-      ffi_type* ffi_type_Size7_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size7;
-      ffi_type_Size7.type = FFI_TYPE_STRUCT;
-      ffi_type_Size7.size = sizeof(Size7);
-      ffi_type_Size7.alignment = alignof_slot(Size7);
-      ffi_type_Size7.elements = ffi_type_Size7_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size7);
-      {
-        FFI_CALL(cif,S7_v,NULL,&r);
-      }
-    }
-    fprintf(out,"->{%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7);
-    fflush(out);
-  }
-#endif
-#if (!defined(DGTEST)) || DGTEST == 49
-  {
-    Size8 r = S8_v();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    {
-      ffi_type* ffi_type_Size8_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size8;
-      ffi_type_Size8.type = FFI_TYPE_STRUCT;
-      ffi_type_Size8.size = sizeof(Size8);
-      ffi_type_Size8.alignment = alignof_slot(Size8);
-      ffi_type_Size8.elements = ffi_type_Size8_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size8);
-      {
-        FFI_CALL(cif,S8_v,NULL,&r);
-      }
-    }
-    fprintf(out,"->{%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8);
-    fflush(out);
-  }
-#endif
-#if (!defined(DGTEST)) || DGTEST == 50
-  {
-    Size12 r = S12_v();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    {
-      ffi_type* ffi_type_Size12_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size12;
-      ffi_type_Size12.type = FFI_TYPE_STRUCT;
-      ffi_type_Size12.size = sizeof(Size12);
-      ffi_type_Size12.alignment = alignof_slot(Size12);
-      ffi_type_Size12.elements = ffi_type_Size12_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size12);
-      {
-        FFI_CALL(cif,S12_v,NULL,&r);
-      }
-    }
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12);
-    fflush(out);
-  }
-#endif
-#if (!defined(DGTEST)) || DGTEST == 51  
-  {
-    Size15 r = S15_v();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    {
-      ffi_type* ffi_type_Size15_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size15;
-      ffi_type_Size15.type = FFI_TYPE_STRUCT;
-      ffi_type_Size15.size = sizeof(Size15);
-      ffi_type_Size15.alignment = alignof_slot(Size15);
-      ffi_type_Size15.elements = ffi_type_Size15_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size15);
-      {
-        FFI_CALL(cif,S15_v,NULL,&r);
-      }
-    }
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15);
-    fflush(out);
-  }
-#endif
-#if (!defined(DGTEST)) || DGTEST == 52  
-  {
-    Size16 r = S16_v();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15,r.x16);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    {
-      ffi_type* ffi_type_Size16_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size16;
-      ffi_type_Size16.type = FFI_TYPE_STRUCT;
-      ffi_type_Size16.size = sizeof(Size16);
-      ffi_type_Size16.alignment = alignof_slot(Size16);
-      ffi_type_Size16.elements = ffi_type_Size16_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size16);
-      {
-        FFI_CALL(cif,S16_v,NULL,&r);
-      }
-    }
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15,r.x16);
-    fflush(out);
-  }
-#endif
-}
-void
-  structure_tests (void)
-{
-  Int Ir;
-  Char Cr;
-  Float Fr;
-  Double Dr;
-  J Jr;
-#ifndef SKIP_EXTRA_STRUCTS  
-  T Tr;
-  X Xr;
-#endif  
-
-#if (!defined(DGTEST)) || DGTEST == 53  
-  Ir = I_III(I1,I2,I3);
-  fprintf(out,"->{%d}\n",Ir.x);
-  fflush(out);
-  Ir.x = 0; clear_traces();
-  {
-    ffi_type* ffi_type_Int_elements[] = { &ffi_type_sint, NULL };
-    ffi_type ffi_type_Int;
-    ffi_type_Int.type = FFI_TYPE_STRUCT;
-    ffi_type_Int.size = sizeof(Int);
-    ffi_type_Int.alignment = alignof_slot(Int);
-    ffi_type_Int.elements = ffi_type_Int_elements;
-    ffi_type* argtypes[] = { &ffi_type_Int, &ffi_type_Int, &ffi_type_Int };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_Int);
-    {
-      /*const*/ void* args[] = { &I1, &I2, &I3 };
-      FFI_CALL(cif,I_III,args,&Ir);
-    }
-  }
-  fprintf(out,"->{%d}\n",Ir.x);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 54
-  Cr = C_CdC(C1,d2,C3);
-  fprintf(out,"->{'%c'}\n",Cr.x);
-  fflush(out);
-  Cr.x = '\0'; clear_traces();
-  {
-    ffi_type* ffi_type_Char_elements[] = { &ffi_type_char, NULL };
-    ffi_type ffi_type_Char;
-    ffi_type_Char.type = FFI_TYPE_STRUCT;
-    ffi_type_Char.size = sizeof(Char);
-    ffi_type_Char.alignment = alignof_slot(Char);
-    ffi_type_Char.elements = ffi_type_Char_elements;
-    ffi_type* argtypes[] = { &ffi_type_Char, &ffi_type_double, &ffi_type_Char };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_Char);
-    {
-      /*const*/ void* args[] = { &C1, &d2, &C3 };
-      FFI_CALL(cif,C_CdC,args,&Cr);
-    }
-  }
-  fprintf(out,"->{'%c'}\n",Cr.x);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 55
-  Fr = F_Ffd(F1,f2,d3);
-  fprintf(out,"->{%g}\n",Fr.x);
-  fflush(out);
-  Fr.x = 0.0; clear_traces();
-  {
-    ffi_type* ffi_type_Float_elements[] = { &ffi_type_float, NULL };
-    ffi_type ffi_type_Float;
-    ffi_type_Float.type = FFI_TYPE_STRUCT;
-    ffi_type_Float.size = sizeof(Float);
-    ffi_type_Float.alignment = alignof_slot(Float);
-    ffi_type_Float.elements = ffi_type_Float_elements;
-    ffi_type* argtypes[] = { &ffi_type_Float, &ffi_type_float, &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_Float);
-    {
-      /*const*/ void* args[] = { &F1, &f2, &d3 };
-      FFI_CALL(cif,F_Ffd,args,&Fr);
-    }
-  }
-  fprintf(out,"->{%g}\n",Fr.x);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 56  
-  Dr = D_fDd(f1,D2,d3);
-  fprintf(out,"->{%g}\n",Dr.x);
-  fflush(out);
-  Dr.x = 0.0; clear_traces();
-  {
-    ffi_type* ffi_type_Double_elements[] = { &ffi_type_double, NULL };
-    ffi_type ffi_type_Double;
-    ffi_type_Double.type = FFI_TYPE_STRUCT;
-    ffi_type_Double.size = sizeof(Double);
-    ffi_type_Double.alignment = alignof_slot(Double);
-    ffi_type_Double.elements = ffi_type_Double_elements;
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_Double, &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_Double);
-    {
-      /*const*/ void* args[] = { &f1, &D2, &d3 };
-      FFI_CALL(cif,D_fDd,args,&Dr);
-    }
-  }
-  fprintf(out,"->{%g}\n",Dr.x);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 57  
-  Dr = D_Dfd(D1,f2,d3);
-  fprintf(out,"->{%g}\n",Dr.x);
-  fflush(out);
-  Dr.x = 0.0; clear_traces();
-  {
-    ffi_type* ffi_type_Double_elements[] = { &ffi_type_double, NULL };
-    ffi_type ffi_type_Double;
-    ffi_type_Double.type = FFI_TYPE_STRUCT;
-    ffi_type_Double.size = sizeof(Double);
-    ffi_type_Double.alignment = alignof_slot(Double);
-    ffi_type_Double.elements = ffi_type_Double_elements;
-    ffi_type* argtypes[] = { &ffi_type_Double, &ffi_type_float, &ffi_type_double };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_Double);
-    {
-      /*const*/ void* args[] = { &D1, &f2, &d3 };
-      FFI_CALL(cif,D_Dfd,args,&Dr);
-    }
-  }
-  fprintf(out,"->{%g}\n",Dr.x);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 58  
-  Jr = J_JiJ(J1,i2,J2);
-  fprintf(out,"->{%ld,%ld}\n",Jr.l1,Jr.l2);
-  fflush(out);
-  Jr.l1 = Jr.l2 = 0; clear_traces();
-  {
-    ffi_type* ffi_type_J_elements[] = { &ffi_type_slong, &ffi_type_slong, NULL };
-    ffi_type ffi_type_J;
-    ffi_type_J.type = FFI_TYPE_STRUCT;
-    ffi_type_J.size = sizeof(J);
-    ffi_type_J.alignment = alignof_slot(J);
-    ffi_type_J.elements = ffi_type_J_elements;
-    ffi_type* argtypes[] = { &ffi_type_J, &ffi_type_sint, &ffi_type_J };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_J);
-    {
-      /*const*/ void* args[] = { &J1, &i2, &J2 };
-      FFI_CALL(cif,J_JiJ,args,&Jr);
-    }
-  }
-  fprintf(out,"->{%ld,%ld}\n",Jr.l1,Jr.l2);
-  fflush(out);
-#endif
-#ifndef SKIP_EXTRA_STRUCTS
-#if (!defined(DGTEST)) || DGTEST == 59
-  Tr = T_TcT(T1,' ',T2);
-  fprintf(out,"->{\"%c%c%c\"}\n",Tr.c[0],Tr.c[1],Tr.c[2]);
-  fflush(out);
-  Tr.c[0] = Tr.c[1] = Tr.c[2] = 0; clear_traces();
-  {
-    ffi_type* ffi_type_T_elements[] = { ??, NULL };
-    ffi_type ffi_type_T;
-    ffi_type_T.type = FFI_TYPE_STRUCT;
-    ffi_type_T.size = sizeof(T);
-    ffi_type_T.alignment = alignof_slot(T);
-    ffi_type_T.elements = ffi_type_T_elements;
-    ffi_type* argtypes[] = { &ffi_type_T, &ffi_type_char, &ffi_type_T };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_T);
-    {
-      char space = ' ';
-      /*const*/ void* args[] = { &T1, &space, &T2 };
-      FFI_CALL(cif,T_TcT,args,&Tr);
-    }
-  }
-  fprintf(out,"->{\"%c%c%c\"}\n",Tr.c[0],Tr.c[1],Tr.c[2]);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 60
-  Xr = X_BcdB(B1,c2,d3,B2);
-  fprintf(out,"->{\"%s\",'%c'}\n",Xr.c,Xr.c1);
-  fflush(out);
-  Xr.c[0]=Xr.c1='\0'; clear_traces();
-  {
-    ffi_type* ffi_type_X_elements[] = { ??, NULL };
-    ffi_type ffi_type_X;
-    ffi_type_X.type = FFI_TYPE_STRUCT;
-    ffi_type_X.size = sizeof(X);
-    ffi_type_X.alignment = alignof_slot(X);
-    ffi_type_X.elements = ffi_type_X_elements;
-    ffi_type* argtypes[] = { &ffi_type_X, &ffi_type_char, &ffi_type_double, &ffi_type_X };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_X);
-    {
-      /*const*/ void* args[] = { &B1, &c2, &d3, &B2 };
-      FFI_CALL(cif,X_BcdB,args,&Xr);
-    }
-  }
-  fprintf(out,"->{\"%s\",'%c'}\n",Xr.c,Xr.c1);
-  fflush(out);
-#endif
-#endif
-
-  return;
-}
-
-void
-  gpargs_boundary_tests (void)
-{
-  ffi_type* ffi_type_K_elements[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, NULL };
-  ffi_type ffi_type_K;
-  ffi_type* ffi_type_L_elements[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, NULL };
-  ffi_type ffi_type_L;
-  long lr;
-  long long llr;
-  float fr;
-  double dr;
-
-  ffi_type_K.type = FFI_TYPE_STRUCT;
-  ffi_type_K.size = sizeof(K);
-  ffi_type_K.alignment = alignof_slot(K);
-  ffi_type_K.elements = ffi_type_K_elements;
-
-  ffi_type_L.type = FFI_TYPE_STRUCT;
-  ffi_type_L.size = sizeof(L);
-  ffi_type_L.alignment = alignof_slot(L);
-  ffi_type_L.elements = ffi_type_L_elements;
-
-#if (!defined(DGTEST)) || DGTEST == 61  
-  lr = l_l0K(K1,l9);
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-  lr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_K, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-    {
-      /*const*/ void* args[] = { &K1, &l9 };
-      FFI_CALL(cif,l_l0K,args,&lr);
-    }
-  }
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 62  
-  lr = l_l1K(l1,K1,l9);
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-  lr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-    {
-      /*const*/ void* args[] = { &l1, &K1, &l9 };
-      FFI_CALL(cif,l_l1K,args,&lr);
-    }
-  }
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 63  
-  lr = l_l2K(l1,l2,K1,l9);
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-  lr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &K1, &l9 };
-      FFI_CALL(cif,l_l2K,args,&lr);
-    }
-  }
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 64  
-  lr = l_l3K(l1,l2,l3,K1,l9);
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-  lr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &K1, &l9 };
-      FFI_CALL(cif,l_l3K,args,&lr);
-    }
-  }
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 65
-  lr = l_l4K(l1,l2,l3,l4,K1,l9);
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-  lr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &K1, &l9 };
-      FFI_CALL(cif,l_l4K,args,&lr);
-    }
-  }
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 66
-  lr = l_l5K(l1,l2,l3,l4,l5,K1,l9);
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-  lr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &K1, &l9 };
-      FFI_CALL(cif,l_l5K,args,&lr);
-    }
-  }
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 67  
-  lr = l_l6K(l1,l2,l3,l4,l5,l6,K1,l9);
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-  lr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &l6, &K1, &l9 };
-      FFI_CALL(cif,l_l6K,args,&lr);
-    }
-  }
-  fprintf(out,"->%ld\n",lr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 68  
-  fr = f_f17l3L(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,l6,l7,l8,L1);
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-  fr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_L };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-    {
-      /*const*/ void* args[] = { &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9, &f10, &f11, &f12, &f13, &f14, &f15, &f16, &f17, &l6, &l7, &l8, &L1 };
-      FFI_CALL(cif,f_f17l3L,args,&fr);
-    }
-  }
-  fprintf(out,"->%g\n",fr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 69  
-  dr = d_d17l3L(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,d17,l6,l7,l8,L1);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_L };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &d13, &d14, &d15, &d16, &d17, &l6, &l7, &l8, &L1 };
-      FFI_CALL(cif,d_d17l3L,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 70  
-  llr = ll_l2ll(l1,l2,ll1,l9);
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-  llr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &ll1, &l9 };
-      FFI_CALL(cif,ll_l2ll,args,&llr);
-    }
-  }
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 71
-  llr = ll_l3ll(l1,l2,l3,ll1,l9);
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-  llr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &ll1, &l9 };
-      FFI_CALL(cif,ll_l3ll,args,&llr);
-    }
-  }
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 72  
-  llr = ll_l4ll(l1,l2,l3,l4,ll1,l9);
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-  llr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &ll1, &l9 };
-      FFI_CALL(cif,ll_l4ll,args,&llr);
-    }
-  }
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 73  
-  llr = ll_l5ll(l1,l2,l3,l4,l5,ll1,l9);
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-  llr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &ll1, &l9 };
-      FFI_CALL(cif,ll_l5ll,args,&llr);
-    }
-  }
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 74  
-  llr = ll_l6ll(l1,l2,l3,l4,l5,l6,ll1,l9);
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-  llr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &l6, &ll1, &l9 };
-      FFI_CALL(cif,ll_l6ll,args,&llr);
-    }
-  }
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 75  
-  llr = ll_l7ll(l1,l2,l3,l4,l5,l6,l7,ll1,l9);
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-  llr = 0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &l6, &l7, &ll1, &l9 };
-      FFI_CALL(cif,ll_l7ll,args,&llr);
-    }
-  }
-  fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 76  
-  dr = d_l2d(l1,l2,d2,l9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &d2, &l9 };
-      FFI_CALL(cif,d_l2d,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 77  
-  dr = d_l3d(l1,l2,l3,d2,l9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &d2, &l9 };
-      FFI_CALL(cif,d_l3d,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 78  
-  dr = d_l4d(l1,l2,l3,l4,d2,l9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &d2, &l9 };
-      FFI_CALL(cif,d_l4d,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 79  
-  dr = d_l5d(l1,l2,l3,l4,l5,d2,l9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &d2, &l9 };
-      FFI_CALL(cif,d_l5d,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 80  
-  dr = d_l6d(l1,l2,l3,l4,l5,l6,d2,l9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &l6, &d2, &l9 };
-      FFI_CALL(cif,d_l6d,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-#if (!defined(DGTEST)) || DGTEST == 81  
-  dr = d_l7d(l1,l2,l3,l4,l5,l6,l7,d2,l9);
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-  dr = 0.0; clear_traces();
-  {
-    ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-    ffi_cif cif;
-    FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-    {
-      /*const*/ void* args[] = { &l1, &l2, &l3, &l4, &l5, &l6, &l7, &d2, &l9 };
-      FFI_CALL(cif,d_l7d,args,&dr);
-    }
-  }
-  fprintf(out,"->%g\n",dr);
-  fflush(out);
-#endif
-  return;
-}
-
-int
-  main (void)
-{
-  ffi_type_char = (char)(-1) < 0 ? ffi_type_schar : ffi_type_uchar;
-  out = stdout;
-
-  void_tests();
-  int_tests();
-  float_tests();
-  double_tests();
-  pointer_tests();
-  mixed_number_tests();
-  small_structure_return_tests();
-  structure_tests();
-  gpargs_boundary_tests();
-
-  exit(0);
-}
diff --git a/testsuite/libffi.bhaible/test-callback.c b/testsuite/libffi.bhaible/test-callback.c
deleted file mode 100644
index c2633c7..0000000
--- a/testsuite/libffi.bhaible/test-callback.c
+++ /dev/null
@@ -1,2885 +0,0 @@
-/*
- * Copyright 1993 Bill Triggs <Bill.Triggs@inrialpes.fr>
- * Copyright 1995-2017 Bruno Haible <bruno@clisp.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* { dg-do run } */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ffi.h>
-#include "alignof.h"
-#include <stdarg.h>
-
-/* libffi testsuite local changes -------------------------------- */
-#ifdef DGTEST
-/* Redefine exit(1) as a test failure */
-#define exit(V) (void)((V) ? (abort(), 1) : exit(0))
-int count = 0;
-char rbuf1[2048];
-char rbuf2[2048];
-int _fprintf(FILE *stream, const char *format, ...)
-{
-  va_list args;
-  va_start(args, format);
-
-  switch (count++)
-    {
-    case 0:
-    case 1:
-      vsprintf(&rbuf1[strlen(rbuf1)], format, args);
-      break;
-    case 2:
-      printf("%s", rbuf1);
-      vsprintf(rbuf2, format, args);
-      break;
-    case 3:
-      vsprintf(&rbuf2[strlen(rbuf2)], format, args);
-      printf("%s", rbuf2);
-      if (strcmp (rbuf1, rbuf2)) abort();
-      break;
-    }
-
-  va_end(args);
-
-  return 0;
-}
-#define fprintf _fprintf
-#endif
-/* --------------------------------------------------------------- */
-
-#include "testcases.c"
-
-#ifndef ABI_NUM
-#define ABI_NUM FFI_DEFAULT_ABI
-#endif
-
-/* Definitions that ought to be part of libffi. */
-static ffi_type ffi_type_char;
-#define ffi_type_slonglong ffi_type_sint64
-#define ffi_type_ulonglong ffi_type_uint64
-
-/* libffi does not support arrays inside structs. */
-#define SKIP_EXTRA_STRUCTS
-
-#define FFI_PREP_CIF(cif,argtypes,rettype) \
-  if (ffi_prep_cif(&(cif),ABI_NUM,sizeof(argtypes)/sizeof(argtypes[0]),&rettype,argtypes) != FFI_OK) abort()
-#define FFI_PREP_CIF_NOARGS(cif,rettype) \
-  if (ffi_prep_cif(&(cif),ABI_NUM,0,&rettype,NULL) != FFI_OK) abort()
-
-#if defined(__sparc__) && defined(__sun) && defined(__SUNPRO_C) /* SUNWspro cc */
-/* SunPRO cc miscompiles the simulator function for X_BcdB: d.i[1] is
- * temporarily stored in %l2 and put onto the stack from %l2, but in between
- * the copy of X has used %l2 as a counter without saving and restoring its
- * value.
- */
-#define SKIP_X
-#endif
-#if defined(__mipsn32__) && !defined(__GNUC__)
-/* The X test crashes for an unknown reason. */
-#define SKIP_X
-#endif
-
-
-/* These functions simulate the behaviour of the functions defined in testcases.c. */
-
-/* void tests */
-void v_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&v_v) { fprintf(out,"wrong data for v_v\n"); exit(1); }
-  fprintf(out,"void f(void):\n");
-  fflush(out);
-}
-
-/* int tests */
-void i_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&i_v) { fprintf(out,"wrong data for i_v\n"); exit(1); }
- {int r=99;
-  fprintf(out,"int f(void):");
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void i_i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&i_i) { fprintf(out,"wrong data for i_i\n"); exit(1); }
-  int a = *(int*)(*args++);
-  int r=a+1;
-  fprintf(out,"int f(int):(%d)",a);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}
-void i_i2_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&i_i2) { fprintf(out,"wrong data for i_i2\n"); exit(1); }
- {int a = *(int*)(*args++);
-  int b = *(int*)(*args++);
-  int r=a+b;
-  fprintf(out,"int f(2*int):(%d,%d)",a,b);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void i_i4_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&i_i4) { fprintf(out,"wrong data for i_i4\n"); exit(1); }
- {int a = *(int*)(*args++);
-  int b = *(int*)(*args++);
-  int c = *(int*)(*args++);
-  int d = *(int*)(*args++);
-  int r=a+b+c+d;
-  fprintf(out,"int f(4*int):(%d,%d,%d,%d)",a,b,c,d);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void i_i8_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&i_i8) { fprintf(out,"wrong data for i_i8\n"); exit(1); }
- {int a = *(int*)(*args++);
-  int b = *(int*)(*args++);
-  int c = *(int*)(*args++);
-  int d = *(int*)(*args++);
-  int e = *(int*)(*args++);
-  int f = *(int*)(*args++);
-  int g = *(int*)(*args++);
-  int h = *(int*)(*args++);
-  int r=a+b+c+d+e+f+g+h;
-  fprintf(out,"int f(8*int):(%d,%d,%d,%d,%d,%d,%d,%d)",a,b,c,d,e,f,g,h);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void i_i16_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&i_i16) { fprintf(out,"wrong data for i_i16\n"); exit(1); }
- {int a = *(int*)(*args++);
-  int b = *(int*)(*args++);
-  int c = *(int*)(*args++);
-  int d = *(int*)(*args++);
-  int e = *(int*)(*args++);
-  int f = *(int*)(*args++);
-  int g = *(int*)(*args++);
-  int h = *(int*)(*args++);
-  int i = *(int*)(*args++);
-  int j = *(int*)(*args++);
-  int k = *(int*)(*args++);
-  int l = *(int*)(*args++);
-  int m = *(int*)(*args++);
-  int n = *(int*)(*args++);
-  int o = *(int*)(*args++);
-  int p = *(int*)(*args++);
-  int r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
-  fprintf(out,"int f(16*int):(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
-          a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-
-/* float tests */
-void f_f_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f) { fprintf(out,"wrong data for f_f\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float r=a+1.0;
-  fprintf(out,"float f(float):(%g)",a);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f2_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f2) { fprintf(out,"wrong data for f_f2\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float r=a+b;
-  fprintf(out,"float f(2*float):(%g,%g)",a,b);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f4_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f4) { fprintf(out,"wrong data for f_f4\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  float d = *(float*)(*args++);
-  float r=a+b+c+d;
-  fprintf(out,"float f(4*float):(%g,%g,%g,%g)",a,b,c,d);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f8_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f8) { fprintf(out,"wrong data for f_f8\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  float d = *(float*)(*args++);
-  float e = *(float*)(*args++);
-  float f = *(float*)(*args++);
-  float g = *(float*)(*args++);
-  float h = *(float*)(*args++);
-  float r=a+b+c+d+e+f+g+h;
-  fprintf(out,"float f(8*float):(%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f16_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f16) { fprintf(out,"wrong data for f_f16\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  float d = *(float*)(*args++);
-  float e = *(float*)(*args++);
-  float f = *(float*)(*args++);
-  float g = *(float*)(*args++);
-  float h = *(float*)(*args++);
-  float i = *(float*)(*args++);
-  float j = *(float*)(*args++);
-  float k = *(float*)(*args++);
-  float l = *(float*)(*args++);
-  float m = *(float*)(*args++);
-  float n = *(float*)(*args++);
-  float o = *(float*)(*args++);
-  float p = *(float*)(*args++);
-  float r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
-  fprintf(out,"float f(16*float):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f24_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f24) { fprintf(out,"wrong data for f_f24\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  float d = *(float*)(*args++);
-  float e = *(float*)(*args++);
-  float f = *(float*)(*args++);
-  float g = *(float*)(*args++);
-  float h = *(float*)(*args++);
-  float i = *(float*)(*args++);
-  float j = *(float*)(*args++);
-  float k = *(float*)(*args++);
-  float l = *(float*)(*args++);
-  float m = *(float*)(*args++);
-  float n = *(float*)(*args++);
-  float o = *(float*)(*args++);
-  float p = *(float*)(*args++);
-  float q = *(float*)(*args++);
-  float s = *(float*)(*args++);
-  float t = *(float*)(*args++);
-  float u = *(float*)(*args++);
-  float v = *(float*)(*args++);
-  float w = *(float*)(*args++);
-  float x = *(float*)(*args++);
-  float y = *(float*)(*args++);
-  float r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+v+w+x+y;
-  fprintf(out,"float f(24*float):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,v,w,x,y);
-  fflush(out);
-  *(float*)retp = r;
-}}
-
-/* double tests */
-void d_d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d) { fprintf(out,"wrong data for d_d\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double r=a+1.0;
-  fprintf(out,"double f(double):(%g)",a);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d2_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d2) { fprintf(out,"wrong data for d_d2\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double r=a+b;
-  fprintf(out,"double f(2*double):(%g,%g)",a,b);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d4_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d4) { fprintf(out,"wrong data for d_d4\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double c = *(double*)(*args++);
-  double d = *(double*)(*args++);
-  double r=a+b+c+d;
-  fprintf(out,"double f(4*double):(%g,%g,%g,%g)",a,b,c,d);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d8_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d8) { fprintf(out,"wrong data for d_d8\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double c = *(double*)(*args++);
-  double d = *(double*)(*args++);
-  double e = *(double*)(*args++);
-  double f = *(double*)(*args++);
-  double g = *(double*)(*args++);
-  double h = *(double*)(*args++);
-  double r=a+b+c+d+e+f+g+h;
-  fprintf(out,"double f(8*double):(%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d16_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d16) { fprintf(out,"wrong data for d_d16\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double c = *(double*)(*args++);
-  double d = *(double*)(*args++);
-  double e = *(double*)(*args++);
-  double f = *(double*)(*args++);
-  double g = *(double*)(*args++);
-  double h = *(double*)(*args++);
-  double i = *(double*)(*args++);
-  double j = *(double*)(*args++);
-  double k = *(double*)(*args++);
-  double l = *(double*)(*args++);
-  double m = *(double*)(*args++);
-  double n = *(double*)(*args++);
-  double o = *(double*)(*args++);
-  double p = *(double*)(*args++);
-  double r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
-  fprintf(out,"double f(16*double):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
-  fflush(out);
-  *(double*)retp = r;
-}}
-
-/* pointer tests */
-void vp_vpdpcpsp_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&vp_vpdpcpsp) { fprintf(out,"wrong data for vp_vpdpcpsp\n"); exit(1); }
- {void* a = *(void* *)(*args++);
-  double* b = *(double* *)(*args++);
-  char* c = *(char* *)(*args++);
-  Int* d = *(Int* *)(*args++);
-  void* ret = (char*)b + 1;
-  fprintf(out,"void* f(void*,double*,char*,Int*):(0x%p,0x%p,0x%p,0x%p)",a,b,c,d);
-  fflush(out);
-  *(void* *)retp = ret;
-}}
-
-/* mixed number tests */
-void uc_ucsil_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&uc_ucsil) { fprintf(out,"wrong data for uc_ucsil\n"); exit(1); }
- {uchar a = *(unsigned char *)(*args++);
-  ushort b = *(unsigned short *)(*args++);
-  uint c = *(unsigned int *)(*args++);
-  ulong d = *(unsigned long *)(*args++);
-  uchar r = (uchar)-1;
-  fprintf(out,"uchar f(uchar,ushort,uint,ulong):(%u,%u,%u,%lu)",a,b,c,d);
-  fflush(out);
-  *(ffi_arg *)retp = r;
-}}
-void d_iidd_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_iidd) { fprintf(out,"wrong data for d_iidd\n"); exit(1); }
- {int a = *(int*)(*args++);
-  int b = *(int*)(*args++);
-  double c = *(double*)(*args++);
-  double d = *(double*)(*args++);
-  double r=a+b+c+d;
-  fprintf(out,"double f(int,int,double,double):(%d,%d,%g,%g)",a,b,c,d);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_iiidi_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_iiidi) { fprintf(out,"wrong data for d_iiidi\n"); exit(1); }
- {int a = *(int*)(*args++);
-  int b = *(int*)(*args++);
-  int c = *(int*)(*args++);
-  double d = *(double*)(*args++);
-  int e = *(int*)(*args++);
-  double r=a+b+c+d+e;
-  fprintf(out,"double f(int,int,int,double,int):(%d,%d,%d,%g,%d)",a,b,c,d,e);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_idid_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_idid) { fprintf(out,"wrong data for d_idid\n"); exit(1); }
- {int a = *(int*)(*args++);
-  double b = *(double*)(*args++);
-  int c = *(int*)(*args++);
-  double d = *(double*)(*args++);
-  double r=a+b+c+d;
-  fprintf(out,"double f(int,double,int,double):(%d,%g,%d,%g)",a,b,c,d);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_fdi_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_fdi) { fprintf(out,"wrong data for d_fdi\n"); exit(1); }
- {float a = *(float*)(*args++);
-  double b = *(double*)(*args++);
-  int c = *(int*)(*args++);
-  double r=a+b+c;
-  fprintf(out,"double f(float,double,int):(%g,%g,%d)",a,b,c);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void us_cdcd_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&us_cdcd) { fprintf(out,"wrong data for us_cdcd\n"); exit(1); }
- {char a = *(char*)(*args++);
-  double b = *(double*)(*args++);
-  char c = *(char*)(*args++);
-  double d = *(double*)(*args++);
-  ushort r = (ushort)(a + b + c + d);
-  fprintf(out,"ushort f(char,double,char,double):('%c',%g,'%c',%g)",a,b,c,d);
-  fflush(out);
-  *(ffi_arg *)retp = r;
-}}
-void ll_iiilli_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&ll_iiilli) { fprintf(out,"wrong data for ll_iiilli\n"); exit(1); }
- {int a = *(int*)(*args++);
-  int b = *(int*)(*args++);
-  int c = *(int*)(*args++);
-  long long d = *(long long *)(*args++);
-  int e = *(int*)(*args++);
-  long long r = (long long)(int)a + (long long)(int)b + (long long)(int)c + d + (long long)e;
-  fprintf(out,"long long f(int,int,int,long long,int):(%d,%d,%d,0x%lx%08lx,%d)",a,b,c,(long)(d>>32),(long)(d&0xffffffff),e);
-  fflush(out);
-  *(long long *)retp = r;
-}}
-void ll_flli_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&ll_flli) { fprintf(out,"wrong data for ll_flli\n"); exit(1); }
- {float a = *(float*)(*args++);
-  long long b = *(long long *)(*args++);
-  int c = *(int*)(*args++);
-  long long r = (long long)(int)a + b + (long long)c;
-  fprintf(out,"long long f(float,long long,int):(%g,0x%lx%08lx,0x%lx)",a,(long)(b>>32),(long)(b&0xffffffff),(long)c);
-  fflush(out);
-  *(long long *)retp = r;
-}}
-void f_fi_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_fi) { fprintf(out,"wrong data for f_fi\n"); exit(1); }
- {float a = *(float*)(*args++);
-  int z = *(int*)(*args++);
-  float r=a+z;
-  fprintf(out,"float f(float,int):(%g,%d)",a,z);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f2i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f2i) { fprintf(out,"wrong data for f_f2i\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  int z = *(int*)(*args++);
-  float r=a+b+z;
-  fprintf(out,"float f(2*float,int):(%g,%g,%d)",a,b,z);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f3i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f3i) { fprintf(out,"wrong data for f_f3i\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  int z = *(int*)(*args++);
-  float r=a+b+c+z;
-  fprintf(out,"float f(3*float,int):(%g,%g,%g,%d)",a,b,c,z);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f4i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f4i) { fprintf(out,"wrong data for f_f4i\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  float d = *(float*)(*args++);
-  int z = *(int*)(*args++);
-  float r=a+b+c+d+z;
-  fprintf(out,"float f(4*float,int):(%g,%g,%g,%g,%d)",a,b,c,d,z);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f7i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f7i) { fprintf(out,"wrong data for f_f7i\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  float d = *(float*)(*args++);
-  float e = *(float*)(*args++);
-  float f = *(float*)(*args++);
-  float g = *(float*)(*args++);
-  int z = *(int*)(*args++);
-  float r=a+b+c+d+e+f+g+z;
-  fprintf(out,"float f(7*float,int):(%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,z);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f8i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f8i) { fprintf(out,"wrong data for f_f8i\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  float d = *(float*)(*args++);
-  float e = *(float*)(*args++);
-  float f = *(float*)(*args++);
-  float g = *(float*)(*args++);
-  float h = *(float*)(*args++);
-  int z = *(int*)(*args++);
-  float r=a+b+c+d+e+f+g+h+z;
-  fprintf(out,"float f(8*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,z);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f12i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f12i) { fprintf(out,"wrong data for f_f12i\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  float d = *(float*)(*args++);
-  float e = *(float*)(*args++);
-  float f = *(float*)(*args++);
-  float g = *(float*)(*args++);
-  float h = *(float*)(*args++);
-  float i = *(float*)(*args++);
-  float j = *(float*)(*args++);
-  float k = *(float*)(*args++);
-  float l = *(float*)(*args++);
-  int z = *(int*)(*args++);
-  float r=a+b+c+d+e+f+g+h+i+j+k+l+z;
-  fprintf(out,"float f(12*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,z);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void f_f13i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f13i) { fprintf(out,"wrong data for f_f13i\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  float d = *(float*)(*args++);
-  float e = *(float*)(*args++);
-  float f = *(float*)(*args++);
-  float g = *(float*)(*args++);
-  float h = *(float*)(*args++);
-  float i = *(float*)(*args++);
-  float j = *(float*)(*args++);
-  float k = *(float*)(*args++);
-  float l = *(float*)(*args++);
-  float m = *(float*)(*args++);
-  int z = *(int*)(*args++);
-  float r=a+b+c+d+e+f+g+h+i+j+k+l+m+z;
-  fprintf(out,"float f(13*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,m,z);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void d_di_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_di) { fprintf(out,"wrong data for d_di\n"); exit(1); }
- {double a = *(double*)(*args++);
-  int z = *(int*)(*args++);
-  double r=a+z;
-  fprintf(out,"double f(double,int):(%g,%d)",a,z);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d2i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d2i) { fprintf(out,"wrong data for d_d2i\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  int z = *(int*)(*args++);
-  double r=a+b+z;
-  fprintf(out,"double f(2*double,int):(%g,%g,%d)",a,b,z);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d3i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d3i) { fprintf(out,"wrong data for d_d3i\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double c = *(double*)(*args++);
-  int z = *(int*)(*args++);
-  double r=a+b+c+z;
-  fprintf(out,"double f(3*double,int):(%g,%g,%g,%d)",a,b,c,z);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d4i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d4i) { fprintf(out,"wrong data for d_d4i\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double c = *(double*)(*args++);
-  double d = *(double*)(*args++);
-  int z = *(int*)(*args++);
-  double r=a+b+c+d+z;
-  fprintf(out,"double f(4*double,int):(%g,%g,%g,%g,%d)",a,b,c,d,z);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d7i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d7i) { fprintf(out,"wrong data for d_d7i\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double c = *(double*)(*args++);
-  double d = *(double*)(*args++);
-  double e = *(double*)(*args++);
-  double f = *(double*)(*args++);
-  double g = *(double*)(*args++);
-  int z = *(int*)(*args++);
-  double r=a+b+c+d+e+f+g+z;
-  fprintf(out,"double f(7*double,int):(%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,z);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d8i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d8i) { fprintf(out,"wrong data for d_d8i\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double c = *(double*)(*args++);
-  double d = *(double*)(*args++);
-  double e = *(double*)(*args++);
-  double f = *(double*)(*args++);
-  double g = *(double*)(*args++);
-  double h = *(double*)(*args++);
-  int z = *(int*)(*args++);
-  double r=a+b+c+d+e+f+g+h+z;
-  fprintf(out,"double f(8*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,z);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d12i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d12i) { fprintf(out,"wrong data for d_d12i\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double c = *(double*)(*args++);
-  double d = *(double*)(*args++);
-  double e = *(double*)(*args++);
-  double f = *(double*)(*args++);
-  double g = *(double*)(*args++);
-  double h = *(double*)(*args++);
-  double i = *(double*)(*args++);
-  double j = *(double*)(*args++);
-  double k = *(double*)(*args++);
-  double l = *(double*)(*args++);
-  int z = *(int*)(*args++);
-  double r=a+b+c+d+e+f+g+h+i+j+k+l+z;
-  fprintf(out,"double f(12*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,z);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_d13i_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d13i) { fprintf(out,"wrong data for d_d13i\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double c = *(double*)(*args++);
-  double d = *(double*)(*args++);
-  double e = *(double*)(*args++);
-  double f = *(double*)(*args++);
-  double g = *(double*)(*args++);
-  double h = *(double*)(*args++);
-  double i = *(double*)(*args++);
-  double j = *(double*)(*args++);
-  double k = *(double*)(*args++);
-  double l = *(double*)(*args++);
-  double m = *(double*)(*args++);
-  int z = *(int*)(*args++);
-  double r=a+b+c+d+e+f+g+h+i+j+k+l+m+z;
-  fprintf(out,"double f(13*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,m,z);
-  fflush(out);
-  *(double*)retp = r;
-}}
-
-/* small structure return tests */
-void S1_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&S1_v) { fprintf(out,"wrong data for S1_v\n"); exit(1); }
- {Size1 r = Size1_1;
-  fprintf(out,"Size1 f(void):");
-  fflush(out);
-  *(Size1*)retp = r;
-}}
-void S2_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&S2_v) { fprintf(out,"wrong data for S2_v\n"); exit(1); }
- {Size2 r = Size2_1;
-  fprintf(out,"Size2 f(void):");
-  fflush(out);
-  *(Size2*)retp = r;
-}}
-void S3_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&S3_v) { fprintf(out,"wrong data for S3_v\n"); exit(1); }
- {Size3 r = Size3_1;
-  fprintf(out,"Size3 f(void):");
-  fflush(out);
-  *(Size3*)retp = r;
-}}
-void S4_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&S4_v) { fprintf(out,"wrong data for S4_v\n"); exit(1); }
- {Size4 r = Size4_1;
-  fprintf(out,"Size4 f(void):");
-  fflush(out);
-  *(Size4*)retp = r;
-}}
-void S7_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&S7_v) { fprintf(out,"wrong data for S7_v\n"); exit(1); }
- {Size7 r = Size7_1;
-  fprintf(out,"Size7 f(void):");
-  fflush(out);
-  *(Size7*)retp = r;
-}}
-void S8_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&S8_v) { fprintf(out,"wrong data for S8_v\n"); exit(1); }
- {Size8 r = Size8_1;
-  fprintf(out,"Size8 f(void):");
-  fflush(out);
-  *(Size8*)retp = r;
-}}
-void S12_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&S12_v) { fprintf(out,"wrong data for S12_v\n"); exit(1); }
- {Size12 r = Size12_1;
-  fprintf(out,"Size12 f(void):");
-  fflush(out);
-  *(Size12*)retp = r;
-}}
-void S15_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&S15_v) { fprintf(out,"wrong data for S15_v\n"); exit(1); }
- {Size15 r = Size15_1;
-  fprintf(out,"Size15 f(void):");
-  fflush(out);
-  *(Size15*)retp = r;
-}}
-void S16_v_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&S16_v) { fprintf(out,"wrong data for S16_v\n"); exit(1); }
- {Size16 r = Size16_1;
-  fprintf(out,"Size16 f(void):");
-  fflush(out);
-  *(Size16*)retp = r;
-}}
-
-/* structure tests */
-void I_III_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&I_III) { fprintf(out,"wrong data for I_III\n"); exit(1); }
- {Int a = *(Int*)(*args++);
-  Int b = *(Int*)(*args++);
-  Int c = *(Int*)(*args++);
-  Int r;
-  r.x = a.x + b.x + c.x;
-  fprintf(out,"Int f(Int,Int,Int):({%d},{%d},{%d})",a.x,b.x,c.x);
-  fflush(out);
-  *(Int*)retp = r;
-}}
-void C_CdC_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&C_CdC) { fprintf(out,"wrong data for C_CdC\n"); exit(1); }
- {Char a = *(Char*)(*args++);
-  double b = *(double*)(*args++);
-  Char c = *(Char*)(*args++);
-  Char r;
-  r.x = (a.x + c.x)/2;
-  fprintf(out,"Char f(Char,double,Char):({'%c'},%g,{'%c'})",a.x,b,c.x);
-  fflush(out);
-  *(Char*)retp = r;
-}}
-void F_Ffd_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&F_Ffd) { fprintf(out,"wrong data for F_Ffd\n"); exit(1); }
- {Float a = *(Float*)(*args++);
-  float b = *(float*)(*args++);
-  double c = *(double*)(*args++);
-  Float r;
-  r.x = a.x + b + c;
-  fprintf(out,"Float f(Float,float,double):({%g},%g,%g)",a.x,b,c);
-  fflush(out);
-  *(Float*)retp = r;
-}}
-void D_fDd_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&D_fDd) { fprintf(out,"wrong data for D_fDd\n"); exit(1); }
- {float a = *(float*)(*args++);
-  Double b = *(Double*)(*args++);
-  double c = *(double*)(*args++);
-  Double r;
-  r.x = a + b.x + c;
-  fprintf(out,"Double f(float,Double,double):(%g,{%g},%g)",a,b.x,c);
-  fflush(out);
-  *(Double*)retp = r;
-}}
-void D_Dfd_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&D_Dfd) { fprintf(out,"wrong data for D_Dfd\n"); exit(1); }
- {Double a = *(Double*)(*args++);
-  float b = *(float*)(*args++);
-  double c = *(double*)(*args++);
-  Double r;
-  r.x = a.x + b + c;
-  fprintf(out,"Double f(Double,float,double):({%g},%g,%g)",a.x,b,c);
-  fflush(out);
-  *(Double*)retp = r;
-}}
-void J_JiJ_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&J_JiJ) { fprintf(out,"wrong data for J_JiJ\n"); exit(1); }
- {J a = *(J*)(*args++);
-  int b= *(int*)(*args++);
-  J c = *(J*)(*args++);
-  J r;
-  r.l1 = a.l1+c.l1; r.l2 = a.l2+b+c.l2;
-  fprintf(out,"J f(J,int,J):({%ld,%ld},%d,{%ld,%ld})",a.l1,a.l2,b,c.l1,c.l2);
-  fflush(out);
-  *(J*)retp = r;
-}}
-#ifndef SKIP_EXTRA_STRUCTS
-void T_TcT_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&T_TcT) { fprintf(out,"wrong data for T_TcT\n"); exit(1); }
- {T a = *(T*)(*args++);
-  char b = *(char*)(*args++);
-  T c = *(T*)(*args++);
-  T r;
-  r.c[0]='b'; r.c[1]=c.c[1]; r.c[2]=c.c[2];
-  fprintf(out,"T f(T,char,T):({\"%c%c%c\"},'%c',{\"%c%c%c\"})",a.c[0],a.c[1],a.c[2],b,c.c[0],c.c[1],c.c[2]);
-  fflush(out);
-  *(T*)retp = r;
-}}
-void X_BcdB_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&X_BcdB) { fprintf(out,"wrong data for X_BcdB\n"); exit(1); }
- {B a = *(B*)(*args++);
-  char b = *(char*)(*args++);
-  double c = *(double*)(*args++);
-  B d = *(B*)(*args++);
-  static X xr={"return val",'R'};
-  X r;
-  r = xr;
-  r.c1 = b;
-  fprintf(out,"X f(B,char,double,B):({%g,{%d,%d,%d}},'%c',%g,{%g,{%d,%d,%d}})",
-          a.d,a.i[0],a.i[1],a.i[2],b,c,d.d,d.i[0],d.i[1],d.i[2]);
-  fflush(out);
-  *(X*)retp = r;
-}}
-#endif
-
-/* gpargs boundary tests */
-void l_l0K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&l_l0K) { fprintf(out,"wrong data for l_l0K\n"); exit(1); }
- {K b = *(K*)(*args++);
-  long c = *(long*)(*args++);
-  long r = b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(K,long):(%ld,%ld,%ld,%ld,%ld)",b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void l_l1K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&l_l1K) { fprintf(out,"wrong data for l_l1K\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  K b = *(K*)(*args++);
-  long c = *(long*)(*args++);
-  long r = a1 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld)",a1,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void l_l2K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&l_l2K) { fprintf(out,"wrong data for l_l2K\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  K b = *(K*)(*args++);
-  long c = *(long*)(*args++);
-  long r = a1 + a2 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(2*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void l_l3K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&l_l3K) { fprintf(out,"wrong data for l_l3K\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  K b = *(K*)(*args++);
-  long c = *(long*)(*args++);
-  long r = a1 + a2 + a3 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(3*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void l_l4K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&l_l4K) { fprintf(out,"wrong data for l_l4K\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  K b = *(K*)(*args++);
-  long c = *(long*)(*args++);
-  long r = a1 + a2 + a3 + a4 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(4*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void l_l5K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&l_l5K) { fprintf(out,"wrong data for l_l5K\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  long a5 = *(long*)(*args++);
-  K b = *(K*)(*args++);
-  long c = *(long*)(*args++);
-  long r = a1 + a2 + a3 + a4 + a5 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(5*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,a5,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void l_l6K_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&l_l6K) { fprintf(out,"wrong data for l_l6K\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  long a5 = *(long*)(*args++);
-  long a6 = *(long*)(*args++);
-  K b = *(K*)(*args++);
-  long c = *(long*)(*args++);
-  long r = a1 + a2 + a3 + a4 + a5 + a6 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(6*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,a5,a6,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  *(ffi_arg*)retp = r;
-}}
-void f_f17l3L_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&f_f17l3L) { fprintf(out,"wrong data for f_f17l3L\n"); exit(1); }
- {float a = *(float*)(*args++);
-  float b = *(float*)(*args++);
-  float c = *(float*)(*args++);
-  float d = *(float*)(*args++);
-  float e = *(float*)(*args++);
-  float f = *(float*)(*args++);
-  float g = *(float*)(*args++);
-  float h = *(float*)(*args++);
-  float i = *(float*)(*args++);
-  float j = *(float*)(*args++);
-  float k = *(float*)(*args++);
-  float l = *(float*)(*args++);
-  float m = *(float*)(*args++);
-  float n = *(float*)(*args++);
-  float o = *(float*)(*args++);
-  float p = *(float*)(*args++);
-  float q = *(float*)(*args++);
-  long s = *(long*)(*args++);
-  long t = *(long*)(*args++);
-  long u = *(long*)(*args++);
-  L z = *(L*)(*args++);
-  float r = a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+z.l1+z.l2+z.l3+z.l4+z.l5+z.l6;
-  fprintf(out,"float f(17*float,3*int,L):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,z.l1,z.l2,z.l3,z.l4,z.l5,z.l6);
-  fflush(out);
-  *(float*)retp = r;
-}}
-void d_d17l3L_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_d17l3L) { fprintf(out,"wrong data for d_d17l3L\n"); exit(1); }
- {double a = *(double*)(*args++);
-  double b = *(double*)(*args++);
-  double c = *(double*)(*args++);
-  double d = *(double*)(*args++);
-  double e = *(double*)(*args++);
-  double f = *(double*)(*args++);
-  double g = *(double*)(*args++);
-  double h = *(double*)(*args++);
-  double i = *(double*)(*args++);
-  double j = *(double*)(*args++);
-  double k = *(double*)(*args++);
-  double l = *(double*)(*args++);
-  double m = *(double*)(*args++);
-  double n = *(double*)(*args++);
-  double o = *(double*)(*args++);
-  double p = *(double*)(*args++);
-  double q = *(double*)(*args++);
-  long s = *(long*)(*args++);
-  long t = *(long*)(*args++);
-  long u = *(long*)(*args++);
-  L z = *(L*)(*args++);
-  double r = a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+z.l1+z.l2+z.l3+z.l4+z.l5+z.l6;
-  fprintf(out,"double f(17*double,3*int,L):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,z.l1,z.l2,z.l3,z.l4,z.l5,z.l6);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void ll_l2ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&ll_l2ll) { fprintf(out,"wrong data for ll_l2ll\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long long b = *(long long *)(*args++);
-  long c = *(long*)(*args++);
-  long long r = (long long) (a1 + a2) + b + c;
-  fprintf(out,"long long f(2*long,long long,long):(%ld,%ld,0x%lx%08lx,%ld)",a1,a2,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  *(long long *)retp = r;
-}}
-void ll_l3ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&ll_l3ll) { fprintf(out,"wrong data for ll_l3ll\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long long b = *(long long *)(*args++);
-  long c = *(long*)(*args++);
-  long long r = (long long) (a1 + a2 + a3) + b + c;
-  fprintf(out,"long long f(3*long,long long,long):(%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  *(long long *)retp = r;
-}}
-void ll_l4ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&ll_l4ll) { fprintf(out,"wrong data for ll_l4ll\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  long long b = *(long long *)(*args++);
-  long c = *(long*)(*args++);
-  long long r = (long long) (a1 + a2 + a3 + a4) + b + c;
-  fprintf(out,"long long f(4*long,long long,long):(%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  *(long long *)retp = r;
-}}
-void ll_l5ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&ll_l5ll) { fprintf(out,"wrong data for ll_l5ll\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  long a5 = *(long*)(*args++);
-  long long b = *(long long *)(*args++);
-  long c = *(long*)(*args++);
-  long long r = (long long) (a1 + a2 + a3 + a4 + a5) + b + c;
-  fprintf(out,"long long f(5*long,long long,long):(%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  *(long long *)retp = r;
-}}
-void ll_l6ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&ll_l6ll) { fprintf(out,"wrong data for ll_l6ll\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  long a5 = *(long*)(*args++);
-  long a6 = *(long*)(*args++);
-  long long b = *(long long *)(*args++);
-  long c = *(long*)(*args++);
-  long long r = (long long) (a1 + a2 + a3 + a4 + a5 + a6) + b + c;
-  fprintf(out,"long long f(6*long,long long,long):(%ld,%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,a6,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  *(long long *)retp = r;
-}}
-void ll_l7ll_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&ll_l7ll) { fprintf(out,"wrong data for ll_l7ll\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  long a5 = *(long*)(*args++);
-  long a6 = *(long*)(*args++);
-  long a7 = *(long*)(*args++);
-  long long b = *(long long *)(*args++);
-  long c = *(long*)(*args++);
-  long long r = (long long) (a1 + a2 + a3 + a4 + a5 + a6 + a7) + b + c;
-  fprintf(out,"long long f(7*long,long long,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,a6,a7,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  *(long long *)retp = r;
-}}
-void d_l2d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_l2d) { fprintf(out,"wrong data for d_l2d\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  double b = *(double*)(*args++);
-  long c = *(long*)(*args++);
-  double r = (double) (a1 + a2) + b + c;
-  fprintf(out,"double f(2*long,double,long):(%ld,%ld,%g,%ld)",a1,a2,b,c);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_l3d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_l3d) { fprintf(out,"wrong data for d_l3d\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  double b = *(double*)(*args++);
-  long c = *(long*)(*args++);
-  double r = (double) (a1 + a2 + a3) + b + c;
-  fprintf(out,"double f(3*long,double,long):(%ld,%ld,%ld,%g,%ld)",a1,a2,a3,b,c);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_l4d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_l4d) { fprintf(out,"wrong data for d_l4d\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  double b = *(double*)(*args++);
-  long c = *(long*)(*args++);
-  double r = (double) (a1 + a2 + a3 + a4) + b + c;
-  fprintf(out,"double f(4*long,double,long):(%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,b,c);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_l5d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_l5d) { fprintf(out,"wrong data for d_l5d\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  long a5 = *(long*)(*args++);
-  double b = *(double*)(*args++);
-  long c = *(long*)(*args++);
-  double r = (double) (a1 + a2 + a3 + a4 + a5) + b + c;
-  fprintf(out,"double f(5*long,double,long):(%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,b,c);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_l6d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_l6d) { fprintf(out,"wrong data for d_l6d\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  long a5 = *(long*)(*args++);
-  long a6 = *(long*)(*args++);
-  double b = *(double*)(*args++);
-  long c = *(long*)(*args++);
-  double r = (double) (a1 + a2 + a3 + a4 + a5 + a6) + b + c;
-  fprintf(out,"double f(6*long,double,long):(%ld,%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,a6,b,c);
-  fflush(out);
-  *(double*)retp = r;
-}}
-void d_l7d_simulator (ffi_cif* cif, void* retp, /*const*/ void* /*const*/ *args, void* data)
-{
-  if (data != (void*)&d_l7d) { fprintf(out,"wrong data for d_l7d\n"); exit(1); }
- {long a1 = *(long*)(*args++);
-  long a2 = *(long*)(*args++);
-  long a3 = *(long*)(*args++);
-  long a4 = *(long*)(*args++);
-  long a5 = *(long*)(*args++);
-  long a6 = *(long*)(*args++);
-  long a7 = *(long*)(*args++);
-  double b = *(double*)(*args++);
-  long c = *(long*)(*args++);
-  double r = (double) (a1 + a2 + a3 + a4 + a5 + a6 + a7) + b + c;
-  fprintf(out,"double f(7*long,double,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,a6,a7,b,c);
-  fflush(out);
-  *(double*)retp = r;
-}}
-
-
-/*
- * The way we run these tests - first call the function directly, then
- * through vacall() - there is the danger that arguments or results seem
- * to be passed correctly, but what we are seeing are in fact the vestiges
- * (traces) or the previous call. This may seriously fake the test.
- * Avoid this by clearing the registers between the first and the second call.
- */
-long clear_traces_i (long a, long b, long c, long d, long e, long f, long g, long h,
-                     long i, long j, long k, long l, long m, long n, long o, long p)
-{ return 0; }
-float clear_traces_f (float a, float b, float c, float d, float e, float f, float g,
-                      float h, float i, float j, float k, float l, float m, float n,
-                      float o, float p)
-{ return 0.0; }
-double clear_traces_d (double a, double b, double c, double d, double e, double f, double g,
-                       double h, double i, double j, double k, double l, double m, double n,
-                       double o, double p)
-{ return 0.0; }
-J clear_traces_J (void)
-{ J j; j.l1 = j.l2 = 0; return j; }
-void clear_traces (void)
-{ clear_traces_i(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
-  clear_traces_f(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
-  clear_traces_d(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
-  clear_traces_J();
-}
-
-int main (void)
-{
-  void* callback_code;
-  void* callback_writable;
-#define ALLOC_CALLBACK() \
-  callback_writable = ffi_closure_alloc(sizeof(ffi_closure),&callback_code); \
-  if (!callback_writable) abort()
-#define PREP_CALLBACK(cif,simulator,data) \
-  if (ffi_prep_closure_loc(callback_writable,&(cif),simulator,data,callback_code) != FFI_OK) abort()
-#define FREE_CALLBACK() \
-  ffi_closure_free(callback_writable)
-
-  ffi_type_char = (char)(-1) < 0 ? ffi_type_schar : ffi_type_uchar;
-  out = stdout;
-
-#if (!defined(DGTEST)) || DGTEST == 1  
-  /* void tests */
-  v_v();
-  clear_traces();
-  ALLOC_CALLBACK();
-  {
-    ffi_cif cif;
-    FFI_PREP_CIF_NOARGS(cif,ffi_type_void);
-    PREP_CALLBACK(cif,v_v_simulator,(void*)&v_v);
-    ((void (ABI_ATTR *) (void)) callback_code) ();
-  }
-  FREE_CALLBACK();
-#endif
-
-  /* int tests */
-  { int ir;
-
-#if (!defined(DGTEST)) || DGTEST == 2
-    ir = i_v();
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-    ir = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_sint);
-      PREP_CALLBACK(cif,i_v_simulator,(void*)&i_v);
-      ir = ((int (ABI_ATTR *) (void)) callback_code) ();
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-#endif    
-
-#if (!defined(DGTEST)) || DGTEST == 3
-    ir = i_i(i1);
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-    ir = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
-      PREP_CALLBACK(cif,i_i_simulator,(void*)&i_i);
-      ir = ((int (ABI_ATTR *) (int)) callback_code) (i1);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 4    
-    ir = i_i2(i1,i2);
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-    ir = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
-      PREP_CALLBACK(cif,i_i2_simulator,(void*)&i_i2);
-      ir = ((int (ABI_ATTR *) (int,int)) callback_code) (i1,i2);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 5    
-    ir = i_i4(i1,i2,i3,i4);
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-    ir = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
-      PREP_CALLBACK(cif,i_i4_simulator,(void*)&i_i4);
-      ir = ((int (ABI_ATTR *) (int,int,int,int)) callback_code) (i1,i2,i3,i4);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 6    
-    ir = i_i8(i1,i2,i3,i4,i5,i6,i7,i8);
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-    ir = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
-      PREP_CALLBACK(cif,i_i8_simulator,(void*)&i_i8);
-      ir = ((int (ABI_ATTR *) (int,int,int,int,int,int,int,int)) callback_code) (i1,i2,i3,i4,i5,i6,i7,i8);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-#endif
-  
-#if (!defined(DGTEST)) || DGTEST == 7
-    ir = i_i16(i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16);
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-    ir = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_sint);
-      PREP_CALLBACK(cif,i_i16_simulator,(void*)&i_i16);
-      ir = ((int (ABI_ATTR *) (int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int)) callback_code) (i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%d\n",ir);
-    fflush(out);
-#endif
-  }
-
-  /* float tests */
-  { float fr;
-
-#if (!defined(DGTEST)) || DGTEST == 8  
-    fr = f_f(f1);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f_simulator,(void*)&f_f);
-      fr = ((float (ABI_ATTR *) (float)) callback_code) (f1);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 9    
-    fr = f_f2(f1,f2);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f2_simulator,(void*)&f_f2);
-      fr = ((float (ABI_ATTR *) (float,float)) callback_code) (f1,f2);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 10
-    fr = f_f4(f1,f2,f3,f4);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f4_simulator,(void*)&f_f4);
-      fr = ((float (ABI_ATTR *) (float,float,float,float)) callback_code) (f1,f2,f3,f4);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 11    
-    fr = f_f8(f1,f2,f3,f4,f5,f6,f7,f8);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f8_simulator,(void*)&f_f8);
-      fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 12    
-    fr = f_f16(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f16_simulator,(void*)&f_f16);
-      fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 13    
-    fr = f_f24(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20,f21,f22,f23,f24);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f24_simulator,(void*)&f_f24);
-      fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20,f21,f22,f23,f24);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-  }
-
-  /* double tests */
-  { double dr;
-
-#if (!defined(DGTEST)) || DGTEST == 14
-    dr = d_d(d1);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d_simulator,(void*)&d_d);
-      dr = ((double (ABI_ATTR *) (double)) callback_code) (d1);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 15    
-    dr = d_d2(d1,d2);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d2_simulator,(void*)&d_d2);
-      dr = ((double (ABI_ATTR *) (double,double)) callback_code) (d1,d2);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-  
-#if (!defined(DGTEST)) || DGTEST == 16    
-    dr = d_d4(d1,d2,d3,d4);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d4_simulator,(void*)&d_d4);
-      dr = ((double (ABI_ATTR *) (double,double,double,double)) callback_code) (d1,d2,d3,d4);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 17    
-    dr = d_d8(d1,d2,d3,d4,d5,d6,d7,d8);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d8_simulator,(void*)&d_d8);
-      dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 18    
-    dr = d_d16(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d16_simulator,(void*)&d_d16);
-      dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,double)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-  }
-
-  /* pointer tests */
-  { void* vpr;
-
-#if (!defined(DGTEST)) || DGTEST == 19 
-    vpr = vp_vpdpcpsp(&uc1,&d2,str3,&I4);
-    fprintf(out,"->0x%p\n",vpr);
-    fflush(out);
-    vpr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_pointer, &ffi_type_pointer, &ffi_type_pointer, &ffi_type_pointer };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_pointer);
-      PREP_CALLBACK(cif,vp_vpdpcpsp_simulator,(void*)&vp_vpdpcpsp);
-      vpr = ((void* (ABI_ATTR *) (void*,double*,char*,Int*)) callback_code) (&uc1,&d2,str3,&I4);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->0x%p\n",vpr);
-    fflush(out);
-#endif
-  }
-
-  /* mixed number tests */
-  { uchar ucr;
-    ushort usr;
-    float fr;
-    double dr;
-    long long llr;
-
-#if (!defined(DGTEST)) || DGTEST == 20
-    ucr = uc_ucsil(uc1,us2,ui3,ul4);
-    fprintf(out,"->%u\n",ucr);
-    fflush(out);
-    ucr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_uchar, &ffi_type_ushort, &ffi_type_uint, &ffi_type_ulong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_uchar);
-      PREP_CALLBACK(cif,uc_ucsil_simulator,(void*)&uc_ucsil);
-      ucr = ((uchar (ABI_ATTR *) (uchar,ushort,uint,ulong)) callback_code) (uc1,us2,ui3,ul4);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%u\n",ucr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 21    
-    dr = d_iidd(i1,i2,d3,d4);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_double, &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_iidd_simulator,(void*)&d_iidd);
-      dr = ((double (ABI_ATTR *) (int,int,double,double)) callback_code) (i1,i2,d3,d4);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 22    
-    dr = d_iiidi(i1,i2,i3,d4,i5);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_double, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_iiidi_simulator,(void*)&d_iiidi);
-      dr = ((double (ABI_ATTR *) (int,int,int,double,int)) callback_code) (i1,i2,i3,d4,i5);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 23    
-    dr = d_idid(i1,d2,i3,d4);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_double, &ffi_type_sint, &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_idid_simulator,(void*)&d_idid);
-      dr = ((double (ABI_ATTR *) (int,double,int,double)) callback_code) (i1,d2,i3,d4);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 24    
-    dr = d_fdi(f1,d2,i3);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_double, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_fdi_simulator,(void*)&d_fdi);
-      dr = ((double (ABI_ATTR *) (float,double,int)) callback_code) (f1,d2,i3);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 25    
-    usr = us_cdcd(c1,d2,c3,d4);
-    fprintf(out,"->%u\n",usr);
-    fflush(out);
-    usr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_char, &ffi_type_double, &ffi_type_char, &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_ushort);
-      PREP_CALLBACK(cif,us_cdcd_simulator,(void*)&us_cdcd);
-      usr = ((ushort (ABI_ATTR *) (char,double,char,double)) callback_code) (c1,d2,c3,d4);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%u\n",usr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 26    
-    llr = ll_iiilli(i1,i2,i3,ll1,i13);
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-    llr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_sint, &ffi_type_sint, &ffi_type_sint, &ffi_type_slonglong, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-      PREP_CALLBACK(cif,ll_iiilli_simulator,(void*)&ll_iiilli);
-      llr = ((long long (ABI_ATTR *) (int,int,int,long long,int)) callback_code) (i1,i2,i3,ll1,i13);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 27    
-    llr = ll_flli(f13,ll1,i13);
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-    llr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_slonglong, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-      PREP_CALLBACK(cif,ll_flli_simulator,(void*)&ll_flli);
-      llr = ((long long (ABI_ATTR *) (float,long long,int)) callback_code) (f13,ll1,i13);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 28    
-    fr = f_fi(f1,i9);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_fi_simulator,(void*)&f_fi);
-      fr = ((float (ABI_ATTR *) (float,int)) callback_code) (f1,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 29    
-    fr = f_f2i(f1,f2,i9);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f2i_simulator,(void*)&f_f2i);
-      fr = ((float (ABI_ATTR *) (float,float,int)) callback_code) (f1,f2,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 30    
-    fr = f_f3i(f1,f2,f3,i9);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f3i_simulator,(void*)&f_f3i);
-      fr = ((float (ABI_ATTR *) (float,float,float,int)) callback_code) (f1,f2,f3,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 31    
-    fr = f_f4i(f1,f2,f3,f4,i9);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f4i_simulator,(void*)&f_f4i);
-      fr = ((float (ABI_ATTR *) (float,float,float,float,int)) callback_code) (f1,f2,f3,f4,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 32    
-    fr = f_f7i(f1,f2,f3,f4,f5,f6,f7,i9);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f7i_simulator,(void*)&f_f7i);
-      fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,int)) callback_code) (f1,f2,f3,f4,f5,f6,f7,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 33    
-    fr = f_f8i(f1,f2,f3,f4,f5,f6,f7,f8,i9);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f8i_simulator,(void*)&f_f8i);
-      fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float,int)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 34    
-    fr = f_f13i(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,i9);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f13i_simulator,(void*)&f_f13i);
-      fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float,float,float,float,float,float,int)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 35    
-    dr = d_di(d1,i9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_di_simulator,(void*)&d_di);
-      dr = ((double (ABI_ATTR *) (double,int)) callback_code) (d1,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 36    
-    dr = d_d2i(d1,d2,i9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d2i_simulator,(void*)&d_d2i);
-      dr = ((double (ABI_ATTR *) (double,double,int)) callback_code) (d1,d2,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 37    
-    dr = d_d3i(d1,d2,d3,i9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d3i_simulator,(void*)&d_d3i);
-      dr = ((double (ABI_ATTR *) (double,double,double,int)) callback_code) (d1,d2,d3,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 38    
-    dr = d_d4i(d1,d2,d3,d4,i9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d4i_simulator,(void*)&d_d4i);
-      dr = ((double (ABI_ATTR *) (double,double,double,double,int)) callback_code) (d1,d2,d3,d4,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 39    
-    dr = d_d7i(d1,d2,d3,d4,d5,d6,d7,i9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d7i_simulator,(void*)&d_d7i);
-      dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,int)) callback_code) (d1,d2,d3,d4,d5,d6,d7,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 40    
-    dr = d_d8i(d1,d2,d3,d4,d5,d6,d7,d8,i9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d8i_simulator,(void*)&d_d8i);
-      dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double,int)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 41    
-    dr = d_d12i(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,i9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d12i_simulator,(void*)&d_d12i);
-      dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double,double,double,double,double,int)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 42    
-    dr = d_d13i(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,i9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_sint };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d13i_simulator,(void*)&d_d13i);
-      dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double,double,double,double,double,double,int)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,i9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-  }
-
-  /* small structure return tests */
-#if (!defined(DGTEST)) || DGTEST == 43
-  {
-    Size1 r = S1_v();
-    fprintf(out,"->{%c}\n",r.x1);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Size1_elements[] = { &ffi_type_char, NULL };
-      ffi_type ffi_type_Size1;
-      ffi_type_Size1.type = FFI_TYPE_STRUCT;
-      ffi_type_Size1.size = sizeof(Size1);
-      ffi_type_Size1.alignment = alignof_slot(Size1);
-      ffi_type_Size1.elements = ffi_type_Size1_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size1);
-      PREP_CALLBACK(cif,S1_v_simulator,(void*)&S1_v);
-      r = ((Size1 (ABI_ATTR *) (void)) callback_code) ();
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%c}\n",r.x1);
-    fflush(out);
-  }
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 44
-  {
-    Size2 r = S2_v();
-    fprintf(out,"->{%c%c}\n",r.x1,r.x2);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Size2_elements[] = { &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size2;
-      ffi_type_Size2.type = FFI_TYPE_STRUCT;
-      ffi_type_Size2.size = sizeof(Size2);
-      ffi_type_Size2.alignment = alignof_slot(Size2);
-      ffi_type_Size2.elements = ffi_type_Size2_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size2);
-      PREP_CALLBACK(cif,S2_v_simulator,(void*)&S2_v);
-      r = ((Size2 (ABI_ATTR *) (void)) callback_code) ();
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%c%c}\n",r.x1,r.x2);
-    fflush(out);
-  }
-#endif    
-
-#if (!defined(DGTEST)) || DGTEST == 45
-  {
-    Size3 r = S3_v();
-    fprintf(out,"->{%c%c%c}\n",r.x1,r.x2,r.x3);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Size3_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size3;
-      ffi_type_Size3.type = FFI_TYPE_STRUCT;
-      ffi_type_Size3.size = sizeof(Size3);
-      ffi_type_Size3.alignment = alignof_slot(Size3);
-      ffi_type_Size3.elements = ffi_type_Size3_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size3);
-      PREP_CALLBACK(cif,S3_v_simulator,(void*)&S3_v);
-      r = ((Size3 (ABI_ATTR *) (void)) callback_code) ();
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%c%c%c}\n",r.x1,r.x2,r.x3);
-    fflush(out);
-  }
-#endif    
-
-#if (!defined(DGTEST)) || DGTEST == 46
-  {
-    Size4 r = S4_v();
-    fprintf(out,"->{%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Size4_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size4;
-      ffi_type_Size4.type = FFI_TYPE_STRUCT;
-      ffi_type_Size4.size = sizeof(Size4);
-      ffi_type_Size4.alignment = alignof_slot(Size4);
-      ffi_type_Size4.elements = ffi_type_Size4_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size4);
-      PREP_CALLBACK(cif,S4_v_simulator,(void*)&S4_v);
-      r = ((Size4 (ABI_ATTR *) (void)) callback_code) ();
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4);
-    fflush(out);
-  }
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 47  
-  {
-    Size7 r = S7_v();
-    fprintf(out,"->{%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Size7_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size7;
-      ffi_type_Size7.type = FFI_TYPE_STRUCT;
-      ffi_type_Size7.size = sizeof(Size7);
-      ffi_type_Size7.alignment = alignof_slot(Size7);
-      ffi_type_Size7.elements = ffi_type_Size7_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size7);
-      PREP_CALLBACK(cif,S7_v_simulator,(void*)&S7_v);
-      r = ((Size7 (ABI_ATTR *) (void)) callback_code) ();
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7);
-    fflush(out);
-  }
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 48  
-  {
-    Size8 r = S8_v();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Size8_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size8;
-      ffi_type_Size8.type = FFI_TYPE_STRUCT;
-      ffi_type_Size8.size = sizeof(Size8);
-      ffi_type_Size8.alignment = alignof_slot(Size8);
-      ffi_type_Size8.elements = ffi_type_Size8_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size8);
-      PREP_CALLBACK(cif,S8_v_simulator,(void*)&S8_v);
-      r = ((Size8 (ABI_ATTR *) (void)) callback_code) ();
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8);
-    fflush(out);
-  }
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 49
-  {
-    Size12 r = S12_v();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Size12_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size12;
-      ffi_type_Size12.type = FFI_TYPE_STRUCT;
-      ffi_type_Size12.size = sizeof(Size12);
-      ffi_type_Size12.alignment = alignof_slot(Size12);
-      ffi_type_Size12.elements = ffi_type_Size12_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size12);
-      PREP_CALLBACK(cif,S12_v_simulator,(void*)&S12_v);
-      r = ((Size12 (ABI_ATTR *) (void)) callback_code) ();
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12);
-    fflush(out);
-  }
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 50  
-  {
-    Size15 r = S15_v();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Size15_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size15;
-      ffi_type_Size15.type = FFI_TYPE_STRUCT;
-      ffi_type_Size15.size = sizeof(Size15);
-      ffi_type_Size15.alignment = alignof_slot(Size15);
-      ffi_type_Size15.elements = ffi_type_Size15_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size15);
-      PREP_CALLBACK(cif,S15_v_simulator,(void*)&S15_v);
-      r = ((Size15 (ABI_ATTR *) (void)) callback_code) ();
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15);
-    fflush(out);
-  }
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 51
-  {
-    Size16 r = S16_v();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15,r.x16);
-    fflush(out);
-    memset(&r,0,sizeof(r)); clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Size16_elements[] = { &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, &ffi_type_char, NULL };
-      ffi_type ffi_type_Size16;
-      ffi_type_Size16.type = FFI_TYPE_STRUCT;
-      ffi_type_Size16.size = sizeof(Size16);
-      ffi_type_Size16.alignment = alignof_slot(Size16);
-      ffi_type_Size16.elements = ffi_type_Size16_elements;
-      ffi_cif cif;
-      FFI_PREP_CIF_NOARGS(cif,ffi_type_Size16);
-      PREP_CALLBACK(cif,S16_v_simulator,(void*)&S16_v);
-      r = ((Size16 (ABI_ATTR *) (void)) callback_code) ();
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c}\n",r.x1,r.x2,r.x3,r.x4,r.x5,r.x6,r.x7,r.x8,r.x9,r.x10,r.x11,r.x12,r.x13,r.x14,r.x15,r.x16);
-    fflush(out);
-  }
-#endif
-
-  
-  /* structure tests */
-  { Int Ir;
-    Char Cr;
-    Float Fr;
-    Double Dr;
-    J Jr;
-#ifndef SKIP_EXTRA_STRUCTS
-    T Tr;
-    X Xr;
-#endif    
-
-#if (!defined(DGTEST)) || DGTEST == 52
-    Ir = I_III(I1,I2,I3);
-    fprintf(out,"->{%d}\n",Ir.x);
-    fflush(out);
-    Ir.x = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Int_elements[] = { &ffi_type_sint, NULL };
-      ffi_type ffi_type_Int;
-      ffi_type_Int.type = FFI_TYPE_STRUCT;
-      ffi_type_Int.size = sizeof(Int);
-      ffi_type_Int.alignment = alignof_slot(Int);
-      ffi_type_Int.elements = ffi_type_Int_elements;
-      ffi_type* argtypes[] = { &ffi_type_Int, &ffi_type_Int, &ffi_type_Int };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_Int);
-      PREP_CALLBACK(cif,I_III_simulator,(void*)&I_III);
-      Ir = ((Int (ABI_ATTR *) (Int,Int,Int)) callback_code) (I1,I2,I3);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%d}\n",Ir.x);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 53
-    Cr = C_CdC(C1,d2,C3);
-    fprintf(out,"->{'%c'}\n",Cr.x);
-    fflush(out);
-    Cr.x = '\0'; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Char_elements[] = { &ffi_type_char, NULL };
-      ffi_type ffi_type_Char;
-      ffi_type_Char.type = FFI_TYPE_STRUCT;
-      ffi_type_Char.size = sizeof(Char);
-      ffi_type_Char.alignment = alignof_slot(Char);
-      ffi_type_Char.elements = ffi_type_Char_elements;
-      ffi_type* argtypes[] = { &ffi_type_Char, &ffi_type_double, &ffi_type_Char };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_Char);
-      PREP_CALLBACK(cif,C_CdC_simulator,(void*)&C_CdC);
-      Cr = ((Char (ABI_ATTR *) (Char,double,Char)) callback_code) (C1,d2,C3);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{'%c'}\n",Cr.x);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 54    
-    Fr = F_Ffd(F1,f2,d3);
-    fprintf(out,"->{%g}\n",Fr.x);
-    fflush(out);
-    Fr.x = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Float_elements[] = { &ffi_type_float, NULL };
-      ffi_type ffi_type_Float;
-      ffi_type_Float.type = FFI_TYPE_STRUCT;
-      ffi_type_Float.size = sizeof(Float);
-      ffi_type_Float.alignment = alignof_slot(Float);
-      ffi_type_Float.elements = ffi_type_Float_elements;
-      ffi_type* argtypes[] = { &ffi_type_Float, &ffi_type_float, &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_Float);
-      PREP_CALLBACK(cif,F_Ffd_simulator,(void*)&F_Ffd);
-      Fr = ((Float (ABI_ATTR *) (Float,float,double)) callback_code) (F1,f2,d3);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%g}\n",Fr.x);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 55    
-    Dr = D_fDd(f1,D2,d3);
-    fprintf(out,"->{%g}\n",Dr.x);
-    fflush(out);
-    Dr.x = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Double_elements[] = { &ffi_type_double, NULL };
-      ffi_type ffi_type_Double;
-      ffi_type_Double.type = FFI_TYPE_STRUCT;
-      ffi_type_Double.size = sizeof(Double);
-      ffi_type_Double.alignment = alignof_slot(Double);
-      ffi_type_Double.elements = ffi_type_Double_elements;
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_Double, &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_Double);
-      PREP_CALLBACK(cif,D_fDd_simulator,(void*)&D_fDd);
-      Dr = ((Double (ABI_ATTR *) (float,Double,double)) callback_code) (f1,D2,d3);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%g}\n",Dr.x);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 56
-    Dr = D_Dfd(D1,f2,d3);
-    fprintf(out,"->{%g}\n",Dr.x);
-    fflush(out);
-    Dr.x = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_Double_elements[] = { &ffi_type_double, NULL };
-      ffi_type ffi_type_Double;
-      ffi_type_Double.type = FFI_TYPE_STRUCT;
-      ffi_type_Double.size = sizeof(Double);
-      ffi_type_Double.alignment = alignof_slot(Double);
-      ffi_type_Double.elements = ffi_type_Double_elements;
-      ffi_type* argtypes[] = { &ffi_type_Double, &ffi_type_float, &ffi_type_double };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_Double);
-      PREP_CALLBACK(cif,D_Dfd_simulator,(void*)&D_Dfd);
-      Dr = ((Double (ABI_ATTR *) (Double,float,double)) callback_code) (D1,f2,d3);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%g}\n",Dr.x);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 57
-    Jr = J_JiJ(J1,i2,J2);
-    fprintf(out,"->{%ld,%ld}\n",Jr.l1,Jr.l2);
-    fflush(out);
-    Jr.l1 = Jr.l2 = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_J_elements[] = { &ffi_type_slong, &ffi_type_slong, NULL };
-      ffi_type ffi_type_J;
-      ffi_type_J.type = FFI_TYPE_STRUCT;
-      ffi_type_J.size = sizeof(J);
-      ffi_type_J.alignment = alignof_slot(J);
-      ffi_type_J.elements = ffi_type_J_elements;
-      ffi_type* argtypes[] = { &ffi_type_J, &ffi_type_sint, &ffi_type_J };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_J);
-      PREP_CALLBACK(cif,J_JiJ_simulator,(void*)&J_JiJ);
-      Jr = ((J (ABI_ATTR *) (J,int,J)) callback_code) (J1,i2,J2);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{%ld,%ld}\n",Jr.l1,Jr.l2);
-    fflush(out);
-#endif
-
-#ifndef SKIP_EXTRA_STRUCTS
-#if (!defined(DGTEST)) || DGTEST == 58
-    Tr = T_TcT(T1,' ',T2);
-    fprintf(out,"->{\"%c%c%c\"}\n",Tr.c[0],Tr.c[1],Tr.c[2]);
-    fflush(out);
-    Tr.c[0] = Tr.c[1] = Tr.c[2] = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_T_elements[] = { ??, NULL };
-      ffi_type ffi_type_T;
-      ffi_type_T.type = FFI_TYPE_STRUCT;
-      ffi_type_T.size = sizeof(T);
-      ffi_type_T.alignment = alignof_slot(T);
-      ffi_type_T.elements = ffi_type_T_elements;
-      ffi_type* argtypes[] = { &ffi_type_T, &ffi_type_char, &ffi_type_T };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_T);
-      PREP_CALLBACK(cif,T_TcT_simulator,(void*)&T_TcT);
-      Tr = ((T (ABI_ATTR *) (T,char,T)) callback_code) (T1,' ',T2);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{\"%c%c%c\"}\n",Tr.c[0],Tr.c[1],Tr.c[2]);
-    fflush(out);
-#endif
-
-#ifndef SKIP_X
-#if (!defined(DGTEST)) || DGTEST == 59
-    Xr = X_BcdB(B1,c2,d3,B2);
-    fprintf(out,"->{\"%s\",'%c'}\n",Xr.c,Xr.c1);
-    fflush(out);
-    Xr.c[0]=Xr.c1='\0'; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* ffi_type_X_elements[] = { ??, NULL };
-      ffi_type ffi_type_X;
-      ffi_type_X.type = FFI_TYPE_STRUCT;
-      ffi_type_X.size = sizeof(X);
-      ffi_type_X.alignment = alignof_slot(X);
-      ffi_type_X.elements = ffi_type_X_elements;
-      ffi_type* argtypes[] = { &ffi_type_X, &ffi_type_char, &ffi_type_double, &ffi_type_X };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_X);
-      PREP_CALLBACK(cif,X_BcdB_simulator,(void*)&X_BcdB);
-      Xr = ((X (ABI_ATTR *) (B,char,double,B)) callback_code) (B1,c2,d3,B2);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->{\"%s\",'%c'}\n",Xr.c,Xr.c1);
-    fflush(out);
-#endif
-#endif
-#endif
-  }
-
-  
-  /* gpargs boundary tests */
-  {
-    ffi_type* ffi_type_K_elements[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, NULL };
-    ffi_type ffi_type_K;
-    ffi_type* ffi_type_L_elements[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, NULL };
-    ffi_type ffi_type_L;
-    long lr;
-    long long llr;
-    float fr;
-    double dr;
-
-    ffi_type_K.type = FFI_TYPE_STRUCT;
-    ffi_type_K.size = sizeof(K);
-    ffi_type_K.alignment = alignof_slot(K);
-    ffi_type_K.elements = ffi_type_K_elements;
-
-    ffi_type_L.type = FFI_TYPE_STRUCT;
-    ffi_type_L.size = sizeof(L);
-    ffi_type_L.alignment = alignof_slot(L);
-    ffi_type_L.elements = ffi_type_L_elements;
-
-#if (!defined(DGTEST)) || DGTEST == 60
-    lr = l_l0K(K1,l9);
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-    lr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_K, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-      PREP_CALLBACK(cif,l_l0K_simulator,(void*)l_l0K);
-      lr = ((long (ABI_ATTR *) (K,long)) callback_code) (K1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 61
-    lr = l_l1K(l1,K1,l9);
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-    lr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-      PREP_CALLBACK(cif,l_l1K_simulator,(void*)l_l1K);
-      lr = ((long (ABI_ATTR *) (long,K,long)) callback_code) (l1,K1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 62
-    lr = l_l2K(l1,l2,K1,l9);
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-    lr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-      PREP_CALLBACK(cif,l_l2K_simulator,(void*)l_l2K);
-      lr = ((long (ABI_ATTR *) (long,long,K,long)) callback_code) (l1,l2,K1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 63
-    lr = l_l3K(l1,l2,l3,K1,l9);
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-    lr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-      PREP_CALLBACK(cif,l_l3K_simulator,(void*)l_l3K);
-      lr = ((long (ABI_ATTR *) (long,long,long,K,long)) callback_code) (l1,l2,l3,K1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 64
-    lr = l_l4K(l1,l2,l3,l4,K1,l9);
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-    lr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-      PREP_CALLBACK(cif,l_l4K_simulator,(void*)l_l4K);
-      lr = ((long (ABI_ATTR *) (long,long,long,long,K,long)) callback_code) (l1,l2,l3,l4,K1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 65  
-    lr = l_l5K(l1,l2,l3,l4,l5,K1,l9);
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-    lr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-      PREP_CALLBACK(cif,l_l5K_simulator,(void*)l_l5K);
-      lr = ((long (ABI_ATTR *) (long,long,long,long,long,K,long)) callback_code) (l1,l2,l3,l4,l5,K1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 66
-    lr = l_l6K(l1,l2,l3,l4,l5,l6,K1,l9);
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-    lr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_K, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slong);
-      PREP_CALLBACK(cif,l_l6K_simulator,(void*)l_l6K);
-      lr = ((long (ABI_ATTR *) (long,long,long,long,long,long,K,long)) callback_code) (l1,l2,l3,l4,l5,l6,K1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%ld\n",lr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 67    
-    fr = f_f17l3L(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,l6,l7,l8,L1);
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-    fr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_float, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_L };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_float);
-      PREP_CALLBACK(cif,f_f17l3L_simulator,(void*)&f_f17l3L);
-      fr = ((float (ABI_ATTR *) (float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,long,long,long,L)) callback_code) (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,l6,l7,l8,L1);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",fr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 68    
-    dr = d_d17l3L(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,d17,l6,l7,l8,L1);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_double, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_L };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_d17l3L_simulator,(void*)&d_d17l3L);
-      dr = ((double (ABI_ATTR *) (double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,long,long,long,L)) callback_code) (d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,d17,l6,l7,l8,L1);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 69    
-    llr = ll_l2ll(l1,l2,ll1,l9);
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-    llr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-      PREP_CALLBACK(cif,ll_l2ll_simulator,(void*)ll_l2ll);
-      llr = ((long long (ABI_ATTR *) (long,long,long long,long)) callback_code) (l1,l2,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 70
-    llr = ll_l3ll(l1,l2,l3,ll1,l9);
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-    llr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-      PREP_CALLBACK(cif,ll_l3ll_simulator,(void*)ll_l3ll);
-      llr = ((long long (ABI_ATTR *) (long,long,long,long long,long)) callback_code) (l1,l2,l3,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 71    
-    llr = ll_l4ll(l1,l2,l3,l4,ll1,l9);
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-    llr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-      PREP_CALLBACK(cif,ll_l4ll_simulator,(void*)ll_l4ll);
-      llr = ((long long (ABI_ATTR *) (long,long,long,long,long long,long)) callback_code) (l1,l2,l3,l4,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 72    
-    llr = ll_l5ll(l1,l2,l3,l4,l5,ll1,l9);
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-    llr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-      PREP_CALLBACK(cif,ll_l5ll_simulator,(void*)ll_l5ll);
-      llr = ((long long (ABI_ATTR *) (long,long,long,long,long,long long,long)) callback_code) (l1,l2,l3,l4,l5,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 73    
-    llr = ll_l6ll(l1,l2,l3,l4,l5,l6,ll1,l9);
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-    llr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-      PREP_CALLBACK(cif,ll_l6ll_simulator,(void*)ll_l6ll);
-      llr = ((long long (ABI_ATTR *) (long,long,long,long,long,long,long long,long)) callback_code) (l1,l2,l3,l4,l5,l6,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 74    
-    llr = ll_l7ll(l1,l2,l3,l4,l5,l6,l7,ll1,l9);
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-    llr = 0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slonglong, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_slonglong);
-      PREP_CALLBACK(cif,ll_l7ll_simulator,(void*)ll_l7ll);
-      llr = ((long long (ABI_ATTR *) (long,long,long,long,long,long,long,long long,long)) callback_code) (l1,l2,l3,l4,l5,l6,l7,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->0x%lx%08lx\n",(long)(llr>>32),(long)(llr&0xffffffff));
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 75    
-    dr = d_l2d(l1,l2,ll1,l9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_l2d_simulator,(void*)d_l2d);
-      dr = ((double (ABI_ATTR *) (long,long,double,long)) callback_code) (l1,l2,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 76    
-    dr = d_l3d(l1,l2,l3,ll1,l9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_l3d_simulator,(void*)d_l3d);
-      dr = ((double (ABI_ATTR *) (long,long,long,double,long)) callback_code) (l1,l2,l3,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 77    
-    dr = d_l4d(l1,l2,l3,l4,ll1,l9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_l4d_simulator,(void*)d_l4d);
-      dr = ((double (ABI_ATTR *) (long,long,long,long,double,long)) callback_code) (l1,l2,l3,l4,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 78
-    dr = d_l5d(l1,l2,l3,l4,l5,ll1,l9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_l5d_simulator,(void*)d_l5d);
-      dr = ((double (ABI_ATTR *) (long,long,long,long,long,double,long)) callback_code) (l1,l2,l3,l4,l5,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 79
-    dr = d_l6d(l1,l2,l3,l4,l5,l6,ll1,l9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_l6d_simulator,(void*)d_l6d);
-      dr = ((double (ABI_ATTR *) (long,long,long,long,long,long,double,long)) callback_code) (l1,l2,l3,l4,l5,l6,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-#if (!defined(DGTEST)) || DGTEST == 80
-    dr = d_l7d(l1,l2,l3,l4,l5,l6,l7,ll1,l9);
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-    dr = 0.0; clear_traces();
-    ALLOC_CALLBACK();
-    {
-      ffi_type* argtypes[] = { &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_slong, &ffi_type_double, &ffi_type_slong };
-      ffi_cif cif;
-      FFI_PREP_CIF(cif,argtypes,ffi_type_double);
-      PREP_CALLBACK(cif,d_l7d_simulator,(void*)d_l7d);
-      dr = ((double (ABI_ATTR *) (long,long,long,long,long,long,long,double,long)) callback_code) (l1,l2,l3,l4,l5,l6,l7,ll1,l9);
-    }
-    FREE_CALLBACK();
-    fprintf(out,"->%g\n",dr);
-    fflush(out);
-#endif
-
-  }
-  
-  exit(0);
-}
-
diff --git a/testsuite/libffi.bhaible/testcases.c b/testsuite/libffi.bhaible/testcases.c
deleted file mode 100644
index d25ebf4..0000000
--- a/testsuite/libffi.bhaible/testcases.c
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * Copyright 1993 Bill Triggs <Bill.Triggs@inrialpes.fr>
- * Copyright 1995-2017 Bruno Haible <bruno@clisp.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* This file defines test functions of selected signatures, that exercise
-   dark corners of the various ABIs. */
-
-#include <stdio.h>
-
-FILE* out;
-
-#define uchar unsigned char
-#define ushort unsigned short
-#define uint unsigned int
-#define ulong unsigned long
-
-typedef struct { char x; } Char;
-typedef struct { short x; } Short;
-typedef struct { int x; } Int;
-typedef struct { long x; } Long;
-typedef struct { float x; } Float;
-typedef struct { double x; } Double;
-typedef struct { char c; float f; } A;
-typedef struct { double d; int i[3]; } B;
-typedef struct { long l1; long l2; } J;
-typedef struct { long l1; long l2; long l3; long l4; } K;
-typedef struct { long l1; long l2; long l3; long l4; long l5; long l6; } L;
-typedef struct { char x1; } Size1;
-typedef struct { char x1; char x2; } Size2;
-typedef struct { char x1; char x2; char x3; } Size3;
-typedef struct { char x1; char x2; char x3; char x4; } Size4;
-typedef struct {
-  char x1; char x2; char x3; char x4; char x5; char x6; char x7;
-} Size7;
-typedef struct {
-  char x1; char x2; char x3; char x4; char x5; char x6; char x7; char x8;
-} Size8;
-typedef struct {
-  char x1; char x2; char x3; char x4; char x5; char x6; char x7; char x8;
-  char x9; char x10; char x11; char x12;
-} Size12;
-typedef struct {
-  char x1; char x2; char x3; char x4; char x5; char x6; char x7; char x8;
-  char x9; char x10; char x11; char x12; char x13; char x14; char x15;
-} Size15;
-typedef struct {
-  char x1; char x2; char x3; char x4; char x5; char x6; char x7; char x8;
-  char x9; char x10; char x11; char x12; char x13; char x14; char x15; char x16;
-} Size16;
-typedef struct { char c[3]; } T;
-typedef struct { char c[33],c1; } X;
-
-char c1='a', c2=127, c3=(char)128, c4=(char)255, c5=-1;
-short s1=32767, s2=(short)32768, s3=3, s4=4, s5=5, s6=6, s7=7, s8=8, s9=9;
-int i1=1, i2=2, i3=3, i4=4, i5=5, i6=6, i7=7, i8=8, i9=9,
-    i10=11, i11=12, i12=13, i13=14, i14=15, i15=16, i16=17;
-long l1=1, l2=2, l3=3, l4=4, l5=5, l6=6, l7=7, l8=8, l9=9;
-long long ll1 = 3875056143130689530LL;
-float f1=0.1f, f2=0.2f, f3=0.3f, f4=0.4f, f5=0.5f, f6=0.6f, f7=0.7f, f8=0.8f, f9=0.9f,
-      f10=1.1f, f11=1.2f, f12=1.3f, f13=1.4f, f14=1.5f, f15=1.6f, f16=1.7f, f17=1.8f,
-      f18=1.9f, f19=2.1f, f20=2.2f, f21=2.3f, f22=2.4f, f23=2.5f, f24=2.6f;
-double d1=0.1, d2=0.2, d3=0.3, d4=0.4, d5=0.5, d6=0.6, d7=0.7, d8=0.8, d9=0.9,
-       d10=1.1, d11=1.2, d12=1.3, d13=1.4, d14=1.5, d15=1.6, d16=1.7, d17=1.8;
-
-uchar uc1='a', uc2=127, uc3=128, uc4=255, uc5=(uchar)-1;
-ushort us1=1, us2=2, us3=3, us4=4, us5=5, us6=6, us7=7, us8=8, us9=9;
-uint ui1=1, ui2=2, ui3=3, ui4=4, ui5=5, ui6=6, ui7=7, ui8=8, ui9=9;
-ulong ul1=1, ul2=2, ul3=3, ul4=4, ul5=5, ul6=6, ul7=7, ul8=8, ul9=9;
-
-char *str1="hello",str2[]="goodbye",*str3="still here?";
-Char C1={'A'}, C2={'B'}, C3={'C'}, C4={'\377'}, C5={(char)(-1)};
-Short S1={1}, S2={2}, S3={3}, S4={4}, S5={5}, S6={6}, S7={7}, S8={8}, S9={9};
-Int I1={1}, I2={2}, I3={3}, I4={4}, I5={5}, I6={6}, I7={7}, I8={8}, I9={9};
-Float F1={0.1f}, F2={0.2f}, F3={0.3f}, F4={0.4f}, F5={0.5f}, F6={0.6f}, F7={0.7f}, F8={0.8f}, F9={0.9f};
-Double D1={0.1}, D2={0.2}, D3={0.3}, D4={0.4}, D5={0.5}, D6={0.6}, D7={0.7}, D8={0.8}, D9={0.9};
-
-A A1={'a',0.1f},A2={'b',0.2f},A3={'\377',0.3f};
-B B1={0.1,{1,2,3}},B2={0.2,{5,4,3}};
-J J1={47,11},J2={73,55};
-K K1={19,69,12,28};
-L L1={561,1105,1729,2465,2821,6601}; /* A002997 */
-Size1 Size1_1={'a'};
-Size2 Size2_1={'a','b'};
-Size3 Size3_1={'a','b','c'};
-Size4 Size4_1={'a','b','c','d'};
-Size7 Size7_1={'a','b','c','d','e','f','g'};
-Size8 Size8_1={'a','b','c','d','e','f','g','h'};
-Size12 Size12_1={'a','b','c','d','e','f','g','h','i','j','k','l'};
-Size15 Size15_1={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o'};
-Size16 Size16_1={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'};
-T T1={{'t','h','e'}},T2={{'f','o','x'}};
-X X1={"abcdefghijklmnopqrstuvwxyzABCDEF",'G'}, X2={"123",'9'}, X3={"return-return-return",'R'};
-
-#if defined(__GNUC__)
-#define __STDCALL__ __attribute__((stdcall))
-#define __THISCALL__ __attribute__((thiscall))
-#define __FASTCALL__ __attribute__((fastcall))
-#define __MSABI__ __attribute__((ms_abi))
-#else
-#define __STDCALL__ __stdcall
-#define __THISCALL__ __thiscall
-#define __FASTCALL__ __fastcall
-#endif
-
-#ifndef ABI_ATTR
-#define ABI_ATTR
-#endif
-
-/* void tests */
-void ABI_ATTR v_v (void)
-{
-  fprintf(out,"void f(void):\n");
-  fflush(out);
-}
-
-/* int tests */
-int ABI_ATTR i_v (void)
-{
-  int r=99;
-  fprintf(out,"int f(void):");
-  fflush(out);
-  return r;
-}
-int ABI_ATTR i_i (int a)
-{
-  int r=a+1;
-  fprintf(out,"int f(int):(%d)",a);
-  fflush(out);
-  return r;
-}
-int ABI_ATTR i_i2 (int a, int b)
-{
-  int r=a+b;
-  fprintf(out,"int f(2*int):(%d,%d)",a,b);
-  fflush(out);
-  return r;
-}
-int ABI_ATTR i_i4 (int a, int b, int c, int d)
-{
-  int r=a+b+c+d;
-  fprintf(out,"int f(4*int):(%d,%d,%d,%d)",a,b,c,d);
-  fflush(out);
-  return r;
-}
-int ABI_ATTR i_i8 (int a, int b, int c, int d, int e, int f, int g, int h)
-{
-  int r=a+b+c+d+e+f+g+h;
-  fprintf(out,"int f(8*int):(%d,%d,%d,%d,%d,%d,%d,%d)",a,b,c,d,e,f,g,h);
-  fflush(out);
-  return r;
-}
-int ABI_ATTR i_i16 (int a, int b, int c, int d, int e, int f, int g, int h,
-           int i, int j, int k, int l, int m, int n, int o, int p)
-{
-  int r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
-  fprintf(out,"int f(16*int):(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
-          a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
-  fflush(out);
-  return r;
-}
-
-/* float tests */
-float ABI_ATTR f_f (float a)
-{
-  float r=a+1.0f;
-  fprintf(out,"float f(float):(%g)",a);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f2 (float a, float b)
-{
-  float r=a+b;
-  fprintf(out,"float f(2*float):(%g,%g)",a,b);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f4 (float a, float b, float c, float d)
-{
-  float r=a+b+c+d;
-  fprintf(out,"float f(4*float):(%g,%g,%g,%g)",a,b,c,d);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f8 (float a, float b, float c, float d, float e, float f,
-            float g, float h)
-{
-  float r=a+b+c+d+e+f+g+h;
-  fprintf(out,"float f(8*float):(%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f16 (float a, float b, float c, float d, float e, float f, float g, float h,
-             float i, float j, float k, float l, float m, float n, float o, float p)
-{
-  float r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
-  fprintf(out,"float f(16*float):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f24 (float a, float b, float c, float d, float e, float f, float g, float h,
-             float i, float j, float k, float l, float m, float n, float o, float p,
-             float q, float s, float t, float u, float v, float w, float x, float y)
-{
-  float r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+v+w+x+y;
-  fprintf(out,"float f(24*float):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,v,w,x,y);
-  fflush(out);
-  return r;
-}
-
-/* double tests */
-double ABI_ATTR d_d (double a)
-{
-  double r=a+1.0;
-  fprintf(out,"double f(double):(%g)",a);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d2 (double a, double b)
-{
-  double r=a+b;
-  fprintf(out,"double f(2*double):(%g,%g)",a,b);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d4 (double a, double b, double c, double d)
-{
-  double r=a+b+c+d;
-  fprintf(out,"double f(4*double):(%g,%g,%g,%g)",a,b,c,d);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d8 (double a, double b, double c, double d, double e, double f,
-             double g, double h)
-{
-  double r=a+b+c+d+e+f+g+h;
-  fprintf(out,"double f(8*double):(%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d16 (double a, double b, double c, double d, double e, double f,
-              double g, double h, double i, double j, double k, double l,
-              double m, double n, double o, double p)
-{
-  double r=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p;
-  fprintf(out,"double f(16*double):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
-  fflush(out);
-  return r;
-}
-
-/* pointer tests */
-void* ABI_ATTR vp_vpdpcpsp (void* a, double* b, char* c, Int* d)
-{
-  void* ret = (char*)b + 1;
-  fprintf(out,"void* f(void*,double*,char*,Int*):(0x%p,0x%p,0x%p,0x%p)",a,b,c,d);
-  fflush(out);
-  return ret;
-}
-
-/* mixed number tests */
-uchar ABI_ATTR uc_ucsil (uchar a, ushort b, uint c, ulong d)
-{
-  uchar r = (uchar)-1;
-  fprintf(out,"uchar f(uchar,ushort,uint,ulong):(%u,%u,%u,%lu)",a,b,c,d);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_iidd (int a, int b, double c, double d)
-{
-  double r = a+b+c+d;
-  fprintf(out,"double f(int,int,double,double):(%d,%d,%g,%g)",a,b,c,d);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_iiidi (int a, int b, int c, double d, int e)
-{
-  double r = a+b+c+d+e;
-  fprintf(out,"double f(int,int,int,double,int):(%d,%d,%d,%g,%d)",a,b,c,d,e);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_idid (int a, double b, int c, double d)
-{
-  double r = a+b+c+d;
-  fprintf(out,"double f(int,double,int,double):(%d,%g,%d,%g)",a,b,c,d);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_fdi (float a, double b, int c)
-{
-  double r = a+b+c;
-  fprintf(out,"double f(float,double,int):(%g,%g,%d)",a,b,c);
-  fflush(out);
-  return r;
-}
-ushort ABI_ATTR us_cdcd (char a, double b, char c, double d)
-{
-  ushort r = (ushort)(a + b + c + d);
-  fprintf(out,"ushort f(char,double,char,double):('%c',%g,'%c',%g)",a,b,c,d);
-  fflush(out);
-  return r;
-}
-
-long long ABI_ATTR ll_iiilli (int a, int b, int c, long long d, int e)
-{
-  long long r = (long long)(int)a+(long long)(int)b+(long long)(int)c+d+(long long)(int)e;
-  fprintf(out,"long long f(int,int,int,long long,int):(%d,%d,%d,0x%lx%08lx,%d)",a,b,c,(long)(d>>32),(long)(d&0xffffffff),e);
-  fflush(out);
-  return r;
-}
-long long ABI_ATTR ll_flli (float a, long long b, int c)
-{
-  long long r = (long long)(int)a + b + (long long)c;
-  fprintf(out,"long long f(float,long long,int):(%g,0x%lx%08lx,0x%lx)",a,(long)(b>>32),(long)(b&0xffffffff),(long)c);
-  fflush(out);
-  return r;
-}
-
-float ABI_ATTR f_fi (float a, int z)
-{
-  float r = a+z;
-  fprintf(out,"float f(float,int):(%g,%d)",a,z);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f2i (float a, float b, int z)
-{
-  float r = a+b+z;
-  fprintf(out,"float f(2*float,int):(%g,%g,%d)",a,b,z);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f3i (float a, float b, float c, int z)
-{
-  float r = a+b+c+z;
-  fprintf(out,"float f(3*float,int):(%g,%g,%g,%d)",a,b,c,z);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f4i (float a, float b, float c, float d, int z)
-{
-  float r = a+b+c+d+z;
-  fprintf(out,"float f(4*float,int):(%g,%g,%g,%g,%d)",a,b,c,d,z);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f7i (float a, float b, float c, float d, float e, float f, float g,
-             int z)
-{
-  float r = a+b+c+d+e+f+g+z;
-  fprintf(out,"float f(7*float,int):(%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,z);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f8i (float a, float b, float c, float d, float e, float f, float g,
-             float h, int z)
-{
-  float r = a+b+c+d+e+f+g+h+z;
-  fprintf(out,"float f(8*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,z);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f12i (float a, float b, float c, float d, float e, float f, float g,
-              float h, float i, float j, float k, float l, int z)
-{
-  float r = a+b+c+d+e+f+g+h+i+j+k+l+z;
-  fprintf(out,"float f(12*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,z);
-  fflush(out);
-  return r;
-}
-float ABI_ATTR f_f13i (float a, float b, float c, float d, float e, float f, float g,
-              float h, float i, float j, float k, float l, float m, int z)
-{
-  float r = a+b+c+d+e+f+g+h+i+j+k+l+m+z;
-  fprintf(out,"float f(13*float,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,m,z);
-  fflush(out);
-  return r;
-}
-
-double ABI_ATTR d_di (double a, int z)
-{
-  double r = a+z;
-  fprintf(out,"double f(double,int):(%g,%d)",a,z);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d2i (double a, double b, int z)
-{
-  double r = a+b+z;
-  fprintf(out,"double f(2*double,int):(%g,%g,%d)",a,b,z);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d3i (double a, double b, double c, int z)
-{
-  double r = a+b+c+z;
-  fprintf(out,"double f(3*double,int):(%g,%g,%g,%d)",a,b,c,z);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d4i (double a, double b, double c, double d, int z)
-{
-  double r = a+b+c+d+z;
-  fprintf(out,"double f(4*double,int):(%g,%g,%g,%g,%d)",a,b,c,d,z);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d7i (double a, double b, double c, double d, double e, double f,
-              double g, int z)
-{
-  double r = a+b+c+d+e+f+g+z;
-  fprintf(out,"double f(7*double,int):(%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,z);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d8i (double a, double b, double c, double d, double e, double f,
-              double g, double h, int z)
-{
-  double r = a+b+c+d+e+f+g+h+z;
-  fprintf(out,"double f(8*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,z);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d12i (double a, double b, double c, double d, double e, double f,
-               double g, double h, double i, double j, double k, double l,
-               int z)
-{
-  double r = a+b+c+d+e+f+g+h+i+j+k+l+z;
-  fprintf(out,"double f(12*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,z);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d13i (double a, double b, double c, double d, double e, double f,
-               double g, double h, double i, double j, double k, double l,
-               double m, int z)
-{
-  double r = a+b+c+d+e+f+g+h+i+j+k+l+m+z;
-  fprintf(out,"double f(13*double,int):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d)",a,b,c,d,e,f,g,h,i,j,k,l,m,z);
-  fflush(out);
-  return r;
-}
-
-/* small structure return tests */
-Size1 ABI_ATTR S1_v (void)
-{
-  fprintf(out,"Size1 f(void):");
-  fflush(out);
-  return Size1_1;
-}
-Size2 ABI_ATTR S2_v (void)
-{
-  fprintf(out,"Size2 f(void):");
-  fflush(out);
-  return Size2_1;
-}
-Size3 ABI_ATTR S3_v (void)
-{
-  fprintf(out,"Size3 f(void):");
-  fflush(out);
-  return Size3_1;
-}
-Size4 ABI_ATTR S4_v (void)
-{
-  fprintf(out,"Size4 f(void):");
-  fflush(out);
-  return Size4_1;
-}
-Size7 ABI_ATTR S7_v (void)
-{
-  fprintf(out,"Size7 f(void):");
-  fflush(out);
-  return Size7_1;
-}
-Size8 ABI_ATTR S8_v (void)
-{
-  fprintf(out,"Size8 f(void):");
-  fflush(out);
-  return Size8_1;
-}
-Size12 ABI_ATTR S12_v (void)
-{
-  fprintf(out,"Size12 f(void):");
-  fflush(out);
-  return Size12_1;
-}
-Size15 ABI_ATTR S15_v (void)
-{
-  fprintf(out,"Size15 f(void):");
-  fflush(out);
-  return Size15_1;
-}
-Size16 ABI_ATTR S16_v (void)
-{
-  fprintf(out,"Size16 f(void):");
-  fflush(out);
-  return Size16_1;
-}
-
-/* structure tests */
-Int ABI_ATTR I_III (Int a, Int b, Int c)
-{
-  Int r;
-  r.x = a.x + b.x + c.x;
-  fprintf(out,"Int f(Int,Int,Int):({%d},{%d},{%d})",a.x,b.x,c.x);
-  fflush(out);
-  return r;
-}
-Char ABI_ATTR C_CdC (Char a, double b, Char c)
-{
-  Char r;
-  r.x = (a.x + c.x)/2;
-  fprintf(out,"Char f(Char,double,Char):({'%c'},%g,{'%c'})",a.x,b,c.x);
-  fflush(out);
-  return r;
-}
-Float ABI_ATTR F_Ffd (Float a, float b, double c)
-{
-  Float r;
-  r.x = (float) (a.x + b + c);
-  fprintf(out,"Float f(Float,float,double):({%g},%g,%g)",a.x,b,c);
-  fflush(out);
-  return r;
-}
-Double ABI_ATTR D_fDd (float a, Double b, double c)
-{
-  Double r;
-  r.x = a + b.x + c;
-  fprintf(out,"Double f(float,Double,double):(%g,{%g},%g)",a,b.x,c);
-  fflush(out);
-  return r;
-}
-Double ABI_ATTR D_Dfd (Double a, float b, double c)
-{
-  Double r;
-  r.x = a.x + b + c;
-  fprintf(out,"Double f(Double,float,double):({%g},%g,%g)",a.x,b,c);
-  fflush(out);
-  return r;
-}
-J ABI_ATTR J_JiJ (J a, int b, J c)
-{
-  J r;
-  r.l1 = a.l1+c.l1; r.l2 = a.l2+b+c.l2;
-  fprintf(out,"J f(J,int,J):({%ld,%ld},%d,{%ld,%ld})",a.l1,a.l2,b,c.l1,c.l2);
-  fflush(out);
-  return r;
-}
-T ABI_ATTR T_TcT (T a, char b, T c)
-{
-  T r;
-  r.c[0]='b'; r.c[1]=c.c[1]; r.c[2]=c.c[2];
-  fprintf(out,"T f(T,char,T):({\"%c%c%c\"},'%c',{\"%c%c%c\"})",a.c[0],a.c[1],a.c[2],b,c.c[0],c.c[1],c.c[2]);
-  fflush(out);
-  return r;
-}
-X ABI_ATTR X_BcdB (B a, char b, double c, B d)
-{
-  static X xr={"return val",'R'};
-  X r;
-  r = xr;
-  r.c1 = b;
-  fprintf(out,"X f(B,char,double,B):({%g,{%d,%d,%d}},'%c',%g,{%g,{%d,%d,%d}})",
-          a.d,a.i[0],a.i[1],a.i[2],b,c,d.d,d.i[0],d.i[1],d.i[2]);
-  fflush(out);
-  return r;
-}
-
-/* Test for cases where some argument (especially structure, 'long long', or
-   'double') may be passed partially in general-purpose argument registers
-   and partially on the stack. Different ABIs pass between 4 and 8 arguments
-   (or none) in general-purpose argument registers. */
-
-long ABI_ATTR l_l0K (K b, long c)
-{
-  long r = b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(K,long):(%ld,%ld,%ld,%ld,%ld)",b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  return r;
-}
-long ABI_ATTR l_l1K (long a1, K b, long c)
-{
-  long r = a1 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld)",a1,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  return r;
-}
-long ABI_ATTR l_l2K (long a1, long a2, K b, long c)
-{
-  long r = a1 + a2 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(2*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  return r;
-}
-long ABI_ATTR l_l3K (long a1, long a2, long a3, K b, long c)
-{
-  long r = a1 + a2 + a3 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(3*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  return r;
-}
-long ABI_ATTR l_l4K (long a1, long a2, long a3, long a4, K b, long c)
-{
-  long r = a1 + a2 + a3 + a4 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(4*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  return r;
-}
-long ABI_ATTR l_l5K (long a1, long a2, long a3, long a4, long a5, K b, long c)
-{
-  long r = a1 + a2 + a3 + a4 + a5 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(5*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,a5,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  return r;
-}
-long ABI_ATTR l_l6K (long a1, long a2, long a3, long a4, long a5, long a6, K b, long c)
-{
-  long r = a1 + a2 + a3 + a4 + a5 + a6 + b.l1 + b.l2 + b.l3 + b.l4 + c;
-  fprintf(out,"long f(6*long,K,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a1,a2,a3,a4,a5,a6,b.l1,b.l2,b.l3,b.l4,c);
-  fflush(out);
-  return r;
-}
-/* These tests is crafted on the knowledge that for all known ABIs:
-   * 17 > number of floating-point argument registers,
-   * 3 < number of general-purpose argument registers < 3 + 6. */
-float ABI_ATTR f_f17l3L (float a, float b, float c, float d, float e, float f, float g,
-                float h, float i, float j, float k, float l, float m, float n,
-                float o, float p, float q,
-                long s, long t, long u, L z)
-{
-  float r = a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+z.l1+z.l2+z.l3+z.l4+z.l5+z.l6;
-  fprintf(out,"float f(17*float,3*int,L):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,z.l1,z.l2,z.l3,z.l4,z.l5,z.l6);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_d17l3L (double a, double b, double c, double d, double e, double f,
-                 double g, double h, double i, double j, double k, double l,
-                 double m, double n, double o, double p, double q,
-                 long s, long t, long u, L z)
-{
-  double r = a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+s+t+u+z.l1+z.l2+z.l3+z.l4+z.l5+z.l6;
-  fprintf(out,"double f(17*double,3*int,L):(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t,u,z.l1,z.l2,z.l3,z.l4,z.l5,z.l6);
-  fflush(out);
-  return r;
-}
-
-long long ABI_ATTR ll_l2ll (long a1, long a2, long long b, long c)
-{
-  long long r = (long long) (a1 + a2) + b + c;
-  fprintf(out,"long long f(2*long,long long,long):(%ld,%ld,0x%lx%08lx,%ld)",a1,a2,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  return r;
-}
-long long ABI_ATTR ll_l3ll (long a1, long a2, long a3, long long b, long c)
-{
-  long long r = (long long) (a1 + a2 + a3) + b + c;
-  fprintf(out,"long long f(3*long,long long,long):(%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  return r;
-}
-long long ABI_ATTR ll_l4ll (long a1, long a2, long a3, long a4, long long b, long c)
-{
-  long long r = (long long) (a1 + a2 + a3 + a4) + b + c;
-  fprintf(out,"long long f(4*long,long long,long):(%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  return r;
-}
-long long ABI_ATTR ll_l5ll (long a1, long a2, long a3, long a4, long a5, long long b, long c)
-{
-  long long r = (long long) (a1 + a2 + a3 + a4 + a5) + b + c;
-  fprintf(out,"long long f(5*long,long long,long):(%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  return r;
-}
-long long ABI_ATTR ll_l6ll (long a1, long a2, long a3, long a4, long a5, long a6, long long b, long c)
-{
-  long long r = (long long) (a1 + a2 + a3 + a4 + a5 + a6) + b + c;
-  fprintf(out,"long long f(6*long,long long,long):(%ld,%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,a6,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  return r;
-}
-long long ABI_ATTR ll_l7ll (long a1, long a2, long a3, long a4, long a5, long a6, long a7, long long b, long c)
-{
-  long long r = (long long) (a1 + a2 + a3 + a4 + a5 + a6 + a7) + b + c;
-  fprintf(out,"long long f(7*long,long long,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,0x%lx%08lx,%ld)",a1,a2,a3,a4,a5,a6,a7,(long)(b>>32),(long)(b&0xffffffff),c);
-  fflush(out);
-  return r;
-}
-
-double ABI_ATTR d_l2d (long a1, long a2, double b, long c)
-{
-  double r = (double) (a1 + a2) + b + c;
-  fprintf(out,"double f(2*long,double,long):(%ld,%ld,%g,%ld)",a1,a2,b,c);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_l3d (long a1, long a2, long a3, double b, long c)
-{
-  double r = (double) (a1 + a2 + a3) + b + c;
-  fprintf(out,"double f(3*long,double,long):(%ld,%ld,%ld,%g,%ld)",a1,a2,a3,b,c);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_l4d (long a1, long a2, long a3, long a4, double b, long c)
-{
-  double r = (double) (a1 + a2 + a3 + a4) + b + c;
-  fprintf(out,"double f(4*long,double,long):(%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,b,c);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_l5d (long a1, long a2, long a3, long a4, long a5, double b, long c)
-{
-  double r = (double) (a1 + a2 + a3 + a4 + a5) + b + c;
-  fprintf(out,"double f(5*long,double,long):(%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,b,c);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_l6d (long a1, long a2, long a3, long a4, long a5, long a6, double b, long c)
-{
-  double r = (double) (a1 + a2 + a3 + a4 + a5 + a6) + b + c;
-  fprintf(out,"double f(6*long,double,long):(%ld,%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,a6,b,c);
-  fflush(out);
-  return r;
-}
-double ABI_ATTR d_l7d (long a1, long a2, long a3, long a4, long a5, long a6, long a7, double b, long c)
-{
-  double r = (double) (a1 + a2 + a3 + a4 + a5 + a6 + a7) + b + c;
-  fprintf(out,"double f(7*long,double,long):(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%g,%ld)",a1,a2,a3,a4,a5,a6,a7,b,c);
-  fflush(out);
-  return r;
-}
diff --git a/testsuite/libffi.call/align_mixed.c b/testsuite/libffi.call/align_mixed.c
deleted file mode 100644
index 5d4959c..0000000
--- a/testsuite/libffi.call/align_mixed.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check for proper argument alignment.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<twalljava@java.net> (from many_win32.c) */
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-static float ABI_ATTR align_arguments(int i1,
-                                      double f2,
-                                      int i3,
-                                      double f4)
-{
-  return i1+f2+i3+f4;
-}
-
-int main(void)
-{
-  ffi_cif cif;
-  ffi_type *args[4] = {
-    &ffi_type_sint,
-    &ffi_type_double,
-    &ffi_type_sint,
-    &ffi_type_double
-  };
-  double fa[2] = {1,2};
-  int ia[2] = {1,2};
-  void *values[4] = {&ia[0], &fa[0], &ia[1], &fa[1]};
-  float f, ff;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, ABI_NUM, 4,
-		     &ffi_type_float, args) == FFI_OK);
-
-  ff = align_arguments(ia[0], fa[0], ia[1], fa[1]);
-
-  ffi_call(&cif, FFI_FN(align_arguments), &f, values);
-
-  if (f == ff)
-    printf("align arguments tests ok!\n");
-  else
-    CHECK(0);
-  exit(0);
-}
diff --git a/testsuite/libffi.call/align_stdcall.c b/testsuite/libffi.call/align_stdcall.c
deleted file mode 100644
index 5e5cb86..0000000
--- a/testsuite/libffi.call/align_stdcall.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check for proper argument alignment.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<twalljava@java.net> (from many_win32.c) */
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-static float ABI_ATTR align_arguments(int i1,
-                                      double f2,
-                                      int i3,
-                                      double f4)
-{
-  return i1+f2+i3+f4;
-}
-
-int main(void)
-{
-  ffi_cif cif;
-  ffi_type *args[4] = {
-    &ffi_type_sint,
-    &ffi_type_double,
-    &ffi_type_sint,
-    &ffi_type_double
-  };
-  double fa[2] = {1,2};
-  int ia[2] = {1,2};
-  void *values[4] = {&ia[0], &fa[0], &ia[1], &fa[1]};
-  float f, ff;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, ABI_NUM, 4,
-		     &ffi_type_float, args) == FFI_OK);
-
-  ff = align_arguments(ia[0], fa[0], ia[1], fa[1]);;
-
-  ffi_call(&cif, FFI_FN(align_arguments), &f, values);
-
-  if (f == ff)
-    printf("align arguments tests ok!\n");
-  else
-    CHECK(0);
-  exit(0);
-}
diff --git a/testsuite/libffi.call/call.exp b/testsuite/libffi.call/call.exp
index 13ba2bd..5177f07 100644
--- a/testsuite/libffi.call/call.exp
+++ b/testsuite/libffi.call/call.exp
@@ -19,32 +19,21 @@
 
 global srcdir subdir
 
-if { [string match $compiler_vendor "microsoft"] } {
-    # -wd4005  macro redefinition
-    # -wd4244  implicit conversion to type of smaller size
-    # -wd4305  truncation to smaller type
-    # -wd4477  printf %lu of uintptr_t
-    # -wd4312  implicit conversion to type of greater size
-    # -wd4311  pointer truncation to unsigned long
-    # -EHsc    C++ Exception Handling (no SEH exceptions)
-    set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc";
-} else {
-    set additional_options "";
-}
+set tlist [lsearch -inline -all -not -glob [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] *complex*]
+set ctlist [lsearch -inline -all -glob [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] *complex*]
 
-set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]]
+run-many-tests $tlist ""
 
-run-many-tests $tlist $additional_options
+if { ![istarget s390*] } {
 
-set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]]
-
-# No C++ for or1k
-if { [istarget "or1k-*-*"] } {
-    foreach test $tlist {
-        unsupported "$test"
+    foreach test $ctlist {
+	unsupported "$test"
     }
+
 } else {
-    run-many-tests $tlist $additional_options
+
+  run-many-tests $ctlist ""
+
 }
 
 dg-finish
diff --git a/testsuite/libffi.call/ffitest.h b/testsuite/libffi.call/ffitest.h
index cfce1ad..15d5e44 100644
--- a/testsuite/libffi.call/ffitest.h
+++ b/testsuite/libffi.call/ffitest.h
@@ -24,7 +24,6 @@
 #define __STDCALL__ __attribute__((stdcall))
 #define __THISCALL__ __attribute__((thiscall))
 #define __FASTCALL__ __attribute__((fastcall))
-#define __MSABI__ __attribute__((ms_abi))
 #else
 #define __UNUSED__
 #define __STDCALL__ __stdcall
@@ -64,7 +63,7 @@
 #endif
 
 /* MinGW kludge.  */
-#if defined(_WIN64) | defined(_WIN32)
+#ifdef _WIN64
 #define PRIdLL "I64d"
 #define PRIuLL "I64u"
 #else
@@ -124,14 +123,12 @@
 
 /* MSVC kludge.  */
 #if defined _MSC_VER
-#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
 #define PRIuPTR "lu"
 #define PRIu8 "u"
 #define PRId8 "d"
 #define PRIu64 "I64u"
 #define PRId64 "I64d"
 #endif
-#endif
 
 #ifndef PRIuPTR
 #define PRIuPTR "u"
diff --git a/testsuite/libffi.call/float1.c b/testsuite/libffi.call/float1.c
index c48493c..991d059 100644
--- a/testsuite/libffi.call/float1.c
+++ b/testsuite/libffi.call/float1.c
@@ -8,8 +8,6 @@
 #include "ffitest.h"
 #include "float.h"
 
-#include <math.h>
-
 typedef union
 {
   double d;
@@ -49,7 +47,7 @@
 
   /* These are not always the same!! Check for a reasonable delta */
 
-  CHECK(fabs(result[0].d - dblit(f)) < DBL_EPSILON);
+  CHECK(result[0].d - dblit(f) < DBL_EPSILON);
 
   /* Check the canary.  */
   for (i = 0; i < sizeof (double); ++i)
diff --git a/testsuite/libffi.call/float2.c b/testsuite/libffi.call/float2.c
index 57cd9e3..a0b296c 100644
--- a/testsuite/libffi.call/float2.c
+++ b/testsuite/libffi.call/float2.c
@@ -3,13 +3,13 @@
    Limitations:	none.
    PR:		none.
    Originator:	From the original ffitest.c  */
-/* { dg-do run } */
+
+/* { dg-excess-errors "fails" { target x86_64-*-mingw* x86_64-*-cygwin* } } */
+/* { dg-do run { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
 
 #include "ffitest.h"
 #include "float.h"
 
-#include <math.h>
-
 static long double ldblit(float f)
 {
   return (long double) (((long double) f)/ (long double) 3.0);
@@ -22,7 +22,6 @@
   void *values[MAX_ARGS];
   float f;
   long double ld;
-  long double original;
 
   args[0] = &ffi_type_float;
   values[0] = &f;
@@ -33,26 +32,24 @@
 
   f = 3.14159;
 
-#if defined(__sun) && defined(__GNUC__)
-  /* long double support under SunOS/gcc is pretty much non-existent.
-     You'll get the odd bus error in library routines like printf() */
-#else
+#if 1
+  /* This is ifdef'd out for now. long double support under SunOS/gcc
+     is pretty much non-existent.  You'll get the odd bus error in library
+     routines like printf().  */
   printf ("%Lf\n", ldblit(f));
 #endif
-
   ld = 666;
   ffi_call(&cif, FFI_FN(ldblit), &ld, values);
 
-#if defined(__sun) && defined(__GNUC__)
-  /* long double support under SunOS/gcc is pretty much non-existent.
-     You'll get the odd bus error in library routines like printf() */
-#else
+#if 1
+  /* This is ifdef'd out for now. long double support under SunOS/gcc
+     is pretty much non-existent.  You'll get the odd bus error in library
+     routines like printf().  */
   printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
 #endif
 
   /* These are not always the same!! Check for a reasonable delta */
-  original = ldblit(f);
-  if (((ld > original) ? (ld - original) : (original - ld)) < LDBL_EPSILON)
+  if (ld - ldblit(f) < LDBL_EPSILON)
     puts("long double return value tests ok!");
   else
     CHECK(0);
diff --git a/testsuite/libffi.call/float3.c b/testsuite/libffi.call/float3.c
index bab3206..76bd5f2 100644
--- a/testsuite/libffi.call/float3.c
+++ b/testsuite/libffi.call/float3.c
@@ -9,8 +9,6 @@
 #include "ffitest.h"
 #include "float.h"
 
-#include <math.h>
-
 static double floating_1(float a, double b, long double c)
 {
   return (double) a + b + (double) c;
@@ -51,7 +49,7 @@
 
   ffi_call(&cif, FFI_FN(floating_1), &rd, values);
 
-  CHECK(fabs(rd - floating_1(f, d, ld)) < DBL_EPSILON);
+  CHECK(rd - floating_1(f, d, ld) < DBL_EPSILON);
 
   args[0] = &ffi_type_longdouble;
   values[0] = &ld;
@@ -68,7 +66,7 @@
 
   ffi_call(&cif, FFI_FN(floating_2), &rd, values);
 
-  CHECK(fabs(rd - floating_2(ld, d, f)) < DBL_EPSILON);
+  CHECK(rd - floating_2(ld, d, f) < DBL_EPSILON);
 
   exit (0);
 }
diff --git a/testsuite/libffi.call/offsets.c b/testsuite/libffi.call/offsets.c
deleted file mode 100644
index 23d88b3..0000000
--- a/testsuite/libffi.call/offsets.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Area:		Struct layout
-   Purpose:		Test ffi_get_struct_offsets
-   Limitations:		none.
-   PR:			none.
-   Originator: 		Tom Tromey. */
-
-/* { dg-do run } */
-#include "ffitest.h"
-#include <stddef.h>
-
-struct test_1
-{
-  char c;
-  float f;
-  char c2;
-  int i;
-};
-
-int
-main (void)
-{
-  ffi_type test_1_type;
-  ffi_type *test_1_elements[5];
-  size_t test_1_offsets[4];
-
-  test_1_elements[0] = &ffi_type_schar;
-  test_1_elements[1] = &ffi_type_float;
-  test_1_elements[2] = &ffi_type_schar;
-  test_1_elements[3] = &ffi_type_sint;
-  test_1_elements[4] = NULL;
-
-  test_1_type.size = 0;
-  test_1_type.alignment = 0;
-  test_1_type.type = FFI_TYPE_STRUCT;
-  test_1_type.elements = test_1_elements;
-
-  CHECK (ffi_get_struct_offsets (FFI_DEFAULT_ABI, &test_1_type, test_1_offsets)
-	 == FFI_OK);
-  CHECK (test_1_type.size == sizeof (struct test_1));
-  CHECK (offsetof (struct test_1, c) == test_1_offsets[0]);
-  CHECK (offsetof (struct test_1, f) == test_1_offsets[1]);
-  CHECK (offsetof (struct test_1, c2) == test_1_offsets[2]);
-  CHECK (offsetof (struct test_1, i) == test_1_offsets[3]);
-
-  return 0;
-}
diff --git a/testsuite/libffi.call/pr1172638.c b/testsuite/libffi.call/pr1172638.c
deleted file mode 100644
index 7da1621..0000000
--- a/testsuite/libffi.call/pr1172638.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Reproduce bug found in python ctypes
-   Limitations:	none.
-   PR:		Fedora 1174037  */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct {
-  long x;
-  long y;
-} POINT;
-
-typedef struct {
-  long left;
-  long top;
-  long right;
-  long bottom;
-} RECT;
-
-static RECT ABI_ATTR pr_test(int i __UNUSED__, RECT ar __UNUSED__, 
-			     RECT* br __UNUSED__, POINT cp __UNUSED__, 
-			     RECT dr __UNUSED__, RECT *er __UNUSED__, 
-			     POINT fp, RECT gr __UNUSED__)
-{
-  RECT result;
-
-  result.left = fp.x;
-  result.right = fp.y;
-  result.top = fp.x;
-  result.bottom = fp.y;
-
-  return result;
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  ffi_type *args[MAX_ARGS];
-  void *values[MAX_ARGS];
-  ffi_type point_type, rect_type;
-  ffi_type *point_type_elements[3];  
-  ffi_type *rect_type_elements[5];  
-  
-  int i;
-  POINT cp, fp;
-  RECT ar, br, dr, er, gr; 
-  RECT *p1, *p2;
-
-  /* This is a hack to get a properly aligned result buffer */
-  RECT *rect_result =
-    (RECT *) malloc (sizeof(RECT));
-
-  point_type.size = 0;
-  point_type.alignment = 0;
-  point_type.type = FFI_TYPE_STRUCT;
-  point_type.elements = point_type_elements;
-  point_type_elements[0] = &ffi_type_slong;
-  point_type_elements[1] = &ffi_type_slong;
-  point_type_elements[2] = NULL;
-
-  rect_type.size = 0;
-  rect_type.alignment = 0;
-  rect_type.type = FFI_TYPE_STRUCT;
-  rect_type.elements = rect_type_elements;
-  rect_type_elements[0] = &ffi_type_slong;
-  rect_type_elements[1] = &ffi_type_slong;
-  rect_type_elements[2] = &ffi_type_slong;
-  rect_type_elements[3] = &ffi_type_slong;
-  rect_type_elements[4] = NULL;
-
-  args[0] = &ffi_type_sint;
-  args[1] = &rect_type;
-  args[2] = &ffi_type_pointer;
-  args[3] = &point_type;
-  args[4] = &rect_type;
-  args[5] = &ffi_type_pointer;
-  args[6] = &point_type;
-  args[7] = &rect_type;
-  
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, ABI_NUM, 8, &rect_type, args) == FFI_OK);
-
-  i = 1;
-  ar.left = 2;
-  ar.right = 3;
-  ar.top = 4;
-  ar.bottom = 5;
-  br.left = 6;
-  br.right = 7;
-  br.top = 8;
-  br.bottom = 9;
-  cp.x = 10;
-  cp.y = 11;
-  dr.left = 12;
-  dr.right = 13;
-  dr.top = 14;
-  dr.bottom = 15;
-  er.left = 16;
-  er.right = 17;
-  er.top = 18;
-  er.bottom = 19;
-  fp.x = 20;
-  fp.y = 21;
-  gr.left = 22;
-  gr.right = 23;
-  gr.top = 24;
-  gr.bottom = 25;
-  
-  values[0] = &i;
-  values[1] = &ar;
-  p1 = &br;
-  values[2] = &p1;
-  values[3] = &cp;
-  values[4] = &dr;
-  p2 = &er;
-  values[5] = &p2;
-  values[6] = &fp;
-  values[7] = &gr;
-
-  ffi_call (&cif, FFI_FN(pr_test), rect_result, values);
-  
-  CHECK(rect_result->top == 20);
- 
-  free (rect_result);
-  exit(0);
-}
diff --git a/testsuite/libffi.call/return_ldl.c b/testsuite/libffi.call/return_ldl.c
index 52a92fe..5c2fe65 100644
--- a/testsuite/libffi.call/return_ldl.c
+++ b/testsuite/libffi.call/return_ldl.c
@@ -3,8 +3,8 @@
    Limitations:	none.
    PR:		none.
    Originator:	<andreast@gcc.gnu.org> 20071113  */
-/* { dg-do run } */
 
+/* { dg-do run { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
 #include "ffitest.h"
 
 static long double return_ldl(long double ldl)
diff --git a/testsuite/libffi.call/struct10.c b/testsuite/libffi.call/struct10.c
deleted file mode 100644
index 17b1377..0000000
--- a/testsuite/libffi.call/struct10.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check structures.
-   Limitations:	none.
-   PR:		none.
-   Originator:	Sergei Trofimovich <slyfox@gentoo.org>
-
-   The test originally discovered in ruby's bindings
-   for ffi in https://bugs.gentoo.org/634190  */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-struct s {
-  int s32;
-  float f32;
-  signed char s8;
-};
-
-struct s make_s(void) {
-  struct s r;
-  r.s32 = 0x1234;
-  r.f32 = 7.0;
-  r.s8  = 0x78;
-  return r;
-}
-
-int main() {
-  ffi_cif cif;
-  struct s r;
-  ffi_type rtype;
-  ffi_type* s_fields[] = {
-    &ffi_type_sint,
-    &ffi_type_float,
-    &ffi_type_schar,
-    NULL,
-  };
-
-  rtype.size      = 0;
-  rtype.alignment = 0,
-  rtype.type      = FFI_TYPE_STRUCT,
-  rtype.elements  = s_fields,
-
-  r.s32 = 0xbad;
-  r.f32 = 999.999;
-  r.s8  = 0x51;
-
-  // Here we emulate the following call:
-  //r = make_s();
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &rtype, NULL) == FFI_OK);
-  ffi_call(&cif, FFI_FN(make_s), &r, NULL);
-
-  CHECK(r.s32 == 0x1234);
-  CHECK(r.f32 == 7.0);
-  CHECK(r.s8  == 0x78);
-  exit(0);
-}
diff --git a/testsuite/libffi.call/va_1.c b/testsuite/libffi.call/va_1.c
index 59d085c..7f96809 100644
--- a/testsuite/libffi.call/va_1.c
+++ b/testsuite/libffi.call/va_1.c
@@ -5,7 +5,7 @@
    Originator:	        ARM Ltd. */
 
 /* { dg-do run } */
-/* { dg-output "" { xfail avr32*-*-* m68k-*-* alpha-*-* } } */
+/* { dg-output "" { xfail avr32*-*-* } } */
 
 #include "ffitest.h"
 #include <stdarg.h>
diff --git a/testsuite/libffi.closures/closure.exp b/testsuite/libffi.closures/closure.exp
deleted file mode 100644
index ed4145c..0000000
--- a/testsuite/libffi.closures/closure.exp
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2003, 2006, 2009, 2010, 2014, 2019 Free Software Foundation, Inc.
-# Copyright (C) 2019 Anthony Green
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-dg-init
-libffi-init
-
-global srcdir subdir
-
-if { [string match $compiler_vendor "microsoft"] } {
-    # -wd4005  macro redefinition
-    # -wd4244  implicit conversion to type of smaller size
-    # -wd4305  truncation to smaller type
-    # -wd4477  printf %lu of uintptr_t
-    # -wd4312  implicit conversion to type of greater size
-    # -wd4311  pointer truncation to unsigned long
-    # -EHsc    C++ Exception Handling (no SEH exceptions)
-    set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc";
-} else {
-    set additional_options "";
-}
-
-set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]]
-
-if { [libffi_feature_test "#if FFI_CLOSURES"] } {
-    run-many-tests $tlist ""
-} else {
-    foreach test $tlist {
-	unsupported "$test"
-    }
-}
-
-set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]]
-
-# No C++ for or1k
-if { [istarget "or1k-*-*"] } {
-    foreach test $tlist {
-        unsupported "$test"
-    }
-} else {
-    if { [libffi_feature_test "#if FFI_CLOSURES"] } {
-        run-many-tests $tlist  $additional_options
-    } else {
-        foreach test $tlist {
-	    unsupported "$test"
-        }
-    }
-}
-
-dg-finish
-
-# Local Variables:
-# tcl-indent-level:4
-# End:
diff --git a/testsuite/libffi.closures/closure_fn0.c b/testsuite/libffi.closures/closure_fn0.c
deleted file mode 100644
index a579ff6..0000000
--- a/testsuite/libffi.closures/closure_fn0.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check multiple values passing from different type.
-		Also, exceed the limit of gpr and fpr registers on PowerPC
-		Darwin.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-
-
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void
-closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		 void* userdata)
-{
-  *(ffi_arg*)resp =
-    (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
-    (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
-    (int)(*(signed short *)args[4]) +
-    (int)(*(unsigned long long *)args[5]) +
-    (int)*(int *)args[6] + (int)(*(int *)args[7]) +
-    (int)(*(double *)args[8]) + (int)*(int *)args[9] +
-    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
-    (int)*(int *)args[12] + (int)(*(int *)args[13]) +
-    (int)(*(int *)args[14]) +  *(int *)args[15] + (intptr_t)userdata;
-
-  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
-	 (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
-	 (int)(*(unsigned long long *)args[2]),
-	 (int)*(int *)args[3], (int)(*(signed short *)args[4]),
-	 (int)(*(unsigned long long *)args[5]),
-	 (int)*(int *)args[6], (int)(*(int *)args[7]),
-	 (int)(*(double *)args[8]), (int)*(int *)args[9],
-	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
-	 (int)*(int *)args[12], (int)(*(int *)args[13]),
-	 (int)(*(int *)args[14]),*(int *)args[15],
-	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
-
-}
-
-typedef int (*closure_test_type0)(unsigned long long, int, unsigned long long,
-				  int, signed short, unsigned long long, int,
-				  int, double, int, int, float, int, int,
-				  int, int);
-
-int main (void)
-{
-  ffi_cif cif;
-  void * code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[17];
-  int res;
-
-  cl_arg_types[0] = &ffi_type_uint64;
-  cl_arg_types[1] = &ffi_type_sint;
-  cl_arg_types[2] = &ffi_type_uint64;
-  cl_arg_types[3] = &ffi_type_sint;
-  cl_arg_types[4] = &ffi_type_sshort;
-  cl_arg_types[5] = &ffi_type_uint64;
-  cl_arg_types[6] = &ffi_type_sint;
-  cl_arg_types[7] = &ffi_type_sint;
-  cl_arg_types[8] = &ffi_type_double;
-  cl_arg_types[9] = &ffi_type_sint;
-  cl_arg_types[10] = &ffi_type_sint;
-  cl_arg_types[11] = &ffi_type_float;
-  cl_arg_types[12] = &ffi_type_sint;
-  cl_arg_types[13] = &ffi_type_sint;
-  cl_arg_types[14] = &ffi_type_sint;
-  cl_arg_types[15] = &ffi_type_sint;
-  cl_arg_types[16] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
-		     &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
-                             (void *) 3 /* userdata */, code) == FFI_OK);
-
-  res = (*((closure_test_type0)code))
-    (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
-     19, 21, 1);
-  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 680" } */
-     exit(0);
-}
diff --git a/testsuite/libffi.closures/closure_fn1.c b/testsuite/libffi.closures/closure_fn1.c
deleted file mode 100644
index 9123173..0000000
--- a/testsuite/libffi.closures/closure_fn1.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Area:	closure_call.
-   Purpose:	Check multiple values passing from different type.
-		Also, exceed the limit of gpr and fpr registers on PowerPC
-		Darwin.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-
-static void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			     void* userdata)
-{
-  *(ffi_arg*)resp =
-    (int)*(float *)args[0] +(int)(*(float *)args[1]) +
-    (int)(*(float *)args[2]) + (int)*(float *)args[3] +
-    (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) +
-    (int)*(float *)args[6] + (int)(*(int *)args[7]) +
-    (int)(*(double*)args[8]) + (int)*(int *)args[9] +
-    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
-    (int)*(int *)args[12] + (int)(*(int *)args[13]) +
-    (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
-
-  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
-	 (int)*(float *)args[0], (int)(*(float *)args[1]),
-	 (int)(*(float *)args[2]), (int)*(float *)args[3],
-	 (int)(*(signed short *)args[4]), (int)(*(float *)args[5]),
-	 (int)*(float *)args[6], (int)(*(int *)args[7]),
-	 (int)(*(double *)args[8]), (int)*(int *)args[9],
-	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
-	 (int)*(int *)args[12], (int)(*(int *)args[13]),
-	 (int)(*(int *)args[14]), *(int *)args[15],
-	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
-}
-
-typedef int (*closure_test_type1)(float, float, float, float, signed short,
-				  float, float, int, double, int, int, float,
-				  int, int, int, int);
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[17];
-  int res;
-
-  cl_arg_types[0] = &ffi_type_float;
-  cl_arg_types[1] = &ffi_type_float;
-  cl_arg_types[2] = &ffi_type_float;
-  cl_arg_types[3] = &ffi_type_float;
-  cl_arg_types[4] = &ffi_type_sshort;
-  cl_arg_types[5] = &ffi_type_float;
-  cl_arg_types[6] = &ffi_type_float;
-  cl_arg_types[7] = &ffi_type_sint;
-  cl_arg_types[8] = &ffi_type_double;
-  cl_arg_types[9] = &ffi_type_sint;
-  cl_arg_types[10] = &ffi_type_sint;
-  cl_arg_types[11] = &ffi_type_float;
-  cl_arg_types[12] = &ffi_type_sint;
-  cl_arg_types[13] = &ffi_type_sint;
-  cl_arg_types[14] = &ffi_type_sint;
-  cl_arg_types[15] = &ffi_type_sint;
-  cl_arg_types[16] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
-		     &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1,
-                             (void *) 3 /* userdata */, code)  == FFI_OK);
-
-  res = (*((closure_test_type1)code))
-    (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
-     19, 21, 1);
-  /* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 255" } */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/closure_fn2.c b/testsuite/libffi.closures/closure_fn2.c
deleted file mode 100644
index 08ff9d9..0000000
--- a/testsuite/libffi.closures/closure_fn2.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check multiple values passing from different type.
-		Also, exceed the limit of gpr and fpr registers on PowerPC
-		Darwin.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void closure_test_fn2(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			     void* userdata)
-{
-  *(ffi_arg*)resp =
-    (int)*(double *)args[0] +(int)(*(double *)args[1]) +
-    (int)(*(double *)args[2]) + (int)*(double *)args[3] +
-    (int)(*(signed short *)args[4]) + (int)(*(double *)args[5]) +
-    (int)*(double *)args[6] + (int)(*(int *)args[7]) +
-    (int)(*(double *)args[8]) + (int)*(int *)args[9] +
-    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
-    (int)*(int *)args[12] + (int)(*(float *)args[13]) +
-    (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
-
-  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
-	 (int)*(double *)args[0], (int)(*(double *)args[1]),
-	 (int)(*(double *)args[2]), (int)*(double *)args[3],
-	 (int)(*(signed short *)args[4]), (int)(*(double *)args[5]),
-	 (int)*(double *)args[6], (int)(*(int *)args[7]),
-	 (int)(*(double*)args[8]), (int)*(int *)args[9],
-	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
-	 (int)*(int *)args[12], (int)(*(float *)args[13]),
-	 (int)(*(int *)args[14]), *(int *)args[15], (int)(intptr_t)userdata,
-	 (int)*(ffi_arg *)resp);
-}
-
-typedef int (*closure_test_type2)(double, double, double, double, signed short,
-				  double, double, int, double, int, int, float,
-				  int, float, int, int);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[17];
-  int res;
-
-  cl_arg_types[0] = &ffi_type_double;
-  cl_arg_types[1] = &ffi_type_double;
-  cl_arg_types[2] = &ffi_type_double;
-  cl_arg_types[3] = &ffi_type_double;
-  cl_arg_types[4] = &ffi_type_sshort;
-  cl_arg_types[5] = &ffi_type_double;
-  cl_arg_types[6] = &ffi_type_double;
-  cl_arg_types[7] = &ffi_type_sint;
-  cl_arg_types[8] = &ffi_type_double;
-  cl_arg_types[9] = &ffi_type_sint;
-  cl_arg_types[10] = &ffi_type_sint;
-  cl_arg_types[11] = &ffi_type_float;
-  cl_arg_types[12] = &ffi_type_sint;
-  cl_arg_types[13] = &ffi_type_float;
-  cl_arg_types[14] = &ffi_type_sint;
-  cl_arg_types[15] = &ffi_type_sint;
-  cl_arg_types[16] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
-		     &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn2,
-                             (void *) 3 /* userdata */, code) == FFI_OK);
-
-  res = (*((closure_test_type2)code))
-    (1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
-     19.0, 21, 1);
-  /* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 255" } */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/closure_fn3.c b/testsuite/libffi.closures/closure_fn3.c
deleted file mode 100644
index 9b54d80..0000000
--- a/testsuite/libffi.closures/closure_fn3.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check multiple values passing from different type.
-		Also, exceed the limit of gpr and fpr registers on PowerPC
-		Darwin.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void closure_test_fn3(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			     void* userdata)
- {
-   *(ffi_arg*)resp =
-     (int)*(float *)args[0] +(int)(*(float *)args[1]) +
-     (int)(*(float *)args[2]) + (int)*(float *)args[3] +
-     (int)(*(float *)args[4]) + (int)(*(float *)args[5]) +
-     (int)*(float *)args[6] + (int)(*(float *)args[7]) +
-     (int)(*(double *)args[8]) + (int)*(int *)args[9] +
-     (int)(*(float *)args[10]) + (int)(*(float *)args[11]) +
-     (int)*(int *)args[12] + (int)(*(float *)args[13]) +
-     (int)(*(float *)args[14]) +  *(int *)args[15] + (intptr_t)userdata;
-
-   printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
-	  (int)*(float *)args[0], (int)(*(float *)args[1]),
-	  (int)(*(float *)args[2]), (int)*(float *)args[3],
-	  (int)(*(float *)args[4]), (int)(*(float *)args[5]),
-	  (int)*(float *)args[6], (int)(*(float *)args[7]),
-	  (int)(*(double *)args[8]), (int)*(int *)args[9],
-	  (int)(*(float *)args[10]), (int)(*(float *)args[11]),
-	  (int)*(int *)args[12], (int)(*(float *)args[13]),
-	  (int)(*(float *)args[14]), *(int *)args[15], (int)(intptr_t)userdata,
-	  (int)*(ffi_arg *)resp);
-
- }
-
-typedef int (*closure_test_type3)(float, float, float, float, float, float,
-				  float, float, double, int, float, float, int,
-				  float, float, int);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[17];
-  int res;
-
-  cl_arg_types[0] = &ffi_type_float;
-  cl_arg_types[1] = &ffi_type_float;
-  cl_arg_types[2] = &ffi_type_float;
-  cl_arg_types[3] = &ffi_type_float;
-  cl_arg_types[4] = &ffi_type_float;
-  cl_arg_types[5] = &ffi_type_float;
-  cl_arg_types[6] = &ffi_type_float;
-  cl_arg_types[7] = &ffi_type_float;
-  cl_arg_types[8] = &ffi_type_double;
-  cl_arg_types[9] = &ffi_type_sint;
-  cl_arg_types[10] = &ffi_type_float;
-  cl_arg_types[11] = &ffi_type_float;
-  cl_arg_types[12] = &ffi_type_sint;
-  cl_arg_types[13] = &ffi_type_float;
-  cl_arg_types[14] = &ffi_type_float;
-  cl_arg_types[15] = &ffi_type_sint;
-  cl_arg_types[16] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
-		     &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn3,
-                             (void *) 3 /* userdata */, code)  == FFI_OK);
-
-  res = (*((closure_test_type3)code))
-    (1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
-     19.19, 21.21, 1);
-  /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 19 21 1 3: 135" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 135" } */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/closure_fn4.c b/testsuite/libffi.closures/closure_fn4.c
deleted file mode 100644
index d4a1530..0000000
--- a/testsuite/libffi.closures/closure_fn4.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check multiple long long values passing.
-		Also, exceed the limit of gpr and fpr registers on PowerPC
-		Darwin.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20031026	 */
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-static void
-closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		 void* userdata)
-{
-  *(ffi_arg*)resp =
-    (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
-    (int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] +
-    (int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] +
-    (int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] +
-    (int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] +
-    (int)*(unsigned long long *)args[10] +
-    (int)*(unsigned long long *)args[11] +
-    (int)*(unsigned long long *)args[12] +
-    (int)*(unsigned long long *)args[13] +
-    (int)*(unsigned long long *)args[14] +
-    *(int *)args[15] + (intptr_t)userdata;
-
-  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
-	 (int)*(unsigned long long *)args[0],
-	 (int)*(unsigned long long *)args[1],
-	 (int)*(unsigned long long *)args[2],
-	 (int)*(unsigned long long *)args[3],
-	 (int)*(unsigned long long *)args[4],
-	 (int)*(unsigned long long *)args[5],
-	 (int)*(unsigned long long *)args[6],
-	 (int)*(unsigned long long *)args[7],
-	 (int)*(unsigned long long *)args[8],
-	 (int)*(unsigned long long *)args[9],
-	 (int)*(unsigned long long *)args[10],
-	 (int)*(unsigned long long *)args[11],
-	 (int)*(unsigned long long *)args[12],
-	 (int)*(unsigned long long *)args[13],
-	 (int)*(unsigned long long *)args[14],
-	 *(int *)args[15],
-	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
-
-}
-
-typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  unsigned long long, int);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[17];
-  int i, res;
-
-  for (i = 0; i < 15; i++) {
-    cl_arg_types[i] = &ffi_type_uint64;
-  }
-  cl_arg_types[15] = &ffi_type_sint;
-  cl_arg_types[16] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
-		     &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
-                             (void *) 3 /* userdata */, code) == FFI_OK);
-
-  res = (*((closure_test_type0)code))
-    (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11LL, 12LL,
-     13LL, 19LL, 21LL, 1);
-  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 680" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/closure_fn5.c b/testsuite/libffi.closures/closure_fn5.c
deleted file mode 100644
index 9907442..0000000
--- a/testsuite/libffi.closures/closure_fn5.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check multiple long long values passing.
-		Exceed the limit of gpr registers on PowerPC
-		Darwin.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20031026	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void
-closure_test_fn5(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		 void* userdata)
-{
-  *(ffi_arg*)resp =
-    (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
-    (int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] +
-    (int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] +
-    (int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] +
-    (int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] +
-    (int)*(int *)args[10] +
-    (int)*(unsigned long long *)args[11] +
-    (int)*(unsigned long long *)args[12] +
-    (int)*(unsigned long long *)args[13] +
-    (int)*(unsigned long long *)args[14] +
-    *(int *)args[15] + (intptr_t)userdata;
-
-  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
-	 (int)*(unsigned long long *)args[0],
-	 (int)*(unsigned long long *)args[1],
-	 (int)*(unsigned long long *)args[2],
-	 (int)*(unsigned long long *)args[3],
-	 (int)*(unsigned long long *)args[4],
-	 (int)*(unsigned long long *)args[5],
-	 (int)*(unsigned long long *)args[6],
-	 (int)*(unsigned long long *)args[7],
-	 (int)*(unsigned long long *)args[8],
-	 (int)*(unsigned long long *)args[9],
-	 (int)*(int *)args[10],
-	 (int)*(unsigned long long *)args[11],
-	 (int)*(unsigned long long *)args[12],
-	 (int)*(unsigned long long *)args[13],
-	 (int)*(unsigned long long *)args[14],
-	 *(int *)args[15],
-	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
-
-}
-
-typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  int, unsigned long long,
-				  unsigned long long, unsigned long long,
-				  unsigned long long, int);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[17];
-  int i, res;
-
-  for (i = 0; i < 10; i++) {
-    cl_arg_types[i] = &ffi_type_uint64;
-  }
-  cl_arg_types[10] = &ffi_type_sint;
-  for (i = 11; i < 15; i++) {
-    cl_arg_types[i] = &ffi_type_uint64;
-  }
-  cl_arg_types[15] = &ffi_type_sint;
-  cl_arg_types[16] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
-		     &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn5,
-                             (void *) 3 /* userdata */, code) == FFI_OK);
-
-  res = (*((closure_test_type0)code))
-    (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11, 12LL,
-     13LL, 19LL, 21LL, 1);
-  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 680" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/closure_fn6.c b/testsuite/libffi.closures/closure_fn6.c
deleted file mode 100644
index 73c54fd..0000000
--- a/testsuite/libffi.closures/closure_fn6.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check multiple values passing from different type.
-		Also, exceed the limit of gpr and fpr registers on PowerPC.
-   Limitations:	none.
-   PR:		PR23404
-   Originator:	<andreast@gcc.gnu.org> 20050830	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void
-closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		 void* userdata)
-{
-  *(ffi_arg*)resp =
-    (int)*(unsigned long long *)args[0] +
-    (int)(*(unsigned long long *)args[1]) +
-    (int)(*(unsigned long long *)args[2]) +
-    (int)*(unsigned long long *)args[3] +
-    (int)(*(int *)args[4]) + (int)(*(double *)args[5]) +
-    (int)*(double *)args[6] + (int)(*(float *)args[7]) +
-    (int)(*(double *)args[8]) + (int)*(double *)args[9] +
-    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
-    (int)*(int *)args[12] + (int)(*(int *)args[13]) +
-    (int)(*(double *)args[14]) +  (int)*(double *)args[15] +
-    (intptr_t)userdata;
-
-  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
-	 (int)*(unsigned long long  *)args[0],
-	 (int)(*(unsigned long long  *)args[1]),
-	 (int)(*(unsigned long long  *)args[2]),
-	 (int)*(unsigned long long  *)args[3],
-	 (int)(*(int *)args[4]), (int)(*(double *)args[5]),
-	 (int)*(double *)args[6], (int)(*(float *)args[7]),
-	 (int)(*(double *)args[8]), (int)*(double *)args[9],
-	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
-	 (int)*(int *)args[12], (int)(*(int *)args[13]),
-	 (int)(*(double *)args[14]), (int)(*(double *)args[15]),
-	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
-
-}
-
-typedef int (*closure_test_type0)(unsigned long long,
-				  unsigned long long,
-				  unsigned long long,
-				  unsigned long long,
-				  int, double, double, float, double, double,
-				  int, float, int, int, double, double);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[17];
-  int res;
-
-  cl_arg_types[0] = &ffi_type_uint64;
-  cl_arg_types[1] = &ffi_type_uint64;
-  cl_arg_types[2] = &ffi_type_uint64;
-  cl_arg_types[3] = &ffi_type_uint64;
-  cl_arg_types[4] = &ffi_type_sint;
-  cl_arg_types[5] = &ffi_type_double;
-  cl_arg_types[6] = &ffi_type_double;
-  cl_arg_types[7] = &ffi_type_float;
-  cl_arg_types[8] = &ffi_type_double;
-  cl_arg_types[9] = &ffi_type_double;
-  cl_arg_types[10] = &ffi_type_sint;
-  cl_arg_types[11] = &ffi_type_float;
-  cl_arg_types[12] = &ffi_type_sint;
-  cl_arg_types[13] = &ffi_type_sint;
-  cl_arg_types[14] = &ffi_type_double;
-  cl_arg_types[15] = &ffi_type_double;
-  cl_arg_types[16] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
-		     &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
-                             (void *) 3 /* userdata */, code) == FFI_OK);
-
-  res = (*((closure_test_type0)code))
-    (1, 2, 3, 4, 127, 429., 7., 8., 9.5, 10., 11, 12., 13,
-     19, 21., 1.);
-  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 680" } */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/closure_loc_fn0.c b/testsuite/libffi.closures/closure_loc_fn0.c
deleted file mode 100644
index b3afa0b..0000000
--- a/testsuite/libffi.closures/closure_loc_fn0.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check multiple values passing from different type.
-		Also, exceed the limit of gpr and fpr registers on PowerPC
-		Darwin.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-
-
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void
-closure_loc_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		 void* userdata)
-{
-  *(ffi_arg*)resp =
-    (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
-    (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
-    (int)(*(signed short *)args[4]) +
-    (int)(*(unsigned long long *)args[5]) +
-    (int)*(int *)args[6] + (int)(*(int *)args[7]) +
-    (int)(*(double *)args[8]) + (int)*(int *)args[9] +
-    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
-    (int)*(int *)args[12] + (int)(*(int *)args[13]) +
-    (int)(*(int *)args[14]) +  *(int *)args[15] + (intptr_t)userdata;
-
-  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
-	 (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
-	 (int)(*(unsigned long long *)args[2]),
-	 (int)*(int *)args[3], (int)(*(signed short *)args[4]),
-	 (int)(*(unsigned long long *)args[5]),
-	 (int)*(int *)args[6], (int)(*(int *)args[7]),
-	 (int)(*(double *)args[8]), (int)*(int *)args[9],
-	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
-	 (int)*(int *)args[12], (int)(*(int *)args[13]),
-	 (int)(*(int *)args[14]),*(int *)args[15],
-	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
-
-}
-
-typedef int (*closure_loc_test_type0)(unsigned long long, int, unsigned long long,
-				  int, signed short, unsigned long long, int,
-				  int, double, int, int, float, int, int,
-				  int, int);
-
-int main (void)
-{
-  ffi_cif cif;
-  ffi_closure *pcl;
-  ffi_type * cl_arg_types[17];
-  int res;
-  void *codeloc;
-
-  cl_arg_types[0] = &ffi_type_uint64;
-  cl_arg_types[1] = &ffi_type_sint;
-  cl_arg_types[2] = &ffi_type_uint64;
-  cl_arg_types[3] = &ffi_type_sint;
-  cl_arg_types[4] = &ffi_type_sshort;
-  cl_arg_types[5] = &ffi_type_uint64;
-  cl_arg_types[6] = &ffi_type_sint;
-  cl_arg_types[7] = &ffi_type_sint;
-  cl_arg_types[8] = &ffi_type_double;
-  cl_arg_types[9] = &ffi_type_sint;
-  cl_arg_types[10] = &ffi_type_sint;
-  cl_arg_types[11] = &ffi_type_float;
-  cl_arg_types[12] = &ffi_type_sint;
-  cl_arg_types[13] = &ffi_type_sint;
-  cl_arg_types[14] = &ffi_type_sint;
-  cl_arg_types[15] = &ffi_type_sint;
-  cl_arg_types[16] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
-		     &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-  pcl = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
-  CHECK(pcl != NULL);
-  CHECK(codeloc != NULL);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_loc_test_fn0,
-			 (void *) 3 /* userdata */, codeloc) == FFI_OK);
-  
-  CHECK(memcmp(pcl, codeloc, sizeof(*pcl)) == 0);
-
-  res = (*((closure_loc_test_type0)codeloc))
-    (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
-     19, 21, 1);
-  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 680" } */
-     exit(0);
-}
diff --git a/testsuite/libffi.closures/closure_simple.c b/testsuite/libffi.closures/closure_simple.c
deleted file mode 100644
index 5a4e728..0000000
--- a/testsuite/libffi.closures/closure_simple.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check simple closure handling with all ABIs
-   Limitations:	none.
-   PR:		none.
-   Originator:	<twalljava@dev.java.net> */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void
-closure_test(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata)
-{
-  *(ffi_arg*)resp =
-    (int)*(int *)args[0] + (int)(*(int *)args[1])
-    + (int)(*(int *)args[2])  + (int)(*(int *)args[3])
-    + (int)(intptr_t)userdata;
-
-  printf("%d %d %d %d: %d\n",
-	 (int)*(int *)args[0], (int)(*(int *)args[1]),
-	 (int)(*(int *)args[2]), (int)(*(int *)args[3]),
-         (int)*(ffi_arg *)resp);
-
-}
-
-typedef int (ABI_ATTR *closure_test_type0)(int, int, int, int);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[17];
-  int res;
-
-  cl_arg_types[0] = &ffi_type_uint;
-  cl_arg_types[1] = &ffi_type_uint;
-  cl_arg_types[2] = &ffi_type_uint;
-  cl_arg_types[3] = &ffi_type_uint;
-  cl_arg_types[4] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, ABI_NUM, 4,
-		     &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test,
-                             (void *) 3 /* userdata */, code) == FFI_OK);
-
-  res = (*(closure_test_type0)code)(0, 1, 2, 3);
-  /* { dg-output "0 1 2 3: 9" } */
-
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 9" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_12byte.c b/testsuite/libffi.closures/cls_12byte.c
deleted file mode 100644
index ea0825d..0000000
--- a/testsuite/libffi.closures/cls_12byte.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_12byte {
-  int a;
-  int b;
-  int c;
-} cls_struct_12byte;
-
-cls_struct_12byte cls_struct_12byte_fn(struct cls_struct_12byte b1,
-			    struct cls_struct_12byte b2)
-{
-  struct cls_struct_12byte result;
-
-  result.a = b1.a + b2.a;
-  result.b = b1.b + b2.b;
-  result.c = b1.c + b2.c;
-
-  printf("%d %d %d %d %d %d: %d %d %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
-	 result.a, result.b, result.c);
-
-  return result;
-}
-
-static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp,
-				 void** args , void* userdata __UNUSED__)
-{
-  struct cls_struct_12byte b1, b2;
-
-  b1 = *(struct cls_struct_12byte*)(args[0]);
-  b2 = *(struct cls_struct_12byte*)(args[1]);
-
-  *(cls_struct_12byte*)resp = cls_struct_12byte_fn(b1, b2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_12byte h_dbl = { 7, 4, 9 };
-  struct cls_struct_12byte j_dbl = { 1, 5, 3 };
-  struct cls_struct_12byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_sint;
-  cls_struct_fields[1] = &ffi_type_sint;
-  cls_struct_fields[2] = &ffi_type_sint;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &h_dbl;
-  args_dbl[1] = &j_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_12byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "7 4 9 1 5 3: 8 9 12" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 8 9 12" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_12byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl.a = 0;
-  res_dbl.b = 0;
-  res_dbl.c = 0;
-
-  res_dbl = ((cls_struct_12byte(*)(cls_struct_12byte, cls_struct_12byte))(code))(h_dbl, j_dbl);
-  /* { dg-output "\n7 4 9 1 5 3: 8 9 12" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 8 9 12" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_16byte.c b/testsuite/libffi.closures/cls_16byte.c
deleted file mode 100644
index 89a08a2..0000000
--- a/testsuite/libffi.closures/cls_16byte.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_16byte {
-  int a;
-  double b;
-  int c;
-} cls_struct_16byte;
-
-cls_struct_16byte cls_struct_16byte_fn(struct cls_struct_16byte b1,
-			    struct cls_struct_16byte b2)
-{
-  struct cls_struct_16byte result;
-
-  result.a = b1.a + b2.a;
-  result.b = b1.b + b2.b;
-  result.c = b1.c + b2.c;
-
-  printf("%d %g %d %d %g %d: %d %g %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
-	 result.a, result.b, result.c);
-
-  return result;
-}
-
-static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp,
-				 void** args, void* userdata __UNUSED__)
-{
-  struct cls_struct_16byte b1, b2;
-
-  b1 = *(struct cls_struct_16byte*)(args[0]);
-  b2 = *(struct cls_struct_16byte*)(args[1]);
-
-  *(cls_struct_16byte*)resp = cls_struct_16byte_fn(b1, b2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
-  struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
-  struct cls_struct_16byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_sint;
-  cls_struct_fields[1] = &ffi_type_double;
-  cls_struct_fields[2] = &ffi_type_sint;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &h_dbl;
-  args_dbl[1] = &j_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_16byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "7 8 9 1 9 3: 8 17 12" } */
-  printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 8 17 12" } */
-
-  res_dbl.a = 0;
-  res_dbl.b = 0.0;
-  res_dbl.c = 0;
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_16byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(code))(h_dbl, j_dbl);
-  /* { dg-output "\n7 8 9 1 9 3: 8 17 12" } */
-  printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 8 17 12" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_18byte.c b/testsuite/libffi.closures/cls_18byte.c
deleted file mode 100644
index 9f75da8..0000000
--- a/testsuite/libffi.closures/cls_18byte.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Double alignment check on darwin.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030915	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_18byte {
-  double a;
-  unsigned char b;
-  unsigned char c;
-  double d;
-} cls_struct_18byte;
-
-cls_struct_18byte cls_struct_18byte_fn(struct cls_struct_18byte a1,
-			    struct cls_struct_18byte a2)
-{
-  struct cls_struct_18byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-  result.d = a1.d + a2.d;
-
-
-  printf("%g %d %d %g %g %d %d %g: %g %d %d %g\n", a1.a, a1.b, a1.c, a1.d,
-	 a2.a, a2.b, a2.c, a2.d,
-	 result.a, result.b, result.c, result.d);
-  return result;
-}
-
-static void
-cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		     void* userdata __UNUSED__)
-{
-  struct cls_struct_18byte a1, a2;
-
-  a1 = *(struct cls_struct_18byte*)(args[0]);
-  a2 = *(struct cls_struct_18byte*)(args[1]);
-
-  *(cls_struct_18byte*)resp = cls_struct_18byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[3];
-  ffi_type* cls_struct_fields[5];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[3];
-
-  struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
-  struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
-  struct cls_struct_18byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_double;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = &ffi_type_double;
-  cls_struct_fields[4] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_18byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 127 126 3 4 125 124 5: 5 252 250 8" } */
-  printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
-  /* { dg-output "\nres: 5 252 250 8" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_18byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_18byte(*)(cls_struct_18byte, cls_struct_18byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n1 127 126 3 4 125 124 5: 5 252 250 8" } */
-  printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
-  /* { dg-output "\nres: 5 252 250 8" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_19byte.c b/testsuite/libffi.closures/cls_19byte.c
deleted file mode 100644
index 278794b..0000000
--- a/testsuite/libffi.closures/cls_19byte.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Double alignment check on darwin.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030915	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_19byte {
-  double a;
-  unsigned char b;
-  unsigned char c;
-  double d;
-  unsigned char e;
-} cls_struct_19byte;
-
-cls_struct_19byte cls_struct_19byte_fn(struct cls_struct_19byte a1,
-			    struct cls_struct_19byte a2)
-{
-  struct cls_struct_19byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-  result.d = a1.d + a2.d;
-  result.e = a1.e + a2.e;
-
-
-  printf("%g %d %d %g %d %g %d %d %g %d: %g %d %d %g %d\n",
-	 a1.a, a1.b, a1.c, a1.d, a1.e,
-	 a2.a, a2.b, a2.c, a2.d, a2.e,
-	 result.a, result.b, result.c, result.d, result.e);
-  return result;
-}
-
-static void
-cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		     void* userdata __UNUSED__)
-{
-  struct cls_struct_19byte a1, a2;
-
-  a1 = *(struct cls_struct_19byte*)(args[0]);
-  a2 = *(struct cls_struct_19byte*)(args[1]);
-
-  *(cls_struct_19byte*)resp = cls_struct_19byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[3];
-  ffi_type* cls_struct_fields[6];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[3];
-
-  struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
-  struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
-  struct cls_struct_19byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_double;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = &ffi_type_double;
-  cls_struct_fields[4] = &ffi_type_uchar;
-  cls_struct_fields[5] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_19byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
-  printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
-	 res_dbl.d, res_dbl.e);
-  /* { dg-output "\nres: 5 252 250 8 239" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_19byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_19byte(*)(cls_struct_19byte, cls_struct_19byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
-  printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
-	 res_dbl.d, res_dbl.e);
-  /* { dg-output "\nres: 5 252 250 8 239" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_1_1byte.c b/testsuite/libffi.closures/cls_1_1byte.c
deleted file mode 100644
index 82492c0..0000000
--- a/testsuite/libffi.closures/cls_1_1byte.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Especially with small structures which may fit in one
-		register. Depending on the ABI.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030902	 */
-
-
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_1_1byte {
-  unsigned char a;
-} cls_struct_1_1byte;
-
-cls_struct_1_1byte cls_struct_1_1byte_fn(struct cls_struct_1_1byte a1,
-			    struct cls_struct_1_1byte a2)
-{
-  struct cls_struct_1_1byte result;
-
-  result.a = a1.a + a2.a;
-
-  printf("%d %d: %d\n", a1.a, a2.a, result.a);
-
-  return  result;
-}
-
-static void
-cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		      void* userdata __UNUSED__)
-{
-
-  struct cls_struct_1_1byte a1, a2;
-
-  a1 = *(struct cls_struct_1_1byte*)(args[0]);
-  a2 = *(struct cls_struct_1_1byte*)(args[1]);
-
-  *(cls_struct_1_1byte*)resp = cls_struct_1_1byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[2];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_1_1byte g_dbl = { 12 };
-  struct cls_struct_1_1byte f_dbl = { 178 };
-  struct cls_struct_1_1byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_1_1byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 178: 190" } */
-  printf("res: %d\n", res_dbl.a);
-  /* { dg-output "\nres: 190" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_1_1byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 178: 190" } */
-  printf("res: %d\n", res_dbl.a);
-  /* { dg-output "\nres: 190" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_20byte.c b/testsuite/libffi.closures/cls_20byte.c
deleted file mode 100644
index 3f8bb28..0000000
--- a/testsuite/libffi.closures/cls_20byte.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_20byte {
-  double a;
-  double b;
-  int c;
-} cls_struct_20byte;
-
-cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
-			    struct cls_struct_20byte a2)
-{
-  struct cls_struct_20byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%g %g %d %g %g %d: %g %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
-	 result.a, result.b, result.c);
-  return result;
-}
-
-static void
-cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		     void* userdata __UNUSED__)
-{
-  struct cls_struct_20byte a1, a2;
-
-  a1 = *(struct cls_struct_20byte*)(args[0]);
-  a2 = *(struct cls_struct_20byte*)(args[1]);
-
-  *(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
-  struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
-  struct cls_struct_20byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_double;
-  cls_struct_fields[1] = &ffi_type_double;
-  cls_struct_fields[2] = &ffi_type_sint;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 2 3 4 5 7: 5 7 10" } */
-  printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 5 7 10" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
-  printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 5 7 10" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_20byte1.c b/testsuite/libffi.closures/cls_20byte1.c
deleted file mode 100644
index 6562727..0000000
--- a/testsuite/libffi.closures/cls_20byte1.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_20byte {
-  int a;
-  double b;
-  double c;
-} cls_struct_20byte;
-
-cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
-			    struct cls_struct_20byte a2)
-{
-  struct cls_struct_20byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %g %g %d %g %g: %d %g %g\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
-	 result.a, result.b, result.c);
-  return result;
-}
-
-static void
-cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		     void* userdata __UNUSED__)
-{
-  struct cls_struct_20byte a1, a2;
-
-  a1 = *(struct cls_struct_20byte*)(args[0]);
-  a2 = *(struct cls_struct_20byte*)(args[1]);
-
-  *(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[3];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[3];
-
-  struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
-  struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
-  struct cls_struct_20byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_sint;
-  cls_struct_fields[1] = &ffi_type_double;
-  cls_struct_fields[2] = &ffi_type_double;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 2 3 4 5 7: 5 7 10" } */
-  printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 5 7 10" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
-  printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 5 7 10" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_24byte.c b/testsuite/libffi.closures/cls_24byte.c
deleted file mode 100644
index 1d82f6e..0000000
--- a/testsuite/libffi.closures/cls_24byte.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_24byte {
-  double a;
-  double b;
-  int c;
-  float d;
-} cls_struct_24byte;
-
-cls_struct_24byte cls_struct_24byte_fn(struct cls_struct_24byte b0,
-			    struct cls_struct_24byte b1,
-			    struct cls_struct_24byte b2,
-			    struct cls_struct_24byte b3)
-{
-  struct cls_struct_24byte result;
-
-  result.a = b0.a + b1.a + b2.a + b3.a;
-  result.b = b0.b + b1.b + b2.b + b3.b;
-  result.c = b0.c + b1.c + b2.c + b3.c;
-  result.d = b0.d + b1.d + b2.d + b3.d;
-
-  printf("%g %g %d %g %g %g %d %g %g %g %d %g %g %g %d %g: %g %g %d %g\n",
-	 b0.a, b0.b, b0.c, b0.d,
-	 b1.a, b1.b, b1.c, b1.d,
-	 b2.a, b2.b, b2.c, b2.d,
-	 b3.a, b3.b, b3.c, b2.d,
-	 result.a, result.b, result.c, result.d);
-
-  return result;
-}
-
-static void
-cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		     void* userdata __UNUSED__)
-{
-  struct cls_struct_24byte b0, b1, b2, b3;
-
-  b0 = *(struct cls_struct_24byte*)(args[0]);
-  b1 = *(struct cls_struct_24byte*)(args[1]);
-  b2 = *(struct cls_struct_24byte*)(args[2]);
-  b3 = *(struct cls_struct_24byte*)(args[3]);
-
-  *(cls_struct_24byte*)resp = cls_struct_24byte_fn(b0, b1, b2, b3);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[5];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 };
-  struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 };
-  struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 };
-  struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 };
-  struct cls_struct_24byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_double;
-  cls_struct_fields[1] = &ffi_type_double;
-  cls_struct_fields[2] = &ffi_type_sint;
-  cls_struct_fields[3] = &ffi_type_float;
-  cls_struct_fields[4] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = &cls_struct_type;
-  dbl_arg_types[3] = &cls_struct_type;
-  dbl_arg_types[4] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = &g_dbl;
-  args_dbl[3] = &h_dbl;
-  args_dbl[4] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_24byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
-  printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
-  /* { dg-output "\nres: 22 15 17 25" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_24byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_24byte(*)(cls_struct_24byte,
-				   cls_struct_24byte,
-				   cls_struct_24byte,
-				   cls_struct_24byte))
-	     (code))(e_dbl, f_dbl, g_dbl, h_dbl);
-  /* { dg-output "\n9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
-  printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
-  /* { dg-output "\nres: 22 15 17 25" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_2byte.c b/testsuite/libffi.closures/cls_2byte.c
deleted file mode 100644
index 81bb0a6..0000000
--- a/testsuite/libffi.closures/cls_2byte.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Especially with small structures which may fit in one
-		register. Depending on the ABI.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_2byte {
-  unsigned char a;
-  unsigned char b;
-} cls_struct_2byte;
-
-cls_struct_2byte cls_struct_2byte_fn(struct cls_struct_2byte a1,
-			    struct cls_struct_2byte a2)
-{
-  struct cls_struct_2byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-
-  printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
-
-  return  result;
-}
-
-static void
-cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_2byte a1, a2;
-
-  a1 = *(struct cls_struct_2byte*)(args[0]);
-  a2 = *(struct cls_struct_2byte*)(args[1]);
-
-  *(cls_struct_2byte*)resp = cls_struct_2byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_2byte g_dbl = { 12, 127 };
-  struct cls_struct_2byte f_dbl = { 1, 13 };
-  struct cls_struct_2byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_2byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 127 1 13: 13 140" } */
-  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 13 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_2byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_2byte(*)(cls_struct_2byte, cls_struct_2byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 127 1 13: 13 140" } */
-  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 13 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_3_1byte.c b/testsuite/libffi.closures/cls_3_1byte.c
deleted file mode 100644
index b782746..0000000
--- a/testsuite/libffi.closures/cls_3_1byte.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Especially with small structures which may fit in one
-		register. Depending on the ABI.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030902	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_3_1byte {
-  unsigned char a;
-  unsigned char b;
-  unsigned char c;
-} cls_struct_3_1byte;
-
-cls_struct_3_1byte cls_struct_3_1byte_fn(struct cls_struct_3_1byte a1,
-			    struct cls_struct_3_1byte a2)
-{
-  struct cls_struct_3_1byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
-	 a2.a, a2.b, a2.c,
-	 result.a, result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		      void* userdata __UNUSED__)
-{
-
-  struct cls_struct_3_1byte a1, a2;
-
-  a1 = *(struct cls_struct_3_1byte*)(args[0]);
-  a2 = *(struct cls_struct_3_1byte*)(args[1]);
-
-  *(cls_struct_3_1byte*)resp = cls_struct_3_1byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
-  struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
-  struct cls_struct_3_1byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_3_1byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 13 14 178 179 180: 190 192 194" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 190 192 194" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3_1byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_3_1byte(*)(cls_struct_3_1byte, cls_struct_3_1byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 13 14 178 179 180: 190 192 194" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 190 192 194" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_3byte1.c b/testsuite/libffi.closures/cls_3byte1.c
deleted file mode 100644
index a02c463..0000000
--- a/testsuite/libffi.closures/cls_3byte1.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Especially with small structures which may fit in one
-		register. Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_3byte {
-  unsigned short a;
-  unsigned char b;
-} cls_struct_3byte;
-
-cls_struct_3byte cls_struct_3byte_fn(struct cls_struct_3byte a1,
-			    struct cls_struct_3byte a2)
-{
-  struct cls_struct_3byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-
-  printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
-
-  return  result;
-}
-
-static void
-cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_3byte a1, a2;
-
-  a1 = *(struct cls_struct_3byte*)(args[0]);
-  a2 = *(struct cls_struct_3byte*)(args[1]);
-
-  *(cls_struct_3byte*)resp = cls_struct_3byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_3byte g_dbl = { 12, 119 };
-  struct cls_struct_3byte f_dbl = { 1, 15 };
-  struct cls_struct_3byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_ushort;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_3byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 119 1 15: 13 134" } */
-  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 13 134" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 119 1 15: 13 134" } */
-  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 13 134" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_3byte2.c b/testsuite/libffi.closures/cls_3byte2.c
deleted file mode 100644
index c7251ce..0000000
--- a/testsuite/libffi.closures/cls_3byte2.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Especially with small structures which may fit in one
-		register. Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_3byte_1 {
-  unsigned char a;
-  unsigned short b;
-} cls_struct_3byte_1;
-
-cls_struct_3byte_1 cls_struct_3byte_fn1(struct cls_struct_3byte_1 a1,
-			    struct cls_struct_3byte_1 a2)
-{
-  struct cls_struct_3byte_1 result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-
-  printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
-
-  return  result;
-}
-
-static void
-cls_struct_3byte_gn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		     void* userdata __UNUSED__)
-{
-
-  struct cls_struct_3byte_1 a1, a2;
-
-  a1 = *(struct cls_struct_3byte_1*)(args[0]);
-  a2 = *(struct cls_struct_3byte_1*)(args[1]);
-
-  *(cls_struct_3byte_1*)resp = cls_struct_3byte_fn1(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_3byte_1 g_dbl = { 15, 125 };
-  struct cls_struct_3byte_1 f_dbl = { 9, 19 };
-  struct cls_struct_3byte_1 res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_ushort;
-  cls_struct_fields[2] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_3byte_fn1), &res_dbl, args_dbl);
-  /* { dg-output "15 125 9 19: 24 144" } */
-  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 24 144" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn1, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n15 125 9 19: 24 144" } */
-  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 24 144" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_3float.c b/testsuite/libffi.closures/cls_3float.c
deleted file mode 100644
index 48888f8..0000000
--- a/testsuite/libffi.closures/cls_3float.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:>none.
-   PR:		none.
-   Originator:	<compnerd@compnerd.org> 20171026	 */
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-typedef struct cls_struct_3float {
-  float f;
-  float g;
-  float h;
-} cls_struct_3float;
-
-cls_struct_3float cls_struct_3float_fn(struct cls_struct_3float a1,
-				       struct cls_struct_3float a2)
-{
-  struct cls_struct_3float result;
-
-  result.f = a1.f + a2.f;
-  result.g = a1.g + a2.g;
-  result.h = a1.h + a2.h;
-
-  printf("%g %g %g %g %g %g: %g %g %g\n", a1.f, a1.g, a1.h,
-	 a2.f, a2.g, a2.h, result.f, result.g, result.h);
-
-  return result;
-}
-
-static void
-cls_struct_3float_gn(ffi_cif *cif __UNUSED__, void* resp, void **args,
-		     void* userdata __UNUSED__)
-{
-  struct cls_struct_3float a1, a2;
-
-  a1 = *(struct cls_struct_3float*)(args[0]);
-  a2 = *(struct cls_struct_3float*)(args[1]);
-
-  *(cls_struct_3float*)resp = cls_struct_3float_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void *args_dbl[3];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[3];
-
-  struct cls_struct_3float g_dbl = { 1.0f, 2.0f, 3.0f };
-  struct cls_struct_3float f_dbl = { 1.0f, 2.0f, 3.0f };
-  struct cls_struct_3float res_dbl;
-
-  cls_struct_fields[0] = &ffi_type_float;
-  cls_struct_fields[1] = &ffi_type_float;
-  cls_struct_fields[2] = &ffi_type_float;
-  cls_struct_fields[3] = NULL;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_3float_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 2 3 1 2 3: 2 4 6" } */
-  printf("res: %g %g %g\n", res_dbl.f, res_dbl.g, res_dbl.h);
-  /* { dg-output "\nres: 2 4 6" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3float_gn, NULL, code) ==
-	FFI_OK);
-
-  res_dbl = ((cls_struct_3float(*)(cls_struct_3float,
-				   cls_struct_3float))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */
-  printf("res: %g %g %g\n", res_dbl.f, res_dbl.g, res_dbl.h);
-  /* { dg-output "\nres: 2 4 6" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_4_1byte.c b/testsuite/libffi.closures/cls_4_1byte.c
deleted file mode 100644
index 2d6d8b6..0000000
--- a/testsuite/libffi.closures/cls_4_1byte.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Especially with small structures which may fit in one
-		register. Depending on the ABI.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030902	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_4_1byte {
-  unsigned char a;
-  unsigned char b;
-  unsigned char c;
-  unsigned char d;
-} cls_struct_4_1byte;
-
-cls_struct_4_1byte cls_struct_4_1byte_fn(struct cls_struct_4_1byte a1,
-			    struct cls_struct_4_1byte a2)
-{
-  struct cls_struct_4_1byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-  result.d = a1.d + a2.d;
-
-  printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
-	 a2.a, a2.b, a2.c, a2.d,
-	 result.a, result.b, result.c, result.d);
-
-  return  result;
-}
-
-static void
-cls_struct_4_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		      void* userdata __UNUSED__)
-{
-
-  struct cls_struct_4_1byte a1, a2;
-
-  a1 = *(struct cls_struct_4_1byte*)(args[0]);
-  a2 = *(struct cls_struct_4_1byte*)(args[1]);
-
-  *(cls_struct_4_1byte*)resp = cls_struct_4_1byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[5];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
-  struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
-  struct cls_struct_4_1byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = &ffi_type_uchar;
-  cls_struct_fields[4] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_4_1byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 13 14 15 178 179 180 181: 190 192 194 196" } */
-  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
-  /* { dg-output "\nres: 190 192 194 196" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4_1byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 13 14 15 178 179 180 181: 190 192 194 196" } */
-  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
-  /* { dg-output "\nres: 190 192 194 196" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_4byte.c b/testsuite/libffi.closures/cls_4byte.c
deleted file mode 100644
index 4ac3787..0000000
--- a/testsuite/libffi.closures/cls_4byte.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-typedef struct cls_struct_4byte {
-  unsigned short a;
-  unsigned short b;
-} cls_struct_4byte;
-
-cls_struct_4byte cls_struct_4byte_fn(struct cls_struct_4byte a1,
-			    struct cls_struct_4byte a2)
-{
-  struct cls_struct_4byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-
-  printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
-
-  return  result;
-}
-
-static void
-cls_struct_4byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_4byte a1, a2;
-
-  a1 = *(struct cls_struct_4byte*)(args[0]);
-  a2 = *(struct cls_struct_4byte*)(args[1]);
-
-  *(cls_struct_4byte*)resp = cls_struct_4byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_4byte g_dbl = { 127, 120 };
-  struct cls_struct_4byte f_dbl = { 12, 128 };
-  struct cls_struct_4byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_ushort;
-  cls_struct_fields[1] = &ffi_type_ushort;
-  cls_struct_fields[2] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_4byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "127 120 12 128: 139 248" } */
-  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 139 248" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_4byte(*)(cls_struct_4byte, cls_struct_4byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n127 120 12 128: 139 248" } */
-  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 139 248" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_5_1_byte.c b/testsuite/libffi.closures/cls_5_1_byte.c
deleted file mode 100644
index ad9d51c..0000000
--- a/testsuite/libffi.closures/cls_5_1_byte.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20050708	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_5byte {
-  unsigned char a;
-  unsigned char b;
-  unsigned char c;
-  unsigned char d;
-  unsigned char e;
-} cls_struct_5byte;
-
-cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
-			    struct cls_struct_5byte a2)
-{
-  struct cls_struct_5byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-  result.d = a1.d + a2.d;
-  result.e = a1.e + a2.e;
-
-  printf("%d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d\n",
-	 a1.a, a1.b, a1.c, a1.d, a1.e,
-	 a2.a, a2.b, a2.c, a2.d, a2.e,
-	 result.a, result.b, result.c, result.d, result.e);
-
-  return  result;
-}
-
-static void
-cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_5byte a1, a2;
-
-  a1 = *(struct cls_struct_5byte*)(args[0]);
-  a2 = *(struct cls_struct_5byte*)(args[1]);
-
-  *(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[6];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 };
-  struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 };
-  struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 };
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = &ffi_type_uchar;
-  cls_struct_fields[4] = &ffi_type_uchar;
-  cls_struct_fields[5] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
-  printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
-	 res_dbl.d, res_dbl.e);
-  /* { dg-output "\nres: 139 248 10 6 8" } */
-
-  res_dbl.a = 0;
-  res_dbl.b = 0;
-  res_dbl.c = 0;
-  res_dbl.d = 0;
-  res_dbl.e = 0;
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
-  printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
-	 res_dbl.d, res_dbl.e);
-  /* { dg-output "\nres: 139 248 10 6 8" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_5byte.c b/testsuite/libffi.closures/cls_5byte.c
deleted file mode 100644
index 4e0c000..0000000
--- a/testsuite/libffi.closures/cls_5byte.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_5byte {
-  unsigned short a;
-  unsigned short b;
-  unsigned char c;
-} cls_struct_5byte;
-
-cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
-			    struct cls_struct_5byte a2)
-{
-  struct cls_struct_5byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
-	 a2.a, a2.b, a2.c,
-	 result.a, result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_5byte a1, a2;
-
-  a1 = *(struct cls_struct_5byte*)(args[0]);
-  a2 = *(struct cls_struct_5byte*)(args[1]);
-
-  *(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_5byte g_dbl = { 127, 120, 1 };
-  struct cls_struct_5byte f_dbl = { 12, 128, 9 };
-  struct cls_struct_5byte res_dbl = { 0, 0, 0 };
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_ushort;
-  cls_struct_fields[1] = &ffi_type_ushort;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "127 120 1 12 128 9: 139 248 10" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 139 248 10" } */
-
-  res_dbl.a = 0;
-  res_dbl.b = 0;
-  res_dbl.c = 0;
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n127 120 1 12 128 9: 139 248 10" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 139 248 10" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_64byte.c b/testsuite/libffi.closures/cls_64byte.c
deleted file mode 100644
index a55edc2..0000000
--- a/testsuite/libffi.closures/cls_64byte.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check bigger struct which overlaps
-		the gp and fp register count on Darwin/AIX/ppc64.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_64byte {
-  double a;
-  double b;
-  double c;
-  double d;
-  double e;
-  double f;
-  double g;
-  double h;
-} cls_struct_64byte;
-
-cls_struct_64byte cls_struct_64byte_fn(struct cls_struct_64byte b0,
-			    struct cls_struct_64byte b1,
-			    struct cls_struct_64byte b2,
-			    struct cls_struct_64byte b3)
-{
-  struct cls_struct_64byte result;
-
-  result.a = b0.a + b1.a + b2.a + b3.a;
-  result.b = b0.b + b1.b + b2.b + b3.b;
-  result.c = b0.c + b1.c + b2.c + b3.c;
-  result.d = b0.d + b1.d + b2.d + b3.d;
-  result.e = b0.e + b1.e + b2.e + b3.e;
-  result.f = b0.f + b1.f + b2.f + b3.f;
-  result.g = b0.g + b1.g + b2.g + b3.g;
-  result.h = b0.h + b1.h + b2.h + b3.h;
-
-  printf("%g %g %g %g %g %g %g %g\n", result.a, result.b, result.c,
-	 result.d, result.e, result.f, result.g, result.h);
-
-  return result;
-}
-
-static void
-cls_struct_64byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		     void* userdata __UNUSED__)
-{
-  struct cls_struct_64byte b0, b1, b2, b3;
-
-  b0 = *(struct cls_struct_64byte*)(args[0]);
-  b1 = *(struct cls_struct_64byte*)(args[1]);
-  b2 = *(struct cls_struct_64byte*)(args[2]);
-  b3 = *(struct cls_struct_64byte*)(args[3]);
-
-  *(cls_struct_64byte*)resp = cls_struct_64byte_fn(b0, b1, b2, b3);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[9];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_64byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0 };
-  struct cls_struct_64byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0 };
-  struct cls_struct_64byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0 };
-  struct cls_struct_64byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 };
-  struct cls_struct_64byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_double;
-  cls_struct_fields[1] = &ffi_type_double;
-  cls_struct_fields[2] = &ffi_type_double;
-  cls_struct_fields[3] = &ffi_type_double;
-  cls_struct_fields[4] = &ffi_type_double;
-  cls_struct_fields[5] = &ffi_type_double;
-  cls_struct_fields[6] = &ffi_type_double;
-  cls_struct_fields[7] = &ffi_type_double;
-  cls_struct_fields[8] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = &cls_struct_type;
-  dbl_arg_types[3] = &cls_struct_type;
-  dbl_arg_types[4] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = &g_dbl;
-  args_dbl[3] = &h_dbl;
-  args_dbl[4] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_64byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "22 15 17 25 6 13 19 18" } */
-  printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
-	 res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
-  /* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_64byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_64byte(*)(cls_struct_64byte,
-				   cls_struct_64byte,
-				   cls_struct_64byte,
-				   cls_struct_64byte))
-	     (code))(e_dbl, f_dbl, g_dbl, h_dbl);
-  /* { dg-output "\n22 15 17 25 6 13 19 18" } */
-  printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
-	 res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
-  /* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_6_1_byte.c b/testsuite/libffi.closures/cls_6_1_byte.c
deleted file mode 100644
index b4dcdba..0000000
--- a/testsuite/libffi.closures/cls_6_1_byte.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20050708	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_6byte {
-  unsigned char a;
-  unsigned char b;
-  unsigned char c;
-  unsigned char d;
-  unsigned char e;
-  unsigned char f;
-} cls_struct_6byte;
-
-cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
-			    struct cls_struct_6byte a2)
-{
-  struct cls_struct_6byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-  result.d = a1.d + a2.d;
-  result.e = a1.e + a2.e;
-  result.f = a1.f + a2.f;
-
-  printf("%d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d\n",
-	 a1.a, a1.b, a1.c, a1.d, a1.e, a1.f,
-	 a2.a, a2.b, a2.c, a2.d, a2.e, a2.f,
-	 result.a, result.b, result.c, result.d, result.e, result.f);
-
-  return  result;
-}
-
-static void
-cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_6byte a1, a2;
-
-  a1 = *(struct cls_struct_6byte*)(args[0]);
-  a2 = *(struct cls_struct_6byte*)(args[1]);
-
-  *(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[7];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 };
-  struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 };
-  struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 };
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = &ffi_type_uchar;
-  cls_struct_fields[4] = &ffi_type_uchar;
-  cls_struct_fields[5] = &ffi_type_uchar;
-  cls_struct_fields[6] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
-  printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
-	 res_dbl.d, res_dbl.e, res_dbl.f);
-  /* { dg-output "\nres: 139 248 10 6 8 10" } */
-
-  res_dbl.a = 0;
-  res_dbl.b = 0;
-  res_dbl.c = 0;
-  res_dbl.d = 0;
-  res_dbl.e = 0;
-  res_dbl.f = 0;
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
-  printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
-	 res_dbl.d, res_dbl.e, res_dbl.f);
-  /* { dg-output "\nres: 139 248 10 6 8 10" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_6byte.c b/testsuite/libffi.closures/cls_6byte.c
deleted file mode 100644
index 7406780..0000000
--- a/testsuite/libffi.closures/cls_6byte.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_6byte {
-  unsigned short a;
-  unsigned short b;
-  unsigned char c;
-  unsigned char d;
-} cls_struct_6byte;
-
-cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
-			    struct cls_struct_6byte a2)
-{
-  struct cls_struct_6byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-  result.d = a1.d + a2.d;
-
-  printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
-	 a2.a, a2.b, a2.c, a2.d,
-	 result.a, result.b, result.c, result.d);
-
-  return  result;
-}
-
-static void
-cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_6byte a1, a2;
-
-  a1 = *(struct cls_struct_6byte*)(args[0]);
-  a2 = *(struct cls_struct_6byte*)(args[1]);
-
-  *(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[5];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 };
-  struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 };
-  struct cls_struct_6byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_ushort;
-  cls_struct_fields[1] = &ffi_type_ushort;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = &ffi_type_uchar;
-  cls_struct_fields[4] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "127 120 1 128 12 128 9 127: 139 248 10 255" } */
-  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
-  /* { dg-output "\nres: 139 248 10 255" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n127 120 1 128 12 128 9 127: 139 248 10 255" } */
-  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
-  /* { dg-output "\nres: 139 248 10 255" } */
-
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_7_1_byte.c b/testsuite/libffi.closures/cls_7_1_byte.c
deleted file mode 100644
index 14a7e96..0000000
--- a/testsuite/libffi.closures/cls_7_1_byte.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20050708	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_7byte {
-  unsigned char a;
-  unsigned char b;
-  unsigned char c;
-  unsigned char d;
-  unsigned char e;
-  unsigned char f;
-  unsigned char g;
-} cls_struct_7byte;
-
-cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
-			    struct cls_struct_7byte a2)
-{
-  struct cls_struct_7byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-  result.d = a1.d + a2.d;
-  result.e = a1.e + a2.e;
-  result.f = a1.f + a2.f;
-  result.g = a1.g + a2.g;
-
-  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d %d\n",
-	 a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
-	 a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
-	 result.a, result.b, result.c, result.d, result.e, result.f, result.g);
-
-  return  result;
-}
-
-static void
-cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_7byte a1, a2;
-
-  a1 = *(struct cls_struct_7byte*)(args[0]);
-  a2 = *(struct cls_struct_7byte*)(args[1]);
-
-  *(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[8];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 };
-  struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 };
-  struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 };
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = &ffi_type_uchar;
-  cls_struct_fields[4] = &ffi_type_uchar;
-  cls_struct_fields[5] = &ffi_type_uchar;
-  cls_struct_fields[6] = &ffi_type_uchar;
-  cls_struct_fields[7] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
-  printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
-	 res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
-  /* { dg-output "\nres: 139 248 10 6 8 10 12" } */
-
-  res_dbl.a = 0;
-  res_dbl.b = 0;
-  res_dbl.c = 0;
-  res_dbl.d = 0;
-  res_dbl.e = 0;
-  res_dbl.f = 0;
-  res_dbl.g = 0;
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
-  printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
-	 res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
-  /* { dg-output "\nres: 139 248 10 6 8 10 12" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_7byte.c b/testsuite/libffi.closures/cls_7byte.c
deleted file mode 100644
index 1645cc6..0000000
--- a/testsuite/libffi.closures/cls_7byte.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_7byte {
-  unsigned short a;
-  unsigned short b;
-  unsigned char c;
-  unsigned short d;
-} cls_struct_7byte;
-
-cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
-			    struct cls_struct_7byte a2)
-{
-  struct cls_struct_7byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-  result.d = a1.d + a2.d;
-
-  printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
-	 a2.a, a2.b, a2.c, a2.d,
-	 result.a, result.b, result.c, result.d);
-
-  return  result;
-}
-
-static void
-cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_7byte a1, a2;
-
-  a1 = *(struct cls_struct_7byte*)(args[0]);
-  a2 = *(struct cls_struct_7byte*)(args[1]);
-
-  *(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[5];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
-  struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
-  struct cls_struct_7byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_ushort;
-  cls_struct_fields[1] = &ffi_type_ushort;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = &ffi_type_ushort;
-  cls_struct_fields[4] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "127 120 1 254 12 128 9 255: 139 248 10 509" } */
-  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
-  /* { dg-output "\nres: 139 248 10 509" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n127 120 1 254 12 128 9 255: 139 248 10 509" } */
-  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
-  /* { dg-output "\nres: 139 248 10 509" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_8byte.c b/testsuite/libffi.closures/cls_8byte.c
deleted file mode 100644
index f6c1ea5..0000000
--- a/testsuite/libffi.closures/cls_8byte.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Check overlapping.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_8byte {
-  int a;
-  float b;
-} cls_struct_8byte;
-
-cls_struct_8byte cls_struct_8byte_fn(struct cls_struct_8byte a1,
-			    struct cls_struct_8byte a2)
-{
-  struct cls_struct_8byte result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-
-  printf("%d %g %d %g: %d %g\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
-
-  return  result;
-}
-
-static void
-cls_struct_8byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_8byte a1, a2;
-
-  a1 = *(struct cls_struct_8byte*)(args[0]);
-  a2 = *(struct cls_struct_8byte*)(args[1]);
-
-  *(cls_struct_8byte*)resp = cls_struct_8byte_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_8byte g_dbl = { 1, 2.0 };
-  struct cls_struct_8byte f_dbl = { 4, 5.0 };
-  struct cls_struct_8byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_sint;
-  cls_struct_fields[1] = &ffi_type_float;
-  cls_struct_fields[2] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_8byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 2 4 5: 5 7" } */
-  printf("res: %d %g\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 5 7" } */
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_8byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_8byte(*)(cls_struct_8byte, cls_struct_8byte))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n1 2 4 5: 5 7" } */
-  printf("res: %d %g\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 5 7" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_9byte1.c b/testsuite/libffi.closures/cls_9byte1.c
deleted file mode 100644
index 0b85722..0000000
--- a/testsuite/libffi.closures/cls_9byte1.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Darwin/AIX do double-word
-		alignment of the struct if the first element is a double.
-		Check that it does not here.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030914	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_9byte {
-  int a;
-  double b;
-} cls_struct_9byte;
-
-cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
-			    struct cls_struct_9byte b2)
-{
-  struct cls_struct_9byte result;
-
-  result.a = b1.a + b2.a;
-  result.b = b1.b + b2.b;
-
-  printf("%d %g %d %g: %d %g\n", b1.a, b1.b,  b2.a, b2.b,
-	 result.a, result.b);
-
-  return result;
-}
-
-static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
-				void** args, void* userdata __UNUSED__)
-{
-  struct cls_struct_9byte b1, b2;
-
-  b1 = *(struct cls_struct_9byte*)(args[0]);
-  b2 = *(struct cls_struct_9byte*)(args[1]);
-
-  *(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[3];
-  ffi_type* cls_struct_fields[3];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[3];
-
-  struct cls_struct_9byte h_dbl = { 7, 8.0};
-  struct cls_struct_9byte j_dbl = { 1, 9.0};
-  struct cls_struct_9byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_sint;
-  cls_struct_fields[1] = &ffi_type_double;
-  cls_struct_fields[2] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &h_dbl;
-  args_dbl[1] = &j_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "7 8 1 9: 8 17" } */
-  printf("res: %d %g\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 8 17" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
-  /* { dg-output "\n7 8 1 9: 8 17" } */
-  printf("res: %d %g\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 8 17" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_9byte2.c b/testsuite/libffi.closures/cls_9byte2.c
deleted file mode 100644
index edf991d..0000000
--- a/testsuite/libffi.closures/cls_9byte2.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Depending on the ABI. Darwin/AIX do double-word
-		alignment of the struct if the first element is a double.
-		Check that it does here.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030914	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_9byte {
-  double a;
-  int b;
-} cls_struct_9byte;
-
-cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
-			    struct cls_struct_9byte b2)
-{
-  struct cls_struct_9byte result;
-
-  result.a = b1.a + b2.a;
-  result.b = b1.b + b2.b;
-
-  printf("%g %d %g %d: %g %d\n", b1.a, b1.b,  b2.a, b2.b,
-	 result.a, result.b);
-
-  return result;
-}
-
-static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
-				void** args, void* userdata __UNUSED__)
-{
-  struct cls_struct_9byte b1, b2;
-
-  b1 = *(struct cls_struct_9byte*)(args[0]);
-  b2 = *(struct cls_struct_9byte*)(args[1]);
-
-  *(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[3];
-  ffi_type* cls_struct_fields[3];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[3];
-
-  struct cls_struct_9byte h_dbl = { 7.0, 8};
-  struct cls_struct_9byte j_dbl = { 1.0, 9};
-  struct cls_struct_9byte res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_double;
-  cls_struct_fields[1] = &ffi_type_sint;
-  cls_struct_fields[2] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &h_dbl;
-  args_dbl[1] = &j_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
-  /* { dg-output "7 8 1 9: 8 17" } */
-  printf("res: %g %d\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 8 17" } */
-
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
-  /* { dg-output "\n7 8 1 9: 8 17" } */
-  printf("res: %g %d\n", res_dbl.a, res_dbl.b);
-  /* { dg-output "\nres: 8 17" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_double.c b/testsuite/libffi.closures/cls_align_double.c
deleted file mode 100644
index aad5f3c..0000000
--- a/testsuite/libffi.closures/cls_align_double.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of double.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  double b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
-			    struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_double;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_float.c b/testsuite/libffi.closures/cls_align_float.c
deleted file mode 100644
index 37e0855..0000000
--- a/testsuite/libffi.closures/cls_align_float.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of float.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  float b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
-			    struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_float;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_longdouble.c b/testsuite/libffi.closures/cls_align_longdouble.c
deleted file mode 100644
index b3322d8..0000000
--- a/testsuite/libffi.closures/cls_align_longdouble.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of long double.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  long double b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
-			    struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_longdouble;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_longdouble_split.c b/testsuite/libffi.closures/cls_align_longdouble_split.c
deleted file mode 100644
index cc1c43b..0000000
--- a/testsuite/libffi.closures/cls_align_longdouble_split.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of long double.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
-/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
-
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  long double a;
-  long double b;
-  long double c;
-  long double d;
-  long double e;
-  long double f;
-  long double g;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(
-	cls_struct_align	a1,
-	cls_struct_align	a2)
-{
-	struct cls_struct_align r;
-
-	r.a = a1.a + a2.a;
-	r.b = a1.b + a2.b;
-	r.c = a1.c + a2.c;
-	r.d = a1.d + a2.d;
-	r.e = a1.e + a2.e;
-	r.f = a1.f + a2.f;
-	r.g = a1.g + a2.g;
-
-	printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
-		"%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
-		a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
-		a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
-		r.a, r.b, r.c, r.d, r.e, r.f, r.g);
-
-	return r;
-}
-
-cls_struct_align cls_struct_align_fn2(
-	cls_struct_align	a1)
-{
-	struct cls_struct_align r;
-
-	r.a = a1.a + 1;
-	r.b = a1.b + 1;
-	r.c = a1.c + 1;
-	r.d = a1.d + 1;
-	r.e = a1.e + 1;
-	r.f = a1.f + 1;
-	r.g = a1.g + 1;
-
-	printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
-		"%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
-		a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
-		r.a, r.b, r.c, r.d, r.e, r.f, r.g);
-
-	return r;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, 
-		    void* userdata __UNUSED__)
-{
-	struct cls_struct_align a1, a2;
-
-	a1 = *(struct cls_struct_align*)(args[0]);
-	a2 = *(struct cls_struct_align*)(args[1]);
-
-	*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-	ffi_cif cif;
-        void *code;
-	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void* args_dbl[3];
-	ffi_type* cls_struct_fields[8];
-	ffi_type cls_struct_type;
-	ffi_type* dbl_arg_types[3];
-
-	struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
-	struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
-	struct cls_struct_align res_dbl;
-
-	cls_struct_type.size = 0;
-	cls_struct_type.alignment = 0;
-	cls_struct_type.type = FFI_TYPE_STRUCT;
-	cls_struct_type.elements = cls_struct_fields;
-
-	cls_struct_fields[0] = &ffi_type_longdouble;
-	cls_struct_fields[1] = &ffi_type_longdouble;
-	cls_struct_fields[2] = &ffi_type_longdouble;
-	cls_struct_fields[3] = &ffi_type_longdouble;
-	cls_struct_fields[4] = &ffi_type_longdouble;
-	cls_struct_fields[5] = &ffi_type_longdouble;
-	cls_struct_fields[6] = &ffi_type_longdouble;
-	cls_struct_fields[7] = NULL;
-
-	dbl_arg_types[0] = &cls_struct_type;
-	dbl_arg_types[1] = &cls_struct_type;
-	dbl_arg_types[2] = NULL;
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		dbl_arg_types) == FFI_OK);
-
-	args_dbl[0] = &g_dbl;
-	args_dbl[1] = &f_dbl;
-	args_dbl[2] = NULL;
-
-	ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-	/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
-	printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
-		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
-	/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-	res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-	/* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
-	printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
-		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
-	/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_longdouble_split2.c b/testsuite/libffi.closures/cls_align_longdouble_split2.c
deleted file mode 100644
index 5d3bec0..0000000
--- a/testsuite/libffi.closures/cls_align_longdouble_split2.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*	Area:			ffi_call, closure_call
-	Purpose:		Check structure alignment of long double.
-	Limitations:	none.
-	PR:				none.
-	Originator:		Blake Chaffin	6/18/2007
-*/
-
-/* { dg-do run { xfail strongarm*-*-* } } */
-/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
-
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  long double a;
-  long double b;
-  long double c;
-  long double d;
-  long double e;
-  double f;
-  long double g;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(
-	cls_struct_align	a1,
-	cls_struct_align	a2)
-{
-	struct cls_struct_align r;
-
-	r.a = a1.a + a2.a;
-	r.b = a1.b + a2.b;
-	r.c = a1.c + a2.c;
-	r.d = a1.d + a2.d;
-	r.e = a1.e + a2.e;
-	r.f = a1.f + a2.f;
-	r.g = a1.g + a2.g;
-
-	printf("%Lg %Lg %Lg %Lg %Lg %g %Lg %Lg %Lg %Lg %Lg %Lg %g %Lg: "
-		"%Lg %Lg %Lg %Lg %Lg %g %Lg\n",
-		a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
-		a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
-		r.a, r.b, r.c, r.d, r.e, r.f, r.g);
-
-	return r;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, 
-		    void* userdata __UNUSED__)
-{
-	struct cls_struct_align a1, a2;
-
-	a1 = *(struct cls_struct_align*)(args[0]);
-	a2 = *(struct cls_struct_align*)(args[1]);
-
-	*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-	ffi_cif cif;
-        void *code;
-	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void* args_dbl[3];
-	ffi_type* cls_struct_fields[8];
-	ffi_type cls_struct_type;
-	ffi_type* dbl_arg_types[3];
-
-	struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
-	struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
-	struct cls_struct_align res_dbl;
-
-	cls_struct_type.size = 0;
-	cls_struct_type.alignment = 0;
-	cls_struct_type.type = FFI_TYPE_STRUCT;
-	cls_struct_type.elements = cls_struct_fields;
-
-	cls_struct_fields[0] = &ffi_type_longdouble;
-	cls_struct_fields[1] = &ffi_type_longdouble;
-	cls_struct_fields[2] = &ffi_type_longdouble;
-	cls_struct_fields[3] = &ffi_type_longdouble;
-	cls_struct_fields[4] = &ffi_type_longdouble;
-	cls_struct_fields[5] = &ffi_type_double;
-	cls_struct_fields[6] = &ffi_type_longdouble;
-	cls_struct_fields[7] = NULL;
-
-	dbl_arg_types[0] = &cls_struct_type;
-	dbl_arg_types[1] = &cls_struct_type;
-	dbl_arg_types[2] = NULL;
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		dbl_arg_types) == FFI_OK);
-
-	args_dbl[0] = &g_dbl;
-	args_dbl[1] = &f_dbl;
-	args_dbl[2] = NULL;
-
-	ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-	/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
-	printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
-		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
-	/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-	res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-	/* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
-	printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
-		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
-	/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
-
-  exit(0);
-}
-
-
-
diff --git a/testsuite/libffi.closures/cls_align_pointer.c b/testsuite/libffi.closures/cls_align_pointer.c
deleted file mode 100644
index 8fbf36a..0000000
--- a/testsuite/libffi.closures/cls_align_pointer.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of pointer.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  void *b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
-			    struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = (void *)((uintptr_t)a1.b + (uintptr_t)a2.b);
-  result.c = a1.c + a2.c;
-
-  printf("%d %" PRIuPTR " %d %d %" PRIuPTR " %d: %d %" PRIuPTR " %d\n", 
-         a1.a, (uintptr_t)a1.b, a1.c,
-	 a2.a, (uintptr_t)a2.b, a2.c,
-         result.a, (uintptr_t)result.b,
-	 result.c);
-
-  return result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
-  struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
-  struct cls_struct_align res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_pointer;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_sint16.c b/testsuite/libffi.closures/cls_align_sint16.c
deleted file mode 100644
index 039b874..0000000
--- a/testsuite/libffi.closures/cls_align_sint16.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of sint16.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  signed short b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
-			    struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_sshort;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_sint32.c b/testsuite/libffi.closures/cls_align_sint32.c
deleted file mode 100644
index c96c6d1..0000000
--- a/testsuite/libffi.closures/cls_align_sint32.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of sint32.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  signed int b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
-			    struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_sint;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_sint64.c b/testsuite/libffi.closures/cls_align_sint64.c
deleted file mode 100644
index 9aa7bdd..0000000
--- a/testsuite/libffi.closures/cls_align_sint64.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of sint64.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-/* { dg-do run } */
-/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  signed long long b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
-			    struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_sint64;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_uint16.c b/testsuite/libffi.closures/cls_align_uint16.c
deleted file mode 100644
index 97620b7..0000000
--- a/testsuite/libffi.closures/cls_align_uint16.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of uint16.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  unsigned short b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
-			    struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_ushort;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_uint32.c b/testsuite/libffi.closures/cls_align_uint32.c
deleted file mode 100644
index 5766fad..0000000
--- a/testsuite/libffi.closures/cls_align_uint32.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of uint32.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  unsigned int b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
-			    struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_uint;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_align_uint64.c b/testsuite/libffi.closures/cls_align_uint64.c
deleted file mode 100644
index a52cb89..0000000
--- a/testsuite/libffi.closures/cls_align_uint64.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of uint64.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<hos@tamanegi.org> 20031203	 */
-
-
-/* { dg-do run } */
-/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
-#include "ffitest.h"
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  unsigned long long b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
-			    struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_uint64;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &g_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
-  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
-  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
-  printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
-  /* { dg-output "\nres: 13 14271 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_dbls_struct.c b/testsuite/libffi.closures/cls_dbls_struct.c
deleted file mode 100644
index e451dea..0000000
--- a/testsuite/libffi.closures/cls_dbls_struct.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Check double arguments in structs.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin 6/23/2007	*/
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-typedef struct Dbls {
-	double x;
-	double y;
-} Dbls;
-
-void
-closure_test_fn(Dbls p)
-{
-	printf("%.1f %.1f\n", p.x, p.y);
-}
-
-void
-closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
-		void** args, void* userdata __UNUSED__)
-{
-	closure_test_fn(*(Dbls*)args[0]);
-}
-
-int main(int argc __UNUSED__, char** argv __UNUSED__)
-{
-	ffi_cif cif;
-
-        void *code;
-	ffi_closure*	pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	ffi_type*		cl_arg_types[1];
-
-	ffi_type	ts1_type;
-	ffi_type*	ts1_type_elements[4];
-
-	Dbls arg = { 1.0, 2.0 };
-
-	ts1_type.size = 0;
-	ts1_type.alignment = 0;
-	ts1_type.type = FFI_TYPE_STRUCT;
-	ts1_type.elements = ts1_type_elements;
-
-	ts1_type_elements[0] = &ffi_type_double;
-	ts1_type_elements[1] = &ffi_type_double;
-	ts1_type_elements[2] = NULL;
-
-	cl_arg_types[0] = &ts1_type;
-
-	/* Initialize the cif */
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-				 &ffi_type_void, cl_arg_types) == FFI_OK);
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
-
-	((void*(*)(Dbls))(code))(arg);
-	/* { dg-output "1.0 2.0" } */
-
-	closure_test_fn(arg);
-	/* { dg-output "\n1.0 2.0" } */
-
-	return 0;
-}
diff --git a/testsuite/libffi.closures/cls_double.c b/testsuite/libffi.closures/cls_double.c
deleted file mode 100644
index 84ad4cb..0000000
--- a/testsuite/libffi.closures/cls_double.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value double.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			      void* userdata __UNUSED__)
- {
-   *(double *)resp = *(double *)args[0];
-
-   printf("%f: %f\n",*(double *)args[0],
-	  *(double *)resp);
- }
-typedef double (*cls_ret_double)(double);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[2];
-  double res;
-
-  cl_arg_types[0] = &ffi_type_double;
-  cl_arg_types[1] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &ffi_type_double, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code)  == FFI_OK);
-
-  res = (*((cls_ret_double)code))(21474.789);
-  /* { dg-output "21474.789000: 21474.789000" } */
-  printf("res: %.6f\n", res);
-  /* { dg-output "\nres: 21474.789000" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_double_va.c b/testsuite/libffi.closures/cls_double_va.c
deleted file mode 100644
index e077f92..0000000
--- a/testsuite/libffi.closures/cls_double_va.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Test doubles passed in variable argument lists.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin 6/6/2007	 */
-
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
-/* { dg-output "" { xfail avr32*-*-* } } */
-/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
-
-#include "ffitest.h"
-
-static void
-cls_double_va_fn(ffi_cif* cif __UNUSED__, void* resp, 
-		 void** args, void* userdata __UNUSED__)
-{
-	char*	format		= *(char**)args[0];
-	double	doubleValue	= *(double*)args[1];
-
-	*(ffi_arg*)resp = printf(format, doubleValue);
-}
-
-int main (void)
-{
-	ffi_cif cif;
-        void *code;
-	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void* args[3];
-	ffi_type* arg_types[3];
-
-	char*	format		= "%.1f\n";
-	double	doubleArg	= 7;
-	ffi_arg	res			= 0;
-
-	arg_types[0] = &ffi_type_pointer;
-	arg_types[1] = &ffi_type_double;
-	arg_types[2] = NULL;
-
-	/* This printf call is variadic */
-	CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
-			       arg_types) == FFI_OK);
-
-	args[0] = &format;
-	args[1] = &doubleArg;
-	args[2] = NULL;
-
-	ffi_call(&cif, FFI_FN(printf), &res, args);
-	/* { dg-output "7.0" } */
-	printf("res: %d\n", (int) res);
-	/* { dg-output "\nres: 4" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL,
-				   code) == FFI_OK);
-
-	res = ((int(*)(char*, ...))(code))(format, doubleArg);
-	/* { dg-output "\n7.0" } */
-	printf("res: %d\n", (int) res);
-	/* { dg-output "\nres: 4" } */
-
-	exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_float.c b/testsuite/libffi.closures/cls_float.c
deleted file mode 100644
index 0090fed..0000000
--- a/testsuite/libffi.closures/cls_float.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value float.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void cls_ret_float_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			     void* userdata __UNUSED__)
- {
-   *(float *)resp = *(float *)args[0];
-
-   printf("%g: %g\n",*(float *)args[0],
-	  *(float *)resp);
- }
-
-typedef float (*cls_ret_float)(float);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[2];
-  float res;
-
-  cl_arg_types[0] = &ffi_type_float;
-  cl_arg_types[1] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &ffi_type_float, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_float_fn, NULL, code)  == FFI_OK);
-  res = ((((cls_ret_float)code)(-2122.12)));
-  /* { dg-output "\\-2122.12: \\-2122.12" } */
-  printf("res: %.6f\n", res);
-  /* { dg-output "\nres: \-2122.120117" } */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_longdouble.c b/testsuite/libffi.closures/cls_longdouble.c
deleted file mode 100644
index d24e72e..0000000
--- a/testsuite/libffi.closures/cls_longdouble.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Check long double arguments.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin	*/
-
-/* This test is known to PASS on armv7l-unknown-linux-gnueabihf, so I have
-   remove the xfail for arm*-*-* below, until we know more.  */
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
-/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
-
-#include "ffitest.h"
-
-long double cls_ldouble_fn(
-	long double	a1,
-	long double	a2,
-	long double	a3,
-	long double	a4,
-	long double	a5,
-	long double	a6,
-	long double	a7,
-	long double	a8)
-{
-	long double	r = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
-
-	printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: %Lg\n",
-		a1, a2, a3, a4, a5, a6, a7, a8, r);
-
-	return r;
-}
-
-static void
-cls_ldouble_gn(ffi_cif* cif __UNUSED__, void* resp, 
-	       void** args, void* userdata __UNUSED__)
-{
-	long double	a1	= *(long double*)args[0];
-	long double	a2	= *(long double*)args[1];
-	long double	a3	= *(long double*)args[2];
-	long double	a4	= *(long double*)args[3];
-	long double	a5	= *(long double*)args[4];
-	long double	a6	= *(long double*)args[5];
-	long double	a7	= *(long double*)args[6];
-	long double	a8	= *(long double*)args[7];
-
-	*(long double*)resp = cls_ldouble_fn(
-		a1, a2, a3, a4, a5, a6, a7, a8);
-}
-
-int main(void)
-{
-	ffi_cif	cif;
-        void* code;
-	ffi_closure*	pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void*			args[9];
-	ffi_type*		arg_types[9];
-	long double		res	= 0;
-
-	long double	arg1	= 1;
-	long double	arg2	= 2;
-	long double	arg3	= 3;
-	long double	arg4	= 4;
-	long double	arg5	= 5;
-	long double	arg6	= 6;
-	long double	arg7	= 7;
-	long double	arg8	= 8;
-
-	arg_types[0] = &ffi_type_longdouble;
-	arg_types[1] = &ffi_type_longdouble;
-	arg_types[2] = &ffi_type_longdouble;
-	arg_types[3] = &ffi_type_longdouble;
-	arg_types[4] = &ffi_type_longdouble;
-	arg_types[5] = &ffi_type_longdouble;
-	arg_types[6] = &ffi_type_longdouble;
-	arg_types[7] = &ffi_type_longdouble;
-	arg_types[8] = NULL;
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 8, &ffi_type_longdouble,
-		arg_types) == FFI_OK);
-
-	args[0] = &arg1;
-	args[1] = &arg2;
-	args[2] = &arg3;
-	args[3] = &arg4;
-	args[4] = &arg5;
-	args[5] = &arg6;
-	args[6] = &arg7;
-	args[7] = &arg8;
-	args[8] = NULL;
-
-	ffi_call(&cif, FFI_FN(cls_ldouble_fn), &res, args);
-	/* { dg-output "1 2 3 4 5 6 7 8: 36" } */
-	printf("res: %Lg\n", res);
-	/* { dg-output "\nres: 36" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ldouble_gn, NULL, code) == FFI_OK);
-
-	res = ((long double(*)(long double, long double, long double, long double,
-		long double, long double, long double, long double))(code))(arg1, arg2,
-		arg3, arg4, arg5, arg6, arg7, arg8);
-	/* { dg-output "\n1 2 3 4 5 6 7 8: 36" } */
-	printf("res: %Lg\n", res);
-	/* { dg-output "\nres: 36" } */
-
-	return 0;
-}
diff --git a/testsuite/libffi.closures/cls_longdouble_va.c b/testsuite/libffi.closures/cls_longdouble_va.c
deleted file mode 100644
index 39b438b..0000000
--- a/testsuite/libffi.closures/cls_longdouble_va.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Test long doubles passed in variable argument lists.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin 6/6/2007	 */
-
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
-/* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */
-/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
-
-#include "ffitest.h"
-
-static void
-cls_longdouble_va_fn(ffi_cif* cif __UNUSED__, void* resp, 
-		     void** args, void* userdata __UNUSED__)
-{
-	char*		format	= *(char**)args[0];
-	long double	ldValue	= *(long double*)args[1];
-
-	*(ffi_arg*)resp = printf(format, ldValue);
-}
-
-int main (void)
-{
-	ffi_cif cif;
-        void *code;
-	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void* args[3];
-	ffi_type* arg_types[3];
-
-	char*		format	= "%.1Lf\n";
-	long double	ldArg	= 7;
-	ffi_arg		res		= 0;
-
-	arg_types[0] = &ffi_type_pointer;
-	arg_types[1] = &ffi_type_longdouble;
-	arg_types[2] = NULL;
-
-	/* This printf call is variadic */
-	CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
-			       arg_types) == FFI_OK);
-
-	args[0] = &format;
-	args[1] = &ldArg;
-	args[2] = NULL;
-
-	ffi_call(&cif, FFI_FN(printf), &res, args);
-	/* { dg-output "7.0" } */
-	printf("res: %d\n", (int) res);
-	/* { dg-output "\nres: 4" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL,
-				   code) == FFI_OK);
-
-	res = ((int(*)(char*, ...))(code))(format, ldArg);
-	/* { dg-output "\n7.0" } */
-	printf("res: %d\n", (int) res);
-	/* { dg-output "\nres: 4" } */
-
-	exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_many_mixed_args.c b/testsuite/libffi.closures/cls_many_mixed_args.c
deleted file mode 100644
index 7fd6c82..0000000
--- a/testsuite/libffi.closures/cls_many_mixed_args.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check closures called with many args of mixed types
-   Limitations:	none.
-   PR:		none.
-   Originator:	<david.schneider@picle.org> */
-
-/* { dg-do run } */
-#include "ffitest.h"
-#include <float.h>
-#include <math.h>
-
-#define NARGS 16
-
-static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			      void* userdata __UNUSED__)
-{
-  int i;
-  double r = 0;
-  double t;
-  for(i = 0; i < NARGS; i++)
-    {
-    if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
-      {
-      t = *(long int *)args[i];
-      CHECK(t == i+1);
-      }
-    else
-      {
-      t = *(double *)args[i];
-      CHECK(fabs(t - ((i+1) * 0.1)) < FLT_EPSILON);
-      }
-    r += t;
-    }
-  *(double *)resp = r;
-}
-typedef double (*cls_ret_double)(double, double, double, double, long int,
-double, double, double, double, long int, double, long int, double, long int,
-double, long int);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[NARGS];
-  double res;
-  int i;
-  double expected = 64.9;
-
-  for(i = 0; i < NARGS; i++)
-    {
-    if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
-      cl_arg_types[i] = &ffi_type_slong;
-    else
-      cl_arg_types[i] = &ffi_type_double;
-    }
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NARGS,
-		     &ffi_type_double, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK);
-
-  res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10,
-                                 1.1, 12, 1.3, 14, 1.5, 16);
-  if (fabs(res - expected) < FLT_EPSILON)
-    exit(0);
-  else
-    abort();
-}
diff --git a/testsuite/libffi.closures/cls_many_mixed_float_double.c b/testsuite/libffi.closures/cls_many_mixed_float_double.c
deleted file mode 100644
index 62b0697..0000000
--- a/testsuite/libffi.closures/cls_many_mixed_float_double.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check register allocation for closure calls with many float and double arguments
-   Limitations:	none.
-   PR:		none.
-   Originator:	<david.schneider@picle.org> */
-
-/* { dg-do run } */
-#include "ffitest.h"
-#include <float.h>
-#include <math.h>
-
-#define NARGS 16
-
-static void cls_mixed_float_double_fn(ffi_cif* cif , void* ret, void** args,
-			      void* userdata __UNUSED__)
-{
-    double r = 0;
-    unsigned int i;
-    double t;
-    for(i=0; i < cif->nargs; i++)
-    {
-        if(cif->arg_types[i] == &ffi_type_double) {
-				t = *(((double**)(args))[i]);
-        } else {
-				t = *(((float**)(args))[i]);
-        }
-        r += t;
-    }
-    *((double*)ret) = r;
-}
-typedef double (*cls_mixed)(double, float, double, double, double, double, double, float, float, double, float, float);
-
-int main (void)
-{
-    ffi_cif cif;
-    ffi_closure *closure;
-	void* code;
-    ffi_type *argtypes[12] = {&ffi_type_double, &ffi_type_float, &ffi_type_double,
-                          &ffi_type_double, &ffi_type_double, &ffi_type_double,
-                          &ffi_type_double, &ffi_type_float, &ffi_type_float,
-                          &ffi_type_double, &ffi_type_float, &ffi_type_float};
-
-
-    closure = ffi_closure_alloc(sizeof(ffi_closure), (void**)&code);
-    if(closure ==NULL)
-		abort();
-    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 12, &ffi_type_double, argtypes) == FFI_OK);
-	CHECK(ffi_prep_closure_loc(closure, &cif, cls_mixed_float_double_fn, NULL,  code) == FFI_OK);
-    double ret = ((cls_mixed)code)(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2);
-    ffi_closure_free(closure);
-	if(fabs(ret - 7.8) < FLT_EPSILON)
-		exit(0);
-	else
-		abort();
-}
diff --git a/testsuite/libffi.closures/cls_multi_schar.c b/testsuite/libffi.closures/cls_multi_schar.c
deleted file mode 100644
index 71df7b6..0000000
--- a/testsuite/libffi.closures/cls_multi_schar.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check passing of multiple signed char values.
-   Limitations:	none.
-   PR:		PR13221.
-   Originator:	<hos@tamanegi.org> 20031129  */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-signed char test_func_fn(signed char a1, signed char a2)
-{
-  signed char result;
-
-  result = a1 + a2;
-
-  printf("%d %d: %d\n", a1, a2, result);
-
-  return result;
-
-}
-
-static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
-			 void *data __UNUSED__)
-{
-  signed char a1, a2;
-
-  a1 = *(signed char *)avals[0];
-  a2 = *(signed char *)avals[1];
-
-  *(ffi_arg *)rval = test_func_fn(a1, a2);
-
-}
-
-typedef signed char (*test_type)(signed char, signed char);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void * args_dbl[3];
-  ffi_type * cl_arg_types[3];
-  ffi_arg res_call;
-  signed char a, b, res_closure;
-
-  a = 2;
-  b = 125;
-
-  args_dbl[0] = &a;
-  args_dbl[1] = &b;
-  args_dbl[2] = NULL;
-
-  cl_arg_types[0] = &ffi_type_schar;
-  cl_arg_types[1] = &ffi_type_schar;
-  cl_arg_types[2] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
-		     &ffi_type_schar, cl_arg_types) == FFI_OK);
-
-  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
-  /* { dg-output "2 125: 127" } */
-  printf("res: %d\n", (signed char)res_call);
-  /* { dg-output "\nres: 127" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
-
-  res_closure = (*((test_type)code))(2, 125);
-  /* { dg-output "\n2 125: 127" } */
-  printf("res: %d\n", res_closure);
-  /* { dg-output "\nres: 127" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_multi_sshort.c b/testsuite/libffi.closures/cls_multi_sshort.c
deleted file mode 100644
index 4c39153..0000000
--- a/testsuite/libffi.closures/cls_multi_sshort.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check passing of multiple signed short values.
-   Limitations:	none.
-   PR:		PR13221.
-   Originator:	<andreast@gcc.gnu.org> 20031129  */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-signed short test_func_fn(signed short a1, signed short a2)
-{
-  signed short result;
-
-  result = a1 + a2;
-
-  printf("%d %d: %d\n", a1, a2, result);
-
-  return result;
-
-}
-
-static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
-			 void *data __UNUSED__)
-{
-  signed short a1, a2;
-
-  a1 = *(signed short *)avals[0];
-  a2 = *(signed short *)avals[1];
-
-  *(ffi_arg *)rval = test_func_fn(a1, a2);
-
-}
-
-typedef signed short (*test_type)(signed short, signed short);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void * args_dbl[3];
-  ffi_type * cl_arg_types[3];
-  ffi_arg res_call;
-  unsigned short a, b, res_closure;
-
-  a = 2;
-  b = 32765;
-
-  args_dbl[0] = &a;
-  args_dbl[1] = &b;
-  args_dbl[2] = NULL;
-
-  cl_arg_types[0] = &ffi_type_sshort;
-  cl_arg_types[1] = &ffi_type_sshort;
-  cl_arg_types[2] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
-		     &ffi_type_sshort, cl_arg_types) == FFI_OK);
-
-  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
-  /* { dg-output "2 32765: 32767" } */
-  printf("res: %d\n", (unsigned short)res_call);
-  /* { dg-output "\nres: 32767" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
-
-  res_closure = (*((test_type)code))(2, 32765);
-  /* { dg-output "\n2 32765: 32767" } */
-  printf("res: %d\n", res_closure);
-  /* { dg-output "\nres: 32767" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_multi_sshortchar.c b/testsuite/libffi.closures/cls_multi_sshortchar.c
deleted file mode 100644
index 1c3aeb5..0000000
--- a/testsuite/libffi.closures/cls_multi_sshortchar.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check passing of multiple signed short/char values.
-   Limitations:	none.
-   PR:		PR13221.
-   Originator:	<andreast@gcc.gnu.org> 20031129  */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-signed short test_func_fn(signed char a1, signed short a2,
-			  signed char a3, signed short a4)
-{
-  signed short result;
-
-  result = a1 + a2 + a3 + a4;
-
-  printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
-
-  return result;
-
-}
-
-static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
-			 void *data __UNUSED__)
-{
-  signed char a1, a3;
-  signed short a2, a4;
-
-  a1 = *(signed char *)avals[0];
-  a2 = *(signed short *)avals[1];
-  a3 = *(signed char *)avals[2];
-  a4 = *(signed short *)avals[3];
-
-  *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
-
-}
-
-typedef signed short (*test_type)(signed char, signed short,
-				  signed char, signed short);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void * args_dbl[5];
-  ffi_type * cl_arg_types[5];
-  ffi_arg res_call;
-  signed char a, c;
-  signed short b, d, res_closure;
-
-  a = 1;
-  b = 32765;
-  c = 127;
-  d = -128;
-
-  args_dbl[0] = &a;
-  args_dbl[1] = &b;
-  args_dbl[2] = &c;
-  args_dbl[3] = &d;
-  args_dbl[4] = NULL;
-
-  cl_arg_types[0] = &ffi_type_schar;
-  cl_arg_types[1] = &ffi_type_sshort;
-  cl_arg_types[2] = &ffi_type_schar;
-  cl_arg_types[3] = &ffi_type_sshort;
-  cl_arg_types[4] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
-		     &ffi_type_sshort, cl_arg_types) == FFI_OK);
-
-  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
-  /* { dg-output "1 32765 127 -128: 32765" } */
-  printf("res: %d\n", (signed short)res_call);
-  /* { dg-output "\nres: 32765" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
-
-  res_closure = (*((test_type)code))(1, 32765, 127, -128);
-  /* { dg-output "\n1 32765 127 -128: 32765" } */
-  printf("res: %d\n", res_closure);
-  /* { dg-output "\nres: 32765" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_multi_uchar.c b/testsuite/libffi.closures/cls_multi_uchar.c
deleted file mode 100644
index 009c02c..0000000
--- a/testsuite/libffi.closures/cls_multi_uchar.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check passing of multiple unsigned char values.
-   Limitations:	none.
-   PR:		PR13221.
-   Originator:	<andreast@gcc.gnu.org> 20031129  */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-unsigned char test_func_fn(unsigned char a1, unsigned char a2,
-			   unsigned char a3, unsigned char a4)
-{
-  unsigned char result;
-
-  result = a1 + a2 + a3 + a4;
-
-  printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
-
-  return result;
-
-}
-
-static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
-			 void *data __UNUSED__)
-{
-  unsigned char a1, a2, a3, a4;
-
-  a1 = *(unsigned char *)avals[0];
-  a2 = *(unsigned char *)avals[1];
-  a3 = *(unsigned char *)avals[2];
-  a4 = *(unsigned char *)avals[3];
-
-  *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
-
-}
-
-typedef unsigned char (*test_type)(unsigned char, unsigned char,
-				   unsigned char, unsigned char);
-
-void test_func(ffi_cif *cif __UNUSED__, void *rval __UNUSED__, void **avals,
-	       void *data __UNUSED__)
-{
-  printf("%d %d %d %d\n", *(unsigned char *)avals[0],
-	 *(unsigned char *)avals[1], *(unsigned char *)avals[2],
-	 *(unsigned char *)avals[3]);
-}
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void * args_dbl[5];
-  ffi_type * cl_arg_types[5];
-  ffi_arg res_call;
-  unsigned char a, b, c, d, res_closure;
-
-  a = 1;
-  b = 2;
-  c = 127;
-  d = 125;
-
-  args_dbl[0] = &a;
-  args_dbl[1] = &b;
-  args_dbl[2] = &c;
-  args_dbl[3] = &d;
-  args_dbl[4] = NULL;
-
-  cl_arg_types[0] = &ffi_type_uchar;
-  cl_arg_types[1] = &ffi_type_uchar;
-  cl_arg_types[2] = &ffi_type_uchar;
-  cl_arg_types[3] = &ffi_type_uchar;
-  cl_arg_types[4] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
-		     &ffi_type_uchar, cl_arg_types) == FFI_OK);
-
-  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
-  /* { dg-output "1 2 127 125: 255" } */
-  printf("res: %d\n", (unsigned char)res_call);
-  /* { dg-output "\nres: 255" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
-
-  res_closure = (*((test_type)code))(1, 2, 127, 125);
-  /* { dg-output "\n1 2 127 125: 255" } */
-  printf("res: %d\n", res_closure);
-  /* { dg-output "\nres: 255" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_multi_ushort.c b/testsuite/libffi.closures/cls_multi_ushort.c
deleted file mode 100644
index dd10ca7..0000000
--- a/testsuite/libffi.closures/cls_multi_ushort.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check passing of multiple unsigned short values.
-   Limitations:	none.
-   PR:		PR13221.
-   Originator:	<andreast@gcc.gnu.org> 20031129  */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-unsigned short test_func_fn(unsigned short a1, unsigned short a2)
-{
-  unsigned short result;
-
-  result = a1 + a2;
-
-  printf("%d %d: %d\n", a1, a2, result);
-
-  return result;
-
-}
-
-static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
-			 void *data __UNUSED__)
-{
-  unsigned short a1, a2;
-
-  a1 = *(unsigned short *)avals[0];
-  a2 = *(unsigned short *)avals[1];
-
-  *(ffi_arg *)rval = test_func_fn(a1, a2);
-
-}
-
-typedef unsigned short (*test_type)(unsigned short, unsigned short);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void * args_dbl[3];
-  ffi_type * cl_arg_types[3];
-  ffi_arg res_call;
-  unsigned short a, b, res_closure;
-
-  a = 2;
-  b = 32765;
-
-  args_dbl[0] = &a;
-  args_dbl[1] = &b;
-  args_dbl[2] = NULL;
-
-  cl_arg_types[0] = &ffi_type_ushort;
-  cl_arg_types[1] = &ffi_type_ushort;
-  cl_arg_types[2] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
-		     &ffi_type_ushort, cl_arg_types) == FFI_OK);
-
-  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
-  /* { dg-output "2 32765: 32767" } */
-  printf("res: %d\n", (unsigned short)res_call);
-  /* { dg-output "\nres: 32767" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
-
-  res_closure = (*((test_type)code))(2, 32765);
-  /* { dg-output "\n2 32765: 32767" } */
-  printf("res: %d\n", res_closure);
-  /* { dg-output "\nres: 32767" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_multi_ushortchar.c b/testsuite/libffi.closures/cls_multi_ushortchar.c
deleted file mode 100644
index 2588e97..0000000
--- a/testsuite/libffi.closures/cls_multi_ushortchar.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check passing of multiple unsigned short/char values.
-   Limitations:	none.
-   PR:		PR13221.
-   Originator:	<andreast@gcc.gnu.org> 20031129  */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-unsigned short test_func_fn(unsigned char a1, unsigned short a2,
-			    unsigned char a3, unsigned short a4)
-{
-  unsigned short result;
-
-  result = a1 + a2 + a3 + a4;
-
-  printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
-
-  return result;
-
-}
-
-static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
-			 void *data __UNUSED__)
-{
-  unsigned char a1, a3;
-  unsigned short a2, a4;
-
-  a1 = *(unsigned char *)avals[0];
-  a2 = *(unsigned short *)avals[1];
-  a3 = *(unsigned char *)avals[2];
-  a4 = *(unsigned short *)avals[3];
-
-  *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
-
-}
-
-typedef unsigned short (*test_type)(unsigned char, unsigned short,
-				   unsigned char, unsigned short);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void * args_dbl[5];
-  ffi_type * cl_arg_types[5];
-  ffi_arg res_call;
-  unsigned char a, c;
-  unsigned short b, d, res_closure;
-
-  a = 1;
-  b = 2;
-  c = 127;
-  d = 128;
-
-  args_dbl[0] = &a;
-  args_dbl[1] = &b;
-  args_dbl[2] = &c;
-  args_dbl[3] = &d;
-  args_dbl[4] = NULL;
-
-  cl_arg_types[0] = &ffi_type_uchar;
-  cl_arg_types[1] = &ffi_type_ushort;
-  cl_arg_types[2] = &ffi_type_uchar;
-  cl_arg_types[3] = &ffi_type_ushort;
-  cl_arg_types[4] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
-		     &ffi_type_ushort, cl_arg_types) == FFI_OK);
-
-  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
-  /* { dg-output "1 2 127 128: 258" } */
-  printf("res: %d\n", (unsigned short)res_call);
-  /* { dg-output "\nres: 258" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
-
-  res_closure = (*((test_type)code))(1, 2, 127, 128);
-  /* { dg-output "\n1 2 127 128: 258" } */
-  printf("res: %d\n", res_closure);
-  /* { dg-output "\nres: 258" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_pointer.c b/testsuite/libffi.closures/cls_pointer.c
deleted file mode 100644
index d82a87a..0000000
--- a/testsuite/libffi.closures/cls_pointer.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Check pointer arguments.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin 6/6/2007	*/
-
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
-#include "ffitest.h"
-
-void* cls_pointer_fn(void* a1, void* a2)
-{
-	void*	result	= (void*)((intptr_t)a1 + (intptr_t)a2);
-
-	printf("0x%08x 0x%08x: 0x%08x\n", 
-	       (unsigned int)(uintptr_t) a1,
-               (unsigned int)(uintptr_t) a2,
-               (unsigned int)(uintptr_t) result);
-
-	return result;
-}
-
-static void
-cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp, 
-	       void** args, void* userdata __UNUSED__)
-{
-	void*	a1	= *(void**)(args[0]);
-	void*	a2	= *(void**)(args[1]);
-
-	*(void**)resp = cls_pointer_fn(a1, a2);
-}
-
-int main (void)
-{
-	ffi_cif	cif;
-        void *code;
-	ffi_closure*	pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void*			args[3];
-	/*	ffi_type		cls_pointer_type; */
-	ffi_type*		arg_types[3];
-
-/*	cls_pointer_type.size = sizeof(void*);
-	cls_pointer_type.alignment = 0;
-	cls_pointer_type.type = FFI_TYPE_POINTER;
-	cls_pointer_type.elements = NULL;*/
-
-	void*	arg1	= (void*)0x12345678;
-	void*	arg2	= (void*)0x89abcdef;
-	ffi_arg	res		= 0;
-
-	arg_types[0] = &ffi_type_pointer;
-	arg_types[1] = &ffi_type_pointer;
-	arg_types[2] = NULL;
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
-		arg_types) == FFI_OK);
-
-	args[0] = &arg1;
-	args[1] = &arg2;
-	args[2] = NULL;
-
-	ffi_call(&cif, FFI_FN(cls_pointer_fn), &res, args);
-	/* { dg-output "0x12345678 0x89abcdef: 0x9be02467" } */
-	printf("res: 0x%08x\n", (unsigned int) res);
-	/* { dg-output "\nres: 0x9be02467" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
-
-	res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
-	/* { dg-output "\n0x12345678 0x89abcdef: 0x9be02467" } */
-	printf("res: 0x%08x\n", (unsigned int) res);
-	/* { dg-output "\nres: 0x9be02467" } */
-
-	exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_pointer_stack.c b/testsuite/libffi.closures/cls_pointer_stack.c
deleted file mode 100644
index 1f1d915..0000000
--- a/testsuite/libffi.closures/cls_pointer_stack.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Check pointer arguments across multiple hideous stack frames.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin 6/7/2007	*/
-
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
-#include "ffitest.h"
-
-static	long dummyVar;
-
-long dummy_func(
-	long double a1, char b1,
-	long double a2, char b2,
-	long double a3, char b3,
-	long double a4, char b4)
-{
-	return a1 + b1 + a2 + b2 + a3 + b3 + a4 + b4;
-}
-
-void* cls_pointer_fn2(void* a1, void* a2)
-{
-	long double	trample1	= (intptr_t)a1 + (intptr_t)a2;
-	char		trample2	= ((char*)&a1)[0] + ((char*)&a2)[0];
-	long double	trample3	= (intptr_t)trample1 + (intptr_t)a1;
-	char		trample4	= trample2 + ((char*)&a1)[1];
-	long double	trample5	= (intptr_t)trample3 + (intptr_t)a2;
-	char		trample6	= trample4 + ((char*)&a2)[1];
-	long double	trample7	= (intptr_t)trample5 + (intptr_t)trample1;
-	char		trample8	= trample6 + trample2;
-	void*		result;
-
-	dummyVar	= dummy_func(trample1, trample2, trample3, trample4,
-		trample5, trample6, trample7, trample8);
-
-	result	= (void*)((intptr_t)a1 + (intptr_t)a2);
-
-	printf("0x%08x 0x%08x: 0x%08x\n", 
-	       (unsigned int)(uintptr_t) a1,
-               (unsigned int)(uintptr_t) a2,
-               (unsigned int)(uintptr_t) result);
-
-	return result;
-}
-
-void* cls_pointer_fn1(void* a1, void* a2)
-{
-	long double	trample1	= (intptr_t)a1 + (intptr_t)a2;
-	char		trample2	= ((char*)&a1)[0] + ((char*)&a2)[0];
-	long double	trample3	= (intptr_t)trample1 + (intptr_t)a1;
-	char		trample4	= trample2 + ((char*)&a1)[1];
-	long double	trample5	= (intptr_t)trample3 + (intptr_t)a2;
-	char		trample6	= trample4 + ((char*)&a2)[1];
-	long double	trample7	= (intptr_t)trample5 + (intptr_t)trample1;
-	char		trample8	= trample6 + trample2;
-	void*		result;
-
-	dummyVar	= dummy_func(trample1, trample2, trample3, trample4,
-		trample5, trample6, trample7, trample8);
-
-	result	= (void*)((intptr_t)a1 + (intptr_t)a2);
-
-	printf("0x%08x 0x%08x: 0x%08x\n",
-               (unsigned int)(intptr_t) a1,
-               (unsigned int)(intptr_t) a2,
-               (unsigned int)(intptr_t) result);
-
-	result	= cls_pointer_fn2(result, a1);
-
-	return result;
-}
-
-static void
-cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp, 
-	       void** args, void* userdata __UNUSED__)
-{
-	void*	a1	= *(void**)(args[0]);
-	void*	a2	= *(void**)(args[1]);
-
-	long double	trample1	= (intptr_t)a1 + (intptr_t)a2;
-	char		trample2	= ((char*)&a1)[0] + ((char*)&a2)[0];
-	long double	trample3	= (intptr_t)trample1 + (intptr_t)a1;
-	char		trample4	= trample2 + ((char*)&a1)[1];
-	long double	trample5	= (intptr_t)trample3 + (intptr_t)a2;
-	char		trample6	= trample4 + ((char*)&a2)[1];
-	long double	trample7	= (intptr_t)trample5 + (intptr_t)trample1;
-	char		trample8	= trample6 + trample2;
-
-	dummyVar	= dummy_func(trample1, trample2, trample3, trample4,
-		trample5, trample6, trample7, trample8);
-
-	*(void**)resp = cls_pointer_fn1(a1, a2);
-}
-
-int main (void)
-{
-	ffi_cif	cif;
-        void *code;
-	ffi_closure*	pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void*			args[3];
-	/*	ffi_type		cls_pointer_type; */
-	ffi_type*		arg_types[3];
-
-/*	cls_pointer_type.size = sizeof(void*);
-	cls_pointer_type.alignment = 0;
-	cls_pointer_type.type = FFI_TYPE_POINTER;
-	cls_pointer_type.elements = NULL;*/
-
-	void*	arg1	= (void*)0x01234567;
-	void*	arg2	= (void*)0x89abcdef;
-	ffi_arg	res		= 0;
-
-	arg_types[0] = &ffi_type_pointer;
-	arg_types[1] = &ffi_type_pointer;
-	arg_types[2] = NULL;
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
-		arg_types) == FFI_OK);
-
-	args[0] = &arg1;
-	args[1] = &arg2;
-	args[2] = NULL;
-
-	printf("\n");
-	ffi_call(&cif, FFI_FN(cls_pointer_fn1), &res, args);
-
-	printf("res: 0x%08x\n", (unsigned int) res);
-	/* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */
-	/* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */
-	/* { dg-output "\nres: 0x8bf258bd" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
-
-	res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
-
-	printf("res: 0x%08x\n", (unsigned int) res);
-	/* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */
-	/* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */
-	/* { dg-output "\nres: 0x8bf258bd" } */
-
-	exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_schar.c b/testsuite/libffi.closures/cls_schar.c
deleted file mode 100644
index 82986b1..0000000
--- a/testsuite/libffi.closures/cls_schar.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value schar.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20031108	 */
-
-
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void cls_ret_schar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			     void* userdata __UNUSED__)
-{
-  *(ffi_arg*)resp = *(signed char *)args[0];
-  printf("%d: %d\n",*(signed char *)args[0],
-	 (int)*(ffi_arg *)(resp));
-}
-typedef signed char (*cls_ret_schar)(signed char);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[2];
-  signed char res;
-
-  cl_arg_types[0] = &ffi_type_schar;
-  cl_arg_types[1] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &ffi_type_schar, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_schar_fn, NULL, code)  == FFI_OK);
-
-  res = (*((cls_ret_schar)code))(127);
-  /* { dg-output "127: 127" } */
-  printf("res: %d\n", res);
-  /* { dg-output "\nres: 127" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_sint.c b/testsuite/libffi.closures/cls_sint.c
deleted file mode 100644
index c7e13b7..0000000
--- a/testsuite/libffi.closures/cls_sint.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value sint32.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20031108	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void cls_ret_sint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			    void* userdata __UNUSED__)
-{
-  *(ffi_arg*)resp = *(signed int *)args[0];
-  printf("%d: %d\n",*(signed int *)args[0],
-	 (int)*(ffi_arg *)(resp));
-}
-typedef signed int (*cls_ret_sint)(signed int);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[2];
-  signed int res;
-
-  cl_arg_types[0] = &ffi_type_sint;
-  cl_arg_types[1] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sint_fn, NULL, code)  == FFI_OK);
-
-  res = (*((cls_ret_sint)code))(65534);
-  /* { dg-output "65534: 65534" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 65534" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_sshort.c b/testsuite/libffi.closures/cls_sshort.c
deleted file mode 100644
index 846d57e..0000000
--- a/testsuite/libffi.closures/cls_sshort.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value sshort.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20031108	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void cls_ret_sshort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			      void* userdata __UNUSED__)
-{
-  *(ffi_arg*)resp = *(signed short *)args[0];
-  printf("%d: %d\n",*(signed short *)args[0],
-	 (int)*(ffi_arg *)(resp));
-}
-typedef signed short (*cls_ret_sshort)(signed short);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[2];
-  signed short res;
-
-  cl_arg_types[0] = &ffi_type_sshort;
-  cl_arg_types[1] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &ffi_type_sshort, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sshort_fn, NULL, code)  == FFI_OK);
-
-  res = (*((cls_ret_sshort)code))(255);
-  /* { dg-output "255: 255" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 255" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_struct_va1.c b/testsuite/libffi.closures/cls_struct_va1.c
deleted file mode 100644
index 6d1fdae..0000000
--- a/testsuite/libffi.closures/cls_struct_va1.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Test doubles passed in variable argument lists.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin 6/6/2007	 */
-
-/* { dg-do run } */
-/* { dg-output "" { xfail avr32*-*-* } } */
-#include "ffitest.h"
-
-struct small_tag
-{
-  unsigned char a;
-  unsigned char b;
-};
-
-struct large_tag
-{
-  unsigned a;
-  unsigned b;
-  unsigned c;
-  unsigned d;
-  unsigned e;
-};
-
-static void
-test_fn (ffi_cif* cif __UNUSED__, void* resp,
-	 void** args, void* userdata __UNUSED__)
-{
-  int n = *(int*)args[0];
-  struct small_tag s1 = * (struct small_tag *) args[1];
-  struct large_tag l1 = * (struct large_tag *) args[2];
-  struct small_tag s2 = * (struct small_tag *) args[3];
-
-  printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b,
-	  l1.a, l1.b, l1.c, l1.d, l1.e,
-	  s2.a, s2.b);
-  * (ffi_arg*) resp = 42;
-}
-
-int
-main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc (sizeof (ffi_closure), &code);
-  ffi_type* arg_types[5];
-
-  ffi_arg res = 0;
-
-  ffi_type s_type;
-  ffi_type *s_type_elements[3];
-
-  ffi_type l_type;
-  ffi_type *l_type_elements[6];
-
-  struct small_tag s1;
-  struct small_tag s2;
-  struct large_tag l1;
-
-  int si;
-
-  s_type.size = 0;
-  s_type.alignment = 0;
-  s_type.type = FFI_TYPE_STRUCT;
-  s_type.elements = s_type_elements;
-
-  s_type_elements[0] = &ffi_type_uchar;
-  s_type_elements[1] = &ffi_type_uchar;
-  s_type_elements[2] = NULL;
-
-  l_type.size = 0;
-  l_type.alignment = 0;
-  l_type.type = FFI_TYPE_STRUCT;
-  l_type.elements = l_type_elements;
-
-  l_type_elements[0] = &ffi_type_uint;
-  l_type_elements[1] = &ffi_type_uint;
-  l_type_elements[2] = &ffi_type_uint;
-  l_type_elements[3] = &ffi_type_uint;
-  l_type_elements[4] = &ffi_type_uint;
-  l_type_elements[5] = NULL;
-
-  arg_types[0] = &ffi_type_sint;
-  arg_types[1] = &s_type;
-  arg_types[2] = &l_type;
-  arg_types[3] = &s_type;
-  arg_types[4] = NULL;
-
-  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint,
-			 arg_types) == FFI_OK);
-
-  si = 4;
-  s1.a = 5;
-  s1.b = 6;
-
-  s2.a = 20;
-  s2.b = 21;
-
-  l1.a = 10;
-  l1.b = 11;
-  l1.c = 12;
-  l1.d = 13;
-  l1.e = 14;
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, test_fn, NULL, code) == FFI_OK);
-
-  res = ((int (*)(int, ...))(code))(si, s1, l1, s2);
-  /* { dg-output "4 5 6 10 11 12 13 14 20 21" } */
-  printf("res: %d\n", (int) res);
-  /* { dg-output "\nres: 42" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_uchar.c b/testsuite/libffi.closures/cls_uchar.c
deleted file mode 100644
index c1317e7..0000000
--- a/testsuite/libffi.closures/cls_uchar.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value uchar.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void cls_ret_uchar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			     void* userdata __UNUSED__)
-{
-  *(ffi_arg*)resp = *(unsigned char *)args[0];
-  printf("%d: %d\n",*(unsigned char *)args[0],
-	 (int)*(ffi_arg *)(resp));
-}
-typedef unsigned char (*cls_ret_uchar)(unsigned char);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[2];
-  unsigned char res;
-
-  cl_arg_types[0] = &ffi_type_uchar;
-  cl_arg_types[1] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &ffi_type_uchar, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uchar_fn, NULL, code)  == FFI_OK);
-
-  res = (*((cls_ret_uchar)code))(127);
-  /* { dg-output "127: 127" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 127" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_uchar_va.c b/testsuite/libffi.closures/cls_uchar_va.c
deleted file mode 100644
index 6491c5b..0000000
--- a/testsuite/libffi.closures/cls_uchar_va.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Test anonymous unsigned char argument.
-   Limitations:	none.
-   PR:		none.
-   Originator:	ARM Ltd. */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef unsigned char T;
-
-static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			 void* userdata __UNUSED__)
- {
-   *(ffi_arg *)resp = *(T *)args[0];
-
-   printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]);
- }
-
-typedef T (*cls_ret_T)(T, ...);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[3];
-  T res;
-
-  cl_arg_types[0] = &ffi_type_uchar;
-  cl_arg_types[1] = &ffi_type_uchar;
-  cl_arg_types[2] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
-			 &ffi_type_uchar, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
-  res = ((((cls_ret_T)code)(67, 4)));
-  /* { dg-output "67: 67 4" } */
-  printf("res: %d\n", res);
-  /* { dg-output "\nres: 67" } */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_uint.c b/testsuite/libffi.closures/cls_uint.c
deleted file mode 100644
index 885cff5..0000000
--- a/testsuite/libffi.closures/cls_uint.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value uint.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void cls_ret_uint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			    void* userdata __UNUSED__)
-{
-  *(ffi_arg *)resp = *(unsigned int *)args[0];
-
-  printf("%d: %d\n",*(unsigned int *)args[0],
-	 (int)*(ffi_arg *)(resp));
-}
-typedef unsigned int (*cls_ret_uint)(unsigned int);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[2];
-  unsigned int res;
-
-  cl_arg_types[0] = &ffi_type_uint;
-  cl_arg_types[1] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &ffi_type_uint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uint_fn, NULL, code)  == FFI_OK);
-
-  res = (*((cls_ret_uint)code))(2147483647);
-  /* { dg-output "2147483647: 2147483647" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 2147483647" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_uint_va.c b/testsuite/libffi.closures/cls_uint_va.c
deleted file mode 100644
index b04cfd1..0000000
--- a/testsuite/libffi.closures/cls_uint_va.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Test anonymous unsigned int argument.
-   Limitations:	none.
-   PR:		none.
-   Originator:	ARM Ltd. */
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-typedef unsigned int T;
-
-static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			 void* userdata __UNUSED__)
- {
-   *(ffi_arg *)resp = *(T *)args[0];
-
-   printf("%d: %d %d\n", (int)*(ffi_arg *)resp, *(T *)args[0], *(T *)args[1]);
- }
-
-typedef T (*cls_ret_T)(T, ...);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[3];
-  T res;
-
-  cl_arg_types[0] = &ffi_type_uint;
-  cl_arg_types[1] = &ffi_type_uint;
-  cl_arg_types[2] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
-			 &ffi_type_uint, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
-  res = ((((cls_ret_T)code)(67, 4)));
-  /* { dg-output "67: 67 4" } */
-  printf("res: %d\n", res);
-  /* { dg-output "\nres: 67" } */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_ulong_va.c b/testsuite/libffi.closures/cls_ulong_va.c
deleted file mode 100644
index 0315082..0000000
--- a/testsuite/libffi.closures/cls_ulong_va.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Test anonymous unsigned long argument.
-   Limitations:	none.
-   PR:		none.
-   Originator:	ARM Ltd. */
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-typedef unsigned long T;
-
-static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			 void* userdata __UNUSED__)
- {
-   *(T *)resp = *(T *)args[0];
-
-   printf("%ld: %ld %ld\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
- }
-
-typedef T (*cls_ret_T)(T, ...);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[3];
-  T res;
-
-  cl_arg_types[0] = &ffi_type_ulong;
-  cl_arg_types[1] = &ffi_type_ulong;
-  cl_arg_types[2] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
-			 &ffi_type_ulong, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
-  res = ((((cls_ret_T)code)(67, 4)));
-  /* { dg-output "67: 67 4" } */
-  printf("res: %ld\n", res);
-  /* { dg-output "\nres: 67" } */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_ulonglong.c b/testsuite/libffi.closures/cls_ulonglong.c
deleted file mode 100644
index 62f2cae..0000000
--- a/testsuite/libffi.closures/cls_ulonglong.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value long long.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
-#include "ffitest.h"
-
-static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp,
-				 void** args, void* userdata __UNUSED__)
-{
-  *(unsigned long long *)resp= 0xfffffffffffffffLL ^ *(unsigned long long *)args[0];
-
-  printf("%" PRIuLL ": %" PRIuLL "\n",*(unsigned long long *)args[0],
-	 *(unsigned long long *)(resp));
-}
-typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[2];
-  unsigned long long res;
-
-  cl_arg_types[0] = &ffi_type_uint64;
-  cl_arg_types[1] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &ffi_type_uint64, cl_arg_types) == FFI_OK);
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ulonglong_fn, NULL, code)  == FFI_OK);
-  res = (*((cls_ret_ulonglong)code))(214LL);
-  /* { dg-output "214: 1152921504606846761" } */
-  printf("res: %" PRIdLL "\n", res);
-  /* { dg-output "\nres: 1152921504606846761" } */
-
-  res = (*((cls_ret_ulonglong)code))(9223372035854775808LL);
-  /* { dg-output "\n9223372035854775808: 8070450533247928831" } */
-  printf("res: %" PRIdLL "\n", res);
-  /* { dg-output "\nres: 8070450533247928831" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_ushort.c b/testsuite/libffi.closures/cls_ushort.c
deleted file mode 100644
index a00100e..0000000
--- a/testsuite/libffi.closures/cls_ushort.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value ushort.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-static void cls_ret_ushort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			      void* userdata __UNUSED__)
-{
-  *(ffi_arg*)resp = *(unsigned short *)args[0];
-
-  printf("%d: %d\n",*(unsigned short *)args[0],
-	 (int)*(ffi_arg *)(resp));
-}
-typedef unsigned short (*cls_ret_ushort)(unsigned short);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[2];
-  unsigned short res;
-
-  cl_arg_types[0] = &ffi_type_ushort;
-  cl_arg_types[1] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &ffi_type_ushort, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ushort_fn, NULL, code)  == FFI_OK);
-
-  res = (*((cls_ret_ushort)code))(65535);
-  /* { dg-output "65535: 65535" } */
-  printf("res: %d\n",res);
-  /* { dg-output "\nres: 65535" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/cls_ushort_va.c b/testsuite/libffi.closures/cls_ushort_va.c
deleted file mode 100644
index 37aa106..0000000
--- a/testsuite/libffi.closures/cls_ushort_va.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Test anonymous unsigned short argument.
-   Limitations:	none.
-   PR:		none.
-   Originator:	ARM Ltd. */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef unsigned short T;
-
-static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			 void* userdata __UNUSED__)
- {
-   *(ffi_arg *)resp = *(T *)args[0];
-
-   printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]);
- }
-
-typedef T (*cls_ret_T)(T, ...);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[3];
-  T res;
-
-  cl_arg_types[0] = &ffi_type_ushort;
-  cl_arg_types[1] = &ffi_type_ushort;
-  cl_arg_types[2] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
-			 &ffi_type_ushort, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
-  res = ((((cls_ret_T)code)(67, 4)));
-  /* { dg-output "67: 67 4" } */
-  printf("res: %d\n", res);
-  /* { dg-output "\nres: 67" } */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/err_bad_abi.c b/testsuite/libffi.closures/err_bad_abi.c
deleted file mode 100644
index f5a7317..0000000
--- a/testsuite/libffi.closures/err_bad_abi.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Area:		ffi_prep_cif, ffi_prep_closure
-   Purpose:		Test error return for bad ABIs.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin 6/6/2007	 */
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-static void
-dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, 
-	 void** args __UNUSED__, void* userdata __UNUSED__)
-{}
-
-int main (void)
-{
-	ffi_cif cif;
-        void *code;
-	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	ffi_type* arg_types[1];
-
-	arg_types[0] = NULL;
-
-	CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void,
-		arg_types) == FFI_BAD_ABI);
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void,
-		arg_types) == FFI_OK);
-
-	cif.abi= 255;
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI);
-
-	exit(0);
-}
diff --git a/testsuite/libffi.closures/ffitest.h b/testsuite/libffi.closures/ffitest.h
deleted file mode 100644
index cfce1ad..0000000
--- a/testsuite/libffi.closures/ffitest.h
+++ /dev/null
@@ -1,138 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <ffi.h>
-#include "fficonfig.h"
-
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#if defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#define MAX_ARGS 256
-
-#define CHECK(x) (void)(!(x) ? (abort(), 1) : 0)
-
-/* Define macros so that compilers other than gcc can run the tests.  */
-#undef __UNUSED__
-#if defined(__GNUC__)
-#define __UNUSED__ __attribute__((__unused__))
-#define __STDCALL__ __attribute__((stdcall))
-#define __THISCALL__ __attribute__((thiscall))
-#define __FASTCALL__ __attribute__((fastcall))
-#define __MSABI__ __attribute__((ms_abi))
-#else
-#define __UNUSED__
-#define __STDCALL__ __stdcall
-#define __THISCALL__ __thiscall
-#define __FASTCALL__ __fastcall
-#endif
-
-#ifndef ABI_NUM
-#define ABI_NUM FFI_DEFAULT_ABI
-#define ABI_ATTR
-#endif
-
-/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
-   file open.  */
-#ifdef HAVE_MMAP_ANON
-# undef HAVE_MMAP_DEV_ZERO
-
-# include <sys/mman.h>
-# ifndef MAP_FAILED
-#  define MAP_FAILED -1
-# endif
-# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
-#  define MAP_ANONYMOUS MAP_ANON
-# endif
-# define USING_MMAP
-
-#endif
-
-#ifdef HAVE_MMAP_DEV_ZERO
-
-# include <sys/mman.h>
-# ifndef MAP_FAILED
-#  define MAP_FAILED -1
-# endif
-# define USING_MMAP
-
-#endif
-
-/* MinGW kludge.  */
-#if defined(_WIN64) | defined(_WIN32)
-#define PRIdLL "I64d"
-#define PRIuLL "I64u"
-#else
-#define PRIdLL "lld"
-#define PRIuLL "llu"
-#endif
-
-/* Tru64 UNIX kludge.  */
-#if defined(__alpha__) && defined(__osf__)
-/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit.  */
-#undef PRIdLL
-#define PRIdLL "ld"
-#undef PRIuLL
-#define PRIuLL "lu"
-#define PRId8 "hd"
-#define PRIu8 "hu"
-#define PRId64 "ld"
-#define PRIu64 "lu"
-#define PRIuPTR "lu"
-#endif
-
-/* PA HP-UX kludge.  */
-#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR)
-#define PRIuPTR "lu"
-#endif
-
-/* IRIX kludge.  */
-#if defined(__sgi)
-/* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99
-   compilations.  */
-#define PRId8 "hhd"
-#define PRIu8 "hhu"
-#if (_MIPS_SZLONG == 32)
-#define PRId64 "lld"
-#define PRIu64 "llu"
-#endif
-/* This doesn't match <inttypes.h>, which always has "lld" here, but the
-   arguments are uint64_t, int64_t, which are unsigned long, long for
-   64-bit in <sgidefs.h>.  */
-#if (_MIPS_SZLONG == 64)
-#define PRId64 "ld"
-#define PRIu64 "lu"
-#endif
-/* This doesn't match <inttypes.h>, which has "u" here, but the arguments
-   are uintptr_t, which is always unsigned long.  */
-#define PRIuPTR "lu"
-#endif
-
-/* Solaris < 10 kludge.  */
-#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR)
-#if defined(__arch64__) || defined (__x86_64__)
-#define PRIuPTR "lu"
-#else
-#define PRIuPTR "u"
-#endif
-#endif
-
-/* MSVC kludge.  */
-#if defined _MSC_VER
-#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
-#define PRIuPTR "lu"
-#define PRIu8 "u"
-#define PRId8 "d"
-#define PRIu64 "I64u"
-#define PRId64 "I64d"
-#endif
-#endif
-
-#ifndef PRIuPTR
-#define PRIuPTR "u"
-#endif
diff --git a/testsuite/libffi.closures/huge_struct.c b/testsuite/libffi.closures/huge_struct.c
deleted file mode 100644
index 1915c3f..0000000
--- a/testsuite/libffi.closures/huge_struct.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*	Area:			ffi_call, closure_call
-	Purpose:		Check large structure returns.
-	Limitations:	none.
-	PR:				none.
-	Originator:		Blake Chaffin	6/18/2007
-*/
-
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
-/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
-/* { dg-options -Wformat=0 { target moxie*-*-elf or1k-*-* } } */
-
-#include "ffitest.h"
-
-typedef	struct BigStruct{
-	uint8_t		a;
-	int8_t		b;
-	uint16_t	c;
-	int16_t		d;
-	uint32_t	e;
-	int32_t		f;
-	uint64_t	g;
-	int64_t		h;
-	float		i;
-	double		j;
-	long double	k;
-	char*		l;
-	uint8_t		m;
-	int8_t		n;
-	uint16_t	o;
-	int16_t		p;
-	uint32_t	q;
-	int32_t		r;
-	uint64_t	s;
-	int64_t		t;
-	float		u;
-	double		v;
-	long double	w;
-	char*		x;
-	uint8_t		y;
-	int8_t		z;
-	uint16_t	aa;
-	int16_t		bb;
-	uint32_t	cc;
-	int32_t		dd;
-	uint64_t	ee;
-	int64_t		ff;
-	float		gg;
-	double		hh;
-	long double	ii;
-	char*		jj;
-	uint8_t		kk;
-	int8_t		ll;
-	uint16_t	mm;
-	int16_t		nn;
-	uint32_t	oo;
-	int32_t		pp;
-	uint64_t	qq;
-	int64_t		rr;
-	float		ss;
-	double		tt;
-	long double	uu;
-	char*		vv;
-	uint8_t		ww;
-	int8_t		xx;
-} BigStruct;
-
-BigStruct
-test_large_fn(
-	uint8_t		ui8_1,
-	int8_t		si8_1,
-	uint16_t	ui16_1,
-	int16_t		si16_1,
-	uint32_t	ui32_1,
-	int32_t		si32_1,
-	uint64_t	ui64_1,
-	int64_t		si64_1,
-	float		f_1,
-	double		d_1,
-	long double	ld_1,
-	char*		p_1,
-	uint8_t		ui8_2,
-	int8_t		si8_2,
-	uint16_t	ui16_2,
-	int16_t		si16_2,
-	uint32_t	ui32_2,
-	int32_t		si32_2,
-	uint64_t	ui64_2,
-	int64_t		si64_2,
-	float		f_2,
-	double		d_2,
-	long double	ld_2,
-	char*		p_2,
-	uint8_t		ui8_3,
-	int8_t		si8_3,
-	uint16_t	ui16_3,
-	int16_t		si16_3,
-	uint32_t	ui32_3,
-	int32_t		si32_3,
-	uint64_t	ui64_3,
-	int64_t		si64_3,
-	float		f_3,
-	double		d_3,
-	long double	ld_3,
-	char*		p_3,
-	uint8_t		ui8_4,
-	int8_t		si8_4,
-	uint16_t	ui16_4,
-	int16_t		si16_4,
-	uint32_t	ui32_4,
-	int32_t		si32_4,
-	uint64_t	ui64_4,
-	int64_t		si64_4,
-	float		f_4,
-	double		d_4,
-	long double	ld_4,
-	char*		p_4,
-	uint8_t		ui8_5,
-	int8_t		si8_5)
-{
-	BigStruct	retVal	= {
-		ui8_1 + 1, si8_1 + 1, ui16_1 + 1, si16_1 + 1, ui32_1 + 1, si32_1 + 1,
-			ui64_1 + 1, si64_1 + 1, f_1 + 1, d_1 + 1, ld_1 + 1, (char*)((intptr_t)p_1 + 1), 
-		ui8_2 + 2, si8_2 + 2, ui16_2 + 2, si16_2 + 2, ui32_2 + 2, si32_2 + 2,
-			ui64_2 + 2, si64_2 + 2, f_2 + 2, d_2 + 2, ld_2 + 2, (char*)((intptr_t)p_2 + 2), 
-		ui8_3 + 3, si8_3 + 3, ui16_3 + 3, si16_3 + 3, ui32_3 + 3, si32_3 + 3,
-			ui64_3 + 3, si64_3 + 3, f_3 + 3, d_3 + 3, ld_3 + 3, (char*)((intptr_t)p_3 + 3), 
-		ui8_4 + 4, si8_4 + 4, ui16_4 + 4, si16_4 + 4, ui32_4 + 4, si32_4 + 4,
-			ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((intptr_t)p_4 + 4), 
-		ui8_5 + 5, si8_5 + 5};
-
-	printf("%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 ": "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
-	       ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, (unsigned long)p_1,
-		ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, (unsigned long)p_2,
-		ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, (unsigned long)p_3,
-		ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, (unsigned long)p_4, ui8_5, si8_5,
-		retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
-	       retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
-		retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
-	       retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
-		retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
-	       retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
-		retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
-	       retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
-
-	return	retVal;
-}
-
-static void
-cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
-{
-	uint8_t		ui8_1	= *(uint8_t*)args[0];
-	int8_t		si8_1	= *(int8_t*)args[1];
-	uint16_t	ui16_1	= *(uint16_t*)args[2];
-	int16_t		si16_1	= *(int16_t*)args[3];
-	uint32_t	ui32_1	= *(uint32_t*)args[4];
-	int32_t		si32_1	= *(int32_t*)args[5];
-	uint64_t	ui64_1	= *(uint64_t*)args[6];
-	int64_t		si64_1	= *(int64_t*)args[7];
-	float		f_1		= *(float*)args[8];
-	double		d_1		= *(double*)args[9];
-	long double	ld_1	= *(long double*)args[10];
-	char*		p_1		= *(char**)args[11];
-	uint8_t		ui8_2	= *(uint8_t*)args[12];
-	int8_t		si8_2	= *(int8_t*)args[13];
-	uint16_t	ui16_2	= *(uint16_t*)args[14];
-	int16_t		si16_2	= *(int16_t*)args[15];
-	uint32_t	ui32_2	= *(uint32_t*)args[16];
-	int32_t		si32_2	= *(int32_t*)args[17];
-	uint64_t	ui64_2	= *(uint64_t*)args[18];
-	int64_t		si64_2	= *(int64_t*)args[19];
-	float		f_2		= *(float*)args[20];
-	double		d_2		= *(double*)args[21];
-	long double	ld_2	= *(long double*)args[22];
-	char*		p_2		= *(char**)args[23];
-	uint8_t		ui8_3	= *(uint8_t*)args[24];
-	int8_t		si8_3	= *(int8_t*)args[25];
-	uint16_t	ui16_3	= *(uint16_t*)args[26];
-	int16_t		si16_3	= *(int16_t*)args[27];
-	uint32_t	ui32_3	= *(uint32_t*)args[28];
-	int32_t		si32_3	= *(int32_t*)args[29];
-	uint64_t	ui64_3	= *(uint64_t*)args[30];
-	int64_t		si64_3	= *(int64_t*)args[31];
-	float		f_3		= *(float*)args[32];
-	double		d_3		= *(double*)args[33];
-	long double	ld_3	= *(long double*)args[34];
-	char*		p_3		= *(char**)args[35];
-	uint8_t		ui8_4	= *(uint8_t*)args[36];
-	int8_t		si8_4	= *(int8_t*)args[37];
-	uint16_t	ui16_4	= *(uint16_t*)args[38];
-	int16_t		si16_4	= *(int16_t*)args[39];
-	uint32_t	ui32_4	= *(uint32_t*)args[40];
-	int32_t		si32_4	= *(int32_t*)args[41];
-	uint64_t	ui64_4	= *(uint64_t*)args[42];
-	int64_t		si64_4	= *(int64_t*)args[43];
-	float		f_4		= *(float*)args[44];
-	double		d_4		= *(double*)args[45];
-	long double	ld_4	= *(long double*)args[46];
-	char*		p_4		= *(char**)args[47];
-	uint8_t		ui8_5	= *(uint8_t*)args[48];
-	int8_t		si8_5	= *(int8_t*)args[49];
-
-	*(BigStruct*)resp = test_large_fn(
-		ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, p_1,
-		ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, p_2,
-		ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, p_3,
-		ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, p_4,
-		ui8_5, si8_5);
-}
-
-int
-main(int argc __UNUSED__, const char** argv __UNUSED__)
-{
-        void *code;
-	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-
-	ffi_cif		cif;
-	ffi_type*	argTypes[51];
-	void*		argValues[51];
-
-	ffi_type	ret_struct_type;
-	ffi_type*	st_fields[51];
-	BigStruct	retVal;
-
-	uint8_t		ui8		= 1;
-	int8_t		si8		= 2;
-	uint16_t	ui16	= 3;
-	int16_t		si16	= 4;
-	uint32_t	ui32	= 5;
-	int32_t		si32	= 6;
-	uint64_t	ui64	= 7;
-	int64_t		si64	= 8;
-	float		f		= 9;
-	double		d		= 10;
-	long double	ld		= 11;
-	char*		p		= (char*)0x12345678;
-
-	memset (&retVal, 0, sizeof(retVal));
-
-	ret_struct_type.size = 0;
-	ret_struct_type.alignment = 0;
-	ret_struct_type.type = FFI_TYPE_STRUCT;
-	ret_struct_type.elements = st_fields;
-
-	st_fields[0]	= st_fields[12]	= st_fields[24]	= st_fields[36]	= st_fields[48]	= &ffi_type_uint8;
-	st_fields[1]	= st_fields[13]	= st_fields[25]	= st_fields[37]	= st_fields[49]	= &ffi_type_sint8;
-	st_fields[2]	= st_fields[14]	= st_fields[26]	= st_fields[38]	= &ffi_type_uint16;
-	st_fields[3]	= st_fields[15]	= st_fields[27]	= st_fields[39]	= &ffi_type_sint16;
-	st_fields[4]	= st_fields[16]	= st_fields[28]	= st_fields[40]	= &ffi_type_uint32;
-	st_fields[5]	= st_fields[17]	= st_fields[29]	= st_fields[41]	= &ffi_type_sint32;
-	st_fields[6]	= st_fields[18]	= st_fields[30]	= st_fields[42]	= &ffi_type_uint64;
-	st_fields[7]	= st_fields[19]	= st_fields[31]	= st_fields[43]	= &ffi_type_sint64;
-	st_fields[8]	= st_fields[20]	= st_fields[32]	= st_fields[44]	= &ffi_type_float;
-	st_fields[9]	= st_fields[21]	= st_fields[33]	= st_fields[45]	= &ffi_type_double;
-	st_fields[10]	= st_fields[22]	= st_fields[34]	= st_fields[46]	= &ffi_type_longdouble;
-	st_fields[11]	= st_fields[23]	= st_fields[35]	= st_fields[47]	= &ffi_type_pointer;
-
-	st_fields[50] = NULL;
-
-	argTypes[0]		= argTypes[12]	= argTypes[24]	= argTypes[36]	= argTypes[48]	= &ffi_type_uint8;
-	argValues[0]	= argValues[12]	= argValues[24]	= argValues[36]	= argValues[48]	= &ui8;
-	argTypes[1]		= argTypes[13]	= argTypes[25]	= argTypes[37]	= argTypes[49]	= &ffi_type_sint8;
-	argValues[1]	= argValues[13]	= argValues[25]	= argValues[37]	= argValues[49]	= &si8;
-	argTypes[2]		= argTypes[14]	= argTypes[26]	= argTypes[38]	= &ffi_type_uint16;
-	argValues[2]	= argValues[14]	= argValues[26]	= argValues[38]	= &ui16;
-	argTypes[3]		= argTypes[15]	= argTypes[27]	= argTypes[39]	= &ffi_type_sint16;
-	argValues[3]	= argValues[15]	= argValues[27]	= argValues[39]	= &si16;
-	argTypes[4]		= argTypes[16]	= argTypes[28]	= argTypes[40]	= &ffi_type_uint32;
-	argValues[4]	= argValues[16]	= argValues[28]	= argValues[40]	= &ui32;
-	argTypes[5]		= argTypes[17]	= argTypes[29]	= argTypes[41]	= &ffi_type_sint32;
-	argValues[5]	= argValues[17]	= argValues[29]	= argValues[41]	= &si32;
-	argTypes[6]		= argTypes[18]	= argTypes[30]	= argTypes[42]	= &ffi_type_uint64;
-	argValues[6]	= argValues[18]	= argValues[30]	= argValues[42]	= &ui64;
-	argTypes[7]		= argTypes[19]	= argTypes[31]	= argTypes[43]	= &ffi_type_sint64;
-	argValues[7]	= argValues[19]	= argValues[31]	= argValues[43]	= &si64;
-	argTypes[8]		= argTypes[20]	= argTypes[32]	= argTypes[44]	= &ffi_type_float;
-	argValues[8]	= argValues[20]	= argValues[32]	= argValues[44]	= &f;
-	argTypes[9]		= argTypes[21]	= argTypes[33]	= argTypes[45]	= &ffi_type_double;
-	argValues[9]	= argValues[21]	= argValues[33]	= argValues[45]	= &d;
-	argTypes[10]	= argTypes[22]	= argTypes[34]	= argTypes[46]	= &ffi_type_longdouble;
-	argValues[10]	= argValues[22]	= argValues[34]	= argValues[46]	= &ld;
-	argTypes[11]	= argTypes[23]	= argTypes[35]	= argTypes[47]	= &ffi_type_pointer;
-	argValues[11]	= argValues[23]	= argValues[35]	= argValues[47]	= &p;
-
-	argTypes[50]	= NULL;
-	argValues[50]	= NULL;
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK);
-
-	ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues);
-	/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
-	printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
-		retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
-	       retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
-		retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
-	       retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
-		retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
-	       retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
-		retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
-	       retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
-	/* { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_large_fn, NULL, code) == FFI_OK);
-
-	retVal	= ((BigStruct(*)(
-		uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
-		uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
-		uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
-		uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
-		uint8_t, int8_t))(code))(
-		ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
-		ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
-		ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
-		ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
-		ui8, si8);
-	/* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
-	printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
-		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
-		retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
-	       retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
-		retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
-	       retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
-		retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
-	       retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
-		retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
-	       retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
-	/* { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
-
-    return 0;
-}
diff --git a/testsuite/libffi.closures/nested_struct.c b/testsuite/libffi.closures/nested_struct.c
deleted file mode 100644
index c15e3a0..0000000
--- a/testsuite/libffi.closures/nested_struct.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_16byte1 {
-  double a;
-  float b;
-  int c;
-} cls_struct_16byte1;
-
-typedef struct cls_struct_16byte2 {
-  int ii;
-  double dd;
-  float ff;
-} cls_struct_16byte2;
-
-typedef struct cls_struct_combined {
-  cls_struct_16byte1 d;
-  cls_struct_16byte2 e;
-} cls_struct_combined;
-
-cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
-			    struct cls_struct_16byte2 b1,
-			    struct cls_struct_combined b2)
-{
-  struct cls_struct_combined result;
-
-  result.d.a = b0.a + b1.dd + b2.d.a;
-  result.d.b = b0.b + b1.ff + b2.d.b;
-  result.d.c = b0.c + b1.ii + b2.d.c;
-  result.e.ii = b0.c + b1.ii + b2.e.ii;
-  result.e.dd = b0.a + b1.dd + b2.e.dd;
-  result.e.ff = b0.b + b1.ff + b2.e.ff;
-
-  printf("%g %g %d %d %g %g %g %g %d %d %g %g: %g %g %d %d %g %g\n",
-	 b0.a, b0.b, b0.c,
-	 b1.ii, b1.dd, b1.ff,
-	 b2.d.a, b2.d.b, b2.d.c,
-	 b2.e.ii, b2.e.dd, b2.e.ff,
-	 result.d.a, result.d.b, result.d.c,
-	 result.e.ii, result.e.dd, result.e.ff);
-
-  return result;
-}
-
-static void
-cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		       void* userdata __UNUSED__)
-{
-  struct cls_struct_16byte1 b0;
-  struct cls_struct_16byte2 b1;
-  struct cls_struct_combined b2;
-
-  b0 = *(struct cls_struct_16byte1*)(args[0]);
-  b1 = *(struct cls_struct_16byte2*)(args[1]);
-  b2 = *(struct cls_struct_combined*)(args[2]);
-
-
-  *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[5];
-  ffi_type* cls_struct_fields1[5];
-  ffi_type* cls_struct_fields2[5];
-  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
-  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
-  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
-				      {3, 1.0, 8.0}};
-  struct cls_struct_combined res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_type2.size = 0;
-  cls_struct_type2.alignment = 0;
-  cls_struct_type2.type = FFI_TYPE_STRUCT;
-  cls_struct_type2.elements = cls_struct_fields2;
-
-  cls_struct_fields[0] = &ffi_type_double;
-  cls_struct_fields[1] = &ffi_type_float;
-  cls_struct_fields[2] = &ffi_type_sint;
-  cls_struct_fields[3] = NULL;
-
-  cls_struct_fields1[0] = &ffi_type_sint;
-  cls_struct_fields1[1] = &ffi_type_double;
-  cls_struct_fields1[2] = &ffi_type_float;
-  cls_struct_fields1[3] = NULL;
-
-  cls_struct_fields2[0] = &cls_struct_type;
-  cls_struct_fields2[1] = &cls_struct_type1;
-  cls_struct_fields2[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = &cls_struct_type2;
-  dbl_arg_types[3] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type2,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = &g_dbl;
-  args_dbl[3] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
-  /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
-  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
-  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
-  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
-  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
-  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
-  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
-				     cls_struct_16byte2,
-				     cls_struct_combined))
-	     (code))(e_dbl, f_dbl, g_dbl);
-  /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
-  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
-  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
-  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
-  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
-  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
-  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/nested_struct1.c b/testsuite/libffi.closures/nested_struct1.c
deleted file mode 100644
index 477a6b9..0000000
--- a/testsuite/libffi.closures/nested_struct1.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_16byte1 {
-  double a;
-  float b;
-  int c;
-} cls_struct_16byte1;
-
-typedef struct cls_struct_16byte2 {
-  int ii;
-  double dd;
-  float ff;
-} cls_struct_16byte2;
-
-typedef struct cls_struct_combined {
-  cls_struct_16byte1 d;
-  cls_struct_16byte2 e;
-} cls_struct_combined;
-
-cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
-					   struct cls_struct_16byte2 b1,
-					   struct cls_struct_combined b2,
-					   struct cls_struct_16byte1 b3)
-{
-  struct cls_struct_combined result;
-
-  result.d.a = b0.a + b1.dd + b2.d.a;
-  result.d.b = b0.b + b1.ff + b2.d.b;
-  result.d.c = b0.c + b1.ii + b2.d.c;
-  result.e.ii = b0.c + b1.ii + b2.e.ii;
-  result.e.dd = b0.a + b1.dd + b2.e.dd;
-  result.e.ff = b0.b + b1.ff + b2.e.ff;
-
-  printf("%g %g %d %d %g %g %g %g %d %d %g %g %g %g %d: %g %g %d %d %g %g\n",
-	 b0.a, b0.b, b0.c,
-	 b1.ii, b1.dd, b1.ff,
-	 b2.d.a, b2.d.b, b2.d.c,
-	 b2.e.ii, b2.e.dd, b2.e.ff,
-	 b3.a, b3.b, b3.c,
-	 result.d.a, result.d.b, result.d.c,
-	 result.e.ii, result.e.dd, result.e.ff);
-
-  return result;
-}
-
-static void
-cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		       void* userdata __UNUSED__)
-{
-  struct cls_struct_16byte1 b0;
-  struct cls_struct_16byte2 b1;
-  struct cls_struct_combined b2;
-  struct cls_struct_16byte1 b3;
-
-  b0 = *(struct cls_struct_16byte1*)(args[0]);
-  b1 = *(struct cls_struct_16byte2*)(args[1]);
-  b2 = *(struct cls_struct_combined*)(args[2]);
-  b3 = *(struct cls_struct_16byte1*)(args[3]);
-
-
-  *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2, b3);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[5];
-  ffi_type* cls_struct_fields[5];
-  ffi_type* cls_struct_fields1[5];
-  ffi_type* cls_struct_fields2[5];
-  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
-  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
-  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
-				      {3, 1.0, 8.0}};
-  struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4};
-  struct cls_struct_combined res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_type2.size = 0;
-  cls_struct_type2.alignment = 0;
-  cls_struct_type2.type = FFI_TYPE_STRUCT;
-  cls_struct_type2.elements = cls_struct_fields2;
-
-  cls_struct_fields[0] = &ffi_type_double;
-  cls_struct_fields[1] = &ffi_type_float;
-  cls_struct_fields[2] = &ffi_type_sint;
-  cls_struct_fields[3] = NULL;
-
-  cls_struct_fields1[0] = &ffi_type_sint;
-  cls_struct_fields1[1] = &ffi_type_double;
-  cls_struct_fields1[2] = &ffi_type_float;
-  cls_struct_fields1[3] = NULL;
-
-  cls_struct_fields2[0] = &cls_struct_type;
-  cls_struct_fields2[1] = &cls_struct_type1;
-  cls_struct_fields2[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = &cls_struct_type2;
-  dbl_arg_types[3] = &cls_struct_type;
-  dbl_arg_types[4] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type2,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = &g_dbl;
-  args_dbl[3] = &h_dbl;
-  args_dbl[4] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
-  /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
-  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
-  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
-  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
-  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
-  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
-  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
-				     cls_struct_16byte2,
-				     cls_struct_combined,
-				     cls_struct_16byte1))
-	     (code))(e_dbl, f_dbl, g_dbl, h_dbl);
-  /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
-  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
-  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
-  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
-  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
-  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
-  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
-  /*  CHECK( 1 == 0); */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/nested_struct10.c b/testsuite/libffi.closures/nested_struct10.c
deleted file mode 100644
index 3cf2b44..0000000
--- a/testsuite/libffi.closures/nested_struct10.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-		Sample taken from Alan Modras patch to src/prep_cif.c.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20051010	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct A {
-  unsigned long long a;
-  unsigned char b;
-} A;
-
-typedef struct B {
-  unsigned char y;
-  struct A x;
-  unsigned int z;
-} B;
-
-typedef struct C {
-  unsigned long long d;
-  unsigned char e;
-} C;
-
-static B B_fn(struct A b2, struct B b3, struct C b4)
-{
-  struct B result;
-
-  result.x.a = b2.a + b3.x.a + b3.z + b4.d;
-  result.x.b = b2.b + b3.x.b + b3.y + b4.e;
-  result.y = b2.b + b3.x.b + b4.e;
-  result.z = 0;
-
-  printf("%d %d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
-	 (int)b3.x.a, b3.x.b, b3.y, b3.z, (int)b4.d, b4.e,
-	 (int)result.x.a, result.x.b, result.y);
-
-  return result;
-}
-
-static void
-B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-     void* userdata __UNUSED__)
-{
-  struct A b0;
-  struct B b1;
-  struct C b2;
-
-  b0 = *(struct A*)(args[0]);
-  b1 = *(struct B*)(args[1]);
-  b2 = *(struct C*)(args[2]);
-
-  *(B*)resp = B_fn(b0, b1, b2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[4];
-  ffi_type* cls_struct_fields[3];
-  ffi_type* cls_struct_fields1[4];
-  ffi_type* cls_struct_fields2[3];
-  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
-  ffi_type* dbl_arg_types[4];
-
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = { 99, {12LL , 127}, 255};
-  struct C g_dbl = { 2LL, 9};
-
-  struct B res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_type2.size = 0;
-  cls_struct_type2.alignment = 0;
-  cls_struct_type2.type = FFI_TYPE_STRUCT;
-  cls_struct_type2.elements = cls_struct_fields2;
-
-  cls_struct_fields[0] = &ffi_type_uint64;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = NULL;
-
-  cls_struct_fields1[0] = &ffi_type_uchar;
-  cls_struct_fields1[1] = &cls_struct_type;
-  cls_struct_fields1[2] = &ffi_type_uint;
-  cls_struct_fields1[3] = NULL;
-
-  cls_struct_fields2[0] = &ffi_type_uint64;
-  cls_struct_fields2[1] = &ffi_type_uchar;
-  cls_struct_fields2[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = &cls_struct_type2;
-  dbl_arg_types[3] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = &g_dbl;
-  args_dbl[3] = NULL;
-
-  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 7 12 127 99 255 2 9: 270 242 143" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
-  /* { dg-output "\n1 7 12 127 99 255 2 9: 270 242 143" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/nested_struct11.c b/testsuite/libffi.closures/nested_struct11.c
deleted file mode 100644
index 3510493..0000000
--- a/testsuite/libffi.closures/nested_struct11.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check parameter passing with nested structs
-		of a single type.  This tests the special cases
-		for homogeneous floating-point aggregates in the
-		AArch64 PCS.
-   Limitations:	none.
-   PR:		none.
-   Originator:  ARM Ltd.  */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct A {
-  float a_x;
-  float a_y;
-} A;
-
-typedef struct B {
-  float b_x;
-  float b_y;
-} B;
-
-typedef struct C {
-  A a;
-  B b;
-} C;
-
-static C C_fn (int x, int y, int z, C source, int i, int j, int k)
-{
-  C result;
-  result.a.a_x = source.a.a_x;
-  result.a.a_y = source.a.a_y;
-  result.b.b_x = source.b.b_x;
-  result.b.b_y = source.b.b_y;
-
-  printf ("%d, %d, %d, %d, %d, %d\n", x, y, z, i, j, k);
-
-  printf ("%.1f, %.1f, %.1f, %.1f, "
-	  "%.1f, %.1f, %.1f, %.1f\n",
-	  source.a.a_x, source.a.a_y,
-	  source.b.b_x, source.b.b_y,
-	  result.a.a_x, result.a.a_y,
-	  result.b.b_x, result.b.b_y);
-
-  return result;
-}
-
-int main (void)
-{
-  ffi_cif cif;
-
-  ffi_type* struct_fields_source_a[3];
-  ffi_type* struct_fields_source_b[3];
-  ffi_type* struct_fields_source_c[3];
-  ffi_type* arg_types[8];
-
-  ffi_type struct_type_a, struct_type_b, struct_type_c;
-
-  struct A source_fld_a = {1.0, 2.0};
-  struct B source_fld_b = {4.0, 8.0};
-  int k = 1;
-
-  struct C result;
-  struct C source = {source_fld_a, source_fld_b};
-
-  struct_type_a.size = 0;
-  struct_type_a.alignment = 0;
-  struct_type_a.type = FFI_TYPE_STRUCT;
-  struct_type_a.elements = struct_fields_source_a;
-
-  struct_type_b.size = 0;
-  struct_type_b.alignment = 0;
-  struct_type_b.type = FFI_TYPE_STRUCT;
-  struct_type_b.elements = struct_fields_source_b;
-
-  struct_type_c.size = 0;
-  struct_type_c.alignment = 0;
-  struct_type_c.type = FFI_TYPE_STRUCT;
-  struct_type_c.elements = struct_fields_source_c;
-
-  struct_fields_source_a[0] = &ffi_type_float;
-  struct_fields_source_a[1] = &ffi_type_float;
-  struct_fields_source_a[2] = NULL;
-
-  struct_fields_source_b[0] = &ffi_type_float;
-  struct_fields_source_b[1] = &ffi_type_float;
-  struct_fields_source_b[2] = NULL;
-
-  struct_fields_source_c[0] = &struct_type_a;
-  struct_fields_source_c[1] = &struct_type_b;
-  struct_fields_source_c[2] = NULL;
-
-  arg_types[0] = &ffi_type_sint32;
-  arg_types[1] = &ffi_type_sint32;
-  arg_types[2] = &ffi_type_sint32;
-  arg_types[3] = &struct_type_c;
-  arg_types[4] = &ffi_type_sint32;
-  arg_types[5] = &ffi_type_sint32;
-  arg_types[6] = &ffi_type_sint32;
-  arg_types[7] = NULL;
-
-  void *args[7];
-  args[0] = &k;
-  args[1] = &k;
-  args[2] = &k;
-  args[3] = &source;
-  args[4] = &k;
-  args[5] = &k;
-  args[6] = &k;
-  CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 7, &struct_type_c,
-		       arg_types) == FFI_OK);
-
-  ffi_call (&cif, FFI_FN (C_fn), &result, args);
-  /* { dg-output "1, 1, 1, 1, 1, 1\n" } */
-  /* { dg-output "1.0, 2.0, 4.0, 8.0, 1.0, 2.0, 4.0, 8.0" } */
-  CHECK (result.a.a_x == source.a.a_x);
-  CHECK (result.a.a_y == source.a.a_y);
-  CHECK (result.b.b_x == source.b.b_x);
-  CHECK (result.b.b_y == source.b.b_y);
-  exit (0);
-}
diff --git a/testsuite/libffi.closures/nested_struct2.c b/testsuite/libffi.closures/nested_struct2.c
deleted file mode 100644
index 69268cd..0000000
--- a/testsuite/libffi.closures/nested_struct2.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-		Sample taken from Alan Modras patch to src/prep_cif.c.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030911	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct A {
-  unsigned long a;
-  unsigned char b;
-} A;
-
-typedef struct B {
-  struct A x;
-  unsigned char y;
-} B;
-
-B B_fn(struct A b0, struct B b1)
-{
-  struct B result;
-
-  result.x.a = b0.a + b1.x.a;
-  result.x.b = b0.b + b1.x.b + b1.y;
-  result.y = b0.b + b1.x.b;
-
-  printf("%lu %d %lu %d %d: %lu %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y,
-	 result.x.a, result.x.b, result.y);
-
-  return result;
-}
-
-static void
-B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-     void* userdata __UNUSED__)
-{
-  struct A b0;
-  struct B b1;
-
-  b0 = *(struct A*)(args[0]);
-  b1 = *(struct B*)(args[1]);
-
-  *(B*)resp = B_fn(b0, b1);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[3];
-  ffi_type* cls_struct_fields[3];
-  ffi_type* cls_struct_fields1[3];
-  ffi_type cls_struct_type, cls_struct_type1;
-  ffi_type* dbl_arg_types[3];
-
-  struct A e_dbl = { 1, 7};
-  struct B f_dbl = {{12 , 127}, 99};
-
-  struct B res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_fields[0] = &ffi_type_ulong;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = NULL;
-
-  cls_struct_fields1[0] = &cls_struct_type;
-  cls_struct_fields1[1] = &ffi_type_uchar;
-  cls_struct_fields1[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 7 12 127 99: 13 233 134" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
-  /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/nested_struct3.c b/testsuite/libffi.closures/nested_struct3.c
deleted file mode 100644
index ab18cad..0000000
--- a/testsuite/libffi.closures/nested_struct3.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-		Sample taken from Alan Modras patch to src/prep_cif.c.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030911	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct A {
-  unsigned long long a;
-  unsigned char b;
-} A;
-
-typedef struct B {
-  struct A x;
-  unsigned char y;
-} B;
-
-B B_fn(struct A b0, struct B b1)
-{
-  struct B result;
-
-  result.x.a = b0.a + b1.x.a;
-  result.x.b = b0.b + b1.x.b + b1.y;
-  result.y = b0.b + b1.x.b;
-
-  printf("%d %d %d %d %d: %d %d %d\n", (int)b0.a, b0.b,
-	 (int)b1.x.a, b1.x.b, b1.y,
-	 (int)result.x.a, result.x.b, result.y);
-
-  return result;
-}
-
-static void
-B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-     void* userdata __UNUSED__)
-{
-  struct A b0;
-  struct B b1;
-
-  b0 = *(struct A*)(args[0]);
-  b1 = *(struct B*)(args[1]);
-
-  *(B*)resp = B_fn(b0, b1);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[3];
-  ffi_type* cls_struct_fields[3];
-  ffi_type* cls_struct_fields1[3];
-  ffi_type cls_struct_type, cls_struct_type1;
-  ffi_type* dbl_arg_types[3];
-
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = {{12LL , 127}, 99};
-
-  struct B res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_fields[0] = &ffi_type_uint64;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = NULL;
-
-  cls_struct_fields1[0] = &cls_struct_type;
-  cls_struct_fields1[1] = &ffi_type_uchar;
-  cls_struct_fields1[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 7 12 127 99: 13 233 134" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
-
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
-  /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/nested_struct4.c b/testsuite/libffi.closures/nested_struct4.c
deleted file mode 100644
index 2ffb4d6..0000000
--- a/testsuite/libffi.closures/nested_struct4.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-		Sample taken from Alan Modras patch to src/prep_cif.c.
-   Limitations:	none.
-   PR:		PR 25630.
-   Originator:	<andreast@gcc.gnu.org> 20051010	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct A {
-  double a;
-  unsigned char b;
-} A;
-
-typedef struct B {
-  struct A x;
-  unsigned char y;
-} B;
-
-static B B_fn(struct A b2, struct B b3)
-{
-  struct B result;
-
-  result.x.a = b2.a + b3.x.a;
-  result.x.b = b2.b + b3.x.b + b3.y;
-  result.y = b2.b + b3.x.b;
-
-  printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
-	 (int)b3.x.a, b3.x.b, b3.y,
-	 (int)result.x.a, result.x.b, result.y);
-
-  return result;
-}
-
-static void
-B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-     void* userdata __UNUSED__)
-{
-  struct A b0;
-  struct B b1;
-
-  b0 = *(struct A*)(args[0]);
-  b1 = *(struct B*)(args[1]);
-
-  *(B*)resp = B_fn(b0, b1);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[3];
-  ffi_type* cls_struct_fields[3];
-  ffi_type* cls_struct_fields1[3];
-  ffi_type cls_struct_type, cls_struct_type1;
-  ffi_type* dbl_arg_types[3];
-
-  struct A e_dbl = { 1.0, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-
-  struct B res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_fields[0] = &ffi_type_double;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = NULL;
-
-  cls_struct_fields1[0] = &cls_struct_type;
-  cls_struct_fields1[1] = &ffi_type_uchar;
-  cls_struct_fields1[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 7 12 127 99: 13 233 134" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
-  /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/nested_struct5.c b/testsuite/libffi.closures/nested_struct5.c
deleted file mode 100644
index 6c79845..0000000
--- a/testsuite/libffi.closures/nested_struct5.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-		Sample taken from Alan Modras patch to src/prep_cif.c.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20051010	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct A {
-  long double a;
-  unsigned char b;
-} A;
-
-typedef struct B {
-  struct A x;
-  unsigned char y;
-} B;
-
-static B B_fn(struct A b2, struct B b3)
-{
-  struct B result;
-
-  result.x.a = b2.a + b3.x.a;
-  result.x.b = b2.b + b3.x.b + b3.y;
-  result.y = b2.b + b3.x.b;
-
-  printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
-	 (int)b3.x.a, b3.x.b, b3.y,
-	 (int)result.x.a, result.x.b, result.y);
-
-  return result;
-}
-
-static void
-B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-     void* userdata __UNUSED__)
-{
-  struct A b0;
-  struct B b1;
-
-  b0 = *(struct A*)(args[0]);
-  b1 = *(struct B*)(args[1]);
-
-  *(B*)resp = B_fn(b0, b1);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[3];
-  ffi_type* cls_struct_fields[3];
-  ffi_type* cls_struct_fields1[3];
-  ffi_type cls_struct_type, cls_struct_type1;
-  ffi_type* dbl_arg_types[3];
-
-  struct A e_dbl = { 1.0, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-
-  struct B res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_fields[0] = &ffi_type_longdouble;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = NULL;
-
-  cls_struct_fields1[0] = &cls_struct_type;
-  cls_struct_fields1[1] = &ffi_type_uchar;
-  cls_struct_fields1[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 7 12 127 99: 13 233 134" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
-
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
-  /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/nested_struct6.c b/testsuite/libffi.closures/nested_struct6.c
deleted file mode 100644
index 59d3579..0000000
--- a/testsuite/libffi.closures/nested_struct6.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-		Sample taken from Alan Modras patch to src/prep_cif.c.
-   Limitations:	none.
-   PR:		PR 25630.
-   Originator:	<andreast@gcc.gnu.org> 20051010	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct A {
-  double a;
-  unsigned char b;
-} A;
-
-typedef struct B {
-  struct A x;
-  unsigned char y;
-} B;
-
-typedef struct C {
-  long d;
-  unsigned char e;
-} C;
-
-static B B_fn(struct A b2, struct B b3, struct C b4)
-{
-  struct B result;
-
-  result.x.a = b2.a + b3.x.a + b4.d;
-  result.x.b = b2.b + b3.x.b + b3.y + b4.e;
-  result.y = b2.b + b3.x.b + b4.e;
-
-  printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
-	 (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e,
-	 (int)result.x.a, result.x.b, result.y);
-
-  return result;
-}
-
-static void
-B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-     void* userdata __UNUSED__)
-{
-  struct A b0;
-  struct B b1;
-  struct C b2;
-
-  b0 = *(struct A*)(args[0]);
-  b1 = *(struct B*)(args[1]);
-  b2 = *(struct C*)(args[2]);
-
-  *(B*)resp = B_fn(b0, b1, b2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[4];
-  ffi_type* cls_struct_fields[3];
-  ffi_type* cls_struct_fields1[3];
-  ffi_type* cls_struct_fields2[3];
-  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
-  ffi_type* dbl_arg_types[4];
-
-  struct A e_dbl = { 1.0, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-  struct C g_dbl = { 2, 9};
-
-  struct B res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_type2.size = 0;
-  cls_struct_type2.alignment = 0;
-  cls_struct_type2.type = FFI_TYPE_STRUCT;
-  cls_struct_type2.elements = cls_struct_fields2;
-
-  cls_struct_fields[0] = &ffi_type_double;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = NULL;
-
-  cls_struct_fields1[0] = &cls_struct_type;
-  cls_struct_fields1[1] = &ffi_type_uchar;
-  cls_struct_fields1[2] = NULL;
-
-  cls_struct_fields2[0] = &ffi_type_slong;
-  cls_struct_fields2[1] = &ffi_type_uchar;
-  cls_struct_fields2[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = &cls_struct_type2;
-  dbl_arg_types[3] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = &g_dbl;
-  args_dbl[3] = NULL;
-
-  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
-  /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/nested_struct7.c b/testsuite/libffi.closures/nested_struct7.c
deleted file mode 100644
index 27595e6..0000000
--- a/testsuite/libffi.closures/nested_struct7.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-		Sample taken from Alan Modras patch to src/prep_cif.c.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20051010	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct A {
-  unsigned long long a;
-  unsigned char b;
-} A;
-
-typedef struct B {
-  struct A x;
-  unsigned char y;
-} B;
-
-static B B_fn(struct A b2, struct B b3)
-{
-  struct B result;
-
-  result.x.a = b2.a + b3.x.a;
-  result.x.b = b2.b + b3.x.b + b3.y;
-  result.y = b2.b + b3.x.b;
-
-  printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
-	 (int)b3.x.a, b3.x.b, b3.y,
-	 (int)result.x.a, result.x.b, result.y);
-
-  return result;
-}
-
-static void
-B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-     void* userdata __UNUSED__)
-{
-  struct A b0;
-  struct B b1;
-
-  b0 = *(struct A*)(args[0]);
-  b1 = *(struct B*)(args[1]);
-
-  *(B*)resp = B_fn(b0, b1);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[3];
-  ffi_type* cls_struct_fields[3];
-  ffi_type* cls_struct_fields1[3];
-  ffi_type cls_struct_type, cls_struct_type1;
-  ffi_type* dbl_arg_types[3];
-
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-
-  struct B res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_fields[0] = &ffi_type_uint64;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = NULL;
-
-  cls_struct_fields1[0] = &cls_struct_type;
-  cls_struct_fields1[1] = &ffi_type_uchar;
-  cls_struct_fields1[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 7 12 127 99: 13 233 134" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
-  /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/nested_struct8.c b/testsuite/libffi.closures/nested_struct8.c
deleted file mode 100644
index 0e6c682..0000000
--- a/testsuite/libffi.closures/nested_struct8.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-		Sample taken from Alan Modras patch to src/prep_cif.c.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20051010	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct A {
-  unsigned long long a;
-  unsigned char b;
-} A;
-
-typedef struct B {
-  struct A x;
-  unsigned char y;
-} B;
-
-typedef struct C {
-  unsigned long long d;
-  unsigned char e;
-} C;
-
-static B B_fn(struct A b2, struct B b3, struct C b4)
-{
-  struct B result;
-
-  result.x.a = b2.a + b3.x.a + b4.d;
-  result.x.b = b2.b + b3.x.b + b3.y + b4.e;
-  result.y = b2.b + b3.x.b + b4.e;
-
-  printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
-	 (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e,
-	 (int)result.x.a, result.x.b, result.y);
-
-  return result;
-}
-
-static void
-B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-     void* userdata __UNUSED__)
-{
-  struct A b0;
-  struct B b1;
-  struct C b2;
-
-  b0 = *(struct A*)(args[0]);
-  b1 = *(struct B*)(args[1]);
-  b2 = *(struct C*)(args[2]);
-
-  *(B*)resp = B_fn(b0, b1, b2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[4];
-  ffi_type* cls_struct_fields[3];
-  ffi_type* cls_struct_fields1[3];
-  ffi_type* cls_struct_fields2[3];
-  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
-  ffi_type* dbl_arg_types[4];
-
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = {{12LL , 127}, 99};
-  struct C g_dbl = { 2LL, 9};
-
-  struct B res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_type2.size = 0;
-  cls_struct_type2.alignment = 0;
-  cls_struct_type2.type = FFI_TYPE_STRUCT;
-  cls_struct_type2.elements = cls_struct_fields2;
-
-  cls_struct_fields[0] = &ffi_type_uint64;
-  cls_struct_fields[1] = &ffi_type_uchar;
-  cls_struct_fields[2] = NULL;
-
-  cls_struct_fields1[0] = &cls_struct_type;
-  cls_struct_fields1[1] = &ffi_type_uchar;
-  cls_struct_fields1[2] = NULL;
-
-  cls_struct_fields2[0] = &ffi_type_uint64;
-  cls_struct_fields2[1] = &ffi_type_uchar;
-  cls_struct_fields2[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = &cls_struct_type2;
-  dbl_arg_types[3] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = &g_dbl;
-  args_dbl[3] = NULL;
-
-  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
-  /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/nested_struct9.c b/testsuite/libffi.closures/nested_struct9.c
deleted file mode 100644
index 5f7ac67..0000000
--- a/testsuite/libffi.closures/nested_struct9.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-		Contains structs as parameter of the struct itself.
-		Sample taken from Alan Modras patch to src/prep_cif.c.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20051010	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct A {
-  unsigned char a;
-  unsigned long long b;
-} A;
-
-typedef struct B {
-  struct A x;
-  unsigned char y;
-} B;
-
-typedef struct C {
-  unsigned long d;
-  unsigned char e;
-} C;
-
-static B B_fn(struct A b2, struct B b3, struct C b4)
-{
-  struct B result;
-
-  result.x.a = b2.a + b3.x.a + b4.d;
-  result.x.b = b2.b + b3.x.b + b3.y + b4.e;
-  result.y = b2.b + b3.x.b + b4.e;
-
-  printf("%d %d %d %d %d %d %d: %d %d %d\n", b2.a, (int)b2.b,
-	 b3.x.a, (int)b3.x.b, b3.y, (int)b4.d, b4.e,
-	 result.x.a, (int)result.x.b, result.y);
-
-  return result;
-}
-
-static void
-B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-     void* userdata __UNUSED__)
-{
-  struct A b0;
-  struct B b1;
-  struct C b2;
-
-  b0 = *(struct A*)(args[0]);
-  b1 = *(struct B*)(args[1]);
-  b2 = *(struct C*)(args[2]);
-
-  *(B*)resp = B_fn(b0, b1, b2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_dbl[4];
-  ffi_type* cls_struct_fields[3];
-  ffi_type* cls_struct_fields1[3];
-  ffi_type* cls_struct_fields2[3];
-  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
-  ffi_type* dbl_arg_types[4];
-
-  struct A e_dbl = { 1, 7LL};
-  struct B f_dbl = {{12.0 , 127}, 99};
-  struct C g_dbl = { 2, 9};
-
-  struct B res_dbl;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_type1.size = 0;
-  cls_struct_type1.alignment = 0;
-  cls_struct_type1.type = FFI_TYPE_STRUCT;
-  cls_struct_type1.elements = cls_struct_fields1;
-
-  cls_struct_type2.size = 0;
-  cls_struct_type2.alignment = 0;
-  cls_struct_type2.type = FFI_TYPE_STRUCT;
-  cls_struct_type2.elements = cls_struct_fields2;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &ffi_type_uint64;
-  cls_struct_fields[2] = NULL;
-
-  cls_struct_fields1[0] = &cls_struct_type;
-  cls_struct_fields1[1] = &ffi_type_uchar;
-  cls_struct_fields1[2] = NULL;
-
-  cls_struct_fields2[0] = &ffi_type_ulong;
-  cls_struct_fields2[1] = &ffi_type_uchar;
-  cls_struct_fields2[2] = NULL;
-
-
-  dbl_arg_types[0] = &cls_struct_type;
-  dbl_arg_types[1] = &cls_struct_type1;
-  dbl_arg_types[2] = &cls_struct_type2;
-  dbl_arg_types[3] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
-		     dbl_arg_types) == FFI_OK);
-
-  args_dbl[0] = &e_dbl;
-  args_dbl[1] = &f_dbl;
-  args_dbl[2] = &g_dbl;
-  args_dbl[3] = NULL;
-
-  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
-  /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
-
-  res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
-  /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
-  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
-  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
-  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
-
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/problem1.c b/testsuite/libffi.closures/problem1.c
deleted file mode 100644
index 6a91555..0000000
--- a/testsuite/libffi.closures/problem1.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure passing with different structure size.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<andreast@gcc.gnu.org> 20030828	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct my_ffi_struct {
-  double a;
-  double b;
-  double c;
-} my_ffi_struct;
-
-my_ffi_struct callee(struct my_ffi_struct a1, struct my_ffi_struct a2)
-{
-  struct my_ffi_struct result;
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-
-  printf("%g %g %g %g %g %g: %g %g %g\n", a1.a, a1.b, a1.c,
-	 a2.a, a2.b, a2.c, result.a, result.b, result.c);
-
-  return result;
-}
-
-void stub(ffi_cif* cif __UNUSED__, void* resp, void** args,
-	  void* userdata __UNUSED__)
-{
-  struct my_ffi_struct a1;
-  struct my_ffi_struct a2;
-
-  a1 = *(struct my_ffi_struct*)(args[0]);
-  a2 = *(struct my_ffi_struct*)(args[1]);
-
-  *(my_ffi_struct *)resp = callee(a1, a2);
-}
-
-
-int main(void)
-{
-  ffi_type* my_ffi_struct_fields[4];
-  ffi_type my_ffi_struct_type;
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args[4];
-  ffi_type* arg_types[3];
-
-  struct my_ffi_struct g = { 1.0, 2.0, 3.0 };
-  struct my_ffi_struct f = { 1.0, 2.0, 3.0 };
-  struct my_ffi_struct res;
-
-  my_ffi_struct_type.size = 0;
-  my_ffi_struct_type.alignment = 0;
-  my_ffi_struct_type.type = FFI_TYPE_STRUCT;
-  my_ffi_struct_type.elements = my_ffi_struct_fields;
-
-  my_ffi_struct_fields[0] = &ffi_type_double;
-  my_ffi_struct_fields[1] = &ffi_type_double;
-  my_ffi_struct_fields[2] = &ffi_type_double;
-  my_ffi_struct_fields[3] = NULL;
-
-  arg_types[0] = &my_ffi_struct_type;
-  arg_types[1] = &my_ffi_struct_type;
-  arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &my_ffi_struct_type,
-		     arg_types) == FFI_OK);
-
-  args[0] = &g;
-  args[1] = &f;
-  args[2] = NULL;
-  ffi_call(&cif, FFI_FN(callee), &res, args);
-  /* { dg-output "1 2 3 1 2 3: 2 4 6" } */
-  printf("res: %g %g %g\n", res.a, res.b, res.c);
-  /* { dg-output "\nres: 2 4 6" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, stub, NULL, code) == FFI_OK);
-
-  res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(code))(g, f);
-  /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */
-  printf("res: %g %g %g\n", res.a, res.b, res.c);
-  /* { dg-output "\nres: 2 4 6" } */
-
-  exit(0);;
-}
diff --git a/testsuite/libffi.closures/stret_large.c b/testsuite/libffi.closures/stret_large.c
deleted file mode 100644
index 71c2469..0000000
--- a/testsuite/libffi.closures/stret_large.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Check structure returning with different structure size.
-				Depending on the ABI. Check bigger struct which overlaps
-				the gp and fp register count on Darwin/AIX/ppc64.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin	6/21/2007	*/
-
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-*  } } */
-#include "ffitest.h"
-
-/* 13 FPRs: 104 bytes */
-/* 14 FPRs: 112 bytes */
-
-typedef struct struct_108byte {
-	double a;
-	double b;
-	double c;
-	double d;
-	double e;
-	double f;
-	double g;
-	double h;
-	double i;
-	double j;
-	double k;
-	double l;
-	double m;
-	int n;
-} struct_108byte;
-
-struct_108byte cls_struct_108byte_fn(
-	struct_108byte b0,
-	struct_108byte b1,
-	struct_108byte b2,
-	struct_108byte b3)
-{
-	struct_108byte	result;
-
-	result.a = b0.a + b1.a + b2.a + b3.a;
-	result.b = b0.b + b1.b + b2.b + b3.b;
-	result.c = b0.c + b1.c + b2.c + b3.c;
-	result.d = b0.d + b1.d + b2.d + b3.d;
-	result.e = b0.e + b1.e + b2.e + b3.e;
-	result.f = b0.f + b1.f + b2.f + b3.f;
-	result.g = b0.g + b1.g + b2.g + b3.g;
-	result.h = b0.h + b1.h + b2.h + b3.h;
-	result.i = b0.i + b1.i + b2.i + b3.i;
-	result.j = b0.j + b1.j + b2.j + b3.j;
-	result.k = b0.k + b1.k + b2.k + b3.k;
-	result.l = b0.l + b1.l + b2.l + b3.l;
-	result.m = b0.m + b1.m + b2.m + b3.m;
-	result.n = b0.n + b1.n + b2.n + b3.n;
-
-	printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c,
-		result.d, result.e, result.f, result.g, result.h, result.i,
-		result.j, result.k, result.l, result.m, result.n);
-
-	return result;
-}
-
-static void
-cls_struct_108byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
-{
-	struct_108byte	b0, b1, b2, b3;
-
-	b0 = *(struct_108byte*)(args[0]);
-	b1 = *(struct_108byte*)(args[1]);
-	b2 = *(struct_108byte*)(args[2]);
-	b3 = *(struct_108byte*)(args[3]);
-
-	*(struct_108byte*)resp = cls_struct_108byte_fn(b0, b1, b2, b3);
-}
-
-int main (void)
-{
-	ffi_cif cif;
-        void *code;
-	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void* args_dbl[5];
-	ffi_type* cls_struct_fields[15];
-	ffi_type cls_struct_type;
-	ffi_type* dbl_arg_types[5];
-
-	struct_108byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 7 };
-	struct_108byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 4 };
-	struct_108byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 3 };
-	struct_108byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 2 };
-	struct_108byte res_dbl;
-
-	cls_struct_type.size = 0;
-	cls_struct_type.alignment = 0;
-	cls_struct_type.type = FFI_TYPE_STRUCT;
-	cls_struct_type.elements = cls_struct_fields;
-
-	cls_struct_fields[0] = &ffi_type_double;
-	cls_struct_fields[1] = &ffi_type_double;
-	cls_struct_fields[2] = &ffi_type_double;
-	cls_struct_fields[3] = &ffi_type_double;
-	cls_struct_fields[4] = &ffi_type_double;
-	cls_struct_fields[5] = &ffi_type_double;
-	cls_struct_fields[6] = &ffi_type_double;
-	cls_struct_fields[7] = &ffi_type_double;
-	cls_struct_fields[8] = &ffi_type_double;
-	cls_struct_fields[9] = &ffi_type_double;
-	cls_struct_fields[10] = &ffi_type_double;
-	cls_struct_fields[11] = &ffi_type_double;
-	cls_struct_fields[12] = &ffi_type_double;
-	cls_struct_fields[13] = &ffi_type_sint32;
-	cls_struct_fields[14] = NULL;
-
-	dbl_arg_types[0] = &cls_struct_type;
-	dbl_arg_types[1] = &cls_struct_type;
-	dbl_arg_types[2] = &cls_struct_type;
-	dbl_arg_types[3] = &cls_struct_type;
-	dbl_arg_types[4] = NULL;
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
-		dbl_arg_types) == FFI_OK);
-
-	args_dbl[0] = &e_dbl;
-	args_dbl[1] = &f_dbl;
-	args_dbl[2] = &g_dbl;
-	args_dbl[3] = &h_dbl;
-	args_dbl[4] = NULL;
-
-	ffi_call(&cif, FFI_FN(cls_struct_108byte_fn), &res_dbl, args_dbl);
-	/* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
-	printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
-		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
-		res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n);
-	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_108byte_gn, NULL, code) == FFI_OK);
-
-	res_dbl = ((struct_108byte(*)(struct_108byte, struct_108byte,
-		struct_108byte, struct_108byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
-	/* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
-	printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
-		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
-		res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n);
-	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
-
-	exit(0);
-}
diff --git a/testsuite/libffi.closures/stret_large2.c b/testsuite/libffi.closures/stret_large2.c
deleted file mode 100644
index d9c750e..0000000
--- a/testsuite/libffi.closures/stret_large2.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Check structure returning with different structure size.
-				Depending on the ABI. Check bigger struct which overlaps
-				the gp and fp register count on Darwin/AIX/ppc64.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin	6/21/2007	*/
-
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-*  } } */
-#include "ffitest.h"
-
-/* 13 FPRs: 104 bytes */
-/* 14 FPRs: 112 bytes */
-
-typedef struct struct_116byte {
-	double a;
-	double b;
-	double c;
-	double d;
-	double e;
-	double f;
-	double g;
-	double h;
-	double i;
-	double j;
-	double k;
-	double l;
-	double m;
-	double n;
-	int o;
-} struct_116byte;
-
-struct_116byte cls_struct_116byte_fn(
-	struct_116byte b0,
-	struct_116byte b1,
-	struct_116byte b2,
-	struct_116byte b3)
-{
-	struct_116byte	result;
-
-	result.a = b0.a + b1.a + b2.a + b3.a;
-	result.b = b0.b + b1.b + b2.b + b3.b;
-	result.c = b0.c + b1.c + b2.c + b3.c;
-	result.d = b0.d + b1.d + b2.d + b3.d;
-	result.e = b0.e + b1.e + b2.e + b3.e;
-	result.f = b0.f + b1.f + b2.f + b3.f;
-	result.g = b0.g + b1.g + b2.g + b3.g;
-	result.h = b0.h + b1.h + b2.h + b3.h;
-	result.i = b0.i + b1.i + b2.i + b3.i;
-	result.j = b0.j + b1.j + b2.j + b3.j;
-	result.k = b0.k + b1.k + b2.k + b3.k;
-	result.l = b0.l + b1.l + b2.l + b3.l;
-	result.m = b0.m + b1.m + b2.m + b3.m;
-	result.n = b0.n + b1.n + b2.n + b3.n;
-	result.o = b0.o + b1.o + b2.o + b3.o;
-
-	printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c,
-		result.d, result.e, result.f, result.g, result.h, result.i,
-		result.j, result.k, result.l, result.m, result.n, result.o);
-
-	return result;
-}
-
-static void
-cls_struct_116byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
-{
-	struct_116byte	b0, b1, b2, b3;
-
-	b0 = *(struct_116byte*)(args[0]);
-	b1 = *(struct_116byte*)(args[1]);
-	b2 = *(struct_116byte*)(args[2]);
-	b3 = *(struct_116byte*)(args[3]);
-
-	*(struct_116byte*)resp = cls_struct_116byte_fn(b0, b1, b2, b3);
-}
-
-int main (void)
-{
-	ffi_cif cif;
-        void *code;
-	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void* args_dbl[5];
-	ffi_type* cls_struct_fields[16];
-	ffi_type cls_struct_type;
-	ffi_type* dbl_arg_types[5];
-
-	struct_116byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 7 };
-	struct_116byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 6.0, 4 };
-	struct_116byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 7.0, 3 };
-	struct_116byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 8.0, 2 };
-	struct_116byte res_dbl;
-
-	cls_struct_type.size = 0;
-	cls_struct_type.alignment = 0;
-	cls_struct_type.type = FFI_TYPE_STRUCT;
-	cls_struct_type.elements = cls_struct_fields;
-
-	cls_struct_fields[0] = &ffi_type_double;
-	cls_struct_fields[1] = &ffi_type_double;
-	cls_struct_fields[2] = &ffi_type_double;
-	cls_struct_fields[3] = &ffi_type_double;
-	cls_struct_fields[4] = &ffi_type_double;
-	cls_struct_fields[5] = &ffi_type_double;
-	cls_struct_fields[6] = &ffi_type_double;
-	cls_struct_fields[7] = &ffi_type_double;
-	cls_struct_fields[8] = &ffi_type_double;
-	cls_struct_fields[9] = &ffi_type_double;
-	cls_struct_fields[10] = &ffi_type_double;
-	cls_struct_fields[11] = &ffi_type_double;
-	cls_struct_fields[12] = &ffi_type_double;
-	cls_struct_fields[13] = &ffi_type_double;
-	cls_struct_fields[14] = &ffi_type_sint32;
-	cls_struct_fields[15] = NULL;
-
-	dbl_arg_types[0] = &cls_struct_type;
-	dbl_arg_types[1] = &cls_struct_type;
-	dbl_arg_types[2] = &cls_struct_type;
-	dbl_arg_types[3] = &cls_struct_type;
-	dbl_arg_types[4] = NULL;
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
-		dbl_arg_types) == FFI_OK);
-
-	args_dbl[0] = &e_dbl;
-	args_dbl[1] = &f_dbl;
-	args_dbl[2] = &g_dbl;
-	args_dbl[3] = &h_dbl;
-	args_dbl[4] = NULL;
-
-	ffi_call(&cif, FFI_FN(cls_struct_116byte_fn), &res_dbl, args_dbl);
-	/* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
-	printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
-		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
-		res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o);
-	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_116byte_gn, NULL, code) == FFI_OK);
-
-	res_dbl = ((struct_116byte(*)(struct_116byte, struct_116byte,
-		struct_116byte, struct_116byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
-	/* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
-	printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
-		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
-		res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o);
-	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
-
-	exit(0);
-}
diff --git a/testsuite/libffi.closures/stret_medium.c b/testsuite/libffi.closures/stret_medium.c
deleted file mode 100644
index 973ee02..0000000
--- a/testsuite/libffi.closures/stret_medium.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Check structure returning with different structure size.
-				Depending on the ABI. Check bigger struct which overlaps
-				the gp and fp register count on Darwin/AIX/ppc64.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin	6/21/2007	*/
-
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-*  } } */
-#include "ffitest.h"
-
-typedef struct struct_72byte {
-	double a;
-	double b;
-	double c;
-	double d;
-	double e;
-	double f;
-	double g;
-	double h;
-	double i;
-} struct_72byte;
-
-struct_72byte cls_struct_72byte_fn(
-	struct_72byte b0,
-	struct_72byte b1,
-	struct_72byte b2,
-	struct_72byte b3)
-{
-	struct_72byte	result;
-
-	result.a = b0.a + b1.a + b2.a + b3.a;
-	result.b = b0.b + b1.b + b2.b + b3.b;
-	result.c = b0.c + b1.c + b2.c + b3.c;
-	result.d = b0.d + b1.d + b2.d + b3.d;
-	result.e = b0.e + b1.e + b2.e + b3.e;
-	result.f = b0.f + b1.f + b2.f + b3.f;
-	result.g = b0.g + b1.g + b2.g + b3.g;
-	result.h = b0.h + b1.h + b2.h + b3.h;
-	result.i = b0.i + b1.i + b2.i + b3.i;
-
-	printf("%g %g %g %g %g %g %g %g %g\n", result.a, result.b, result.c,
-		result.d, result.e, result.f, result.g, result.h, result.i);
-
-	return result;
-}
-
-static void
-cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
-{
-	struct_72byte	b0, b1, b2, b3;
-
-	b0 = *(struct_72byte*)(args[0]);
-	b1 = *(struct_72byte*)(args[1]);
-	b2 = *(struct_72byte*)(args[2]);
-	b3 = *(struct_72byte*)(args[3]);
-
-	*(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3);
-}
-
-int main (void)
-{
-	ffi_cif cif;
-        void *code;
-	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void* args_dbl[5];
-	ffi_type* cls_struct_fields[10];
-	ffi_type cls_struct_type;
-	ffi_type* dbl_arg_types[5];
-
-	struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7.0 };
-	struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0 };
-	struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3.0 };
-	struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2.0 };
-	struct_72byte res_dbl;
-
-	cls_struct_type.size = 0;
-	cls_struct_type.alignment = 0;
-	cls_struct_type.type = FFI_TYPE_STRUCT;
-	cls_struct_type.elements = cls_struct_fields;
-
-	cls_struct_fields[0] = &ffi_type_double;
-	cls_struct_fields[1] = &ffi_type_double;
-	cls_struct_fields[2] = &ffi_type_double;
-	cls_struct_fields[3] = &ffi_type_double;
-	cls_struct_fields[4] = &ffi_type_double;
-	cls_struct_fields[5] = &ffi_type_double;
-	cls_struct_fields[6] = &ffi_type_double;
-	cls_struct_fields[7] = &ffi_type_double;
-	cls_struct_fields[8] = &ffi_type_double;
-	cls_struct_fields[9] = NULL;
-
-	dbl_arg_types[0] = &cls_struct_type;
-	dbl_arg_types[1] = &cls_struct_type;
-	dbl_arg_types[2] = &cls_struct_type;
-	dbl_arg_types[3] = &cls_struct_type;
-	dbl_arg_types[4] = NULL;
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
-		dbl_arg_types) == FFI_OK);
-
-	args_dbl[0] = &e_dbl;
-	args_dbl[1] = &f_dbl;
-	args_dbl[2] = &g_dbl;
-	args_dbl[3] = &h_dbl;
-	args_dbl[4] = NULL;
-
-	ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
-	/* { dg-output "22 15 17 25 6 13 19 18 16" } */
-	printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
-		res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
-	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK);
-
-	res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
-		struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
-	/* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
-	printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
-		res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
-	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
-
-	exit(0);
-}
diff --git a/testsuite/libffi.closures/stret_medium2.c b/testsuite/libffi.closures/stret_medium2.c
deleted file mode 100644
index 84323d1..0000000
--- a/testsuite/libffi.closures/stret_medium2.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Area:		ffi_call, closure_call
-   Purpose:		Check structure returning with different structure size.
-				Depending on the ABI. Check bigger struct which overlaps
-				the gp and fp register count on Darwin/AIX/ppc64.
-   Limitations:	none.
-   PR:			none.
-   Originator:	Blake Chaffin	6/21/2007	*/
-
-/* { dg-do run { xfail strongarm*-*-* xscale*-*-*  } } */
-/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
-#include "ffitest.h"
-
-typedef struct struct_72byte {
-	double a;
-	double b;
-	double c;
-	double d;
-	double e;
-	double f;
-	double g;
-	double h;
-	long long i;
-} struct_72byte;
-
-struct_72byte cls_struct_72byte_fn(
-	struct_72byte b0,
-	struct_72byte b1,
-	struct_72byte b2,
-	struct_72byte b3)
-{
-	struct_72byte	result;
-
-	result.a = b0.a + b1.a + b2.a + b3.a;
-	result.b = b0.b + b1.b + b2.b + b3.b;
-	result.c = b0.c + b1.c + b2.c + b3.c;
-	result.d = b0.d + b1.d + b2.d + b3.d;
-	result.e = b0.e + b1.e + b2.e + b3.e;
-	result.f = b0.f + b1.f + b2.f + b3.f;
-	result.g = b0.g + b1.g + b2.g + b3.g;
-	result.h = b0.h + b1.h + b2.h + b3.h;
-	result.i = b0.i + b1.i + b2.i + b3.i;
-
-	printf("%g %g %g %g %g %g %g %g %" PRIdLL "\n", result.a, result.b, result.c,
-		result.d, result.e, result.f, result.g, result.h, result.i);
-
-	return result;
-}
-
-static void
-cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
-{
-	struct_72byte	b0, b1, b2, b3;
-
-	b0 = *(struct_72byte*)(args[0]);
-	b1 = *(struct_72byte*)(args[1]);
-	b2 = *(struct_72byte*)(args[2]);
-	b3 = *(struct_72byte*)(args[3]);
-
-	*(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3);
-}
-
-int main (void)
-{
-	ffi_cif cif;
-        void *code;
-	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-	void* args_dbl[5];
-	ffi_type* cls_struct_fields[10];
-	ffi_type cls_struct_type;
-	ffi_type* dbl_arg_types[5];
-
-	struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 };
-	struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 };
-	struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 };
-	struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 };
-	struct_72byte res_dbl;
-
-	cls_struct_type.size = 0;
-	cls_struct_type.alignment = 0;
-	cls_struct_type.type = FFI_TYPE_STRUCT;
-	cls_struct_type.elements = cls_struct_fields;
-
-	cls_struct_fields[0] = &ffi_type_double;
-	cls_struct_fields[1] = &ffi_type_double;
-	cls_struct_fields[2] = &ffi_type_double;
-	cls_struct_fields[3] = &ffi_type_double;
-	cls_struct_fields[4] = &ffi_type_double;
-	cls_struct_fields[5] = &ffi_type_double;
-	cls_struct_fields[6] = &ffi_type_double;
-	cls_struct_fields[7] = &ffi_type_double;
-	cls_struct_fields[8] = &ffi_type_sint64;
-	cls_struct_fields[9] = NULL;
-
-	dbl_arg_types[0] = &cls_struct_type;
-	dbl_arg_types[1] = &cls_struct_type;
-	dbl_arg_types[2] = &cls_struct_type;
-	dbl_arg_types[3] = &cls_struct_type;
-	dbl_arg_types[4] = NULL;
-
-	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
-		dbl_arg_types) == FFI_OK);
-
-	args_dbl[0] = &e_dbl;
-	args_dbl[1] = &f_dbl;
-	args_dbl[2] = &g_dbl;
-	args_dbl[3] = &h_dbl;
-	args_dbl[4] = NULL;
-
-	ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
-	/* { dg-output "22 15 17 25 6 13 19 18 16" } */
-	printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c,
-		res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
-	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
-
-	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK);
-
-	res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
-		struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
-	/* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
-	printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c,
-		res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
-	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
-
-	exit(0);
-}
diff --git a/testsuite/libffi.closures/testclosure.c b/testsuite/libffi.closures/testclosure.c
deleted file mode 100644
index ca31056..0000000
--- a/testsuite/libffi.closures/testclosure.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value float.
-   Limitations:	none.
-   PR:		41908.
-   Originator:	<rfm@gnu.org> 20091102	 */
-
-/* { dg-do run } */
-#include "ffitest.h"
-
-typedef struct cls_struct_combined {
-  float a;
-  float b;
-  float c;
-  float d;
-} cls_struct_combined;
-
-void cls_struct_combined_fn(struct cls_struct_combined arg)
-{
-  printf("%g %g %g %g\n",
-	 arg.a, arg.b,
-	 arg.c, arg.d);
-  fflush(stdout);
-}
-
-static void
-cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
-        void** args, void* userdata __UNUSED__)
-{
-  struct cls_struct_combined a0;
-
-  a0 = *(struct cls_struct_combined*)(args[0]);
-
-  cls_struct_combined_fn(a0);
-}
-
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type* cls_struct_fields0[5];
-  ffi_type cls_struct_type0;
-  ffi_type* dbl_arg_types[5];
-
-  struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
-
-  cls_struct_type0.size = 0;
-  cls_struct_type0.alignment = 0;
-  cls_struct_type0.type = FFI_TYPE_STRUCT;
-  cls_struct_type0.elements = cls_struct_fields0;
-
-  cls_struct_fields0[0] = &ffi_type_float;
-  cls_struct_fields0[1] = &ffi_type_float;
-  cls_struct_fields0[2] = &ffi_type_float;
-  cls_struct_fields0[3] = &ffi_type_float;
-  cls_struct_fields0[4] = NULL;
-
-  dbl_arg_types[0] = &cls_struct_type0;
-  dbl_arg_types[1] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void,
-		     dbl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
-
-  ((void(*)(cls_struct_combined)) (code))(g_dbl);
-  /* { dg-output "4 5 1 8" } */
-  exit(0);
-}
diff --git a/testsuite/libffi.closures/unwindtest.cc b/testsuite/libffi.closures/unwindtest.cc
deleted file mode 100644
index e114565..0000000
--- a/testsuite/libffi.closures/unwindtest.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Area:	ffi_closure, unwind info
-   Purpose:	Check if the unwind information is passed correctly.
-   Limitations:	none.
-   PR:		none.
-   Originator:	Jeff Sturm <jsturm@one-point.com>  */
-
-/* { dg-do run { xfail x86_64-apple-darwin* moxie*-*-* } } */
-
-#include "ffitest.h"
-
-void ABI_ATTR
-closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
-		void** args __UNUSED__, void* userdata __UNUSED__)
-{
-  throw 9;
-}
-
-typedef void (*closure_test_type)();
-
-void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp,
-		      void** args, void* userdata __UNUSED__)
- {
-    *(ffi_arg*)resp =
-      (int)*(float *)args[0] +(int)(*(float *)args[1]) +
-      (int)(*(float *)args[2]) + (int)*(float *)args[3] +
-      (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) +
-      (int)*(float *)args[6] + (int)(*(int *)args[7]) +
-      (int)(*(double*)args[8]) + (int)*(int *)args[9] +
-      (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
-      (int)*(int *)args[12] + (int)(*(int *)args[13]) +
-      (int)(*(int *)args[14]) + *(int *)args[15] + (int)(intptr_t)userdata;
-
-    printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
-	   (int)*(float *)args[0], (int)(*(float *)args[1]),
-	   (int)(*(float *)args[2]), (int)*(float *)args[3],
-	   (int)(*(signed short *)args[4]), (int)(*(float *)args[5]),
-	   (int)*(float *)args[6], (int)(*(int *)args[7]),
-	   (int)(*(double *)args[8]), (int)*(int *)args[9],
-	   (int)(*(int *)args[10]), (int)(*(float *)args[11]),
-	   (int)*(int *)args[12], (int)(*(int *)args[13]),
-	   (int)(*(int *)args[14]), *(int *)args[15],
-	   (int)(intptr_t)userdata, (int)*(ffi_arg*)resp);
-
-    throw (int)*(ffi_arg*)resp;
-}
-
-typedef int (*closure_test_type1)(float, float, float, float, signed short,
-				  float, float, int, double, int, int, float,
-				  int, int, int, int);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[17];
-
-  {
-    cl_arg_types[1] = NULL;
-
-    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0,
-		       &ffi_type_void, cl_arg_types) == FFI_OK);
-    CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn, NULL, code) == FFI_OK);
-
-    try
-      {
-	(*((closure_test_type)(code)))();
-      } catch (int exception_code)
-      {
-	CHECK(exception_code == 9);
-      }
-
-    printf("part one OK\n");
-    /* { dg-output "part one OK" } */
-    }
-
-    {
-
-      cl_arg_types[0] = &ffi_type_float;
-      cl_arg_types[1] = &ffi_type_float;
-      cl_arg_types[2] = &ffi_type_float;
-      cl_arg_types[3] = &ffi_type_float;
-      cl_arg_types[4] = &ffi_type_sshort;
-      cl_arg_types[5] = &ffi_type_float;
-      cl_arg_types[6] = &ffi_type_float;
-      cl_arg_types[7] = &ffi_type_uint;
-      cl_arg_types[8] = &ffi_type_double;
-      cl_arg_types[9] = &ffi_type_uint;
-      cl_arg_types[10] = &ffi_type_uint;
-      cl_arg_types[11] = &ffi_type_float;
-      cl_arg_types[12] = &ffi_type_uint;
-      cl_arg_types[13] = &ffi_type_uint;
-      cl_arg_types[14] = &ffi_type_uint;
-      cl_arg_types[15] = &ffi_type_uint;
-      cl_arg_types[16] = NULL;
-
-      /* Initialize the cif */
-      CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
-			 &ffi_type_sint, cl_arg_types) == FFI_OK);
-
-      CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1,
-                                 (void *) 3 /* userdata */, code)  == FFI_OK);
-      try
-	{
-	  (*((closure_test_type1)code))
-	    (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
-	     19, 21, 1);
-	  /* { dg-output "\n1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
-	} catch (int exception_code)
-	{
-	  CHECK(exception_code == 255);
-	}
-      printf("part two OK\n");
-      /* { dg-output "\npart two OK" } */
-    }
-    exit(0);
-}
diff --git a/testsuite/libffi.closures/unwindtest_ffi_call.cc b/testsuite/libffi.closures/unwindtest_ffi_call.cc
deleted file mode 100644
index 153d240..0000000
--- a/testsuite/libffi.closures/unwindtest_ffi_call.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Area:	ffi_call, unwind info
-   Purpose:	Check if the unwind information is passed correctly.
-   Limitations:	none.
-   PR:		none.
-   Originator:	Andreas Tobler <andreast@gcc.gnu.org> 20061213  */
-
-/* { dg-do run { xfail moxie*-*-* } } */
-
-#include "ffitest.h"
-
-static int checking(int a __UNUSED__, short b __UNUSED__,
-		    signed char c __UNUSED__)
-{
-  throw 9;
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  ffi_type *args[MAX_ARGS];
-  void *values[MAX_ARGS];
-  ffi_arg rint;
-
-  signed int si;
-  signed short ss;
-  signed char sc;
-
-  args[0] = &ffi_type_sint;
-  values[0] = &si;
-  args[1] = &ffi_type_sshort;
-  values[1] = &ss;
-  args[2] = &ffi_type_schar;
-  values[2] = &sc;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
-		     &ffi_type_sint, args) == FFI_OK);
-
-  si = -6;
-  ss = -12;
-  sc = -1;
-  {
-    try
-      {
-	ffi_call(&cif, FFI_FN(checking), &rint, values);
-      } catch (int exception_code)
-      {
-	CHECK(exception_code == 9);
-      }
-    printf("part one OK\n");
-    /* { dg-output "part one OK" } */
-  }
-  exit(0);
-}
diff --git a/testsuite/libffi.complex/cls_align_complex.inc b/testsuite/libffi.complex/cls_align_complex.inc
deleted file mode 100644
index 4a812ed..0000000
--- a/testsuite/libffi.complex/cls_align_complex.inc
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*-c-*- */
-#include "ffitest.h"
-#include <complex.h>
-
-typedef struct cls_struct_align {
-  unsigned char a;
-  _Complex T_C_TYPE b;
-  unsigned char c;
-} cls_struct_align;
-
-cls_struct_align cls_struct_align_fn(
-	struct cls_struct_align a1, struct cls_struct_align a2)
-{
-  struct cls_struct_align result;
-
-  result.a = a1.a + a2.a;
-  result.b = a1.b + a2.b;
-  result.c = a1.c + a2.c;
-
-  printf("%d %f,%fi %d %d %f,%fi %d: %d %f,%fi %d\n",
-	 a1.a, T_CONV creal (a1.b), T_CONV cimag (a1.b), a1.c,
-	 a2.a, T_CONV creal (a2.b), T_CONV cimag (a2.b), a2.c,
-	 result.a, T_CONV creal (result.b), T_CONV cimag (result.b), result.c);
-
-  return  result;
-}
-
-static void
-cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-		    void* userdata __UNUSED__)
-{
-
-  struct cls_struct_align a1, a2;
-
-  a1 = *(struct cls_struct_align*)(args[0]);
-  a2 = *(struct cls_struct_align*)(args[1]);
-
-  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args_c[5];
-  ffi_type* cls_struct_fields[4];
-  ffi_type cls_struct_type;
-  ffi_type* c_arg_types[5];
-
-  struct cls_struct_align g_c = { 12, 4951 + 7 * I, 127 };
-  struct cls_struct_align f_c = { 1, 9320 + 1 * I, 13 };
-  struct cls_struct_align res_c;
-
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
-  cls_struct_fields[0] = &ffi_type_uchar;
-  cls_struct_fields[1] = &T_FFI_TYPE;
-  cls_struct_fields[2] = &ffi_type_uchar;
-  cls_struct_fields[3] = NULL;
-
-  c_arg_types[0] = &cls_struct_type;
-  c_arg_types[1] = &cls_struct_type;
-  c_arg_types[2] = NULL;
-
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
-		     c_arg_types) == FFI_OK);
-
-  args_c[0] = &g_c;
-  args_c[1] = &f_c;
-  args_c[2] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_c, args_c);
-  /* { dg-output "12 4951,7i 127 1 9320,1i 13: 13 14271,8i 140" } */
-  printf("res: %d %f,%fi %d\n",
-	 res_c.a, T_CONV  creal (res_c.b), T_CONV  cimag (res_c.b), res_c.c);
-  /* { dg-output "\nres: 13 14271,8i 140" } */
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
-
-  res_c = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_c, f_c);
-  /* { dg-output "\n12 4951,7i 127 1 9320,1i 13: 13 14271,8i 140" } */
-  printf("res: %d %f,%fi %d\n",
-	 res_c.a, T_CONV  creal (res_c.b), T_CONV  cimag (res_c.b), res_c.c);
-  /* { dg-output "\nres: 13 14271,8i 140" } */
-
-  exit(0);
-}
diff --git a/testsuite/libffi.complex/cls_align_complex_double.c b/testsuite/libffi.complex/cls_align_complex_double.c
deleted file mode 100644
index 0dff23a..0000000
--- a/testsuite/libffi.complex/cls_align_complex_double.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_double.inc"
-#include "cls_align_complex.inc"
diff --git a/testsuite/libffi.complex/cls_align_complex_float.c b/testsuite/libffi.complex/cls_align_complex_float.c
deleted file mode 100644
index 0affbd0..0000000
--- a/testsuite/libffi.complex/cls_align_complex_float.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_float.inc"
-#include "cls_align_complex.inc"
diff --git a/testsuite/libffi.complex/cls_align_complex_longdouble.c b/testsuite/libffi.complex/cls_align_complex_longdouble.c
deleted file mode 100644
index 7889ba8..0000000
--- a/testsuite/libffi.complex/cls_align_complex_longdouble.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check structure alignment of complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_longdouble.inc"
-#include "cls_align_complex.inc"
diff --git a/testsuite/libffi.complex/cls_complex.inc b/testsuite/libffi.complex/cls_complex.inc
deleted file mode 100644
index f937404..0000000
--- a/testsuite/libffi.complex/cls_complex.inc
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*-c-*- */
-#include "ffitest.h"
-#include <complex.h>
-
-static void cls_ret_complex_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
-			      void* userdata __UNUSED__)
- {
-   _Complex T_C_TYPE *pa;
-   _Complex T_C_TYPE *pr;
-   pa = (_Complex T_C_TYPE *)args[0];
-   pr = (_Complex T_C_TYPE *)resp;
-   *pr = *pa;
-
-   printf("%.6f,%.6fi: %.6f,%.6fi\n",
-	  T_CONV creal (*pa), T_CONV cimag (*pa),
-	  T_CONV creal (*pr), T_CONV cimag (*pr));
- }
-typedef _Complex T_C_TYPE (*cls_ret_complex)(_Complex T_C_TYPE);
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type * cl_arg_types[2];
-  _Complex T_C_TYPE res;
-
-  cl_arg_types[0] = &T_FFI_TYPE;
-  cl_arg_types[1] = NULL;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &T_FFI_TYPE, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_complex_fn, NULL, code)  == FFI_OK);
-
-  res = (*((cls_ret_complex)code))(0.125 + 128.0 * I);
-  printf("res: %.6f,%.6fi\n", T_CONV creal (res), T_CONV cimag (res));
-  CHECK (res == (0.125 + 128.0 * I));
-
-  exit(0);
-}
diff --git a/testsuite/libffi.complex/cls_complex_double.c b/testsuite/libffi.complex/cls_complex_double.c
deleted file mode 100644
index 05e3534..0000000
--- a/testsuite/libffi.complex/cls_complex_double.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_double.inc"
-#include "cls_complex.inc"
diff --git a/testsuite/libffi.complex/cls_complex_float.c b/testsuite/libffi.complex/cls_complex_float.c
deleted file mode 100644
index 5df7849..0000000
--- a/testsuite/libffi.complex/cls_complex_float.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_float.inc"
-#include "cls_complex.inc"
diff --git a/testsuite/libffi.complex/cls_complex_longdouble.c b/testsuite/libffi.complex/cls_complex_longdouble.c
deleted file mode 100644
index 2b1c320..0000000
--- a/testsuite/libffi.complex/cls_complex_longdouble.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	closure_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_longdouble.inc"
-#include "cls_complex.inc"
diff --git a/testsuite/libffi.complex/cls_complex_struct.inc b/testsuite/libffi.complex/cls_complex_struct.inc
deleted file mode 100644
index df8708d..0000000
--- a/testsuite/libffi.complex/cls_complex_struct.inc
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*-c-*- */
-#include "ffitest.h"
-#include <complex.h>
-
-typedef struct Cs {
-  _Complex T_C_TYPE x;
-  _Complex T_C_TYPE y;
-} Cs;
-
-Cs gc;
-
-void
-closure_test_fn(Cs p)
-{
-  printf("%.1f,%.1fi %.1f,%.1fi\n",
-	 T_CONV creal (p.x), T_CONV cimag (p.x),
-	 T_CONV creal (p.y), T_CONV cimag (p.y));
-  gc = p;
-}
-
-void
-closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
-		void** args, void* userdata __UNUSED__)
-{
-  closure_test_fn(*(Cs*)args[0]);
-}
-
-int main(int argc __UNUSED__, char** argv __UNUSED__)
-{
-  ffi_cif cif;
-
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  ffi_type *cl_arg_types[1];
-
-  ffi_type ts1_type;
-  ffi_type* ts1_type_elements[4];
-
-  Cs arg = { 1.0 + 11.0 * I, 2.0 + 22.0 * I};
-
-  ts1_type.size = 0;
-  ts1_type.alignment = 0;
-  ts1_type.type = FFI_TYPE_STRUCT;
-  ts1_type.elements = ts1_type_elements;
-
-  ts1_type_elements[0] = &T_FFI_TYPE;
-  ts1_type_elements[1] = &T_FFI_TYPE;
-  ts1_type_elements[2] = NULL;
-
-  cl_arg_types[0] = &ts1_type;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &ffi_type_void, cl_arg_types) == FFI_OK);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
-
-  gc.x = 0.0 + 0.0 * I;
-  gc.y = 0.0 + 0.0 * I;
-  ((void*(*)(Cs))(code))(arg);
-  /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */
-  CHECK (gc.x == arg.x && gc.y == arg.y);
-
-  gc.x = 0.0 + 0.0 * I;
-  gc.y = 0.0 + 0.0 * I;
-  closure_test_fn(arg);
-  /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */
-  CHECK (gc.x == arg.x && gc.y == arg.y);
-
-  return 0;
-}
diff --git a/testsuite/libffi.complex/cls_complex_struct_double.c b/testsuite/libffi.complex/cls_complex_struct_double.c
deleted file mode 100644
index ec71346..0000000
--- a/testsuite/libffi.complex/cls_complex_struct_double.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check complex arguments in structs.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_double.inc"
-#include "cls_complex_struct.inc"
diff --git a/testsuite/libffi.complex/cls_complex_struct_float.c b/testsuite/libffi.complex/cls_complex_struct_float.c
deleted file mode 100644
index 96fdf75..0000000
--- a/testsuite/libffi.complex/cls_complex_struct_float.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check complex arguments in structs.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_float.inc"
-#include "cls_complex_struct.inc"
diff --git a/testsuite/libffi.complex/cls_complex_struct_longdouble.c b/testsuite/libffi.complex/cls_complex_struct_longdouble.c
deleted file mode 100644
index 005b467..0000000
--- a/testsuite/libffi.complex/cls_complex_struct_longdouble.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Check complex arguments in structs.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_longdouble.inc"
-#include "cls_complex_struct.inc"
diff --git a/testsuite/libffi.complex/cls_complex_va.inc b/testsuite/libffi.complex/cls_complex_va.inc
deleted file mode 100644
index 8a3e15f..0000000
--- a/testsuite/libffi.complex/cls_complex_va.inc
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*-c-*- */
-#include "ffitest.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <complex.h>
-
-static _Complex T_C_TYPE gComplexValue1 = 1 + 2 * I;
-static _Complex T_C_TYPE gComplexValue2 = 3 + 4 * I;
-
-static int cls_variadic(const char *format, ...)
-{
-  va_list ap;
-  _Complex T_C_TYPE p1, p2;
-
-  va_start (ap, format);
-  p1 = va_arg (ap, _Complex T_C_TYPE);
-  p2 = va_arg (ap, _Complex T_C_TYPE);
-  va_end (ap);
-
-  return printf(format, T_CONV creal (p1), T_CONV cimag (p1),
-		T_CONV creal (p2), T_CONV cimag (p2));
-}
-
-static void
-cls_complex_va_fn(ffi_cif* cif __UNUSED__, void* resp,
-		  void** args, void* userdata __UNUSED__)
-{
-  char*	format = *(char**)args[0];
-  gComplexValue1 = *(_Complex T_C_TYPE*)args[1];
-  gComplexValue2 = *(_Complex T_C_TYPE*)args[2];
-
-  *(ffi_arg*)resp =
-    printf(format,
-	   T_CONV creal (gComplexValue1), T_CONV cimag (gComplexValue1),
-	   T_CONV creal (gComplexValue2), T_CONV cimag (gComplexValue2));
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  void *code;
-  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
-  void* args[4];
-  ffi_type* arg_types[4];
-  char *format = "%.1f,%.1fi %.1f,%.1fi\n";
-
-  _Complex T_C_TYPE complexArg1 = 1.0 + 22.0 *I;
-  _Complex T_C_TYPE complexArg2 = 333.0 + 4444.0 *I;
-  ffi_arg res = 0;
-
-  arg_types[0] = &ffi_type_pointer;
-  arg_types[1] = &T_FFI_TYPE;
-  arg_types[2] = &T_FFI_TYPE;
-  arg_types[3] = NULL;
-
-  /* This printf call is variadic */
-  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 3, &ffi_type_sint,
-			 arg_types) == FFI_OK);
-
-  args[0] = &format;
-  args[1] = &complexArg1;
-  args[2] = &complexArg2;
-  args[3] = NULL;
-
-  ffi_call(&cif, FFI_FN(cls_variadic), &res, args);
-  printf("res: %d\n", (int) res);
-  CHECK (res == 24);
-
-  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_complex_va_fn, NULL, code)
-	== FFI_OK);
-
-  res = ((int(*)(char *, ...))(code))(format, complexArg1, complexArg2);
-  CHECK (gComplexValue1 == complexArg1);
-  CHECK (gComplexValue2 == complexArg2);
-  printf("res: %d\n", (int) res);
-  CHECK (res == 24);
-
-  exit(0);
-}
diff --git a/testsuite/libffi.complex/cls_complex_va_double.c b/testsuite/libffi.complex/cls_complex_va_double.c
deleted file mode 100644
index 879ccf3..0000000
--- a/testsuite/libffi.complex/cls_complex_va_double.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Test complex' passed in variable argument lists.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_double.inc"
-#include "cls_complex_va.inc"
diff --git a/testsuite/libffi.complex/cls_complex_va_float.c b/testsuite/libffi.complex/cls_complex_va_float.c
deleted file mode 100644
index 2b17826..0000000
--- a/testsuite/libffi.complex/cls_complex_va_float.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Test complex' passed in variable argument lists.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-/* Alpha splits _Complex into two arguments.  It's illegal to pass
-   float through varargs, so _Complex float goes badly.  In sort of
-   gets passed as _Complex double, but the compiler doesn't agree
-   with itself on this issue.  */
-/* { dg-do run { xfail alpha*-*-* } } */
-
-#include "complex_defs_float.inc"
-#include "cls_complex_va.inc"
diff --git a/testsuite/libffi.complex/cls_complex_va_longdouble.c b/testsuite/libffi.complex/cls_complex_va_longdouble.c
deleted file mode 100644
index 6eca965..0000000
--- a/testsuite/libffi.complex/cls_complex_va_longdouble.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call, closure_call
-   Purpose:	Test complex' passed in variable argument lists.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_longdouble.inc"
-#include "cls_complex_va.inc"
diff --git a/testsuite/libffi.complex/complex.exp b/testsuite/libffi.complex/complex.exp
deleted file mode 100644
index 4631db2..0000000
--- a/testsuite/libffi.complex/complex.exp
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-dg-init
-libffi-init
-
-global srcdir subdir
-
-set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]]
-
-if { [libffi_feature_test "#ifdef FFI_TARGET_HAS_COMPLEX_TYPE"] } {
-    run-many-tests $tlist ""
-} else {
-    foreach test $tlist {
-	unsupported "$test"
-    }
-}
-
-dg-finish
-
-# Local Variables:
-# tcl-indent-level:4
-# End:
diff --git a/testsuite/libffi.complex/complex.inc b/testsuite/libffi.complex/complex.inc
deleted file mode 100644
index 515ae3e..0000000
--- a/testsuite/libffi.complex/complex.inc
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*-c-*-*/
-#include "ffitest.h"
-#include <complex.h>
-
-static _Complex T_C_TYPE f_complex(_Complex T_C_TYPE c, int x, int *py)
-{
-  c = -(2 * creal (c)) + (cimag (c) + 1)* I;
-  *py += x;
-
-  return c;
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  ffi_type *args[MAX_ARGS];
-  void *values[MAX_ARGS];
-
-  _Complex T_C_TYPE tc_arg;
-  _Complex T_C_TYPE tc_result;
-  int tc_int_arg_x;
-  int tc_y;
-  int *tc_ptr_arg_y = &tc_y;
-
-  args[0] = &T_FFI_TYPE;
-  args[1] = &ffi_type_sint;
-  args[2] = &ffi_type_pointer;
-  values[0] = &tc_arg;
-  values[1] = &tc_int_arg_x;
-  values[2] = &tc_ptr_arg_y;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
-		     &T_FFI_TYPE, args) == FFI_OK);
-
-  tc_arg = 1 + 7 * I;
-  tc_int_arg_x = 1234;
-  tc_y = 9876;
-  ffi_call(&cif, FFI_FN(f_complex), &tc_result, values);
-
-  printf ("%f,%fi %f,%fi, x %d 1234, y %d 11110\n",
-	  T_CONV creal (tc_result), T_CONV cimag (tc_result),
-	  T_CONV creal (2.0), T_CONV creal (8.0), tc_int_arg_x, tc_y);
-
-  CHECK (creal (tc_result) == -2);
-  CHECK (cimag (tc_result) == 8);
-  CHECK (tc_int_arg_x == 1234);
-  CHECK (*tc_ptr_arg_y == 11110);
-
-  exit(0);
-}
diff --git a/testsuite/libffi.complex/complex_defs_double.inc b/testsuite/libffi.complex/complex_defs_double.inc
deleted file mode 100644
index 3583e16..0000000
--- a/testsuite/libffi.complex/complex_defs_double.inc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* -*-c-*- */
-/* Complex base type.  */
-#define T_FFI_TYPE ffi_type_complex_double
-/* C type corresponding to the base type.  */
-#define T_C_TYPE double
-/* C cast for a value of type T_C_TYPE that is passed to printf.  */
-#define T_CONV
diff --git a/testsuite/libffi.complex/complex_defs_float.inc b/testsuite/libffi.complex/complex_defs_float.inc
deleted file mode 100644
index bbd9375..0000000
--- a/testsuite/libffi.complex/complex_defs_float.inc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* -*-c-*- */
-/* Complex base type.  */
-#define T_FFI_TYPE ffi_type_complex_float
-/* C type corresponding to the base type.  */
-#define T_C_TYPE float
-/* C cast for a value of type T_C_TYPE that is passed to printf.  */
-#define T_CONV (double)
diff --git a/testsuite/libffi.complex/complex_defs_longdouble.inc b/testsuite/libffi.complex/complex_defs_longdouble.inc
deleted file mode 100644
index 14b9f24..0000000
--- a/testsuite/libffi.complex/complex_defs_longdouble.inc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* -*-c-*- */
-/* Complex base type.  */
-#define T_FFI_TYPE ffi_type_complex_longdouble
-/* C type corresponding to the base type.  */
-#define T_C_TYPE long double
-/* C cast for a value of type T_C_TYPE that is passed to printf.  */
-#define T_CONV
diff --git a/testsuite/libffi.complex/complex_double.c b/testsuite/libffi.complex/complex_double.c
deleted file mode 100644
index 8a3297b..0000000
--- a/testsuite/libffi.complex/complex_double.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check complex types.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_double.inc"
-#include "complex.inc"
diff --git a/testsuite/libffi.complex/complex_float.c b/testsuite/libffi.complex/complex_float.c
deleted file mode 100644
index 5044ebb..0000000
--- a/testsuite/libffi.complex/complex_float.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check complex types.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_float.inc"
-#include "complex.inc"
diff --git a/testsuite/libffi.complex/complex_int.c b/testsuite/libffi.complex/complex_int.c
deleted file mode 100644
index bac3190..0000000
--- a/testsuite/libffi.complex/complex_int.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check non-standard complex types.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "ffitest.h"
-#include "ffi.h"
-#include <complex.h>
-
-_Complex int f_complex(_Complex int c, int x, int *py)
-{
-  __real__ c = -2 * __real__ c;
-  __imag__ c = __imag__ c + 1;
-  *py += x;
-  return c;
-}
-
-/*
- * This macro can be used to define new complex type descriptors
- * in a platform independent way.
- *
- * name: Name of the new descriptor is ffi_type_complex_<name>.
- * type: The C base type of the complex type.
- */
-#define FFI_COMPLEX_TYPEDEF(name, type, ffitype)	     \
-  static ffi_type *ffi_elements_complex_##name [2] = {	     \
-    (ffi_type *)(&ffitype), NULL			     \
-  };							     \
-  struct struct_align_complex_##name {			     \
-    char c;						     \
-    _Complex type x;					     \
-  };							     \
-  ffi_type ffi_type_complex_##name = {		     \
-    sizeof(_Complex type),				     \
-    offsetof(struct struct_align_complex_##name, x),	     \
-    FFI_TYPE_COMPLEX,					     \
-    (ffi_type **)ffi_elements_complex_##name		     \
-  }
-
-/* Define new complex type descriptors using the macro: */
-/* ffi_type_complex_sint */
-FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint);
-/* ffi_type_complex_uchar */
-FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8);
-
-int main (void)
-{
-  ffi_cif cif;
-  ffi_type *args[MAX_ARGS];
-  void *values[MAX_ARGS];
-
-  _Complex int tc_arg;
-  _Complex int tc_result;
-  int tc_int_arg_x;
-  int tc_y;
-  int *tc_ptr_arg_y = &tc_y;
-
-  args[0] = &ffi_type_complex_sint;
-  args[1] = &ffi_type_sint;
-  args[2] = &ffi_type_pointer;
-  values[0] = &tc_arg;
-  values[1] = &tc_int_arg_x;
-  values[2] = &tc_ptr_arg_y;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_complex_sint, args)
-	== FFI_OK);
-
-  tc_arg = 1 + 7 * I;
-  tc_int_arg_x = 1234;
-  tc_y = 9876;
-  ffi_call(&cif, FFI_FN(f_complex), &tc_result, values);
-
-  printf ("%d,%di %d,%di, x %d 1234, y %d 11110\n",
-	  (int)tc_result, (int)(tc_result * -I), 2, 8, tc_int_arg_x, tc_y);
-  /* dg-output "-2,8i 2,8i, x 1234 1234, y 11110 11110" */
-  CHECK (creal (tc_result) == -2);
-  CHECK (cimag (tc_result) == 8);
-  CHECK (tc_int_arg_x == 1234);
-  CHECK (*tc_ptr_arg_y == 11110);
-
-  exit(0);
-}
diff --git a/testsuite/libffi.complex/complex_longdouble.c b/testsuite/libffi.complex/complex_longdouble.c
deleted file mode 100644
index 7e78366..0000000
--- a/testsuite/libffi.complex/complex_longdouble.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check complex types.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_longdouble.inc"
-#include "complex.inc"
diff --git a/testsuite/libffi.complex/ffitest.h b/testsuite/libffi.complex/ffitest.h
deleted file mode 100644
index d27d362..0000000
--- a/testsuite/libffi.complex/ffitest.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../libffi.call/ffitest.h"
diff --git a/testsuite/libffi.complex/many_complex.inc b/testsuite/libffi.complex/many_complex.inc
deleted file mode 100644
index e37a774..0000000
--- a/testsuite/libffi.complex/many_complex.inc
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*-c-*- */
-#include "ffitest.h"
-
-#include <stdlib.h>
-#include <complex.h>
-
-static _Complex T_C_TYPE many(_Complex T_C_TYPE c1,
-			      _Complex T_C_TYPE c2,
-			      _Complex T_C_TYPE c3,
-			      _Complex T_C_TYPE c4,
-			      _Complex T_C_TYPE c5,
-			      _Complex T_C_TYPE c6,
-			      _Complex T_C_TYPE c7,
-			      _Complex T_C_TYPE c8,
-			      _Complex T_C_TYPE c9,
-			      _Complex T_C_TYPE c10,
-			      _Complex T_C_TYPE c11,
-			      _Complex T_C_TYPE c12,
-			      _Complex T_C_TYPE c13)
-{
-  printf("0 :%f,%fi\n"
-	 "1 :%f,%fi\n"
-	 "2 :%f,%fi\n"
-	 "3 :%f,%fi\n"
-	 "4 :%f,%fi\n"
-	 "5 :%f,%fi\n"
-	 "6 :%f,%fi\n"
-	 "7 :%f,%fi\n"
-	 "8 :%f,%fi\n"
-	 "9 :%f,%fi\n"
-	 "10:%f,%fi\n"
-	 "11:%f,%fi\n"
-	 "12:%f,%fi\n",
-	 T_CONV creal (c1), T_CONV cimag (c1),
-	 T_CONV creal (c2), T_CONV cimag (c2),
-	 T_CONV creal (c3), T_CONV cimag (c3),
-	 T_CONV creal (c4), T_CONV cimag (c4),
-	 T_CONV creal (c5), T_CONV cimag (c5),
-	 T_CONV creal (c6), T_CONV cimag (c6),
-	 T_CONV creal (c7), T_CONV cimag (c7),
-	 T_CONV creal (c8), T_CONV cimag (c8),
-	 T_CONV creal (c9), T_CONV cimag (c9),
-	 T_CONV creal (c10), T_CONV cimag (c10),
-	 T_CONV creal (c11), T_CONV cimag (c11),
-	 T_CONV creal (c12), T_CONV cimag (c12),
-	 T_CONV creal (c13), T_CONV cimag (c13));
-
-  return (c1+c2-c3-c4+c5+c6+c7-c8-c9-c10-c11+c12+c13);
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  ffi_type *args[13];
-  void *values[13];
-  _Complex T_C_TYPE ca[13];
-  _Complex T_C_TYPE c, cc;
-  int i;
-
-  for (i = 0; i < 13; i++)
-    {
-      args[i] = &T_FFI_TYPE;
-      values[i] = &ca[i];
-      ca[i] = i + (-20 - i) * I;
-    }
-
-    /* Initialize the cif */
-    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, &T_FFI_TYPE, args) == FFI_OK);
-
-    ffi_call(&cif, FFI_FN(many), &c, values);
-
-    cc =  many(ca[0], ca[1], ca[2], ca[3], ca[4], ca[5], ca[6], ca[7], ca[8],
-	       ca[9], ca[10], ca[11], ca[12]);
-    CHECK(creal (cc) == creal (c));
-    CHECK(cimag (cc) == cimag (c));
-
-    exit(0);
-}
diff --git a/testsuite/libffi.complex/many_complex_double.c b/testsuite/libffi.complex/many_complex_double.c
deleted file mode 100644
index 3fd53c3..0000000
--- a/testsuite/libffi.complex/many_complex_double.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex, with many arguments
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_double.inc"
-#include "many_complex.inc"
diff --git a/testsuite/libffi.complex/many_complex_float.c b/testsuite/libffi.complex/many_complex_float.c
deleted file mode 100644
index c43d21c..0000000
--- a/testsuite/libffi.complex/many_complex_float.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex, with many arguments
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_float.inc"
-#include "many_complex.inc"
diff --git a/testsuite/libffi.complex/many_complex_longdouble.c b/testsuite/libffi.complex/many_complex_longdouble.c
deleted file mode 100644
index dbab723..0000000
--- a/testsuite/libffi.complex/many_complex_longdouble.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex, with many arguments
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_longdouble.inc"
-#include "many_complex.inc"
diff --git a/testsuite/libffi.complex/return_complex.inc b/testsuite/libffi.complex/return_complex.inc
deleted file mode 100644
index 8bf0c1f..0000000
--- a/testsuite/libffi.complex/return_complex.inc
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*-c-*- */
-#include "ffitest.h"
-#include <complex.h>
-
-static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c)
-{
-  printf ("%f,%fi\n", T_CONV creal (c), T_CONV cimag (c));
-  return 2 * c;
-}
-int main (void)
-{
-  ffi_cif cif;
-  ffi_type *args[MAX_ARGS];
-  void *values[MAX_ARGS];
-  _Complex T_C_TYPE c, rc, rc2;
-  T_C_TYPE cr, ci;
-
-  args[0] = &T_FFI_TYPE;
-  values[0] = &c;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
-		     &T_FFI_TYPE, args) == FFI_OK);
-
-  for (cr = -127.0; cr <  127; cr++)
-    {
-      ci = 1000.0 - cr;
-      c = cr + ci * I;
-      ffi_call(&cif, FFI_FN(return_c), &rc, values);
-      rc2 = return_c(c);
-      printf ("%f,%fi vs %f,%fi\n",
-	      T_CONV creal (rc), T_CONV cimag (rc),
-	      T_CONV creal (rc2), T_CONV cimag (rc2));
-      CHECK(rc == 2 * c);
-    }
-  exit(0);
-}
diff --git a/testsuite/libffi.complex/return_complex1.inc b/testsuite/libffi.complex/return_complex1.inc
deleted file mode 100644
index 7cecc0f..0000000
--- a/testsuite/libffi.complex/return_complex1.inc
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*-c-*- */
-#include "ffitest.h"
-#include <complex.h>
-
-static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c1, float fl2, unsigned int in3, _Complex T_C_TYPE c4)
-{
-  return c1 + fl2 + in3 + c4;
-}
-int main (void)
-{
-  ffi_cif cif;
-  ffi_type *args[MAX_ARGS];
-  void *values[MAX_ARGS];
-  _Complex T_C_TYPE c1, c4, rc, rc2;
-  float fl2;
-  unsigned int in3;
-  args[0] = &T_FFI_TYPE;
-  args[1] = &ffi_type_float;
-  args[2] = &ffi_type_uint;
-  args[3] = &T_FFI_TYPE;
-  values[0] = &c1;
-  values[1] = &fl2;
-  values[2] = &in3;
-  values[3] = &c4;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
-		     &T_FFI_TYPE, args) == FFI_OK);
-  c1 = 127.0 + 255.0 * I;
-  fl2 = 128.0;
-  in3 = 255;
-  c4 = 512.7 + 1024.1 * I;
-
-  ffi_call(&cif, FFI_FN(return_c), &rc, values);
-  rc2 = return_c(c1, fl2, in3, c4);
-  printf ("%f,%fi vs %f,%fi\n",
-	  T_CONV creal (rc), T_CONV cimag (rc),
-	  T_CONV creal (rc2), T_CONV cimag (rc2));
-  CHECK(rc == rc2);
-  exit(0);
-}
diff --git a/testsuite/libffi.complex/return_complex1_double.c b/testsuite/libffi.complex/return_complex1_double.c
deleted file mode 100644
index 727410d..0000000
--- a/testsuite/libffi.complex/return_complex1_double.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_double.inc"
-#include "return_complex1.inc"
diff --git a/testsuite/libffi.complex/return_complex1_float.c b/testsuite/libffi.complex/return_complex1_float.c
deleted file mode 100644
index a2aeada..0000000
--- a/testsuite/libffi.complex/return_complex1_float.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_float.inc"
-#include "return_complex1.inc"
diff --git a/testsuite/libffi.complex/return_complex1_longdouble.c b/testsuite/libffi.complex/return_complex1_longdouble.c
deleted file mode 100644
index 103504b..0000000
--- a/testsuite/libffi.complex/return_complex1_longdouble.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_longdouble.inc"
-#include "return_complex1.inc"
diff --git a/testsuite/libffi.complex/return_complex2.inc b/testsuite/libffi.complex/return_complex2.inc
deleted file mode 100644
index 265170b..0000000
--- a/testsuite/libffi.complex/return_complex2.inc
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*-c-*- */
-#include "ffitest.h"
-#include <complex.h>
-
-_Complex T_C_TYPE
-return_c(_Complex T_C_TYPE c1, _Complex T_C_TYPE c2,
-	 unsigned int in3, _Complex T_C_TYPE c4)
-{
-  volatile _Complex T_C_TYPE r = c1 + c2 + in3 + c4;
-  return r;
-}
-
-int main (void)
-{
-  ffi_cif cif;
-  ffi_type *args[MAX_ARGS];
-  void *values[MAX_ARGS];
-  _Complex T_C_TYPE c1, c2, c4, rc, rc2;
-  unsigned int in3;
-  args[0] = &T_FFI_TYPE;
-  args[1] = &T_FFI_TYPE;
-  args[2] = &ffi_type_uint;
-  args[3] = &T_FFI_TYPE;
-  values[0] = &c1;
-  values[1] = &c2;
-  values[2] = &in3;
-  values[3] = &c4;
-
-  /* Initialize the cif */
-  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
-		     &T_FFI_TYPE, args) == FFI_OK);
-  c1 = 127.0 + 255.0 * I;
-  c2 = 128.0 + 256.0;
-  in3 = 255;
-  c4 = 512.7 + 1024.1 * I;
-
-  ffi_call(&cif, FFI_FN(return_c), &rc, values);
-  rc2 = return_c(c1, c2, in3, c4);
-  printf ("%f,%fi vs %f,%fi\n",
-	  T_CONV creal (rc), T_CONV cimag (rc),
-	  T_CONV creal (rc2), T_CONV cimag (rc2));
-  CHECK(rc == rc2);
-  exit(0);
-}
diff --git a/testsuite/libffi.complex/return_complex2_double.c b/testsuite/libffi.complex/return_complex2_double.c
deleted file mode 100644
index ab9efac..0000000
--- a/testsuite/libffi.complex/return_complex2_double.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_double.inc"
-#include "return_complex2.inc"
diff --git a/testsuite/libffi.complex/return_complex2_float.c b/testsuite/libffi.complex/return_complex2_float.c
deleted file mode 100644
index d7f22c2..0000000
--- a/testsuite/libffi.complex/return_complex2_float.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_float.inc"
-#include "return_complex2.inc"
diff --git a/testsuite/libffi.complex/return_complex2_longdouble.c b/testsuite/libffi.complex/return_complex2_longdouble.c
deleted file mode 100644
index 3edea62..0000000
--- a/testsuite/libffi.complex/return_complex2_longdouble.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_longdouble.inc"
-#include "return_complex2.inc"
diff --git a/testsuite/libffi.complex/return_complex_double.c b/testsuite/libffi.complex/return_complex_double.c
deleted file mode 100644
index e2497cc..0000000
--- a/testsuite/libffi.complex/return_complex_double.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_double.inc"
-#include "return_complex.inc"
diff --git a/testsuite/libffi.complex/return_complex_float.c b/testsuite/libffi.complex/return_complex_float.c
deleted file mode 100644
index a35528f..0000000
--- a/testsuite/libffi.complex/return_complex_float.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_float.inc"
-#include "return_complex.inc"
diff --git a/testsuite/libffi.complex/return_complex_longdouble.c b/testsuite/libffi.complex/return_complex_longdouble.c
deleted file mode 100644
index 142d7be..0000000
--- a/testsuite/libffi.complex/return_complex_longdouble.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Area:	ffi_call
-   Purpose:	Check return value complex.
-   Limitations:	none.
-   PR:		none.
-   Originator:	<vogt@linux.vnet.ibm.com>.  */
-
-/* { dg-do run } */
-
-#include "complex_defs_longdouble.inc"
-#include "return_complex.inc"
diff --git a/testsuite/libffi.go/aa-direct.c b/testsuite/libffi.go/aa-direct.c
deleted file mode 100644
index b00c404..0000000
--- a/testsuite/libffi.go/aa-direct.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* { dg-do run } */
-
-#include "static-chain.h"
-
-#if defined(__GNUC__) && !defined(__clang__) && defined(STATIC_CHAIN_REG)
-
-#include "ffitest.h"
-
-/* Blatent assumption here that the prologue doesn't clobber the
-   static chain for trivial functions.  If this is not true, don't
-   define STATIC_CHAIN_REG, and we'll test what we can via other tests.  */
-void *doit(void)
-{
-  register void *chain __asm__(STATIC_CHAIN_REG);
-  return chain;
-}
-
-int main()
-{
-  ffi_cif cif;
-  void *result;
-
-  CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK);
-
-  ffi_call_go(&cif, FFI_FN(doit), &result, NULL, &result);
-
-  CHECK(result == &result);
-
-  return 0;
-}
-
-#else /* UNSUPPORTED */
-int main() { return 0; }
-#endif
diff --git a/testsuite/libffi.go/closure1.c b/testsuite/libffi.go/closure1.c
deleted file mode 100644
index 7b34afc..0000000
--- a/testsuite/libffi.go/closure1.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* { dg-do run } */
-
-#include "ffitest.h"
-
-void doit(ffi_cif *cif, void *rvalue, void **avalue, void *closure)
-{
-  (void)cif;
-  (void)avalue;
-  *(void **)rvalue = closure;
-}
-
-typedef void * (*FN)(void);
-
-int main()
-{
-  ffi_cif cif;
-  ffi_go_closure cl;
-  void *result;
-
-  CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK);
-  CHECK(ffi_prep_go_closure(&cl, &cif, doit) == FFI_OK);
-
-  ffi_call_go(&cif, FFI_FN(*(FN *)&cl), &result, NULL, &cl);
-
-  CHECK(result == &cl);
-
-  exit(0);
-}
diff --git a/testsuite/libffi.go/ffitest.h b/testsuite/libffi.go/ffitest.h
deleted file mode 100644
index d27d362..0000000
--- a/testsuite/libffi.go/ffitest.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../libffi.call/ffitest.h"
diff --git a/testsuite/libffi.go/go.exp b/testsuite/libffi.go/go.exp
deleted file mode 100644
index 100c5e7..0000000
--- a/testsuite/libffi.go/go.exp
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-dg-init
-libffi-init
-
-global srcdir subdir
-
-set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]]
-
-if { [libffi_feature_test "#ifdef FFI_GO_CLOSURES"] } {
-    run-many-tests $tlist ""
-} else {
-    foreach test $tlist {
-	unsupported "$test"
-    }
-}
-
-dg-finish
-
-# Local Variables:
-# tcl-indent-level:4
-# End:
diff --git a/testsuite/libffi.go/static-chain.h b/testsuite/libffi.go/static-chain.h
deleted file mode 100644
index 3675b40..0000000
--- a/testsuite/libffi.go/static-chain.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifdef __aarch64__
-# define STATIC_CHAIN_REG  "x18"
-#elif defined(__alpha__)
-# define STATIC_CHAIN_REG  "$1"
-#elif defined(__arm__)
-# define STATIC_CHAIN_REG  "ip"
-#elif defined(__sparc__)
-# if defined(__arch64__) || defined(__sparcv9)
-#  define STATIC_CHAIN_REG "g5"
-# else
-#  define STATIC_CHAIN_REG "g2"
-# endif
-#elif defined(__x86_64__)
-# define STATIC_CHAIN_REG  "r10"
-#elif defined(__i386__)
-# ifndef ABI_NUM
-#  define STATIC_CHAIN_REG  "ecx"	/* FFI_DEFAULT_ABI only */
-# endif
-#endif