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