[Mono-list] S390 patch
Ferguson, Neale
Neale.Ferguson@SoftwareAG-USA.com
Mon, 30 Sep 2002 08:54:37 -0400
This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.
------_=_NextPart_000_01C26880.8868B020
Content-Type: text/plain;
charset="iso-8859-1"
Hi,
Here's my first effort at the S390 port.
------_=_NextPart_000_01C26880.8868B020
Content-Type: application/octet-stream;
name="mono-s390.diffs"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="mono-s390.diffs"
Index: mono/configure.in
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /mono/mono/configure.in,v
retrieving revision 1.105
diff -u -r1.105 configure.in
--- mono/configure.in 27 Sep 2002 13:54:16 -0000 1.105
+++ mono/configure.in 30 Sep 2002 12:43:59 -0000
@@ -470,6 +470,7 @@
#m68k-*-linux*) TARGET=3DM68K;;
macppc-*-openbsd* | powerpc-*-linux* | powerpc-*-openbsd* | =
powerpc-*-sysv*) TARGET=3DPOWERPC; arch_target=3Dppc;;
arm-*-linux-* | armv4l-*-linux-*) TARGET=3DARM; arch_target=3Darm; =
ACCESS_UNALIGNED=3D"no";;
+s390-*-linux*) TARGET=3DS390; arch_target=3Ds390; =
ACCESS_UNALIGNED=3D"no";;
esac
=20
if test ${TARGET} =3D unknown; then
@@ -489,6 +490,7 @@
AM_CONDITIONAL(M68K, test x$TARGET =3D xM68K)
AM_CONDITIONAL(POWERPC, test x$TARGET =3D xPOWERPC)
AM_CONDITIONAL(ARM, test x$TARGET =3D xARM)
+AM_CONDITIONAL(S390, test x$TARGET =3D xS390)
=20
LIBC=3D"libc.so.6"
AC_SUBST(LIBC)
@@ -512,6 +514,7 @@
mono/arch/x86/Makefile
mono/arch/ppc/Makefile
mono/arch/sparc/Makefile
+mono/arch/s390/Makefile
mono/arch/arm/Makefile
mono/interpreter/Makefile
mono/tests/Makefile
Index: mono/mono/io-layer/atomic.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /mono/mono/mono/io-layer/atomic.h,v
retrieving revision 1.9
diff -u -r1.9 atomic.h
--- mono/mono/io-layer/atomic.h 27 Sep 2002 12:02:56 -0000 1.9
+++ mono/mono/io-layer/atomic.h 30 Sep 2002 12:43:59 -0000
@@ -246,6 +246,93 @@
return(ret);
}
=20
+#elif __s390__
+
+#define WAPI_ATOMIC_ASM
+
+static inline gint32=20
+InterlockedCompareExchange(volatile gint32 *dest,
+ gint32 exch, gint32 comp)
+{
+ gint32 old;
+
+ __asm__ __volatile__ ("\tL\t%1,%0\n"
+ "\tCS\t%3,%2,%0\n"
+ : "=3Dm" (*dest), "=3Dr" (old)
+ : "r" (exch), "r" (comp)
+ : "cc");=09
+ return(old);
+}
+
+#define InterlockedCompareExchangePointer InterlockedCompareExchange
+
+static inline gint32=20
+InterlockedIncrement(volatile gint32 *val)
+{
+ gint32 tmp;
+=09
+ __asm__ __volatile__ ("0:\tL\t%0,%1\n"
+ "\tLR\t1,%0\n"
+ "\tAHI\t1,1\n"
+ "0:\tCS\t%0,1,%1\n"
+ "\tJNZ\t0b"
+ : "=3Dr" (tmp), "+m" (*val)
+ : : "1", "cc");
+
+ return(tmp+1);
+}
+
+static inline gint32=20
+InterlockedDecrement(volatile gint32 *val)
+{
+ gint32 tmp;
+=09
+ __asm__ __volatile__ ("0:\tL\t%0,%1\n"
+ "\tLR\t1,%0\n"
+ "\tAHI\t1,-1\n"
+ "0:\tCS\t%0,1,%1\n"
+ "\tJNZ\t0b"
+ : "=3Dr" (tmp), "+m" (*val)
+ : : "1", "cc");
+
+ return(tmp-1);
+}
+
+
+static inline gint32=20
+InterlockedExchange(volatile gint32 *val, gint32 new_val)
+{
+ gint32 ret;
+=09
+ __asm__ __volatile__ ("0:\tL\t%1,%0\n"
+ "\tCS\t%1,%2,%0\n"
+ "\tJNZ\t0b"
+ : "+m" (*val), "=3Dr" (ret)
+ : "r" (new_val)
+ : "cc");
+
+ return(ret);
+}
+
+#define InterlockedExchangePointer InterlockedExchange
+
+static inline gint32=20
+InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
+{
+ gint32 ret;
+
+ __asm__ __volatile__ ("0:\tL\t%0,%1\n"
+ "\tLR\t1,%0\n"
+ "\tAR\t1,%2\n"
+ "0:\tCS\t%0,1,%1\n"
+ "\tJNZ\t0b"
+ : "=3Dr" (ret), "+m" (*val)
+ : "r" (add)=20
+ : "1", "cc");
+=09
+ return(ret);
+}
+
#else
=20
extern gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 =
exch, gint32 comp);
--- /dev/null Thu Sep 26 21:58:57 2002
+++ mono/mono/arch/s390/Makefile.am Fri Sep 27 12:06:53 2002
@@ -0,0 +1,7 @@
+
+INCLUDES =3D $(GLIB_CFLAGS) -I$(top_srcdir)
+
+noinst_LTLIBRARIES =3D libmonoarch-s390.la
+
+libmonoarch_s390_la_SOURCES =3D tramp.c s390-codegen.h
+
--- /dev/null Thu Sep 26 21:58:57 2002
+++ mono/mono/arch/s390/Makefile.in Fri Sep 27 12:43:41 2002
@@ -0,0 +1,342 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL =3D @SHELL@
+
+srcdir =3D @srcdir@
+top_srcdir =3D @top_srcdir@
+VPATH =3D @srcdir@
+prefix =3D @prefix@
+exec_prefix =3D @exec_prefix@
+
+bindir =3D @bindir@
+sbindir =3D @sbindir@
+libexecdir =3D @libexecdir@
+datadir =3D @datadir@
+sysconfdir =3D @sysconfdir@
+sharedstatedir =3D @sharedstatedir@
+localstatedir =3D @localstatedir@
+libdir =3D @libdir@
+infodir =3D @infodir@
+mandir =3D @mandir@
+includedir =3D @includedir@
+oldincludedir =3D /usr/include
+
+DESTDIR =3D
+
+pkgdatadir =3D $(datadir)/@PACKAGE@
+pkglibdir =3D $(libdir)/@PACKAGE@
+pkgincludedir =3D $(includedir)/@PACKAGE@
+
+top_builddir =3D ../../..
+
+ACLOCAL =3D @ACLOCAL@
+AUTOCONF =3D @AUTOCONF@
+AUTOMAKE =3D @AUTOMAKE@
+AUTOHEADER =3D @AUTOHEADER@
+
+INSTALL =3D @INSTALL@
+INSTALL_PROGRAM =3D @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA =3D @INSTALL_DATA@
+INSTALL_SCRIPT =3D @INSTALL_SCRIPT@
+transform =3D @program_transform_name@
+
+NORMAL_INSTALL =3D :
+PRE_INSTALL =3D :
+POST_INSTALL =3D :
+NORMAL_UNINSTALL =3D :
+PRE_UNINSTALL =3D :
+POST_UNINSTALL =3D :
+build_alias =3D @build_alias@
+build_triplet =3D @build@
+host_alias =3D @host_alias@
+host_triplet =3D @host@
+target_alias =3D @target_alias@
+target_triplet =3D @target@
+AS =3D @AS@
+BISON =3D @BISON@
+BUILD_EXEEXT =3D @BUILD_EXEEXT@
+BUILD_GLIB_CFLAGS =3D @BUILD_GLIB_CFLAGS@
+BUILD_GLIB_LIBS =3D @BUILD_GLIB_LIBS@
+CC =3D @CC@
+CC_FOR_BUILD =3D @CC_FOR_BUILD@
+CFLAGS =3D @CFLAGS@
+CPPFLAGS =3D @CPPFLAGS@
+DISABLE_SHARED_HANDLES =3D @DISABLE_SHARED_HANDLES@
+DLLTOOL =3D @DLLTOOL@
+GLIB_CFLAGS =3D @GLIB_CFLAGS@
+GLIB_LIBS =3D @GLIB_LIBS@
+GMODULE_CFLAGS =3D @GMODULE_CFLAGS@
+GMODULE_LIBS =3D @GMODULE_LIBS@
+HAVE_BOEHM_GC =3D @HAVE_BOEHM_GC@
+HOST_CC =3D @HOST_CC@
+LIBC =3D @LIBC@
+LIBTOOL =3D @LIBTOOL@
+LN_S =3D @LN_S@
+MAINT =3D @MAINT@
+MAKEINFO =3D @MAKEINFO@
+OBJDUMP =3D @OBJDUMP@
+PACKAGE =3D @PACKAGE@
+PKG_CONFIG =3D @PKG_CONFIG@
+RANLIB =3D @RANLIB@
+VERSION =3D @VERSION@
+arch_target =3D @arch_target@
+
+INCLUDES =3D $(GLIB_CFLAGS) -I$(top_srcdir)
+
+noinst_LTLIBRARIES =3D libmonoarch-s390.la
+
+libmonoarch_s390_la_SOURCES =3D tramp.c s390-codegen.h
+mkinstalldirs =3D $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER =3D ../../../config.h
+CONFIG_CLEAN_FILES =3D=20
+LTLIBRARIES =3D $(noinst_LTLIBRARIES)
+
+
+DEFS =3D @DEFS@ -I. -I$(srcdir) -I../../..
+LDFLAGS =3D @LDFLAGS@
+LIBS =3D @LIBS@
+libmonoarch_s390_la_LDFLAGS =3D=20
+libmonoarch_s390_la_LIBADD =3D=20
+libmonoarch_s390_la_OBJECTS =3D tramp.lo
+COMPILE =3D $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) =
$(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE =3D $(LIBTOOL) --mode=3Dcompile $(CC) $(DEFS) $(INCLUDES) =
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD =3D $(CC)
+LINK =3D $(LIBTOOL) --mode=3Dlink $(CCLD) $(AM_CFLAGS) $(CFLAGS) =
$(LDFLAGS) -o $@
+DIST_COMMON =3D Makefile.am Makefile.in
+
+
+DISTFILES =3D $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) =
$(EXTRA_DIST)
+
+TAR =3D tar
+GZIP_ENV =3D --best
+DEP_FILES =3D .deps/tramp.P
+SOURCES =3D $(libmonoarch_s390_la_SOURCES)
+OBJECTS =3D $(libmonoarch_s390_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am =
$(top_srcdir)/configure.in $(ACLOCAL_M4)=20
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu mono/arch/s390/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status =
$(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=3D$(subdir)/$@ CONFIG_HEADERS=3D $(SHELL) =
./config.status
+
+
+mostlyclean-noinstLTLIBRARIES:
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+
+distclean-noinstLTLIBRARIES:
+
+maintainer-clean-noinstLTLIBRARIES:
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=3Dcompile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=3Dcompile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libmonoarch-s390.la: $(libmonoarch_s390_la_OBJECTS) =
$(libmonoarch_s390_la_DEPENDENCIES)
+ $(LINK) $(libmonoarch_s390_la_LDFLAGS) =
$(libmonoarch_s390_la_OBJECTS) $(libmonoarch_s390_la_LIBADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list=3D'$(SOURCES) $(HEADERS)'; \
+ unique=3D`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] =3D 1; } \
+ END { for (i in files) print i; }'`; \
+ here=3D`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=3D; \
+ here=3D`pwd`; \
+ list=3D'$(SOURCES) $(HEADERS)'; \
+ unique=3D`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] =3D 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o =
$$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir =3D $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir =3D mono/arch/s390
+
+distdir: $(DISTFILES)
+ here=3D`cd $(top_builddir) && pwd`; \
+ top_distdir=3D`cd $(top_distdir) && pwd`; \
+ distdir=3D`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=3D$$here =
--srcdir-name=3D$(top_srcdir) --output-dir=3D$$top_distdir --gnu =
mono/arch/s390/Makefile
+ @for file in $(DISTFILES); do \
+ d=3D$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC :=3D $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=3D-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstLTLIBRARIES clean-compile clean-libtool \
+ clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall =
\
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null Thu Sep 26 21:58:57 2002
+++ mono/mono/arch/s390/s390-codegen.h Fri Sep 27 12:06:43 2002
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) 2001 Radek Doulik
+*/
+
+#ifndef S390_H
+#define S390_H
+#include <glib.h>
+#include <assert.h>
+
+typedef enum {
+ s390_r0 =3D 0,
+ s390_r1,
+ s390_r2,
+ s390_r3,
+ s390_r4,
+ s390_r5,
+ s390_r6,
+ s390_r7,
+ s390_r8,
+ s390_r9,
+ s390_r10,
+ s390_r11,
+ s390_r12,
+ s390_r13,
+ s390_r14,
+ s390_r15,
+} S390IntRegister;
+
+typedef enum {
+ s390_f0 =3D 0,
+ s390_f1,
+ s390_f2,
+ s390_f3,
+ s390_f4,
+ s390_f5,
+ s390_f6,
+ s390_f7,
+ s390_f8,
+ s390_f9,
+ s390_f10,
+ s390_f11,
+ s390_f12,
+ s390_f13,
+ s390_f14,
+ s390_f15,
+} S390FloatRegister;
+
+typedef enum {
+ s390_fpc =3D 256,
+} S390SpecialRegister;
+
+#define s390_word(addr, value) *((guint32 *) addr) =3D (guint32) =
(value); ((guint32 *) addr)++
+#define s390_emit16(c, x) *((guint16 *) c) =3D x; ((guint16 *) c)++
+#define s390_emit32(c, x) *((guint32 *) c) =3D x; ((guint32 *) c)++
+#define s390_basr(code, r1, r2) s390_emit16 (code, (13 << 8 | (r1) << =
4 | (r2)))
+#define s390_bras(code, r, o) s390_emit32 (code, (167 << 24 | (r) << =
20 | 5 << 16 | (o)))
+#define s390_ahi(code, r, v) s390_emit32 (code, (167 << 24 | (r) << =
20 | 10 << 16 | ((v) & 0xffff)))
+#define s390_br(code, r) s390_emit16 (code, (7 << 8 | 15 << 4 | (r)))
+#define s390_lr(code, r1, r2) s390_emit16 (code, (24 << 8 | (r1) << 4 =
| (r2)))
+#define s390_l(code, r, b, d) s390_emit32 (code, (88 << 24 | (r) << =
20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_lm(code, r1, r2, b, d) s390_emit32 (code, (152 << 24 | =
(r1) << 20 | (r2) << 16 \
+ | (b) << 12 | ((d) & 0xfff)))
+#define s390_lh(code, r, b, d) s390_emit32 (code, (72 << 24 | (r) << =
20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_lhi(code, r, v) s390_emit32 (code, (167 << 24 | (r) << =
20 | 8 << 16 | ((v) & 0xffff)))
+#define s390_ic(code, r, b, d) s390_emit32 (code, (67 << 24 | (r) << =
20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_st(code, r, b, d) s390_emit32 (code, (80 << 24 | (r) << =
20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_stm(code, r1, r2, b, d) s390_emit32 (code, (144 << 24 | =
(r1) << 20 | (r2) << 16 \
+ | (b) << 12 | ((d) & 0xfff)))
+#define s390_sth(code, r, b, d) s390_emit32 (code, (64 << 24 | (r) << =
20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_stc(code, r, b, d) s390_emit32 (code, (66 << 24 | (r) << =
20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_la(code, r, b, d) s390_emit32 (code, (65 << 24 | (r) << =
20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_ld(code, f, b, d) s390_emit32 (code, (104 << 24 | (f) << =
20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_le(code, f, b, d) s390_emit32 (code, (120 << 24 | (f) << =
20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_std(code, f, b, d) s390_emit32 (code, (96 << 24 | (f) << =
20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_ste(code, f, b, d) s390_emit32 (code, (112 << 24 | (f) =
<< 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_mvc(c, l, b1, d1, b2, d2) s390_emit32 (c, (210 << 24 | =
(((l) << 16) & 0x00ff0000) | \
+ (b1) << 12 | ((d1) & 0xfff))); \
+ s390_emit16 (c, ((b2) << 12 | ((d2) & 0xfff)))
+
+#endif
--- /dev/null Thu Sep 26 21:58:57 2002
+++ mono/mono/arch/s390/tramp.c Fri Sep 27 12:20:08 2002
@@ -0,0 +1,729 @@
+/*
+ * Create trampolines to invoke arbitrary functions.
+ *=20
+ * Copyright (C) Radek Doulik
+ *=20
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include "s390-codegen.h"
+#include "mono/metadata/class.h"
+#include "mono/metadata/tabledefs.h"
+#include "mono/interpreter/interp.h"
+#include "mono/metadata/appdomain.h"
+
+#ifdef NEED_MPROTECT
+# include <sys/mman.h>
+# include <limits.h> /* for PAGESIZE */
+# ifndef PAGESIZE
+# define PAGESIZE 4096
+# endif
+#endif
+
+#define DEBUG(x) (x)
+
+#define MIN_CACHE_LINE 256
+
+#define NOT_IMPLEMENTED(x) \
+ g_error ("FIXME: %s is not yet implemented. =
(trampoline)", x);
+
+#define PROLOG_INS 20
+#define CALL_INS 4
+#define EPILOG_INS 18
+#define MIN_STACK_SIZE 96
+#define FLOAT_REGS 2
+#define GENERAL_REGS 5
+
+static void inline
+add_general (guint *gr, guint *stack_size, guint *code_size, gboolean =
simple)
+{
+ if (simple) {
+ if (*gr >=3D GENERAL_REGS) {
+ *stack_size +=3D 4;
+ *code_size +=3D 8; /* load from stack, save on stack */
+ } else {
+ *code_size +=3D 4; /* load from stack */
+ }
+ } else {
+ if (*gr >=3D GENERAL_REGS - 1) {
+ *stack_size +=3D 8 + (*stack_size % 8);
+ *code_size +=3D 8; /* 2x load from stack, 2x save to stack */
+ } else {
+ *code_size +=3D 8; /* 2x load from stack */
+ }
+ (*gr) ++;
+ }
+ (*gr) ++;
+}
+
+static void inline
+calculate_sizes (MonoMethodSignature *sig, guint *stack_size, guint =
*code_size, gboolean string_ctor)
+{
+ guint i, fr, gr;
+ guint32 simpletype;
+
+ fr =3D 0;
+ gr =3D 2;
+ *stack_size =3D MIN_STACK_SIZE;
+ *code_size =3D (PROLOG_INS + CALL_INS + EPILOG_INS);
+
+ if (sig->hasthis) {
+ add_general (&gr, stack_size, code_size, TRUE);
+ }
+
+ for (i =3D 0; i < sig->param_count; ++i) {
+ if (sig->params [i]->byref) {
+ add_general (&gr, stack_size, code_size, TRUE);
+ continue;
+ }
+ simpletype =3D sig->params [i]->type;
+ enum_calc_size:
+ switch (simpletype) {
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ add_general (&gr, stack_size, code_size, TRUE);
+ break;
+ case MONO_TYPE_SZARRAY:
+ add_general (&gr, stack_size, code_size, TRUE);
+ *code_size +=3D 4;
+ break;
+ case MONO_TYPE_VALUETYPE:
+ if (sig->params [i]->data.klass->enumtype) {
+ simpletype =3D sig->params [i]->data.klass->enum_basetype->type;
+ goto enum_calc_size;
+ }
+ if (mono_class_value_size (sig->params [i]->data.klass, NULL) !=3D =
4)
+ g_error ("can only marshal enums, not generic structures (size: =
%d)",
+ mono_class_value_size (sig->params [i]->data.klass, NULL));
+ add_general (&gr, stack_size, code_size, TRUE);
+ *code_size +=3D 4;
+ break;
+ case MONO_TYPE_I8:
+ add_general (&gr, stack_size, code_size, FALSE);
+ break;
+ case MONO_TYPE_R4:
+ if (fr < FLOAT_REGS) {
+ *code_size +=3D 4;
+ fr++;
+ }
+ else {
+ *code_size +=3D 4;
+ *stack_size +=3D 8;
+ }
+ break;
+ case MONO_TYPE_R8:
+ if (fr < FLOAT_REGS) {
+ *code_size +=3D 4;
+ fr ++;
+ } else {
+ *code_size +=3D 4;
+ *stack_size +=3D 8 + (*stack_size % 8);
+ }
+ break;
+ default:
+ g_error ("Can't trampoline 0x%x", sig->params [i]->type);
+ }
+ }
+
+ if (sig->ret->byref || string_ctor) {
+ *code_size +=3D 8;
+ } else {
+ simpletype =3D sig->ret->type;
+enum_retvalue:
+ switch (simpletype) {
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_R4:
+ case MONO_TYPE_R8:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_STRING:
+ *code_size +=3D 8;
+ break;
+ case MONO_TYPE_I8:
+ *code_size +=3D 12;
+ break;
+ case MONO_TYPE_VALUETYPE:
+ if (sig->ret->data.klass->enumtype) {
+ simpletype =3D sig->ret->data.klass->enum_basetype->type;
+ goto enum_retvalue;
+ }
+ NOT_IMPLEMENTED ("valuetype");
+ break;
+ case MONO_TYPE_VOID:
+ break;
+ default:
+ g_error ("Can't handle as return value 0x%x", sig->ret->type);
+ }
+ }
+
+ /* align stack size to 16 */
+ DEBUG (printf (" stack size: %d (%d)\n code size: %d\n", =
(*stack_size + 15) & ~15, *stack_size, *code_size));
+ *stack_size =3D (*stack_size + 15) & ~15;
+
+}
+
+static inline guint8 *
+emit_prolog (guint8 *p, MonoMethodSignature *sig, guint stack_size)
+{
+ /* function prolog */
+ s390_stm (p, s390_r6, s390_r15, s390_r15, 24);
+ s390_l (p, s390_r7, s390_r15, 96);
+ s390_lr (p, s390_r11, s390_r15);
+ s390_ahi (p, s390_r15, -(stack_size+96));
+ s390_st (p, s390_r11, s390_r15, 0);
+
+ /*-----------------------------------------*/
+ /* Save: */
+ /* - address of "callme" */
+ /* - address of "retval" */
+ /* - address of "arguments" */
+ /*-----------------------------------------*/
+ s390_lr (p, s390_r9, s390_r2);
+ s390_lr (p, s390_r8, s390_r3);
+ s390_lr (p, s390_r10, s390_r5);
+
+ return p;
+}
+
+#define ARG_BASE s390_r10
+#define STK_BASE s390_r15
+#define STKARG (i*(sizeof(stackval)))
+/*
+ * The resulting function takes the form:
+ * void func (void (*callme)(), void *retval, void *this_obj, stackval =
*arguments);
+ */
+
+
+inline static guint8*
+emit_save_parameters (guint8 *p, MonoMethodSignature *sig, guint =
stack_size)
+{
+ guint i, fr, gr, act_strs, stack_par_pos;
+ guint32 simpletype;
+
+ gr =3D fr =3D 0;
+ act_strs =3D 0;
+ stack_par_pos =3D MIN_STACK_SIZE;
+
+ if (sig->hasthis) {
+ s390_lr (p, s390_r2, s390_r4);
+ gr++;
+ }
+
+ DEBUG (printf (" count: %d\n",sig->param_count));
+ act_strs =3D 0;
+ for (i =3D 0; i < sig->param_count; ++i) {
+ if (sig->params [i]->byref) {
+ if (gr < GENERAL_REGS) {
+ s390_l (p, s390_r2 + gr, ARG_BASE, STKARG);
+ gr ++;
+ } else {
+ s390_l (p, s390_r0, ARG_BASE, STKARG);
+ s390_st (p, s390_r0, STK_BASE, stack_par_pos);
+ stack_par_pos +=3D sizeof(long);
+ }
+ continue;
+ }
+ simpletype =3D sig->params [i]->type;
+ enum_calc_size:
+ switch (simpletype) {
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_SZARRAY:
+ if (gr < GENERAL_REGS) {
+ s390_l (p, s390_r2 + gr, ARG_BASE, STKARG);
+ gr ++;
+ } else {
+ s390_l (p, s390_r0, ARG_BASE, STKARG);
+ s390_st (p, s390_r0, STK_BASE, stack_par_pos);
+ stack_par_pos +=3D sizeof(long);
+ }
+ break;
+ case MONO_TYPE_VALUETYPE:
+ if (sig->params [i]->data.klass->enumtype) {
+ simpletype =3D sig->params [i]->data.klass->enum_basetype->type;
+ goto enum_calc_size;
+ }
+ if (mono_class_value_size (sig->params [i]->data.klass, NULL) !=3D =
4)
+ g_error ("can only marshal enums, not generic structures (size: =
%d)",
+ mono_class_value_size (sig->params [i]->data.klass, NULL));
+ if (gr < GENERAL_REGS) {
+ s390_l (p, s390_r2 + gr, ARG_BASE, STKARG);
+ s390_l (p, s390_r2 + gr, s390_r2 + gr, 0);
+ gr++;
+ } else {
+ s390_l (p, s390_r10, ARG_BASE, STKARG);
+ s390_l (p, s390_r10, s390_r10, 0);
+ s390_st (p, s390_r10, STK_BASE, stack_par_pos);
+ stack_par_pos +=3D sizeof(long);
+ }
+ break;
+ case MONO_TYPE_I8:
+ if (gr < GENERAL_REGS-1) {
+ s390_lm (p, s390_r2 + gr, s390_r2 + gr + 1, ARG_BASE, STKARG);=20
+ gr +=3D 2;
+ } else {
+ *(guint32 *) p +=3D 7;
+ *(guint32 *) p &=3D ~7;
+ s390_mvc (p, sizeof(long long), STK_BASE, stack_par_pos, ARG_BASE, =
STKARG);=20
+ stack_par_pos +=3D sizeof(long long) + (stack_par_pos % =
sizeof(long long));
+ }
+ break;
+ case MONO_TYPE_R4:
+ if (fr < FLOAT_REGS) {
+ s390_le (p, s390_r0 + fr, ARG_BASE, STKARG);
+ fr++;
+ } else {
+ s390_mvc (p, sizeof(float), STK_BASE, stack_par_pos, ARG_BASE, =
STKARG);
+ stack_par_pos +=3D sizeof(float);
+ }
+ break;
+ case MONO_TYPE_R8:
+ if (fr < FLOAT_REGS) {
+ s390_ld (p, s390_r0 + fr, ARG_BASE, STKARG);
+ fr++;
+ } else {
+ *(guint32 *) p +=3D 7;
+ *(guint32 *) p &=3D ~7;
+ s390_mvc (p, sizeof(double), STK_BASE, stack_par_pos, ARG_BASE, =
STKARG);
+ stack_par_pos +=3D sizeof(long long) + (stack_par_pos % =
sizeof(long long));
+ }
+ break;
+ default:
+ g_error ("Can't trampoline 0x%x", sig->params [i]->type);
+ }
+ }
+
+ return p;
+}
+
+static inline guint8 *
+alloc_code_memory (guint code_size)
+{
+ guint8 *p;
+
+#ifdef NEED_MPROTECT
+ p =3D g_malloc (code_size + PAGESIZE - 1);
+
+ /* Align to a multiple of PAGESIZE, assumed to be a power of two */
+ p =3D (char *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1));
+#else
+ p =3D g_malloc (code_size);
+#endif
+ DEBUG (printf (" align: %p (%d)\n", p, (guint)p % 4));
+
+ return p;
+}
+
+static inline guint8 *
+emit_call_and_store_retval (guint8 *p, MonoMethodSignature *sig, guint =
stack_size, gboolean string_ctor)
+{
+ guint32 simpletype;
+
+ /* call "callme" */
+ s390_basr (p, s390_r14, s390_r9);=20
+
+ /* get return value */
+ if (sig->ret->byref || string_ctor) {
+ s390_st (p, s390_r2, s390_r8, 0);
+ } else {
+ simpletype =3D sig->ret->type;
+enum_retvalue:
+ switch (simpletype) {
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ s390_stc (p, s390_r2, s390_r8, 0);
+ break;
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ s390_sth (p, s390_r2, s390_r8, 0);
+ break;
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_STRING:
+ s390_st (p, s390_r2, s390_r8, 0);
+ break;
+ case MONO_TYPE_R4:
+ s390_ste (p, s390_f0, s390_r8, 0);
+ break;
+ case MONO_TYPE_R8:
+ s390_std (p, s390_f0, s390_r8, 0);
+ break;
+ case MONO_TYPE_I8:
+ s390_stm (p, s390_r2, s390_r3, s390_r8, 0);
+ break;
+ case MONO_TYPE_VALUETYPE:
+ if (sig->ret->data.klass->enumtype) {
+ simpletype =3D sig->ret->data.klass->enum_basetype->type;
+ goto enum_retvalue;
+ }
+ s390_st (p, s390_r2, s390_r8, 0);
+ break;
+ case MONO_TYPE_VOID:
+ break;
+ default:
+ g_error ("Can't handle as return value 0x%x", sig->ret->type);
+ }
+ }
+
+ return p;
+}
+
+static inline guint8 *
+emit_epilog (guint8 *p, MonoMethodSignature *sig, guint stack_size)
+{
+ /* function epilog */
+ s390_l (p, s390_r15, s390_r15, 0);
+ s390_l (p, s390_r4, s390_r15, 56);
+ s390_lm (p, s390_r6, s390_r15, s390_r15, 24);
+ s390_br (p, s390_r4);
+
+ return p;
+}
+
+MonoPIFunc
+mono_create_trampoline (MonoMethodSignature *sig, gboolean =
string_ctor)
+{
+ guint8 *p, *code_buffer;
+ guint stack_size, code_size;
+
+ DEBUG (printf ("\nPInvoke [start emiting]\n"));
+ calculate_sizes (sig, &stack_size, &code_size, string_ctor);
+
+ p =3D code_buffer =3D alloc_code_memory (code_size);
+ p =3D emit_prolog (p, sig, stack_size);
+ p =3D emit_save_parameters (p, sig, stack_size);
+ p =3D emit_call_and_store_retval (p, sig, stack_size, string_ctor);
+ p =3D emit_epilog (p, sig, stack_size);
+
+#ifdef NEED_MPROTECT
+ if (mprotect (code_buffer, 1024, PROT_READ | PROT_WRITE | PROT_EXEC)) =
{
+ g_error ("Cannot mprotect trampoline\n");
+ }
+#endif
+
+ DEBUG (printf ("emited code size: %d\n", p - code_buffer));
+
+ DEBUG (printf ("PInvoke [end emiting]\n"));
+
+ return (MonoPIFunc) code_buffer;
+ /* return fake_func; */
+}
+
+
+#define MINV_POS 96 /* MonoInvocation structure offset on stack */
+#define STACK_POS (MINV_POS - sizeof (stackval) * sig->param_count)
+#define OBJ_POS 8
+#define TYPE_OFFSET (G_STRUCT_OFFSET (stackval, type))
+
+/*
+ * Returns a pointer to a native function that can be used to
+ * call the specified method.
+ * The function created will receive the arguments according
+ * to the call convention specified in the method.
+ * This function works by creating a MonoInvocation structure,
+ * filling the fields in and calling ves_exec_method on it.
+ * Still need to figure out how to handle the exception stuff
+ * across the managed/unmanaged boundary.
+ *
+ * Logic:
+ * ------
+ * mono_create_method_pointer (MonoMethod *method)
+ * create the unmanaged->managed wrapper for method
+ * register it with mono_jit_info_table_add ()
+ * return the pointer to the code.
+ *=20
+ * What does the unmanaged->managed wrapper do?
+ * allocate a MonoInvocation structure (inv) on the stack
+ * allocate an array of stackval on the stack with length
+ * method->signature->param_count + 1 (call it stack_args)
+ * set inv->ex, inv->ex_handler, inv->child, inv->parent to NULL
+ * set inv->method to method
+ * if method is an instance method, set inv->obj to the 'this' =
argument
+ * (the first argument) otherwise set it to NULL
+ * for each argument to the method, call:
+ * stackval_from_data (sig->params [i], &stack_args [i], arg, =
sig->pinvoke);
+ * where sig is method->signature, arg is a pointer to the
+ * argument received by the function according to the call
+ * convention (if it gets passed in a reg, you need to save
+ * it on the stack first), &stack_args [i] is the pointer
+ * to the i element in the stackval array we allocated on
+ * the stack
+ * set inv->retval to the address of the last element of stack_args
+ * (we allocated param_count + 1, remember)
+ * call ves_exec_method (inv)
+ * copy the return value from inv->retval where the calling
+ * convention expects to find it on return from the wrapper
+ * (if it's a structure, use stackval_to_data)
+ * return
+ *=20
+ */
+void *
+mono_create_method_pointer (MonoMethod *method)
+{
+ MonoMethodSignature *sig;
+ MonoJitInfo *ji;
+ guint8 *p, *code_buffer;
+ guint i, align =3D 0, code_size, stack_size,=20
+ stackval_arg_pos, local_pos,=20
+ local_start, reg_param, stack_param,
+ this_flag;
+ guint32 simpletype;
+ int *vtbuf, cpos, vt_cur;
+
+ code_size =3D 1024;
+ stack_size =3D 1024;
+ stack_param =3D 0;
+
+ sig =3D method->signature;
+
+ p =3D code_buffer =3D g_malloc (code_size);
+
+ DEBUG (printf ("\nDelegate [start emiting] %s at 0x%08x\n", =
method->name,p));
+
+ /* prolog */
+ s390_stm (p, s390_r6, s390_r15, s390_r15, 24);
+ s390_l (p, s390_r7, s390_r15, 96);
+ s390_lr (p, s390_r0, s390_r15);
+ s390_ahi (p, s390_r15, -(stack_size+96));
+ s390_st (p, s390_r0, s390_r15, 0);
+
+ /* let's fill MonoInvocation */
+ /* first zero some fields */
+ s390_lhi (p, s390_r0, 0);
+ s390_st (p, s390_r0, s390_r15, (MINV_POS + G_STRUCT_OFFSET =
(MonoInvocation, ex)));
+ s390_st (p, s390_r0, s390_r15, (MINV_POS + G_STRUCT_OFFSET =
(MonoInvocation, ex_handler)));
+ s390_st (p, s390_r0, s390_r15, (MINV_POS + G_STRUCT_OFFSET =
(MonoInvocation, child)));
+ s390_st (p, s390_r0, s390_r15, (MINV_POS + G_STRUCT_OFFSET =
(MonoInvocation, parent)));
+
+ /* set method pointer */
+ s390_bras (p, s390_r13, 4);
+ s390_word (p, method);
+ s390_l (p, s390_r0, s390_r13, 0);
+ s390_st (p, s390_r0, s390_r15, (MINV_POS + G_STRUCT_OFFSET =
(MonoInvocation, method)));
+
+ local_start =3D local_pos =3D MINV_POS +=20
+ sizeof (MonoInvocation) + (sig->param_count + 1) * sizeof =
(stackval);
+
+ if (sig->hasthis) {
+ s390_st (p, s390_r2, s390_r15, (MINV_POS + G_STRUCT_OFFSET =
(MonoInvocation, obj)));
+ reg_param =3D 1;
+ } else if (sig->param_count) {
+ DEBUG (printf ("save r%d\n", 3));
+ s390_st (p, s390_r2, s390_r15, local_pos);
+ local_pos +=3D sizeof(int);
+ reg_param =3D 0;
+ }
+
+ this_flag =3D (sig->hasthis ? 1 : 0);
+ if (sig->param_count) {
+ gint save_count =3D MAX (3, MIN (6, sig->param_count - 1));
+ for (i =3D reg_param; i < save_count; i ++) {
+ s390_st (p, s390_r3 + i, s390_r15, local_pos);
+ local_pos +=3D sizeof(int);
+ DEBUG (printf ("save r%d\n", 4 + i));
+ }
+ }
+
+ /* prepare space for valuetypes */
+ vt_cur =3D local_pos;
+ vtbuf =3D alloca (sizeof(int)*sig->param_count);
+ cpos =3D 0;
+ for (i =3D 0; i < sig->param_count; i++) {
+ MonoType *type =3D sig->params [i];
+ vtbuf [i] =3D -1;
+ if (type->type =3D=3D MONO_TYPE_VALUETYPE) {
+ MonoClass *klass =3D type->data.klass;
+ gint size;
+
+ if (klass->enumtype)
+ continue;
+ size =3D mono_class_native_size (klass, &align);
+ cpos +=3D align - 1;
+ cpos &=3D ~(align - 1);
+ vtbuf [i] =3D cpos;
+ cpos +=3D size;
+ }
+ }
+ cpos +=3D 3;
+ cpos &=3D ~3;
+
+ local_pos +=3D cpos;
+
+ /* set MonoInvocation::stack_args */
+ stackval_arg_pos =3D MINV_POS + sizeof (MonoInvocation);
+ s390_la (p, s390_r0, s390_r15, stackval_arg_pos);
+ s390_st (p, s390_r0, s390_r15, (MINV_POS + G_STRUCT_OFFSET =
(MonoInvocation, stack_args)));
+
+ /* add stackval arguments */
+ for (i =3D 0; i < sig->param_count; ++i) {
+ if (reg_param < GENERAL_REGS) {
+ s390_la (p, s390_r4, s390_r15, local_start + (reg_param - =
this_flag)*4);
+ reg_param ++;
+ } else {
+ s390_la (p, s390_r4, s390_r15, stack_size + 8 + stack_param);
+ stack_param ++;
+ }
+ /*--------------------------------------*/
+ /* Load the parameter registers for the */
+ /* call to stackval_from_data */
+ /*--------------------------------------*/
+ s390_bras (p, s390_r13, 8);
+ s390_word (p, sig->params [i]);
+ s390_word (p, sig->pinvoke);
+ s390_word (p, stackval_from_data);
+ s390_l (p, s390_r2, s390_r13, 0);
+
+ s390_la (p, s390_r3, s390_r15, stackval_arg_pos);
+
+ s390_l (p, s390_r5, s390_r13, 4);
+
+ s390_l (p, s390_r9, s390_r13, 8);
+ s390_basr (p, s390_r14, s390_r9);
+
+ /* fixme: alignment */
+ DEBUG (printf ("arg_pos %d --> ", stackval_arg_pos));
+ if (sig->pinvoke)
+ stackval_arg_pos +=3D 4*mono_type_native_stack_size (sig->params =
[i], &align);
+ else
+ stackval_arg_pos +=3D 4*mono_type_stack_size (sig->params [i], =
&align);
+ DEBUG (printf ("%d\n", stackval_arg_pos));
+ }
+
+ /* return value storage */
+ s390_la (p, s390_r10, s390_r15, stackval_arg_pos);
+ s390_st (p, s390_r10, s390_r15, (MINV_POS + G_STRUCT_OFFSET =
(MonoInvocation, retval)));
+
+ /* call ves_exec_method */
+ s390_bras (p, s390_r13, 4);
+ s390_word (p, ves_exec_method);
+ s390_l (p, s390_r9, s390_r13, 0);
+ s390_la (p, s390_r2, s390_r15, MINV_POS);
+ s390_basr (p, s390_r14, s390_r9);
+
+ /* move retval from stackval to proper place (r3/r4/...) */
+ if (sig->ret->byref) {
+ DEBUG (printf ("ret by ref\n"));
+ s390_st (p, s390_r2, s390_r10, 0);
+ } else {
+ enum_retvalue:
+ switch (sig->ret->type) {
+ case MONO_TYPE_VOID:
+ break;
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ s390_lhi (p, s390_r2, 0);
+ s390_ic (p, s390_r2, s390_r10, 0);
+ break;
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ s390_lh (p, s390_r2, s390_r10, 0);
+ break;
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_CLASS:
+ s390_l (p, s390_r2, s390_r10, 0);
+ break;
+ case MONO_TYPE_I8:
+ s390_lm (p, s390_r2, s390_r3, s390_r10, 0);
+ break;
+ case MONO_TYPE_R4:
+ s390_le (p, s390_f0, s390_r10, 0);
+ break;
+ case MONO_TYPE_R8:
+ s390_ld (p, s390_f0, s390_r10, 0);
+ break;
+ case MONO_TYPE_VALUETYPE:
+ if (sig->ret->data.klass->enumtype) {
+ simpletype =3D sig->ret->data.klass->enum_basetype->type;
+ goto enum_retvalue;
+ }
+ /*---------------------------------*/
+ /* Call stackval_to_data to return */
+ /* the structure */
+ /*---------------------------------*/
+ s390_bras (p, s390_r13, 8);
+ s390_word (p, sig->ret);
+ s390_word (p, sig->pinvoke);
+ s390_word (p, stackval_to_data);
+ s390_l (p, s390_r2, s390_r13, 0);
+ s390_l (p, s390_r3, s390_r15, stackval_arg_pos);
+ s390_la (p, s390_r4, s390_r10, 0);
+ s390_l (p, s390_r5, s390_r13, 4);
+ s390_l (p, s390_r9, s390_r13, 8);
+ s390_basr (p, s390_r14, s390_r9);
+ break;
+ default:
+ g_error ("Type 0x%x not handled yet in thunk creation", =
sig->ret->type);
+ break;
+ }
+ }
+
+ /* epilog */
+ s390_l (p, s390_r15, s390_r11, 0);
+ s390_l (p, s390_r4, s390_r15, 56);
+ s390_lm (p, s390_r6, s390_r15, s390_r15, 24);
+ s390_br (p, s390_r4);
+
+ DEBUG (printf ("emited code size: %d\n", p - code_buffer));
+
+ DEBUG (printf ("Delegate [end emiting]\n"));
+
+ ji =3D g_new0 (MonoJitInfo, 1);
+ ji->method =3D method;
+ ji->code_size =3D p - code_buffer;
+ ji->code_start =3D code_buffer;
+
+ mono_jit_info_table_add (mono_root_domain, ji);
+
+ return ji->code_start;
+}
------_=_NextPart_000_01C26880.8868B020--