Request to commit to head: Thumb 2 JIT

ed at camswl.com ed at camswl.com
Tue Jan 19 09:45:50 PST 2010


Hi folks,

The following patch adds a Thumb2 JIT to the ARM port. As the diffs are quite large
and may be truncated here, I have put a .gz of the diffs at

http://mint.camswl.com/diffs_t2jit.gz

The files affected are

icedtea6/ports/hotspot/make/linux/makefiles/zeroshark.make
icedtea6/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp
icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_arm.def
icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
icedtea6/ports/hotspot/src/cpu/zero/vm/thumb2.cpp (new file)

The only non ARM file affected is zeroshark.make. The change here is to add the make
rules for the Thumb2 JIT.

The JIT does not build by default. The default build is still the ARM interpreter.

To build the JIT

Edit /ports/hotspot/make/linux/makefiles/zeroshark.make and add

-DTHUMB2EE

to the CFLAGS line.

If you want to have a play with the JIT I have put pre build binaries at

http://mint.camswl.com/j2re-image-jit.tar.bz2
http://mint.camswl.com/j2sdk-image-jit.tar.bz2
http://mint.camswl.com/libjvm-jit.so.bz2

These are hosted on my home computer and as such are using the uplink side of a DSL
line so download will be SLOW (9 mins for j2re, 22 mins for j2sdk, 30 secs for libjvm).

The images were build on Ubuntu karmic. I have tested the images on Ubuntu karmic,
Ubuntu jaunty and Debian lenny.

I have done a reasonable amount of testing on the JIT and it seems quite stable but
is not quite ready for prime time as there are a number of infelicities.

The testing I have done..

- Builds itself using --with-openjdk=<Thumb2 JIT>
- Passes all the 'compiler' and 'langtools' JTReg tests
- Fails about the same number of 'jdk' JTReg tests as the interpreter
- Passes the same CDC TCK tests as the interpreter except for 4 tests which are
  due to stack overflow testing.
- Runs large applications such as Thunk Free Office.

The known infelicities are as follows:-

- Stack checking

Checking of the Java stack is not implemented.

- Notice safepoints

The JITTed code ignores the 'Notice safepoint' call. This means that there is a very
small possibility the the VM will 'lock up' when a GC is requested. I have never seen
this happen.

- The compiler is not MP safe

I have run it successfully on a 4 core ARM A9 platform and seen no problems, however,
I know there are windows where it can end up trying to use the same compile buffer
to compile 2 methods at the same time.

- For certain excessively large methods the compiler will generate an assertion failure.

For this to happen there needs to be a tableswitch which generates > 32K code. I have
never seen this happen in testing.

If you are having a play with it you may find the following environmental variables
useful.

T2EE_PRINT_COMPILATION	- Prints a line per method compiled if defined
T2EE_PRINT_STATISTICS	- Prints some compilation time and code size stats if defined
T2EE_PRINT_DISASS	- Disassembles the generated code
T2EE_PRINT_REGUSAGE	- Print the register assignment from regalloc.

If you want to use T2EE_PRINT_DISASS options you will need to compile in the disassembler.
Uncomment the following line in thumb2.cpp

//#define T2EE_PRINT_DISASS

You will also need to ensure that libopcodes is installed on your system (from package
'bfd').

There have been a number of changes to the interpreter alongside the addition of the
JIT.  These have generally been tidying up.

- Removal of hard coded constants ISTATE_XXX and tos_XXXX.
- Moved nore 'complex' asm code to C in asm_helper.cpp from cppInterpreter_asm.S
  The bytecodes affected are 'new', 'instanceof', 'checkcast', 'aastore'.  In addition
  all the exception handling code has been moved to C.

These changes will help may the interpreter more reliable between releases as the
interpreter will not be subject to interface changes in the C code (for example,
changes in the mangled names which has been a problem in the past).

All changes included in and upto icedtes6-1.7 have been merged.

The Thumb2 JIT will not build in conjunction with Shark or Cacao.  I have tested the
tested the interpreter build with Shark using the latest (ie SVN head as of 18/1/10) llvm.
This seems to work OK.

On non Thumb2 platforms (ie ARM arch < V7) the JIT will revert to the interpreter. I have
tested this on ARM V5, but have been unable to test it on ARM V4 due to lack of hardware
(I have tested the build with gcc 4.1 so it should build on V4 platforms). If anyone has
access to V4 hw could the try it and let me know the results.

OK to commit?

Regards,
Ed.

--- CUT HERE --------------------------------------------------------------------------
diff -ruNE old/icedtea6/ports/hotspot/make/linux/makefiles/zeroshark.make new/icedtea6/ports/hotspot/make/linux/makefiles/zeroshark.make
--- old/icedtea6/ports/hotspot/make/linux/makefiles/zeroshark.make	2010-01-19 15:29:04.000000000 +0000
+++ new/icedtea6/ports/hotspot/make/linux/makefiles/zeroshark.make	2010-01-19 15:42:27.000000000 +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
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp new/icedtea6/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp	2010-01-19 15:29:04.000000000 +0000
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp	2010-01-19 15:41:20.000000000 +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("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("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("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);
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_arm.def new/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_arm.def
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_arm.def	2010-01-19 15:29:04.000000000 +0000
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_arm.def	2010-01-19 15:41:58.000000000 +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 {
-	ldrb	r1, [jpc, #2]
 	POP	r3
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         cmp     r3, #0
-        orr     ip, r1, r2, asr #16
 	beq	1f
-	mov	ip, #3
+	DISPATCH 3
 1:
+	mov	r2, r2, lsl #24
+        orr     ip, r1, r2, asr #16
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (ifne,ifnonnull) ifne_unsafe {
-	ldrb	r1, [jpc, #2]
 	POP	r3
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         cmp     r3, #0
-        orr     ip, r1, r2, asr #16
 	bne	1f
-	mov	ip, #3
+	DISPATCH 3
 1:
+	mov	r2, r2, lsl #24
+        orr     ip, r1, r2, asr #16
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (iflt) iflt_unsafe {
-	ldrb	r1, [jpc, #2]
 	POP	r3
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         cmp     r3, #0
-        orr     ip, r1, r2, asr #16
 	blt	1f
-	mov	ip, #3
+	DISPATCH 3
 1:
+	mov	r2, r2, lsl #24
+        orr     ip, r1, r2, asr #16
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (ifge) ifge_unsafe {
-	ldrb	r1, [jpc, #2]
 	POP	r3
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         cmp     r3, #0
-        orr     ip, r1, r2, asr #16
 	bge	1f
-	mov	ip, #3
+	DISPATCH 3
 1:
+	mov	r2, r2, lsl #24
+        orr     ip, r1, r2, asr #16
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (ifgt) ifgt_unsafe {
-	ldrb	r1, [jpc, #2]
 	POP	r3
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         cmp     r3, #0
-        orr     ip, r1, r2, asr #16
 	bgt	1f
-	mov	ip, #3
+	DISPATCH 3
 1:
+	mov	r2, r2, lsl #24
+        orr     ip, r1, r2, asr #16
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (ifle) ifle_unsafe {
-	ldrb	r1, [jpc, #2]
 	POP	r3
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         cmp     r3, #0
-        orr     ip, r1, r2, asr #16
 	ble	1f
-	mov	ip, #3
+	DISPATCH 3
 1:
+	mov	r2, r2, lsl #24
+        orr     ip, r1, r2, asr #16
         ldrb  r0, [jpc, ip]!
 	DISPATCH_BYTECODE
 }
 
 (if_icmpeq,if_acmpeq) if_icmpeq_unsafe {
-	ldrb	r1, [jpc, #2]
 	POP	r3, tmp1
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         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 {
-	ldrb	r1, [jpc, #2]
 	POP	r3, tmp1
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         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 {
-	ldrb	r1, [jpc, #2]
 	POP	r3, tmp1
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         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 {
-	ldrb	r1, [jpc, #2]
 	POP	r3, tmp1
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         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 {
-	ldrb	r1, [jpc, #2]
 	POP	r3, tmp1
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         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 {
-	ldrb	r1, [jpc, #2]
 	POP	r3, tmp1
-	mov	r2, r2, lsl #24
+	ldrb	r1, [jpc, #2]
         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
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
-        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
+	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
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
-        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
+	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
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
-        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
+	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,31 +2366,8 @@
 	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
 	vldr	s15, [stack, #8]
@@ -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)
 {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
 	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
+        ldrsb   r1, [jpc, #2]
 	ldr	r3, [locals, r3, lsl #2]
+        ldrb    ip, [jpc, #3]
         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)
 {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
 	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
+        ldrsb   r1, [jpc, #2]
 	ldr	r3, [locals, r3, lsl #2]
+        ldrb    ip, [jpc, #3]
         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)
 {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
 	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
+        ldrsb   r1, [jpc, #2]
 	ldr	r3, [locals, r3, lsl #2]
+        ldrb    ip, [jpc, #3]
         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)
 {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
 	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
+        ldrsb   r1, [jpc, #2]
 	ldr	r3, [locals, r3, lsl #2]
+        ldrb    ip, [jpc, #3]
         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)
 {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
 	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
+        ldrsb   r1, [jpc, #2]
 	ldr	r3, [locals, r3, lsl #2]
+        ldrb    ip, [jpc, #3]
         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)
 {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
 	rsb	r3, r0, #opc_iload_0
-	add	jpc, jpc, #1
+        ldrsb   r1, [jpc, #2]
 	ldr	r3, [locals, r3, lsl #2]
+        ldrb    ip, [jpc, #3]
         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]
-        ldrb    ip, [jpc, #3]
 	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
+        ldrb    ip, [jpc, #3]
         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]
-        ldrb    ip, [jpc, #3]
 	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
+        ldrb    ip, [jpc, #3]
         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]
-        ldrb    ip, [jpc, #3]
 	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
+        ldrb    ip, [jpc, #3]
         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]
-        ldrb    ip, [jpc, #3]
 	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
+        ldrb    ip, [jpc, #3]
         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]
-        ldrb    ip, [jpc, #3]
 	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
+        ldrb    ip, [jpc, #3]
         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]
-        ldrb    ip, [jpc, #3]
 	ldr	r2, [locals, r2, lsl #2]
-	add	jpc, jpc, #1
+        ldrb    ip, [jpc, #3]
         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
+	ble	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
-@ --- ECN: load; return/invoke -------------------------------------------------
+@ --- 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
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
-        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
+	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
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
-        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
+	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]
-        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
+        ldrb    ip, [jpc, #3]
+	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]
-        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
+        ldrb    ip, [jpc, #3]
+	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]
-        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
+        ldrb    ip, [jpc, #3]
+	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]
-        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
+        ldrb    ip, [jpc, #3]
+	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]
-        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
+        ldrb    ip, [jpc, #3]
+	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]
-        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
+        ldrb    ip, [jpc, #3]
+	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
+	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
-        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
+	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	PUSH	r1
 	add	jpc, jpc, #1
@@ -5001,295 +4649,253 @@
 	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
+@ ---- iadd; xxx ------------------------------------------------------------
 
-        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
+(iadd)(iload,fload,aload) {
+	ldrb	r3, [jpc, #2]
+	DISPATCH_START	\seq_len
+	POP	tmp2, tmp1
+	DISPATCH_NEXT
+	rsb	r3, r3, #0
+	DISPATCH_NEXT
+	ldr	r3, [locals, r3, lsl #2]
+	DISPATCH_NEXT
+	add	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	PUSH	r3, tmp2
+	DISPATCH_FINISH
 }
 
-(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
+(iadd)
+(iload_0,iload_1,iload_2,iload_3)
+{
+	DISPATCH_START	\seq_len
+	rsb	r3, r1, #opc_iload_0
+	POP	tmp2, tmp1
+	DISPATCH_NEXT
+	ldr	r3, [locals, r3, lsl #2]
+	add	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	r3, tmp2
+	DISPATCH_FINISH
 }
 
-(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
+(iadd)(iaload,aaload,faload) {
+	POP	r2, r3, lr		@ lr = ref
+	DISPATCH_START	\seq_len
+	add	r2, r3, r2		@ r2 = index
+	SW_NPC	cmp	lr, #0
+	SW_NPC	beq	null_ptr_exception_jpc_1
+.abortentry73:
+	ldr	tmp1, [lr, #8]		@ tmp1 = length
+	DISPATCH_NEXT
+	cmp	r2, tmp1
+	bcs	array_bound_exception_jpc_1
+	add	lr, lr, r2, lsl #2
+	ldr	tmp1, [lr, #BASE_OFFSET_WORD]
+	DISPATCH_NEXT
+	PUSH	tmp1
+	DISPATCH_FINISH
 }
 
-(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
+(iadd)(istore) {
+	mov	r0, #opc_iadd_u4store
+	strb	r0, [jpc]
+	b	do_iadd_u4store
 }
 
-(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
+(iadd)
+(istore_0,istore_1,istore_2,istore_3) {
+	mov	r0, #opc_iadd_istore_N
+	strb	r0, [jpc]
+	b	do_iadd_istore_N
 }
 
-(iaload,faload,aaload)(ifle) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
+(iadd)(iastore,fastore) {
+	POP	r2, r3
+	DISPATCH_START	\seq_len
+	add	tmp1, r3, r2		@ tmp1 = value
+	POP	r2, r3			@ r2, index, r3 = ref
 	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
+	SW_NPC	beq	null_ptr_exception_jpc_1
+.abortentry106:
+	ldr	lr, [r3, #8]		@ lr = limit
+	DISPATCH_NEXT
+	cmp	r2, lr
+	bcs	array_bound_exception_jpc_1
+	DISPATCH_NEXT
 	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
+	str	tmp1, [r3, #BASE_OFFSET_WORD]
+	DISPATCH_FINISH
 }
 
-(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
+(iadd)(iadd) {
+	DISPATCH_START	\seq_len
+	POP	r2, r3, tmp1
+	DISPATCH_NEXT
+	add	tmp2, r3, r2
+	DISPATCH_NEXT
+	add	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
 }
 
-(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
+(iadd)(isub) {
+	DISPATCH_START	\seq_len
+	POP	r2, r3, tmp1
+	DISPATCH_NEXT
+	add	tmp2, r3, r2
+	DISPATCH_NEXT
+	sub	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
 }
 
-(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
+(iadd)(iinc) {
+	POP	tmp1, lr
+	DISPATCH_START	\seq_len
+	add	tmp1, lr, tmp1
+        ldrb    r3, [jpc, #-2]	@ jpc now points to next bc
+        ldrsb   r2, [jpc, #-1]
+	DISPATCH_NEXT
+	PUSH	tmp1
+	ldr	tmp1, [locals, -r3, lsl #2]
+	DISPATCH_NEXT
+	add	tmp1, tmp1, r2
+	str	tmp1, [locals, -r3, lsl #2]
+	DISPATCH_FINISH
+}
+@ ---- sub; xxx ------------------------------------------------------------
 
-	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
+(isub)(iload,fload,aload) {
+	ldrb	r3, [jpc, #2]
+	DISPATCH_START	\seq_len
+	POP	tmp2, tmp1
+	DISPATCH_NEXT
+	rsb	r3, r3, #0
+	DISPATCH_NEXT
+	ldr	r3, [locals, r3, lsl #2]
+	DISPATCH_NEXT
+	sub	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	PUSH	r3, tmp2
+	DISPATCH_FINISH
 }
 
-(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
+(isub)
+(iload_0,iload_1,iload_2,iload_3)
+{
+	DISPATCH_START	\seq_len
+	rsb	r3, r1, #opc_iload_0
+	POP	tmp2, tmp1
+	DISPATCH_NEXT
+	ldr	r3, [locals, r3, lsl #2]
+	sub	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	r3, tmp2
+	DISPATCH_FINISH
+}
 
-	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
+(isub)(iaload,aaload,faload) {
+	POP	r2, r3, lr		@ lr = ref
+	DISPATCH_START	\seq_len
+	sub	r2, r3, r2		@ r2 = index
+	SW_NPC	cmp	lr, #0
+	SW_NPC	beq	null_ptr_exception_jpc_1
+.abortentry74:
+	ldr	tmp1, [lr, #8]		@ tmp1 = length
+	DISPATCH_NEXT
+	cmp	r2, tmp1
+	bcs	array_bound_exception_jpc_1
+	add	lr, lr, r2, lsl #2
+	ldr	tmp1, [lr, #BASE_OFFSET_WORD]
+	DISPATCH_NEXT
+	PUSH	tmp1
+	DISPATCH_FINISH
 }
 
-(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
+(isub)(istore) {
+	mov	r0, #opc_isub_u4store
+	strb	r0, [jpc]
+	b	do_isub_u4store
+}
 
-	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
+(isub)
+(istore_0,istore_1,istore_2,istore_3) {
+	mov	r0, #opc_isub_istore_N
+	strb	r0, [jpc]
+	b	do_isub_istore_N
 }
 
-(iaload,faload,aaload)(if_icmple) {
-	POP	r2, r3			@ r2 = index, r3 = arrayref
+(isub)(iastore,fastore) {
+	POP	r2, r3
+	DISPATCH_START	\seq_len
+	sub	tmp1, r3, r2		@ tmp1 = value
+	POP	r2, r3			@ r2, index, r3 = ref
 	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
+	SW_NPC	beq	null_ptr_exception_jpc_1
+.abortentry105:
+	ldr	lr, [r3, #8]		@ lr = limit
+	DISPATCH_NEXT
+	cmp	r2, lr
+	bcs	array_bound_exception_jpc_1
+	DISPATCH_NEXT
 	add	r3, r3, r2, lsl #2
-	ldr	r2, [r3, #BASE_OFFSET_WORD]		@ r1 = tos
+	str	tmp1, [r3, #BASE_OFFSET_WORD]
+	DISPATCH_FINISH
+}
 
-	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
+(isub)(iadd) {
+	DISPATCH_START	\seq_len
+	POP	r2, r3, tmp1
+	DISPATCH_NEXT
+	sub	tmp2, r3, r2
+	DISPATCH_NEXT
+	add	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
 }
 
-#endif // NOTICE_SAFEPOINTS
+(isub)(isub) {
+	DISPATCH_START	\seq_len
+	POP	r2, r3, tmp1
+	DISPATCH_NEXT
+	sub	tmp2, r3, r2
+	DISPATCH_NEXT
+	sub	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
+}
 
-@ ---- iadd; xxx ------------------------------------------------------------
+(isub)(iinc) {
+	POP	tmp1, lr
+	DISPATCH_START	\seq_len
+	sub	tmp1, lr, tmp1
+        ldrb    r3, [jpc, #-2]	@ jpc now points to next bc
+        ldrsb   r2, [jpc, #-1]
+	DISPATCH_NEXT
+	PUSH	tmp1
+	ldr	tmp1, [locals, -r3, lsl #2]
+	DISPATCH_NEXT
+	add	tmp1, tmp1, r2
+	str	tmp1, [locals, -r3, lsl #2]
+	DISPATCH_FINISH
+}
+@ ---- iand; xxx ------------------------------------------------------------
 
-(iadd)(iload,fload,aload) {
+(iand)(iload,fload,aload) {
 	ldrb	r3, [jpc, #2]
 	DISPATCH_START	\seq_len
 	POP	tmp2, tmp1
@@ -5298,13 +4904,13 @@
 	DISPATCH_NEXT
 	ldr	r3, [locals, r3, lsl #2]
 	DISPATCH_NEXT
-	add	tmp2, tmp1, tmp2
+	and	tmp2, tmp1, tmp2
 	DISPATCH_NEXT
 	PUSH	r3, tmp2
 	DISPATCH_FINISH
 }
 
-(iadd)
+(iand)
 (iload_0,iload_1,iload_2,iload_3)
 {
 	DISPATCH_START	\seq_len
@@ -5312,7 +4918,7 @@
 	POP	tmp2, tmp1
 	DISPATCH_NEXT
 	ldr	r3, [locals, r3, lsl #2]
-	add	tmp2, tmp1, tmp2
+	and	tmp2, tmp1, tmp2
 	DISPATCH_NEXT
 	DISPATCH_NEXT
 	DISPATCH_NEXT
@@ -5320,13 +4926,13 @@
 	DISPATCH_FINISH
 }
 
-(iadd)(iaload,aaload,faload) {
+(iand)(iaload,aaload,faload) {
 	POP	r2, r3, lr		@ lr = ref
 	DISPATCH_START	\seq_len
-	add	r2, r3, r2		@ r2 = index
+	and	r2, r3, r2		@ r2 = index
 	SW_NPC	cmp	lr, #0
 	SW_NPC	beq	null_ptr_exception_jpc_1
-.abortentry73:
+.abortentry75:
 	ldr	tmp1, [lr, #8]		@ tmp1 = length
 	DISPATCH_NEXT
 	cmp	r2, tmp1
@@ -5338,27 +4944,27 @@
 	DISPATCH_FINISH
 }
 
-(iadd)(istore) {
-	mov	r0, #opc_iadd_u4store
+(iand)(istore) {
+	mov	r0, #opc_iand_u4store
 	strb	r0, [jpc]
-	b	do_iadd_u4store
+	b	do_iand_u4store
 }
 
-(iadd)
+(iand)
 (istore_0,istore_1,istore_2,istore_3) {
-	mov	r0, #opc_iadd_istore_N
+	mov	r0, #opc_iand_istore_N
 	strb	r0, [jpc]
-	b	do_iadd_istore_N
+	b	do_iand_istore_N
 }
 
-(iadd)(iastore,fastore) {
+(iand)(iastore,fastore) {
 	POP	r2, r3
 	DISPATCH_START	\seq_len
-	add	tmp1, r3, r2		@ tmp1 = value
+	and	tmp1, r3, r2		@ tmp1 = value
 	POP	r2, r3			@ r2, index, r3 = ref
 	SW_NPC	cmp	r3, #0
 	SW_NPC	beq	null_ptr_exception_jpc_1
-.abortentry106:
+.abortentry107:
 	ldr	lr, [r3, #8]		@ lr = limit
 	DISPATCH_NEXT
 	cmp	r2, lr
@@ -5369,11 +4975,11 @@
 	DISPATCH_FINISH
 }
 
-(iadd)(iadd) {
+(iand)(iadd) {
 	DISPATCH_START	\seq_len
 	POP	r2, r3, tmp1
 	DISPATCH_NEXT
-	add	tmp2, r3, r2
+	and	tmp2, r3, r2
 	DISPATCH_NEXT
 	add	tmp2, tmp1, tmp2
 	DISPATCH_NEXT
@@ -5382,11 +4988,11 @@
 	DISPATCH_FINISH
 }
 
-(iadd)(isub) {
+(iand)(isub) {
 	DISPATCH_START	\seq_len
 	POP	r2, r3, tmp1
 	DISPATCH_NEXT
-	add	tmp2, r3, r2
+	and	tmp2, r3, r2
 	DISPATCH_NEXT
 	sub	tmp2, tmp1, tmp2
 	DISPATCH_NEXT
@@ -5395,1353 +5001,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
-        ldrsb   r2, [jpc, #-1]
-	DISPATCH_NEXT
-	PUSH	tmp1
-	ldr	tmp1, [locals, -r3, lsl #2]
-	DISPATCH_NEXT
-	add	tmp1, tmp1, r2
-	str	tmp1, [locals, -r3, lsl #2]
-	DISPATCH_FINISH
-}
-@ ---- sub; xxx ------------------------------------------------------------
-
-(isub)(iload,fload,aload) {
-	ldrb	r3, [jpc, #2]
-	DISPATCH_START	\seq_len
-	POP	tmp2, tmp1
-	DISPATCH_NEXT
-	rsb	r3, r3, #0
-	DISPATCH_NEXT
-	ldr	r3, [locals, r3, lsl #2]
-	DISPATCH_NEXT
-	sub	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	PUSH	r3, tmp2
-	DISPATCH_FINISH
-}
-
-(isub)
-(iload_0,iload_1,iload_2,iload_3)
-{
-	DISPATCH_START	\seq_len
-	rsb	r3, r1, #opc_iload_0
-	POP	tmp2, tmp1
-	DISPATCH_NEXT
-	ldr	r3, [locals, r3, lsl #2]
-	sub	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	r3, tmp2
-	DISPATCH_FINISH
-}
-
-(isub)(iaload,aaload,faload) {
-	POP	r2, r3, lr		@ lr = ref
-	DISPATCH_START	\seq_len
-	sub	r2, r3, r2		@ r2 = index
-	SW_NPC	cmp	lr, #0
-	SW_NPC	beq	null_ptr_exception_jpc_1
-.abortentry74:
-	ldr	tmp1, [lr, #8]		@ tmp1 = length
-	DISPATCH_NEXT
-	cmp	r2, tmp1
-	bcs	array_bound_exception_jpc_1
-	add	lr, lr, r2, lsl #2
-	ldr	tmp1, [lr, #BASE_OFFSET_WORD]
-	DISPATCH_NEXT
-	PUSH	tmp1
-	DISPATCH_FINISH
-}
-
-(isub)(istore) {
-	mov	r0, #opc_isub_u4store
-	strb	r0, [jpc]
-	b	do_isub_u4store
-}
-
-(isub)
-(istore_0,istore_1,istore_2,istore_3) {
-	mov	r0, #opc_isub_istore_N
-	strb	r0, [jpc]
-	b	do_isub_istore_N
-}
-
-(isub)(iastore,fastore) {
-	POP	r2, r3
-	DISPATCH_START	\seq_len
-	sub	tmp1, r3, r2		@ tmp1 = value
-	POP	r2, r3			@ r2, index, r3 = ref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_1
-.abortentry105:
-	ldr	lr, [r3, #8]		@ lr = limit
-	DISPATCH_NEXT
-	cmp	r2, lr
-	bcs	array_bound_exception_jpc_1
-	DISPATCH_NEXT
-	add	r3, r3, r2, lsl #2
-	str	tmp1, [r3, #BASE_OFFSET_WORD]
-	DISPATCH_FINISH
-}
-
-(isub)(iadd) {
-	DISPATCH_START	\seq_len
-	POP	r2, r3, tmp1
-	DISPATCH_NEXT
-	sub	tmp2, r3, r2
-	DISPATCH_NEXT
-	add	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-}
-
-(isub)(isub) {
-	DISPATCH_START	\seq_len
-	POP	r2, r3, tmp1
-	DISPATCH_NEXT
-	sub	tmp2, r3, r2
-	DISPATCH_NEXT
-	sub	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	tmp2
-	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
-        ldrsb   r2, [jpc, #-1]
-	DISPATCH_NEXT
-	PUSH	tmp1
-	ldr	tmp1, [locals, -r3, lsl #2]
-	DISPATCH_NEXT
-	add	tmp1, tmp1, r2
-	str	tmp1, [locals, -r3, lsl #2]
-	DISPATCH_FINISH
-}
-@ ---- iand; xxx ------------------------------------------------------------
-
-(iand)(iload,fload,aload) {
-	ldrb	r3, [jpc, #2]
-	DISPATCH_START	\seq_len
-	POP	tmp2, tmp1
-	DISPATCH_NEXT
-	rsb	r3, r3, #0
-	DISPATCH_NEXT
-	ldr	r3, [locals, r3, lsl #2]
-	DISPATCH_NEXT
-	and	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	PUSH	r3, tmp2
-	DISPATCH_FINISH
-}
-
-(iand)
-(iload_0,iload_1,iload_2,iload_3)
-{
-	DISPATCH_START	\seq_len
-	rsb	r3, r1, #opc_iload_0
-	POP	tmp2, tmp1
-	DISPATCH_NEXT
-	ldr	r3, [locals, r3, lsl #2]
-	and	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	r3, tmp2
-	DISPATCH_FINISH
-}
-
-(iand)(iaload,aaload,faload) {
-	POP	r2, r3, lr		@ lr = ref
-	DISPATCH_START	\seq_len
-	and	r2, r3, r2		@ r2 = index
-	SW_NPC	cmp	lr, #0
-	SW_NPC	beq	null_ptr_exception_jpc_1
-.abortentry75:
-	ldr	tmp1, [lr, #8]		@ tmp1 = length
-	DISPATCH_NEXT
-	cmp	r2, tmp1
-	bcs	array_bound_exception_jpc_1
-	add	lr, lr, r2, lsl #2
-	ldr	tmp1, [lr, #BASE_OFFSET_WORD]
-	DISPATCH_NEXT
-	PUSH	tmp1
-	DISPATCH_FINISH
-}
-
-(iand)(istore) {
-	mov	r0, #opc_iand_u4store
-	strb	r0, [jpc]
-	b	do_iand_u4store
-}
-
-(iand)
-(istore_0,istore_1,istore_2,istore_3) {
-	mov	r0, #opc_iand_istore_N
-	strb	r0, [jpc]
-	b	do_iand_istore_N
-}
-
-(iand)(iastore,fastore) {
-	POP	r2, r3
-	DISPATCH_START	\seq_len
-	and	tmp1, r3, r2		@ tmp1 = value
-	POP	r2, r3			@ r2, index, r3 = ref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_1
-.abortentry107:
-	ldr	lr, [r3, #8]		@ lr = limit
-	DISPATCH_NEXT
-	cmp	r2, lr
-	bcs	array_bound_exception_jpc_1
-	DISPATCH_NEXT
-	add	r3, r3, r2, lsl #2
-	str	tmp1, [r3, #BASE_OFFSET_WORD]
-	DISPATCH_FINISH
-}
-
-(iand)(iadd) {
-	DISPATCH_START	\seq_len
-	POP	r2, r3, tmp1
-	DISPATCH_NEXT
-	and	tmp2, r3, r2
-	DISPATCH_NEXT
-	add	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-}
-
-(iand)(isub) {
-	DISPATCH_START	\seq_len
-	POP	r2, r3, tmp1
-	DISPATCH_NEXT
-	and	tmp2, r3, r2
-	DISPATCH_NEXT
-	sub	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	tmp2
-	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
-        ldrsb   r2, [jpc, #-1]
-	DISPATCH_NEXT
-	PUSH	tmp1
-	ldr	tmp1, [locals, -r3, lsl #2]
-	DISPATCH_NEXT
-	add	tmp1, tmp1, r2
-	str	tmp1, [locals, -r3, lsl #2]
-	DISPATCH_FINISH
-}
-@ ---- ior; xxx ------------------------------------------------------------
-
-(ior)(iload,fload,aload) {
-	ldrb	r3, [jpc, #2]
-	DISPATCH_START	\seq_len
-	POP	tmp2, tmp1
-	DISPATCH_NEXT
-	rsb	r3, r3, #0
-	DISPATCH_NEXT
-	ldr	r3, [locals, r3, lsl #2]
-	DISPATCH_NEXT
-	orr	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	PUSH	r3, tmp2
-	DISPATCH_FINISH
-}
-
-(ior)
-(iload_0,iload_1,iload_2,iload_3)
-{
-	DISPATCH_START	\seq_len
-	rsb	r3, r1, #opc_iload_0
-	POP	tmp2, tmp1
-	DISPATCH_NEXT
-	ldr	r3, [locals, r3, lsl #2]
-	orr	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	r3, tmp2
-	DISPATCH_FINISH
-}
-
-(ior)(iaload,aaload,faload) {
-	POP	r2, r3, lr		@ lr = ref
-	DISPATCH_START	\seq_len
-	orr	r2, r3, r2		@ r2 = index
-	SW_NPC	cmp	lr, #0
-	SW_NPC	beq	null_ptr_exception_jpc_1
-.abortentry76:
-	ldr	tmp1, [lr, #8]		@ tmp1 = length
-	DISPATCH_NEXT
-	cmp	r2, tmp1
-	bcs	array_bound_exception_jpc_1
-	add	lr, lr, r2, lsl #2
-	ldr	tmp1, [lr, #BASE_OFFSET_WORD]
-	DISPATCH_NEXT
-	PUSH	tmp1
-	DISPATCH_FINISH
-}
-
-(ior)(istore) {
-	mov	r0, #opc_ior_u4store
-	strb	r0, [jpc]
-	b	do_ior_u4store
-}
-
-(ior)
-(istore_0,istore_1,istore_2,istore_3) {
-	mov	r0, #opc_ior_istore_N
-	strb	r0, [jpc]
-	b	do_ior_istore_N
-}
-
-(ior)(iastore,fastore) {
-	POP	r2, r3
-	DISPATCH_START	\seq_len
-	orr	tmp1, r3, r2		@ tmp1 = value
-	POP	r2, r3			@ r2, index, r3 = ref
-	SW_NPC	cmp	r3, #0
-	SW_NPC	beq	null_ptr_exception_jpc_1
-.abortentry108:
-	ldr	lr, [r3, #8]		@ lr = limit
-	DISPATCH_NEXT
-	cmp	r2, lr
-	bcs	array_bound_exception_jpc_1
-	DISPATCH_NEXT
-	add	r3, r3, r2, lsl #2
-	str	tmp1, [r3, #BASE_OFFSET_WORD]
-	DISPATCH_FINISH
-}
-
-(ior)(iadd) {
-	DISPATCH_START	\seq_len
-	POP	r2, r3, tmp1
-	DISPATCH_NEXT
-	orr	tmp2, r3, r2
-	DISPATCH_NEXT
-	add	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	tmp2
-	DISPATCH_FINISH
-}
-
-(ior)(isub) {
-	DISPATCH_START	\seq_len
-	POP	r2, r3, tmp1
-	DISPATCH_NEXT
-	orr	tmp2, r3, r2
-	DISPATCH_NEXT
-	sub	tmp2, tmp1, tmp2
-	DISPATCH_NEXT
-	DISPATCH_NEXT
-	PUSH	tmp2
-	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) {
+(iand)(iinc) {
 	POP	tmp1, lr
 	DISPATCH_START	\seq_len
-	orr	tmp1, lr, tmp1
-        ldrb    r3, [jpc, #-2]	@ ECN: jpc now points to next bc
+	and	tmp1, lr, tmp1
+        ldrb    r3, [jpc, #-2]	@ jpc now points to next bc
         ldrsb   r2, [jpc, #-1]
 	DISPATCH_NEXT
 	PUSH	tmp1
@@ -6751,10 +5015,9 @@
 	str	tmp1, [locals, -r3, lsl #2]
 	DISPATCH_FINISH
 }
+@ ---- ior; xxx ------------------------------------------------------------
 
-@ ---- ixor; xxx ------------------------------------------------------------
-
-(ixor)(iload,fload,aload) {
+(ior)(iload,fload,aload) {
 	ldrb	r3, [jpc, #2]
 	DISPATCH_START	\seq_len
 	POP	tmp2, tmp1
@@ -6763,13 +5026,13 @@
 	DISPATCH_NEXT
 	ldr	r3, [locals, r3, lsl #2]
 	DISPATCH_NEXT
-	eor	tmp2, tmp1, tmp2
+	orr	tmp2, tmp1, tmp2
 	DISPATCH_NEXT
 	PUSH	r3, tmp2
 	DISPATCH_FINISH
 }
 
-(ixor)
+(ior)
 (iload_0,iload_1,iload_2,iload_3)
 {
 	DISPATCH_START	\seq_len
@@ -6777,7 +5040,7 @@
 	POP	tmp2, tmp1
 	DISPATCH_NEXT
 	ldr	r3, [locals, r3, lsl #2]
-	eor	tmp2, tmp1, tmp2
+	orr	tmp2, tmp1, tmp2
 	DISPATCH_NEXT
 	DISPATCH_NEXT
 	DISPATCH_NEXT
@@ -6785,13 +5048,13 @@
 	DISPATCH_FINISH
 }
 
-(ixor)(iaload,aaload,faload) {
+(ior)(iaload,aaload,faload) {
 	POP	r2, r3, lr		@ lr = ref
 	DISPATCH_START	\seq_len
-	eor	r2, r3, r2		@ r2 = index
+	orr	r2, r3, r2		@ r2 = index
 	SW_NPC	cmp	lr, #0
 	SW_NPC	beq	null_ptr_exception_jpc_1
-.abortentry77:
+.abortentry76:
 	ldr	tmp1, [lr, #8]		@ tmp1 = length
 	DISPATCH_NEXT
 	cmp	r2, tmp1
@@ -6803,27 +5066,27 @@
 	DISPATCH_FINISH
 }
 
-(ixor)(istore) {
-	mov	r0, #opc_ixor_u4store
+(ior)(istore) {
+	mov	r0, #opc_ior_u4store
 	strb	r0, [jpc]
-	b	do_ixor_u4store
+	b	do_ior_u4store
 }
 
-(ixor)
+(ior)
 (istore_0,istore_1,istore_2,istore_3) {
-	mov	r0, #opc_ixor_istore_N
+	mov	r0, #opc_ior_istore_N
 	strb	r0, [jpc]
-	b	do_ixor_istore_N
+	b	do_ior_istore_N
 }
 
-(ixor)(iastore,fastore) {
+(ior)(iastore,fastore) {
 	POP	r2, r3
 	DISPATCH_START	\seq_len
-	eor	tmp1, r3, r2		@ tmp1 = value
+	orr	tmp1, r3, r2		@ tmp1 = value
 	POP	r2, r3			@ r2, index, r3 = ref
 	SW_NPC	cmp	r3, #0
 	SW_NPC	beq	null_ptr_exception_jpc_1
-.abortentry109:
+.abortentry108:
 	ldr	lr, [r3, #8]		@ lr = limit
 	DISPATCH_NEXT
 	cmp	r2, lr
@@ -6834,11 +5097,11 @@
 	DISPATCH_FINISH
 }
 
-(ixor)(iadd) {
+(ior)(iadd) {
 	DISPATCH_START	\seq_len
 	POP	r2, r3, tmp1
 	DISPATCH_NEXT
-	eor	tmp2, r3, r2
+	orr	tmp2, r3, r2
 	DISPATCH_NEXT
 	add	tmp2, tmp1, tmp2
 	DISPATCH_NEXT
@@ -6847,11 +5110,11 @@
 	DISPATCH_FINISH
 }
 
-(ixor)(isub) {
+(ior)(isub) {
 	DISPATCH_START	\seq_len
 	POP	r2, r3, tmp1
 	DISPATCH_NEXT
-	eor	tmp2, r3, r2
+	orr	tmp2, r3, r2
 	DISPATCH_NEXT
 	sub	tmp2, tmp1, tmp2
 	DISPATCH_NEXT
@@ -6860,255 +5123,134 @@
 	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
+(ior)(iinc) {
+	POP	tmp1, lr
+	DISPATCH_START	\seq_len
+	orr	tmp1, lr, tmp1
+        ldrb    r3, [jpc, #-2]	@ jpc now points to next bc
+        ldrsb   r2, [jpc, #-1]
+	DISPATCH_NEXT
+	PUSH	tmp1
+	ldr	tmp1, [locals, -r3, lsl #2]
+	DISPATCH_NEXT
+	add	tmp1, tmp1, r2
+	str	tmp1, [locals, -r3, lsl #2]
+	DISPATCH_FINISH
 }
 
-(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; xxx ------------------------------------------------------------
 
-(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)(iload,fload,aload) {
+	ldrb	r3, [jpc, #2]
+	DISPATCH_START	\seq_len
+	POP	tmp2, tmp1
+	DISPATCH_NEXT
+	rsb	r3, r3, #0
+	DISPATCH_NEXT
+	ldr	r3, [locals, r3, lsl #2]
+	DISPATCH_NEXT
+	eor	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	PUSH	r3, tmp2
+	DISPATCH_FINISH
 }
 
-(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)
+(iload_0,iload_1,iload_2,iload_3)
+{
+	DISPATCH_START	\seq_len
+	rsb	r3, r1, #opc_iload_0
+	POP	tmp2, tmp1
+	DISPATCH_NEXT
+	ldr	r3, [locals, r3, lsl #2]
+	eor	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	r3, tmp2
+	DISPATCH_FINISH
 }
 
-(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)(iaload,aaload,faload) {
+	POP	r2, r3, lr		@ lr = ref
+	DISPATCH_START	\seq_len
+	eor	r2, r3, r2		@ r2 = index
+	SW_NPC	cmp	lr, #0
+	SW_NPC	beq	null_ptr_exception_jpc_1
+.abortentry77:
+	ldr	tmp1, [lr, #8]		@ tmp1 = length
+	DISPATCH_NEXT
+	cmp	r2, tmp1
+	bcs	array_bound_exception_jpc_1
+	add	lr, lr, r2, lsl #2
+	ldr	tmp1, [lr, #BASE_OFFSET_WORD]
+	DISPATCH_NEXT
+	PUSH	tmp1
+	DISPATCH_FINISH
 }
 
-(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)(istore) {
+	mov	r0, #opc_ixor_u4store
+	strb	r0, [jpc]
+	b	do_ixor_u4store
 }
 
-(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)
+(istore_0,istore_1,istore_2,istore_3) {
+	mov	r0, #opc_ixor_istore_N
+	strb	r0, [jpc]
+	b	do_ixor_istore_N
 }
 
-(ixor)(goto) {
-        ldrsb   r1, [jpc, #2]
-        ldrb    ip, [jpc, #3]
-	add	jpc, jpc, #1
-	orr	ip, ip, r1, lsl #8
-	DISPATCH_START_REG	ip
+(ixor)(iastore,fastore) {
 	POP	r2, r3
-	eor	r2, r3, r2
+	DISPATCH_START	\seq_len
+	eor	tmp1, r3, r2		@ tmp1 = value
+	POP	r2, r3			@ r2, index, r3 = ref
+	SW_NPC	cmp	r3, #0
+	SW_NPC	beq	null_ptr_exception_jpc_1
+.abortentry109:
+	ldr	lr, [r3, #8]		@ lr = limit
 	DISPATCH_NEXT
-	PUSH	r2
+	cmp	r2, lr
+	bcs	array_bound_exception_jpc_1
+	DISPATCH_NEXT
+	add	r3, r3, r2, lsl #2
+	str	tmp1, [r3, #BASE_OFFSET_WORD]
 	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
+(ixor)(iadd) {
+	DISPATCH_START	\seq_len
+	POP	r2, r3, tmp1
+	DISPATCH_NEXT
+	eor	tmp2, r3, r2
+	DISPATCH_NEXT
+	add	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	tmp2
         DISPATCH_FINISH
-1:
-	PUSH	r1
-	add	jpc, jpc, #1
-	bl	return_check_monitors
-	POP	r1
-	b	2b
 }
 
-#endif // NOTICE_SAFEPOINTS
+(ixor)(isub) {
+	DISPATCH_START	\seq_len
+	POP	r2, r3, tmp1
+	DISPATCH_NEXT
+	eor	tmp2, r3, r2
+	DISPATCH_NEXT
+	sub	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
+}
 
 (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)
@@ -7233,334 +5375,24 @@
 	rsb	tmp1, r0, #opc_iaccess_0
 	ldrb	ip, [jpc, #2]
 	add	tmp2, constpool, r2, lsl #12
-	DISPATCH_START	5
-	ldr	tmp1, [locals, tmp1, lsl #2]
-	add	tmp2, ip, lsl #4
-	DISPATCH_NEXT
-	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_4
-	DISPATCH_NEXT
-        ldr     tmp2, [tmp2, #CP_OFFSET+8]
-	DISPATCH_NEXT
-	POP	r3
-.abortentry91:
-	ldr	tmp2, [tmp1, tmp2]
-	DISPATCH_NEXT
-	add	tmp2, tmp2, r3
-	PUSH	tmp2
-	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
+	DISPATCH_START	5
 	ldr	tmp1, [locals, tmp1, lsl #2]
 	add	tmp2, ip, lsl #4
-	ldrb	ip, [jpc, #2]
+	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
-	SW_NPC	beq	null_ptr_exception_jpc_3
+	SW_NPC	beq	null_ptr_exception_jpc_4
+	DISPATCH_NEXT
         ldr     tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
 	POP	r3
-	orr	ip, ip, r0, lsl #8
-.abortentry103:
+.abortentry91:
 	ldr	tmp2, [tmp1, tmp2]
-	cmp	r3, tmp2
-	ble	1f
-	mov	ip, #3
-1:
-	ldrb	r0, [jpc, ip]!
-	DISPATCH_BYTECODE
+	DISPATCH_NEXT
+	add	tmp2, tmp2, r3
+	PUSH	tmp2
+	DISPATCH_FINISH
 }
 
-#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,19 +6558,16 @@
 	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
-	rsb	r2, r0, #opc_iload_0_iload_N
 	ldrsb	r1, [jpc, #3]
+	rsb	r2, r0, #opc_iload_0_iload_N
+	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
-	rsb	r2, r0, #opc_iload_0_iload_N
 	ldrsb	r1, [jpc, #3]
-	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
+	rsb	r2, r0, #opc_iload_0_iload_N
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
+	ldr	r2, [locals, r2, lsl #2]
+	ldrb	ip, [jpc, #4]
 	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
-	rsb	r2, r0, #opc_iload_0_iload_N
 	ldrsb	r1, [jpc, #3]
-	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
+	rsb	r2, r0, #opc_iload_0_iload_N
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
+	ldr	r2, [locals, r2, lsl #2]
+	ldrb	ip, [jpc, #4]
 	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
-	rsb	r2, r0, #opc_iload_0_iload_N
 	ldrsb	r1, [jpc, #3]
-	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
+	rsb	r2, r0, #opc_iload_0_iload_N
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
+	ldr	r2, [locals, r2, lsl #2]
+	ldrb	ip, [jpc, #4]
 	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
-	rsb	r2, r0, #opc_iload_0_iload_N
 	ldrsb	r1, [jpc, #3]
-	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
+	rsb	r2, r0, #opc_iload_0_iload_N
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
+	ldr	r2, [locals, r2, lsl #2]
+	ldrb	ip, [jpc, #4]
 	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
-	rsb	r2, r0, #opc_iload_0_iload_N
 	ldrsb	r1, [jpc, #3]
-	ldrb	ip, [jpc, #4]
-	ldr	r2, [locals, r2, lsl #2]
+	rsb	r2, r0, #opc_iload_0_iload_N
 	ldr	r3, [locals, r3, lsl #2]
-	add	jpc, jpc, #2
+	ldr	r2, [locals, r2, lsl #2]
+	ldrb	ip, [jpc, #4]
 	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
+	ble	branch_taken_unsafe_2
+	DISPATCH 5
 }
 
-#endif //HW_FP
+#endif
 
 #endif // FAST_BYTECODES
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S new/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	2010-01-19 15:29:04.000000000 +0000
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	2010-01-19 15:41:12.000000000 +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
+ at ------------------------------------------------
+@ THUMB2 specific code macro
+@ Usage:
+@	T2	<thumb2 specific code>
+ at ------------------------------------------------
+	.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
+native_entry_synchronized:
+	b	fast_native_entry_synchronized
+
+	ALIGN_CODE
+fast_native_entry_synchronized:
+	b	_ZN14CppInterpreter12native_entryEP13methodOopDesciP6Thread
 
 	ALIGN_CODE
-	.global	empty_entry
 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
+	POP	r1
+	POP	r0
+	cmp	r1, #0
+	beq	divide_by_zero_exception
+	bl	__aeabi_idiv
+	PUSH	r0
+	DISPATCH 1
 
-.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
+	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
+	POP	r1
+	POP	r0
+	cmp	r1, #0
+	beq	divide_by_zero_exception
+	bl	__aeabi_idivmod
+	PUSH	r1
+	DISPATCH 1
 
-.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
+	Opcode	irem_clz
 
-.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
+	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}
+	ldmfd	arm_sp!, {fast_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
+#endif // THUMB2EE
 
-        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
+#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
-	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]
+	DECACHE_JPC
+	DECACHE_STACK
+	mov	r0, r8
+	POP	r1, r2, r3
+	bl	Helper_aastore
+	CACHE_JPC
 	CACHE_CP
-	DISPATCH	1
+	cmp	r0, #0
+	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]
-	CACHE_LOCALS
 	tst	r3, #JVM_ACC_SYNCHRONIZED
-	CACHE_CP
-	bne	normal_do_synchronization
-	DISPATCH	0
-#endif
+	beq	1f
 
-do_execute_java_bytecodes_restore_locals_and_jpc:
-	CACHE_JPC
-do_execute_java_bytecodes_restore_locals:
+@ Do Synchronisation
+	CACHE_STACK
 	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,39 +2386,76 @@
 	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
-
-# r2 = [jpc, #1]
-# r1 = [jpc, #2]
-	Opcode	invokeinterface
-	ldrb	r1, [jpc, #2]
-	DECACHE_STACK
-        add     r0, constpool, r1, lsl #12
-	add	r0, r0, r2, asl #4
-	DECACHE_JPC
-        ldr     r2, [r0, #CP_OFFSET]
-        and     r2, r2, #0x00ff0000
-        cmp     r2, #opc_invokeinterface << 16
-        blne    resolve_invokeinterface
+	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
 
-	ldr	r3, [r0, #CP_OFFSET+12]
-	and	r2, r3, #255
-	ldr	r2, [stack, r2, lsl #2]
-	SW_NPC	cmp	r2, #0
-	SW_NPC	beq	null_ptr_exception
-.abortentry110:
+#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]
+	Opcode	invokeinterface
+	ldrb	r1, [jpc, #2]
+	DECACHE_STACK
+        add     r0, constpool, r1, lsl #12
+	add	r0, r0, r2, asl #4
+	DECACHE_JPC
+        ldr     r2, [r0, #CP_OFFSET]
+        and     r2, r2, #0x00ff0000
+        cmp     r2, #opc_invokeinterface << 16
+        blne    resolve_invokeinterface
+
+	ldr	r3, [r0, #CP_OFFSET+12]
+	and	r2, r3, #255
+	ldr	r2, [stack, r2, lsl #2]
+	SW_NPC	cmp	r2, #0
+	SW_NPC	beq	null_ptr_exception
+.abortentry110:
 	ldr	tmp2, [r2, #4]				@ rcvr->klass()
 	tst	r3, #flag_methodInterface
 	bne	.invokeinterface_methodInterface
@@ -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
+normal_entry:
+	stmfd	arm_sp!, {regset, lr}
 
-	cmp	r3, #0
-	beq	normal_entry
+	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
 
-	ldr	r0, [r1, #12]
-	ldr	r1, [r1, #8]
-	movs	r0, r0, lsr #29
-	bls	accessor_non_w
+	bl	fast_normal_entry
 
-	ldr	r0, [r3, r1]
-	str	r0, [ip, #0]
-	bx	lr
+	ldmfd	arm_sp!, {regset, pc}
 
-#ifdef NATIVE_ENTRY
 	ALIGN_CODE
-native_entry:
+fast_normal_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
+	mov	tmp2, r0
+	ldm	ip, {r0, r1}
+	mov	tmp1, r2
+	add	r0, r0, ip
+	ldr	stack, [tmp1, #THREAD_JAVA_SP]
+	add	dispatch, r1, r0
 
-	b	fast_native_entry_with_args
-#endif
+	stmdb	arm_sp!, {fast_regset, lr}
 
-@ tmp1 = thread
-@ tmp2 == method
-@ stack == THREAD_JAVA_SP (=> FULL stack)
-	ALIGN_CODE
-fast_normal_entry:
-	mov	tmp_invoke_len, #3
-fast_normal_entry_with_len:
 	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
 
-handle_return:
-@	CHECK_CONSTPOOL
-@	CHECK_BACKTRACE
+#endif // USE_COMPILER
+	.global	Thumb2_Install
+Thumb2_Install:
+@	ldr	r0, [r0]
+	str	r1, [r0, #METHOD_FROM_INTERPRETED]
+	bx	lr
 
+handle_return:
 	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
-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}
 
+stack_overflow_before_frame:
+	mov	r0, tmp1
+	ldr	ip, [r0, #THREAD_TOP_ZERO_FRAME]
+	str	ip, [r0, #THREAD_LAST_JAVA_SP]
+	bl	_ZN18InterpreterRuntime24throw_StackOverflowErrorEP10JavaThread
+	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	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]
-	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	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
-	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
+	ldrb	r0, [tmp_xxx, #THREAD_DO_NOT_UNLOCK]
+	strb	r3, [tmp_xxx, #THREAD_DO_NOT_UNLOCK]
 	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]
+	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_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]
-	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:
-	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
+	str	r3, [tmp2, #4]			@ base->obj = NULL
 
-.handle_exception_27:
-	add	r0, except_sp, #EXCEPTION_HANDLEMARK2
-	ldr	r1, [istate, #ISTATE_THREAD]
-	bl	_ZN10HandleMark10initializeEP6Thread
-	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]
-	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
+	ldmeqia	arm_sp!, {r4, pc}
 
-#ifdef FASTPATH_ENTRY
+	mov	r1, tmp1
+	mov	r2, tmp2
+	bl	cmpxchg_ptr
+	cmp	tmp2, r0
 
-	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]
+	ldmeqia	arm_sp!, {r4, pc}
 
-	DISPATCH_START	3
+	str	tmp1, [tmp2, #4]
 
-	orr	r2, r2, r3, lsl #8		@ r2 = index
-	add	r3, ip, #16
-	ldr	r2, [r3, r2, lsl #4]!		@ r3 = cache, r2 = flags
+	mov	r1, tmp2
+	ldr	r0, [istate, #ISTATE_THREAD]
+	bl	Helper_synchronized_exit
 
-	DISPATCH_NEXT
+	ldmeqia	arm_sp!, {r4, pc}
 
-	cmp	r2, #opc_getfield << 16
-	GET_STACK	0, r2
-	bne	fast_normal_entry
+3:
+	ldr	r0, [istate, #ISTATE_THREAD]
+	bl	Helper_RaiseIllegalMonitorException
+	b	2b
 
-	cmp	r2, #0
-	beq	fast_normal_entry
+4:
+	ldr	r0, [istate, #ISTATE_THREAD]
+	bl	Helper_RaiseIllegalMonitorException
+	ldmia	arm_sp!, {r4, pc}
 
+	ALIGN_CODE
+accessor_entry:
+	b	slow_accessor_entry
 
-	ldr	lr, [r3, #12]
-	ldr	r3, [r3, #8]
-	movs	lr, lr, lsr #29
-	bls	.fast_accessor_non_w
+	ALIGN_CODE
+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]
 
-	DISPATCH_NEXT
+  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
 
-	ldr	tmp1, [r2, r3]
+	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
 
-	DISPATCH_NEXT
-	DISPATCH_NEXT
+	cmp	r3, #0
+	beq	normal_entry
 
-	PUT_STACK	0, tmp1
+	ldr	r0, [r1, #12]
+	ldr	r1, [r1, #8]
+	movs	r0, r0, lsr #29
+	bls	accessor_non_w
 
-	DISPATCH_FINISH
+	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
 
-	.section	.init_array,"aw",%init_array
-	.word	bci_init(target1)
+	.arch	armv7-a
 
-	.data
-	ALIGN_DATA
-#ifdef CODETRACE
-CodeTrace_Buffer_Base:
-	.space	CODETRACE_BUFFER_SIZE
-#endif
+	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
         .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
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/thumb2.cpp new/icedtea6/ports/hotspot/src/cpu/zero/vm/thumb2.cpp
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/thumb2.cpp	1970-01-01 01:00:00.000000000 +0100
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/thumb2.cpp	2010-01-19 15:42:03.000000000 +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



More information about the distro-pkg-dev mailing list