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))
......
...@@ -40,49 +40,38 @@ ...@@ -40,49 +40,38 @@
/* ------- */ /* ------- */
/*====================================================================*/ /*====================================================================*/
#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
/*===================== End of Defines ===============================*/ #define MAX_FPRARGS 2
#endif
/*====================================================================*/ /* Round to multiple of 16. */
/* Types */ #define ROUND_SIZE(size) (((size) + 15) & ~15)
/* ----- */
/*====================================================================*/
typedef struct stackLayout /* If these values change, sysv.S must be adapted! */
{ #define FFI390_RET_VOID 0
int *backChain; #define FFI390_RET_STRUCT 1
int *endOfStack; #define FFI390_RET_FLOAT 2
int glue[2]; #define FFI390_RET_DOUBLE 3
int scratch[2]; #define FFI390_RET_INT32 4
int gprArgs[MAX_GPRARGS]; #define FFI390_RET_INT64 5
int notUsed;
union
{
float f;
double d;
} fprArgs[MAX_FPRARGS];
int unUsed[8];
int outArgs[100];
} stackLayout;
/*======================== End of Types ==============================*/ /*===================== End of Defines ===============================*/
/*====================================================================*/ /*====================================================================*/
/* 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,127 +80,65 @@ static void ffi_insert_double(double, stackLayout *, int *, int *); ...@@ -91,127 +80,65 @@ 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
ffi_check_struct(ffi_type *arg, unsigned int *strFlags)
{
ffi_type *element;
int i_Element;
for (i_Element = 0; arg->elements[i_Element]; i_Element++) {
element = arg->elements[i_Element];
switch (element->type) {
case FFI_TYPE_DOUBLE :
*strFlags |= STR_FPR;
break;
case FFI_TYPE_STRUCT :
*strFlags |= ffi_check_struct(element, strFlags);
break;
default :
*strFlags |= STR_GPR;
}
}
return (*strFlags);
}
/*======================== End of Routine ============================*/
/*====================================================================*/
/* */
/* Name - ffi_insert_int. */
/* */
/* Function - Insert an integer parameter in a register if there are */
/* spares else on the stack. */
/* */
/*====================================================================*/
void
ffi_insert_int(int gprValue, stackLayout *stack,
int *intArgC, int *outArgC)
{
if (*intArgC < MAX_GPRARGS) {
stack->gprArgs[*intArgC] = gprValue;
*intArgC += 1;
}
else {
stack->outArgs[*outArgC++] = gprValue;
*outArgC += 1;
}
}
/*======================== End of Routine ============================*/
/*====================================================================*/
/* */
/* Name - ffi_insert_int64. */
/* */
/* Function - Insert a long long parameter in registers if there are */
/* spares else on the stack. */
/* */ /* */
/*====================================================================*/ /*====================================================================*/
void static int
ffi_insert_int64(long long llngValue, stackLayout *stack, ffi_check_struct_type (ffi_type *arg)
int *intArgC, int *outArgC)
{ {
size_t size = arg->size;
if (*intArgC < (MAX_GPRARGS-1)) { /* If the struct has just one element, look at that element
memcpy(&stack->gprArgs[*intArgC], to find out whether to consider the struct as floating point. */
&llngValue, sizeof(long long)); while (arg->type == FFI_TYPE_STRUCT
*intArgC += 2; && arg->elements[0] && !arg->elements[1])
} arg = arg->elements[0];
else {
memcpy(&stack->outArgs[*outArgC],
&llngValue, sizeof(long long));
*outArgC += 2;
}
} /* Structs of size 1, 2, 4, and 8 are passed in registers,
just like the corresponding int/float types. */
switch (size)
{
case 1:
return FFI_TYPE_UINT8;
/*======================== End of Routine ============================*/ case 2:
return FFI_TYPE_UINT16;
/*====================================================================*/ case 4:
/* */ if (arg->type == FFI_TYPE_FLOAT)
/* Name - ffi_insert_double. */ return FFI_TYPE_FLOAT;
/* */ else
/* Function - Insert a double parameter in a FP register if there is */ return FFI_TYPE_UINT32;
/* a spare else on the stack. */
/* */
/*====================================================================*/
void case 8:
ffi_insert_double(double dblValue, stackLayout *stack, if (arg->type == FFI_TYPE_DOUBLE)
int *fprArgC, int *outArgC) return FFI_TYPE_DOUBLE;
{ else
return FFI_TYPE_UINT64;
if (*fprArgC < MAX_FPRARGS) { default:
stack->fprArgs[*fprArgC].d = dblValue; break;
*fprArgC += 1;
}
else {
memcpy(&stack->outArgs[*outArgC],
&dblValue,sizeof(double));
*outArgC += 2;
} }
/* Other structs are passed via a pointer to the data. */
return FFI_TYPE_POINTER;
} }
/*======================== End of Routine ============================*/ /*======================== End of Routine ============================*/
...@@ -225,201 +152,167 @@ ffi_insert_double(double dblValue, stackLayout *stack, ...@@ -225,201 +152,167 @@ ffi_insert_double(double dblValue, stackLayout *stack,
/* ffi_prep_args is called by the assembly routine once stack space */ /* ffi_prep_args is called by the assembly routine once stack space */
/* has been allocated for the function's arguments. */ /* 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 static void
ffi_prep_args(stackLayout *stack, extended_cif *ecif) ffi_prep_args (unsigned char *stack, extended_cif *ecif)
{ {
const unsigned bytes = ecif->cif->bytes; /* The stack space will be filled with those areas:
const unsigned flags = ecif->cif->flags;
/*----------------------------------------------------------*/ FPR argument register save area (highest addresses)
/* Pointer to the copy area on stack for structures */ GPR argument register save area
/*----------------------------------------------------------*/ temporary struct copies
char *copySpace = (char *) stack + bytes + sizeof(stackLayout); overflow argument area (lowest addresses)
/*----------------------------------------------------------*/ We set up the following pointers:
/* Count of general and floating point register usage */
/*----------------------------------------------------------*/ p_fpr: bottom of the FPR area (growing upwards)
int intArgC = 0, p_gpr: bottom of the GPR area (growing upwards)
fprArgC = 0, p_ov: bottom of the overflow area (growing upwards)
outArgC = 0; 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;
int i;
ffi_type **ptr; ffi_type **ptr;
void **p_argv; void **p_argv = ecif->avalue;
size_t structCopySize; int i;
unsigned gprValue, strFlags = 0;
unsigned long long llngValue;
double dblValue;
/* Now for the arguments. */ /* If we returning a structure then we set the first parameter register
p_argv = ecif->avalue; to the address of where we are returning this structure. */
/*----------------------------------------------------------------------*/ if (ecif->cif->flags == FFI390_RET_STRUCT)
/* If we returning a structure then we set the first parameter register */ p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
/* to the address of where we are returning this structure */
/*----------------------------------------------------------------------*/ /* Now for the arguments. */
if (flags == FFI_TYPE_STRUCT)
stack->gprArgs[intArgC++] = (int) ecif->rvalue;
for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
i > 0; i > 0;
i--, ptr++, p_argv++) i--, ptr++, p_argv++)
{ {
switch ((*ptr)->type) { void *arg = *p_argv;
int type = (*ptr)->type;
case FFI_TYPE_FLOAT: /* Check how a structure type is passed. */
if (fprArgC < MAX_FPRARGS) if (type == FFI_TYPE_STRUCT)
stack->fprArgs[fprArgC++].f = *(float *) *p_argv; {
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 else
stack->outArgs[outArgC++] = *(int *) *p_argv; #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; break;
case FFI_TYPE_DOUBLE: case FFI_TYPE_FLOAT:
dblValue = *(double *) *p_argv; if (n_fpr < MAX_FPRARGS)
ffi_insert_double(dblValue, stack, &fprArgC, &outArgC); p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
else
p_ov[n_ov++] = *(unsigned int *) arg;
break; break;
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); 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; break;
case FFI_TYPE_UINT8: case FFI_TYPE_UINT32:
gprValue = *(unsigned char *)*p_argv; if (n_gpr < MAX_GPRARGS)
ffi_insert_int(gprValue, stack, &intArgC, &outArgC); p_gpr[n_gpr++] = *(unsigned int *) arg;
else
p_ov[n_ov++] = *(unsigned int *) arg;
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); if (n_gpr < MAX_GPRARGS)
p_gpr[n_gpr++] = *(signed int *) arg;
else
p_ov[n_ov++] = *(signed int *) arg;
break; break;
case FFI_TYPE_UINT16: case FFI_TYPE_UINT16:
gprValue = *(unsigned short *)*p_argv; if (n_gpr < MAX_GPRARGS)
ffi_insert_int(gprValue, stack, &intArgC, &outArgC); p_gpr[n_gpr++] = *(unsigned short *) arg;
else
p_ov[n_ov++] = *(unsigned short *) arg;
break; break;
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
gprValue = *(signed short *)*p_argv; if (n_gpr < MAX_GPRARGS)
ffi_insert_int(gprValue, stack, &intArgC, &outArgC); p_gpr[n_gpr++] = *(signed short *) arg;
break;
case FFI_TYPE_STRUCT:
/*--------------------------------------------------*/
/* If structure > 8 bytes then it goes on the stack */
/*--------------------------------------------------*/
if (((*ptr)->size > 8) ||
((*ptr)->size > 4 &&
(*ptr)->size < 8))
strFlags = STR_STACK;
else else
strFlags = ffi_check_struct((ffi_type *) *ptr, &strFlags); p_ov[n_ov++] = *(signed short *) arg;
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; break;
/*-------------------------------------------*/ case FFI_TYPE_UINT8:
/* Structure that will fit in one FPR */ if (n_gpr < MAX_GPRARGS)
/*-------------------------------------------*/ p_gpr[n_gpr++] = *(unsigned char *) arg;
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 else
stack->outArgs[outArgC++] = gprValue; p_ov[n_ov++] = *(unsigned char *) arg;
}
break; break;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_SINT8:
case FFI_TYPE_LONGDOUBLE: if (n_gpr < MAX_GPRARGS)
structCopySize = (((*ptr)->size + 15) & ~0xF); p_gpr[n_gpr++] = *(signed char *) arg;
copySpace -= structCopySize;
memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
gprValue = (unsigned) copySpace;
if (intArgC < MAX_GPRARGS)
stack->gprArgs[intArgC++] = gprValue;
else else
stack->outArgs[outArgC++] = gprValue; p_ov[n_ov++] = *(signed char *) arg;
break; break;
#endif
case FFI_TYPE_INT: default:
case FFI_TYPE_UINT32: FFI_ASSERT (0);
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;
} }
} }
} }
...@@ -437,106 +330,137 @@ ffi_prep_args(stackLayout *stack, extended_cif *ecif) ...@@ -437,106 +330,137 @@ ffi_prep_args(stackLayout *stack, extended_cif *ecif)
ffi_status ffi_status
ffi_prep_cif_machdep(ffi_cif *cif) ffi_prep_cif_machdep(ffi_cif *cif)
{ {
int i; size_t struct_size = 0;
int n_gpr = 0;
int n_fpr = 0;
int n_ov = 0;
ffi_type **ptr; ffi_type **ptr;
unsigned bytes; int i;
int fpArgC = 0,
intArgC = 0; /* Determine return value handling. */
unsigned flags = 0;
unsigned structCopySize = 0; switch (cif->rtype->type)
/*-----------------------------------------------------------------*/
/* Extra space required in stack for overflow parameters. */
/*-----------------------------------------------------------------*/
bytes = 0;
/*--------------------------------------------------------*/
/* Return value handling. The rules are as follows: */
/* - 32-bit (or less) integer values are returned in gpr2 */
/* - Structures are returned as pointers in gpr2 */
/* - 64-bit integer values are returned in gpr2 and 3 */
/* - Single/double FP values are returned in fpr0 */
/*--------------------------------------------------------*/
flags = cif->rtype->type;
/*------------------------------------------------------------------------*/
/* The first MAX_GPRARGS words of integer arguments, and the */
/* first MAX_FPRARGS floating point arguments, go in registers; the rest */
/* goes on the stack. Structures and long doubles (if not equivalent */
/* to double) are passed as a pointer to a copy of the structure. */
/* Stuff on the stack needs to keep proper alignment. */
/*------------------------------------------------------------------------*/
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
switch ((*ptr)->type)
{ {
/* 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: case FFI_TYPE_FLOAT:
cif->flags = FFI390_RET_FLOAT;
break;
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
fpArgC++; cif->flags = FFI390_RET_DOUBLE;
if (fpArgC > MAX_FPRARGS && intArgC%2 != 0)
intArgC++;
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:
/*----------------------------------------------------*/ cif->flags = FFI390_RET_INT64;
/* '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; break;
case FFI_TYPE_STRUCT: case FFI_TYPE_INT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_UINT32:
case FFI_TYPE_LONGDOUBLE: 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 #endif
/*----------------------------------------------------*/ break;
/* 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: default:
/*----------------------------------------------------*/ FFI_ASSERT (0);
/* Everything else is passed as a 4-byte word in a */
/* GPR either the object itself or a pointer to it. */
/*----------------------------------------------------*/
intArgC++;
break; break;
} }
/* Now for the arguments. */
for (ptr = cif->arg_types, i = cif->nargs;
i > 0;
i--, ptr++)
{
int type = (*ptr)->type;
/* Check how a structure type is passed. */
if (type == FFI_TYPE_STRUCT)
{
type = ffi_check_struct_type (*ptr);
/* If we pass the struct via pointer, we must reserve space
to copy its data for proper call-by-value semantics. */
if (type == FFI_TYPE_POINTER)
struct_size += ROUND_SIZE ((*ptr)->size);
} }
/*-----------------------------------------------------------------*/ /* Now handle all primitive int/float data types. */
/* Stack space. */ switch (type)
/*-----------------------------------------------------------------*/ {
if (intArgC > MAX_GPRARGS) /* The first MAX_FPRARGS floating point arguments
bytes += (intArgC - MAX_GPRARGS) * sizeof(int); go in FPRs, the rest overflow to the stack. */
if (fpArgC > MAX_FPRARGS)
bytes += (fpArgC - MAX_FPRARGS) * sizeof(double); 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,
/* The stack space allocated needs to be a multiple of 16 bytes. */ 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
bytes = (bytes + 15) & ~0xF; subsequent argument either). */
/*-----------------------------------------------------------------*/ #ifndef __s390x__
/* Add in the space for the copied structures. */ case FFI_TYPE_UINT64:
/*-----------------------------------------------------------------*/ case FFI_TYPE_SINT64:
bytes += structCopySize; if (n_gpr == MAX_GPRARGS-1)
n_gpr = MAX_GPRARGS;
if (n_gpr < MAX_GPRARGS)
n_gpr += 2;
else
n_ov += 2;
break;
#endif
cif->flags = flags; /* Everything else is passed in GPRs (until MAX_GPRARGS
cif->bytes = bytes; 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; return FFI_OK;
} }
...@@ -557,33 +481,279 @@ ffi_call(ffi_cif *cif, ...@@ -557,33 +481,279 @@ ffi_call(ffi_cif *cif,
void *rvalue, void *rvalue,
void **avalue) void **avalue)
{ {
int ret_type = cif->flags;
extended_cif ecif; extended_cif ecif;
ecif.cif = cif; ecif.cif = cif;
ecif.avalue = avalue; ecif.avalue = avalue;
ecif.rvalue = rvalue;
/*-----------------------------------------------------------------*/ /* If we don't have a return value, we need to fake one. */
/* If the return value is a struct and we don't have a return */ if (rvalue == NULL)
/* value address then we need to make one */ {
/*-----------------------------------------------------------------*/ if (ret_type == FFI390_RET_STRUCT)
if ((rvalue == NULL) && ecif.rvalue = alloca (cif->rtype->size);
(cif->rtype->type == FFI_TYPE_STRUCT))
ecif.rvalue = alloca(cif->rtype->size);
else else
ecif.rvalue = rvalue; ret_type = FFI390_RET_VOID;
}
switch (cif->abi) switch (cif->abi)
{ {
case FFI_SYSV: case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args, ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
&ecif, cif->bytes, ret_type, ecif.rvalue, fn);
cif->flags, ecif.rvalue, fn); break;
default:
FFI_ASSERT (0);
break;
}
}
/*======================== End of Routine ============================*/
/*====================================================================*/
/* */
/* Name - ffi_closure_helper_SYSV. */
/* */
/* Function - Call a FFI closure target function. */
/* */
/*====================================================================*/
void
ffi_closure_helper_SYSV (ffi_closure *closure,
unsigned long *p_gpr,
unsigned long long *p_fpr,
unsigned long *p_ov)
{
unsigned long long ret_buffer;
void *rvalue = &ret_buffer;
void **avalue;
void **p_arg;
int n_gpr = 0;
int n_fpr = 0;
int n_ov = 0;
ffi_type **ptr;
int i;
/* Allocate buffer for argument list pointers. */
p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
/* If we returning a structure, pass the structure address
directly to the target function. Otherwise, have the target
function store the return value to the GPR save area. */
if (closure->cif->flags == FFI390_RET_STRUCT)
rvalue = (void *) p_gpr[n_gpr++];
/* Now for the arguments. */
for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
i > 0;
i--, p_arg++, ptr++)
{
int deref_struct_pointer = 0;
int type = (*ptr)->type;
/* Check how a structure type is passed. */
if (type == FFI_TYPE_STRUCT)
{
type = ffi_check_struct_type (*ptr);
/* If we pass the struct via pointer, remember to
retrieve the pointer later. */
if (type == FFI_TYPE_POINTER)
deref_struct_pointer = 1;
}
/* Pointers are passed like UINTs of the same size. */
if (type == FFI_TYPE_POINTER)
#ifdef __s390x__
type = FFI_TYPE_UINT64;
#else
type = FFI_TYPE_UINT32;
#endif
/* Now handle all primitive int/float data types. */
switch (type)
{
case FFI_TYPE_DOUBLE:
if (n_fpr < MAX_FPRARGS)
*p_arg = &p_fpr[n_fpr++];
else
*p_arg = &p_ov[n_ov],
n_ov += sizeof (double) / sizeof (long);
break;
case FFI_TYPE_FLOAT:
if (n_fpr < MAX_FPRARGS)
*p_arg = &p_fpr[n_fpr++];
else
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
break;
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
#ifdef __s390x__
if (n_gpr < MAX_GPRARGS)
*p_arg = &p_gpr[n_gpr++];
else
*p_arg = &p_ov[n_ov++];
#else
if (n_gpr == MAX_GPRARGS-1)
n_gpr = MAX_GPRARGS;
if (n_gpr < MAX_GPRARGS)
*p_arg = &p_gpr[n_gpr], n_gpr += 2;
else
*p_arg = &p_ov[n_ov], n_ov += 2;
#endif
break;
case FFI_TYPE_INT:
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
if (n_gpr < MAX_GPRARGS)
*p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
else
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
break;
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT16:
if (n_gpr < MAX_GPRARGS)
*p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
else
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
break;
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT8:
if (n_gpr < MAX_GPRARGS)
*p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
else
*p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
break;
default:
FFI_ASSERT (0);
break;
}
/* If this is a struct passed via pointer, we need to
actually retrieve that pointer. */
if (deref_struct_pointer)
*p_arg = *(void **)*p_arg;
}
/* Call the target function. */
(closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
/* Convert the return value. */
switch (closure->cif->rtype->type)
{
/* Void is easy, and so is struct. */
case FFI_TYPE_VOID:
case FFI_TYPE_STRUCT:
break;
/* Floating point values are returned in fpr 0. */
case FFI_TYPE_FLOAT:
p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
break;
case FFI_TYPE_DOUBLE:
p_fpr[0] = *(unsigned long long *) rvalue;
break;
/* Integer values are returned in gpr 2 (and gpr 3
for 64-bit values on 31-bit machines). */
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
#ifdef __s390x__
p_gpr[0] = *(unsigned long *) rvalue;
#else
p_gpr[0] = ((unsigned long *) rvalue)[0],
p_gpr[1] = ((unsigned long *) rvalue)[1];
#endif
break;
case FFI_TYPE_UINT32:
p_gpr[0] = *(unsigned int *) rvalue;
break;
case FFI_TYPE_INT:
case FFI_TYPE_SINT32:
p_gpr[0] = *(signed int *) rvalue;
break;
case FFI_TYPE_UINT16:
p_gpr[0] = *(unsigned short *) rvalue;
break;
case FFI_TYPE_SINT16:
p_gpr[0] = *(signed short *) rvalue;
break;
case FFI_TYPE_UINT8:
p_gpr[0] = *(unsigned char *) rvalue;
break;
case FFI_TYPE_SINT8:
p_gpr[0] = *(signed char *) rvalue;
break; break;
default: default:
FFI_ASSERT(0); FFI_ASSERT (0);
break; break;
} }
} }
/*======================== End of Routine ============================*/ /*======================== End of Routine ============================*/
/*====================================================================*/
/* */
/* Name - ffi_prep_closure. */
/* */
/* Function - Prepare a FFI closure. */
/* */
/*====================================================================*/
ffi_status
ffi_prep_closure (ffi_closure *closure,
ffi_cif *cif,
void (*fun) (ffi_cif *, void *, void **, void *),
void *user_data)
{
FFI_ASSERT (cif->abi == FFI_SYSV);
#ifndef __s390x__
*(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
*(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */
*(short *)&closure->tramp [4] = 0x1006;
*(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */
*(long *)&closure->tramp [8] = (long)closure;
*(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
#else
*(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
*(short *)&closure->tramp [2] = 0xeb01; /* lmg %r0,%r1,14(%r1) */
*(short *)&closure->tramp [4] = 0x100e;
*(short *)&closure->tramp [6] = 0x0004;
*(short *)&closure->tramp [8] = 0x07f1; /* br %r1 */
*(long *)&closure->tramp[16] = (long)closure;
*(long *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
#endif
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
}
/*======================== End of Routine ============================*/
...@@ -23,149 +23,129 @@ ...@@ -23,149 +23,129 @@
OTHER DEALINGS IN THE SOFTWARE. OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */ ----------------------------------------------------------------------- */
#define LIBFFI_ASM #ifndef __s390x__
#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) .LretDouble:
ld %f2,56(%r10) l %r4,48+56(%r11)
std %f0,0(%r8) # Return double
#------------------------------------------------------------------ lm %r6,%r15,48+24(%r11)
# 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:
#------------------------------------------------------------------
# return a pointer
#------------------------------------------------------------------
st %r2,0(%r6)
j .Lepilogue
.Lepilogue:
l %r15,0(%r11)
l %r4,56(%r15)
lm %r6,%r15,24(%r15)
br %r4 br %r4
.LretInt32:
l %r4,48+56(%r11)
st %r2,0(%r8) # Return int
lm %r6,%r15,48+24(%r11)
br %r4
.LretInt64:
l %r4,48+56(%r11)
stm %r2,%r3,0(%r8) # Return long long
lm %r6,%r15,48+24(%r11)
br %r4
.Ltable:
.byte .LretNone-.Lbase # FFI390_RET_VOID
.byte .LretNone-.Lbase # FFI390_RET_STRUCT
.byte .LretFloat-.Lbase # FFI390_RET_FLOAT
.byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
.byte .LretInt32-.Lbase # FFI390_RET_INT32
.byte .LretInt64-.Lbase # FFI390_RET_INT64
.LFE1: .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