Commit c4f17c6f by Ulrich Weigand Committed by Ulrich Weigand

configure.in: Add s390x-*-linux-* target.

	* 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.

From-SVN: r57646
parent b93a0fe6
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> 2002-09-29 Richard Earnshaw <rearnsha@arm.com>
* src/arm/sysv.S: Fix typo. * src/arm/sysv.S: Fix typo.
......
...@@ -2431,6 +2431,7 @@ powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; ...@@ -2431,6 +2431,7 @@ powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;;
x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;; x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;;
sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;; sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;;
esac esac
...@@ -2589,7 +2590,7 @@ if test x$TARGET = xMIPS_LINUX; then ...@@ -2589,7 +2590,7 @@ if test x$TARGET = xMIPS_LINUX; then
fi fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:2593: checking how to run the C preprocessor" >&5 echo "configure:2594: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory. # On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then if test -n "$CPP" && test -d "$CPP"; then
CPP= CPP=
...@@ -2604,13 +2605,13 @@ else ...@@ -2604,13 +2605,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser, # On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. # not just through cpp.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2608 "configure" #line 2609 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2614: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:2615: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
...@@ -2621,13 +2622,13 @@ else ...@@ -2621,13 +2622,13 @@ else
rm -rf conftest* rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp" CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2625 "configure" #line 2626 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2631: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:2632: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
...@@ -2638,13 +2639,13 @@ else ...@@ -2638,13 +2639,13 @@ else
rm -rf conftest* rm -rf conftest*
CPP="${CC-cc} -nologo -E" CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2642 "configure" #line 2643 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2648: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:2649: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
...@@ -2669,12 +2670,12 @@ fi ...@@ -2669,12 +2670,12 @@ fi
echo "$ac_t""$CPP" 1>&6 echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
echo "configure:2673: checking for ANSI C header files" >&5 echo "configure:2674: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2678 "configure" #line 2679 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
...@@ -2682,7 +2683,7 @@ else ...@@ -2682,7 +2683,7 @@ else
#include <float.h> #include <float.h>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2686: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:2687: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
...@@ -2699,7 +2700,7 @@ rm -f conftest* ...@@ -2699,7 +2700,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI. # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2703 "configure" #line 2704 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <string.h> #include <string.h>
EOF EOF
...@@ -2717,7 +2718,7 @@ fi ...@@ -2717,7 +2718,7 @@ fi
if test $ac_cv_header_stdc = yes; then if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2721 "configure" #line 2722 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <stdlib.h> #include <stdlib.h>
EOF EOF
...@@ -2738,7 +2739,7 @@ if test "$cross_compiling" = yes; then ...@@ -2738,7 +2739,7 @@ if test "$cross_compiling" = yes; then
: :
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2742 "configure" #line 2743 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <ctype.h> #include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
...@@ -2749,7 +2750,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); ...@@ -2749,7 +2750,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); } exit (0); }
EOF EOF
if { (eval echo configure:2753: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null if { (eval echo configure:2754: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then then
: :
else else
...@@ -2775,12 +2776,12 @@ fi ...@@ -2775,12 +2776,12 @@ fi
for ac_func in memcpy for ac_func in memcpy
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2779: checking for $ac_func" >&5 echo "configure:2780: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2784 "configure" #line 2785 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -2803,7 +2804,7 @@ $ac_func(); ...@@ -2803,7 +2804,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2807: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2808: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -2830,19 +2831,19 @@ done ...@@ -2830,19 +2831,19 @@ done
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
# for constant arguments. Useless! # for constant arguments. Useless!
echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
echo "configure:2834: checking for working alloca.h" >&5 echo "configure:2835: checking for working alloca.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2839 "configure" #line 2840 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <alloca.h> #include <alloca.h>
int main() { int main() {
char *p = alloca(2 * sizeof(int)); char *p = alloca(2 * sizeof(int));
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2846: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2847: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
ac_cv_header_alloca_h=yes ac_cv_header_alloca_h=yes
else else
...@@ -2863,12 +2864,12 @@ EOF ...@@ -2863,12 +2864,12 @@ EOF
fi fi
echo $ac_n "checking for alloca""... $ac_c" 1>&6 echo $ac_n "checking for alloca""... $ac_c" 1>&6
echo "configure:2867: checking for alloca" >&5 echo "configure:2868: checking for alloca" >&5
if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2872 "configure" #line 2873 "configure"
#include "confdefs.h" #include "confdefs.h"
#ifdef __GNUC__ #ifdef __GNUC__
...@@ -2896,7 +2897,7 @@ int main() { ...@@ -2896,7 +2897,7 @@ int main() {
char *p = (char *) alloca(1); char *p = (char *) alloca(1);
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2900: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2901: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
ac_cv_func_alloca_works=yes ac_cv_func_alloca_works=yes
else else
...@@ -2928,12 +2929,12 @@ EOF ...@@ -2928,12 +2929,12 @@ EOF
echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
echo "configure:2932: checking whether alloca needs Cray hooks" >&5 echo "configure:2933: checking whether alloca needs Cray hooks" >&5
if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2937 "configure" #line 2938 "configure"
#include "confdefs.h" #include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2) #if defined(CRAY) && ! defined(CRAY2)
webecray webecray
...@@ -2958,12 +2959,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6 ...@@ -2958,12 +2959,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
if test $ac_cv_os_cray = yes; then if test $ac_cv_os_cray = yes; then
for ac_func in _getb67 GETB67 getb67; do for ac_func in _getb67 GETB67 getb67; do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2962: checking for $ac_func" >&5 echo "configure:2963: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2967 "configure" #line 2968 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
...@@ -2986,7 +2987,7 @@ $ac_func(); ...@@ -2986,7 +2987,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2991: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
...@@ -3013,7 +3014,7 @@ done ...@@ -3013,7 +3014,7 @@ done
fi fi
echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
echo "configure:3017: checking stack direction for C alloca" >&5 echo "configure:3018: checking stack direction for C alloca" >&5
if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -3021,7 +3022,7 @@ else ...@@ -3021,7 +3022,7 @@ else
ac_cv_c_stack_direction=0 ac_cv_c_stack_direction=0
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3025 "configure" #line 3026 "configure"
#include "confdefs.h" #include "confdefs.h"
find_stack_direction () find_stack_direction ()
{ {
...@@ -3040,7 +3041,7 @@ main () ...@@ -3040,7 +3041,7 @@ main ()
exit (find_stack_direction() < 0); exit (find_stack_direction() < 0);
} }
EOF EOF
if { (eval echo configure:3044: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null if { (eval echo configure:3045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then then
ac_cv_c_stack_direction=1 ac_cv_c_stack_direction=1
else else
...@@ -3063,13 +3064,13 @@ fi ...@@ -3063,13 +3064,13 @@ fi
echo $ac_n "checking size of short""... $ac_c" 1>&6 echo $ac_n "checking size of short""... $ac_c" 1>&6
echo "configure:3067: checking size of short" >&5 echo "configure:3068: checking size of short" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence. for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3073 "configure" #line 3074 "configure"
#include "confdefs.h" #include "confdefs.h"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -3079,7 +3080,7 @@ int main() { ...@@ -3079,7 +3080,7 @@ int main() {
switch (0) case 0: case (sizeof (short) == $ac_size):; switch (0) case 0: case (sizeof (short) == $ac_size):;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3083: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3084: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_sizeof_short=$ac_size ac_cv_sizeof_short=$ac_size
else else
...@@ -3102,13 +3103,13 @@ EOF ...@@ -3102,13 +3103,13 @@ EOF
echo $ac_n "checking size of int""... $ac_c" 1>&6 echo $ac_n "checking size of int""... $ac_c" 1>&6
echo "configure:3106: checking size of int" >&5 echo "configure:3107: checking size of int" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence. for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3112 "configure" #line 3113 "configure"
#include "confdefs.h" #include "confdefs.h"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -3118,7 +3119,7 @@ int main() { ...@@ -3118,7 +3119,7 @@ int main() {
switch (0) case 0: case (sizeof (int) == $ac_size):; switch (0) case 0: case (sizeof (int) == $ac_size):;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3122: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3123: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_sizeof_int=$ac_size ac_cv_sizeof_int=$ac_size
else else
...@@ -3141,13 +3142,13 @@ EOF ...@@ -3141,13 +3142,13 @@ EOF
echo $ac_n "checking size of long""... $ac_c" 1>&6 echo $ac_n "checking size of long""... $ac_c" 1>&6
echo "configure:3145: checking size of long" >&5 echo "configure:3146: checking size of long" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence. for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3151 "configure" #line 3152 "configure"
#include "confdefs.h" #include "confdefs.h"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -3157,7 +3158,7 @@ int main() { ...@@ -3157,7 +3158,7 @@ int main() {
switch (0) case 0: case (sizeof (long) == $ac_size):; switch (0) case 0: case (sizeof (long) == $ac_size):;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3161: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3162: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_sizeof_long=$ac_size ac_cv_sizeof_long=$ac_size
else else
...@@ -3180,13 +3181,13 @@ EOF ...@@ -3180,13 +3181,13 @@ EOF
echo $ac_n "checking size of long long""... $ac_c" 1>&6 echo $ac_n "checking size of long long""... $ac_c" 1>&6
echo "configure:3184: checking size of long long" >&5 echo "configure:3185: checking size of long long" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence. for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3190 "configure" #line 3191 "configure"
#include "confdefs.h" #include "confdefs.h"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -3196,7 +3197,7 @@ int main() { ...@@ -3196,7 +3197,7 @@ int main() {
switch (0) case 0: case (sizeof (long long) == $ac_size):; switch (0) case 0: case (sizeof (long long) == $ac_size):;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3200: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3201: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_sizeof_long_long=$ac_size ac_cv_sizeof_long_long=$ac_size
else else
...@@ -3219,13 +3220,13 @@ EOF ...@@ -3219,13 +3220,13 @@ EOF
echo $ac_n "checking size of float""... $ac_c" 1>&6 echo $ac_n "checking size of float""... $ac_c" 1>&6
echo "configure:3223: checking size of float" >&5 echo "configure:3224: checking size of float" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_float'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_sizeof_float'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence. for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3229 "configure" #line 3230 "configure"
#include "confdefs.h" #include "confdefs.h"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -3235,7 +3236,7 @@ int main() { ...@@ -3235,7 +3236,7 @@ int main() {
switch (0) case 0: case (sizeof (float) == $ac_size):; switch (0) case 0: case (sizeof (float) == $ac_size):;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3239: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3240: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_sizeof_float=$ac_size ac_cv_sizeof_float=$ac_size
else else
...@@ -3258,13 +3259,13 @@ EOF ...@@ -3258,13 +3259,13 @@ EOF
echo $ac_n "checking size of double""... $ac_c" 1>&6 echo $ac_n "checking size of double""... $ac_c" 1>&6
echo "configure:3262: checking size of double" >&5 echo "configure:3263: checking size of double" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence. for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3268 "configure" #line 3269 "configure"
#include "confdefs.h" #include "confdefs.h"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -3274,7 +3275,7 @@ int main() { ...@@ -3274,7 +3275,7 @@ int main() {
switch (0) case 0: case (sizeof (double) == $ac_size):; switch (0) case 0: case (sizeof (double) == $ac_size):;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3278: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3279: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_sizeof_double=$ac_size ac_cv_sizeof_double=$ac_size
else else
...@@ -3297,13 +3298,13 @@ EOF ...@@ -3297,13 +3298,13 @@ EOF
echo $ac_n "checking size of long double""... $ac_c" 1>&6 echo $ac_n "checking size of long double""... $ac_c" 1>&6
echo "configure:3301: checking size of long double" >&5 echo "configure:3302: checking size of long double" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long_double'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_sizeof_long_double'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence. for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3307 "configure" #line 3308 "configure"
#include "confdefs.h" #include "confdefs.h"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -3313,7 +3314,7 @@ int main() { ...@@ -3313,7 +3314,7 @@ int main() {
switch (0) case 0: case (sizeof (long double) == $ac_size):; switch (0) case 0: case (sizeof (long double) == $ac_size):;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3317: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3318: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_sizeof_long_double=$ac_size ac_cv_sizeof_long_double=$ac_size
else else
...@@ -3337,13 +3338,13 @@ EOF ...@@ -3337,13 +3338,13 @@ EOF
echo $ac_n "checking size of void *""... $ac_c" 1>&6 echo $ac_n "checking size of void *""... $ac_c" 1>&6
echo "configure:3341: checking size of void *" >&5 echo "configure:3342: checking size of void *" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_void_p'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_sizeof_void_p'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence. for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3347 "configure" #line 3348 "configure"
#include "confdefs.h" #include "confdefs.h"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -3353,7 +3354,7 @@ int main() { ...@@ -3353,7 +3354,7 @@ int main() {
switch (0) case 0: case (sizeof (void *) == $ac_size):; switch (0) case 0: case (sizeof (void *) == $ac_size):;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3357: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3358: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_sizeof_void_p=$ac_size ac_cv_sizeof_void_p=$ac_size
else else
...@@ -3376,14 +3377,14 @@ EOF ...@@ -3376,14 +3377,14 @@ EOF
echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
echo "configure:3380: checking whether byte ordering is bigendian" >&5 echo "configure:3381: checking whether byte ordering is bigendian" >&5
if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
ac_cv_c_bigendian=unknown ac_cv_c_bigendian=unknown
# See if sys/param.h defines the BYTE_ORDER macro. # See if sys/param.h defines the BYTE_ORDER macro.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3387 "configure" #line 3388 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
...@@ -3394,11 +3395,11 @@ int main() { ...@@ -3394,11 +3395,11 @@ int main() {
#endif #endif
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3398: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3399: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
# It does; now see whether it defined to BIG_ENDIAN or not. # It does; now see whether it defined to BIG_ENDIAN or not.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3402 "configure" #line 3403 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
...@@ -3409,7 +3410,7 @@ int main() { ...@@ -3409,7 +3410,7 @@ int main() {
#endif #endif
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3413: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:3414: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_c_bigendian=yes ac_cv_c_bigendian=yes
else else
...@@ -3429,7 +3430,7 @@ if test "$cross_compiling" = yes; then ...@@ -3429,7 +3430,7 @@ if test "$cross_compiling" = yes; then
echo $ac_n "cross-compiling... " 2>&6 echo $ac_n "cross-compiling... " 2>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3433 "configure" #line 3434 "configure"
#include "confdefs.h" #include "confdefs.h"
main () { main () {
/* Are we little or big endian? From Harbison&Steele. */ /* Are we little or big endian? From Harbison&Steele. */
...@@ -3442,7 +3443,7 @@ main () { ...@@ -3442,7 +3443,7 @@ main () {
exit (u.c[sizeof (long) - 1] == 1); exit (u.c[sizeof (long) - 1] == 1);
} }
EOF EOF
if { (eval echo configure:3446: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null if { (eval echo configure:3447: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then then
ac_cv_c_bigendian=no ac_cv_c_bigendian=no
else else
...@@ -3460,7 +3461,7 @@ fi ...@@ -3460,7 +3461,7 @@ fi
echo "$ac_t""$ac_cv_c_bigendian" 1>&6 echo "$ac_t""$ac_cv_c_bigendian" 1>&6
if test $ac_cv_c_bigendian = unknown; then if test $ac_cv_c_bigendian = unknown; then
echo $ac_n "checking to probe for byte ordering""... $ac_c" 1>&6 echo $ac_n "checking to probe for byte ordering""... $ac_c" 1>&6
echo "configure:3464: checking to probe for byte ordering" >&5 echo "configure:3465: checking to probe for byte ordering" >&5
cat >conftest.c <<EOF cat >conftest.c <<EOF
short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
...@@ -3510,7 +3511,7 @@ fi ...@@ -3510,7 +3511,7 @@ fi
if test x$TARGET = xSPARC; then if test x$TARGET = xSPARC; then
echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6 echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6
echo "configure:3514: checking assembler and linker support unaligned pc related relocs" >&5 echo "configure:3515: checking assembler and linker support unaligned pc related relocs" >&5
if eval "test \"`echo '$''{'libffi_cv_as_sparc_ua_pcrel'+set}'`\" = set"; then if eval "test \"`echo '$''{'libffi_cv_as_sparc_ua_pcrel'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -3520,14 +3521,14 @@ else ...@@ -3520,14 +3521,14 @@ else
CFLAGS="$CFLAGS -fpic" CFLAGS="$CFLAGS -fpic"
LDFLAGS="$LDFLAGS -shared" LDFLAGS="$LDFLAGS -shared"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3524 "configure" #line 3525 "configure"
#include "confdefs.h" #include "confdefs.h"
asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text"); asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");
int main() { int main() {
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3532: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
libffi_cv_as_sparc_ua_pcrel=yes libffi_cv_as_sparc_ua_pcrel=yes
else else
......
...@@ -70,6 +70,7 @@ powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; ...@@ -70,6 +70,7 @@ powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;;
x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;; x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;;
sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;; sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;;
esac esac
......
...@@ -164,6 +164,12 @@ extern "C" { ...@@ -164,6 +164,12 @@ extern "C" {
#endif #endif
#endif #endif
#ifdef S390
#if defined (__s390x__)
#define S390X
#endif
#endif
#ifndef LIBFFI_ASM #ifndef LIBFFI_ASM
/* ---- Generic type definitions ----------------------------------------- */ /* ---- Generic type definitions ----------------------------------------- */
...@@ -435,6 +441,16 @@ struct ffi_ia64_trampoline_struct { ...@@ -435,6 +441,16 @@ struct ffi_ia64_trampoline_struct {
#define FFI_TRAMPOLINE_SIZE 24 /* see struct below */ #define FFI_TRAMPOLINE_SIZE 24 /* see struct below */
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0
#elif defined(S390)
#define FFI_CLOSURES 1
#ifdef S390X
#define FFI_TRAMPOLINE_SIZE 32
#else
#define FFI_TRAMPOLINE_SIZE 16
#endif
#define FFI_NATIVE_RAW_API 0
#elif defined(SH) #elif defined(SH)
#define FFI_CLOSURES 1 #define FFI_CLOSURES 1
......
...@@ -103,9 +103,8 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, ...@@ -103,9 +103,8 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
/* Perform a sanity check on the return type */ /* Perform a sanity check on the return type */
FFI_ASSERT(ffi_type_test(cif->rtype)); FFI_ASSERT(ffi_type_test(cif->rtype));
/* x86-64 and s390 stack space allocation is handled in prep_machdep. /* x86-64 and s390 stack space allocation is handled in prep_machdep. */
TODO: Disable this for s390 too? */ #if !defined M68K && !defined __x86_64__ && !defined S390
#if !defined M68K && !defined __x86_64__
/* Make space for the return structure pointer */ /* Make space for the return structure pointer */
if (cif->rtype->type == FFI_TYPE_STRUCT if (cif->rtype->type == FFI_TYPE_STRUCT
#ifdef SPARC #ifdef SPARC
...@@ -124,8 +123,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, ...@@ -124,8 +123,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF; return FFI_BAD_TYPEDEF;
/* TODO: Disable this calculation for s390 too? */ #if !defined __x86_64__ && !defined S390
#ifndef __x86_64__
#ifdef SPARC #ifdef SPARC
if (((*ptr)->type == FFI_TYPE_STRUCT if (((*ptr)->type == FFI_TYPE_STRUCT
&& ((*ptr)->size > 16 || cif->abi != FFI_V9)) && ((*ptr)->size > 16 || cif->abi != FFI_V9))
......
...@@ -39,50 +39,39 @@ ...@@ -39,50 +39,39 @@
/* Defines */ /* Defines */
/* ------- */ /* ------- */
/*====================================================================*/ /*====================================================================*/
#define MAX_GPRARGS 5 /* Max. no. of GPR available */ /* Maximum number of GPRs available for argument passing. */
#define MAX_FPRARGS 2 /* Max. no. of FPR available */ #define MAX_GPRARGS 5
#define STR_GPR 1 /* Structure will fit in 1 or 2 GPR */ /* Maximum number of FPRs available for argument passing. */
#define STR_FPR 2 /* Structure will fit in a FPR */ #ifdef __s390x__
#define STR_STACK 3 /* Structure needs to go on stack */ #define MAX_FPRARGS 4
#else
#define MAX_FPRARGS 2
#endif
/* Round to multiple of 16. */
#define ROUND_SIZE(size) (((size) + 15) & ~15)
/* If these values change, sysv.S must be adapted! */
#define FFI390_RET_VOID 0
#define FFI390_RET_STRUCT 1
#define FFI390_RET_FLOAT 2
#define FFI390_RET_DOUBLE 3
#define FFI390_RET_INT32 4
#define FFI390_RET_INT64 5
/*===================== End of Defines ===============================*/ /*===================== End of Defines ===============================*/
/*====================================================================*/ /*====================================================================*/
/* Types */
/* ----- */
/*====================================================================*/
typedef struct stackLayout
{
int *backChain;
int *endOfStack;
int glue[2];
int scratch[2];
int gprArgs[MAX_GPRARGS];
int notUsed;
union
{
float f;
double d;
} fprArgs[MAX_FPRARGS];
int unUsed[8];
int outArgs[100];
} stackLayout;
/*======================== End of Types ==============================*/
/*====================================================================*/
/* Prototypes */ /* Prototypes */
/* ---------- */ /* ---------- */
/*====================================================================*/ /*====================================================================*/
void ffi_prep_args(stackLayout *, extended_cif *); static void ffi_prep_args (unsigned char *, extended_cif *);
static int ffi_check_struct(ffi_type *, unsigned int *); static int ffi_check_float_struct (ffi_type *);
static void ffi_insert_int(int, stackLayout *, int *, int *); void ffi_closure_helper_SYSV (ffi_closure *, unsigned long *,
static void ffi_insert_int64(long long, stackLayout *, int *, int *); unsigned long long *, unsigned long *);
static void ffi_insert_double(double, stackLayout *, int *, int *);
/*====================== End of Prototypes ===========================*/ /*====================== End of Prototypes ===========================*/
...@@ -91,499 +80,680 @@ static void ffi_insert_double(double, stackLayout *, int *, int *); ...@@ -91,499 +80,680 @@ static void ffi_insert_double(double, stackLayout *, int *, int *);
/* --------- */ /* --------- */
/*====================================================================*/ /*====================================================================*/
extern void ffi_call_SYSV(void (*)(stackLayout *, extended_cif *), extern void ffi_call_SYSV(unsigned,
extended_cif *, extended_cif *,
unsigned, unsigned, void (*)(unsigned char *, extended_cif *),
unsigned *, unsigned,
void *,
void (*fn)()); void (*fn)());
extern void ffi_closure_SYSV(void);
/*====================== End of Externals ============================*/ /*====================== End of Externals ============================*/
/*====================================================================*/ /*====================================================================*/
/* */ /* */
/* Name - ffi_check_struct. */ /* Name - ffi_check_struct_type. */
/* */ /* */
/* Function - Determine if a structure can be passed within a */ /* Function - Determine if a structure can be passed within a */
/* general or floating point register. */ /* general purpose or floating point register. */
/* */ /* */
/*====================================================================*/ /*====================================================================*/
int static int
ffi_check_struct(ffi_type *arg, unsigned int *strFlags) ffi_check_struct_type (ffi_type *arg)
{ {
ffi_type *element; size_t size = arg->size;
int i_Element;
/* If the struct has just one element, look at that element
for (i_Element = 0; arg->elements[i_Element]; i_Element++) { to find out whether to consider the struct as floating point. */
element = arg->elements[i_Element]; while (arg->type == FFI_TYPE_STRUCT
switch (element->type) { && arg->elements[0] && !arg->elements[1])
case FFI_TYPE_DOUBLE : arg = arg->elements[0];
*strFlags |= STR_FPR;
break; /* Structs of size 1, 2, 4, and 8 are passed in registers,
just like the corresponding int/float types. */
case FFI_TYPE_STRUCT : switch (size)
*strFlags |= ffi_check_struct(element, strFlags); {
break; case 1:
return FFI_TYPE_UINT8;
default :
*strFlags |= STR_GPR; case 2:
} return FFI_TYPE_UINT16;
}
return (*strFlags); case 4:
if (arg->type == FFI_TYPE_FLOAT)
return FFI_TYPE_FLOAT;
else
return FFI_TYPE_UINT32;
case 8:
if (arg->type == FFI_TYPE_DOUBLE)
return FFI_TYPE_DOUBLE;
else
return FFI_TYPE_UINT64;
default:
break;
}
/* Other structs are passed via a pointer to the data. */
return FFI_TYPE_POINTER;
} }
/*======================== End of Routine ============================*/ /*======================== End of Routine ============================*/
/*====================================================================*/ /*====================================================================*/
/* */ /* */
/* Name - ffi_insert_int. */ /* Name - ffi_prep_args. */
/* */
/* Function - Prepare parameters for call to function. */
/* */ /* */
/* Function - Insert an integer parameter in a register if there are */ /* ffi_prep_args is called by the assembly routine once stack space */
/* spares else on the stack. */ /* has been allocated for the function's arguments. */
/* */ /* */
/*====================================================================*/ /*====================================================================*/
void static void
ffi_insert_int(int gprValue, stackLayout *stack, ffi_prep_args (unsigned char *stack, extended_cif *ecif)
int *intArgC, int *outArgC)
{ {
if (*intArgC < MAX_GPRARGS) { /* The stack space will be filled with those areas:
stack->gprArgs[*intArgC] = gprValue;
*intArgC += 1; FPR argument register save area (highest addresses)
} GPR argument register save area
else { temporary struct copies
stack->outArgs[*outArgC++] = gprValue; overflow argument area (lowest addresses)
*outArgC += 1;
} We set up the following pointers:
}
p_fpr: bottom of the FPR area (growing upwards)
p_gpr: bottom of the GPR area (growing upwards)
p_ov: bottom of the overflow area (growing upwards)
p_struct: top of the struct copy area (growing downwards)
All areas are kept aligned to twice the word size. */
int gpr_off = ecif->cif->bytes;
int fpr_off = gpr_off + ROUND_SIZE (MAX_GPRARGS * sizeof (long));
unsigned long long *p_fpr = (unsigned long long *)(stack + fpr_off);
unsigned long *p_gpr = (unsigned long *)(stack + gpr_off);
unsigned char *p_struct = (unsigned char *)p_gpr;
unsigned long *p_ov = (unsigned long *)stack;
int n_fpr = 0;
int n_gpr = 0;
int n_ov = 0;
ffi_type **ptr;
void **p_argv = ecif->avalue;
int i;
/* If we returning a structure then we set the first parameter register
to the address of where we are returning this structure. */
if (ecif->cif->flags == FFI390_RET_STRUCT)
p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
/* Now for the arguments. */
for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
i > 0;
i--, ptr++, p_argv++)
{
void *arg = *p_argv;
int type = (*ptr)->type;
/* Check how a structure type is passed. */
if (type == FFI_TYPE_STRUCT)
{
type = ffi_check_struct_type (*ptr);
/* If we pass the struct via pointer, copy the data. */
if (type == FFI_TYPE_POINTER)
{
p_struct -= ROUND_SIZE ((*ptr)->size);
memcpy (p_struct, (char *)arg, (*ptr)->size);
arg = &p_struct;
}
}
/* Pointers are passed like UINTs of the same size. */
if (type == FFI_TYPE_POINTER)
#ifdef __s390x__
type = FFI_TYPE_UINT64;
#else
type = FFI_TYPE_UINT32;
#endif
/* Now handle all primitive int/float data types. */
switch (type)
{
case FFI_TYPE_DOUBLE:
if (n_fpr < MAX_FPRARGS)
p_fpr[n_fpr++] = *(unsigned long long *) arg;
else
#ifdef __s390x__
p_ov[n_ov++] = *(unsigned long *) arg;
#else
p_ov[n_ov++] = ((unsigned long *) arg)[0],
p_ov[n_ov++] = ((unsigned long *) arg)[1];
#endif
break;
case FFI_TYPE_FLOAT:
if (n_fpr < MAX_FPRARGS)
p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
else
p_ov[n_ov++] = *(unsigned int *) arg;
break;
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
#ifdef __s390x__
if (n_gpr < MAX_GPRARGS)
p_gpr[n_gpr++] = *(unsigned long *) arg;
else
p_ov[n_ov++] = *(unsigned long *) arg;
#else
if (n_gpr == MAX_GPRARGS-1)
n_gpr = MAX_GPRARGS;
if (n_gpr < MAX_GPRARGS)
p_gpr[n_gpr++] = ((unsigned long *) arg)[0],
p_gpr[n_gpr++] = ((unsigned long *) arg)[1];
else
p_ov[n_ov++] = ((unsigned long *) arg)[0],
p_ov[n_ov++] = ((unsigned long *) arg)[1];
#endif
break;
case FFI_TYPE_UINT32:
if (n_gpr < MAX_GPRARGS)
p_gpr[n_gpr++] = *(unsigned int *) arg;
else
p_ov[n_ov++] = *(unsigned int *) arg;
break;
case FFI_TYPE_INT:
case FFI_TYPE_SINT32:
if (n_gpr < MAX_GPRARGS)
p_gpr[n_gpr++] = *(signed int *) arg;
else
p_ov[n_ov++] = *(signed int *) arg;
break;
case FFI_TYPE_UINT16:
if (n_gpr < MAX_GPRARGS)
p_gpr[n_gpr++] = *(unsigned short *) arg;
else
p_ov[n_ov++] = *(unsigned short *) arg;
break;
case FFI_TYPE_SINT16:
if (n_gpr < MAX_GPRARGS)
p_gpr[n_gpr++] = *(signed short *) arg;
else
p_ov[n_ov++] = *(signed short *) arg;
break;
case FFI_TYPE_UINT8:
if (n_gpr < MAX_GPRARGS)
p_gpr[n_gpr++] = *(unsigned char *) arg;
else
p_ov[n_ov++] = *(unsigned char *) arg;
break;
case FFI_TYPE_SINT8:
if (n_gpr < MAX_GPRARGS)
p_gpr[n_gpr++] = *(signed char *) arg;
else
p_ov[n_ov++] = *(signed char *) arg;
break;
default:
FFI_ASSERT (0);
break;
}
}
}
/*======================== End of Routine ============================*/ /*======================== End of Routine ============================*/
/*====================================================================*/ /*====================================================================*/
/* */ /* */
/* Name - ffi_insert_int64. */ /* Name - ffi_prep_cif_machdep. */
/* */ /* */
/* Function - Insert a long long parameter in registers if there are */ /* Function - Perform machine dependent CIF processing. */
/* spares else on the stack. */
/* */ /* */
/*====================================================================*/ /*====================================================================*/
void ffi_status
ffi_insert_int64(long long llngValue, stackLayout *stack, ffi_prep_cif_machdep(ffi_cif *cif)
int *intArgC, int *outArgC)
{ {
size_t struct_size = 0;
int n_gpr = 0;
int n_fpr = 0;
int n_ov = 0;
ffi_type **ptr;
int i;
/* Determine return value handling. */
switch (cif->rtype->type)
{
/* Void is easy. */
case FFI_TYPE_VOID:
cif->flags = FFI390_RET_VOID;
break;
/* Structures are returned via a hidden pointer. */
case FFI_TYPE_STRUCT:
cif->flags = FFI390_RET_STRUCT;
n_gpr++; /* We need one GPR to pass the pointer. */
break;
/* Floating point values are returned in fpr 0. */
case FFI_TYPE_FLOAT:
cif->flags = FFI390_RET_FLOAT;
break;
case FFI_TYPE_DOUBLE:
cif->flags = FFI390_RET_DOUBLE;
break;
/* Integer values are returned in gpr 2 (and gpr 3
for 64-bit values on 31-bit machines). */
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
cif->flags = FFI390_RET_INT64;
break;
case FFI_TYPE_INT:
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT8:
/* These are to be extended to word size. */
#ifdef __s390x__
cif->flags = FFI390_RET_INT64;
#else
cif->flags = FFI390_RET_INT32;
#endif
break;
if (*intArgC < (MAX_GPRARGS-1)) { default:
memcpy(&stack->gprArgs[*intArgC], FFI_ASSERT (0);
&llngValue, sizeof(long long)); break;
*intArgC += 2; }
}
else { /* Now for the arguments. */
memcpy(&stack->outArgs[*outArgC],
&llngValue, sizeof(long long));
*outArgC += 2;
}
for (ptr = cif->arg_types, i = cif->nargs;
i > 0;
i--, ptr++)
{
int type = (*ptr)->type;
/* Check how a structure type is passed. */
if (type == FFI_TYPE_STRUCT)
{
type = ffi_check_struct_type (*ptr);
/* If we pass the struct via pointer, we must reserve space
to copy its data for proper call-by-value semantics. */
if (type == FFI_TYPE_POINTER)
struct_size += ROUND_SIZE ((*ptr)->size);
}
/* Now handle all primitive int/float data types. */
switch (type)
{
/* The first MAX_FPRARGS floating point arguments
go in FPRs, the rest overflow to the stack. */
case FFI_TYPE_DOUBLE:
if (n_fpr < MAX_FPRARGS)
n_fpr++;
else
n_ov += sizeof (double) / sizeof (long);
break;
case FFI_TYPE_FLOAT:
if (n_fpr < MAX_FPRARGS)
n_fpr++;
else
n_ov++;
break;
/* On 31-bit machines, 64-bit integers are passed in GPR pairs,
if one is still available, or else on the stack. If only one
register is free, skip the register (it won't be used for any
subsequent argument either). */
#ifndef __s390x__
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
if (n_gpr == MAX_GPRARGS-1)
n_gpr = MAX_GPRARGS;
if (n_gpr < MAX_GPRARGS)
n_gpr += 2;
else
n_ov += 2;
break;
#endif
/* Everything else is passed in GPRs (until MAX_GPRARGS
have been used) or overflows to the stack. */
default:
if (n_gpr < MAX_GPRARGS)
n_gpr++;
else
n_ov++;
break;
}
}
/* Total stack space as required for overflow arguments
and temporary structure copies. */
cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
return FFI_OK;
} }
/*======================== End of Routine ============================*/ /*======================== End of Routine ============================*/
/*====================================================================*/ /*====================================================================*/
/* */ /* */
/* Name - ffi_insert_double. */ /* Name - ffi_call. */
/* */ /* */
/* Function - Insert a double parameter in a FP register if there is */ /* Function - Call the FFI routine. */
/* a spare else on the stack. */
/* */ /* */
/*====================================================================*/ /*====================================================================*/
void void
ffi_insert_double(double dblValue, stackLayout *stack, ffi_call(ffi_cif *cif,
int *fprArgC, int *outArgC) void (*fn)(),
void *rvalue,
void **avalue)
{ {
int ret_type = cif->flags;
extended_cif ecif;
if (*fprArgC < MAX_FPRARGS) { ecif.cif = cif;
stack->fprArgs[*fprArgC].d = dblValue; ecif.avalue = avalue;
*fprArgC += 1; ecif.rvalue = rvalue;
}
else { /* If we don't have a return value, we need to fake one. */
memcpy(&stack->outArgs[*outArgC], if (rvalue == NULL)
&dblValue,sizeof(double)); {
*outArgC += 2; if (ret_type == FFI390_RET_STRUCT)
} ecif.rvalue = alloca (cif->rtype->size);
else
ret_type = FFI390_RET_VOID;
}
switch (cif->abi)
{
case FFI_SYSV:
ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
ret_type, ecif.rvalue, fn);
break;
default:
FFI_ASSERT (0);
break;
}
} }
/*======================== End of Routine ============================*/ /*======================== End of Routine ============================*/
/*====================================================================*/ /*====================================================================*/
/* */ /* */
/* Name - ffi_prep_args. */ /* Name - ffi_closure_helper_SYSV. */
/* */ /* */
/* Function - Prepare parameters for call to function. */ /* Function - Call a FFI closure target function. */
/* */
/* ffi_prep_args is called by the assembly routine once stack space */
/* has been allocated for the function's arguments. */
/* */
/* The stack layout we want looks like this: */
/* *------------------------------------------------------------* */
/* | 0 | Back chain (a 0 here signifies end of back chain) | */
/* +--------+---------------------------------------------------+ */
/* | 4 | EOS (end of stack, not used on Linux for S390) | */
/* +--------+---------------------------------------------------+ */
/* | 8 | Glue used in other linkage formats | */
/* +--------+---------------------------------------------------+ */
/* | 12 | Glue used in other linkage formats | */
/* +--------+---------------------------------------------------+ */
/* | 16 | Scratch area | */
/* +--------+---------------------------------------------------+ */
/* | 20 | Scratch area | */
/* +--------+---------------------------------------------------+ */
/* | 24 | GPR parameter register 1 | */
/* +--------+---------------------------------------------------+ */
/* | 28 | GPR parameter register 2 | */
/* +--------+---------------------------------------------------+ */
/* | 32 | GPR parameter register 3 | */
/* +--------+---------------------------------------------------+ */
/* | 36 | GPR parameter register 4 | */
/* +--------+---------------------------------------------------+ */
/* | 40 | GPR parameter register 5 | */
/* +--------+---------------------------------------------------+ */
/* | 44 | Unused | */
/* +--------+---------------------------------------------------+ */
/* | 48 | FPR parameter register 1 | */
/* +--------+---------------------------------------------------+ */
/* | 56 | FPR parameter register 2 | */
/* +--------+---------------------------------------------------+ */
/* | 64 | Unused | */
/* +--------+---------------------------------------------------+ */
/* | 96 | Outgoing args (length x) | */
/* +--------+---------------------------------------------------+ */
/* | 96+x | Copy area for structures (length y) | */
/* +--------+---------------------------------------------------+ */
/* | 96+x+y | Possible stack alignment | */
/* *------------------------------------------------------------* */
/* */ /* */
/*====================================================================*/ /*====================================================================*/
void void
ffi_prep_args(stackLayout *stack, extended_cif *ecif) ffi_closure_helper_SYSV (ffi_closure *closure,
unsigned long *p_gpr,
unsigned long long *p_fpr,
unsigned long *p_ov)
{ {
const unsigned bytes = ecif->cif->bytes; unsigned long long ret_buffer;
const unsigned flags = ecif->cif->flags;
void *rvalue = &ret_buffer;
/*----------------------------------------------------------*/ void **avalue;
/* Pointer to the copy area on stack for structures */ void **p_arg;
/*----------------------------------------------------------*/
char *copySpace = (char *) stack + bytes + sizeof(stackLayout); int n_gpr = 0;
int n_fpr = 0;
/*----------------------------------------------------------*/ int n_ov = 0;
/* Count of general and floating point register usage */
/*----------------------------------------------------------*/
int intArgC = 0,
fprArgC = 0,
outArgC = 0;
int i;
ffi_type **ptr; ffi_type **ptr;
void **p_argv; int i;
size_t structCopySize;
unsigned gprValue, strFlags = 0; /* Allocate buffer for argument list pointers. */
unsigned long long llngValue;
double dblValue; p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
/* If we returning a structure, pass the structure address
directly to the target function. Otherwise, have the target
function store the return value to the GPR save area. */
if (closure->cif->flags == FFI390_RET_STRUCT)
rvalue = (void *) p_gpr[n_gpr++];
/* Now for the arguments. */ /* Now for the arguments. */
p_argv = ecif->avalue;
for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
/*----------------------------------------------------------------------*/
/* If we returning a structure then we set the first parameter register */
/* to the address of where we are returning this structure */
/*----------------------------------------------------------------------*/
if (flags == FFI_TYPE_STRUCT)
stack->gprArgs[intArgC++] = (int) ecif->rvalue;
for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
i > 0; i > 0;
i--, ptr++, p_argv++) i--, p_arg++, ptr++)
{ {
switch ((*ptr)->type) { int deref_struct_pointer = 0;
int type = (*ptr)->type;
/* Check how a structure type is passed. */
if (type == FFI_TYPE_STRUCT)
{
type = ffi_check_struct_type (*ptr);
/* If we pass the struct via pointer, remember to
retrieve the pointer later. */
if (type == FFI_TYPE_POINTER)
deref_struct_pointer = 1;
}
/* Pointers are passed like UINTs of the same size. */
if (type == FFI_TYPE_POINTER)
#ifdef __s390x__
type = FFI_TYPE_UINT64;
#else
type = FFI_TYPE_UINT32;
#endif
/* Now handle all primitive int/float data types. */
switch (type)
{
case FFI_TYPE_DOUBLE:
if (n_fpr < MAX_FPRARGS)
*p_arg = &p_fpr[n_fpr++];
else
*p_arg = &p_ov[n_ov],
n_ov += sizeof (double) / sizeof (long);
break;
case FFI_TYPE_FLOAT:
if (n_fpr < MAX_FPRARGS)
*p_arg = &p_fpr[n_fpr++];
else
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
break;
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
#ifdef __s390x__
if (n_gpr < MAX_GPRARGS)
*p_arg = &p_gpr[n_gpr++];
else
*p_arg = &p_ov[n_ov++];
#else
if (n_gpr == MAX_GPRARGS-1)
n_gpr = MAX_GPRARGS;
if (n_gpr < MAX_GPRARGS)
*p_arg = &p_gpr[n_gpr], n_gpr += 2;
else
*p_arg = &p_ov[n_ov], n_ov += 2;
#endif
break;
case FFI_TYPE_INT:
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
if (n_gpr < MAX_GPRARGS)
*p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
else
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
break;
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT16:
if (n_gpr < MAX_GPRARGS)
*p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
else
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
break;
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT8:
if (n_gpr < MAX_GPRARGS)
*p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
else
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
break;
default:
FFI_ASSERT (0);
break;
}
/* If this is a struct passed via pointer, we need to
actually retrieve that pointer. */
if (deref_struct_pointer)
*p_arg = *(void **)*p_arg;
}
/* Call the target function. */
(closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
/* Convert the return value. */
switch (closure->cif->rtype->type)
{
/* Void is easy, and so is struct. */
case FFI_TYPE_VOID:
case FFI_TYPE_STRUCT:
break;
/* Floating point values are returned in fpr 0. */
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
if (fprArgC < MAX_FPRARGS) p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
stack->fprArgs[fprArgC++].f = *(float *) *p_argv;
else
stack->outArgs[outArgC++] = *(int *) *p_argv;
break; break;
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
dblValue = *(double *) *p_argv; p_fpr[0] = *(unsigned long long *) rvalue;
ffi_insert_double(dblValue, stack, &fprArgC, &outArgC);
break; break;
/* Integer values are returned in gpr 2 (and gpr 3
for 64-bit values on 31-bit machines). */
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
llngValue = *(unsigned long long *) *p_argv; #ifdef __s390x__
ffi_insert_int64(llngValue, stack, &intArgC, &outArgC); p_gpr[0] = *(unsigned long *) rvalue;
#else
p_gpr[0] = ((unsigned long *) rvalue)[0],
p_gpr[1] = ((unsigned long *) rvalue)[1];
#endif
break; break;
case FFI_TYPE_UINT8: case FFI_TYPE_UINT32:
gprValue = *(unsigned char *)*p_argv; p_gpr[0] = *(unsigned int *) rvalue;
ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
break; break;
case FFI_TYPE_SINT8: case FFI_TYPE_INT:
gprValue = *(signed char *)*p_argv; case FFI_TYPE_SINT32:
ffi_insert_int(gprValue, stack, &intArgC, &outArgC); p_gpr[0] = *(signed int *) rvalue;
break; break;
case FFI_TYPE_UINT16: case FFI_TYPE_UINT16:
gprValue = *(unsigned short *)*p_argv; p_gpr[0] = *(unsigned short *) rvalue;
ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
break; break;
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
gprValue = *(signed short *)*p_argv; p_gpr[0] = *(signed short *) rvalue;
ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
break; break;
case FFI_TYPE_STRUCT: case FFI_TYPE_UINT8:
/*--------------------------------------------------*/ p_gpr[0] = *(unsigned char *) rvalue;
/* If structure > 8 bytes then it goes on the stack */
/*--------------------------------------------------*/
if (((*ptr)->size > 8) ||
((*ptr)->size > 4 &&
(*ptr)->size < 8))
strFlags = STR_STACK;
else
strFlags = ffi_check_struct((ffi_type *) *ptr, &strFlags);
switch (strFlags) {
/*-------------------------------------------*/
/* Structure that will fit in one or two GPR */
/*-------------------------------------------*/
case STR_GPR :
if ((*ptr)->size <= 4) {
gprValue = *(unsigned int *) *p_argv;
gprValue = gprValue >> ((4 - (*ptr)->size) * 8);
ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
}
else {
llngValue = *(unsigned long long *) *p_argv;
ffi_insert_int64(llngValue, stack, &intArgC, &outArgC);
}
break;
/*-------------------------------------------*/
/* Structure that will fit in one FPR */
/*-------------------------------------------*/
case STR_FPR :
dblValue = *(double *) *p_argv;
ffi_insert_double(dblValue, stack, &fprArgC, &outArgC);
break;
/*-------------------------------------------*/
/* Structure that must be copied to stack */
/*-------------------------------------------*/
default :
structCopySize = (((*ptr)->size + 15) & ~0xF);
copySpace -= structCopySize;
memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
gprValue = (unsigned) copySpace;
if (intArgC < MAX_GPRARGS)
stack->gprArgs[intArgC++] = gprValue;
else
stack->outArgs[outArgC++] = gprValue;
}
break;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE:
structCopySize = (((*ptr)->size + 15) & ~0xF);
copySpace -= structCopySize;
memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
gprValue = (unsigned) copySpace;
if (intArgC < MAX_GPRARGS)
stack->gprArgs[intArgC++] = gprValue;
else
stack->outArgs[outArgC++] = gprValue;
break; break;
#endif
case FFI_TYPE_SINT8:
case FFI_TYPE_INT: p_gpr[0] = *(signed char *) rvalue;
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
case FFI_TYPE_POINTER:
gprValue = *(unsigned *)*p_argv;
if (intArgC < MAX_GPRARGS)
stack->gprArgs[intArgC++] = gprValue;
else
stack->outArgs[outArgC++] = gprValue;
break; break;
} default:
FFI_ASSERT (0);
break;
} }
} }
/*======================== End of Routine ============================*/
/*======================== End of Routine ============================*/
/*====================================================================*/ /*====================================================================*/
/* */ /* */
/* Name - ffi_prep_cif_machdep. */ /* Name - ffi_prep_closure. */
/* */ /* */
/* Function - Perform machine dependent CIF processing. */ /* Function - Prepare a FFI closure. */
/* */ /* */
/*====================================================================*/ /*====================================================================*/
ffi_status ffi_status
ffi_prep_cif_machdep(ffi_cif *cif) ffi_prep_closure (ffi_closure *closure,
ffi_cif *cif,
void (*fun) (ffi_cif *, void *, void **, void *),
void *user_data)
{ {
int i; FFI_ASSERT (cif->abi == FFI_SYSV);
ffi_type **ptr;
unsigned bytes; #ifndef __s390x__
int fpArgC = 0, *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
intArgC = 0; *(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */
unsigned flags = 0; *(short *)&closure->tramp [4] = 0x1006;
unsigned structCopySize = 0; *(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */
*(long *)&closure->tramp [8] = (long)closure;
/*-----------------------------------------------------------------*/ *(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
/* Extra space required in stack for overflow parameters. */ #else
/*-----------------------------------------------------------------*/ *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
bytes = 0; *(short *)&closure->tramp [2] = 0xeb01; /* lmg %r0,%r1,14(%r1) */
*(short *)&closure->tramp [4] = 0x100e;
/*--------------------------------------------------------*/ *(short *)&closure->tramp [6] = 0x0004;
/* Return value handling. The rules are as follows: */ *(short *)&closure->tramp [8] = 0x07f1; /* br %r1 */
/* - 32-bit (or less) integer values are returned in gpr2 */ *(long *)&closure->tramp[16] = (long)closure;
/* - Structures are returned as pointers in gpr2 */ *(long *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
/* - 64-bit integer values are returned in gpr2 and 3 */ #endif
/* - Single/double FP values are returned in fpr0 */
/*--------------------------------------------------------*/ closure->cif = cif;
flags = cif->rtype->type; closure->user_data = user_data;
closure->fun = fun;
/*------------------------------------------------------------------------*/
/* The first MAX_GPRARGS words of integer arguments, and the */
/* first MAX_FPRARGS floating point arguments, go in registers; the rest */
/* goes on the stack. Structures and long doubles (if not equivalent */
/* to double) are passed as a pointer to a copy of the structure. */
/* Stuff on the stack needs to keep proper alignment. */
/*------------------------------------------------------------------------*/
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
switch ((*ptr)->type)
{
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
fpArgC++;
if (fpArgC > MAX_FPRARGS && intArgC%2 != 0)
intArgC++;
break;
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
/*----------------------------------------------------*/
/* 'long long' arguments are passed as two words, but */
/* either both words must fit in registers or both go */
/* on the stack. If they go on the stack, they must */
/* be 8-byte-aligned. */
/*----------------------------------------------------*/
if ((intArgC == MAX_GPRARGS-1) ||
(intArgC >= MAX_GPRARGS) &&
(intArgC%2 != 0))
intArgC++;
intArgC += 2;
break;
case FFI_TYPE_STRUCT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE:
#endif
/*----------------------------------------------------*/
/* We must allocate space for a copy of these to */
/* enforce pass-by-value. Pad the space up to a */
/* multiple of 16 bytes (the maximum alignment */
/* required for anything under the SYSV ABI). */
/*----------------------------------------------------*/
structCopySize += ((*ptr)->size + 15) & ~0xF;
/*----------------------------------------------------*/
/* Fall through (allocate space for the pointer). */
/*----------------------------------------------------*/
default:
/*----------------------------------------------------*/
/* Everything else is passed as a 4-byte word in a */
/* GPR either the object itself or a pointer to it. */
/*----------------------------------------------------*/
intArgC++;
break;
}
}
/*-----------------------------------------------------------------*/
/* Stack space. */
/*-----------------------------------------------------------------*/
if (intArgC > MAX_GPRARGS)
bytes += (intArgC - MAX_GPRARGS) * sizeof(int);
if (fpArgC > MAX_FPRARGS)
bytes += (fpArgC - MAX_FPRARGS) * sizeof(double);
/*-----------------------------------------------------------------*/
/* The stack space allocated needs to be a multiple of 16 bytes. */
/*-----------------------------------------------------------------*/
bytes = (bytes + 15) & ~0xF;
/*-----------------------------------------------------------------*/
/* Add in the space for the copied structures. */
/*-----------------------------------------------------------------*/
bytes += structCopySize;
cif->flags = flags;
cif->bytes = bytes;
return FFI_OK; return FFI_OK;
} }
/*======================== End of Routine ============================*/ /*======================== End of Routine ============================*/
/*====================================================================*/
/* */
/* Name - ffi_call. */
/* */
/* Function - Call the FFI routine. */
/* */
/*====================================================================*/
void
ffi_call(ffi_cif *cif,
void (*fn)(),
void *rvalue,
void **avalue)
{
extended_cif ecif;
ecif.cif = cif;
ecif.avalue = avalue;
/*-----------------------------------------------------------------*/
/* If the return value is a struct and we don't have a return */
/* value address then we need to make one */
/*-----------------------------------------------------------------*/
if ((rvalue == NULL) &&
(cif->rtype->type == FFI_TYPE_STRUCT))
ecif.rvalue = alloca(cif->rtype->size);
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args,
&ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
break;
default:
FFI_ASSERT(0);
break;
}
}
/*======================== End of Routine ============================*/
...@@ -22,150 +22,130 @@ ...@@ -22,150 +22,130 @@
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE. OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */ ----------------------------------------------------------------------- */
#ifndef __s390x__
#define LIBFFI_ASM
#include <ffi.h>
#ifdef HAVE_MACHINE_ASM_H
#include <machine/asm.h>
#endif
.text .text
# r2: ffi_prep_args # r2: cif->bytes
# r3: &ecif # r3: &ecif
# r4: cif->bytes # r4: ffi_prep_args
# r5: fig->flags # r5: ret_type
# r6: ecif.rvalue # r6: ecif.rvalue
# sp+0: fn # ov: fn
# This assumes we are using gas. # This assumes we are using gas.
.globl ffi_call_SYSV .globl ffi_call_SYSV
.type ffi_call_SYSV,%function .type ffi_call_SYSV,%function
ffi_call_SYSV: ffi_call_SYSV:
.LFB1: .LFB1:
# Save registers stm %r6,%r15,24(%r15) # Save registers
stm %r6,%r15,24(%r15)
.LCFI0: .LCFI0:
l %r7,96(%r15) # Get A(fn) basr %r13,0 # Set up base register
lr %r0,%r15 .Lbase:
ahi %r15,-128 # Make room for my args lr %r11,%r15 # Set up frame pointer
.LCFI1: .LCFI1:
st %r0,0(%r15) # Set backchain sr %r15,%r2
lr %r11,%r15 # Establish my stack register 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: .LCFI2:
sr %r15,%r4 # Make room for fn args
ahi %r15,-96 # Make room for new frame la %r2,96(%r15) # Save area
lr %r10,%r15 # Establish stack build area # r3 already holds &ecif
ahi %r15,-96 # Stack for next call basr %r14,%r4 # Call ffi_prep_args
lr %r1,%r7
stm %r2,%r7,96(%r11) # Save args on my stack lm %r2,%r6,0(%r11) # Load arguments
ld %f0,32(%r11)
#------------------------------------------------------------------ ld %f2,40(%r11)
# move first 3 parameters in registers la %r14,0(%r13,%r9) # Set return address
#------------------------------------------------------------------ br %r7 # ... and call function
lr %r9,%r2 # r9: &ffi_prep_args
lr %r2,%r10 # Parm 1: &stack Parm 2: &ecif .LretNone: # Return void
basr %r14,%r9 # call ffi_prep_args l %r4,48+56(%r11)
lm %r6,%r15,48+24(%r11)
#------------------------------------------------------------------ br %r4
# load first 5 parameter registers
#------------------------------------------------------------------ .LretFloat:
lm %r2,%r6,24(%r10) l %r4,48+56(%r11)
ste %f0,0(%r8) # Return float
#------------------------------------------------------------------ lm %r6,%r15,48+24(%r11)
# load fp parameter registers br %r4
#------------------------------------------------------------------
ld %f0,48(%r10)
ld %f2,56(%r10)
#------------------------------------------------------------------
# call function
#------------------------------------------------------------------
lr %r15,%r10 # Set new stack
l %r9,116(%r11) # Get &fn
basr %r14,%r9 # Call function
#------------------------------------------------------------------
# On return:
# r2: Return value (r3: Return value + 4 for long long)
#------------------------------------------------------------------
#------------------------------------------------------------------
# If the return value pointer is NULL, assume no return value.
#------------------------------------------------------------------
icm %r6,15,112(%r11)
jz .Lepilogue
l %r5,108(%r11) # Get return type
#------------------------------------------------------------------
# return INT
#------------------------------------------------------------------
chi %r5,FFI_TYPE_INT
jne .Lchk64
st %r2,0(%r6)
j .Lepilogue
.Lchk64:
#------------------------------------------------------------------
# return LONG LONG (signed/unsigned)
#------------------------------------------------------------------
chi %r5,FFI_TYPE_UINT64
je .LdoLongLong
chi %r5,FFI_TYPE_SINT64
jne .LchkFloat
.LdoLongLong:
stm %r2,%r3,0(%r6)
j .Lepilogue
.LchkFloat:
#------------------------------------------------------------------
# return FLOAT
#------------------------------------------------------------------
chi %r5,FFI_TYPE_FLOAT
jne .LchkDouble
std %f0,0(%r6)
j .Lepilogue
.LchkDouble:
#------------------------------------------------------------------
# return DOUBLE or LONGDOUBLE
#------------------------------------------------------------------
chi %r5,FFI_TYPE_DOUBLE
jne .LchkStruct
std %f0,0(%r6)
std %f2,8(%r6)
j .Lepilogue
.LchkStruct:
#------------------------------------------------------------------
# Structure - rvalue already set as sent as 1st parm to routine
#------------------------------------------------------------------
chi %r5,FFI_TYPE_STRUCT
je .Lepilogue
.Ldefault: .LretDouble:
#------------------------------------------------------------------ l %r4,48+56(%r11)
# return a pointer std %f0,0(%r8) # Return double
#------------------------------------------------------------------ lm %r6,%r15,48+24(%r11)
st %r2,0(%r6) br %r4
j .Lepilogue
.LretInt32:
l %r4,48+56(%r11)
st %r2,0(%r8) # Return int
lm %r6,%r15,48+24(%r11)
br %r4
.Lepilogue: .LretInt64:
l %r15,0(%r11) l %r4,48+56(%r11)
l %r4,56(%r15) stm %r2,%r3,0(%r8) # Return long long
lm %r6,%r15,24(%r15) lm %r6,%r15,48+24(%r11)
br %r4 br %r4
.Ltable:
.byte .LretNone-.Lbase # FFI390_RET_VOID
.byte .LretNone-.Lbase # FFI390_RET_STRUCT
.byte .LretFloat-.Lbase # FFI390_RET_FLOAT
.byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
.byte .LretInt32-.Lbase # FFI390_RET_INT32
.byte .LretInt64-.Lbase # FFI390_RET_INT64
.LFE1: .LFE1:
.ffi_call_SYSV_end: .ffi_call_SYSV_end:
.size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
.globl ffi_closure_SYSV
.type ffi_closure_SYSV,%function
ffi_closure_SYSV:
.LFB2:
stm %r12,%r15,48(%r15) # Save registers
.LCFI10:
basr %r13,0 # Set up base register
.Lcbase:
stm %r2,%r6,8(%r15) # Save arguments
std %f0,64(%r15)
std %f2,72(%r15)
lr %r1,%r15 # Set up stack frame
ahi %r15,-96
.LCFI11:
l %r12,.Lchelper-.Lcbase(%r13) # Get helper function
lr %r2,%r0 # Closure
la %r3,8(%r1) # GPRs
la %r4,64(%r1) # FPRs
la %r5,96(%r1) # Overflow
st %r1,0(%r15) # Set up back chain
bas %r14,0(%r12,%r13) # Call helper
l %r4,96+56(%r15)
ld %f0,96+64(%r15) # Load return registers
lm %r2,%r3,96+8(%r15)
lm %r12,%r15,96+48(%r15)
br %r4
.align 4
.Lchelper:
.long ffi_closure_helper_SYSV-.Lcbase
.LFE2:
.ffi_closure_SYSV_end:
.size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
.section .eh_frame,"aw",@progbits .section .eh_frame,"aw",@progbits
.Lframe1: .Lframe1:
.4byte .LECIE1-.LSCIE1 # Length of Common Information Entry .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
...@@ -187,7 +167,6 @@ ffi_call_SYSV: ...@@ -187,7 +167,6 @@ ffi_call_SYSV:
.4byte .LASFDE1-.Lframe1 # FDE CIE offset .4byte .LASFDE1-.Lframe1 # FDE CIE offset
.4byte .LFB1 # FDE initial location .4byte .LFB1 # FDE initial location
.4byte .LFE1-.LFB1 # FDE address range .4byte .LFE1-.LFB1 # FDE address range
.uleb128 0x0 # Augmentation size
.byte 0x4 # DW_CFA_advance_loc4 .byte 0x4 # DW_CFA_advance_loc4
.4byte .LCFI0-.LFB1 .4byte .LCFI0-.LFB1
.byte 0x8f # DW_CFA_offset, column 0xf .byte 0x8f # DW_CFA_offset, column 0xf
...@@ -212,12 +191,227 @@ ffi_call_SYSV: ...@@ -212,12 +191,227 @@ ffi_call_SYSV:
.uleb128 0x12 .uleb128 0x12
.byte 0x4 # DW_CFA_advance_loc4 .byte 0x4 # DW_CFA_advance_loc4
.4byte .LCFI1-.LCFI0 .4byte .LCFI1-.LCFI0
.byte 0xe # DW_CFA_def_cfa_offset .byte 0xd # DW_CFA_def_cfa_register
.uleb128 0xe0 .uleb128 0xb
.byte 0x4 # DW_CFA_advance_loc4 .byte 0x4 # DW_CFA_advance_loc4
.4byte .LCFI2-.LCFI1 .4byte .LCFI2-.LCFI1
.byte 0xd # DW_CFA_def_cfa_register .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
.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 .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 .align 4
.LEFDE2:
#else
.text
# r2: cif->bytes
# r3: &ecif
# r4: ffi_prep_args
# r5: ret_type
# r6: ecif.rvalue
# ov: fn
# This assumes we are using gas.
.globl ffi_call_SYSV
.type ffi_call_SYSV,%function
ffi_call_SYSV:
.LFB1:
stmg %r6,%r15,48(%r15) # Save registers
.LCFI0:
larl %r13,.Lbase # Set up base register
lgr %r11,%r15 # Set up frame pointer
.LCFI1:
sgr %r15,%r2
aghi %r15,-160-80 # Allocate stack
lgr %r8,%r6 # Save ecif.rvalue
llgc %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
lg %r7,160(%r11) # Load function address
stg %r11,0(%r15) # Set up back chain
aghi %r11,-80 # Register save area
.LCFI2:
la %r2,160(%r15) # Save area
# r3 already holds &ecif
basr %r14,%r4 # Call ffi_prep_args
lmg %r2,%r6,0(%r11) # Load arguments
ld %f0,48(%r11)
ld %f2,56(%r11)
ld %f4,64(%r11)
ld %f6,72(%r11)
la %r14,0(%r13,%r9) # Set return address
br %r7 # ... and call function
.Lbase:
.LretNone: # Return void
lg %r4,80+112(%r11)
lmg %r6,%r15,80+48(%r11)
br %r4
.LretFloat:
lg %r4,80+112(%r11)
ste %f0,0(%r8) # Return float
lmg %r6,%r15,80+48(%r11)
br %r4
.LretDouble:
lg %r4,80+112(%r11)
std %f0,0(%r8) # Return double
lmg %r6,%r15,80+48(%r11)
br %r4
.LretInt32:
lg %r4,80+112(%r11)
st %r2,0(%r8) # Return int
lmg %r6,%r15,80+48(%r11)
br %r4
.LretInt64:
lg %r4,80+112(%r11)
stg %r2,0(%r8) # Return long
lmg %r6,%r15,80+48(%r11)
br %r4
.Ltable:
.byte .LretNone-.Lbase # FFI390_RET_VOID
.byte .LretNone-.Lbase # FFI390_RET_STRUCT
.byte .LretFloat-.Lbase # FFI390_RET_FLOAT
.byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
.byte .LretInt32-.Lbase # FFI390_RET_INT32
.byte .LretInt64-.Lbase # FFI390_RET_INT64
.LFE1:
.ffi_call_SYSV_end:
.size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
.globl ffi_closure_SYSV
.type ffi_closure_SYSV,%function
ffi_closure_SYSV:
.LFB2:
stmg %r14,%r15,112(%r15) # Save registers
.LCFI10:
stmg %r2,%r6,16(%r15) # Save arguments
std %f0,128(%r15)
std %f2,136(%r15)
std %f4,144(%r15)
std %f6,152(%r15)
lgr %r1,%r15 # Set up stack frame
aghi %r15,-160
.LCFI11:
lgr %r2,%r0 # Closure
la %r3,16(%r1) # GPRs
la %r4,128(%r1) # FPRs
la %r5,160(%r1) # Overflow
stg %r1,0(%r15) # Set up back chain
brasl %r14,ffi_closure_helper_SYSV # Call helper
lg %r14,160+112(%r15)
ld %f0,160+128(%r15) # Load return registers
lg %r2,160+16(%r15)
la %r15,160(%r15)
br %r14
.LFE2:
.ffi_closure_SYSV_end:
.size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
.section .eh_frame,"aw",@progbits
.Lframe1:
.4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
.LSCIE1:
.4byte 0x0 # CIE Identifier Tag
.byte 0x1 # CIE Version
.ascii "\0" # CIE Augmentation
.uleb128 0x1 # CIE Code Alignment Factor
.sleb128 -8 # CIE Data Alignment Factor
.byte 0xe # CIE RA Column
.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
.8byte .LFB1 # FDE initial location
.8byte .LFE1-.LFB1 # FDE address range
.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: .LEFDE1:
.LSFDE2:
.4byte .LEFDE2-.LASFDE2 # FDE Length
.LASFDE2:
.4byte .LASFDE2-.Lframe1 # FDE CIE offset
.8byte .LFB2 # FDE initial location
.8byte .LFE2-.LFB2 # FDE address range
.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
...@@ -42,7 +42,7 @@ FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); ...@@ -42,7 +42,7 @@ FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32);
FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32);
FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT);
#if defined ALPHA || defined SPARC64 || defined X86_64 #if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X
FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment