changeset 1909:30881dc8076c

Merge
author Andrew John Hughes <ahughes@redhat.com>
date Thu, 28 Jan 2010 16:34:49 +0000
parents ac7b942245f2 (current diff) bb0e039df90a (diff)
children 2e9cc3b3a882
files ChangeLog Makefile.am acinclude.m4 configure.ac
diffstat 15 files changed, 10696 insertions(+), 5816 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Jan 21 02:04:50 2010 +0000
+++ b/ChangeLog	Thu Jan 28 16:34:49 2010 +0000
@@ -1,3 +1,167 @@
+2010-01-27 Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am: Reference plugin
+	directory by absolute path in EXTRA_DIST
+	to avoid confusion with build rule.
+	
+2010-01-27 Andrew John Hughes  <ahughes@redhat.com>
+
+	* NEWS: Updated for 1.7 release.
+	
+2010-01-27 Andrew John Hughes  <ahughes@redhat.com>
+	
+	* HACKING: Document new patch.
+	* Makefile.am: Add new patch.
+	* patches/libpng.patch:
+	Patch splashscreen code so that
+	it will build against libpng 1.4
+	(png_check_sig --> png_sig_cmp)
+
+2010-01-27 Andrew John Hughes  <ahughes@redhat.com>
+
+	* NEWS:
+	Add missing items for 1.5.1, 1.5.2,
+	1.5.3, 1.6.1 and 1.6.2.
+	
+2010-01-27  Edward Nevill   <ed@camswl.com>
+
+	* ports/hotspot/src/cpu/zero/vm/thumb2.cpp
+	Forgot to do hg add on this file in my last commit
+
+2010-01-26  Deepak Bhole <dbhole@redhat.com>
+
+	* NEWS: Added message about alpha release for the new NPR based plugin.
+
+2010-01-27  Matthias Klose  <doko@ubuntu.com>
+	
+	* Makefile.am: Remove quoting from ICEDTEA_NAME ICEDTEA_REV
+	ICEDTEA_PKG.
+
+2010-01-26 Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am:
+	(stamps/plugin-tests.stamp): Add
+	a target for building the plugin tests.
+	(plugin-tests): Alias for the above.
+
+2010-01-25 Andrew John Hughes  <ahughes@redhat.com>
+
+	* acinclude.m4:
+	(IT_CHECK_OLD_PLUGIN): New macro for
+	--enable/disable-plugin.
+	(IT_CHECK_NEW_PLUGIN): Likewise for
+	--enable/disable-npplugin.
+	(IT_CHECK_PLUGIN_DEPENDENCIES): New macro
+	to run pkg-config checks.  Enables the new
+	plugin if xulrunner 1.9.2 or above is
+	detected.
+	(IT_CHECK_XULRUNNER_VERSION): Obtain the
+	XULrunner vgersion for MOZILLA_VERSION_COLLAPSED.
+	* configure.ac:
+	Replace old plugin stuff with a single call
+	to IT_CHECK_XULRUNNER_VERSION (which depends
+	on the other macros).
+
+2010-01-25 Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am:
+	Build NPPlugin source files separately.
+	
+2010-01-25 Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am:
+	Fix ICEDTEAPLUGIN_TARGET to use new
+	stamp targets and remove redundant
+	ICEDTEANPPPLUGIN_TARGET.
+	
+2010-01-25 Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am:
+	Use NPPLUGIN_SRCDIR for Java plugin sources.
+	
+2010-01-25 Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am:
+	Provide stamp targets for both npplugin
+	and the old plugin so 'make plugin' builds
+	the one configured.
+	
+2010-01-25 Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am:
+	Remove trailing space after IcedTea version
+	in plugin version information when package
+	version is not set.
+	
+2010-01-25 Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am:
+	Build NPPlugin in the build directory,
+	not the source tree.
+	
+2010-01-22  Deepak Bhole <dbhole@redhat.com>
+
+	* Makefile.am:
+	Use MOZILLA_CFLAGS/LIBS rather than
+	XULRUNNER.
+	* configure.ac:
+	Check for Mozilla not XULrunner.
+	Bring in libxul-unstable as well.
+	* plugin/icedteanp/IcedTeaNPPlugin.cc:
+	Use PRInt32 rather than PRInt32_t for port.
+
+2010-01-25 Andrew John Hughes  <ahughes@redhat.com>
+
+	* IcedTeaPlugin.cc:
+	Standardise plugin versioning.
+	* Makefile.am:
+	Set ICEDTEA_NAME and use in place of literal
+	"IcedTea6".  Use HAS_PKGVERSION to set ICEDTEA_PKG
+	and output DISTRO_PACKAGE_VERSION rather than
+	running test.  Set PLUGIN_VERSION and use for
+	both plugins.
+	* acinclude.m4:
+	(IT_GET_PKGVERSION): Moved from configure.ac and
+	changed to a macro with output.
+	(IT_GET_LSB_DATA): Depend on IT_GET_PKGVERSION.
+	* configure.ac:
+	Invoke new IT_GET_PKGVERSION macro.
+	* plugin/icedteanp/IcedTeaNPPlugin.cc:
+	Standardise plugin versioning.
+
+2010-01-25 Andrew John Hughes  <ahughes@redhat.com>
+
+	* patches/icedtea-libraries.patch:
+	Make all dlopen choices at build-time,
+	not just one.  Support libjpeg8 as well.
+	
+2010-01-21  Andrew John Hughes  <ahughes@redhat.com>
+
+	PR icedtea/433
+	* Makefile.am:
+	Add set -e to tarball extractions so
+	that they fail immediately.
+
+2010-01-21  Edward Nevill   <ed@camswl.com>
+
+	* zeroshark.make, asm_helper.cpp, bytecodes_arm.def,
+	cppInterpreter_arm.S, thumb2.cpp (new file)
+	Added Thumb2 JIT (not build as default - yet)
+	Removal of, more, hard coded constants
+	Move 'complex' bytecodes from cppInterpreter_arm.S to asm_helper.cpp
+	General tidying up of cppInterpreter_arm.S
+
+2010-01-21  Matthias Klose  <doko@ubuntu.com>
+
+	* Makefile.am: Don't hide errors in statement sequences building
+	the NPPlugin. Use ICEDTEA_REV to defined PLUGIN_VERSION.
+
+2010-01-21  Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am:
+	Fix paths to patches and IcedTeaNPPlugin.cc
+	for make dist.
+	
 2010-01-20  Andrew John Hughes  <ahughes@redhat.com>
 
 	* Makefile.am:
@@ -23,6 +187,23 @@
 	Create a link from client to server after CACAO install
 	to make openjdk find the expected client dir on 32bit systems.
 
+2010-01-08  Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am:
+	Calculate JDK and HotSpot Mercurial revisions
+	if available and pass to build.  Also pass
+	DIST_NAME to build.
+	* acinclude.m4:
+	(IT_GET_LSB_DATA): Moved from configure.ac
+	and extended to also obtain the name of
+	the distribution from either lsb_release -is
+	or $build_os.
+	* configure.ac:
+	Invoke IT_GET_LSB_DATA macro.
+	* patches/icedtea-version.patch:
+	Updated to use distribution name and JDK and
+	HotSpot Mercurial revision IDs.
+
 2010-01-19 Man Lung Wong  <mwong@redhat.com>
 
 	* rt/net/sourceforge/jnlp/JNLPFile.java
--- a/HACKING	Thu Jan 21 02:04:50 2010 +0000
+++ b/HACKING	Thu Jan 28 16:34:49 2010 +0000
@@ -115,6 +115,7 @@
 * openjdk/6648816.patch: Backport of regression (NPE) fix in AccessControlContext (PR364/S6648816)
 * icedtea-nss-config.patch: Add the NSS PKCS11 security provider. (PR356)
 * icedtea-nss-6763530.patch: Fix PKCS11 provider when used with newer version of NSS (>=3.12.3) (PR356, S6763530).
+* libpng.patch: Use png_sig_cmp instead of png_check_sig so we can build against libpng 1.4.
 
 The following patches are only applied to OpenJDK in IcedTea:
 
--- a/IcedTeaPlugin.cc	Thu Jan 21 02:04:50 2010 +0000
+++ b/IcedTeaPlugin.cc	Thu Jan 28 16:34:49 2010 +0000
@@ -275,8 +275,8 @@
 #define PLUGIN_CHECK(message, result)
 #endif
 
-#define PLUGIN_NAME "IcedTea Java Web Browser Plugin"
-#define PLUGIN_DESCRIPTION "The " PLUGIN_NAME PLUGIN_VERSION " executes Java applets."
+#define PLUGIN_NAME "IcedTea Java Web Browser Plugin (using " PLUGIN_VERSION ")"
+#define PLUGIN_DESCRIPTION "The " PLUGIN_NAME " executes Java applets."
 #define PLUGIN_MIME_DESC                                               \
   "application/x-java-vm:class,jar:IcedTea;"                           \
   "application/x-java-applet:class,jar:IcedTea;"                       \
--- a/Makefile.am	Thu Jan 21 02:04:50 2010 +0000
+++ b/Makefile.am	Thu Jan 28 16:34:49 2010 +0000
@@ -123,15 +123,16 @@
 # FIXME (plugin): NPPLUGIN_DIR becomes PLUGIN_DIR
 if ENABLE_NPPLUGIN
 ICEDTEAPLUGIN_CLEAN = clean-IcedTeaNPPlugin
-ICEDTEAPLUGIN_TARGET = stamps/icedtea-npplugin
+ICEDTEAPLUGIN_TARGET = stamps/icedtea-npplugin.stamp
 PLUGIN_PATCH = patches/icedtea-liveconnect.patch
 LIVECONNECT_DIR = -C lib/rt netscape -C lib/rt sun/applet
-NPPLUGIN_DIR=$(abs_top_srcdir)/plugin/icedteanp
-LIVECONNECT_SRCS = $(NPPLUGIN_DIR)/java
+NPPLUGIN_DIR=$(abs_top_builddir)/plugin/icedteanp
+NPPLUGIN_SRCDIR=$(abs_top_srcdir)/plugin/icedteanp
+LIVECONNECT_SRCS = $(NPPLUGIN_SRCDIR)/java
 else
 if ENABLE_PLUGIN
 ICEDTEAPLUGIN_CLEAN = clean-IcedTeaPlugin
-ICEDTEAPLUGIN_TARGET = IcedTeaPlugin.so
+ICEDTEAPLUGIN_TARGET = stamps/icedtea-plugin.stamp
 PLUGIN_PATCH = patches/icedtea-liveconnect.patch
 LIVECONNECT_DIR = -C lib/rt netscape -C lib/rt sun/applet
 NPPLUGIN_DIR = 
@@ -202,6 +203,10 @@
   ICEDTEA_HOME = $(abs_top_builddir)/bootstrap/icedtea
 endif
 
+# Sources list
+
+PLUGIN_TEST_SRCS = $(abs_top_srcdir)/plugin/tests/LiveConnect/*.java
+
 # Patch list
 
 ICEDTEA_FSG_PATCHES =
@@ -293,7 +298,8 @@
 	patches/icedtea-6897844-xshm.patch \
 	patches/icedtea-linux-separate-debuginfo.patch \
 	patches/icedtea-parisc.patch \
-	patches/icedtea-sh4-support.patch
+	patches/icedtea-sh4-support.patch \
+	patches/libpng.patch
 
 if WITH_RHINO
 ICEDTEA_PATCHES += \
@@ -379,9 +385,15 @@
 JDK_UPDATE_VERSION = $(shell echo $(OPENJDK_VERSION) | sed -e "s/^b//")
 COMBINED_VERSION = $(JDK_UPDATE_VERSION)-$(OPENJDK_VERSION)
 
+ICEDTEA_NAME = IcedTea6
 if HAS_ICEDTEA_REVISION
-ICEDTEA_REV="+${ICEDTEA_REVISION}"
+ICEDTEA_REV = +${ICEDTEA_REVISION}
 endif
+if HAS_PKGVERSION
+ICEDTEA_PKG = $(EMPTY) (${PKGVERSION})
+endif
+
+PLUGIN_VERSION = $(ICEDTEA_NAME) $(PACKAGE_VERSION)$(ICEDTEA_REV)$(ICEDTEA_PKG)
 
 ICEDTEA_ENV = \
 	IMPORT_BINARY_PLUGS=true \
@@ -423,7 +435,7 @@
 	JDK_HOME="" \
 	RHINO_JAR="$(RHINO_JAR)" \
 	DISTRIBUTION_ID="$(DIST_ID)" \
-	DERIVATIVE_ID="IcedTea6 $(PACKAGE_VERSION)$(ICEDTEA_REV)" \
+	DERIVATIVE_ID="$(ICEDTEA_NAME) $(PACKAGE_VERSION)$(ICEDTEA_REV)" \
 	DEBUG_CLASSFILES="true" \
 	DEBUG_BINARIES="true" \
 	ALT_DROPS_DIR="$(abs_top_builddir)/drops"
@@ -511,7 +523,7 @@
 	JAR_KNOWS_J_OPTIONS="$(JAR_KNOWS_J_OPTIONS)" \
 	JAR_ACCEPTS_STDIN_LIST="$(JAR_ACCEPTS_STDIN_LIST)" \
 	DISTRIBUTION_ID="$(DIST_ID)" \
-	DERIVATIVE_ID="IcedTea6 $(PACKAGE_VERSION)$(ICEDTEA_REV)" \
+	DERIVATIVE_ID="$(ICEDTEA_NAME) $(PACKAGE_VERSION)$(ICEDTEA_REV)" \
 	DEBUG_CLASSFILES="true" \
 	DEBUG_BINARIES="true" \
 	DISABLE_NIMBUS="true" \
@@ -551,16 +563,15 @@
 # FIXME (distclean): Add pulseaudio sources
 
 EXTRA_DIST = rt generated \
-	patches/* \
+	$(abs_top_srcdir)/patches/* \
 	tools-copy contrib ports \
 	extra overlays \
 	javaws.png javaws.desktop visualvm.desktop \
 	jconsole.desktop policytool.desktop \
 	test/jtreg \
 	IcedTeaPlugin.cc \
-	IcedTeaNPPlugin.cc \
 	HACKING pulseaudio fsg.sh \
-	plugin \
+	$(abs_top_srcdir)/plugin \
 	hotspot.map \
 	autogen.sh \
 	tapset/hotspot.stp.in \
@@ -863,6 +874,7 @@
 if OPENJDK_SRC_DIR_FOUND
 	cp -a $(OPENJDK_SRC_DIR) openjdk
 else
+	set -e ; \
 	if ! test -d openjdk ; \
 	then \
 	  mkdir openjdk ; \
@@ -874,12 +886,14 @@
 if BUILD_CACAO
 if !USE_SYSTEM_CACAO
 if USE_ALT_CACAO_SRC_DIR
+	set -e ; \
 	if ! test -d cacao ; \
 	then \
 	  mkdir -p cacao/cacao ; \
 	  cp -r $(ALT_CACAO_SRC_DIR)/* cacao/cacao/ ; \
 	fi
 else
+	set -e ; \
 	if ! test -d cacao ; \
 	then \
 	  mkdir cacao ; \
@@ -891,17 +905,20 @@
 endif
 endif
 if WITH_VISUALVM
+	set -e ; \
 	if ! test -d netbeans ; \
 	then \
 	  mkdir netbeans ; \
 	  $(TAR) xf $(NETBEANS_PROFILER_SRC_ZIP) -C netbeans ; \
 	fi
 
+	set -e ; \
 	if ! test -d visualvm ; \
 	then \
 	  $(TAR) xf $(VISUALVM_SRC_ZIP) ; \
 	fi
 endif
+	set -e ; \
 	if [ ! -e $(abs_top_builddir)/generated ]; then \
 	  cp -a $(abs_top_srcdir)/generated $(abs_top_builddir); \
 	  find $(abs_top_builddir)/generated -type f -exec chmod 640 '{}' ';' \
@@ -1043,10 +1060,10 @@
 	if ! test "x$(WITH_CACAO)" = "xno"; then \
 	  echo "JDK_DERIVATIVE_NAME=$${icedtea_version}" \
 	    >>openjdk/jdk/make/common/shared/Defs.gmk ; \
-	  echo "PRODUCT_NAME=IcedTea6" \
+	  echo "PRODUCT_NAME=$(ICEDTEA_NAME)" \
 	    >>openjdk/jdk/make/common/shared/Defs.gmk ; \
 	else \
-	  echo "JDK_DERIVATIVE_NAME=IcedTea6 $${icedtea_version}" \
+	  echo "JDK_DERIVATIVE_NAME=$(ICEDTEA_NAME) $${icedtea_version}" \
 	    >>openjdk/jdk/make/common/shared/Defs.gmk ; \
 	fi ; 
 
@@ -1054,11 +1071,11 @@
 	echo "JDK_REVID=$(JDK_REVISION)" >>openjdk/jdk/make/common/shared/Defs.gmk ;
 endif
 
-	echo "DISTRO_NAME=$(DIST_NAME)" >>openjdk/jdk/make/common/shared/Defs.gmk ; \
-	if [ -n "$(PKGVERSION)" ]; then \
+	echo "DISTRO_NAME=$(DIST_NAME)" >>openjdk/jdk/make/common/shared/Defs.gmk ;
+if HAS_PKGVERSION
 	  echo "DISTRO_PACKAGE_VERSION=$(PKGVERSION)" \
-	    >>openjdk/jdk/make/common/shared/Defs.gmk ; \
-	fi
+	    >>openjdk/jdk/make/common/shared/Defs.gmk ;
+endif
 
 #FIXME (plugin): Don't do this copying
 if ENABLE_NPPLUGIN
@@ -1283,7 +1300,7 @@
 stamps/icedtea.stamp: stamps/bootstrap-directory-symlink.stamp \
 	stamps/hotspot-tools.stamp stamps/plugs.stamp \
 	stamps/ports.stamp stamps/patch.stamp stamps/overlay.stamp \
-	$(ICEDTEAPLUGIN_TARGET) $(ICEDTEANPPLUGIN_TARGET) \
+	$(ICEDTEAPLUGIN_TARGET) \
 	extra-lib/about.jar stamps/cacao.stamp stamps/visualvm.stamp \
 	stamps/pulse-java.stamp
 	$(ARCH_PREFIX) $(MAKE) \
@@ -1386,7 +1403,7 @@
 stamps/icedtea-debug.stamp: stamps/bootstrap-directory-symlink.stamp \
 	stamps/hotspot-tools.stamp stamps/plugs.stamp \
 	stamps/ports.stamp stamps/patch.stamp stamps/overlay.stamp \
-	$(ICEDTEAPLUGIN_TARGET) $(ICEDTEANPPLUGIN_TARGET) \
+	$(ICEDTEAPLUGIN_TARGET) \
 	extra-lib/about.jar stamps/cacao.stamp stamps/visualvm.stamp \
 	stamps/pulse-java.stamp
 	$(ARCH_PREFIX) $(MAKE) \
@@ -1572,35 +1589,29 @@
         IcedTeaJavaRequestProcessor.o IcedTeaPluginRequestProcessor.o \
 		IcedTeaPluginUtils.o
 
-$(addprefix $(NPPLUGIN_DIR)/,$(NPPLUGIN_OBJECTS)): $(addprefix $(NPPLUGIN_DIR)/,$(NPPLUGIN_SRC))
-	cd $(NPPLUGIN_DIR); \
-	if [ -e $(abs_top_srcdir)/.hg ] && which $(HG) >/dev/null; then \
-	  revision="-r`(cd $(abs_top_srcdir); $(HG) tip --template '{rev}')`" ; \
-	fi ; \
-	if [ -n "$(PKGVERSION)" ]; then plugin_version=" ($(PKGVERSION))"; fi; \
-	plugin_version=" $(PACKAGE_VERSION)$$revision$$plugin_version"; \
+$(NPPLUGIN_DIR)/%.o: $(NPPLUGIN_SRCDIR)/%.cc
+	mkdir -p $(NPPLUGIN_DIR) && \
+	cd $(NPPLUGIN_DIR) && \
 	$(CXX) $(CXXFLAGS) \
-	  -DPACKAGE_VERSION="\"$(PACKAGE_VERSION)\"" \
-	  -DPLUGIN_VERSION="\"$$plugin_version\"" \
+	  -DPLUGIN_VERSION="\"$(PLUGIN_VERSION)\"" \
 	  -DMOZILLA_VERSION_COLLAPSED="$(MOZILLA_VERSION_COLLAPSED)" \
 	  $(GLIB_CFLAGS) \
 	  $(GTK_CFLAGS) \
 	  $(MOZILLA_CFLAGS) \
-	  -fPIC -c $(NPPLUGIN_SRC); \
-	cd ../
+	  -fPIC -o $@ -c $<
 
 $(NPPLUGIN_DIR)/IcedTeaNPPlugin.so: $(addprefix $(NPPLUGIN_DIR)/,$(NPPLUGIN_OBJECTS))
-	cd $(NPPLUGIN_DIR); \
+	cd $(NPPLUGIN_DIR) && \
 	$(CXX) $(CXXFLAGS) \
 	  $(NPPLUGIN_OBJECTS) \
 	  $(GLIB_LIBS) \
 	  $(GTK_LIBS) \
 	  $(MOZILLA_LIBS)\
-	  -shared -o $@; \
-	cd ../
+	  -shared -o $@
 
-stamps/icedtea-npplugin: $(NPPLUGIN_DIR)/IcedTeaNPPlugin.so
-	touch stamps/icedtea-npplugin
+stamps/icedtea-npplugin.stamp: $(NPPLUGIN_DIR)/IcedTeaNPPlugin.so
+	mkdir -p stamps
+	touch stamps/icedtea-npplugin.stamp
 
 clean-IcedTeaNPPlugin:
 	cd $(NPPLUGIN_DIR);\
@@ -1614,25 +1625,23 @@
 # is listed before -l options.  See:
 # http://developer.mozilla.org/en/docs/XPCOM_Glue
 IcedTeaPlugin.o: IcedTeaPlugin.cc
-	if [ -e $(abs_top_srcdir)/.hg ] && which $(HG) >/dev/null; then \
-	  revision="-r`(cd $(abs_top_srcdir); $(HG) tip --template '{rev}')`" ; \
-	fi ; \
-	if [ -n "$(PKGVERSION)" ]; then plugin_version=" ($(PKGVERSION))"; fi; \
-	plugin_version=" $(PACKAGE_VERSION)$$revision$$plugin_version"; \
 	$(CXX) $(CXXFLAGS) \
-	  -DPACKAGE_VERSION="\"$(PACKAGE_VERSION)\"" \
-	  -DPLUGIN_VERSION="\"$$plugin_version\"" \
+	  -DPLUGIN_VERSION="\"$(PLUGIN_VERSION)\"" \
 	  -DMOZILLA_VERSION_COLLAPSED="$(MOZILLA_VERSION_COLLAPSED)" \
 	  $(GTK_CFLAGS) \
-	  $(XULRUNNER_CFLAGS) \
+	  $(MOZILLA_CFLAGS) \
 	  -fPIC -c -o $@ $<
 IcedTeaPlugin.so: IcedTeaPlugin.o
 	$(CXX) $(CXXFLAGS) \
 	  $< \
 	  $(GTK_LIBS) \
-	  $(XULRUNNER_LIBS) \
+	  $(MOZILLA_LIBS) \
 	  -shared -o $@
 
+stamps/icedtea-plugin.stamp: IcedTeaPlugin.so
+	mkdir -p stamps
+	touch stamps/icedtea-plugin.stamp
+
 clean-IcedTeaPlugin:
 	rm -f IcedTeaPlugin.o
 	rm -f IcedTeaPlugin.so
@@ -1981,6 +1990,33 @@
 
 # end additional VMs
 
+# plugin tests
+
+stamps/plugin-tests.stamp: $(PLUGIN_TEST_SRCS) \
+ bootstrap/jdk1.7.0/jre/lib/rt-closed.jar
+	mkdir -p plugin/tests/LiveConnect
+	if test -d lib/rt/netscape ; then \
+	  set -e ; \
+	  if ! test -d $(ICEDTEA_BOOT_DIR) ; then \
+	    $(JAVAC) $(MEMORY_LIMIT) -g -d plugin/tests/LiveConnect \
+	      -classpath bootstrap/jdk1.7.0/jre/lib/rt-closed.jar \
+              -source 1.5 $(PLUGIN_TEST_SRCS) ; \
+	    $(JAR) cf plugin/tests/LiveConnect/PluginTest.jar \
+	      plugin/tests/LiveConnect/*.class ; \
+	  else \
+	    $(ICEDTEA_BOOT_DIR)/bin/javac $(MEMORY_LIMIT) -g \
+	      -d plugin/tests/LiveConnect \
+	      -classpath bootstrap/jdk1.7.0/jre/lib/rt-closed.jar \
+	      -source 1.5 $(PLUGIN_TEST_SRCS) ; \
+	    $(ICEDTEA_BOOT_DIR)/bin/jar cf plugin/tests/LiveConnect/PluginTest.jar \
+	      plugin/tests/LiveConnect/*.class ; \
+	  fi ; \
+	  cp -a $(abs_top_srcdir)/plugin/tests/LiveConnect/*.{js,html} plugin/tests/LiveConnect ; \
+	  echo "Done. Now launch \"firefox file://`pwd`/index.html\"" ; \
+	fi
+	mkdir -p stamps
+	touch stamps/plugin-tests.stamp
+
 # jtreg
 
 stamps/jtreg.stamp: stamps/icedtea.stamp
@@ -2305,3 +2341,7 @@
 clean: distclean-local
 
 jtreg: stamps/jtreg.stamp
+
+plugin: $(ICEDTEAPLUGIN_TARGET)
+
+plugin-tests: stamps/plugin-tests.stamp
--- a/NEWS	Thu Jan 21 02:04:50 2010 +0000
+++ b/NEWS	Thu Jan 28 16:34:49 2010 +0000
@@ -1,16 +1,25 @@
 New in release 1.8 (XXXX-XX-XX):
 
 
-New in release 1.7 (XXXX-XX-XX):
+New in release 1.7 (2010-01-27):
 
 - Updated to OpenJDK6 b17.
+- Alpha version of the new IcedTea NPRuntime based plugin with support for 
+  Firefox >= 3.5, Chromium, and other browsers that support NPRuntime 
+  (use --enable-npplugin to build it).  For xulrunner >= 1.9.2 (used
+  by Firefox >= 3.6), the new plugin is required and the build will
+  automatically enable it if the old plugin is requested.
 - Support added for building with HotSpot 16 using
-  --with-hotspot-build=hs16.
+  --with-hotspot-build=hs16.  This is the same as was released
+  in the proprietary JDK6 update 18.
 - Zero port updated to match the version submitted to OpenJDK
   as closely as possible.
-- libjpeg7 and libXext >= 1.1.0 supported.
+- libjpeg7, libjpeg8, libpng 1.4 and libXext >= 1.1.0 supported.
 - Added JNI call tracing using systemtap version 1.0+ when
   configuring with --enable-systemtap. See tapset/hotspot_jni.stp.
+- Add support for building the Zero assembler port on Hitachi SH.
+
+New in release 1.6.2 (2009-11-09)
 - Latest security updates:
   - (CVE-2009-3728) ICC_Profile file existence detection information leak (6631533)
   - (CVE-2009-3885) BMP parsing DoS with UNC ICC links (6632445)
@@ -27,11 +36,50 @@
   - (CVE-2009-3869) JRE AWT setDifflCM stack overflow (6872357)
   - (CVE-2009-3874) ImageI/O JPEG heap overflow (6874643
   - (CVE-2009-3871) JRE AWT setBytePixels heap overflow (6872358)
-- Add support for zero build on Hitachi SH.
+
+New in release 1.5.3 (2009-11-09)
+- Latest security updates:
+  - (CVE-2009-3728) ICC_Profile file existence detection information leak (6631533)
+  - (CVE-2009-3885) BMP parsing DoS with UNC ICC links (6632445)
+  - (CVE-2009-3881) resurrected classloaders can still have children (6636650) 
+  - (CVE-2009-3882) Numerous static security flaws in Swing (findbugs) (6657026)
+  - (CVE-2009-3883) Mutable statics in Windows PL&F (findbugs) (6657138)
+  - (CVE-2009-3880) UI logging information leakage (6664512)
+  - (CVE-2009-3879) GraphicsConfiguration information leak (6822057)
+  - (CVE-2009-3884) zoneinfo file existence information leak (6824265)
+  - (CVE-2009-2409) deprecate MD2 in SSL cert validation (Kaminsky) (6861062)
+  - (CVE-2009-3873) JPEG Image Writer quantization problem (6862968)
+  - (CVE-2009-3875) MessageDigest.isEqual introduces timing attack vulnerabilities (6863503)
+  - (CVE-2009-3876, CVE-2009-3877) OpenJDK ASN.1/DER input stream parser denial of service (6864911)
+  - (CVE-2009-3869) JRE AWT setDifflCM stack overflow (6872357)
+  - (CVE-2009-3874) ImageI/O JPEG heap overflow (6874643
+  - (CVE-2009-3871) JRE AWT setBytePixels heap overflow (6872358)
+
+New in release 1.6.1 (2009-09-14):
+
+- Fix tarball error in 1.6
+- Improve jar performance,
+  http://hg.openjdk.java.net/jdk6/jdk6/jdk/rev/b35f1e5075a4
 
 New in release 1.6 (2009-09-10):
 
 - Added java method tracing using systemtap version 0.9.9+.
+- FAST interpreter for ARM
+- Timezone fix: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=377
+- Stackoverflow error fix: 
+http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=381
+- Backport regression (NPE) fix for AccessControlContext fix
+- Bump to hs14b16
+- The plugin has been updated to improve stability and cookie support.
+  Support for certificates with mismatched CNs has been added as well.
+
+New in release 1.5.2 (2009-09-04)
+- Timezone fix: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=377
+- Stackoverflow error fix: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=381
+- Backport regression (NPE) fix for AccessControlContext fix
+- Bump to hs14b16
+
+New in release 1.5.1 (2009-08-07)
 - Security fixes for:
   CVE-2009-2670 - OpenJDK Untrusted applet System properties access
   CVE-2009-2671 CVE-2009-2672 - OpenJDK Proxy mechanism information leaks
@@ -43,14 +91,7 @@
   CVE-2009-2476 - OpenJDK OpenType checks can be bypassed
   CVE-2009-2689 - OpenJDK JDK13Services grants unnecessary privileges
   CVE-2009-2690 - OpenJDK private variable information disclosure
-- FAST interpreter for ARM
-- Timezone fix: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=377
-- Stackoverflow error fix: 
-http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=381
-- Backport regression (NPE) fix for AccessControlContext fix
-- Bump to hs14b16
-- The plugin has been updated to improve stability and cookie support.
-  Support for certificates with mismatched CNs has been added as well.
+- Plugin/Netx security fix.
 
 New in release 1.5 (2009-05-20)
 
--- a/acinclude.m4	Thu Jan 21 02:04:50 2010 +0000
+++ b/acinclude.m4	Thu Jan 28 16:34:49 2010 +0000
@@ -1268,15 +1268,33 @@
 AC_SUBST(PARALLEL_JOBS)
 ])
 
-AC_DEFUN([IT_GET_LSB_DATA],
+AC_DEFUN_ONCE([IT_GET_PKGVERSION],
 [
+AC_MSG_CHECKING([for distribution package version])
+AC_ARG_WITH([pkgversion],
+        [AS_HELP_STRING([--with-pkgversion=PKG],
+                        [Use PKG in the version string in addition to "IcedTea"])],
+        [case "$withval" in
+          yes) AC_MSG_ERROR([package version not specified]) ;;
+          no)  PKGVERSION=none ;;
+          *)   PKGVERSION="$withval" ;;
+         esac],
+        [PKGVERSION=none])
+AC_MSG_RESULT([${PKGVERSION}])
+AM_CONDITIONAL(HAS_PKGVERSION, test "x${PKGVERSION}" != "xnone") 
+AC_SUBST(PKGVERSION)
+])
+
+AC_DEFUN_ONCE([IT_GET_LSB_DATA],
+[
+AC_REQUIRE([IT_GET_PKGVERSION])
 AC_MSG_CHECKING([build identification])
 if test -n "$LSB_RELEASE"; then
   lsb_info="$($LSB_RELEASE -ds | sed 's/^"//;s/"$//')"
-  if test -n "$PKGVERSION"; then
+  if test "x$PKGVERSION" = "xnone"; then
+    DIST_ID="Built on $lsb_info ($(date))"
+  else
     DIST_ID="$lsb_info, package $PKGVERSION"
-  else
-    DIST_ID="Built on $lsb_info ($(date))"
   fi
   DIST_NAME="$($LSB_RELEASE -is | sed 's/^"//;s/"$//')"
 else
@@ -1326,3 +1344,126 @@
   AM_CONDITIONAL([HAS_JDK_REVISION], test "x${JDK_REVISION}" != xnone)
   AM_CONDITIONAL([HAS_HOTSPOT_REVISION], test "x${HOTSPOT_REVISION}" != xnone)
 ])
+
+AC_DEFUN_ONCE([IT_CHECK_OLD_PLUGIN],
+[
+AC_MSG_CHECKING([whether to build the browser plugin])
+AC_ARG_ENABLE([plugin],
+              [AS_HELP_STRING([--disable-plugin],
+                              [Disable compilation of browser plugin])],
+              [enable_plugin="${enableval}"], [enable_plugin="yes"])
+AC_MSG_RESULT(${enable_plugin})
+])
+
+AC_DEFUN_ONCE([IT_CHECK_NEW_PLUGIN],
+[
+AC_MSG_CHECKING([whether to build the new experimental browser plugin based on npruntime])
+AC_ARG_ENABLE([npplugin],
+              [AS_HELP_STRING([--enable-npplugin],
+                              [Enable compilation of browser plugin (automatically disables default plugin)])],
+              [enable_npplugin="${enableval}"], [enable_npplugin="no"])
+AC_MSG_RESULT(${enable_npplugin})
+])
+
+AC_DEFUN_ONCE([IT_CHECK_PLUGIN_DEPENDENCIES],
+[
+dnl Check for plugin support headers and libraries.
+dnl FIXME: use unstable
+AC_REQUIRE([IT_CHECK_OLD_PLUGIN])
+AC_REQUIRE([IT_CHECK_NEW_PLUGIN])
+if test "x${enable_plugin}" = "xyes" -o "x${enable_npplugin}" = "xyes" ; then
+  PKG_CHECK_MODULES(GTK, gtk+-2.0)
+  PKG_CHECK_MODULES(GLIB, glib-2.0)
+  AC_SUBST(GLIB_CFLAGS)
+  AC_SUBST(GLIB_LIBS)
+  AC_SUBST(GTK_CFLAGS)
+  AC_SUBST(GTK_LIBS)
+
+
+  if $PKG_CONFIG --atleast-version 1.9.2 libxul 2>&AS_MESSAGE_LOG_FD ; then
+    if test "x${enable_npplugin}" != "xyes" ; then
+      AC_MSG_WARN([The old plugin does not work with xulrunner >= 1.9.2.  Enabling new plugin.])
+      enable_npplugin=yes;
+    fi
+    xullibs=libxul
+  else
+    xullibs="libxul libxul-unstable"
+  fi
+
+  if test "x${enable_npplugin}" = "xyes" ;
+  then
+    PKG_CHECK_MODULES(MOZILLA, \
+      mozilla-plugin ${xullibs})
+    
+    AC_SUBST(MOZILLA_CFLAGS)
+    AC_SUBST(MOZILLA_LIBS)
+  else
+    if test "x${enable_plugin}" = "xyes"
+    then
+      PKG_CHECK_MODULES(MOZILLA, \
+        nspr mozilla-js mozilla-plugin libxul-unstable >= 1.9)
+
+      AC_SUBST(MOZILLA_CFLAGS)
+      AC_SUBST(MOZILLA_LIBS)
+    fi
+  fi
+fi
+AM_CONDITIONAL(ENABLE_PLUGIN, test "x${enable_plugin}" = "xyes")
+AM_CONDITIONAL(ENABLE_NPPLUGIN, test "x${enable_npplugin}" = "xyes")
+])
+
+AC_DEFUN_ONCE([IT_CHECK_XULRUNNER_VERSION],
+[
+AC_REQUIRE([IT_CHECK_PLUGIN_DEPENDENCIES])
+if test "x${enable_plugin}" = "xyes" -o "x${enable_npplugin}" = "xyes"
+then
+  AC_LANG_PUSH([C++])
+  OLDCPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $MOZILLA_CFLAGS"
+
+  AC_CACHE_CHECK([for xulrunner version], [xulrunner_cv_collapsed_version],
+      [AC_RUN_IFELSE(
+        [AC_LANG_PROGRAM([[
+#include <mozilla-config.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+]],[[
+int version = 0;
+const char* token = NULL;
+int power=6;
+FILE *datafile;
+
+datafile = fopen ("conftest.vdata", "w");
+if (!datafile) return 1;
+
+// 32 chars is more than enough to hold version
+char* mozilla_version = (char*) malloc(32*sizeof(char));
+snprintf(mozilla_version, 32, "%s", MOZILLA_VERSION);
+
+token = strtok(mozilla_version, ".");
+while (token)
+{
+    version += atoi(token)*(pow(10, power));
+    power -=2;
+    token = strtok(NULL, ".");
+}
+
+fprintf (datafile, "%d\n", version);
+free(mozilla_version);
+if (fclose(datafile)) return 1;
+
+return EXIT_SUCCESS;
+]])],
+    [xulrunner_cv_collapsed_version="$(cat conftest.vdata)"],
+    [AC_MSG_FAILURE([cannot determine xulrunner version])])],
+  [xulrunner_cv_collapsed_version="190000"])
+
+  CPPFLAGS="$OLDCPPFLAGS"
+  AC_LANG_POP([C++])
+
+  AC_SUBST(MOZILLA_VERSION_COLLAPSED, $xulrunner_cv_collapsed_version)
+fi
+])
+
--- a/configure.ac	Thu Jan 21 02:04:50 2010 +0000
+++ b/configure.ac	Thu Jan 28 16:34:49 2010 +0000
@@ -94,22 +94,6 @@
 AM_CONDITIONAL(WITH_VISUALVM, test "x${enable_visualvm}" = "xyes")
 AC_MSG_RESULT(${enable_visualvm})
 
-AC_MSG_CHECKING([whether to build the browser plugin])
-AC_ARG_ENABLE([plugin],
-              [AS_HELP_STRING([--disable-plugin],
-                              [Disable compilation of browser plugin])],
-              [enable_plugin="${enableval}"], [enable_plugin="yes"])
-AM_CONDITIONAL(ENABLE_PLUGIN, test "x${enable_plugin}" = "xyes")
-AC_MSG_RESULT(${enable_plugin})
-
-AC_MSG_CHECKING([whether to build the new experimental browser plugin based on npruntime])
-AC_ARG_ENABLE([npplugin],
-              [AS_HELP_STRING([--enable-npplugin],
-                              [Enable compilation of browser plugin (automatically disables default plugin)])],
-              [enable_npplugin="${enableval}"], [enable_npplugin="no"])
-AM_CONDITIONAL(ENABLE_NPPLUGIN, test "x${enable_npplugin}" = "xyes")
-AC_MSG_RESULT(${enable_npplugin})
-
 AC_MSG_CHECKING([whether to include PulseAudio support])
 AC_ARG_ENABLE([pulse-java],
               [AS_HELP_STRING([--enable-pulse-java],
@@ -167,17 +151,7 @@
 AM_CONDITIONAL([ENABLE_NSS], [test x$ENABLE_NSS = xyes])
 AC_MSG_RESULT(${ENABLE_NSS})
 
-AC_ARG_WITH([pkgversion],
-        [AS_HELP_STRING([--with-pkgversion=PKG],
-                        [Use PKG in the version string in addition to "IcedTea"])],
-        [case "$withval" in
-          yes) AC_MSG_ERROR([package version not specified]) ;;
-          no)  PKGVERSION= ;;
-          *)   PKGVERSION="$withval" ;;
-         esac],
-        [PKGVERSION=])
-AC_SUBST(PKGVERSION)
-
+IT_GET_PKGVERSION
 IT_GET_LSB_DATA
 
 SET_ARCH_DIRS
@@ -229,8 +203,8 @@
 ENABLE_HG
 AC_CHECK_WITH_HG_REVISION
 AC_CHECK_WITH_TZDATA_DIR
-
 IT_CHECK_FOR_CLASS([SUN_AWT_TOOLKIT], [sun.awt.SunToolkit])
+IT_CHECK_XULRUNNER_VERSION
 
 if test "x${enable_visualvm}" = "xyes"
 then
@@ -432,89 +406,6 @@
   AC_SUBST(LIBPULSE_LIBS)
 fi
 
-dnl Check for plugin support headers and libraries.
-dnl FIXME: use unstable
-if test "x${enable_plugin}" = "xyes"
-  then
-    PKG_CHECK_MODULES(XULRUNNER, \
-      nspr mozilla-js mozilla-plugin libxul-unstable >= 1.9)
-    PKG_CHECK_MODULES(GTK, gtk+-2.0)
-    PKG_CHECK_MODULES(GLIB, glib-2.0)
-
-    AC_SUBST(MOZILLA_CFLAGS)
-    AC_SUBST(MOZILLA_LIBS)
-    AC_SUBST(GLIB_CFLAGS)
-    AC_SUBST(GLIB_LIBS)
-    AC_SUBST(GTK_CFLAGS)
-    AC_SUBST(GTK_LIBS)
-  fi
-
-if test "x${enable_npplugin}" = "xyes"
-  then
-    PKG_CHECK_MODULES(MOZILLA, \
-      mozilla-plugin libxul)
-    PKG_CHECK_MODULES(GTK, gtk+-2.0)
-    PKG_CHECK_MODULES(GLIB, glib-2.0)
-
-    AC_SUBST(MOZILLA_CFLAGS)
-    AC_SUBST(MOZILLA_LIBS)
-    AC_SUBST(GLIB_CFLAGS)
-    AC_SUBST(GLIB_LIBS)
-    AC_SUBST(GTK_CFLAGS)
-    AC_SUBST(GTK_LIBS)
-  fi
-
-if test "x${enable_plugin}" = "xyes" -o "x${enable_npplugin}" = "xyes"
-then
-  AC_LANG_PUSH([C++])
-  OLDCPPFLAGS="$CPPFLAGS"
-  CPPFLAGS="$CPPFLAGS $XULRUNNER_CFLAGS"
-
-  AC_CACHE_CHECK([for xulrunner version], [xulrunner_cv_collapsed_version],
-      [AC_RUN_IFELSE(
-        [AC_LANG_PROGRAM([[
-#include <mozilla-config.h>
-#include <math.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-]],[[
-int version = 0;
-const char* token = NULL;
-int power=6;
-FILE *datafile;
-
-datafile = fopen ("conftest.vdata", "w");
-if (!datafile) return 1;
-
-// 32 chars is more than enough to hold version
-char* mozilla_version = (char*) malloc(32*sizeof(char));
-snprintf(mozilla_version, 32, "%s", MOZILLA_VERSION);
-
-token = strtok(mozilla_version, ".");
-while (token)
-{
-    version += atoi(token)*(pow(10, power));
-    power -=2;
-    token = strtok(NULL, ".");
-}
-
-fprintf (datafile, "%d\n", version);
-free(mozilla_version);
-if (fclose(datafile)) return 1;
-
-return EXIT_SUCCESS;
-]])],
-    [xulrunner_cv_collapsed_version="$(cat conftest.vdata)"],
-    [AC_MSG_FAILURE([cannot determine xulrunner version])])],
-  [xulrunner_cv_collapsed_version="190000"])
-
-  CPPFLAGS="$OLDCPPFLAGS"
-  AC_LANG_POP([C++])
-
-  AC_SUBST(MOZILLA_VERSION_COLLAPSED, $xulrunner_cv_collapsed_version)
-fi
-
 if test "x${ENABLE_NSS}" = "xyes"
 then
   PKG_CHECK_MODULES(NSS, nss, [NSS_FOUND=yes], [NSS_FOUND=no])
--- a/patches/icedtea-libraries.patch	Thu Jan 21 02:04:50 2010 +0000
+++ b/patches/icedtea-libraries.patch	Thu Jan 28 16:34:49 2010 +0000
@@ -25045,18 +25045,22 @@
  }
  
  
-@@ -2317,6 +2377,146 @@
+@@ -2317,6 +2377,150 @@
  
  /********************** end of destination manager ************/
  
 +METHODDEF(void)
 +initIDs()
 +{
++#if JPEG_LIB_VERSION >= 80
++    void *handle = dlopen("libjpeg.so.8", RTLD_LAZY | RTLD_GLOBAL);
++#else
 +#if JPEG_LIB_VERSION >= 70
 +    void *handle = dlopen("libjpeg.so.7", RTLD_LAZY | RTLD_GLOBAL);
 +#else
 +    void *handle = dlopen("libjpeg.so.62", RTLD_LAZY | RTLD_GLOBAL);
 +#endif
++#endif
 +    
 +    jpegstderror = (fn_jpegstderror)dlsym(handle, "jpeg_std_error");
 +    if (jpegstderror == NULL) {
@@ -25343,14 +25347,19 @@
  /* Initialize the Java VM instance variable when the library is
     first loaded */
  JavaVM *jvm;
-@@ -462,6 +493,71 @@
+@@ -462,6 +493,76 @@
  Java_sun_awt_image_JPEGImageDecoder_initIDs(JNIEnv *env, jclass cls,
                                              jclass InputStreamClass)
  {
++#if JPEG_LIB_VERSION >= 80
++    void *handle = dlopen("libjpeg.so.8", RTLD_LAZY | RTLD_GLOBAL);
++#else
++#if JPEG_LIB_VERSION >= 70
 +    void *handle = dlopen("libjpeg.so.7", RTLD_LAZY | RTLD_GLOBAL);
-+    if (handle == NULL) {
-+       handle = dlopen("libjpeg.so.62", RTLD_LAZY | RTLD_GLOBAL);
-+    }
++#else
++    void *handle = dlopen("libjpeg.so.62", RTLD_LAZY | RTLD_GLOBAL);
++#endif
++#endif
 + 
 +    jpegstderror = (fn_jpegstderror)dlsym(handle, "jpeg_std_error");
 +    if (jpegstderror == NULL) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/libpng.patch	Thu Jan 28 16:34:49 2010 +0000
@@ -0,0 +1,12 @@
+diff -r 93c580ce5e88 jdk/src/share/native/sun/awt/splashscreen/splashscreen_png.c
+--- openjdk.orig/jdk/src/share/native/sun/awt/splashscreen/splashscreen_png.c	Fri Jan 15 08:41:51 2010 -0800
++++ openjdk/jdk/src/share/native/sun/awt/splashscreen/splashscreen_png.c	Wed Jan 27 16:52:44 2010 +0000
+@@ -182,7 +182,7 @@
+     int success = 0;
+ 
+     stream->read(stream, sig, SIG_BYTES);
+-    if (!png_check_sig(sig, SIG_BYTES)) {
++    if (png_sig_cmp(sig, 0, SIG_BYTES)) {
+         goto done;
+     }
+     success = SplashDecodePng(splash, my_png_read_stream, stream);
--- a/plugin/icedteanp/IcedTeaNPPlugin.cc	Thu Jan 21 02:04:50 2010 +0000
+++ b/plugin/icedteanp/IcedTeaNPPlugin.cc	Thu Jan 28 16:34:49 2010 +0000
@@ -87,8 +87,8 @@
               __LINE__, g_thread_self (), first, second, third)
 
 // Plugin information passed to about:plugins.
-#define PLUGIN_NAME "IcedTea NPR Web Browser Plugin (using IcedTea)"
-#define PLUGIN_DESC "The " PLUGIN_NAME PLUGIN_VERSION " executes Java applets."
+#define PLUGIN_NAME "IcedTea NPR Web Browser Plugin (using " PLUGIN_VERSION ")"
+#define PLUGIN_DESC "The " PLUGIN_NAME " executes Java applets."
 
 #define PLUGIN_MIME_DESC                                               \
   "application/x-java-vm:class,jar:IcedTea;"                           \
@@ -1336,7 +1336,7 @@
 
   // if proxy info is available, extract it
   nsCString phost;
-  PRint32_t pport;
+  PRInt32 pport;
   nsCString ptype;
 
   info->GetHost(phost);
@@ -2079,7 +2079,7 @@
     {
     case NPPVpluginNameString:
       PLUGIN_DEBUG_0ARG ("NP_GetValue: returning plugin name.\n");
-      *char_value = g_strdup (PLUGIN_NAME " " PACKAGE_VERSION);
+      *char_value = g_strdup (PLUGIN_NAME);
       break;
 
     case NPPVpluginDescriptionString:
--- a/ports/hotspot/make/linux/makefiles/zeroshark.make	Thu Jan 21 02:04:50 2010 +0000
+++ b/ports/hotspot/make/linux/makefiles/zeroshark.make	Thu Jan 28 16:34:49 2010 +0000
@@ -29,6 +29,7 @@
 
 Obj_Files += asm_helper.o
 Obj_Files += cppInterpreter_arm.o
+Obj_Files += thumb2.o
 
 CFLAGS += -DHOTSPOT_ASM
 
@@ -38,6 +39,7 @@
 	$(COMPILE.CC) -o $@ $< $(COMPILE_DONE)
 
 cppInterpreter_arm.o:	offsets_arm.s bytecodes_arm.s
+thumb2.o:		offsets_arm.s
 
 offsets_arm.s:	mkoffsets
 	@echo Generating assembler offsets
--- a/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp	Thu Jan 21 02:04:50 2010 +0000
+++ b/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp	Thu Jan 28 16:34:49 2010 +0000
@@ -16,10 +16,60 @@
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include "incls/_precompiled.incl"
+#define	ARCH_THUMBEE	(1<<16)
+#define ARCH_VFP	(1<<17)
+#define ARCH_CLZ	(1<<18)
 
 #ifndef STATIC_OFFSETS
 
+#include "incls/_bytecodeInterpreter.cpp.incl"
+
+#include <linux/auxvec.h>
+#include <asm/hwcap.h>
+
+#define VECBUFF_SIZE 64
+
+extern "C" unsigned hwcap(void)
+{
+  int fd;
+  unsigned vecs[VECBUFF_SIZE];
+  unsigned *p;
+  int i, n;
+  unsigned rc = 0;
+  unsigned arch = 4;
+ 
+  fd = open("/proc/self/auxv", O_RDONLY);
+  if (fd < 0) return 0;
+  do {
+    n = read(fd, vecs, VECBUFF_SIZE * sizeof(unsigned));
+    p = vecs;
+    i = n/8;
+    while (--i >= 0) {
+      unsigned tag = *p++;
+      unsigned value = *p++;
+      if (tag == 0) goto fini;
+      if (tag == AT_HWCAP) {
+	if (value & HWCAP_THUMBEE) rc |= ARCH_THUMBEE;
+	if (value & HWCAP_VFP) rc |= ARCH_VFP;
+      } else if (tag == AT_PLATFORM) {
+	const char *s = (const char *)value;
+	int c;
+
+	if (*s++ == 'v') {
+	  arch = 0;
+	  while ((isdigit)(c = *s++)) arch = arch * 10 + c - '0';
+	}
+      }
+    }
+  } while (n == VECBUFF_SIZE * sizeof(unsigned));
+fini:
+  close(fd);
+//  printf("arch = %d, rc = 0x%08x\n", arch, rc);
+  if (arch >= 5) rc |= ARCH_CLZ;
+  if (arch >= 7) rc |= ARCH_THUMBEE;
+  return rc | (1<<arch);
+}
+
 /* Thease functions allow the ASM interpreter to call CPP virtual functions.
  * Otherwise the ASM interpreter has to grup around in the VTABLE which is
  * not very portable.
@@ -44,10 +94,262 @@
 	return SharedRuntime::generate_class_cast_message(name, klass);
 }
 
+#define HELPER_THROW(thread, name, msg) Exceptions::_throw_msg(thread, __FILE__, __LINE__, name, msg)
+
+class VMStructs {
+public:
+	static inline klassOop klass_at_addr(constantPoolOop constants, u2 index) {
+	  return (klassOop) *constants->obj_at_addr(index);
+	}
+};
+
+extern "C" oop Helper_new(interpreterState istate, unsigned index)
+{
+    JavaThread *thread = istate->thread();
+
+    constantPoolOop constants = istate->method()->constants();
+    oop result = NULL;
+    if (!constants->tag_at(index).is_unresolved_klass()) {
+      // Make sure klass is initialized and doesn't have a finalizer
+      oop entry = VMStructs::klass_at_addr(constants, index);
+      klassOop k_entry = (klassOop) entry;
+      instanceKlass* ik = (instanceKlass*) k_entry->klass_part();
+      if ( ik->is_initialized() && ik->can_be_fastpath_allocated() ) {
+	size_t obj_size = ik->size_helper();
+	// If the TLAB isn't pre-zeroed then we'll have to do it
+	bool need_zero = !ZeroTLAB;
+	if (UseTLAB) {
+	  result = (oop) thread->tlab().allocate(obj_size);
+	}
+	if (result == NULL) {
+	  need_zero = true;
+	  // Try allocate in shared eden
+    retry:
+	  HeapWord* compare_to = *Universe::heap()->top_addr();
+	  HeapWord* new_top = compare_to + obj_size;
+	  if (new_top <= *Universe::heap()->end_addr()) {
+	    if (Atomic::cmpxchg_ptr(new_top, Universe::heap()->top_addr(), compare_to) != compare_to) {
+	      goto retry;
+	    }
+	    result = (oop) compare_to;
+	  }
+	}
+	if (result != NULL) {
+	  // Initialize object (if nonzero size and need) and then the header
+	  if (need_zero ) {
+	    HeapWord* to_zero = (HeapWord*) result + sizeof(oopDesc) / oopSize;
+	    obj_size -= sizeof(oopDesc) / oopSize;
+	    if (obj_size > 0 ) {
+	      memset(to_zero, 0, obj_size * HeapWordSize);
+	    }
+	  }
+	  if (UseBiasedLocking) {
+	    result->set_mark(ik->prototype_header());
+	  } else {
+	    result->set_mark(markOopDesc::prototype());
+	  }
+	  result->set_klass_gap(0);
+	  result->set_klass(k_entry);
+	  return result;
+	}
+      }
+    }
+    // Slow case allocation
+    InterpreterRuntime::_new(thread, istate->method()->constants(), index);
+    result = thread->vm_result();
+    thread->set_vm_result(NULL);
+    return result;
+}
+
+extern "C" int Helper_instanceof(interpreterState istate, unsigned index, oop tos)
+{
+    if (tos == NULL) return 0;
+
+    // Constant pool may have actual klass or unresolved klass. If it is
+    // unresolved we must resolve it
+    if (istate->method()->constants()->tag_at(index).is_unresolved_klass()) {
+      InterpreterRuntime::quicken_io_cc(istate->thread());
+      if (istate->thread()->has_pending_exception()) return 0;
+    }
+    klassOop klassOf = VMStructs::klass_at_addr(istate->method()->constants(), index);
+    klassOop objKlassOop = tos->klass();
+    //
+    // Check for compatibilty. This check must not GC!!
+    // Seems way more expensive now that we must dispatch
+    //
+    return objKlassOop == klassOf || objKlassOop->klass_part()->is_subtype_of(klassOf);
+}
+
+extern "C" oop Helper_checkcast(interpreterState istate, unsigned index, oop tos)
+{
+    if (tos == NULL) return NULL;
+
+    // Constant pool may have actual klass or unresolved klass. If it is
+    // unresolved we must resolve it
+    if (istate->method()->constants()->tag_at(index).is_unresolved_klass()) {
+      oop except_oop;
+      InterpreterRuntime::quicken_io_cc(istate->thread());
+      if (except_oop = istate->thread()->pending_exception()) return except_oop;
+    }
+    klassOop klassOf = VMStructs::klass_at_addr(istate->method()->constants(), index);
+    klassOop objKlassOop = tos->klass(); //ebx
+    //
+    // Check for compatibilty. This check must not GC!!
+    // Seems way more expensive now that we must dispatch
+    //
+    if (objKlassOop != klassOf && !objKlassOop->klass_part()->is_subtype_of(klassOf)) {
+      ResourceMark rm(istate->thread());
+      const char* objName = Klass::cast(objKlassOop)->external_name();
+      const char* klassName = Klass::cast(klassOf)->external_name();
+      char* message = SharedRuntime::generate_class_cast_message(objName, klassName);
+      ThreadInVMfromJava trans(istate->thread());
+      HELPER_THROW(istate->thread(), vmSymbols::java_lang_ClassCastException(), message);
+    }
+    return istate->thread()->pending_exception();
+}
+
+extern "C" oop Helper_aastore(interpreterState istate, oop value, int index, arrayOop arrayref)
+{
+    if (arrayref == NULL) {
+      ThreadInVMfromJava trans(istate->thread());
+      HELPER_THROW(istate->thread(), vmSymbols::java_lang_NullPointerException(), "");
+    } else if ((uint32_t)index >= (uint32_t)arrayref->length()) {
+      char message[jintAsStringSize];
+      sprintf(message, "%d", index);
+      HELPER_THROW(istate->thread(), vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message);
+    } else {
+      if (value != NULL) {
+	/* Check assignability of value into arrayref */
+	klassOop rhsKlassOop = value->klass(); // EBX (subclass)
+	klassOop elemKlassOop = ((objArrayKlass*) arrayref->klass()->klass_part())->element_klass();
+	//
+	// Check for compatibilty. This check must not GC!!
+	// Seems way more expensive now that we must dispatch
+	//
+	if (rhsKlassOop != elemKlassOop && !rhsKlassOop->klass_part()->is_subtype_of(elemKlassOop)) {
+	  HELPER_THROW(istate->thread(), vmSymbols::java_lang_ArrayStoreException(), "");
+	  goto handle_exception;
+	}
+      }
+      oop* elem_loc = (oop*)(((address) arrayref->base(T_OBJECT)) + index * sizeof(oop));
+      // *(oop*)(((address) arrayref->base(T_OBJECT)) + index * sizeof(oop)) = value;
+      *elem_loc = value;
+      // Mark the card
+      BarrierSet* bs = Universe::heap()->barrier_set();
+      static volatile jbyte* _byte_map_base = (volatile jbyte*)(((CardTableModRefBS*)bs)->byte_map_base);
+      OrderAccess::release_store(&_byte_map_base[(uintptr_t)elem_loc >> CardTableModRefBS::card_shift], 0);
+    }
+handle_exception:
+    return istate->thread()->pending_exception();
+}
+
+extern "C" void Helper_aputfield(oop obj)
+{
+      BarrierSet* bs = Universe::heap()->barrier_set();
+      static volatile jbyte* _byte_map_base = (volatile jbyte*)(((CardTableModRefBS*)bs)->byte_map_base);
+      OrderAccess::release_store(&_byte_map_base[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0);
+}
+
+extern "C" oop Helper_synchronized_enter(JavaThread *thread, BasicObjectLock *mon)
+{
+    BasicLock *lock = mon->lock();
+    markOop displaced = lock->displaced_header();
+
+    if (thread->is_lock_owned((address)displaced->clear_lock_bits()))
+      lock->set_displaced_header(NULL);
+    else
+      InterpreterRuntime::monitorenter(thread, mon);
+    return thread->pending_exception();
+}
+
+extern "C" oop Helper_synchronized_exit(JavaThread *thread, BasicObjectLock *mon)
+{
+    {
+      HandleMark __hm(thread);
+      if (mon->obj() == NULL)
+	InterpreterRuntime::throw_illegal_monitor_state_exception(thread);
+      else
+        InterpreterRuntime::monitorexit(thread, mon);
+    }
+    return thread->pending_exception();
+}
+
+extern "C" oop Helper_SafePoint(JavaThread *thread)
+{
+    {
+      HandleMarkCleaner __hmc(thread);
+    }
+    SafepointSynchronize::block(thread);
+    return thread->pending_exception();
+}
+
+extern "C" void Helper_RaiseArrayBoundException(JavaThread *thread, int index)
+{
+  char message[jintAsStringSize];
+  sprintf(message, "%d", index);
+  {
+       ThreadInVMfromJava trans(thread);
+       Exceptions::_throw_msg(thread, "[Bytecoce Interpreter]", 99,
+			vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message);
+  }
+}
+
+extern "C" void Helper_Raise(JavaThread *thread, symbolOopDesc *name, char const *msg)
+{
+   ThreadInVMfromJava trans(thread);
+   Exceptions::_throw_msg(thread, "[Bytecoce Interpreter]", 99, name, msg);
+}
+
+extern "C" void Helper_RaiseIllegalMonitorException(JavaThread *thread)
+{
+    HandleMark __hm(thread);
+    InterpreterRuntime::throw_illegal_monitor_state_exception(thread);
+}
+
+extern "C" address Helper_HandleException(interpreterState istate, JavaThread *thread)
+{
+    HandleMarkCleaner __hmc(thread);
+    Handle except_oop(thread, thread->pending_exception());
+    HandleMark __hm(thread);
+    intptr_t continuation_bci;
+    intptr_t *topOfStack;
+    address pc;
+
+    thread->clear_pending_exception();
+    continuation_bci = (intptr_t)InterpreterRuntime::exception_handler_for_exception(thread, except_oop());
+    except_oop = (oop) thread->vm_result();
+    thread->set_vm_result(NULL);
+    if (continuation_bci >= 0) {
+      topOfStack = (intptr_t *)istate->stack();
+      *topOfStack-- = (intptr_t)except_oop();
+      istate->set_stack(topOfStack);
+      pc = istate->method()->code_base() + continuation_bci;
+#if 0
+        tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", Klass::cast(except_oop->klass())->external_name(), except_oop());
+        tty->print_cr(" thrown in interpreter method <%s>", istate->method()->name_and_sig_as_C_string());
+        tty->print_cr(" at bci %d, continuing at %d for thread " INTPTR_FORMAT,
+                      pc - (intptr_t)istate->method()->code_base(),
+                      continuation_bci, thread);
+#endif
+      return pc;
+    }
+#if 0
+      tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", Klass::cast(except_oop->klass())->external_name(), except_oop());
+      tty->print_cr(" thrown in interpreter method <%s>", istate->method()->name_and_sig_as_C_string());
+      tty->print_cr(" at bci %d, unwinding for thread " INTPTR_FORMAT,
+                    pc  - (intptr_t) istate->method()->code_base(),
+                    thread);
+#endif
+    thread->set_pending_exception(except_oop(), NULL, 0);
+    return 0;
+}
+
 #endif // STATIC_OFFSETS
 
 #ifdef STATIC_OFFSETS
 
+#include "incls/_precompiled.incl"
+
 class VMStructs {
 public:
 	static void print_vm_offsets(void);
@@ -57,6 +359,7 @@
 
 void print_def(const char *s, int v)
 {
+	fprintf(outfile, "#undef %-40s\n", s);
 	fprintf(outfile, "#define %-40s 0x%02x\n", s, v);
 }
 
@@ -65,80 +368,115 @@
 	fputc('\n', outfile);
 }
 
+// ZeroFrame is not friends with VMStructs, but it is with ZeroStackPrinter
+class ZeroStackPrinter {
+public:
+  static void print_vm_offsets(void);
+};
+
+void ZeroStackPrinter::print_vm_offsets(void)
+{
+    print_def("INTERPRETER_FRAME", ZeroFrame::INTERPRETER_FRAME);
+}
+
 void VMStructs::print_vm_offsets(void)
 {
-	print_def("THREAD_PENDING_EXC", offset_of(JavaThread, _pending_exception));
-	print_def("THREAD_SUSPEND_FLAGS", offset_of(JavaThread, _suspend_flags));
-	print_def("THREAD_ACTIVE_HANDLES", offset_of(JavaThread, _active_handles));
-	print_def("THREAD_LAST_HANDLE_MARK", offset_of(JavaThread, _last_handle_mark));
-	print_def("THREAD_TLAB_TOP", offset_of(JavaThread, _tlab) + offset_of(ThreadLocalAllocBuffer, _top));
-	print_def("THREAD_TLAB_END", offset_of(JavaThread, _tlab) + offset_of(ThreadLocalAllocBuffer, _end));
-	print_def("THREAD_RESOURCEAREA", offset_of(JavaThread, _resource_area));
-	print_def("THREAD_HANDLE_AREA", offset_of(JavaThread, _handle_area));
-	print_def("THREAD_STACK_BASE", offset_of(JavaThread, _stack_base));
-	print_def("THREAD_STACK_SIZE", offset_of(JavaThread, _stack_size));
-	print_def("THREAD_LAST_JAVA_SP", offset_of(JavaThread, _anchor) + offset_of(JavaFrameAnchor, _last_Java_sp));
-	print_def("THREAD_JNI_ENVIRONMENT", offset_of(JavaThread, _jni_environment));
-	print_def("THREAD_VM_RESULT", offset_of(JavaThread, _vm_result));
-	print_def("THREAD_STATE", offset_of(JavaThread, _thread_state));
-	print_def("THREAD_DO_NOT_UNLOCK", offset_of(JavaThread, _do_not_unlock_if_synchronized));
+  print_def("ISTATE_THREAD",    offset_of(BytecodeInterpreter, _thread));
+  print_def("ISTATE_BCP",       offset_of(BytecodeInterpreter, _bcp));
+  print_def("ISTATE_LOCALS",    offset_of(BytecodeInterpreter, _locals));
+  print_def("ISTATE_CONSTANTS", offset_of(BytecodeInterpreter, _constants));
+  print_def("ISTATE_METHOD",    offset_of(BytecodeInterpreter, _method));
+  print_def("ISTATE_STACK",     offset_of(BytecodeInterpreter, _stack));
+  print_def("ISTATE_MSG",       offset_of(BytecodeInterpreter, _msg));
+  print_def("ISTATE_OOP_TEMP",	offset_of(BytecodeInterpreter, _oop_temp));
+  print_def("ISTATE_STACK_BASE",offset_of(BytecodeInterpreter, _stack_base));
+  print_def("ISTATE_STACK_LIMIT",offset_of(BytecodeInterpreter, _stack_limit));
+  print_def("ISTATE_MONITOR_BASE",offset_of(BytecodeInterpreter, _monitor_base));
+  print_def("ISTATE_SELF_LINK",	offset_of(BytecodeInterpreter, _self_link));
+  print_def("ISTATE_FRAME_TYPE", sizeof(BytecodeInterpreter) + 0);
+  print_def("ISTATE_NEXT_FRAME", sizeof(BytecodeInterpreter) + 4);
+  print_def("FRAME_SIZE", sizeof(BytecodeInterpreter) + 8);
+  nl();
+  ZeroStackPrinter::print_vm_offsets();
+  nl();
+  print_def("THREAD_PENDING_EXC", offset_of(JavaThread, _pending_exception));
+  print_def("THREAD_SUSPEND_FLAGS", offset_of(JavaThread, _suspend_flags));
+  print_def("THREAD_ACTIVE_HANDLES", offset_of(JavaThread, _active_handles));
+  print_def("THREAD_LAST_HANDLE_MARK", offset_of(JavaThread, _last_handle_mark));
+  print_def("THREAD_TLAB_TOP", offset_of(JavaThread, _tlab) + offset_of(ThreadLocalAllocBuffer, _top));
+  print_def("THREAD_TLAB_END", offset_of(JavaThread, _tlab) + offset_of(ThreadLocalAllocBuffer, _end));
+  print_def("THREAD_RESOURCEAREA", offset_of(JavaThread, _resource_area));
+  print_def("THREAD_HANDLE_AREA", offset_of(JavaThread, _handle_area));
+  print_def("THREAD_STACK_BASE", offset_of(JavaThread, _stack_base));
+  print_def("THREAD_STACK_SIZE", offset_of(JavaThread, _stack_size));
+  print_def("THREAD_LAST_JAVA_SP", offset_of(JavaThread, _anchor) + offset_of(JavaFrameAnchor, _last_Java_sp));
+  print_def("THREAD_JNI_ENVIRONMENT", offset_of(JavaThread, _jni_environment));
+  print_def("THREAD_VM_RESULT", offset_of(JavaThread, _vm_result));
+  print_def("THREAD_STATE", offset_of(JavaThread, _thread_state));
+  print_def("THREAD_DO_NOT_UNLOCK", offset_of(JavaThread, _do_not_unlock_if_synchronized));
 
-	print_def("THREAD_JAVA_STACK_BASE", offset_of(JavaThread, _zero_stack) + in_bytes(ZeroStack::base_offset()));
-	print_def("THREAD_JAVA_SP", offset_of(JavaThread, _zero_stack) + in_bytes(ZeroStack::sp_offset()));
-	print_def("THREAD_TOP_ZERO_FRAME", offset_of(JavaThread, _top_zero_frame));
-	print_def("THREAD_SPECIALRUNTIMEEXITCONDITION", offset_of(JavaThread, _special_runtime_exit_condition));
-	nl();
-	print_def("_thread_external_suspend",	Thread::_external_suspend);
-	print_def("_thread_ext_suspended",	Thread::_ext_suspended);
-	print_def("_thread_deopt_suspend",	Thread::_deopt_suspend);
-	nl();
-	print_def("METHOD_CONSTMETHOD", offset_of(methodOopDesc, _constMethod));
-	print_def("METHOD_CONSTANTS", offset_of(methodOopDesc, _constants));
-	print_def("METHOD_METHODDATA", offset_of(methodOopDesc, _method_data));
-	print_def("METHOD_INVOKECOUNT", offset_of(methodOopDesc, _interpreter_invocation_count));
-	print_def("METHOD_ACCESSFLAGS", offset_of(methodOopDesc, _access_flags));
-	print_def("METHOD_VTABLEINDEX", offset_of(methodOopDesc, _vtable_index));
-	print_def("METHOD_RESULTINDEX", offset_of(methodOopDesc, _result_index));
-	print_def("METHOD_METHODSIZE", offset_of(methodOopDesc, _method_size));
-	print_def("METHOD_MAXSTACK", offset_of(methodOopDesc, _max_stack));
-	print_def("METHOD_MAXLOCALS", offset_of(methodOopDesc, _max_locals));
-	print_def("METHOD_SIZEOFPARAMETERS", offset_of(methodOopDesc, _size_of_parameters));
-	print_def("METHOD_INVOCATIONCOUNTER", offset_of(methodOopDesc, _invocation_counter));
-	print_def("METHOD_BACKEDGECOUNTER", offset_of(methodOopDesc, _backedge_counter));
-	print_def("METHOD_FROM_INTERPRETED", offset_of(methodOopDesc, _from_interpreted_entry));
-	// ECN: These two appear to be just tagged onto the end of the class
-	print_def("METHOD_NATIVEHANDLER", sizeof(methodOopDesc));
-	print_def("METHOD_SIGNATUREHANDLER", sizeof(methodOopDesc)+4);
-	nl();
-        print_def("CONSTMETHOD_CODESIZE", offset_of(constMethodOopDesc, _code_size));
-	print_def("CONSTMETHOD_CODEOFFSET", sizeof(constMethodOopDesc));
-	nl();
-	print_def("JNIHANDLEBLOCK_TOP", offset_of(JNIHandleBlock, _top));
-	nl();
-	print_def("KLASS_PART", klassOopDesc::klass_part_offset_in_bytes());
-	print_def("KLASS_ACCESSFLAGS", offset_of(Klass, _access_flags));
-	print_def("INSTANCEKLASS_INITSTATE", offset_of(instanceKlass, _init_state));
-	print_def("INSTANCEKLASS_VTABLE_LEN", offset_of(instanceKlass, _vtable_len));
-	print_def("INSTANCEKLASS_ITABLE_LEN", offset_of(instanceKlass, _itable_len));
-	print_def("INSTANCEKLASS_VTABLE_OFFSET", instanceKlass::vtable_start_offset() * sizeof(int *));
-	print_def("OBJARRAYKLASS_ELEMENTKLASS", offset_of(objArrayKlass, _element_klass));
-	nl();
-	print_def("CONSTANTPOOL_TAGS", offset_of(constantPoolOopDesc, _tags));
-	print_def("CONSTANTPOOL_CACHE", offset_of(constantPoolOopDesc, _cache));
-	print_def("CONSTANTPOOL_BASE", sizeof(constantPoolOopDesc));
-	nl();
-	print_def("CP_OFFSET", in_bytes(constantPoolCacheOopDesc::base_offset()));
-	nl();
-	print_def("BASE_OFFSET_BYTE", arrayOopDesc::base_offset_in_bytes(T_BYTE));
-	print_def("BASE_OFFSET_SHORT", arrayOopDesc::base_offset_in_bytes(T_SHORT));
-	print_def("BASE_OFFSET_WORD", arrayOopDesc::base_offset_in_bytes(T_INT));
-	print_def("BASE_OFFSET_LONG", arrayOopDesc::base_offset_in_bytes(T_LONG));
-	nl();
-	print_def("SIZEOF_HANDLEMARK", sizeof(HandleMark));
+  print_def("THREAD_JAVA_STACK_BASE", offset_of(JavaThread, _zero_stack) + in_bytes(ZeroStack::base_offset()));
+  print_def("THREAD_JAVA_SP", offset_of(JavaThread, _zero_stack) + in_bytes(ZeroStack::sp_offset()));
+  print_def("THREAD_TOP_ZERO_FRAME", offset_of(JavaThread, _top_zero_frame));
+  print_def("THREAD_SPECIALRUNTIMEEXITCONDITION", offset_of(JavaThread, _special_runtime_exit_condition));
+  nl();
+  print_def("_thread_external_suspend",	Thread::_external_suspend);
+  print_def("_thread_ext_suspended",	Thread::_ext_suspended);
+  print_def("_thread_deopt_suspend",	Thread::_deopt_suspend);
+  nl();
+  print_def("METHOD_CONSTMETHOD", offset_of(methodOopDesc, _constMethod));
+  print_def("METHOD_CONSTANTS", offset_of(methodOopDesc, _constants));
+  print_def("METHOD_METHODDATA", offset_of(methodOopDesc, _method_data));
+  print_def("METHOD_INVOKECOUNT", offset_of(methodOopDesc, _interpreter_invocation_count));
+  print_def("METHOD_ACCESSFLAGS", offset_of(methodOopDesc, _access_flags));
+  print_def("METHOD_VTABLEINDEX", offset_of(methodOopDesc, _vtable_index));
+  print_def("METHOD_RESULTINDEX", offset_of(methodOopDesc, _result_index));
+  print_def("METHOD_METHODSIZE", offset_of(methodOopDesc, _method_size));
+  print_def("METHOD_MAXSTACK", offset_of(methodOopDesc, _max_stack));
+  print_def("METHOD_MAXLOCALS", offset_of(methodOopDesc, _max_locals));
+  print_def("METHOD_SIZEOFPARAMETERS", offset_of(methodOopDesc, _size_of_parameters));
+  print_def("METHOD_INVOCATIONCOUNTER", offset_of(methodOopDesc, _invocation_counter));
+  print_def("METHOD_BACKEDGECOUNTER", offset_of(methodOopDesc, _backedge_counter));
+  print_def("METHOD_FROM_INTERPRETED", offset_of(methodOopDesc, _from_interpreted_entry));
+  // ECN: These two appear to be just tagged onto the end of the class
+  print_def("METHOD_NATIVEHANDLER", sizeof(methodOopDesc));
+  print_def("METHOD_SIGNATUREHANDLER", sizeof(methodOopDesc)+4);
+  nl();
+  print_def("CONSTMETHOD_CODESIZE", offset_of(constMethodOopDesc, _code_size));
+  print_def("CONSTMETHOD_CODEOFFSET", sizeof(constMethodOopDesc));
+  nl();
+  print_def("JNIHANDLEBLOCK_TOP", offset_of(JNIHandleBlock, _top));
+  nl();
+  print_def("KLASS_PART", klassOopDesc::klass_part_offset_in_bytes());
+  print_def("KLASS_ACCESSFLAGS", offset_of(Klass, _access_flags));
+  print_def("KLASS_JAVA_MIRROR", offset_of(Klass, _java_mirror));
+  print_def("INSTANCEKLASS_INITSTATE", offset_of(instanceKlass, _init_state));
+  print_def("INSTANCEKLASS_VTABLE_LEN", offset_of(instanceKlass, _vtable_len));
+  print_def("INSTANCEKLASS_ITABLE_LEN", offset_of(instanceKlass, _itable_len));
+  print_def("INSTANCEKLASS_VTABLE_OFFSET", instanceKlass::vtable_start_offset() * sizeof(int *));
+  print_def("OBJARRAYKLASS_ELEMENTKLASS", offset_of(objArrayKlass, _element_klass));
+  nl();
+  print_def("CONSTANTPOOL_TAGS", offset_of(constantPoolOopDesc, _tags));
+  print_def("CONSTANTPOOL_CACHE", offset_of(constantPoolOopDesc, _cache));
+  print_def("CONSTANTPOOL_POOL_HOLDER", offset_of(constantPoolOopDesc, _pool_holder));
+  print_def("CONSTANTPOOL_BASE", sizeof(constantPoolOopDesc));
+  nl();
+  print_def("CP_OFFSET", in_bytes(constantPoolCacheOopDesc::base_offset()));
+  nl();
+  print_def("BASE_OFFSET_BYTE", arrayOopDesc::base_offset_in_bytes(T_BYTE));
+  print_def("BASE_OFFSET_SHORT", arrayOopDesc::base_offset_in_bytes(T_SHORT));
+  print_def("BASE_OFFSET_WORD", arrayOopDesc::base_offset_in_bytes(T_INT));
+  print_def("BASE_OFFSET_LONG", arrayOopDesc::base_offset_in_bytes(T_LONG));
+  nl();
+  print_def("SIZEOF_HANDLEMARK", sizeof(HandleMark));
 }
 
 int main(void)
 {
+	print_def("ARCH_VFP",			ARCH_VFP);
+	print_def("ARCH_THUMBEE",		ARCH_THUMBEE);
+	print_def("ARCH_CLZ",			ARCH_CLZ);
+	nl();
 	print_def("JVM_CONSTANT_Utf8",		JVM_CONSTANT_Utf8);
 	print_def("JVM_CONSTANT_Unicode",	JVM_CONSTANT_Unicode);
 	print_def("JVM_CONSTANT_Integer",	JVM_CONSTANT_Integer);
@@ -190,6 +528,15 @@
 	print_def("T_ARRAY",	T_ARRAY);
 	print_def("T_VOID",	T_VOID);
 	nl();
+	print_def("tos_btos",	btos);
+	print_def("tos_ctos",	ctos);
+	print_def("tos_stos",	stos);
+	print_def("tos_itos",	itos);
+	print_def("tos_ltos",	ltos);
+	print_def("tos_ftos",	ftos);
+	print_def("tos_dtos",	dtos);
+	print_def("tos_atos",	atos);
+	nl();
 	print_def("_thread_uninitialized",	_thread_uninitialized);
 	print_def("_thread_new",		_thread_new);
 	print_def("_thread_new_trans",		_thread_new_trans);
--- a/ports/hotspot/src/cpu/zero/vm/bytecodes_arm.def	Thu Jan 21 02:04:50 2010 +0000
+++ b/ports/hotspot/src/cpu/zero/vm/bytecodes_arm.def	Thu Jan 28 16:34:49 2010 +0000
@@ -267,8 +267,6 @@
 
 @return_register_finalizer = 0xe5, 1
 
-dmac			= 0xe6, 2
-
 iload_0_iconst_N        = 0xe7, 2
 iload_1_iconst_N        = 0xe8, 2
 iload_2_iconst_N        = 0xe9, 2
@@ -967,7 +965,7 @@
 }
 
 (frem) frem {
-@ ECN: It must be possible to do better than this
+@ It must be possible to do better than this
 	POP	r0
         bl      __aeabi_f2d
 	PUSH	r0, r1
@@ -1336,166 +1334,138 @@
 @ r2 = [jpc, #1]
 @ r1 = [jpc, #2]
 (ifeq,ifnull) ifeq_unsafe {
+	POP	r3
 	ldrb	r1, [jpc, #2]
-	POP	r3
-	mov	r2, r2, lsl #24
         cmp     r3, #0
+	beq	1f
+	DISPATCH 3
+1:
+	mov	r2, r2, lsl #24
         orr     ip, r1, r2, asr #16
-	beq	1f
-	mov	ip, #3
-1:
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (ifne,ifnonnull) ifne_unsafe {
+	POP	r3
 	ldrb	r1, [jpc, #2]
-	POP	r3
-	mov	r2, r2, lsl #24
         cmp     r3, #0
+	bne	1f
+	DISPATCH 3
+1:
+	mov	r2, r2, lsl #24
         orr     ip, r1, r2, asr #16
-	bne	1f
-	mov	ip, #3
-1:
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (iflt) iflt_unsafe {
+	POP	r3
 	ldrb	r1, [jpc, #2]
-	POP	r3
-	mov	r2, r2, lsl #24
         cmp     r3, #0
+	blt	1f
+	DISPATCH 3
+1:
+	mov	r2, r2, lsl #24
         orr     ip, r1, r2, asr #16
-	blt	1f
-	mov	ip, #3
-1:
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (ifge) ifge_unsafe {
+	POP	r3
 	ldrb	r1, [jpc, #2]
-	POP	r3
-	mov	r2, r2, lsl #24
         cmp     r3, #0
+	bge	1f
+	DISPATCH 3
+1:
+	mov	r2, r2, lsl #24
         orr     ip, r1, r2, asr #16
-	bge	1f
-	mov	ip, #3
-1:
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (ifgt) ifgt_unsafe {
+	POP	r3
 	ldrb	r1, [jpc, #2]
-	POP	r3
-	mov	r2, r2, lsl #24
         cmp     r3, #0
+	bgt	1f
+	DISPATCH 3
+1:
+	mov	r2, r2, lsl #24
         orr     ip, r1, r2, asr #16
-	bgt	1f
-	mov	ip, #3
-1:
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (ifle) ifle_unsafe {
+	POP	r3
 	ldrb	r1, [jpc, #2]
-	POP	r3
-	mov	r2, r2, lsl #24
         cmp     r3, #0
+	ble	1f
+	DISPATCH 3
+1:
+	mov	r2, r2, lsl #24
         orr     ip, r1, r2, asr #16
-	ble	1f
-	mov	ip, #3
-1:
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (if_icmpeq,if_acmpeq) if_icmpeq_unsafe {
+	POP	r3, tmp1
 	ldrb	r1, [jpc, #2]
-	POP	r3, tmp1
-	mov	r2, r2, lsl #24
         cmp     tmp1, r3
-	orr	ip, r1, r2, asr #16
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb  r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe
+	DISPATCH 3
 }
 
 (if_icmpne,if_acmpne) if_icmpne_unsafe {
+	POP	r3, tmp1
 	ldrb	r1, [jpc, #2]
-	POP	r3, tmp1
-	mov	r2, r2, lsl #24
         cmp     tmp1, r3
-	orr	ip, r1, r2, asr #16
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb  r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe
+	DISPATCH 3
 }
 
 (if_icmplt) if_icmplt_unsafe {
+	POP	r3, tmp1
 	ldrb	r1, [jpc, #2]
-	POP	r3, tmp1
-	mov	r2, r2, lsl #24
         cmp     tmp1, r3
-	orr	ip, r1, r2, asr #16
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb  r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe
+	DISPATCH 3
 }
 
 (if_icmpge) if_icmpge_unsafe {
+	POP	r3, tmp1
 	ldrb	r1, [jpc, #2]
-	POP	r3, tmp1
-	mov	r2, r2, lsl #24
         cmp     tmp1, r3
-	orr	ip, r1, r2, asr #16
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb  r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe
+	DISPATCH 3
 }
 
 (if_icmpgt) if_icmpgt_unsafe {
+	POP	r3, tmp1
 	ldrb	r1, [jpc, #2]
-	POP	r3, tmp1
-	mov	r2, r2, lsl #24
         cmp     tmp1, r3
-	orr	ip, r1, r2, asr #16
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb  r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe
+	DISPATCH 3
 }
 
 (if_icmple) if_icmple_unsafe {
+	POP	r3, tmp1
 	ldrb	r1, [jpc, #2]
-	POP	r3, tmp1
-	mov	r2, r2, lsl #24
         cmp     tmp1, r3
-	orr	ip, r1, r2, asr #16
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb  r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	ble	branch_taken_unsafe
+	DISPATCH 3
 }
 
 (goto) goto_unsafe {
 	ldrb	r1, [jpc, #2]
 	mov	r2, r2, lsl #24
-        orr     ip, r1, r2, asr #16
-        DISPATCH_START_REG	ip
+        orr     tmp1, r1, r2, asr #16
+        DISPATCH_START_REG	tmp1
+  USEC  cmp     tmp1, #0
+  USEC  ble     do_backedge
 	DISPATCH_BYTECODE
 }
 
@@ -1520,7 +1490,7 @@
 	DISPATCH	48
 }
 
-@ ECN: We dont do safe and unsafe versions of tableswitch and lookupswitch
+@ We dont do safe and unsafe versions of tableswitch and lookupswitch
 (tableswitch) tableswitch {
 	POP	a2
         bic     a1, jpc, #3
@@ -1752,28 +1722,17 @@
 
 (aputfield) aputfield {
 	ldrb	r1, [jpc, #2]
-	GET_STACK	1, r0		@ r0 = object
-	POP	oop_value_tmp			@ r1 = value
-        add     r3, constpool, r1, lsl #12
-	add	r3, r3, r2, lsl #4
-	ldr	r3, [r3, #CP_OFFSET+8]
-	SW_NPC	cmp	r0, #0
-	add	oop_address_tmp, r0, r3
-	SW_NPC	beq	null_ptr_exception
+	POP	r3, tmp1		@ r3 = value, tmp1 = object
+        add     tmp2, constpool, r1, lsl #12
+	add	tmp2, tmp2, r2, lsl #4
+	SW_NPC	cmp	tmp1, #0
+	SW_NPC	beq	null_ptr_exception_jpc_3
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 .abortentry113:
-	HW_NPC	ldr	ip, [r0]		@ Only to provoke an abort
-	bl	oop_store
-    ldr	r3, [dispatch, #Universe_collectedHeap_Address-XXX]
-        DISPATCH_START  3
-        POP     r2
-    ldr r3, [r3, #0]
-        DISPATCH_NEXT
-    ldr r3, [r3, #12]
-        DISPATCH_NEXT
-    ldr r3, [r3, #76]
-        mov     tmp2, #0
-        strb    tmp2, [r3, r2, lsr #9]
-        DISPATCH_FINISH
+	str	r3, [tmp1, tmp2]
+	mov	r0, tmp1
+	bl	Helper_aputfield
+	DISPATCH 3
 }
 
 (lputfield) lputfield {
@@ -1862,29 +1821,11 @@
 	add	r1, r2, #4
 	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
 
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
 	add	stack, r1, r0, lsl #2
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-        DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-        DISPATCH_NEXT
-        add     r2, r2, #4
-        DISPATCH_NEXT
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-        DISPATCH_NEXT
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-        DISPATCH_NEXT
-        DISPATCH_FINISH
+
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
+
+	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	bl	return_check_monitors
 	b	2b
@@ -1909,30 +1850,12 @@
 	ldr	r3, [stack, #0]
 	ldrh	r0, [r0, #40]
 
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
 	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
 	str	r1, [stack, r0, lsl #2]!
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-	DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	DISPATCH_NEXT					@ ldrb	r1, [jpc, #2]
-        add     r2, r2, #4
-	DISPATCH_NEXT					@ ldr	ip, [dispatch, r0, lsl #2]
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-	DISPATCH_NEXT					@ ldrb	r2, [jpc, #1]
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-	DISPATCH_NEXT					@ ands	lr, ip, lr
-        DISPATCH_FINISH
+
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
+
+	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	bl	return_check_monitors
 	b	2b
@@ -1956,33 +1879,14 @@
 	add	r1, r2, #4
 	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
 
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
-
 	POP	r2, r3
 
 	add	stack, r1, r0, lsl #2
 	stmdb	stack!, {r2, r3}
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-        DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-        DISPATCH_NEXT
-        add     r2, r2, #4
-        DISPATCH_NEXT
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-        DISPATCH_NEXT
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-        DISPATCH_NEXT
-        DISPATCH_FINISH
+
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
+
+	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	bl	return_check_monitors
 	b	2b
@@ -2032,12 +1936,10 @@
 	mov	r1, #0
         bl      _ZN18InterpreterRuntime3ldcEP10JavaThreadb
 	ldr	r0, [istate, #ISTATE_THREAD]			@ thread
-	ASSERT_STACK_CACHED
 	CACHE_CP
 	ldr	r1, [r0, #THREAD_PENDING_EXC]
 	CACHE_JPC
 	cmp	r1, #0
-	ASSERT_LOCALS_CACHED
 	bne	handle_exception
 	ldr	r3, [r0, #THREAD_VM_RESULT]
 	mov	r2, #0
@@ -2089,8 +1991,6 @@
         DECACHE_STACK
 	mov	r1, #1
         bl      _ZN18InterpreterRuntime3ldcEP10JavaThreadb
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]			@ thread
 	CACHE_CP
 	ldr	r1, [r0, #THREAD_PENDING_EXC]
@@ -2455,10 +2355,7 @@
 }
 
 (dmul) dmul_vfp {
-	FBC	cmp	r2, #opc_dadd
 	DISPATCH_START_R2
-	FBC	beq	1f
-2:
 	vldr	d7, [stack, #12]
 	vldr	d6, [stack, #4]
 	DISPATCH_NEXT
@@ -2469,30 +2366,7 @@
 	vstr	d0, [stack, #12]
 	add	stack, stack, #8
 	DISPATCH_FINISH
-1:
-	FBC	mov	r2, #opc_dmac
-	FBC	strb	r2, [jpc, #-1]
-	FBC	b	2b
-}
-
-#ifdef FAST_BYTECODES
-
-(dmac) dmac_vfp {
-	DISPATCH_START	\seq_len
-	vldr	d2, [stack, #20]
-	vldr	d1, [stack, #12]
-	vldr	d0, [stack, #4]
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	fmacd	d2, d1, d0
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	vstr	d2, [stack, #20]
-	add	stack, stack, #16
-	DISPATCH_FINISH
-}
-
-#endif // FAST_BYTECODES
+}
 
 (fdiv) fdiv_vfp {
 	DISPATCH_START_R2
@@ -2623,10 +2497,10 @@
 #ifdef FAST_BYTECODES
 
 @##############################################################################
-@ ECN: Optimised bytecode pairs
+@ Optimised bytecode pairs
 @##############################################################################
 
-@ --- ECN: load; iaccess ------------------------------------------------------
+@ --- load; iaccess ------------------------------------------------------
 
 (iload_0,iload_1,iload_2,iload_3)
 (iaccess_0,iaccess_1,iaccess_2,iaccess_3)
@@ -2680,7 +2554,7 @@
 	DISPATCH_FINISH
 }
 
-@ --- ECN: load; load ---------------------------------------------------------
+@ --- load; load ---------------------------------------------------------
 
 (aload_0,aload_1,aload_2,aload_3)
 (aload_0,aload_1,aload_2,aload_3)
@@ -2875,7 +2749,7 @@
 	DISPATCH_FINISH
 }
 
-@ --- ECN: load; store --------------------------------------------------------
+@ --- load; store --------------------------------------------------------
 
 (aload_0,aload_1,aload_2,aload_3)
 (astore_0,astore_1,astore_2,astore_3)
@@ -2986,7 +2860,7 @@
 	DISPATCH_FINISH
 }
 
-@ --- ECN: load; const -------------------------------------------------------
+@ --- load; const -------------------------------------------------------
 
 (aload_0,aload_1,aload_2,aload_3)
 (iconst_m1,iconst_0,iconst_1,iconst_2,iconst_3,iconst_4,iconst_5)
@@ -3109,7 +2983,7 @@
 	DISPATCH_FINISH
 }
 
-@ --- ECN: load; Xaload -------------------------------------------------------
+@ --- load; Xaload -------------------------------------------------------
 
 (iload_0,iload_1,iload_2,iload_3)
 (iaload,aaload,faload)
@@ -3271,7 +3145,7 @@
 	DISPATCH_FINISH
 }
 
-@ --- ECN: load; Xastore -------------------------------------------------------
+@ --- load; Xastore -------------------------------------------------------
 
 (iload_0,iload_1,iload_2,iload_3)
 (iastore,fastore)
@@ -3384,7 +3258,7 @@
 	DISPATCH_FINISH
 }
 
-@ --- ECN: load; dataop -------------------------------------------------------
+@ --- load; dataop -------------------------------------------------------
 
 (iload_0,iload_1,iload_2,iload_3)
 (iadd)
@@ -3472,40 +3346,6 @@
 }
 
 (iload_0,iload_1,iload_2,iload_3)
-(idiv)
-{
-	rsb	tmp2, r0, #opc_iload_0
-	DISPATCH_START	2
-	ldr	tmp2, [locals, tmp2, lsl #2]
-	POP	tmp1
-	b	int_div
-}
-
-(iload,aload,fload)(idiv) {
-	DISPATCH_START	3
-	POP	tmp1
-	ldr	tmp2, [locals, -r2, lsl #2]
-	b	int_div
-}
-
-(iload_0,iload_1,iload_2,iload_3)
-(irem)
-{
-	rsb	tmp2, r0, #opc_iload_0
-	DISPATCH_START	2
-	ldr	tmp2, [locals, tmp2, lsl #2]
-	POP	tmp1
-	b	int_rem
-}
-
-(iload,aload,fload)(irem) {
-	DISPATCH_START	3
-	POP	tmp1
-	ldr	tmp2, [locals, -r2, lsl #2]
-	b	int_rem
-}
-
-(iload_0,iload_1,iload_2,iload_3)
 (ineg)
 {
 	rsb	lr, r0, #opc_iload_0
@@ -3717,192 +3557,138 @@
 
 #ifdef NOTICE_SAFEPOINTS
 
-@ --- ECN: load; branch -------------------------------------------------------
+@ --- load; branch -------------------------------------------------------
 
 (iload_0,iload_1,iload_2,iload_3)
 (ifeq,ifnull)
 {
+	rsb	r3, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r3, [locals, r3, lsl #2]
         ldrb    ip, [jpc, #3]
-	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
-	ldr	r3, [locals, r3, lsl #2]
         cmp     r3, #0
-	orr	ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(ifeq,ifnull) {
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r3, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	add	jpc, jpc, #2
-	ldr	r3, [locals, -r2, lsl #2]
         cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
 (ifne,ifnonnull)
 {
+	rsb	r3, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r3, [locals, r3, lsl #2]
         ldrb    ip, [jpc, #3]
-	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
-	ldr	r3, [locals, r3, lsl #2]
         cmp     r3, #0
-	orr	ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(ifne,ifnonnull) {
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r3, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	add	jpc, jpc, #2
-	ldr	r3, [locals, -r2, lsl #2]
         cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
 (iflt)
 {
+	rsb	r3, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r3, [locals, r3, lsl #2]
         ldrb    ip, [jpc, #3]
-	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
-	ldr	r3, [locals, r3, lsl #2]
         cmp     r3, #0
-	orr	ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(iflt) {
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r3, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	add	jpc, jpc, #2
-	ldr	r3, [locals, -r2, lsl #2]
         cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
 (ifge)
 {
+	rsb	r3, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r3, [locals, r3, lsl #2]
         ldrb    ip, [jpc, #3]
-	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
-	ldr	r3, [locals, r3, lsl #2]
         cmp     r3, #0
-	orr	ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(ifge) {
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r3, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	add	jpc, jpc, #2
-	ldr	r3, [locals, -r2, lsl #2]
         cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
 (ifgt)
 {
+	rsb	r3, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r3, [locals, r3, lsl #2]
         ldrb    ip, [jpc, #3]
-	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
-	ldr	r3, [locals, r3, lsl #2]
         cmp     r3, #0
-	orr	ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(ifgt) {
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r3, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	add	jpc, jpc, #2
-	ldr	r3, [locals, -r2, lsl #2]
         cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
 (ifle)
 {
+	rsb	r3, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r3, [locals, r3, lsl #2]
         ldrb    ip, [jpc, #3]
-	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
-	ldr	r3, [locals, r3, lsl #2]
         cmp     r3, #0
-	orr	ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	ble	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(ifle) {
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r3, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	add	jpc, jpc, #2
-	ldr	r3, [locals, -r2, lsl #2]
         cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	ble	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
@@ -3911,31 +3697,22 @@
 	POP	r3
 	rsb	r2, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #3]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
         cmp     r3, r2
-	orr	ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(if_icmpeq,if_acmpeq) {
 	POP	r3
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	ldr	r2, [locals, -r2, lsl #2]
-	add	jpc, jpc, #2
         cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
@@ -3944,31 +3721,22 @@
 	POP	r3
 	rsb	r2, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #3]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
         cmp     r3, r2
-	orr	ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(if_icmpne,if_acmpne) {
 	POP	r3
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	ldr	r2, [locals, -r2, lsl #2]
-	add	jpc, jpc, #2
         cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
@@ -3977,31 +3745,22 @@
 	POP	r3
 	rsb	r2, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #3]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
         cmp     r3, r2
-	orr	ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(if_icmplt) {
 	POP	r3
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	ldr	r2, [locals, -r2, lsl #2]
-	add	jpc, jpc, #2
         cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
@@ -4010,31 +3769,22 @@
 	POP	r3
 	rsb	r2, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #3]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
         cmp     r3, r2
-	orr	ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(if_icmpge) {
 	POP	r3
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	ldr	r2, [locals, -r2, lsl #2]
-	add	jpc, jpc, #2
         cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
@@ -4043,31 +3793,22 @@
 	POP	r3
 	rsb	r2, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #3]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
         cmp     r3, r2
-	orr	ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(if_icmpgt) {
 	POP	r3
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	ldr	r2, [locals, -r2, lsl #2]
-	add	jpc, jpc, #2
         cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_0,iload_1,iload_2,iload_3)
@@ -4076,34 +3817,25 @@
 	POP	r3
 	rsb	r2, r0, #opc_iload_0
         ldrsb   r1, [jpc, #2]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #3]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
         cmp     r3, r2
-	orr	ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	ble	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iload,aload,fload)(if_icmple) {
 	POP	r3
+	rsb	r2, r2, #0
         ldrsb   r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
         ldrb    ip, [jpc, #4]
-	ldr	r2, [locals, -r2, lsl #2]
-	add	jpc, jpc, #2
         cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-@ --- ECN: load; return/invoke -------------------------------------------------
+	ble	branch_taken_unsafe_2
+	DISPATCH 5
+}
+
+@ --- load; return/invoke -------------------------------------------------
 
 (iload_0,iload_1,iload_2,iload_3)
 (ireturn,areturn,freturn)
@@ -4122,30 +3854,12 @@
 	ldr	r0, [istate, #ISTATE_METHOD]
 	ldr	r3, [stack, #0]
 	ldrh	r0, [r0, #40]
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
 	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
 	str	r1, [stack, r0, lsl #2]!
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-	DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	DISPATCH_NEXT					@ ldrb	r1, [jpc, #2]
-        add     r2, r2, #4
-	DISPATCH_NEXT					@ ldr	ip, [dispatch, r0, lsl #2]
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-	DISPATCH_NEXT					@ ldrb	r2, [jpc, #1]
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-	DISPATCH_NEXT					@ ands	lr, ip, lr
-        DISPATCH_FINISH
+
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
+
+	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	PUSH	r1
 	add	jpc, jpc, #1
@@ -4169,30 +3883,12 @@
 	ldr	r0, [istate, #ISTATE_METHOD]
 	ldr	r3, [stack, #0]
 	ldrh	r0, [r0, #40]
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
 	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
 	str	r1, [stack, r0, lsl #2]!
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-	DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	DISPATCH_NEXT					@ ldrb	r1, [jpc, #2]
-        add     r2, r2, #4
-	DISPATCH_NEXT					@ ldr	ip, [dispatch, r0, lsl #2]
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-	DISPATCH_NEXT					@ ldrb	r2, [jpc, #1]
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-	DISPATCH_NEXT					@ ands	lr, ip, lr
-        DISPATCH_FINISH
+
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
+
+	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	PUSH	r1
 	add	jpc, jpc, #2
@@ -4399,7 +4095,7 @@
 	DISPATCH_FINISH
 }
 
-@ --- ECN: iconst; store -------------------------------------------------
+@ --- iconst; store -------------------------------------------------
 
 (iconst_m1,iconst_0,iconst_1,iconst_2,iconst_3,iconst_4,iconst_5)
 (istore_0,istore_1,istore_2,istore_3)
@@ -4419,7 +4115,7 @@
 	DISPATCH_BYTECODE
 }
 
-@ --- ECN: iconst; dataop -------------------------------------------------
+@ --- iconst; dataop -------------------------------------------------
 
 (iconst_m1,iconst_0,iconst_1,iconst_2,iconst_3,iconst_4,iconst_5)(iadd) {
 	sub	tmp1, r0, #opc_iconst_0
@@ -4505,7 +4201,7 @@
 	DISPATCH_FINISH
 }
 
-@ --- ECN: iconst; branch -------------------------------------------------
+@ --- iconst; branch -------------------------------------------------
 
 #ifdef NOTICE_SAFEPOINTS
 
@@ -4513,90 +4209,60 @@
 	POP	r3
 	sub	r2, r0, #opc_iconst_0
         ldrsb   r1, [jpc, #2]
+        cmp     r3, r2
         ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iconst_m1,iconst_0,iconst_1,iconst_2,iconst_3,iconst_4,iconst_5)(if_icmpne) {
 	POP	r3
 	sub	r2, r0, #opc_iconst_0
         ldrsb   r1, [jpc, #2]
+        cmp     r3, r2
         ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iconst_m1,iconst_0,iconst_1,iconst_2,iconst_3,iconst_4,iconst_5)(if_icmplt) {
 	POP	r3
 	sub	r2, r0, #opc_iconst_0
         ldrsb   r1, [jpc, #2]
+        cmp     r3, r2
         ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iconst_m1,iconst_0,iconst_1,iconst_2,iconst_3,iconst_4,iconst_5)(if_icmpge) {
 	POP	r3
 	sub	r2, r0, #opc_iconst_0
         ldrsb   r1, [jpc, #2]
+        cmp     r3, r2
         ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iconst_m1,iconst_0,iconst_1,iconst_2,iconst_3,iconst_4,iconst_5)(if_icmpgt) {
 	POP	r3
 	sub	r2, r0, #opc_iconst_0
         ldrsb   r1, [jpc, #2]
+        cmp     r3, r2
         ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iconst_m1,iconst_0,iconst_1,iconst_2,iconst_3,iconst_4,iconst_5)(if_icmple) {
 	POP	r3
 	sub	r2, r0, #opc_iconst_0
         ldrsb   r1, [jpc, #2]
+        cmp     r3, r2
         ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	ble	branch_taken_unsafe_1
+	DISPATCH 4
 }
 
 (iconst_m1,iconst_0,iconst_1,iconst_2,iconst_3,iconst_4,iconst_5)(ireturn) {
@@ -4613,30 +4279,12 @@
 	ldr	r0, [istate, #ISTATE_METHOD]
 	ldr	r3, [stack, #0]
 	ldrh	r0, [r0, #40]
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
 	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
 	str	r1, [stack, r0, lsl #2]!
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-	DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	DISPATCH_NEXT					@ ldrb	r1, [jpc, #2]
-        add     r2, r2, #4
-	DISPATCH_NEXT					@ ldr	ip, [dispatch, r0, lsl #2]
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-	DISPATCH_NEXT					@ ldrb	r2, [jpc, #1]
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-	DISPATCH_NEXT					@ ands	lr, ip, lr
-        DISPATCH_FINISH
+
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
+
+	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	PUSH	r1
 	add	jpc, jpc, #1
@@ -5001,292 +4649,6 @@
 	DISPATCH_FINISH
 }
 
-#ifdef NOTICE_SAFEPOINTS
-
-(iaload,faload,aaload)(ifeq,ifnull) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry61:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r3, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(ifne,ifnonnull) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry62:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r3, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(iflt) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry63:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r3, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(ifge) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry64:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r3, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(ifgt) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry65:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r3, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(ifle) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry66:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r3, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(if_icmpeq,if_acmpeq) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry67:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r2, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-	POP	r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(if_icmpne,if_acmpne) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry68:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r2, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-	POP	r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(if_icmplt) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry69:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r2, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-	POP	r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(if_icmpge) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry70:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r2, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-	POP	r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(if_icmpgt) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry71:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r2, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-	POP	r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaload,faload,aaload)(if_icmple) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_0
-.abortentry72:
-	ldr	r1, [r3, #8]		@ r1 = length
-	cmp	r2, r1
-	bcs	array_bound_exception_jpc_0
-	add	r3, r3, r2, lsl #2
-	ldr	r2, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
-
-	POP	r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-        cmp     r3, r2
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-#endif // NOTICE_SAFEPOINTS
-
 @ ---- iadd; xxx ------------------------------------------------------------
 
 (iadd)(iload,fload,aload) {
@@ -5395,255 +4757,11 @@
 	DISPATCH_FINISH
 }
 
-#ifdef NOTICE_SAFEPOINTS
-
-(iadd)(ifeq,ifnull) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(ifne,ifnonnull) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(iflt) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(ifge) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(ifgt) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(ifle) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(if_icmpeq,if_acmpeq) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(if_icmpne,if_acmpne) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(if_icmplt) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(if_icmpge) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(if_icmpgt) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(if_icmple) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iadd)(goto) {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-	orr	ip, ip, r1, lsl #8
-	DISPATCH_START_REG	ip
-	POP	r2, r3
-	add	r2, r3, r2
-	DISPATCH_NEXT
-	PUSH	r2
-	DISPATCH_FINISH
-}
-
-(iadd)(ireturn) {
-	POP	r2, r3
-	ldr	tmp2, [istate, #ISTATE_MONITOR_BASE]	@ tmp2 = base
-	ldr	tmp1, [istate, #ISTATE_STACK_BASE]	@ tmp1 = end
-	add	r1, r3, r2
-	ldr	tmp_xxx, [istate, #ISTATE_THREAD]
-	cmp	tmp1, tmp2
-	bcc	1f
-2:
-	mov	r3, #0
-	ldr	stack, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	str	r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-	ldr	r0, [istate, #ISTATE_METHOD]
-	ldr	r3, [stack, #0]
-	ldrh	r0, [r0, #40]
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
-	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	str	r1, [stack, r0, lsl #2]!
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-	DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	DISPATCH_NEXT					@ ldrb	r1, [jpc, #2]
-        add     r2, r2, #4
-	DISPATCH_NEXT					@ ldr	ip, [dispatch, r0, lsl #2]
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-	DISPATCH_NEXT					@ ldrb	r2, [jpc, #1]
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-	DISPATCH_NEXT					@ ands	lr, ip, lr
-        DISPATCH_FINISH
-1:
-	PUSH	r1
-	add	jpc, jpc, #1
-	bl	return_check_monitors
-	POP	r1
-	b	2b
-}
-
-#endif // NOTICE_SAFEPOINTS
-
 (iadd)(iinc) {
 	POP	tmp1, lr
 	DISPATCH_START	\seq_len
 	add	tmp1, lr, tmp1
-        ldrb    r3, [jpc, #-2]	@ ECN: jpc now points to next bc
+        ldrb    r3, [jpc, #-2]	@ jpc now points to next bc
         ldrsb   r2, [jpc, #-1]
 	DISPATCH_NEXT
 	PUSH	tmp1
@@ -5761,255 +4879,11 @@
 	DISPATCH_FINISH
 }
 
-#ifdef NOTICE_SAFEPOINTS
-
-(isub)(ifeq,ifnull) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(ifne,ifnonnull) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(iflt) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(ifge) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(ifgt) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(ifle) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(if_icmpeq,if_acmpeq) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(if_icmpne,if_acmpne) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(if_icmplt) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(if_icmpge) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(if_icmpgt) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(if_icmple) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	sub	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(isub)(goto) {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-	orr	ip, ip, r1, lsl #8
-	DISPATCH_START_REG	ip
-	POP	r2, r3
-	sub	r2, r3, r2
-	DISPATCH_NEXT
-	PUSH	r2
-	DISPATCH_FINISH
-}
-
-(isub)(ireturn) {
-	POP	r2, r3
-	ldr	tmp2, [istate, #ISTATE_MONITOR_BASE]	@ tmp2 = base
-	ldr	tmp1, [istate, #ISTATE_STACK_BASE]	@ tmp1 = end
-	sub	r1, r3, r2
-	ldr	tmp_xxx, [istate, #ISTATE_THREAD]
-	cmp	tmp1, tmp2
-	bcc	1f
-2:
-	mov	r3, #0
-	ldr	stack, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	str	r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-	ldr	r0, [istate, #ISTATE_METHOD]
-	ldr	r3, [stack, #0]
-	ldrh	r0, [r0, #40]
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
-	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	str	r1, [stack, r0, lsl #2]!
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-	DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	DISPATCH_NEXT					@ ldrb	r1, [jpc, #2]
-        add     r2, r2, #4
-	DISPATCH_NEXT					@ ldr	ip, [dispatch, r0, lsl #2]
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-	DISPATCH_NEXT					@ ldrb	r2, [jpc, #1]
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-	DISPATCH_NEXT					@ ands	lr, ip, lr
-        DISPATCH_FINISH
-1:
-	PUSH	r1
-	add	jpc, jpc, #1
-	bl	return_check_monitors
-	POP	r1
-	b	2b
-}
-
-#endif // NOTICE_SAFEPOINTS
-
 (isub)(iinc) {
 	POP	tmp1, lr
 	DISPATCH_START	\seq_len
 	sub	tmp1, lr, tmp1
-        ldrb    r3, [jpc, #-2]	@ ECN: jpc now points to next bc
+        ldrb    r3, [jpc, #-2]	@ jpc now points to next bc
         ldrsb   r2, [jpc, #-1]
 	DISPATCH_NEXT
 	PUSH	tmp1
@@ -6127,255 +5001,11 @@
 	DISPATCH_FINISH
 }
 
-#ifdef NOTICE_SAFEPOINTS
-
-(iand)(ifeq,ifnull) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(ifne,ifnonnull) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(iflt) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(ifge) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(ifgt) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(ifle) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(if_icmpeq,if_acmpeq) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(if_icmpne,if_acmpne) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(if_icmplt) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(if_icmpge) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(if_icmpgt) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(if_icmple) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	and	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iand)(goto) {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-	orr	ip, ip, r1, lsl #8
-	DISPATCH_START_REG	ip
-	POP	r2, r3
-	and	r2, r3, r2
-	DISPATCH_NEXT
-	PUSH	r2
-	DISPATCH_FINISH
-}
-
-(iand)(ireturn) {
-	POP	r2, r3
-	ldr	tmp2, [istate, #ISTATE_MONITOR_BASE]	@ tmp2 = base
-	ldr	tmp1, [istate, #ISTATE_STACK_BASE]	@ tmp1 = end
-	and	r1, r3, r2
-	ldr	tmp_xxx, [istate, #ISTATE_THREAD]
-	cmp	tmp1, tmp2
-	bcc	1f
-2:
-	mov	r3, #0
-	ldr	stack, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	str	r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-	ldr	r0, [istate, #ISTATE_METHOD]
-	ldr	r3, [stack, #0]
-	ldrh	r0, [r0, #40]
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
-	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	str	r1, [stack, r0, lsl #2]!
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-	DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	DISPATCH_NEXT					@ ldrb	r1, [jpc, #2]
-        add     r2, r2, #4
-	DISPATCH_NEXT					@ ldr	ip, [dispatch, r0, lsl #2]
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-	DISPATCH_NEXT					@ ldrb	r2, [jpc, #1]
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-	DISPATCH_NEXT					@ ands	lr, ip, lr
-        DISPATCH_FINISH
-1:
-	PUSH	r1
-	add	jpc, jpc, #1
-	bl	return_check_monitors
-	POP	r1
-	b	2b
-}
-
-#endif // NOTICE_SAFEPOINTS
-
 (iand)(iinc) {
 	POP	tmp1, lr
 	DISPATCH_START	\seq_len
 	and	tmp1, lr, tmp1
-        ldrb    r3, [jpc, #-2]	@ ECN: jpc now points to next bc
+        ldrb    r3, [jpc, #-2]	@ jpc now points to next bc
         ldrsb   r2, [jpc, #-1]
 	DISPATCH_NEXT
 	PUSH	tmp1
@@ -6493,255 +5123,11 @@
 	DISPATCH_FINISH
 }
 
-#ifdef NOTICE_SAFEPOINTS
-
-(ior)(ifeq,ifnull) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(ifne,ifnonnull) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(iflt) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(ifge) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(ifgt) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(ifle) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(if_icmpeq,if_acmpeq) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(if_icmpne,if_acmpne) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(if_icmplt) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(if_icmpge) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(if_icmpgt) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(if_icmple) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	orr	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ior)(goto) {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-	orr	ip, ip, r1, lsl #8
-	DISPATCH_START_REG	ip
-	POP	r2, r3
-	orr	r2, r3, r2
-	DISPATCH_NEXT
-	PUSH	r2
-	DISPATCH_FINISH
-}
-
-(ior)(ireturn) {
-	POP	r2, r3
-	ldr	tmp2, [istate, #ISTATE_MONITOR_BASE]	@ tmp2 = base
-	ldr	tmp1, [istate, #ISTATE_STACK_BASE]	@ tmp1 = end
-	orr	r1, r3, r2
-	ldr	tmp_xxx, [istate, #ISTATE_THREAD]
-	cmp	tmp1, tmp2
-	bcc	1f
-2:
-	mov	r3, #0
-	ldr	stack, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	str	r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-	ldr	r0, [istate, #ISTATE_METHOD]
-	ldr	r3, [stack, #0]
-	ldrh	r0, [r0, #40]
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
-	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	str	r1, [stack, r0, lsl #2]!
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-	DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	DISPATCH_NEXT					@ ldrb	r1, [jpc, #2]
-        add     r2, r2, #4
-	DISPATCH_NEXT					@ ldr	ip, [dispatch, r0, lsl #2]
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-	DISPATCH_NEXT					@ ldrb	r2, [jpc, #1]
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-	DISPATCH_NEXT					@ ands	lr, ip, lr
-        DISPATCH_FINISH
-1:
-	PUSH	r1
-	add	jpc, jpc, #1
-	bl	return_check_monitors
-	POP	r1
-	b	2b
-}
-
-#endif // NOTICE_SAFEPOINTS
-
 (ior)(iinc) {
 	POP	tmp1, lr
 	DISPATCH_START	\seq_len
 	orr	tmp1, lr, tmp1
-        ldrb    r3, [jpc, #-2]	@ ECN: jpc now points to next bc
+        ldrb    r3, [jpc, #-2]	@ jpc now points to next bc
         ldrsb   r2, [jpc, #-1]
 	DISPATCH_NEXT
 	PUSH	tmp1
@@ -6844,7 +5230,7 @@
 	DISPATCH_NEXT
 	DISPATCH_NEXT
 	PUSH	tmp2
-	DISPATCH_FINISH
+        DISPATCH_FINISH
 }
 
 (ixor)(isub) {
@@ -6860,255 +5246,11 @@
 	DISPATCH_FINISH
 }
 
-#ifdef NOTICE_SAFEPOINTS
-
-(ixor)(ifeq,ifnull) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(ifne,ifnonnull) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(iflt) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(ifge) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(ifgt) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(ifle) {
-	POP	r2, r3
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r3, r3, r2
-	add	jpc, jpc, #1
-        cmp     r3, #0
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(if_icmpeq,if_acmpeq) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(if_icmpne,if_acmpne) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(if_icmplt) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(if_icmpge) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(if_icmpgt) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(if_icmple) {
-	POP	r2, r3, lr
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	eor	r2, r3, r2
-	add	jpc, jpc, #1
-        cmp     lr, r2
-        orr     ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-        ldrb    r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(ixor)(goto) {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-	orr	ip, ip, r1, lsl #8
-	DISPATCH_START_REG	ip
-	POP	r2, r3
-	eor	r2, r3, r2
-	DISPATCH_NEXT
-	PUSH	r2
-	DISPATCH_FINISH
-}
-
-(ixor)(ireturn) {
-	POP	r2, r3
-	ldr	tmp2, [istate, #ISTATE_MONITOR_BASE]	@ tmp2 = base
-	ldr	tmp1, [istate, #ISTATE_STACK_BASE]	@ tmp1 = end
-	eor	r1, r3, r2
-	ldr	tmp_xxx, [istate, #ISTATE_THREAD]
-	cmp	tmp1, tmp2
-	bcc	1f
-2:
-	mov	r3, #0
-	ldr	stack, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	str	r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-	ldr	r0, [istate, #ISTATE_METHOD]
-	ldr	r3, [stack, #0]
-	ldrh	r0, [r0, #40]
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
-	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	str	r1, [stack, r0, lsl #2]!
-	cmp	ip, #0
-	beq	normal_return
-
-	sub	istate, istate, #ISTATE_NEXT_FRAME
-
-        CACHE_JPC
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-	DISPATCH_START_REG ip
-        sub     stack, stack, #4
-        ldr     r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
-	DISPATCH_NEXT					@ ldrb	r1, [jpc, #2]
-        add     r2, r2, #4
-	DISPATCH_NEXT					@ ldr	ip, [dispatch, r0, lsl #2]
-        str     r2, [tmp_xxx, #THREAD_JAVA_SP]
-	DISPATCH_NEXT					@ ldrb	r2, [jpc, #1]
-        str     r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
-        CACHE_CP
-        CACHE_LOCALS
-	DISPATCH_NEXT					@ ands	lr, ip, lr
-        DISPATCH_FINISH
-1:
-	PUSH	r1
-	add	jpc, jpc, #1
-	bl	return_check_monitors
-	POP	r1
-	b	2b
-}
-
-#endif // NOTICE_SAFEPOINTS
-
 (ixor)(iinc) {
 	POP	tmp1, lr
 	DISPATCH_START	\seq_len
 	eor	tmp1, lr, tmp1
-        ldrb    r3, [jpc, #-2]	@ ECN: jpc now points to next bc
+        ldrb    r3, [jpc, #-2]	@ jpc now points to next bc
         ldrsb   r2, [jpc, #-1]
 	DISPATCH_NEXT
 	PUSH	tmp1
@@ -7175,7 +5317,7 @@
 }
 
 @###############################################################################
-@# ECN: Optimised bytecode triples
+@# Optimised bytecode triples
 @###############################################################################
 
 (iaccess_0,iaccess_1,iaccess_2,iaccess_3)
@@ -7251,316 +5393,6 @@
 	DISPATCH_FINISH
 }
 
-#ifdef NOTICE_SAFEPOINTS
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(ifeq,ifnull) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	orr	ip, ip, r0, lsl #8
-.abortentry92:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	tmp2, #0
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(ifne,ifnonnull) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	orr	ip, ip, r0, lsl #8
-.abortentry93:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	tmp2, #0
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(iflt) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	orr	ip, ip, r0, lsl #8
-.abortentry94:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	tmp2, #0
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(ifge) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	orr	ip, ip, r0, lsl #8
-.abortentry95:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	tmp2, #0
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(ifgt) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	orr	ip, ip, r0, lsl #8
-.abortentry96:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	tmp2, #0
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(ifle) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	orr	ip, ip, r0, lsl #8
-.abortentry97:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	tmp2, #0
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(if_icmpeq,if_acmpeq) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	POP	r3
-	orr	ip, ip, r0, lsl #8
-.abortentry98:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	r3, tmp2
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(if_icmpne,if_acmpne) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	POP	r3
-	orr	ip, ip, r0, lsl #8
-.abortentry99:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	r3, tmp2
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(if_icmplt) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	POP	r3
-	orr	ip, ip, r0, lsl #8
-.abortentry100:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	r3, tmp2
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(if_icmpge) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	POP	r3
-	orr	ip, ip, r0, lsl #8
-.abortentry101:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	r3, tmp2
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(if_icmpgt) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	POP	r3
-	orr	ip, ip, r0, lsl #8
-.abortentry102:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	r3, tmp2
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-(iaccess_0,iaccess_1,iaccess_2,iaccess_3)
-(if_icmple) {
-	ldrb	r2, [jpc, #3]
-	rsb	tmp1, r0, #opc_iaccess_0
-	ldrb	ip, [jpc, #2]
-	add	jpc, jpc, #4
-	ldrsb	r0, [jpc, #1]
-	add	tmp2, constpool, r2, lsl #12
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	POP	r3
-	orr	ip, ip, r0, lsl #8
-.abortentry103:
-	ldr	tmp2, [tmp1, tmp2]
-	cmp	r3, tmp2
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-#endif // NOTICE_SAFEPOINTS
-
 (iload_0_iconst_N,iload_1_iconst_N,iload_2_iconst_N,iload_3_iconst_N)
 (iadd)
 {
@@ -8564,23 +6396,20 @@
 	DISPATCH_FINISH
 }
 
+#ifdef NOTICE_SAFEPOINTS
+
 (iload_0_iconst_N,iload_1_iconst_N,iload_2_iconst_N,iload_3_iconst_N)
 (if_icmpeq,if_acmpeq)
 {
 	ldrb	r3, [jpc, #1]
 	rsb	r2, r0, #opc_iload_0_iconst_N
 	ldrsb	r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_iconst_N)
@@ -8589,17 +6418,12 @@
 	ldrb	r3, [jpc, #2]
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #5]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #3
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iconst_N,iload_1_iconst_N,iload_2_iconst_N,iload_3_iconst_N)
@@ -8608,17 +6432,12 @@
 	ldrb	r3, [jpc, #1]
 	rsb	r2, r0, #opc_iload_0_iconst_N
 	ldrsb	r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_iconst_N)
@@ -8627,17 +6446,12 @@
 	ldrb	r3, [jpc, #2]
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #5]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #3
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iconst_N,iload_1_iconst_N,iload_2_iconst_N,iload_3_iconst_N)
@@ -8646,17 +6460,12 @@
 	ldrb	r3, [jpc, #1]
 	rsb	r2, r0, #opc_iload_0_iconst_N
 	ldrsb	r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_iconst_N)
@@ -8665,17 +6474,12 @@
 	ldrb	r3, [jpc, #2]
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #5]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #3
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iconst_N,iload_1_iconst_N,iload_2_iconst_N,iload_3_iconst_N)
@@ -8684,17 +6488,12 @@
 	ldrb	r3, [jpc, #1]
 	rsb	r2, r0, #opc_iload_0_iconst_N
 	ldrsb	r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_iconst_N)
@@ -8703,17 +6502,12 @@
 	ldrb	r3, [jpc, #2]
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #5]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #3
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iconst_N,iload_1_iconst_N,iload_2_iconst_N,iload_3_iconst_N)
@@ -8722,17 +6516,12 @@
 	ldrb	r3, [jpc, #1]
 	rsb	r2, r0, #opc_iload_0_iconst_N
 	ldrsb	r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_iconst_N)
@@ -8741,17 +6530,12 @@
 	ldrb	r3, [jpc, #2]
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #5]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #3
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iconst_N,iload_1_iconst_N,iload_2_iconst_N,iload_3_iconst_N)
@@ -8760,17 +6544,12 @@
 	ldrb	r3, [jpc, #1]
 	rsb	r2, r0, #opc_iload_0_iconst_N
 	ldrsb	r1, [jpc, #3]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	ble	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_iconst_N)
@@ -8779,18 +6558,15 @@
 	ldrb	r3, [jpc, #2]
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
+	ldr	r2, [locals, r2, lsl #2]
 	sub	r3, r3, #opc_iconst_0
 	ldrb	ip, [jpc, #5]
-	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #3
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
+	ble	branch_taken_unsafe_3
+	DISPATCH 6
+}
+
+#endif // NOTICE_SAFEPOINTS
 
 (iload_iload)
 (iadd_istore_N)
@@ -9582,23 +7358,20 @@
 	DISPATCH_FINISH
 }
 
+#ifdef NOTICE_SAFEPOINTS
+
 (iload_iload)
 (if_icmpeq,if_acmpeq) {
 	ldrb	r3, [jpc, #3]
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #5]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #6]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #4
+	ldrb	ip, [jpc, #6]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe_4
+	DISPATCH 7
 }
 
 (iload_iload_N)
@@ -9607,17 +7380,12 @@
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #opc_iload_0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload,iload_1_iload,iload_2_iload,iload_3_iload)
@@ -9626,35 +7394,39 @@
 	rsb	r2, r0, #opc_iload_0_iload
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	beq	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload_N,iload_1_iload_N,iload_2_iload_N,iload_3_iload_N)
 (if_icmpeq,if_acmpeq) {
 	rsb	r3, r2, #opc_iload_0
+	ldrsb	r1, [jpc, #3]
 	rsb	r2, r0, #opc_iload_0_iload_N
-	ldrsb	r1, [jpc, #3]
+	ldr	r3, [locals, r3, lsl #2]
+	ldr	r2, [locals, r2, lsl #2]
 	ldrb	ip, [jpc, #4]
+	cmp	r2, r3
+	beq	branch_taken_unsafe_2
+	DISPATCH 5
+}
+
+(iload_iload)
+(if_icmpne,if_acmpne) {
+	ldrb	r3, [jpc, #3]
+	rsb	r2, r2, #0
+	ldrsb	r1, [jpc, #5]
+	rsb	r3, r3, #0
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
+	ldrb	ip, [jpc, #6]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	beq	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_4
+	DISPATCH 7
 }
 
 (iload_iload_N)
@@ -9663,17 +7435,12 @@
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #opc_iload_0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload,iload_1_iload,iload_2_iload,iload_3_iload)
@@ -9682,35 +7449,25 @@
 	rsb	r2, r0, #opc_iload_0_iload
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload_N,iload_1_iload_N,iload_2_iload_N,iload_3_iload_N)
 (if_icmpne,if_acmpne) {
 	rsb	r3, r2, #opc_iload_0
+	ldrsb	r1, [jpc, #3]
 	rsb	r2, r0, #opc_iload_0_iload_N
-	ldrsb	r1, [jpc, #3]
+	ldr	r3, [locals, r3, lsl #2]
+	ldr	r2, [locals, r2, lsl #2]
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bne	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bne	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_iload)
@@ -9719,17 +7476,12 @@
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #5]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #6]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #4
+	ldrb	ip, [jpc, #6]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_4
+	DISPATCH 7
 }
 
 (iload_iload_N)
@@ -9738,17 +7490,12 @@
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #opc_iload_0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload,iload_1_iload,iload_2_iload,iload_3_iload)
@@ -9757,35 +7504,25 @@
 	rsb	r2, r0, #opc_iload_0_iload
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload_N,iload_1_iload_N,iload_2_iload_N,iload_3_iload_N)
 (if_icmplt) {
 	rsb	r3, r2, #opc_iload_0
+	ldrsb	r1, [jpc, #3]
 	rsb	r2, r0, #opc_iload_0_iload_N
-	ldrsb	r1, [jpc, #3]
+	ldr	r3, [locals, r3, lsl #2]
+	ldr	r2, [locals, r2, lsl #2]
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	blt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	blt	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_iload)
@@ -9794,17 +7531,12 @@
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #5]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #6]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #4
+	ldrb	ip, [jpc, #6]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_4
+	DISPATCH 7
 }
 
 (iload_iload_N)
@@ -9813,17 +7545,12 @@
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #opc_iload_0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload,iload_1_iload,iload_2_iload,iload_3_iload)
@@ -9832,35 +7559,25 @@
 	rsb	r2, r0, #opc_iload_0_iload
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload_N,iload_1_iload_N,iload_2_iload_N,iload_3_iload_N)
 (if_icmpge) {
 	rsb	r3, r2, #opc_iload_0
+	ldrsb	r1, [jpc, #3]
 	rsb	r2, r0, #opc_iload_0_iload_N
-	ldrsb	r1, [jpc, #3]
+	ldr	r3, [locals, r3, lsl #2]
+	ldr	r2, [locals, r2, lsl #2]
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bge	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bge	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_iload)
@@ -9869,17 +7586,12 @@
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #5]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #6]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #4
+	ldrb	ip, [jpc, #6]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_4
+	DISPATCH 7
 }
 
 (iload_iload_N)
@@ -9888,17 +7600,12 @@
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #opc_iload_0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload,iload_1_iload,iload_2_iload,iload_3_iload)
@@ -9907,35 +7614,25 @@
 	rsb	r2, r0, #opc_iload_0_iload
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload_N,iload_1_iload_N,iload_2_iload_N,iload_3_iload_N)
 (if_icmpgt) {
 	rsb	r3, r2, #opc_iload_0
+	ldrsb	r1, [jpc, #3]
 	rsb	r2, r0, #opc_iload_0_iload_N
-	ldrsb	r1, [jpc, #3]
+	ldr	r3, [locals, r3, lsl #2]
+	ldr	r2, [locals, r2, lsl #2]
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	bgt	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	bgt	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
 (iload_iload)
@@ -9944,17 +7641,12 @@
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #5]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #6]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #4
+	ldrb	ip, [jpc, #6]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	ble	branch_taken_unsafe_4
+	DISPATCH 7
 }
 
 (iload_iload_N)
@@ -9963,17 +7655,12 @@
 	rsb	r2, r2, #0
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #opc_iload_0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	ble	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload,iload_1_iload,iload_2_iload,iload_3_iload)
@@ -9982,63 +7669,27 @@
 	rsb	r2, r0, #opc_iload_0_iload
 	ldrsb	r1, [jpc, #4]
 	rsb	r3, r3, #0
-	ldrb	ip, [jpc, #5]
 	ldr	r2, [locals, r2, lsl #2]
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #3
+	ldrb	ip, [jpc, #5]
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	ble	branch_taken_unsafe_3
+	DISPATCH 6
 }
 
 (iload_0_iload_N,iload_1_iload_N,iload_2_iload_N,iload_3_iload_N)
 (if_icmple) {
 	rsb	r3, r2, #opc_iload_0
+	ldrsb	r1, [jpc, #3]
 	rsb	r2, r0, #opc_iload_0_iload_N
-	ldrsb	r1, [jpc, #3]
+	ldr	r3, [locals, r3, lsl #2]
+	ldr	r2, [locals, r2, lsl #2]
 	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
-	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
 	cmp	r2, r3
-	orr	ip, ip, r1, lsl #8
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
-}
-
-#ifdef HW_FP
-
-(dmac)(dastore) {
-	ldr	tmp2, [stack, #28]
-	ldr	tmp1, [stack, #32]
-	vldr	d2, [stack, #20]
-	vldr	d1, [stack, #12]
-	vldr	d0, [stack, #4]
-	DISPATCH_START	\seq_len
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception
-.abortentry120:
-	ldr	ip, [tmp1, #8]
-	cmp	tmp2, ip
-	DISPATCH_NEXT
-	bcs	array_bound_exception_jpc_1_tmp2
-	DISPATCH_NEXT
-	add	tmp2, tmp1, tmp2, lsl #3
-	fmacd	d2, d1, d0
-	vstr	d2, [tmp2, #BASE_OFFSET_LONG]
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	add	stack, stack, #32
-	DISPATCH_FINISH
-}
-
-#endif //HW_FP
+	ble	branch_taken_unsafe_2
+	DISPATCH 5
+}
+
+#endif
 
 #endif // FAST_BYTECODES
--- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	Thu Jan 21 02:04:50 2010 +0000
+++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	Thu Jan 28 16:34:49 2010 +0000
@@ -19,15 +19,21 @@
 
 #define ARMv4
 
-#ifdef SHARK
+#if defined(SHARK) || defined(THUMB2EE)
+
 #define USE_COMPILER
-#define DISABLE_NOTICE_SAFEPOINTS
+
 #endif
 
 #ifdef USE_COMPILER
 
+#ifdef SHARK
 #define MP_COMPILE_THRESHOLD    0x10000         // 65536 - must be a single MOV constant
 #define UP_COMPILE_THRESHOLD    0x30000         // 196608 - must be a single MOV constant
+#else
+#define MP_COMPILE_THRESHOLD    0x2700		// 10000 - must be a single MOV constant
+#define UP_COMPILE_THRESHOLD    0x2700		// 10000 - must be a single MOV constant
+#endif
 
 #define MAX_FG_METHOD_SIZE      500
 
@@ -38,6 +44,12 @@
 #define DISABLE_BG_COMP_ON_NON_MP
 #endif
 
+#ifdef THUMB2EE
+#define FREQ_COUNT_OVERFLOW Thumb2_Compile
+#else
+#define FREQ_COUNT_OVERFLOW _ZN18InterpreterRuntime26frequency_counter_overflowEP10JavaThreadPh
+#endif
+
 #endif // USE_COMPILER
 
 #ifndef DISABLE_NOTICE_SAFEPOINTS
@@ -46,12 +58,6 @@
 #ifndef DISABLE_HW_NULL_PTR_CHECK
 #define HW_NULL_PTR_CHECK
 #endif
-#ifndef DISABLE_FASTPATH_ENTRY
-#define FASTPATH_ENTRY
-#endif
-#ifndef DISABLE_NATIVE_ENTRY
-#define NATIVE_ENTRY
-#endif
 #ifndef DISABLE_FAST_BYTECODES
 #define FAST_BYTECODES
 #endif
@@ -74,67 +80,25 @@
 #define tmp1		r11
 #define tmp2		r10
 
-#define tmp_invoke_len	lr
-
-#define regset r3-r11
-
-// XXX hardwired constants!
-#define tos_btos        0
-#define tos_ctos        1
-#define tos_stos        2
-#define tos_itos        3
-#define tos_ltos        4
-#define tos_ftos        5
-#define tos_dtos        6
-#define tos_atos        7
+#define regset		r4,r5,r6,r7,r9,r10,r11
+#define fast_regset	r8
 
 #include "offsets_arm.s"
 
-// XXX hardwired constants!
-#define RESOURCEAREA_AREA	0
-#define RESOURCEAREA_CHUNK	4
-#define RESOURCEAREA_HWM	8
-#define RESOURCEAREA_MAX	12
-
-// XXX hardwired constants!
-#define ISTATE_THREAD		0
-#define ISTATE_BCP		4
-#define	ISTATE_LOCALS		8
-#define	ISTATE_CONSTANTS	12
-#define ISTATE_METHOD		16
-#define ISTATE_MDX		20
-#define ISTATE_STACK		24
-#define ISTATE_ADVANCE_PC	28
-#define ISTATE_MSG		28
-#define ISTATE_CALLEE		32	// union frame_manager_message
-#define	ISTATE_PREV_LINK	44
-#define ISTATE_OOP_TEMP		48
-#define ISTATE_STACK_BASE	52
-#define ISTATE_STACK_LIMIT	56
-#define ISTATE_MONITOR_BASE	60
-#define ISTATE_SELF_LINK	64
-#define ISTATE_FRAME_TYPE	68
-#define ISTATE_NEXT_FRAME	72
-#define FRAME_SIZE		76
-
-// XXX hardwired constants!
-#define ENTRY_FRAME             1
-#define INTERPRETER_FRAME       2
-#define SHARK_FRAME             3
-#define FAKE_STUB_FRAME         4
-
 #define last_implemented_bytecode 201
 
+#define CODE_ALIGN_SIZE 64
+
 	.macro	ALIGN_CODE
-	.align	3
+	.align	6
 	.endm
 
 	.macro	ALIGN_DATA
-	.align	3
+	.align	6
 	.endm
 
 	.macro	ALIGN_OPCODE
-	.align	3
+	.align	6
 	.endm
 
 	.macro	ALIGN_WORD
@@ -276,6 +240,24 @@
   .endif
 #endif
         .endm
+@------------------------------------------------
+@ THUMB2 specific code macro
+@ Usage:
+@	T2	<thumb2 specific code>
+@------------------------------------------------
+	.macro	T2	p1, p2, p3, p4
+#ifdef THUMB2EE
+  .ifnes "\p4", ""
+        \p1 \p2, \p3, \p4
+  .else
+    .ifnes "\p3", ""
+        \p1 \p2, \p3
+    .else
+        \p1 \p2
+    .endif
+  .endif
+#endif
+        .endm
 
 	.macro	Opcode	label
 	ALIGN_OPCODE
@@ -290,6 +272,7 @@
 	str	\reg, [stack, #(\offset+1) * 4]
 	.endm
 
+#define PUSH	java_push
 	.macro	PUSH	reg1, reg2, reg3, reg4
   .ifnes "\reg4", ""
 	stmda	stack!, {\reg1, \reg2, \reg3, \reg4}
@@ -306,6 +289,7 @@
   .endif
 	.endm
 
+#define POP	java_pop
 	.macro	POP	reg1, reg2, reg3, reg4
   .ifnes "\reg4", ""
 	ldmib	stack!, {\reg1, \reg2, \reg3, \reg4}
@@ -346,227 +330,6 @@
 	str	jpc, [istate, #ISTATE_BCP]
 	.endm
 
-@ ECN:	I assert that istate->locals and istate->stack cannot move on a GC.
-@	The reasoning is that istate itself is stored on the Java stack
-@	and locals and stack are relative to istate. Therefore if locals or
-@	stack were to move, istate itself would have to move and we would
-@	lose our entire interpreter state.
-@ To prove this I have changed the code which recaches locals and stack
-@ to assert that locals == istate->locals and stack == istate->stack.
-@ This saves a lot of needles recaching of interpreter state.
-	.macro	ASSERT_LOCALS_CACHED
-#if 0
-	str	ip, [arm_sp, #-4]!
-	mrs	ip, cpsr
-	str	ip, [arm_sp, #-4]!
-	mov	ip, locals
-	ldr	locals, [istate, #ISTATE_LOCALS]
-	cmp	ip, locals
-	strne	r0, [r0, -r0]
-	ldr	ip, [arm_sp], #4
-	msr	cpsr, ip
-	ldr	ip, [arm_sp], #4
-#endif
-	.endm
-
-	.macro	ASSERT_STACK_CACHED
-#if 0
-	str	ip, [arm_sp, #-4]!
-	mrs	ip, cpsr
-	str	ip, [arm_sp, #-4]!
-	mov	ip, stack
-	ldr	stack, [istate, #ISTATE_STACK]
-	cmp	ip, stack
-	strne	r0, [r0, -r0]
-	ldr	ip, [arm_sp], #4
-	msr	cpsr, ip
-	ldr	ip, [arm_sp], #4
-#endif
-	.endm
-
-@ DISPATCH_LOOP causes the dispatch code to branch every time to a label 'dispatch_loop'
-@ This is primarily for debugging so we can stick assertions at the dispatch_loop label
-@ which will then be checked after every bytcode.
-@ #define DISPATCH_LOOP
-
-@ CODETRACE tarces bytecodes in a code buffer which can be examined under gdb
-@ Note: DISPATCH_LOOP must be enabled for CODETRACE to work
-@ #define CODETRACE
-
-@ DISPATCH_ASSERTS enables various assertions in the dispatch loop, such as checking
-@ stack, frame, locals and constpool are all consistent and not corrupted
-@#define DISPATCH_ASSERTS
-
-	.macro	ABORTNE
-	strne	r0, [r0, -r0]
-	.endm
-
-	.macro	ABORTCS
-	strcs	r0, [r0, -r0]
-	.endm
-
-	.macro	ABORTCC
-	strcc	r0, [r0, -r0]
-	.endm
-
-	.macro	CHECK_CONSTPOOL
-#ifdef DISPATCH_ASSERTS
-	@ First check istate->constpool == method->constpool
-	ldr	r1, [istate, #ISTATE_CONSTANTS]
-	ldr	r2, [istate, #ISTATE_METHOD]
-	ldr	r2, [r2, #METHOD_CONSTANTS]
-	ldr	r2, [r2, #CONSTANTPOOL_CACHE]
-	cmp	r1, r2
-	ABORTNE
-@	cmp	r1, constpool
-@	ABORTNE
-#endif
-	.endm
-
-	.macro	CHECK_LOCALS
-#ifdef DISPATCH_ASSERTS
-	@ Check cached locals var is the same as that in istate
-	ldr	r1, [istate, #ISTATE_LOCALS]
-	cmp	r1, locals
-	ABORTNE
-#endif
-	.endm
-
-	.macro	CHECK_FRAME
-#ifdef DISPATCH_ASSERTS
-	@ Check #INTERPRETER_FRAME hasn't been overwritten
-	ldr	r1, [istate, #ISTATE_FRAME_TYPE]
-	cmp	r1, #INTERPRETER_FRAME
-	ABORTNE
-	@ Check we are still the topmost frame
-	ldr	r1, [istate, #ISTATE_THREAD]
-	ldr	r1, [r1, #THREAD_TOP_ZERO_FRAME]
-	add	r2, istate, #ISTATE_NEXT_FRAME
-	cmp	r1, r2
-	ABORTNE
-	@ And check the NEXT_FRAME pointer points to a valid frame
-	ldr	r1, [istate, #ISTATE_NEXT_FRAME]
-	ldr	r2, [r1, #-ISTATE_NEXT_FRAME + ISTATE_FRAME_TYPE]
-	bic	r2, r2, #7	@ ECN: Allow for differing frames
-	cmp	r2, #0
-	ABORTNE
-#endif
-	.endm
-
-	.macro	CHECK_BACKTRACE
-#ifdef DISPATCH_ASSERTS
-	add	r3, istate, #ISTATE_NEXT_FRAME
-@ ECN: Only check a limited no of frames back. topmost frame already checked
-@ Check 2nd frame up
-	ldr	r3, [r3]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_FRAME_TYPE]
-	cmp	r2, #ENTRY_FRAME
-	beq	2f
-	cmp	ip, #INTERPRETER_FRAME
-	ABORTNE				@ Must be ENTRY_FRAME, or INTERPRETER_FRAME
-	ldr	r1, [r3, #-ISTATE_NEXT_FRAME + ISTATE_CONSTANTS]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_METHOD]
-	ldr	r2, [r2, #12]
-	ldr	r2, [r2, #12]
-	cmp	r1, r2
-	ABORTNE
-@ Check 3rd frame up
-	ldr	r3, [r3]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_FRAME_TYPE]
-	cmp	r2, #ENTRY_FRAME
-	beq	2f
-	cmp	r2, #INTERPRETER_FRAME
-	ABORTNE				@ Must be ENTRY_FRAME, or INTERPRETER_FRAME
-	ldr	r1, [r3, #-ISTATE_NEXT_FRAME + ISTATE_CONSTANTS]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_METHOD]
-	ldr	r2, [r2, #12]
-	ldr	r2, [r2, #12]
-	cmp	r1, r2
-	ABORTNE
-@ Check 4th frame up
-	ldr	r3, [r3]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_FRAME_TYPE]
-	cmp	r2, #ENTRY_FRAME
-	beq	2f
-	cmp	r2, #INTERPRETER_FRAME
-	ABORTNE				@ Must be ENTRY_FRAME, or INTERPRETER_FRAME
-	ldr	r1, [r3, #-ISTATE_NEXT_FRAME + ISTATE_CONSTANTS]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_METHOD]
-	ldr	r2, [r2, #12]
-	ldr	r2, [r2, #12]
-	cmp	r1, r2
-	ABORTNE
-@ Check 5th frame up
-	ldr	r3, [r3]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_FRAME_TYPE]
-	cmp	r2, #ENTRY_FRAME
-	beq	2f
-	cmp	r2, #INTERPRETER_FRAME
-	ABORTNE				@ Must be ENTRY_FRAME, or INTERPRETER_FRAME
-	ldr	r1, [r3, #-ISTATE_NEXT_FRAME + ISTATE_CONSTANTS]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_METHOD]
-	ldr	r2, [r2, #12]
-	ldr	r2, [r2, #12]
-	cmp	r1, r2
-	ABORTNE
-@ Check 7th frame up
-	ldr	r3, [r3]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_FRAME_TYPE]
-	cmp	r2, #ENTRY_FRAME
-	beq	2f
-	cmp	r2, #INTERPRETER_FRAME
-	ABORTNE				@ Must be ENTRY_FRAME, or INTERPRETER_FRAME
-	ldr	r1, [r3, #-ISTATE_NEXT_FRAME + ISTATE_CONSTANTS]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_METHOD]
-	ldr	r2, [r2, #12]
-	ldr	r2, [r2, #12]
-	cmp	r1, r2
-	ABORTNE
-@ Check 8th frame up
-	ldr	r3, [r3]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_FRAME_TYPE]
-	cmp	r2, #ENTRY_FRAME
-	beq	2f
-	cmp	r2, #INTERPRETER_FRAME
-	ABORTNE				@ Must be ENTRY_FRAME, or INTERPRETER_FRAME
-	ldr	r1, [r3, #-ISTATE_NEXT_FRAME + ISTATE_CONSTANTS]
-	ldr	r2, [r3, #-ISTATE_NEXT_FRAME + ISTATE_METHOD]
-	ldr	r2, [r2, #12]
-	ldr	r2, [r2, #12]
-	cmp	r1, r2
-	ABORTNE
-2:
-#endif
-	.endm
-
-	.macro	CHECK_STACK
-#ifdef DISPATCH_ASSERTS
-	ldr	r1, [istate, #ISTATE_STACK_BASE]
-	cmp	stack, r1
-	ABORTCS
-	ldr	r1, [istate, #ISTATE_STACK_LIMIT]
-	@ ECN: The stack can point below the stack limit in the
-	@	case that we have a full stack. As long as we dont actually
-	@	try writing to it.
-	add	r2, stack, #4
-	cmp	r2, r1
-	ABORTCC
-#endif
-	.endm
-
-#define CODETRACE_BUFFER_SIZE	(1 * 1024)
-	.macro	TRACE_CODE
-#ifdef CODETRACE
-	ldr	r1, [dispatch, #CodeTrace_Idx-XXX]
-	cmp	r1, #CODETRACE_BUFFER_SIZE
-	moveq	r1, #0
-	sub	r2, dispatch, #XXX-CodeTrace_Buffer_Base
-	str	jpc, [r2, r1]
-	add	r1, r1, #4
-	str	r1, [dispatch, #CodeTrace_Idx-XXX]
-#endif
-	.endm
-
 	.macro	BREAK_DISPATCH
 	ldr	r1, [dispatch, #DispatchBreakPoint-XXX]
 	cmp	r1, jpc
@@ -605,23 +368,6 @@
 	mov	r0, r2
 	.endm
 
-#ifdef DISPATCH_LOOP
-	.macro	DISPATCH_NEXT
-	.endm
-
-	.macro	DISPATCH_FINISH
-	b	dispatch_loop
-	.endm
-
-	.macro	DISPATCH_BYTECODE
-	b	dispatch_loop
-	.endm
-
-	.macro	DISPATCH	step=0
-	ldrb	r0, [jpc, #\step]!
-	b	dispatch_loop
-	.endm
-#else
 	.macro	DISPATCH_1
 @        ldrb    r1, [jpc, #2]
 	.endm
@@ -702,7 +448,6 @@
         bic     ip, ip, #7
         ldr     pc, [ip, r1, lsl #2]
 	.endm
-#endif // DISPATCH_LOOP
 
 #define FFI_TYPE_VOID		0
 #define FFI_TYPE_FLOAT		2
@@ -759,105 +504,6 @@
 
 	.text
 
-do_dispatch_break:
-	mov	pc, lr
-
-#ifdef DISPATCH_LOOP
-@ r0 = bytecode
-@ jpc has been updated
-dispatch_loop:
-	TRACE_CODE
-dispatch_check_constpool:
-	CHECK_CONSTPOOL
-dispatch_check_locals:
-	CHECK_LOCALS
-dispatch_check_stack:
-	CHECK_STACK
-dispatch_check_frame:
-	CHECK_FRAME
-dispatch_check_backtrace:
-	CHECK_BACKTRACE
-dispatch_break:
-	BREAK_DISPATCH
-        ldrb    r1, [jpc, #2]
-        ldr     ip, [dispatch, r0, lsl #2]
-        ldrb    r2, [jpc, #1]
-        ands    lr, ip, #7
-        moveq   pc, ip
-	ldrb	r1, [jpc, lr]
-        bic     ip, ip, #7
-        ldr     ip, [ip, r1, lsl #2]
-        mov     pc, ip
-#endif
-
-is_subtype_of:
-	ldr	r2, [r1, #16]
-	add	ip, r0, r2
-	ldr	ip, [ip, #-8]
-	cmp	ip, r1
-	moveq	r0, #1
-	bxeq	lr
-	cmp	r2, #20
-	movne	r0, #0
-	bxne	lr
-	b	_ZNK5Klass23search_secondary_supersEP12klassOopDesc
-
-HandleC:
-	stmfd	sp!, {r4, r5, r6, lr}
-	ldr	r3, HandleC_adcons
-	subs	r5, r1, #0
-	mov	r4, r0
-.HandleC_pic:
-	add	r3, pc, r3
-	streq	r5, [r0, #0]
-	beq	2f
-	ldr	r2, HandleC_adcons+4
-	ldr	r3, [r3, r2]
-	ldr	r0, [r3, #0]
-	bl	pthread_getspecific
-	ldr	r3, [r0, #THREAD_HANDLE_AREA]
-	ldr	r0, [r3, #8]
-	ldr	r1, [r3, #12]
-	add	r2, r0, #4
-	cmp	r2, r1
-	strls	r2, [r3, #8]
-	bhi	3f
-1:
-	str	r5, [r0, #0]
-	str	r0, [r4, #0]
-2:
-	mov	r0, r4
-	ldmfd	sp!, {r4, r5, r6, pc}
-3:
-	mov	r0, r3
-	mov	r1, #4
-	bl	_ZN5Arena4growEj
-	b	1b
-HandleC_adcons:
-	.word	_GLOBAL_OFFSET_TABLE_-(.HandleC_pic+8)
-	.word	_ZN18ThreadLocalStorage13_thread_indexE(GOT)
-
-HandleMarkCleanerD:
-	stmfd	sp!, {r4, r5, r6, lr}
-	ldr	r3, [r0, #0]
-	mov	r6, r0
-	ldr	r4, [r3, #40]
-	ldr	r0, [r4, #8]
-	ldr	r5, [r4, #4]
-	ldr	r3, [r0, #0]
-	cmp	r3, #0
-	beq	1f
-	bl	_ZN5Chunk9next_chopEv
-	ldr	r0, [r4, #8]
-1:
-	str	r0, [r5, #4]
-	mov	r0, r6
-	ldr	r3, [r4, #12]
-	str	r3, [r5, #8]
-	ldr	r3, [r4, #16]
-	str	r3, [r5, #12]
-	ldmfd	sp!, {r4, r5, r6, pc}
-
 cmpxchg_ptr:
 	stmfd	sp!, {r4, r5, r6, r7, r8, lr}
 	mov	r6, #0xffffffc0
@@ -883,126 +529,6 @@
 	mov	r0, r8
 	ldmfd	sp!, {r4, r5, r6, r7, r8, pc}
 
-ThreadInVMfromJavaD:
-	stmfd	sp!, {r4, r5, r6, lr}
-	ldr	r5, ThreadInVMfromJavaD_adcons
-	ldr	r3, ThreadInVMfromJavaD_adcons+4
-	mov	r2, #_thread_in_vm_trans
-.ThreadInVMfromJavaD_pic:
-	add	r5, pc, r5
-	ldr	r6, [r0, #0]
-	mov	r4, r0
-	ldr	r3, [r5, r3]
-	str	r2, [r6, #THREAD_STATE]
-	ldr	r3, [r3, #0]
-	cmp	r3, #1
-	ble	1f
-	ldr	r3, ThreadInVMfromJavaD_adcons+8
-	ldr	r3, [r5, r3]
-	ldrb	r3, [r3, #0]	@ zero_extendqisi2
-	cmp	r3, #0
-	bne	6f
-	ldr	r3, ThreadInVMfromJavaD_adcons+12
-	mov	r1, #1
-	ldr	r2, ThreadInVMfromJavaD_adcons+16
-	ldr	r3, [r5, r3]
-	ldr	r2, [r5, r2]
-	ldr	r3, [r3, #0]
-	ldr	r2, [r2, #0]
-	and	r3, r3, r6, lsr #3
-	str	r1, [r2, r3]
-1:
-	ldr	r3, ThreadInVMfromJavaD_adcons+20
-	ldr	r3, [r5, r3]
-	ldr	r3, [r3, #0]
-	cmp	r3, #0
-	bne	5f
-2:
-	mov	r3, #8
-	str	r3, [r6, #THREAD_STATE]
-	ldr	r0, [r4, #0]
-	ldr	r3, [r0, #THREAD_SPECIALRUNTIMEEXITCONDITION]
-	cmp	r3, #0
-	bne	3f
-	ldr	r3, [r0, #THREAD_SUSPEND_FLAGS]
-	tst	r3, #_thread_external_suspend
-	beq	4f
-3:
-	mov	r1, #1
-	bl	_ZN10JavaThread37handle_special_runtime_exit_conditionEb
-	mov	r0, r4
-	ldmfd	sp!, {r4, r5, r6, pc}
-4:
-	ldr	r3, [r0, #THREAD_SUSPEND_FLAGS]
-	tst	r3, #_thread_deopt_suspend
-	bne	3b
-	mov	r0, r4
-	ldmfd	sp!, {r4, r5, r6, pc}
-5:
-	mov	r0, r6
-	bl	_ZN20SafepointSynchronize5blockEP10JavaThread
-	b	2b
-6:
-	mov	r3, #0xffffffa0
-	bic	r3, r3, #0xf000
-	blx	r3
-	b	1b
-ThreadInVMfromJavaD_adcons:
-	.word	_GLOBAL_OFFSET_TABLE_-(.ThreadInVMfromJavaD_pic+8)
-	.word	_ZN2os16_processor_countE(GOT)
-	.word	UseMembar(GOT)
-	.word	_ZN2os20_serialize_page_maskE(GOT)
-	.word	_ZN2os19_mem_serialize_pageE(GOT)
-	.word	_ZN20SafepointSynchronize6_stateE(GOT)
-
-#define oop_address_tmp	tmp1
-#define oop_value_tmp	tmp2
-#define oop_lr		locals
-
-	ALIGN_CODE
-oop_store:
-	mov	oop_lr, lr
-@	mov	oop_address_tmp, r0
-@	mov	oop_value_tmp, r1
-	ldr	r3, [dispatch, #oopDesc_Address-XXX]
-	ldr	r3, [r3, #0]
-	ldr	r2, [r3, #8]
-	cmp	r2, #1
-	beq	1f
-	mov	r0, r3
-	mov	r1, oop_address_tmp
-	ldr	r3, [r3, #0]
-	mov	r2, oop_value_tmp
-	mov	lr, pc
-	ldr	pc, [r3, #48]
-1:
-	ldr	r3, [dispatch, #always_do_update_barrier_Address-XXX]
-	ldrb	r3, [r3]
-	cmp	r3, #0
-	beq	2f
-	mov	r3, #0xffffffa0
-	bic	r3, r3, #0xf000
-	blx	r3
-2:
-	mov	lr, oop_lr
-	CACHE_LOCALS
-	ldr	r3, [dispatch, #oopDesc_Address-XXX]
-	str	oop_value_tmp, [oop_address_tmp, #0]
-	ldr	r3, [r3, #0]
-	ldr	r2, [r3, #8]
-	cmp	r2, #1
-	beq	3f
-	mov	r0, r3
-	mov	r1, oop_address_tmp
-	mov	r2, oop_value_tmp
-	ldr	r3, [r3, #0]
-	ldr	pc, [r3, #52]
-3:
-	ldr	r3, [r3, #76]
-	mov	r2, #0
-	strb	r2, [r3, oop_address_tmp, lsr #9]
-	mov	pc, lr
-
 build_frame:
 	mov	r3, r0
 	ldr	r0, [r1, #METHOD_ACCESSFLAGS]
@@ -1093,13 +619,6 @@
 	add	r1, r1, ip
 	add	r1, r1, r2		@ r1->dispatch
 
-#ifndef USE_COMPILER
-	ldr	r2, [r1, #UseCompiler_Address-XXX]
-	ldrb	r2, [r2]
-	cmp	r2, #0
-	bne	1f
-#endif
-
 	ldr	r2, [r1, #can_post_interpreter_events-XXX]
 	ldrb	r2, [r2]
 	cmp	r2, #0
@@ -1119,26 +638,33 @@
 asm_method_table:
 	.word	normal_entry
 	.word	normal_entry_synchronized
-#ifdef NATIVE_ENTRY
 	.word	native_entry
-#else
-	.word	0
-#endif
-	.word	0			@ cppInterpreter can handle native_entry_synchronized
+	.word	native_entry_synchronized
 	.word	empty_entry
 	.word	accessor_entry
-	.word	normal_entry
-	.word	normal_entry
-	.word	normal_entry
-	.word	normal_entry
-	.word	normal_entry
-	.word	normal_entry
-	.word	normal_entry
-	.word	normal_entry
+	.word	normal_entry		@ abstract entry
+	.word	normal_entry		@ java_lang_math_sin
+	.word	normal_entry		@ java_lang_math_cos
+	.word	normal_entry		@ java_lang_math_tan
+	.word	normal_entry		@ java_lang_math_abs
+	.word	normal_entry		@ java_lang_math_sqrt
+	.word	normal_entry		@ java_lang_math_log
+	.word	normal_entry		@ java_lang_math_log10
 
 	ALIGN_CODE
-	.global	empty_entry
+native_entry_synchronized:
+	b	fast_native_entry_synchronized
+
+	ALIGN_CODE
+fast_native_entry_synchronized:
+	b	_ZN14CppInterpreter12native_entryEP13methodOopDesciP6Thread
+
+	ALIGN_CODE
 empty_entry:
+	b	fast_empty_entry
+
+	ALIGN_CODE
+fast_empty_entry:
 	ldr	r3, .L1359
 	ldr	r1, .L1359+4
 .LPIC19:
@@ -1160,22 +686,22 @@
 
 @ ---- START execute.s ---------------------------------------------------------------------
 
+	.global	asm_check_null_ptr
+asm_check_null_ptr:
+
 #ifdef HW_NULL_PTR_CHECK
 
 #define uc_mcontext		20
 #define arm_registers_offset	12
 #define arm_cpsr_offset		16*4
 
-	.global	asm_check_null_ptr
-asm_check_null_ptr:
 	add	r0, r0, #uc_mcontext + arm_registers_offset
 	ldr	r1, [r0, #15*4]
 	adr	ip, abort_table
 abort_loop:
 	ldr	r2, [ip], #8
 	cmp	r2, #0
-	moveq	r0, #0
-	bxeq	lr
+	beq	2f
 	cmp	r2, r1
 	bne	abort_loop
 
@@ -1193,6 +719,16 @@
 do_setcontext:
 	mov	r0, #1
 	bx	lr
+#endif // HW_NULL_PTR_CHECK
+2:
+#ifdef THUMB2EE
+	b	Thumb2_Check_Null
+#else
+	mov	r0, #0
+	bx	lr
+#endif
+
+#ifdef HW_NULL_PTR_CHECK
 abort_table:
 			.word	.abortentry5, 1
 			.word	.abortentry6, 1
@@ -1240,19 +776,6 @@
 		FBC	.word	.abortentry59, 2
 		FBC	.word	.abortentry60, 2
 
-	NSP	FBC	.word	.abortentry61, 0
-	NSP	FBC	.word	.abortentry62, 0
-	NSP	FBC	.word	.abortentry63, 0
-	NSP	FBC	.word	.abortentry64, 0
-	NSP	FBC	.word	.abortentry65, 0
-	NSP	FBC	.word	.abortentry66, 0
-	NSP	FBC	.word	.abortentry67, 0
-	NSP	FBC	.word	.abortentry68, 0
-	NSP	FBC	.word	.abortentry69, 0
-	NSP	FBC	.word	.abortentry70, 0
-	NSP	FBC	.word	.abortentry71, 0
-	NSP	FBC	.word	.abortentry72, 0
-
 		FBC	.word	.abortentry73, 1
 		FBC	.word	.abortentry74, 1
 		FBC	.word	.abortentry75, 1
@@ -1274,18 +797,6 @@
 	    FBC	   	.word	.abortentry89, 5
 	    FBC	     	.word	.abortentry90, 4
 	    FBC	     	.word	.abortentry91, 4
-	NSP FBC	     	.word	.abortentry92, 3
-	NSP FBC	     	.word	.abortentry93, 3
-	NSP FBC	     	.word	.abortentry94, 3
-	NSP FBC	     	.word	.abortentry95, 3
-	NSP FBC	     	.word	.abortentry96, 3
-	NSP FBC	     	.word	.abortentry97, 3
-	NSP FBC	     	.word	.abortentry98, 3
-	NSP FBC	     	.word	.abortentry99, 3
-	NSP FBC	     	.word	.abortentry100, 3
-	NSP FBC	     	.word	.abortentry101, 3
-	NSP FBC	     	.word	.abortentry102, 3
-	NSP FBC	     	.word	.abortentry103, 3
 	    FBC		.word	.abortentry104, 0
 		FBC	.word	.abortentry105, 1
 		FBC	.word	.abortentry106, 1
@@ -1299,28 +810,27 @@
 
 		FBC	.word	.abortentry113, 0
 			.word	.abortentry114, 1
-			.word	.abortentry115, 0
-			.word	.abortentry116, abstractmethod_exception
 		FBC	.word	.abortentry117, 0
 			.word	.abortentry118, 0
-			.word	.abortentry119, return_throw_illegal_monitor_state
-		FBC	.word	.abortentry120, 0
 	.word	0
 
-#else
-	.global	asm_check_null_ptr
-asm_check_null_ptr:
-	mov	r0, #0
-	bx	lr
-
 #endif
 
-#ifdef NATIVE_ENTRY
+
+	ALIGN_CODE
+native_entry:
+	stmfd	arm_sp!, {regset, lr}
+	bl	fast_native_entry
+	ldmia	sp!, {regset, pc}
+
 	ALIGN_CODE
 fast_native_entry:
-	mov	r2, tmp1
-	mov	r11, tmp2
-fast_native_entry_with_args:
+	adrl	ip, dispatch_init_adcon
+	mov	r11, r0
+	ldm	ip, {dispatch, r7}
+	stmdb	sp!, {fast_regset, lr}
+	add	dispatch, dispatch, ip
+	add	dispatch, dispatch, r7
 	ldrh	r1, [r11, #METHOD_SIZEOFPARAMETERS]
 	ldr	r4, [r2, #THREAD_JAVA_SP]
 	ldr	r3, [r2, #THREAD_TOP_ZERO_FRAME]
@@ -1477,24 +987,6 @@
 	ldr	ip, [r11, #METHOD_NATIVEHANDLER]
 	ldrh	r11, [r11, #METHOD_SIZEOFPARAMETERS]
 
-#ifdef CODETRACE
-	ldr	r1, [dispatch, #CodeTrace_Idx-XXX]
-	cmp	r1, #CODETRACE_BUFFER_SIZE
-	moveq	r1, #0
-	sub	r2, dispatch, #XXX-CodeTrace_Buffer_Base
-	mov	r3, #0x4e << 24		@ 'NATV' -> r3
-	orr	r3, r3, #0x4a << 16
-	orr	r3, r3, #0x54 << 8
-	orr	r3, r3, #0x56
-	str	r3, [r2, r1]
-	add	r1, r1, #4
-	cmp	r1, #CODETRACE_BUFFER_SIZE
-	moveq	r1, #0
-	str	ip, [r2, r1]
-	add	r1, r1, #4
-	str	r1, [dispatch, #CodeTrace_Idx-XXX]
-#endif
-
 	ldmia	arm_sp!, {r0, r1, r2, r3}
 	blx	ip
 
@@ -1557,50 +1049,40 @@
 	str	lr, [r9, #THREAD_TOP_ZERO_FRAME]
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
 	str	r1, [r5, #4]
-	cmp	istate, #0
 	str	r5, [r9, #THREAD_JAVA_SP]
-	bne	.fast_native_return
-	ldmfd	arm_sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, pc}
+	ldmfd	arm_sp!, {fast_regset, pc}
 .fast_native_return_byte:
 	mov	r0, r0, lsl #24
 	str	lr, [r9, #THREAD_TOP_ZERO_FRAME]
 	mov	r0, r0, asr #24
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
 	str	r0, [r5, #-4]!
-	cmp	istate, #0
 	str	r5, [r9, #THREAD_JAVA_SP]
-	bne	.fast_native_return
-	ldmfd	arm_sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, pc}
+	ldmfd	arm_sp!, {fast_regset, pc}
 .fast_native_return_char:
 	mov	r0, r0, lsl #16
 	str	lr, [r9, #THREAD_TOP_ZERO_FRAME]
 	mov	r0, r0, lsr #16
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
 	str	r0, [r5, #-4]!
-	cmp	istate, #0
 	str	r5, [r9, #THREAD_JAVA_SP]
-	bne	.fast_native_return
-	ldmfd	arm_sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, pc}
+	ldmfd	arm_sp!, {fast_regset, pc}
 .fast_native_return_bool:
 	ands	r0, r0, #255
 	str	lr, [r9, #THREAD_TOP_ZERO_FRAME]
 	movne	r0, #1
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
 	str	r0, [r5, #-4]!
-	cmp	istate, #0
 	str	r5, [r9, #THREAD_JAVA_SP]
-	bne	.fast_native_return
-	ldmfd	arm_sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, pc}
+	ldmfd	arm_sp!, {fast_regset, pc}
 .fast_native_return_obj:
 	cmp	r0, #0
 	ldrne	r0, [r0]
 	str	r0, [r5, #-4]!
 	str	lr, [r9, #THREAD_TOP_ZERO_FRAME]
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
-	cmp	istate, #0
 	str	r5, [r9, #THREAD_JAVA_SP]
-	bne	.fast_native_return
-	ldmfd	arm_sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, pc}
+	ldmfd	arm_sp!, {fast_regset, pc}
 .fast_native_return_short:
 	mov	r0, r0, lsl #16
 	mov	r0, r0, asr #16
@@ -1610,32 +1092,8 @@
 	str	lr, [r9, #THREAD_TOP_ZERO_FRAME]
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
 .fast_native_exit:
-	cmp	istate, #0
 	str	r5, [r9, #THREAD_JAVA_SP]
-	ldmeqfd	arm_sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, pc}
-.fast_native_return:
-	ldr	r2, [istate, #ISTATE_STACK_LIMIT]
-	sub	r5, r5, #4
-	str	r5, [istate, #ISTATE_STACK]
-
-	ldr	r1, [r9, #THREAD_TOP_ZERO_FRAME]
-	add	r2, r2, #4
-	str	r2, [r9, #THREAD_JAVA_SP]
-	str	r1, [r9, #THREAD_LAST_JAVA_SP]
-	ldr	r0, [istate, #ISTATE_THREAD]
-	CACHE_STACK
-	CACHE_JPC
-	ldr	r3, [r0, #THREAD_PENDING_EXC]
-	DISPATCH_START	3
-	DISPATCH_NEXT
-	CACHE_CP
-	DISPATCH_NEXT
-	cmp	r3, #0
-	DISPATCH_NEXT
-	bne	invokenative_exception
-	DISPATCH_NEXT
-	CACHE_LOCALS
-	DISPATCH_FINISH
+	ldmfd	arm_sp!, {fast_regset, pc}
 
 .fast_native_entry_throw_stack_overflow:
 	str	r0, [r9, #THREAD_LAST_JAVA_SP]
@@ -1659,958 +1117,46 @@
 	bl	_ZN10JavaThread40check_special_condition_for_native_transEPS_
 	ldmia	arm_sp!, {r0, r1}
 	b	.fast_native_entry_do_return
-#endif // NATIVE_ENTRY
 
 #include "bytecodes_arm.s"
 
 	Opcode	idiv
 
-	POP	tmp2, tmp1
-	DISPATCH_START	1
-int_div:
-	cmp	tmp2, #0x20
-	DISPATCH_NEXT
-	adr	r3, .div_table
-	DISPATCH_NEXT
-	ldrcc	pc, [r3, tmp2, lsl #2]
-
-        ands    a4, tmp2, #0x80000000
-        rsbmi   tmp2, tmp2, #0
-        eors    lr, a4, tmp1, ASR #32
-        rsbcs   tmp1, tmp1, #0
-	movs	a3, tmp2
-.s_loop:
-        cmp     a3, tmp1, LSR #8
-        movls   a3, a3, LSL #8
-        blo     .s_loop
-        cmp     a3, tmp1, LSR #1
-        bhi     .s_jump7
-        cmp     a3, tmp1, LSR #2
-        bhi     .s_jump6
-        cmp     a3, tmp1, LSR #3
-        bhi     .s_jump5
-        cmp     a3, tmp1, LSR #4
-        bhi     .s_jump4
-        cmp     a3, tmp1, LSR #5
-        bhi     .s_jump3
-        cmp     a3, tmp1, LSR #6
-        bhi     .s_jump2
-        cmp     a3, tmp1, LSR #7
-        bhi     .s_jump1
-.s_loop2:
-@ not executed when falling into .s_loop2
-        movhi   a3, a3, LSR #8
-        cmp     tmp1, a3, LSL #7
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #7
-        cmp     tmp1, a3, LSL #6
-.s_jump1:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #6
-        cmp     tmp1, a3, LSL #5
-.s_jump2:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #5
-        cmp     tmp1, a3, LSL #4
-.s_jump3:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #4
-        cmp     tmp1, a3, LSL #3
-.s_jump4:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #3
-        cmp     tmp1, a3, LSL #2
-.s_jump5:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #2
-        cmp     tmp1, a3, LSL #1
-.s_jump6:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #1
-.s_jump7:
-        cmp     tmp1, a3
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3
-        cmp     a3, tmp2
-        bne     .s_loop2
-        movs    lr, lr, lsl #1
-	rsbcs	a4, a4, #0
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	a4
-	DISPATCH_FINISH
-
-.div_table:
-	.word	div_zero_jpc_1
-	.word	.divc_1
-	.word	.divc_2
-	.word	.divc_3
-	.word	.divc_4
-	.word	.divc_5
-	.word	.divc_6
-	.word	.divc_7
-	.word	.divc_8
-	.word	.divc_9
-	.word	.divc_10
-	.word	.divc_11
-	.word	.divc_12
-	.word	.divc_13
-	.word	.divc_14
-	.word	.divc_15
-	.word	.divc_16
-	.word	.divc_17
-	.word	.divc_18
-	.word	.divc_19
-	.word	.divc_20
-	.word	.divc_21
-	.word	.divc_22
-	.word	.divc_23
-	.word	.divc_24
-	.word	.divc_25
-	.word	.divc_26
-	.word	.divc_27
-	.word	.divc_28
-	.word	.divc_29
-	.word	.divc_30
-	.word	.divc_31
-
-.divc_1:
-	DISPATCH_STATE	3
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	tmp1
-	DISPATCH_FINISH
-.divc_2:
-	DISPATCH_STATE	3
-	DISPATCH_NEXT
-        add     tmp1, tmp1, tmp1, lsr #31
-        mov     tmp2, tmp1, asr #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_3:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_3
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        sub	tmp2, a4, tmp1, asr #31
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_4:
-	DISPATCH_STATE	3
-	movs	a4, tmp1
-	DISPATCH_NEXT
-        addmi	a4, a4, #3
-        mov	tmp2, a4, asr #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_5:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_5
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_6:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_6
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        sub	tmp2, a4, tmp1, asr #31
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_7:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_7
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_8:
-	DISPATCH_STATE	3
-	movs	lr, tmp1
-	DISPATCH_NEXT
-        addmi	lr, lr, #7
-        mov	tmp2, lr, asr #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_9:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_9
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_10:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_10
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_11:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_11
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_12:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_12
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_13:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_13
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_14:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_14
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_15:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_15
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_16:
-	DISPATCH_STATE	3
-	movs	lr, tmp1
-	DISPATCH_NEXT
-        addmi	lr, lr, #15
-        mov	tmp2, lr, asr #4
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_17:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_17
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_18:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_18
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_19:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_19
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_20:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_20
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_21:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_21
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_22:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_22
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_23:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_23
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #4
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_24:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_24
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_25:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_25
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_26:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_26
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_27:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_27
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_28:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_28
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #4
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_29:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_29
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #4
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_30:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_30
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #4
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.divc_31:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_31
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #4
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.dc_7:
-.dc_14:
-	.word     0x92492493
-.dc_15:
-.dc_30:
-	.word     0x88888889
-.dc_23:
-	.word     0xb21642c9
-.dc_28:
-	.word     0x92492493
-.dc_29:
-	.word     0x8d3dcb09
-.dc_31:
-	.word     0x84210843
-.dc_6:
-.dc_12:
-.dc_24:
-	.word     0x2aaaaaab
-.dc_19:
-	.word     0x6bca1af3
-.dc_5:
-.dc_10:
-.dc_20:
-	.word     0x66666667
-.dc_21:
-	.word     0x30c30c31
-.dc_11:
-.dc_22:
-	.word     0x2e8ba2e9
-.dc_26:
-.dc_13:
-	.word     0x4ec4ec4f
-.dc_25:
-	.word     0x51eb851f
-.dc_27:
-	.word     0x4bda12f7
-.dc_3:
-	.word     0x55555556
-.dc_17:
-	.word     0x78787879
-.dc_9:
-.dc_18:
-	.word     0x38e38e39
-
+	POP	r1
+	POP	r0
+	cmp	r1, #0
+	beq	divide_by_zero_exception
+	bl	__aeabi_idiv
+	PUSH	r0
+	DISPATCH 1
+
+	Opcode	idiv_clz
+
+	POP	r1
+	POP	r0
+	bl	int_div
+idiv_clz_ret:
+	PUSH	r0
+	DISPATCH 1
 
 	Opcode	irem
 
-	POP	tmp2, tmp1
-	DISPATCH_START	1
-int_rem:
-	cmp	tmp2, #0x20
-	DISPATCH_NEXT
-	adr	r3, .rem_table
-	DISPATCH_NEXT
-	ldrcc	pc, [r3, tmp2, lsl #2]
-
-        ands    a4, tmp2, #0x80000000
-        rsbmi   tmp2, tmp2, #0
-        eors    lr, a4, tmp1, ASR #32
-        rsbcs   tmp1, tmp1, #0
-	movs	a3, tmp2
-.r_loop:
-        cmp     a3, tmp1, LSR #8
-        movls   a3, a3, LSL #8
-        blo     .r_loop
-        cmp     a3, tmp1, LSR #1
-        bhi     .r_jump7
-        cmp     a3, tmp1, LSR #2
-        bhi     .r_jump6
-        cmp     a3, tmp1, LSR #3
-        bhi     .r_jump5
-        cmp     a3, tmp1, LSR #4
-        bhi     .r_jump4
-        cmp     a3, tmp1, LSR #5
-        bhi     .r_jump3
-        cmp     a3, tmp1, LSR #6
-        bhi     .r_jump2
-        cmp     a3, tmp1, LSR #7
-        bhi     .r_jump1
-.r_loop2:
-@ not executed when falling into .r_loop2
-        movhi   a3, a3, LSR #8
-        cmp     tmp1, a3, LSL #7
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #7
-        cmp     tmp1, a3, LSL #6
-.r_jump1:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #6
-        cmp     tmp1, a3, LSL #5
-.r_jump2:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #5
-        cmp     tmp1, a3, LSL #4
-.r_jump3:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #4
-        cmp     tmp1, a3, LSL #3
-.r_jump4:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #3
-        cmp     tmp1, a3, LSL #2
-.r_jump5:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #2
-        cmp     tmp1, a3, LSL #1
-.r_jump6:
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3, LSL #1
-.r_jump7:
-        cmp     tmp1, a3
-        adc     a4, a4, a4
-        subcs   tmp1, tmp1, a3
-        cmp     a3, tmp2
-        bne     .r_loop2
-        movs    lr, lr, lsl #1
-	DISPATCH_NEXT
-	rsbmi	tmp1, tmp1, #0
-	DISPATCH_NEXT
-	PUSH	tmp1
-	DISPATCH_FINISH
-
-.rem_table:
-	.word	div_zero_jpc_1
-	.word	.remc_1
-	.word	.remc_2
-	.word	.remc_3
-	.word	.remc_4
-	.word	.remc_5
-	.word	.remc_6
-	.word	.remc_7
-	.word	.remc_8
-	.word	.remc_9
-	.word	.remc_10
-	.word	.remc_11
-	.word	.remc_12
-	.word	.remc_13
-	.word	.remc_14
-	.word	.remc_15
-	.word	.remc_16
-	.word	.remc_17
-	.word	.remc_18
-	.word	.remc_19
-	.word	.remc_20
-	.word	.remc_21
-	.word	.remc_22
-	.word	.remc_23
-	.word	.remc_24
-	.word	.remc_25
-	.word	.remc_26
-	.word	.remc_27
-	.word	.remc_28
-	.word	.remc_29
-	.word	.remc_30
-	.word	.remc_31
-
-.remc_1:
-	DISPATCH_STATE	3
-	DISPATCH_NEXT
-	mov	tmp2, #0
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_2:
-	DISPATCH_STATE	3
-	add	lr, tmp1, tmp1, lsr #31
-        mov	tmp2, lr, asr #1
-	DISPATCH_NEXT
-	sub	tmp2, tmp1, tmp2, lsl #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_3:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_3
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        sub	tmp2, a4, tmp1, asr #31
-	add	lr, tmp2, tmp2, lsl #1
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_4:
-	DISPATCH_STATE	3
-	movs	lr, tmp1
-	DISPATCH_NEXT
-        addmi	lr, lr, #3
-        mov	tmp2, lr, asr #2
-	sub	tmp2, tmp1, tmp2, lsl #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_5:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_5
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #1
-	add	lr, tmp2, tmp2, lsl #2
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_6:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_6
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        sub	tmp2, a4, tmp1, asr #31
-	add	lr, tmp2, tmp2, lsl #1
-	sub	tmp2, tmp1, lr, lsl #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_7:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_7
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #2
-	rsb	lr, tmp2, tmp2, lsl #3
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_8:
-	DISPATCH_STATE	3
-	movs	lr, tmp1
-	DISPATCH_NEXT
-        addmi	lr, lr, #7
-        mov	tmp2, lr, asr #3
-	sub	tmp2, tmp1, tmp2, lsl #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_9:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_9
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #1
-	add	lr, tmp2, tmp2, lsl #3
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_10:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_10
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	add	lr, tmp2, tmp2, lsl #2
-	sub	tmp2, tmp1, lr, lsl #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_11:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_11
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #1
-	add	lr, tmp2, tmp2, lsl #2
-	add	lr, tmp2, lr, lsl #1
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_12:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_12
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #1
-	add	lr, tmp2, tmp2, lsl #1
-	sub	tmp2, tmp1, lr, lsl #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_13:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_13
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	add	lr, tmp2, tmp2, lsl #1
-	add	lr, tmp2, lr, lsl #2
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_14:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_14
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #3
-	rsb	lr, tmp2, tmp2, lsl #3
-	sub	tmp2, tmp1, lr, lsl #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_15:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_15
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #3
-	rsb	lr, tmp2, tmp2, lsl #4
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_16:
-	DISPATCH_STATE	3
-	movs	lr, tmp1
-	DISPATCH_NEXT
-        addmi	lr, lr, #15
-        mov	tmp2, lr, asr #4
-	sub	tmp2, tmp1, tmp2, lsl #4
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_17:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_17
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	add	lr, tmp2, tmp2, lsl #4
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_18:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_18
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	add	lr, tmp2, tmp2, lsl #3
-	sub	tmp2, tmp1, lr, lsl #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_19:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_19
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	add	lr, tmp2, tmp2, lsl #3
-	add	lr, tmp2, lr, lsl #1
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_20:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_20
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	add	lr, tmp2, tmp2, lsl #2
-	sub	tmp2, tmp1, lr, lsl #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_21:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_21
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	add	lr, tmp2, tmp2, lsl #1
-	rsb	lr, lr, lr, lsl #3
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_22:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_22
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	add	lr, tmp2, tmp2, lsl #2
-	add	lr, tmp2, lr, lsl #1
-	sub	tmp2, tmp1, lr, lsl #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_23:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_23
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #4
-	add	lr, tmp2, tmp2, lsl #1
-	rsb	lr, tmp2, lr, lsl #3
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_24:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_24
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #2
-	add	lr, tmp2, tmp2, lsl #1
-	sub	tmp2, tmp1, lr, lsl #3
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_25:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_25
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	add	lr, tmp2, tmp2, lsl #2
-	add	lr, lr, lr, lsl #2
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_26:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_26
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	add	lr, tmp2, tmp2, lsl #1
-	add	lr, tmp2, lr, lsl #2
-	sub	tmp2, tmp1, lr, lsl #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_27:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_27
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	lr, tmp1, asr #31
-        rsb	tmp2, lr, a4, asr #3
-	add	lr, tmp2, tmp2, lsl #1
-	add	lr, lr, lr, lsl #3
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_28:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_28
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #4
-	rsb	lr, tmp2, tmp2, lsl #3
-	sub	tmp2, tmp1, lr, lsl #2
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_29:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_29
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #4
-	rsb	lr, tmp2, tmp2, lsl #3
-	add	lr, tmp2, lr, lsl #2
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_30:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_30
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #4
-	rsb	lr, tmp2, tmp2, lsl #4
-	sub	tmp2, tmp1, lr, lsl #1
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-.remc_31:
-	DISPATCH_STATE	3
-	ldr	tmp2, .dc_31
-	DISPATCH_NEXT
-        smull	lr, a4, tmp1, tmp2
-        mov	tmp2, tmp1, asr #31
-        add	lr, tmp1, a4
-        rsb	tmp2, tmp2, lr, asr #4
-	rsb	lr, tmp2, tmp2, lsl #5
-	sub	tmp2, tmp1, lr
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
+	POP	r1
+	POP	r0
+	cmp	r1, #0
+	beq	divide_by_zero_exception
+	bl	__aeabi_idivmod
+	PUSH	r1
+	DISPATCH 1
+
+	Opcode	irem_clz
+
+	POP	r1
+	POP	r0
+	bl	int_rem
+irem_clz_ret:
+	PUSH	r0
+	DISPATCH 1
 
 	Opcode	goto
         ldrsb   r1, [jpc, #1]
@@ -2622,6 +1168,46 @@
 	ble	do_backedge
 	DISPATCH_FINISH
 
+branch_taken_unsafe:
+	mov	r2, r2, lsl #24
+	orr	tmp1, r1, r2, asr #16
+        DISPATCH_START_REG	tmp1
+  USEC	cmp	tmp1, #0
+  USEC	ble	do_backedge
+	DISPATCH_FINISH
+
+branch_taken_unsafe_1:
+	add	jpc, jpc, #1
+	orr	tmp1, ip, r1, lsl #8
+        DISPATCH_START_REG	tmp1
+  USEC	cmp	tmp1, #0
+  USEC	ble	do_backedge
+	DISPATCH_FINISH
+
+branch_taken_unsafe_2:
+	add	jpc, jpc, #2
+	orr	tmp1, ip, r1, lsl #8
+        DISPATCH_START_REG	tmp1
+  USEC	cmp	tmp1, #0
+  USEC	ble	do_backedge
+	DISPATCH_FINISH
+
+branch_taken_unsafe_3:
+	add	jpc, jpc, #3
+	orr	tmp1, ip, r1, lsl #8
+        DISPATCH_START_REG	tmp1
+  USEC	cmp	tmp1, #0
+  USEC	ble	do_backedge
+	DISPATCH_FINISH
+
+branch_taken_unsafe_4:
+	add	jpc, jpc, #4
+	orr	tmp1, ip, r1, lsl #8
+        DISPATCH_START_REG	tmp1
+  USEC	cmp	tmp1, #0
+  USEC	ble	do_backedge
+	DISPATCH_FINISH
+
 do_backedge:
   USEC	ldr	tmp2, [istate, #ISTATE_METHOD]
   OSR	ldr	lr, [dispatch, #InterpreterInvocationLimit_Address-XXX]
@@ -2631,7 +1217,11 @@
   OSR	ldr	lr, [lr]
   USEC	add	ip, ip, #INVOCATIONCOUNTER_COUNTINCREMENT
   USEC	str	r1, [tmp2, #METHOD_BACKEDGECOUNTER]
+#ifdef THUMB2EE
+  OSR	cmp	r1, lr
+#else
   OSR	cmp	r1, lr, lsl #2
+#endif
   USEC	str	ip, [tmp2, #METHOD_INVOCATIONCOUNTER]
   OSR	bcs	do_osr
 
@@ -2645,23 +1235,37 @@
 
 
 do_synchronize:
-	add	r0, istate, #ISTATE_THREAD
-	bl	HandleMarkCleanerD
-	ldr	r0, [istate, #ISTATE_THREAD]
 	DECACHE_JPC
 	DECACHE_STACK
-	bl	_ZN20SafepointSynchronize5blockEP10JavaThread
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]
+	bl	Helper_SafePoint
 	CACHE_CP
-	ldr	r3, [r0, #THREAD_PENDING_EXC]
 	CACHE_JPC
-	cmp	r3, #0
+	cmp	r0, #0
 	bne	handle_exception
 	DISPATCH	0
 
 #ifdef ON_STACK_REPLACEMENT
+
+#ifdef THUMB2EE
+do_osr:
+	ldr	r3, [tmp2, #METHOD_CONSTMETHOD]
+	DECACHE_JPC
+	DECACHE_STACK
+	ldr	r0, [istate, #ISTATE_THREAD]
+	sub	r1, jpc, r3
+	sub	r1, r1, #CONSTMETHOD_CODEOFFSET
+	bl	FREQ_COUNT_OVERFLOW
+1:
+	cmp	r0, #0
+	bne	call_thumb2
+	CACHE_CP
+	CACHE_JPC
+	DISPATCH_START	0
+	b	osr_continue
+
+#else
+
 do_osr:
 	ldr	ip, [dispatch, #UseOnStackReplacement_Address-XXX]
 	ldrb	ip, [ip]
@@ -2680,15 +1284,13 @@
 	mov	r3, #1
 	ldr	r5, [tmp2]
 	str	r3, [tmp2]
-	bl	_ZN18InterpreterRuntime26frequency_counter_overflowEP10JavaThreadPh
+	bl	FREQ_COUNT_OVERFLOW
 	str	r5, [tmp2]
 	b	2f
 1:
-	bl	_ZN18InterpreterRuntime26frequency_counter_overflowEP10JavaThreadPh
+	bl	FREQ_COUNT_OVERFLOW
 2:
 	ldr	r3, [istate, #ISTATE_THREAD]
-	ASSERT_LOCALS_CACHED
-	ASSERT_STACK_CACHED
 	CACHE_CP
 	ldr	r1, [r3, #THREAD_PENDING_EXC]
 	CACHE_JPC
@@ -2702,13 +1304,9 @@
 1:
 	DISPATCH_START	0
 	b	osr_continue
-#endif
-
-#ifdef ON_STACK_REPLACEMENT
+
 osr_migrate:
 	ldr	tmp1, [r0, #128]	@ osr_method->osr_entry()
-	ldr	tmp2, [istate, #ISTATE_ADVANCE_PC]
-@	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
 	mov	r0, r3
 	bl	_ZN13SharedRuntime19OSR_migration_beginEP10JavaThread
 	mov	r1, r0
@@ -2730,32 +1328,11 @@
 	mov	lr, pc
 	ldr	pc, [tmp1]
 
-	cmp	tmp2, #0
-	ldmeqfd	arm_sp!, {regset, pc}
-
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
-        ldr	lr, [istate, #-ISTATE_NEXT_FRAME+ISTATE_THREAD]!
-        CACHE_JPC
-        ldr     stack, [lr, #THREAD_JAVA_SP]
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-        sub     stack, stack, #4
-
-        ldr     r1, [lr, #THREAD_TOP_ZERO_FRAME]
-        add     r2, r2, #4
-        str     r2, [lr, #THREAD_JAVA_SP]
-        str     r1, [lr, #THREAD_LAST_JAVA_SP]
-        ldr     r3, [lr, #THREAD_PENDING_EXC]
-        DISPATCH_START_REG tmp2
-        CACHE_LOCALS
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-        cmp     r3, #0
-        DISPATCH_NEXT
-        bne     return_exception
-	DISPATCH_NEXT
-        CACHE_CP
-	DISPATCH_FINISH
-#endif
+	ldmfd	arm_sp!, {fast_regset, pc}
+
+#endif // THUMB2EE
+
+#endif // ON_STACK_REPLACEMENT
 
 	Opcode	ifeq
 	Opcode	ifnull
@@ -2867,18 +1444,12 @@
 	ldr	r1, [r3]
 	cmp	r1, #1
 	bne	handle_return
-	add	r0, istate, #ISTATE_THREAD
-	bl	HandleMarkCleanerD
-	ldr	r0, [istate, #ISTATE_THREAD]
 	DECACHE_JPC
 	DECACHE_STACK
-	bl	_ZN20SafepointSynchronize5blockEP10JavaThread
 	ldr	r0, [istate, #ISTATE_THREAD]
-	ASSERT_STACK_CACHED
-	ldr	r3, [r0, #THREAD_PENDING_EXC]
+	bl	Helper_SafePoint
 	CACHE_JPC
-@ CACHE_LOCALS & CACHE_CP not require for handle_retuen / handle_exception
-	cmp	r3, #0
+	cmp	r0, #0
 	beq	handle_return
 	b	handle_exception
 
@@ -2889,8 +1460,6 @@
 	DECACHE_JPC
         DECACHE_STACK
        	bl      _ZN18InterpreterRuntime15resolve_get_putEP10JavaThreadN9Bytecodes4CodeE
-        ASSERT_STACK_CACHED
-        ASSERT_LOCALS_CACHED
         ldr     r0, [istate, #ISTATE_THREAD]
 	CACHE_JPC
         ldr     r3, [r0, #THREAD_PENDING_EXC]
@@ -3057,19 +1626,12 @@
 	stm	tmp2, {r2, r3}
 	DISPATCH 3
 putfield_a:
-	GET_STACK	1, r0
-	add	oop_address_tmp, r0, tmp2
-	POP	oop_value_tmp
-	cmp	r0, #0
+	POP	r2, r3
+	cmp	r3, #0
 	beq	null_ptr_exception
-	bl	oop_store
-    	ldr r3, [dispatch, #Universe_collectedHeap_Address-XXX]
-        POP     r2
-	ldr r3, [r3, #0]
-	ldr r3, [r3, #12]
-	ldr r3, [r3, #76]
-        mov     tmp2, #0
-        strb    tmp2, [r3, r2, lsr #9]
+	str	r2, [r3, tmp2]
+	mov	r0, r3
+	bl	Helper_aputfield
 	DISPATCH 3
 #endif
 
@@ -3134,21 +1696,11 @@
 	stm	r2, {r3, tmp2}
 	DISPATCH_FINISH
 putstatic_a:
-	POP	oop_value_tmp
-	add	oop_address_tmp, r3, r2
-	PUSH	r3
-       	bl      oop_store
-    ldr	r3, [dispatch, #Universe_collectedHeap_Address-XXX]
-	DISPATCH_START	3
-	POP	r2
-    ldr	r3, [r3]
-	DISPATCH_NEXT
-    ldr	r3, [r3, #12]
-	DISPATCH_NEXT
-        mov     tmp2, #0
-    ldr	r3, [r3, #76]
-        strb    tmp2, [r3, r2, lsr #9]
-	DISPATCH_FINISH
+	POP	tmp2
+	str	tmp2, [r3, r2]
+	mov	r0, r3
+	bl	Helper_aputfield
+	DISPATCH 3
 
 resolve_invokeinterface:
 	mov	r1, #opc_invokeinterface
@@ -3167,8 +1719,6 @@
 	DECACHE_JPC
 	DECACHE_STACK
 	bl	_ZN18InterpreterRuntime14resolve_invokeEP10JavaThreadN9Bytecodes4CodeE
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]
 	CACHE_JPC
 	ldr	r3, [r0, #4]
@@ -3185,109 +1735,17 @@
 # r1 = [jpc, #2]
 	Opcode	new
 	ldrb	r1, [jpc, #2]
-#define k_entry		tmp2
-#define new_result	r7
-#define top_addr	r7
-#define uch		r7
-#define obj_size	tmp1
-	ldr	r3, [istate, #ISTATE_METHOD]
-	orr	r2, r1, r2, lsl #8
-	ldr	lr, [r3, #METHOD_CONSTANTS]
-	ldr	r1, [lr, #CONSTANTPOOL_TAGS]
-	add	r1, r1, #12
-	ldrb	r3, [r1, r2]
-	cmp	r3, #JVM_CONSTANT_UnresolvedClassInError
-	cmpne	r3, #JVM_CONSTANT_UnresolvedClass
-	beq	.new_slow_case
-
-	add	r3, lr, #CONSTANTPOOL_BASE
-	ldr	k_entry, [r3, r2, lsl #2]
-
-	add	r1, k_entry, #KLASS_PART
-	ldr	r3, [r1, #INSTANCEKLASS_INITSTATE]
-	cmp	r3, #class_fully_initialized
-	bne	.new_slow_case
-	ldr	r3, [r1, #4]
-	tst	r3, #1
-	bne	.new_slow_case
-
-	mov	obj_size, r3, asr #2
-.new_retry:
-	ldr	r0, [dispatch, #Universe_collectedHeap_Address-XXX]
-	ldr	r0, [r0]
-	bl	CollectedHeap_top_addr
-	mov	top_addr, r0
-	ldr	r0, [dispatch, #Universe_collectedHeap_Address-XXX]
-	ldr	r0, [r0]
-	bl	CollectedHeap_end_addr
-	mov	r1, top_addr
-	ldr	new_result, [top_addr, #0]
-	add	ip, new_result, obj_size, lsl #2
-	ldr	r3, [r0, #0]
-	cmp	ip, r3
-	bhi	.new_slow_case
-	mov	r2, new_result
-	add	r0, new_result, obj_size, lsl #2
-	bl	cmpxchg_ptr
-	cmp	r0, new_result
-	bne	.new_retry
-	subs	r2, obj_size, #2
-@ ECN: sub optimimal memset
-	tst	r2, #1
-	add	r0, new_result, #8
-	mov	r1, #0
-	mov	ip, #0
-	strne	r1, [r0], #4
-	tst	r2, #2
-	mov	r3, #0
-	mov	lr, #0
-	stmneia	r0!, {r1, r3}
-	bics	r2, r2, #3
-	beq	.new_zero_done
-1:
-	subs	r2, r2, #4
-	stmia	r0!, {r1, r3, ip, lr}
-	bne	1b
-.new_zero_done:
-	ldr	r3, [dispatch, #always_do_update_barrier_Address-XXX]
-	mov	r2, #1
-	ldrb	r1, [r3]	@ zero_extendqisi2
-	str	r2, [new_result, #0]
-	cmp	r1, #0
-	bne	.new_do_update_barrier
-	str	k_entry, [new_result, #4]
-.new_exit:
-	str	new_result, [stack], #-4
-	CACHE_LOCALS
-	DISPATCH	3
-.new_do_update_barrier:
-	add	oop_address_tmp, new_result, #4
-@	mov	oop_value_tmp, k_entry		@ oop_value_tmp == k_entry
-	adr	lr, .new_exit
-	b	oop_store
-.new_slow_case:
-	ldrb	r2, [jpc, #1]
-	ldrb	r1, [jpc, #2]
-	ldr	r3, [istate, #ISTATE_METHOD]
 	DECACHE_JPC
 	DECACHE_STACK
-	orr	r2, r1, r2, lsl #8
-	ldr	r0, [istate, #ISTATE_THREAD]
-	ldr	r1, [r3, #METHOD_CONSTANTS]
-	bl	_ZN18InterpreterRuntime4_newEP10JavaThreadP19constantPoolOopDesci
-	ldr	r0, [istate, #ISTATE_THREAD]
-	ASSERT_STACK_CACHED
-	ldr	ip, [r0, #THREAD_PENDING_EXC]
+	orr	r1, r1, r2, lsl #8
+	mov	r0, r8
+	bl	Helper_new
 	CACHE_JPC
 	CACHE_CP
-	cmp	ip, #0
-	CACHE_LOCALS
-	bne	handle_exception
-	ldr	r2, [r0, #THREAD_VM_RESULT]
-	str	r2, [stack], #-4
-	ldr	r3, [istate, #ISTATE_THREAD]
-	str	ip, [r3, #THREAD_VM_RESULT]
-	DISPATCH	3
+	cmp	r0, #0
+	beq	handle_exception
+	PUSH	r0
+	DISPATCH 3
 
 bytecode_interpreter_str:
 	.ascii  "[Bytecode Interpreter]\000"
@@ -3300,8 +1758,6 @@
 	DECACHE_JPC
 	DECACHE_STACK
 	bl	_ZN18InterpreterRuntime8newarrayEP10JavaThread9BasicTypei
-	ASSERT_LOCALS_CACHED
-	ASSERT_STACK_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]
 	CACHE_JPC
 	ldr	ip, [r0, #THREAD_PENDING_EXC]
@@ -3324,8 +1780,6 @@
 	ldr	r1, [lr, #METHOD_CONSTANTS]
 	ldr	r0, [istate, #ISTATE_THREAD]
 	bl	_ZN18InterpreterRuntime9anewarrayEP10JavaThreadP19constantPoolOopDescii
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]
 	CACHE_JPC
 	ldr	ip, [r0, #THREAD_PENDING_EXC]
@@ -3370,174 +1824,34 @@
 # r1 = [jpc, #2]
 	Opcode	checkcast
 	ldrb	r1, [jpc, #2]
-	ldr	r3, [istate, #ISTATE_METHOD]
-	ldr	r0, [stack, #4]
-	ldr	r3, [r3, #METHOD_CONSTANTS]		@ R3 = METHOD->constants()
-	cmp	r0, #0
-	ldr	ip, [r3, #CONSTANTPOOL_TAGS]
-	beq	.checkcast_exit
-	add	ip, ip, #12
-	orr	tmp2, r1, r2, lsl #8
-	ldrb	r2, [ip, tmp2]	@ zero_extendqisi2
-	cmp	r2, #JVM_CONSTANT_UnresolvedClassInError
-	cmpne	r2, #JVM_CONSTANT_UnresolvedClass
-	beq	3f
-
-4:
-	ldr	r0, [r0, #4]
-	add	r3, r3, tmp2, lsl #2
-	ldr	tmp1, [r3, #CONSTANTPOOL_BASE]
-	cmp	tmp1, r0
-	beq	.checkcast_exit
-
-	ldr	r2, [tmp1, #16]
-	add	tmp2, r0, #8
-	add	ip, tmp2, r2
-	ldr	ip, [ip, #-8]
-	cmp	ip, tmp1
-	beq	.checkcast_exit
-
-	cmp	r2, #secondary_super_cache_offset_in_bytes
-	bne	2f
-
-	mov	r0, tmp2
-	mov	r1, tmp1
-
-	bl	_ZNK5Klass23search_secondary_supersEP12klassOopDesc
-	cmp	r0, #0
-	beq	2f
-.checkcast_exit:
-	DISPATCH	3
-
-3:
-	ldr	r0, [istate, #ISTATE_THREAD]
 	DECACHE_JPC
 	DECACHE_STACK
-	bl	_ZN18InterpreterRuntime13quicken_io_ccEP10JavaThread
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
-	ldr	r0, [istate, #ISTATE_THREAD]
+	orr	r1, r1, r2, lsl #8
+	mov	r0, r8
+	GET_STACK	0, r2
+	bl	Helper_checkcast
 	CACHE_JPC
-	ldr	r3, [r0, #THREAD_PENDING_EXC]
 	CACHE_CP
-	cmp	r3, #0
-	ldr	r3, [istate, #ISTATE_METHOD]
+	cmp	r0, #0
 	bne	handle_exception
-	ldr	r0, [stack, #4]
-	ldr	r3, [r3, #METHOD_CONSTANTS]		@ METHOD->constanst() might have moved
-	b	4b
-
-2:
-	DECACHE_JPC
-	DECACHE_STACK
-	mov	r0, tmp2
-	ldr	r3, [istate, #ISTATE_THREAD]
-	ldr	tmp2, [r3, #THREAD_RESOURCEAREA]
-
-	ldr	tmp_chunk, [tmp2, #RESOURCEAREA_CHUNK]
-	ldr	tmp_hwm, [tmp2, #RESOURCEAREA_HWM]
-	ldr	tmp_max, [tmp2, #RESOURCEAREA_MAX]
-
-	bl	_ZNK5Klass13external_nameEv
-	mov	ip, r0
-	add	r0, tmp1, #8
-	mov	tmp1, ip
-	bl	_ZNK5Klass13external_nameEv
-	mov	r1, r0
-	mov	r0, tmp1
-	bl	SharedRuntime_generate_class_cast_message
-	str	r0, [arm_sp, #0]
-	ldr	r0, [istate, #ISTATE_THREAD]
-	adrl	r1, bytecode_interpreter_str
-	mov	r2, #99
-	mov	r3, #_thread_in_vm
-	str	r3, [r0, #THREAD_STATE]
-	ldr	r3, [dispatch, #VmSymbols_symbols_Address-XXX]
-	ldr	r3, [r3, #VMSYMBOLS_ClassCastException * 4]
-	bl	_ZN10Exceptions10_throw_msgEP6ThreadPKciP13symbolOopDescS3_
-	add	r0, istate, #ISTATE_THREAD
-	bl	ThreadInVMfromJavaD
-	mov	r0, tmp_chunk
-	ldr	r3, [r0, #0]
-	CACHE_JPC
-	cmp	r3, #0
-	beq	1f
-	bl	_ZN5Chunk9next_chopEv
-1:
-	str	tmp_hwm, [tmp2, #RESOURCEAREA_HWM]
-	str	tmp_max, [tmp2, #RESOURCEAREA_MAX]
-	str	tmp_chunk, [tmp2, #RESOURCEAREA_CHUNK]
-	b	handle_exception
+	DISPATCH 3
 
 # r2 = [jpc, #1]
 # r1 = [jpc, #2]
 	Opcode	instanceof
 	ldrb	r1, [jpc, #2]
-	ldr	r3, [istate, #ISTATE_METHOD]
-	ldr	r0, [stack, #4]
-	ldr	r3, [r3, #METHOD_CONSTANTS]
-	cmp	r0, #0
-	ldr	ip, [r3, #CONSTANTPOOL_TAGS]
-	beq	.instanceof_not_instance
-	add	ip, ip, #BASE_OFFSET_BYTE
-	orr	tmp2, r1, r2, lsl #8
-	ldrb	r2, [ip, tmp2]
-	cmp	r2, #JVM_CONSTANT_UnresolvedClassInError
-	cmpne	r2, #JVM_CONSTANT_UnresolvedClass
-	beq	2f
-
-1:
-	ldr	r0, [r0, #4]
-	add	r3, r3, tmp2, lsl #2
-	ldr	tmp1, [r3, #CONSTANTPOOL_BASE]
-	cmp	tmp1, r0
-	beq	.instanceof_is_instance
-
-	ldr	r2, [tmp1, #16]
-	add	tmp2, r0, #8
-	add	ip, tmp2, r2
-	ldr	ip, [ip, #-8]
-	cmp	ip, tmp1
-	beq	.instanceof_is_instance
-
-	mov	r0, #0
-	cmp	r2, #secondary_super_cache_offset_in_bytes
-	bne	.instanceof_not_instance
-
-	mov	r0, tmp2
-	mov	r1, tmp1
-
-	bl	_ZNK5Klass23search_secondary_supersEP12klassOopDesc
-	cmp	r0, #0
-	beq	.instanceof_not_instance
-
-.instanceof_is_instance:
-	mov	r0, #1
-	str	r0, [stack, #4]
-	DISPATCH	3
-.instanceof_not_instance:
-	mov	r0, #0
-	str	r0, [stack, #4]
-	DISPATCH	3
-
-2:
-	ldr	r0, [istate, #ISTATE_THREAD]
 	DECACHE_JPC
 	DECACHE_STACK
-	bl	_ZN18InterpreterRuntime13quicken_io_ccEP10JavaThread
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
-	ldr	r0, [istate, #ISTATE_THREAD]
+	orr	r1, r1, r2, lsl #8
+	mov	r0, r8
+	POP	r2
+	bl	Helper_instanceof
 	CACHE_JPC
-	ldr	r3, [r0, #THREAD_PENDING_EXC]
 	CACHE_CP
-	cmp	r3, #0
-	bne	handle_exception
-
-	ldr	r3, [istate, #ISTATE_METHOD]
-	ldr	r0, [stack, #4]
-	ldr	r3, [r3, #METHOD_CONSTANTS]		@ METHOD->constanst() might have moved
-	b	1b
+	cmp	r0, #-1
+	beq	handle_exception
+	PUSH	r0
+	DISPATCH 3
 
 	Opcode	monitorenter
 	ldr	r1, [stack, #4]
@@ -3583,8 +1897,6 @@
 	DECACHE_STACK
 	ldr	r0, [istate, #ISTATE_THREAD]
 	bl	_ZN18InterpreterRuntime12monitorenterEP10JavaThreadP15BasicObjectLock
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]
 	CACHE_JPC
 	ldr	r3, [r0, #THREAD_PENDING_EXC]
@@ -3640,7 +1952,6 @@
 	ldr	sl, [istate, #ISTATE_STACK_BASE]
 	ldr	r3, [stack, #4]
 	CACHE_JPC
-	ASSERT_LOCALS_CACHED
 	mov	r1, r3
 	str	r3, [sl, #4]
 	ldr	r2, [r3, #0]
@@ -3663,8 +1974,6 @@
 	DECACHE_JPC
 	DECACHE_STACK
 	bl	_ZN18InterpreterRuntime12monitorenterEP10JavaThreadP15BasicObjectLock
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]
 	CACHE_JPC
 	ldr	r3, [r0, #THREAD_PENDING_EXC]
@@ -3710,8 +2019,6 @@
 	ldr	r0, [istate, #ISTATE_THREAD]
 	bl	_ZN18InterpreterRuntime11monitorexitEP10JavaThreadP15BasicObjectLock
 	ldr	r0, [istate, #ISTATE_THREAD]
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
 	ldr	r3, [r0, #THREAD_PENDING_EXC]
 	CACHE_JPC
 	cmp	r3, #0
@@ -3740,39 +2047,16 @@
 	ALIGN_WORD
 
 	Opcode	aastore
-	ldr	tmp1, [stack, #12]	@ arrObj
-	ldr	tmp_vvv, [stack, #8]
-	SW_NPC	cmp	tmp1, #0
-	ldr	sl, [stack, #4]
-	SW_NPC	beq	null_ptr_exception
-.abortentry115:
-	ldr	r3, [tmp1, #8]
-	cmp	tmp_vvv, r3
-	bcs	array_bounds_exception
-	cmp	sl, #0
-	beq	.aastore_exit
-	ldr	r3, [tmp1, #4]		@ arrObj->klass()
-	ldr	r0, [sl, #4]
-	ldr	r1, [r3, #KLASS_PART+OBJARRAYKLASS_ELEMENTKLASS]
-	cmp	r0, r1
-	beq	.aastore_exit
-	add	r0, r0, #8
-	bl	is_subtype_of
+	DECACHE_JPC
+	DECACHE_STACK
+	mov	r0, r8
+	POP	r1, r2, r3
+	bl	Helper_aastore
+	CACHE_JPC
+	CACHE_CP
 	cmp	r0, #0
-	moveq	r0, #VMSYMBOLS_ArrayStoreException
-	beq	raise_exception
-.aastore_exit:
-    ldr r2, [dispatch, #Universe_collectedHeap_Address-XXX]
-	add	r1, tmp1, #BASE_OFFSET_WORD
-	str	sl, [r1, tmp_vvv, asl #2]!
-    ldr	r3, [r2]
-	mov	lr, #0
-    ldr	r3, [r3, #12]
-	add	stack, stack, #12
-    ldr	r3, [r3, #76]
-	strb	lr, [r3, r1, lsr #9]
-	CACHE_CP
-	DISPATCH	1
+	bne	handle_exception
+	DISPATCH 1
 
 	Opcode	wide
 	ldrb	r2, [jpc, #1]
@@ -3862,8 +2146,6 @@
 	DECACHE_JPC
 	DECACHE_STACK
 	bl	_ZN18InterpreterRuntime14multianewarrayEP10JavaThreadPi
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]
 	CACHE_JPC
 	ldr	r1, [r0, #THREAD_PENDING_EXC]
@@ -3901,19 +2183,13 @@
 	ldr	r1, [r3]
 	cmp	r1, #1
 	bne	1f
-	add	r0, istate, #ISTATE_THREAD
-	bl	HandleMarkCleanerD
-	ldr	r0, [istate, #ISTATE_THREAD]
 	DECACHE_JPC
 	DECACHE_STACK
-	bl	_ZN20SafepointSynchronize5blockEP10JavaThread
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]
+	bl	Helper_SafePoint
 	CACHE_JPC
-	ldr	r3, [r0, #THREAD_PENDING_EXC]
 	CACHE_CP
-	cmp	r3, #0
+	cmp	r0, #0
 	bne	handle_exception
 1:
 	DISPATCH	0
@@ -3933,8 +2209,6 @@
 	ldr	r2, [istate, #ISTATE_BCP]
 	ldr	r1, [istate, #ISTATE_METHOD]
 	bl	_ZN18InterpreterRuntime11_breakpointEP10JavaThreadP13methodOopDescPh
-	ASSERT_STACK_CACHED
-	ASSERT_LOCALS_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]
 	CACHE_JPC
 	ldr	r3, [r0, #THREAD_PENDING_EXC]
@@ -3986,7 +2260,7 @@
 	ldrcc	ip, [r2, r3, asl #2]
 	adr	r2, unimplemented_opcode_msg
 	mov	r1, #99
-	str	ip, [arm_sp, #0]
+	str	ip, [arm_sp, #-8]!
 	bl	_Z19report_fatal_varargPKciS0_z
 	b	breakpoint
 unimplemented_opcode_msg:
@@ -4005,7 +2279,6 @@
 	DECACHE_STACK
 	ldr	r0, [istate, #ISTATE_THREAD]
 	bl	_ZN18InterpreterRuntime18register_finalizerEP10JavaThreadP7oopDesc
-	ASSERT_STACK_CACHED
 	ldr	r0, [istate, #ISTATE_THREAD]
 	CACHE_JPC
 	ldr	r3, [r0, #THREAD_PENDING_EXC]
@@ -4014,11 +2287,16 @@
 	beq	handle_return
 	b	handle_exception
 
-@ ECN: normal_entry_synchronized doesn't really mean synchronized. It means
-@ may or may not be synchronized. So we still have to check the synchronized
-@ flag in the synchronized path, otherwise we may get an IllegalMonitor.
+	ALIGN_CODE
 normal_entry_synchronized:
 	stmfd	arm_sp!, {regset, lr}
+	bl	fast_normal_entry_synchronized
+	ldmfd	arm_sp!, {regset, pc}
+
+	ALIGN_CODE
+fast_normal_entry_synchronized:
+	stmfd	arm_sp!, {fast_regset, lr}
+
 	mov	sl, r0
 	mov	tmp1, r2
 
@@ -4027,7 +2305,7 @@
 	rsb	r3, r0, r3
 	rsb	r3, r3, arm_sp
 	cmp	r3, #32768
-	blt	stack_overflow_no_frame
+	blt	stack_overflow_before_frame
 
 	ldrh	r2, [sl, #METHOD_MAXLOCALS]
 	ldrh	r3, [sl, #METHOD_SIZEOFPARAMETERS]
@@ -4041,7 +2319,7 @@
 	sub	r5, r5, #FRAME_SIZE+4
 	sub	r5, r5, r0, lsl #2
 	cmp	r3, r5
-	bcs	stack_overflow_no_frame
+	bcs	stack_overflow_before_frame
 
 	cmp	r8, #0
 	ble	.normal_entry_synchronized_no_locals
@@ -4067,61 +2345,17 @@
 	ldm	ip, {r0, r1}
 	add	r0, r0, ip
 	str	tmp_vvv, [tmp1, #THREAD_TOP_ZERO_FRAME]
-	CACHE_JPC
+@	CACHE_JPC
 	str	tmp_vvv, [tmp1, #THREAD_LAST_JAVA_SP]
 	add	dispatch, r1, r0
 	ldr	r0, [istate, #ISTATE_METHOD]
-	CACHE_STACK
-  USEC	ldr	r2, [r0, #METHOD_INVOCATIONCOUNTER]
-  USEC	ldr	lr, [dispatch, #InterpreterInvocationLimit_Address-XXX]
-  USEC	add	r2, r2, #INVOCATIONCOUNTER_COUNTINCREMENT
-  USEC	ldr	lr, [lr]
-  USEC	str	r2, [r0, #METHOD_INVOCATIONCOUNTER]
-  USEC	cmp	r2, lr
 	ldr	r3, [r0, #METHOD_ACCESSFLAGS]
-  USEC	bcs	sync_method_entry_freq_count_overflow
-	CACHE_LOCALS
 	tst	r3, #JVM_ACC_SYNCHRONIZED
-	CACHE_CP
-	bne	normal_do_synchronization
-	DISPATCH	0
-
-#ifdef USE_COMPILER
-sync_method_entry_freq_count_overflow:
-        ldr     r3, [r0, #METHOD_CONSTMETHOD]
-        ldrh    r3, [r3, #CONSTMETHOD_CODESIZE]
-	mov	r1, #0
-	mov	r0, tmp1
-        cmp     r3, #MAX_FG_METHOD_SIZE
-        bcc     1f
-        ldr     tmp2, [dispatch, #BackgroundCompilation_Address-XXX]
-        mov     r3, #1
-        ldr     r5, [tmp2]
-        str     r3, [tmp2]
-        bl      _ZN18InterpreterRuntime26frequency_counter_overflowEP10JavaThreadPh
-        str     r5, [tmp2]
-        b       2f
-1:
-	bl	_ZN18InterpreterRuntime26frequency_counter_overflowEP10JavaThreadPh
-2:
-	ldr	r0, [istate, #ISTATE_METHOD]
-	CACHE_JPC
-	ldr	r3, [r0, #METHOD_ACCESSFLAGS]
+	beq	1f
+
+@ Do Synchronisation
+	CACHE_STACK
 	CACHE_LOCALS
-	tst	r3, #JVM_ACC_SYNCHRONIZED
-	CACHE_CP
-	bne	normal_do_synchronization
-	DISPATCH	0
-#endif
-
-do_execute_java_bytecodes_restore_locals_and_jpc:
-	CACHE_JPC
-do_execute_java_bytecodes_restore_locals:
-	CACHE_LOCALS
-	CACHE_CP
-	DISPATCH	0
-
-normal_do_synchronization:
 	tst	r3, #JVM_ACC_STATIC
 	ldrne	r3, [r0, #METHOD_CONSTANTS]
 	ldreq	sl, [locals, #0]
@@ -4143,9 +2377,8 @@
 	blx	r3
 	cmp	r0, #0
 	bne	.normal_do_synchronisation_2
+	b	1f
 .normal_do_synchronisation_3:
-	cmp	tmp_xxx, tmp_vvv
-	beq	do_execute_java_bytecodes_restore_locals
 	ldr	r0, [istate, #ISTATE_THREAD]
 	bic	r1, tmp_xxx, #3
 	bl	JavaThread_is_lock_owned
@@ -4153,19 +2386,56 @@
 	beq	.normal_do_synchronisation_4
 	mov	r3, #0
 	str	r3, [tmp1]
-	b	do_execute_java_bytecodes_restore_locals
+	b	1f
 .normal_do_synchronisation_4:
 	mov	r1, tmp1
 	DECACHE_STACK
 	ldr	r0, [istate, #ISTATE_THREAD]
 	bl	_ZN18InterpreterRuntime12monitorenterEP10JavaThreadP15BasicObjectLock
 	ldr	r0, [istate, #ISTATE_THREAD]
-	ASSERT_STACK_CACHED
 	ldr	r3, [r0, #THREAD_PENDING_EXC]
 	cmp	r3, #0
 	mov	r2, r0
-	beq	do_execute_java_bytecodes_restore_locals_and_jpc
-	b	handle_exception_do_not_unlock
+	bne	handle_exception_do_not_unlock
+1:
+  USEC ldr	r0, [istate, #ISTATE_METHOD]
+  USEC	ldr	r2, [r0, #METHOD_INVOCATIONCOUNTER]
+  USEC	ldr	lr, [dispatch, #InterpreterInvocationLimit_Address-XXX]
+  USEC	add	r2, r2, #INVOCATIONCOUNTER_COUNTINCREMENT
+  USEC	ldr	lr, [lr]
+  USEC	str	r2, [r0, #METHOD_INVOCATIONCOUNTER]
+  USEC	cmp	r2, lr
+  USEC	bcs	sync_method_entry_freq_count_overflow
+	CACHE_JPC
+	CACHE_LOCALS
+	CACHE_CP
+	DISPATCH	0
+
+#ifdef USE_COMPILER
+sync_method_entry_freq_count_overflow:
+        ldr     r3, [r0, #METHOD_CONSTMETHOD]
+        ldrh    r3, [r3, #CONSTMETHOD_CODESIZE]
+	mov	r1, #0
+	ldr	r0, [istate, #ISTATE_THREAD]
+        cmp     r3, #MAX_FG_METHOD_SIZE
+        bcc     1f
+        ldr     tmp2, [dispatch, #BackgroundCompilation_Address-XXX]
+        mov     r3, #1
+        ldr     r5, [tmp2]
+        str     r3, [tmp2]
+        bl      FREQ_COUNT_OVERFLOW
+        str     r5, [tmp2]
+        b       2f
+1:
+	bl	FREQ_COUNT_OVERFLOW
+2:
+  T2	cmp	r0, #0
+	CACHE_LOCALS
+  T2	bne	call_thumb2
+	CACHE_JPC
+	CACHE_CP
+	DISPATCH	0
+#endif
 
 # r2 = [jpc, #1]
 # r1 = [jpc, #2]
@@ -4213,12 +2483,11 @@
 	ldr	r2, [r1, #-4]
 	add	r3, tmp2, r3, lsl #2
 	ldr	tmp2, [r3, r2]
-	SW_NPC	cmp	tmp2, #0
-	SW_NPC	beq	abstractmethod_exception
+	cmp	tmp2, #0
+	beq	abstractmethod_exception
 .invokeinterface_invoke:
 	ldr	tmp1, [istate, #ISTATE_THREAD]
 @	str	tmp2, [istate, #ISTATE_CALLEE]
-.abortentry116:
 	ldr	ip, [tmp2, #METHOD_FROM_INTERPRETED]
 	mov	r1, #0
 	str	ip, [istate, #36]
@@ -4229,20 +2498,20 @@
 
 	ldr	r3, [ip]
 
-	mov	tmp_invoke_len, #5
-
-#ifdef FASTPATH_ENTRY
-	adr	r0, normal_entry
-	cmp	r3, r0
-	beq	fast_normal_entry_with_len
-#endif
-
 	mov	r0, tmp2
 	mov	r1, ip
+#ifndef SHARK
+	add	r3, r3, #CODE_ALIGN_SIZE
+#endif
 	mov	r2, tmp1
 	blx	r3
 
-	ASSERT_LOCALS_CACHED
+	adrl	ip, dispatch_init_adcon
+	ldm	ip, {r0, r1}
+	add	r0, r0, ip
+	add	dispatch, r1, r0
+
+	CACHE_LOCALS
 
 	ldr	ip, [istate, #ISTATE_THREAD]
 	CACHE_JPC
@@ -4304,19 +2573,6 @@
 	str	stack, [tmp1, #THREAD_JAVA_SP]
 
 	ldr	r3, [ip, #0]
-#ifdef FASTPATH_ENTRY
-	adr	r0, normal_entry
-	cmp	r3, r0
-	beq	fast_normal_entry
-#ifdef NATIVE_ENTRY
-	adrl	r0, native_entry
-	cmp	r3, r0
-	beq	fast_native_entry
-#endif
-	adr	r0, accessor_entry
-	cmp	r3, r0
-	beq	fast_accessor_entry
-#endif
 	b	normal_dispatch_and_return
 #endif // FAST_BYTECODES
 
@@ -4389,28 +2645,22 @@
         str     stack, [tmp1, #THREAD_JAVA_SP]
 
         ldr     r3, [ip, #0]
-#ifdef FASTPATH_ENTRY
-        adr     r0, normal_entry
-        cmp     r3, r0
-        beq     fast_normal_entry
-#ifdef NATIVE_ENTRY
-        adr     r0, native_entry
-        cmp     r3, r0
-        beq     fast_native_entry
-#endif
-        adr     r0, accessor_entry
-        cmp     r3, r0
-        beq     fast_accessor_entry
-#endif
 
 normal_dispatch_and_return:
 	mov	r0, tmp2
 	mov	r1, ip
+#ifndef SHARK
+	add	r3, r3, #CODE_ALIGN_SIZE
+#endif
 	mov	r2, tmp1
-	ldr	r2, [istate, #ISTATE_THREAD]
 	blx	r3
 
-	ASSERT_LOCALS_CACHED
+	adrl	ip, dispatch_init_adcon
+	ldm	ip, {r0, r1}
+	add	r0, r0, ip
+	add	dispatch, r1, r0
+
+	CACHE_LOCALS
 
 	ldr	ip, [istate, #ISTATE_THREAD]
 	CACHE_JPC
@@ -4464,48 +2714,8 @@
 
 	ldr	ip, [istate, #36]
 	ldr	r3, [ip, #0]
-#ifdef FASTPATH_ENTRY
-	adr	r0, normal_entry
-	cmp	r3, r0
-	beq	fast_normal_entry
-#ifdef NATIVE_ENTRY
-	adr	r0, native_entry
-	cmp	r3, r0
-	beq	fast_native_entry
-#endif
-	adr	r0, accessor_entry
-	cmp	r3, r0
-	beq	fast_accessor_entry
-#endif
 	b	normal_dispatch_and_return
 
-	ALIGN_CODE
-normal_entry:
-	adrl	ip, dispatch_init_adcon
-	stmfd	arm_sp!, {regset, lr}
-	mov	tmp2, r0
-	ldm	ip, {r0, r1}
-
-	mov	tmp_invoke_len, #0
-	mov	tmp1, r2
-
-	add	r0, r0, ip
-	add	dispatch, r1, r0
-
-  USEC  ldr     r2, [r10, #METHOD_INVOCATIONCOUNTER]
-
-	ldr	stack, [tmp1, #THREAD_JAVA_SP]
-
-	ldr	r0, [tmp1, #THREAD_STACK_SIZE]
-  USEC  add     r2, r2, #INVOCATIONCOUNTER_COUNTINCREMENT * 4
-	ldr	r3, [tmp1, #THREAD_STACK_BASE]
-	rsb	r3, r0, r3
-	rsb	r3, r3, arm_sp
-  USEC  str     r2, [tmp2, #METHOD_INVOCATIONCOUNTER]
-	cmp	r3, #32768
-	bge	fast_normal_entry_with_len
-
-	b	stack_overflow_before_frame
 
 	Opcode	invokespecial
      	ldrb	r1, [jpc, #2]
@@ -4546,81 +2756,35 @@
 	str	stack, [tmp1, #THREAD_JAVA_SP]
 
 	ldr	r3, [ip, #0]
-#ifdef FASTPATH_ENTRY
-	adr	r0, normal_entry
-	cmp	r3, r0
-	beq	fast_normal_entry
-#ifdef NATIVE_ENTRY
-	adr	r0, native_entry
-	cmp	r3, r0
-	beq	fast_native_entry
-#endif
-	adr	r0, accessor_entry
-	cmp	r3, r0
-	beq	fast_accessor_entry
-#endif
 	b	normal_dispatch_and_return
 
 	ALIGN_CODE
-accessor_entry:
-	adrl	ip, dispatch_init_adcon
-	ldr	r3, [ip]
-	add	r3, r3, ip
-	ldr	ip, [ip, #12]
-	ldr	ip, [r3, ip]
-	ldr	r1, [r0, #8]
-	ldr	ip, [ip, #0]
-	ldrb	r3, [r1, #50]
-	ldrb	r1, [r1, #51]
-	cmp	ip, #0
-	ldr	ip, [r0, #12]
-	bne	normal_entry
-	ldr	ip, [ip, #12]
-	orr	r3, r3, r1, lsl #8		@ r3 = index
-
-	add	r1, ip, #16
-	ldr	r3, [r1, r3, lsl #4]!		@ r1 = cache, r3 = flags
-	ldr	ip, [r2, #THREAD_JAVA_SP]			@ ip == stack
-	and	r3, r3, #0x00ff0000
-	cmp	r3, #opc_getfield << 16
-	ldr	r3, [ip, #0]
-	bne	normal_entry
-
-	cmp	r3, #0
-	beq	normal_entry
-
-	ldr	r0, [r1, #12]
-	ldr	r1, [r1, #8]
-	movs	r0, r0, lsr #29
-	bls	accessor_non_w
-
-	ldr	r0, [r3, r1]
-	str	r0, [ip, #0]
-	bx	lr
-
-#ifdef NATIVE_ENTRY
-	ALIGN_CODE
-native_entry:
-	adrl	ip, dispatch_init_adcon
-	stmfd	arm_sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
-
-	ldm	ip, {dispatch, r7}
-	mov	r11, r0
-	add	dispatch, dispatch, ip
-	add	dispatch, dispatch, r7
-
-	mov	istate, #0
-
-	b	fast_native_entry_with_args
-#endif
-
-@ tmp1 = thread
-@ tmp2 == method
-@ stack == THREAD_JAVA_SP (=> FULL stack)
+normal_entry:
+	stmfd	arm_sp!, {regset, lr}
+
+	ldr	r7, [r2, #THREAD_STACK_SIZE]
+	ldr	r3, [r2, #THREAD_STACK_BASE]
+	rsb	r3, r7, r3
+	rsb	r3, r3, arm_sp
+	cmp	r3, #32768
+	blt	stack_overflow_no_frame
+
+	bl	fast_normal_entry
+
+	ldmfd	arm_sp!, {regset, pc}
+
 	ALIGN_CODE
 fast_normal_entry:
-	mov	tmp_invoke_len, #3
-fast_normal_entry_with_len:
+	adrl	ip, dispatch_init_adcon
+	mov	tmp2, r0
+	ldm	ip, {r0, r1}
+	mov	tmp1, r2
+	add	r0, r0, ip
+	ldr	stack, [tmp1, #THREAD_JAVA_SP]
+	add	dispatch, r1, r0
+
+	stmdb	arm_sp!, {fast_regset, lr}
+
 	ldrh	r0, [tmp2, #METHOD_MAXLOCALS]
 	mov	r1, #0
 	ldrh	r3, [tmp2, #METHOD_SIZEOFPARAMETERS]
@@ -4646,9 +2810,10 @@
         bcs     1b
 3:
 	ldr	r3, [tmp1, #THREAD_TOP_ZERO_FRAME]
+	mov	lr, #0
         sub     istate, stack, #FRAME_SIZE
         sub     r2, istate, r2, lsl #2
-        str     tmp_invoke_len, [istate, #ISTATE_ADVANCE_PC]
+        str     lr, [istate, #ISTATE_MSG]
 	str	r2, [tmp1, #THREAD_JAVA_SP]
         sub     r5, r2, #4                      @ stack limit = istate - stackwords - 4
 	str	r3, [istate, #ISTATE_NEXT_FRAME]
@@ -4664,7 +2829,7 @@
         ldr     jpc, [tmp2, #METHOD_CONSTMETHOD]
         ldr     constpool, [tmp2, #METHOD_CONSTANTS]
         add     ip, istate, #ISTATE_NEXT_FRAME
-	DISPATCH_START	48
+	DISPATCH_START	CONSTMETHOD_CODEOFFSET
         ldr     constpool, [constpool, #CONSTANTPOOL_CACHE]
         str     ip, [tmp1, #THREAD_TOP_ZERO_FRAME]
   USEC	ldr	r3, [r10, #METHOD_INVOCATIONCOUNTER]
@@ -4701,22 +2866,35 @@
         mov     r3, #1
         ldr     r5, [tmp2]
         str     r3, [tmp2]
-        bl      _ZN18InterpreterRuntime26frequency_counter_overflowEP10JavaThreadPh
+        bl      FREQ_COUNT_OVERFLOW
         str     r5, [tmp2]
         b       2f
 1:
-	bl	_ZN18InterpreterRuntime26frequency_counter_overflowEP10JavaThreadPh
+	bl	FREQ_COUNT_OVERFLOW
 2:
+ T2	cmp	r0, #0
+ T2	bne	call_thumb2
 	CACHE_JPC
 	CACHE_CP
 	DISPATCH	0
-#endif
-
+
+#ifdef THUMB2EE
+call_thumb2:
+	mov	ip, r1
+	mov	r1, locals
+	ldr	r2, [istate, #ISTATE_THREAD]
+	add	stack, stack, #4
+	bx	ip
+#endif // THUMB2EE
+
+#endif // USE_COMPILER
+	.global	Thumb2_Install
+Thumb2_Install:
+@	ldr	r0, [r0]
+	str	r1, [r0, #METHOD_FROM_INTERPRETED]
+	bx	lr
 
 handle_return:
-@	CHECK_CONSTPOOL
-@	CHECK_BACKTRACE
-
 	ldr	tmp2, [istate, #ISTATE_MONITOR_BASE]	@ tmp2 = base
 
 	ldr	tmp1, [istate, #ISTATE_STACK_BASE]	@ tmp1 = end
@@ -4725,9 +2903,6 @@
 	cmp	tmp1, tmp2
 	blcc	return_check_monitors
 
-@	CHECK_CONSTPOOL
-@	CHECK_BACKTRACE
-
 	mov	r3, #0
 	ldrb	lr, [jpc, #0]
 
@@ -4739,9 +2914,6 @@
 	add	r1, r2, #4
 	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
 
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
-
 	add	r1, r1, r0, lsl #2
 
 	cmp	lr, #opc_lreturn
@@ -4756,152 +2928,27 @@
 
 	str	r1, [tmp_xxx, #THREAD_JAVA_SP]
 
-	cmp	ip, #0
-
-	ldmeqfd	arm_sp!, {regset, pc}
-
-        ldr	lr, [istate, #-ISTATE_NEXT_FRAME+ISTATE_THREAD]!
-        CACHE_JPC
-        ldr     stack, [lr, #THREAD_JAVA_SP]
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-        sub     stack, stack, #4
-
-        ldr     r1, [lr, #THREAD_TOP_ZERO_FRAME]
-        add     r2, r2, #4
-        str     r2, [lr, #THREAD_JAVA_SP]
-        str     r1, [lr, #THREAD_LAST_JAVA_SP]
-        ldr     r3, [lr, #THREAD_PENDING_EXC]
-        DISPATCH_START_REG ip
-        CACHE_LOCALS
-        DISPATCH_NEXT
-        DISPATCH_NEXT
-        cmp     r3, #0
-        DISPATCH_NEXT
-        bne     return_exception
-	DISPATCH_NEXT
-        CACHE_CP
-        DISPATCH_FINISH
-
-@ ip = PC ADVANCE
-fast_handle_return:
-        ldr	lr, [istate, #-ISTATE_NEXT_FRAME+ISTATE_THREAD]!
-        CACHE_JPC
-        ldr     stack, [lr, #THREAD_JAVA_SP]
-        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
-        sub     stack, stack, #4
-
-        ldr     r1, [lr, #THREAD_TOP_ZERO_FRAME]
-        add     r2, r2, #4
-        str     r2, [lr, #THREAD_JAVA_SP]
-        str     r1, [lr, #THREAD_LAST_JAVA_SP]
-        ldr     r3, [lr, #THREAD_PENDING_EXC]
-        DISPATCH_START_REG ip
-        CACHE_LOCALS
-        DISPATCH_NEXT
-        DISPATCH_NEXT
-        cmp     r3, #0
-        DISPATCH_NEXT
-        bne     return_exception
-	DISPATCH_NEXT
-        CACHE_CP
-        DISPATCH_FINISH
-
-normal_return:
-        str   stack, [tmp_xxx, #THREAD_JAVA_SP]
-        ldmfd arm_sp!, {regset, pc}
-
-return_check_monitors:
-	ldr	r2, [istate, #ISTATE_METHOD]
-	ldr	r0, [r2, #24]
-	tst	r0, #1<<5
-	subne	tmp2, tmp2, #8
-	cmp	tmp1, tmp2
-	bcs	.return_unlock
-1:
-	ldr	r3, [tmp1, #4]
-	cmp	r3, #0
-	bne	return_throw_illegal_monitor_state
-	add	tmp1, tmp1, #8
-	cmp	tmp1, tmp2
-	bcc	1b
-
-#define RETURN_STACKSIZE	SIZEOF_HANDLEMARK
-
-.return_unlock:
-	tst	r0, #1<<5
-	bxeq	lr
-
-	ldr	tmp1, [tmp2, #4]		@ base->obj == NULL
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	return_throw_illegal_monitor_state
-.abortentry119:
-	HW_NPC	ldr	ip, [tmp1]		@ Only to provoke abort
-
-	ldr	r0, [tmp2, #0]			@ r0 = header
-	mov	r3, #0
-	cmp	r0, #0
-	str	r3, [tmp2, #4]			@ base->obj = NULL
-	bxeq	lr
-
-	mov	tmp_vvv, lr
-	mov	r1, tmp1
-	mov	r2, tmp2
-	bl	cmpxchg_ptr
-	cmp	tmp2, r0
-	bxeq	tmp_vvv
-
-	str	tmp1, [tmp2, #4]
-	sub	arm_sp, arm_sp, #RETURN_STACKSIZE
-	mov	r0, arm_sp
-	mov	r1, tmp_xxx
-	bl	_ZN10HandleMark10initializeEP6Thread
-	mov	r1, tmp2
-	mov	r0, tmp_xxx
-	DECACHE_JPC
-	DECACHE_STACK
-	bl	_ZN18InterpreterRuntime11monitorexitEP10JavaThreadP15BasicObjectLock
-	ASSERT_STACK_CACHED
-	CACHE_JPC
-	mov	r0, arm_sp
-	bl	_ZN10HandleMarkD1Ev
-	add	arm_sp, arm_sp, #RETURN_STACKSIZE
-	ldr	r3, [tmp_xxx, #THREAD_PENDING_EXC]
-	cmp	r3, #0
-	bne	handle_exception
-	mov	lr, tmp_vvv
-	bx	lr
-
-return_throw_illegal_monitor_state:
-	sub	arm_sp, arm_sp, #RETURN_STACKSIZE
-	mov	r0, arm_sp
-	mov	r1, tmp_xxx
-	bl	_ZN10HandleMark10initializeEP6Thread
-	DECACHE_JPC
-	DECACHE_STACK
-	mov	r0, tmp_xxx
-	bl	_ZN18InterpreterRuntime37throw_illegal_monitor_state_exceptionEP10JavaThread
-	mov	r0, arm_sp
-	bl	_ZN10HandleMarkD1Ev
-	add	arm_sp, arm_sp, #RETURN_STACKSIZE
-	b	handle_exception_with_bcp
+	ldmfd	arm_sp!, {fast_regset, pc}
 
 @ ----------------------------------------------------------------------------------------
 stack_overflow_no_frame:
-	mov	tmp_invoke_len, #0
+	mov	r0, tmp1
+	ldr	ip, [r0, #THREAD_TOP_ZERO_FRAME]
+	str	ip, [r0, #THREAD_LAST_JAVA_SP]
+	bl	_ZN18InterpreterRuntime24throw_StackOverflowErrorEP10JavaThread
+	ldmfd	arm_sp!, {regset, pc}
+
 stack_overflow_before_frame:
 	mov	r0, tmp1
 	ldr	ip, [r0, #THREAD_TOP_ZERO_FRAME]
 	str	ip, [r0, #THREAD_LAST_JAVA_SP]
-	mov	tmp1, tmp_invoke_len
 	bl	_ZN18InterpreterRuntime24throw_StackOverflowErrorEP10JavaThread
-	cmp	tmp1, #0
-	bne	handle_exception_with_bcp
-	ldmfd	arm_sp!, {regset, pc}
+	ldmfd	arm_sp!, {fast_regset, pc}
 
 handle_exception_do_not_unlock:
 	mov	r3, #1
 	strb	r3, [r2, #THREAD_DO_NOT_UNLOCK]
-	b	handle_exception
+	b	handle_exception_with_bcp
 
 abstractmethod_exception:
 	mov	r0, #VMSYMBOLS_AbstractMethodError
@@ -4911,39 +2958,21 @@
 raise_exception:
 	adr	r1, null_str
 raise_exception_with_msg:
-	str	r1, [arm_sp]
-	ldr	r3, [dispatch, #VmSymbols_symbols_Address-XXX]
-	ldr	r3, [r3, r0, lsl #2]
-        ldr     r0, [istate, #ISTATE_THREAD]
+	stmdb	sp!, {r0, r1}
+	bl	load_dispatch
+	ldmia	sp!, {r0, r1}
 	DECACHE_JPC
         DECACHE_STACK
-        mov     ip, #_thread_in_vm
-        str     ip, [r0, #THREAD_STATE]
-        mov     r2, #99
-        adrl    r1, bytecode_interpreter_str
-       	bl      _ZN10Exceptions10_throw_msgEP6ThreadPKciP13symbolOopDescS3_
-	add	r0, istate, #ISTATE_THREAD
-       	bl      ThreadInVMfromJavaD
+	mov	r2, r1
+	ldr	r1, [dispatch, #VmSymbols_symbols_Address-XXX]
+	ldr	r1, [r1, r0, lsl #2]
+        ldr     r0, [istate, #ISTATE_THREAD]
+	bl	Helper_Raise
         b       handle_exception_with_bcp
 null_str:
 	.byte	0
 	ALIGN_WORD
 
-#define EXCEPTION_HANDLEMARK		0
-#define EXCEPTION_THREAD		EXCEPTION_HANDLEMARK + SIZEOF_HANDLEMARK
-#define EXCEPTION_EXCEPTION		EXCEPTION_THREAD + 4
-#define EXCEPTION_EXCEPTION2		EXCEPTION_EXCEPTION + 4
-#define EXCEPTION_MONITORBASE		EXCEPTION_EXCEPTION2 + 4
-#define EXCEPTION_TMP1			EXCEPTION_MONITORBASE + 4
-#define EXCEPTION_HANDLEMARK2		EXCEPTION_TMP1 + 4
-#define EXCEPTION_HANDLE		EXCEPTION_HANDLEMARK2 + SIZEOF_HANDLEMARK
-#define EXCEPTION_HANDLE2		EXCEPTION_HANDLE + 4
-#define EXCEPTION_HANDLE3		EXCEPTION_HANDLE2 + 4
-
-#define EXCEPTION_STACKSIZE		EXCEPTION_HANDLE3 + 4
-
-#define except_sp	r13
-
 invokeinterface_exception_fix:
 	sub	jpc, jpc, #2
 invoke_exception_fix:
@@ -4960,432 +2989,157 @@
 @ constpool = garbage
 	DECACHE_JPC
 handle_exception_with_bcp:
-	sub	except_sp, except_sp, #EXCEPTION_STACKSIZE
+	bl	load_dispatch
 	ldr	stack, [istate, #ISTATE_STACK_BASE]
 	sub	stack, stack, #4
 	DECACHE_STACK
-	ldr	r0, [istate, #ISTATE_THREAD]
-handle_exception_1:
-	ldr	sl, [r0, #4]
-	str	r0, [except_sp, #EXCEPTION_THREAD]
-	cmp	sl, #0
-	moveq	tmp_yyy, sl
-	beq	.handle_exception_3
-	ldr	r0, [r0, #THREAD_HANDLE_AREA]
-	ldr	r1, [r0, #8]
-	ldr	r3, [r0, #12]
-	add	r2, r1, #4
-	cmp	r2, r3
-	movls	r3, r1
-	strls	r2, [r0, #8]
-	bls	.handle_exception_2
-	mov	r1, #4
-	bl	_ZN5Arena4growEj
-	mov	r3, r0
-.handle_exception_2:
-	str	sl, [r3, #0]
-	mov	tmp_yyy, r3
-	ldr	r0, [istate, #ISTATE_THREAD]
-.handle_exception_3:
-	mov	r1, r0
-	add	r0, except_sp, #EXCEPTION_HANDLEMARK
-	bl	_ZN10HandleMark10initializeEP6Thread
-	ldr	r0, [istate, #ISTATE_THREAD]
-	bl	_ZN12ThreadShadow23clear_pending_exceptionEv
-	ldr	r1, [istate, #ISTATE_STACK_BASE]
-	ldr	r0, [istate, #ISTATE_THREAD]
-	cmp	tmp_yyy, #0
-	sub	stack, r1, #4
-	moveq	r1, tmp_yyy
-	DECACHE_STACK
-	ldrne	r1, [tmp_yyy, #0]
-	bl	_ZN18InterpreterRuntime31exception_handler_for_exceptionEP10JavaThreadP7oopDesc
-	ASSERT_STACK_CACHED
-	mov	sl, r0
-	ldr	r0, [istate, #ISTATE_THREAD]
-	ldr	r3, [r0, #THREAD_PENDING_EXC]
-	cmp	r3, #0
-	beq	.handle_exception_5
-	add	r0, except_sp, #EXCEPTION_HANDLEMARK
-	bl	_ZN10HandleMarkD1Ev
-	ldr	r1, [except_sp, #EXCEPTION_THREAD]
-	ldr	tmp_yyy, [r1, #THREAD_LAST_HANDLE_MARK]
-	ldr	r0, [tmp_yyy, #8]
-	ldr	sl, [tmp_yyy, #4]
-	ldr	r3, [r0, #0]
-	cmp	r3, #0
-	beq	.handle_exception_4
-	bl	_ZN5Chunk9next_chopEv
-	ldr	r0, [tmp_yyy, #8]
-.handle_exception_4:
-	str	r0, [sl, #4]
-	ldr	r3, [tmp_yyy, #12]
-	str	r3, [sl, #8]
-	ldr	r2, [tmp_yyy, #16]
-	str	r2, [sl, #12]
-	ldr	r0, [istate, #ISTATE_THREAD]
-	b	handle_exception_1
-.handle_exception_5:
-	ldr	tmp_yyy, [r0, #THREAD_VM_RESULT]
-	cmp	tmp_yyy, #0
-	moveq	r1, tmp_yyy
-	beq	.handle_exception_7
-	ldr	r3, [dispatch, #ThreadLocalStorage_thread_index-XXX]
-	ldr	r0, [r3]
-	bl	pthread_getspecific
-	ldr	r0, [r0, #THREAD_HANDLE_AREA]
-	ldr	r1, [r0, #8]
-	ldr	r3, [r0, #12]
-	add	r2, r1, #4
-	cmp	r2, r3
-	movls	r3, r1
-	strls	r2, [r0, #8]
-	bls	.handle_exception_6
-	mov	r1, #4
-	bl	_ZN5Arena4growEj
-	mov	r3, r0
-.handle_exception_6:
-	str	tmp_yyy, [r3, #0]
-	mov	r1, r3
-	ldr	r0, [istate, #ISTATE_THREAD]
-.handle_exception_7:
-	cmp	sl, #0
+
+	mov	r0, istate
+	ldr	r1, [istate, #ISTATE_THREAD]
+	bl	Helper_HandleException
+	cmp	r0, #0
+	beq	1f
+
+	mov	jpc, r0
+	CACHE_STACK
+	CACHE_LOCALS
+	CACHE_CP
+	DISPATCH 0
+1:
+	ldr	tmp2, [istate, #ISTATE_MONITOR_BASE]	@ tmp2 = base
+
+	ldr	tmp1, [istate, #ISTATE_STACK_BASE]	@ tmp1 = end
+	ldr	tmp_xxx, [istate, #ISTATE_THREAD]
+
 	mov	r3, #0
-	str	r3, [r0, #THREAD_VM_RESULT]
-	blt	.handle_exception_9
-	cmp	r1, r3
-	moveq	r0, r1
-	ldrne	r0, [r1, #0]
-	str	r0, [stack, #0]
-	sub	stack, stack, #4
-	ldr	r3, [istate, #ISTATE_METHOD]
-	add	r0, except_sp, #EXCEPTION_HANDLEMARK
-	ldr	r2, [r3, #8]
-	add	r2, r2, #48
-	add	ip, r2, sl
-	str	ip, [istate, #ISTATE_BCP]
-	bl	_ZN10HandleMarkD1Ev
-	ldr	r1, [except_sp, #EXCEPTION_THREAD]
-	ldr	tmp_yyy, [r1, #THREAD_LAST_HANDLE_MARK]
-	ldr	r0, [tmp_yyy, #8]
-	ldr	sl, [tmp_yyy, #4]
-	ldr	r3, [r0, #0]
+	ldrb	r0, [tmp_xxx, #THREAD_DO_NOT_UNLOCK]
+	strb	r3, [tmp_xxx, #THREAD_DO_NOT_UNLOCK]
+	cmp	r0, #0
+	bne	2f
+
+	cmp	tmp1, tmp2
+	blcc	return_check_monitors
+
+2:
+	mov	r3, #0
+
+	ldr	r2, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
+	str	r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
+	ldr	r0, [istate, #ISTATE_METHOD]
+	ldr	r3, [r2, #0]
+	ldrh	r0, [r0, #40]
+	add	r1, r2, #4
+	str	r3, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
+
+	add	r1, r1, r0, lsl #2
+
+	str	r1, [tmp_xxx, #THREAD_JAVA_SP]
+
+	ldmfd	arm_sp!, {fast_regset, pc}
+
+return_check_monitors:
+	stmdb	arm_sp!, {r4, lr}
+
+	ldr	r2, [istate, #ISTATE_METHOD]
+	ldr	r4, [r2, #METHOD_ACCESSFLAGS]
+	tst	r4, #1<<5
+	subne	tmp2, tmp2, #8
+	cmp	tmp1, tmp2
+	bcs	2f
+1:
+	ldr	r3, [tmp1, #4]
 	cmp	r3, #0
-	beq	.handle_exception_8
-	bl	_ZN5Chunk9next_chopEv
-	ldr	r0, [tmp_yyy, #8]
-.handle_exception_8:
-	str	r0, [sl, #4]
-	ldr	r3, [tmp_yyy, #12]
-	str	r3, [sl, #8]
-	ldr	r2, [tmp_yyy, #16]
-	str	r2, [sl, #12]
-	add	except_sp, except_sp, #EXCEPTION_STACKSIZE
-	b	do_execute_java_bytecodes_restore_locals_and_jpc
-.handle_exception_9:
-	cmp	r1, #0
-	ldr	r0, [istate, #ISTATE_THREAD]
-	mov	r2, #0
-	ldrne	r1, [r1, #0]
-	mov	r3, r2
-	bl	_ZN12ThreadShadow21set_pending_exceptionEP7oopDescPKci
-	ldr	r0, [istate, #ISTATE_THREAD]
-	ldr	tmp_yyy, [r0, #4]
-	cmp	tmp_yyy, #0
-	streq	tmp_yyy, [except_sp, #EXCEPTION_EXCEPTION]
-	beq	.handle_exception_11
-	ldr	r0, [r0, #THREAD_HANDLE_AREA]
-	ldr	r1, [r0, #8]
-	ldr	r3, [r0, #12]
-	add	r2, r1, #4
-	cmp	r2, r3
-	movls	r3, r1
-	strls	r2, [r0, #8]
-	bls	.handle_exception_10
-	mov	r1, #4
-	bl	_ZN5Arena4growEj
-	mov	r3, r0
-.handle_exception_10:
-	str	tmp_yyy, [r3, #0]
-	ldr	r0, [istate, #ISTATE_THREAD]
-	str	r3, [except_sp, #EXCEPTION_EXCEPTION]
-.handle_exception_11:
-	bl	_ZN12ThreadShadow23clear_pending_exceptionEv
-	mov	r1, #0
-	ldr	r0, [istate, #ISTATE_THREAD]
-	str	r1, [except_sp, #EXCEPTION_EXCEPTION2]
-	ldrb	r3, [r0, #THREAD_DO_NOT_UNLOCK]	@ zero_extendqisi2
-	cmp	r3, r1
-	beq	.handle_exception_15
-	strb	r1, [r0, #THREAD_DO_NOT_UNLOCK]
-	ldr	r0, [istate, #ISTATE_THREAD]
-.handle_exception_12:
-	ldr	r1, [except_sp, #EXCEPTION_EXCEPTION]
-	cmp	r1, #0
-	movne	r2, r1
-	ldrne	r1, [r2, #0]
-.handle_exception_13:
-	mov	r2, #0
-	mov	r3, r2
-	bl	_ZN12ThreadShadow21set_pending_exceptionEP7oopDescPKci
-	mov	r3, #0
-	ldr	r2, [istate, #ISTATE_BCP]
-	ldrb	r2, [r2, #0]	@ zero_extendqisi2
-	DECACHE_STACK
-	str	r2, [istate, #ISTATE_CALLEE]
-	ldr	lr, [istate, #ISTATE_THREAD]
-	ldr	r1, [lr, #THREAD_TOP_ZERO_FRAME]
-	str	r3, [lr, #THREAD_LAST_JAVA_SP]
-	add	r2, r1, #4
-	str	r2, [lr, #THREAD_JAVA_SP]
-	ldr	r3, [r1, #0]
-	str	r3, [lr, #THREAD_TOP_ZERO_FRAME]
-	ldr	r1, [istate, #ISTATE_METHOD]
-	ldrh	r3, [r1, #40]
-	add	r0, except_sp, #EXCEPTION_HANDLEMARK
-	mov	r3, r3, asl #2
-	add	r2, r2, r3
-	str	r2, [lr, #THREAD_JAVA_SP]
-	bl	_ZN10HandleMarkD1Ev
-	ldr	r0, [except_sp, #EXCEPTION_THREAD]
-	ldr	tmp_yyy, [r0, #THREAD_LAST_HANDLE_MARK]
-	ldr	r0, [tmp_yyy, #8]
-	ldr	sl, [tmp_yyy, #4]
-	ldr	r3, [r0, #0]
-	cmp	r3, #0
-	beq	.handle_exception_14
-	bl	_ZN5Chunk9next_chopEv
-	ldr	r0, [tmp_yyy, #8]
-.handle_exception_14:
-	str	r0, [sl, #4]
-	ldr	r3, [tmp_yyy, #12]
-	str	r3, [sl, #8]
-	ldr	r2, [tmp_yyy, #16]
-	str	r2, [sl, #12]
-	add	except_sp, except_sp, #EXCEPTION_STACKSIZE
-	ldr	ip, [istate, #ISTATE_ADVANCE_PC]
-	ldr	istate, [istate, #ISTATE_NEXT_FRAME]
-	cmp	ip, #0
-	bne	fast_handle_return
-	ldmfd	arm_sp!, {regset, pc}
-.handle_exception_15:
-	ldr	ip, [istate, #ISTATE_MONITOR_BASE]
-	ldr	r2, [istate, #ISTATE_METHOD]
-	str	ip, [except_sp, #EXCEPTION_MONITORBASE]
-	ldr	tmp_vvv, [istate, #ISTATE_STACK_BASE]
-	ldr	r3, [r2, #24]
-	mov	r3, r3, lsr #5
-	ands	r3, r3, #1
-	subne	ip, ip, #8
-	strne	ip, [except_sp, #EXCEPTION_MONITORBASE]
-	ldr	lr, [except_sp, #EXCEPTION_MONITORBASE]
-	str	r3, [except_sp, #EXCEPTION_TMP1]
-	cmp	tmp_vvv, lr
-	bcs	.handle_exception_21
-
-	.p2align 3
-.handle_exception_16:
-	ldr	tmp_yyy, [tmp_vvv, #4]
-	cmp	tmp_yyy, #0
-	beq	.handle_exception_20
-	ldr	fp, [tmp_vvv, #0]
-	mov	r2, #0
-	cmp	fp, r2
-	str	r2, [tmp_vvv, #4]
-	beq	.handle_exception_19
-	.p2align 3
-.handle_exception_17:
-	ldr	sl, [tmp_yyy, #0]
-	cmp	tmp_vvv, sl
-	bne	.handle_exception_18
-	mov	r0, tmp_vvv
-	mov	r1, fp
-	mov	r2, tmp_yyy
-	mov	r3, #0xffffffc0
-	bic	r3, r3, #0xf000
-	blx	r3
-	cmp	r0, #0
-	bne	.handle_exception_17
-.handle_exception_18:
-	cmp	tmp_vvv, sl
-	beq	.handle_exception_19
-	str	tmp_yyy, [tmp_vvv, #4]
-	add	r0, except_sp, #EXCEPTION_HANDLEMARK2
-	ldr	r1, [istate, #ISTATE_THREAD]
-	bl	_ZN10HandleMark10initializeEP6Thread
-	mov	r1, tmp_vvv
-	ldr	r0, [istate, #ISTATE_THREAD]
-	DECACHE_STACK
-	bl	_ZN18InterpreterRuntime11monitorexitEP10JavaThreadP15BasicObjectLock
-	ASSERT_STACK_CACHED
-	add	r0, except_sp, #EXCEPTION_HANDLEMARK2
-	bl	_ZN10HandleMarkD1Ev
-.handle_exception_19:
-	ldr	r1, [except_sp, #EXCEPTION_EXCEPTION2]
-	cmp	r1, #0
-	beq	.handle_exception_27
-	ldr	r3, [r1, #0]
-	cmp	r3, #0
-	beq	.handle_exception_27
-.handle_exception_20:
-	ldr	r3, [except_sp, #EXCEPTION_MONITORBASE]
-	add	tmp_vvv, tmp_vvv, #8
-	cmp	tmp_vvv, r3
-	bcc	.handle_exception_16
-.handle_exception_21:
-	ldr	ip, [except_sp, #EXCEPTION_TMP1]
-	cmp	ip, #0
-	beq	.handle_exception_23
-	ldr	r0, [except_sp, #EXCEPTION_MONITORBASE]
-	ldr	sl, [r0, #4]
-	cmp	sl, #0
-	beq	.handle_exception_26
-	mov	ip, r0
-	ldr	r0, [r0, #0]
+	bne	3f
+	add	tmp1, tmp1, #8
+	cmp	tmp1, tmp2
+	bcc	1b
+
+2:
+	tst	r4, #1<<5
+
+	ldmeqia	arm_sp!, {r4, pc}
+
+	ldr	tmp1, [tmp2, #4]		@ base->obj == NULL
+	cmp	tmp1, #0
+	beq	4f
+
+	ldr	r0, [tmp2, #0]			@ r0 = header
 	mov	r3, #0
 	cmp	r0, #0
-	str	r3, [ip, #4]
-	beq	.handle_exception_23
-	mov	r1, sl
-	ldr	r2, [except_sp, #EXCEPTION_MONITORBASE]
+	str	r3, [tmp2, #4]			@ base->obj = NULL
+
+	ldmeqia	arm_sp!, {r4, pc}
+
+	mov	r1, tmp1
+	mov	r2, tmp2
 	bl	cmpxchg_ptr
-	ldr	r1, [except_sp, #EXCEPTION_MONITORBASE]
-	cmp	r1, r0
-	beq	.handle_exception_22
-	ldr	r3, [except_sp, #EXCEPTION_MONITORBASE]
-	add	tmp_yyy, except_sp, #EXCEPTION_HANDLEMARK2
-	mov	r0, tmp_yyy
-	str	sl, [r3, #4]
-	ldr	r1, [istate, #ISTATE_THREAD]
-	bl	_ZN10HandleMark10initializeEP6Thread
-	ldr	r1, [except_sp, #EXCEPTION_MONITORBASE]
-	ldr	r0, [istate, #ISTATE_THREAD]
-	DECACHE_STACK
-	bl	_ZN18InterpreterRuntime11monitorexitEP10JavaThreadP15BasicObjectLock
-	mov	r0, tmp_yyy
-	ASSERT_STACK_CACHED
-	bl	_ZN10HandleMarkD1Ev
-	ldr	r0, [istate, #ISTATE_THREAD]
-	ldr	r1, [r0, #4]
-	cmp	r1, #0
-	beq	.handle_exception_24
-	add	r0, except_sp, #EXCEPTION_HANDLE2
-	bl	HandleC
-	ldr	r1, [except_sp, #EXCEPTION_HANDLE2]
-	ldr	r0, [istate, #ISTATE_THREAD]
-	str	r1, [except_sp, #EXCEPTION_EXCEPTION2]
-	bl	_ZN12ThreadShadow23clear_pending_exceptionEv
-.handle_exception_22:
-	ldr	r0, [istate, #ISTATE_THREAD]
-	b	.handle_exception_24
-.handle_exception_23:
+	cmp	tmp2, r0
+
+	ldmeqia	arm_sp!, {r4, pc}
+
+	str	tmp1, [tmp2, #4]
+
+	mov	r1, tmp2
 	ldr	r0, [istate, #ISTATE_THREAD]
-.handle_exception_24:
-	ldr	r3, [except_sp, #EXCEPTION_EXCEPTION2]
-	cmp	r3, #0
-	beq	.handle_exception_12
-.handle_exception_25:
-	ldr	lr, [except_sp, #EXCEPTION_EXCEPTION2]
-	ldr	r1, [lr, #0]
-	cmp	r1, #0
-	bne	.handle_exception_13
-	b	.handle_exception_12
-.handle_exception_26:
-	ldr	r1, [except_sp, #EXCEPTION_EXCEPTION2]
-	cmp	r1, #0
-	beq	.handle_exception_29
-	ldr	r3, [r1, #0]
-	cmp	r3, #0
-	beq	.handle_exception_29
-	ldr	r0, [istate, #ISTATE_THREAD]
-	b	.handle_exception_25
-
-.handle_exception_27:
-	add	r0, except_sp, #EXCEPTION_HANDLEMARK2
-	ldr	r1, [istate, #ISTATE_THREAD]
-	bl	_ZN10HandleMark10initializeEP6Thread
+	bl	Helper_synchronized_exit
+
+	ldmeqia	arm_sp!, {r4, pc}
+
+3:
 	ldr	r0, [istate, #ISTATE_THREAD]
-	DECACHE_STACK
-	bl	_ZN18InterpreterRuntime37throw_illegal_monitor_state_exceptionEP10JavaThread
-	add	r0, except_sp, #EXCEPTION_HANDLEMARK2
-	ASSERT_STACK_CACHED
-	bl	_ZN10HandleMarkD1Ev
-	add	r0, except_sp, #EXCEPTION_HANDLE
-	ldr	r3, [istate, #ISTATE_THREAD]
-	ldr	r1, [r3, #4]
-	bl	HandleC
-	ldr	r2, [except_sp, #EXCEPTION_HANDLE]
+	bl	Helper_RaiseIllegalMonitorException
+	b	2b
+
+4:
 	ldr	r0, [istate, #ISTATE_THREAD]
-	str	r2, [except_sp, #EXCEPTION_EXCEPTION2]
-	bl	_ZN12ThreadShadow23clear_pending_exceptionEv
-	b	.handle_exception_20
-.handle_exception_29:
-	add	tmp_yyy, except_sp, #EXCEPTION_HANDLEMARK2
-	mov	r0, tmp_yyy
-	ldr	r1, [istate, #ISTATE_THREAD]
-	bl	_ZN10HandleMark10initializeEP6Thread
-	ldr	r0, [istate, #ISTATE_THREAD]
-	DECACHE_STACK
-	bl	_ZN18InterpreterRuntime37throw_illegal_monitor_state_exceptionEP10JavaThread
-	mov	r0, tmp_yyy
-	ASSERT_STACK_CACHED
-	bl	_ZN10HandleMarkD1Ev
-	ldr	r3, [istate, #ISTATE_THREAD]
-	add	r0, except_sp, #EXCEPTION_HANDLE3
-	ldr	r1, [r3, #4]
-	bl	HandleC
-	ldr	r2, [except_sp, #EXCEPTION_HANDLE3]
-	ldr	r0, [istate, #ISTATE_THREAD]
-	str	r2, [except_sp, #EXCEPTION_EXCEPTION2]
-	bl	_ZN12ThreadShadow23clear_pending_exceptionEv
-	ldr	r0, [istate, #ISTATE_THREAD]
-	b	.handle_exception_24
-
-#ifdef FASTPATH_ENTRY
+	bl	Helper_RaiseIllegalMonitorException
+	ldmia	arm_sp!, {r4, pc}
+
+	ALIGN_CODE
+accessor_entry:
+	b	slow_accessor_entry
 
 	ALIGN_CODE
-fast_accessor_entry:
-	ldr	ip, [dispatch, #SafePointSynchronize_state_Address-XXX]
-	ldr	r3, [tmp2, #8]
-	ldr	ip, [ip, #0]
-	ldrb	r2, [r3, #50]
-	ldrb	r3, [r3, #51]
-	cmp	ip, #0
-	ldr	ip, [tmp2, #12]
-	bne	fast_normal_entry
-	ldr	ip, [ip, #12]
-
-	DISPATCH_START	3
-
-	orr	r2, r2, r3, lsl #8		@ r2 = index
-	add	r3, ip, #16
-	ldr	r2, [r3, r2, lsl #4]!		@ r3 = cache, r2 = flags
-
-	DISPATCH_NEXT
-
-	cmp	r2, #opc_getfield << 16
-	GET_STACK	0, r2
-	bne	fast_normal_entry
-
-	cmp	r2, #0
-	beq	fast_normal_entry
-
-
-	ldr	lr, [r3, #12]
-	ldr	r3, [r3, #8]
-	movs	lr, lr, lsr #29
-	bls	.fast_accessor_non_w
-
-	DISPATCH_NEXT
-
-	ldr	tmp1, [r2, r3]
-
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-
-	PUT_STACK	0, tmp1
-
-	DISPATCH_FINISH
+slow_accessor_entry:
+  USEC	adrl	ip, dispatch_init_adcon
+  USEC	ldr	r3, [ip]
+  USEC	add	r3, r3, ip
+  USEC	ldr	ip, [ip, #invocationlimit_adcon-dispatch_init_adcon]
+  USEC	ldr	ip, [r3, ip]
+
+  USEC	ldr	r3, [r0, #METHOD_INVOCATIONCOUNTER]
+  USEC	ldr	ip, [ip, #0]
+  USEC	add	r3, r3, #INVOCATIONCOUNTER_COUNTINCREMENT
+  USEC	str	r3, [r0, #METHOD_INVOCATIONCOUNTER]
+  USEC	cmp	r3, ip
+  USEC	bcs	normal_entry
+
+	ldr	r1, [r0, #METHOD_CONSTMETHOD]
+	ldrb	r3, [r1, #CONSTMETHOD_CODEOFFSET+2]
+	ldrb	r1, [r1, #CONSTMETHOD_CODEOFFSET+3]
+	ldr	ip, [r0, #METHOD_CONSTANTS]
+	ldr	ip, [ip, #CONSTANTPOOL_CACHE]
+	orr	r3, r3, r1, lsl #8		@ r3 = index
+
+	add	r1, ip, #CP_OFFSET
+	ldr	r3, [r1, r3, lsl #4]!		@ r1 = cache, r3 = flags
+	ldr	ip, [r2, #THREAD_JAVA_SP]			@ ip == stack
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getfield << 16
+	ldr	r3, [ip, #0]
+	bne	normal_entry
+
+	cmp	r3, #0
+	beq	normal_entry
+
+	ldr	r0, [r1, #12]
+	ldr	r1, [r1, #8]
+	movs	r0, r0, lsr #29
+	bls	accessor_non_w
+
+	ldr	r0, [r3, r1]
+	str	r0, [ip, #0]
+	bx	lr
 
 .fast_accessor_non_w:
 	bcs	.fast_accessor_h
@@ -5427,10 +3181,8 @@
 	PUSH	tmp2
 	DISPATCH_FINISH
 
-#endif // FASTPATH_ENTRY
-
 div_zero_jpc_1:
-	sub	jpc, jpc, #1			@ Point to idiv
+	sub	jpc, jpc, #1
 .lrem_0:
 .ldiv_0:
 divide_by_zero_exception:
@@ -5465,30 +3217,12 @@
 	sub	jpc, jpc, #1
 array_bound_exception_jpc_0:
 array_bounds_exception:
-	adr	r1, percent_d_str
-	sub	arm_sp, arm_sp, #16
-	add	r0, arm_sp, #4
-	bl	sprintf
-	add	r1, arm_sp, #4
-	mov	r0, #VMSYMBOLS_ArrayIndexOutOfBounds
-	str	r1, [arm_sp]
-	ldr	r3, [dispatch, #VmSymbols_symbols_Address-XXX]
-	ldr	r3, [r3, r0, lsl #2]
-        ldr     r0, [istate, #ISTATE_THREAD]
 	DECACHE_JPC
         DECACHE_STACK
-        mov     ip, #_thread_in_vm
-        str     ip, [r0, #THREAD_STATE]
-        mov     r2, #99
-        adrl    r1, bytecode_interpreter_str
-       	bl      _ZN10Exceptions10_throw_msgEP6ThreadPKciP13symbolOopDescS3_
-	add	r0, istate, #ISTATE_THREAD
-       	bl      ThreadInVMfromJavaD
-	add	arm_sp, arm_sp, #16
+	mov	r1, r2
+        ldr     r0, [istate, #ISTATE_THREAD]
+	bl	Helper_RaiseArrayBoundException
         b       handle_exception_with_bcp
-percent_d_str:
-	.ascii	"%d\000"
-	ALIGN_WORD
 
 #ifndef HW_NULL_PTR_CHECK
 null_ptr_exception_jpc_5:
@@ -5780,8 +3514,6 @@
 	bpl	.dadd_exit
 	b	.return_double_NaN
 
-@ ECN: load 1st arg off stack and do a reverse subtract
-@ ECN: We want TOSM1 - TOS, but args end up in wrong order so do rsb
 @ --- do_dsub_itos -------------------------------------------------
 	Opcode	dsub
 	POP	al, ah, bl, bh
@@ -6189,7 +3921,6 @@
         orr     ah, ah, al, LSR ul     @ put in high end of low word
         mov     al, tl
 
-@ ECN: Reload tmp
 	mov	tmp, #0x7f00000
 	orr	tmp, tmp, #0x00f0000
 
@@ -6228,7 +3959,6 @@
         orr     bh, bh, bl, LSR ul     @ put in high end of low word
         mov     bl, tl
 
-@ ECN: Reload tmp
 	mov	tmp, #0x7f00000
 	orr	tmp, tmp, #0x00f0000
 
@@ -6293,9 +4023,9 @@
 	strb	r3, [r2, #0]
 	adrl	r3, main_dispatch_table
 #ifdef HW_FP
-	ldr	r0, [ip, #VFP_Flag-XXX]
-	cmp	r0, #0
-	bne	2f
+	ldr	r0, [ip, #CPUInfo-XXX]
+	tst	r0, #ARCH_VFP
+	beq	2f
 #endif
 	mov	r2, #256
 1:
@@ -6303,7 +4033,8 @@
 	str	r1, [ip], #4
 	subs	r2, r2, #1
 	bne	1b
-	bx	lr
+	sub	ip, ip, #4 * 256
+	b	4f
 
 @ No HW FP - must update the table from a combination main_dispatch_table and
 @ vfp_table. Previously this updated from main_dispatch_table first, and then
@@ -6327,9 +4058,23 @@
 	add	r2, r2, #1
 	cmp	r2, #256
 	bcc	3b
+	sub	ip, ip, #4 * 256
 	ldmia	arm_sp!, {r4, lr}
 #endif // HW_FP
+
+4:
+	ldr	r0, [ip, #CPUInfo-XXX]
+	tst	r0, #ARCH_CLZ
+	beq	5f
+
+	adrl	r0, do_idiv_clz
+	str	r0, [ip, #opc_idiv * 4]
+	adrl	r0, do_irem_clz
+	str	r0, [ip, #opc_irem * 4]
+
+5:
 #endif // NOTICE_SAFEPOINTS
+
 	bx	lr
 
 @ --- notice_safepoints ---------------------------------------------------------------------------
@@ -6384,6 +4129,9 @@
 	subs	r1, r1, #1
 	bne	2b
 
+	bl	hwcap
+	str	r0, [r4, #CPUInfo-XXX]
+
 #ifdef USE_COMPILER
 
 #define NPROCESSORS_CONF        83
@@ -6403,51 +4151,18 @@
         ldr     r1, [r4, #CompileThreshold_Address-XXX]
         str     r0, [r1]
 
-
 #endif // USE_COMPILER
 
-        ldmfd   sp!, {r4, lr}
+#ifdef THUMB2EE
+	ldr	r1, [r4, #CPUInfo-XXX]
+	tst	r1, #ARCH_THUMBEE
+	blne	Thumb2_Initialize
+#endif
 
 #ifdef HW_FP
-vfp_init:
-	stmfd	sp!, {r4, r5, lr}
-	sub	sp, sp, #132
-	mov	r4, #0
-	adr	r0, proc_self_auxv
-	mov	r1, #0
-	bl	open
-	subs	r5, r0, #0
-	blt	.exit_vfp_init
-.vfp_init_read_loop:
-	mov	r2, #128
-	mov	r0, r5
-	mov	r1, sp
-	bl	read
-	mov	r2, sp
-	mov	r3, r0, lsr #3
-	b	.vfp_init_1
-.vfp_init_vec_loop:
-	ldmia	r2!, {r1, ip}
-	cmp	r1, #0
-	beq	.fini_vfp_init
-	cmp	r1, #16
-	bne	.vfp_init_1
-	tst	ip, #64
-	movne	r4, #1
-	bne	.fini_vfp_init
-.vfp_init_1:
-	subs	r3, r3, #1
-	bpl	.vfp_init_vec_loop
-	cmp	r0, #128
-	beq	.vfp_init_read_loop
-.fini_vfp_init:
-	mov	r0, r5
-	bl	close
-.exit_vfp_init:
-	movs	r0, r4
-	add	sp, sp, #132
-	ldmfd	sp!, {r4, r5, lr}
-	bxne	lr		@ We have HW FP - just exit
+	ldr	r0, [r4, #CPUInfo-XXX]
+	tst	r0, #ARCH_VFP
+	bne	4f
 
 @ No HW FP - replace the HW FP entries with SW entries
 update_vfp_table:
@@ -6456,17 +4171,26 @@
 	ldm	ip, {r2, r3}
 	add	r2, r2, ip
 	add	ip, r3, r2
-	mov	r1, #1
-	str	r1, [ip, #VFP_Flag-XXX]
 .update_vfp_loop:
 	ldr	r1, [r0], #4
 	cmp	r1, #0
 	ldrne	r2, [r0], #4
 	strne	r2, [ip, r1, lsl #2]
 	bne	.update_vfp_loop
+4:
 #endif // HW_FP
 
-	bx	lr
+	ldr	r0, [r4, #CPUInfo-XXX]
+	tst	r0, #ARCH_CLZ
+	beq	5f
+
+	adrl	r0, do_idiv_clz
+	str	r0, [r4, #opc_idiv * 4]
+	adrl	r0, do_irem_clz
+	str	r0, [r4, #opc_irem * 4]
+
+5:
+	ldmia	sp!, {r4, pc}
 
 #ifdef HW_FP
 vfp_table:
@@ -6483,13 +4207,15 @@
 	.word	opc_dcmpl,	do_dcmpl
 	.word	opc_dcmpg,	do_dcmpg
 	.word	0
-
-proc_self_auxv:
-	.ascii	"/proc/self/auxv\000"
-	.align	2
-
 #endif // HW_FP
 
+load_dispatch:
+	adrl	ip, dispatch_init_adcon
+	ldm	ip, {r0, r1}
+	add	r0, r0, ip
+	add	dispatch, r1, r0
+	mov	pc, lr
+
 	ALIGN_DATA
 dispatch_init_adcon:
 	.word	_GLOBAL_OFFSET_TABLE_-dispatch_init_adcon, opclabels_data(GOTOFF)
@@ -6506,6 +4232,7 @@
 	.word	PrintCommandLineFlags(GOT)
 	.word	_ZN11JvmtiExport28_can_post_interpreter_eventsE(GOT)
 	.word	UseCompiler(GOT)
+invocationlimit_adcon:
 	.word	_ZN17InvocationCounter26InterpreterInvocationLimitE(GOT)
         .word   CompileThreshold(GOT)
         .word   BackgroundCompilation(GOT)
@@ -6516,8 +4243,6 @@
 main_dispatch_table:
 	MAIN_DISPATCH_TABLE
 
-@ ECN: Strange logic here! We don't need the safe_dispatch_table if NOTICE_SAFEPOINTS is
-@      disabled because in this case the main_dispatch_table must be safepoint safe.
 #ifdef NOTICE_SAFEPOINTS
 safe_dispatch_table:
 	.word	do_nop
@@ -6780,19 +4505,1717 @@
 
 	SUB_DISPATCH_TABLES
 
+	.arch	armv7-a
+
+	ALIGN_CODE
+	.global	Thumb2_stubs
+Thumb2_stubs:
+	.global	Thumb2_idiv_stub
+Thumb2_idiv_stub:
+int_div:
+	cmp     r1, #0x21
+	adr	r3, 1f
+	eor     r12, r0, r1
+	ldrcc	pc, [r3, r1, lsl #2]
+	rsblt   r1, r1, #0
+	subs    r2, r1, #1
+	beq     2f
+	movs    r3, r0
+	rsbmi   r3, r0, #0
+	cmp     r3, r1
+	bls     3f
+	tst     r1, r2
+	beq     4f
+	clz     r2, r3
+	clz     r0, r1
+	sub     r2, r0, r2
+	rsbs    r2, r2, #31
+	add     r2, r2, r2, lsl #1
+	mov     r0, #0
+	add     pc, pc, r2, lsl #2
+	mov	r0, #0
+	cmp     r3, r1, lsl #31
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #31
+	cmp     r3, r1, lsl #30
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #30
+	cmp     r3, r1, lsl #29
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #29
+	cmp     r3, r1, lsl #28
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #28
+	cmp     r3, r1, lsl #27
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #27
+	cmp     r3, r1, lsl #26
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #26
+	cmp     r3, r1, lsl #25
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #25
+	cmp     r3, r1, lsl #24
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #24
+	cmp     r3, r1, lsl #23
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #23
+	cmp     r3, r1, lsl #22
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #22
+	cmp     r3, r1, lsl #21
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #21
+	cmp     r3, r1, lsl #20
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #20
+	cmp     r3, r1, lsl #19
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #19
+	cmp     r3, r1, lsl #18
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #18
+	cmp     r3, r1, lsl #17
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #17
+	cmp     r3, r1, lsl #16
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #16
+	cmp     r3, r1, lsl #15
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #15
+	cmp     r3, r1, lsl #14
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #14
+	cmp     r3, r1, lsl #13
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #13
+	cmp     r3, r1, lsl #12
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #12
+	cmp     r3, r1, lsl #11
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #11
+	cmp     r3, r1, lsl #10
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #10
+	cmp     r3, r1, lsl #9
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #9
+	cmp     r3, r1, lsl #8
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #8
+	cmp     r3, r1, lsl #7
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #7
+	cmp     r3, r1, lsl #6
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #6
+	cmp     r3, r1, lsl #5
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #5
+	cmp     r3, r1, lsl #4
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #4
+	cmp     r3, r1, lsl #3
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #3
+	cmp     r3, r1, lsl #2
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #2
+	cmp     r3, r1, lsl #1
+	adc     r0, r0, r0
+	subcs   r3, r3, r1, lsl #1
+	cmp     r3, r1
+	adc     r0, r0, r0
+	subcs   r3, r3, r1
+	cmp     r12, #0
+	rsbmi   r0, r0, #0
+	bx      lr
+2:
+	teq     r12, r0
+	rsbmi   r0, r0, #0
+	bx      lr
+3:
+	movcc   r0, #0
+	asreq   r0, r12, #31
+	orreq   r0, r0, #1
+	bx      lr
+4:
+	clz     r2, r1
+	rsb     r2, r2, #31
+	cmp     r12, #0
+	lsr     r0, r3, r2
+	rsbmi   r0, r0, #0
+	bx      lr
+1:
+	.word	Thumb2_DivZero_Handler
+	.word	jdiv_1
+	.word	jdiv_2
+	.word	jdiv_3
+	.word	jdiv_4
+	.word	jdiv_5
+	.word	jdiv_6
+	.word	jdiv_7
+	.word	jdiv_8
+	.word	jdiv_9
+	.word	jdiv_10
+	.word	jdiv_11
+	.word	jdiv_12
+	.word	jdiv_13
+	.word	jdiv_14
+	.word	jdiv_15
+	.word	jdiv_16
+	.word	jdiv_17
+	.word	jdiv_18
+	.word	jdiv_19
+	.word	jdiv_20
+	.word	jdiv_21
+	.word	jdiv_22
+	.word	jdiv_23
+	.word	jdiv_24
+	.word	jdiv_25
+	.word	jdiv_26
+	.word	jdiv_27
+	.word	jdiv_28
+	.word	jdiv_29
+	.word	jdiv_30
+	.word	jdiv_31
+	.word	jdiv_32
+	ALIGN_CODE
+	.global	Thumb2_irem_stub
+Thumb2_irem_stub:
+int_rem:
+	cmp     r1, #0x21
+	adr	r3, 1f
+	ldrcc	pc, [r3, r1, lsl #2]
+	rsblt   r1, r1, #0
+	subs    r2, r1, #1
+	beq     2f
+	movs    r12, r0
+	rsbmi   r0, r0, #0
+	cmp     r0, r1
+	bls     3f
+	tst     r1, r2
+	beq     4f
+	clz     r2, r0
+	clz     r3, r1
+	sub     r2, r3, r2
+	rsbs    r2, r2, #31
+	add     pc, pc, r2, lsl #3
+	mov	r3, #0
+	cmp     r0, r1, lsl #31
+	subcs   r0, r0, r1, lsl #31
+	cmp     r0, r1, lsl #30
+	subcs   r0, r0, r1, lsl #30
+	cmp     r0, r1, lsl #29
+	subcs   r0, r0, r1, lsl #29
+	cmp     r0, r1, lsl #28
+	subcs   r0, r0, r1, lsl #28
+	cmp     r0, r1, lsl #27
+	subcs   r0, r0, r1, lsl #27
+	cmp     r0, r1, lsl #26
+	subcs   r0, r0, r1, lsl #26
+	cmp     r0, r1, lsl #25
+	subcs   r0, r0, r1, lsl #25
+	cmp     r0, r1, lsl #24
+	subcs   r0, r0, r1, lsl #24
+	cmp     r0, r1, lsl #23
+	subcs   r0, r0, r1, lsl #23
+	cmp     r0, r1, lsl #22
+	subcs   r0, r0, r1, lsl #22
+	cmp     r0, r1, lsl #21
+	subcs   r0, r0, r1, lsl #21
+	cmp     r0, r1, lsl #20
+	subcs   r0, r0, r1, lsl #20
+	cmp     r0, r1, lsl #19
+	subcs   r0, r0, r1, lsl #19
+	cmp     r0, r1, lsl #18
+	subcs   r0, r0, r1, lsl #18
+	cmp     r0, r1, lsl #17
+	subcs   r0, r0, r1, lsl #17
+	cmp     r0, r1, lsl #16
+	subcs   r0, r0, r1, lsl #16
+	cmp     r0, r1, lsl #15
+	subcs   r0, r0, r1, lsl #15
+	cmp     r0, r1, lsl #14
+	subcs   r0, r0, r1, lsl #14
+	cmp     r0, r1, lsl #13
+	subcs   r0, r0, r1, lsl #13
+	cmp     r0, r1, lsl #12
+	subcs   r0, r0, r1, lsl #12
+	cmp     r0, r1, lsl #11
+	subcs   r0, r0, r1, lsl #11
+	cmp     r0, r1, lsl #10
+	subcs   r0, r0, r1, lsl #10
+	cmp     r0, r1, lsl #9
+	subcs   r0, r0, r1, lsl #9
+	cmp     r0, r1, lsl #8
+	subcs   r0, r0, r1, lsl #8
+	cmp     r0, r1, lsl #7
+	subcs   r0, r0, r1, lsl #7
+	cmp     r0, r1, lsl #6
+	subcs   r0, r0, r1, lsl #6
+	cmp     r0, r1, lsl #5
+	subcs   r0, r0, r1, lsl #5
+	cmp     r0, r1, lsl #4
+	subcs   r0, r0, r1, lsl #4
+	cmp     r0, r1, lsl #3
+	subcs   r0, r0, r1, lsl #3
+	cmp     r0, r1, lsl #2
+	subcs   r0, r0, r1, lsl #2
+	cmp     r0, r1, lsl #1
+	subcs   r0, r0, r1, lsl #1
+	cmp     r0, r1
+	subcs   r0, r0, r1
+	cmp     r12, #0
+	rsbmi   r0, r0, #0
+	bx      lr
+2:
+	mov	r0, #0
+	bx      lr
+3:
+	moveq	r0, #0
+	cmp	r12, #0
+	rsbmi	r0, r0, #0
+	bx	lr
+4:
+	and	r0, r0, r2
+	cmp	r12, #0
+	rsbmi	r0, r0, #0
+	bx      lr
+1:
+	.word	Thumb2_DivZero_Handler
+	.word	jrem_1
+	.word	jrem_2
+	.word	jrem_3
+	.word	jrem_4
+	.word	jrem_5
+	.word	jrem_6
+	.word	jrem_7
+	.word	jrem_8
+	.word	jrem_9
+	.word	jrem_10
+	.word	jrem_11
+	.word	jrem_12
+	.word	jrem_13
+	.word	jrem_14
+	.word	jrem_15
+	.word	jrem_16
+	.word	jrem_17
+	.word	jrem_18
+	.word	jrem_19
+	.word	jrem_20
+	.word	jrem_21
+	.word	jrem_22
+	.word	jrem_23
+	.word	jrem_24
+	.word	jrem_25
+	.word	jrem_26
+	.word	jrem_27
+	.word	jrem_28
+	.word	jrem_29
+	.word	jrem_30
+	.word	jrem_31
+	.word	jrem_32
+
+#ifdef THUMB2EE
+@ R0 = BCI
+@ R1 = index
+#define Rthread	r9
+	.global	Thumb2_invokeinterface_stub
+Thumb2_invokeinterface_stub:
+	stmdb	sp!, {ip, lr}
+	ldr	ip, [istate, #ISTATE_METHOD]
+	sub	stack, stack, #4
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	ldr	ip, [ip, #METHOD_CONSTMETHOD]
+	DECACHE_STACK
+	add	jpc, ip, r0
+
+        add     r0, r2, r1, lsl #4
+	DECACHE_JPC
+
+        ldr     r2, [r0, #CP_OFFSET]
+        and     r2, r2, #0x00ff0000
+        cmp     r2, #opc_invokeinterface << 16
+        bne     istub_resolve
+2:
+	ldr	r3, [r0, #CP_OFFSET+12]
+	and	r2, r3, #255
+	ldr	r2, [stack, r2, lsl #2]
+	cmp	r2, #0
+	beq	istub_null_ptr_exception
+	ldr	tmp2, [r2, #4]				@ rcvr->klass()
+	tst	r3, #flag_methodInterface
+	bne	istub_methodInterface
+
+	ldr	lr, [r0, #CP_OFFSET+4]			@ lr = iclass
+
+	add	r1, tmp2, #INSTANCEKLASS_VTABLE_OFFSET
+	ldr	r2, [tmp2, #KLASS_PART+INSTANCEKLASS_VTABLE_LEN]
+	ldr	ip, [tmp2, #KLASS_PART+INSTANCEKLASS_ITABLE_LEN]
+	add	r2, r2, #1
+	bic	r2, r2, #1
+
+	add	r1, r1, r2, lsl #2
+
+	mov	r2, #0
+1:
+	cmp	r2, ip
+	beq	istub_incompatibleclass_exception
+	ldr	r3, [r1], #8
+	add	r2, r2, #1
+	cmp	lr, r3
+	bne	1b
+
+	ldr	r3, [r0, #CP_OFFSET+8]
+	ldr	r2, [r1, #-4]
+	add	r3, tmp2, r3, lsl #2
+	ldr	tmp2, [r3, r2]
+	cmp	tmp2, #0
+	beq	istub_abstractmethod_exception
+istub_invoke:
+	ldr	ip, [tmp2, #METHOD_FROM_INTERPRETED]
+	mov	r1, #0
+	str	ip, [istate, #36]
+	str	r1, [Rthread, #THREAD_LAST_JAVA_SP]
+
+	add	stack, stack, #4
+	str	stack, [Rthread, #THREAD_JAVA_SP]
+
+	ldr	r3, [ip]
+
+	mov	r0, tmp2
+	mov	r1, ip
+#ifndef SHARK
+	add	r3, r3, #CODE_ALIGN_SIZE
+#endif
+	mov	r2, Rthread
+	blx	r3
+
+	ldr	Rthread, [istate, #ISTATE_THREAD]
+
+	ldr	stack, [Rthread, #THREAD_JAVA_SP]
+	ldr	r2, [istate, #ISTATE_STACK_LIMIT]
+
+	ldr	r1, [Rthread, #THREAD_TOP_ZERO_FRAME]
+	add	r2, r2, #4
+	str	r2, [Rthread, #THREAD_JAVA_SP]
+	str	r1, [Rthread, #THREAD_LAST_JAVA_SP]
+	ldr	r3, [Rthread, #4]
+	cmp	r3, #0
+	bne	istub_exception
+	ldmia	sp!, {ip, pc}
+
+istub_methodInterface:
+	tst	r3, #flag_vfinalMethod
+	ldrne	tmp2, [r0, #CP_OFFSET+8]
+	bne	istub_invoke
+	ldr	r1, [r0, #CP_OFFSET+8]
+	add	r3, tmp2, r1, lsl #2
+	ldr	tmp2, [r3, #INSTANCEKLASS_VTABLE_OFFSET]
+	b	istub_invoke
+
+istub_resolve:
+	mov	tmp2, r1
+	mov	r1, #opc_invokeinterface
+	ldr	r0, [istate, #ISTATE_THREAD]
+	ldr	ip, resolve_invoke_adcon
+	blx	ip
+	ldr	r3, [Rthread, #4]
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	cmp	r3, #0
+	bne	istub_exception
+	add	r0, r2, tmp2, lsl #4	@ r1 = cache
+	b	2b
+
+istub_exception:
+	ldmia	sp!, {ip, lr}
+	ldr	ip, handle_exception_adcon
+	bx	ip
+
+istub_null_ptr_exception:
+	mov	r0, #VMSYMBOLS_NullPointerException
+	b	3f
+istub_abstractmethod_exception:
+	mov	r0, #VMSYMBOLS_AbstractMethodError
+	b	3f
+istub_incompatibleclass_exception:
+	mov	r0, #VMSYMBOLS_IncompatibleClassChangeError
+3:
+	CACHE_JPC
+	ldmia	sp!, {ip, lr}
+	ldr	ip, raise_exception_adcon
+	bx	ip
+
+resolve_invoke_adcon:
+	.word	_ZN18InterpreterRuntime14resolve_invokeEP10JavaThreadN9Bytecodes4CodeE
+resolve_get_put_adcon:
+       	.word   _ZN18InterpreterRuntime15resolve_get_putEP10JavaThreadN9Bytecodes4CodeE
+handle_exception_adcon:
+	.word	handle_exception_with_bcp
+raise_exception_adcon:
+	.word	raise_exception
+helper_aputfield_adcon:
+	.word	Helper_aputfield
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_invokevirtual_stub
+Thumb2_invokevirtual_stub:
+	stmdb	sp!, {ip, lr}
+        ldr     ip, [istate, #ISTATE_METHOD]
+        sub     stack, stack, #4
+        ldr     r2, [istate, #ISTATE_CONSTANTS]
+        ldr     ip, [ip, #METHOD_CONSTMETHOD]
+        DECACHE_STACK
+        add     jpc, ip, r0
+
+        add     r0, r2, r1, lsl #4
+        DECACHE_JPC
+
+        ldr     r2, [r0, #CP_OFFSET]
+        and     r2, r2, #0xff000000
+        cmp     r2, #opc_invokevirtual << 24
+        bne     ivstub_resolve
+2:
+
+	ldr	r3, [r0, #CP_OFFSET+12]
+        and     r2, r3, #255
+        ldr     r2, [stack, r2, asl #2]
+        cmp     r2, #0
+        beq     istub_null_ptr_exception
+
+        ldr     tmp2, [r0, #CP_OFFSET+8]
+        tst     r3, #flag_vfinalMethod
+        bne     1f
+
+        ldr     r3, [r2, #4]
+        add     r3, r3, tmp2, lsl #2
+        ldr     tmp2, [r3, #INSTANCEKLASS_VTABLE_OFFSET]
+1:
+	mov	r1, #0
+        ldr     ip, [tmp2, #METHOD_FROM_INTERPRETED]
+        str     r1, [Rthread, #THREAD_LAST_JAVA_SP]
+        str     ip, [istate, #36]
+
+        add     stack, stack, #4
+        str     stack, [Rthread, #THREAD_JAVA_SP]
+
+        ldr     r3, [ip, #0]
+
+	mov	r0, tmp2
+	mov	r1, ip
+#ifndef SHARK
+	add	r3, r3, #CODE_ALIGN_SIZE
+#endif
+	mov	r2, Rthread
+	blx	r3
+
+        ldr     Rthread, [istate, #ISTATE_THREAD]
+
+	ldr	stack, [Rthread, #THREAD_JAVA_SP]
+	ldr	r2, [istate, #ISTATE_STACK_LIMIT]
+
+	ldr	r1, [Rthread, #THREAD_TOP_ZERO_FRAME]
+	add	r2, r2, #4
+	str	r2, [Rthread, #THREAD_JAVA_SP]
+	str	r1, [Rthread, #THREAD_LAST_JAVA_SP]
+	ldr	r3, [Rthread, #4]
+	cmp	r3, #0
+	bne	istub_exception
+	ldmia	sp!, {ip, pc}
+
+ivstub_resolve:
+	mov	tmp2, r1
+	mov	r1, #opc_invokevirtual
+	ldr	r0, [istate, #ISTATE_THREAD]
+	ldr	ip, resolve_invoke_adcon
+	blx	ip
+	ldr	r3, [Rthread, #4]
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	cmp	r3, #0
+	bne	istub_exception
+	add	r0, r2, tmp2, lsl #4	@ r1 = cache
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_invokestatic_stub
+Thumb2_invokestatic_stub:
+        stmdb   sp!, {ip, lr}
+        ldr     ip, [istate, #ISTATE_METHOD]
+        sub     stack, stack, #4
+        ldr     r2, [istate, #ISTATE_CONSTANTS]
+        ldr     ip, [ip, #METHOD_CONSTMETHOD]
+        DECACHE_STACK
+        add     jpc, ip, r0
+
+        add     r0, r2, r1, lsl #4
+        DECACHE_JPC
+
+        ldr     r2, [r0, #CP_OFFSET]
+	and	r2, r2, #0x00ff0000
+	cmp	r2, #opc_invokestatic << 16
+	bne	isstub_resolve
+2:
+	ldr	tmp2, [r0, #CP_OFFSET+4]
+	mov	r1, #0
+	ldr	ip, [tmp2, #METHOD_FROM_INTERPRETED]
+	str	r1, [Rthread, #THREAD_LAST_JAVA_SP]
+	str	ip, [istate, #36]
+
+	add	stack, stack, #4
+	str	stack, [Rthread, #THREAD_JAVA_SP]
+
+	ldr	r3, [ip, #0]
+
+        mov     r0, tmp2
+        mov     r1, ip
+#ifndef SHARK
+        add     r3, r3, #CODE_ALIGN_SIZE
+#endif
+        mov     r2, Rthread
+        blx     r3
+
+        ldr     Rthread, [istate, #ISTATE_THREAD]
+
+        ldr     stack, [Rthread, #THREAD_JAVA_SP]
+        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
+
+        ldr     r1, [Rthread, #THREAD_TOP_ZERO_FRAME]
+        add     r2, r2, #4
+        str     r2, [Rthread, #THREAD_JAVA_SP]
+        str     r1, [Rthread, #THREAD_LAST_JAVA_SP]
+        ldr     r3, [Rthread, #4]
+        cmp     r3, #0
+        bne     istub_exception
+        ldmia   sp!, {ip, pc}
+
+isstub_resolve:
+        mov     tmp2, r1
+        mov     r1, #opc_invokestatic
+        ldr     r0, [istate, #ISTATE_THREAD]
+        ldr     ip, resolve_invoke_adcon
+        blx     ip
+        ldr     r3, [Rthread, #4]
+        ldr     r2, [istate, #ISTATE_CONSTANTS]
+        cmp     r3, #0
+        bne     istub_exception
+        add     r0, r2, tmp2, lsl #4    @ r1 = cache
+        b       2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_invokespecial_stub
+Thumb2_invokespecial_stub:
+        stmdb   sp!, {ip, lr}
+        ldr     ip, [istate, #ISTATE_METHOD]
+        sub     stack, stack, #4
+        ldr     r2, [istate, #ISTATE_CONSTANTS]
+        ldr     ip, [ip, #METHOD_CONSTMETHOD]
+        DECACHE_STACK
+        add     jpc, ip, r0
+
+        add     r0, r2, r1, lsl #4
+        DECACHE_JPC
+
+        ldr     r2, [r0, #CP_OFFSET]
+	and	r2, r2, #0x00ff0000
+	cmp	r2, #opc_invokespecial << 16
+	bne	ispstub_resolve
+2:
+        ldr     r3, [r0, #CP_OFFSET+12]
+        and     r3, r3, #255
+        ldr     r2, [stack, r3, asl #2]
+	cmp	r2, #0
+	beq	istub_null_ptr_exception
+
+	ldr	tmp2, [r0, #CP_OFFSET+4]
+	mov	r1, #0
+	ldr	ip, [tmp2, #METHOD_FROM_INTERPRETED]
+	str	r1, [Rthread, #THREAD_LAST_JAVA_SP]
+	str	ip, [istate, #36]
+
+	add	stack, stack, #4
+	str	stack, [Rthread, #THREAD_JAVA_SP]
+
+	ldr	r3, [ip, #0]
+
+        mov     r0, tmp2
+        mov     r1, ip
+#ifndef SHARK
+        add     r3, r3, #CODE_ALIGN_SIZE
+#endif
+        mov     r2, Rthread
+        blx     r3
+
+        ldr     Rthread, [istate, #ISTATE_THREAD]
+
+        ldr     stack, [Rthread, #THREAD_JAVA_SP]
+        ldr     r2, [istate, #ISTATE_STACK_LIMIT]
+
+        ldr     r1, [Rthread, #THREAD_TOP_ZERO_FRAME]
+        add     r2, r2, #4
+        str     r2, [Rthread, #THREAD_JAVA_SP]
+        str     r1, [Rthread, #THREAD_LAST_JAVA_SP]
+        ldr     r3, [Rthread, #4]
+        cmp     r3, #0
+        bne     istub_exception
+        ldmia   sp!, {ip, pc}
+
+ispstub_resolve:
+        mov     tmp2, r1
+        mov     r1, #opc_invokespecial
+        ldr     r0, [istate, #ISTATE_THREAD]
+        ldr     ip, resolve_invoke_adcon
+        blx     ip
+        ldr     r3, [Rthread, #4]
+        ldr     r2, [istate, #ISTATE_CONSTANTS]
+        cmp     r3, #0
+        bne     istub_exception
+        add     r0, r2, tmp2, lsl #4    @ r1 = cache
+        b       2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_getfield_word_stub
+Thumb2_getfield_word_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getfield << 16
+	bne	1f
+2:
+	ldr	r3, [stack], #4		@ POP r3
+	ldr	ip, [r2, #CP_OFFSET+8]
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	ldr	r3, [r3, ip]
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
+1:
+	mov	ip, lr
+	bl	getfield_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_getfield_sh_stub
+Thumb2_getfield_sh_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getfield << 16
+	bne	1f
+2:
+	ldr	r3, [stack], #4		@ POP r3
+	ldr	ip, [r2, #CP_OFFSET+8]
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	ldrsh	r3, [r3, ip]
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
+1:
+	mov	ip, lr
+	bl	getfield_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_getfield_h_stub
+Thumb2_getfield_h_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getfield << 16
+	bne	1f
+2:
+	ldr	r3, [stack], #4		@ POP r3
+	ldr	ip, [r2, #CP_OFFSET+8]
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	ldrh	r3, [r3, ip]
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
+1:
+	mov	ip, lr
+	bl	getfield_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_getfield_sb_stub
+Thumb2_getfield_sb_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getfield << 16
+	bne	1f
+2:
+	ldr	r3, [stack], #4		@ POP r3
+	ldr	ip, [r2, #CP_OFFSET+8]
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	ldrsb	r3, [r3, ip]
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
+1:
+	mov	ip, lr
+	bl	getfield_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_getfield_dw_stub
+Thumb2_getfield_dw_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getfield << 16
+	bne	1f
+2:
+	ldr	r3, [stack], #4		@ POP r3
+	ldr	ip, [r2, #CP_OFFSET+8]
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	ldrd	r2, r3, [r3, ip]
+	stmdb	stack!, {r2, r3}	@ PUSH r2, r3
+	bx	lr
+1:
+	mov	ip, lr
+	bl	getfield_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+putstatic_stub_unresolved:
+	mov	r2, #opc_putstatic
+	b	field_stub_unresolved
+getstatic_stub_unresolved:
+	mov	r2, #opc_getstatic
+	b	field_stub_unresolved
+putfield_stub_unresolved:
+	mov	r2, #opc_putfield
+	b	field_stub_unresolved
+getfield_stub_unresolved:
+	mov	r2, #opc_getfield
+field_stub_unresolved:
+	stmdb	sp!, {r0, r1, ip, lr}
+        ldr     ip, [istate, #ISTATE_METHOD]
+	sub	r3, stack, #4
+	ldr	ip, [ip, #METHOD_CONSTMETHOD]
+	str	r3, [istate, #ISTATE_STACK]	@ DECACHE_STACK
+	add	r3, ip, r0
+	str	r3, [istate, #ISTATE_BCP]	@ DECACHE_JPC
+	ldr	ip, resolve_get_put_adcon
+	mov	r1, r2
+	ldr	r0, [istate, #ISTATE_THREAD]
+	blx	ip
+	ldmia	sp!, {r0, r1, ip, lr}
+	ldr	r3, [Rthread, #4]
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	cmp	r3, #0
+	bne	field_exception
+	add	r2, r2, r1, lsl #4
+	bx	lr
+
+field_null_ptr_exception:
+        ldr     ip, [istate, #ISTATE_METHOD]
+        ldr     ip, [ip, #METHOD_CONSTMETHOD]
+        add     jpc, ip, r0
+	mov	r0, #VMSYMBOLS_NullPointerException
+	ldr	ip, raise_exception_adcon
+	bx	ip
+
+field_exception:
+	ldr	ip, handle_exception_adcon
+	bx	ip
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_putfield_word_stub
+Thumb2_putfield_word_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0xff000000
+	cmp	r3, #opc_putfield << 24
+	bne	1f
+2:
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	str	r2, [r3, ip]
+	bx	lr
+1:
+	mov	ip, lr
+	bl	putfield_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+	.global	Thumb2_putfield_h_stub
+Thumb2_putfield_h_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0xff000000
+	cmp	r3, #opc_putfield << 24
+	bne	1f
+2:
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	strh	r2, [r3, ip]
+	bx	lr
+1:
+	mov	ip, lr
+	bl	putfield_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+	.global	Thumb2_putfield_b_stub
+Thumb2_putfield_b_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0xff000000
+	cmp	r3, #opc_putfield << 24
+	bne	1f
+2:
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	strb	r2, [r3, ip]
+	bx	lr
+1:
+	mov	ip, lr
+	bl	putfield_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+	.global	Thumb2_putfield_a_stub
+Thumb2_putfield_a_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0xff000000
+	cmp	r3, #opc_putfield << 24
+	bne	1f
+2:
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	str	r2, [r3, ip]
+	ldr	ip, helper_aputfield_adcon
+	mov	r0, r3
+	bx	ip
+1:
+	mov	ip, lr
+	bl	putfield_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+	.global	Thumb2_putfield_dw_stub
+Thumb2_putfield_dw_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0xff000000
+	cmp	r3, #opc_putfield << 24
+	bne	1f
+2:
+	ldr	r1, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3, ip}	@ r2,r3 = value, ip = obj
+	cmp	ip, #0
+	beq	field_null_ptr_exception
+
+	strd	r2,r3, [ip, r1]
+	bx	lr
+1:
+	mov	ip, lr
+	bl	putfield_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_getstatic_word_stub
+Thumb2_getstatic_word_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getstatic << 16
+	bne	1f
+2:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+
+	ldr	r3, [r3, ip]
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
+1:
+	mov	ip, lr
+	bl	getstatic_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+	.global	Thumb2_getstatic_h_stub
+Thumb2_getstatic_h_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getstatic << 16
+	bne	1f
+2:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+
+	ldrh	r3, [r3, ip]
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
+1:
+	mov	ip, lr
+	bl	getstatic_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+	.global	Thumb2_getstatic_sh_stub
+Thumb2_getstatic_sh_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getstatic << 16
+	bne	1f
+2:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+
+	ldrsh	r3, [r3, ip]
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
+1:
+	mov	ip, lr
+	bl	getstatic_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+	.global	Thumb2_getstatic_sb_stub
+Thumb2_getstatic_sb_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getstatic << 16
+	bne	1f
+2:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+
+	ldrsb	r3, [r3, ip]
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
+1:
+	mov	ip, lr
+	bl	getstatic_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+	.global	Thumb2_getstatic_dw_stub
+Thumb2_getstatic_dw_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0x00ff0000
+	cmp	r3, #opc_getstatic << 16
+	bne	1f
+2:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+
+	ldrd	r2, r3, [r3, ip]
+	stmdb	stack!, {r2, r3}	@ PUSH r2, r3
+	bx	lr
+1:
+	mov	ip, lr
+	bl	getstatic_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_putstatic_word_stub
+Thumb2_putstatic_word_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0xff000000
+	cmp	r3, #opc_putstatic << 24
+	bne	1f
+2:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldr	r2, [stack], #4		@ POP r2
+
+	str	r2, [r3, ip]
+	bx	lr
+1:
+	mov	ip, lr
+	bl	putstatic_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_putstatic_h_stub
+Thumb2_putstatic_h_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0xff000000
+	cmp	r3, #opc_putstatic << 24
+	bne	1f
+2:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldr	r2, [stack], #4		@ POP r2
+
+	strh	r2, [r3, ip]
+	bx	lr
+1:
+	mov	ip, lr
+	bl	putstatic_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_putstatic_b_stub
+Thumb2_putstatic_b_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0xff000000
+	cmp	r3, #opc_putstatic << 24
+	bne	1f
+2:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldr	r2, [stack], #4		@ POP r2
+
+	strb	r2, [r3, ip]
+	bx	lr
+1:
+	mov	ip, lr
+	bl	putstatic_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_putstatic_dw_stub
+Thumb2_putstatic_dw_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0xff000000
+	cmp	r3, #opc_putstatic << 24
+	bne	1f
+2:
+	ldr	r1, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3}
+
+	strd	r2,r3, [r1, ip]
+	bx	lr
+1:
+	mov	ip, lr
+	bl	putstatic_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+@ R0 = BCI
+@ R1 = index
+	.global	Thumb2_putstatic_a_stub
+Thumb2_putstatic_a_stub:
+	ldr	r2, [istate, #ISTATE_CONSTANTS]
+	add	r2, r2, r1, lsl #4
+	ldr	r3, [r2, #CP_OFFSET]
+	and	r3, r3, #0xff000000
+	cmp	r3, #opc_putstatic << 24
+	bne	1f
+2:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldr	r2, [stack], #4		@ POP r2
+
+	str	r2, [r3, ip]
+	ldr	ip, helper_aputfield_adcon
+	mov	r0, r3
+	bx	ip
+1:
+	mov	ip, lr
+	bl	putstatic_stub_unresolved
+	mov	lr, ip
+	b	2b
+
+#endif // THUMB2EE
+
+	.global	Thumb2_stubs_end
+Thumb2_stubs_end:
+
+	ALIGN_CODE
+jdiv_1:
+	bx	lr
+jdiv_2:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+	bx	lr
+jdiv_24:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_12:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_6:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_3:
+	ldr	r1, dc_3
+        smull	r3, r2, r0, r1
+        sub	r0, r2, r0, asr #31
+	bx	lr
+jdiv_4:
+	mov	r1, r0, asr #31
+	add	r0, r0, r1, lsr #30
+	mov	r0, r0, asr #2
+	bx	lr
+jdiv_20:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_10:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_5:
+	ldr	r1, dc_5
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r0, r3, r2, asr #1
+	bx	lr
+jdiv_28:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_14:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_7:
+	ldr	r1, dc_7
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r0, r1, r3, asr #2
+	bx	lr
+jdiv_8:
+	mov	r1, r0, asr #31
+	add	r0, r0, r1, lsr #29
+	mov	r0, r0, asr #3
+	bx	lr
+jdiv_18:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_9:
+	ldr	r1, dc_9
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r0, r3, r2, asr #1
+	bx	lr
+jdiv_22:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_11:
+	ldr	r1, dc_11
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r0, r3, r2, asr #1
+	bx	lr
+jdiv_26:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_13:
+	ldr	r1, dc_13
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r0, r3, r2, asr #2
+	bx	lr
+jdiv_30:
+        add     r0, r0, r0, lsr #31
+        mov     r0, r0, asr #1
+jdiv_15:
+	ldr	r1, dc_15
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r0, r1, r3, asr #3
+	bx	lr
+jdiv_16:
+	mov	r1, r0, asr #31
+	add	r0, r0, r1, lsr #28
+	mov	r0, r0, asr #4
+	bx	lr
+jdiv_17:
+	ldr	r1, dc_17
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r0, r3, r2, asr #3
+	bx	lr
+jdiv_19:
+	ldr	r1, dc_19
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r0, r3, r2, asr #3
+	bx	lr
+jdiv_21:
+	ldr	r1, dc_21
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r0, r3, r2, asr #2
+	bx	lr
+jdiv_23:
+	ldr	r1, dc_23
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r0, r1, r3, asr #4
+	bx	lr
+jdiv_25:
+	ldr	r1, dc_25
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r0, r3, r2, asr #3
+	bx	lr
+jdiv_27:
+	ldr	r1, dc_27
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r0, r3, r2, asr #3
+	bx	lr
+jdiv_29:
+	ldr	r1, dc_29
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r0, r1, r3, asr #4
+	bx	lr
+jdiv_31:
+	ldr	r1, dc_31
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r0, r1, r3, asr #4
+	bx	lr
+jdiv_32:
+	mov	r1, r0, asr #31
+	add	r0, r0, r1, lsr #27
+	mov	r0, r0, asr #5
+	bx	lr
+jrem_1:
+	mov	r0, #0
+	bx	lr
+jrem_2:
+	add	r3, r0, r0, lsr #31
+        mov	r1, r3, asr #1
+	sub	r0, r0, r1, lsl #1
+	bx	lr
+jrem_3:
+	ldr	r1, dc_3
+        smull	r3, r2, r0, r1
+        sub	r1, r2, r0, asr #31
+	add	r3, r1, r1, lsl #1
+	sub	r0, r0, r3
+	bx	lr
+jrem_4:
+	movs	r3, r0
+        addmi	r3, r3, #3
+        mov	r1, r3, asr #2
+	sub	r0, r0, r1, lsl #2
+	bx	lr
+jrem_5:
+	ldr	r1, dc_5
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #1
+	add	r3, r1, r1, lsl #2
+	sub	r0, r0, r3
+	bx	lr
+jrem_6:
+	ldr	r1, dc_6
+        smull	r3, r2, r0, r1
+        sub	r1, r2, r0, asr #31
+	add	r3, r1, r1, lsl #1
+	sub	r0, r0, r3, lsl #1
+	bx	lr
+jrem_7:
+	ldr	r1, dc_7
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r1, r1, r3, asr #2
+	rsb	r3, r1, r1, lsl #3
+	sub	r0, r0, r3
+	bx	lr
+jrem_8:
+	movs	r3, r0
+        addmi	r3, r3, #7
+        mov	r1, r3, asr #3
+	sub	r0, r0, r1, lsl #3
+	bx	lr
+jrem_9:
+	ldr	r1, dc_9
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #1
+	add	r3, r1, r1, lsl #3
+	sub	r0, r0, r3
+	bx	lr
+jrem_10:
+	ldr	r1, dc_10
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #2
+	add	r3, r1, r1, lsl #2
+	sub	r0, r0, r3, lsl #1
+	bx	lr
+jrem_11:
+	ldr	r1, dc_11
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #1
+	add	r3, r1, r1, lsl #2
+	add	r3, r1, r3, lsl #1
+	sub	r0, r0, r3
+	bx	lr
+jrem_12:
+	ldr	r1, dc_12
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #1
+	add	r3, r1, r1, lsl #1
+	sub	r0, r0, r3, lsl #2
+	bx	lr
+jrem_13:
+	ldr	r1, dc_13
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #2
+	add	r3, r1, r1, lsl #1
+	add	r3, r1, r3, lsl #2
+	sub	r0, r0, r3
+	bx	lr
+jrem_14:
+	ldr	r1, dc_14
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r1, r1, r3, asr #3
+	rsb	r3, r1, r1, lsl #3
+	sub	r0, r0, r3, lsl #1
+	bx	lr
+jrem_15:
+	ldr	r1, dc_15
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r1, r1, r3, asr #3
+	rsb	r3, r1, r1, lsl #4
+	sub	r0, r0, r3
+	bx	lr
+jrem_16:
+	movs	r3, r0
+        addmi	r3, r3, #15
+        mov	r1, r3, asr #4
+	sub	r0, r0, r1, lsl #4
+	bx	lr
+jrem_17:
+	ldr	r1, dc_17
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #3
+	add	r3, r1, r1, lsl #4
+	sub	r0, r0, r3
+	bx	lr
+jrem_18:
+	ldr	r1, dc_18
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #2
+	add	r3, r1, r1, lsl #3
+	sub	r0, r0, r3, lsl #1
+	bx	lr
+jrem_19:
+	ldr	r1, dc_19
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #3
+	add	r3, r1, r1, lsl #3
+	add	r3, r1, r3, lsl #1
+	sub	r0, r0, r3
+	bx	lr
+jrem_20:
+	ldr	r1, dc_20
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #3
+	add	r3, r1, r1, lsl #2
+	sub	r0, r0, r3, lsl #2
+	bx	lr
+jrem_21:
+	ldr	r1, dc_21
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #2
+	add	r3, r1, r1, lsl #1
+	rsb	r3, r3, r3, lsl #3
+	sub	r0, r0, r3
+	bx	lr
+jrem_22:
+	ldr	r1, dc_22
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #2
+	add	r3, r1, r1, lsl #2
+	add	r3, r1, r3, lsl #1
+	sub	r0, r0, r3, lsl #1
+	bx	lr
+jrem_23:
+	ldr	r1, dc_23
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r1, r1, r3, asr #4
+	add	r3, r1, r1, lsl #1
+	rsb	r3, r1, r3, lsl #3
+	sub	r0, r0, r3
+	bx	lr
+jrem_24:
+	ldr	r1, dc_24
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #2
+	add	r3, r1, r1, lsl #1
+	sub	r0, r0, r3, lsl #3
+	bx	lr
+jrem_25:
+	ldr	r1, dc_25
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #3
+	add	r3, r1, r1, lsl #2
+	add	r3, r3, r3, lsl #2
+	sub	r0, r0, r3
+	bx	lr
+jrem_26:
+	ldr	r1, dc_26
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #3
+	add	r3, r1, r1, lsl #1
+	add	r3, r1, r3, lsl #2
+	sub	r0, r0, r3, lsl #1
+	bx	lr
+jrem_27:
+	ldr	r1, dc_27
+        smull	r3, r2, r0, r1
+        mov	r3, r0, asr #31
+        rsb	r1, r3, r2, asr #3
+	add	r3, r1, r1, lsl #1
+	add	r3, r3, r3, lsl #3
+	sub	r0, r0, r3
+	bx	lr
+jrem_28:
+	ldr	r1, dc_28
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r1, r1, r3, asr #4
+	rsb	r3, r1, r1, lsl #3
+	sub	r0, r0, r3, lsl #2
+	bx	lr
+jrem_29:
+	ldr	r1, dc_29
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r1, r1, r3, asr #4
+	rsb	r3, r1, r1, lsl #3
+	add	r3, r1, r3, lsl #2
+	sub	r0, r0, r3
+	bx	lr
+jrem_30:
+	ldr	r1, dc_30
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r1, r1, r3, asr #4
+	rsb	r3, r1, r1, lsl #4
+	sub	r0, r0, r3, lsl #1
+	bx	lr
+jrem_31:
+	ldr	r1, dc_31
+        smull	r3, r2, r0, r1
+        mov	r1, r0, asr #31
+        add	r3, r0, r2
+        rsb	r1, r1, r3, asr #4
+	rsb	r3, r1, r1, lsl #5
+	sub	r0, r0, r3
+	bx	lr
+jrem_32:
+	movs	r3, r0
+        addmi	r3, r3, #31
+        mov	r1, r3, asr #5
+	sub	r0, r0, r1, lsl #5
+	bx	lr
+	ALIGN_DATA
+dc_7:
+dc_14:
+	.word     0x92492493
+dc_15:
+dc_30:
+	.word     0x88888889
+dc_23:
+	.word     0xb21642c9
+dc_28:
+	.word     0x92492493
+dc_29:
+	.word     0x8d3dcb09
+dc_31:
+	.word     0x84210843
+dc_6:
+dc_12:
+dc_24:
+	.word     0x2aaaaaab
+dc_19:
+	.word     0x6bca1af3
+dc_5:
+dc_10:
+dc_20:
+	.word     0x66666667
+dc_21:
+	.word     0x30c30c31
+dc_11:
+dc_22:
+	.word     0x2e8ba2e9
+dc_26:
+dc_13:
+	.word     0x4ec4ec4f
+dc_25:
+	.word     0x51eb851f
+dc_27:
+	.word     0x4bda12f7
+dc_3:
+	.word     0x55555556
+dc_17:
+	.word     0x78787879
+dc_9:
+dc_18:
+	.word     0x38e38e39
+
+	.global	Thumb2_DivZero_Handler
+Thumb2_DivZero_Handler:
+	adrl	r0, idiv_clz_ret
+	cmp	r0, lr
+	addne	r0, r0, #irem_clz_ret - idiv_clz_ret
+	cmpne	r0, lr
+	beq	divide_by_zero_exception
+	ldr	r0, [istate, #ISTATE_METHOD]
+        ldr     jpc, [r0, #METHOD_CONSTMETHOD]
+	add	jpc, jpc, #CONSTMETHOD_CODEOFFSET
+	bl	load_dispatch
+	b	divide_by_zero_exception
+
+#ifdef THUMB2EE
+
+	.global	Thumb2_Handle_Exception
+	.global	Thumb2_ArrayBounds_Handler
+	.global	Thumb2_NullPtr_Handler
+Thumb2_ArrayBounds_Handler:
+	ldr	r0, [istate, #ISTATE_METHOD]
+        ldr     jpc, [r0, #METHOD_CONSTMETHOD]
+	add	jpc, jpc, #CONSTMETHOD_CODEOFFSET
+	bl	load_dispatch
+	mov	r0, #VMSYMBOLS_ArrayIndexOutOfBounds
+	b	raise_exception
+Thumb2_Handle_Exception:
+	ldr	r0, [istate, #ISTATE_METHOD]
+        ldr     jpc, [r0, #METHOD_CONSTMETHOD]
+	add	jpc, jpc, #CONSTMETHOD_CODEOFFSET
+	bl	load_dispatch
+	b	handle_exception
+
+	.global	Thumb2_Exit_To_Interpreter
+Thumb2_Exit_To_Interpreter:
+	bl	load_dispatch
+	sub	stack, stack, #4
+	CACHE_CP
+	CACHE_LOCALS
+	DISPATCH	0
+
+Thumb2_NullPtr_Handler:
+	ldr	r0, [istate, #ISTATE_METHOD]
+        ldr     jpc, [r0, #METHOD_CONSTMETHOD]
+	add	jpc, jpc, #CONSTMETHOD_CODEOFFSET
+	bl	load_dispatch
+	b	null_ptr_exception
+
+	.global	Thumb2_Clear_Cache
+Thumb2_Clear_Cache:
+	stmdb	sp!, {r7}
+	mov	r2, #0
+	mov	r7, #2
+	orr	r7, r7, #0xf0000
+	svc	0
+	ldmia	sp!, {r7}
+	bx	lr
+
+#endif // THUMB2EE
+
 	.section	.init_array,"aw",%init_array
 	.word	bci_init(target1)
 
 	.data
+	.global	CPUInfo
 	ALIGN_DATA
-#ifdef CODETRACE
-CodeTrace_Buffer_Base:
-	.space	CODETRACE_BUFFER_SIZE
-#endif
         .word   0, 0, 0, 0, 0, 0, 0, 0
         .word   0, 0, 0, 0, 0
 DispatchBreakPoint:					.word	0
-VFP_Flag:						.word	0
+CPUInfo:						.word	0
 CodeTrace_Idx:						.word	0
 UseOnStackReplacement_Address:                          .word   0
 BackgroundCompilation_Address:                          .word   0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/cpu/zero/vm/thumb2.cpp	Thu Jan 28 16:34:49 2010 +0000
@@ -0,0 +1,7141 @@
+#ifdef THUMB2EE
+
+#define T2EE_PRINT_COMPILATION
+#define T2EE_PRINT_STATISTICS
+//#define T2EE_PRINT_DISASS
+#define T2EE_PRINT_REGUSAGE
+
+#ifdef T2EE_PRINT_COMPILATION
+static char *t2ee_print_compilation;
+#endif
+
+#ifdef T2EE_PRINT_STATISTICS
+static char *t2ee_print_statistics;
+#endif
+
+#ifdef T2EE_PRINT_DISASS
+static char *t2ee_print_disass;
+#endif
+
+#ifdef T2EE_PRINT_REGUSAGE
+static char *t2ee_print_regusage;
+#endif
+
+#define THUMB2_CODEBUF_SIZE (8 * 1024 * 1024)
+
+#include <sys/mman.h>
+
+#include "incls/_precompiled.incl"
+
+#ifdef T2EE_PRINT_DISASS
+#include "dis-asm.h"
+#include "bfd.h"
+#endif
+
+#define opc_nop			0x00
+#define opc_aconst_null		0x01
+#define opc_iconst_m1		0x02
+#define opc_iconst_0		0x03
+#define opc_iconst_1		0x04
+#define opc_iconst_2		0x05
+#define opc_iconst_3		0x06
+#define opc_iconst_4		0x07
+#define opc_iconst_5		0x08
+#define opc_lconst_0		0x09
+#define opc_lconst_1		0x0a
+#define opc_fconst_0		0x0b
+#define opc_fconst_1		0x0c
+#define opc_fconst_2		0x0d
+#define opc_dconst_0		0x0e
+#define opc_dconst_1		0x0f
+#define opc_bipush		0x10
+#define opc_sipush		0x11
+#define opc_ldc			0x12
+#define opc_ldc_w		0x13
+#define opc_ldc2_w		0x14
+#define opc_iload		0x15
+#define opc_lload		0x16
+#define opc_fload		0x17
+#define opc_dload		0x18
+#define opc_aload		0x19
+#define opc_iload_0		0x1a
+#define opc_iload_1		0x1b
+#define opc_iload_2		0x1c
+#define opc_iload_3		0x1d
+#define opc_lload_0		0x1e
+#define opc_lload_1		0x1f
+#define opc_lload_2		0x20
+#define opc_lload_3		0x21
+#define opc_fload_0		0x22
+#define opc_fload_1		0x23
+#define opc_fload_2		0x24
+#define opc_fload_3		0x25
+#define opc_dload_0		0x26
+#define opc_dload_1		0x27
+#define opc_dload_2		0x28
+#define opc_dload_3		0x29
+#define opc_aload_0		0x2a
+#define opc_aload_1		0x2b
+#define opc_aload_2		0x2c
+#define opc_aload_3		0x2d
+#define opc_iaload		0x2e
+#define opc_laload		0x2f
+#define opc_faload		0x30
+#define opc_daload		0x31
+#define opc_aaload		0x32
+#define opc_baload		0x33
+#define opc_caload		0x34
+#define opc_saload		0x35
+#define opc_istore		0x36
+#define opc_lstore		0x37
+#define opc_fstore		0x38
+#define opc_dstore		0x39
+#define opc_astore		0x3a
+#define opc_istore_0		0x3b
+#define opc_istore_1		0x3c
+#define opc_istore_2		0x3d
+#define opc_istore_3		0x3e
+#define opc_lstore_0		0x3f
+#define opc_lstore_1		0x40
+#define opc_lstore_2		0x41
+#define opc_lstore_3		0x42
+#define opc_fstore_0		0x43
+#define opc_fstore_1		0x44
+#define opc_fstore_2		0x45
+#define opc_fstore_3		0x46
+#define opc_dstore_0		0x47
+#define opc_dstore_1		0x48
+#define opc_dstore_2		0x49
+#define opc_dstore_3		0x4a
+#define opc_astore_0		0x4b
+#define opc_astore_1		0x4c
+#define opc_astore_2		0x4d
+#define opc_astore_3		0x4e
+#define opc_iastore		0x4f
+#define opc_lastore		0x50
+#define opc_fastore		0x51
+#define opc_dastore		0x52
+#define opc_aastore		0x53
+#define opc_bastore		0x54
+#define opc_castore		0x55
+#define opc_sastore		0x56
+#define opc_pop			0x57
+#define opc_pop2		0x58
+#define opc_dup			0x59
+#define opc_dup_x1		0x5a
+#define opc_dup_x2		0x5b
+#define opc_dup2		0x5c
+#define opc_dup2_x1		0x5d
+#define opc_dup2_x2		0x5e
+#define opc_swap		0x5f
+#define opc_iadd		0x60
+#define opc_ladd		0x61
+#define opc_fadd		0x62
+#define opc_dadd		0x63
+#define opc_isub		0x64
+#define opc_lsub		0x65
+#define opc_fsub		0x66
+#define opc_dsub		0x67
+#define opc_imul		0x68
+#define opc_lmul		0x69
+#define opc_fmul		0x6a
+#define opc_dmul		0x6b
+#define opc_idiv		0x6c
+#define opc_ldiv		0x6d
+#define opc_fdiv		0x6e
+#define opc_ddiv		0x6f
+#define opc_irem		0x70
+#define opc_lrem		0x71
+#define opc_frem		0x72
+#define opc_drem		0x73
+#define opc_ineg		0x74
+#define opc_lneg		0x75
+#define opc_fneg		0x76
+#define opc_dneg		0x77
+#define opc_ishl		0x78
+#define opc_lshl		0x79
+#define opc_ishr		0x7a
+#define opc_lshr		0x7b
+#define opc_iushr		0x7c
+#define opc_lushr		0x7d
+#define opc_iand		0x7e
+#define opc_land		0x7f
+#define opc_ior			0x80
+#define opc_lor			0x81
+#define opc_ixor		0x82
+#define opc_lxor		0x83
+#define opc_iinc		0x84
+#define opc_i2l			0x85
+#define opc_i2f			0x86
+#define opc_i2d			0x87
+#define opc_l2i			0x88
+#define opc_l2f			0x89
+#define opc_l2d			0x8a
+#define opc_f2i			0x8b
+#define opc_f2l			0x8c
+#define opc_f2d			0x8d
+#define opc_d2i			0x8e
+#define opc_d2l			0x8f
+#define opc_d2f			0x90
+#define opc_i2b			0x91
+#define opc_i2c			0x92
+#define opc_i2s			0x93
+#define opc_lcmp		0x94
+#define opc_fcmpl		0x95
+#define opc_fcmpg		0x96
+#define opc_dcmpl		0x97
+#define opc_dcmpg		0x98
+#define opc_ifeq		0x99
+#define opc_ifne		0x9a
+#define opc_iflt		0x9b
+#define opc_ifge		0x9c
+#define opc_ifgt		0x9d
+#define opc_ifle		0x9e
+#define opc_if_icmpeq		0x9f
+#define opc_if_icmpne		0xa0
+#define opc_if_icmplt		0xa1
+#define opc_if_icmpge		0xa2
+#define opc_if_icmpgt		0xa3
+#define opc_if_icmple		0xa4
+#define opc_if_acmpeq		0xa5
+#define opc_if_acmpne		0xa6
+#define opc_goto		0xa7
+#define opc_jsr			0xa8
+#define opc_ret			0xa9
+#define opc_tableswitch		0xaa
+#define opc_lookupswitch	0xab
+#define opc_ireturn		0xac
+#define opc_lreturn		0xad
+#define opc_freturn		0xae
+#define opc_dreturn		0xaf
+#define opc_areturn		0xb0
+#define opc_return		0xb1
+#define opc_getstatic		0xb2
+#define opc_putstatic		0xb3
+#define opc_getfield		0xb4
+#define opc_putfield		0xb5
+#define opc_invokevirtual	0xb6
+#define opc_invokespecial	0xb7
+#define opc_invokestatic	0xb8
+#define opc_invokeinterface	0xb9
+#define opc_new			0xbb
+#define opc_newarray		0xbc
+#define opc_anewarray		0xbd
+#define opc_arraylength		0xbe
+#define opc_athrow		0xbf
+#define opc_checkcast		0xc0
+#define opc_instanceof		0xc1
+#define opc_monitorenter	0xc2
+#define opc_monitorexit		0xc3
+#define opc_wide		0xc4
+#define opc_multianewarray	0xc5
+#define opc_ifnull		0xc6
+#define opc_ifnonnull		0xc7
+#define opc_goto_w		0xc8
+#define opc_jsr_w		0xc9
+#define opc_breakpoint		0xca
+
+#define OPC_LAST_JAVA_OP	0xca
+
+#define opc_bgetfield			0xcc
+#define opc_cgetfield			0xcd
+#define opc_igetfield			0xd0
+#define opc_lgetfield			0xd1
+#define opc_sgetfield			0xd2
+#define opc_aputfield			0xd3
+#define opc_bputfield			0xd4
+#define opc_cputfield			0xd5
+#define opc_iputfield			0xd8
+#define opc_lputfield			0xd9
+#define opc_iaccess_0			0xdb
+#define opc_iaccess_1			0xdc
+#define opc_iaccess_2			0xdd
+#define opc_iaccess_3			0xde
+#define opc_invokeresolved		0xdf
+#define opc_invokespecialresolved	0xe0
+#define opc_invokestaticresolved	0xe1
+#define opc_invokevfinal		0xe2
+#define opc_iload_iload			0xe3
+#define opc_iload_iload_N		0xe4
+#define opc_return_register_finalizer	0xe5
+#define opc_dmac			0xe6
+#define opc_iload_0_iconst_N		0xe7
+#define opc_iload_1_iconst_N		0xe8
+#define opc_iload_2_iconst_N		0xe9
+#define opc_iload_3_iconst_N		0xea
+#define opc_iload_iconst_N		0xeb
+#define opc_iadd_istore_N		0xec
+#define opc_isub_istore_N		0xed
+#define opc_iand_istore_N		0xee
+#define opc_ior_istore_N		0xef
+#define opc_ixor_istore_N		0xf0
+#define opc_iadd_u4store		0xf1
+#define opc_isub_u4store		0xf2
+#define opc_iand_u4store		0xf3
+#define opc_ior_u4store			0xf4
+#define opc_ixor_u4store		0xf5
+#define opc_iload_0_iload		0xf6
+#define opc_iload_1_iload		0xf7
+#define opc_iload_2_iload		0xf8
+#define opc_iload_3_iload		0xf9
+#define opc_iload_0_iload_N		0xfa
+#define opc_iload_1_iload_N		0xfb
+#define opc_iload_2_iload_N		0xfc
+#define opc_iload_3_iload_N		0xfd
+
+#define H_IREM				0
+#define H_IDIV				1
+#define H_LDIV				2
+#define H_LREM				3
+#define H_FREM				4
+#define H_DREM				5
+#define	H_LDC				6
+#define H_NEW				8
+#define H_I2F				9
+#define H_I2D				10
+#define H_L2F				11
+#define H_L2D				12
+#define H_F2I				13
+#define H_F2L				14
+#define H_F2D				15
+#define H_D2I				16
+#define H_D2L				17
+#define H_D2F				18
+#define H_NEWARRAY			19
+#define H_ANEWARRAY			20
+#define H_MULTIANEWARRAY		21
+#define H_INSTANCEOF			22
+#define H_CHECKCAST			23
+#define H_AASTORE			24
+#define H_APUTFIELD			25
+#define H_SYNCHRONIZED_ENTER		26
+#define H_SYNCHRONIZED_EXIT		27
+
+#define H_EXIT_TO_INTERPRETER		28
+
+#define H_GETSTATIC			H_EXIT_TO_INTERPRETER
+#define H_PUTSTATIC			H_EXIT_TO_INTERPRETER
+#define H_JSR				H_EXIT_TO_INTERPRETER
+#define H_RET				H_EXIT_TO_INTERPRETER
+#define H_ZOMBIE			H_EXIT_TO_INTERPRETER
+#define H_MONITOR			H_EXIT_TO_INTERPRETER
+#define H_ATHROW			H_EXIT_TO_INTERPRETER
+
+#define H_HANDLE_EXCEPTION		29
+#define H_ARRAYBOUND			30
+#define H_UNKNOWN			31
+
+#define H_DEBUG_METHODENTRY		32
+#define H_DEBUG_METHODEXIT		33
+#define H_DEBUG_METHODCALL		34
+
+#define H_INVOKEINTERFACE		35
+#define H_INVOKEVIRTUAL			36
+#define H_INVOKESTATIC			37
+#define H_INVOKESPECIAL			38
+
+#define H_GETFIELD_WORD			39
+#define H_GETFIELD_SH			40
+#define H_GETFIELD_H			41
+#define H_GETFIELD_SB			42
+#define H_GETFIELD_DW			43
+
+#define H_PUTFIELD_WORD			44
+#define H_PUTFIELD_H			45
+#define H_PUTFIELD_B			46
+#define H_PUTFIELD_A			47
+#define H_PUTFIELD_DW			48
+
+#define H_GETSTATIC_WORD		49
+#define H_GETSTATIC_SH			50
+#define H_GETSTATIC_H			51
+#define H_GETSTATIC_SB			52
+#define H_GETSTATIC_DW			53
+
+#define H_PUTSTATIC_WORD		54
+#define H_PUTSTATIC_H			55
+#define H_PUTSTATIC_B			56
+#define H_PUTSTATIC_A			57
+#define H_PUTSTATIC_DW			58
+
+unsigned handlers[59];
+
+#define JASSERT(cond, msg)	do { if (!(cond)) fatal(msg); } while (0)
+#define J_Unimplemented()       { report_unimplemented(__FILE__, __LINE__); BREAKPOINT; }
+
+#define GET_NATIVE_U2(p)	(*(unsigned short *)(p))
+
+#define GET_JAVA_S1(p)		(((signed char *)(p))[0])
+#define GET_JAVA_S2(p)  	((((signed char *)(p))[0] << 8) + (p)[1])
+#define GET_JAVA_U2(p)		(((p)[0] << 8) + (p)[1])
+#define GET_JAVA_U4(p)		(((p)[0] << 24) + ((p)[1] << 16) + ((p)[2] << 8) + (p)[3])
+
+#define BYTESEX_REVERSE(v) (((v)<<24) | (((v)<<8) & 0xff0000) | (((v)>>8) & 0xff00) | ((v)>>24))
+#define BYTESEX_REVERSE_U2(v) (((v)<<8) | ((v)>>8))
+
+typedef struct Thumb2_CodeBuf {
+  unsigned size;
+  char *sp;
+  char *hp;
+} Thumb2_CodeBuf;
+
+Thumb2_CodeBuf *thumb2_codebuf;
+
+unsigned bc_stackinfo[8000];
+unsigned locals_info[1000];
+unsigned stack[1000];
+unsigned r_local[1000];
+
+#ifdef T2EE_PRINT_DISASS
+short start_bci[65000];
+short end_bci[65000];
+#endif
+
+// XXX hardwired constants!
+#define ENTRY_FRAME             1
+#define INTERPRETER_FRAME       2
+#define SHARK_FRAME             3
+#define FAKE_STUB_FRAME         4
+
+#include "offsets_arm.s"
+
+#define BC_FLAGS_MASK		0xfc000000
+#define BC_VISITED_P1		0x80000000
+#define BC_BRANCH_TARGET	0x40000000
+#define BC_COMPILED		0x20000000
+#define BC_VISITED_P2		0x10000000
+#define BC_ZOMBIE		0x08000000
+#define BC_BACK_TARGET		0x04000000
+
+#define IS_DEAD(x)	(((x) & BC_VISITED_P1) == 0)
+#define IS_ZOMBIE(x)	(((x) & BC_ZOMBIE) || ((x) & BC_VISITED_P2) == 0)
+
+#define LOCAL_MODIFIED		31
+#define LOCAL_REF		30
+#define LOCAL_DOUBLE		29
+#define LOCAL_FLOAT		28
+#define LOCAL_LONG		27
+#define LOCAL_INT		26
+#define LOCAL_ALLOCATED		25
+
+#define LOCAL_COUNT_BITS	10
+#define LOCAL_READ_POS		0
+#define LOCAL_WRITE_POS		LOCAL_COUNT_BITS
+
+#define LOCAL_READS(x)		(((x) >> LOCAL_READ_POS) & ((1<<LOCAL_COUNT_BITS)-1))
+#define LOCAL_WRITES(x)		(((x) >> LOCAL_WRITE_POS) & ((1<<LOCAL_COUNT_BITS)-1))
+#define LOCAL_SET_COUNTS(r, w)	(((r) << LOCAL_READ_POS) | (((w) << LOCAL_WRITE_POS)))
+#define LOCAL_INC_COUNT(c)	((c) < ((1<<LOCAL_COUNT_BITS)-1) ? (c)+1 : (c))
+
+#define STACK_REGS	4
+#define FP_STACK_REGS	4
+
+typedef unsigned	u32;
+typedef unsigned	Reg;
+
+#define	ARM_R0		0
+#define ARM_R1		1
+#define ARM_R2		2
+#define ARM_R3		3
+#define ARM_R4		4
+#define ARM_R5		5
+#define ARM_R6		6
+#define ARM_R7		7
+#define ARM_R8		8
+#define ARM_R9		9
+#define ARM_R10		10
+#define ARM_R11		11
+#define ARM_IP		12
+#define ARM_SP		13
+#define ARM_LR		14
+#define ARM_PC		15
+#define ARM_CPSR	16	// CPSR in sigcontext
+#define ARM_FAULT	17	// fault address in sigcontext
+
+#define CPSR_THUMB_BIT	(1<<5)
+
+#define VFP_S0		32
+#define VFP_S1		33
+#define VFP_S2		34
+#define VFP_S3		35
+#define VFP_S4		36
+#define VFP_S5		37
+#define VFP_S6		38
+#define VFP_S7		39
+
+#define VFP_D0		64
+#define VFP_D1		65
+#define VFP_D2		66
+#define VFP_D3		67
+#define VFP_D4		68
+#define VFP_D5		69
+#define VFP_D6		70
+#define VFP_D7		71
+
+#define JAZ_V1	ARM_R6
+#define JAZ_V2	ARM_R5
+#define JAZ_V3	ARM_R7
+#define JAZ_V4	ARM_R11
+#define JAZ_V5	ARM_R10
+
+#define Rstack		ARM_R4
+#define Rlocals		ARM_R7
+#define Ristate		ARM_R8
+#define Rthread		ARM_R9
+
+#define Rint_stack	ARM_R4
+#define Rint_jpc	ARM_R5
+#define Rint_istate	ARM_R8
+
+#define IS_ARM_INT_REG(r) ((r) <= ARM_PC)
+#define IS_ARM_FP_REG(r) (!IS_ARM_INT_REG(r))
+
+#define I_REGSET	((1<<ARM_R4) | (1<<ARM_R5) | (1<<ARM_R6) | (1<<ARM_R7) | \
+			 (1<<ARM_R9) | (1<<ARM_R10) | (1<<ARM_R11))
+#define C_REGSET	(1<<ARM_R8)
+
+#define LOG2(n) binary_log2(n)
+
+unsigned binary_log2(unsigned n)
+{
+  unsigned r = 0;
+  if ((n & 0xffff) == 0) r = 16, n >>= 16;
+  if ((n & 0xff) == 0) r += 8, n >>= 8;
+  if ((n & 0xf) == 0) r += 4, n >>= 4;
+  if ((n & 3) == 0) r += 2, n >>= 2;
+  if ((n & 1) == 0) r += 1;
+  return r;
+}
+
+typedef struct CodeBuf {
+    unsigned short *codebuf;
+    unsigned idx;
+} CodeBuf;
+
+typedef struct Thumb2_Stack {
+    unsigned *stack;
+    unsigned depth;
+} Thumb2_Stack;
+
+#define IS_SREG(r) ((r) < STACK_REGS)
+
+typedef struct Thumb2_Registers {
+    unsigned *r_local;
+} Thumb2_Registers;
+
+typedef struct Thumb2_Info {
+    JavaThread *thread;
+    methodOop method;
+    unsigned *bc_stackinfo;
+    unsigned *locals_info;
+    jubyte *code_base;
+    unsigned code_size;
+    CodeBuf *codebuf;
+    Thumb2_Stack *jstack;
+    Thumb2_Registers *jregs;
+    unsigned compiled_return;
+    unsigned zombie_bytes;
+} Thumb2_Info;
+
+#define IS_INT_SIZE_BASE_TYPE(c) (c=='B' || c=='C' || c=='F' || c=='I' || c=='S' || c=='Z')
+#define IS_INT_SIZE_TYPE(c) (IS_INT_SIZE_BASE_TYPE(c) || c == 'L' || c == '[')
+
+static int method_stackchange(jbyte *base)
+{
+  jbyte c;
+  int stackchange = 0;
+
+  c = *base++;
+  JASSERT(c == '(', "Invalid signature, missing '('");
+  while ((c = *base++) != ')') {
+    stackchange -= 1;
+    if (c == 'J' || c == 'D') {
+      stackchange -= 1;
+    } else if (c == '[') {
+      do { c = *base++; } while (c == '[');
+      if (c == 'L')
+	do { c = *base++; } while (c != ';');
+    } else if (c == 'L') {
+      do { c = *base++; } while (c != ';');
+    } else {
+      JASSERT(IS_INT_SIZE_BASE_TYPE(c), "Invalid signature, bad arg type");
+    }
+  }
+  JASSERT(c == ')', "Invalid signature, missing ')'");
+  c = *base++;
+  if (c == 'J' || c == 'D') stackchange += 2;
+  else if (c != 'V') {
+    stackchange += 1;
+    JASSERT(IS_INT_SIZE_TYPE(c), "Invalid signature, bad ret type");
+  }
+  return stackchange;
+}
+
+static void Thumb2_local_info_from_sig(Thumb2_Info *jinfo, methodOop method, jbyte *base)
+{
+  jbyte c;
+  unsigned arg = 0;
+  unsigned *locals_info = jinfo->locals_info;
+  unsigned local_info;
+
+  if (!method->is_static()) locals_info[arg++] = 1 << LOCAL_REF;
+  c = *base++;
+  JASSERT(c == '(', "Invalid signature, missing '('");
+  while ((c = *base++) != ')') {
+    local_info = 1 << LOCAL_INT;
+    if (c == 'J') local_info = 1 << LOCAL_LONG;
+    else if (c == 'D') local_info = 1 << LOCAL_DOUBLE;
+    else if (c == '[') {
+      local_info = 1 << LOCAL_REF;
+      do { c = *base++; } while (c == '[');
+      if (c == 'L')
+	do { c = *base++; } while (c != ';');
+    } else if (c == 'L') {
+      local_info = 1 << LOCAL_REF;
+      do { c = *base++; } while (c != ';');
+    } else {
+      JASSERT(IS_INT_SIZE_BASE_TYPE(c), "Invalid signature, bad arg type");
+    }
+    locals_info[arg++] = local_info;
+  }
+}
+
+#define T_UNDEFINED_32	0xf7f0a000
+#define T_UNDEFINED_16	0xde00
+
+static const char *local_types[] = { "int", "long", "float", "double", "ref" };
+
+#ifdef T2EE_PRINT_DISASS
+void Thumb2_disass(Thumb2_Info *jinfo)
+{
+  unsigned code_size = jinfo->code_size;
+  jubyte *code_base = jinfo->code_base;
+  unsigned *bc_stackinfo = jinfo->bc_stackinfo;
+  unsigned *locals_info = jinfo->locals_info;
+  unsigned nlocals = jinfo->method->max_locals();
+  int bci = 0;
+  int last_bci = -1;
+  int start_b, end_b;
+  unsigned nodisass;
+
+  struct disassemble_info info;
+  unsigned short *codebuf = jinfo->codebuf->codebuf;
+  unsigned idx, compiled_len;
+
+#if 0
+  printf("Local Variable Usage\n");
+  printf("====================\n");
+  for (idx = 0; idx < nlocals; idx++) {
+    unsigned linfo = locals_info[idx];
+    unsigned typ = (linfo >> LOCAL_INT) & 0x1f;
+
+    printf("Local %d, type = %s (%x)", idx, typ ? local_types[LOG2(typ)] : "!!!unknown!!!", typ);
+    if (linfo & (1 << LOCAL_MODIFIED)) printf(", modified");
+    if (idx < (unsigned)jinfo->method->size_of_parameters()) printf(", parameter");
+    putchar('\n');
+  }
+#endif
+
+  init_disassemble_info(&info, stdout, (fprintf_ftype)fprintf);
+  info.arch = bfd_arch_arm;
+  disassemble_init_for_target(&info);
+  info.endian = BFD_ENDIAN_LITTLE;
+  info.endian_code = BFD_ENDIAN_LITTLE;
+  info.buffer = (bfd_byte *)codebuf;
+  info.buffer_vma = (bfd_vma)codebuf;
+  info.buffer_length = jinfo->codebuf->idx * sizeof(short);
+  info.disassembler_options = (char *)"force-thumb";
+
+  compiled_len = jinfo->codebuf->idx * 2;
+  for (idx = 0; idx < compiled_len; ) {
+    nodisass = 0;
+    start_b = start_bci[idx/2];
+    end_b = end_bci[idx/2];
+    if (start_b != -1) {
+      last_bci != -1;
+      for (bci = start_b; bci < end_b; ) {
+	unsigned stackinfo = bc_stackinfo[bci];
+	unsigned opcode;
+	int len;
+
+	if (stackinfo & BC_BRANCH_TARGET)
+	  printf("----- Basic Block -----\n");
+	JASSERT(bci > last_bci, "disass not advancing");
+	last_bci = bci;
+	printf("%c%4d : ", (stackinfo & BC_VISITED_P1) ? ' ' : '?', bci);
+	opcode = code_base[bci];
+	if (opcode > OPC_LAST_JAVA_OP) {
+	  if (Bytecodes::is_defined((Bytecodes::Code)opcode))
+	    opcode = (unsigned)Bytecodes::java_code((Bytecodes::Code)opcode);
+	}
+	len = Bytecodes::length_for((Bytecodes::Code)opcode);
+	if (len <= 0) len = Bytecodes::special_length_at((address)(code_base+bci), (address)(code_base+code_size));
+	switch (opcode) {
+	  case opc_tableswitch: {
+	    int nbci = (bci & ~3) + 4;
+	    int low, high;
+	    unsigned w;
+	    unsigned *table;
+	    int def;
+	    unsigned n, i;
+
+	    printf("%02x ", opcode);
+	    for (int i = 1; i < 5; i++)
+	      printf("   ");
+	    printf("%s\n", Bytecodes::name((Bytecodes::Code)opcode));
+	    printf("\t%d bytes padding\n", nbci - (bci+1));
+	    w = *(unsigned int *)(code_base + nbci + 4);
+	    low = (int)BYTESEX_REVERSE(w);
+	    w = *(unsigned int *)(code_base + nbci + 8);
+	    high = (int)BYTESEX_REVERSE(w);
+	    w = *(unsigned int *)(code_base + nbci + 0);
+	    def = (int)BYTESEX_REVERSE(w);
+	    table = (unsigned int *)(code_base + nbci + 12);
+	    printf("\tdefault:\t0x%08x\n", def);
+	    printf("\tlow:\t\t0x%08x\n", low);
+	    printf("\thigh:\t\t0x%08x\n", high);
+	    n = high - low + 1;
+	    while (low <= high) {
+	      int off;
+
+	      w = *table++;
+	      off = (int)BYTESEX_REVERSE(w);
+	      printf("\toffset %d:\t0x%08x\n", low, off);
+	      low++;
+	    }
+	    bci += len;
+	    for (i = 0; i < 4; i++) {
+	      printf("0x%08x:\t", (int)codebuf+idx);
+	      {
+		int len = print_insn_little_arm((bfd_vma)codebuf+idx, &info);
+		if (len == -1) len = 2;
+		idx += len;
+		putchar('\n');
+	      }
+	    }
+	    for (i = 0; i < n; i++) {
+	      printf("0x%08x:\t.short\t0x%04x\n", (int)codebuf+idx, *(short *)((int)codebuf + idx));
+	      idx += 2;
+	    }
+	    nodisass = 1;
+	    break;
+	  }
+	  case opc_lookupswitch: {
+	    unsigned w;
+	    unsigned nbci = (bci & ~3) + 4;;
+	    int def;
+	    int npairs;	// The Java spec says signed but must be >= 0??
+	    unsigned *table;
+
+	    printf("%02x ", opcode);
+	    for (int i = 1; i < 5; i++)
+	      printf("   ");
+	    printf("%s\n", Bytecodes::name((Bytecodes::Code)opcode));
+	    printf("\t%d bytes padding\n", nbci - (bci+1));
+
+	    w = *(unsigned int *)(code_base + nbci + 0);
+	    def = (int)BYTESEX_REVERSE(w);
+	    w = *(unsigned int *)(code_base + nbci + 4);
+	    npairs = (int)BYTESEX_REVERSE(w);
+	    table = (unsigned int *)(code_base + nbci + 8);
+	    printf("\tdefault:\t0x%08x\n", def);
+	    printf("\tnpairs:\t\t0x%08x\n", npairs);
+	    for (int i = 0; i < npairs; i++) {
+	      unsigned match, off;
+	      w = table[0];
+	      match = BYTESEX_REVERSE(w);
+	      w = table[1];
+	      table += 2;
+	      off = BYTESEX_REVERSE(w);
+	      printf("\t  match: 0x%08x, offset: 0x%08x\n", match, off);
+	    }
+	    break;
+	  }
+
+	  default:
+	    for (int i = 0; i < 5; i++) {
+	      if (i < len)
+		printf("%02x ", code_base[bci+i]);
+	      else
+		printf("   ");
+	    }
+	    printf("%s\n", Bytecodes::name((Bytecodes::Code)code_base[bci]));
+	    break;
+	}
+	bci += len;
+      }
+    }
+    if (!nodisass) {
+      printf("0x%08x:\t", (int)codebuf+idx);
+      {
+	int len;
+	unsigned s1, s2;
+
+	s1 = *(unsigned short *)((int)codebuf + idx);
+	s2 = *(unsigned short *)((int)codebuf + idx + 2);
+	if (s1 == T_UNDEFINED_16 || ((s1 << 16) + s2) == T_UNDEFINED_32) {
+	  if (s1 == T_UNDEFINED_16) {
+	    printf("undefined (0xde00) - UNPATCHED BRANCH???");
+	    len = 2;
+	  } else {
+	    printf("undefined (0xf7f0a000) - UNPATCHED BRANCH???");
+	    len = 4;
+	  }
+	} else {
+	  len = print_insn_little_arm((bfd_vma)codebuf+idx, &info);
+	  if (len == -1) len = 2;
+	  idx += len;
+	}
+	putchar('\n');
+      }
+    }
+  }
+}
+#endif
+
+#define BCI(len, pop, push, special, islocal, islocal_n, isstore, local_n, local_type) \
+	((len) | ((pop)<<3) | ((push)<<6) | (unsigned)((special) << 31) | ((islocal) << 30) | ((islocal_n) << 29) | ((isstore) << 28) | ((local_n) << 9) | ((local_type) << 11))
+
+#define BCI_LEN(x) 	((x) & 7)
+#define BCI_POP(x) 	(((x)>>3) & 7)
+#define BCI_PUSH(x) 	(((x)>>6) & 7)
+#define BCI_LOCAL_N(x)	(((x)>>9) & 3)
+#define BCI_LOCAL_TYPE(x) (((x) >> 11) & 7)
+
+#define BCI_TYPE_INT	0
+#define BCI_TYPE_LONG	1
+#define BCI_TYPE_FLOAT	2
+#define BCI_TYPE_DOUBLE	3
+#define BCI_TYPE_REF	4
+
+#define BCI_SPECIAL(x) 	((x) & 0x80000000)
+#define BCI_ISLOCAL(x)	((x) & 0x40000000)
+#define BCI_ISLOCAL_N(x) ((x) & 0x20000000)
+#define BCI_ISSTORE(x)	((x) & 0x10000000)
+
+static const unsigned bcinfo[256] = {
+	BCI(1, 0, 0, 0, 0, 0, 0, 0, 0),	// nop
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// aconst_null
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// iconst_m1
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// iconst_0
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// iconst_1
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// iconst_2
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// iconst_3
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// iconst_4
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// iconst_5
+	BCI(1, 0, 2, 0, 0, 0, 0, 0, 0),	// lconst_0
+	BCI(1, 0, 2, 0, 0, 0, 0, 0, 0),	// lconst_1
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// fconst_0
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// fconst_1
+	BCI(1, 0, 1, 0, 0, 0, 0, 0, 0),	// fconst_2
+	BCI(1, 0, 2, 0, 0, 0, 0, 0, 0),	// dconst_0
+	BCI(1, 0, 2, 0, 0, 0, 0, 0, 0),	// dconst_1
+	BCI(2, 0, 1, 0, 0, 0, 0, 0, 0),	// bipush
+	BCI(3, 0, 1, 0, 0, 0, 0, 0, 0),	// bipush
+	BCI(2, 0, 1, 0, 0, 0, 0, 0, 0),	// ldc
+	BCI(3, 0, 1, 0, 0, 0, 0, 0, 0),	// ldc_w
+	BCI(3, 0, 2, 0, 0, 0, 0, 0, 0),	// ldc2_w
+	BCI(2, 0, 1, 0, 1, 0, 0, 0, BCI_TYPE_INT),	// iload
+	BCI(2, 0, 2, 0, 1, 0, 0, 0, BCI_TYPE_LONG),	// lload
+	BCI(2, 0, 1, 0, 1, 0, 0, 0, BCI_TYPE_FLOAT),	// fload
+	BCI(2, 0, 2, 0, 1, 0, 0, 0, BCI_TYPE_DOUBLE),	// dload
+	BCI(2, 0, 1, 0, 1, 0, 0, 0, BCI_TYPE_REF),	// aload
+	BCI(1, 0, 1, 0, 1, 1, 0, 0, BCI_TYPE_INT),	// iload_0
+	BCI(1, 0, 1, 0, 1, 1, 0, 1, BCI_TYPE_INT),	// iload_1
+	BCI(1, 0, 1, 0, 1, 1, 0, 2, BCI_TYPE_INT),	// iload_2
+	BCI(1, 0, 1, 0, 1, 1, 0, 3, BCI_TYPE_INT),	// iload_3
+	BCI(1, 0, 2, 0, 1, 1, 0, 0, BCI_TYPE_LONG),	// lload_0
+	BCI(1, 0, 2, 0, 1, 1, 0, 1, BCI_TYPE_LONG),	// lload_1
+	BCI(1, 0, 2, 0, 1, 1, 0, 2, BCI_TYPE_LONG),	// lload_2
+	BCI(1, 0, 2, 0, 1, 1, 0, 3, BCI_TYPE_LONG),	// lload_3
+	BCI(1, 0, 1, 0, 1, 1, 0, 0, BCI_TYPE_FLOAT),	// fload_0
+	BCI(1, 0, 1, 0, 1, 1, 0, 1, BCI_TYPE_FLOAT),	// fload_1
+	BCI(1, 0, 1, 0, 1, 1, 0, 2, BCI_TYPE_FLOAT),	// fload_2
+	BCI(1, 0, 1, 0, 1, 1, 0, 3, BCI_TYPE_FLOAT),	// fload_3
+	BCI(1, 0, 2, 0, 1, 1, 0, 0, BCI_TYPE_DOUBLE),	// dload_0
+	BCI(1, 0, 2, 0, 1, 1, 0, 1, BCI_TYPE_DOUBLE),	// dload_1
+	BCI(1, 0, 2, 0, 1, 1, 0, 2, BCI_TYPE_DOUBLE),	// dload_2
+	BCI(1, 0, 2, 0, 1, 1, 0, 3, BCI_TYPE_DOUBLE),	// dload_3
+	BCI(1, 0, 1, 0, 1, 1, 0, 0, BCI_TYPE_REF),	// aload_0
+	BCI(1, 0, 1, 0, 1, 1, 0, 1, BCI_TYPE_REF),	// aload_1
+	BCI(1, 0, 1, 0, 1, 1, 0, 2, BCI_TYPE_REF),	// aload_2
+	BCI(1, 0, 1, 0, 1, 1, 0, 3, BCI_TYPE_REF),	// aload_3
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// iaload
+	BCI(1, 2, 2, 0, 0, 0, 0, 0, 0),	// laload
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// faload
+	BCI(1, 2, 2, 0, 0, 0, 0, 0, 0),	// daload
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// aaload
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// baload
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// caload
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// saload
+	BCI(2, 1, 0, 0, 1, 0, 1, 0, BCI_TYPE_INT),	// istore
+	BCI(2, 2, 0, 0, 1, 0, 1, 0, BCI_TYPE_LONG),	// lstore
+	BCI(2, 1, 0, 0, 1, 0, 1, 0, BCI_TYPE_FLOAT),	// fstore
+	BCI(2, 2, 0, 0, 1, 0, 1, 0, BCI_TYPE_DOUBLE),	// dstore
+	BCI(2, 1, 0, 0, 1, 0, 1, 0, BCI_TYPE_REF),	// astore
+	BCI(1, 1, 0, 0, 1, 1, 1, 0, BCI_TYPE_INT),	// istore_0
+	BCI(1, 1, 0, 0, 1, 1, 1, 1, BCI_TYPE_INT),	// istore_1
+	BCI(1, 1, 0, 0, 1, 1, 1, 2, BCI_TYPE_INT),	// istore_2
+	BCI(1, 1, 0, 0, 1, 1, 1, 3, BCI_TYPE_INT),	// istore_3
+	BCI(1, 2, 0, 0, 1, 1, 1, 0, BCI_TYPE_LONG),	// lstore_0
+	BCI(1, 2, 0, 0, 1, 1, 1, 1, BCI_TYPE_LONG),	// lstore_1
+	BCI(1, 2, 0, 0, 1, 1, 1, 2, BCI_TYPE_LONG),	// lstore_2
+	BCI(1, 2, 0, 0, 1, 1, 1, 3, BCI_TYPE_LONG),	// lstore_3
+	BCI(1, 1, 0, 0, 1, 1, 1, 0, BCI_TYPE_FLOAT),	// fstore_0
+	BCI(1, 1, 0, 0, 1, 1, 1, 1, BCI_TYPE_FLOAT),	// fstore_1
+	BCI(1, 1, 0, 0, 1, 1, 1, 2, BCI_TYPE_FLOAT),	// fstore_2
+	BCI(1, 1, 0, 0, 1, 1, 1, 3, BCI_TYPE_FLOAT),	// fstore_3
+	BCI(1, 2, 0, 0, 1, 1, 1, 0, BCI_TYPE_DOUBLE),	// dstore_0
+	BCI(1, 2, 0, 0, 1, 1, 1, 1, BCI_TYPE_DOUBLE),	// dstore_1
+	BCI(1, 2, 0, 0, 1, 1, 1, 2, BCI_TYPE_DOUBLE),	// dstore_2
+	BCI(1, 2, 0, 0, 1, 1, 1, 3, BCI_TYPE_DOUBLE),	// dstore_3
+	BCI(1, 1, 0, 0, 1, 1, 1, 0, BCI_TYPE_REF),	// astore_0
+	BCI(1, 1, 0, 0, 1, 1, 1, 1, BCI_TYPE_REF),	// astore_1
+	BCI(1, 1, 0, 0, 1, 1, 1, 2, BCI_TYPE_REF),	// astore_2
+	BCI(1, 1, 0, 0, 1, 1, 1, 3, BCI_TYPE_REF),	// astore_3
+	BCI(1, 3, 0, 0, 0, 0, 0, 0, 0),	// iastore
+	BCI(1, 4, 0, 0, 0, 0, 0, 0, 0),	// dastore
+	BCI(1, 3, 0, 0, 0, 0, 0, 0, 0),	// fastore
+	BCI(1, 4, 0, 0, 0, 0, 0, 0, 0),	// lastore
+	BCI(1, 3, 0, 0, 0, 0, 0, 0, 0),	// aastore
+	BCI(1, 3, 0, 0, 0, 0, 0, 0, 0),	// bastore
+	BCI(1, 3, 0, 0, 0, 0, 0, 0, 0),	// castore
+	BCI(1, 3, 0, 0, 0, 0, 0, 0, 0),	// sastore
+	BCI(1, 1, 0, 0, 0, 0, 0, 0, 0),	// pop
+	BCI(1, 2, 0, 0, 0, 0, 0, 0, 0),	// pop2
+	BCI(1, 1, 2, 0, 0, 0, 0, 0, 0),	// dup
+	BCI(1, 2, 3, 0, 0, 0, 0, 0, 0),	// dup_x1
+	BCI(1, 3, 4, 0, 0, 0, 0, 0, 0),	// dup_x2
+	BCI(1, 2, 4, 0, 0, 0, 0, 0, 0),	// dup2
+	BCI(1, 3, 5, 0, 0, 0, 0, 0, 0),	// dup2_x1
+	BCI(1, 4, 6, 0, 0, 0, 0, 0, 0),	// dup2_x2
+	BCI(1, 1, 1, 0, 0, 0, 0, 0, 0),	// swap
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// iadd
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// ladd
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// fadd
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// dadd
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// isub
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// lsub
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// fsub
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// dsub
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// imul
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// lmul
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// fmul
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// dmul
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// idiv
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// ldiv
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// fdiv
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// ddiv
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// irem
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// lrem
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// frem
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// drem
+	BCI(1, 1, 1, 0, 0, 0, 0, 0, 0),	// ineg
+	BCI(1, 2, 2, 0, 0, 0, 0, 0, 0),	// lneg
+	BCI(1, 1, 1, 0, 0, 0, 0, 0, 0),	// fneg
+	BCI(1, 2, 2, 0, 0, 0, 0, 0, 0),	// dneg
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// ishl
+	BCI(1, 3, 2, 0, 0, 0, 0, 0, 0),	// lshl
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// ishr
+	BCI(1, 3, 2, 0, 0, 0, 0, 0, 0),	// lshr
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// iushr
+	BCI(1, 3, 2, 0, 0, 0, 0, 0, 0),	// lushr
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// iand
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// land
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// ior
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// lor
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// ixor
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// lxor
+	BCI(3, 0, 0, 0, 1, 0, 1, 0, BCI_TYPE_INT),	// iinc
+	BCI(1, 1, 2, 0, 0, 0, 0, 0, 0),	// i2l
+	BCI(1, 1, 1, 0, 0, 0, 0, 0, 0),	// i2f
+	BCI(1, 1, 2, 0, 0, 0, 0, 0, 0),	// i2d
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// l2i
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// l2f
+	BCI(1, 2, 2, 0, 0, 0, 0, 0, 0),	// l2d
+	BCI(1, 1, 1, 0, 0, 0, 0, 0, 0),	// f2i
+	BCI(1, 1, 2, 0, 0, 0, 0, 0, 0),	// f2l
+	BCI(1, 1, 2, 0, 0, 0, 0, 0, 0),	// f2d
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// d2i
+	BCI(1, 2, 2, 0, 0, 0, 0, 0, 0),	// d2l
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// d2f
+	BCI(1, 1, 1, 0, 0, 0, 0, 0, 0),	// i2b
+	BCI(1, 1, 1, 0, 0, 0, 0, 0, 0),	// i2c
+	BCI(1, 1, 1, 0, 0, 0, 0, 0, 0),	// i2s
+	BCI(1, 4, 1, 0, 0, 0, 0, 0, 0),	// lcmp
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// fcmpl
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// fcmpg
+	BCI(1, 4, 1, 0, 0, 0, 0, 0, 0),	// dcmpl
+	BCI(1, 4, 1, 0, 0, 0, 0, 0, 0),	// dcmpg
+	BCI(3, 1, 0, 1, 0, 0, 0, 0, 0),	// ifeq
+	BCI(3, 1, 0, 1, 0, 0, 0, 0, 0),	// ifne
+	BCI(3, 1, 0, 1, 0, 0, 0, 0, 0),	// iflt
+	BCI(3, 1, 0, 1, 0, 0, 0, 0, 0),	// ifge
+	BCI(3, 1, 0, 1, 0, 0, 0, 0, 0),	// ifgt
+	BCI(3, 1, 0, 1, 0, 0, 0, 0, 0),	// ifle
+	BCI(3, 2, 0, 1, 0, 0, 0, 0, 0),	// if_icmpeq
+	BCI(3, 2, 0, 1, 0, 0, 0, 0, 0),	// if_icmpne
+	BCI(3, 2, 0, 1, 0, 0, 0, 0, 0),	// if_icmplt
+	BCI(3, 2, 0, 1, 0, 0, 0, 0, 0),	// if_icmpge
+	BCI(3, 2, 0, 1, 0, 0, 0, 0, 0),	// if_icmpgt
+	BCI(3, 2, 0, 1, 0, 0, 0, 0, 0),	// if_icmple
+	BCI(3, 2, 0, 1, 0, 0, 0, 0, 0),	// if_acmpeq
+	BCI(3, 2, 0, 1, 0, 0, 0, 0, 0),	// if_acmpne
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// goto
+	BCI(3, 0, 1, 1, 0, 0, 0, 0, 0),	// jsr
+	BCI(2, 0, 0, 1, 0, 0, 0, 0, 0),	// ret
+	BCI(0, 1, 0, 1, 0, 0, 0, 0, 0),	// tableswitch
+	BCI(0, 1, 0, 1, 0, 0, 0, 0, 0),	// lookupswitch
+	BCI(1, 1, 0, 1, 0, 0, 0, 0, 0),	// ireturn
+	BCI(1, 2, 0, 1, 0, 0, 0, 0, 0),	// lreturn
+	BCI(1, 1, 0, 1, 0, 0, 0, 0, 0),	// freturn
+	BCI(1, 2, 0, 1, 0, 0, 0, 0, 0),	// dreturn
+	BCI(1, 1, 0, 1, 0, 0, 0, 0, 0),	// areturn
+	BCI(1, 0, 0, 1, 0, 0, 0, 0, 0),	// return
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// getstatic
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// putstatic
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// getfield
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// putfield
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokevirtual
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokespecial
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokestatic
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokeinterface
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// xxxunusedxxx
+	BCI(3, 0, 1, 0, 0, 0, 0, 0, 0),	// new
+	BCI(2, 1, 1, 0, 0, 0, 0, 0, 0),	// newarray
+	BCI(3, 1, 1, 0, 0, 0, 0, 0, 0),	// anewarray
+	BCI(1, 1, 1, 0, 0, 0, 0, 0, 0),	// arraylength
+	BCI(1, 1, 1, 1, 0, 0, 0, 0, 0),	// athrow
+	BCI(3, 1, 1, 0, 0, 0, 0, 0, 0),	// checkcast
+	BCI(3, 1, 1, 0, 0, 0, 0, 0, 0),	// instanceof
+	BCI(1, 1, 0, 0, 0, 0, 0, 0, 0),	// monitorenter
+	BCI(1, 1, 0, 0, 0, 0, 0, 0, 0),	// monitorexit
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// wide
+	BCI(4, 0, 0, 1, 0, 0, 0, 0, 0),	// multianewarray
+	BCI(3, 1, 0, 1, 0, 0, 0, 0, 0),	// ifnull
+	BCI(3, 1, 0, 1, 0, 0, 0, 0, 0),	// ifnonnull
+	BCI(5, 0, 0, 1, 0, 0, 0, 0, 0),	// goto_w
+	BCI(5, 0, 0, 1, 0, 0, 0, 0, 0),	// jsr_w
+	BCI(1, 0, 0, 1, 0, 0, 0, 0, 0),	// breakpoint
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// unused 0xcb
+	BCI(3, 1, 1, 0, 0, 0, 0, 0, 0),	// bgetfield
+	BCI(3, 1, 1, 0, 0, 0, 0, 0, 0),	// cgetfield
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// unused 0xce
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// unused 0xcf
+	BCI(3, 1, 1, 0, 0, 0, 0, 0, 0),	// igetfield
+	BCI(3, 1, 2, 0, 0, 0, 0, 0, 0),	// lgetfield
+	BCI(3, 1, 1, 0, 0, 0, 0, 0, 0),	// sgetfield
+	BCI(3, 2, 0, 0, 0, 0, 0, 0, 0),	// aputfield
+	BCI(3, 2, 0, 0, 0, 0, 0, 0, 0),	// bputfield
+	BCI(3, 2, 0, 0, 0, 0, 0, 0, 0),	// cputfield
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// unused 0xd6
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// unused 0xd7
+	BCI(3, 2, 0, 0, 0, 0, 0, 0, 0),	// iputfield
+	BCI(3, 3, 0, 0, 0, 0, 0, 0, 0),	// lputfield
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// unused 0xda
+	BCI(1, 0, 1, 0, 1, 1, 0, 0, BCI_TYPE_REF),	// iaccess_0
+	BCI(1, 0, 1, 0, 1, 1, 0, 1, BCI_TYPE_REF),	// iaccess_1
+	BCI(1, 0, 1, 0, 1, 1, 0, 2, BCI_TYPE_REF),	// iaccess_2
+	BCI(1, 0, 1, 0, 1, 1, 0, 3, BCI_TYPE_REF),	// iaccess_3
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokeresolved
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokespecialresolved
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokestaticresolved
+	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokevfinal
+	BCI(2, 0, 1, 0, 1, 0, 0, 0, BCI_TYPE_INT),	// iload_iload
+	BCI(2, 0, 1, 0, 1, 0, 0, 0, BCI_TYPE_INT),	// iload_iload_N
+	BCI(1, 0, 0, 1, 0, 0, 0, 0, 0),	// return_register_finalizer
+	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// dmac
+	BCI(1, 0, 1, 0, 1, 1, 0, 0, BCI_TYPE_INT),	// iload_0_iconst_N
+	BCI(1, 0, 1, 0, 1, 1, 0, 1, BCI_TYPE_INT),	// iload_1_iconst_N
+	BCI(1, 0, 1, 0, 1, 1, 0, 2, BCI_TYPE_INT),	// iload_2_iconst_N
+	BCI(1, 0, 1, 0, 1, 1, 0, 3, BCI_TYPE_INT),	// iload_3_iconst_N
+	BCI(2, 0, 1, 0, 1, 0, 0, 0, BCI_TYPE_INT),	// iload_iconst_N
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// iadd_istore_N
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// isub_istore_N
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// iand_istore_N
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// ior_istore_N
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// ixor_istore_N
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// iadd_u4store
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// isub_u4store
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// iand_u4store
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// ior_u4store
+	BCI(1, 2, 1, 0, 0, 0, 0, 0, 0),	// ixor_u4store
+	BCI(1, 0, 1, 0, 1, 1, 0, 0, BCI_TYPE_INT),	// iload_0_iload
+	BCI(1, 0, 1, 0, 1, 1, 0, 1, BCI_TYPE_INT),	// iload_1_iload
+	BCI(1, 0, 1, 0, 1, 1, 0, 2, BCI_TYPE_INT),	// iload_2_iload
+	BCI(1, 0, 1, 0, 1, 1, 0, 3, BCI_TYPE_INT),	// iload_3_iload
+	BCI(1, 0, 1, 0, 1, 1, 0, 0, BCI_TYPE_INT),	// iload_0_iload_N
+	BCI(1, 0, 1, 0, 1, 1, 0, 1, BCI_TYPE_INT),	// iload_1_iload_N
+	BCI(1, 0, 1, 0, 1, 1, 0, 2, BCI_TYPE_INT),	// iload_2_iload_N
+	BCI(1, 0, 1, 0, 1, 1, 0, 3, BCI_TYPE_INT),	// iload_3_iload_N
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// impdep1
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// impdep2
+};
+
+void Thumb2_pass1(Thumb2_Info *jinfo, unsigned bci)
+{
+  unsigned code_size = jinfo->code_size;
+  jubyte *code_base = jinfo->code_base;
+  unsigned *bc_stackinfo = jinfo->bc_stackinfo;
+  unsigned *locals_info = jinfo->locals_info;
+  //constantPoolCacheOop cp = jinfo->method->constants()->cache();
+
+  bc_stackinfo[bci] |= BC_BRANCH_TARGET;
+  while (bci < code_size) {
+    unsigned stackinfo = bc_stackinfo[bci];
+    unsigned bytecodeinfo;
+    unsigned opcode;
+
+    if (stackinfo & BC_VISITED_P1) break;
+    bc_stackinfo[bci] = (stackinfo & BC_FLAGS_MASK) | BC_VISITED_P1;
+    opcode = code_base[bci];
+//	printf("bci = 0x%04x, opcode = 0x%02x (%s)", bci, opcode,  Bytecodes::name((Bytecodes::Code)opcode));
+    bytecodeinfo = bcinfo[opcode];
+    if (!BCI_SPECIAL(bytecodeinfo)) {
+      bci += BCI_LEN(bytecodeinfo);
+      continue;
+    }
+
+    switch (opcode) {
+
+      case opc_goto: {
+	int off = GET_JAVA_S2(code_base+bci+1);
+	bci += off;
+	bc_stackinfo[bci] |= BC_BRANCH_TARGET;
+	if (off < 0) bc_stackinfo[bci] |= BC_BACK_TARGET;
+	break;
+      }
+      case opc_goto_w: {
+	int off = GET_JAVA_U4(code_base+bci+1);
+	bci += off;
+	bc_stackinfo[bci] |= BC_BRANCH_TARGET;
+	if (off < 0) bc_stackinfo[bci] |= BC_BACK_TARGET;
+	break;
+      }
+
+      case opc_if_icmpeq:
+      case opc_if_icmpne:
+      case opc_if_icmplt:
+      case opc_if_icmpge:
+      case opc_if_icmpgt:
+      case opc_if_icmple:
+      case opc_if_acmpeq:
+      case opc_if_acmpne:
+      case opc_ifeq:
+      case opc_ifne:
+      case opc_iflt:
+      case opc_ifge:
+      case opc_ifgt:
+      case opc_ifle:
+      case opc_ifnull:
+      case opc_ifnonnull: {
+	int off = GET_JAVA_S2(code_base+bci+1);
+	if (off < 0) bc_stackinfo[bci+off] |= BC_BACK_TARGET;
+	Thumb2_pass1(jinfo, bci + off);
+	bci += 3;
+	break;
+      }
+
+      case opc_jsr: {
+	int off = GET_JAVA_S2(code_base+bci+1);
+	if (off < 0) bc_stackinfo[bci+off] |= BC_BACK_TARGET;
+	Thumb2_pass1(jinfo, bci + off);
+	bci += 3;
+	break;
+      }
+      case opc_jsr_w: {
+	int off = GET_JAVA_U4(code_base+bci+1);
+	if (off < 0) bc_stackinfo[bci+off] |= BC_BACK_TARGET;
+	Thumb2_pass1(jinfo, bci + off);
+	bci += 5;
+	break;
+      }
+
+      case opc_ireturn:
+      case opc_lreturn:
+      case opc_freturn:
+      case opc_dreturn:
+      case opc_areturn:
+      case opc_return:
+      case opc_return_register_finalizer:
+      case opc_ret:
+      case opc_athrow:
+	// The test for BC_VISITED_P1 above will break out of the loop!!!
+	break;
+
+      case opc_tableswitch: {
+	int low, high;
+	unsigned w;
+	unsigned *table;
+	unsigned nbci;
+	int def;
+
+	nbci = bci & ~3;
+	w = *(unsigned int *)(code_base + nbci + 8);
+	low = (int)BYTESEX_REVERSE(w);
+	w = *(unsigned int *)(code_base + nbci + 12);
+	high = (int)BYTESEX_REVERSE(w);
+	w = *(unsigned int *)(code_base + nbci + 4);
+	def = (int)BYTESEX_REVERSE(w);
+	table = (unsigned int *)(code_base + nbci + 16);
+
+	while (low <= high) {
+	  int off;
+	  w = *table++;
+	  off = (int)BYTESEX_REVERSE(w);
+	  if (off < 0) bc_stackinfo[bci+off] |= BC_BACK_TARGET;
+	  Thumb2_pass1(jinfo, bci + off);
+	  low++;
+	}
+
+	bci += def;
+	bc_stackinfo[bci] |= BC_BRANCH_TARGET;
+	if (def < 0) bc_stackinfo[bci] |= BC_BACK_TARGET;
+	break;
+      }
+
+      case opc_lookupswitch: {
+	unsigned w;
+	unsigned nbci;
+	int def;
+	int npairs;	// The Java spec says signed but must be >= 0??
+	unsigned *table;
+
+	nbci = bci & ~3;
+	w = *(unsigned int *)(code_base + nbci + 4);
+	def = (int)BYTESEX_REVERSE(w);
+	w = *(unsigned int *)(code_base + nbci + 8);
+	npairs = (int)BYTESEX_REVERSE(w);
+	table = (unsigned int *)(code_base + nbci + 16);
+
+	for (int i = 0; i < npairs; i++) {
+	  int off;
+	  w = *table;
+	  table += 2;
+	  off = (int)BYTESEX_REVERSE(w);
+	  if (off < 0) bc_stackinfo[bci+off] |= BC_BACK_TARGET;
+	  Thumb2_pass1(jinfo, bci + off);
+	}
+
+	bci += def;
+	bc_stackinfo[bci] |= BC_BRANCH_TARGET;
+	if (def < 0) bc_stackinfo[bci] |= BC_BACK_TARGET;
+	break;
+      }
+
+      case opc_getstatic:
+      case opc_putstatic:
+      case opc_getfield:
+      case opc_putfield: {
+	bci += 3;
+	break;
+      }
+
+      case opc_invokeresolved:
+      case opc_invokespecialresolved:
+      case opc_invokestaticresolved:
+      case opc_invokevfinal:
+      case opc_invokevirtual:
+      case opc_invokespecial:
+      case opc_invokestatic:
+	bci += 3;
+	break;
+
+      case opc_invokeinterface:
+	bci += 5;
+	break;
+
+      case opc_multianewarray:
+	bci += 4;
+	break;
+
+      case opc_wide:
+	opcode = code_base[bci+1];
+	if (opcode == opc_iinc) {
+	  bci += 6;
+	} else {
+	  bci += 4;
+	}
+	break;
+
+      default:
+	opcode = code_base[bci];
+	fatal1("Undefined opcode %d\n", opcode);
+	break;
+    }
+  }
+}
+
+#ifdef ZOMBIE_DETECTION
+int Thumb2_is_zombie(Thumb2_Info *jinfo, unsigned bci)
+{
+  unsigned code_size = jinfo->code_size;
+  jubyte *code_base = jinfo->code_base;
+  unsigned bytecodeinfo;
+  unsigned opcode;
+  unsigned *bc_stackinfo = jinfo->bc_stackinfo;
+
+  do {
+    opcode = code_base[bci];
+    // Short circuit exit - commented out because even if it has been executed
+    // we treat throw, jsr, and ret as zombies because they will call out to the
+    // interpreter.
+    // if (opcode > OPC_LAST_JAVA_OP) return 0;
+    bytecodeinfo = bcinfo[opcode];
+    if (!BCI_SPECIAL(bytecodeinfo)) {
+	bci += BCI_LEN(bytecodeinfo);
+#if 0
+	if (opcode >= opc_iload_iload) {
+	  opcode = code_base[bci];
+	  bci += BCI_LEN(bcinfo[opcode]);
+	} else if (BCI_ISLOCAL(bytecodeinfo)) {
+	  if (opcode == opc_iload || (opcode >= opc_iload_0 && opcode <= opc_iload_3)) {
+	    opcode = code_base[bci];
+	    if (opcode == opc_iload || (opcode >= opc_iload_0 && opcode <= opc_iload_3) ||
+					(opcode >= opc_iconst_m1 && opcode <= opc_iconst_5)) {
+		printf("found new zombie at %d\n", bci);
+		return 1;
+	    }
+	  }
+	} else if (opcode == opc_iadd || opcode == opc_isub ||
+		      opcode == opc_iand || opcode == opc_ior || opcode == opc_ixor) {
+	    opcode = code_base[bci];
+	    if (opcode == opc_istore || (opcode >= opc_istore_0 && opcode <= opc_istore_3)) {
+		printf("found new zombie at %d\n", bci);
+		return 1;
+	    }
+	}
+#endif
+    } else {
+      switch (opcode) {
+	case opc_goto:
+	case opc_goto_w:
+	case opc_ifeq:
+	case opc_ifne:
+	case opc_iflt:
+	case opc_ifge:
+	case opc_ifgt:
+	case opc_ifle:
+	case opc_ifnull:
+	case opc_ifnonnull:
+	case opc_if_icmpeq:
+	case opc_if_icmpne:
+	case opc_if_icmplt:
+	case opc_if_icmpge:
+	case opc_if_icmpgt:
+	case opc_if_icmple:
+	case opc_if_acmpeq:
+	case opc_if_acmpne:
+	case opc_tableswitch:
+	case opc_lookupswitch:
+	  return 0;
+	case opc_ireturn:
+	case opc_lreturn:
+	case opc_freturn:
+	case opc_dreturn:
+	case opc_areturn:
+	case opc_return:
+	case opc_return_register_finalizer:
+	    return 0;
+	case opc_jsr:
+	case opc_jsr_w:
+	case opc_ret:
+	case opc_athrow:
+	    return 1;
+	case opc_invokeinterface:
+	case opc_invokevirtual:
+	case opc_invokespecial:
+	case opc_invokestatic:
+	case opc_putfield:
+	case opc_getfield:
+	case opc_putstatic:
+	case opc_getstatic: {
+	  constantPoolCacheOop  cp = jinfo->method->constants()->cache();
+	  ConstantPoolCacheEntry* cache;
+	  int index = GET_NATIVE_U2(code_base+bci+1);
+
+	  cache = cp->entry_at(index);
+	  if (!cache->is_resolved((Bytecodes::Code)opcode)) return 1;
+	  bci += 3;
+	  if (opcode == opc_invokeinterface) bci += 2;
+	  break;
+
+	}
+	case opc_invokeresolved:
+	case opc_invokespecialresolved:
+	case opc_invokestaticresolved:
+	case opc_invokevfinal:
+	  bci += 3;
+	  break;
+
+	case opc_multianewarray:
+	  bci += 4;
+	  break;
+
+	case opc_wide:
+	  opcode = code_base[bci+1];
+	  if (opcode == opc_iinc) {
+	    bci += 6;
+	  } else {
+	    bci += 4;
+	  }
+	  break;
+
+	default:
+	  opcode = code_base[bci];
+	  fatal1("Undefined opcode %d\n", opcode);
+	  break;
+      }
+    }
+    if (bci >= code_size) break;
+  } while (!(bc_stackinfo[bci] & BC_BRANCH_TARGET));
+  return 0;
+}
+#endif // ZOMBIT_DETECTION
+
+void Thumb2_RegAlloc(Thumb2_Info *jinfo, unsigned *pregs, unsigned npregs)
+{
+  unsigned *locals_info = jinfo->locals_info;
+  unsigned i, j;
+  unsigned linfo;
+  unsigned score, max_score;
+  unsigned local;
+  unsigned nlocals = jinfo->method->max_locals();
+
+  for (i = 0; i < npregs; i++) {
+    max_score = 0;
+    for (j = 0; j < nlocals; j++) {
+      linfo = locals_info[j];
+
+      if (linfo & ((1<<LOCAL_ALLOCATED)|(1<<LOCAL_DOUBLE))) continue;
+      score = LOCAL_READS(linfo) + LOCAL_WRITES(linfo);
+      if (linfo & (1<<LOCAL_MODIFIED)) score = (score+1) >> 2;
+      if (linfo & (1<<LOCAL_REF)) score = score - (score >> 2);
+      if (linfo & (1<<LOCAL_LONG)) score = (score+1) >> 2;
+      if (score > max_score) max_score = score, local = j;
+    }
+    if (max_score < 2) break;
+    locals_info[local] |= 1<<LOCAL_ALLOCATED;
+    jinfo->jregs->r_local[local] = pregs[i];
+  }
+#ifdef T2EE_PRINT_REGUSAGE
+  if (t2ee_print_regusage) {
+    printf("Regalloc: %d physical registers allocated as follows\n", npregs);
+    for (j = 0; j < nlocals; j++) {
+      unsigned r = jinfo->jregs->r_local[j];
+      if (r) {
+	unsigned typ = (locals_info[j] >> LOCAL_INT) & 0x1f;
+	printf("  ARM Reg R%d -> local %d (type = %s)\n", r, j, local_types[LOG2(typ)]);
+      }
+    }
+  }
+#endif
+}
+
+void Thumb2_pass2(Thumb2_Info *jinfo, unsigned stackdepth, unsigned bci)
+{
+  unsigned code_size = jinfo->code_size;
+  jubyte *code_base = jinfo->code_base;
+  unsigned *bc_stackinfo = jinfo->bc_stackinfo;
+  unsigned *locals_info = jinfo->locals_info;
+  unsigned check_zombie = 0;
+  //constantPoolCacheOop cp = jinfo->method->constants()->cache();
+
+  while (bci < code_size) {
+    unsigned stackinfo = bc_stackinfo[bci];
+    unsigned bytecodeinfo;
+    unsigned opcode;
+
+    if (stackinfo & BC_VISITED_P2) break;
+    JASSERT((int)stackdepth >= 0, "stackdepth < 0!!");
+    bc_stackinfo[bci] = (stackinfo & BC_FLAGS_MASK) | stackdepth | BC_VISITED_P2;
+#ifdef ZOMBIE_DETECTION
+    if (check_zombie || (stackinfo & BC_BRANCH_TARGET)) {
+      if (Thumb2_is_zombie(jinfo, bci)) {
+	printf("zombie code at %d\n", bci);
+	bc_stackinfo[bci] |= BC_ZOMBIE;
+	return;
+      }
+      check_zombie = 0;
+    }
+#endif
+    opcode = code_base[bci];
+//	printf("bci = 0x%04x, opcode = 0x%02x (%s), stackdepth = %d\n", bci, opcode,  Bytecodes::name((Bytecodes::Code)opcode), stackdepth);
+    bytecodeinfo = bcinfo[opcode];
+    if (!BCI_SPECIAL(bytecodeinfo)) {
+      if (BCI_ISLOCAL(bytecodeinfo)) {
+	unsigned local = BCI_LOCAL_N(bytecodeinfo);
+	unsigned local_type = BCI_LOCAL_TYPE(bytecodeinfo) + LOCAL_INT;
+	unsigned local_modified = 0;
+	unsigned linfo;
+	unsigned read_count, write_count;
+
+	if (!BCI_ISLOCAL_N(bytecodeinfo)) local = code_base[bci+1];
+	if (BCI_ISSTORE(bytecodeinfo)) local_modified = 1U << LOCAL_MODIFIED;
+	linfo = locals_info[local];
+	read_count = LOCAL_READS(linfo);
+	write_count = LOCAL_WRITES(linfo);
+	if (local_modified)
+	  write_count = LOCAL_INC_COUNT(write_count);
+	else
+	  read_count = LOCAL_INC_COUNT(read_count);
+	
+	locals_info[local] |= (1 << local_type) | LOCAL_SET_COUNTS(read_count, write_count) | local_modified;
+	if (local_type == LOCAL_LONG || local_type == LOCAL_DOUBLE) {
+	  locals_info[local+1] |= (1 << local_type) | LOCAL_SET_COUNTS(read_count, write_count) | local_modified;
+	}
+      }
+      bci += BCI_LEN(bytecodeinfo);
+      stackdepth += BCI_PUSH(bytecodeinfo) - BCI_POP(bytecodeinfo);
+      JASSERT(stackdepth <= (unsigned)jinfo->method->max_stack(), "stack over/under flow?");
+      continue;
+    }
+
+    switch (opcode) {
+
+      case opc_goto:
+	bci += GET_JAVA_S2(code_base+bci+1);
+	break;
+      case opc_goto_w:
+	bci += GET_JAVA_U4(code_base+bci+1);
+	break;
+
+      case opc_ifeq:
+      case opc_ifne:
+      case opc_iflt:
+      case opc_ifge:
+      case opc_ifgt:
+      case opc_ifle:
+      case opc_ifnull:
+      case opc_ifnonnull:
+	stackdepth -= 1;
+	Thumb2_pass2(jinfo, stackdepth, bci + GET_JAVA_S2(code_base+bci+1));
+	check_zombie = 1;
+	bci += 3;
+	break;
+
+      case opc_if_icmpeq:
+      case opc_if_icmpne:
+      case opc_if_icmplt:
+      case opc_if_icmpge:
+      case opc_if_icmpgt:
+      case opc_if_icmple:
+      case opc_if_acmpeq:
+      case opc_if_acmpne:
+	stackdepth -= 2;
+	Thumb2_pass2(jinfo, stackdepth, bci + GET_JAVA_S2(code_base+bci+1));
+	check_zombie = 1;
+	bci += 3;
+	break;
+
+      case opc_jsr:
+	Thumb2_pass2(jinfo, stackdepth+1, bci + GET_JAVA_S2(code_base+bci+1));
+	bci += 3;
+	stackdepth = 0;
+	break;
+      case opc_jsr_w:
+	Thumb2_pass2(jinfo, stackdepth+1, bci + GET_JAVA_U4(code_base+bci+1));
+	bci += 5;
+	break;
+
+      case opc_ireturn:
+      case opc_lreturn:
+      case opc_freturn:
+      case opc_dreturn:
+      case opc_areturn:
+      case opc_return:
+      case opc_return_register_finalizer:
+      case opc_ret:
+      case opc_athrow:
+	// The test for BC_VISITED_P2 above will break out of the loop!!!
+	break;
+
+      case opc_tableswitch: {
+	int low, high;
+	unsigned w;
+	unsigned *table;
+	unsigned nbci;
+	int def;
+
+	stackdepth -= 1;
+	nbci = bci & ~3;
+	w = *(unsigned int *)(code_base + nbci + 8);
+	low = (int)BYTESEX_REVERSE(w);
+	w = *(unsigned int *)(code_base + nbci + 12);
+	high = (int)BYTESEX_REVERSE(w);
+	w = *(unsigned int *)(code_base + nbci + 4);
+	def = (int)BYTESEX_REVERSE(w);
+	table = (unsigned int *)(code_base + nbci + 16);
+
+	while (low <= high) {
+	  int off;
+	  w = *table++;
+	  off = (int)BYTESEX_REVERSE(w);
+	  Thumb2_pass2(jinfo, stackdepth, bci + off);
+	  low++;
+	}
+
+	check_zombie = 1;
+	bci += def;
+	break;
+      }
+
+      case opc_lookupswitch: {
+	unsigned w;
+	unsigned nbci;
+	int def;
+	int npairs;	// The Java spec says signed but must be >= 0??
+	unsigned *table;
+
+	stackdepth -= 1;
+	nbci = bci & ~3;
+	w = *(unsigned int *)(code_base + nbci + 4);
+	def = (int)BYTESEX_REVERSE(w);
+	w = *(unsigned int *)(code_base + nbci + 8);
+	npairs = (int)BYTESEX_REVERSE(w);
+	table = (unsigned int *)(code_base + nbci + 16);
+
+	for (int i = 0; i < npairs; i++) {
+	  int off;
+	  w = *table;
+	  table += 2;
+	  off = (int)BYTESEX_REVERSE(w);
+	  Thumb2_pass2(jinfo, stackdepth, bci + off);
+	}
+
+	check_zombie = 1;
+	bci += def;
+	break;
+      }
+
+      case opc_getstatic:
+      case opc_putstatic:
+      case opc_getfield:
+      case opc_putfield: {
+	int index = GET_JAVA_U2(code_base+bci+1);
+	constantPoolOop pool = jinfo->method->constants();
+	symbolOop sig = pool->signature_ref_at(index);
+	jbyte *base = sig->base();
+	jbyte c = *base;
+	int stackchange;
+
+	opcode = code_base[bci];
+	if (opcode == opc_getfield || opcode == opc_putfield)
+	  stackdepth -= 1;
+	stackchange = 1;
+	if (c == 'J' || c == 'D') stackchange = 2;
+	if (opcode == opc_getfield || opcode == opc_getstatic)
+	  stackdepth += stackchange;
+	else
+	  stackdepth -= stackchange;
+	bci += 3;
+	break;
+      }
+
+      case opc_invokeresolved:
+      case opc_invokespecialresolved:
+      case opc_invokestaticresolved:
+      case opc_invokevfinal:
+      case opc_invokeinterface:
+      case opc_invokevirtual:
+      case opc_invokespecial:
+      case opc_invokestatic: {
+	int index = GET_JAVA_U2(code_base+bci+1);
+	constantPoolOop pool = jinfo->method->constants();
+	//symbolOop name = pool->name_ref_at(index);
+	symbolOop sig = pool->signature_ref_at(index);
+	jbyte *base = sig->base();
+
+	//tty->print("%d: %s: %s\n", opcode, name->as_C_string(), sig->as_C_string());
+	stackdepth += method_stackchange(base);
+	opcode = code_base[bci];
+	bci += 3;
+	if (opcode == opc_invokeinterface) bci += 2;
+	if (opcode != opc_invokestatic && opcode != opc_invokestaticresolved)
+	  stackdepth -= 1;
+	break;
+      }
+
+      case opc_multianewarray:
+	stackdepth = (stackdepth - code_base[bci+3]) + 1;
+	bci += 4;
+	break;
+
+      case opc_wide:
+	opcode = code_base[bci+1];
+	if (opcode == opc_iinc) {
+	  bci += 6;
+	} else {
+	  bci += 4;
+	  if (opcode == opc_iload ||
+	  	opcode == opc_fload || opcode == opc_aload)
+	    stackdepth += 1;
+	  else if (opcode == opc_lload || opcode == opc_dload)
+	    stackdepth += 2;
+	  else if (opcode == opc_istore ||
+	  	opcode == opc_fstore || opcode == opc_astore)
+	    stackdepth -= 1;
+	  else if (opcode == opc_lstore || opcode == opc_dstore)
+	    stackdepth -= 2;
+	  else if (opcode != opc_ret)
+	    fatal1("Undefined wide opcode %d\n", opcode);
+	}
+	break;
+
+      default:
+	opcode = code_base[bci];
+	fatal1("Undefined opcode %d\n", opcode);
+	break;
+    }
+  }
+}
+
+//-------------------------------------------------------------------------------------
+
+#define Thumb2		1
+#define ThumbEE		0
+
+#define	DA	0
+#define	IA	1
+#define DB	2
+#define IB	3
+
+#define	PUSH_ED	0
+#define PUSH_EA	1
+#define	PUSH_FD	2
+#define	PUSH_FA	3
+
+#define	POP_FA	0
+#define	POP_FD	1
+#define	POP_EA	2
+#define	POP_ED	3
+
+#define ROR(imm, sh) (((imm) >> (sh)) | ((imm) << (32 - (sh))))
+#define ROL(imm, sh) (((imm) << (sh)) | ((imm) >> (32 - (sh))))
+
+#define abs(i) ((i) < 0 ? -(i) : (i))
+#define U(i) ((i) < 0 ? 0 : 1)
+
+#define LS_STR		0
+#define	LS_STRB		1
+#define	LS_STRH		2
+#define LS_LDRSB	3
+#define	LS_LDR		4
+#define LS_LDRB		5
+#define	LS_LDRH		6
+#define LS_LDRSH	7
+
+#define LS_IS_LDR(op)	((op) >= LS_LDRSB)
+#define LS_IS_WORD(op)	(((op) & 3) == LS_STR)
+#define LS_IS_BYTE(op)	(((op) & 3) == LS_STRB || (op) == LS_LDRSB)
+#define LS_IS_HW(op)	(((op) & 3) == LS_STRH || (op) == LS_LDRSH)
+
+static const unsigned t_ls_ops[16] = {
+	0x5000,		0xf8400000,
+	0x5400,		0xf8000000,
+	0x5200,		0xf8200000,
+	0x5600,		0xf9100000,
+	0x5800,		0xf8500000,
+	0x5c00,		0xf8100000,
+	0x5a00,		0xf8300000,
+	0x5e00,		0xf9300000,
+};
+
+#define DP_ADC	0
+#define DP_ADD	1
+#define DP_AND	2
+#define DP_ASR	3
+#define DP_BIC	4
+#define DP_CMN	5
+#define DP_CMP	6
+#define DP_EOR	7
+#define DP_LSL	8
+#define DP_LSR	9
+#define DP_MOV	10
+#define DP_MVN	11
+#define DP_ORN	12
+#define DP_ORR	13
+#define DP_ROR	14
+#define DP_RSB	15
+#define DP_SBC	16
+#define DP_SUB	17
+#define DP_TEQ	18
+#define DP_TST	19
+#define DP_MUL	20
+
+static const unsigned n_ops[] = {
+	DP_SBC,		// ADC	x, y == SBC x, ~y
+	DP_SUB,		// ADD	x, y == SUB x, -y
+	DP_BIC,		// AND	x, y == BIX x, ~y
+	(unsigned)-1,	// ASR
+	DP_AND,		// BIC	x, y == AND x, ~y
+	DP_CMP,		// CMN	x, y == CMP x, -y
+	DP_CMN,		// CMP	x, y == CMN x, -y
+	(unsigned)-1,	// EOR
+	(unsigned)-1,	// LSL
+	(unsigned)-1,	// LSR
+	DP_MVN,		// MOV	x, y == MVN x, ~y
+	DP_MOV,		// MVN	x, y == MOV x, ~y
+	DP_ORR,		// ORN	x, y == ORR x, ~y
+	DP_ORN,		// ORR	x, y == ORN x, ~y
+	(unsigned)-1,	// ROR
+	(unsigned)-1,	// RSB
+	DP_ADC,		// SBC	x, y == ADC x, ~y
+	DP_ADD,		// ADD	x, y == SUB x, -y
+	(unsigned)-1,	// TEQ
+	(unsigned)-1,	// TST
+	(unsigned)-1,	// MUL
+};
+
+#define N_OP(op)	n_ops[(op)]
+
+static const unsigned t_dop_ops[] = {
+//	Rd, Rm, #N	Rd, Rn, Rm
+	0xf1400000,	0xeb400000,	// ADC
+	0xf1000000,	0xeb000000,	// ADD
+	0xf0000000,	0xea000000,	// AND
+	0xea4f0020,	0xfa40f000,	// ASR
+	0xf0200000,	0xea200000,	// BIC
+	0xf1100f00,	0xeb100f00,	// CMN
+	0xf1b00f00,	0xebb00f00,	// CMP
+	0xf0800000,	0xea800000,	// EOR
+	0xea4f0000,	0xfa00f000,	// LSL
+	0xea4f0010,	0xfa20f000,	// LSR
+	0xf04f0000,	0xea4f0000,	// MOV
+	0xf06f0000,	0xea6f0000,	// MVN
+	0xf0600000,	0xea600000,	// ORN
+	0xf0400000,	0xea400000,	// ORR
+	0xea4f0030,	0xfa6f0000,	// ROR
+	0xf1c00000,	0xebc00000,	// RSB
+	0xf1600000,	0xeb600000,	// SBC
+	0xf1a00000,	0xeba00000,	// SUB
+	0xf0900f00,	0xea900f00,	// TEQ
+	0xf0100f00,	0xea100f00,	// TST
+	(unsigned)-1,	0xfb00f000,	// MUL
+};
+
+#define DP_IMM(op)	t_dop_ops[(op)*2]
+#define DP_REG(op)	t_dop_ops[(op)*2+1]
+
+#define VP_ADD	0
+#define VP_SUB	1
+#define VP_MUL	2
+#define VP_DIV	3
+
+static const unsigned t_vop_ops[] = {
+	0xee300a00,			// VADD
+	0xee300a40,			// VSUB
+	0xee200a00,			// VMUL
+	0xee800a00,			// VDIV
+};
+
+#define VP_REG(op)	t_vop_ops[op]
+
+#define T1_LS_OP(op)	t_ls_ops[(op)*2]
+#define T2_LS_OP(op)	t_ls_ops[(op)*2+1]
+
+#define SHIFT_LSL	0
+#define SHIFT_LSR	1
+#define SHIFT_ASR	2
+#define SHIFT_ROR	3
+#define SHIFT_RRX	3
+
+//------------------------------------------------------------------------------------
+
+#define E_STR_IMM6(src, imm6)		(0xce00 | ((imm6)<<3) | (src))
+#define E_LDR_IMM6(dst, imm6)		(0xcc00 | ((imm6)<<3) | (dst))
+#define E_LDR_IMM5(dst, imm5)		(0xcb00 | ((imm5)<<3) | (dst))
+#define E_LDR_IMM3(dst, base, imm3)	(0xc800 | ((imm3)<<6) | ((base) << 3) | (dst))
+
+#define T_MOV_IMM8(r, imm8)		(0x2000 | ((r)<<8) | (imm8))
+#define T_MOV_BYTELANE(r, typ, b)	(0xf04f0000 | ((typ) << 12) | ((r) << 8) | (b))
+#define T_MOV_ROT_IMM(r, ror, imm)	\
+		(0xf04f0000 | (((ror) & 0x10) << (26-4)) | (((ror) & 0xe) << (12-1)) |	\
+		(((ror) & 1) << 7) | ((r) << 8) | ((imm) & 0x7f))
+#define T_MOVW_IMM16(r, imm)		\
+		(0xf2400000 | (((imm) & 0xf000) << (16-12)) | (((imm) & 0x800) << (26-11)) | \
+		(((imm) & 0x700) << (12-8)) | ((imm) & 0xff) | ((r) << 8))
+#define T_MOVT_IMM16(r, imm)		\
+		(0xf2c00000 | (((imm) & 0xf000) << (16-12)) | (((imm) & 0x800) << (26-11)) | \
+		(((imm) & 0x700) << (12-8)) | ((imm) & 0xff) | ((r) << 8))
+#define T_MVN_BYTELANE(r, typ, b)	(0xf06f0000 | ((typ) << 12) | ((r) << 8) | (b))
+#define T_MVN_ROT_IMM(r, ror, imm)	(0xf06f0000 | (((ror) & 0x10) << (26-4)) |	\
+		(((ror) & 0xe) << (12-1)) | (((ror) & 1) << 7) | ((r) << 8) | ((imm) & 0x7f))
+
+#define T_ORR_ROT_IMM(dst, src, ror, imm)	(0xf0400000 | (((ror) & 0x10) << (26-4)) | \
+		(((ror) & 0xe) << (12-1)) | (((ror) & 1) << 7) | ((src) << 16) |	\
+		((dst) << 8) | ((imm) & 0x7f))
+#define T_ORN_ROT_IMM(dst, src, ror, imm)	(0xf0600000 | (((ror) & 0x10) << (26-4)) | \
+		(((ror) & 0xe) << (12-1)) | (((ror) & 1) << 7) | ((src) << 16) |	\
+		((dst) << 8) | ((imm) & 0x7f))
+
+#define T_STR_IMM5(src, base, imm5)	(0x6000 | ((imm5) << 6) | ((base) << 3) | (src))
+#define T_STR_SP_IMM8(src, imm8)	(0x9000 | ((src) << 8) | (imm8))
+#define T_STR_IMM12(src, base, imm12)	(0xf8c00000 | ((src)<<12) | ((base)<<16) | (imm12))
+#define T_STR_IMM8(src, base, imm8, pre, wb)	(0xf8400800 | ((src)<<12) | 		\
+		((base)<<16) | ((pre)<<10) | (U(imm8)<<9) | ((wb)<<8) | abs(imm8))
+
+#define T_LDR_IMM5(dst, base, imm5)	(0x6800 | ((imm5) << 6) | ((base) << 3) | (dst))
+#define T_LDR_SP_IMM8(src, imm8)	(0x9800 | ((dst) << 8) | (imm8))
+#define T_LDR_IMM12(dst, base, imm12)	(0xf8d00000 | ((dst)<<12) | ((base)<<16) | (imm12))
+#define T_LDR_IMM8(src, base, imm8, pre, wb)	(0xf8500800 | ((dst)<<12) | 		\
+		((base)<<16) | ((pre)<<10) | (U(imm8)<<9) | ((wb)<<8) | abs(imm8))
+
+#define T_STRB_IMM5(src, base, imm5)	(0x7000 | ((imm5) << 6) | ((base) << 3) | (src))
+#define T_STRB_IMM12(src, base, imm12)	(0xf8800000 | ((src)<<12) | ((base)<<16) | (imm12))
+#define T_STRB_IMM8(src, base, imm8, pre, wb)	(0xf8000800 | ((src)<<12) | 		\
+		((base)<<16) | ((pre)<<10) | (U(imm8)<<9) | ((wb)<<8) | abs(imm8))
+
+#define T_LDRB_IMM5(dst, base, imm5)	(0x7800 | ((imm5) << 6) | ((base) << 3) | (dst))
+#define T_LDRB_IMM12(dst, base, imm12)	(0xf8900000 | ((dst)<<12) | ((base)<<16) | (imm12))
+#define T_LDRB_IMM8(dst, base, imm8, pre, wb)	(0xf8100800 | ((dst)<<12) | 		\
+		((base)<<16) | ((pre)<<10) | (U(imm8)<<9) | ((wb)<<8) | abs(imm8))
+
+#define T_STRH_IMM5(dst, base, imm5)	(0x8000 | ((imm5) << 6) | ((base) << 3) | (dst))
+#define T_STRH_IMM12(dst, base, imm12)	(0xf8a00000 | ((dst)<<12) | ((base)<<16) | (imm12))
+#define T_STRH_IMM8(dst, base, imm8, pre, wb)	(0xf8200800 | ((dst)<<12) | 		\
+		((base)<<16) | ((pre)<<10) | (U(imm8)<<9) | ((wb)<<8) | abs(imm8))
+
+#define T_LDRH_IMM5(dst, base, imm5)	(0x8800 | ((imm5) << 6) | ((base) << 3) | (dst))
+#define T_LDRH_IMM12(dst, base, imm12)	(0xf8b00000 | ((dst)<<12) | ((base)<<16) | (imm12))
+#define T_LDRH_IMM8(dst, base, imm8, pre, wb)	(0xf8300800 | ((dst)<<12) | 		\
+		((base)<<16) | ((pre)<<10) | (U(imm8)<<9) | ((wb)<<8) | abs(imm8))
+
+#define T_LDRSH_IMM12(dst, base, imm12)	(0xf9b00000 | ((dst)<<12) | ((base)<<16) | (imm12))
+#define T_LDRSH_IMM8(dst, base, imm8, pre, wb)	(0xf9300800 | ((dst)<<12) | 		\
+		((base)<<16) | ((pre)<<10) | (U(imm8)<<9) | ((wb)<<8) | abs(imm8))
+
+#define T_LDRSB_IMM12(dst, base, imm12)	(0xf9900000 | ((dst)<<12) | ((base)<<16) | (imm12))
+#define T_LDRSB_IMM8(dst, base, imm8, pre, wb)	(0xf9100800 | ((dst)<<12) | 		\
+		((base)<<16) | ((pre)<<10) | (U(imm8)<<9) | ((wb)<<8) | abs(imm8))
+
+#define T_LDRD_IMM(lo, hi, base, imm8, pre, wb)	(0xe8500000 | ((base)<<16) |		\
+		((lo) << 12) | ((hi)<<8) | ((pre)<<24) | (U(imm8)<<23) | ((wb)<<21) | abs(imm8))
+#define T_STRD_IMM(lo, hi, base, imm8, pre, wb)	(0xe8400000 | ((base)<<16) |		\
+		((lo) << 12) | ((hi)<<8) | ((pre)<<24) | (U(imm8)<<23) | ((wb)<<21) | abs(imm8))
+
+#define T_LDREX(dst, base, off) (0xe8500f00 | ((base) << 16) | ((dst) << 12) | ((off) >> 2))
+#define T_STREX(dst, src, base, off) (0xe8400000 | ((base) << 16) | \
+		((src) << 12) | ((dst) << 8) | ((off >> 2)))
+
+#define T_STM8(base, regset)		(0xc000 | ((base) << 8) | (regset))
+#define T_STM16(base, regset, st, wb)	(0xe8000000 | ((st) << 23) | ((wb) << 21) |	\
+		((base) << 16) | (regset))
+
+#define T_LDM8(base, regset)		(0xc800 | ((base) << 8) | (regset))
+#define	T_LDM16(base, regset, st, wb)	(0xe8100000 | ((st) << 23) | ((wb) << 21) |	\
+		((base) << 16) | (regset))
+#define T_POP(regset)	(0xbc00 | (((regset & (1<<ARM_PC)) >> ARM_PC) << 8) | (regset & 0xff))
+#define T_PUSH(regset)	(0xb400 | (((regset & (1<<ARM_LR)) >> ARM_LR) << 8) | (regset & 0xff))
+
+#define	T1_LDR_STR_REG(op, xfer, base, off) 	((op) | ((off) << 6) | ((base) << 3) | (xfer))
+#define T2_LDR_STR_REG(op, xfer, base, off, sh)	((op) | ((base) << 16) | ((xfer) << 12) | \
+		((sh)<<4) | (off))
+
+#define T_CHKA(size, idx)		(0xca00 | (((size) & 8) << (7-3)) | ((idx) << 3) | ((size) & 7))
+#define T_HBL(handler)			(0xc300 | (handler))
+#define T_ENTER_LEAVE(enter)		(0xf3bf8f0f | ((enter)<<4))
+
+#define T1_ADD_IMM(dst, src, imm3)	(0x1c00 | ((imm3) << 6) | ((src) << 3) | (dst))
+#define T2_ADD_IMM(r, imm8)		(0x3000 | ((r) << 8) | (imm8))
+#define T3_ADD_BYTELANE(dst, src, typ, b) (0xf1000000 | ((src) << 16) | ((typ) << 12) | \
+		((dst) << 8) | (b))
+#define T3_ADD_ROT_IMM(dst, src, ror, imm) (0xf1000000 | ((src) << 16) | ((dst) << 8) | \
+		(((ror) & 0x10) << (26-4)) | (((ror) & 0x0e) << (12-1)) | (((ror) & 1) << 7) | \
+		((imm) & 0x7f))
+#define T4_ADD_IMM(dst, src, imm)	(0xf2000000 | ((src) << 16) | ((dst) << 8) | \
+		(((imm) & 0x800) << (26-11)) | (((imm) & 0x700) << (12-8)) | ((imm) & 0xff))
+
+#define T1_SUB_IMM(dst, src, imm3)	(0x1e00 | ((imm3) << 6) | ((src) << 3) | (dst))
+#define T2_SUB_IMM(r, imm8)		(0x3800 | ((r) << 8) | (imm8))
+#define T3_SUB_BYTELANE(dst, src, typ, b) (0xf1a00000 | ((src) << 16) | ((typ) << 12) | \
+		((dst) << 8) | (b))
+#define T3_SUB_ROT_IMM(dst, src, ror, imm) (0xf1a00000 | ((src) << 16) | ((dst) << 8) | \
+		(((ror) & 0x10) << (26-4)) | (((ror) & 0x0e) << (12-1)) | (((ror) & 1) << 7) | \
+		((imm) & 0x7f))
+#define T4_SUB_IMM(dst, src, imm)	(0xf2a00000 | ((src) << 16) | ((dst) << 8) | \
+		(((imm) & 0x800) << (26-11)) | (((imm) & 0x700) << (12-8)) | ((imm) & 0xff))
+
+#define T_DOP_BYTELANE(op, dst, src, typ, b)	((op) | ((dst) << 8) | ((src) << 16) | \
+		((typ) << 12) | (b))
+#define T_DOP_ROT_IMM(op, dst, src, ror, imm)	((op) | ((dst) << 8) | ((src) << 16) | \
+		(((ror) & 0x10) << (26-4)) | (((ror) & 0x0e) << (12-1)) | (((ror) & 1) << 7) | \
+		((imm) & 0x7f))
+#define T_SHIFT_IMM(op, dst, src, imm)	((op) | ((dst) << 8) | (src) | \
+		(((imm) & 3) << 6) | (((imm) & 0x1c) << (12-2)))
+#define T_DOP_REG(op, dst, lho, rho, st, sh)	((op) | ((dst) << 8) | ((lho) << 16) | (rho) | \
+		((st) << 4) | (((sh) & 0x1c) << (12-2)) | (((sh) & 3) << 6))
+#define T3_ADD_BYTELANE(dst, src, typ, b) (0xf1000000 | ((src) << 16) | ((typ) << 12) | \
+		((dst) << 8) | (b))
+
+#define T_CMP_IMM(src, imm)		(0x2800 | ((src) << 8) | (imm))
+#define T_CMP_REG(lho, rho)		(0x4280 | ((rho) << 3) | (lho))
+
+#define T_NEG(dst, src)		(0x4240 | (dst) | ((src) << 3))
+#define T_MVN(dst, src)		(0x43c0 | (dst) | ((src) << 3))
+#define T_MOV(dst, src)		(0x4600 | (((dst) & 8) << (7-3)) | ((src) << 3) | ((dst) & 7))
+
+#define T_VMOVS_TOARM(dst, src)	\
+	(0xee100a10 | ((dst) << 12) | (((src) & 1) << 7) | (((src) & 0x1e)<<(16-1)))
+#define T_VMOVS_TOVFP(dst, src) \
+	(0xee000a10 | ((src) << 12) | (((dst) & 1) << 7) | (((dst) & 0x1e)<<(16-1)))
+
+#define T_VMOVD_TOARM(dst_lo, dst_hi, src) \
+  (0xec500b10 | ((dst_lo) << 12) | ((dst_hi) << 16) | (((src) & 0x10)<<(5-4)) | ((src) & 0x0f))
+#define T_VMOVD_TOVFP(dst, src_lo, src_hi) \
+  (0xec400b10 | ((src_lo) << 12) | ((src_hi) << 16) | (((dst) & 0x10)<<(5-4)) | ((dst) & 0x0f))
+
+#define T_VOP_REG_S(op, dst, lho, rho)	((op) |				\
+		(((dst) & 1) << 22) | (((dst) & 0x1e) << (12-1)) | 	\
+		(((lho) & 1) << 7) | (((lho) & 0x1e) << (16-1))	 |	\
+		(((rho) & 1) << 5) | (((rho) & 0x1e) >> 1))
+#define T_VOP_REG_D(op, dst, lho, rho)	((op) |	(1 << 8) |		\
+		(((dst) & 0x10) << (22-4)) | (((dst) & 0xf) << 12) | 	\
+		(((lho) & 0x10) << (7-4)) | (((lho) & 0xf) << 16)   |	\
+		(((rho) & 0x10) << (5-4)) | ((rho) & 0xf))
+
+#define T_VCMP_S(lho, rho, e)		(0xeeb40a40 | ((e) << 7) |	\
+		(((lho) & 1) << 22) | (((lho) & 0x1e) << (12-1)) |	\
+		(((rho) & 1) << 5) | (((rho) & 0x1e) >>1))
+#define T_VCMP_D(lho, rho, e)		(0xeeb40b40 | ((e) << 7) |	\
+		(((lho) & 0x10) << (22-4)) | (((lho) & 0x0f) << 12) |	\
+		(((rho) & 0x10) << (5-4)) | ((rho) & 0x0f))
+#define T_VMRS(dst)	(0xeef10a10 | ((dst) << 12))
+
+#define T_MLA(res, lho, rho, a) \
+		(0xfb000000 | ((res) << 8) | ((lho) << 16) | (rho) | ((a) << 12))
+#define T_UMULL(res_lo, res_hi, lho, rho) \
+		(0xfba00000 | ((res_lo) << 12) | ((res_hi) << 8) | ((lho) << 16) | (rho))
+
+#define T_BX(src)		(0x4700 | ((src) << 3))
+#define T_TBH(base, idx)	(0xe8d0f010 | ((base) << 16) | (idx))
+
+#define T_SXTB(dst, src)	(0xb240 | ((src) << 3) | (dst))
+#define T_SXTH(dst, src)	(0xb200 | ((src) << 3) | (dst))
+#define T2_SXTB(dst, src)	(0xfa4ff080 | ((dst) << 8) | (src))
+#define T2_SXTH(dst, src)	(0xfa0ff080 | ((dst) << 8) | (src))
+#define T_UXTH(dst, src)	(0xb280 | ((src) << 3) | (dst))
+#define T2_UXTH(dst, src)	(0xfa1ff080 | ((dst) << 8) | (src))
+
+int out_16(CodeBuf *codebuf, u32 s)
+{
+  codebuf->codebuf[codebuf->idx++] = s;
+  return 0;
+}
+
+int out_16x2(CodeBuf *codebuf, u32 sx2)
+{
+  unsigned s1 = sx2 >> 16;
+  unsigned s2 = sx2 & 0xffff;
+
+  out_16(codebuf, s1);
+  return out_16(codebuf, s2);
+}
+
+int out_32(CodeBuf *codebuf, u32 w)
+{
+  *(u32 *)&(codebuf->codebuf[codebuf->idx]) = w;
+  codebuf->idx += 2;
+  return 0;
+}
+
+u32 out_pos(CodeBuf *codebuf)
+{
+  return (u32)&(codebuf->codebuf[codebuf->idx]);
+}
+
+u32 out_loc(CodeBuf *codebuf)
+{
+  return codebuf->idx * 2;
+}
+
+#define CODE_ALIGN 64
+#define CODE_ALIGN_SIZE 64
+
+u32 out_align(CodeBuf *codebuf, unsigned align)
+{
+  codebuf->idx += (((out_pos(codebuf) + (align-1)) & ~(align-1)) - out_pos(codebuf)) / sizeof(short);
+  return out_pos(codebuf);
+}
+
+int thumb_single_shift(unsigned imm)
+{
+  unsigned lsl;
+
+  if (!imm) return -1;
+  lsl = 0;
+  while (!(imm & 0x80000000)) {
+    imm <<= 1;
+    lsl++;
+  }
+  if (lsl >= 24) return -1;
+  if ((imm & 0xff000000) == imm) return lsl+8;
+  return -1;
+}
+
+int thumb_bytelane(u32 imm)
+{
+    unsigned b1 = imm & 0xff;
+    unsigned b2 = (imm >> 8) & 0xff;
+    unsigned b3 = (imm >> 16) & 0xff;
+    unsigned b4 = imm >> 24;
+    int mov_type = -1;
+
+    if (b1 == b3 && b2 == 0 && b4 == 0) mov_type = 1;
+    if (b1 == b2 && b1 == b3 && b1 == b4) mov_type = 3;
+    if (b2 == b4 && b1 == 0 && b3 == 0) mov_type = 2;
+    if (imm < 256) mov_type = 0;
+    return mov_type;
+}
+
+int mov_imm(CodeBuf *codebuf, Reg r, u32 imm)
+{
+  int mov_type, rol;
+
+  if (Thumb2) {
+    if (r < ARM_R8 && imm < 256)
+      return out_16(codebuf, T_MOV_IMM8(r, imm));
+    mov_type = thumb_bytelane(imm);
+    if (mov_type >= 0) {
+      if (mov_type == 2) imm >>= 8;
+      return out_16x2(codebuf, T_MOV_BYTELANE(r, mov_type, (imm & 0xff)));
+    }
+    mov_type = thumb_bytelane(~imm);
+    if (mov_type >= 0) {
+      imm = ~imm;
+      if (mov_type == 2) imm >>= 8;
+      return out_16x2(codebuf, T_MVN_BYTELANE(r, mov_type, (imm & 0xff)));
+    }
+    rol = thumb_single_shift(imm);
+    if (rol >= 0)
+      return out_16x2(codebuf, T_MOV_ROT_IMM(r, rol, ROL(imm, rol)));
+    rol = thumb_single_shift(~imm);
+    if (rol >= 0)
+      return out_16x2(codebuf, T_MVN_ROT_IMM(r, rol, ROL(~imm, rol)));
+    if ((imm & ~0xffff) == 0)
+      return out_16x2(codebuf, T_MOVW_IMM16(r, imm & 0xffff));
+    if (r < ARM_R8) {
+      rol = thumb_single_shift(imm & ~0xff);
+      if (rol >= 0) {
+	out_16(codebuf, T_MOV_IMM8(r, imm & 0xff));
+	return out_16x2(codebuf, T_ORR_ROT_IMM(r, r, rol, ROL(imm & ~0xff, rol)));
+      }
+    }
+    out_16x2(codebuf, T_MOVW_IMM16(r, imm & 0xffff));
+    return out_16x2(codebuf, T_MOVT_IMM16(r, imm >> 16));
+  }
+  J_Unimplemented();
+}
+
+int load_store_reg_no_wb(CodeBuf *codebuf, u32 op, Reg xfer, Reg base, Reg offset,
+							  u32 shift, int pre)
+{
+  if (pre) {
+    if (xfer < ARM_R8 && base < ARM_R8 && offset < ARM_R8) {
+      if (ThumbEE) {
+	if ((shift == 0 && LS_IS_BYTE(op)) || (shift == 1 && LS_IS_HW(op)) ||
+							(shift == 2 && LS_IS_WORD(op)))
+	  return out_16(codebuf, T1_LDR_STR_REG(T1_LS_OP(op), xfer, base, offset));
+      } else if (shift == 0)
+	return out_16(codebuf, T1_LDR_STR_REG(T1_LS_OP(op), xfer, base, offset));
+    }
+    if (shift < 4)
+      return out_16x2(codebuf, T2_LDR_STR_REG(T2_LS_OP(op), xfer, base, offset, shift));
+  }
+  J_Unimplemented();
+}
+
+static int add_reg(CodeBuf *codebuf, u32 dst, u32 lho, u32 rho);
+
+int load_store_reg(CodeBuf *codebuf, u32 op, Reg xfer, Reg base, Reg offset,
+							  u32 shift, int pre, int wb)
+{
+  int rc = load_store_reg_no_wb(codebuf, op, xfer, base, offset, shift, pre);
+  if (wb) {
+    return add_reg(codebuf, base, base, offset);
+  }
+  return rc;
+}
+
+int str_reg(CodeBuf *codebuf, Reg src, Reg base, Reg offset, u32 shift, int pre, int wb)
+{
+  return load_store_reg(codebuf, LS_STR, src, base, offset, shift, pre, wb);
+}
+
+int ldr_reg(CodeBuf *codebuf, Reg dst, Reg base, Reg offset, u32 shift, int pre, int wb)
+{
+  return load_store_reg(codebuf, LS_LDR, dst, base, offset, shift, pre, wb);
+}
+
+int strb_reg(CodeBuf *codebuf, Reg src, Reg base, Reg offset, u32 shift, int pre, int wb)
+{
+  return load_store_reg(codebuf, LS_STRB, src, base, offset, shift, pre, wb);
+}
+
+int ldrb_reg(CodeBuf *codebuf, Reg dst, Reg base, Reg offset, u32 shift, int pre, int wb)
+{
+  return load_store_reg(codebuf, LS_LDRB, dst, base, offset, shift, pre, wb);
+}
+
+int strh_reg(CodeBuf *codebuf, Reg src, Reg base, Reg offset, u32 shift, int pre, int wb)
+{
+  return load_store_reg(codebuf, LS_STRH, src, base, offset, shift, pre, wb);
+}
+
+int ldrh_reg(CodeBuf *codebuf, Reg dst, Reg base, Reg offset, u32 shift, int pre, int wb)
+{
+  return load_store_reg(codebuf, LS_LDRH, dst, base, offset, shift, pre, wb);
+}
+
+int ldrsh_reg(CodeBuf *codebuf, Reg dst, Reg base, Reg offset, u32 shift, int pre, int wb)
+{
+  return load_store_reg(codebuf, LS_LDRSH, dst, base, offset, shift, pre, wb);
+}
+
+int ldrsb_reg(CodeBuf *codebuf, Reg dst, Reg base, Reg offset, u32 shift, int pre, int wb)
+{
+  return load_store_reg(codebuf, LS_LDRSB, dst, base, offset, shift, pre, wb);
+}
+
+int ldrex_imm(CodeBuf *codebuf, Reg dst, Reg base, unsigned offset)
+{
+  if (Thumb2) {
+    if ((offset & 3) == 0 && offset < 256 * 4) {
+      return out_16x2(codebuf, T_LDREX(dst, base, offset));
+    }
+  }
+  J_Unimplemented();
+}
+
+int strex_imm(CodeBuf *codebuf, Reg dst, Reg src, Reg base, unsigned offset)
+{
+  if (Thumb2) {
+    if ((offset & 3) == 0 && offset < 256 * 4) {
+      return out_16x2(codebuf, T_STREX(dst, src, base, offset));
+    }
+  }
+  J_Unimplemented();
+}
+
+int str_imm(CodeBuf *codebuf, Reg src, Reg base, int offset, int pre, int wb)
+{
+  unsigned uoff;
+
+  if (!pre && !wb) pre = 1, offset = 0;
+  uoff = (unsigned)offset;
+  if (Thumb2) {
+    if (pre && !wb && offset >= 0) {
+      if (base < ARM_R8 && src < ARM_R8 && uoff < 128 && (uoff & 3) == 0)
+	return out_16(codebuf, T_STR_IMM5(src, base, uoff>>2));
+      if (base == ARM_SP && src < ARM_R8 && uoff < 1024 && (uoff &3) ==0)
+	return out_16(codebuf, T_STR_SP_IMM8(src, uoff>>2));
+      if (ThumbEE && base == ARM_R9 && src < ARM_R8 && uoff < 256 && (uoff & 3) == 0)
+	return out_16(codebuf, E_STR_IMM6(src, uoff>>2));
+      if (uoff < (1 << 12))
+	return out_16x2(codebuf, T_STR_IMM12(src, base, uoff));
+    } else if (offset < 256 && offset > -256)
+	return out_16x2(codebuf, T_STR_IMM8(src, base, offset, pre, wb));
+    JASSERT(base != ARM_IP && src != ARM_IP, "src or base == IP in str_imm");
+    mov_imm(codebuf, ARM_IP, offset);
+    return str_reg(codebuf, src, base, ARM_IP, 0, pre, wb);
+  }
+  J_Unimplemented();
+}
+
+int ldr_imm(CodeBuf *codebuf, Reg dst, Reg base, int offset, int pre, int wb)
+{
+  unsigned uoff;
+
+  if (!pre && !wb) pre = 1, offset = 0;
+  uoff = (unsigned)offset;
+  if (Thumb2) {
+    if (pre && !wb && offset >= 0) {
+      if (base < ARM_R8 && dst < ARM_R8 && uoff < 128 && (uoff & 3) ==0)
+	return out_16(codebuf, T_LDR_IMM5(dst, base, uoff>>2));
+      if (base == ARM_SP && dst < ARM_R8 && uoff < 1024 & (uoff & 3) == 0)
+	return out_16(codebuf, T_LDR_SP_IMM8(dst, uoff>>2));
+      if (ThumbEE && base == ARM_R9 && dst < ARM_R8 && uoff < 256 && (uoff & 3) == 0)
+	return out_16(codebuf, E_LDR_IMM6(dst, uoff>>2));
+      if (ThumbEE && base == ARM_R10 && dst < ARM_R8 && uoff < 128 && (uoff & 3) == 0)
+	return out_16(codebuf, E_LDR_IMM5(dst, uoff>>2));
+      if (uoff < (1 << 12))
+	return out_16x2(codebuf, T_LDR_IMM12(dst, base, uoff));
+    } else {
+      if (ThumbEE && pre && !wb && offset <= 0 && offset > -32 && (uoff & 3) == 0 &&
+							base < ARM_R8 && dst < ARM_R8)
+	return out_16(codebuf, E_LDR_IMM3(dst, base, -offset >> 2));
+      if (offset < 256 && offset > -256)
+	return out_16x2(codebuf, T_LDR_IMM8(dst, base, offset, pre, wb));
+    }
+    JASSERT(base != ARM_IP, "base == IP in ldr_imm");
+    mov_imm(codebuf, ARM_IP, offset);
+    return ldr_reg(codebuf, dst, base, ARM_IP, 0, pre, wb);
+  }
+  J_Unimplemented();
+}
+
+int strb_imm(CodeBuf *codebuf, Reg src, Reg base, int offset, int pre, int wb)
+{
+  unsigned uoff;
+
+  if (!pre && !wb) pre = 1, offset = 0;
+  uoff = (unsigned)offset;
+  if (Thumb2) {
+    if (pre && !wb && offset >= 0) {
+      if (base < ARM_R8 && src < ARM_R8 && uoff < 32)
+	return out_16(codebuf, T_STRB_IMM5(src, base, uoff));
+      if (uoff < (1 << 12))
+	return out_16x2(codebuf, T_STRB_IMM12(src, base, uoff));
+    } else if (offset < 256 && offset > -256)
+	return out_16x2(codebuf, T_STRB_IMM8(src, base, offset, pre, wb));
+    JASSERT(base != ARM_IP && src != ARM_IP, "src or base == IP in str_imm");
+    mov_imm(codebuf, ARM_IP, offset);
+    return strb_reg(codebuf, src, base, ARM_IP, 0, pre, wb);
+  }
+  J_Unimplemented();
+}
+
+int ldrb_imm(CodeBuf *codebuf, Reg dst, Reg base, int offset, int pre, int wb)
+{
+  unsigned uoff;
+
+  if (!pre && !wb) pre = 1, offset = 0;
+  uoff = (unsigned)offset;
+  if (Thumb2) {
+    if (pre && !wb && offset >= 0) {
+      if (base < ARM_R8 && dst < ARM_R8 && uoff < 32)
+	return out_16(codebuf, T_LDRB_IMM5(dst, base, uoff));
+      if (uoff < (1 << 12))
+	return out_16x2(codebuf, T_LDRB_IMM12(dst, base, uoff));
+    } else if (offset < 256 && offset > -256)
+	return out_16x2(codebuf, T_LDRB_IMM8(dst, base, offset, pre, wb));
+    JASSERT(base != ARM_IP, "base == IP in ldr_imm");
+    mov_imm(codebuf, ARM_IP, offset);
+    return ldrb_reg(codebuf, dst, base, ARM_IP, 0, pre, wb);
+  }
+  J_Unimplemented();
+}
+
+int strh_imm(CodeBuf *codebuf, Reg src, Reg base, int offset, int pre, int wb)
+{
+  unsigned uoff;
+
+  if (!pre && !wb) pre = 1, offset = 0;
+  uoff = (unsigned)offset;
+  if (Thumb2) {
+    if (pre && !wb && offset >= 0) {
+      if (base < ARM_R8 && src < ARM_R8 && uoff < 64 && (uoff & 1) == 0)
+	return out_16(codebuf, T_STRH_IMM5(src, base, uoff>>1));
+      if (uoff < (1 << 12))
+	return out_16x2(codebuf, T_STRH_IMM12(src, base, uoff));
+    } else if (offset < 256 && offset > -256)
+	return out_16x2(codebuf, T_STRH_IMM8(src, base, offset, pre, wb));
+    JASSERT(base != ARM_IP && src != ARM_IP, "src or base == IP in str_imm");
+    mov_imm(codebuf, ARM_IP, offset);
+    return strh_reg(codebuf, src, base, ARM_IP, 0, pre, wb);
+  }
+  J_Unimplemented();
+}
+
+int ldrh_imm(CodeBuf *codebuf, Reg dst, Reg base, int offset, int pre, int wb)
+{
+  unsigned uoff;
+
+  if (!pre && !wb) pre = 1, offset = 0;
+  uoff = (unsigned)offset;
+  if (Thumb2) {
+    if (pre && !wb && offset >= 0) {
+      if (base < ARM_R8 && dst < ARM_R8 && uoff < 64 && (uoff & 1) == 0)
+	return out_16(codebuf, T_LDRH_IMM5(dst, base, uoff>>1));
+      if (uoff < (1 << 12))
+	return out_16x2(codebuf, T_LDRH_IMM12(dst, base, uoff));
+    } else if (offset < 256 && offset > -256)
+	return out_16x2(codebuf, T_LDRH_IMM8(dst, base, offset, pre, wb));
+    JASSERT(base != ARM_IP, "base == IP in ldr_imm");
+    mov_imm(codebuf, ARM_IP, offset);
+    return ldrh_reg(codebuf, dst, base, ARM_IP, 0, pre, wb);
+  }
+  J_Unimplemented();
+}
+
+int ldrsh_imm(CodeBuf *codebuf, Reg dst, Reg base, int offset, int pre, int wb)
+{
+  unsigned uoff;
+
+  if (!pre && !wb) pre = 1, offset = 0;
+  uoff = (unsigned)offset;
+  if (Thumb2) {
+    if (pre && !wb && offset >= 0) {
+      if (uoff < (1 << 12))
+	return out_16x2(codebuf, T_LDRSH_IMM12(dst, base, uoff));
+    } else if (offset < 256 && offset > -256)
+	return out_16x2(codebuf, T_LDRSH_IMM8(dst, base, offset, pre, wb));
+    JASSERT(base != ARM_IP, "base == IP in ldr_imm");
+    mov_imm(codebuf, ARM_IP, offset);
+    return ldrsh_reg(codebuf, dst, base, ARM_IP, 0, pre, wb);
+  }
+  J_Unimplemented();
+}
+
+int ldrsb_imm(CodeBuf *codebuf, Reg dst, Reg base, int offset, int pre, int wb)
+{
+  unsigned uoff;
+
+  if (!pre && !wb) pre = 1, offset = 0;
+  uoff = (unsigned)offset;
+  if (Thumb2) {
+    if (pre && !wb && offset >= 0) {
+      if (uoff < (1 << 12))
+	return out_16x2(codebuf, T_LDRSB_IMM12(dst, base, uoff));
+    } else if (offset < 256 && offset > -256)
+	return out_16x2(codebuf, T_LDRSB_IMM8(dst, base, offset, pre, wb));
+    JASSERT(base != ARM_IP, "base == IP in ldr_imm");
+    mov_imm(codebuf, ARM_IP, offset);
+    return ldrsb_reg(codebuf, dst, base, ARM_IP, 0, pre, wb);
+  }
+  J_Unimplemented();
+}
+
+int add_imm(CodeBuf *codebuf, u32 dst, u32 src, u32 imm);
+
+int ldrd_imm(CodeBuf *codebuf, Reg dst_lo, Reg dst_hi, Reg base, int offset, int pre, int wb)
+{
+  unsigned uoff;
+
+  if (!pre && !wb) pre = 1, offset = 0;
+  uoff = (unsigned)offset;
+  if (Thumb2) {
+    if (offset < 256 * 4 && offset > -256 * 4 && (offset & 3) == 0)
+      return out_16x2(codebuf, T_LDRD_IMM(dst_lo, dst_hi, base, offset>>2, pre, wb));
+    if (pre && !wb) {
+      add_imm(codebuf, ARM_IP, base, offset);
+      return out_16x2(codebuf, T_LDRD_IMM(dst_lo, dst_hi, ARM_IP, 0, 1, 0));
+    }
+  }
+  J_Unimplemented();
+}
+
+int strd_imm(CodeBuf *codebuf, Reg src_lo, Reg src_hi, Reg base, int offset, int pre, int wb)
+{
+  unsigned uoff;
+
+  if (!pre && !wb) pre = 1, offset = 0;
+  uoff = (unsigned)offset;
+  if (Thumb2) {
+    if (offset < 256 * 4 && offset > -256 * 4 && (offset & 3) == 0)
+      return out_16x2(codebuf, T_STRD_IMM(src_lo, src_hi, base, offset>>2, pre, wb));
+    if (pre && !wb) {
+      add_imm(codebuf, ARM_IP, base, offset);
+      return out_16x2(codebuf, T_STRD_IMM(src_lo, src_hi, ARM_IP, 0, 1, 0));
+    }
+  }
+  J_Unimplemented();
+}
+
+int stm(CodeBuf *codebuf, u32 regset, u32 base, u32 st, u32 wb)
+{
+  JASSERT(regset != 0, "regset != 0 in stm");
+  if (Thumb2) {
+    if (!ThumbEE && base < ARM_R8 && (regset & ~0xff) == 0 && st == IA && wb)
+      return out_16(codebuf, T_STM8(base, regset));
+    if (base == ARM_SP) {
+      if ((regset & ~0x40ff) == 0 && st == DB && wb)
+	return out_16(codebuf, T_PUSH(regset));
+    }
+    if ((regset & -regset) == regset)
+      return str_imm(codebuf, LOG2(regset), base, (st & 1) ? 4 : -4, (st & 2) >> 1, wb);
+    if (st == PUSH_EA || st == PUSH_FD)
+      return out_16x2(codebuf, T_STM16(base, regset, st, wb));
+    return out_16x2(codebuf, T_STM16(base, regset, st, wb));
+  }
+  J_Unimplemented();
+}
+
+int ldm(CodeBuf *codebuf, u32 regset, u32 base, u32 st, u32 wb)
+{
+  JASSERT(regset != 0, "regset != 0 in stm");
+  if (Thumb2) {
+    if (!ThumbEE && base < ARM_R8 && (regset & ~0xff) == 0 && st == IA && wb)
+      return out_16(codebuf, T_LDM8(base, regset));
+    if (base == ARM_SP) {
+      if ((regset & ~0x80ff) == 0 && st == IA && wb)
+	return out_16(codebuf, T_POP(regset));
+    }
+    if ((regset & -regset) == regset)
+      return ldr_imm(codebuf, LOG2(regset), base, (st & 1) ? 4 : -4, (st & 2) >> 1, wb);
+    if (st == POP_EA || st == POP_FD)
+      return out_16x2(codebuf, T_LDM16(base, regset, st, wb));
+  }
+  J_Unimplemented();
+}
+
+int dop_reg(CodeBuf *codebuf, u32 op, u32 dst, u32 lho, u32 rho, u32 sh_typ, u32 shift)
+{
+  unsigned s = 0;
+  if (op != DP_MUL) s = 1 << 20;
+//  JASSERT(dst != ARM_PC, "Terrible things happen if dst == PC && S bit set");
+  return out_16x2(codebuf, T_DOP_REG(DP_REG(op)|s, dst, lho, rho, sh_typ, shift));
+}
+
+int dop_reg_preserve(CodeBuf *codebuf, u32 op, u32 dst, u32 lho, u32 rho, u32 sh_typ, u32 shift)
+{
+  return out_16x2(codebuf, T_DOP_REG(DP_REG(op), dst, lho, rho, sh_typ, shift));
+}
+
+int sxtb(CodeBuf *codebuf, u32 dst, u32 src)
+{
+  if (dst < ARM_R8 && src < ARM_R8)
+    return out_16(codebuf, T_SXTB(dst, src));
+  return out_16x2(codebuf, T2_SXTB(dst, src));
+}
+
+int sxth(CodeBuf *codebuf, u32 dst, u32 src)
+{
+  if (dst < ARM_R8 && src < ARM_R8)
+    return out_16(codebuf, T_SXTH(dst, src));
+  return out_16x2(codebuf, T2_SXTH(dst, src));
+}
+
+int uxth(CodeBuf *codebuf, u32 dst, u32 src)
+{
+  if (dst < ARM_R8 && src < ARM_R8)
+    return out_16(codebuf, T_UXTH(dst, src));
+  return out_16x2(codebuf, T2_UXTH(dst, src));
+}
+
+int mov_reg(CodeBuf *codebuf, u32 dst, u32 src)
+{
+  if (dst == src) return 0;
+  if (dst == ARM_PC) return out_16(codebuf, T_BX(src));
+  return out_16(codebuf, T_MOV(dst, src));
+//  return dop_reg(codebuf, DP_MOV, dst, 0, src, SHIFT_LSL, 0);
+}
+
+int mvn_reg(CodeBuf *codebuf, u32 dst, u32 src)
+{
+  if (dst < ARM_R8 && src < ARM_R8)
+    return out_16(codebuf, T_MVN(dst, src));
+  return dop_reg(codebuf, DP_MVN, dst, 0, src, SHIFT_LSL, 0);
+}
+
+int vmov_reg_s_toVFP(CodeBuf *codebuf, u32 dst, u32 src)
+{
+  return out_16x2(codebuf, T_VMOVS_TOVFP(dst, src));
+}
+
+int vmov_reg_s_toARM(CodeBuf *codebuf, u32 dst, u32 src)
+{
+  return out_16x2(codebuf, T_VMOVS_TOARM(dst, src));
+}
+
+int vmov_reg_d_toVFP(CodeBuf *codebuf, u32 dst, u32 src_lo, u32 src_hi)
+{
+  return out_16x2(codebuf, T_VMOVD_TOVFP(dst, src_lo, src_hi));
+}
+
+int vmov_reg_d_toARM(CodeBuf *codebuf, u32 dst_lo, u32 dst_hi, u32 src)
+{
+  return out_16x2(codebuf, T_VMOVD_TOARM(dst_lo, dst_hi, src));
+}
+
+int vop_reg_s(CodeBuf *codebuf, u32 op, u32 dst, u32 lho, u32 rho)
+{
+  return out_16x2(codebuf, T_VOP_REG_S(VP_REG(op), dst, lho, rho));
+}
+
+int vop_reg_d(CodeBuf *codebuf, u32 op, u32 dst, u32 lho, u32 rho)
+{
+  return out_16x2(codebuf, T_VOP_REG_D(VP_REG(op), dst, lho, rho));
+}
+
+int vcmp_reg_s(CodeBuf *codebuf, u32 lho, u32 rho, unsigned e)
+{
+  return out_16x2(codebuf, T_VCMP_S(lho, rho, e));
+}
+
+int vcmp_reg_d(CodeBuf *codebuf, u32 lho, u32 rho, unsigned e)
+{
+  return out_16x2(codebuf, T_VCMP_D(lho, rho, e));
+}
+
+int vmrs(CodeBuf *codebuf, u32 dst)
+{
+  return out_16x2(codebuf, T_VMRS(dst));
+}
+
+int add_reg(CodeBuf *codebuf, u32 dst, u32 lho, u32 rho)
+{
+  return dop_reg(codebuf, DP_ADD, dst, lho, rho, SHIFT_LSL, 0);
+}
+
+int cmp_reg(CodeBuf *codebuf, Reg lho, Reg rho)
+{
+  if (lho < ARM_R8 && rho < ARM_R8)
+    return out_16(codebuf, T_CMP_REG(lho, rho));
+  return dop_reg(codebuf, DP_CMP, 0x0f, lho, rho, SHIFT_LSL, 0);
+}
+
+int add_reg_shift(CodeBuf *codebuf, u32 dst, u32 lho, u32 rho, u2 sh_typ, u32 shift)
+{
+  return dop_reg(codebuf, DP_ADD, dst, lho, rho, sh_typ, shift);
+}
+
+int add_imm(CodeBuf *codebuf, u32 dst, u32 src, u32 imm)
+{
+  int imm_type, rol;
+
+  if (imm == 0) return mov_reg(codebuf, dst, src);
+  if (Thumb2) {
+    if (dst < ARM_R8 && src < ARM_R8) {
+      if (imm < 8)
+	return out_16(codebuf, T1_ADD_IMM(dst, src, imm));
+      if (-imm < 8)
+	return out_16(codebuf, T1_SUB_IMM(dst, src, -imm));
+      if (src == dst) {
+	if (imm < 256)
+	  return out_16(codebuf, T2_ADD_IMM(src, imm));
+	if (-imm < 256)
+	  return out_16(codebuf, T2_SUB_IMM(src, -imm));
+      }
+    }
+    imm_type = thumb_bytelane(imm);
+    if (imm_type >= 0) {
+      if (imm_type == 2) imm >>= 8;
+      return out_16x2(codebuf, T3_ADD_BYTELANE(dst, src, imm_type, (imm & 0xff)));
+    }
+    imm_type = thumb_bytelane(-imm);
+    if (imm_type >= 0) {
+      imm = -imm;
+      if (imm_type == 2) imm >>= 8;
+      return out_16x2(codebuf, T3_SUB_BYTELANE(dst, src, imm_type, (imm & 0xff)));
+    }
+    rol = thumb_single_shift(imm);
+    if (rol >= 0)
+      return out_16x2(codebuf, T3_ADD_ROT_IMM(dst, src, rol, ROL(imm, rol)));
+    rol = thumb_single_shift(-imm);
+    if (rol >= 0)
+      return out_16x2(codebuf, T3_SUB_ROT_IMM(dst, src, rol, ROL(-imm, rol)));
+    if (imm < (1 << 12))
+      return out_16x2(codebuf, T4_ADD_IMM(dst, src, imm));
+    if (-imm < (1 << 12))
+      return out_16x2(codebuf, T4_SUB_IMM(dst, src, -imm));
+    mov_imm(codebuf, ARM_IP, imm);
+    return add_reg(codebuf, dst, src, ARM_IP);
+  }
+  J_Unimplemented();
+}
+
+int sub_imm(CodeBuf *codebuf, u32 dst, u32 src, u32 imm)
+{
+  return add_imm(codebuf, dst, src, -imm);
+}
+
+int dop_imm_s(CodeBuf *codebuf, u32 op, u32 dst, u32 src, u32 imm, unsigned s)
+{
+    int imm_type, rol;
+    unsigned n_op, n_imm;
+
+    JASSERT(op == DP_ADC || op == DP_ADD || op == DP_AND || op == DP_BIC || op == DP_CMN ||
+		op == DP_CMP || op == DP_EOR || op == DP_MOV || op == DP_MVN ||
+		op == DP_ORN || op == DP_ORR || op == DP_RSB || op == DP_SBC ||
+		op == DP_SUB || op == DP_TEQ || op == DP_TST, "bad op");
+    if (op == DP_CMP || op == DP_CMN || op == DP_TEQ || op == DP_TST) dst = 0x0f;
+    if (op == DP_MOV || op == DP_MVN) src = 0x0f;
+    imm_type = thumb_bytelane(imm);
+    if (imm_type >= 0) {
+      if (imm_type == 2) imm >>= 8;
+      return out_16x2(codebuf, T_DOP_BYTELANE(DP_IMM(op)|s, dst, src, imm_type, (imm & 0xff)));
+    }
+    rol = thumb_single_shift(imm);
+    if (rol >= 0)
+      return out_16x2(codebuf, T_DOP_ROT_IMM(DP_IMM(op)|s, dst, src, rol, ROL(imm, rol)));
+    n_op = N_OP(op);
+    if (n_op != (unsigned)-1) {
+      n_imm = ~imm;
+      if (op == DP_ADD || op == DP_SUB || op == DP_CMP || op == DP_CMN) n_imm = -imm;
+      imm_type = thumb_bytelane(n_imm);
+      if (imm_type >= 0) {
+	if (imm_type == 2) n_imm >>= 8;
+	return out_16x2(codebuf, T_DOP_BYTELANE(DP_IMM(n_op)|s, dst, src, imm_type, (n_imm & 0xff)));
+      }
+      rol = thumb_single_shift(n_imm);
+      if (rol >= 0)
+	return out_16x2(codebuf, T_DOP_ROT_IMM(DP_IMM(n_op)|s, dst, src, rol, ROL(n_imm, rol)));
+    }
+    mov_imm(codebuf, ARM_IP, imm);
+    return out_16x2(codebuf, T_DOP_REG(DP_REG(op)|s, dst, src, ARM_IP, SHIFT_LSL, 0));
+}
+
+int dop_imm(CodeBuf *codebuf, u32 op, u32 dst, u32 src, u32 imm)
+{
+    return dop_imm_s(codebuf, op, dst, src, imm, 1<<20);
+}
+
+int dop_imm_preserve(CodeBuf *codebuf, u32 op, u32 dst, u32 src, u32 imm)
+{
+    return dop_imm_s(codebuf, op, dst, src, imm, 0);
+}
+
+int shift_imm(CodeBuf *codebuf, u32 op, u32 dst, u32 src, u32 imm)
+{
+    imm &= 31;
+    if (imm == 0)
+      return mov_reg(codebuf, dst, src);
+    else
+      return out_16x2(codebuf, T_SHIFT_IMM(DP_IMM(op), dst, src, imm));
+}
+
+int rsb_imm(CodeBuf *codebuf, u32 dst, u32 src, u32 imm)
+{
+  if (dst < ARM_R8 && src < ARM_R8 && imm == 0)
+    return out_16(codebuf, T_NEG(dst, src));
+  return dop_imm(codebuf, DP_RSB, dst, src, imm);
+}
+
+int adc_imm(CodeBuf *codebuf, u32 dst, u32 src, u32 imm)
+{
+  return dop_imm(codebuf, DP_ADC, dst, src, imm);
+}
+
+int asr_imm(CodeBuf *codebuf, u32 dst, u32 src, u32 imm)
+{
+  return shift_imm(codebuf, DP_ASR, dst, src, imm);
+}
+
+int eor_imm(CodeBuf *codebuf, u32 dst, u32 src, u32 imm)
+{
+  return dop_imm(codebuf, DP_EOR, dst, src, imm);
+}
+
+int and_imm(CodeBuf *codebuf, u32 dst, u32 src, u32 imm)
+{
+  return dop_imm(codebuf, DP_AND, dst, src, imm);
+}
+
+int orr_imm(CodeBuf *codebuf, u32 dst, u32 src, u32 imm)
+{
+  return dop_imm(codebuf, DP_ORR, dst, src, imm);
+}
+
+int cmp_imm(CodeBuf *codebuf, Reg src, u32 imm)
+{
+  if (src <= ARM_R8 && imm < 256) return out_16(codebuf, T_CMP_IMM(src, imm));
+  return dop_imm(codebuf, DP_CMP, 0x0f, src, imm);
+}
+
+int tst_imm(CodeBuf *codebuf, Reg src, u32 imm)
+{
+  return dop_imm(codebuf, DP_TST, 0x0f, src, imm);
+}
+
+int hbl(CodeBuf *codebuf, unsigned handler)
+{
+  mov_imm(codebuf, ARM_IP, 0);
+  str_imm(codebuf, ARM_IP, ARM_IP, 0, 1, 0);
+#if 0
+  if ((Thumb2 && ThumbEE))
+    return out_16(codebuf, T_HBL(handler));
+  if (TESTING)
+    return mov_imm(codebuf, ARM_R8, handler);
+  J_Unimplemented();
+#endif
+}
+
+#if 0
+int enter_leave(CodeBuf *codebuf, unsigned enter)
+{
+  if ((Thumb2 && ThumbEE))
+    return out_16x2(codebuf, T_ENTER_LEAVE(enter));
+  J_Unimplemented();
+}
+#endif
+
+int tbh(CodeBuf *codebuf, Reg base, Reg idx)
+{
+  out_16x2(codebuf, T_TBH(base, idx));
+}
+
+int umull(CodeBuf *codebuf, u32 res_lo, u32 res_hi, u32 lho, u32 rho)
+{
+  return out_16x2(codebuf, T_UMULL(res_lo, res_hi, lho, rho));
+}
+
+int mla(CodeBuf *codebuf, u32 res, u32 lho, u32 rho, u32 a)
+{
+  return out_16x2(codebuf, T_MLA(res, lho, rho, a));
+}
+
+#define COND_EQ 0
+#define COND_NE 1
+#define COND_LT	2
+#define COND_GE 3
+#define COND_GT 4
+#define COND_LE 5
+#define COND_CS 6
+#define COND_CC 7
+#define COND_MI 8
+#define COND_PL 9
+
+static unsigned conds[] = {
+	0x0,
+	0x1,
+	0xb,
+	0xa,
+	0xc,
+	0xd,
+	0x2,
+	0x3,
+	0x4,
+	0x5,
+};
+
+#define NEG_COND(cond)	((cond) ^ 1)
+
+#define T_B(uoff)	(0xe000 | ((uoff) & 0x7ff))
+#define T_BW(uoff)	(0xf0009000 | \
+			  (((uoff) & (1<<23)) << (26-23)) | \
+			  (((~(uoff) & (1<<22)) >> 22) ^ (((uoff) & (1<<23)) >> 23)) << 13 | \
+			  (((~(uoff) & (1<<21)) >> 21) ^ (((uoff) & (1<<23)) >> 23)) << 11 | \
+			  (((uoff) & 0x1ff800) << (16-11)) | \
+			  ((uoff) & 0x7ff))
+#define T_BL(uoff)	(0xf000d000 | \
+			  (((uoff) & (1<<23)) << (26-23)) | \
+			  (((~(uoff) & (1<<22)) >> 22) ^ (((uoff) & (1<<23)) >> 23)) << 13 | \
+			  (((~(uoff) & (1<<21)) >> 21) ^ (((uoff) & (1<<23)) >> 23)) << 11 | \
+			  (((uoff) & 0x1ff800) << (16-11)) | \
+			  ((uoff) & 0x7ff))
+#define T_BLX(uoff)	(0xf000c000 | \
+			  (((uoff) & (1<<23)) << (26-23)) | \
+			  (((~(uoff) & (1<<22)) >> 22) ^ (((uoff) & (1<<23)) >> 23)) << 13 | \
+			  (((~(uoff) & (1<<21)) >> 21) ^ (((uoff) & (1<<23)) >> 23)) << 11 | \
+			  (((uoff) & 0x1ff800) << (16-11)) | \
+			  ((uoff) & 0x7ff))
+#define T_BCC(cond, uoff) (0xd000 | (conds[cond] << 8) | ((uoff) & 0xff))
+#define T_BCCW(cond, uoff) (0xf0008000 | \
+			     (conds[cond] << 22) | \
+			     (((uoff) & (1<<19)) << (26-19)) | \
+			     (((uoff) & (1<<18)) >> (18-11)) | \
+			     (((uoff) & (1<<17)) >> (17-13)) | \
+			     (((uoff) & 0x1f800) << (16-11)) | \
+			     ((uoff) & 0x7ff))
+#define T_BLX_REG(r)	(0x4780 | ((r) << 3))
+#define T_CBZ(r, uoff)	(0xb100 | (((uoff) & 0x1f) << 3) | (((uoff) & 0x20) << (8-5)) | ((r) & 7))
+#define T_CBNZ(r, uoff)	(0xb900 | (((uoff) & 0x1f) << 3) | (((uoff) & 0x20) << (8-5)) | ((r) & 7))
+
+#define T_IT(cond, mask) (0xbf00 | (conds[cond] << 4) | (mask))
+
+#define IT_MASK_T	8
+
+#define PATCH(loc)	do {						\
+	  unsigned oldidx = codebuf->idx;				\
+	  codebuf->idx = (loc) >> 1;					\
+
+#define HCTAP								\
+	  codebuf->idx = oldidx;					\
+    	} while (0)
+
+int forward_16(CodeBuf *codebuf)
+{
+  int loc = out_loc(codebuf);
+  out_16(codebuf, T_UNDEFINED_16);
+  return loc;
+}
+
+int forward_32(CodeBuf *codebuf)
+{
+  int loc = out_loc(codebuf);
+  out_32(codebuf, T_UNDEFINED_32);
+  return loc;
+}
+
+int it(CodeBuf *codebuf, unsigned cond, unsigned mask)
+{
+  return out_16(codebuf, T_IT(cond, mask));
+}
+
+void t2_bug_align(CodeBuf *codebuf)
+{
+  unsigned pc = (unsigned)&codebuf->codebuf[codebuf->idx];
+  if ((pc & 0xffe) != 0xffe) return;
+  mov_reg(codebuf, ARM_R0, ARM_R0);
+}
+
+void t2_bug_fix(CodeBuf *codebuf, int offset)
+{
+  unsigned pc = (unsigned)&codebuf->codebuf[codebuf->idx];
+  if ((pc & 0xffe) != 0xffe) return;
+  if (offset >= 0 || offset < -(4096+4)) return;
+  mov_reg(codebuf, ARM_R0, ARM_R0);
+}
+
+int branch_uncond(CodeBuf *codebuf, unsigned dest)
+{
+  unsigned loc = (codebuf->idx * 2) + 4;
+  int offset;
+  unsigned uoff;
+
+  JASSERT((dest & 1) == 0 && (loc & 1) == 0, "unaligned code");
+  dest >>= 1;
+  loc >>= 1;
+  offset = dest - loc;
+  if (offset >= -(1<<10) && offset < (1<<10)) {
+    uoff = offset;
+    return out_16(codebuf, T_B(uoff));
+  }
+  t2_bug_fix(codebuf, offset);
+  if (offset >= -(1<<23) && offset < (1<<23)) {
+    uoff = offset;
+    return out_16x2(codebuf, T_BW(uoff));
+  }
+  J_Unimplemented();
+}
+
+int branch_uncond_patch(CodeBuf *codebuf, unsigned loc, unsigned dest)
+{
+  int offset;
+  unsigned uoff;
+  unsigned oldidx;
+  int rc;
+
+  oldidx = codebuf->idx;
+  codebuf->idx = loc >> 1;
+  loc += 4;
+  JASSERT((dest & 1) == 0 && (loc & 1) == 0, "unaligned code");
+  dest >>= 1;
+  loc >>= 1;
+  offset = dest - loc;
+  t2_bug_fix(codebuf, offset);
+  if (offset >= -(1<<23) && offset < (1<<23)) {
+    uoff = offset & ((1<<24)-1);
+    rc = out_16x2(codebuf, T_BW(uoff));
+    codebuf->idx = oldidx;
+    return rc;
+  }
+  J_Unimplemented();
+}
+
+int branch_narrow_patch(CodeBuf *codebuf, unsigned loc)
+{
+  int offset;
+  unsigned uoff;
+  unsigned oldidx;
+  unsigned dest;
+  int rc;
+
+  dest = codebuf->idx * 2;
+  oldidx = codebuf->idx;
+  codebuf->idx = loc >> 1;
+  loc += 4;
+  JASSERT((dest & 1) == 0 && (loc & 1) == 0, "unaligned code");
+  dest >>= 1;
+  loc >>= 1;
+  offset = dest - loc;
+  if (offset >= -(1<<10) && offset < (1<<10)) {
+    uoff = offset & ((1<<11)-1);
+    rc = out_16(codebuf, T_B(uoff));
+    codebuf->idx = oldidx;
+    return rc;
+  }
+  J_Unimplemented();
+}
+
+int branch(CodeBuf *codebuf, unsigned cond, unsigned dest)
+{
+  unsigned loc = (codebuf->idx * 2) + 4;
+  int offset;
+  unsigned uoff;
+
+  JASSERT((dest & 1) == 0 && (loc & 1) == 0, "unaligned code");
+  dest >>= 1;
+  loc >>= 1;
+  offset = dest - loc;
+  if (offset >= -(1<<7) && offset < (1<<7)) {
+    uoff = offset;
+    return out_16(codebuf, T_BCC(cond, uoff));
+  }
+  t2_bug_fix(codebuf, offset);
+  if (offset >= -(1<<19) && offset < (1<<19)) {
+    uoff = offset;
+    return out_16x2(codebuf, T_BCCW(cond, uoff));
+  }
+  J_Unimplemented();
+}
+
+int bcc_patch(CodeBuf *codebuf, unsigned cond, unsigned loc)
+{
+  int offset;
+  unsigned uoff;
+  unsigned oldidx;
+  unsigned dest;
+  int rc;
+
+  dest = codebuf->idx * 2;
+  oldidx = codebuf->idx;
+  codebuf->idx = loc >> 1;
+  loc += 4;
+  JASSERT((dest & 1) == 0 && (loc & 1) == 0, "unaligned code");
+  dest >>= 1;
+  loc >>= 1;
+  offset = dest-loc;
+  if (offset >= -(1<<7) && offset < (1<<7)) {
+    uoff = offset;
+    rc = out_16(codebuf, T_BCC(cond, uoff));
+    codebuf->idx = oldidx;
+    return rc;
+  }
+  J_Unimplemented();
+}
+
+int bl(CodeBuf *codebuf, unsigned dest)
+{
+  unsigned loc = (unsigned)&codebuf->codebuf[codebuf->idx] + 4;
+  int offset;
+  unsigned uoff;
+
+  JASSERT((dest & 1) == 0 && (loc & 1) == 0, "unaligned code");
+  dest >>= 1;
+  loc >>= 1;
+  offset = dest - loc;
+  t2_bug_fix(codebuf, offset);
+  if (offset >= -(1<<23) && offset < (1<<23)) {
+    uoff = offset;
+    return out_16x2(codebuf, T_BL(uoff));
+  }
+  J_Unimplemented();
+}
+
+int blx(CodeBuf *codebuf, unsigned dest)
+{
+  unsigned loc = (unsigned)&codebuf->codebuf[codebuf->idx] + 4;
+  int offset;
+  unsigned uoff;
+
+  JASSERT((dest & 3) == 0 && (loc & 1) == 0, "unaligned code");
+  dest >>= 1;
+  loc >>= 1;
+  loc &= ~1;
+  offset = dest - loc;
+  t2_bug_fix(codebuf, offset);
+  if (offset >= -(1<<23) && offset < (1<<23)) {
+    uoff = offset;
+    return out_16x2(codebuf, T_BLX(uoff));
+  }
+  J_Unimplemented();
+}
+
+int branch_patch(CodeBuf *codebuf, unsigned cond, unsigned loc, unsigned dest)
+{
+  int offset;
+  unsigned uoff;
+  unsigned oldidx;
+  int rc;
+
+  oldidx = codebuf->idx;
+  codebuf->idx = loc >> 1;
+  loc += 4;
+  JASSERT((dest & 1) == 0 && (loc & 1) == 0, "unaligned code");
+  dest >>= 1;
+  loc >>= 1;
+  offset = dest - loc;
+  t2_bug_fix(codebuf, offset);
+  if (offset >= -(1<<19) && offset < (1<<19)) {
+    uoff = offset & ((1<<20)-1);
+    rc = out_16x2(codebuf, T_BCCW(cond, uoff));
+    codebuf->idx = oldidx;
+    return rc;
+  }
+  J_Unimplemented();
+}
+
+int blx_reg(CodeBuf *codebuf, Reg r)
+{
+  return out_16(codebuf, T_BLX_REG(r));
+}
+
+int cbz_patch(CodeBuf *codebuf, Reg r, unsigned loc)
+{
+  unsigned offset;
+  unsigned oldidx;
+  unsigned dest;
+  int rc;
+
+  dest = codebuf->idx * 2;
+  oldidx = codebuf->idx;
+  codebuf->idx = loc >> 1;
+  loc += 4;
+  JASSERT((dest & 1) == 0 && (loc & 1) == 0, "unaligned code");
+  dest >>= 1;
+  loc >>= 1;
+  offset = dest-loc;
+  if (r < ARM_R8 && offset < 64) {
+    rc = out_16(codebuf, T_CBZ(r, offset));
+    codebuf->idx = oldidx;
+    return rc;
+  }
+  J_Unimplemented();
+}
+
+int cbnz_patch(CodeBuf *codebuf, Reg r, unsigned loc)
+{
+  unsigned offset;
+  unsigned oldidx;
+  unsigned dest;
+  int rc;
+
+  dest = codebuf->idx * 2;
+  oldidx = codebuf->idx;
+  codebuf->idx = loc >> 1;
+  loc += 4;
+  JASSERT((dest & 1) == 0 && (loc & 1) == 0, "unaligned code");
+  dest >>= 1;
+  loc >>= 1;
+  offset = dest-loc;
+  if (r < ARM_R8 && offset < 64) {
+    rc = out_16(codebuf, T_CBNZ(r, offset));
+    codebuf->idx = oldidx;
+    return rc;
+  }
+  J_Unimplemented();
+}
+
+int chka(CodeBuf *codebuf, u32 size, u32 idx)
+{
+  cmp_reg(codebuf, idx, size);
+  it(codebuf, COND_CS, IT_MASK_T);
+  bl(codebuf, handlers[H_ARRAYBOUND]);
+}
+
+//-----------------------------------------------------------------------------------
+
+void Thumb2_Push_Multiple(CodeBuf *codebuf, Reg *regs, unsigned nregs)
+{
+  unsigned regset = 0;
+  unsigned regmask;
+  unsigned i;
+  Reg r;
+
+  JASSERT(nregs > 0, "nregs must be > 0");
+  if (nregs == 1) {
+    str_imm(codebuf, regs[0], Rstack, -4, 1, 1);
+    return;
+  }
+  for (i = 0; i < nregs; i++) {
+    r = regs[i];
+    if (!IS_ARM_INT_REG(r)) J_Unimplemented();
+    regmask = 1<<r;
+    if (regset != 0 && regmask >= (regset & -regset)) {
+      stm(codebuf, regset, Rstack, PUSH_FD, 1);
+      regset = 0;
+    }
+    regset |= regmask;
+  }
+  stm(codebuf, regset, Rstack, PUSH_FD, 1);
+}
+
+void Thumb2_Pop_Multiple(CodeBuf *codebuf, Reg *regs, unsigned nregs)
+{
+  unsigned regset = 0;
+  unsigned regmask;
+  unsigned i;
+  Reg r;
+
+  JASSERT(nregs > 0, "nregs must be > 0");
+  if (nregs == 1) {
+    ldr_imm(codebuf, regs[0], Rstack, 4, 0, 1);
+    return;
+  }
+  i = nregs;
+  do {
+    i--;
+    r = regs[i];
+    if (!IS_ARM_INT_REG(r)) J_Unimplemented();
+    regmask = 1<<r;
+    if (regmask <= (regset & -regset)) {
+      ldm(codebuf, regset, Rstack, POP_FD, 1);
+      regset = 0;
+    }
+    regset |= regmask;
+  } while (i > 0);
+  ldm(codebuf, regset, Rstack, POP_FD, 1);
+}
+
+#if 0
+int load_multiple(CodeBuf *codebuf, Reg base, Reg *regs, u32 nregs, u32 st, u32 wb)
+{
+  unsigned regset = 0;
+  unsigned regmask;
+  unsigned pre = 0;
+  int dir = 1;
+  unsigned u;
+  Reg r;
+
+  if (st == IB || st == DB) pre = 4;
+  if (st == DA || st == DB) dir = -4;
+  JASSERT(nregs > 0, "nregs must be > 0");
+  if (nregs == 1)
+    return ldr_imm(codebuf, regs[0], base, dir, pre, wb);
+  if (dir > 0) {
+    u = 0;
+    do {
+      r = regs[u];
+      regmask = 1<<r;
+      if (regset != 0 && regmask >= regset) {
+	if (!wb && base != ARM_IP) {
+	  mov_reg(codebuf, ARM_IP, base);
+	  base = ARM_IP;
+	}
+	ldm(codebuf, regset, base, st, 1);
+	regset = 0;
+      }
+      regset |= regmask;
+    } while (++u < nregs);
+    ldm(codebuf, regset, base, st, wb);
+  } else {
+    u = nregs;
+    do {
+      u--;
+      r = regs[u];
+      regmask = 1<<r;
+      if (regmask <= (regset & -regset)) {
+	if (!wb && base != ARM_IP) {
+	  mov_reg(codebuf, ARM_IP, base);
+	  base = ARM_IP;
+	}
+	ldm(codebuf, regset, base, st, 1);
+	regset = 0;
+      }
+      regset |= regmask;
+    } while (u > 0);
+    ldm(codebuf, regset, base, st, wb);
+  }
+}
+#endif
+
+int mov_multiple(CodeBuf *codebuf, Reg *dst, Reg *src, unsigned nregs)
+{
+  unsigned u, n, p;
+  unsigned smask = 0;
+  unsigned dmask = 0;
+  unsigned free_mask, free_reg;
+
+  for (u = 0, n = 0; u < nregs; u++) {
+    JASSERT(dst[u] != ARM_IP, "mov_multiple cannot be used for ARM_IP");
+    JASSERT(src[u] != ARM_IP, "mov_multiple cannot be used for ARM_IP");
+    if (dst[u] != src[u]) {
+      dst[n] = dst[u];
+      src[n++] = src[u];
+    }
+  }
+  while (n) {
+    // Find a reg which is in the dst reg set but not the src reg set
+    smask = 0;
+    dmask = 0;
+    for (u = 0; u < n; u++) {
+      smask |= (1 << src[u]);
+      dmask |= (1 << dst[u]);
+    }
+    free_mask = dmask & ~smask;
+    if (!free_mask) {
+      // No such reg => must use IP
+      Reg r = dst[0];
+      mov_reg(codebuf, ARM_IP, r);
+      for (u = 0; u < n; u++) {
+	if (src[u] == r) src[u] = ARM_IP;
+      }
+      smask ^= (1<<r) | (1<<ARM_IP);
+      free_mask = dmask & ~smask;
+      JASSERT(free_mask, "still no free reg after using ARM_IP?");
+    }
+    free_reg = LOG2(free_mask);
+    for (u = 0, p = 0; u < n; u++) {
+      if (dst[u] == free_reg) {
+	mov_reg(codebuf, dst[u], src[u]);
+      } else {
+	dst[p] = dst[u];
+	src[p++] = src[u];
+      }
+    }
+    n--;
+  }
+  return 0;
+}
+
+#define TOS(jstack)	((jstack)->stack[(jstack)->depth-1])
+#define TOSM1(jstack)	((jstack)->stack[(jstack)->depth-2])
+#define TOSM2(jstack)	((jstack)->stack[(jstack)->depth-3])
+#define TOSM3(jstack)	((jstack)->stack[(jstack)->depth-4])
+
+#define POP(jstack)		((jstack)->stack[--(jstack)->depth])
+#define PUSH(jstack, r)		((jstack)->stack[(jstack)->depth++] = (r))
+#define SWAP(jstack) do { \
+		      Reg r = (jstack)->stack[(jstack)->depth-1]; \
+		      (jstack)->stack[(jstack)->depth-1] = (jstack)->stack[(jstack)->depth-2]; \
+		      (jstack)->stack[(jstack)->depth-2] = r; \
+		    } while (0)
+
+#define JSTACK_REG(jstack)		jstack_reg(jstack)
+#define JSTACK_PREFER(jstack, prefer)	jstack_prefer(jstack, prefer)
+
+static const unsigned last_clear_bit[] = {
+	3,	//	0000
+	3,	//	0001
+	3,	//	0010
+	3,	//	0011
+	3,	//	0100
+	3,	//	0101
+	3,	//	0110
+	3,	//	0111
+	2,	//	1000
+	2,	//	1001
+	2,	//	1010
+	2,	//	1011
+	1,	//	1100
+	1,	//	1101
+	0,	//	1110
+	0,	//	1111
+};
+
+#define LAST_CLEAR_BIT(mask) last_clear_bit[mask]
+
+unsigned jstack_reg(Thumb2_Stack *jstack)
+{
+  unsigned *stack = jstack->stack;
+  unsigned depth = jstack->depth;
+  unsigned mask = 0;
+  unsigned r;
+  unsigned i;
+
+  for (i = 0; i < depth; i++) mask |= 1 << stack[i];
+  mask &= (1 << STACK_REGS) - 1;
+  JASSERT(mask != (1 << STACK_REGS) - 1, "No free reg in push");
+  r = LAST_CLEAR_BIT(mask);
+  return r;
+}
+
+unsigned jstack_prefer(Thumb2_Stack *jstack, Reg prefer)
+{
+  unsigned *stack = jstack->stack;
+  unsigned depth = jstack->depth;
+  unsigned mask = 0;
+  unsigned r;
+  unsigned i;
+
+  for (i = 0; i < depth; i++) mask |= 1 << stack[i];
+  mask &= (1 << STACK_REGS) - 1;
+  if ((prefer & ~mask) & 0x0f) mask |= (~prefer & ((1 << STACK_REGS) - 1));
+  JASSERT(mask != (1 << STACK_REGS) - 1, "No free reg in push");
+  r = LAST_CLEAR_BIT(mask);
+  return r;
+}
+
+void Thumb2_Fill(Thumb2_Info *jinfo, unsigned required)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned *stack = jstack->stack;
+  unsigned depth = jstack->depth;
+  unsigned mask = 0;
+  unsigned tofill;
+  unsigned r, i;
+
+  if (depth >= required) return;
+  tofill = required - depth;
+  for (i = depth; i > 0;) {
+    i--;
+    mask |= 1 << stack[i];
+    stack[i+tofill] = stack[i];
+  }
+  mask &= (1 << STACK_REGS) - 1;
+  for (i = 0; i < tofill; i++) {
+    JASSERT(mask != (1 << STACK_REGS) - 1, "Fill failed!!!");
+    r = LAST_CLEAR_BIT(mask);
+    mask |= (1 << r);
+    stack[i] = r;
+  }
+  jstack->depth = depth + tofill;
+  Thumb2_Pop_Multiple(jinfo->codebuf, stack, tofill);
+}
+
+static const unsigned bitcount[] = {
+	0,	// 0000
+	1,	// 0001
+	1,	// 0010
+	2,	// 0011
+	1,	// 0100
+	2,	// 0101
+	2,	// 0110
+	3,	// 0111
+	1,	// 1000
+	2,	// 1001
+	2,	// 1010
+	3,	// 1011
+	2,	// 1100
+	3,	// 1101
+	3,	// 1110
+	4,	// 1111
+};
+
+#define BITCOUNT(mask) bitcount[mask]
+
+// Thumb2_Spill:-
+// 	required - ensure that at least this many registers are available
+// 	exclude - bitmask, do not count these registers as available
+//
+// 	The no. of available regs (STACK_REGS) less the no. of registers in
+// 	exclude must be >= the number required, otherwise this function loops!
+//
+// 	Typical usage is
+//
+// 	Thumb2_Spill(jinfo, 2, 0);	// get 2 free regs
+// 	r_res_lo = PUSH(jinfo->jstack, JSTACK_REG(jinfo->jstack));
+// 	r_res_hi = PUSH(jinfo->jstack, JSTACK_REG(jinfo->jstack));
+//
+//	Use the exclude mask when you do not want a subsequent call to
+//	JSTACK_REG to return a particular register or registers. This can
+//	be useful, for example, with long (64) bit operations. Eg. In the
+//	following we use it to ensure that the hi inputs are not clobbered
+//	by the lo result as part of the intermediate calculation.
+//
+//	Thumb2_Fill(jinfo, 4);
+//	exclude = (1<<rho_hi)|(1<<lho_hi);
+//	rho_lo = POP(jstack);
+//	rho_hi = POP(jstack);
+//	lho_lo = POP(jstack);
+//	lho_hi = POP(jstack);
+//	Thumb2_Spill(jinfo, 2, exclude);
+//	res_hi = PUSH(jstack, JSTACK_PREFER(jstack, ~exclude));	// != rho_hi or lho_hi
+//	res_lo = PUSH(jstack, JSTACK_PREFER(jstack, ~exclude));	// != rho_hi or lho_hi
+//	dop_reg(jinfo->codebuf, DP_ADD, res_lo, lho_lo, rho_lo, SHIFT_LSL, 0); 
+//	dop_reg(jinfo->codebuf, DP_ADC, res_hi, lho_hi, rho_hi, SHIFT_LSL, 0);
+//	
+void Thumb2_Spill(Thumb2_Info *jinfo, unsigned required, unsigned exclude)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned *stack = jstack->stack;
+  unsigned depth = jstack->depth;
+  unsigned mask;
+  unsigned i;
+  unsigned tospill = 0;
+
+  exclude &= (1 << STACK_REGS) - 1;
+  if (depth <= (STACK_REGS - required) && exclude == 0) return;
+  while (1) {
+    mask = 0;
+    for (i = tospill; i < depth; i++) mask |= 1 << stack[i];
+    mask &= ((1 << STACK_REGS) - 1);
+    mask |= exclude;
+    if (STACK_REGS - BITCOUNT(mask) >= required) break;
+    tospill++;
+  }
+  if (tospill == 0) return;
+  Thumb2_Push_Multiple(jinfo->codebuf, stack, tospill);
+  for (i = tospill; i < depth; i++)
+    stack[i-tospill] = stack[i];
+  jstack->depth = depth - tospill;
+  JASSERT((int)jstack->depth >= 0, "Stack underflow");
+}
+
+// Thumb2_Tmp:-
+// 	Allocate a temp reg for use in local code generation.
+// 	exclude is a bit mask of regs not to use.
+// 	A max of 2 regs can be guaranteed (ARM_IP & ARM_LR)
+// 	If allocating 2 regs you must include the reg you got the
+// 	first time in the exclude list. Otherwise you just get
+// 	the same reg again.
+Reg Thumb2_Tmp(Thumb2_Info *jinfo, unsigned exclude)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned *stack = jstack->stack;
+  unsigned depth = jstack->depth;
+  unsigned mask;
+  unsigned i;
+
+  mask = 0;
+  for (i = 0; i < depth; i++) mask |= 1 << stack[i];
+  mask |= exclude;
+  for (i = 0; i < STACK_REGS; i++)
+    if ((mask & (1<<i)) == 0) return i;
+  if ((mask & (1<<ARM_IP)) == 0) return ARM_IP;
+  if ((mask & (1<<ARM_LR)) == 0) return ARM_LR;
+  JASSERT(0, "failed to allocate a tmp reg");
+}
+
+void Thumb2_Flush(Thumb2_Info *jinfo)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+
+  if (jstack->depth > 0)
+    Thumb2_Push_Multiple(jinfo->codebuf, jstack->stack, jstack->depth);
+  jstack->depth = 0;
+}
+
+// Call this when we are about to corrupt a local
+// The local may already be on the stack
+// For example
+// 	iload	0
+// 	iconst	2
+// 	istore	0
+// 	istore	1
+// Without this check the code generated would be (r4 is local 0, r5 is local 1)
+// 	mov	r4, #2
+//	mov	r5, r4
+// With this check the code should be
+// 	mov	r3, r4
+// 	mov	r4, #2
+// 	mov	r5, r3
+// This is not ideal, but is better than the previous:-)
+//
+void Thumb2_Corrupt(Thumb2_Info *jinfo, unsigned r, unsigned ignore)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned *stack = jstack->stack;
+  unsigned depth = jstack->depth;
+  unsigned r_new, mask;
+  unsigned i;
+
+  if (ignore >= depth) return;
+//  JASSERT(depth >= ignore, "Cant ignore more than the whole stack!!");
+  if (IS_SREG(r)) return;
+  depth -= ignore;
+  for (i = 0; i < depth; i++) {
+    if (r == stack[i]) {
+      Thumb2_Spill(jinfo, 1, 0);
+      depth = jstack->depth - ignore;
+      r_new = JSTACK_REG(jstack);
+      mov_reg(jinfo->codebuf, r_new, r);
+      for (i = 0; i < depth; i++) if (r == stack[i]) stack[i] = r_new;
+      break;
+    }
+  }
+}
+
+unsigned Thumb2_ResultLocal(Thumb2_Info *jinfo, unsigned bci)
+{
+  unsigned opc = jinfo->code_base[bci];
+  if (jinfo->bc_stackinfo[bci] & BC_BRANCH_TARGET) return 0;
+  if (opc < opc_istore || opc > opc_astore_3) return 0;
+  if (opc == opc_istore || opc == opc_fstore || opc == opc_astore)
+    return jinfo->jregs->r_local[jinfo->code_base[bci+1]];
+  if ((opc >= opc_istore_0 && opc <= opc_istore_3) ||
+	(opc >= opc_fstore_0 && opc <= opc_fstore_3) ||
+	(opc >= opc_astore_0 && opc <= opc_astore_3))
+    return jinfo->jregs->r_local[(opc-opc_istore_0)&3];
+  return 0;
+}
+
+static const unsigned char dOps[] = {
+	DP_ADD, DP_ADC, VP_ADD, VP_ADD,
+	DP_SUB, DP_SBC, VP_SUB, VP_SUB,
+	DP_MUL, 0, VP_MUL, VP_MUL,
+	0, 0, VP_DIV, VP_DIV,
+	0, 0, 0, 0,
+	0, 0, 0, 0,
+	DP_LSL, 0,
+	DP_ASR, 0,
+	DP_LSR, 0,
+	DP_AND, DP_AND, DP_ORR, DP_ORR, DP_EOR, DP_EOR,
+};
+
+unsigned Thumb2_Imm(Thumb2_Info *jinfo, unsigned imm, unsigned next_bci)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r;
+  unsigned next_op;
+
+  if (!(jinfo->bc_stackinfo[next_bci] & BC_BRANCH_TARGET)) {
+    next_op = jinfo->code_base[next_bci];
+    if (next_op > OPC_LAST_JAVA_OP) {
+      if (Bytecodes::is_defined((Bytecodes::Code)next_op))
+	next_op = (unsigned)Bytecodes::java_code((Bytecodes::Code)next_op);
+    }
+    switch (next_op) {
+      case opc_istore:
+      case opc_fstore:
+      case opc_astore: {
+	unsigned local = jinfo->code_base[next_bci+1];
+	r = jinfo->jregs->r_local[local];
+	if (r) {
+	  Thumb2_Corrupt(jinfo, r, 0);
+	  mov_imm(jinfo->codebuf, r, imm);
+	  return 2;
+	}
+	break;
+      }
+      case opc_istore_0:
+      case opc_istore_1:
+      case opc_istore_2:
+      case opc_istore_3:
+      case opc_fstore_0:
+      case opc_fstore_1:
+      case opc_fstore_2:
+      case opc_fstore_3:
+      case opc_astore_0:
+      case opc_astore_1:
+      case opc_astore_2:
+      case opc_astore_3: {
+	unsigned local = (jinfo->code_base[next_bci]-opc_istore_0) & 3;
+	r = jinfo->jregs->r_local[local];
+	if (r) {
+	  Thumb2_Corrupt(jinfo, r, 0);
+	  mov_imm(jinfo->codebuf, r, imm);
+	  return 1;
+	}
+	break;
+      }
+      case opc_iadd:
+      case opc_isub:
+      case opc_ishl:
+      case opc_ishr:
+      case opc_iushr:
+      case opc_iand:
+      case opc_ior:
+      case opc_ixor: {
+	unsigned len = 0;
+	unsigned r_lho;
+
+	Thumb2_Fill(jinfo, 1);
+	r_lho = POP(jstack);
+
+	r = Thumb2_ResultLocal(jinfo, next_bci+1);
+	if (r) {
+	  Thumb2_Corrupt(jinfo, r, 0);
+	  len = Bytecodes::length_for((Bytecodes::Code)jinfo->code_base[next_bci+1]);
+	} else {
+	  Thumb2_Spill(jinfo, 1, 0);
+	  r = JSTACK_REG(jstack);
+	  PUSH(jstack, r);
+	}
+	if (next_op == opc_ishl || next_op == opc_ishr || next_op == opc_iushr)
+	  shift_imm(jinfo->codebuf, dOps[next_op-opc_iadd], r, r_lho, imm);
+	else
+	  dop_imm(jinfo->codebuf, dOps[next_op-opc_iadd], r, r_lho, imm);
+	return 1+len;
+      }
+
+      case opc_idiv: {
+	unsigned len = 0;
+	unsigned r_lho;
+	unsigned abs_imm = abs((int)imm);
+
+	if ((imm & -imm) == abs_imm) {
+	  unsigned l2_imm = LOG2(abs_imm);
+	  unsigned r_lho;
+
+	  if (imm == 0) break;
+	  if (imm == 1) return 1;
+
+	  Thumb2_Fill(jinfo, 1);
+	  r_lho = POP(jstack);
+
+	  r = Thumb2_ResultLocal(jinfo, next_bci+1);
+	  if (r) {
+	    Thumb2_Corrupt(jinfo, r, 0);
+	    len = Bytecodes::length_for((Bytecodes::Code)jinfo->code_base[next_bci+1]);
+	  } else {
+	    Thumb2_Spill(jinfo, 1, 0);
+	    r = JSTACK_REG(jstack);
+	    PUSH(jstack, r);
+	  }
+
+	  if (abs_imm != 1) {
+	    unsigned r_tmp = r_lho;
+	    if (abs_imm != 2) {
+	      r_tmp = Thumb2_Tmp(jinfo, (1<<r_lho));
+	      asr_imm(jinfo->codebuf, r_tmp, r_lho, 31);
+	    }
+	    add_reg_shift(jinfo->codebuf, r, r_lho, r_tmp, SHIFT_LSR, 32-l2_imm);
+	    asr_imm(jinfo->codebuf, r, r, l2_imm);
+	  }
+	  if ((int)imm < 0)
+	    rsb_imm(jinfo->codebuf, r, r, 0);
+	  return 1+len;
+	}
+	break;
+      }
+    }
+  }
+  Thumb2_Spill(jinfo, 1, 0);
+  r = JSTACK_REG(jstack);
+  PUSH(jstack, r);
+  mov_imm(jinfo->codebuf, r, imm);
+  return 0;
+}
+
+void Thumb2_ImmX2(Thumb2_Info *jinfo, unsigned lo, unsigned hi)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_lo, r_hi;
+
+  Thumb2_Spill(jinfo, 2, 0);
+  r_hi = PUSH(jstack, JSTACK_REG(jstack));
+  r_lo = PUSH(jstack, JSTACK_REG(jstack));
+  mov_imm(jinfo->codebuf, r_lo, lo);
+  mov_imm(jinfo->codebuf, r_hi, hi);
+}
+
+#define LOCAL_OFFSET(local, stackdepth, nlocals) ((stackdepth)*4 + FRAME_SIZE + ((nlocals)-1-(local))*4)
+
+void load_local(Thumb2_Info *jinfo, Reg r, unsigned local, unsigned stackdepth)
+{
+#ifdef USE_RLOCAL
+  ldr_imm(jinfo->codebuf, r, Rlocals, -local * 4, 1, 0);
+#else
+  int nlocals = jinfo->method->max_locals();
+  ldr_imm(jinfo->codebuf, r, Rstack, LOCAL_OFFSET(local, stackdepth, nlocals), 1, 0);
+#endif
+}
+
+void store_local(Thumb2_Info *jinfo, Reg r, unsigned local, unsigned stackdepth)
+{
+#ifdef USE_RLOCAL
+  str_imm(jinfo->codebuf, r, Rlocals, -local << 2, 1, 0);
+#else
+  int nlocals = jinfo->method->max_locals();
+  str_imm(jinfo->codebuf, r, Rstack, LOCAL_OFFSET(local, stackdepth, nlocals), 1, 0);
+#endif
+}
+
+void Thumb2_Load(Thumb2_Info *jinfo, int local, unsigned stackdepth)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r;
+
+  r = jinfo->jregs->r_local[local];
+  if (r) {
+    PUSH(jstack, r);
+  } else {
+    int nlocals = jinfo->method->max_locals();
+
+    Thumb2_Spill(jinfo, 1, 0);
+    JASSERT(stackdepth >= jstack->depth, "negative stack offset?");
+    stackdepth -= jstack->depth;
+    if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+    r = JSTACK_REG(jstack);
+    PUSH(jstack, r);
+    load_local(jinfo, r, local, stackdepth);
+  }
+}
+
+void Thumb2_LoadX2(Thumb2_Info *jinfo, int local, unsigned stackdepth)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_lo, r_hi;
+  int nlocals = jinfo->method->max_locals();
+
+  r_hi = jinfo->jregs->r_local[local];
+  if (r_hi) {
+    r_lo = jinfo->jregs->r_local[local+1];
+    if (r_lo) {
+      PUSH(jstack, r_hi);
+      PUSH(jstack, r_lo);
+    } else {
+      Thumb2_Spill(jinfo, 1, 0);
+      stackdepth -= jstack->depth;
+      if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+      PUSH(jstack, r_hi);
+      r_lo = PUSH(jstack, JSTACK_REG(jstack));
+      load_local(jinfo, r_lo, local+1, stackdepth);
+    }
+  } else {
+    r_lo = jinfo->jregs->r_local[local+1];
+    if (r_lo) {
+      Thumb2_Spill(jinfo, 1, 0);
+      stackdepth -= jstack->depth;
+      if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+      r_hi = PUSH(jstack, JSTACK_REG(jstack));
+      load_local(jinfo, r_hi, local, stackdepth);
+      PUSH(jstack, r_lo);
+    } else {
+      Thumb2_Spill(jinfo, 2, 0);
+      stackdepth -= jstack->depth;
+      if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+      r_hi = PUSH(jstack, JSTACK_REG(jstack));
+      r_lo = PUSH(jstack, JSTACK_REG(jstack));
+      load_local(jinfo, r_hi, local, stackdepth);
+      load_local(jinfo, r_lo, local+1, stackdepth);
+    }
+  }
+}
+
+void Thumb2_Store(Thumb2_Info *jinfo, int local, unsigned stackdepth)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r, r_local;
+  int nlocals = jinfo->method->max_locals();
+
+  Thumb2_Fill(jinfo, 1);
+  stackdepth -= jstack->depth;
+  if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+  r = POP(jstack);
+  r_local = jinfo->jregs->r_local[local];
+  if (r_local) {
+    Thumb2_Corrupt(jinfo, r_local, 0);
+    mov_reg(jinfo->codebuf, r_local, r);
+  } else {
+    store_local(jinfo, r, local, stackdepth);
+  }
+}
+
+void Thumb2_StoreX2(Thumb2_Info *jinfo, int local, unsigned stackdepth)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_lo, r_hi;
+  unsigned r_local_lo, r_local_hi;
+  int nlocals = jinfo->method->max_locals();
+
+  Thumb2_Fill(jinfo, 2);
+  if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+  r_lo = POP(jstack);
+  r_hi = POP(jstack);
+  stackdepth -= 2;
+
+  r_local_hi = jinfo->jregs->r_local[local];
+  if (r_local_hi) {
+    Thumb2_Corrupt(jinfo, r_local_hi, 0);
+    mov_reg(jinfo->codebuf, r_local_hi, r_hi);
+  } else {
+    store_local(jinfo, r_hi, local, stackdepth-jstack->depth);
+  }
+
+  r_local_lo = jinfo->jregs->r_local[local+1];
+  if (r_local_lo) {
+    Thumb2_Corrupt(jinfo, r_local_lo, 0);
+    mov_reg(jinfo->codebuf, r_local_lo, r_lo);
+  } else {
+    store_local(jinfo, r_lo, local+1, stackdepth-jstack->depth);
+  }
+}
+
+void Thumb2_Xaload(Thumb2_Info *jinfo, u32 opc)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_index, r_array, r_value;
+  unsigned op = opc - (unsigned)opc_iaload;
+  unsigned r_tmp;
+
+  Thumb2_Fill(jinfo, 2);
+  r_index = POP(jstack);
+  r_array = POP(jstack);
+  Thumb2_Spill(jinfo, 1, 0);
+  r_tmp = Thumb2_Tmp(jinfo, (1<<r_array)|(1<<r_index));
+  r_value = JSTACK_REG(jstack);
+  PUSH(jstack, r_value);
+  ldr_imm(jinfo->codebuf, r_tmp, r_array, 8, 1, 0);
+  chka(jinfo->codebuf, r_tmp, r_index);
+  if (opc == opc_baload) {
+    add_reg(jinfo->codebuf, r_tmp, r_array, r_index);
+    ldrsb_imm(jinfo->codebuf, r_value, r_tmp, 12, 1, 0);
+  } else if (opc == opc_caload) {
+    add_reg_shift(jinfo->codebuf, r_tmp, r_array, r_index, SHIFT_LSL, 1);
+    ldrh_imm(jinfo->codebuf, r_value, r_tmp, 12, 1, 0);
+  } else if (opc == opc_saload) {
+    add_reg_shift(jinfo->codebuf, r_tmp, r_array, r_index, SHIFT_LSL, 1);
+    ldrsh_imm(jinfo->codebuf, r_value, r_tmp, 12, 1, 0);
+  } else {
+    add_reg_shift(jinfo->codebuf, r_tmp, r_array, r_index, SHIFT_LSL, 2);
+    ldr_imm(jinfo->codebuf, r_value, r_tmp, 12, 1, 0);
+  }
+}
+
+void Thumb2_X2aload(Thumb2_Info *jinfo)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_index, r_array, r_lo, r_hi;
+  unsigned r_tmp;
+
+  Thumb2_Fill(jinfo, 2);
+  r_index = POP(jstack);
+  r_array = POP(jstack);
+  Thumb2_Spill(jinfo, 2, 0);
+  r_tmp = Thumb2_Tmp(jinfo, (1<<r_array)|(1<<r_index));
+  r_hi = PUSH(jstack, JSTACK_REG(jstack));
+  r_lo = PUSH(jstack, JSTACK_REG(jstack));
+  ldr_imm(jinfo->codebuf, r_tmp, r_array, 8, 1, 0);
+  chka(jinfo->codebuf, r_tmp, r_index);
+  add_reg_shift(jinfo->codebuf, r_tmp, r_array, r_index, SHIFT_LSL, 3);
+  ldrd_imm(jinfo->codebuf, r_lo, r_hi, r_tmp, 16, 1, 0);
+}
+
+void Thumb2_Xastore(Thumb2_Info *jinfo, u32 opc)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_value, r_index, r_array;
+  unsigned op = opc - (unsigned)opc_iastore;
+  unsigned r_tmp;
+
+  Thumb2_Fill(jinfo, 3);
+  r_value = POP(jstack);
+  r_index = POP(jstack);
+  r_array = POP(jstack);
+  r_tmp = Thumb2_Tmp(jinfo, (1<<r_array)|(1<<r_index)|(1<<r_value));
+  ldr_imm(jinfo->codebuf, r_tmp, r_array, 8, 1, 0);
+  chka(jinfo->codebuf, r_tmp, r_index);
+  if (opc == opc_bastore) {
+    add_reg(jinfo->codebuf, r_tmp, r_array, r_index);
+    strb_imm(jinfo->codebuf, r_value, r_tmp, 12, 1, 0);
+  } else if (opc == opc_castore || opc == opc_sastore) {
+    add_reg_shift(jinfo->codebuf, r_tmp, r_array, r_index, SHIFT_LSL, 1);
+    strh_imm(jinfo->codebuf, r_value, r_tmp, 12, 1, 0);
+  } else {
+    add_reg_shift(jinfo->codebuf, r_tmp, r_array, r_index, SHIFT_LSL, 2);
+    str_imm(jinfo->codebuf, r_value, r_tmp, 12, 1, 0);
+  }
+}
+
+void Thumb2_X2astore(Thumb2_Info *jinfo)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_lo, r_hi, r_index, r_array;
+  unsigned r_tmp;
+
+  Thumb2_Fill(jinfo, 4);
+  r_lo = POP(jstack);
+  r_hi = POP(jstack);
+  r_index = POP(jstack);
+  r_array = POP(jstack);
+  r_tmp = Thumb2_Tmp(jinfo, (1<<r_array)|(1<<r_index)|(1<<r_lo)|(1<<r_hi));
+  ldr_imm(jinfo->codebuf, r_tmp, r_array, 8, 1, 0);
+  chka(jinfo->codebuf, r_tmp, r_index);
+  add_reg_shift(jinfo->codebuf, r_tmp, r_array, r_index, SHIFT_LSL, 3);
+  strd_imm(jinfo->codebuf, r_lo, r_hi, r_tmp, 16, 1, 0);
+}
+
+void Thumb2_Pop(Thumb2_Info *jinfo, unsigned n)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+
+  while (n > 0 && jstack->depth > 0) {
+    POP(jstack);
+    n--;
+  }
+  if (n > 0) add_imm(jinfo->codebuf, Rstack, Rstack, n * 4);
+}
+
+void Thumb2_Dup(Thumb2_Info *jinfo, unsigned n)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned *stack = jstack->stack;
+  unsigned depth;
+  unsigned i;
+
+  Thumb2_Fill(jinfo, n+1);
+  depth = jstack->depth;
+  for (i = 0; i <= n; i++)
+    stack[depth-i] = stack[depth-i-1];
+  stack[depth-n-1] = stack[depth];
+  jstack->depth = depth + 1;
+}
+
+void Thumb2_Dup2(Thumb2_Info *jinfo, unsigned n)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned *stack = jstack->stack;
+  unsigned depth;
+  unsigned i;
+
+  Thumb2_Fill(jinfo, n+2);
+  depth = jstack->depth;
+  for (i = 0; i <= n+1; i++)
+    stack[depth-i+1] = stack[depth-i-1];
+  stack[depth-n-1] = stack[depth+1];
+  stack[depth-n-2] = stack[depth];
+  jstack->depth = depth + 2;
+}
+
+void Thumb2_Swap(Thumb2_Info *jinfo)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+
+  Thumb2_Fill(jinfo, 2);
+  SWAP(jstack);
+}
+
+void Thumb2_iOp(Thumb2_Info *jinfo, u32 opc)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_lho, r_rho, r;
+
+  Thumb2_Fill(jinfo, 2);
+  r_rho = POP(jstack);
+  r_lho = POP(jstack);
+  Thumb2_Spill(jinfo, 1, 0);
+  r = JSTACK_REG(jstack);
+  PUSH(jstack, r);
+  dop_reg(jinfo->codebuf, dOps[opc-opc_iadd], r, r_lho, r_rho, 0, 0);
+}
+
+void Thumb2_iNeg(Thumb2_Info *jinfo, u32 opc)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_src, r;
+
+  Thumb2_Fill(jinfo, 1);
+  r_src = POP(jstack);
+  Thumb2_Spill(jinfo, 1, 0);
+  r = JSTACK_REG(jstack);
+  PUSH(jstack, r);
+  rsb_imm(jinfo->codebuf, r, r_src, 0);
+}
+
+void Thumb2_lNeg(Thumb2_Info *jinfo, u32 opc)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_lo, r_hi, r_res_lo, r_res_hi;
+  unsigned r_tmp;
+
+  Thumb2_Fill(jinfo, 2);
+  r_lo = POP(jstack);
+  r_hi = POP(jstack);
+  Thumb2_Spill(jinfo, 1, 0);
+  r_res_hi = PUSH(jstack, JSTACK_REG(jstack));
+  Thumb2_Spill(jinfo, 1, (1<<r_hi));
+  r_res_lo = PUSH(jstack, JSTACK_PREFER(jstack, ~(1<<r_hi)));
+  JASSERT(r_res_lo != r_res_hi, "oops");
+  JASSERT(r_res_lo != r_hi, "r_res_lo != r_hi");
+  rsb_imm(jinfo->codebuf, r_res_lo, r_lo, 0);
+  r_tmp = Thumb2_Tmp(jinfo, (1<<r_hi)|(1<<r_res_lo));
+  mov_imm(jinfo->codebuf, r_tmp, 0);
+  dop_reg(jinfo->codebuf, DP_SBC, r_res_hi, r_tmp, r_hi, SHIFT_LSL, 0);
+}
+
+void Thumb2_fNeg(Thumb2_Info *jinfo, u32 opc)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r, r_result;
+
+  Thumb2_Fill(jinfo, 1);
+  r = POP(jstack);
+  Thumb2_Spill(jinfo, 1, 0);
+  r_result = PUSH(jstack, JSTACK_REG(jstack));
+  eor_imm(jinfo->codebuf, r_result, r, 0x80000000);
+}
+
+void Thumb2_dNeg(Thumb2_Info *jinfo, u32 opc)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned r_lo, r_hi, r_res_lo, r_res_hi;
+
+  Thumb2_Fill(jinfo, 2);
+  r_lo = POP(jstack);
+  r_hi = POP(jstack);
+  Thumb2_Spill(jinfo, 1, 0);
+  r_res_hi = PUSH(jstack, JSTACK_REG(jstack));
+  Thumb2_Spill(jinfo, 1, (1<<r_hi));
+  r_res_lo = PUSH(jstack, JSTACK_PREFER(jstack, ~(1<<r_hi)));
+  JASSERT(r_res_lo != r_res_hi, "oops");
+  JASSERT(r_res_lo != r_hi, "r_res_lo != r_hi");
+  mov_reg(jinfo->codebuf, r_res_lo, r_lo);
+  eor_imm(jinfo->codebuf, r_res_hi, r_hi, 0x80000000);
+}
+
+void Thumb2_lOp(Thumb2_Info *jinfo, u32 opc)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned res_lo, res_hi;
+  unsigned lho_lo, lho_hi;
+  unsigned rho_lo, rho_hi;
+
+  Thumb2_Fill(jinfo, 4);
+  rho_lo = POP(jstack);
+  rho_hi = POP(jstack);
+  lho_lo = POP(jstack);
+  lho_hi = POP(jstack);
+  Thumb2_Spill(jinfo, 1, 0);
+  res_hi = PUSH(jstack, JSTACK_REG(jstack));
+  Thumb2_Spill(jinfo, 1, (1<<lho_hi)|(1<<rho_hi));
+  res_lo = PUSH(jstack, JSTACK_PREFER(jstack, ~((1<<lho_hi)|(1<<rho_hi))));
+  JASSERT(res_lo != rho_hi && res_lo != lho_hi, "res_lo != rho_hi && res_lo != lho_hi");
+  dop_reg(jinfo->codebuf, dOps[opc-opc_ladd], res_lo, lho_lo, rho_lo, SHIFT_LSL, 0);
+  dop_reg(jinfo->codebuf, dOps[opc-opc_ladd+1], res_hi, lho_hi, rho_hi, SHIFT_LSL, 0);
+}
+
+void Thumb2_lmul(Thumb2_Info *jinfo)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned res_lo, res_hi;
+  unsigned lho_lo, lho_hi;
+  unsigned rho_lo, rho_hi;
+  unsigned r_tmp_lo, r_tmp_hi;
+  unsigned op_mask;
+
+  Thumb2_Fill(jinfo, 4);
+  rho_lo = POP(jstack);
+  rho_hi = POP(jstack);
+  lho_lo = POP(jstack);
+  lho_hi = POP(jstack);
+  op_mask = (1<<rho_lo)|(1<<rho_hi)|(1<<lho_lo)|(1<<lho_hi);
+  Thumb2_Spill(jinfo, 2, 0);
+  res_hi = PUSH(jstack, JSTACK_PREFER(jstack, ~op_mask));
+  res_lo = PUSH(jstack, JSTACK_PREFER(jstack, ~op_mask));
+  r_tmp_lo = res_lo;
+  r_tmp_hi = res_hi;
+  if (op_mask & (1<<r_tmp_lo)) r_tmp_lo = Thumb2_Tmp(jinfo, op_mask);
+  if (op_mask & (1<<r_tmp_hi)) r_tmp_hi = Thumb2_Tmp(jinfo, op_mask|(1<<r_tmp_lo));
+  umull(jinfo->codebuf, r_tmp_lo, r_tmp_hi, rho_lo, lho_lo);
+  mla(jinfo->codebuf, r_tmp_hi, rho_lo, lho_hi, r_tmp_hi);
+  mla(jinfo->codebuf, res_hi, rho_hi, lho_lo, r_tmp_hi);
+  mov_reg(jinfo->codebuf, res_lo, r_tmp_lo);
+}
+
+void Thumb2_fOp(Thumb2_Info *jinfo, u32 opc)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned rho, lho, res;
+
+  Thumb2_Fill(jinfo, 2);
+  rho = POP(jstack);
+  lho = POP(jstack);
+  Thumb2_Spill(jinfo, 1, 0);
+  res = PUSH(jstack, JSTACK_REG(jstack));
+  vmov_reg_s_toVFP(jinfo->codebuf, VFP_S0, lho);
+  vmov_reg_s_toVFP(jinfo->codebuf, VFP_S1, rho);
+  vop_reg_s(jinfo->codebuf, dOps[opc-opc_iadd], VFP_S0, VFP_S0, VFP_S1);
+  vmov_reg_s_toARM(jinfo->codebuf, res, VFP_S0);
+}
+
+void Thumb2_dOp(Thumb2_Info *jinfo, u32 opc)
+{
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned rho_lo, rho_hi, lho_lo, lho_hi, res_lo, res_hi;
+
+  Thumb2_Fill(jinfo, 4);
+  rho_lo = POP(jstack);
+  rho_hi = POP(jstack);
+  lho_lo = POP(jstack);
+  lho_hi = POP(jstack);
+  Thumb2_Spill(jinfo, 2, 0);
+  res_hi = PUSH(jstack, JSTACK_REG(jstack));
+  res_lo = PUSH(jstack, JSTACK_REG(jstack));
+  vmov_reg_d_toVFP(jinfo->codebuf, VFP_D0, lho_lo, lho_hi);
+  vmov_reg_d_toVFP(jinfo->codebuf, VFP_D1, rho_lo, rho_hi);
+  vop_reg_d(jinfo->codebuf, dOps[opc-opc_iadd], VFP_D0, VFP_D0, VFP_D1);
+  vmov_reg_d_toARM(jinfo->codebuf, res_lo, res_hi, VFP_D0);
+}
+
+void Thumb2_Handler(Thumb2_Info *jinfo, unsigned handler, unsigned opcode, unsigned bci)
+{
+  mov_imm(jinfo->codebuf, ARM_R0, opcode);
+  mov_imm(jinfo->codebuf, ARM_R1, bci);
+  mov_imm(jinfo->codebuf, ARM_IP, 0);
+  str_imm(jinfo->codebuf, ARM_IP, ARM_IP, 0, 1, 0);
+//  hbl(jinfo->codebuf, handler);
+}
+
+void Thumb2_Debug(Thumb2_Info *jinfo, unsigned handler)
+{
+#if 0
+  Thumb2_Flush(jinfo);
+  bl(jinfo->codebuf, handlers[handler]);
+#endif
+}
+
+void Thumb2_codegen(Thumb2_Info *jinfo, unsigned start);
+
+int Thumb2_Branch(Thumb2_Info *jinfo, unsigned bci, unsigned cond)
+{
+    int offset = GET_JAVA_S2(jinfo->code_base + bci + 1);
+    unsigned dest_taken = bci + offset;
+    unsigned dest_not_taken = bci + 3;
+    unsigned loc;
+
+    if (jinfo->bc_stackinfo[dest_taken] & BC_COMPILED) {
+      branch(jinfo->codebuf, cond, jinfo->bc_stackinfo[dest_taken] & ~BC_FLAGS_MASK);
+      return dest_not_taken;
+    }
+    loc = forward_32(jinfo->codebuf);
+    Thumb2_codegen(jinfo, dest_not_taken);
+    JASSERT(jinfo->bc_stackinfo[dest_taken] & BC_COMPILED, "dest in branch not compiled!!!");
+    branch_patch(jinfo->codebuf, cond, loc, jinfo->bc_stackinfo[dest_taken] & ~BC_FLAGS_MASK);
+    return -1;
+}
+
+int Thumb2_Goto(Thumb2_Info *jinfo, unsigned bci, int offset, int len)
+{
+    unsigned dest_taken = bci + offset;
+    unsigned dest_not_taken = bci + len;
+    unsigned loc;
+
+    if (jinfo->bc_stackinfo[dest_taken] & BC_COMPILED) {
+      branch_uncond(jinfo->codebuf, jinfo->bc_stackinfo[dest_taken] & ~BC_FLAGS_MASK);
+      return dest_not_taken;
+    }
+    loc = forward_32(jinfo->codebuf);
+    Thumb2_codegen(jinfo, dest_not_taken);
+    JASSERT(jinfo->bc_stackinfo[dest_taken] & BC_COMPILED, "dest in goto not compiled!!!");
+    branch_uncond_patch(jinfo->codebuf, loc, jinfo->bc_stackinfo[dest_taken] & ~BC_FLAGS_MASK);
+    return -1;
+}
+
+void Thumb2_Return(Thumb2_Info *jinfo, unsigned opcode)
+{
+  Reg r_lo, r;
+  Thumb2_Stack *jstack = jinfo->jstack;
+
+  if (0 /*jinfo->compiled_return*/) {
+    unsigned bci = jinfo->compiled_return;
+
+    JASSERT(jinfo->bc_stackinfo[bci] & BC_COMPILED, "return not compiled");
+    JASSERT(jinfo->code_base[bci] == opcode, "type of return changed");
+    branch_uncond(jinfo->codebuf, jinfo->bc_stackinfo[bci] & ~BC_FLAGS_MASK);
+    return;
+  }
+
+  if (jinfo->method->is_synchronized()) {
+    unsigned loc_success1, loc_success2, loc_failed, loc_retry, loc_exception;
+    unsigned loc_illegal_monitor_state;
+    Thumb2_Flush(jinfo);
+//    Thumb2_save_locals(jinfo);
+    // Free the monitor
+    //
+    // 		sub	r1, Ristate, #8
+    // 		ldr	r2, [r1, #4]
+    //		cbz	r2, throw_illegal_monitor_state
+    //		ldr	r0, [r1, #0]
+    //		mov	r3, #0
+    //		str	r3, [r1, #4]
+    //		cbz	r0, success
+    //	retry:
+    //		ldrex	r3, [r2, #0]
+    //		cmp	r1, r3
+    //		bne	failed
+    //		strex	r3, r0, [r2, #0]
+    //		cbz	r3, success
+    //		b	retry
+    //	failed:
+    //		str	r2, [r1, #4]
+    //		...
+    //  success:
+    //
+    // JAZ_V1 == tmp2
+    // JAZ_V2 == tmp1
+    sub_imm(jinfo->codebuf, ARM_R1, Ristate, frame::interpreter_frame_monitor_size()*wordSize);
+    ldr_imm(jinfo->codebuf, ARM_R2, ARM_R1, 4, 1, 0);
+    loc_illegal_monitor_state = forward_16(jinfo->codebuf);
+    ldr_imm(jinfo->codebuf, ARM_R0, ARM_R1, 0, 1, 0);
+    mov_imm(jinfo->codebuf, ARM_R3, 0);
+    str_imm(jinfo->codebuf, ARM_R3, ARM_R1, 4, 1, 0);
+    loc_success1 = forward_16(jinfo->codebuf);
+    loc_retry = out_loc(jinfo->codebuf);
+    ldrex_imm(jinfo->codebuf, ARM_R3, ARM_R2, 0);
+    cmp_reg(jinfo->codebuf, ARM_R1, ARM_R3);
+    loc_failed = forward_16(jinfo->codebuf);
+    strex_imm(jinfo->codebuf, ARM_R3, ARM_R0, ARM_R2, 0);
+    loc_success2 = forward_16(jinfo->codebuf);
+    branch_uncond(jinfo->codebuf, loc_retry);
+    bcc_patch(jinfo->codebuf, COND_NE, loc_failed);
+    cbz_patch(jinfo->codebuf, ARM_R2, loc_illegal_monitor_state);
+    str_imm(jinfo->codebuf, ARM_R2, ARM_R1, 4, 1, 0);
+    mov_imm(jinfo->codebuf, ARM_R0, 0+CONSTMETHOD_CODEOFFSET);
+    bl(jinfo->codebuf, handlers[H_SYNCHRONIZED_EXIT]);
+    loc_exception = forward_16(jinfo->codebuf);
+    bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+    cbz_patch(jinfo->codebuf, ARM_R0, loc_exception);
+    cbz_patch(jinfo->codebuf, ARM_R0, loc_success1);
+    cbz_patch(jinfo->codebuf, ARM_R3, loc_success2);
+  }
+
+  if (opcode != opc_return) {
+    if (opcode == opc_lreturn || opcode == opc_dreturn) {
+      Thumb2_Fill(jinfo, 2);
+      r_lo = POP(jstack);
+      r = POP(jstack);
+    } else {
+      Thumb2_Fill(jinfo, 1);
+      r = POP(jstack);
+    }
+  }
+
+  mov_imm(jinfo->codebuf, ARM_LR, 0);
+  str_imm(jinfo->codebuf, ARM_LR, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+  ldr_imm(jinfo->codebuf, Rstack, Rthread, THREAD_TOP_ZERO_FRAME, 1, 0);
+  ldr_imm(jinfo->codebuf, ARM_LR, Rstack, 0, 1, 0);
+
+  if (opcode == opc_return) {
+    add_imm(jinfo->codebuf, Rstack, Rstack, jinfo->method->max_locals() * sizeof(int) + 4);
+  } else {
+    if (opcode == opc_lreturn || opcode == opc_dreturn) {
+      str_imm(jinfo->codebuf, r, Rstack, jinfo->method->max_locals() * sizeof(int), 1, 0);
+      str_imm(jinfo->codebuf, r_lo, Rstack, jinfo->method->max_locals() * sizeof(int)-4, 1, 1);
+    } else
+      str_imm(jinfo->codebuf, r, Rstack, jinfo->method->max_locals() * sizeof(int), 1, 1);
+  }
+
+//  sub_imm(jinfo->codebuf, Ristate, ARM_LR, ISTATE_NEXT_FRAME);
+  str_imm(jinfo->codebuf, ARM_LR, Rthread, THREAD_TOP_ZERO_FRAME, 1, 0);
+  str_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
+  Thumb2_Debug(jinfo, H_DEBUG_METHODEXIT);
+//  enter_leave(jinfo->codebuf, 0);
+  ldm(jinfo->codebuf, C_REGSET + (1<<ARM_PC), ARM_SP, POP_FD, 1);
+}
+
+#if 0
+void Thumb2_save_all_locals(Thumb2_Info *jinfo, unsigned stackdepth)
+{
+  int nlocals = jinfo->method->max_locals();
+  int i;
+
+  JASSERT(jinfo->jstack->depth == 0, "stack not empty");
+  if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+  for (i = 0; i < nlocals; i++) {
+    Reg r = jinfo->jregs->r_local[i];
+    if (r) {
+	store_local(jinfo, r, i, stackdepth);
+    }
+  }
+}
+#endif
+
+void Thumb2_save_locals(Thumb2_Info *jinfo, unsigned stackdepth)
+{
+  int nlocals = jinfo->method->max_locals();
+  unsigned *locals_info = jinfo->locals_info;
+  int i;
+
+  JASSERT(jinfo->jstack->depth == 0, "stack not empty");
+  if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+  for (i = 0; i < nlocals; i++) {
+    Reg r = jinfo->jregs->r_local[i];
+    if (r) {
+      if ((locals_info[i] & (1 << LOCAL_REF)) && (locals_info[i] & (1 << LOCAL_MODIFIED))) {
+	store_local(jinfo, r, i, stackdepth);
+      }
+    }
+  }
+}
+
+void Thumb2_restore_locals(Thumb2_Info *jinfo, unsigned stackdepth)
+{
+  int nlocals = jinfo->method->max_locals();
+  unsigned *locals_info = jinfo->locals_info;
+  int i;
+
+  JASSERT(jinfo->jstack->depth == 0, "stack not empty");
+  if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+  for (i = 0; i < nlocals; i++) {
+    Reg r = jinfo->jregs->r_local[i];
+    if (r) {
+      if (locals_info[i] & (1<<LOCAL_REF)) {
+	load_local(jinfo, r, i, stackdepth);
+      }
+    }
+  }
+}
+
+void Thumb2_invoke_save(Thumb2_Info *jinfo, unsigned stackdepth)
+{
+  int nlocals = jinfo->method->max_locals();
+  unsigned *locals_info = jinfo->locals_info;
+  int i;
+
+  JASSERT(jinfo->jstack->depth == 0, "stack not empty");
+  if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+  for (i = 0; i < nlocals; i++) {
+    Reg r = jinfo->jregs->r_local[i];
+    if (r) {
+      if (locals_info[i] & (1 << LOCAL_MODIFIED)) {
+	store_local(jinfo, r, i, stackdepth);
+      }
+    }
+  }
+}
+
+void Thumb2_invoke_restore(Thumb2_Info *jinfo, unsigned stackdepth)
+{
+  int nlocals = jinfo->method->max_locals();
+  unsigned *locals_info = jinfo->locals_info;
+  int i;
+
+  JASSERT(jinfo->jstack->depth == 0, "stack not empty");
+  if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+  for (i = 0; i < nlocals; i++) {
+    Reg r = jinfo->jregs->r_local[i];
+    if (r) {
+	load_local(jinfo, r, i, stackdepth);
+    }
+  }
+}
+
+void Thumb2_Exit(Thumb2_Info *jinfo, unsigned handler, unsigned bci, unsigned stackdepth)
+{
+    Thumb2_Flush(jinfo);
+    Thumb2_invoke_save(jinfo, stackdepth);
+    mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+    bl(jinfo->codebuf, handlers[handler]);
+}
+
+void Thumb2_Jsr(Thumb2_Info *jinfo, unsigned bci, unsigned stackdepth)
+{
+      Thumb2_Exit(jinfo, H_JSR, bci, stackdepth);
+}
+
+int Thumb2_Accessor(Thumb2_Info *jinfo)
+{
+  jubyte *code_base = jinfo->code_base;
+  constantPoolCacheOop  cp = jinfo->method->constants()->cache();
+  ConstantPoolCacheEntry* cache;
+  int index = GET_NATIVE_U2(code_base+2);
+  unsigned loc;
+  unsigned *bc_stackinfo = jinfo->bc_stackinfo;
+
+  JASSERT(code_base[0] == opc_aload_0 || code_base[0] == opc_iaccess_0, "not an aload_0 in accessor");
+  JASSERT(code_base[4] == opc_ireturn || code_base[4] == opc_areturn, "not an ireturn in accessor");
+  cache = cp->entry_at(index);
+  if (!cache->is_resolved((Bytecodes::Code)opc_getfield)) return 0;
+
+  TosState tos_type = cache->flag_state();
+  int field_offset = cache->f2();
+
+  // Slow entry point
+  loc = forward_32(jinfo->codebuf);
+  out_32(jinfo->codebuf, 0);
+  out_32(jinfo->codebuf, 0);
+  out_32(jinfo->codebuf, 0);
+
+  // OSR entry point
+  mov_reg(jinfo->codebuf, ARM_PC, ARM_R0);
+
+  out_align(jinfo->codebuf, CODE_ALIGN);
+
+  // fast entry point
+  bc_stackinfo[0] = (bc_stackinfo[0] & BC_FLAGS_MASK) | (jinfo->codebuf->idx * 2) | BC_COMPILED;
+  branch_uncond_patch(jinfo->codebuf, loc, jinfo->codebuf->idx * 2);
+  ldr_imm(jinfo->codebuf, ARM_R1, ARM_R2, THREAD_JAVA_SP, 1, 0);
+  ldr_imm(jinfo->codebuf, ARM_R0, ARM_R1, 0, 1, 0);
+  if (tos_type == btos)
+    ldrb_imm(jinfo->codebuf, ARM_R0, ARM_R0, field_offset, 1, 0);
+  else if (tos_type == ctos)
+    ldrh_imm(jinfo->codebuf, ARM_R0, ARM_R0, field_offset, 1, 0);
+  else if (tos_type == stos)
+    ldrsh_imm(jinfo->codebuf, ARM_R0, ARM_R0, field_offset, 1, 0);
+  else
+    ldr_imm(jinfo->codebuf, ARM_R0, ARM_R0, field_offset, 1, 0);
+  str_imm(jinfo->codebuf, ARM_R0, ARM_R1, 0, 1, 0);
+  mov_reg(jinfo->codebuf, ARM_PC, ARM_LR);
+
+  return 1;
+}
+
+void Thumb2_Enter(Thumb2_Info *jinfo)
+{
+  int parms = jinfo->method->size_of_parameters();
+  int extra_locals = jinfo->method->max_locals() - parms;
+  unsigned *locals_info = jinfo->locals_info;
+  int i;
+
+  // Slow entry point - callee save
+  // R0 = method
+  // R2 = thread
+  stm(jinfo->codebuf, I_REGSET + (1<<ARM_LR), ARM_SP, PUSH_FD, 1);
+  bl(jinfo->codebuf, out_pos(jinfo->codebuf) + CODE_ALIGN - 4);
+  ldm(jinfo->codebuf, I_REGSET + (1<<ARM_PC), ARM_SP, POP_FD, 1);
+
+  out_32(jinfo->codebuf, 0);
+
+  // OSR entry point == Slow entry + 16 - caller save
+  // R0 = entry point within compiled method
+  // R1 = locals
+  // R2 = thread
+  {
+    int nlocals = jinfo->method->max_locals();
+
+    for (i = 0; i < nlocals; i++) {
+      Reg r = jinfo->jregs->r_local[i];
+      if (r) {
+	ldr_imm(jinfo->codebuf, r, ARM_R1, -i * 4, 1, 0);
+      }
+    }
+    mov_reg(jinfo->codebuf, Rthread, ARM_R2);
+    mov_reg(jinfo->codebuf, ARM_PC, ARM_R0);
+  }
+
+  out_align(jinfo->codebuf, CODE_ALIGN);
+
+  // Fast entry point == Slow entry + 64 - caller save
+  // R0 = method
+  // R2 = thread
+  stm(jinfo->codebuf, C_REGSET + (1<<ARM_LR), ARM_SP, PUSH_FD, 1);
+//  enter_leave(jinfo->codebuf, 1);
+  ldr_imm(jinfo->codebuf, Rstack, ARM_R2, THREAD_JAVA_SP, 1, 0);
+  Thumb2_Debug(jinfo, H_DEBUG_METHODENTRY);
+  mov_imm(jinfo->codebuf, ARM_R1, 0);
+
+  if (extra_locals > 0) {
+    sub_imm(jinfo->codebuf, Rstack, Rstack, extra_locals * 4);
+
+    for (i = 0; i < extra_locals; i++) {
+      unsigned linfo = locals_info[parms+i];
+      if (linfo & (1<< LOCAL_REF))
+	str_imm(jinfo->codebuf, ARM_R1, Rstack, (extra_locals-1 - i) * 4, 1, 0);
+    }
+  }
+
+  ldr_imm(jinfo->codebuf, ARM_IP, ARM_R0, METHOD_CONSTANTS, 1, 0);
+
+  sub_imm(jinfo->codebuf, Ristate, Rstack, FRAME_SIZE);
+
+  add_imm(jinfo->codebuf, Rlocals, Rstack, (jinfo->method->max_locals()-1) * sizeof(int));
+  str_imm(jinfo->codebuf, Rlocals, Ristate, ISTATE_LOCALS, 1, 0);
+
+  if (jinfo->method->is_synchronized()) {
+    sub_imm(jinfo->codebuf, Rstack, Ristate, frame::interpreter_frame_monitor_size()*wordSize);
+    if (jinfo->method->is_static()) {
+      ldr_imm(jinfo->codebuf, ARM_R3, ARM_IP, CONSTANTPOOL_POOL_HOLDER, 1, 0);
+      ldr_imm(jinfo->codebuf, JAZ_V1, ARM_R3, KLASS_PART+KLASS_JAVA_MIRROR, 1, 0);
+    } else {
+      ldr_imm(jinfo->codebuf, JAZ_V1, Rlocals, 0, 1, 0);
+    }
+    str_imm(jinfo->codebuf, JAZ_V1, Rstack, 4, 1, 0);
+  } else
+    mov_reg(jinfo->codebuf, Rstack, Ristate);
+
+  str_imm(jinfo->codebuf, ARM_R1, Ristate, ISTATE_MSG, 1, 0);
+  str_imm(jinfo->codebuf, ARM_R1, Ristate, ISTATE_OOP_TEMP, 1, 0);
+
+  sub_imm(jinfo->codebuf, ARM_R3, Rstack, jinfo->method->max_stack() * sizeof(int));
+  str_imm(jinfo->codebuf, ARM_R3, ARM_R2, THREAD_JAVA_SP, 1, 0);
+
+  str_imm(jinfo->codebuf, Rstack, Ristate, ISTATE_STACK_BASE, 1, 0);
+
+  sub_imm(jinfo->codebuf, ARM_R3, ARM_R3, 4);
+  str_imm(jinfo->codebuf, ARM_R3, Ristate, ISTATE_STACK_LIMIT, 1, 0);
+
+  ldr_imm(jinfo->codebuf, ARM_R3, ARM_R2, THREAD_TOP_ZERO_FRAME, 1, 0);
+  str_imm(jinfo->codebuf, ARM_R3, Ristate, ISTATE_NEXT_FRAME, 1, 0);
+
+  mov_imm(jinfo->codebuf, ARM_R3, INTERPRETER_FRAME);
+  str_imm(jinfo->codebuf, ARM_R3, Ristate, ISTATE_FRAME_TYPE, 1, 0);
+
+  str_imm(jinfo->codebuf, Ristate, Ristate, ISTATE_MONITOR_BASE, 1, 0);
+
+  add_imm(jinfo->codebuf, ARM_R3, Ristate, ISTATE_NEXT_FRAME);
+  str_imm(jinfo->codebuf, ARM_R3, ARM_R2, THREAD_TOP_ZERO_FRAME, 1, 0);
+  str_imm(jinfo->codebuf, ARM_R3, ARM_R2, THREAD_LAST_JAVA_SP, 1, 0);
+
+  ldr_imm(jinfo->codebuf, ARM_R3, ARM_IP, CONSTANTPOOL_CACHE, 1, 0);
+  str_imm(jinfo->codebuf, ARM_R3, Ristate, ISTATE_CONSTANTS, 1, 0);
+
+  str_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_THREAD, 1, 0);
+  str_imm(jinfo->codebuf, ARM_R0, Ristate, ISTATE_METHOD, 1, 0);
+
+  mov_reg(jinfo->codebuf, Rthread, ARM_R2);
+
+  if (jinfo->method->is_synchronized()) {
+    unsigned loc_retry, loc_failed, loc_success, loc_exception;
+
+    // JAZ_V1 == monitor object
+    //
+    // Try to acquire the monitor. Seems very sub-optimal
+    // 		ldr	r3, [JAZ_V1, #0]
+    // 		sub	r1, Ristate, #8
+    // 		orr	r3, r3, #1
+    // 		str	r3, [r1, #0]
+    // 	retry:
+    // 		ldrex	r0, [JAZ_V1, #0]
+    // 		cmp	r3, r0
+    // 		bne	failed
+    // 		strex	r0, r1, [JAZ_V1, #0]
+    // 		cbz	r0, success
+    // 		b	retry
+    // 	failed:
+    // 		<failed - someone else has the monitor - must yield>
+    //  success:
+    // 		<success - acquired the monitor>
+    //
+    ldr_imm(jinfo->codebuf, ARM_R3, JAZ_V1, 0, 1, 0);
+    sub_imm(jinfo->codebuf, ARM_R1, Ristate, frame::interpreter_frame_monitor_size()*wordSize);
+    orr_imm(jinfo->codebuf, ARM_R3, ARM_R3, 1);
+    str_imm(jinfo->codebuf, ARM_R3, ARM_R1, 0, 1, 0);
+    loc_retry = out_loc(jinfo->codebuf);
+// retry:
+    ldrex_imm(jinfo->codebuf, ARM_R0, JAZ_V1, 0);
+    cmp_reg(jinfo->codebuf, ARM_R3, ARM_R0);
+    loc_failed = forward_16(jinfo->codebuf);
+    strex_imm(jinfo->codebuf, ARM_R0, ARM_R1, JAZ_V1, 0);
+    loc_success = forward_16(jinfo->codebuf);
+    branch_uncond(jinfo->codebuf, loc_retry);
+    bcc_patch(jinfo->codebuf, COND_NE, loc_failed);
+// failed:
+    mov_imm(jinfo->codebuf, ARM_R0, 0+CONSTMETHOD_CODEOFFSET);
+    bl(jinfo->codebuf, handlers[H_SYNCHRONIZED_ENTER]);
+    loc_exception = forward_16(jinfo->codebuf);
+    bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+    cbz_patch(jinfo->codebuf, ARM_R0, loc_exception);
+    cbz_patch(jinfo->codebuf, ARM_R0, loc_success);
+//    mov_imm(jinfo->codebuf, ARM_R0, 0+CONSTMETHOD_CODEOFFSET);
+//    bl(jinfo->codebuf, handlers[H_MONITOR]);
+// success:
+
+  }
+
+  {
+    int nlocals = jinfo->method->max_locals();
+
+    for (i = 0; i < nlocals; i++) {
+      Reg r = jinfo->jregs->r_local[i];
+      if (r) {
+	unsigned stackdepth = 0;
+	if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+	if (i < parms || (locals_info[i] & (1<<LOCAL_REF))) {
+	  load_local(jinfo, r, i, stackdepth);
+	}
+      }
+    }
+  }
+}
+
+unsigned opcode2handler[] = {
+  H_IDIV,
+  H_LDIV,
+  0, 0,			// fdiv, ddiv
+  H_IREM,
+  H_LREM,
+  H_FREM,
+  H_DREM,
+  0, 0, 0, 0,		// ineg, lneg, fneg, dneg
+  0, 0, 0, 0, 0, 0,	// shifts
+  0, 0, 0, 0, 0, 0,	// and, or, xor
+  0,			// iinc
+  0,			// i2l
+  H_I2F,
+  H_I2D,
+  0,			// l2i
+  H_L2F,
+  H_L2D,
+  H_F2I,
+  H_F2L,
+  H_F2D,
+  H_D2I,
+  H_D2L,
+  H_D2F,
+};
+
+#define OPCODE2HANDLER(opc) (handlers[opcode2handler[(opc)-opc_idiv]])
+
+void Thumb2_codegen(Thumb2_Info *jinfo, unsigned start)
+{
+  unsigned code_size = jinfo->code_size;
+  jubyte *code_base = jinfo->code_base;
+  unsigned *bc_stackinfo = jinfo->bc_stackinfo;
+  CodeBuf *codebuf = jinfo->codebuf;
+  Thumb2_Stack *jstack = jinfo->jstack;
+  unsigned bci;
+  unsigned opcode;
+  unsigned stackinfo;
+  int len;
+  unsigned stackdepth;
+
+  for (bci = start; bci < code_size; ) {
+#ifdef T2EE_PRINT_DISASS
+    unsigned start_idx = jinfo->codebuf->idx;
+    if (start_bci[start_idx] == -1) start_bci[start_idx] = bci;
+#endif
+    opcode = code_base[bci];
+    stackinfo = bc_stackinfo[bci];
+
+    if (stackinfo & BC_BRANCH_TARGET) Thumb2_Flush(jinfo);
+    JASSERT(!(stackinfo & BC_COMPILED), "code already compiled for this bytecode?");
+    stackdepth = stackinfo & ~BC_FLAGS_MASK;
+    bc_stackinfo[bci] = (stackinfo & BC_FLAGS_MASK) | (codebuf->idx * 2) | BC_COMPILED;
+
+    if (opcode > OPC_LAST_JAVA_OP) {
+      if (Bytecodes::is_defined((Bytecodes::Code)opcode))
+	opcode = (unsigned)Bytecodes::java_code((Bytecodes::Code)opcode);
+    }
+
+    len = Bytecodes::length_for((Bytecodes::Code)opcode);
+    if (len <= 0) len = Bytecodes::special_length_at((address)(code_base+bci), (address)(code_base+code_size));
+
+    if (IS_DEAD(stackinfo) || IS_ZOMBIE(stackinfo)) {
+      unsigned zlen = 0;
+#ifdef T2EE_PRINT_DISASS
+      unsigned start_bci = bci;
+#endif
+
+      Thumb2_Exit(jinfo, H_ZOMBIE, bci, stackdepth);
+      do {
+	zlen += len;
+	bci += len;
+	if (bci >= code_size) break;
+	opcode = code_base[bci];
+	stackinfo = bc_stackinfo[bci];
+
+	if (stackinfo & BC_BRANCH_TARGET) break;
+	if (!(IS_DEAD(stackinfo) || IS_ZOMBIE(stackinfo))) break;
+
+	if (opcode > OPC_LAST_JAVA_OP) {
+	  if (Bytecodes::is_defined((Bytecodes::Code)opcode))
+	    opcode = (unsigned)Bytecodes::java_code((Bytecodes::Code)opcode);
+	}
+
+	len = Bytecodes::length_for((Bytecodes::Code)opcode);
+	if (len <= 0) len = Bytecodes::special_length_at((address)(code_base+bci), (address)(code_base+code_size));
+
+      } while (1);
+#ifdef T2EE_PRINT_DISASS
+      end_bci[start_idx] = start_bci + zlen;
+#endif
+      jinfo->zombie_bytes += zlen;
+      continue;
+    }
+
+#if 0
+    if (bci >= 2620) {
+      unsigned zlen = 0;
+#ifdef T2EE_PRINT_DISASS
+      unsigned start_bci = bci;
+#endif
+
+      Thumb2_Exit(jinfo, H_ZOMBIE, bci, stackdepth);
+      do {
+	zlen += len;
+	bci += len;
+	if (bci >= code_size) break;
+	opcode = code_base[bci];
+	stackinfo = bc_stackinfo[bci];
+
+	if (stackinfo & BC_BRANCH_TARGET) break;
+
+	if (opcode > OPC_LAST_JAVA_OP) {
+	  if (Bytecodes::is_defined((Bytecodes::Code)opcode))
+	    opcode = (unsigned)Bytecodes::java_code((Bytecodes::Code)opcode);
+	}
+
+	len = Bytecodes::length_for((Bytecodes::Code)opcode);
+	if (len <= 0) len = Bytecodes::special_length_at((address)(code_base+bci), (address)(code_base+code_size));
+
+      } while (1);
+#ifdef T2EE_PRINT_DISASS
+      end_bci[start_idx] = start_bci + zlen;
+#endif
+      jinfo->zombie_bytes += zlen;
+      continue;
+    }
+#endif
+
+#ifdef T2EE_PRINT_DISASS
+    end_bci[start_idx] = bci + len;
+#endif
+
+    switch (opcode) {
+      case opc_nop:
+	break;
+      case opc_aconst_null:
+	len += Thumb2_Imm(jinfo, 0, bci+1);
+	break;
+      case opc_iconst_m1:
+      case opc_iconst_0:
+      case opc_iconst_1:
+      case opc_iconst_2:
+      case opc_iconst_3:
+      case opc_iconst_4:
+      case opc_iconst_5:
+	len += Thumb2_Imm(jinfo, opcode - (unsigned)opc_iconst_0, bci+1);
+	break;
+      case opc_lconst_0:
+      case opc_lconst_1:
+	Thumb2_ImmX2(jinfo, opcode - (unsigned)opc_lconst_0, 0);
+	break;
+      case opc_fconst_0:
+      case opc_fconst_1:
+      case opc_fconst_2: {
+	unsigned v = 0;
+	if (opcode == (unsigned)opc_fconst_1) v = 0x3f800000;
+	if (opcode == (unsigned)opc_fconst_2) v = 0x40000000;
+	len += Thumb2_Imm(jinfo, v, bci+1);
+	break;
+      }
+      case opc_dconst_0:
+      case opc_dconst_1: {
+	unsigned v_hi = 0;
+	if (opcode == (unsigned)opc_dconst_1) v_hi = 0x3ff00000;
+	Thumb2_ImmX2(jinfo, 0, v_hi);
+	break;
+      }
+      case opc_bipush:
+	len += Thumb2_Imm(jinfo, GET_JAVA_S1(code_base+bci+1), bci+2);
+	break;
+      case opc_sipush:
+	len += Thumb2_Imm(jinfo, GET_JAVA_S2(code_base+bci+1), bci+3);
+	break;
+      case opc_ldc:
+      case opc_ldc_w:
+      case opc_ldc2_w: {
+	unsigned index = (opcode == (unsigned)opc_ldc) ?
+				code_base[bci+1] : GET_JAVA_U2(code_base+bci+1);
+	constantPoolOop constants = jinfo->method->constants();
+	unsigned v;
+
+	switch (v = constants->tag_at(index).value()) {
+	  case JVM_CONSTANT_Integer:
+	  case JVM_CONSTANT_Float:
+	    v = (unsigned)constants->int_at(index);
+	    len += Thumb2_Imm(jinfo, v, bci+len);
+	    break;
+#if 0
+	  case JVM_CONSTANT_String:
+	    v = (unsigned)constants->resolved_string_at(index);
+	    len += Thumb2_Imm(jinfo, v, bci+len);
+	    break;
+	  case JVM_CONSTANT_Class:
+	    v = (unsigned)constants->resolved_klass_at(index)->klass_part()->java_mirror();
+	    len += Thumb2_Imm(jinfo, v, bci+len);
+	    break;
+#endif
+	  case JVM_CONSTANT_Long:
+	  case JVM_CONSTANT_Double: {
+	    unsigned long long v;
+	    v = constants->long_at(index);
+	    Thumb2_ImmX2(jinfo, v & 0xffffffff, v >> 32);
+	    break;
+	  }
+	  case JVM_CONSTANT_Class:
+	  case JVM_CONSTANT_String: {
+	    Reg r;
+	    Thumb2_Spill(jinfo, 1, 0);
+	    r = JSTACK_REG(jstack);
+	    PUSH(jstack, r);
+	    ldr_imm(jinfo->codebuf, r, Ristate, ISTATE_METHOD, 1, 0);
+	    ldr_imm(jinfo->codebuf, r, r, METHOD_CONSTANTS, 1, 0);
+	    ldr_imm(jinfo->codebuf, r, r, CONSTANTPOOL_BASE + (index << 2), 1, 0);
+	    if (v == JVM_CONSTANT_Class)
+	      ldr_imm(jinfo->codebuf, r, r, KLASS_PART+KLASS_JAVA_MIRROR, 1, 0);
+	    break;
+	  }
+	  default:
+	    unsigned loc;
+
+	    JASSERT(opcode != opc_ldc2_w, "ldc2_w unresolved?");
+	    Thumb2_Flush(jinfo);
+	    mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+	  Thumb2_save_locals(jinfo, stackdepth);
+	    mov_imm(jinfo->codebuf, ARM_R1, opcode != opc_ldc);
+	    bl(jinfo->codebuf, handlers[H_LDC]);
+	  Thumb2_restore_locals(jinfo, stackdepth);
+	    ldr_imm(jinfo->codebuf, ARM_R0, Rthread, THREAD_VM_RESULT, 1, 0);
+	    mov_imm(jinfo->codebuf, ARM_R2, 0);
+	    str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_VM_RESULT, 1, 0);
+	    loc = forward_16(jinfo->codebuf);
+	    bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	    cbnz_patch(jinfo->codebuf, ARM_R0, loc);
+	    PUSH(jstack, ARM_R0);
+	    break;
+	}
+	break;
+      }
+
+      case opc_iload:
+      case opc_fload:
+      case opc_aload:
+	Thumb2_Load(jinfo, code_base[bci+1], stackdepth);
+	break;
+      case opc_lload:
+      case opc_dload:
+	Thumb2_LoadX2(jinfo, code_base[bci+1], stackdepth);
+	break;
+      case opc_iload_0:
+      case opc_iload_1:
+      case opc_iload_2:
+      case opc_iload_3:
+      case opc_fload_0:
+      case opc_fload_1:
+      case opc_fload_2:
+      case opc_fload_3:
+      case opc_aload_0:
+      case opc_aload_1:
+      case opc_aload_2:
+      case opc_aload_3:
+	Thumb2_Load(jinfo, (opcode - opc_iload_0) & 3, stackdepth);
+	break;
+      case opc_lload_0:
+      case opc_lload_1:
+      case opc_lload_2:
+      case opc_lload_3:
+      case opc_dload_0:
+      case opc_dload_1:
+      case opc_dload_2:
+      case opc_dload_3:
+	Thumb2_LoadX2(jinfo, (opcode - opc_iload_0) & 3, stackdepth);
+	break;
+      case opc_iaload:
+      case opc_faload:
+      case opc_aaload:
+      case opc_baload:
+      case opc_caload:
+      case opc_saload:
+	Thumb2_Xaload(jinfo, opcode);
+	break;
+      case opc_laload:
+      case opc_daload:
+	Thumb2_X2aload(jinfo);
+	break;
+      case opc_istore:
+      case opc_fstore:
+      case opc_astore:
+	Thumb2_Store(jinfo, code_base[bci+1], stackdepth);
+	break;
+      case opc_lstore:
+      case opc_dstore:
+	Thumb2_StoreX2(jinfo, code_base[bci+1], stackdepth);
+	break;
+      case opc_istore_0:
+      case opc_istore_1:
+      case opc_istore_2:
+      case opc_istore_3:
+      case opc_fstore_0:
+      case opc_fstore_1:
+      case opc_fstore_2:
+      case opc_fstore_3:
+      case opc_astore_0:
+      case opc_astore_1:
+      case opc_astore_2:
+      case opc_astore_3:
+	Thumb2_Store(jinfo, (opcode - opc_istore_0) & 3, stackdepth);
+	break;
+      case opc_lstore_0:
+      case opc_lstore_1:
+      case opc_lstore_2:
+      case opc_lstore_3:
+      case opc_dstore_0:
+      case opc_dstore_1:
+      case opc_dstore_2:
+      case opc_dstore_3:
+	Thumb2_StoreX2(jinfo, (opcode - opc_istore_0) & 3, stackdepth);
+	break;
+      case opc_iastore:
+      case opc_fastore:
+      case opc_bastore:
+      case opc_castore:
+      case opc_sastore:
+	Thumb2_Xastore(jinfo, opcode);
+	break;
+      case opc_lastore:
+      case opc_dastore:
+	Thumb2_X2astore(jinfo);
+	break;
+
+      case opc_pop:
+      case opc_pop2:
+	Thumb2_Pop(jinfo, opcode - opc_pop + 1);
+	break;
+
+      case opc_dup:
+      case opc_dup_x1:
+      case opc_dup_x2:
+	Thumb2_Dup(jinfo, opcode - opc_dup);
+	break;
+
+      case opc_dup2:
+      case opc_dup2_x1:
+      case opc_dup2_x2:
+	Thumb2_Dup2(jinfo, opcode - opc_dup2);
+	break;
+
+      case opc_swap:
+	Thumb2_Swap(jinfo);
+	break;
+
+      case opc_iadd:
+      case opc_isub:
+      case opc_imul:
+      case opc_ishl:
+      case opc_ishr:
+      case opc_iushr:
+      case opc_iand:
+      case opc_ior:
+      case opc_ixor:
+	Thumb2_iOp(jinfo, opcode);
+	break;
+
+      case opc_ladd:
+      case opc_lsub:
+      case opc_land:
+      case opc_lor:
+      case opc_lxor:
+	Thumb2_lOp(jinfo, opcode);
+	break;
+
+      case opc_lshl: {
+	Reg lho_lo, lho_hi, res_lo, res_hi, shift;
+	unsigned loc1, loc2;
+
+	Thumb2_Fill(jinfo, 3);
+	shift = POP(jstack);
+	lho_lo = POP(jstack);
+	lho_hi = POP(jstack);
+	Thumb2_Spill(jinfo, 2, (1<<lho_lo)|(1<<lho_hi));
+	res_hi = PUSH(jstack, JSTACK_PREFER(jstack, ~((1<<lho_lo)|(1<<lho_hi))));
+	res_lo = PUSH(jstack, JSTACK_PREFER(jstack, ~((1<<lho_lo)|(1<<lho_hi))));
+	JASSERT(res_lo != lho_lo && res_lo != lho_hi, "Spill failed");
+	JASSERT(res_hi != lho_lo && res_hi != lho_hi, "Spill failed");
+	and_imm(jinfo->codebuf, ARM_IP, shift, 31);
+	tst_imm(jinfo->codebuf, shift, 32);
+	loc1 = forward_16(jinfo->codebuf);
+	mov_imm(jinfo->codebuf, res_lo, 0);
+	dop_reg(jinfo->codebuf, DP_LSL, res_hi, lho_lo, ARM_IP, SHIFT_LSL, 0);
+	loc2 = forward_16(jinfo->codebuf);
+	bcc_patch(jinfo->codebuf, COND_EQ, loc1);
+	dop_reg(jinfo->codebuf, DP_LSL, res_lo, lho_lo, ARM_IP, SHIFT_LSL, 0);
+	dop_reg(jinfo->codebuf, DP_LSL, res_hi, lho_hi, ARM_IP, SHIFT_LSL, 0);
+	rsb_imm(jinfo->codebuf, ARM_IP, ARM_IP, 32);
+	dop_reg(jinfo->codebuf, DP_LSR, ARM_IP, lho_lo, ARM_IP, SHIFT_LSL, 0);
+	dop_reg(jinfo->codebuf, DP_ORR, res_hi, res_hi, ARM_IP, SHIFT_LSL, 0);
+	branch_narrow_patch(jinfo->codebuf, loc2);
+	break;
+      }
+
+      case opc_lushr: {
+	Reg lho_lo, lho_hi, res_lo, res_hi, shift;
+	unsigned loc1, loc2;
+
+	Thumb2_Fill(jinfo, 3);
+	shift = POP(jstack);
+	lho_lo = POP(jstack);
+	lho_hi = POP(jstack);
+	Thumb2_Spill(jinfo, 2, (1<<lho_lo)|(1<<lho_hi));
+	res_hi = PUSH(jstack, JSTACK_PREFER(jstack, ~((1<<lho_lo)|(1<<lho_hi))));
+	res_lo = PUSH(jstack, JSTACK_PREFER(jstack, ~((1<<lho_lo)|(1<<lho_hi))));
+	JASSERT(res_lo != lho_lo && res_lo != lho_hi, "Spill failed");
+	JASSERT(res_hi != lho_lo && res_hi != lho_hi, "Spill failed");
+	and_imm(jinfo->codebuf, ARM_IP, shift, 31);
+	tst_imm(jinfo->codebuf, shift, 32);
+	loc1 = forward_16(jinfo->codebuf);
+	mov_imm(jinfo->codebuf, res_hi, 0);
+	dop_reg(jinfo->codebuf, DP_LSR, res_lo, lho_hi, ARM_IP, SHIFT_LSL, 0);
+	loc2 = forward_16(jinfo->codebuf);
+	bcc_patch(jinfo->codebuf, COND_EQ, loc1);
+	dop_reg(jinfo->codebuf, DP_LSR, res_hi, lho_hi, ARM_IP, SHIFT_LSL, 0);
+	dop_reg(jinfo->codebuf, DP_LSR, res_lo, lho_lo, ARM_IP, SHIFT_LSL, 0);
+	rsb_imm(jinfo->codebuf, ARM_IP, ARM_IP, 32);
+	dop_reg(jinfo->codebuf, DP_LSL, ARM_IP, lho_hi, ARM_IP, SHIFT_LSL, 0);
+	dop_reg(jinfo->codebuf, DP_ORR, res_lo, res_lo, ARM_IP, SHIFT_LSL, 0);
+	branch_narrow_patch(jinfo->codebuf, loc2);
+	break;
+      }
+
+      case opc_lshr: {
+	Reg lho_lo, lho_hi, res_lo, res_hi, shift;
+	unsigned loc1, loc2;
+
+	Thumb2_Fill(jinfo, 3);
+	shift = POP(jstack);
+	lho_lo = POP(jstack);
+	lho_hi = POP(jstack);
+	Thumb2_Spill(jinfo, 2, (1<<lho_lo)|(1<<lho_hi));
+	res_hi = PUSH(jstack, JSTACK_PREFER(jstack, ~((1<<lho_lo)|(1<<lho_hi))));
+	res_lo = PUSH(jstack, JSTACK_PREFER(jstack, ~((1<<lho_lo)|(1<<lho_hi))));
+	JASSERT(res_lo != lho_lo && res_lo != lho_hi, "Spill failed");
+	JASSERT(res_hi != lho_lo && res_hi != lho_hi, "Spill failed");
+	and_imm(jinfo->codebuf, ARM_IP, shift, 31);
+	tst_imm(jinfo->codebuf, shift, 32);
+	loc1 = forward_16(jinfo->codebuf);
+	asr_imm(jinfo->codebuf, res_hi, lho_hi, 31);
+	dop_reg(jinfo->codebuf, DP_ASR, res_lo, lho_hi, ARM_IP, SHIFT_LSL, 0);
+	loc2 = forward_16(jinfo->codebuf);
+	bcc_patch(jinfo->codebuf, COND_EQ, loc1);
+	dop_reg(jinfo->codebuf, DP_ASR, res_hi, lho_hi, ARM_IP, SHIFT_LSL, 0);
+	dop_reg(jinfo->codebuf, DP_LSR, res_lo, lho_lo, ARM_IP, SHIFT_LSL, 0);
+	rsb_imm(jinfo->codebuf, ARM_IP, ARM_IP, 32);
+	dop_reg(jinfo->codebuf, DP_LSL, ARM_IP, lho_hi, ARM_IP, SHIFT_LSL, 0);
+	dop_reg(jinfo->codebuf, DP_ORR, res_lo, res_lo, ARM_IP, SHIFT_LSL, 0);
+	branch_narrow_patch(jinfo->codebuf, loc2);
+	break;
+      }
+
+      case opc_lmul:
+	Thumb2_lmul(jinfo);
+	break;
+
+      case opc_fadd:
+      case opc_fsub:
+      case opc_fmul:
+      case opc_fdiv:
+	Thumb2_fOp(jinfo, opcode);
+	break;
+
+      case opc_dadd:
+      case opc_dsub:
+      case opc_dmul:
+      case opc_ddiv:
+	Thumb2_dOp(jinfo, opcode);
+	break;
+
+      case opc_fcmpl:
+      case opc_fcmpg: {
+	Thumb2_Stack *jstack = jinfo->jstack;
+	unsigned rho, lho, res;
+	unsigned loc1, loc2, loc_ne;
+
+	Thumb2_Fill(jinfo, 2);
+	rho = POP(jstack);
+	lho = POP(jstack);
+	Thumb2_Spill(jinfo, 1, 0);
+	res = PUSH(jstack, JSTACK_REG(jstack));
+	vmov_reg_s_toVFP(jinfo->codebuf, VFP_S0, lho);
+	vmov_reg_s_toVFP(jinfo->codebuf, VFP_S1, rho);
+	vcmp_reg_s(jinfo->codebuf, VFP_S0, VFP_S1, 1);
+	mov_imm(jinfo->codebuf, res, opcode == opc_fcmpl ? 1 : -1);
+	vmrs(jinfo->codebuf, ARM_PC);
+	loc1 = forward_16(jinfo->codebuf);
+	dop_imm_preserve(jinfo->codebuf, DP_RSB, res, res, 0);
+	loc2 = forward_16(jinfo->codebuf);
+	vcmp_reg_s(jinfo->codebuf, VFP_S0, VFP_S1, 0);
+	loc_ne = forward_16(jinfo->codebuf);
+	mov_imm(jinfo->codebuf, res, 0);
+	bcc_patch(jinfo->codebuf, opcode == opc_fcmpl ? COND_GT : COND_MI, loc1);
+	bcc_patch(jinfo->codebuf, opcode == opc_fcmpl ? COND_MI : COND_GT, loc2);
+	bcc_patch(jinfo->codebuf, COND_NE, loc_ne);
+	break;
+      }
+
+      case opc_dcmpl:
+      case opc_dcmpg: {
+	Thumb2_Stack *jstack = jinfo->jstack;
+	unsigned rho_lo, rho_hi, lho_lo, lho_hi, res;
+	unsigned loc1, loc2, loc_ne;
+
+	Thumb2_Fill(jinfo, 4);
+	rho_lo = POP(jstack);
+	rho_hi = POP(jstack);
+	lho_lo = POP(jstack);
+	lho_hi = POP(jstack);
+	Thumb2_Spill(jinfo, 1, 0);
+	res = PUSH(jstack, JSTACK_REG(jstack));
+	vmov_reg_d_toVFP(jinfo->codebuf, VFP_S0, lho_lo, lho_hi);
+	vmov_reg_d_toVFP(jinfo->codebuf, VFP_S1, rho_lo, rho_hi);
+	vcmp_reg_d(jinfo->codebuf, VFP_S0, VFP_S1, 1);
+	mov_imm(jinfo->codebuf, res, opcode == opc_dcmpl ? 1 : -1);
+	vmrs(jinfo->codebuf, ARM_PC);
+	loc1 = forward_16(jinfo->codebuf);
+	dop_imm_preserve(jinfo->codebuf, DP_RSB, res, res, 0);
+	loc2 = forward_16(jinfo->codebuf);
+	vcmp_reg_d(jinfo->codebuf, VFP_S0, VFP_S1, 0);
+	loc_ne = forward_16(jinfo->codebuf);
+	mov_imm(jinfo->codebuf, res, 0);
+	bcc_patch(jinfo->codebuf, opcode == opc_dcmpl ? COND_GT : COND_MI, loc1);
+	bcc_patch(jinfo->codebuf, opcode == opc_dcmpl ? COND_MI : COND_GT, loc2);
+	bcc_patch(jinfo->codebuf, COND_NE, loc_ne);
+	break;
+      }
+
+      case opc_drem:
+      case opc_lrem:
+      case opc_ldiv: {
+	Reg src[4], dst[4];
+
+	Thumb2_Fill(jinfo, 4);
+	src[2] = POP(jstack);
+	src[3] = POP(jstack);
+	src[0] = POP(jstack);
+	src[1] = POP(jstack);
+	Thumb2_Flush(jinfo);
+	dst[0] = ARM_R0;
+	dst[1] = ARM_R1;
+	dst[2] = ARM_R2;
+	dst[3] = ARM_R3;
+	mov_multiple(jinfo->codebuf, dst, src, 4);
+	bl(jinfo->codebuf, OPCODE2HANDLER(opcode));
+	if (opcode != opc_lrem) {
+	  PUSH(jstack, ARM_R1);
+	  PUSH(jstack, ARM_R0);
+	} else {
+	  PUSH(jstack, ARM_R3);
+	  PUSH(jstack, ARM_R2);
+	}
+	break;
+      }
+
+      case opc_frem:
+      case opc_idiv:
+      case opc_irem: {
+	Reg r_rho, r_lho;
+
+	Thumb2_Fill(jinfo, 2);
+	r_rho = POP(jstack);
+	r_lho = POP(jstack);
+	Thumb2_Flush(jinfo);
+	if (r_rho == ARM_R0) {
+	  if (r_lho == ARM_R1) {
+	    mov_reg(jinfo->codebuf, ARM_IP, r_rho);
+	    mov_reg(jinfo->codebuf, ARM_R0, r_lho);
+	    mov_reg(jinfo->codebuf, ARM_R1, ARM_IP);
+	  } else {
+	    mov_reg(jinfo->codebuf, ARM_R1, r_rho);
+	    mov_reg(jinfo->codebuf, ARM_R0, r_lho);
+	  }
+	} else {
+	  mov_reg(jinfo->codebuf, ARM_R0, r_lho);
+	  mov_reg(jinfo->codebuf, ARM_R1, r_rho);
+	}
+#if 1
+	if (opcode == opc_frem)
+	  bl(jinfo->codebuf, OPCODE2HANDLER(opcode));
+	else
+	  blx(jinfo->codebuf, OPCODE2HANDLER(opcode));
+#else
+	bl(jinfo->codebuf, OPCODE2HANDLER(opcode));
+#endif
+	PUSH(jstack, ARM_R0);
+	break;
+      }
+
+      case opc_f2i:
+      case opc_i2f: {
+	Reg r;
+
+	Thumb2_Fill(jinfo, 1);
+	r = POP(jstack);
+	Thumb2_Flush(jinfo);
+	mov_reg(jinfo->codebuf, ARM_R0, r);
+	bl(jinfo->codebuf, OPCODE2HANDLER(opcode));
+	PUSH(jstack, ARM_R0);
+	break;
+      }
+
+      case opc_f2d:
+      case opc_f2l:
+      case opc_i2d: {
+	Reg r;
+
+	Thumb2_Fill(jinfo, 1);
+	r = POP(jstack);
+	Thumb2_Flush(jinfo);
+	mov_reg(jinfo->codebuf, ARM_R0, r);
+	bl(jinfo->codebuf, OPCODE2HANDLER(opcode));
+	PUSH(jstack, ARM_R1);
+	PUSH(jstack, ARM_R0);
+	break;
+    }
+
+      case opc_d2f:
+      case opc_d2i:
+      case opc_l2d:
+      case opc_d2l:
+      case opc_l2f: {
+	Reg lo, hi;
+
+	Thumb2_Fill(jinfo, 2);
+	lo = POP(jstack);
+	hi = POP(jstack);
+	Thumb2_Flush(jinfo);
+	if (hi == ARM_R0) {
+	  if (lo == ARM_R1) {
+	    mov_reg(jinfo->codebuf, ARM_IP, hi);
+	    mov_reg(jinfo->codebuf, ARM_R0, lo);
+	    mov_reg(jinfo->codebuf, ARM_R1, ARM_IP);
+	  } else {
+	    mov_reg(jinfo->codebuf, ARM_R1, hi);
+	    mov_reg(jinfo->codebuf, ARM_R0, lo);
+	  }
+	} else {
+	  mov_reg(jinfo->codebuf, ARM_R0, lo);
+	  mov_reg(jinfo->codebuf, ARM_R1, hi);
+	}
+	bl(jinfo->codebuf, OPCODE2HANDLER(opcode));
+	if (opcode == opc_l2d || opcode == opc_d2l) PUSH(jstack, ARM_R1);
+	PUSH(jstack, ARM_R0);
+	break;
+      }
+
+      case opc_ineg:
+	Thumb2_iNeg(jinfo, opcode);
+	break;
+
+      case opc_lneg:
+	Thumb2_lNeg(jinfo, opcode);
+	break;
+
+      case opc_fneg:
+	Thumb2_fNeg(jinfo, opcode);
+	break;
+
+      case opc_dneg:
+	Thumb2_dNeg(jinfo, opcode);
+	break;
+
+      case opc_i2l: {
+	unsigned r, r_res_lo, r_res_hi;
+
+	Thumb2_Fill(jinfo, 1);
+	r = POP(jstack);
+	Thumb2_Spill(jinfo, 2, 0);
+	r_res_hi = PUSH(jstack, JSTACK_REG(jstack));
+	r_res_lo = PUSH(jstack, JSTACK_REG(jstack));
+	if (r == r_res_hi) {
+	  SWAP(jstack);
+	  r_res_hi = r_res_lo;
+	  r_res_lo = r;
+	}
+	mov_reg(jinfo->codebuf, r_res_lo, r);
+	asr_imm(jinfo->codebuf, r_res_hi, r, 31);
+	break;
+      }
+
+      case opc_l2i: {
+	unsigned r_lo, r_hi;
+	unsigned r;
+
+	Thumb2_Fill(jinfo, 2);
+	r_lo = POP(jstack);
+	r_hi = POP(jstack);
+	Thumb2_Spill(jinfo, 1, 0);
+	r = PUSH(jstack, r_lo);
+	break;
+      }
+
+      case opc_i2b: {
+	unsigned r_src, r_dst;
+
+	Thumb2_Fill(jinfo, 1);
+	r_src = POP(jstack);
+	Thumb2_Spill(jinfo, 1, 0);
+	r_dst = PUSH(jstack, JSTACK_REG(jstack));
+	sxtb(jinfo->codebuf, r_dst, r_src);
+	break;
+      }
+
+      case opc_i2s: {
+	unsigned r_src, r_dst;
+
+	Thumb2_Fill(jinfo, 1);
+	r_src = POP(jstack);
+	Thumb2_Spill(jinfo, 1, 0);
+	r_dst = PUSH(jstack, JSTACK_REG(jstack));
+	sxth(jinfo->codebuf, r_dst, r_src);
+	break;
+      }
+
+      case opc_i2c: {
+	unsigned r_src, r_dst;
+
+	Thumb2_Fill(jinfo, 1);
+	r_src = POP(jstack);
+	Thumb2_Spill(jinfo, 1, 0);
+	r_dst = PUSH(jstack, JSTACK_REG(jstack));
+	uxth(jinfo->codebuf, r_dst, r_src);
+	break;
+      }
+
+      case opc_lcmp: {
+	unsigned lho_lo, lho_hi;
+	unsigned rho_lo, rho_hi;
+	unsigned r_tmp_lo, r_tmp_hi;
+	unsigned res;
+	unsigned loc_lt, loc_eq;
+
+	Thumb2_Fill(jinfo, 4);
+	rho_lo = POP(jstack);
+	rho_hi = POP(jstack);
+	lho_lo = POP(jstack);
+	lho_hi = POP(jstack);
+	Thumb2_Spill(jinfo, 1, 0);
+	res = JSTACK_REG(jstack);
+	PUSH(jstack, res);
+	r_tmp_lo = Thumb2_Tmp(jinfo, (1<<rho_lo)|(1<<rho_hi)|(1<<lho_lo)|(1<<lho_hi));
+	r_tmp_hi = Thumb2_Tmp(jinfo, (1<<rho_lo)|(1<<rho_hi)|(1<<lho_lo)|(1<<lho_hi)|(1<<r_tmp_lo));
+	dop_reg(jinfo->codebuf, DP_SUB, r_tmp_lo, lho_lo, rho_lo, SHIFT_LSL, 0);
+	dop_reg(jinfo->codebuf, DP_SBC, r_tmp_hi, lho_hi, rho_hi, SHIFT_LSL, 0);
+	mov_imm(jinfo->codebuf, res, (unsigned)-1);
+	loc_lt = forward_16(jinfo->codebuf);
+	dop_reg(jinfo->codebuf, DP_ORR, res, r_tmp_lo, r_tmp_hi, SHIFT_LSL, 0);
+	loc_eq = forward_16(jinfo->codebuf);
+	mov_imm(jinfo->codebuf, res, 1);
+	bcc_patch(jinfo->codebuf, COND_LT, loc_lt);
+	bcc_patch(jinfo->codebuf, COND_EQ, loc_eq);
+	break;
+      }
+
+      case opc_iinc: {
+	unsigned local = code_base[bci+1];
+	int constant = GET_JAVA_S1(code_base+bci+2);
+	unsigned r = jinfo->jregs->r_local[local];
+
+	if (!r) {
+	  int nlocals = jinfo->method->max_locals();
+	  r = Thumb2_Tmp(jinfo, 0);
+	  stackdepth -= jstack->depth;
+	  if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+	  load_local(jinfo, r, local, stackdepth);
+	  add_imm(jinfo->codebuf, r, r, constant);
+	  store_local(jinfo, r, local, stackdepth);
+	} else {
+	  Thumb2_Corrupt(jinfo, r, 0);
+	  add_imm(jinfo->codebuf, r, r, constant);
+	}
+	break;
+      }
+
+      case opc_getfield: {
+	constantPoolCacheOop  cp = jinfo->method->constants()->cache();
+        ConstantPoolCacheEntry* cache;
+	int index = GET_NATIVE_U2(code_base+bci+1);
+	Reg r_obj;
+
+        cache = cp->entry_at(index);
+        if (!cache->is_resolved((Bytecodes::Code)opcode)) {
+	  int java_index = GET_JAVA_U2(code_base+bci+1);
+	  constantPoolOop pool = jinfo->method->constants();
+	  symbolOop sig = pool->signature_ref_at(java_index);
+	  jbyte *base = sig->base();
+	  jbyte c = *base;
+	  int handler = H_GETFIELD_WORD;
+
+	  if (c == 'J' || c == 'D') handler = H_GETFIELD_DW;
+	  if (c == 'B' || c == 'Z') handler = H_GETFIELD_SB;
+	  if (c == 'C') handler = H_GETFIELD_H;
+	  if (c == 'S') handler = H_GETFIELD_SH;
+	  Thumb2_Flush(jinfo);
+	  Thumb2_save_locals(jinfo, stackdepth);
+	  mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+	  mov_imm(jinfo->codebuf, ARM_R1, index);
+	  blx(jinfo->codebuf, handlers[handler]);
+	  Thumb2_restore_locals(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	  break;
+	}
+
+	TosState tos_type = cache->flag_state();
+	int field_offset = cache->f2();
+
+	if (tos_type == ltos || tos_type == dtos) {
+	  Reg r_lo, r_hi;
+	  Thumb2_Fill(jinfo, 1);
+	  r_obj = POP(jstack);
+	  Thumb2_Spill(jinfo, 2, 0);
+	  r_hi = PUSH(jstack, JSTACK_REG(jstack));
+	  r_lo = PUSH(jstack, JSTACK_REG(jstack));
+	  ldrd_imm(jinfo->codebuf, r_lo, r_hi, r_obj, field_offset, 1, 0);
+	} else {
+	  Reg r;
+
+	  Thumb2_Fill(jinfo, 1);
+	  r_obj = POP(jstack);
+	  Thumb2_Spill(jinfo, 1, 0);
+	  r = JSTACK_REG(jstack);
+	  PUSH(jstack, r);
+	  if (tos_type == btos)
+	    ldrsb_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	  else if (tos_type == ctos)
+	    ldrh_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	  else if (tos_type == stos)
+	    ldrsh_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	  else
+	    ldr_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	}
+	break;
+      }
+
+      case opc_monitorexit:
+      case opc_monitorenter:
+	  Thumb2_Exit(jinfo, H_MONITOR, bci, stackdepth);
+	  break;
+
+      case opc_getstatic: {
+	constantPoolCacheOop  cp = jinfo->method->constants()->cache();
+        ConstantPoolCacheEntry* cache;
+	int index = GET_NATIVE_U2(code_base+bci+1);
+
+        cache = cp->entry_at(index);
+        if (!cache->is_resolved((Bytecodes::Code)opcode)) {
+	  int java_index = GET_JAVA_U2(code_base+bci+1);
+	  constantPoolOop pool = jinfo->method->constants();
+	  symbolOop sig = pool->signature_ref_at(java_index);
+	  jbyte *base = sig->base();
+	  jbyte c = *base;
+	  int handler = H_GETSTATIC_WORD;
+
+	  if (c == 'J' || c == 'D') handler = H_GETSTATIC_DW;
+	  if (c == 'B' || c == 'Z') handler = H_GETSTATIC_SB;
+	  if (c == 'C') handler = H_GETSTATIC_H;
+	  if (c == 'S') handler = H_GETSTATIC_SH;
+	  Thumb2_Flush(jinfo);
+	  Thumb2_save_locals(jinfo, stackdepth);
+	  mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+	  mov_imm(jinfo->codebuf, ARM_R1, index);
+	  blx(jinfo->codebuf, handlers[handler]);
+	  Thumb2_restore_locals(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	  break;
+	}
+
+	TosState tos_type = cache->flag_state();
+	int field_offset = cache->f2();
+
+	if (tos_type == ltos || tos_type == dtos) {
+	  Reg r_lo, r_hi;
+	  Thumb2_Spill(jinfo, 2, 0);
+	  r_hi = PUSH(jstack, JSTACK_REG(jstack));
+	  r_lo = PUSH(jstack, JSTACK_REG(jstack));
+	  ldr_imm(jinfo->codebuf, r_lo, Ristate, ISTATE_CONSTANTS, 1, 0);
+	  ldr_imm(jinfo->codebuf, r_lo, r_lo, CP_OFFSET + (index << 4) + 4, 1, 0);
+	  ldrd_imm(jinfo->codebuf, r_lo, r_hi, r_lo, field_offset, 1, 0);
+	} else {
+	  Reg r;
+	  Thumb2_Spill(jinfo, 1, 0);
+	  r = JSTACK_REG(jstack);
+	  PUSH(jstack, r);
+	  ldr_imm(jinfo->codebuf, r, Ristate, ISTATE_CONSTANTS, 1, 0);
+	  ldr_imm(jinfo->codebuf, r, r, CP_OFFSET + (index << 4) + 4, 1, 0);
+	  if (tos_type == btos)
+	    ldrsb_imm(jinfo->codebuf, r, r, field_offset, 1, 0);
+	  else if (tos_type == ctos)
+	    ldrh_imm(jinfo->codebuf, r, r, field_offset, 1, 0);
+	  else if (tos_type == stos)
+	    ldrsh_imm(jinfo->codebuf, r, r, field_offset, 1, 0);
+	  else
+	    ldr_imm(jinfo->codebuf, r, r, field_offset, 1, 0);
+	}
+	break;
+      }
+
+      case opc_putfield: {
+	constantPoolCacheOop  cp = jinfo->method->constants()->cache();
+        ConstantPoolCacheEntry* cache;
+	int index = GET_NATIVE_U2(code_base+bci+1);
+	Reg r_obj;
+
+        cache = cp->entry_at(index);
+        if (!cache->is_resolved((Bytecodes::Code)opcode)) {
+	  int java_index = GET_JAVA_U2(code_base+bci+1);
+	  constantPoolOop pool = jinfo->method->constants();
+	  symbolOop sig = pool->signature_ref_at(java_index);
+	  jbyte *base = sig->base();
+	  jbyte c = *base;
+	  int handler = H_PUTFIELD_WORD;
+
+	  if (c == 'J' || c == 'D') handler = H_PUTFIELD_DW;
+	  if (c == 'B' || c == 'Z') handler = H_PUTFIELD_B;
+	  if (c == 'C' || c == 'S') handler = H_PUTFIELD_H;
+	  if (c == '[' || c == 'L') handler = H_PUTFIELD_A;
+	  Thumb2_Flush(jinfo);
+	  Thumb2_save_locals(jinfo, stackdepth);
+	  mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+	  mov_imm(jinfo->codebuf, ARM_R1, index);
+	  blx(jinfo->codebuf, handlers[handler]);
+	  Thumb2_restore_locals(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	  break;
+	}
+
+	TosState tos_type = cache->flag_state();
+	int field_offset = cache->f2();
+
+	if (tos_type == ltos || tos_type == dtos) {
+	  Reg r_lo, r_hi;
+	  Thumb2_Fill(jinfo, 3);
+	  r_lo = POP(jstack);
+	  r_hi = POP(jstack);
+	  r_obj = POP(jstack);
+	  strd_imm(jinfo->codebuf, r_lo, r_hi, r_obj, field_offset, 1, 0);
+	} else {
+	  Reg r;
+	  Thumb2_Fill(jinfo, 2);
+	  r = POP(jstack);
+	  r_obj = POP(jstack);
+	  if (tos_type == btos)
+	    strb_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	  else if (tos_type == ctos | tos_type == stos)
+	    strh_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	  else {
+	    str_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	    if (tos_type == atos) {
+	      Thumb2_Flush(jinfo);
+	      mov_reg(jinfo->codebuf, ARM_R0, r_obj);
+	      bl(jinfo->codebuf, handlers[H_APUTFIELD]);
+	    }
+	  }
+	}
+	break;
+      }
+
+      case opc_putstatic: {
+	constantPoolCacheOop  cp = jinfo->method->constants()->cache();
+        ConstantPoolCacheEntry* cache;
+	int index = GET_NATIVE_U2(code_base+bci+1);
+
+        cache = cp->entry_at(index);
+        if (!cache->is_resolved((Bytecodes::Code)opcode)) {
+	  int java_index = GET_JAVA_U2(code_base+bci+1);
+	  constantPoolOop pool = jinfo->method->constants();
+	  symbolOop sig = pool->signature_ref_at(java_index);
+	  jbyte *base = sig->base();
+	  jbyte c = *base;
+	  int handler = H_PUTSTATIC_WORD;
+
+	  if (c == 'J' || c == 'D') handler = H_PUTSTATIC_DW;
+	  if (c == 'B' || c == 'Z') handler = H_PUTSTATIC_B;
+	  if (c == 'C' || c == 'S') handler = H_PUTSTATIC_H;
+	  if (c == '[' || c == 'L') handler = H_PUTSTATIC_A;
+	  Thumb2_Flush(jinfo);
+	  Thumb2_save_locals(jinfo, stackdepth);
+	  mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+	  mov_imm(jinfo->codebuf, ARM_R1, index);
+	  blx(jinfo->codebuf, handlers[handler]);
+	  Thumb2_restore_locals(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	  break;
+	}
+
+	TosState tos_type = cache->flag_state();
+	int field_offset = cache->f2();
+	Reg r_obj;
+
+	if (tos_type == ltos || tos_type == dtos) {
+	  Reg r_lo, r_hi;
+	  Thumb2_Fill(jinfo, 2);
+	  r_lo = POP(jstack);
+	  r_hi = POP(jstack);
+	  Thumb2_Spill(jinfo, 1, (1<<r_lo)|(1<<r_hi));
+	  r_obj = JSTACK_PREFER(jstack, ~((1<<r_lo)|(1<<r_hi)));
+	  JASSERT(r_obj != r_lo && r_obj != r_hi, "corruption in putstatic");
+	  ldr_imm(jinfo->codebuf, r_obj, Ristate, ISTATE_CONSTANTS, 1, 0);
+	  ldr_imm(jinfo->codebuf, r_obj, r_obj, CP_OFFSET + (index << 4) + 4, 1, 0);
+	  strd_imm(jinfo->codebuf, r_lo, r_hi, r_obj, field_offset, 1, 0);
+	} else {
+	  Reg r;
+	  Thumb2_Fill(jinfo, 1);
+	  r = POP(jstack);
+	  Thumb2_Spill(jinfo, 1, (1<<r));
+	  r_obj = JSTACK_PREFER(jstack, ~(1<<r));
+	  JASSERT(r_obj != r, "corruption in putstatic");
+	  ldr_imm(jinfo->codebuf, r_obj, Ristate, ISTATE_CONSTANTS, 1, 0);
+	  ldr_imm(jinfo->codebuf, r_obj, r_obj, CP_OFFSET + (index << 4) + 4, 1, 0);
+	  if (tos_type == btos)
+	    strb_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	  else if (tos_type == ctos | tos_type == stos)
+	    strh_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	  else {
+	    str_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	    if (tos_type == atos) {
+	      Thumb2_Flush(jinfo);
+	      mov_reg(jinfo->codebuf, ARM_R0, r_obj);
+	      bl(jinfo->codebuf, handlers[H_APUTFIELD]);
+	    }
+	  }
+	}
+	break;
+      }
+
+      case opc_invokestatic:
+      case opc_invokespecial: {
+	constantPoolCacheOop  cp = jinfo->method->constants()->cache();
+        ConstantPoolCacheEntry* cache;
+	int index = GET_NATIVE_U2(code_base+bci+1);
+	unsigned loc;
+	methodOop callee;
+
+        cache = cp->entry_at(index);
+        if (!cache->is_resolved((Bytecodes::Code)opcode)) {
+	  Thumb2_Flush(jinfo);
+	  Thumb2_invoke_save(jinfo, stackdepth);
+	  mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+	  mov_imm(jinfo->codebuf, ARM_R1, index);
+	  blx(jinfo->codebuf,
+	    handlers[opcode == opc_invokestatic ? H_INVOKESTATIC : H_INVOKESPECIAL]);
+	  Thumb2_invoke_restore(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	  break;
+	}
+
+	callee = (methodOop)cache->f1();
+	if (callee->is_accessor()) {
+	  u1 *code = callee->code_base();
+	  int index = GET_NATIVE_U2(&code[2]);
+	  constantPoolCacheOop callee_cache = callee->constants()->cache();
+	  ConstantPoolCacheEntry *entry = callee_cache->entry_at(index);
+	  Reg r_obj, r;
+
+	  if (entry->is_resolved(Bytecodes::_getfield)) {
+#if 0
+	    tty->print("Inlining accessor (opcode = %s) ", opcode == opc_invokestatic ? "invokestatic" : "invokespecial");
+	    callee->print_short_name(tty);
+	    tty->print("\n");
+#endif
+	    JASSERT(cache->parameter_size() == 1, "not 1 parameter to accessor");
+
+	    TosState tos_type = entry->flag_state();
+	    int field_offset = entry->f2();
+
+	    JASSERT(tos_type == btos || tos_type == ctos || tos_type == stos || tos_type == atos || tos_type == itos, "not itos or atos");
+
+	    Thumb2_Fill(jinfo, 1);
+	    r_obj = POP(jstack);
+	    Thumb2_Spill(jinfo, 1, 0);
+	    r = JSTACK_REG(jstack);
+	    PUSH(jstack, r);
+	    if (tos_type == btos)
+	      ldrb_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	    else if (tos_type == ctos)
+	      ldrh_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	    else if (tos_type == stos)
+	      ldrsh_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	    else
+	      ldr_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	    break;
+	  }
+	}
+
+	Thumb2_Flush(jinfo);
+  ldr_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_METHOD, 1, 0);
+	ldr_imm(jinfo->codebuf, ARM_R0, Ristate, ISTATE_CONSTANTS, 1, 0);
+	mov_imm(jinfo->codebuf, ARM_R1, 0);
+  ldr_imm(jinfo->codebuf, ARM_R2, ARM_R2, METHOD_CONSTMETHOD, 1, 0);
+	if (opcode == opc_invokespecial)
+	  ldr_imm(jinfo->codebuf, ARM_R3, Rstack, (cache->parameter_size()-1) * sizeof(int), 1, 0);
+	ldr_imm(jinfo->codebuf, ARM_R0, ARM_R0, CP_OFFSET + (index << 4) + 4, 1, 0);
+  add_imm(jinfo->codebuf, ARM_R2, ARM_R2, bci+CONSTMETHOD_CODEOFFSET);
+	if (opcode == opc_invokespecial)
+	  ldr_imm(jinfo->codebuf, ARM_R3, ARM_R3, 0, 1, 0); // Null pointer check - cbz better?
+	str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	ldr_imm(jinfo->codebuf, ARM_R1, ARM_R0, METHOD_FROM_INTERPRETED, 1, 0);
+  str_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_BCP, 1, 0);
+	str_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
+	  Thumb2_Debug(jinfo, H_DEBUG_METHODCALL);
+	Thumb2_invoke_save(jinfo, stackdepth);
+  sub_imm(jinfo->codebuf, Rstack, Rstack, 4);
+	ldr_imm(jinfo->codebuf, ARM_R3, ARM_R1, 0, 1, 0);
+	mov_reg(jinfo->codebuf, ARM_R2, Rthread);
+  str_imm(jinfo->codebuf, Rstack, Ristate, ISTATE_STACK, 1, 0);
+add_imm(jinfo->codebuf, ARM_R3, ARM_R3, CODE_ALIGN_SIZE);
+//	enter_leave(jinfo->codebuf, 0);
+	blx_reg(jinfo->codebuf, ARM_R3);
+//	enter_leave(jinfo->codebuf, 1);
+  ldr_imm(jinfo->codebuf, Rthread, Ristate, ISTATE_THREAD, 1, 0);
+#ifdef USE_RLOCAL
+  ldr_imm(jinfo->codebuf, Rlocals, Ristate, ISTATE_LOCALS, 1, 0);
+#endif
+	ldr_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
+	ldr_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_STACK_LIMIT, 1, 0);
+	JASSERT(!(bc_stackinfo[bci+len] & BC_COMPILED), "code already compiled for this bytecode?");
+	Thumb2_invoke_restore(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	ldr_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_TOP_ZERO_FRAME, 1, 0);
+	add_imm(jinfo->codebuf, ARM_R2, ARM_R2, 4);
+	ldr_imm(jinfo->codebuf, ARM_R3, Rthread, THREAD_PENDING_EXC, 1, 0);
+	str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_JAVA_SP, 1, 0);
+	str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	cmp_imm(jinfo->codebuf, ARM_R3, 0);
+	it(jinfo->codebuf, COND_NE, IT_MASK_T);
+	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	break;
+      }
+
+      case opc_invokeinterface: {
+	constantPoolCacheOop  cp = jinfo->method->constants()->cache();
+        ConstantPoolCacheEntry* cache;
+	int index = GET_NATIVE_U2(code_base+bci+1);
+	unsigned loc, loc_inc_ex;
+
+// Currently we just call the unresolved invokeinterface entry for resolved /
+// unresolved alike!
+    Thumb2_Flush(jinfo);
+    Thumb2_invoke_save(jinfo, stackdepth);
+    mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+    mov_imm(jinfo->codebuf, ARM_R1, index);
+    blx(jinfo->codebuf, handlers[H_INVOKEINTERFACE]);
+    Thumb2_invoke_restore(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	break;
+      }
+
+      case opc_invokevirtual: {
+	constantPoolCacheOop  cp = jinfo->method->constants()->cache();
+        ConstantPoolCacheEntry* cache;
+	int index = GET_NATIVE_U2(code_base+bci+1);
+	unsigned loc;
+
+        cache = cp->entry_at(index);
+        if (!cache->is_resolved((Bytecodes::Code)opcode)) {
+	  Thumb2_Flush(jinfo);
+	  Thumb2_invoke_save(jinfo, stackdepth);
+	  mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+	  mov_imm(jinfo->codebuf, ARM_R1, index);
+	  blx(jinfo->codebuf, handlers[H_INVOKEVIRTUAL]);
+	  Thumb2_invoke_restore(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	  break;
+	}
+
+	if (cache->is_vfinal()) {
+	  methodOop callee = (methodOop)cache->f2();
+	  if (callee->is_accessor()) {
+	    u1 *code = callee->code_base();
+	    int index = GET_NATIVE_U2(&code[2]);
+	    constantPoolCacheOop callee_cache = callee->constants()->cache();
+	    ConstantPoolCacheEntry *entry = callee_cache->entry_at(index);
+	    Reg r_obj, r;
+
+	    if (entry->is_resolved(Bytecodes::_getfield)) {
+#if 0
+	      tty->print("Inlining accessor (opcode = invokevfinal) ");
+	      callee->print_short_name(tty);
+	      tty->print("\n");
+#endif
+	      JASSERT(cache->parameter_size() == 1, "not 1 parameter to accessor");
+
+	      TosState tos_type = entry->flag_state();
+	      int field_offset = entry->f2();
+
+	      JASSERT(tos_type == btos || tos_type == ctos || tos_type == stos || tos_type == atos || tos_type == itos, "not itos or atos");
+
+	      Thumb2_Fill(jinfo, 1);
+	      r_obj = POP(jstack);
+	      Thumb2_Spill(jinfo, 1, 0);
+	      r = JSTACK_REG(jstack);
+	      PUSH(jstack, r);
+	      if (tos_type == btos)
+		ldrb_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	      else if (tos_type == ctos)
+		ldrh_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	      else if (tos_type == stos)
+		ldrsh_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	      else
+		ldr_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
+	      break;
+	    }
+	  }
+	}
+
+	Thumb2_Flush(jinfo);
+	if (cache->is_vfinal()) {
+  ldr_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_METHOD, 1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R0, Ristate, ISTATE_CONSTANTS, 1, 0);
+	  mov_imm(jinfo->codebuf, ARM_R1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R3, Rstack, (cache->parameter_size()-1) * sizeof(int), 1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R0, ARM_R0, CP_OFFSET + (index << 4) + 8, 1, 0);
+  ldr_imm(jinfo->codebuf, ARM_R2, ARM_R2, METHOD_CONSTMETHOD, 1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R3, ARM_R3, 0, 1, 0); // Null pointer check - cbz better?
+	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R1, ARM_R0, METHOD_FROM_INTERPRETED, 1, 0);
+  add_imm(jinfo->codebuf, ARM_R2, ARM_R2, bci+CONSTMETHOD_CODEOFFSET);
+	  str_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
+	  Thumb2_Debug(jinfo, H_DEBUG_METHODCALL);
+	Thumb2_invoke_save(jinfo, stackdepth);
+  sub_imm(jinfo->codebuf, Rstack, Rstack, 4);
+	  ldr_imm(jinfo->codebuf, ARM_R3, ARM_R1, 0, 1, 0);
+  str_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_BCP, 1, 0);
+	  mov_reg(jinfo->codebuf, ARM_R2, Rthread);
+  str_imm(jinfo->codebuf, Rstack, Ristate, ISTATE_STACK, 1, 0);
+add_imm(jinfo->codebuf, ARM_R3, ARM_R3, CODE_ALIGN_SIZE);
+//	  enter_leave(jinfo->codebuf, 0);
+	  blx_reg(jinfo->codebuf, ARM_R3);
+//	  enter_leave(jinfo->codebuf, 1);
+  ldr_imm(jinfo->codebuf, Rthread, Ristate, ISTATE_THREAD, 1, 0);
+#ifdef USE_RLOCAL
+  ldr_imm(jinfo->codebuf, Rlocals, Ristate, ISTATE_LOCALS, 1, 0);
+#endif
+	  ldr_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_STACK_LIMIT, 1, 0);
+	JASSERT(!(bc_stackinfo[bci+len] & BC_COMPILED), "code already compiled for this bytecode?");
+	Thumb2_invoke_restore(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	  ldr_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_TOP_ZERO_FRAME, 1, 0);
+	  add_imm(jinfo->codebuf, ARM_R2, ARM_R2, 4);
+	  ldr_imm(jinfo->codebuf, ARM_R3, Rthread, THREAD_PENDING_EXC, 1, 0);
+	  str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_JAVA_SP, 1, 0);
+	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	cmp_imm(jinfo->codebuf, ARM_R3, 0);
+	it(jinfo->codebuf, COND_NE, IT_MASK_T);
+	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	  break;
+	} else {
+  ldr_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_METHOD, 1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R3, Rstack, (cache->parameter_size()-1) * sizeof(int), 1, 0);
+  ldr_imm(jinfo->codebuf, ARM_R2, ARM_R2, METHOD_CONSTMETHOD, 1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R3, ARM_R3, 4, 1, 0);
+	  mov_imm(jinfo->codebuf, ARM_R1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R0, ARM_R3, INSTANCEKLASS_VTABLE_OFFSET + cache->f2() * 4, 1, 0);
+  add_imm(jinfo->codebuf, ARM_R2, ARM_R2, bci+CONSTMETHOD_CODEOFFSET);
+	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R1, ARM_R0, METHOD_FROM_INTERPRETED, 1, 0);
+  str_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_BCP, 1, 0);
+	  str_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
+	  Thumb2_Debug(jinfo, H_DEBUG_METHODCALL);
+	Thumb2_invoke_save(jinfo, stackdepth);
+  sub_imm(jinfo->codebuf, Rstack, Rstack, 4);
+	  ldr_imm(jinfo->codebuf, ARM_R3, ARM_R1, 0, 1, 0);
+	  mov_reg(jinfo->codebuf, ARM_R2, Rthread);
+  str_imm(jinfo->codebuf, Rstack, Ristate, ISTATE_STACK, 1, 0);
+add_imm(jinfo->codebuf, ARM_R3, ARM_R3, CODE_ALIGN_SIZE);
+//	  enter_leave(jinfo->codebuf, 0);
+	  blx_reg(jinfo->codebuf, ARM_R3);
+//	  enter_leave(jinfo->codebuf, 1);
+  ldr_imm(jinfo->codebuf, Rthread, Ristate, ISTATE_THREAD, 1, 0);
+#ifdef USE_RLOCAL
+  ldr_imm(jinfo->codebuf, Rlocals, Ristate, ISTATE_LOCALS, 1, 0);
+#endif
+	  ldr_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
+	  ldr_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_STACK_LIMIT, 1, 0);
+	JASSERT(!(bc_stackinfo[bci+len] & BC_COMPILED), "code already compiled for this bytecode?");
+	Thumb2_invoke_restore(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	  ldr_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_TOP_ZERO_FRAME, 1, 0);
+	  add_imm(jinfo->codebuf, ARM_R2, ARM_R2, 4);
+	  ldr_imm(jinfo->codebuf, ARM_R3, Rthread, THREAD_PENDING_EXC, 1, 0);
+	  str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_JAVA_SP, 1, 0);
+	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	cmp_imm(jinfo->codebuf, ARM_R3, 0);
+	it(jinfo->codebuf, COND_NE, IT_MASK_T);
+	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	}
+	break;
+      }
+
+      case opc_jsr_w:
+      case opc_jsr: {
+	Thumb2_Jsr(jinfo , bci, stackdepth);
+	break;
+      }
+
+      case opc_ret: {
+	Thumb2_Exit(jinfo, H_RET, bci, stackdepth);
+	break;
+      }
+
+      case opc_athrow:
+	Thumb2_Exit(jinfo, H_ATHROW, bci, stackdepth);
+	break;
+
+      case opc_goto: {
+	int offset = GET_JAVA_S2(jinfo->code_base + bci + 1);
+	Thumb2_Flush(jinfo);
+	bci = Thumb2_Goto(jinfo, bci, offset, len);
+	len = 0;
+	break;
+      }
+
+      case opc_goto_w: {
+	int offset = GET_JAVA_U4(jinfo->code_base + bci + 1);
+	Thumb2_Flush(jinfo);
+	bci = Thumb2_Goto(jinfo, bci, offset, len);
+	len = 0;
+	break;
+      }
+
+      case opc_ifeq:
+      case opc_ifne:
+      case opc_iflt:
+      case opc_ifge:
+      case opc_ifgt:
+      case opc_ifle:
+      case opc_ifnull:
+      case opc_ifnonnull: {
+	Reg r;
+	unsigned cond = opcode - opc_ifeq;
+	if (opcode >= opc_ifnull) cond = opcode - opc_ifnull;
+	Thumb2_Fill(jinfo, 1);
+	r = POP(jstack);
+	Thumb2_Flush(jinfo);
+	cmp_imm(jinfo->codebuf, r, 0);
+	bci = Thumb2_Branch(jinfo, bci, cond);
+	len = 0;
+	break;
+      }
+
+      case opc_if_icmpeq:
+      case opc_if_icmpne:
+      case opc_if_icmplt:
+      case opc_if_icmpge:
+      case opc_if_icmpgt:
+      case opc_if_icmple:
+      case opc_if_acmpeq:
+      case opc_if_acmpne: {
+	Reg r_lho, r_rho;
+	unsigned cond = opcode - opc_if_icmpeq;
+	if (opcode >= opc_if_acmpeq) cond = opcode - opc_if_acmpeq;
+	Thumb2_Fill(jinfo, 2);
+	r_rho = POP(jstack);
+	r_lho = POP(jstack);
+	Thumb2_Flush(jinfo);
+	cmp_reg(jinfo->codebuf, r_lho, r_rho);
+	bci = Thumb2_Branch(jinfo, bci, cond);
+	len = 0;
+	break;
+      }
+
+      case opc_return:
+      case opc_dreturn:
+      case opc_lreturn:
+      case opc_ireturn:
+      case opc_freturn:
+      case opc_areturn:
+	Thumb2_Return(jinfo, opcode);
+	if (!jinfo->compiled_return) jinfo->compiled_return = bci;
+	break;
+
+      case opc_new: {
+	unsigned loc;
+
+	Thumb2_Flush(jinfo);
+	mov_imm(jinfo->codebuf, ARM_R1, GET_JAVA_U2(code_base+bci+1));
+	mov_imm(jinfo->codebuf, ARM_R3, bci+CONSTMETHOD_CODEOFFSET);
+      Thumb2_save_locals(jinfo, stackdepth);
+	bl(jinfo->codebuf, handlers[H_NEW]);
+      Thumb2_restore_locals(jinfo, stackdepth);
+	cmp_imm(jinfo->codebuf, ARM_R0, 0);
+	it(jinfo->codebuf, COND_EQ, IT_MASK_T);
+	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	PUSH(jstack, ARM_R0);
+	break;
+      }
+
+      case opc_aastore: {
+	Reg src[3], dst[3];
+	unsigned loc;
+
+	Thumb2_Fill(jinfo, 3);
+	src[0] = POP(jstack);	// value
+	src[1] = POP(jstack);	// index
+	src[2] = POP(jstack);	// arrayref
+	Thumb2_Flush(jinfo);
+	dst[0] = ARM_R1;
+	dst[1] = ARM_R2;
+	dst[2] = ARM_R3;
+	mov_multiple(jinfo->codebuf, dst, src, 3);
+	mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+      Thumb2_save_locals(jinfo, stackdepth - 3);	// 3 args popped above
+	bl(jinfo->codebuf, handlers[H_AASTORE]);
+      Thumb2_restore_locals(jinfo, stackdepth - 3);
+	cmp_imm(jinfo->codebuf, ARM_R0, 0);
+	it(jinfo->codebuf, COND_NE, IT_MASK_T);
+	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	break;
+      }
+
+      case opc_instanceof: {
+	unsigned loc;
+	Reg r;
+
+	Thumb2_Fill(jinfo, 1);
+	r = POP(jstack);
+	Thumb2_Flush(jinfo);
+	mov_reg(jinfo->codebuf, ARM_R2, r);
+	mov_imm(jinfo->codebuf, ARM_R1, GET_JAVA_U2(code_base+bci+1));
+	mov_imm(jinfo->codebuf, ARM_R3, bci+CONSTMETHOD_CODEOFFSET);
+      Thumb2_save_locals(jinfo, stackdepth - 1);
+	bl(jinfo->codebuf, handlers[H_INSTANCEOF]);
+      Thumb2_restore_locals(jinfo, stackdepth - 1);	// 1 arg popped above
+	cmp_imm(jinfo->codebuf, ARM_R0, (unsigned)-1);
+	it(jinfo->codebuf, COND_EQ, IT_MASK_T);
+	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	PUSH(jstack, ARM_R0);
+	break;
+      }
+
+      case opc_checkcast: {
+	unsigned loc;
+	Reg r;
+
+	Thumb2_Fill(jinfo, 1);
+	r = TOS(jstack);
+	Thumb2_Flush(jinfo);
+	mov_reg(jinfo->codebuf, ARM_R2, r);
+	mov_imm(jinfo->codebuf, ARM_R1, GET_JAVA_U2(code_base+bci+1));
+	mov_imm(jinfo->codebuf, ARM_R3, bci+CONSTMETHOD_CODEOFFSET);
+      Thumb2_save_locals(jinfo, stackdepth);
+	bl(jinfo->codebuf, handlers[H_CHECKCAST]);
+      Thumb2_restore_locals(jinfo, stackdepth);
+	cmp_imm(jinfo->codebuf, ARM_R0, 0);
+	it(jinfo->codebuf, COND_NE, IT_MASK_T);
+	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	break;
+      }
+
+      case opc_newarray: {
+	Reg r;
+	unsigned loc;
+
+	Thumb2_Fill(jinfo, 1);
+	r = POP(jstack);
+	Thumb2_Flush(jinfo);
+	mov_reg(jinfo->codebuf, ARM_R2, r);
+	mov_imm(jinfo->codebuf, ARM_R1, code_base[bci+1]);
+	mov_imm(jinfo->codebuf, ARM_R3, bci+CONSTMETHOD_CODEOFFSET);
+      Thumb2_save_locals(jinfo, stackdepth-1);
+	bl(jinfo->codebuf, handlers[H_NEWARRAY]);
+      Thumb2_restore_locals(jinfo, stackdepth-1);
+	ldr_imm(jinfo->codebuf, ARM_R0, Rthread, THREAD_VM_RESULT, 1, 0);
+	mov_imm(jinfo->codebuf, ARM_R2, 0);
+  	str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_VM_RESULT, 1, 0);
+	cmp_imm(jinfo->codebuf, ARM_R0, 0);
+	it(jinfo->codebuf, COND_EQ, IT_MASK_T);
+	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	PUSH(jstack, ARM_R0);
+	break;
+      }
+
+      case opc_anewarray: {
+	Reg r;
+	unsigned loc;
+
+	Thumb2_Fill(jinfo, 1);
+	r = POP(jstack);
+	Thumb2_Flush(jinfo);
+	mov_reg(jinfo->codebuf, ARM_R3, r);
+	mov_imm(jinfo->codebuf, ARM_R2, GET_JAVA_U2(code_base+bci+1));
+	mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+      Thumb2_save_locals(jinfo, stackdepth-1);
+	bl(jinfo->codebuf, handlers[H_ANEWARRAY]);
+      Thumb2_restore_locals(jinfo, stackdepth-1);
+	ldr_imm(jinfo->codebuf, ARM_R0, Rthread, THREAD_VM_RESULT, 1, 0);
+	mov_imm(jinfo->codebuf, ARM_R2, 0);
+  	str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_VM_RESULT, 1, 0);
+	cmp_imm(jinfo->codebuf, ARM_R0, 0);
+	it(jinfo->codebuf, COND_EQ, IT_MASK_T);
+	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	PUSH(jstack, ARM_R0);
+	break;
+      }
+
+      case opc_multianewarray: {
+	unsigned loc;
+
+	Thumb2_Flush(jinfo);
+	mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
+	mov_imm(jinfo->codebuf, ARM_R1, code_base[bci+3] * 4);
+      Thumb2_save_locals(jinfo, stackdepth);
+	bl(jinfo->codebuf, handlers[H_MULTIANEWARRAY]);
+      Thumb2_restore_locals(jinfo, stackdepth - code_base[bci+3]);
+	ldr_imm(jinfo->codebuf, ARM_R0, Rthread, THREAD_VM_RESULT, 1, 0);
+	mov_imm(jinfo->codebuf, ARM_R2, 0);
+  	str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_VM_RESULT, 1, 0);
+	cmp_imm(jinfo->codebuf, ARM_R0, 0);
+	it(jinfo->codebuf, COND_EQ, IT_MASK_T);
+	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
+	PUSH(jstack, ARM_R0);
+	break;
+      }
+
+      case opc_arraylength: {
+	Reg r_obj, r_len;
+
+	Thumb2_Fill(jinfo, 1);
+	r_obj = POP(jstack);
+	Thumb2_Spill(jinfo, 1, 0);
+	r_len = JSTACK_REG(jstack);
+	PUSH(jstack, r_len);
+	ldr_imm(jinfo->codebuf, r_len, r_obj, 8, 1, 0);
+	break;
+      }
+
+      case opc_lookupswitch: {
+	unsigned w;
+	unsigned nbci;
+	int def;
+	int npairs;	// The Java spec says signed but must be >= 0??
+	unsigned *table, *tablep;
+	unsigned r;
+	unsigned oldidx;
+	unsigned table_loc;
+	int i;
+
+	nbci = bci & ~3;
+	w = *(unsigned int *)(code_base + nbci + 4);
+	def = bci + (int)BYTESEX_REVERSE(w);
+	w = *(unsigned int *)(code_base + nbci + 8);
+	npairs = (int)BYTESEX_REVERSE(w);
+	table = (unsigned int *)(code_base + nbci + 12);
+
+	Thumb2_Fill(jinfo, 1);
+	r = POP(jstack);
+
+	table_loc = out_loc(jinfo->codebuf);
+	for (i = 0, tablep = table; i < npairs; i++) {
+	  unsigned match;
+
+	  w = tablep[0];
+	  match = BYTESEX_REVERSE(w);
+	  tablep += 2;
+	  cmp_imm(jinfo->codebuf, r, match);
+	  t2_bug_align(jinfo->codebuf);
+	  forward_32(jinfo->codebuf);
+	}
+	t2_bug_align(jinfo->codebuf);
+	forward_32(jinfo->codebuf);
+	Thumb2_codegen(jinfo, bci+len);
+
+	oldidx = codebuf->idx;
+	codebuf->idx = table_loc >> 1;
+	for (i = 0, tablep = table; i < npairs; i++) {
+	  unsigned match;
+	  unsigned dest;
+	  unsigned loc;
+
+	  w = tablep[0];
+	  match = BYTESEX_REVERSE(w);
+	  w = tablep[1];
+	  dest = bci + (int)BYTESEX_REVERSE(w);
+	  tablep += 2;
+	  cmp_imm(jinfo->codebuf, r, match);
+	  JASSERT(jinfo->bc_stackinfo[dest] & BC_COMPILED, "code not compiled");
+	  t2_bug_align(jinfo->codebuf);
+	  loc = forward_32(jinfo->codebuf);
+	  branch_patch(jinfo->codebuf, COND_EQ, loc, jinfo->bc_stackinfo[dest] & ~BC_FLAGS_MASK);
+	}
+	JASSERT(jinfo->bc_stackinfo[def] & BC_COMPILED, "default in lookupswitch not compiled");
+	t2_bug_align(jinfo->codebuf);
+	branch_uncond_patch(jinfo->codebuf, out_loc(jinfo->codebuf), jinfo->bc_stackinfo[def] & ~BC_FLAGS_MASK);
+	codebuf->idx = oldidx;
+
+	bci = (unsigned)-1;
+	len = 0;
+
+	break;
+      }
+
+      case opc_tableswitch: {
+	int low, high, i;
+	unsigned w;
+	unsigned *table, *tablep;
+	unsigned nbci;
+	int def;
+	unsigned loc, table_loc;
+	unsigned r, rs;
+	unsigned oldidx;
+	unsigned negative_offsets, negative_branch_table;
+
+	nbci = bci & ~3;
+	w = *(unsigned int *)(code_base + nbci + 8);
+	low = (int)BYTESEX_REVERSE(w);
+	w = *(unsigned int *)(code_base + nbci + 12);
+	high = (int)BYTESEX_REVERSE(w);
+	w = *(unsigned int *)(code_base + nbci + 4);
+	def = bci + (int)BYTESEX_REVERSE(w);
+	table = (unsigned int *)(code_base + nbci + 16);
+
+	Thumb2_Fill(jinfo, 1);
+	rs = POP(jstack);
+	r = Thumb2_Tmp(jinfo, (1<<rs));
+	sub_imm(jinfo->codebuf, r, rs, low);
+	cmp_imm(jinfo->codebuf, r, (high-low)+1);
+	loc = 0;
+	if (jinfo->bc_stackinfo[def] & BC_COMPILED)
+	  branch(jinfo->codebuf, COND_CS, jinfo->bc_stackinfo[def] & ~BC_FLAGS_MASK);
+	else
+	  loc = forward_32(jinfo->codebuf);
+	tbh(jinfo->codebuf, ARM_PC, r);
+	table_loc = out_loc(jinfo->codebuf);
+	negative_offsets = 0;
+	for (i = low, tablep = table; i <= high; i++) {
+	  int offset;
+	  w = *tablep++;
+	  offset = (int)BYTESEX_REVERSE(w);
+	  if (offset < 0) negative_offsets++;
+	  out_16(jinfo->codebuf, 0);
+	}
+	negative_branch_table = out_loc(jinfo->codebuf);
+	for (i = 0; i < (int)negative_offsets; i++) {
+	  t2_bug_align(jinfo->codebuf);
+	  out_16x2(jinfo->codebuf, 0);
+	}
+
+	Thumb2_codegen(jinfo, bci+len);
+
+	if (loc) {
+	  JASSERT(jinfo->bc_stackinfo[def] & BC_COMPILED, "def not compiled in tableswitch");
+	  branch_patch(jinfo->codebuf, COND_CS, loc, jinfo->bc_stackinfo[def] & ~BC_FLAGS_MASK);
+	}
+
+	oldidx = codebuf->idx;
+	codebuf->idx = table_loc >> 1;
+	for (i = low, tablep = table; i <= high; i++) {
+	  unsigned dest;
+	  int offset;
+
+	  w = *tablep++;
+	  offset = (int)BYTESEX_REVERSE(w);
+	  dest = bci + offset;
+	  JASSERT(jinfo->bc_stackinfo[dest] & BC_COMPILED, "code not compiled");
+	  dest = jinfo->bc_stackinfo[dest] & ~BC_FLAGS_MASK;
+	  if (offset < 0) {
+	    unsigned oldidx;
+	    out_16(jinfo->codebuf, (negative_branch_table >> 1) - (table_loc >> 1));
+	    PATCH(negative_branch_table) {
+	      t2_bug_align(jinfo->codebuf);
+	      branch_uncond_patch(jinfo->codebuf, out_loc(jinfo->codebuf), dest);
+	      negative_branch_table = out_loc(jinfo->codebuf);
+	    } HCTAP;
+	  } else {
+	    JASSERT((dest & 1) == 0 && (table_loc & 1) == 0, "unaligned code");
+	    offset = (dest >> 1) - (table_loc >> 1);
+	    JASSERT(offset < 65536, "offset too big in tableswitch");
+	    out_16(jinfo->codebuf, offset);
+	  }
+	}
+	codebuf->idx = oldidx;
+	bci = (unsigned)-1;
+	len = 0;
+	break;
+      }
+
+      case opc_wide: {
+	unsigned local = GET_JAVA_U2(code_base + bci + 2);
+	opcode = code_base[bci+1];
+	if (opcode == opc_iinc) {
+	  int constant = GET_JAVA_S2(code_base + bci + 4);
+	  unsigned r = jinfo->jregs->r_local[local];
+	  
+	  if (!r) {
+	    int nlocals = jinfo->method->max_locals();
+	    r = ARM_IP;
+	    stackdepth -= jstack->depth;
+	    if (jinfo->method->is_synchronized()) stackdepth += frame::interpreter_frame_monitor_size();
+	    load_local(jinfo, r, local, stackdepth);
+	    add_imm(jinfo->codebuf, r, r, constant);
+	    store_local(jinfo, r, local, stackdepth);
+	  } else {
+	    Thumb2_Corrupt(jinfo, r, 0);
+	    add_imm(jinfo->codebuf, r, r, constant);
+	  }
+	} else if (opcode == opc_ret) {
+	  Thumb2_Exit(jinfo, H_RET, bci, stackdepth);
+	} else {
+	  if (opcode == opc_iload ||
+	  	opcode == opc_fload || opcode == opc_aload)
+	    Thumb2_Load(jinfo, local, stackdepth);
+	  else if (opcode == opc_lload || opcode == opc_dload)
+	    Thumb2_LoadX2(jinfo, local, stackdepth);
+	  else if (opcode == opc_istore ||
+	  	opcode == opc_fstore || opcode == opc_astore)
+	    Thumb2_Store(jinfo, local, stackdepth);
+	  else if (opcode == opc_lstore || opcode == opc_dstore)
+	    Thumb2_StoreX2(jinfo, local, stackdepth);
+	  else fatal1("Undefined wide opcode %d\n", opcode);
+	}
+	break;
+      }
+
+      default:
+	printf("unknown bytecode = %d\n", opcode);
+	JASSERT(0, "unknown bytecode");
+	break;
+    }
+    bci += len;
+#ifdef T2EE_PRINT_DISASS
+    if (len == 0) {
+      if (start_idx == jinfo->codebuf->idx) start_bci[start_idx] = -1;
+    } else
+      end_bci[start_idx] = bci;
+#endif
+  }
+}
+
+void Thumb2_tablegen(Thumb2_Info *jinfo)
+{
+  unsigned code_size = jinfo->code_size;
+  jubyte *code_base = jinfo->code_base;
+  unsigned *bc_stackinfo = jinfo->bc_stackinfo;
+  unsigned bci;
+  unsigned *count_pos = (unsigned *)out_pos(jinfo->codebuf);
+  unsigned count = 0;
+
+  out_32(jinfo->codebuf, 0);
+  bc_stackinfo[0] |= BC_BACK_TARGET;
+  for (bci = 0; bci < code_size;) {
+    unsigned stackinfo = bc_stackinfo[bci];
+    unsigned bytecodeinfo;
+    unsigned opcode;
+
+    if (stackinfo & BC_BACK_TARGET) {
+      unsigned code_offset = (stackinfo & ~BC_FLAGS_MASK) >> 1;
+      JASSERT(stackinfo & BC_COMPILED, "back branch target not compiled???");
+      JASSERT(code_offset < (1<<16), "oops, codesize too big");
+      out_32(jinfo->codebuf, (bci << 16) | code_offset);
+      count++;
+    }
+
+    opcode = code_base[bci];
+    bytecodeinfo = bcinfo[opcode];
+    if (!BCI_SPECIAL(bytecodeinfo)) {
+      bci += BCI_LEN(bytecodeinfo);
+      continue;
+    } else {
+      int len = Bytecodes::length_for((Bytecodes::Code)opcode);
+      if (len <= 0) len = Bytecodes::special_length_at((address)(code_base+bci), (address)(code_base+code_size));
+      bci += len;
+    }
+  }
+  *count_pos = count;
+}
+
+unsigned Thumb2_osr_from_bci(unsigned slow_entry, unsigned bci)
+{
+  unsigned *osr_table;
+  unsigned count;
+  unsigned i;
+
+  slow_entry &= ~1;
+  osr_table = *(unsigned **)(slow_entry+12);
+  if (!osr_table) return 0;
+  count = *osr_table++;
+  for (i = 0; i < count; i++) {
+    unsigned u = *osr_table++;
+
+    if (bci == (u>>16)) return (u & 0xffff) << 1;
+  }
+  return 0;
+}
+
+static int DebugSwitch = 1;
+
+extern "C" void Debug_Ignore_Safepoints(void)
+{
+	printf("Ignore Safepoints\n");
+}
+
+extern "C" void Debug_Notice_Safepoints(void)
+{
+	printf("Notice Safepoints\n");
+}
+
+extern "C" void Debug_ExceptionReturn(interpreterState istate, intptr_t *stack)
+{
+  JavaThread *thread = istate->thread();
+
+  if (thread->has_pending_exception()) {
+    Handle ex(thread, thread->pending_exception());
+    tty->print_cr("Exception %s", Klass::cast(ex->klass())->external_name());
+  }
+}
+
+extern "C" void Debug_Stack(intptr_t *stack)
+{
+  int i;
+  char msg[16];
+
+  tty->print("  Stack:");
+  for (i = 0; i < 6; i++) {
+    tty->print(" [");
+    sprintf(msg, "%d", i);
+    tty->print(msg);
+    tty->print("] = ");
+    sprintf(msg, "%08x", (int)stack[i]);
+    tty->print(msg);
+  }
+  tty->cr();
+}
+
+extern "C" void Debug_MethodEntry(interpreterState istate, intptr_t *stack, methodOop callee)
+{
+#if 0
+  if (DebugSwitch) {
+    methodOop method = istate->method();
+    tty->print("Entering ");
+    callee->print_short_name(tty);
+    tty->print(" from ");
+    method->print_short_name(tty);
+    tty->cr();
+    Debug_Stack(stack);
+    tty->flush();
+  }
+#endif
+}
+
+extern "C" void Debug_MethodExit(interpreterState istate, intptr_t *stack)
+{
+  if (DebugSwitch) {
+    methodOop method = istate->method();
+    JavaThread *thread = istate->thread();
+    oop exc = thread->pending_exception();
+
+    if (!exc) return;
+    tty->print("Leaving ");
+    method->print_short_name(tty);
+    tty->cr();
+    Debug_Stack(stack);
+    tty->flush();
+    if (exc) tty->print_cr("Exception %s", exc->print_value_string());
+  }
+}
+
+extern "C" void Debug_MethodCall(interpreterState istate, intptr_t *stack, methodOop callee)
+{
+#if 0
+  if (DebugSwitch) {
+    methodOop method = istate->method();
+    tty->print("Calling ");
+    callee->print_short_name(tty);
+    tty->print(" from ");
+    method->print_short_name(tty);
+    tty->cr();
+    Debug_Stack(stack);
+    tty->flush();
+  }
+#endif
+}
+
+extern "C" int Debug_irem_Handler(int a, int b)
+{
+	printf("%d %% %d\n", a, b);
+	return a%b;
+}
+
+extern "C" void Thumb2_Install(methodOop mh, u32 entry);
+
+#define IS_COMPILED(e, cb) ((e) >= (unsigned)(cb) && (e) < (unsigned)(cb) + (cb)->size)
+
+static unsigned compiling;
+static unsigned CompileCount = 0;
+static unsigned MaxCompile = 75;
+
+#define COMPILE_ONLY	0
+#define COMPILE_COUNT	0
+#define DISASS_AFTER	0
+//#define COMPILE_LIST	0
+
+#ifdef COMPILE_LIST
+static const char *compile_list[] = {
+	"java.util.concurrent.ConcurrentHashMap.<init>(IFI)V",
+	0
+};
+#endif
+
+static unsigned compiled_methods = 0;
+
+#ifdef T2EE_PRINT_STATISTICS
+static unsigned bytecodes_compiled = 0;
+static unsigned arm_code_generated = 0;
+static unsigned total_zombie_bytes = 0;
+static clock_t total_compile_time = 0;
+#endif
+
+extern "C" void Thumb2_Clear_Cache(char *base, char *limit);
+
+extern unsigned CPUInfo;
+
+extern "C" unsigned long long Thumb2_Compile(JavaThread *thread, unsigned branch_pc)
+{
+  frame fr = thread->last_frame();
+  methodOop method = fr.interpreter_frame_method();
+  symbolOop name = method->name();
+  symbolOop sig = method->signature();
+  jbyte *base = sig->base();;
+
+  jubyte *code_base = (jubyte *)method->code_base();
+  int code_size = method->code_size();
+  InvocationCounter* ic = method->invocation_counter();
+  InvocationCounter* bc = method->backedge_counter();
+  Thumb2_Info jinfo_str;
+  CodeBuf codebuf_str;
+  Thumb2_Stack jstack_str;
+  Thumb2_Registers jregs_str;
+  int idx;
+  u32 code_handle, slow_entry;
+  u32 osr_entry;
+  Thumb2_CodeBuf *cb = thumb2_codebuf;
+  int compiled_accessor;
+
+  if (!(CPUInfo & ARCH_THUMBEE)) {
+	ic->decay();
+	bc->decay();
+	return 0;
+  }
+
+  slow_entry = *(unsigned *)method->from_interpreted_entry();
+  if (IS_COMPILED(slow_entry, cb)) {
+    osr_entry = Thumb2_osr_from_bci(slow_entry, branch_pc);
+    if (osr_entry == 0) return 0;
+    return ((unsigned long long)(slow_entry + 16)) << 32 | (slow_entry+osr_entry);
+  }
+
+  ic->decay();
+  bc->decay();
+
+  // Dont compile anything with code size >= 32K.
+  // We rely on the bytecode index fitting in 16 bits
+  if (code_size >= 8000)
+	return 0;
+
+  // Dont compile anything with max stack + maxlocal > 1K
+  // The range of an LDR in T2 is -4092..4092
+  // Othersize we have difficulty access the locals from the stack pointer
+  if ((method->max_locals() + method->max_stack()) >= 1000)
+	return 0;
+
+  if (COMPILE_COUNT && compiled_methods == COMPILE_COUNT) return 0;
+
+  if (method->has_monitor_bytecodes()) return 0;
+
+  if (method->has_exception_handler()) return 0;
+
+  if (COMPILE_ONLY) {
+    if (strcmp(name->as_C_string(), COMPILE_ONLY) != 0) return 0;
+  }
+
+#ifdef COMPILE_LIST
+  {
+	const char **argv = compile_list;
+	const char *s;
+	while (s = *argv++) {
+		if (strcmp(s, method->name_and_sig_as_C_string()) == 0)
+			break;
+	}
+	if (!s) return 0;
+  }
+#endif
+
+  if (compiling) return 0;
+  compiling = 1;
+
+#ifdef T2EE_PRINT_STATISTICS
+  clock_t compile_time = clock();
+#endif
+
+#ifdef T2EE_PRINT_COMPILATION
+  if (t2ee_print_compilation) {
+    tty->print("Compiling (%d) ", compiled_methods);
+    tty->print_cr("%s", method->name_and_sig_as_C_string());
+  }
+#endif
+
+  memset(bc_stackinfo, 0, code_size * sizeof(unsigned));
+  memset(locals_info, 0, method->max_locals() * sizeof(unsigned));
+#ifdef T2EE_PRINT_DISASS
+  memset(start_bci, 0xff, sizeof(start_bci));
+  memset(end_bci, 0xff, sizeof(end_bci));
+#endif
+
+  jinfo_str.thread = thread;
+  jinfo_str.method = method;
+  jinfo_str.code_base = code_base;
+  jinfo_str.code_size = code_size;
+  jinfo_str.bc_stackinfo = bc_stackinfo;
+  jinfo_str.locals_info = locals_info;
+  jinfo_str.compiled_return = 0;
+  jinfo_str.zombie_bytes = 0;
+
+  Thumb2_local_info_from_sig(&jinfo_str, method, base);
+
+  Thumb2_pass1(&jinfo_str, 0);
+  Thumb2_pass2(&jinfo_str, 0, 0);
+
+  codebuf_str.codebuf = (unsigned short *)cb->hp;
+  codebuf_str.idx = 0;
+
+  jstack_str.stack = stack;
+  jstack_str.depth = 0;
+
+  memset(r_local, 0, method->max_locals() * sizeof(unsigned));
+
+  jregs_str.r_local = r_local;
+
+  jinfo_str.codebuf = &codebuf_str;
+  jinfo_str.jstack = &jstack_str;
+  jinfo_str.jregs = &jregs_str;
+
+#ifdef USE_RLOCAL
+  {
+    Reg pregs[4];
+    pregs[0] = JAZ_V1;
+    pregs[1] = JAZ_V2;
+    pregs[2] = JAZ_V4;
+    pregs[3] = JAZ_V5;
+    Thumb2_RegAlloc(&jinfo_str, pregs, 4);
+  }
+#else
+  {
+    Reg pregs[5];
+    pregs[0] = JAZ_V1;
+    pregs[1] = JAZ_V2;
+    pregs[2] = JAZ_V3;
+    pregs[3] = JAZ_V4;
+    pregs[4] = JAZ_V5;
+    Thumb2_RegAlloc(&jinfo_str, pregs, 5);
+  }
+#endif
+
+  slow_entry = out_align(&codebuf_str, CODE_ALIGN);
+
+  cb->hp += codebuf_str.idx * 2;
+  codebuf_str.codebuf = (unsigned short *)cb->hp;
+  codebuf_str.idx = 0;
+
+  compiled_accessor = 0;
+  if (method->is_accessor() && Thumb2_Accessor(&jinfo_str)) {
+    compiled_accessor = 1;
+  } else {
+    Thumb2_Enter(&jinfo_str);
+    Thumb2_codegen(&jinfo_str, 0);
+  }
+
+#ifdef T2EE_PRINT_DISASS
+  if (DISASS_AFTER == 0 || compiled_methods >= DISASS_AFTER)
+    if (t2ee_print_disass)
+	Thumb2_disass(&jinfo_str);
+#endif
+
+  Thumb2_Clear_Cache(cb->hp, cb->hp + codebuf_str.idx * 2);
+
+#ifdef T2EE_PRINT_STATISTICS
+  compile_time = clock() - compile_time;
+  total_compile_time += compile_time;
+
+  if (t2ee_print_statistics) {
+    unsigned codegen = codebuf_str.idx * 2;
+    bytecodes_compiled += code_size;
+    arm_code_generated += codegen;
+    total_zombie_bytes += jinfo_str.zombie_bytes;
+    tty->print("%d bytecodes => %d bytes code in %.2f sec, totals: %d => %d in %.2f sec\n",
+      code_size, codegen, (double)compile_time/(double)CLOCKS_PER_SEC,
+    bytecodes_compiled, arm_code_generated, (double)total_compile_time/(double)CLOCKS_PER_SEC);
+  }
+#endif
+
+  code_handle = out_align(&codebuf_str, sizeof(address));
+
+  out_32(&codebuf_str, slow_entry + 1);
+
+  if (!compiled_accessor) {
+    unsigned osr_entry_table = out_pos(jinfo_str.codebuf);
+
+    Thumb2_tablegen(&jinfo_str);
+
+    *(unsigned *)(slow_entry + 12) = osr_entry_table;
+  }
+
+  cb->hp += codebuf_str.idx * 2;
+
+  Thumb2_Install(method, code_handle);
+
+  compiled_methods++;
+
+  compiling = 0;
+
+  osr_entry = Thumb2_osr_from_bci(slow_entry, branch_pc);
+
+  if (osr_entry == 0) return 0;
+
+  return ((unsigned long long)(slow_entry + 16 + 1)) << 32 | (slow_entry+osr_entry+1);
+}
+
+extern "C" void Thumb2_DivZero_Handler(void);
+extern "C" void Thumb2_ArrayBounds_Handler(void);
+extern "C" void Thumb2_Handle_Exception(void);
+extern "C" void Thumb2_Exit_To_Interpreter(void);
+
+extern "C" void __divsi3(void);
+extern "C" void __aeabi_ldivmod(void);
+extern "C" void __aeabi_i2f(void);
+extern "C" void __aeabi_i2d(void);
+extern "C" void __aeabi_l2f(void);
+extern "C" void __aeabi_l2d(void);
+extern "C" void __aeabi_f2d(void);
+extern "C" void __aeabi_d2f(void);
+extern "C" void Helper_new(void);
+extern "C" void Helper_instanceof(void);
+extern "C" void Helper_checkcast(void);
+extern "C" void Helper_aastore(void);
+extern "C" void Helper_aputfield(void);
+extern "C" void Helper_synchronized_enter(void);
+extern "C" void Helper_synchronized_exit(void);
+
+extern "C" void _ZN13SharedRuntime3f2iEf(void);
+extern "C" void _ZN13SharedRuntime3f2lEf(void);
+extern "C" void _ZN13SharedRuntime3d2iEd(void);
+extern "C" void _ZN13SharedRuntime3d2lEd(void);
+extern "C" void _ZN18InterpreterRuntime8newarrayEP10JavaThread9BasicTypei(void);
+extern "C" void _ZN18InterpreterRuntime9anewarrayEP10JavaThreadP19constantPoolOopDescii(void);
+extern "C" void _ZN18InterpreterRuntime14multianewarrayEP10JavaThreadPi(void);
+extern "C" void _ZN18InterpreterRuntime3ldcEP10JavaThreadb(void);
+
+extern char Thumb2_stubs[];
+extern char Thumb2_stubs_end[];
+extern char Thumb2_idiv_stub[];
+extern char Thumb2_irem_stub[];
+extern char Thumb2_invokeinterface_stub[];
+extern char Thumb2_invokevirtual_stub[];
+extern char Thumb2_invokestatic_stub[];
+extern char Thumb2_invokespecial_stub[];
+extern char Thumb2_getfield_word_stub[];
+extern char Thumb2_getfield_sh_stub[];
+extern char Thumb2_getfield_h_stub[];
+extern char Thumb2_getfield_sb_stub[];
+extern char Thumb2_getfield_dw_stub[];
+extern char Thumb2_putfield_word_stub[];
+extern char Thumb2_putfield_h_stub[];
+extern char Thumb2_putfield_b_stub[];
+extern char Thumb2_putfield_a_stub[];
+extern char Thumb2_putfield_dw_stub[];
+extern char Thumb2_getstatic_word_stub[];
+extern char Thumb2_getstatic_sh_stub[];
+extern char Thumb2_getstatic_h_stub[];
+extern char Thumb2_getstatic_sb_stub[];
+extern char Thumb2_getstatic_dw_stub[];
+extern char Thumb2_putstatic_word_stub[];
+extern char Thumb2_putstatic_h_stub[];
+extern char Thumb2_putstatic_b_stub[];
+extern char Thumb2_putstatic_a_stub[];
+extern char Thumb2_putstatic_dw_stub[];
+
+#define STUBS_SIZE	(Thumb2_stubs_end-Thumb2_stubs)
+#define IDIV_STUB		(Thumb2_idiv_stub-Thumb2_stubs)
+#define IREM_STUB		(Thumb2_irem_stub-Thumb2_stubs)
+#define INVOKEINTERFACE_STUB	(Thumb2_invokeinterface_stub-Thumb2_stubs)
+#define INVOKEVIRTUAL_STUB	(Thumb2_invokevirtual_stub-Thumb2_stubs)
+#define INVOKESTATIC_STUB	(Thumb2_invokestatic_stub-Thumb2_stubs)
+#define INVOKESPECIAL_STUB	(Thumb2_invokespecial_stub-Thumb2_stubs)
+#define GETFIELD_WORD_STUB	(Thumb2_getfield_word_stub-Thumb2_stubs)
+#define GETFIELD_SH_STUB	(Thumb2_getfield_sh_stub-Thumb2_stubs)
+#define GETFIELD_H_STUB		(Thumb2_getfield_h_stub-Thumb2_stubs)
+#define GETFIELD_SB_STUB	(Thumb2_getfield_sb_stub-Thumb2_stubs)
+#define GETFIELD_DW_STUB	(Thumb2_getfield_dw_stub-Thumb2_stubs)
+#define PUTFIELD_WORD_STUB	(Thumb2_putfield_word_stub-Thumb2_stubs)
+#define PUTFIELD_H_STUB		(Thumb2_putfield_h_stub-Thumb2_stubs)
+#define PUTFIELD_B_STUB		(Thumb2_putfield_b_stub-Thumb2_stubs)
+#define PUTFIELD_A_STUB		(Thumb2_putfield_a_stub-Thumb2_stubs)
+#define PUTFIELD_DW_STUB	(Thumb2_putfield_dw_stub-Thumb2_stubs)
+#define GETSTATIC_WORD_STUB	(Thumb2_getstatic_word_stub-Thumb2_stubs)
+#define GETSTATIC_SH_STUB	(Thumb2_getstatic_sh_stub-Thumb2_stubs)
+#define GETSTATIC_H_STUB	(Thumb2_getstatic_h_stub-Thumb2_stubs)
+#define GETSTATIC_SB_STUB	(Thumb2_getstatic_sb_stub-Thumb2_stubs)
+#define GETSTATIC_DW_STUB	(Thumb2_getstatic_dw_stub-Thumb2_stubs)
+#define PUTSTATIC_WORD_STUB	(Thumb2_putstatic_word_stub-Thumb2_stubs)
+#define PUTSTATIC_H_STUB	(Thumb2_putstatic_h_stub-Thumb2_stubs)
+#define PUTSTATIC_B_STUB	(Thumb2_putstatic_b_stub-Thumb2_stubs)
+#define PUTSTATIC_A_STUB	(Thumb2_putstatic_a_stub-Thumb2_stubs)
+#define PUTSTATIC_DW_STUB	(Thumb2_putstatic_dw_stub-Thumb2_stubs)
+
+extern "C" void Thumb2_NullPtr_Handler(void);
+
+
+extern "C" int Thumb2_Check_Null(unsigned *regs, unsigned pc)
+{
+  Thumb2_CodeBuf *cb = thumb2_codebuf;
+  if (!(CPUInfo & ARCH_THUMBEE)) return 0;
+  if (IS_COMPILED(pc, cb)) {
+    regs[ARM_PC] = (unsigned)Thumb2_NullPtr_Handler;
+    regs[ARM_CPSR] &= ~CPSR_THUMB_BIT;
+    return 1;
+  }
+  return 0;
+}
+
+extern "C" void Thumb2_Initialize(void)
+{
+  CodeBuf codebuf;
+  Thumb2_CodeBuf *cb;
+  u32 h_divzero;
+  u32 loc_irem, loc_idiv, loc_ldiv;
+
+#ifdef T2EE_PRINT_COMPILATION
+  t2ee_print_compilation = getenv("T2EE_PRINT_COMPILATION");
+#endif
+#ifdef T2EE_PRINT_STATISTICS
+  t2ee_print_statistics = getenv("T2EE_PRINT_STATISTICS");
+#endif
+#ifdef T2EE_PRINT_DISASS
+  t2ee_print_disass = getenv("T2EE_PRINT_DISASS");
+#endif
+#ifdef T2EE_PRINT_REGUSAGE
+  t2ee_print_regusage = getenv("T2EE_PRINT_REGUSAGE");
+#endif
+
+  cb = (Thumb2_CodeBuf *)mmap(0, THUMB2_CODEBUF_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+  if (cb == MAP_FAILED) {
+    UseCompiler = 0;
+    return;
+  }
+
+  cb->size = THUMB2_CODEBUF_SIZE;
+  cb->hp = (char *)cb + sizeof(Thumb2_CodeBuf);
+  cb->sp = (char *)cb + THUMB2_CODEBUF_SIZE;
+
+  codebuf.codebuf = (unsigned short *)cb->hp;
+  codebuf.idx = 0;
+
+#if 1
+  memcpy(cb->hp, Thumb2_stubs, STUBS_SIZE);
+
+  handlers[H_IDIV] = (unsigned)(cb->hp + IDIV_STUB);
+  handlers[H_IREM] = (unsigned)(cb->hp + IREM_STUB);
+  handlers[H_INVOKEINTERFACE] = (unsigned)(cb->hp + INVOKEINTERFACE_STUB);
+  handlers[H_INVOKEVIRTUAL] = (unsigned)(cb->hp + INVOKEVIRTUAL_STUB);
+  handlers[H_INVOKESTATIC] = (unsigned)(cb->hp + INVOKESTATIC_STUB);
+  handlers[H_INVOKESPECIAL] = (unsigned)(cb->hp + INVOKESPECIAL_STUB);
+
+  handlers[H_GETFIELD_WORD] = (unsigned)(cb->hp + GETFIELD_WORD_STUB);
+  handlers[H_GETFIELD_SH] = (unsigned)(cb->hp + GETFIELD_SH_STUB);
+  handlers[H_GETFIELD_H] = (unsigned)(cb->hp + GETFIELD_H_STUB);
+  handlers[H_GETFIELD_SB] = (unsigned)(cb->hp + GETFIELD_SB_STUB);
+  handlers[H_GETFIELD_DW] = (unsigned)(cb->hp + GETFIELD_DW_STUB);
+
+  handlers[H_PUTFIELD_WORD] = (unsigned)(cb->hp + PUTFIELD_WORD_STUB);
+  handlers[H_PUTFIELD_H] = (unsigned)(cb->hp + PUTFIELD_H_STUB);
+  handlers[H_PUTFIELD_B] = (unsigned)(cb->hp + PUTFIELD_B_STUB);
+  handlers[H_PUTFIELD_A] = (unsigned)(cb->hp + PUTFIELD_A_STUB);
+  handlers[H_PUTFIELD_DW] = (unsigned)(cb->hp + PUTFIELD_DW_STUB);
+
+  handlers[H_GETSTATIC_WORD] = (unsigned)(cb->hp + GETSTATIC_WORD_STUB);
+  handlers[H_GETSTATIC_SH] = (unsigned)(cb->hp + GETSTATIC_SH_STUB);
+  handlers[H_GETSTATIC_H] = (unsigned)(cb->hp + GETSTATIC_H_STUB);
+  handlers[H_GETSTATIC_SB] = (unsigned)(cb->hp + GETSTATIC_SB_STUB);
+  handlers[H_GETSTATIC_DW] = (unsigned)(cb->hp + GETSTATIC_DW_STUB);
+
+  handlers[H_PUTSTATIC_WORD] = (unsigned)(cb->hp + PUTSTATIC_WORD_STUB);
+  handlers[H_PUTSTATIC_H] = (unsigned)(cb->hp + PUTSTATIC_H_STUB);
+  handlers[H_PUTSTATIC_B] = (unsigned)(cb->hp + PUTSTATIC_B_STUB);
+  handlers[H_PUTSTATIC_A] = (unsigned)(cb->hp + PUTSTATIC_A_STUB);
+  handlers[H_PUTSTATIC_DW] = (unsigned)(cb->hp + PUTSTATIC_DW_STUB);
+
+  codebuf.idx += (Thumb2_stubs_end-Thumb2_stubs) >> 1;
+#endif
+
+  handlers[H_LDIV] = handlers[H_LREM] = out_pos(&codebuf);
+  dop_reg(&codebuf, DP_ORR, ARM_IP, ARM_R2, ARM_R3, 0, 0);
+  loc_ldiv = forward_16(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)__aeabi_ldivmod);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+  bcc_patch(&codebuf, COND_EQ, loc_ldiv);
+  mov_imm(&codebuf, ARM_IP, (u32)Thumb2_DivZero_Handler);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_ARRAYBOUND] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_R3, (u32)Thumb2_ArrayBounds_Handler);
+  mov_reg(&codebuf, ARM_PC, ARM_R3);
+
+  handlers[H_HANDLE_EXCEPTION] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_R3, (u32)Thumb2_Handle_Exception);
+  mov_reg(&codebuf, ARM_PC, ARM_R3);
+
+  handlers[H_DREM] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)fmod);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_FREM] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_R3, (u32)fmodf);
+  mov_reg(&codebuf, ARM_PC, ARM_R3);
+
+  handlers[H_I2F] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)__aeabi_i2f);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_I2D] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)__aeabi_i2d);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_L2F] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)__aeabi_l2f);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_L2D] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)__aeabi_l2d);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_F2I] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)_ZN13SharedRuntime3f2iEf);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_F2L] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)_ZN13SharedRuntime3f2lEf);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_F2D] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)__aeabi_f2d);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_D2I] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)_ZN13SharedRuntime3d2iEd);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_D2L] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)_ZN13SharedRuntime3d2lEd);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+  handlers[H_D2F] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_IP, (u32)__aeabi_d2f);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+// NEW Stub
+//   r1 = index
+//   r3 = bci
+//   result -> R0, == 0 => exception
+  handlers[H_NEW] = out_pos(&codebuf);
+  mov_reg(&codebuf, ARM_R0, Ristate);
+  ldr_imm(&codebuf, ARM_R2, ARM_R0, ISTATE_METHOD, 1, 0);
+  mov_imm(&codebuf, ARM_IP, (u32)Helper_new);
+  ldr_imm(&codebuf, ARM_R2, ARM_R2, METHOD_CONSTMETHOD, 1, 0);
+  add_reg(&codebuf, ARM_R2, ARM_R2, ARM_R3);
+sub_imm(&codebuf, ARM_R3, Rstack, 4);
+  str_imm(&codebuf, ARM_R3, ARM_R0, ISTATE_STACK, 1, 0);
+  str_imm(&codebuf, ARM_R2, ARM_R0, ISTATE_BCP, 1, 0);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+// NEWARRAY Stub
+//   r1 = atype
+//   r2 = tos
+//   r3 = bci
+//   result -> thread->vm_result
+  handlers[H_NEWARRAY] = out_pos(&codebuf);
+  ldr_imm(&codebuf, ARM_R0, Ristate, ISTATE_METHOD, 1, 0);
+  mov_imm(&codebuf, ARM_IP, (u32)_ZN18InterpreterRuntime8newarrayEP10JavaThread9BasicTypei);
+  ldr_imm(&codebuf, ARM_R0, ARM_R0, METHOD_CONSTMETHOD, 1, 0);
+  add_reg(&codebuf, ARM_R3, ARM_R0, ARM_R3);
+  mov_reg(&codebuf, ARM_R0, Rthread);
+  str_imm(&codebuf, ARM_R3, Ristate, ISTATE_BCP, 1, 0);
+sub_imm(&codebuf, ARM_R3, Rstack, 4);
+  str_imm(&codebuf, ARM_R3, Ristate, ISTATE_STACK, 1, 0);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+// ANEWARRAY Stub
+//   r0 = bci
+//   r2 = index
+//   r3 = tos
+//   result -> thread->vm_result
+  handlers[H_ANEWARRAY] = out_pos(&codebuf);
+sub_imm(&codebuf, ARM_R1, Rstack, 4);
+  str_imm(&codebuf, ARM_R1, Ristate, ISTATE_STACK, 1, 0);
+  ldr_imm(&codebuf, ARM_R1, Ristate, ISTATE_METHOD, 1, 0);
+  ldr_imm(&codebuf, ARM_IP, ARM_R1, METHOD_CONSTMETHOD, 1, 0);
+  ldr_imm(&codebuf, ARM_R1, ARM_R1, METHOD_CONSTANTS, 1, 0);
+  add_reg(&codebuf, ARM_R0, ARM_IP, ARM_R0);
+  mov_imm(&codebuf, ARM_IP, (u32)_ZN18InterpreterRuntime9anewarrayEP10JavaThreadP19constantPoolOopDescii);
+  str_imm(&codebuf, ARM_R0, Ristate, ISTATE_BCP, 1, 0);
+  mov_reg(&codebuf, ARM_R0, Rthread);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+// MULTIANEWARRAY Stub
+//   r0 = bci
+//   r1 = dimensions (*4)
+  handlers[H_MULTIANEWARRAY] = out_pos(&codebuf);
+  ldr_imm(&codebuf, ARM_R2, Ristate, ISTATE_METHOD, 1, 0);
+  sub_imm(&codebuf, ARM_R3, Rstack, 4);
+  ldr_imm(&codebuf, ARM_R2, ARM_R2, METHOD_CONSTMETHOD, 1, 0);
+  str_imm(&codebuf, ARM_R3, Ristate, ISTATE_STACK, 1, 0);
+  add_reg(&codebuf, ARM_R0, ARM_R2, ARM_R0);
+  add_reg(&codebuf, Rstack, Rstack, ARM_R1);
+  mov_imm(&codebuf, ARM_R3, (u32)_ZN18InterpreterRuntime14multianewarrayEP10JavaThreadPi);
+  str_imm(&codebuf, ARM_R0, Ristate, ISTATE_BCP, 1, 0);
+  mov_reg(&codebuf, ARM_R0, Rthread);
+  sub_imm(&codebuf, ARM_R1, Rstack, 4);
+  mov_reg(&codebuf, ARM_PC, ARM_R3);
+
+// LDC Stub
+//   r0 = bci
+  handlers[H_LDC] = out_pos(&codebuf);
+  ldr_imm(&codebuf, ARM_R2, Ristate, ISTATE_METHOD, 1, 0);
+  sub_imm(&codebuf, ARM_R3, Rstack, 4);
+  ldr_imm(&codebuf, ARM_R2, ARM_R2, METHOD_CONSTMETHOD, 1, 0);
+  str_imm(&codebuf, ARM_R3, Ristate, ISTATE_STACK, 1, 0);
+  add_reg(&codebuf, ARM_R0, ARM_R2, ARM_R0);
+  mov_imm(&codebuf, ARM_R3, (u32)_ZN18InterpreterRuntime3ldcEP10JavaThreadb);
+  str_imm(&codebuf, ARM_R0, Ristate, ISTATE_BCP, 1, 0);
+  mov_reg(&codebuf, ARM_R0, Rthread);
+//  mov_imm(&codebuf, ARM_R1, 0);
+  mov_reg(&codebuf, ARM_PC, ARM_R3);
+
+// INSTANCEOF Stub
+//   r1 = index
+//   r3 = bci
+//   result -> R0, == -1 => exception
+  handlers[H_INSTANCEOF] = out_pos(&codebuf);
+  ldr_imm(&codebuf, ARM_R0, Ristate, ISTATE_METHOD, 1, 0);
+  mov_imm(&codebuf, ARM_IP, (u32)Helper_instanceof);
+  ldr_imm(&codebuf, ARM_R0, ARM_R0, METHOD_CONSTMETHOD, 1, 0);
+  add_reg(&codebuf, ARM_R0, ARM_R0, ARM_R3);
+sub_imm(&codebuf, ARM_R3, Rstack, 4);
+  str_imm(&codebuf, ARM_R3, Ristate, ISTATE_STACK, 1, 0);
+  str_imm(&codebuf, ARM_R0, Ristate, ISTATE_BCP, 1, 0);
+  mov_reg(&codebuf, ARM_R0, Ristate);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+// CHECKCAST Stub
+//   r1 = index
+//   r3 = bci
+//   result -> R0, != 0 => exception
+  handlers[H_CHECKCAST] = out_pos(&codebuf);
+  ldr_imm(&codebuf, ARM_R0, Ristate, ISTATE_METHOD, 1, 0);
+  mov_imm(&codebuf, ARM_IP, (u32)Helper_checkcast);
+  ldr_imm(&codebuf, ARM_R0, ARM_R0, METHOD_CONSTMETHOD, 1, 0);
+  add_reg(&codebuf, ARM_R0, ARM_R0, ARM_R3);
+sub_imm(&codebuf, ARM_R3, Rstack, 4);
+  str_imm(&codebuf, ARM_R3, Ristate, ISTATE_STACK, 1, 0);
+  str_imm(&codebuf, ARM_R0, Ristate, ISTATE_BCP, 1, 0);
+  mov_reg(&codebuf, ARM_R0, Ristate);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+// AASTORE Stub
+//   r0 = bci
+//   r1 = value
+//   r2 = index
+//   r3 = arrayref
+  handlers[H_AASTORE] = out_pos(&codebuf);
+  ldr_imm(&codebuf, ARM_IP, Ristate, ISTATE_METHOD, 1, 0);
+  ldr_imm(&codebuf, ARM_IP, ARM_IP, METHOD_CONSTMETHOD, 1, 0);
+  add_reg(&codebuf, ARM_IP, ARM_IP, ARM_R0);
+sub_imm(&codebuf, ARM_R0, Rstack, 4);
+  str_imm(&codebuf, ARM_R0, Ristate, ISTATE_STACK, 1, 0);
+  str_imm(&codebuf, ARM_IP, Ristate, ISTATE_BCP, 1, 0);
+  mov_imm(&codebuf, ARM_IP, (u32)Helper_aastore);
+  mov_reg(&codebuf, ARM_R0, Ristate);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+// APUTFIELD Stub
+//   r0 = obj
+  handlers[H_APUTFIELD] = out_pos(&codebuf);
+  mov_imm(&codebuf, ARM_R3, (u32)Helper_aputfield);
+  mov_reg(&codebuf, ARM_PC, ARM_R3);
+
+// SYNCHRONIZED_ENTER Stub
+//   r0 = bci
+//   r1 = monitor
+  handlers[H_SYNCHRONIZED_ENTER] = out_pos(&codebuf);
+  ldr_imm(&codebuf, ARM_IP, Ristate, ISTATE_METHOD, 1, 0);
+  ldr_imm(&codebuf, ARM_IP, ARM_IP, METHOD_CONSTMETHOD, 1, 0);
+  add_reg(&codebuf, ARM_IP, ARM_IP, ARM_R0);
+sub_imm(&codebuf, ARM_R0, Rstack, 4);
+  str_imm(&codebuf, ARM_R0, Ristate, ISTATE_STACK, 1, 0);
+  str_imm(&codebuf, ARM_IP, Ristate, ISTATE_BCP, 1, 0);
+  mov_imm(&codebuf, ARM_IP, (u32)Helper_synchronized_enter);
+  mov_reg(&codebuf, ARM_R0, Rthread);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+//
+// SYNCHRONIZED_EXIT Stub
+//   r0 = bci
+//   r1 = monitor
+  handlers[H_SYNCHRONIZED_EXIT] = out_pos(&codebuf);
+  ldr_imm(&codebuf, ARM_IP, Ristate, ISTATE_METHOD, 1, 0);
+  ldr_imm(&codebuf, ARM_IP, ARM_IP, METHOD_CONSTMETHOD, 1, 0);
+  add_reg(&codebuf, ARM_IP, ARM_IP, ARM_R0);
+sub_imm(&codebuf, ARM_R0, Rstack, 4);
+  str_imm(&codebuf, ARM_R0, Ristate, ISTATE_STACK, 1, 0);
+  str_imm(&codebuf, ARM_IP, Ristate, ISTATE_BCP, 1, 0);
+  mov_imm(&codebuf, ARM_IP, (u32)Helper_synchronized_exit);
+  mov_reg(&codebuf, ARM_R0, Rthread);
+  mov_reg(&codebuf, ARM_PC, ARM_IP);
+
+#define DEBUG_REGSET ((1<<ARM_R0)|(1<<ARM_R1)|(1<<ARM_R2)|(1<<ARM_R3)|(1<<ARM_IP))
+
+// DEBUG_METHODENTRY
+  handlers[H_DEBUG_METHODENTRY] = out_pos(&codebuf);
+  stm(&codebuf, DEBUG_REGSET | (1<<ARM_LR), ARM_SP, PUSH_FD, 1);
+  mov_reg(&codebuf, ARM_R2, ARM_R0);
+  mov_reg(&codebuf, ARM_R0, ARM_R8);
+  mov_reg(&codebuf, ARM_R1, ARM_R4);
+  mov_imm(&codebuf, ARM_IP, (u32)Debug_MethodEntry);
+  blx_reg(&codebuf, ARM_IP);
+  ldm(&codebuf, DEBUG_REGSET | (1<<ARM_PC), ARM_SP, POP_FD, 1);
+
+// DEBUG_METHODEXIT
+  handlers[H_DEBUG_METHODEXIT] = out_pos(&codebuf);
+  stm(&codebuf, DEBUG_REGSET | (1<<ARM_LR), ARM_SP, PUSH_FD, 1);
+  mov_reg(&codebuf, ARM_R0, ARM_R8);
+  mov_reg(&codebuf, ARM_R1, ARM_R4);
+  mov_imm(&codebuf, ARM_IP, (u32)Debug_MethodExit);
+  blx_reg(&codebuf, ARM_IP);
+  ldm(&codebuf, DEBUG_REGSET | (1<<ARM_PC), ARM_SP, POP_FD, 1);
+
+// DEBUG_METHODCALL
+  handlers[H_DEBUG_METHODCALL] = out_pos(&codebuf);
+  stm(&codebuf, DEBUG_REGSET | (1<<ARM_LR), ARM_SP, PUSH_FD, 1);
+  mov_reg(&codebuf, ARM_R2, ARM_R0);
+  mov_reg(&codebuf, ARM_R0, ARM_R8);
+  mov_reg(&codebuf, ARM_R1, ARM_R4);
+  mov_imm(&codebuf, ARM_IP, (u32)Debug_MethodCall);
+  blx_reg(&codebuf, ARM_IP);
+  ldm(&codebuf, DEBUG_REGSET | (1<<ARM_PC), ARM_SP, POP_FD, 1);
+
+// EXIT_TO_INTERPRETER
+//   r0 = bci
+  handlers[H_EXIT_TO_INTERPRETER] = out_pos(&codebuf);
+  ldr_imm(&codebuf, ARM_R1, Ristate, ISTATE_METHOD, 1, 0);
+  ldr_imm(&codebuf, ARM_IP, ARM_R1, METHOD_CONSTMETHOD, 1, 0);
+  add_reg(&codebuf, Rint_jpc, ARM_IP, ARM_R0);
+  mov_imm(&codebuf, ARM_R3, (u32)Thumb2_Exit_To_Interpreter);
+  mov_reg(&codebuf, ARM_PC, ARM_R3);
+
+  Thumb2_Clear_Cache(cb->hp, cb->hp + codebuf.idx * 2);
+  cb->hp += codebuf.idx * 2;
+
+  thumb2_codebuf = cb;
+}
+
+#endif // THUMB2EE