[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mono-list
Subject:    [Mono-list] S390 patch
From:       "Ferguson, Neale" <Neale.Ferguson () SoftwareAG-USA ! com>
Date:       2002-09-30 12:54:37
[Download RAW message or body]

Hi,
 Here's my first effort at the S390 port. 


["mono-s390.diffs" (application/octet-stream)]

Index: mono/configure.in
===================================================================
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=M68K;;
 macppc-*-openbsd* | powerpc-*-linux* | powerpc-*-openbsd* | powerpc-*-sysv*) \
TARGET=POWERPC; arch_target=ppc;;  arm-*-linux-* | armv4l-*-linux-*) TARGET=ARM; \
arch_target=arm; ACCESS_UNALIGNED="no";; +s390-*-linux*) TARGET=S390; \
arch_target=s390; ACCESS_UNALIGNED="no";;  esac
 
 if test ${TARGET} = unknown; then
@@ -489,6 +490,7 @@
 AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
 AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
 AM_CONDITIONAL(ARM, test x$TARGET = xARM)
+AM_CONDITIONAL(S390, test x$TARGET = xS390)
 
 LIBC="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
===================================================================
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);
 }
 
+#elif __s390__
+
+#define WAPI_ATOMIC_ASM
+
+static inline gint32 
+InterlockedCompareExchange(volatile gint32 *dest,
+			   gint32 exch, gint32 comp)
+{
+	gint32 old;
+
+	__asm__ __volatile__ ("\tL\t%1,%0\n"
+			      "\tCS\t%3,%2,%0\n"
+			      : "=m" (*dest), "=r" (old)
+			      : "r" (exch), "r" (comp)
+			      : "cc");	
+	return(old);
+}
+
+#define InterlockedCompareExchangePointer InterlockedCompareExchange
+
+static inline gint32 
+InterlockedIncrement(volatile gint32 *val)
+{
+	gint32 tmp;
+	
+	__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"
+			      : "=r" (tmp), "+m" (*val)
+			      : : "1", "cc");
+
+	return(tmp+1);
+}
+
+static inline gint32 
+InterlockedDecrement(volatile gint32 *val)
+{
+	gint32 tmp;
+	
+	__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"
+			      : "=r" (tmp), "+m" (*val)
+			      : : "1", "cc");
+
+	return(tmp-1);
+}
+
+
+static inline gint32 
+InterlockedExchange(volatile gint32 *val, gint32 new_val)
+{
+	gint32 ret;
+	
+	__asm__ __volatile__ ("0:\tL\t%1,%0\n"
+			      "\tCS\t%1,%2,%0\n"
+			      "\tJNZ\t0b"
+			      : "+m" (*val), "=r" (ret)
+			      : "r" (new_val)
+			      : "cc");
+
+	return(ret);
+}
+
+#define InterlockedExchangePointer InterlockedExchange
+
+static inline gint32 
+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"
+			      : "=r" (ret), "+m" (*val)
+			      : "r" (add) 
+			      : "1", "cc");
+	
+	return(ret);
+}
+
 #else
 
 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 = $(GLIB_CFLAGS) -I$(top_srcdir)
+
+noinst_LTLIBRARIES = libmonoarch-s390.la
+
+libmonoarch_s390_la_SOURCES = 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 = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+BISON = @BISON@
+BUILD_EXEEXT = @BUILD_EXEEXT@
+BUILD_GLIB_CFLAGS = @BUILD_GLIB_CFLAGS@
+BUILD_GLIB_LIBS = @BUILD_GLIB_LIBS@
+CC = @CC@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+DISABLE_SHARED_HANDLES = @DISABLE_SHARED_HANDLES@
+DLLTOOL = @DLLTOOL@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+HAVE_BOEHM_GC = @HAVE_BOEHM_GC@
+HOST_CC = @HOST_CC@
+LIBC = @LIBC@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+arch_target = @arch_target@
+
+INCLUDES = $(GLIB_CFLAGS) -I$(top_srcdir)
+
+noinst_LTLIBRARIES = libmonoarch-s390.la
+
+libmonoarch_s390_la_SOURCES = tramp.c s390-codegen.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../../config.h
+CONFIG_CLEAN_FILES = 
+LTLIBRARIES =  $(noinst_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../..
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libmonoarch_s390_la_LDFLAGS = 
+libmonoarch_s390_la_LIBADD = 
+libmonoarch_s390_la_OBJECTS =  tramp.lo
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) \
$(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+DEP_FILES =  .deps/tramp.P
+SOURCES = $(libmonoarch_s390_la_SOURCES)
+OBJECTS = $(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)  +	cd $(top_srcdir) && $(AUTOMAKE) --gnu mono/arch/s390/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+	cd $(top_builddir) \
+	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(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=compile $(COMPILE) -c $<
+
+.S.lo:
+	$(LIBTOOL) --mode=compile $(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='$(SOURCES) $(HEADERS)'; \
+	unique=`for i in $$list; do echo $$i; done | \
+	  awk '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	here=`pwd` && cd $(srcdir) \
+	  && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)'; \
+	unique=`for i in $$list; do echo $$i; done | \
+	  awk '    { files[$$0] = 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 = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = mono/arch/s390
+
+distdir: $(DISTFILES)
+	here=`cd $(top_builddir) && pwd`; \
+	top_distdir=`cd $(top_distdir) && pwd`; \
+	distdir=`cd $(distdir) && pwd`; \
+	cd $(top_srcdir) \
+	  && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) \
--output-dir=$$top_distdir --gnu mono/arch/s390/Makefile +	@for file in $(DISTFILES); \
do \ +	  d=$(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 := $(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=-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 = 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 = 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 = 256,
+} S390SpecialRegister;
+
+#define s390_word(addr, value)		*((guint32 *) addr) = (guint32) (value); ((guint32 \
*) addr)++ +#define s390_emit16(c, x)		*((guint16 *) c) = x; ((guint16 *) c)++
+#define s390_emit32(c, x)		*((guint32 *) c) = 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.
+ * 
+ * Copyright (C) Radek Doulik
+ * 
+ */
+
+#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 >= GENERAL_REGS) {
+			*stack_size += 4;
+			*code_size += 8;    /* load from stack, save on stack */
+		} else {
+			*code_size += 4;    /* load from stack */
+		}
+	} else {
+		if (*gr >= GENERAL_REGS - 1) {
+			*stack_size += 8 + (*stack_size % 8);
+			*code_size += 8;   /* 2x load from stack, 2x save to stack */
+		} else {
+			*code_size += 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          = 0;
+	gr          = 2;
+	*stack_size = MIN_STACK_SIZE;
+	*code_size  = (PROLOG_INS + CALL_INS + EPILOG_INS);
+
+	if (sig->hasthis) {
+		add_general (&gr, stack_size, code_size, TRUE);
+	}
+
+	for (i = 0; i < sig->param_count; ++i) {
+		if (sig->params [i]->byref) {
+			add_general (&gr, stack_size, code_size, TRUE);
+			continue;
+		}
+		simpletype = 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 += 4;
+			break;
+		case MONO_TYPE_VALUETYPE:
+			if (sig->params [i]->data.klass->enumtype) {
+				simpletype = sig->params [i]->data.klass->enum_basetype->type;
+				goto enum_calc_size;
+			}
+			if (mono_class_value_size (sig->params [i]->data.klass, NULL) != 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 += 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 += 4;
+				fr++;
+			}
+			else {
+				*code_size  += 4;
+				*stack_size += 8;
+			}
+			break;
+		case MONO_TYPE_R8:
+			if (fr < FLOAT_REGS) {
+				*code_size += 4;
+				fr ++;
+			} else {
+				*code_size  += 4;
+				*stack_size += 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 += 8;
+	} else {
+		simpletype = 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 += 8;
+			break;
+		case MONO_TYPE_I8:
+			*code_size += 12;
+			break;
+		case MONO_TYPE_VALUETYPE:
+			if (sig->ret->data.klass->enumtype) {
+				simpletype = 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 = (*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 = fr       = 0;
+	act_strs      = 0;
+	stack_par_pos = MIN_STACK_SIZE;
+
+	if (sig->hasthis) {
+		s390_lr (p, s390_r2, s390_r4);
+		gr++;
+	}
+
+	DEBUG (printf ("           count: %d\n",sig->param_count));
+	act_strs = 0;
+	for (i = 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 += sizeof(long);
+			}
+			continue;
+		}
+		simpletype = 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 += sizeof(long);
+			}
+			break;
+		case MONO_TYPE_VALUETYPE:
+			if (sig->params [i]->data.klass->enumtype) {
+				simpletype = sig->params [i]->data.klass->enum_basetype->type;
+				goto enum_calc_size;
+			}
+			if (mono_class_value_size (sig->params [i]->data.klass, NULL) != 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 += 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); 
+				gr += 2;
+			} else {
+				*(guint32 *) p += 7;
+				*(guint32 *) p &= ~7;
+				s390_mvc (p, sizeof(long long), STK_BASE, stack_par_pos, ARG_BASE, STKARG); 
+				stack_par_pos += 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 += sizeof(float);
+			}
+			break;
+		case MONO_TYPE_R8:
+			if (fr < FLOAT_REGS) {
+				s390_ld  (p, s390_r0 + fr, ARG_BASE, STKARG);
+				fr++;
+			} else {
+				*(guint32 *) p += 7;
+				*(guint32 *) p &= ~7;
+				s390_mvc  (p, sizeof(double), STK_BASE, stack_par_pos, ARG_BASE, STKARG);
+				stack_par_pos += 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 = g_malloc (code_size + PAGESIZE - 1);
+
+	/* Align to a multiple of PAGESIZE, assumed to be a power of two */
+	p = (char *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1));
+#else
+	p = 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); 
+
+	/* get return value */
+	if (sig->ret->byref || string_ctor) {
+		s390_st (p, s390_r2, s390_r8, 0);
+	} else {
+		simpletype = 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 = 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 = code_buffer = alloc_code_memory (code_size);
+	p = emit_prolog (p, sig, stack_size);
+	p = emit_save_parameters (p, sig, stack_size);
+	p = emit_call_and_store_retval (p, sig, stack_size, string_ctor);
+	p = 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.
+ * 
+ * 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
+ * 
+ */
+void *
+mono_create_method_pointer (MonoMethod *method)
+{
+	MonoMethodSignature *sig;
+	MonoJitInfo *ji;
+	guint8 *p, *code_buffer;
+	guint i, align = 0, code_size, stack_size, 
+		stackval_arg_pos, local_pos, 
+		local_start, reg_param, stack_param,
+		this_flag;
+	guint32 simpletype;
+	int *vtbuf, cpos, vt_cur;
+
+	code_size   = 1024;
+	stack_size  = 1024;
+	stack_param = 0;
+
+	sig = method->signature;
+
+	p = code_buffer = 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 = local_pos = MINV_POS + 
+		      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 = 1;
+	} else if (sig->param_count) {
+		DEBUG (printf ("save r%d\n", 3));
+		s390_st (p, s390_r2, s390_r15, local_pos);
+		local_pos += sizeof(int);
+		reg_param = 0;
+	}
+
+	this_flag = (sig->hasthis ? 1 : 0);
+	if (sig->param_count) {
+		gint save_count = MAX (3, MIN (6, sig->param_count - 1));
+		for (i = reg_param; i < save_count; i ++) {
+			s390_st (p, s390_r3 + i, s390_r15, local_pos);
+			local_pos += sizeof(int);
+			DEBUG (printf ("save r%d\n", 4 + i));
+		}
+	}
+
+	/* prepare space for valuetypes */
+	vt_cur = local_pos;
+	vtbuf  = alloca (sizeof(int)*sig->param_count);
+	cpos   = 0;
+	for (i = 0; i < sig->param_count; i++) {
+		MonoType *type = sig->params [i];
+		vtbuf [i] = -1;
+		if (type->type == MONO_TYPE_VALUETYPE) {
+			MonoClass *klass = type->data.klass;
+			gint size;
+
+			if (klass->enumtype)
+				continue;
+			size = mono_class_native_size (klass, &align);
+			cpos += align - 1;
+			cpos &= ~(align - 1);
+			vtbuf [i] = cpos;
+			cpos += size;
+		}
+	}
+	cpos += 3;
+	cpos &= ~3;
+
+	local_pos += cpos;
+
+	/* set MonoInvocation::stack_args */
+	stackval_arg_pos = 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 = 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 += 4*mono_type_native_stack_size (sig->params [i], &align);
+		else
+			stackval_arg_pos += 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 = 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 = g_new0 (MonoJitInfo, 1);
+	ji->method = method;
+	ji->code_size = p - code_buffer;
+	ji->code_start = code_buffer;
+
+	mono_jit_info_table_add (mono_root_domain, ji);
+
+	return ji->code_start;
+}


_______________________________________________
Mono-list maillist  -  Mono-list@ximian.com
http://lists.ximian.com/mailman/listinfo/mono-list

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic