[X86] X86 trace JIT compiler support

This patch provides a fully functional x86 trace JIT compiler for Dalvik
VM. It is built on top of the existing x86 fast interpreter
with bug fixes and needed extension to support trace JIT interface. The
x86 trace JIT code generator was developed independent of the existing
template-based code generator and thus does not share exactly the same
infrastructure. Included in this patch are:

* Deprecated and removed the x86-atom fast interpreter that is no
  longer functional since ICS.
* Augmented x86 fast interpreter to provide interfaces for x86 trace JIT
  compiler.
* Added x86 trace JIT code generator with full JDWP debugging support.
* Method JIT and self-verification mode are not supported.

The x86 code generator uses the x86 instruction encoder/decoder library
from the Apache Harmony project. Additional wrapper extension and bug
fixes were added to support the x86 trace JIT code generator. The x86
instruction encoder/decoder is embedded inside the x86 code generator
under the libenc subdirectory.

Change-Id: I241113681963a16c13a3562390813cbaaa6eedf0
Signed-off-by: Dong-Yuan Chen <dong-yuan.chen@intel.com>
Signed-off-by: Yixin Shou <yixin.shou@intel.com>
Signed-off-by: Johnnie Birch <johnnie.l.birch.jr@intel.com>
Signed-off-by: Udayan <udayan.banerji@intel.com>
Signed-off-by: Sushma Kyasaralli Thimmappa <sushma.kyasaralli.thimmappa@intel.com>
Signed-off-by: Bijoy Jose <bijoy.a.jose@intel.com>
Signed-off-by: Razvan A Lupusoru <razvan.a.lupusoru@intel.com>
Signed-off-by: Tim Hartley <timothy.d.hartley@intel.com>
diff --git a/NOTICE b/NOTICE
index c5b1efa..4760004 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,3 +1,8 @@
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the Android-specific code.                        ==
+   =========================================================================
 
    Copyright (c) 2005-2008, The Android Open Source Project
 
@@ -188,3 +193,31 @@
 
    END OF TERMS AND CONDITIONS
 
+   =========================================================================
+   ==  NOTICE file for the x86 JIT libenc subdirectory.                   ==
+   =========================================================================
+
+Apache Harmony
+Copyright 2006, 2010 The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Portions of Harmony were originally developed by
+Intel Corporation and are licensed to the Apache Software
+Foundation under the "Software Grant and Corporate Contribution
+License Agreement" and for which the following copyright notices
+apply
+         (C) Copyright 2005 Intel Corporation
+         (C) Copyright 2005-2006 Intel Corporation
+         (C) Copyright 2006 Intel Corporation
+
+Portions of the Apache Portable Runtime used by DRLVM were
+developed at the National Center for Supercomputing Applications
+(NCSA) at the University of Illinois at Urbana-Champaign.
+
+This software contains code derived from the RSA Data Security
+Inc. MD5 Message-Digest Algorithm.
+
+This software contains code derived from UNIX V7, Copyright(C)
+Caldera International Inc.
diff --git a/tests/063-process-manager/src/Main.java b/tests/063-process-manager/src/Main.java
index c94b8ad..68bf878 100644
--- a/tests/063-process-manager/src/Main.java
+++ b/tests/063-process-manager/src/Main.java
@@ -14,7 +14,7 @@
 
     static private void child() throws Exception {
         System.out.println("spawning child");
-        ProcessBuilder pb = new ProcessBuilder("/system/bin/sleep", "5");
+        ProcessBuilder pb = new ProcessBuilder("sleep", "5");
         Process proc = pb.start();
         Thread.sleep(1000);
         checkManager();
diff --git a/tests/etc/host-run-test-jar b/tests/etc/host-run-test-jar
index ab7278e..c85c419 100755
--- a/tests/etc/host-run-test-jar
+++ b/tests/etc/host-run-test-jar
@@ -78,8 +78,8 @@
 done
 
 if [ "x$INTERP" = "x" ]; then
-    INTERP="fast" # TODO: change this to "jit" when the x86 jit is merged.
-    msg "Using fast interpreter by default"
+    INTERP="jit"
+    msg "Using jit by default"
 fi
 
 if [ "$OPTIMIZE" = "y" ]; then
diff --git a/vm/Android.mk b/vm/Android.mk
index 7a0d036..64e4aaf 100644
--- a/vm/Android.mk
+++ b/vm/Android.mk
@@ -92,6 +92,10 @@
     LOCAL_MODULE := libdvm_interp
     include $(BUILD_SHARED_LIBRARY)
 
+  ifeq ($(dvm_arch),x86)    # For x86, we enable JIT on host too
+    # restore WITH_JIT = true for host dalvik build
+    WITH_JIT := true
+  endif # dvm_arch==x86
 endif
 
 #
@@ -108,7 +112,11 @@
     # Note: HOST_ARCH_VARIANT isn't defined.
     dvm_arch_variant := $(HOST_ARCH)
 
-    WITH_JIT := false
+    # We always want the x86 JIT.
+    ifeq ($(dvm_arch),x86)
+        WITH_JIT := true
+    endif
+
     include $(LOCAL_PATH)/Dvm.mk
 
     LOCAL_SHARED_LIBRARIES += libcrypto libssl libicuuc libicui18n
diff --git a/vm/Dvm.mk b/vm/Dvm.mk
index 7774398..1b95d77 100644
--- a/vm/Dvm.mk
+++ b/vm/Dvm.mk
@@ -284,19 +284,41 @@
 ifeq ($(dvm_arch),x86)
   ifeq ($(dvm_os),linux)
     MTERP_ARCH_KNOWN := true
-    LOCAL_CFLAGS += -DDVM_JMP_TABLE_MTERP=1
+    LOCAL_CFLAGS += -DDVM_JMP_TABLE_MTERP=1 \
+                    -DMTERP_STUB
     LOCAL_SRC_FILES += \
 		arch/$(dvm_arch_variant)/Call386ABI.S \
 		arch/$(dvm_arch_variant)/Hints386ABI.cpp \
 		mterp/out/InterpC-$(dvm_arch_variant).cpp \
 		mterp/out/InterpAsm-$(dvm_arch_variant).S
     ifeq ($(WITH_JIT),true)
+      LOCAL_CFLAGS += -DARCH_IA32
       LOCAL_SRC_FILES += \
-		compiler/codegen/x86/Assemble.cpp \
-		compiler/codegen/x86/ArchUtility.cpp \
-		compiler/codegen/x86/ia32/Codegen.cpp \
-		compiler/codegen/x86/ia32/CallingConvention.S \
-		compiler/template/out/CompilerTemplateAsm-ia32.S
+                compiler/codegen/x86/LowerAlu.cpp \
+                compiler/codegen/x86/LowerConst.cpp \
+                compiler/codegen/x86/LowerMove.cpp \
+                compiler/codegen/x86/Lower.cpp \
+                compiler/codegen/x86/LowerHelper.cpp \
+                compiler/codegen/x86/LowerJump.cpp \
+                compiler/codegen/x86/LowerObject.cpp \
+                compiler/codegen/x86/AnalysisO1.cpp \
+                compiler/codegen/x86/BytecodeVisitor.cpp \
+                compiler/codegen/x86/NcgAot.cpp \
+                compiler/codegen/x86/CodegenInterface.cpp \
+                compiler/codegen/x86/LowerInvoke.cpp \
+                compiler/codegen/x86/LowerReturn.cpp \
+                compiler/codegen/x86/NcgHelper.cpp \
+                compiler/codegen/x86/LowerGetPut.cpp
+
+      # need apache harmony x86 encoder/decoder
+      LOCAL_C_INCLUDES += \
+                dalvik/vm/compiler/codegen/x86/libenc
+      LOCAL_SRC_FILES += \
+                compiler/codegen/x86/libenc/enc_base.cpp \
+                compiler/codegen/x86/libenc/dec_base.cpp \
+                compiler/codegen/x86/libenc/enc_wrapper.cpp \
+                compiler/codegen/x86/libenc/enc_tabl.cpp
+
     endif
   endif
 endif
diff --git a/vm/Globals.h b/vm/Globals.h
index c656206..3bef865 100644
--- a/vm/Globals.h
+++ b/vm/Globals.h
@@ -155,6 +155,9 @@
 
     ExecutionMode   executionMode;
 
+    bool        commonInit; /* whether common stubs are generated */
+    bool        constInit; /* whether global constants are initialized */
+
     /*
      * VM init management.
      */
@@ -870,15 +873,28 @@
     /* true/false: compile/reject methods specified in the -Xjitmethod list */
     bool includeSelectedMethod;
 
+    /* true/false: compile/reject traces with offset specified in the -Xjitoffset list */
+    bool includeSelectedOffset;
+
     /* Disable JIT for selected opcodes - one bit for each opcode */
     char opList[(kNumPackedOpcodes+7)/8];
 
     /* Disable JIT for selected methods */
     HashTable *methodTable;
 
+    /* Disable JIT for selected classes */
+    HashTable *classTable;
+
+    /* Disable JIT for selected offsets */
+    unsigned int pcTable[COMPILER_PC_OFFSET_SIZE];
+    int num_entries_pcTable;
+
     /* Flag to dump all compiled code */
     bool printMe;
 
+    /* Flag to dump compiled binary code in bytes */
+    bool printBinary;
+
     /* Per-process debug flag toggled when receiving a SIGUSR2 */
     bool receivedSIGUSR2;
 
@@ -948,6 +964,10 @@
     u8                 maxCompilerThreadBlockGCTime;
 #endif
 
+#if defined(ARCH_IA32)
+    JitOptLevel        optLevel;
+#endif
+
     /* Place arrays at the end to ease the display in gdb sessions */
 
     /* Work order queue for compilations */
diff --git a/vm/Init.cpp b/vm/Init.cpp
index 0a2ad98..5e3711e 100644
--- a/vm/Init.cpp
+++ b/vm/Init.cpp
@@ -31,6 +31,10 @@
 #include "mterp/Mterp.h"
 #include "Hash.h"
 
+#if defined(WITH_JIT)
+#include "compiler/codegen/Optimizer.h"
+#endif
+
 #define kMinHeapStartSize   (1*1024*1024)
 #define kMinHeapSize        (2*1024*1024)
 #define kMaxHeapSize        (1*1024*1024*1024)
@@ -133,6 +137,9 @@
     dvmFprintf(stderr, "  -Xjitblocking\n");
     dvmFprintf(stderr, "  -Xjitmethod:signature[,signature]* "
                        "(eg Ljava/lang/String\\;replace)\n");
+    dvmFprintf(stderr, "  -Xjitclass:classname[,classname]*\n");
+    dvmFprintf(stderr, "  -Xjitoffset:offset[,offset]\n");
+    dvmFprintf(stderr, "  -Xjitconfig:filename\n");
     dvmFprintf(stderr, "  -Xjitcheckcg\n");
     dvmFprintf(stderr, "  -Xjitverbose\n");
     dvmFprintf(stderr, "  -Xjitprofile\n");
@@ -229,16 +236,16 @@
  * Returns 0 (a useless size) if "s" is malformed or specifies a low or
  * non-evenly-divisible value.
  */
-static size_t parseMemOption(const char *s, size_t div)
+static size_t parseMemOption(const char* s, size_t div)
 {
     /* strtoul accepts a leading [+-], which we don't want,
      * so make sure our string starts with a decimal digit.
      */
     if (isdigit(*s)) {
-        const char *s2;
+        const char* s2;
         size_t val;
 
-        val = strtoul(s, (char **)&s2, 10);
+        val = strtoul(s, (char* *)&s2, 10);
         if (s2 != s) {
             /* s2 should be pointing just after the number.
              * If this is the end of the string, the user
@@ -549,11 +556,11 @@
 
 #if defined(WITH_JIT)
 /* Parse -Xjitop to selectively turn on/off certain opcodes for JIT */
-static void processXjitop(const char *opt)
+static void processXjitop(const char* opt)
 {
     if (opt[7] == ':') {
-        const char *startPtr = &opt[8];
-        char *endPtr = NULL;
+        const char* startPtr = &opt[8];
+        char* endPtr = NULL;
 
         do {
             long startValue, endValue;
@@ -602,15 +609,50 @@
     }
 }
 
-/* Parse -Xjitmethod to selectively turn on/off certain methods for JIT */
-static void processXjitmethod(const char *opt)
-{
-    char *buf = strdup(&opt[12]);
-    char *start, *end;
-
-    gDvmJit.methodTable = dvmHashTableCreate(8, NULL);
-
+/* Parse -Xjitoffset to selectively turn on/off traces with certain offsets for JIT */
+static void processXjitoffset(const char* opt) {
+    gDvmJit.num_entries_pcTable = 0;
+    char* buf = strdup(opt);
+    char* start, *end;
     start = buf;
+    int idx = 0;
+    do {
+        end = strchr(start, ',');
+        if (end) {
+            *end = 0;
+        }
+
+        dvmFprintf(stderr, "processXjitoffset start = %s\n", start);
+        char* tmp = strdup(start);
+        gDvmJit.pcTable[idx++] = atoi(tmp);
+        free(tmp);
+        if (idx >= COMPILER_PC_OFFSET_SIZE) {
+            dvmFprintf(stderr, "processXjitoffset: ignore entries beyond %d\n", COMPILER_PC_OFFSET_SIZE);
+            break;
+        }
+        if (end) {
+            start = end + 1;
+        } else {
+            break;
+        }
+    } while (1);
+    gDvmJit.num_entries_pcTable = idx;
+    free(buf);
+}
+
+/* Parse -Xjitmethod to selectively turn on/off certain methods for JIT */
+static void processXjitmethod(const char* opt, bool isMethod) {
+    char* buf = strdup(opt);
+
+    if (isMethod && gDvmJit.methodTable == NULL) {
+        gDvmJit.methodTable = dvmHashTableCreate(8, NULL);
+    }
+    if (!isMethod && gDvmJit.classTable == NULL) {
+        gDvmJit.classTable = dvmHashTableCreate(8, NULL);
+    }
+
+    char* start = buf;
+    char* end;
     /*
      * Break comma-separated method signatures and enter them into the hash
      * table individually.
@@ -624,10 +666,9 @@
         }
 
         hashValue = dvmComputeUtf8Hash(start);
+        dvmHashTableLookup(isMethod ? gDvmJit.methodTable : gDvmJit.classTable,
+                           hashValue, strdup(start), (HashCompareFunc) strcmp, true);
 
-        dvmHashTableLookup(gDvmJit.methodTable, hashValue,
-                           strdup(start),
-                           (HashCompareFunc) strcmp, true);
         if (end) {
             start = end + 1;
         } else {
@@ -636,6 +677,88 @@
     } while (1);
     free(buf);
 }
+
+/* The format of jit_config.list:
+   EXCLUDE or INCLUDE
+   CLASS
+   prefix1 ...
+   METHOD
+   prefix 1 ...
+   OFFSET
+   index ... //each pair is a range, if pcOff falls into a range, JIT
+*/
+static int processXjitconfig(const char* opt) {
+   FILE* fp = fopen(opt, "r");
+   if (fp == NULL) {
+       return -1;
+   }
+
+   char fLine[500];
+   bool startClass = false, startMethod = false, startOffset = false;
+   gDvmJit.num_entries_pcTable = 0;
+   int idx = 0;
+
+   while (fgets(fLine, 500, fp) != NULL) {
+       char* curLine = strtok(fLine, " \t\r\n");
+       /* handles keyword CLASS, METHOD, INCLUDE, EXCLUDE */
+       if (!strncmp(curLine, "CLASS", 5)) {
+           startClass = true;
+           startMethod = false;
+           startOffset = false;
+           continue;
+       }
+       if (!strncmp(curLine, "METHOD", 6)) {
+           startMethod = true;
+           startClass = false;
+           startOffset = false;
+           continue;
+       }
+       if (!strncmp(curLine, "OFFSET", 6)) {
+           startOffset = true;
+           startMethod = false;
+           startClass = false;
+           continue;
+       }
+       if (!strncmp(curLine, "EXCLUDE", 7)) {
+          gDvmJit.includeSelectedMethod = false;
+          continue;
+       }
+       if (!strncmp(curLine, "INCLUDE", 7)) {
+          gDvmJit.includeSelectedMethod = true;
+          continue;
+       }
+       if (!startMethod && !startClass && !startOffset) {
+         continue;
+       }
+
+        int hashValue = dvmComputeUtf8Hash(curLine);
+        if (startMethod) {
+            if (gDvmJit.methodTable == NULL) {
+                gDvmJit.methodTable = dvmHashTableCreate(8, NULL);
+            }
+            dvmHashTableLookup(gDvmJit.methodTable, hashValue,
+                               strdup(curLine),
+                               (HashCompareFunc) strcmp, true);
+        } else if (startClass) {
+            if (gDvmJit.classTable == NULL) {
+                gDvmJit.classTable = dvmHashTableCreate(8, NULL);
+            }
+            dvmHashTableLookup(gDvmJit.classTable, hashValue,
+                               strdup(curLine),
+                               (HashCompareFunc) strcmp, true);
+        } else if (startOffset) {
+           int tmpInt = atoi(curLine);
+           gDvmJit.pcTable[idx++] = tmpInt;
+           if (idx >= COMPILER_PC_OFFSET_SIZE) {
+               printf("processXjitoffset: ignore entries beyond %d\n", COMPILER_PC_OFFSET_SIZE);
+               break;
+           }
+        }
+   }
+   gDvmJit.num_entries_pcTable = idx;
+   fclose(fp);
+   return 0;
+}
 #endif
 
 /*
@@ -954,8 +1077,14 @@
 #ifdef WITH_JIT
         } else if (strncmp(argv[i], "-Xjitop", 7) == 0) {
             processXjitop(argv[i]);
-        } else if (strncmp(argv[i], "-Xjitmethod", 11) == 0) {
-            processXjitmethod(argv[i]);
+        } else if (strncmp(argv[i], "-Xjitmethod:", 12) == 0) {
+            processXjitmethod(argv[i] + strlen("-Xjitmethod:"), true);
+        } else if (strncmp(argv[i], "-Xjitclass:", 11) == 0) {
+            processXjitmethod(argv[i] + strlen("-Xjitclass:"), false);
+        } else if (strncmp(argv[i], "-Xjitoffset:", 12) == 0) {
+            processXjitoffset(argv[i] + strlen("-Xjitoffset:"));
+        } else if (strncmp(argv[i], "-Xjitconfig:", 12) == 0) {
+            processXjitconfig(argv[i] + strlen("-Xjitconfig:"));
         } else if (strncmp(argv[i], "-Xjitblocking", 13) == 0) {
           gDvmJit.blockingMode = true;
         } else if (strncmp(argv[i], "-Xjitthreshold:", 15) == 0) {
@@ -968,6 +1097,8 @@
           gDvmJit.checkCallGraph = true;
           /* Need to enable blocking mode due to stack crawling */
           gDvmJit.blockingMode = true;
+        } else if (strncmp(argv[i], "-Xjitdumpbin", 12) == 0) {
+          gDvmJit.printBinary = true;
         } else if (strncmp(argv[i], "-Xjitverbose", 12) == 0) {
           gDvmJit.printMe = true;
         } else if (strncmp(argv[i], "-Xjitprofile", 12) == 0) {
@@ -1099,6 +1230,15 @@
      */
 #if defined(WITH_JIT)
     gDvm.executionMode = kExecutionModeJit;
+    gDvmJit.num_entries_pcTable = 0;
+    gDvmJit.includeSelectedMethod = false;
+    gDvmJit.includeSelectedOffset = false;
+    gDvmJit.methodTable = NULL;
+    gDvmJit.classTable = NULL;
+
+    gDvm.constInit = false;
+    gDvm.commonInit = false;
+    gDvmJit.disableOpt = 1<<kMethodInlining;
 #else
     gDvm.executionMode = kExecutionModeInterpFast;
 #endif
diff --git a/vm/ReconfigureDvm.mk b/vm/ReconfigureDvm.mk
index 3633e71..34eb0a4 100644
--- a/vm/ReconfigureDvm.mk
+++ b/vm/ReconfigureDvm.mk
@@ -19,11 +19,6 @@
 dvm_arch := $(TARGET_ARCH)
 dvm_arch_variant := $(TARGET_ARCH_VARIANT)
 
-# for now, disable x86-atom variant
-ifeq ($(dvm_arch_variant),x86-atom)
-dvm_arch_variant := x86
-endif
-
 include $(LOCAL_PATH)/Dvm.mk
 
 LOCAL_SHARED_LIBRARIES += liblog libcutils libnativehelper libz libdl libcorkscrew
diff --git a/vm/Thread.h b/vm/Thread.h
index 9fa2e03..8deef6e 100644
--- a/vm/Thread.h
+++ b/vm/Thread.h
@@ -303,6 +303,10 @@
     pthread_mutex_t   callbackMutex;
     SafePointCallback callback;
     void*             callbackArg;
+
+#if defined(ARCH_IA32) && defined(WITH_JIT)
+    u4 spillRegion[MAX_SPILL_JIT_IA];
+#endif
 };
 
 /* start point for an internal thread; mimics pthread args */
diff --git a/vm/arch/x86-atom/Call386ABI.S b/vm/arch/x86-atom/Call386ABI.S
deleted file mode 100644
index f996168..0000000
--- a/vm/arch/x86-atom/Call386ABI.S
+++ /dev/null
@@ -1,189 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: CallABI.S
-    *
-    * Code: facilitates call to native code C and C++ routines.
-    *
-    */
-
-   /*
-    * Function prototype:
-    *
-    * void dvmPlatformInvoke(void* pEnv, ClassObject* clazz, int argInfo, int argc,
-    * const u4* argv, const char* signature, void* func, JValue* pReturn)
-    *
-    * The method we are calling has the form:
-    *
-    * return_type func(JNIEnv* pEnv, ClassObject* clazz, ...)
-    * -or-
-    * return_type func(JNIEnv* pEnv, Object* this, ...)
-    *
-    * We receive a collection of 32-bit values which correspond to arguments from
-    * the interpreter (e.g. float occupies one, double occupies two).  It's up to
-    * us to convert these into local calling conventions.
-    */
-
-   /*
-    * On entry:
-    *   4(%sp)    JNIEnv (can be left alone)
-    *   8(%esp)   clazz (NULL for virtual method calls, non-NULL for static)
-    *   12(%esp)  arg info
-    *   16(%esp)  argc (number of 32-bit values in argv)
-    *   20(%esp)  argv
-    *   24(%esp)  short signature
-    *   28(%esp)  func
-    *   32(%esp)  pReturn
-    *
-    * For a virtual method call, the "this" reference is in argv[0].
-    *
-    * argInfo (32-bit int) layout:
-    *
-    *   SRRRHHHH HHHHHHHH HHHHHHHH HHHHHHHH
-    *
-    *   S - if set, argInfo hints are invalid
-    *   R - return type enumeration (see jniInternal.h)
-    *       VOID   -> 0
-    *       FLOAT  -> 1
-    *       DOUBLE -> 2
-    *       S8     -> 3
-    *       S4     -> 4
-    *    H - target-specific hints (see below for details)
-    *
-    * IA32 ABI JNI hint format
-    *
-    *       ZZZZ ZZZZZZZZ AAAAAAAA AAAAAAAA
-    *
-    *   Z - reserved
-    *   A - size of the variable argument block in 32-bit words
-    */
-
-    .text
-    .align  4
-    .global dvmPlatformInvoke
-    .type   dvmPlatformInvoke, %function
-
-
-dvmPlatformInvoke:
-CallABI_ENTER:
-
-   /*
-    * Save registers.
-    */
-
-    movl        %ebp, -4(%esp)
-    movl        %ebx, -8(%esp)          # save %ebx
-    movl        %esi, -12(%esp)         # save %esi
-    movl        %edi, -16(%esp)         # save %edi
-    lea         (%esp), %ebp
-
-   /*
-    * Check if argInfo is valid. Is always valid so should remove this check?
-    */
-
-    movzwl      12(%ebp), %ecx          # %ecx<- argsize in words
-    movl        12(%ebp), %ebx          # %ebx<- argInfo
-
-    shl         $2, %ecx                # %ecx<- argsize in bytes
-    subl        %ecx, %esp              # %esp<- expanded for arg region
-
-   /*
-    * Prepare for 16 byte alignment
-    */
-
-    and         $0xfffffff0, %esp
-    subl        $24, %esp
-
-
-    movl        8(%ebp), %eax           # %eax<- clazz
-    cmpl        $0, %eax                # Check virtual or static
-    movl        4(%ebp), %ecx           # %ecx<- JNIEnv
-    movl        20(%ebp), %esi          # %esi<- argV
-    jne         1f                      # Branch if static
-    movl        (%esi), %eax            # get the this pointer
-    addl        $4, %esi                # %esi<- update past this
-
-1:
-    movl        %ecx, -8(%esp)          # push JNIEnv as arg #1
-    movl        %eax, -4(%esp)          # push clazz or this as arg #2
-    lea         -8(%esp), %esp
-
-   /*
-    * Copy arguments
-    */
-
-    movzwl      %bx, %ecx               # %ecx<- %bx; argsize in words
-    lea         8(%esp), %edi           # %edi<- stack location for arguments
-    cld
-    rep         movsl                   # move %ecx arguments to 8(%esp)
-    call        *28(%ebp)
-    sarl        $28, %ebx               # %ebx<- SRRR (low 4 bits)
-    je          CallABI_EXIT            # exit call
-    cmpl        $2, %ebx
-    movl        32(%ebp), %ecx          # %ecx<- return pointer
-    je          2f                      # handle double return
-    jl          1f                      # handle float return
-
-   /*
-    *  If a native function returns a result smaller than 8-bytes
-    *  then higher bytes may contain garbage.
-    *  This code does type-checking based on size of return result.
-    *  We zero higher bytes instead of allowing the garbage to go through.
-    */
-
-    cmpl        $3,%ebx
-    je          S8
-    cmpl        $4,%ebx
-    je          S4
-    cmpl        $7,%ebx
-    je          S1
-    cmpl        $6,%ebx
-    jne         S2
-U2:
-    movzwl      %ax, %eax
-    movl        %eax, (%ecx)            # save 32-bit return
-    jmp         CallABI_EXIT            # exit call
-
-S1:
-    movsbl      %al, %eax
-    movl        %eax, (%ecx)            # save 32-bit return
-    jmp         CallABI_EXIT            # exit call
-S2:
-    movswl      %ax, %eax
-    movl        %eax, (%ecx)            # save 32-bit return
-    jmp         CallABI_EXIT            # exit call
-S4:
-    cltd
-    movl        %eax, (%ecx)            # save 32-bit return
-    jmp         CallABI_EXIT            # exit call
-S8:
-    movl        %edx, 4(%ecx)           # save 64-bit return
-    movl        %eax, (%ecx)            # save 32-bit return
-    jmp         CallABI_EXIT            # exit call
-
-2:
-    fstpl       (%ecx)                  # save double return
-    jmp         CallABI_EXIT            # exit call
-1:
-    fstps       (%ecx)                  # save float return
-
-CallABI_EXIT:
-    lea         (%ebp), %esp
-    movl        -16(%ebp), %edi         # restore %edi
-    movl        -12(%ebp), %esi         # restore %esi
-    movl        -8(%ebp), %ebx          # restore %ebx
-    movl        -4(%ebp), %ebp          # restore caller base pointer
-    ret                                 # return
diff --git a/vm/arch/x86-atom/Hints386ABI.cpp b/vm/arch/x86-atom/Hints386ABI.cpp
deleted file mode 100644
index dd2fc69..0000000
--- a/vm/arch/x86-atom/Hints386ABI.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * The class loader will associate with each method a 32-bit info word
-    * (jniArgInfo) to support JNI calls.  The high order 4 bits of this word
-    * are the same for all targets, while the lower 28 are used for hints to
-    * allow accelerated JNI bridge transfers.
-    *
-    * jniArgInfo (32-bit int) layout:
-    *
-    *    SRRRHHHH HHHHHHHH HHHHHHHH HHHHHHHH
-    *
-    *    S - if set, ignore the hints and do things the hard way (scan signature)
-    *    R - return-type enumeration
-    *    H - target-specific hints (see below for details)
-    *
-    * This function produces IA32-specific hints for the standard 32-bit 386 ABI.
-    * All arguments have 32-bit alignment.  Padding is not an issue.
-    *
-    * IA32 ABI JNI hint format
-    *
-    *       ZZZZ ZZZZZZZZ AAAAAAAA AAAAAAAA
-    *
-    *   Z - reserved, must be 0
-    *   A - size of variable argument block in 32-bit words (note - does not
-    *       include JNIEnv or clazz)
-    *
-    * For the 386 ABI, valid hints should always be generated.
-    */
-
-
-#include "Dalvik.h"
-#include "libdex/DexClass.h"
-#include <stdlib.h>
-#include <stddef.h>
-#include <sys/stat.h>
-
-u4 dvmPlatformInvokeHints(const DexProto* proto)  {
-
-const char* sig = dexProtoGetShorty(proto);
-unsigned int wordCount = 0;
-char sigByte;
-
- while (1) {
-
-   /*
-    * Move past return type; dereference sigByte
-    */
-
-    sigByte = *(++sig);
-    if (sigByte == '\0') { break; }
-    ++wordCount;
-
-    if (sigByte == 'D' || sigByte == 'J') {
-      ++wordCount;
-    }
- }
-
-/*
- * Check for Dex file limitation and return
- */
-
- if (wordCount > 0xFFFF) { return DALVIK_JNI_NO_ARG_INFO; }
- return wordCount;
-
-}
diff --git a/vm/arch/x86/Call386ABI.S b/vm/arch/x86/Call386ABI.S
index 39a0e93..766aff7 100644
--- a/vm/arch/x86/Call386ABI.S
+++ b/vm/arch/x86/Call386ABI.S
@@ -55,6 +55,7 @@
 */
 
     .text
+    .align  4
     .global dvmPlatformInvoke
     .type   dvmPlatformInvoke, @function
 
diff --git a/vm/compiler/Compiler.cpp b/vm/compiler/Compiler.cpp
index e539908..cdd62cc 100644
--- a/vm/compiler/Compiler.cpp
+++ b/vm/compiler/Compiler.cpp
@@ -21,6 +21,10 @@
 #include "Dalvik.h"
 #include "interp/Jit.h"
 #include "CompilerInternals.h"
+#ifdef ARCH_IA32
+#include "codegen/x86/Translator.h"
+#include "codegen/x86/Lower.h"
+#endif
 
 extern "C" void dvmCompilerTemplateStart(void);
 extern "C" void dmvCompilerTemplateEnd(void);
@@ -187,6 +191,7 @@
     /* This can be found through "dalvik-jit-code-cache" in /proc/<pid>/maps */
     // ALOGD("Code cache starts at %p", gDvmJit.codeCache);
 
+#ifndef ARCH_IA32
     /* Copy the template code into the beginning of the code cache */
     int templateSize = (intptr_t) dmvCompilerTemplateEnd -
                        (intptr_t) dvmCompilerTemplateStart;
@@ -216,6 +221,16 @@
         ALOGE("Failed to remove the write permission for the code cache");
         dvmAbort();
     }
+#else
+    gDvmJit.codeCacheByteUsed = 0;
+    stream = (char*)gDvmJit.codeCache + gDvmJit.codeCacheByteUsed;
+    ALOGV("codeCache = %p stream = %p before initJIT", gDvmJit.codeCache, stream);
+    streamStart = stream;
+    initJIT(NULL, NULL);
+    gDvmJit.templateSize = (stream - streamStart);
+    gDvmJit.codeCacheByteUsed = (stream - streamStart);
+    ALOGV("stream = %p after initJIT", stream);
+#endif
 
     return true;
 }
diff --git a/vm/compiler/Compiler.h b/vm/compiler/Compiler.h
index f844e3c..7af2809 100644
--- a/vm/compiler/Compiler.h
+++ b/vm/compiler/Compiler.h
@@ -27,6 +27,7 @@
 
 #define COMPILER_WORK_QUEUE_SIZE        100
 #define COMPILER_IC_PATCH_QUEUE_SIZE    64
+#define COMPILER_PC_OFFSET_SIZE         100
 
 /* Architectural-independent parameters for predicted chains */
 #define PREDICTED_CHAIN_CLAZZ_INIT       0
@@ -110,6 +111,8 @@
     u4 branch;                  /* Branch to chained destination */
 #ifdef __mips__
     u4 delay_slot;              /* nop goes here */
+#elif defined(ARCH_IA32)
+    u4 branch2;                 /* IA32 branch instr may be > 32 bits */
 #endif
     const ClassObject *clazz;   /* key for prediction */
     const Method *method;       /* to lookup native PC from dalvik PC */
@@ -245,5 +248,6 @@
 JitInstructionSetType dvmCompilerGetInterpretTemplateSet();
 u8 dvmGetRegResourceMask(int reg);
 void dvmDumpCFG(struct CompilationUnit *cUnit, const char *dirPrefix);
+bool dvmIsOpcodeSupportedByJit(Opcode opcode);
 
 #endif  // DALVIK_VM_COMPILER_H_
diff --git a/vm/compiler/CompilerIR.h b/vm/compiler/CompilerIR.h
index 23dea33..73efad8 100644
--- a/vm/compiler/CompilerIR.h
+++ b/vm/compiler/CompilerIR.h
@@ -18,6 +18,9 @@
 #define DALVIK_VM_COMPILER_IR_H_
 
 #include "codegen/Optimizer.h"
+#ifdef ARCH_IA32
+#include "CompilerUtility.h"
+#endif
 
 typedef enum RegisterClass {
     kCoreReg,
@@ -199,6 +202,9 @@
     int numBlocks;
     GrowableList blockList;
     const Method *method;
+#ifdef ARCH_IA32
+    int exceptionBlockId;               // the block corresponding to exception handling
+#endif
     const JitTraceDescription *traceDesc;
     LIR *firstLIRInsn;
     LIR *lastLIRInsn;
diff --git a/vm/compiler/CompilerUtility.h b/vm/compiler/CompilerUtility.h
index ccf22a7..faca03d 100644
--- a/vm/compiler/CompilerUtility.h
+++ b/vm/compiler/CompilerUtility.h
@@ -73,7 +73,7 @@
 void dvmDumpBlockBitVector(const GrowableList *blocks, char *msg,
                            const BitVector *bv, int length);
 void dvmGetBlockName(struct BasicBlock *bb, char *name);
-int dvmCompilerCacheFlush(long start, long end, long flags);
+void dvmCompilerCacheFlush(long start, long end, long flags);
 void dvmCompilerCacheClear(char *start, size_t size);
 
 
diff --git a/vm/compiler/Frontend.cpp b/vm/compiler/Frontend.cpp
index e0226e9..47c1898 100644
--- a/vm/compiler/Frontend.cpp
+++ b/vm/compiler/Frontend.cpp
@@ -1314,10 +1314,12 @@
     /* Perform SSA transformation for the whole method */
     dvmCompilerMethodSSATransformation(&cUnit);
 
+#ifndef ARCH_IA32
     dvmCompilerInitializeRegAlloc(&cUnit);  // Needs to happen after SSA naming
 
     /* Allocate Registers using simple local allocation scheme */
     dvmCompilerLocalRegAlloc(&cUnit);
+#endif
 
     /* Convert MIR to LIR, etc. */
     dvmCompilerMethodMIR2LIR(&cUnit);
@@ -1536,6 +1538,10 @@
      */
     dvmCompilerInsertBackwardChaining(cUnit);
 
+#if defined(ARCH_IA32)
+    /* Convert MIR to LIR, etc. */
+    dvmCompilerMIR2LIR(cUnit, info);
+#else
     dvmCompilerInitializeRegAlloc(cUnit);
 
     /* Allocate Registers using simple local allocation scheme */
@@ -1543,6 +1549,7 @@
 
     /* Convert MIR to LIR, etc. */
     dvmCompilerMIR2LIR(cUnit);
+#endif
 
     /* Loop contains never executed blocks / heavy instructions */
     if (cUnit->quitLoopMode) {
@@ -1604,6 +1611,23 @@
                            optHints | JIT_OPT_NO_LOOP);
 }
 
+static bool searchClassTablePrefix(const Method* method) {
+    if (gDvmJit.classTable == NULL) {
+        return false;
+    }
+    HashIter iter;
+    HashTable* pTab = gDvmJit.classTable;
+    for (dvmHashIterBegin(pTab, &iter); !dvmHashIterDone(&iter);
+        dvmHashIterNext(&iter))
+    {
+        const char* str = (const char*) dvmHashIterData(&iter);
+        if (strncmp(method->clazz->descriptor, str, strlen(str)) == 0) {
+            return true;
+        }
+    }
+    return false;
+}
+
 /*
  * Main entry point to start trace compilation. Basic blocks are constructed
  * first and they will be passed to the codegen routines to convert Dalvik
@@ -1674,6 +1698,12 @@
     dvmInitGrowableList(blockList, 8);
 
     /* Identify traces that we don't want to compile */
+    if (gDvmJit.classTable) {
+        bool classFound = searchClassTablePrefix(desc->method);
+        if (gDvmJit.classTable && gDvmJit.includeSelectedMethod != classFound) {
+            return false;
+        }
+    }
     if (gDvmJit.methodTable) {
         int len = strlen(desc->method->clazz->descriptor) +
                   strlen(desc->method->name) + 1;
@@ -1734,8 +1764,12 @@
          * 2) If includeSelectedMethod == true, the method does not match the
          *    full and partial signature stored in the hash table.
          */
-        if (gDvmJit.includeSelectedMethod != methodFound) {
+        if (gDvmJit.methodTable && gDvmJit.includeSelectedMethod != methodFound) {
+#ifdef ARCH_IA32
+            return false;
+#else
             cUnit.allSingleStep = true;
+#endif
         } else {
             /* Compile the trace as normal */
 
@@ -1746,6 +1780,22 @@
         }
     }
 
+    // Each pair is a range, check whether curOffset falls into a range.
+    bool includeOffset = (gDvmJit.num_entries_pcTable < 2);
+    for (int pcOff = 0; pcOff < gDvmJit.num_entries_pcTable; ) {
+        if (pcOff+1 >= gDvmJit.num_entries_pcTable) {
+          break;
+        }
+        if (curOffset >= gDvmJit.pcTable[pcOff] && curOffset <= gDvmJit.pcTable[pcOff+1]) {
+            includeOffset = true;
+            break;
+        }
+        pcOff += 2;
+    }
+    if (!includeOffset) {
+        return false;
+    }
+
     /* Allocate the entry block */
     curBB = dvmCompilerNewBB(kEntryBlock, numBlocks++);
     dvmInsertGrowableList(blockList, (intptr_t) curBB);
@@ -2056,17 +2106,24 @@
 
     dvmCompilerNonLoopAnalysis(&cUnit);
 
+#ifndef ARCH_IA32
     dvmCompilerInitializeRegAlloc(&cUnit);  // Needs to happen after SSA naming
+#endif
 
     if (cUnit.printMe) {
         dvmCompilerDumpCompilationUnit(&cUnit);
     }
 
+#ifndef ARCH_IA32
     /* Allocate Registers using simple local allocation scheme */
     dvmCompilerLocalRegAlloc(&cUnit);
 
     /* Convert MIR to LIR, etc. */
     dvmCompilerMIR2LIR(&cUnit);
+#else /* ARCH_IA32 */
+    /* Convert MIR to LIR, etc. */
+    dvmCompilerMIR2LIR(&cUnit, info);
+#endif
 
     /* Convert LIR into machine code. Loop for recoverable retries */
     do {
diff --git a/vm/compiler/Loop.cpp b/vm/compiler/Loop.cpp
index 7090360..f826686 100644
--- a/vm/compiler/Loop.cpp
+++ b/vm/compiler/Loop.cpp
@@ -728,12 +728,15 @@
      * code will be generated along the backward branch to honor the suspend
      * requests.
      */
+#ifndef ARCH_IA32
 #if !defined(WITH_SELF_VERIFICATION)
     if (gDvmJit.profileMode != kTraceProfilingContinuous &&
         gDvmJit.profileMode != kTraceProfilingPeriodicOn) {
         return;
     }
 #endif
+#endif
+
     /*
      * In self-verification or profiling mode, the backward branch is altered
      * to go to the backward chaining cell. Without using the backward chaining
diff --git a/vm/compiler/codegen/CompilerCodegen.h b/vm/compiler/codegen/CompilerCodegen.h
index 6495d07..f2b36a3 100644
--- a/vm/compiler/codegen/CompilerCodegen.h
+++ b/vm/compiler/codegen/CompilerCodegen.h
@@ -26,7 +26,11 @@
 bool dvmCompilerDoWork(CompilerWorkOrder *work);
 
 /* Lower middle-level IR to low-level IR */
+#ifndef ARCH_IA32
 void dvmCompilerMIR2LIR(CompilationUnit *cUnit);
+#else /* ARCH_IA32 */
+void dvmCompilerMIR2LIR(CompilationUnit *cUnit, JitTranslationInfo* info);
+#endif
 
 /* Lower middle-level IR to low-level IR for the whole method */
 void dvmCompilerMethodMIR2LIR(CompilationUnit *cUnit);
diff --git a/vm/compiler/codegen/arm/ArchUtility.cpp b/vm/compiler/codegen/arm/ArchUtility.cpp
index 9b6aaaa..2f59193 100644
--- a/vm/compiler/codegen/arm/ArchUtility.cpp
+++ b/vm/compiler/codegen/arm/ArchUtility.cpp
@@ -421,9 +421,9 @@
 }
 
 /* Target-specific cache flushing */
-int dvmCompilerCacheFlush(long start, long end, long flags)
+void dvmCompilerCacheFlush(long start, long end, long flags)
 {
-    return cacheflush(start, end, flags);
+    cacheflush(start, end, flags);
 }
 
 /* Target-specific cache clearing */
diff --git a/vm/compiler/codegen/arm/Assemble.cpp b/vm/compiler/codegen/arm/Assemble.cpp
index 9842eaf..d1ecd97 100644
--- a/vm/compiler/codegen/arm/Assemble.cpp
+++ b/vm/compiler/codegen/arm/Assemble.cpp
@@ -1955,14 +1955,13 @@
 {
     u4* lowAddress = NULL;
     u4* highAddress = NULL;
-    unsigned int i;
     if (gDvmJit.pJitEntryTable != NULL) {
         COMPILER_TRACE_CHAINING(LOGD("Jit Runtime: unchaining all"));
         dvmLockMutex(&gDvmJit.tableLock);
 
         UNPROTECT_CODE_CACHE(gDvmJit.codeCache, gDvmJit.codeCacheByteUsed);
 
-        for (i = 0; i < gDvmJit.jitTableSize; i++) {
+        for (size_t i = 0; i < gDvmJit.jitTableSize; i++) {
             if (gDvmJit.pJitEntryTable[i].dPC &&
                 !gDvmJit.pJitEntryTable[i].u.info.isMethodEntry &&
                 gDvmJit.pJitEntryTable[i].codeAddress &&
diff --git a/vm/compiler/codegen/mips/ArchUtility.cpp b/vm/compiler/codegen/mips/ArchUtility.cpp
index df7d008..869632e 100644
--- a/vm/compiler/codegen/mips/ArchUtility.cpp
+++ b/vm/compiler/codegen/mips/ArchUtility.cpp
@@ -343,9 +343,9 @@
 }
 
 /* Target-specific cache flushing */
-int dvmCompilerCacheFlush(long start, long end, long flags)
+void dvmCompilerCacheFlush(long start, long end, long flags)
 {
-    return cacheflush(start, end, flags);
+    cacheflush(start, end, flags);
 }
 
 /* Target-specific cache clearing */
diff --git a/vm/compiler/codegen/mips/Assemble.cpp b/vm/compiler/codegen/mips/Assemble.cpp
index a97857d..692fccf 100644
--- a/vm/compiler/codegen/mips/Assemble.cpp
+++ b/vm/compiler/codegen/mips/Assemble.cpp
@@ -1347,8 +1347,9 @@
             }
         }
 
-        if (lowAddress && highAddress)
-                dvmCompilerCacheFlush((long)lowAddress, (long)highAddress, 0);
+        if (lowAddress && highAddress) {
+            dvmCompilerCacheFlush((long)lowAddress, (long)highAddress, 0);
+        }
 
         UPDATE_CODE_CACHE_PATCHES();
 
diff --git a/vm/compiler/codegen/x86/AnalysisO1.cpp b/vm/compiler/codegen/x86/AnalysisO1.cpp
new file mode 100644
index 0000000..d7e9726
--- /dev/null
+++ b/vm/compiler/codegen/x86/AnalysisO1.cpp
@@ -0,0 +1,5315 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file AnalysisO1.cpp
+  \brief This file implements register allocator, constant folding
+*/
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "interp/InterpState.h"
+#include "interp/InterpDefs.h"
+#include "libdex/Leb128.h"
+
+/* compilation flags to turn on debug printout */
+//#define DEBUG_COMPILE_TABLE
+//#define DEBUG_ALLOC_CONSTRAINT
+//#define DEBUG_REGALLOC
+//#define DEBUG_REG_USED
+//#define DEBUG_REFCOUNT
+//#define DEBUG_REACHING_DEF2
+//#define DEBUG_REACHING_DEF
+//#define DEBUG_LIVE_RANGE
+//#define DEBUG_MOVE_OPT
+//#define DEBUG_SPILL
+//#define DEBUG_ENDOFBB
+//#define DEBUG_CONST
+/*
+  #define DEBUG_XFER_POINTS
+  #define DEBUG_DSE
+  #define DEBUG_CFG
+  #define DEBUG_GLOBALTYPE
+  #define DEBUG_STATE
+  #define DEBUG_COMPILE_TABLE
+  #define DEBUG_VIRTUAL_INFO
+  #define DEBUG_MOVE_OPT
+  #define DEBUG_MERGE_ENTRY
+  #define DEBUG_INVALIDATE
+*/
+#include "AnalysisO1.h"
+
+void dumpCompileTable();
+
+/* There are 3 kinds of variables that are handled in this file:
+   1> virtual register (isVirtualReg())
+   2> temporary (!isVirtualReg() && regNum < PhysicalReg_GLUE_DVMDEX)
+   3> glue variables: regNum >= PhysicalReg_GLUE_DVMDEX
+*/
+/** check whether a variable is a virtual register
+ */
+bool isVirtualReg(int type) {
+    if((type & LowOpndRegType_virtual) != 0) return true;
+    return false;
+}
+bool isTemporary(int type, int regNum) {
+    if(!isVirtualReg(type) && regNum < PhysicalReg_GLUE_DVMDEX) return true;
+    return false;
+}
+
+/** convert type defined in lowering module to type defined in register allocator
+    in lowering module <type, isPhysical>
+    in register allocator: LowOpndRegType_hard LowOpndRegType_virtual LowOpndRegType_scratch
+*/
+int convertType(int type, int reg, bool isPhysical) {
+    int newType = type;
+    if(isPhysical) newType |= LowOpndRegType_hard;
+    if(isVirtualReg(type)) newType |= LowOpndRegType_virtual;
+    else {
+        /* reg number for a VR can exceed PhysicalReg_SCRATCH_1 */
+        if(reg >= PhysicalReg_SCRATCH_1 && reg < PhysicalReg_GLUE_DVMDEX)
+            newType |= LowOpndRegType_scratch;
+    }
+    return newType;
+}
+
+/** return the size of a variable
+ */
+OpndSize getRegSize(int type) {
+    if((type & MASK_FOR_TYPE) == LowOpndRegType_xmm) return OpndSize_64;
+    if((type & MASK_FOR_TYPE) == LowOpndRegType_fs) return OpndSize_64;
+    /* for type _gp, _fs_s, _ss */
+    return OpndSize_32;
+}
+
+/*
+   Overlapping cases between two variables A and B
+   layout for A,B   isAPartiallyOverlapB  isBPartiallyOverlapA
+   1> |__|  |____|         OVERLAP_ALIGN        OVERLAP_B_COVER_A
+      |__|  |____|
+   2> |____|           OVERLAP_B_IS_LOW_OF_A    OVERLAP_B_COVER_LOW_OF_A
+        |__|
+   3> |____|           OVERLAP_B_IS_HIGH_OF_A   OVERLAP_B_COVER_HIGH_OF_A
+      |__|
+   4> |____|      OVERLAP_LOW_OF_A_IS_HIGH_OF_B OVERLAP_B_COVER_LOW_OF_A
+         |____|
+   5>    |____|   OVERLAP_HIGH_OF_A_IS_LOW_OF_B OVERLAP_B_COVER_HIGH_OF_A
+      |____|
+   6>   |__|           OVERLAP_A_IS_LOW_OF_B    OVERLAP_B_COVER_A
+      |____|
+   7> |__|             OVERLAP_A_IS_HIGH_OF_B   OVERLAP_B_COVER_A
+      |____|
+*/
+/** determine the overlapping between variable B and A
+*/
+OverlapCase getBPartiallyOverlapA(int regB, LowOpndRegType tB, int regA, LowOpndRegType tA) {
+    if(getRegSize(tA) == getRegSize(tB) && regA == regB) return OVERLAP_B_COVER_A;
+    if(getRegSize(tA) == OpndSize_64 && getRegSize(tB) == OpndSize_32 && regA == regB) return OVERLAP_B_COVER_LOW_OF_A;
+    if(getRegSize(tA) == OpndSize_64 && getRegSize(tB) == OpndSize_32 && regB == regA + 1) return OVERLAP_B_COVER_HIGH_OF_A;
+    if(getRegSize(tA) == OpndSize_32 && getRegSize(tB) == OpndSize_64 && (regA == regB || regA == regB+1)) return OVERLAP_B_COVER_A;
+    if(getRegSize(tB) == OpndSize_64 && getRegSize(tA) == OpndSize_64 && regA == regB+1) return OVERLAP_B_COVER_LOW_OF_A;
+    if(getRegSize(tB) == OpndSize_64 && getRegSize(tA) == OpndSize_64 && regB == regA+1) return OVERLAP_B_COVER_HIGH_OF_A;
+    return OVERLAP_NO;
+}
+
+/** determine overlapping between variable A and B
+*/
+OverlapCase getAPartiallyOverlapB(int regA, LowOpndRegType tA, int regB, LowOpndRegType tB) {
+    if(getRegSize(tA) == getRegSize(tB) && regA == regB) return OVERLAP_ALIGN;
+    if(getRegSize(tA) == OpndSize_64 && getRegSize(tB) == OpndSize_32 && regA == regB)
+        return OVERLAP_B_IS_LOW_OF_A;
+    if(getRegSize(tA) == OpndSize_64 && getRegSize(tB) == OpndSize_32 && regB == regA+1)
+        return OVERLAP_B_IS_HIGH_OF_A;
+    if(getRegSize(tB) == OpndSize_64 && getRegSize(tA) == OpndSize_64 && regA == regB+1)
+        return OVERLAP_LOW_OF_A_IS_HIGH_OF_B;
+    if(getRegSize(tB) == OpndSize_64 && getRegSize(tA) == OpndSize_64 && regB == regA+1)
+        return OVERLAP_HIGH_OF_A_IS_LOW_OF_B;
+    if(getRegSize(tA) == OpndSize_32 && getRegSize(tB) == OpndSize_64 && regA == regB)
+        return OVERLAP_A_IS_LOW_OF_B;
+    if(getRegSize(tA) == OpndSize_32 && getRegSize(tB) == OpndSize_64 && regA == regB+1)
+        return OVERLAP_A_IS_HIGH_OF_B;
+    return OVERLAP_NO;
+}
+
+/** determine whether variable A fully covers B
+ */
+bool isAFullyCoverB(int regA, LowOpndRegType tA, int regB, LowOpndRegType tB) {
+    if(getRegSize(tB) == OpndSize_32) return true;
+    if(getRegSize(tA) == getRegSize(tB) && regA == regB) return true;
+    return false;
+}
+
+/*
+   RegAccessType accessType
+   1> DefOrUse.accessType
+      can only be D(VR), L(low part of VR), H(high part of VR), N(none)
+      for def, it means which part of the VR is live
+      for use, it means which part of the VR comes from the def
+   2> VirtualRegInfo.accessType
+      for currentInfo, it can only be a combination of U & D
+      for entries in infoBasicBlock, it can be a combination of U & D|L|H
+*/
+
+/*
+   Key data structures used:
+   1> BasicBlock_O1
+      VirtualRegInfo infoBasicBlock[]
+      DefUsePair* defUseTable
+      XferPoint xferPoints[]
+   2> MemoryVRInfo memVRTable[]
+      LiveRange* ranges
+   3> compileTableEntry compileTable[]
+   4> VirtualRegInfo
+      DefOrUse reachingDefs[3]
+   5> DefUsePair, LiveRange
+*/
+
+//! one entry for each variable used
+
+//! a variable can be virtual register, or a temporary (can be hard-coded)
+compileTableEntry compileTable[COMPILE_TABLE_SIZE];
+int num_compile_entries;
+//! tables to save the states of register allocation
+regAllocStateEntry1 stateTable1_1[COMPILE_TABLE_SIZE];
+regAllocStateEntry1 stateTable1_2[COMPILE_TABLE_SIZE];
+regAllocStateEntry1 stateTable1_3[COMPILE_TABLE_SIZE];
+regAllocStateEntry1 stateTable1_4[COMPILE_TABLE_SIZE];
+regAllocStateEntry2 stateTable2_1[COMPILE_TABLE_SIZE];
+regAllocStateEntry2 stateTable2_2[COMPILE_TABLE_SIZE];
+regAllocStateEntry2 stateTable2_3[COMPILE_TABLE_SIZE];
+regAllocStateEntry2 stateTable2_4[COMPILE_TABLE_SIZE];
+
+//! array of VirtualRegInfo to store VRs accessed by a single bytecode
+VirtualRegInfo infoByteCode[MAX_REG_PER_BYTECODE];
+int num_regs_per_bytecode;
+//! array of TempRegInfo to store temporaries accessed by a single bytecode
+TempRegInfo infoByteCodeTemp[MAX_TEMP_REG_PER_BYTECODE];
+int num_temp_regs_per_bytecode;
+//! array of MemoryVRInfo to store whether a VR is in memory
+#define NUM_MEM_VR_ENTRY 140
+MemoryVRInfo memVRTable[NUM_MEM_VR_ENTRY];
+int num_memory_vr;
+
+CompilationUnit* currentUnit = NULL;
+
+//! the current basic block
+BasicBlock_O1* currentBB = NULL;
+//! array of RegisterInfo for all the physical registers
+RegisterInfo allRegs[PhysicalReg_GLUE+1]; //initialized in codeGen
+
+VirtualRegInfo currentInfo;
+VirtualRegInfo tmpInfo;
+
+//! this array says whether a spill location is used (0 means not used, 1 means used)
+int spillIndexUsed[MAX_SPILL_JIT_IA];
+int indexForGlue = -1;
+
+int num_bbs_for_method;
+//! array of basic blocks in a method in program order
+BasicBlock_O1* method_bbs_sorted[MAX_NUM_BBS_PER_METHOD];
+//! the entry basic block
+BasicBlock_O1* bb_entry;
+int pc_start = -1;
+int pc_end = -1;
+
+//!array of PCs for exception handlers
+int exceptionHandlers[10];
+int num_exception_handlers;
+
+bool canSpillReg[PhysicalReg_Null]; //physical registers that should not be spilled
+int inGetVR_num = -1;
+int inGetVR_type;
+
+///////////////////////////////////////////////////////////////////////////////
+// FORWARD FUNCTION DECLARATION
+void addExceptionHandler(s4 tmp);
+
+int createCFG(Method* method);
+int collectInfoOfBasicBlock(Method* method, BasicBlock_O1* bb);
+void dumpVirtualInfoOfBasicBlock(BasicBlock_O1* bb);
+void setTypeOfVR();
+void insertGlueReg();
+void dumpVirtualInfoOfMethod();
+int codeGenBasicBlock(const Method* method, BasicBlock_O1* bb);
+
+//used in collectInfoOfBasicBlock: getVirtualRegInfo
+int mergeEntry2(BasicBlock_O1* bb);
+int sortAllocConstraint(RegAllocConstraint* allocConstraints,
+                        RegAllocConstraint* allocConstraintsSorted, bool fromHighToLow);
+
+//used in codeGenBasicBlock
+void insertFromVirtualInfo(BasicBlock_O1* bb, int k); //update compileTable
+void insertFromTempInfo(int k); //update compileTable
+int updateXferPoints();
+void updateLiveTable();
+void printDefUseTable();
+bool isFirstOfHandler(BasicBlock_O1* bb);
+
+//used in mergeEntry2
+//following functions will not update global data structure
+RegAccessType mergeAccess2(RegAccessType A, RegAccessType B, OverlapCase isBPartiallyOverlapA);
+RegAccessType updateAccess1(RegAccessType A, OverlapCase isAPartiallyOverlapB); //will not update global data structure
+RegAccessType updateAccess2(RegAccessType C1, RegAccessType C2);
+RegAccessType updateAccess3(RegAccessType C, RegAccessType B);
+
+void updateDefUseTable();
+void updateReachingDefA(int indexToA, OverlapCase isBPartiallyOverlapA);
+void updateReachingDefB1(int indexToA);
+void updateReachingDefB2();
+void updateReachingDefB3();
+
+RegAccessType insertAUse(DefUsePair* ptr, int offsetPC, int regNum, LowOpndRegType physicalType);
+DefUsePair* insertADef(int offsetPC, int regNum, LowOpndRegType pType, RegAccessType rType);
+RegAccessType insertDefUsePair(int reachingDefIndex);
+
+//used in updateXferPoints
+int fakeUsageAtEndOfBB(BasicBlock_O1* bb);
+void insertLoadXfer(int offset, int regNum, LowOpndRegType pType);
+int searchMemTable(int regNum);
+void mergeLiveRange(int tableIndex, int rangeStart, int rangeEnd);
+//used in updateLiveTable
+RegAccessType setAccessTypeOfUse(OverlapCase isDefPartiallyOverlapUse, RegAccessType reachingDefLive);
+DefUsePair* searchDefUseTable(int offsetPC, int regNum, LowOpndRegType pType);
+void insertAccess(int tableIndex, LiveRange* startP, int rangeStart);
+
+//register allocation
+int spillLogicalReg(int spill_index, bool updateTable);
+
+/** check whether the current bytecode is IF or GOTO or SWITCH
+ */
+bool isCurrentByteCodeJump() {
+    u2 inst_op = INST_INST(inst);
+    if(inst_op == OP_IF_EQ || inst_op == OP_IF_NE || inst_op == OP_IF_LT ||
+       inst_op == OP_IF_GE || inst_op == OP_IF_GT || inst_op == OP_IF_LE) return true;
+    if(inst_op == OP_IF_EQZ || inst_op == OP_IF_NEZ || inst_op == OP_IF_LTZ ||
+       inst_op == OP_IF_GEZ || inst_op == OP_IF_GTZ || inst_op == OP_IF_LEZ) return true;
+    if(inst_op == OP_GOTO || inst_op == OP_GOTO_16 || inst_op == OP_GOTO_32) return true;
+    if(inst_op == OP_PACKED_SWITCH || inst_op == OP_SPARSE_SWITCH) return true;
+    return false;
+}
+
+/* this function is called before code generation of basic blocks
+   initialize data structure allRegs, which stores information for each physical register,
+   whether it is used, when it was last freed, whether it is callee-saved */
+void initializeAllRegs() {
+    int k;
+    for(k = PhysicalReg_EAX; k <= PhysicalReg_EBP; k++) {
+        allRegs[k].physicalReg = (PhysicalReg) k;
+        if(k == PhysicalReg_EDI || k == PhysicalReg_ESP || k == PhysicalReg_EBP)
+            allRegs[k].isUsed = true;
+        else {
+            allRegs[k].isUsed = false;
+            allRegs[k].freeTimeStamp = -1;
+        }
+        if(k == PhysicalReg_EBX || k == PhysicalReg_EBP || k == PhysicalReg_ESI || k == PhysicalReg_EDI)
+            allRegs[k].isCalleeSaved = true;
+        else
+            allRegs[k].isCalleeSaved = false;
+    }
+    for(k = PhysicalReg_XMM0; k <= PhysicalReg_XMM7; k++) {
+        allRegs[k].physicalReg = (PhysicalReg) k;
+        allRegs[k].isUsed = false;
+        allRegs[k].freeTimeStamp = -1;
+        allRegs[k].isCalleeSaved = false;
+    }
+}
+
+/** sync up allRegs (isUsed & freeTimeStamp) with compileTable
+    global data: RegisterInfo allRegs[PhysicalReg_Null]
+    update allRegs[EAX to XMM7] except EDI,ESP,EBP
+    update RegisterInfo.isUsed & RegisterInfo.freeTimeStamp
+        if the physical register was used and is not used now
+*/
+void syncAllRegs() {
+    int k, k2;
+    for(k = PhysicalReg_EAX; k <= PhysicalReg_XMM7; k++) {
+        if(k == PhysicalReg_EDI || k == PhysicalReg_ESP || k == PhysicalReg_EBP)
+            continue;
+        //check whether the physical register is used by any logical register
+        bool stillUsed = false;
+        for(k2 = 0; k2 < num_compile_entries; k2++) {
+            if(compileTable[k2].physicalReg == k) {
+                stillUsed = true;
+                break;
+            }
+        }
+        if(stillUsed && !allRegs[k].isUsed) {
+            allRegs[k].isUsed = true;
+        }
+        if(!stillUsed && allRegs[k].isUsed) {
+            allRegs[k].isUsed = false;
+            allRegs[k].freeTimeStamp = lowOpTimeStamp;
+        }
+    }
+    return;
+}
+
+//!sync up spillIndexUsed with compileTable
+
+//!
+void updateSpillIndexUsed() {
+    int k;
+    for(k = 0; k <= MAX_SPILL_JIT_IA-1; k++) spillIndexUsed[k] = 0;
+    for(k = 0; k < num_compile_entries; k++) {
+        if(isVirtualReg(compileTable[k].physicalType)) continue;
+        if(compileTable[k].spill_loc_index >= 0) {
+            if(compileTable[k].spill_loc_index > 4*(MAX_SPILL_JIT_IA-1))
+                ALOGE("spill_loc_index is wrong for entry %d: %d",
+                      k, compileTable[k].spill_loc_index);
+            spillIndexUsed[compileTable[k].spill_loc_index >> 2] = 1;
+        }
+    }
+}
+
+/* free memory used in all basic blocks */
+void freeCFG() {
+    int k;
+    for(k = 0; k < num_bbs_for_method; k++) {
+        /* free defUseTable for method_bbs_sorted[k] */
+        DefUsePair* ptr = method_bbs_sorted[k]->defUseTable;
+        while(ptr != NULL) {
+            DefUsePair* tmp = ptr->next;
+            /* free ptr->uses */
+            DefOrUseLink* ptrUse = ptr->uses;
+            while(ptrUse != NULL) {
+                DefOrUseLink* tmp2 = ptrUse->next;
+                free(ptrUse);
+                ptrUse = tmp2;
+            }
+            free(ptr);
+            ptr = tmp;
+        }
+        free(method_bbs_sorted[k]);
+    }
+}
+
+/* update compileTable.physicalReg, compileTable.spill_loc_index & allRegs.isUsed
+   for glue-related variables, they do not exist
+       not in a physical register (physicalReg is Null)
+       not in a spilled memory location (spill_loc_index is -1)
+*/
+void initializeRegStateOfBB(BasicBlock_O1* bb) {
+    //for GLUE variables, do not exist
+    int k;
+    for(k = 0; k < num_compile_entries; k++) {
+        /* trace-based JIT: there is no VR with GG type */
+        if(isVirtualReg(compileTable[k].physicalType) && compileTable[k].gType == GLOBALTYPE_GG) {
+            if(bb->bb_index > 0) { //non-entry block
+                if(isFirstOfHandler(bb)) {
+                    /* at the beginning of an exception handler, GG VR is in the interpreted stack */
+                    compileTable[k].physicalReg = PhysicalReg_Null;
+#ifdef DEBUG_COMPILE_TABLE
+                    ALOGI("at the first basic block of an exception handler, GG VR %d type %d is in memory",
+                          compileTable[k].regNum, compileTable[k].physicalType);
+#endif
+                } else {
+                    if(compileTable[k].physicalReg == PhysicalReg_Null) {
+                        /* GG VR is in a specific physical register */
+                        compileTable[k].physicalReg = compileTable[k].physicalReg_prev;
+                    }
+                    int tReg = compileTable[k].physicalReg;
+                    allRegs[tReg].isUsed = true;
+#ifdef DEBUG_REG_USED
+                    ALOGI("REGALLOC: physical reg %d is used by a GG VR %d %d at beginning of BB", tReg, compileTable[k].regNum, compileTable[k].physicalType);
+#endif
+                }
+            } //non-entry block
+        } //if GG VR
+        if(compileTable[k].regNum != PhysicalReg_GLUE &&
+           compileTable[k].regNum >= PhysicalReg_GLUE_DVMDEX) {
+            /* glue related registers */
+            compileTable[k].physicalReg = PhysicalReg_Null;
+            compileTable[k].spill_loc_index = -1;
+        }
+    }
+}
+
+/* update memVRTable[].nullCheckDone */
+void initializeNullCheck(int indexToMemVR) {
+    bool found = false;
+#ifdef GLOBAL_NULLCHECK_OPT
+    /* search nullCheck_inB of the current Basic Block */
+    for(k = 0; k < nullCheck_inSize[currentBB->bb_index2]; k++) {
+        if(nullCheck_inB[currentBB->bb_index2][k] == memVRTable[indexToMemVR].regNum) {
+            found = true;
+            break;
+        }
+    }
+#endif
+    memVRTable[indexToMemVR].nullCheckDone = found;
+}
+
+/* initialize memVRTable */
+void initializeMemVRTable() {
+    num_memory_vr = 0;
+    int k;
+    for(k = 0; k < num_compile_entries; k++) {
+        if(!isVirtualReg(compileTable[k].physicalType)) continue;
+        /* VRs in compileTable */
+        bool setToInMemory = (compileTable[k].physicalReg == PhysicalReg_Null);
+        int regNum = compileTable[k].regNum;
+        OpndSize sizeVR = getRegSize(compileTable[k].physicalType);
+        /* search memVRTable for the VR in compileTable */
+        int kk;
+        int indexL = -1;
+        int indexH = -1;
+        for(kk = 0; kk < num_memory_vr; kk++) {
+            if(memVRTable[kk].regNum == regNum) {
+                indexL = kk;
+                continue;
+            }
+            if(memVRTable[kk].regNum == regNum+1 && sizeVR == OpndSize_64) {
+                indexH = kk;
+                continue;
+            }
+        }
+        if(indexL < 0) {
+            /* the low half of VR is not in memVRTable
+               add an entry for the low half in memVRTable */
+            if(num_memory_vr >= NUM_MEM_VR_ENTRY) {
+                ALOGE("exceeds size of memVRTable");
+                dvmAbort();
+            }
+            memVRTable[num_memory_vr].regNum = regNum;
+            memVRTable[num_memory_vr].inMemory = setToInMemory;
+            initializeNullCheck(num_memory_vr); //set nullCheckDone
+            memVRTable[num_memory_vr].boundCheck.checkDone = false;
+            memVRTable[num_memory_vr].num_ranges = 0;
+            memVRTable[num_memory_vr].ranges = NULL;
+            memVRTable[num_memory_vr].delayFreeFlags = VRDELAY_NONE;
+            num_memory_vr++;
+        }
+        if(sizeVR == OpndSize_64 && indexH < 0) {
+            /* the high half of VR is not in memVRTable
+               add an entry for the high half in memVRTable */
+            if(num_memory_vr >= NUM_MEM_VR_ENTRY) {
+                ALOGE("exceeds size of memVRTable");
+                dvmAbort();
+            }
+            memVRTable[num_memory_vr].regNum = regNum+1;
+            memVRTable[num_memory_vr].inMemory = setToInMemory;
+            initializeNullCheck(num_memory_vr);
+            memVRTable[num_memory_vr].boundCheck.checkDone = false;
+            memVRTable[num_memory_vr].num_ranges = 0;
+            memVRTable[num_memory_vr].ranges = NULL;
+            memVRTable[num_memory_vr].delayFreeFlags = VRDELAY_NONE;
+            num_memory_vr++;
+        }
+    }
+}
+
+/* create a O1 basic block from basic block constructed in JIT MIR */
+BasicBlock_O1* createBasicBlockO1(BasicBlock* bb) {
+    BasicBlock_O1* bb1 = createBasicBlock(0, -1);
+    bb1->jitBasicBlock = bb;
+    return bb1;
+}
+
+/* a basic block in JIT MIR can contain bytecodes that are not in program order
+   for example, a "goto" bytecode will be followed by the goto target */
+void preprocessingBB(BasicBlock* bb) {
+    currentBB = createBasicBlockO1(bb);
+    /* initialize currentBB->allocConstraints */
+    int ii;
+    for(ii = 0; ii < 8; ii++) {
+        currentBB->allocConstraints[ii].physicalReg = (PhysicalReg)ii;
+        currentBB->allocConstraints[ii].count = 0;
+    }
+    collectInfoOfBasicBlock(currentMethod, currentBB);
+#ifdef DEBUG_COMPILE_TABLE
+    dumpVirtualInfoOfBasicBlock(currentBB);
+#endif
+    currentBB = NULL;
+}
+
+void preprocessingTrace() {
+    int k, k2, k3, jj;
+    /* this is a simplified verson of setTypeOfVR()
+        all VRs are assumed to be GL, no VR will be GG
+    */
+    for(k = 0; k < num_bbs_for_method; k++)
+        for(jj = 0; jj < method_bbs_sorted[k]->num_regs; jj++)
+            method_bbs_sorted[k]->infoBasicBlock[jj].gType = GLOBALTYPE_GL;
+
+    /* insert a glue-related register GLUE_DVMDEX to compileTable */
+    insertGlueReg();
+
+    int compile_entries_old = num_compile_entries;
+    for(k2 = 0; k2 < num_bbs_for_method; k2++) {
+        currentBB = method_bbs_sorted[k2];
+        /* update compileTable with virtual register from currentBB */
+        for(k3 = 0; k3 < currentBB->num_regs; k3++) {
+            insertFromVirtualInfo(currentBB, k3);
+        }
+
+        /* for each GL|GG type VR, insert fake usage at end of basic block to keep it live */
+        int offsetPC_back = offsetPC;
+        offsetPC = PC_FOR_END_OF_BB;
+        for(k = 0; k < num_compile_entries; k++) {
+            currentInfo.regNum = compileTable[k].regNum;
+            currentInfo.physicalType = (LowOpndRegType)compileTable[k].physicalType;
+            if(isVirtualReg(compileTable[k].physicalType) &&
+               compileTable[k].gType == GLOBALTYPE_GL) {
+                /* update defUseTable by assuming a fake usage at END of a basic block for variable @ currentInfo */
+                fakeUsageAtEndOfBB(currentBB);
+            }
+            if(isVirtualReg(compileTable[k].physicalType) &&
+               compileTable[k].gType == GLOBALTYPE_GG) {
+                fakeUsageAtEndOfBB(currentBB);
+            }
+        }
+        offsetPC = offsetPC_back;
+        num_compile_entries = compile_entries_old;
+    }
+    /* initialize data structure allRegs */
+    initializeAllRegs();
+#ifdef DEBUG_COMPILE_TABLE
+    dumpCompileTable();
+#endif
+    currentBB = NULL;
+}
+
+void printJitTraceInfoAtRunTime(const Method* method, int offset) {
+    ALOGI("execute trace for %s%s at offset %x", method->clazz->descriptor, method->name, offset);
+}
+
+void startOfTraceO1(const Method* method, LowOpBlockLabel* labelList, int exceptionBlockId, CompilationUnit *cUnit) {
+    num_exception_handlers = 0;
+    num_compile_entries = 0;
+    currentBB = NULL;
+    pc_start = -1;
+    bb_entry = NULL;
+    num_bbs_for_method = 0;
+    currentUnit = cUnit;
+    lowOpTimeStamp = 0;
+
+// dumpDebuggingInfo is gone in CompilationUnit struct
+#if 0
+    /* add code to dump debugging information */
+    if(cUnit->dumpDebuggingInfo) {
+        move_imm_to_mem(OpndSize_32, cUnit->startOffset, -4, PhysicalReg_ESP, true); //2nd argument: offset
+        move_imm_to_mem(OpndSize_32, (int)currentMethod, -8, PhysicalReg_ESP, true); //1st argument: method
+        load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+
+        typedef void (*vmHelper)(const Method*, int);
+        vmHelper funcPtr = printJitTraceInfoAtRunTime;
+        move_imm_to_reg(OpndSize_32, (int)funcPtr, PhysicalReg_ECX, true);
+        call_reg(PhysicalReg_ECX, true);
+
+        load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    }
+#endif
+}
+
+
+/* Code generation for a basic block defined for JIT
+   We have two data structures for a basic block:
+       BasicBlock defined in vm/compiler by JIT
+       BasicBlock_O1 defined in o1 */
+int codeGenBasicBlockJit(const Method* method, BasicBlock* bb) {
+    /* search method_bbs_sorted to find the O1 basic block corresponding to bb */
+    int k;
+    for(k = 0; k < num_bbs_for_method; k++) {
+        if(method_bbs_sorted[k]->jitBasicBlock == bb) {
+            lowOpTimeStamp = 0; //reset time stamp at start of a basic block
+            currentBB = method_bbs_sorted[k];
+            int cg_ret = codeGenBasicBlock(method, currentBB);
+            currentBB = NULL;
+            return cg_ret;
+        }
+    }
+    ALOGE("can't find the corresponding O1 basic block for id %d type %d",
+         bb->id, bb->blockType);
+    return -1;
+}
+void endOfBasicBlock(BasicBlock* bb) {
+    isScratchPhysical = true;
+    currentBB = NULL;
+}
+void endOfTraceO1() {
+     freeCFG();
+}
+
+/** entry point to collect information about virtual registers used in a basic block
+    Initialize data structure BasicBlock_O1
+    The usage information of virtual registers is stoerd in bb->infoBasicBlock
+
+    Global variables accessed: offsetPC, rPC
+*/
+int collectInfoOfBasicBlock(Method* method, BasicBlock_O1* bb) {
+    bb->num_regs = 0;
+    bb->num_defs = 0;
+    bb->defUseTable = NULL;
+    bb->defUseTail = NULL;
+    u2* rPC_start = (u2*)method->insns;
+    int kk;
+    bb->endsWithReturn = false;
+    bb->hasAccessToGlue = false;
+
+    MIR* mir;
+    int seqNum = 0;
+    /* traverse the MIR in basic block
+       sequence number is used to make sure next bytecode will have a larger sequence number */
+    for(mir = bb->jitBasicBlock->firstMIRInsn; mir; mir = mir->next) {
+        offsetPC = seqNum;
+        mir->seqNum = seqNum++;
+        rPC = rPC_start + mir->offset;
+#ifdef WITH_JIT_INLINING
+        if(mir->dalvikInsn.opcode >= kMirOpFirst &&
+           mir->dalvikInsn.opcode != kMirOpCheckInlinePrediction) continue;
+        if(ir->dalvikInsn.opcode == kMirOpCheckInlinePrediction) { //TODO
+        }
+#else
+        if(mir->dalvikInsn.opcode >= kNumPackedOpcodes) continue;
+#endif
+        inst = FETCH(0);
+        u2 inst_op = INST_INST(inst);
+        /* update bb->hasAccessToGlue */
+        if((inst_op >= OP_MOVE_RESULT && inst_op <= OP_RETURN_OBJECT) ||
+           (inst_op >= OP_MONITOR_ENTER && inst_op <= OP_INSTANCE_OF) ||
+           (inst_op == OP_FILLED_NEW_ARRAY) ||
+           (inst_op == OP_FILLED_NEW_ARRAY_RANGE) ||
+           (inst_op == OP_THROW) ||
+           (inst_op >= OP_INVOKE_VIRTUAL && inst_op <= OP_INVOKE_INTERFACE_RANGE) ||
+           (inst_op >= OP_THROW_VERIFICATION_ERROR &&
+            inst_op <= OP_EXECUTE_INLINE_RANGE) ||
+           (inst_op >= OP_INVOKE_VIRTUAL_QUICK && inst_op <= OP_INVOKE_SUPER_QUICK_RANGE))
+            bb->hasAccessToGlue = true;
+        /* update bb->endsWithReturn */
+        if(inst_op == OP_RETURN_VOID || inst_op == OP_RETURN || inst_op == OP_RETURN_VOID_BARRIER ||
+           inst_op == OP_RETURN_OBJECT || inst_op == OP_RETURN_WIDE)
+            bb->endsWithReturn = true;
+
+        /* get virtual register usage in current bytecode */
+        getVirtualRegInfo(infoByteCode);
+        int num_regs = num_regs_per_bytecode;
+        for(kk = 0; kk < num_regs; kk++) {
+            currentInfo = infoByteCode[kk];
+#ifdef DEBUG_MERGE_ENTRY
+            ALOGI("call mergeEntry2 at offsetPC %x kk %d VR %d %d", offsetPC, kk,
+                  currentInfo.regNum, currentInfo.physicalType);
+#endif
+            mergeEntry2(bb); //update defUseTable of the basic block
+        }
+
+        //dumpVirtualInfoOfBasicBlock(bb);
+    }//for each bytecode
+
+    bb->pc_end = seqNum;
+
+    //sort allocConstraints of each basic block
+    for(kk = 0; kk < bb->num_regs; kk++) {
+#ifdef DEBUG_ALLOC_CONSTRAINT
+        ALOGI("sort virtual reg %d type %d -------", bb->infoBasicBlock[kk].regNum,
+              bb->infoBasicBlock[kk].physicalType);
+#endif
+        sortAllocConstraint(bb->infoBasicBlock[kk].allocConstraints,
+                            bb->infoBasicBlock[kk].allocConstraintsSorted, true);
+    }
+#ifdef DEBUG_ALLOC_CONSTRAINT
+    ALOGI("sort constraints for BB %d --------", bb->bb_index);
+#endif
+    sortAllocConstraint(bb->allocConstraints, bb->allocConstraintsSorted, false);
+    return 0;
+}
+
+/** entry point to generate native code for a O1 basic block
+    There are 3 kinds of virtual registers in a O1 basic block:
+    1> L VR: local within the basic block
+    2> GG VR: is live in other basic blocks,
+              its content is in a pre-defined GPR at the beginning of a basic block
+    3> GL VR: is live in other basic blocks,
+              its content is in the interpreted stack at the beginning of a basic block
+    compileTable is updated with infoBasicBlock at the start of the basic block;
+    Before lowering each bytecode, compileTable is updated with infoByteCodeTemp;
+    At end of the basic block, right before the jump instruction, handles constant VRs and GG VRs
+*/
+int codeGenBasicBlock(const Method* method, BasicBlock_O1* bb) {
+    /* we assume at the beginning of each basic block,
+       all GL VRs reside in memory and all GG VRs reside in predefined physical registers,
+       so at the end of a basic block, recover a spilled GG VR, store a GL VR to memory */
+    /* update compileTable with entries in bb->infoBasicBlock */
+    int k;
+    for(k = 0; k < bb->num_regs; k++) {
+        insertFromVirtualInfo(bb, k);
+    }
+    updateXferPoints(); //call fakeUsageAtEndOfBB
+#ifdef DEBUG_REACHING_DEF
+    printDefUseTable();
+#endif
+#ifdef DSE_OPT
+    removeDeadDefs();
+    printDefUseTable();
+#endif
+    //clear const section of compileTable
+    for(k = 0; k < num_compile_entries; k++) compileTable[k].isConst = false;
+    num_const_vr = 0;
+#ifdef DEBUG_COMPILE_TABLE
+    ALOGI("At start of basic block %d (num of VRs %d) -------", bb->bb_index, bb->num_regs);
+    dumpCompileTable();
+#endif
+    initializeRegStateOfBB(bb);
+    initializeMemVRTable();
+    updateLiveTable();
+    freeReg(true);  //before code gen of a basic block, also called at end of a basic block?
+#ifdef DEBUG_COMPILE_TABLE
+    ALOGI("At start of basic block %d (num of VRs %d) -------", bb->bb_index, bb->num_regs);
+#endif
+
+    u2* rPC_start = (u2*)method->insns;
+    bool lastByteCodeIsJump = false;
+    MIR* mir;
+    for(mir = bb->jitBasicBlock->firstMIRInsn; mir; mir = mir->next) {
+        offsetPC = mir->seqNum;
+        rPC = rPC_start + mir->offset;
+#ifdef WITH_JIT_INLINING
+        if(mir->dalvikInsn.opcode >= kMirOpFirst &&
+           mir->dalvikInsn.opcode != kMirOpCheckInlinePrediction) {
+#else
+        if(mir->dalvikInsn.opcode >= kNumPackedOpcodes) {
+#endif
+            handleExtendedMIR(currentUnit, mir);
+            continue;
+        }
+
+        inst = FETCH(0);
+        //before handling a bytecode, import info of temporary registers to compileTable including refCount
+        num_temp_regs_per_bytecode = getTempRegInfo(infoByteCodeTemp);
+        for(k = 0; k < num_temp_regs_per_bytecode; k++) {
+            if(infoByteCodeTemp[k].versionNum > 0) continue;
+            insertFromTempInfo(k);
+        }
+        startNativeCode(-1, -1);
+        for(k = 0; k <= MAX_SPILL_JIT_IA-1; k++) spillIndexUsed[k] = 0;
+        //update spillIndexUsed if a glue variable was spilled
+        for(k = 0; k < num_compile_entries; k++) {
+            if(compileTable[k].regNum >= PhysicalReg_GLUE_DVMDEX) {
+                if(compileTable[k].spill_loc_index >= 0)
+                    spillIndexUsed[compileTable[k].spill_loc_index >> 2] = 1;
+            }
+        }
+#ifdef DEBUG_COMPILE_TABLE
+        ALOGI("compile table size after importing temporary info %d", num_compile_entries);
+        ALOGI("before one bytecode %d (num of VRs %d) -------", bb->bb_index, bb->num_regs);
+#endif
+        //set isConst to true for CONST & MOVE MOVE_OBJ?
+        //clear isConst to true for MOVE, MOVE_OBJ, MOVE_RESULT, MOVE_EXCEPTION ...
+        bool isConst = getConstInfo(bb); //will reset isConst if a VR is updated by the bytecode
+        bool isDeadStmt = false;
+#ifdef DSE_OPT
+        for(k = 0; k < num_dead_pc; k++) {
+            if(deadPCs[k] == offsetPC) {
+                isDeadStmt = true;
+                break;
+            }
+        }
+#endif
+        getVirtualRegInfo(infoByteCode);
+        //call something similar to mergeEntry2, but only update refCount
+        //clear refCount
+        for(k = 0; k < num_regs_per_bytecode; k++) {
+            int indexT = searchCompileTable(LowOpndRegType_virtual | infoByteCode[k].physicalType,
+                                            infoByteCode[k].regNum);
+            if(indexT >= 0)
+                compileTable[indexT].refCount = 0;
+        }
+        for(k = 0; k < num_regs_per_bytecode; k++) {
+            int indexT = searchCompileTable(LowOpndRegType_virtual | infoByteCode[k].physicalType,
+                                            infoByteCode[k].regNum);
+            if(indexT >= 0)
+                compileTable[indexT].refCount += infoByteCode[k].refCount;
+        } //for k
+#ifdef DSE_OPT
+        if(isDeadStmt) { //search compileTable
+            getVirtualRegInfo(infoByteCode);
+#ifdef DEBUG_DSE
+            ALOGI("DSE: stmt at offsetPC %d is dead", offsetPC);
+#endif
+            for(k = 0; k < num_regs_per_bytecode; k++) {
+                int indexT = searchCompileTable(LowOpndRegType_virtual | infoByteCode[k].physicalType,
+                                                infoByteCode[k].regNum);
+                if(indexT >= 0)
+                    compileTable[indexT].refCount -= infoByteCode[k].refCount;
+            }
+        }
+#endif
+        lastByteCodeIsJump = false;
+        if(!isConst && !isDeadStmt)  //isDeadStmt is false when DSE_OPT is not enabled
+        {
+#ifdef DEBUG_COMPILE_TABLE
+            dumpCompileTable();
+#endif
+            globalShortMap = NULL;
+            if(isCurrentByteCodeJump()) lastByteCodeIsJump = true;
+            //lowerByteCode will call globalVREndOfBB if it is jump
+            int retCode = lowerByteCodeJit(method, rPC, mir);
+            if(gDvmJit.codeCacheByteUsed + (stream - streamStart) +
+                 CODE_CACHE_PADDING > gDvmJit.codeCacheSize) {
+                 ALOGE("JIT code cache full");
+                 gDvmJit.codeCacheFull = true;
+                 return -1;
+            }
+
+            if (retCode == 1) {
+                ALOGE("JIT couldn't compile %s%s dex_pc=%d", method->clazz->descriptor, method->name, offsetPC);
+                return -1;
+            }
+            updateConstInfo(bb);
+            freeShortMap();
+            if(retCode < 0) {
+                ALOGE("error in lowering the bytecode");
+                return retCode;
+            }
+            freeReg(true); //may dump GL VR to memory (this is necessary)
+            //after each bytecode, make sure non-VRs have refCount of zero
+            for(k = 0; k < num_compile_entries; k++) {
+                if(isTemporary(compileTable[k].physicalType, compileTable[k].regNum)) {
+#ifdef PRINT_WARNING
+                    if(compileTable[k].refCount > 0) {
+                        ALOGW("refCount for a temporary reg %d %d is %d after a bytecode", compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].refCount);
+                    }
+#endif
+                    compileTable[k].refCount = 0;
+                }
+            }
+        } else { //isConst || isDeadStmt
+            //if this bytecode is the target of a jump, the mapFromBCtoNCG should be updated
+            offsetNCG = stream - streamMethodStart;
+            mapFromBCtoNCG[offsetPC] = offsetNCG;
+#ifdef DEBUG_COMPILE_TABLE
+            ALOGI("this bytecode generates a constant and has no side effect");
+#endif
+            freeReg(true); //may dump GL VR to memory (this is necessary)
+        }
+#ifdef DEBUG_COMPILE_TABLE
+        ALOGI("after one bytecode BB %d (num of VRs %d)", bb->bb_index, bb->num_regs);
+#endif
+    }//for each bytecode
+#ifdef DEBUG_COMPILE_TABLE
+    dumpCompileTable();
+#endif
+    if(!lastByteCodeIsJump) constVREndOfBB();
+    //at end of a basic block, get spilled GG VR & dump GL VR
+    if(!lastByteCodeIsJump) globalVREndOfBB(method);
+    //remove entries for temporary registers, L VR and GL VR
+    int jj;
+    for(k = 0; k < num_compile_entries; ) {
+        bool removeEntry = false;
+        if(isVirtualReg(compileTable[k].physicalType) && compileTable[k].gType != GLOBALTYPE_GG) {
+            removeEntry = true;
+        }
+        if(isTemporary(compileTable[k].physicalType, compileTable[k].regNum))
+            removeEntry = true;
+        if(removeEntry) {
+#ifdef PRINT_WARNING
+            if(compileTable[k].refCount > 0)
+                ALOGW("refCount for REG %d %d is %d at end of a basic block", compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].refCount);
+#endif
+            compileTable[k].refCount = 0;
+            for(jj = k+1; jj < num_compile_entries; jj++) {
+                compileTable[jj-1] = compileTable[jj];
+            }
+            num_compile_entries--;
+        } else {
+            k++;
+        }
+    }
+    freeReg(true);
+    //free LIVE TABLE
+    for(k = 0; k < num_memory_vr; k++) {
+        LiveRange* ptr2 = memVRTable[k].ranges;
+        while(ptr2 != NULL) {
+            LiveRange* tmpP = ptr2->next;
+            free(ptr2->accessPC);
+            free(ptr2);
+            ptr2 = tmpP;
+        }
+    }
+#ifdef DEBUG_COMPILE_TABLE
+    ALOGI("At end of basic block -------");
+    dumpCompileTable();
+#endif
+    return 0;
+}
+
+/** update infoBasicBlock & defUseTable
+    input: currentInfo
+    side effect: update currentInfo.reachingDefs
+
+    update entries in infoBasicBlock by calling updateReachingDefA
+    if there is no entry in infoBasicBlock for B, an entry will be created and inserted to infoBasicBlock
+
+    defUseTable is updated to account for the access at currentInfo
+    if accessType of B is U or UD, we call updateReachingDefB to update currentInfo.reachingDefs
+        in order to correctly insert the usage to defUseTable
+*/
+int mergeEntry2(BasicBlock_O1* bb) {
+    LowOpndRegType typeB = currentInfo.physicalType;
+    int regB = currentInfo.regNum;
+    int jj, k;
+    int jjend = bb->num_regs;
+    bool isMerged = false;
+    bool hasAlias = false;
+    OverlapCase isBPartiallyOverlapA, isAPartiallyOverlapB;
+    RegAccessType tmpType = REGACCESS_N;
+    currentInfo.num_reaching_defs = 0;
+
+    /* traverse variable A in infoBasicBlock */
+    for(jj = 0; jj < jjend; jj++) {
+        int regA = bb->infoBasicBlock[jj].regNum;
+        LowOpndRegType typeA = bb->infoBasicBlock[jj].physicalType;
+        isBPartiallyOverlapA = getBPartiallyOverlapA(regB, typeB, regA, typeA);
+        isAPartiallyOverlapB = getAPartiallyOverlapB(regA, typeA, regB, typeB);
+        if(regA == regB && typeA == typeB) {
+            /* variable A and B are aligned */
+            bb->infoBasicBlock[jj].accessType = mergeAccess2(bb->infoBasicBlock[jj].accessType, currentInfo.accessType,
+                                                             OVERLAP_B_COVER_A);
+            bb->infoBasicBlock[jj].refCount += currentInfo.refCount;
+            /* copy reaching defs of variable B from variable A */
+            currentInfo.num_reaching_defs = bb->infoBasicBlock[jj].num_reaching_defs;
+            for(k = 0; k < currentInfo.num_reaching_defs; k++)
+                currentInfo.reachingDefs[k] = bb->infoBasicBlock[jj].reachingDefs[k];
+            updateDefUseTable(); //use currentInfo to update defUseTable
+            updateReachingDefA(jj, OVERLAP_B_COVER_A); //update reachingDefs of A
+            isMerged = true;
+            hasAlias = true;
+            if(typeB == LowOpndRegType_gp) {
+                //merge allocConstraints
+                for(k = 0; k < 8; k++) {
+                    bb->infoBasicBlock[jj].allocConstraints[k].count += currentInfo.allocConstraints[k].count;
+                }
+            }
+        }
+        else if(isBPartiallyOverlapA != OVERLAP_NO) {
+            tmpType = updateAccess2(tmpType, updateAccess1(bb->infoBasicBlock[jj].accessType, isAPartiallyOverlapB));
+            bb->infoBasicBlock[jj].accessType = mergeAccess2(bb->infoBasicBlock[jj].accessType, currentInfo.accessType,
+                                                             isBPartiallyOverlapA);
+#ifdef DEBUG_MERGE_ENTRY
+            ALOGI("update accessType in case 2: VR %d %d accessType %d", regA, typeA, bb->infoBasicBlock[jj].accessType);
+#endif
+            hasAlias = true;
+            if(currentInfo.accessType == REGACCESS_U || currentInfo.accessType == REGACCESS_UD) {
+                /* update currentInfo.reachingDefs */
+                updateReachingDefB1(jj);
+                updateReachingDefB2();
+            }
+            updateReachingDefA(jj, isBPartiallyOverlapA);
+        }
+        else {
+            //even if B does not overlap with A, B can affect the reaching defs of A
+            //for example, B is a def of "v0", A is "v1"
+            //  B can kill some reaching defs of A or affect the accessType of a reaching def
+            updateReachingDefA(jj, OVERLAP_NO); //update reachingDefs of A
+        }
+    }//for each variable A in infoBasicBlock
+    if(!isMerged) {
+        /* create a new entry in infoBasicBlock */
+        bb->infoBasicBlock[bb->num_regs].refCount = currentInfo.refCount;
+        bb->infoBasicBlock[bb->num_regs].physicalType = typeB;
+        if(hasAlias)
+            bb->infoBasicBlock[bb->num_regs].accessType = updateAccess3(tmpType, currentInfo.accessType);
+        else
+            bb->infoBasicBlock[bb->num_regs].accessType = currentInfo.accessType;
+#ifdef DEBUG_MERGE_ENTRY
+        ALOGI("update accessType in case 3: VR %d %d accessType %d", regB, typeB, bb->infoBasicBlock[bb->num_regs].accessType);
+#endif
+        bb->infoBasicBlock[bb->num_regs].regNum = regB;
+        for(k = 0; k < 8; k++)
+            bb->infoBasicBlock[bb->num_regs].allocConstraints[k] = currentInfo.allocConstraints[k];
+#ifdef DEBUG_MERGE_ENTRY
+        ALOGI("isMerged is false, call updateDefUseTable");
+#endif
+        updateDefUseTable(); //use currentInfo to update defUseTable
+        updateReachingDefB3(); //update currentInfo.reachingDefs if currentInfo defines variable B
+
+        //copy from currentInfo.reachingDefs to bb->infoBasicBlock[bb->num_regs]
+        bb->infoBasicBlock[bb->num_regs].num_reaching_defs = currentInfo.num_reaching_defs;
+        for(k = 0; k < currentInfo.num_reaching_defs; k++)
+            bb->infoBasicBlock[bb->num_regs].reachingDefs[k] = currentInfo.reachingDefs[k];
+#ifdef DEBUG_MERGE_ENTRY
+        ALOGI("try to update reaching defs for VR %d %d", regB, typeB);
+        for(k = 0; k < bb->infoBasicBlock[bb->num_regs].num_reaching_defs; k++)
+            ALOGI("reaching def %d @ %d for VR %d %d access %d", k, currentInfo.reachingDefs[k].offsetPC,
+                  currentInfo.reachingDefs[k].regNum, currentInfo.reachingDefs[k].physicalType,
+                  currentInfo.reachingDefs[k].accessType);
+#endif
+        bb->num_regs++;
+        if(bb->num_regs >= MAX_REG_PER_BASICBLOCK) {
+            ALOGE("too many VRs in a basic block");
+            dvmAbort();
+        }
+        return -1;
+    }
+    return 0;
+}
+
+//!update reaching defs for infoBasicBlock[indexToA]
+
+//!use currentInfo.reachingDefs to update reaching defs for variable A
+void updateReachingDefA(int indexToA, OverlapCase isBPartiallyOverlapA) {
+    if(indexToA < 0) return;
+    int k, k2;
+    OverlapCase isBPartiallyOverlapDef;
+    if(currentInfo.accessType == REGACCESS_U) {
+        return; //no update to reachingDefs of the VR
+    }
+    /* access in currentInfo is DU, D, or UD */
+    if(isBPartiallyOverlapA == OVERLAP_B_COVER_A) {
+        /* from this point on, the reachingDefs for variable A is a single def to currentInfo at offsetPC */
+        currentBB->infoBasicBlock[indexToA].num_reaching_defs = 1;
+        currentBB->infoBasicBlock[indexToA].reachingDefs[0].offsetPC = offsetPC;
+        currentBB->infoBasicBlock[indexToA].reachingDefs[0].regNum = currentInfo.regNum;
+        currentBB->infoBasicBlock[indexToA].reachingDefs[0].physicalType = currentInfo.physicalType;
+        currentBB->infoBasicBlock[indexToA].reachingDefs[0].accessType = REGACCESS_D;
+#ifdef DEBUG_REACHING_DEF
+        ALOGI("single reaching def @ %d for VR %d %d", offsetPC, currentInfo.regNum, currentInfo.physicalType);
+#endif
+        return;
+    }
+    /* update reachingDefs for variable A to get rid of dead defs */
+    /* Bug fix: it is possible that more than one reaching defs need to be removed
+                after one reaching def is removed, num_reaching_defs--, but k should not change
+    */
+    for(k = 0; k < currentBB->infoBasicBlock[indexToA].num_reaching_defs; ) {
+        /* remove one reaching def in one interation of the loop */
+        //check overlapping between def & B
+        isBPartiallyOverlapDef = getBPartiallyOverlapA(currentInfo.regNum, currentInfo.physicalType,
+                                                       currentBB->infoBasicBlock[indexToA].reachingDefs[k].regNum,
+                                                       currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType);
+#ifdef DEBUG_REACHING_DEF
+        ALOGI("DEBUG B %d %d def %d %d %d", currentInfo.regNum, currentInfo.physicalType,
+              currentBB->infoBasicBlock[indexToA].reachingDefs[k].regNum,
+              currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType,
+              currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType);
+#endif
+        /* cases where one def nees to be removed:
+           if B fully covers def, def is removed
+           if B overlaps high half of def & def's accessType is H, def is removed
+           if B overlaps low half of def & def's accessType is L, def is removed
+        */
+        if((isBPartiallyOverlapDef == OVERLAP_B_COVER_HIGH_OF_A &&
+            currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType == REGACCESS_H) ||
+           (isBPartiallyOverlapDef == OVERLAP_B_COVER_LOW_OF_A &&
+            currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType == REGACCESS_L) ||
+           isBPartiallyOverlapDef == OVERLAP_B_COVER_A
+           ) { //remove def
+            //shift from k+1 to end
+            for(k2 = k+1; k2 < currentBB->infoBasicBlock[indexToA].num_reaching_defs; k2++)
+                currentBB->infoBasicBlock[indexToA].reachingDefs[k2-1] = currentBB->infoBasicBlock[indexToA].reachingDefs[k2];
+            currentBB->infoBasicBlock[indexToA].num_reaching_defs--;
+        }
+        /*
+           if B overlaps high half of def & def's accessType is not H --> update accessType of def
+        */
+        else if(isBPartiallyOverlapDef == OVERLAP_B_COVER_HIGH_OF_A &&
+                currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType != REGACCESS_H) {
+            //low half is still valid
+            if(getRegSize(currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType) == OpndSize_32)
+                currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType = REGACCESS_D;
+            else
+                currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType = REGACCESS_L;
+#ifdef DEBUG_REACHING_DEF
+            ALOGI("DEBUG: set accessType of def to L");
+#endif
+            k++;
+        }
+        /*
+           if B overlaps low half of def & def's accessType is not L --> update accessType of def
+        */
+        else if(isBPartiallyOverlapDef == OVERLAP_B_COVER_LOW_OF_A &&
+                currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType != REGACCESS_L) {
+            //high half of def is still valid
+            currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType = REGACCESS_H;
+#ifdef DEBUG_REACHING_DEF
+            ALOGI("DEBUG: set accessType of def to H");
+#endif
+            k++;
+        }
+        else {
+            k++;
+        }
+    }//for k
+    if(isBPartiallyOverlapA != OVERLAP_NO) {
+        //insert the def to variable @ currentInfo
+        k = currentBB->infoBasicBlock[indexToA].num_reaching_defs;
+        if(k >= 3) {
+          ALOGE("more than 3 reaching defs");
+        }
+        currentBB->infoBasicBlock[indexToA].reachingDefs[k].offsetPC = offsetPC;
+        currentBB->infoBasicBlock[indexToA].reachingDefs[k].regNum = currentInfo.regNum;
+        currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType = currentInfo.physicalType;
+        currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType = REGACCESS_D;
+        currentBB->infoBasicBlock[indexToA].num_reaching_defs++;
+    }
+#ifdef DEBUG_REACHING_DEF2
+    ALOGI("IN updateReachingDefA for VR %d %d", currentBB->infoBasicBlock[indexToA].regNum,
+          currentBB->infoBasicBlock[indexToA].physicalType);
+    for(k = 0; k < currentBB->infoBasicBlock[indexToA].num_reaching_defs; k++)
+        ALOGI("reaching def %d @ %d for VR %d %d access %d", k,
+              currentBB->infoBasicBlock[indexToA].reachingDefs[k].offsetPC,
+              currentBB->infoBasicBlock[indexToA].reachingDefs[k].regNum,
+              currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType,
+              currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType);
+#endif
+}
+
+/** Given a variable B @currentInfo,
+    updates its reaching defs by checking reaching defs of variable A @currentBB->infoBasicBlock[indexToA]
+    The result is stored in tmpInfo.reachingDefs
+*/
+void updateReachingDefB1(int indexToA) {
+    if(indexToA < 0) return;
+    int k;
+    tmpInfo.num_reaching_defs = 0;
+    for(k = 0; k < currentBB->infoBasicBlock[indexToA].num_reaching_defs; k++) {
+        /* go through reachingDefs of variable A @currentBB->infoBasicBlock[indexToA]
+           for each def, check whether it overlaps with variable B @currentInfo
+               if the def overlaps with variable B, insert it to tmpInfo.reachingDefs
+        */
+        OverlapCase isDefPartiallyOverlapB = getAPartiallyOverlapB(
+                                                 currentBB->infoBasicBlock[indexToA].reachingDefs[k].regNum,
+                                                 currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType,
+                                                 currentInfo.regNum, currentInfo.physicalType
+                                                 );
+        bool insert1 = false; //whether to insert the def to tmpInfo.reachingDefs
+        if(isDefPartiallyOverlapB == OVERLAP_ALIGN ||
+           isDefPartiallyOverlapB == OVERLAP_A_IS_LOW_OF_B ||
+           isDefPartiallyOverlapB == OVERLAP_A_IS_HIGH_OF_B) {
+            /* B aligns with def */
+            /* def is low half of B, def is high half of B
+               in these two cases, def is 32 bits */
+            insert1 = true;
+        }
+        RegAccessType deftype = currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType;
+        if(isDefPartiallyOverlapB == OVERLAP_B_IS_LOW_OF_A ||
+           isDefPartiallyOverlapB == OVERLAP_LOW_OF_A_IS_HIGH_OF_B) {
+            /* B is the low half of def */
+            /* the low half of def is the high half of B */
+            if(deftype != REGACCESS_H) insert1 = true;
+        }
+        if(isDefPartiallyOverlapB == OVERLAP_B_IS_HIGH_OF_A ||
+           isDefPartiallyOverlapB == OVERLAP_HIGH_OF_A_IS_LOW_OF_B) {
+            /* B is the high half of def */
+            /* the high half of def is the low half of B */
+            if(deftype != REGACCESS_L) insert1 = true;
+        }
+        if(insert1) {
+            if(tmpInfo.num_reaching_defs >= 3) {
+                ALOGE("more than 3 reaching defs for tmpInfo");
+            }
+            tmpInfo.reachingDefs[tmpInfo.num_reaching_defs] = currentBB->infoBasicBlock[indexToA].reachingDefs[k];
+            tmpInfo.num_reaching_defs++;
+#ifdef DEBUG_REACHING_DEF2
+            ALOGI("insert from entry %d %d: index %d", currentBB->infoBasicBlock[indexToA].regNum,
+                  currentBB->infoBasicBlock[indexToA].physicalType, k);
+#endif
+        }
+    }
+}
+
+/** update currentInfo.reachingDefs by merging currentInfo.reachingDefs with tmpInfo.reachingDefs
+*/
+void updateReachingDefB2() {
+    int k, k2;
+    for(k2 = 0; k2 < tmpInfo.num_reaching_defs; k2++ ) {
+        bool merged = false;
+        for(k = 0; k < currentInfo.num_reaching_defs; k++) {
+            /* check whether it is the same def, if yes, do nothing */
+            if(currentInfo.reachingDefs[k].regNum == tmpInfo.reachingDefs[k2].regNum &&
+               currentInfo.reachingDefs[k].physicalType == tmpInfo.reachingDefs[k2].physicalType) {
+                merged = true;
+                if(currentInfo.reachingDefs[k].offsetPC != tmpInfo.reachingDefs[k2].offsetPC) {
+                    ALOGE("defs on the same VR %d %d with different offsetPC %d vs %d",
+                          currentInfo.reachingDefs[k].regNum, currentInfo.reachingDefs[k].physicalType,
+                          currentInfo.reachingDefs[k].offsetPC, tmpInfo.reachingDefs[k2].offsetPC);
+                }
+                if(currentInfo.reachingDefs[k].accessType != tmpInfo.reachingDefs[k2].accessType)
+                    ALOGE("defs on the same VR %d %d with different accessType",
+                          currentInfo.reachingDefs[k].regNum, currentInfo.reachingDefs[k].physicalType);
+                break;
+            }
+        }
+        if(!merged) {
+            if(currentInfo.num_reaching_defs >= 3) {
+               ALOGE("more than 3 reaching defs for currentInfo");
+            }
+            currentInfo.reachingDefs[currentInfo.num_reaching_defs] = tmpInfo.reachingDefs[k2];
+            currentInfo.num_reaching_defs++;
+        }
+    }
+}
+
+//!update currentInfo.reachingDefs with currentInfo if variable is defined in currentInfo
+
+//!
+void updateReachingDefB3() {
+    if(currentInfo.accessType == REGACCESS_U) {
+        return; //no need to update currentInfo.reachingDefs
+    }
+    currentInfo.num_reaching_defs = 1;
+    currentInfo.reachingDefs[0].regNum = currentInfo.regNum;
+    currentInfo.reachingDefs[0].physicalType = currentInfo.physicalType;
+    currentInfo.reachingDefs[0].offsetPC = offsetPC;
+    currentInfo.reachingDefs[0].accessType = REGACCESS_D;
+}
+
+/** update defUseTable by checking currentInfo
+*/
+void updateDefUseTable() {
+    /* no access */
+    if(currentInfo.accessType == REGACCESS_N) return;
+    /* define then use, or define only */
+    if(currentInfo.accessType == REGACCESS_DU || currentInfo.accessType == REGACCESS_D) {
+        /* insert a definition at offsetPC to variable @ currentInfo */
+        DefUsePair* ptr = insertADef(offsetPC, currentInfo.regNum, currentInfo.physicalType, REGACCESS_D);
+        if(currentInfo.accessType != REGACCESS_D) {
+             /* if access is define then use, insert a use at offsetPC */
+            insertAUse(ptr, offsetPC, currentInfo.regNum, currentInfo.physicalType);
+        }
+        return;
+    }
+    /* use only or use then define
+       check the reaching defs for the usage */
+    int k;
+    bool isLCovered = false, isHCovered = false, isDCovered = false;
+    for(k = 0; k < currentInfo.num_reaching_defs; k++) {
+        /* insert a def currentInfo.reachingDefs[k] and a use of variable at offsetPC */
+        RegAccessType useType = insertDefUsePair(k);
+        if(useType == REGACCESS_D) isDCovered = true;
+        if(useType == REGACCESS_L) isLCovered = true;
+        if(useType == REGACCESS_H) isHCovered = true;
+    }
+    OpndSize useSize = getRegSize(currentInfo.physicalType);
+    if((!isDCovered) && (!isLCovered)) {
+        /* the low half of variable is not defined in the basic block
+           so insert a def to the low half at START of the basic block */
+        insertDefUsePair(-1);
+    }
+    if(useSize == OpndSize_64 && (!isDCovered) && (!isHCovered)) {
+        /* the high half of variable is not defined in the basic block
+           so insert a def to the high half at START of the basic block */
+        insertDefUsePair(-2);
+    }
+    if(currentInfo.accessType == REGACCESS_UD) {
+        /* insert a def at offsetPC to variable @ currentInfo */
+        insertADef(offsetPC, currentInfo.regNum, currentInfo.physicalType, REGACCESS_D);
+        return;
+    }
+}
+
+//! insert a use at offsetPC of given variable at end of DefUsePair
+
+//!
+RegAccessType insertAUse(DefUsePair* ptr, int offsetPC, int regNum, LowOpndRegType physicalType) {
+    DefOrUseLink* tLink = (DefOrUseLink*)malloc(sizeof(DefOrUseLink));
+    if(tLink == NULL) {
+        ALOGE("Memory allocation failed");
+        return REGACCESS_UNKNOWN;
+    }
+    tLink->offsetPC = offsetPC;
+    tLink->regNum = regNum;
+    tLink->physicalType = physicalType;
+    tLink->next = NULL;
+    if(ptr->useTail != NULL)
+        ptr->useTail->next = tLink;
+    ptr->useTail = tLink;
+    if(ptr->uses == NULL)
+        ptr->uses = tLink;
+    ptr->num_uses++;
+
+    //check whether the def is partially overlapping with the variable
+    OverlapCase isDefPartiallyOverlapB = getBPartiallyOverlapA(ptr->def.regNum,
+                                                       ptr->def.physicalType,
+                                                       regNum, physicalType);
+    RegAccessType useType = setAccessTypeOfUse(isDefPartiallyOverlapB, ptr->def.accessType);
+    tLink->accessType = useType;
+    return useType;
+}
+
+//! insert a def to currentBB->defUseTable
+
+//! update currentBB->defUseTail if necessary
+DefUsePair* insertADef(int offsetPC, int regNum, LowOpndRegType pType, RegAccessType rType) {
+    DefUsePair* ptr = (DefUsePair*)malloc(sizeof(DefUsePair));
+    if(ptr == NULL) {
+        ALOGE("Memory allocation failed");
+        return NULL;
+    }
+    ptr->next = NULL;
+    ptr->def.offsetPC = offsetPC;
+    ptr->def.regNum = regNum;
+    ptr->def.physicalType = pType;
+    ptr->def.accessType = rType;
+    ptr->num_uses = 0;
+    ptr->useTail = NULL;
+    ptr->uses = NULL;
+    if(currentBB->defUseTail != NULL) {
+        currentBB->defUseTail->next = ptr;
+    }
+    currentBB->defUseTail = ptr;
+    if(currentBB->defUseTable == NULL)
+        currentBB->defUseTable = ptr;
+    currentBB->num_defs++;
+#ifdef DEBUG_REACHING_DEF
+    ALOGI("insert a def at %d to defUseTable for VR %d %d", offsetPC,
+          regNum, pType);
+#endif
+    return ptr;
+}
+
+/** insert a def to defUseTable, then insert a use of variable @ currentInfo
+    if reachingDefIndex >= 0, the def is currentInfo.reachingDefs[index]
+    if reachingDefIndex is -1, the low half is defined at START of the basic block
+    if reachingDefIndex is -2, the high half is defined at START of the basic block
+*/
+RegAccessType insertDefUsePair(int reachingDefIndex) {
+    int k = reachingDefIndex;
+    DefUsePair* tableIndex = NULL;
+    DefOrUse theDef;
+    theDef.regNum = 0;
+    if(k < 0) {
+        /* def at start of the basic blcok */
+        theDef.offsetPC = PC_FOR_START_OF_BB;
+        theDef.accessType = REGACCESS_D;
+        if(k == -1) //low half of variable
+            theDef.regNum = currentInfo.regNum;
+        if(k == -2) //high half of variable
+            theDef.regNum = currentInfo.regNum+1;
+        theDef.physicalType = LowOpndRegType_gp;
+    }
+    else {
+        theDef = currentInfo.reachingDefs[k];
+    }
+    tableIndex = searchDefUseTable(theDef.offsetPC, theDef.regNum, theDef.physicalType);
+    if(tableIndex == NULL) //insert an entry
+        tableIndex = insertADef(theDef.offsetPC, theDef.regNum, theDef.physicalType, theDef.accessType);
+    else
+        tableIndex->def.accessType = theDef.accessType;
+    RegAccessType useType = insertAUse(tableIndex, offsetPC, currentInfo.regNum, currentInfo.physicalType);
+    return useType;
+}
+
+//! insert a XFER_MEM_TO_XMM to currentBB->xferPoints
+
+//!
+void insertLoadXfer(int offset, int regNum, LowOpndRegType pType) {
+    //check whether it is already in currentBB->xferPoints
+    int k;
+    for(k = 0; k < currentBB->num_xfer_points; k++) {
+        if(currentBB->xferPoints[k].xtype == XFER_MEM_TO_XMM &&
+           currentBB->xferPoints[k].offsetPC == offset &&
+           currentBB->xferPoints[k].regNum == regNum &&
+           currentBB->xferPoints[k].physicalType == pType)
+            return;
+    }
+    currentBB->xferPoints[currentBB->num_xfer_points].xtype = XFER_MEM_TO_XMM;
+    currentBB->xferPoints[currentBB->num_xfer_points].regNum = regNum;
+    currentBB->xferPoints[currentBB->num_xfer_points].offsetPC = offset;
+    currentBB->xferPoints[currentBB->num_xfer_points].physicalType = pType;
+#ifdef DEBUG_XFER_POINTS
+    ALOGI("insert to xferPoints %d: XFER_MEM_TO_XMM of VR %d %d at %d", currentBB->num_xfer_points, regNum, pType, offset);
+#endif
+    currentBB->num_xfer_points++;
+    if(currentBB->num_xfer_points >= MAX_XFER_PER_BB) {
+        ALOGE("too many xfer points");
+        dvmAbort();
+    }
+}
+
+/** update defUseTable by assuming a fake usage at END of a basic block for variable @ currentInfo
+    create a fake usage at end of a basic block for variable B (currentInfo.physicalType, currentInfo.regNum)
+    get reaching def info for variable B and store the info in currentInfo.reachingDefs
+        for each virtual register (variable A) accessed in the basic block
+            update reaching defs of B by checking reaching defs of variable A
+    update defUseTable
+*/
+int fakeUsageAtEndOfBB(BasicBlock_O1* bb) {
+    currentInfo.accessType = REGACCESS_U;
+    LowOpndRegType typeB = currentInfo.physicalType;
+    int regB = currentInfo.regNum;
+    int jj, k;
+    currentInfo.num_reaching_defs = 0;
+    for(jj = 0; jj < bb->num_regs; jj++) {
+        int regA = bb->infoBasicBlock[jj].regNum;
+        LowOpndRegType typeA = bb->infoBasicBlock[jj].physicalType;
+        OverlapCase isBPartiallyOverlapA = getBPartiallyOverlapA(regB, typeB, regA, typeA);
+        if(regA == regB && typeA == typeB) {
+            /* copy reachingDefs from variable A */
+            currentInfo.num_reaching_defs = bb->infoBasicBlock[jj].num_reaching_defs;
+            for(k = 0; k < currentInfo.num_reaching_defs; k++)
+                currentInfo.reachingDefs[k] = bb->infoBasicBlock[jj].reachingDefs[k];
+            break;
+        }
+        else if(isBPartiallyOverlapA != OVERLAP_NO) {
+            /* B overlaps with A */
+            /* update reaching defs of variable B by checking reaching defs of bb->infoBasicBlock[jj] */
+            updateReachingDefB1(jj);
+            updateReachingDefB2(); //merge currentInfo with tmpInfo
+        }
+    }
+    /* update defUseTable by checking currentInfo */
+    updateDefUseTable();
+    return 0;
+}
+
+/** update xferPoints of currentBB
+    Traverse currentBB->defUseTable
+*/
+int updateXferPoints() {
+    int k = 0;
+    currentBB->num_xfer_points = 0;
+    DefUsePair* ptr = currentBB->defUseTable;
+    DefOrUseLink* ptrUse = NULL;
+    /* traverse the def use chain of the basic block */
+    while(ptr != NULL) {
+        LowOpndRegType defType = ptr->def.physicalType;
+        //if definition is for a variable of 32 bits
+        if(getRegSize(defType) == OpndSize_32) {
+            /* check usages of the definition, whether it reaches a GPR, a XMM, a FS, or a SS */
+            bool hasGpUsage = false;
+            bool hasGpUsage2 = false; //not a fake usage
+            bool hasXmmUsage = false;
+            bool hasFSUsage = false;
+            bool hasSSUsage = false;
+            ptrUse = ptr->uses;
+            while(ptrUse != NULL) {
+                if(ptrUse->physicalType == LowOpndRegType_gp) {
+                    hasGpUsage = true;
+                    if(ptrUse->offsetPC != PC_FOR_END_OF_BB)
+                        hasGpUsage2 = true;
+                }
+                if(ptrUse->physicalType == LowOpndRegType_ss) hasSSUsage = true;
+                if(ptrUse->physicalType == LowOpndRegType_fs ||
+                   ptrUse->physicalType == LowOpndRegType_fs_s)
+                    hasFSUsage = true;
+                if(ptrUse->physicalType == LowOpndRegType_xmm) {
+                    hasXmmUsage = true;
+                }
+                if(ptrUse->physicalType == LowOpndRegType_xmm ||
+                   ptrUse->physicalType == LowOpndRegType_ss) {
+                    /* if a 32-bit definition reaches a xmm usage or a SS usage,
+                       insert a XFER_MEM_TO_XMM */
+                    insertLoadXfer(ptrUse->offsetPC,
+                                   ptrUse->regNum, LowOpndRegType_xmm);
+                }
+                ptrUse = ptrUse->next;
+            }
+            if(((hasXmmUsage || hasFSUsage || hasSSUsage) && defType == LowOpndRegType_gp) ||
+               (hasGpUsage && defType == LowOpndRegType_fs) ||
+               (defType == LowOpndRegType_ss && (hasGpUsage || hasXmmUsage || hasFSUsage))) {
+                /* insert a transfer if def is on a GPR, usage is on a XMM, FS or SS
+                                     if def is on a FS, usage is on a GPR
+                                     if def is on a SS, usage is on a GPR, XMM or FS
+                   transfer type is XFER_DEF_TO_GP_MEM if a real GPR usage exisits
+                   transfer type is XFER_DEF_TO_GP otherwise*/
+                currentBB->xferPoints[currentBB->num_xfer_points].offsetPC = ptr->def.offsetPC;
+                currentBB->xferPoints[currentBB->num_xfer_points].regNum = ptr->def.regNum;
+                currentBB->xferPoints[currentBB->num_xfer_points].physicalType = ptr->def.physicalType;
+                if(hasGpUsage2) { //create an entry XFER_DEF_TO_GP_MEM
+                    currentBB->xferPoints[currentBB->num_xfer_points].xtype = XFER_DEF_TO_GP_MEM;
+                }
+                else { //create an entry XFER_DEF_TO_MEM
+                    currentBB->xferPoints[currentBB->num_xfer_points].xtype = XFER_DEF_TO_MEM;
+                }
+                currentBB->xferPoints[currentBB->num_xfer_points].tableIndex = k;
+#ifdef DEBUG_XFER_POINTS
+                ALOGI("insert XFER %d at def %d: V%d %d", currentBB->num_xfer_points, ptr->def.offsetPC, ptr->def.regNum, defType);
+#endif
+                currentBB->num_xfer_points++;
+                if(currentBB->num_xfer_points >= MAX_XFER_PER_BB) {
+                    ALOGE("too many xfer points");
+                    dvmAbort();
+                }
+            }
+        }
+        else { /* def is on 64 bits */
+            bool hasGpUsageOfL = false; //exist a GPR usage of the low half
+            bool hasGpUsageOfH = false; //exist a GPR usage of the high half
+            bool hasGpUsageOfL2 = false;
+            bool hasGpUsageOfH2 = false;
+            bool hasMisaligned = false;
+            bool hasAligned = false;
+            bool hasFSUsage = false;
+            bool hasSSUsage = false;
+            ptrUse = ptr->uses;
+            while(ptrUse != NULL) {
+                if(ptrUse->physicalType == LowOpndRegType_gp &&
+                   ptrUse->regNum == ptr->def.regNum) {
+                    hasGpUsageOfL = true;
+                    if(ptrUse->offsetPC != PC_FOR_END_OF_BB)
+                        hasGpUsageOfL2 = true;
+                }
+                if(ptrUse->physicalType == LowOpndRegType_gp &&
+                   ptrUse->regNum == ptr->def.regNum + 1) {
+                    hasGpUsageOfH = true;
+                    if(ptrUse->offsetPC != PC_FOR_END_OF_BB)
+                        hasGpUsageOfH2 = true;
+                }
+                if(ptrUse->physicalType == LowOpndRegType_xmm &&
+                   ptrUse->regNum == ptr->def.regNum) {
+                    hasAligned = true;
+                    /* if def is on FS and use is on XMM, insert a XFER_MEM_TO_XMM */
+                    if(defType == LowOpndRegType_fs)
+                        insertLoadXfer(ptrUse->offsetPC,
+                                       ptrUse->regNum, LowOpndRegType_xmm);
+                }
+                if(ptrUse->physicalType == LowOpndRegType_fs ||
+                   ptrUse->physicalType == LowOpndRegType_fs_s)
+                    hasFSUsage = true;
+                if(ptrUse->physicalType == LowOpndRegType_xmm &&
+                   ptrUse->regNum != ptr->def.regNum) {
+                    hasMisaligned = true;
+                    /* if use is on XMM and use and def are misaligned, insert a XFER_MEM_TO_XMM */
+                    insertLoadXfer(ptrUse->offsetPC,
+                                   ptrUse->regNum, LowOpndRegType_xmm);
+                }
+                if(ptrUse->physicalType == LowOpndRegType_ss) {
+                    hasSSUsage = true;
+                    /* if use is on SS, insert a XFER_MEM_TO_XMM */
+                    insertLoadXfer(ptrUse->offsetPC,
+                                   ptrUse->regNum, LowOpndRegType_ss);
+                }
+                ptrUse = ptrUse->next;
+            }
+            if(defType == LowOpndRegType_fs && !hasGpUsageOfL && !hasGpUsageOfH) {
+                ptr = ptr->next;
+                continue;
+            }
+            if(defType == LowOpndRegType_xmm && !hasFSUsage &&
+               !hasGpUsageOfL && !hasGpUsageOfH && !hasMisaligned && !hasSSUsage) {
+                ptr = ptr->next;
+                continue;
+            }
+            /* insert a XFER_DEF_IS_XMM */
+            currentBB->xferPoints[currentBB->num_xfer_points].regNum = ptr->def.regNum;
+            currentBB->xferPoints[currentBB->num_xfer_points].offsetPC = ptr->def.offsetPC;
+            currentBB->xferPoints[currentBB->num_xfer_points].physicalType = ptr->def.physicalType;
+            currentBB->xferPoints[currentBB->num_xfer_points].xtype = XFER_DEF_IS_XMM;
+            currentBB->xferPoints[currentBB->num_xfer_points].vr_gpl = -1;
+            currentBB->xferPoints[currentBB->num_xfer_points].vr_gph = -1;
+            if(hasGpUsageOfL2) currentBB->xferPoints[currentBB->num_xfer_points].vr_gpl = ptr->def.regNum;
+            if(hasGpUsageOfH2) currentBB->xferPoints[currentBB->num_xfer_points].vr_gph = ptr->def.regNum+1;
+            currentBB->xferPoints[currentBB->num_xfer_points].dumpToMem = true;
+            currentBB->xferPoints[currentBB->num_xfer_points].dumpToXmm = false; //not used in updateVirtualReg
+            if(hasAligned) currentBB->xferPoints[currentBB->num_xfer_points].dumpToXmm = true;
+            currentBB->xferPoints[currentBB->num_xfer_points].tableIndex = k;
+#ifdef DEBUG_XFER_POINTS
+            ALOGI("insert XFER %d at def %d: V%d %d", currentBB->num_xfer_points, ptr->def.offsetPC, ptr->def.regNum, defType);
+#endif
+            currentBB->num_xfer_points++;
+            if(currentBB->num_xfer_points >= MAX_XFER_PER_BB) {
+                ALOGE("too many xfer points");
+                dvmAbort();
+            }
+        }
+        ptr = ptr->next;
+    } //while ptr
+#ifdef DEBUG_XFER_POINTS
+    ALOGI("XFER points for current basic block ------");
+    for(k = 0; k < currentBB->num_xfer_points; k++) {
+        ALOGI("  at offset %x, VR %d %d: type %d, vr_gpl %d, vr_gph %d, dumpToMem %d, dumpToXmm %d",
+              currentBB->xferPoints[k].offsetPC, currentBB->xferPoints[k].regNum,
+              currentBB->xferPoints[k].physicalType, currentBB->xferPoints[k].xtype,
+              currentBB->xferPoints[k].vr_gpl, currentBB->xferPoints[k].vr_gph,
+              currentBB->xferPoints[k].dumpToMem, currentBB->xferPoints[k].dumpToXmm);
+    }
+#endif
+    return -1;
+}
+
+//! update memVRTable[].ranges by browsing the defUseTable
+
+//! each virtual register has a list of live ranges, and each live range has a list of PCs that access the VR
+void updateLiveTable() {
+    DefUsePair* ptr = currentBB->defUseTable;
+    while(ptr != NULL) {
+        bool updateUse = false;
+        if(ptr->num_uses == 0) {
+            ptr->num_uses = 1;
+            ptr->uses = (DefOrUseLink*)malloc(sizeof(DefOrUseLink));
+            if(ptr->uses == NULL) {
+                ALOGE("Memory allocation failed");
+                return;
+            }
+            ptr->uses->accessType = REGACCESS_D;
+            ptr->uses->regNum = ptr->def.regNum;
+            ptr->uses->offsetPC = ptr->def.offsetPC;
+            ptr->uses->physicalType = ptr->def.physicalType;
+            ptr->uses->next = NULL;
+            ptr->useTail = ptr->uses;
+            updateUse = true;
+        }
+        DefOrUseLink* ptrUse = ptr->uses;
+        while(ptrUse != NULL) {
+            RegAccessType useType = ptrUse->accessType;
+            if(useType == REGACCESS_L || useType == REGACCESS_D) {
+                int indexL = searchMemTable(ptrUse->regNum);
+                if(indexL >= 0)
+                    mergeLiveRange(indexL, ptr->def.offsetPC,
+                                   ptrUse->offsetPC); //tableIndex, start PC, end PC
+            }
+            if(getRegSize(ptrUse->physicalType) == OpndSize_64 &&
+               (useType == REGACCESS_H || useType == REGACCESS_D)) {
+                int indexH = searchMemTable(ptrUse->regNum+1);
+                if(indexH >= 0)
+                    mergeLiveRange(indexH, ptr->def.offsetPC,
+                                   ptrUse->offsetPC);
+            }
+            ptrUse = ptrUse->next;
+        }//while ptrUse
+        if(updateUse) {
+            ptr->num_uses = 0;
+            free(ptr->uses);
+            ptr->uses = NULL;
+            ptr->useTail = NULL;
+        }
+        ptr = ptr->next;
+    }//while ptr
+#ifdef DEBUG_LIVE_RANGE
+    ALOGI("LIVE TABLE");
+    for(int k = 0; k < num_memory_vr; k++) {
+        ALOGI("VR %d live ", memVRTable[k].regNum);
+        LiveRange* ptr = memVRTable[k].ranges;
+        while(ptr != NULL) {
+            ALOGI("[%x %x] (", ptr->start, ptr->end);
+            for(int k3 = 0; k3 < ptr->num_access; k3++)
+                ALOGI("%x ", ptr->accessPC[k3]);
+            ALOGI(") ");
+            ptr = ptr->next;
+        }
+        ALOGI("");
+    }
+#endif
+}
+
+//!add a live range [rangeStart, rangeEnd] to ranges of memVRTable, merge to existing live ranges if necessary
+
+//!ranges are in increasing order of startPC
+void mergeLiveRange(int tableIndex, int rangeStart, int rangeEnd) {
+    if(rangeStart == PC_FOR_START_OF_BB) rangeStart = currentBB->pc_start;
+    if(rangeEnd == PC_FOR_END_OF_BB) rangeEnd = currentBB->pc_end;
+#ifdef DEBUG_LIVE_RANGE
+    ALOGI("LIVERANGE call mergeLiveRange on tableIndex %d with [%x %x]", tableIndex, rangeStart, rangeEnd);
+#endif
+    int startIndex = -1, endIndex = -1;
+    bool startBeforeRange = false, endBeforeRange = false; //before the index or in the range
+    bool startDone = false, endDone = false;
+    LiveRange* ptr = memVRTable[tableIndex].ranges;
+    LiveRange* ptrStart = NULL;
+    LiveRange* ptrStart_prev = NULL;
+    LiveRange* ptrEnd = NULL;
+    LiveRange* ptrEnd_prev = NULL;
+    int k = 0;
+    while(ptr != NULL) {
+        if(!startDone) {
+            if(ptr->start <= rangeStart &&
+               ptr->end >= rangeStart) {
+                startIndex = k;
+                ptrStart = ptr;
+                startBeforeRange = false;
+                startDone = true;
+            }
+            else if(ptr->start > rangeStart) {
+                startIndex = k;
+                ptrStart = ptr;
+                startBeforeRange = true;
+                startDone = true;
+            }
+        }
+        if(!startDone) ptrStart_prev = ptr;
+        if(!endDone) {
+            if(ptr->start <= rangeEnd &&
+               ptr->end >= rangeEnd) {
+                endIndex = k;
+                ptrEnd = ptr;
+                endBeforeRange = false;
+                endDone = true;
+            }
+            else if(ptr->start > rangeEnd) {
+                endIndex = k;
+                ptrEnd = ptr;
+                endBeforeRange = true;
+                endDone = true;
+            }
+        }
+        if(!endDone) ptrEnd_prev = ptr;
+        ptr = ptr->next;
+        k++;
+    } //while
+    if(!startDone) { //both can be NULL
+        startIndex = memVRTable[tableIndex].num_ranges;
+        ptrStart = NULL; //ptrStart_prev should be the last live range
+        startBeforeRange = true;
+    }
+    //if endDone, ptrEnd is not NULL, ptrEnd_prev can be NULL
+    if(!endDone) { //both can be NULL
+        endIndex = memVRTable[tableIndex].num_ranges;
+        ptrEnd = NULL;
+        endBeforeRange = true;
+    }
+    if(startIndex == endIndex && startBeforeRange && endBeforeRange) { //insert at startIndex
+        //3 cases depending on BeforeRange when startIndex == endIndex
+        //insert only if both true
+        //merge otherwise
+        /////////// insert before ptrStart
+        LiveRange* currRange = (LiveRange *)malloc(sizeof(LiveRange));
+        if(ptrStart_prev == NULL) {
+            currRange->next = memVRTable[tableIndex].ranges;
+            memVRTable[tableIndex].ranges = currRange;
+        } else {
+            currRange->next = ptrStart_prev->next;
+            ptrStart_prev->next = currRange;
+        }
+        currRange->start = rangeStart;
+        currRange->end = rangeEnd;
+        currRange->accessPC = (int *)malloc(sizeof(int) * NUM_ACCESS_IN_LIVERANGE);
+        currRange->num_alloc = NUM_ACCESS_IN_LIVERANGE;
+        if(rangeStart != rangeEnd) {
+            currRange->num_access = 2;
+            currRange->accessPC[0] = rangeStart;
+            currRange->accessPC[1] = rangeEnd;
+        } else {
+            currRange->num_access = 1;
+            currRange->accessPC[0] = rangeStart;
+        }
+        memVRTable[tableIndex].num_ranges++;
+#ifdef DEBUG_LIVE_RANGE
+        ALOGI("LIVERANGE insert one live range [%x %x] to tableIndex %d", rangeStart, rangeEnd, tableIndex);
+#endif
+        return;
+    }
+    if(!endBeforeRange) { //here ptrEnd is not NULL
+        endIndex++; //next
+        ptrEnd_prev = ptrEnd; //ptrEnd_prev is not NULL
+        ptrEnd = ptrEnd->next; //ptrEnd can be NULL
+    }
+    if(endIndex < startIndex+1) ALOGE("mergeLiveRange endIndex %d startIndex %d", endIndex, startIndex);
+    ///////// use ptrStart & ptrEnd_prev
+    if(ptrStart == NULL || ptrEnd_prev == NULL) {
+        ALOGE("mergeLiveRange ptr is NULL");
+        return;
+    }
+    //endIndex > startIndex (merge the ranges between startIndex and endIndex-1)
+    //update ptrStart
+    if(ptrStart->start > rangeStart)
+        ptrStart->start = rangeStart; //min of old start & rangeStart
+    ptrStart->end = ptrEnd_prev->end; //max of old end & rangeEnd
+    if(rangeEnd > ptrStart->end)
+        ptrStart->end = rangeEnd;
+#ifdef DEBUG_LIVE_RANGE
+    ALOGI("LIVERANGE merge entries for tableIndex %d from %d to %d", tableIndex, startIndex+1, endIndex-1);
+#endif
+    if(ptrStart->num_access <= 0) ALOGE("mergeLiveRange number of access");
+#ifdef DEBUG_LIVE_RANGE
+    ALOGI("LIVERANGE tableIndex %d startIndex %d num_access %d (", tableIndex, startIndex, ptrStart->num_access);
+    for(k = 0; k < ptrStart->num_access; k++)
+        ALOGI("%x ", ptrStart->accessPC[k]);
+    ALOGI(")");
+#endif
+    ///// go through pointers from ptrStart->next to ptrEnd
+    //from startIndex+1 to endIndex-1
+    ptr = ptrStart->next;
+    while(ptr != NULL && ptr != ptrEnd) {
+        int k2;
+        for(k2 = 0; k2 < ptr->num_access; k2++) { //merge to startIndex
+            insertAccess(tableIndex, ptrStart, ptr->accessPC[k2]);
+        }//k2
+        ptr = ptr->next;
+    }
+    insertAccess(tableIndex, ptrStart, rangeStart);
+    insertAccess(tableIndex, ptrStart, rangeEnd);
+    //remove startIndex+1 to endIndex-1
+    if(startIndex+1 < endIndex) {
+        ptr = ptrStart->next;
+        while(ptr != NULL && ptr != ptrEnd) {
+            LiveRange* tmpP = ptr->next;
+            free(ptr->accessPC);
+            free(ptr);
+            ptr = tmpP;
+        }
+        ptrStart->next = ptrEnd;
+    }
+    memVRTable[tableIndex].num_ranges -= (endIndex - startIndex - 1);
+#ifdef DEBUG_LIVE_RANGE
+    ALOGI("num_ranges for VR %d: %d", memVRTable[tableIndex].regNum, memVRTable[tableIndex].num_ranges);
+#endif
+}
+//! insert an access to a given live range, in order
+
+//!
+void insertAccess(int tableIndex, LiveRange* startP, int rangeStart) {
+    int k3, k4;
+#ifdef DEBUG_LIVE_RANGE
+    ALOGI("LIVERANGE insertAccess %d %x", tableIndex, rangeStart);
+#endif
+    int insertIndex = -1;
+    for(k3 = 0; k3 < startP->num_access; k3++) {
+        if(startP->accessPC[k3] == rangeStart) {
+            return;
+        }
+        if(startP->accessPC[k3] > rangeStart) {
+            insertIndex = k3;
+            break;
+        }
+    }
+
+    //insert here
+    k3 = insertIndex;
+    if(insertIndex == -1) {
+        k3 = startP->num_access;
+    }
+    if(startP->num_access == startP->num_alloc) {
+        int currentAlloc = startP->num_alloc;
+        startP->num_alloc += NUM_ACCESS_IN_LIVERANGE;
+        int* tmpPtr = (int *)malloc(sizeof(int) * startP->num_alloc);
+        for(k4 = 0; k4 < currentAlloc; k4++)
+            tmpPtr[k4] = startP->accessPC[k4];
+        free(startP->accessPC);
+        startP->accessPC = tmpPtr;
+    }
+    //insert accessPC
+    for(k4 = startP->num_access-1; k4 >= k3; k4--)
+        startP->accessPC[k4+1] = startP->accessPC[k4];
+    startP->accessPC[k3] = rangeStart;
+#ifdef DEBUG_LIVE_RANGE
+    ALOGI("LIVERANGE insert %x to tableIndex %d", rangeStart, tableIndex);
+#endif
+    startP->num_access++;
+    return;
+}
+
+/////////////////////////////////////////////////////////////////////
+bool isInMemory(int regNum, OpndSize size);
+void setVRToMemory(int regNum, OpndSize size);
+bool isVRLive(int vA);
+int getSpillIndex(bool isGLUE, OpndSize size);
+void clearVRToMemory(int regNum, OpndSize size);
+void clearVRNullCheck(int regNum, OpndSize size);
+
+inline int getSpillLocDisp(int offset) {
+#ifdef SPILL_IN_THREAD
+    return offset+offsetof(Thread, spillRegion);;
+#else
+    return offset+offEBP_spill;
+#endif
+}
+#if 0
+/* used if we keep self pointer in a physical register */
+inline int getSpillLocReg(int offset) {
+    return PhysicalReg_Glue;
+}
+#endif
+#ifdef SPILL_IN_THREAD
+inline void loadFromSpillRegion_with_self(OpndSize size, int reg_self, bool selfPhysical, int reg, int offset) {
+    /* only 1 instruction is generated by move_mem_to_reg_noalloc */
+    move_mem_to_reg_noalloc(size,
+                            getSpillLocDisp(offset), reg_self, selfPhysical,
+                            MemoryAccess_SPILL, offset,
+                            reg, true);
+}
+inline void loadFromSpillRegion(OpndSize size, int reg, int offset) {
+    get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+    int reg_self = registerAlloc(LowOpndRegType_scratch, C_SCRATCH_1, isScratchPhysical, false);
+    /* only 1 instruction is generated by move_mem_to_reg_noalloc */
+    move_mem_to_reg_noalloc(size,
+                            getSpillLocDisp(offset), reg_self, true,
+                            MemoryAccess_SPILL, offset,
+                            reg, true);
+}
+inline void saveToSpillRegion_with_self(OpndSize size, int selfReg, bool selfPhysical, int reg, int offset) {
+    move_reg_to_mem_noalloc(size,
+                            reg, true,
+                            getSpillLocDisp(offset), selfReg, selfPhysical,
+                            MemoryAccess_SPILL, offset);
+}
+inline void saveToSpillRegion(OpndSize size, int reg, int offset) {
+    get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+    int reg_self = registerAlloc(LowOpndRegType_scratch, C_SCRATCH_1, isScratchPhysical, false);
+    move_reg_to_mem_noalloc(size,
+                            reg, true,
+                            getSpillLocDisp(offset), reg_self, true,
+                            MemoryAccess_SPILL, offset);
+}
+#else
+inline void loadFromSpillRegion(OpndSize size, int reg, int offset) {
+    /* only 1 instruction is generated by move_mem_to_reg_noalloc */
+    move_mem_to_reg_noalloc(size,
+                            getSpillLocDisp(offset), PhysicalReg_EBP, true,
+                            MemoryAccess_SPILL, offset,
+                            reg, true);
+}
+inline void saveToSpillRegion(OpndSize size, int reg, int offset) {
+    move_reg_to_mem_noalloc(size,
+                            reg, true,
+                            getSpillLocDisp(offset), PhysicalReg_EBP, true,
+                            MemoryAccess_SPILL, offset);
+}
+#endif
+
+//! dump an immediate to memory, set inMemory to true
+
+//!
+void dumpImmToMem(int vrNum, OpndSize size, int value) {
+    if(isInMemory(vrNum, size)) {
+#ifdef DEBUG_SPILL
+        ALOGI("Skip dumpImmToMem vA %d size %d", vrNum, size);
+#endif
+        return;
+    }
+    set_VR_to_imm_noalloc(vrNum, size, value);
+    setVRToMemory(vrNum, size);
+}
+//! dump content of a VR to memory, set inMemory to true
+
+//!
+void dumpToMem(int vrNum, LowOpndRegType type, int regAll) { //ss,gp,xmm
+    if(isInMemory(vrNum, getRegSize(type))) {
+#ifdef DEBUG_SPILL
+        ALOGI("Skip dumpToMem vA %d type %d", vrNum, type);
+#endif
+        return;
+    }
+    if(type == LowOpndRegType_gp || type == LowOpndRegType_xmm)
+        set_virtual_reg_noalloc(vrNum, getRegSize(type), regAll, true);
+    if(type == LowOpndRegType_ss)
+        move_ss_reg_to_mem_noalloc(regAll, true,
+                                   4*vrNum, PhysicalReg_FP, true,
+                                   MemoryAccess_VR, vrNum);
+    setVRToMemory(vrNum, getRegSize(type));
+}
+//! dump part of a 64-bit VR to memory and update inMemory
+
+//! isLow tells whether low half or high half is dumped
+void dumpPartToMem(int reg /*xmm physical reg*/, int vA, bool isLow) {
+    if(isLow) {
+        if(isInMemory(vA, OpndSize_32)) {
+#ifdef DEBUG_SPILL
+            ALOGI("Skip dumpPartToMem isLow %d vA %d", isLow, vA);
+#endif
+            return;
+        }
+    }
+    else {
+        if(isInMemory(vA+1, OpndSize_32)) {
+#ifdef DEBUG_SPILL
+            ALOGI("Skip dumpPartToMem isLow %d vA %d", isLow, vA);
+#endif
+            return;
+        }
+    }
+    if(isLow) {
+        if(!isVRLive(vA)) return;
+    }
+    else {
+        if(!isVRLive(vA+1)) return;
+    }
+    //move part to vA or vA+1
+    if(isLow) {
+        move_ss_reg_to_mem_noalloc(reg, true,
+                                   4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA);
+    } else {
+        int k = getSpillIndex(false, OpndSize_64);
+        //H, L in 4*k+4 & 4*k
+#ifdef SPILL_IN_THREAD
+        get_self_pointer(PhysicalReg_SCRATCH_1, isScratchPhysical);
+        saveToSpillRegion_with_self(OpndSize_64, PhysicalReg_SCRATCH_1, isScratchPhysical, reg, 4*k);
+        //update low 32 bits of xmm reg from 4*k+4
+        move_ss_mem_to_reg(NULL,
+                                   getSpillLocDisp(4*k+4), PhysicalReg_SCRATCH_1, isScratchPhysical,
+                                   reg, true);
+#else
+        saveToSpillRegion(OpndSize_64, reg, 4*k);
+        //update low 32 bits of xmm reg from 4*k+4
+        move_ss_mem_to_reg_noalloc(
+                                   getSpillLocDisp(4*k+4), PhysicalReg_EBP, true,
+                                   MemoryAccess_SPILL, 4*k+4,
+                                   reg, true);
+#endif
+        //move low 32 bits of xmm reg to vA+1
+        move_ss_reg_to_mem_noalloc(reg, true, 4*(vA+1), PhysicalReg_FP, true, MemoryAccess_VR, vA+1);
+    }
+    if(isLow)
+        setVRToMemory(vA, OpndSize_32);
+    else
+        setVRToMemory(vA+1, OpndSize_32);
+}
+void clearVRBoundCheck(int regNum, OpndSize size);
+//! the content of a VR is no longer in memory or in physical register if the latest content of a VR is constant
+
+//! clear nullCheckDone; if another VR is overlapped with the given VR, the content of that VR is no longer in physical register
+void invalidateVRDueToConst(int reg, OpndSize size) {
+    clearVRToMemory(reg, size); //memory content is out-dated
+    clearVRNullCheck(reg, size);
+    clearVRBoundCheck(reg, size);
+    //check reg,gp reg,ss reg,xmm reg-1,xmm
+    //if size is 64: check reg+1,gp|ss reg+1,xmm
+    int index;
+    //if VR is xmm, check whether we need to dump part of VR to memory
+    index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg);
+    if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+        ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_xmm);
+#endif
+        if(size == OpndSize_32)
+            dumpPartToMem(compileTable[index].physicalReg, reg, false); //dump high of xmm to memory
+        compileTable[index].physicalReg = PhysicalReg_Null;
+    }
+    index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg-1);
+    if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+        ALOGI("INVALIDATE virtual reg %d type %d", reg-1, LowOpndRegType_xmm);
+#endif
+        dumpPartToMem(compileTable[index].physicalReg, reg-1, true); //dump low of xmm to memory
+        compileTable[index].physicalReg = PhysicalReg_Null;
+    }
+    index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_gp, reg);
+    if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+        ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_gp);
+#endif
+        compileTable[index].physicalReg = PhysicalReg_Null;
+    }
+    index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_ss, reg);
+    if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+        ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_ss);
+#endif
+        compileTable[index].physicalReg = PhysicalReg_Null;
+    }
+    if(size == OpndSize_64) {
+        index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg+1);
+        if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+            ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_xmm);
+#endif
+            dumpPartToMem(compileTable[index].physicalReg, reg+1, false); //dump high of xmm to memory
+            compileTable[index].physicalReg = PhysicalReg_Null;
+        }
+        index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_gp, reg+1);
+        if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+            ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_gp);
+#endif
+            compileTable[index].physicalReg = PhysicalReg_Null;
+        }
+        index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_ss, reg+1);
+        if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+            ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_ss);
+#endif
+            compileTable[index].physicalReg = PhysicalReg_Null;
+        }
+    }
+}
+//! check which physical registers hold out-dated content if there is a def
+
+//! if another VR is overlapped with the given VR, the content of that VR is no longer in physical register
+//! should we update inMemory?
+void invalidateVR(int reg, LowOpndRegType pType) {
+    //def at fs: content of xmm & gp & ss are out-dated (reg-1,xmm reg,xmm reg+1,xmm) (reg,gp|ss reg+1,gp|ss)
+    //def at xmm: content of misaligned xmm & gp are out-dated (reg-1,xmm reg+1,xmm) (reg,gp|ss reg+1,gp|ss)
+    //def at fs_s: content of xmm & gp are out-dated (reg-1,xmm reg,xmm) (reg,gp|ss)
+    //def at gp:   content of xmm is out-dated (reg-1,xmm reg,xmm) (reg,ss)
+    //def at ss:   content of xmm & gp are out-dated (reg-1,xmm reg,xmm) (reg,gp)
+    int index;
+    if(pType != LowOpndRegType_xmm) { //check xmm @reg
+        index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg);
+        if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+            ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_xmm);
+#endif
+            if(getRegSize(pType) == OpndSize_32)
+                dumpPartToMem(compileTable[index].physicalReg, reg, false); //dump high of xmm to memory
+            compileTable[index].physicalReg = PhysicalReg_Null;
+        }
+    }
+    //check misaligned xmm @ reg-1
+    index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg-1);
+    if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+        ALOGI("INVALIDATE virtual reg %d type %d", reg-1, LowOpndRegType_xmm);
+#endif
+        dumpPartToMem(compileTable[index].physicalReg, reg-1, true); //dump low of xmm to memory
+        compileTable[index].physicalReg = PhysicalReg_Null;
+    }
+    //check misaligned xmm @ reg+1
+    if(pType == LowOpndRegType_xmm || pType == LowOpndRegType_fs) {
+        //check reg+1,xmm
+        index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg+1);
+        if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+            ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_xmm);
+#endif
+            dumpPartToMem(compileTable[index].physicalReg, reg+1, false); //dump high of xmm to memory
+            compileTable[index].physicalReg = PhysicalReg_Null;
+        }
+    }
+    if(pType != LowOpndRegType_gp) {
+        //check reg,gp
+        index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_gp, reg);
+        if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+            ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_gp);
+#endif
+            compileTable[index].physicalReg = PhysicalReg_Null;
+        }
+    }
+    if(pType == LowOpndRegType_xmm || pType == LowOpndRegType_fs) {
+        //check reg+1,gp
+        index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_gp, reg+1);
+        if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+            ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_gp);
+#endif
+            compileTable[index].physicalReg = PhysicalReg_Null;
+        }
+    }
+    if(pType != LowOpndRegType_ss) {
+        //check reg,ss
+        index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_ss, reg);
+        if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+            ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_ss);
+#endif
+            compileTable[index].physicalReg = PhysicalReg_Null;
+        }
+    }
+    if(pType == LowOpndRegType_xmm || pType == LowOpndRegType_fs) {
+        //check reg+1,ss
+        index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_ss, reg+1);
+        if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_INVALIDATE
+            ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_ss);
+#endif
+            compileTable[index].physicalReg = PhysicalReg_Null;
+        }
+    }
+}
+//! bookkeeping when a VR is updated
+
+//! invalidate contents of some physical registers, clear nullCheckDone, and update inMemory;
+//! check whether there exist tranfer points for this bytecode, if yes, perform the transfer
+int updateVirtualReg(int reg, LowOpndRegType pType) {
+    int k;
+    OpndSize size = getRegSize(pType);
+    //WAS only invalidate xmm VRs for the following cases:
+    //if def reaches a use of vA,xmm and (the def is not xmm or is misaligned xmm)
+    //  invalidate "vA,xmm"
+    invalidateVR(reg, pType);
+    clearVRNullCheck(reg, size);
+    clearVRBoundCheck(reg, size);
+    if(pType == LowOpndRegType_fs || pType == LowOpndRegType_fs_s)
+        setVRToMemory(reg, size);
+    else {
+        clearVRToMemory(reg, size);
+    }
+    for(k = 0; k < currentBB->num_xfer_points; k++) {
+        if(currentBB->xferPoints[k].offsetPC == offsetPC &&
+           currentBB->xferPoints[k].regNum == reg &&
+           currentBB->xferPoints[k].physicalType == pType &&
+           currentBB->xferPoints[k].xtype != XFER_MEM_TO_XMM) {
+            //perform the corresponding action for the def
+            PhysicalReg regAll;
+            if(currentBB->xferPoints[k].xtype == XFER_DEF_IS_XMM) {
+                //def at fs: content of xmm is out-dated
+                //def at xmm: content of misaligned xmm is out-dated
+                //invalidateXmmVR(currentBB->xferPoints[k].tableIndex);
+#ifdef DEBUG_XFER_POINTS
+                if(currentBB->xferPoints[k].dumpToXmm) ALOGI("XFER set_virtual_reg to xmm: xmm VR %d", reg);
+#endif
+                if(pType == LowOpndRegType_xmm)  {
+#ifdef DEBUG_XFER_POINTS
+                    ALOGI("XFER set_virtual_reg to memory: xmm VR %d", reg);
+#endif
+                    PhysicalReg regAll = (PhysicalReg)checkVirtualReg(reg, LowOpndRegType_xmm, 0 /* do not update*/);
+                    dumpToMem(reg, LowOpndRegType_xmm, regAll);
+                }
+                if(currentBB->xferPoints[k].vr_gpl >= 0) { //
+                }
+                if(currentBB->xferPoints[k].vr_gph >= 0) {
+                }
+            }
+            if((pType == LowOpndRegType_gp || pType == LowOpndRegType_ss) &&
+               (currentBB->xferPoints[k].xtype == XFER_DEF_TO_MEM ||
+                currentBB->xferPoints[k].xtype == XFER_DEF_TO_GP_MEM)) {
+                //the defined gp VR already in register
+                //invalidateXmmVR(currentBB->xferPoints[k].tableIndex);
+                regAll = (PhysicalReg)checkVirtualReg(reg, pType, 0 /* do not update*/);
+                dumpToMem(reg, pType, regAll);
+#ifdef DEBUG_XFER_POINTS
+                ALOGI("XFER set_virtual_reg to memory: gp VR %d", reg);
+#endif
+            }
+            if((pType == LowOpndRegType_fs_s || pType == LowOpndRegType_ss) &&
+               currentBB->xferPoints[k].xtype == XFER_DEF_TO_GP_MEM) {
+            }
+        }
+    }
+    return -1;
+}
+////////////////////////////////////////////////////////////////
+//REGISTER ALLOCATION
+int spillForHardReg(int regNum, int type);
+void decreaseRefCount(int index);
+int getFreeReg(int type, int reg, int indexToCompileTable);
+PhysicalReg spillForLogicalReg(int type, int reg, int indexToCompileTable);
+int unspillLogicalReg(int spill_index, int physicalReg);
+int searchVirtualInfoOfBB(LowOpndRegType type, int regNum, BasicBlock_O1* bb);
+bool isTemp8Bit(int type, int reg);
+bool matchType(int typeA, int typeB);
+int getNextAccess(int compileIndex);
+void dumpCompileTable();
+
+//! allocate a register for a variable
+
+//!if no physical register is free, call spillForLogicalReg to free up a physical register;
+//!if the variable is a temporary and it was spilled, call unspillLogicalReg to load from spill location to the allocated physical register;
+//!if updateRefCount is true, reduce reference count of the variable by 1
+int registerAlloc(int type, int reg, bool isPhysical, bool updateRefCount) {
+#ifdef DEBUG_REGALLOC
+    ALOGI("%p: try to allocate register %d type %d isPhysical %d", currentBB, reg, type, isPhysical);
+#endif
+    if(currentBB == NULL) {
+        if(type & LowOpndRegType_virtual) return PhysicalReg_Null;
+        if(isPhysical) return reg; //for helper functions
+        return PhysicalReg_Null;
+    }
+    //ignore EDI, ESP, EBP (glue)
+    if(isPhysical && (reg == PhysicalReg_EDI || reg == PhysicalReg_ESP ||
+                      reg == PhysicalReg_EBP || reg == PhysicalReg_Null))
+        return reg;
+
+    int newType = convertType(type, reg, isPhysical);
+    if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1;
+    int tIndex = searchCompileTable(newType, reg);
+    if(tIndex < 0) {
+      ALOGE("reg %d type %d not found in registerAlloc", reg, newType);
+      return PhysicalReg_Null;
+    }
+
+    //physical register
+    if(isPhysical) {
+        if(allRegs[reg].isUsed) { //if used by a non hard-coded register
+            spillForHardReg(reg, newType);
+        }
+        allRegs[reg].isUsed = true;
+#ifdef DEBUG_REG_USED
+        ALOGI("REGALLOC: allocate a reg %d", reg);
+#endif
+        compileTable[tIndex].physicalReg = reg;
+        if(updateRefCount)
+            decreaseRefCount(tIndex);
+#ifdef DEBUG_REGALLOC
+        ALOGI("REGALLOC: allocate register %d for logical register %d %d",
+               compileTable[tIndex].physicalReg, reg, newType);
+#endif
+        return reg;
+    }
+    //already allocated
+    if(compileTable[tIndex].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_REGALLOC
+        ALOGI("already allocated to physical register %d", compileTable[tIndex].physicalReg);
+#endif
+        if(updateRefCount)
+            decreaseRefCount(tIndex);
+        return compileTable[tIndex].physicalReg;
+    }
+
+    //at this point, the logical register is not hard-coded and is mapped to Reg_Null
+    //first check whether there is a free reg
+    //if not, call spillForLogicalReg
+    int index = getFreeReg(newType, reg, tIndex);
+    if(index >= 0 && index < PhysicalReg_Null) {
+        //update compileTable & allRegs
+        compileTable[tIndex].physicalReg = allRegs[index].physicalReg;
+        allRegs[index].isUsed = true;
+#ifdef DEBUG_REG_USED
+        ALOGI("REGALLOC: register %d is free", allRegs[index].physicalReg);
+#endif
+    } else {
+        PhysicalReg allocR = spillForLogicalReg(newType, reg, tIndex);
+        compileTable[tIndex].physicalReg = allocR;
+    }
+    if(compileTable[tIndex].spill_loc_index >= 0) {
+        unspillLogicalReg(tIndex, compileTable[tIndex].physicalReg);
+    }
+    if(updateRefCount)
+        decreaseRefCount(tIndex);
+#ifdef DEBUG_REGALLOC
+    ALOGI("REGALLOC: allocate register %d for logical register %d %d",
+           compileTable[tIndex].physicalReg, reg, newType);
+#endif
+    return compileTable[tIndex].physicalReg;
+}
+//!a variable will use a physical register allocated for another variable
+
+//!This is used when MOVE_OPT is on, it tries to alias a virtual register with a temporary to remove a move
+int registerAllocMove(int reg, int type, bool isPhysical, int srcReg) {
+    if(srcReg == PhysicalReg_EDI || srcReg == PhysicalReg_ESP || srcReg == PhysicalReg_EBP)
+        ALOGE("can't move from srcReg EDI or ESP or EBP");
+#ifdef DEBUG_REGALLOC
+    ALOGI("in registerAllocMove: reg %d type %d srcReg %d", reg, type, srcReg);
+#endif
+    int newType = convertType(type, reg, isPhysical);
+    if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1;
+    int index = searchCompileTable(newType, reg);
+    if(index < 0) {
+        ALOGE("reg %d type %d not found in registerAllocMove", reg, newType);
+        return -1;
+    }
+
+    decreaseRefCount(index);
+    compileTable[index].physicalReg = srcReg;
+#ifdef DEBUG_REGALLOC
+    ALOGI("REGALLOC: registerAllocMove %d for logical register %d %d",
+           compileTable[index].physicalReg, reg, newType);
+#endif
+    return srcReg;
+}
+
+//! check whether a physical register is available to be used by a variable
+
+//! data structures accessed:
+//! 1> currentBB->infoBasicBlock[index].allocConstraintsSorted
+//!    sorted from high count to low count
+//! 2> currentBB->allocConstraintsSorted
+//!    sorted from low count to high count
+//! 3> allRegs: whether a physical register is available, indexed by PhysicalReg
+//! NOTE: if a temporary variable is 8-bit, only %eax, %ebx, %ecx, %edx can be used
+int getFreeReg(int type, int reg, int indexToCompileTable) {
+    syncAllRegs();
+    /* handles requests for xmm or ss registers */
+    int k;
+    if(((type & MASK_FOR_TYPE) == LowOpndRegType_xmm) ||
+       ((type & MASK_FOR_TYPE) == LowOpndRegType_ss)) {
+        for(k = PhysicalReg_XMM0; k <= PhysicalReg_XMM7; k++) {
+            if(!allRegs[k].isUsed) return k;
+        }
+        return -1;
+    }
+#ifdef DEBUG_REGALLOC
+    ALOGI("USED registers: ");
+    for(k = 0; k < 8; k++)
+        ALOGI("%d used: %d time freed: %d callee-saveld: %d", k, allRegs[k].isUsed,
+             allRegs[k].freeTimeStamp, allRegs[k].isCalleeSaved);
+    ALOGI("");
+#endif
+
+    /* a VR is requesting a physical register */
+    if(isVirtualReg(type)) { //find a callee-saved register
+        /* if VR is type GG, check the pre-allocated physical register first */
+        bool isGGVR = compileTable[indexToCompileTable].gType == GLOBALTYPE_GG;
+        if(isGGVR) {
+            int regCandidateT = compileTable[indexToCompileTable].physicalReg_prev;
+            if(!allRegs[regCandidateT].isUsed) return regCandidateT;
+        }
+
+        int index = searchVirtualInfoOfBB((LowOpndRegType)(type&MASK_FOR_TYPE), reg, currentBB);
+        if(index < 0) {
+            ALOGE("VR %d %d not found in infoBasicBlock of currentBB %d (num of VRs %d)",
+                  reg, type, currentBB->bb_index, currentBB->num_regs);
+            dvmAbort();
+        }
+
+        /* check allocConstraints for this VR,
+           return an available physical register with the highest constraint > 0 */
+        for(k = 0; k < 8; k++) {
+            if(currentBB->infoBasicBlock[index].allocConstraintsSorted[k].count == 0) break;
+            int regCandidateT = currentBB->infoBasicBlock[index].allocConstraintsSorted[k].physicalReg;
+            assert(regCandidateT < PhysicalReg_Null);
+            if(!allRegs[regCandidateT].isUsed) return regCandidateT;
+        }
+
+        /* WAS: return an available physical register with the lowest constraint
+           NOW: consider a new factor (freeTime) when there is a tie
+                if 2 available physical registers have the same number of constraints
+                choose the one with smaller free time stamp */
+        int currentCount = -1;
+        int index1 = -1;
+        int smallestTime = -1;
+        for(k = 0; k < 8; k++) {
+            int regCandidateT = currentBB->allocConstraintsSorted[k].physicalReg;
+            assert(regCandidateT < PhysicalReg_Null);
+            if(index1 >= 0 && currentBB->allocConstraintsSorted[k].count > currentCount)
+                break; //candidate has higher count than index1
+            if(!allRegs[regCandidateT].isUsed) {
+                if(index1 < 0) {
+                    index1 = k;
+                    currentCount = currentBB->allocConstraintsSorted[k].count;
+                    smallestTime = allRegs[regCandidateT].freeTimeStamp;
+                } else if(allRegs[regCandidateT].freeTimeStamp < smallestTime) {
+                    index1 = k;
+                    smallestTime = allRegs[regCandidateT].freeTimeStamp;
+                }
+            }
+        }
+        if(index1 >= 0) return currentBB->allocConstraintsSorted[index1].physicalReg;
+        return -1;
+    }
+    /* handle request from a temporary variable or a glue variable */
+    else {
+        bool is8Bit = isTemp8Bit(type, reg);
+
+        /* if the temporary variable is linked to a VR and
+              the VR is not yet allocated to any physical register */
+        int vr_num = compileTable[indexToCompileTable].linkageToVR;
+        if(vr_num >= 0) {
+            int index3 = searchCompileTable(LowOpndRegType_gp | LowOpndRegType_virtual, vr_num);
+            if(index3 < 0) {
+                ALOGE("2 in tracing linkage to VR %d", vr_num);
+                dvmAbort();
+            }
+
+            if(compileTable[index3].physicalReg == PhysicalReg_Null) {
+                int index2 = searchVirtualInfoOfBB(LowOpndRegType_gp, vr_num, currentBB);
+                if(index2 < 0) {
+                    ALOGE("1 in tracing linkage to VR %d", vr_num);
+                    dvmAbort();
+                }
+#ifdef DEBUG_REGALLOC
+                ALOGI("in getFreeReg for temporary reg %d, trace the linkage to VR %d",
+                     reg, vr_num);
+#endif
+
+                /* check allocConstraints on the VR
+                   return an available physical register with the highest constraint > 0
+                */
+                for(k = 0; k < 8; k++) {
+                    if(currentBB->infoBasicBlock[index2].allocConstraintsSorted[k].count == 0) break;
+                    int regCandidateT = currentBB->infoBasicBlock[index2].allocConstraintsSorted[k].physicalReg;
+#ifdef DEBUG_REGALLOC
+                    ALOGI("check register %d with count %d", regCandidateT,
+                          currentBB->infoBasicBlock[index2].allocConstraintsSorted[k].count);
+#endif
+                    /* if the requesting variable is 8 bit */
+                    if(is8Bit && regCandidateT > PhysicalReg_EDX) continue;
+                    assert(regCandidateT < PhysicalReg_Null);
+                    if(!allRegs[regCandidateT].isUsed) return regCandidateT;
+                }
+            }
+        }
+        /* check allocConstraints of the basic block
+           if 2 available physical registers have the same constraint count,
+              return the non callee-saved physical reg */
+        /* enhancement: record the time when a register is freed (freeTimeStamp)
+                        the purpose is to reduce false dependency
+           priority: constraint count, non callee-saved, time freed
+               let x be the lowest constraint count
+               set A be available callee-saved physical registers with count == x
+               set B be available non callee-saved physical registers with count == x
+               if set B is not null, return the one with smallest free time
+               otherwise, return the one in A with smallest free time
+           To ignore whether it is callee-saved, add all candidates to set A
+        */
+        int setAIndex[8];
+        int num_A = 0;
+        int setBIndex[8];
+        int num_B = 0;
+        int index1 = -1; //points to an available physical reg with lowest count
+        int currentCount = -1;
+        for(k = 0; k < 8; k++) {
+            int regCandidateT = currentBB->allocConstraintsSorted[k].physicalReg;
+            if(is8Bit && regCandidateT > PhysicalReg_EDX) continue;
+
+            if(index1 >= 0 && currentBB->allocConstraintsSorted[k].count > currentCount)
+                break; //candidate has higher count than index1
+            assert(regCandidateT < PhysicalReg_Null);
+            if(!allRegs[regCandidateT].isUsed) {
+                /*To ignore whether it is callee-saved, add all candidates to set A */
+                if(false) {//!allRegs[regCandidateT].isCalleeSaved) { //add to set B
+                    setBIndex[num_B++] = k;
+                } else { //add to set A
+                    setAIndex[num_A++] = k;
+                }
+                if(index1 < 0) {
+                    /* index1 points to a physical reg with lowest count */
+                    index1 = k;
+                    currentCount = currentBB->allocConstraintsSorted[k].count;
+                }
+            }
+        }
+
+        int kk;
+        int smallestTime = -1;
+        index1 = -1;
+        for(kk = 0; kk < num_B; kk++) {
+            k = setBIndex[kk];
+            int regCandidateT = currentBB->allocConstraintsSorted[k].physicalReg;
+            assert(regCandidateT < PhysicalReg_Null);
+            if(kk == 0 || allRegs[regCandidateT].freeTimeStamp < smallestTime) {
+                index1 = k;
+                smallestTime = allRegs[regCandidateT].freeTimeStamp;
+            }
+        }
+        if(index1 >= 0)
+            return currentBB->allocConstraintsSorted[index1].physicalReg;
+        index1 = -1;
+        for(kk = 0; kk < num_A; kk++) {
+            k = setAIndex[kk];
+            int regCandidateT = currentBB->allocConstraintsSorted[k].physicalReg;
+            if(kk == 0 || allRegs[regCandidateT].freeTimeStamp < smallestTime) {
+                index1 = k;
+                smallestTime = allRegs[regCandidateT].freeTimeStamp;
+            }
+        }
+        if(index1 >= 0) return currentBB->allocConstraintsSorted[index1].physicalReg;
+        return -1;
+    }
+    return -1;
+}
+
+//! find a candidate physical register for a variable and spill all variables that are mapped to the candidate
+
+//!
+PhysicalReg spillForLogicalReg(int type, int reg, int indexToCompileTable) {
+    //choose a used register to spill
+    //when a GG virtual register is spilled, write it to interpretd stack, set physicalReg to Null
+    //  at end of the basic block, load spilled GG VR to physical reg
+    //when other types of VR is spilled, write it to interpreted stack, set physicalReg to Null
+    //when a temporary (non-virtual) register is spilled, write it to stack, set physicalReg to Null
+    //can we spill a hard-coded temporary register? YES
+    int k, k2;
+    PhysicalReg allocR;
+
+    //do not try to free a physical reg that is used by more than one logical registers
+    //fix on sep 28, 2009
+    //do not try to spill a hard-coded logical register
+    //do not try to free a physical reg that is outside of the range for 8-bit logical reg
+    /* for each physical register,
+       collect number of non-hardcode entries that are mapped to the physical register */
+    int numOfUses[PhysicalReg_Null];
+    for(k = PhysicalReg_EAX; k < PhysicalReg_Null; k++)
+        numOfUses[k] = 0;
+    for(k = 0; k < num_compile_entries; k++) {
+        if((compileTable[k].physicalReg != PhysicalReg_Null) &&
+           matchType(type, compileTable[k].physicalType) &&
+           (compileTable[k].physicalType & LowOpndRegType_hard) == 0) {
+            numOfUses[compileTable[k].physicalReg]++;
+        }
+    }
+
+    /* candidates: all non-hardcode entries that are mapped to
+           a physical register that is used by only one entry*/
+    bool is8Bit = isTemp8Bit(type, reg);
+    int candidates[COMPILE_TABLE_SIZE];
+    int num_cand = 0;
+    for(k = 0; k < num_compile_entries; k++) {
+        if(matchType(type, compileTable[k].physicalType) &&
+           compileTable[k].physicalReg != PhysicalReg_Null) {
+            if(is8Bit && compileTable[k].physicalReg > PhysicalReg_EDX) continue; //not a candidate
+            if(!canSpillReg[compileTable[k].physicalReg]) continue; //not a candidate
+            if((compileTable[k].physicalType & LowOpndRegType_hard) == 0 &&
+               numOfUses[compileTable[k].physicalReg] <= 1) {
+                candidates[num_cand++] = k;
+            }
+        }
+    }
+
+    /* go through all candidates:
+       first check GLUE-related entries */
+    int spill_index = -1;
+    for(k2 = 0; k2 < num_cand; k2++) {
+        k = candidates[k2];
+        if((compileTable[k].physicalReg != PhysicalReg_Null) &&
+           matchType(type, compileTable[k].physicalType) &&
+           (compileTable[k].regNum >= PhysicalReg_GLUE_DVMDEX &&
+            compileTable[k].regNum != PhysicalReg_GLUE)) {
+            allocR = (PhysicalReg)spillLogicalReg(k, true);
+#ifdef DEBUG_REGALLOC
+            ALOGI("SPILL register used by num %d type %d it is a GLUE register with refCount %d",
+                  compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].refCount);
+#endif
+            return allocR;
+        }
+    }
+
+    /* out of the candates, find a VR that has the furthest next use */
+    int furthestUse = offsetPC;
+    for(k2 = 0; k2 < num_cand; k2++) {
+        k = candidates[k2];
+        if((compileTable[k].physicalReg != PhysicalReg_Null) &&
+           matchType(type, compileTable[k].physicalType) &&
+           isVirtualReg(compileTable[k].physicalType)) {
+            int nextUse = getNextAccess(k);
+            if(spill_index < 0 || nextUse > furthestUse) {
+                spill_index = k;
+                furthestUse = nextUse;
+            }
+        }
+    }
+
+    /* spill the VR with the furthest next use */
+    if(spill_index >= 0) {
+        allocR = (PhysicalReg)spillLogicalReg(spill_index, true);
+        return allocR; //the register is still being used
+    }
+
+    /* spill an entry with the smallest refCount */
+    int baseLeftOver = 0;
+    int index = -1;
+    for(k2 = 0; k2 < num_cand; k2++) {
+        k = candidates[k2];
+        if(k != indexForGlue &&
+           (compileTable[k].physicalReg != PhysicalReg_Null) &&
+           (compileTable[k].physicalType & LowOpndRegType_hard) == 0 && //not hard-coded
+           matchType(type, compileTable[k].physicalType)) {
+            if((index < 0) || (compileTable[k].refCount < baseLeftOver)) {
+                baseLeftOver = compileTable[k].refCount;
+                index = k;
+            }
+        }
+    }
+    if(index < 0) {
+        dumpCompileTable();
+        ALOGE("no register to spill for logical %d %d", reg, type);
+        dvmAbort();
+    }
+    allocR = (PhysicalReg)spillLogicalReg(index, true);
+#ifdef DEBUG_REGALLOC
+    ALOGI("SPILL register used by num %d type %d it is a temporary register with refCount %d",
+           compileTable[index].regNum, compileTable[index].physicalType, compileTable[index].refCount);
+#endif
+    return allocR;
+}
+//!spill a variable to memory, the variable is specified by an index to compileTable
+
+//!If the variable is a temporary, get a spill location that is not in use and spill the content to the spill location;
+//!If updateTable is true, set physicalReg to Null;
+//!Return the physical register that was allocated to the variable
+int spillLogicalReg(int spill_index, bool updateTable) {
+    if((compileTable[spill_index].physicalType & LowOpndRegType_hard) != 0) {
+        ALOGE("can't spill a hard-coded register");
+        dvmAbort();
+    }
+    int physicalReg = compileTable[spill_index].physicalReg;
+    if(!canSpillReg[physicalReg]) {
+#ifdef PRINT_WARNING
+        ALOGW("can't spill register %d", physicalReg);
+#endif
+        //dvmAbort(); //this happens in get_virtual_reg where VR is allocated to the same reg as the hardcoded temporary
+    }
+    if(isVirtualReg(compileTable[spill_index].physicalType)) {
+        //spill back to memory
+        dumpToMem(compileTable[spill_index].regNum,
+                  (LowOpndRegType)(compileTable[spill_index].physicalType&MASK_FOR_TYPE),
+                  compileTable[spill_index].physicalReg);
+    }
+    else {
+        //update spill_loc_index
+        int k = getSpillIndex(spill_index == indexForGlue,
+                    getRegSize(compileTable[spill_index].physicalType));
+        compileTable[spill_index].spill_loc_index = 4*k;
+        if(k >= 0)
+            spillIndexUsed[k] = 1;
+        saveToSpillRegion(getRegSize(compileTable[spill_index].physicalType),
+                          compileTable[spill_index].physicalReg, 4*k);
+    }
+    //compileTable[spill_index].physicalReg_prev = compileTable[spill_index].physicalReg;
+#ifdef DEBUG_REGALLOC
+    ALOGI("REGALLOC: SPILL logical reg %d %d with refCount %d allocated to %d",
+           compileTable[spill_index].regNum,
+           compileTable[spill_index].physicalType, compileTable[spill_index].refCount,
+           compileTable[spill_index].physicalReg);
+#endif
+    if(!updateTable) return PhysicalReg_Null;
+
+    int allocR = compileTable[spill_index].physicalReg;
+    compileTable[spill_index].physicalReg = PhysicalReg_Null;
+    return allocR;
+}
+//! load a varible from memory to physical register, the variable is specified with an index to compileTable
+
+//!If the variable is a temporary, load from spill location and set the flag for the spill location to not used
+int unspillLogicalReg(int spill_index, int physicalReg) {
+    //can't un-spill to %eax in afterCall!!!
+    //what if GG VR is allocated to %eax!!!
+    if(isVirtualReg(compileTable[spill_index].physicalType)) {
+        get_virtual_reg_noalloc(compileTable[spill_index].regNum,
+                                getRegSize(compileTable[spill_index].physicalType),
+                                physicalReg, true);
+    }
+    else {
+        loadFromSpillRegion(getRegSize(compileTable[spill_index].physicalType),
+                            physicalReg, compileTable[spill_index].spill_loc_index);
+        spillIndexUsed[compileTable[spill_index].spill_loc_index >> 2] = 0;
+        compileTable[spill_index].spill_loc_index = -1;
+    }
+#ifdef DEBUG_REGALLOC
+    ALOGI("REGALLOC: UNSPILL logical reg %d %d with refCount %d", compileTable[spill_index].regNum,
+           compileTable[spill_index].physicalType, compileTable[spill_index].refCount);
+#endif
+    return PhysicalReg_Null;
+}
+
+//!spill a virtual register to memory
+
+//!if the current value of a VR is constant, write immediate to memory;
+//!if the current value of a VR is in a physical register, call spillLogicalReg to dump content of the physical register to memory;
+//!ifupdateTable is true, set the physical register for VR to Null and decrease reference count of the virtual register
+int spillVirtualReg(int vrNum, LowOpndRegType type, bool updateTable) {
+    int index = searchCompileTable(type | LowOpndRegType_virtual, vrNum);
+    if(index < 0) {
+        ALOGE("can't find VR %d %d in spillVirtualReg", vrNum, type);
+        return -1;
+    }
+    //check whether it is const
+    int value[2];
+    int isConst = isVirtualRegConstant(vrNum, type, value, false); //do not update refCount
+    if(isConst == 1 || isConst == 3) {
+        dumpImmToMem(vrNum, OpndSize_32, value[0]);
+    }
+    if(getRegSize(type) == OpndSize_64 && (isConst == 2 || isConst == 3)) {
+        dumpImmToMem(vrNum+1, OpndSize_32, value[1]);
+    }
+    if(isConst != 3 && compileTable[index].physicalReg != PhysicalReg_Null)
+        spillLogicalReg(index, updateTable);
+    if(updateTable) decreaseRefCount(index);
+    return -1;
+}
+
+//! spill variables that are mapped to physical register (regNum)
+
+//!
+int spillForHardReg(int regNum, int type) {
+    //find an entry that uses the physical register
+    int spill_index = -1;
+    int k;
+    for(k = 0; k < num_compile_entries; k++) {
+        if(k != indexForGlue &&
+           compileTable[k].physicalReg == regNum &&
+           matchType(type, compileTable[k].physicalType)) {
+            spill_index = k;
+            if(compileTable[k].regNum == regNum && compileTable[k].physicalType == type)
+                continue;
+            if(inGetVR_num >= 0 && compileTable[k].regNum == inGetVR_num && compileTable[k].physicalType == (type | LowOpndRegType_virtual))
+                continue;
+#ifdef DEBUG_REGALLOC
+            ALOGI("SPILL logical reg %d %d to free hard-coded reg %d %d",
+                   compileTable[spill_index].regNum, compileTable[spill_index].physicalType,
+                   regNum, type);
+            if(compileTable[spill_index].physicalType & LowOpndRegType_hard) dumpCompileTable();
+#endif
+            assert(spill_index < COMPILE_TABLE_SIZE);
+            spillLogicalReg(spill_index, true);
+        }
+    }
+    return regNum;
+}
+////////////////////////////////////////////////////////////////
+//! update allocConstraints of the current basic block
+
+//! allocConstraints specify how many times a hardcoded register is used in this basic block
+void updateCurrentBBWithConstraints(PhysicalReg reg) {
+    if(reg > PhysicalReg_EBP) {
+        ALOGE("register %d out of range in updateCurrentBBWithConstraints", reg);
+    }
+    currentBB->allocConstraints[reg].count++;
+}
+//! sort allocConstraints and save the result in allocConstraintsSorted
+
+//! allocConstraints specify how many times a virtual register is linked to a hardcode register
+//! it is updated in getVirtualRegInfo and merged by mergeEntry2
+int sortAllocConstraint(RegAllocConstraint* allocConstraints,
+                        RegAllocConstraint* allocConstraintsSorted, bool fromHighToLow) {
+    int ii, jj;
+    int num_sorted = 0;
+    for(jj = 0; jj < 8; jj++) {
+        //figure out where to insert allocConstraints[jj]
+        int count = allocConstraints[jj].count;
+        int regT = allocConstraints[jj].physicalReg;
+        assert(regT < PhysicalReg_Null);
+        int insertIndex = -1;
+        for(ii = 0; ii < num_sorted; ii++) {
+            int regT2 = allocConstraintsSorted[ii].physicalReg;
+            assert(regT2 < PhysicalReg_Null);
+            if(allRegs[regT].isCalleeSaved &&
+               count == allocConstraintsSorted[ii].count) {
+                insertIndex = ii;
+                break;
+            }
+            if((!allRegs[regT].isCalleeSaved) &&
+               count == allocConstraintsSorted[ii].count &&
+               (!allRegs[regT2].isCalleeSaved)) { //skip until found one that is not callee-saved
+                insertIndex = ii;
+                break;
+            }
+            if((fromHighToLow && count > allocConstraintsSorted[ii].count) ||
+               ((!fromHighToLow) && count < allocConstraintsSorted[ii].count)) {
+                insertIndex = ii;
+                break;
+            }
+        }
+        if(insertIndex < 0) {
+            allocConstraintsSorted[num_sorted].physicalReg = (PhysicalReg)regT;
+            allocConstraintsSorted[num_sorted].count = count;
+            num_sorted++;
+        } else {
+            for(ii = num_sorted-1; ii >= insertIndex; ii--) {
+                allocConstraintsSorted[ii+1] = allocConstraintsSorted[ii];
+            }
+            allocConstraintsSorted[insertIndex] = allocConstraints[jj];
+            num_sorted++;
+        }
+    } //for jj
+#ifdef DEBUG_ALLOC_CONSTRAINT
+    for(jj = 0; jj < 8; jj++) {
+        if(allocConstraintsSorted[jj].count > 0)
+            ALOGI("%d: register %d has count %d", jj, allocConstraintsSorted[jj].physicalReg, allocConstraintsSorted[jj].count);
+    }
+#endif
+    return 0;
+}
+//! find the entry for a given virtual register in compileTable
+
+//!
+int findVirtualRegInTable(u2 vA, LowOpndRegType type, bool printError) {
+    int k = searchCompileTable(type | LowOpndRegType_virtual, vA);
+    if(k < 0 && printError) {
+        ALOGE("findVirtualRegInTable virtual register %d type %d", vA, type);
+        dvmAbort();
+    }
+    return k;
+}
+
+//! check whether a virtual register is constant
+
+//! the value of the constant is stored in valuePtr; if updateRefCount is true & the VR is constant, reference count for the VR will be reduced by 1
+int isVirtualRegConstant(int regNum, LowOpndRegType type, int* valuePtr, bool updateRefCount) {
+
+    OpndSize size = getRegSize(type);
+    int k;
+    int indexL = -1;
+    int indexH = -1;
+    for(k = 0; k < num_const_vr; k++) {
+#ifdef DEBUG_CONST
+        ALOGI("constVRTable VR %d isConst %d value %x", constVRTable[k].regNum, constVRTable[k].isConst, constVRTable[k].value);
+#endif
+        if(constVRTable[k].regNum == regNum) {
+            indexL = k;
+            continue;
+        }
+        if(constVRTable[k].regNum == regNum + 1 && size == OpndSize_64) {
+            indexH = k;
+            continue;
+        }
+    }
+    bool isConstL = false;
+    bool isConstH = false;
+    if(indexL >= 0) {
+        isConstL = constVRTable[indexL].isConst;
+    }
+    if(size == OpndSize_64 && indexH >= 0) {
+        isConstH = constVRTable[indexH].isConst;
+    }
+
+    if((isConstL || isConstH)) {
+        if(size == OpndSize_64 && isConstH)
+            valuePtr[1] = constVRTable[indexH].value;
+        if(isConstL)
+            *valuePtr = constVRTable[indexL].value;
+    }
+    if((isConstL && size == OpndSize_32) || (isConstL && isConstH)) {
+        if(updateRefCount) {
+            int indexOrig = searchCompileTable(type | LowOpndRegType_virtual, regNum);
+            if(indexOrig < 0) ALOGE("can't find VR in isVirtualRegConstant num %d type %d", regNum, type);
+            decreaseRefCount(indexOrig);
+        }
+#ifdef DEBUG_CONST
+        ALOGI("VR %d %d is const case", regNum, type);
+#endif
+        return 3;
+    }
+    if(size == OpndSize_32) return 0;
+    if(isConstL) return 1;
+    if(isConstH) return 2;
+    return 0;
+}
+
+//!update RegAccessType of virtual register vB given RegAccessType of vA
+
+//!RegAccessType can be D, L, H
+//!D means full definition, L means only lower-half is defined, H means only higher half is defined
+//!we say a VR has no exposed usage in a basic block if the accessType is D or DU
+//!we say a VR has exposed usage in a basic block if the accessType is not D nor DU
+//!we say a VR has exposed usage in other basic blocks (hasOtherExposedUsage) if
+//!  there exists another basic block where VR has exposed usage in that basic block
+//!A can be U, D, L, H, UD, UL, UH, DU, LU, HU (merged result)
+//!B can be U, D, UD, DU (an entry for the current bytecode)
+//!input isAPartiallyOverlapB can be any value between -1 to 6
+//!if A is xmm: gp B lower half of A, (isAPartiallyOverlapB is 1)
+//!             gp B higher half of A, (isAPartiallyOverlapB is 2)
+//!             lower half of A covers the higher half of xmm B  (isAPartiallyOverlapB is 4)
+//!             higher half of A covers the lower half of xmm B   (isAPartiallyOverlapB is 3)
+//!if A is gp:  A covers the lower half of xmm B, (isAPartiallyOverlapB is 5)
+//!             A covers the higher half of xmm B (isAPartiallyOverlapB is 6)
+RegAccessType updateAccess1(RegAccessType A, OverlapCase isAPartiallyOverlapB) {
+    if(A == REGACCESS_D || A == REGACCESS_DU || A == REGACCESS_UD) {
+        if(isAPartiallyOverlapB == OVERLAP_ALIGN) return REGACCESS_D;
+        if(isAPartiallyOverlapB == OVERLAP_B_IS_LOW_OF_A || isAPartiallyOverlapB == OVERLAP_B_IS_HIGH_OF_A)
+            return REGACCESS_D;
+        if(isAPartiallyOverlapB == OVERLAP_LOW_OF_A_IS_HIGH_OF_B || isAPartiallyOverlapB == OVERLAP_A_IS_LOW_OF_B)
+            return REGACCESS_L;
+        return REGACCESS_H;
+    }
+    if(A == REGACCESS_L || A == REGACCESS_LU || A == REGACCESS_UL) {
+        if(isAPartiallyOverlapB == OVERLAP_ALIGN || isAPartiallyOverlapB == OVERLAP_A_IS_LOW_OF_B)
+            return REGACCESS_L;
+        if(isAPartiallyOverlapB == OVERLAP_B_IS_LOW_OF_A) return REGACCESS_D;
+        if(isAPartiallyOverlapB == OVERLAP_B_IS_HIGH_OF_A || isAPartiallyOverlapB == OVERLAP_LOW_OF_A_IS_HIGH_OF_B)
+            return REGACCESS_N;
+        if(isAPartiallyOverlapB == OVERLAP_HIGH_OF_A_IS_LOW_OF_B || isAPartiallyOverlapB == OVERLAP_A_IS_HIGH_OF_B)
+            return REGACCESS_H;
+    }
+    if(A == REGACCESS_H || A == REGACCESS_HU || A == REGACCESS_UH) {
+        if(isAPartiallyOverlapB == OVERLAP_ALIGN || isAPartiallyOverlapB == OVERLAP_A_IS_HIGH_OF_B)
+            return REGACCESS_H;
+        if(isAPartiallyOverlapB == OVERLAP_B_IS_LOW_OF_A || isAPartiallyOverlapB == OVERLAP_HIGH_OF_A_IS_LOW_OF_B)
+            return REGACCESS_N;
+        if(isAPartiallyOverlapB == OVERLAP_B_IS_HIGH_OF_A) return REGACCESS_D;
+        if(isAPartiallyOverlapB == OVERLAP_LOW_OF_A_IS_HIGH_OF_B || isAPartiallyOverlapB == OVERLAP_A_IS_LOW_OF_B)
+            return REGACCESS_L;
+    }
+    return REGACCESS_N;
+}
+//! merge RegAccessType C1 with RegAccessType C2
+
+//!C can be N,L,H,D
+RegAccessType updateAccess2(RegAccessType C1, RegAccessType C2) {
+    if(C1 == REGACCESS_D || C2 == REGACCESS_D) return REGACCESS_D;
+    if(C1 == REGACCESS_N) return C2;
+    if(C2 == REGACCESS_N) return C1;
+    if(C1 == REGACCESS_L && C2 == REGACCESS_H) return REGACCESS_D;
+    if(C1 == REGACCESS_H && C2 == REGACCESS_L) return REGACCESS_D;
+    return C1;
+}
+//! merge RegAccessType C with RegAccessType B
+
+//!C can be N,L,H,D
+//!B can be U, D, UD, DU
+RegAccessType updateAccess3(RegAccessType C, RegAccessType B) {
+    if(B == REGACCESS_D || B == REGACCESS_DU) return B; //no exposed usage
+    if(B == REGACCESS_U || B == REGACCESS_UD) {
+        if(C == REGACCESS_N) return B;
+        if(C == REGACCESS_L) return REGACCESS_LU;
+        if(C == REGACCESS_H) return REGACCESS_HU;
+        if(C == REGACCESS_D) return REGACCESS_DU;
+    }
+    return B;
+}
+//! merge RegAccessType A with RegAccessType B
+
+//!argument isBPartiallyOverlapA can be any value between -1 and 2
+//!0 means fully overlapping, 1 means B is the lower half, 2 means B is the higher half
+RegAccessType mergeAccess2(RegAccessType A, RegAccessType B, OverlapCase isBPartiallyOverlapA) {
+    if(A == REGACCESS_UD || A == REGACCESS_UL || A == REGACCESS_UH ||
+       A == REGACCESS_DU || A == REGACCESS_LU || A == REGACCESS_HU) return A;
+    if(A == REGACCESS_D) {
+        if(B == REGACCESS_D) return REGACCESS_D;
+        if(B == REGACCESS_U) return REGACCESS_DU;
+        if(B == REGACCESS_UD) return REGACCESS_DU;
+        if(B == REGACCESS_DU) return B;
+    }
+    if(A == REGACCESS_U) {
+        if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_UL;
+        if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_UH;
+        if(B == REGACCESS_D && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_UD;
+        if(B == REGACCESS_U) return A;
+        if(B == REGACCESS_UD && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_UL;
+        if(B == REGACCESS_UD && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_UH;
+        if(B == REGACCESS_UD && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_UD;
+        if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_UL;
+        if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_UH;
+        if(B == REGACCESS_DU && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_UD;
+    }
+    if(A == REGACCESS_L) {
+        if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_L;
+        if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_D;
+        if(B == REGACCESS_D && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_D;
+        if(B == REGACCESS_U) return REGACCESS_LU;
+        if(B == REGACCESS_UD) return REGACCESS_LU;
+        if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_LU;
+        if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_DU;
+        if(B == REGACCESS_DU && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_DU;
+    }
+    if(A == REGACCESS_H) {
+        if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_D;
+        if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_H;
+        if(B == REGACCESS_D && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_D;
+        if(B == REGACCESS_U) return REGACCESS_HU;
+        if(B == REGACCESS_UD) return REGACCESS_HU;
+        if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_DU;
+        if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_HU;
+        if(B == REGACCESS_DU && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_DU;
+    }
+    return REGACCESS_N;
+}
+
+//!determines which part of a use is from a given definition
+
+//!reachingDefLive tells us which part of the def is live at this point
+//!isDefPartiallyOverlapUse can be any value between -1 and 2
+RegAccessType setAccessTypeOfUse(OverlapCase isDefPartiallyOverlapUse, RegAccessType reachingDefLive) {
+    if(isDefPartiallyOverlapUse == OVERLAP_B_COVER_A)
+        return reachingDefLive;
+    if(isDefPartiallyOverlapUse == OVERLAP_B_COVER_LOW_OF_A) { //def covers the low half of use
+        return REGACCESS_L;
+    }
+    if(isDefPartiallyOverlapUse == OVERLAP_B_COVER_HIGH_OF_A) {
+        return REGACCESS_H;
+    }
+    return REGACCESS_N;
+}
+
+//! search currentBB->defUseTable to find a def for regNum at offsetPC
+
+//!
+DefUsePair* searchDefUseTable(int offsetPC, int regNum, LowOpndRegType pType) {
+    DefUsePair* ptr = currentBB->defUseTable;
+    while(ptr != NULL) {
+        if(ptr->def.offsetPC == offsetPC &&
+           ptr->def.regNum == regNum &&
+           ptr->def.physicalType == pType) {
+            return ptr;
+        }
+        ptr = ptr->next;
+    }
+    return NULL;
+}
+void printDefUseTable() {
+    ALOGI("PRINT defUseTable --------");
+    DefUsePair* ptr = currentBB->defUseTable;
+    while(ptr != NULL) {
+        ALOGI("  def @ %x of VR %d %d has %d uses", ptr->def.offsetPC,
+              ptr->def.regNum, ptr->def.physicalType,
+              ptr->num_uses);
+        DefOrUseLink* ptr2 = ptr->uses;
+        while(ptr2 != NULL) {
+            ALOGI("    use @ %x of VR %d %d accessType %d", ptr2->offsetPC,
+                  ptr2->regNum,
+                  ptr2->physicalType,
+                  ptr2->accessType);
+            ptr2 = ptr2->next;
+        }
+        ptr = ptr->next;
+    }
+}
+//! when a VR is used, check whether a transfer from memory to XMM is necessary
+
+//!
+int updateVRAtUse(int reg, LowOpndRegType pType, int regAll) {
+    int k;
+    for(k = 0; k < currentBB->num_xfer_points; k++) {
+        if(currentBB->xferPoints[k].offsetPC == offsetPC &&
+           currentBB->xferPoints[k].xtype == XFER_MEM_TO_XMM &&
+           currentBB->xferPoints[k].regNum == reg &&
+           currentBB->xferPoints[k].physicalType == pType) {
+#ifdef DEBUG_XFER_POINTS
+            ALOGI("XFER from memory to xmm %d", reg);
+#endif
+            move_mem_to_reg_noalloc(OpndSize_64,
+                                    4*currentBB->xferPoints[k].regNum, PhysicalReg_FP, true,
+                                    MemoryAccess_VR, currentBB->xferPoints[k].regNum,
+                                    regAll, true);
+        }
+    }
+    return 0;
+}
+///////////////////////////////////////////////////////////////////////////////
+// DEAD/USELESS STATEMENT ELMINATION
+// bytecodes can be removed if a bytecode has no side effect and the defs are not used
+// this optimization is guarded with DSE_OPT
+// currently, this optimization is not on, since it does not provide observable performance improvement
+//     and it increases compilation time
+
+/* we remove a maximal of 40 bytecodes within a single basic block */
+#define MAX_NUM_DEAD_PC_IN_BB 40
+int deadPCs[MAX_NUM_DEAD_PC_IN_BB];
+int num_dead_pc = 0;
+//! collect all PCs that can be removed
+
+//! traverse each byte code in the current basic block and check whether it can be removed, if yes, update deadPCs
+void getDeadStmts() {
+    BasicBlock_O1* bb = currentBB;
+    int k;
+    num_dead_pc = 0;
+    //traverse each bytecode in the basic block
+    //update offsetPC, rPC & inst
+    u2* rPC_start = (u2*)currentMethod->insns;
+    MIR* mir;
+    for(mir = bb->jitBasicBlock->firstMIRInsn; mir; mir = mir->next) {
+        offsetPC = mir->seqNum;
+        rPC = rPC_start + mir->offset;
+        if(mir->dalvikInsn.opcode >= kNumPackedOpcodes) continue;
+#ifdef DEBUG_DSE
+        ALOGI("DSE: offsetPC %x", offsetPC);
+#endif
+        inst = FETCH(0);
+        bool isDeadStmt = true;
+        getVirtualRegInfo(infoByteCode);
+        u2 inst_op = INST_INST(inst);
+	//skip bytecodes with side effect
+        if(inst_op != OP_CONST_STRING && inst_op != OP_CONST_STRING_JUMBO &&
+           inst_op != OP_MOVE && inst_op != OP_MOVE_OBJECT &&
+           inst_op != OP_MOVE_FROM16 && inst_op != OP_MOVE_OBJECT_FROM16 &&
+           inst_op != OP_MOVE_16 && inst_op != OP_CONST_CLASS &&
+           inst_op != OP_MOVE_OBJECT_16 && inst_op != OP_MOVE_WIDE &&
+           inst_op != OP_MOVE_WIDE_FROM16 && inst_op != OP_MOVE_WIDE_16 &&
+           inst_op != OP_MOVE_RESULT && inst_op != OP_MOVE_RESULT_OBJECT) {
+            continue;
+        }
+        //some statements do not define any VR!!!
+        int num_defs = 0;
+        for(k = 0; k < num_regs_per_bytecode; k++) {
+            if(infoByteCode[k].accessType == REGACCESS_D ||
+               infoByteCode[k].accessType == REGACCESS_UD ||
+               infoByteCode[k].accessType == REGACCESS_DU) { //search defUseTable
+                num_defs++;
+                DefUsePair* indexT = searchDefUseTable(offsetPC, infoByteCode[k].regNum, infoByteCode[k].physicalType);
+                if(indexT == NULL) {
+                    ALOGE("def at %x of VR %d %d not in table",
+                           offsetPC, infoByteCode[k].regNum, infoByteCode[k].physicalType);
+                    return;
+                }
+                if(indexT->num_uses > 0) {
+                    isDeadStmt = false;
+                    break;
+                } else {
+#ifdef DEBUG_DSE
+                    ALOGI("DSE: num_uses is %d for def at %d for VR %d %d", indexT->num_uses,
+                          offsetPC, infoByteCode[k].regNum, infoByteCode[k].physicalType);
+#endif
+                }
+            }
+        } //for k
+        if(num_defs == 0) isDeadStmt = false;
+        if(isDeadStmt && num_dead_pc < MAX_NUM_DEAD_PC_IN_BB) {
+#ifdef DEBUG_DSE
+            ALOGI("DSE: stmt at %x is dead", offsetPC);
+#endif
+            deadPCs[num_dead_pc++] = offsetPC;
+        }
+    } //for offsetPC
+#ifdef DEBUG_DSE
+    ALOGI("Dead Stmts: ");
+    for(k = 0; k < num_dead_pc; k++) ALOGI("%x ", deadPCs[k]);
+    ALOGI("");
+#endif
+}
+//! entry point to remove dead statements
+
+//! recursively call getDeadStmts and remove uses in defUseTable that are from a dead PC
+//! until there is no change to number of dead PCs
+void removeDeadDefs() {
+    int k;
+    int deadPCs_2[MAX_NUM_DEAD_PC_IN_BB];
+    int num_dead_pc_2 = 0;
+    getDeadStmts();
+    if(num_dead_pc == 0) return;
+    DefUsePair* ptr = NULL;
+    DefOrUseLink* ptrUse = NULL;
+    DefOrUseLink* ptrUse_prev = NULL;
+    while(true) {
+        //check all the uses in defUseTable and remove any use that is from a dead PC
+        ptr = currentBB->defUseTable;
+        while(ptr != NULL) {
+            int k3;
+            ptrUse = ptr->uses;
+            ptrUse_prev = NULL;
+            while(ptrUse != NULL) {
+                bool isIn = false;
+                for(k3 = 0; k3 < num_dead_pc; k3++) {
+                    if(ptrUse->offsetPC == deadPCs[k3]) {
+                        isIn = true;
+                        break;
+                    }
+                }//k3
+                if(!isIn) {
+                    ptrUse_prev = ptrUse;
+                    ptrUse = ptrUse->next; //next use
+                }
+                else {
+                    //go to next use and remove ptrUse
+#ifdef DEBUG_DSE
+                    ALOGI("DSE: remove usage at offsetPC %d reached by def at %d", ptrUse->offsetPC,
+                           ptr->def.offsetPC);
+#endif
+                    DefOrUseLink* nextP = ptrUse->next;
+                    if(ptrUse == ptr->useTail) ptr->useTail = ptrUse_prev;
+                    free(ptrUse);
+                    if(ptrUse_prev == NULL) {
+                        ptr->uses = nextP;
+                    } else {
+                        ptrUse_prev->next = nextP;
+                    }
+                    ptrUse = nextP; //do not update ptrUse_prev
+                    ptr->num_uses--;
+                }
+            }//while ptrUse
+            ptr = ptr->next;
+        }//while ptr
+	//save deadPCs in deadPCs_2
+        num_dead_pc_2 = num_dead_pc;
+        for(k = 0; k < num_dead_pc_2; k++)
+            deadPCs_2[k] = deadPCs[k];
+	//update deadPCs
+        getDeadStmts();
+	//if no change to number of dead PCs, break out of the while loop
+        if(num_dead_pc_2 == num_dead_pc) break;
+    }//while
+#ifdef DEBUG_DSE
+    ALOGI("DSE: DEAD STMTS: ");
+    for(k = 0; k < num_dead_pc; k++) {
+        ALOGI("%d ", deadPCs[k]);
+    }
+    ALOGI("");
+#endif
+}
+/////////////////////////////////////////////////////////////
+//!search memVRTable for a given virtual register
+
+//!
+int searchMemTable(int regNum) {
+    int k;
+    for(k = 0; k < num_memory_vr; k++) {
+        if(memVRTable[k].regNum == regNum) {
+            return k;
+        }
+    }
+    ALOGW("in searchMemTable can't find VR %d num_memory_vr %d", regNum, num_memory_vr);
+    return -1;
+}
+/////////////////////////////////////////////////////////////////////////
+// A VR is already in memory && NULL CHECK
+//!check whether the latest content of a VR is in memory
+
+//!
+bool isInMemory(int regNum, OpndSize size) {
+    int indexL = searchMemTable(regNum);
+    int indexH = -1;
+    if(size == OpndSize_64) indexH = searchMemTable(regNum+1);
+    if(indexL < 0) return false;
+    if(size == OpndSize_64 && indexH < 0) return false;
+    if(!memVRTable[indexL].inMemory) return false;
+    if(size == OpndSize_64 && (!memVRTable[indexH].inMemory)) return false;
+    return true;
+}
+//!set field inMemory of memVRTable to true
+
+//!
+void setVRToMemory(int regNum, OpndSize size) {
+    int indexL = searchMemTable(regNum);
+    int indexH = -1;
+    if(size == OpndSize_64) indexH = searchMemTable(regNum+1);
+    if(indexL < 0) {
+        ALOGE("VR %d not in memVRTable", regNum);
+        return;
+    }
+    memVRTable[indexL].inMemory = true;
+    if(size == OpndSize_64) {
+        if(indexH < 0) {
+            ALOGE("VR %d not in memVRTable", regNum+1);
+            return;
+        }
+        memVRTable[indexH].inMemory = true;
+    }
+}
+//! check whether null check for a VR is performed previously
+
+//!
+bool isVRNullCheck(int regNum, OpndSize size) {
+    if(size != OpndSize_32) {
+        ALOGE("isVRNullCheck size should be 32");
+        dvmAbort();
+    }
+    int indexL = searchMemTable(regNum);
+    if(indexL < 0) {
+        ALOGE("VR %d not in memVRTable", regNum);
+        return false;
+    }
+    return memVRTable[indexL].nullCheckDone;
+}
+bool isVRBoundCheck(int vr_array, int vr_index) {
+    int indexL = searchMemTable(vr_array);
+    if(indexL < 0) {
+        ALOGE("isVRBoundCheck: VR %d not in memVRTable", vr_array);
+        return false;
+    }
+    if(memVRTable[indexL].boundCheck.indexVR == vr_index)
+        return memVRTable[indexL].boundCheck.checkDone;
+    return false;
+}
+//! set nullCheckDone in memVRTable to true
+
+//!
+void setVRNullCheck(int regNum, OpndSize size) {
+    if(size != OpndSize_32) {
+        ALOGE("setVRNullCheck size should be 32");
+        dvmAbort();
+    }
+    int indexL = searchMemTable(regNum);
+    if(indexL < 0) {
+        ALOGE("VR %d not in memVRTable", regNum);
+        return;
+    }
+    memVRTable[indexL].nullCheckDone = true;
+}
+void setVRBoundCheck(int vr_array, int vr_index) {
+    int indexL = searchMemTable(vr_array);
+    if(indexL < 0) {
+        ALOGE("setVRBoundCheck: VR %d not in memVRTable", vr_array);
+        return;
+    }
+    memVRTable[indexL].boundCheck.indexVR = vr_index;
+    memVRTable[indexL].boundCheck.checkDone = true;
+}
+void clearVRBoundCheck(int regNum, OpndSize size) {
+    int k;
+    for(k = 0; k < num_memory_vr; k++) {
+        if(memVRTable[k].regNum == regNum ||
+           (size == OpndSize_64 && memVRTable[k].regNum == regNum+1)) {
+            memVRTable[k].boundCheck.checkDone = false;
+        }
+        if(memVRTable[k].boundCheck.indexVR == regNum ||
+           (size == OpndSize_64 && memVRTable[k].boundCheck.indexVR == regNum+1)) {
+            memVRTable[k].boundCheck.checkDone = false;
+        }
+    }
+}
+//! set inMemory of memVRTable to false
+
+//!
+void clearVRToMemory(int regNum, OpndSize size) {
+    int indexL = searchMemTable(regNum);
+    int indexH = -1;
+    if(size == OpndSize_64) indexH = searchMemTable(regNum+1);
+    if(indexL >= 0) {
+        memVRTable[indexL].inMemory = false;
+    }
+    if(size == OpndSize_64 && indexH >= 0) {
+        memVRTable[indexH].inMemory = false;
+    }
+}
+//! set nullCheckDone of memVRTable to false
+
+//!
+void clearVRNullCheck(int regNum, OpndSize size) {
+    int indexL = searchMemTable(regNum);
+    int indexH = -1;
+    if(size == OpndSize_64) indexH = searchMemTable(regNum+1);
+    if(indexL >= 0) {
+        memVRTable[indexL].nullCheckDone = false;
+    }
+    if(size == OpndSize_64 && indexH >= 0) {
+        memVRTable[indexH].nullCheckDone = false;
+    }
+}
+
+//! Extend Virtual Register life
+
+//! Requests that the life of a specific virtual register be extended. This ensures
+//! that its mapping to a physical register won't be canceled while the extension
+//! request is valid. NOTE: This does not support 64-bit values (when two adjacent
+//! VRs are used)
+//! @see cancelVRFreeDelayRequest
+//! @see getVRFreeDelayRequested
+//! @see VRFreeDelayFlags
+//! @param regNum is the VR number
+//! @param reason explains why freeing must be delayed. A single or combination
+//! of VRFreeDelayFlags should be used.
+//! @return negative value if request failed
+int requestVRFreeDelay(int regNum, u4 reason) {
+    //TODO Add 64-bit operand support when needed
+    int indexL = searchMemTable(regNum);
+    if(indexL >= 0) {
+        memVRTable[indexL].delayFreeFlags |= reason;
+    } else {
+        ALOGE("requestVRFreeDelay: VR %d not in memVRTable", regNum);
+    }
+    return indexL;
+}
+
+//! Cancel request for virtual register life extension
+
+//! Cancels any outstanding requests to extended liveness of VR. Additionally,
+//! this ensures that if the VR is no longer life after this point, it will
+//! no longer be associated with a physical register which can then be reused.
+//! NOTE: This does not support 64-bit values (when two adjacent VRs are used)
+//! @see requestVRFreeDelay
+//! @see getVRFreeDelayRequested
+//! @see VRFreeDelayFlags
+//! @param regNum is the VR number
+//! @param reason explains what freeing delay request should be canceled. A single
+//! or combination of VRFreeDelayFlags should be used.
+void cancelVRFreeDelayRequest(int regNum, u4 reason) {
+    //TODO Add 64-bit operand support when needed
+    bool needCallToFreeReg = false;
+    int indexL = searchMemTable(regNum);
+    if(indexL >= 0) {
+        if((memVRTable[indexL].delayFreeFlags & reason) != VRDELAY_NONE) { // don't cancel delay if it wasn't requested
+            memVRTable[indexL].delayFreeFlags ^= reason; // only cancel this particular reason, not all others
+            if(memVRTable[indexL].delayFreeFlags == VRDELAY_NONE)
+                needCallToFreeReg = true; // freeReg might want to free this VR now if there is no longer a valid delay
+        }
+    }
+    if(needCallToFreeReg)
+        freeReg(true);
+}
+
+//! Gets status of virtual register free delay request
+
+//! Finds out if there was a delay request for freeing this VR.
+//! NOTE: This does not support 64-bit values (when two adjacent VRs are used)
+//! @see requestVRFreeDelay
+//! @see cancelVRFreeDelayRequest
+//! @param regNum is the VR number
+//! @return true if VR has an active delay request
+bool getVRFreeDelayRequested(int regNum) {
+    //TODO Add 64-bit operand support when needed
+    int indexL = searchMemTable(regNum);
+    if(indexL >= 0) {
+        if(memVRTable[indexL].delayFreeFlags != VRDELAY_NONE)
+            return true;
+        return false;
+    }
+    return false;
+}
+
+//! find the basic block that a bytecode is in
+
+//!
+BasicBlock_O1* findForOffset(int offset) {
+    int k;
+    for(k = 0; k < num_bbs_for_method; k++) {
+        if(method_bbs_sorted[k]->pc_start <= offset && method_bbs_sorted[k]->pc_end > offset)
+            return method_bbs_sorted[k];
+    }
+    return NULL;
+}
+void dump_CFG(Method* method);
+
+int current_bc_size = -1;
+
+//! check whether a virtual register is used in a basic block
+
+//!
+bool isUsedInBB(int regNum, int type, BasicBlock_O1* bb) {
+    int k;
+    for(k = 0; k < bb->num_regs; k++) {
+        if(bb->infoBasicBlock[k].physicalType == (type&MASK_FOR_TYPE) && bb->infoBasicBlock[k].regNum == regNum)
+            return true;
+    }
+    return false;
+}
+//! return the index to infoBasicBlock for a given virtual register
+
+//! return -1 if not found
+int searchVirtualInfoOfBB(LowOpndRegType type, int regNum, BasicBlock_O1* bb) {
+    int k;
+    for(k = 0; k < bb->num_regs; k++) {
+        if(bb->infoBasicBlock[k].physicalType == type && bb->infoBasicBlock[k].regNum == regNum)
+            return k;
+    }
+    return -1;
+}
+//! return the index to compileTable for a given virtual register
+
+//! return -1 if not found
+int searchCompileTable(int type, int regNum) { //returns the index
+    int k;
+    for(k = 0; k < num_compile_entries; k++) {
+        if(compileTable[k].physicalType == type && compileTable[k].regNum == regNum)
+            return k;
+    }
+    return -1;
+}
+//!check whether a physical register for a variable with typeA will work for another variable with typeB
+
+//!Type LowOpndRegType_ss is compatible with type LowOpndRegType_xmm
+bool matchType(int typeA, int typeB) {
+    if((typeA & MASK_FOR_TYPE) == (typeB & MASK_FOR_TYPE)) return true;
+    if((typeA & MASK_FOR_TYPE) == LowOpndRegType_ss &&
+       (typeB & MASK_FOR_TYPE) == LowOpndRegType_xmm) return true;
+    if((typeA & MASK_FOR_TYPE) == LowOpndRegType_xmm &&
+       (typeB & MASK_FOR_TYPE) == LowOpndRegType_ss) return true;
+    return false;
+}
+//!check whether a virtual register is used in the current bytecode
+
+//!
+bool isUsedInByteCode(int regNum, int type) {
+    getVirtualRegInfo(infoByteCode);
+    int k;
+    for(k = 0; k < num_regs_per_bytecode; k++) {
+        if(infoByteCode[k].physicalType == (type&MASK_FOR_TYPE) && infoByteCode[k].regNum == regNum)
+            return true;
+    }
+    return false;
+}
+//! obsolete
+bool defineFirst(int atype) {
+    if(atype == REGACCESS_D || atype == REGACCESS_L || atype == REGACCESS_H || atype == REGACCESS_DU)
+        return true;
+    return false;
+}
+//!check whether a virtual register is updated in a basic block
+
+//!
+bool notUpdated(RegAccessType atype) {
+    if(atype == REGACCESS_U) return true;
+    return false;
+}
+//!check whether a virtual register has exposed usage within a given basic block
+
+//!
+bool hasExposedUsage2(BasicBlock_O1* bb, int index) {
+    RegAccessType atype = bb->infoBasicBlock[index].accessType;
+    if(atype == REGACCESS_D || atype == REGACCESS_L || atype == REGACCESS_H || atype == REGACCESS_DU)
+        return false;
+    return true;
+}
+//! return the spill location that is not used
+
+//!
+int getSpillIndex(bool isGLUE, OpndSize size) {
+    if(isGLUE) return 0;
+    int k;
+    for(k = 1; k <= MAX_SPILL_JIT_IA-1; k++) {
+        if(size == OpndSize_64) {
+            if(k < MAX_SPILL_JIT_IA-1 && spillIndexUsed[k] == 0 && spillIndexUsed[k+1] == 0)
+                return k;
+        }
+        else if(spillIndexUsed[k] == 0) {
+            return k;
+        }
+    }
+    ALOGE("can't find spill position in spillLogicalReg");
+    return -1;
+}
+//!this is called before generating a native code, it sets entries in array canSpillReg to true
+
+//!startNativeCode must be paired with endNativeCode
+void startNativeCode(int vr_num, int vr_type) {
+    int k;
+    for(k = 0; k < PhysicalReg_Null; k++) {
+        canSpillReg[k] = true;
+    }
+    inGetVR_num = vr_num;
+    inGetVR_type = vr_type;
+}
+//! called right after generating a native code
+
+//!It sets entries in array canSpillReg to true and reset inGetVR_num to -1
+void endNativeCode() {
+    int k;
+    for(k = 0; k < PhysicalReg_Null; k++) {
+        canSpillReg[k] = true;
+    }
+    inGetVR_num = -1;
+}
+//! set canSpillReg[physicalReg] to false
+
+//!
+void donotSpillReg(int physicalReg) {
+    canSpillReg[physicalReg] = false;
+}
+//! set canSpillReg[physicalReg] to true
+
+//!
+void doSpillReg(int physicalReg) {
+    canSpillReg[physicalReg] = true;
+}
+//! touch hardcoded register %ecx and reduce its reference count
+
+//!
+int touchEcx() {
+    //registerAlloc will spill logical reg that is mapped to ecx
+    //registerAlloc will reduce refCount
+    registerAlloc(LowOpndRegType_gp, PhysicalReg_ECX, true, true);
+    return 0;
+}
+//! touch hardcoded register %eax and reduce its reference count
+
+//!
+int touchEax() {
+    registerAlloc(LowOpndRegType_gp, PhysicalReg_EAX, true, true);
+    return 0;
+}
+int touchEsi() {
+    registerAlloc(LowOpndRegType_gp, PhysicalReg_ESI, true, true);
+    return 0;
+}
+int touchXmm1() {
+    registerAlloc(LowOpndRegType_xmm, XMM_1, true, true);
+    return 0;
+}
+int touchEbx() {
+    registerAlloc(LowOpndRegType_gp, PhysicalReg_EBX, true, true);
+    return 0;
+}
+
+//! touch hardcoded register %edx and reduce its reference count
+
+//!
+int touchEdx() {
+    registerAlloc(LowOpndRegType_gp, PhysicalReg_EDX, true, true);
+    return 0;
+}
+
+#ifdef HACK_FOR_DEBUG
+//for debugging purpose, instructions are added at a certain place
+bool hacked = false;
+void hackBug() {
+  if(!hacked && iget_obj_inst == 13) {
+#if 0
+    move_reg_to_reg_noalloc(OpndSize_32, PhysicalReg_EBX, true, PhysicalReg_ECX, true);
+    //move from ebx to ecx & update compileTable for v3
+    int tIndex = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_gp, 3);
+    if(tIndex < 0) ALOGE("hack can't find VR3");
+    compileTable[tIndex].physicalReg = PhysicalReg_ECX;
+#else
+    move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EBX, true, 12, PhysicalReg_FP, true);
+#endif
+  }
+}
+void hackBug2() {
+  if(!hacked && iget_obj_inst == 13) {
+    dump_imm_mem_noalloc(Mnemonic_MOV, OpndSize_32, 0, 12, PhysicalReg_FP, true);
+    hacked = true;
+  }
+}
+#endif
+
+//! this function is called before calling a helper function or a vm function
+int beforeCall(const char* target) { //spill all live registers
+    if(currentBB == NULL) return -1;
+
+    /* special case for ncgGetEIP: this function only updates %edx */
+    if(!strcmp(target, "ncgGetEIP")) {
+        touchEdx();
+        return -1;
+    }
+
+    /* these functions use %eax for the return value */
+    if((!strcmp(target, "dvmInstanceofNonTrivial")) ||
+       (!strcmp(target, "dvmUnlockObject")) ||
+       (!strcmp(target, "dvmAllocObject")) ||
+       (!strcmp(target, "dvmAllocArrayByClass")) ||
+       (!strcmp(target, "dvmAllocPrimitiveArray")) ||
+       (!strcmp(target, "dvmInterpHandleFillArrayData")) ||
+       (!strcmp(target, "dvmFindInterfaceMethodInCache2")) ||
+       (!strcmp(target, "dvmNcgHandlePackedSwitch")) ||
+       (!strcmp(target, "dvmNcgHandleSparseSwitch")) ||
+       (!strcmp(target, "dvmCanPutArrayElement")) ||
+       (!strcmp(target, "moddi3")) || (!strcmp(target, "divdi3")) ||
+       (!strcmp(target, "execute_inline"))
+       || (!strcmp(target, "dvmJitToPatchPredictedChain"))
+       || (!strcmp(target, "dvmJitHandlePackedSwitch"))
+       || (!strcmp(target, "dvmJitHandleSparseSwitch"))
+       ) {
+        touchEax();
+    }
+
+    //these two functions also use %edx for the return value
+    if((!strcmp(target, "moddi3")) || (!strcmp(target, "divdi3"))) {
+        touchEdx();
+    }
+    if((!strcmp(target, ".new_instance_helper"))) {
+        touchEsi(); touchEax();
+    }
+#if defined(ENABLE_TRACING)
+    if((!strcmp(target, "common_periodicChecks4"))) {
+        touchEdx();
+    }
+#endif
+    if((!strcmp(target, ".const_string_helper"))) {
+        touchEcx(); touchEax();
+    }
+    if((!strcmp(target, ".check_cast_helper"))) {
+        touchEbx(); touchEsi();
+    }
+    if((!strcmp(target, ".instance_of_helper"))) {
+        touchEbx(); touchEsi(); touchEcx();
+    }
+    if((!strcmp(target, ".monitor_enter_helper"))) {
+        touchEbx();
+    }
+    if((!strcmp(target, ".monitor_exit_helper"))) {
+        touchEbx();
+    }
+    if((!strcmp(target, ".aget_wide_helper"))) {
+        touchEbx(); touchEcx(); touchXmm1();
+    }
+    if((!strcmp(target, ".aget_helper")) || (!strcmp(target, ".aget_char_helper")) ||
+       (!strcmp(target, ".aget_short_helper")) || (!strcmp(target, ".aget_bool_helper")) ||
+       (!strcmp(target, ".aget_byte_helper"))) {
+        touchEbx(); touchEcx(); touchEdx();
+    }
+    if((!strcmp(target, ".aput_helper")) || (!strcmp(target, ".aput_char_helper")) ||
+       (!strcmp(target, ".aput_short_helper")) || (!strcmp(target, ".aput_bool_helper")) ||
+       (!strcmp(target, ".aput_byte_helper")) || (!strcmp(target, ".aput_wide_helper"))) {
+        touchEbx(); touchEcx(); touchEdx();
+    }
+    if((!strcmp(target, ".sput_helper")) || (!strcmp(target, ".sput_wide_helper"))) {
+        touchEdx(); touchEax();
+    }
+    if((!strcmp(target, ".sget_helper"))) {
+        touchEdx(); touchEcx();
+    }
+    if((!strcmp(target, ".sget_wide_helper"))) {
+        touchEdx(); touchXmm1();
+    }
+    if((!strcmp(target, ".aput_obj_helper"))) {
+        touchEdx(); touchEcx(); touchEax();
+    }
+    if((!strcmp(target, ".iput_helper")) || (!strcmp(target, ".iput_wide_helper"))) {
+        touchEbx(); touchEcx(); touchEsi();
+    }
+    if((!strcmp(target, ".iget_helper"))) {
+        touchEbx(); touchEcx(); touchEdx();
+    }
+    if((!strcmp(target, ".iget_wide_helper"))) {
+        touchEbx(); touchEcx(); touchXmm1();
+    }
+    if((!strcmp(target, ".new_array_helper"))) {
+        touchEbx(); touchEdx(); touchEax();
+    }
+    if((!strcmp(target, ".invoke_virtual_helper"))) {
+        touchEbx(); touchEcx();
+    }
+    if((!strcmp(target, ".invoke_direct_helper"))) {
+        touchEsi(); touchEcx();
+    }
+    if((!strcmp(target, ".invoke_super_helper"))) {
+        touchEbx(); touchEcx();
+    }
+    if((!strcmp(target, ".invoke_interface_helper"))) {
+        touchEbx(); touchEcx();
+    }
+    if((!strcmp(target, ".invokeMethodNoRange_5_helper")) ||
+       (!strcmp(target, ".invokeMethodNoRange_4_helper"))) {
+        touchEbx(); touchEsi(); touchEax(); touchEdx();
+    }
+    if((!strcmp(target, ".invokeMethodNoRange_3_helper"))) {
+        touchEbx(); touchEsi(); touchEax();
+    }
+    if((!strcmp(target, ".invokeMethodNoRange_2_helper"))) {
+        touchEbx(); touchEsi();
+    }
+    if((!strcmp(target, ".invokeMethodNoRange_1_helper"))) {
+        touchEbx();
+    }
+    if((!strcmp(target, ".invokeMethodRange_helper"))) {
+        touchEdx(); touchEsi();
+    }
+#ifdef DEBUG_REGALLOC
+    ALOGI("enter beforeCall");
+#endif
+    if(!strncmp(target, ".invokeArgsDone", 15)) resetGlue(PhysicalReg_GLUE_DVMDEX);
+
+    freeReg(true); //to avoid spilling dead logical registers
+    int k;
+    for(k = 0; k < num_compile_entries; k++) {
+        /* before throwing an exception, if GLUE is spilled, load to %ebp
+           this should happen at last */
+        if(k == indexForGlue) continue;
+        if(compileTable[k].physicalReg != PhysicalReg_Null &&
+           (compileTable[k].physicalType & LowOpndRegType_hard) == 0) {
+            /* handles non hardcoded variables that are in physical registers */
+            if(!strcmp(target, "exception")) {
+                /* before throwing an exception
+                   update contents of all VRs in Java stack */
+                if(!isVirtualReg(compileTable[k].physicalType)) continue;
+                /* to have correct GC, we should update contents for L VRs as well */
+                //if(compileTable[k].gType == GLOBALTYPE_L) continue;
+            }
+            if((!strcmp(target, ".const_string_resolve")) ||
+               (!strcmp(target, ".static_field_resolve")) ||
+               (!strcmp(target, ".inst_field_resolve")) ||
+               (!strcmp(target, ".class_resolve")) ||
+               (!strcmp(target, ".direct_method_resolve")) ||
+               (!strcmp(target, ".virtual_method_resolve")) ||
+               (!strcmp(target, ".static_method_resolve"))) {
+               /* physical register %ebx will keep its content
+                  but to have correct GC, we should dump content of a VR
+                     that is mapped to %ebx */
+                if(compileTable[k].physicalReg == PhysicalReg_EBX &&
+                   (!isVirtualReg(compileTable[k].physicalType)))
+                    continue;
+            }
+            if((!strncmp(target, "dvm", 3)) || (!strcmp(target, "moddi3")) ||
+               (!strcmp(target, "divdi3")) ||
+               (!strcmp(target, "fmod")) || (!strcmp(target, "fmodf"))) {
+                /* callee-saved registers (%ebx, %esi, %ebp, %edi) will keep the content
+                   but to have correct GC, we should dump content of a VR
+                      that is mapped to a callee-saved register */
+                if((compileTable[k].physicalReg == PhysicalReg_EBX ||
+                    compileTable[k].physicalReg == PhysicalReg_ESI) &&
+                   (!isVirtualReg(compileTable[k].physicalType)))
+                    continue;
+            }
+#ifdef DEBUG_REGALLOC
+            ALOGI("SPILL logical register %d %d in beforeCall",
+                  compileTable[k].regNum, compileTable[k].physicalType);
+#endif
+            spillLogicalReg(k, true);
+        }
+    }
+    if(indexForGlue >= 0 && !strcmp(target, "exception") &&
+       compileTable[indexForGlue].physicalReg == PhysicalReg_Null) {
+        unspillLogicalReg(indexForGlue, PhysicalReg_EBP); //load %ebp
+    }
+#ifdef DEBUG_REGALLOC
+    ALOGI("exit beforeCall");
+#endif
+    return 0;
+}
+int getFreeReg(int type, int reg, int indexToCompileTable);
+//! after calling a helper function or a VM function
+
+//!
+int afterCall(const char* target) { //un-spill
+    if(currentBB == NULL) return -1;
+    if(!strcmp(target, "ncgGetEIP")) return -1;
+
+    return 0;
+}
+//! check whether a temporary is 8-bit
+
+//!
+bool isTemp8Bit(int type, int reg) {
+    if(currentBB == NULL) return false;
+    if(!isTemporary(type, reg)) return false;
+    int k;
+    for(k = 0; k < num_temp_regs_per_bytecode; k++) {
+        if(infoByteCodeTemp[k].physicalType == type &&
+           infoByteCodeTemp[k].regNum == reg) {
+            return infoByteCodeTemp[k].is8Bit;
+        }
+    }
+    ALOGE("isTemp8Bit %d %d", type, reg);
+    return false;
+}
+
+/* functions to access live ranges of a VR
+   Live range info is stored in memVRTable[].ranges, which is a linked list
+*/
+//! check whether a VR is live at the current bytecode
+
+//!
+bool isVRLive(int vA) {
+    int index = searchMemTable(vA);
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", vA);
+        return false;
+    }
+    LiveRange* ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        if(offsetPC >= ptr->start && offsetPC <= ptr->end) return true;
+        ptr = ptr->next;
+    }
+    return false;
+}
+
+//! check whether the current bytecode is the last access to a VR within a live range
+
+//!for 64-bit VR, return true only when true for both low half and high half
+bool isLastByteCodeOfLiveRange(int compileIndex) {
+    int k = compileIndex;
+    OpndSize tSize = getRegSize(compileTable[k].physicalType);
+    int index;
+    LiveRange* ptr = NULL;
+    if(tSize == OpndSize_32) {
+        /* check live ranges for the VR */
+        index = searchMemTable(compileTable[k].regNum);
+        if(index < 0) {
+            ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum);
+            return false;
+        }
+        ptr = memVRTable[index].ranges;
+        while(ptr != NULL) {
+            if(offsetPC == ptr->end) return true;
+            ptr = ptr->next;
+        }
+        return false;
+    }
+    /* size of the VR is 64 */
+    /* check live ranges of the low half */
+    index = searchMemTable(compileTable[k].regNum);
+    bool tmpB = false;
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum);
+        return false;
+    }
+    ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        if(offsetPC == ptr->end) {
+            tmpB = true;
+            break;
+        }
+        ptr = ptr->next;
+    }
+    if(!tmpB) return false;
+    /* check live ranges of the high half */
+    index = searchMemTable(compileTable[k].regNum+1);
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum+1);
+        return false;
+    }
+    ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        if(offsetPC == ptr->end) {
+            return true;
+        }
+        ptr = ptr->next;
+    }
+    return false;
+}
+
+//! check whether the current bytecode is in a live range that extends to end of a basic block
+
+//!for 64 bit, return true if true for both low half and high half
+bool reachEndOfBB(int compileIndex) {
+    int k = compileIndex;
+    OpndSize tSize = getRegSize(compileTable[k].physicalType);
+    int index;
+    bool retCode = false;
+    /* check live ranges of the low half */
+    index = searchMemTable(compileTable[k].regNum);
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum);
+        return false;
+    }
+    LiveRange* ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        if(offsetPC >= ptr->start &&
+           offsetPC <= ptr->end) {
+            if(ptr->end == currentBB->pc_end) {
+                retCode = true;
+            }
+            break;
+        }
+        ptr = ptr->next;
+    }
+    if(!retCode) return false;
+    if(tSize == OpndSize_32) return true;
+    /* check live ranges of the high half */
+    index = searchMemTable(compileTable[k].regNum+1);
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum+1);
+        return false;
+    }
+    ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        if(offsetPC >= ptr->start &&
+           offsetPC <= ptr->end) {
+            if(ptr->end == currentBB->pc_end) return true;
+            return false;
+        }
+        ptr = ptr->next;
+    }
+#ifdef PRINT_WARNING
+    ALOGW("offsetPC %d not in live range of VR %d", offsetPC, compileTable[k].regNum+1);
+#endif
+    return false;
+}
+
+//!check whether the current bytecode is the next to last access to a VR within a live range
+
+//!for 64 bit, return true if true for both low half and high half
+bool isNextToLastAccess(int compileIndex) {
+    int k = compileIndex;
+    OpndSize tSize = getRegSize(compileTable[k].physicalType);
+    int index;
+    /* check live ranges for the low half */
+    bool retCode = false;
+    index = searchMemTable(compileTable[k].regNum);
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum);
+        return false;
+    }
+    LiveRange* ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        int num_access = ptr->num_access;
+
+        if(num_access < 2) {
+           ptr = ptr->next;
+           continue;
+        }
+
+        if(offsetPC == ptr->accessPC[num_access-2]) {
+           retCode = true;
+           break;
+        }
+        ptr = ptr->next;
+    }
+    if(!retCode) return false;
+    if(tSize == OpndSize_32) return true;
+    /* check live ranges for the high half */
+    index = searchMemTable(compileTable[k].regNum+1);
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum+1);
+        return false;
+    }
+    ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        int num_access = ptr->num_access;
+
+        if(num_access < 2) {
+           ptr = ptr->next;
+           continue;
+        }
+
+        if(offsetPC == ptr->accessPC[num_access-2]) return true;
+        ptr = ptr->next;
+    }
+    return false;
+}
+
+/** return the start of the next live range
+    if there does not exist a next live range, return pc_end of the basic block
+    for 64 bits, return the larger one for low half and high half
+    Assume live ranges are sorted in order
+*/
+int getNextLiveRange(int compileIndex) {
+    int k = compileIndex;
+    OpndSize tSize = getRegSize(compileTable[k].physicalType);
+    /* check live ranges of the low half */
+    int index;
+    index = searchMemTable(compileTable[k].regNum);
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum);
+        return offsetPC;
+    }
+    bool found = false;
+    int nextUse = offsetPC;
+    LiveRange* ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        if(ptr->start > offsetPC) {
+            nextUse = ptr->start;
+            found = true;
+            break;
+        }
+        ptr = ptr->next;
+    }
+    if(!found) return currentBB->pc_end;
+    if(tSize == OpndSize_32) return nextUse;
+
+    /* check live ranges of the high half */
+    found = false;
+    index = searchMemTable(compileTable[k].regNum+1);
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum+1);
+        return offsetPC;
+    }
+    int nextUse2 = offsetPC;
+    ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        if(ptr->start > offsetPC) {
+            nextUse2 = ptr->start;
+            found = true;
+            break;
+        }
+        ptr = ptr->next;
+    }
+    if(!found) return currentBB->pc_end;
+    /* return the larger one */
+    return (nextUse2 > nextUse ? nextUse2 : nextUse);
+}
+
+/** return the next access to a variable
+    If variable is 64-bit, get the next access to the lower half and the high half
+        return the eariler one
+*/
+int getNextAccess(int compileIndex) {
+    int k = compileIndex;
+    OpndSize tSize = getRegSize(compileTable[k].physicalType);
+    int index, k3;
+    /* check live ranges of the low half */
+    index = searchMemTable(compileTable[k].regNum);
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum);
+        return offsetPC;
+    }
+    bool found = false;
+    int nextUse = offsetPC;
+    LiveRange* ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        if(offsetPC >= ptr->start &&
+           offsetPC <= ptr->end) {
+            /* offsetPC belongs to this live range */
+            for(k3 = 0; k3 < ptr->num_access; k3++) {
+                if(ptr->accessPC[k3] > offsetPC) {
+                    nextUse = ptr->accessPC[k3];
+                    break;
+                }
+            }
+            found = true;
+            break;
+        }
+        ptr = ptr->next;
+    }
+#ifdef PRINT_WARNING
+    if(!found)
+        ALOGW("offsetPC %d not in live range of VR %d", offsetPC, compileTable[k].regNum);
+#endif
+    if(tSize == OpndSize_32) return nextUse;
+
+    /* check live ranges of the high half */
+    found = false;
+    index = searchMemTable(compileTable[k].regNum+1);
+    if(index < 0) {
+        ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum+1);
+        return offsetPC;
+    }
+    int nextUse2 = offsetPC;
+    ptr = memVRTable[index].ranges;
+    while(ptr != NULL) {
+        if(offsetPC >= ptr->start &&
+           offsetPC <= ptr->end) {
+            for(k3 = 0; k3 < ptr->num_access; k3++) {
+                if(ptr->accessPC[k3] > offsetPC) {
+                    nextUse2 = ptr->accessPC[k3];
+                    break;
+                }
+            }
+            found = true;
+            break;
+        }
+        ptr = ptr->next;
+    }
+#ifdef PRINT_WARNING
+    if(!found) ALOGW("offsetPC %d not in live range of VR %d", offsetPC, compileTable[k].regNum+1);
+#endif
+    /* return the earlier one */
+    if(nextUse2 < nextUse) return nextUse2;
+    return nextUse;
+}
+
+/** free variables that are no longer in use
+    free a temporary with reference count of zero
+    will dump content of a GL VR to memory if necessary
+*/
+int freeReg(bool spillGL) {
+    if(currentBB == NULL) return 0;
+    int k;
+    for(k = 0; k < num_compile_entries; k++) {
+        if(compileTable[k].refCount == 0 && compileTable[k].physicalReg != PhysicalReg_Null) {
+            /* check entries with reference count of zero and is mapped to a physical register */
+            bool typeA = !isVirtualReg(compileTable[k].physicalType);
+            bool freeCrit = true, delayFreeing = false;
+            bool typeC = false, typeB = false, reachEnd = false;
+            if(isVirtualReg(compileTable[k].physicalType)) {
+                /* VRs in the compile table */
+
+                /* Check if delay for freeing was requested for this VR */
+                delayFreeing = getVRFreeDelayRequested(compileTable[k].regNum);
+
+                freeCrit = isLastByteCodeOfLiveRange(k); /* last bytecode of a live range */
+                reachEnd = reachEndOfBB(k); /* in a live range that extends to end of a basic block */
+#ifdef DEBUG_LIVE_RANGE
+                ALOGI("IN freeReg: VR %d offsetPC %x freecrit %d reachEnd %d nextToLast %d", compileTable[k].regNum, offsetPC, freeCrit, reachEnd, isNextToLastAccess(k));
+#endif
+                /* Bug: spilling of VRs after edi(rFP) is updated in RETURN bytecode
+                        will cause variables for callee to be spilled to the caller stack frame and
+                                                        to overwrite varaibles for caller
+                */
+                /* last bytecode of a live range reaching end of BB if not counting the fake usage at end */
+                bool boolB = reachEnd && isNextToLastAccess(k);
+                /* Bug: when a GG VR is checked at end of a basic block,
+                        freeCrit will be true and physicalReg will be set to Null
+                   Fix: change free condition from freeCrit to (freeCrit && offsetPC != currentBB->pc_end)
+                */
+                /* conditions to free a GG VR:
+                       last bytecode of a live range reaching end of BB if not counting the fake usage at end && endsWithReturn
+                       or
+                       last bytecode of a live range && offsetPC != currentBB->pc_end
+                           -> last bytecode of a live range not reaching end
+                */
+                typeC = ((freeCrit && offsetPC != currentBB->pc_end) ||
+                         (currentBB->endsWithReturn && boolB)) &&
+                        compileTable[k].gType == GLOBALTYPE_GG &&
+                        !delayFreeing;
+                /* conditions to free a L|GL VR:
+                       last bytecode of a live range
+                       or
+                       last bytecode of a live range reaching end of BB if not counting the fake usage at end
+                */
+                typeB = (freeCrit || boolB) &&
+                        (compileTable[k].gType != GLOBALTYPE_GG) &&
+                        !delayFreeing;
+            }
+            if(typeA || typeB || typeC) {
+#ifdef DEBUG_REGALLOC
+                if(typeA)
+                    ALOGI("FREE TEMP %d with type %d allocated to %d",
+                           compileTable[k].regNum, compileTable[k].physicalType,
+                           compileTable[k].physicalReg);
+                else if(typeB)
+                    ALOGI("FREE VR L|GL %d with type %d allocated to %d",
+                           compileTable[k].regNum, compileTable[k].physicalType,
+                           compileTable[k].physicalReg);
+                else if(typeC)
+                    ALOGI("FREE VR GG %d with type %d allocated to %d",
+                           compileTable[k].regNum, compileTable[k].physicalType,
+                           compileTable[k].physicalReg);
+#endif
+                bool dumpGL = false;
+                if(compileTable[k].gType == GLOBALTYPE_GL && !reachEnd) {
+                    /* if the live range does not reach end of basic block
+                       and there exists a try block from offsetPC to the next live range
+                           dump VR to interpreted stack */
+                    int tmpPC = getNextLiveRange(k);
+                    if(existATryBlock(currentMethod, offsetPC, tmpPC)) dumpGL = true;
+                }
+                /* if the live range reach end of basic block, dump VR to interpreted stack */
+                if(compileTable[k].gType == GLOBALTYPE_GL && reachEnd) dumpGL = true;
+                if(dumpGL) {
+                    if(spillGL) {
+#ifdef DEBUG_REGALLOC
+                        ALOGI("SPILL VR GL %d %d", compileTable[k].regNum, compileTable[k].physicalType);
+#endif
+                        spillLogicalReg(k, true); //will dump VR to memory & update physicalReg
+                    }
+                }
+                else
+                     compileTable[k].physicalReg = PhysicalReg_Null;
+            }
+            if(typeA) {
+                if(compileTable[k].spill_loc_index >= 0) {
+                    /* update spill info for temporaries */
+                    spillIndexUsed[compileTable[k].spill_loc_index >> 2] = 0;
+                    compileTable[k].spill_loc_index = -1;
+                    ALOGE("free a temporary register with TRSTATE_SPILLED");
+                }
+            }
+        }
+    }
+    syncAllRegs(); //sync up allRegs (isUsed & freeTimeStamp) with compileTable
+    return 0;
+}
+
+//! reduce the reference count by 1
+
+//! input: index to compileTable
+void decreaseRefCount(int index) {
+#ifdef DEBUG_REFCOUNT
+    ALOGI("REFCOUNT: %d in decreaseRefCount %d %d", compileTable[index].refCount,
+            compileTable[index].regNum, compileTable[index].physicalType);
+#endif
+    compileTable[index].refCount--;
+    if(compileTable[index].refCount < 0) {
+        ALOGE("refCount is negative for REG %d %d", compileTable[index].regNum, compileTable[index].physicalType);
+        dvmAbort();
+    }
+}
+//! reduce the reference count of a VR by 1
+
+//! input: reg & type
+int updateRefCount(int reg, LowOpndRegType type) {
+    if(currentBB == NULL) return 0;
+    int index = searchCompileTable(LowOpndRegType_virtual | type, reg);
+    if(index < 0) {
+        ALOGE("virtual reg %d type %d not found in updateRefCount", reg, type);
+        return -1;
+    }
+    decreaseRefCount(index);
+    return 0;
+}
+//! reduce the reference count of a variable by 1
+
+//! The variable is named with lowering module's naming mechanism
+int updateRefCount2(int reg, int type, bool isPhysical) {
+    if(currentBB == NULL) return 0;
+    int newType = convertType(type, reg, isPhysical);
+    if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1;
+    int index = searchCompileTable(newType, reg);
+    if(index < 0) {
+        ALOGE("reg %d type %d not found in updateRefCount", reg, newType);
+        return -1;
+    }
+    decreaseRefCount(index);
+    return 0;
+}
+//! check whether a glue variable is in physical register or spilled
+
+//!
+bool isGlueHandled(int glue_reg) {
+    if(currentBB == NULL) return false;
+    int index = searchCompileTable(LowOpndRegType_gp, glue_reg);
+    if(index < 0) {
+        ALOGE("glue reg %d not found in isGlueHandled", glue_reg);
+        return -1;
+    }
+    if(compileTable[index].spill_loc_index >= 0 ||
+       compileTable[index].physicalReg != PhysicalReg_Null) {
+#ifdef DEBUG_GLUE
+        ALOGI("GLUE isGlueHandled for %d returns true", glue_reg);
+#endif
+        return true;
+    }
+#ifdef DEBUG_GLUE
+    ALOGI("GLUE isGlueHandled for %d returns false", glue_reg);
+#endif
+    return false;
+}
+//! reset the state of a glue variable to not existant (not in physical register nor spilled)
+
+//!
+void resetGlue(int glue_reg) {
+    if(currentBB == NULL) return;
+    int index = searchCompileTable(LowOpndRegType_gp, glue_reg);
+    if(index < 0) {
+        ALOGE("glue reg %d not found in resetGlue", glue_reg);
+        return;
+    }
+#ifdef DEBUG_GLUE
+    ALOGI("GLUE reset for %d", glue_reg);
+#endif
+    compileTable[index].physicalReg = PhysicalReg_Null;
+    if(compileTable[index].spill_loc_index >= 0)
+        spillIndexUsed[compileTable[index].spill_loc_index >> 2] = 0;
+    compileTable[index].spill_loc_index = -1;
+}
+//! set a glue variable in a physical register allocated for a variable
+
+//! Variable is using lowering module's naming convention
+void updateGlue(int reg, bool isPhysical, int glue_reg) {
+    if(currentBB == NULL) return;
+    int index = searchCompileTable(LowOpndRegType_gp, glue_reg);
+    if(index < 0) {
+        ALOGE("glue reg %d not found in updateGlue", glue_reg);
+        return;
+    }
+    /* find the compileTable entry for variable <reg, isPhysical> */
+    int newType = convertType(LowOpndRegType_gp, reg, isPhysical);
+    if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1;
+    int index2 = searchCompileTable(newType, reg);
+    if(index2 < 0 || compileTable[index2].physicalReg == PhysicalReg_Null) {
+        ALOGE("updateGlue reg %d type %d", reg, newType);
+        return;
+    }
+#ifdef DEBUG_GLUE
+    ALOGI("physical register for GLUE %d set to %d", glue_reg, compileTable[index2].physicalReg);
+#endif
+    compileTable[index].physicalReg = compileTable[index2].physicalReg;
+    compileTable[index].spill_loc_index = -1;
+}
+
+//! check whether a virtual register is in a physical register
+
+//! If updateRefCount is 0, do not update reference count;
+//!If updateRefCount is 1, update reference count only when VR is in a physical register
+//!If updateRefCount is 2, update reference count
+int checkVirtualReg(int reg, LowOpndRegType type, int updateRefCount) {
+    if(currentBB == NULL) return PhysicalReg_Null;
+    int index = searchCompileTable(LowOpndRegType_virtual | type, reg);
+    if(index < 0) {
+        ALOGE("virtual reg %d type %d not found in checkVirtualReg", reg, type);
+        return PhysicalReg_Null;
+    }
+    //reduce reference count
+    if(compileTable[index].physicalReg != PhysicalReg_Null) {
+        if(updateRefCount != 0) decreaseRefCount(index);
+        return compileTable[index].physicalReg;
+    }
+    if(updateRefCount == 2) decreaseRefCount(index);
+    return PhysicalReg_Null;
+}
+//!check whether a temporary can share the same physical register with a VR
+
+//!This is called in get_virtual_reg
+//!If this function returns false, new register will be allocated for this temporary
+bool checkTempReg2(int reg, int type, bool isPhysical, int physicalRegForVR) {
+    if(currentBB == NULL) return false;
+    if(isPhysical) return false;
+
+    int newType = convertType(type, reg, isPhysical);
+    if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1;
+    int k;
+    for(k = 0; k < num_temp_regs_per_bytecode; k++) {
+        if(infoByteCodeTemp[k].physicalType == newType &&
+           infoByteCodeTemp[k].regNum == reg) {
+#ifdef DEBUG_MOVE_OPT
+            ALOGI("MOVE_OPT checkTempRegs for %d %d returns %d %d",
+                   reg, newType, infoByteCodeTemp[k].shareWithVR, infoByteCodeTemp[k].is8Bit);
+#endif
+            if(!infoByteCodeTemp[k].is8Bit) return infoByteCodeTemp[k].shareWithVR;
+            //is8Bit true for gp type only
+            if(!infoByteCodeTemp[k].shareWithVR) return false;
+            //both true
+            if(physicalRegForVR >= PhysicalReg_EAX && physicalRegForVR <= PhysicalReg_EDX) return true;
+#ifdef DEBUG_MOVE_OPT
+            ALOGI("MOVE_OPT registerAllocMove not used for 8-bit register");
+#endif
+            return false;
+        }
+    }
+    ALOGE("checkTempReg2 %d %d", reg, newType);
+    return false;
+}
+//!check whether a temporary can share the same physical register with a VR
+
+//!This is called in set_virtual_reg
+int checkTempReg(int reg, int type, bool isPhysical, int vrNum) {
+    if(currentBB == NULL) return PhysicalReg_Null;
+
+    int newType = convertType(type, reg, isPhysical);
+    if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1;
+    int index = searchCompileTable(newType, reg);
+    if(index < 0) {
+        ALOGE("temp reg %d type %d not found in checkTempReg", reg, newType);
+        return PhysicalReg_Null;
+    }
+
+    //a temporary register can share the same physical reg with a VR if registerAllocMove is called
+    //this will cause problem with move bytecode
+    //get_VR(v1, t1) t1 and v1 point to the same physical reg
+    //set_VR(t1, v2) t1 and v2 point to the same physical reg
+    //this will cause v1 and v2 point to the same physical reg
+    //FIX: if this temp reg shares a physical reg with another reg
+    if(compileTable[index].physicalReg != PhysicalReg_Null) {
+        int k;
+        for(k = 0; k < num_compile_entries; k++) {
+            if(k == index) continue;
+            if(compileTable[k].physicalReg == compileTable[index].physicalReg) {
+                return PhysicalReg_Null; //will allocate a register for VR
+            }
+        }
+        decreaseRefCount(index);
+        return compileTable[index].physicalReg;
+    }
+    if(compileTable[index].spill_loc_index >= 0) {
+        //registerAlloc will call unspillLogicalReg (load from memory)
+#ifdef DEBUG_REGALLOC
+        ALOGW("in checkTempReg, the temporary register %d %d was spilled", reg, type);
+#endif
+        int regAll = registerAlloc(type, reg, isPhysical, true/* updateRefCount */);
+        return regAll;
+    }
+    return PhysicalReg_Null;
+}
+//!check whether a variable has exposed usage in a basic block
+
+//!It calls hasExposedUsage2
+bool hasExposedUsage(LowOpndRegType type, int regNum, BasicBlock_O1* bb) {
+    int index = searchVirtualInfoOfBB(type, regNum, bb);
+    if(index >= 0 && hasExposedUsage2(bb, index)) {
+        return true;
+    }
+    return false;
+}
+//!check whether a variable has exposed usage in other basic blocks
+
+//!
+bool hasOtherExposedUsage(OpndSize size, int regNum, BasicBlock_O1* bb) {
+    return true; //assume the worst case
+}
+
+//! handles constant VRs at end of a basic block
+
+//!If a VR is constant at end of a basic block and (it has exposed usage in other basic blocks or reaches a GG VR), dump immediate to memory
+void constVREndOfBB() {
+    BasicBlock_O1* bb = currentBB;
+    int k, k2;
+    //go through GG VRs, update a bool array
+    int constUsedByGG[MAX_CONST_REG];
+    for(k = 0; k < num_const_vr; k++)
+        constUsedByGG[k] = 0;
+    for(k = 0; k < num_compile_entries; k++) {
+        if(isVirtualReg(compileTable[k].physicalType) && compileTable[k].gType == GLOBALTYPE_GG) {
+            OpndSize size = getRegSize(compileTable[k].physicalType);
+            int regNum = compileTable[k].regNum;
+            int indexL = -1;
+            int indexH = -1;
+            for(k2 = 0; k2 < num_const_vr; k2++) {
+                if(constVRTable[k2].regNum == regNum) {
+                    indexL = k2;
+                    continue;
+                }
+                if(constVRTable[k2].regNum == regNum + 1 && size == OpndSize_64) {
+                    indexH = k2;
+                    continue;
+                }
+            }
+            if(indexL >= 0) constUsedByGG[indexL] = 1;
+            if(indexH >= 0) constUsedByGG[indexH] = 1;
+        } //GG VR
+    }
+    for(k = 0; k < num_const_vr; k++) {
+        if(!constVRTable[k].isConst) continue;
+        bool hasExp = false;
+        if(constUsedByGG[k] == 0)
+            hasExp = hasOtherExposedUsage(OpndSize_32, constVRTable[k].regNum, bb);
+        if(constUsedByGG[k] != 0 || hasExp) {
+            dumpImmToMem(constVRTable[k].regNum, OpndSize_32, constVRTable[k].value);
+            setVRToMemory(constVRTable[k].regNum, OpndSize_32);
+#ifdef DEBUG_ENDOFBB
+            ALOGI("ENDOFBB: exposed VR %d is const %d (%x)",
+                  constVRTable[k].regNum, constVRTable[k].value, constVRTable[k].value);
+#endif
+        } else {
+#ifdef DEBUG_ENDOFBB
+            ALOGI("ENDOFBB: unexposed VR %d is const %d (%x)",
+                  constVRTable[k].regNum, constVRTable[k].value, constVRTable[k].value);
+#endif
+        }
+    }
+}
+
+//!handles GG VRs at end of a basic block
+
+//!make sure all GG VRs are in pre-defined physical registers
+void globalVREndOfBB(const Method* method) {
+    //fix: freeReg first to write LL VR back to memory to avoid it gets overwritten by GG VRs
+    freeReg(true);
+    int k;
+    //spill GG VR first if it is not mapped to the specific reg
+    //release GLUE regs
+    for(k = 0; k < num_compile_entries; k++) {
+        if(compileTable[k].regNum >= PhysicalReg_GLUE_DVMDEX &&
+           compileTable[k].regNum != PhysicalReg_GLUE) {
+            compileTable[k].physicalReg = PhysicalReg_Null;
+            compileTable[k].spill_loc_index = -1;
+        }
+        //if part of a GG VR is const, the physical reg is set to null
+        if(isVirtualReg(compileTable[k].physicalType) &&
+           compileTable[k].gType == GLOBALTYPE_GG && compileTable[k].physicalReg != PhysicalReg_Null &&
+           compileTable[k].physicalReg != compileTable[k].physicalReg_prev) {
+#ifdef DEBUG_ENDOFBB
+            ALOGW("end of BB GG VR is not mapped to the specific reg: %d %d %d",
+                  compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].physicalReg);
+            ALOGW("ENDOFBB SPILL VR %d %d", compileTable[k].regNum, compileTable[k].physicalType);
+#endif
+            spillLogicalReg(k, true); //the next section will load VR from memory to the specific reg
+        }
+    }
+    syncAllRegs();
+    for(k = 0; k < num_compile_entries; k++) {
+        if(isVirtualReg(compileTable[k].physicalType)) {
+            if(compileTable[k].gType == GLOBALTYPE_GG &&
+               compileTable[k].physicalReg == PhysicalReg_Null && (!currentBB->endsWithReturn)) {
+#ifdef DEBUG_ENDOFBB
+                ALOGI("ENDOFBB GET GG VR %d %d to physical register %d", compileTable[k].regNum,
+                      compileTable[k].physicalType, compileTable[k].physicalReg_prev);
+#endif
+                compileTable[k].physicalReg = compileTable[k].physicalReg_prev;
+                if(allRegs[compileTable[k].physicalReg_prev].isUsed) {
+                    ALOGE("physical register for GG VR is still used");
+                }
+                get_virtual_reg_noalloc(compileTable[k].regNum,
+                                        getRegSize(compileTable[k].physicalType),
+                                        compileTable[k].physicalReg_prev,
+                                        true);
+            }
+        }//not const
+    }
+    if(indexForGlue >= 0 &&
+        compileTable[indexForGlue].physicalReg == PhysicalReg_Null) {
+        unspillLogicalReg(indexForGlue, PhysicalReg_EBP); //load %ebp
+    }
+}
+
+//! get ready for the next version of a hard-coded register
+
+//!set its physicalReg to Null and update its reference count
+int nextVersionOfHardReg(PhysicalReg pReg, int refCount) {
+    int indexT = searchCompileTable(LowOpndRegType_gp | LowOpndRegType_hard, pReg);
+    if(indexT < 0)
+        return -1;
+    compileTable[indexT].physicalReg = PhysicalReg_Null;
+#ifdef DEBUG_REFCOUNT
+    ALOGI("REFCOUNT: to %d in nextVersionOfHardReg %d", refCount, pReg);
+#endif
+    compileTable[indexT].refCount = refCount;
+    return 0;
+}
+
+/** update compileTable with bb->infoBasicBlock[k]
+*/
+void insertFromVirtualInfo(BasicBlock_O1* bb, int k) {
+    int index = searchCompileTable(LowOpndRegType_virtual | bb->infoBasicBlock[k].physicalType, bb->infoBasicBlock[k].regNum);
+    if(index < 0) {
+        /* the virtual register is not in compileTable, insert it */
+        index = num_compile_entries;
+        compileTable[num_compile_entries].physicalType = (LowOpndRegType_virtual | bb->infoBasicBlock[k].physicalType);
+        compileTable[num_compile_entries].regNum = bb->infoBasicBlock[k].regNum;
+        compileTable[num_compile_entries].physicalReg = PhysicalReg_Null;
+        compileTable[num_compile_entries].bb = bb;
+        compileTable[num_compile_entries].indexToInfoBB = k;
+        compileTable[num_compile_entries].spill_loc_index = -1;
+        compileTable[num_compile_entries].gType = bb->infoBasicBlock[k].gType;
+        num_compile_entries++;
+        if(num_compile_entries >= COMPILE_TABLE_SIZE) {
+            ALOGE("compileTable overflow");
+            dvmAbort();
+        }
+    }
+    /* re-set reference count of all VRs */
+    compileTable[index].refCount = bb->infoBasicBlock[k].refCount;
+    compileTable[index].accessType = bb->infoBasicBlock[k].accessType;
+    if(compileTable[index].gType == GLOBALTYPE_GG)
+        compileTable[index].physicalReg_prev = bb->infoBasicBlock[k].physicalReg_GG;
+}
+
+/** update compileTable with infoByteCodeTemp[k]
+*/
+void insertFromTempInfo(int k) {
+    int index = searchCompileTable(infoByteCodeTemp[k].physicalType, infoByteCodeTemp[k].regNum);
+    if(index < 0) {
+        /* the temporary is not in compileTable, insert it */
+        index = num_compile_entries;
+        compileTable[num_compile_entries].physicalType = infoByteCodeTemp[k].physicalType;
+        compileTable[num_compile_entries].regNum = infoByteCodeTemp[k].regNum;
+        num_compile_entries++;
+        if(num_compile_entries >= COMPILE_TABLE_SIZE) {
+            ALOGE("compileTable overflow");
+            dvmAbort();
+        }
+    }
+    compileTable[index].physicalReg = PhysicalReg_Null;
+    compileTable[index].refCount = infoByteCodeTemp[k].refCount;
+    compileTable[index].linkageToVR = infoByteCodeTemp[k].linkageToVR;
+    compileTable[index].gType = GLOBALTYPE_L;
+    compileTable[index].spill_loc_index = -1;
+}
+
+/* insert a glue-related register GLUE_DVMDEX to compileTable */
+void insertGlueReg() {
+    compileTable[num_compile_entries].physicalType = LowOpndRegType_gp;
+    compileTable[num_compile_entries].regNum = PhysicalReg_GLUE_DVMDEX;
+    compileTable[num_compile_entries].refCount = 2;
+    compileTable[num_compile_entries].physicalReg = PhysicalReg_Null;
+    compileTable[num_compile_entries].bb = NULL;
+    compileTable[num_compile_entries].spill_loc_index = -1;
+    compileTable[num_compile_entries].accessType = REGACCESS_N;
+    compileTable[num_compile_entries].linkageToVR = -1;
+    compileTable[num_compile_entries].gType = GLOBALTYPE_L;
+
+    num_compile_entries++;
+    if(num_compile_entries >= COMPILE_TABLE_SIZE) {
+        ALOGE("compileTable overflow");
+        dvmAbort();
+    }
+}
+
+/** print infoBasicBlock of the given basic block
+*/
+void dumpVirtualInfoOfBasicBlock(BasicBlock_O1* bb) {
+    int jj;
+    ALOGI("Virtual Info for BB%d --------", bb->bb_index);
+    for(jj = 0; jj < bb->num_regs; jj++) {
+        ALOGI("regNum %d physicalType %d accessType %d refCount %d def ",
+               bb->infoBasicBlock[jj].regNum, bb->infoBasicBlock[jj].physicalType,
+               bb->infoBasicBlock[jj].accessType, bb->infoBasicBlock[jj].refCount);
+        int k;
+        for(k = 0; k < bb->infoBasicBlock[jj].num_reaching_defs; k++)
+            ALOGI("[%x %d %d %d] ", bb->infoBasicBlock[jj].reachingDefs[k].offsetPC,
+                   bb->infoBasicBlock[jj].reachingDefs[k].regNum,
+                   bb->infoBasicBlock[jj].reachingDefs[k].physicalType,
+                   bb->infoBasicBlock[jj].reachingDefs[k].accessType);
+        ALOGI("");
+    }
+}
+
+/** print compileTable
+*/
+void dumpCompileTable() {
+    int jj;
+    ALOGI("Compile Table for method ----------");
+    for(jj = 0; jj < num_compile_entries; jj++) {
+        ALOGI("regNum %d physicalType %d refCount %d isConst %d physicalReg %d type %d",
+               compileTable[jj].regNum, compileTable[jj].physicalType,
+               compileTable[jj].refCount, compileTable[jj].isConst, compileTable[jj].physicalReg, compileTable[jj].gType);
+    }
+}
+
+//!check whether a basic block is the start of an exception handler
+
+//!
+bool isFirstOfHandler(BasicBlock_O1* bb) {
+    int i;
+    for(i = 0; i < num_exception_handlers; i++) {
+        if(bb->pc_start == exceptionHandlers[i]) return true;
+    }
+    return false;
+}
+
+//! create a basic block that starts at src_pc and ends at end_pc
+
+//!
+BasicBlock_O1* createBasicBlock(int src_pc, int end_pc) {
+    BasicBlock_O1* bb = (BasicBlock_O1*)malloc(sizeof(BasicBlock_O1));
+    if(bb == NULL) {
+        ALOGE("out of memory");
+        return NULL;
+    }
+    bb->pc_start = src_pc;
+    bb->bb_index = num_bbs_for_method;
+    if(bb_entry == NULL) bb_entry = bb;
+
+    /* insert the basic block to method_bbs_sorted in ascending order of pc_start */
+    int k;
+    int index = -1;
+    for(k = 0; k < num_bbs_for_method; k++)
+        if(method_bbs_sorted[k]->pc_start > src_pc) {
+            index = k;
+            break;
+        }
+    if(index == -1)
+        method_bbs_sorted[num_bbs_for_method] = bb;
+    else {
+        /* push the elements from index by 1 */
+        for(k = num_bbs_for_method-1; k >= index; k--)
+            method_bbs_sorted[k+1] = method_bbs_sorted[k];
+        method_bbs_sorted[index] = bb;
+    }
+    num_bbs_for_method++;
+    if(num_bbs_for_method >= MAX_NUM_BBS_PER_METHOD) {
+        ALOGE("too many basic blocks");
+        dvmAbort();
+    }
+    return bb;
+}
+
+/* BEGIN code to handle state transfers */
+//! save the current state of register allocator to a state table
+
+//!
+void rememberState(int stateNum) {
+#ifdef DEBUG_STATE
+    ALOGI("STATE: remember state %d", stateNum);
+#endif
+    int k;
+    for(k = 0; k < num_compile_entries; k++) {
+        if(stateNum == 1) {
+            stateTable1_1[k].physicalReg = compileTable[k].physicalReg;
+            stateTable1_1[k].spill_loc_index = compileTable[k].spill_loc_index;
+        }
+        else if(stateNum == 2) {
+            stateTable1_2[k].physicalReg = compileTable[k].physicalReg;
+            stateTable1_2[k].spill_loc_index = compileTable[k].spill_loc_index;
+        }
+        else if(stateNum == 3) {
+            stateTable1_3[k].physicalReg = compileTable[k].physicalReg;
+            stateTable1_3[k].spill_loc_index = compileTable[k].spill_loc_index;
+        }
+        else if(stateNum == 4) {
+            stateTable1_4[k].physicalReg = compileTable[k].physicalReg;
+            stateTable1_4[k].spill_loc_index = compileTable[k].spill_loc_index;
+        }
+        else ALOGE("state table overflow");
+#ifdef DEBUG_STATE
+        ALOGI("logical reg %d %d mapped to physical reg %d with spill index %d refCount %d",
+               compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].physicalReg,
+               compileTable[k].spill_loc_index, compileTable[k].refCount);
+#endif
+    }
+    for(k = 0; k < num_memory_vr; k++) {
+        if(stateNum == 1) {
+            stateTable2_1[k].regNum = memVRTable[k].regNum;
+            stateTable2_1[k].inMemory = memVRTable[k].inMemory;
+        }
+        else if(stateNum == 2) {
+            stateTable2_2[k].regNum = memVRTable[k].regNum;
+            stateTable2_2[k].inMemory = memVRTable[k].inMemory;
+        }
+        else if(stateNum == 3) {
+            stateTable2_3[k].regNum = memVRTable[k].regNum;
+            stateTable2_3[k].inMemory = memVRTable[k].inMemory;
+        }
+        else if(stateNum == 4) {
+            stateTable2_4[k].regNum = memVRTable[k].regNum;
+            stateTable2_4[k].inMemory = memVRTable[k].inMemory;
+        }
+        else ALOGE("state table overflow");
+#ifdef DEBUG_STATE
+        ALOGI("virtual reg %d in memory %d", memVRTable[k].regNum, memVRTable[k].inMemory);
+#endif
+    }
+}
+
+//!update current state of register allocator with a state table
+
+//!
+void goToState(int stateNum) {
+    int k;
+#ifdef DEBUG_STATE
+    ALOGI("STATE: go to state %d", stateNum);
+#endif
+    for(k = 0; k < num_compile_entries; k++) {
+        if(stateNum == 1) {
+            compileTable[k].physicalReg = stateTable1_1[k].physicalReg;
+            compileTable[k].spill_loc_index = stateTable1_1[k].spill_loc_index;
+        }
+        else if(stateNum == 2) {
+            compileTable[k].physicalReg = stateTable1_2[k].physicalReg;
+            compileTable[k].spill_loc_index = stateTable1_2[k].spill_loc_index;
+        }
+        else if(stateNum == 3) {
+            compileTable[k].physicalReg = stateTable1_3[k].physicalReg;
+            compileTable[k].spill_loc_index = stateTable1_3[k].spill_loc_index;
+        }
+        else if(stateNum == 4) {
+            compileTable[k].physicalReg = stateTable1_4[k].physicalReg;
+            compileTable[k].spill_loc_index = stateTable1_4[k].spill_loc_index;
+        }
+        else ALOGE("state table overflow");
+    }
+    updateSpillIndexUsed();
+    syncAllRegs(); //to sync up allRegs CAN'T call freeReg here
+    //since it will change the state!!!
+    for(k = 0; k < num_memory_vr; k++) {
+        if(stateNum == 1) {
+            memVRTable[k].regNum = stateTable2_1[k].regNum;
+            memVRTable[k].inMemory = stateTable2_1[k].inMemory;
+        }
+        else if(stateNum == 2) {
+            memVRTable[k].regNum = stateTable2_2[k].regNum;
+            memVRTable[k].inMemory = stateTable2_2[k].inMemory;
+        }
+        else if(stateNum == 3) {
+            memVRTable[k].regNum = stateTable2_3[k].regNum;
+            memVRTable[k].inMemory = stateTable2_3[k].inMemory;
+        }
+        else if(stateNum == 4) {
+            memVRTable[k].regNum = stateTable2_4[k].regNum;
+            memVRTable[k].inMemory = stateTable2_4[k].inMemory;
+        }
+        else ALOGE("state table overflow");
+    }
+}
+typedef struct TransferOrder {
+    int targetReg;
+    int targetSpill;
+    int compileIndex;
+} TransferOrder;
+#define MAX_NUM_DEST 20
+//! a source register is used as a source in transfer
+//! it can have a maximum of MAX_NUM_DEST destinations
+typedef struct SourceReg {
+    int physicalReg;
+    int num_dests; //check bound
+    TransferOrder dsts[MAX_NUM_DEST];
+} SourceReg;
+int num_src_regs = 0; //check bound
+//! physical registers that are used as a source in transfer
+//! we allow a maximum of MAX_NUM_DEST sources in a transfer
+SourceReg srcRegs[MAX_NUM_DEST];
+//! tell us whether a source register is handled already
+bool handledSrc[MAX_NUM_DEST];
+//! in what order should the source registers be handled
+int handledOrder[MAX_NUM_DEST];
+//! insert a source register with a single destination
+
+//!
+void insertSrcReg(int srcPhysical, int targetReg, int targetSpill, int index) {
+    int k = 0;
+    for(k = 0; k < num_src_regs; k++) {
+        if(srcRegs[k].physicalReg == srcPhysical) { //increase num_dests
+            if(srcRegs[k].num_dests >= MAX_NUM_DEST) {
+                ALOGE("exceed number dst regs for a source reg");
+                dvmAbort();
+            }
+            srcRegs[k].dsts[srcRegs[k].num_dests].targetReg = targetReg;
+            srcRegs[k].dsts[srcRegs[k].num_dests].targetSpill = targetSpill;
+            srcRegs[k].dsts[srcRegs[k].num_dests].compileIndex = index;
+            srcRegs[k].num_dests++;
+            return;
+        }
+    }
+    if(num_src_regs >= MAX_NUM_DEST) {
+        ALOGE("exceed number of source regs");
+        dvmAbort();
+    }
+    srcRegs[num_src_regs].physicalReg = srcPhysical;
+    srcRegs[num_src_regs].num_dests = 1;
+    srcRegs[num_src_regs].dsts[0].targetReg = targetReg;
+    srcRegs[num_src_regs].dsts[0].targetSpill = targetSpill;
+    srcRegs[num_src_regs].dsts[0].compileIndex = index;
+    num_src_regs++;
+}
+//! check whether a register is a source and the source is not yet handled
+
+//!
+bool dstStillInUse(int dstReg) {
+    if(dstReg == PhysicalReg_Null) return false;
+    int k;
+    int index = -1;
+    for(k = 0; k < num_src_regs; k++) {
+        if(dstReg == srcRegs[k].physicalReg) {
+            index = k;
+            break;
+        }
+    }
+    if(index < 0) return false; //not in use
+    if(handledSrc[index]) return false; //not in use
+    return true;
+}
+//! reset the state of glue variables in a state table
+
+//!
+void resetStateOfGlue(int stateNum, int k) {
+#ifdef DEBUG_STATE
+    ALOGI("resetStateOfGlue state %d regNum %d", stateNum, compileTable[k].regNum);
+#endif
+    if(stateNum == 1) {
+        stateTable1_1[k].physicalReg = PhysicalReg_Null;
+        stateTable1_1[k].spill_loc_index = -1;
+    }
+    else if(stateNum == 2) {
+        stateTable1_2[k].physicalReg = PhysicalReg_Null;
+        stateTable1_2[k].spill_loc_index = -1;
+    }
+    else if(stateNum == 3) {
+        stateTable1_3[k].physicalReg = PhysicalReg_Null;
+        stateTable1_3[k].spill_loc_index = -1;
+    }
+    else if(stateNum == 4) {
+        stateTable1_4[k].physicalReg = PhysicalReg_Null;
+        stateTable1_4[k].spill_loc_index = -1;
+    }
+}
+//! construct a legal order of the source registers in this transfer
+
+//!
+void constructSrcRegs(int stateNum) {
+    int k;
+    num_src_regs = 0;
+#ifdef DEBUG_STATE
+    ALOGI("IN constructSrcRegs");
+#endif
+
+    for(k = 0; k < num_compile_entries; k++) {
+#ifdef DEBUG_STATE
+        ALOGI("logical reg %d %d mapped to physical reg %d with spill index %d refCount %d",
+               compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].physicalReg,
+               compileTable[k].spill_loc_index, compileTable[k].refCount);
+#endif
+
+        int pType = compileTable[k].physicalType;
+        //ignore hardcoded logical registers
+        if((pType & LowOpndRegType_hard) != 0) continue;
+        //ignore type _fs
+        if((pType & MASK_FOR_TYPE) == LowOpndRegType_fs) continue;
+        if((pType & MASK_FOR_TYPE) == LowOpndRegType_fs_s) continue;
+
+        //GL VR refCount is zero, can't ignore
+        //L VR refCount is zero, ignore
+        //GG VR refCount is zero, can't ignore
+        //temporary refCount is zero, ignore
+
+        //for GLUE variables, if they do not exist, reset the entries in state table
+        if(compileTable[k].physicalReg == PhysicalReg_Null &&
+           compileTable[k].regNum >= PhysicalReg_GLUE_DVMDEX &&
+           compileTable[k].regNum != PhysicalReg_GLUE &&
+           compileTable[k].spill_loc_index < 0) {
+            resetStateOfGlue(stateNum, k);
+        }
+
+        /* get the target state */
+        int targetReg = PhysicalReg_Null;
+        int targetSpill = -1;
+        if(stateNum == 1) {
+            targetReg = stateTable1_1[k].physicalReg;
+            targetSpill = stateTable1_1[k].spill_loc_index;
+        }
+        else if(stateNum == 2) {
+            targetReg = stateTable1_2[k].physicalReg;
+            targetSpill = stateTable1_2[k].spill_loc_index;
+        }
+        else if(stateNum == 3) {
+            targetReg = stateTable1_3[k].physicalReg;
+            targetSpill = stateTable1_3[k].spill_loc_index;
+        }
+        else if(stateNum == 4) {
+            targetReg = stateTable1_4[k].physicalReg;
+            targetSpill = stateTable1_4[k].spill_loc_index;
+        }
+
+        /* there exists an ordering problem
+           for example:
+             for a VR, move from memory to a physical reg esi
+             for a temporary regsiter, from esi to ecx
+             if we handle VR first, content of the temporary reg. will be overwritten
+           there are 4 cases:
+             I: a variable is currently in memory and its target is in physical reg
+             II: a variable is currently in a register and its target is in memory
+             III: a variable is currently in a different register
+             IV: a variable is currently in a different memory location (for non-VRs)
+           for GLUE, since it can only be allocated to %ebp, we don't have case III
+           For now, case IV is not handled since it didn't show
+        */
+        if(compileTable[k].physicalReg != targetReg &&
+           isVirtualReg(compileTable[k].physicalType)) {
+            /* handles VR for case I to III */
+
+            if(compileTable[k].physicalReg == PhysicalReg_Null && targetReg != PhysicalReg_Null) {
+                /* handles VR for case I:
+                   insert a xfer order from PhysicalReg_Null to targetReg */
+                insertSrcReg(PhysicalReg_Null, targetReg, targetSpill, k);
+#ifdef DEBUG_STATE
+                ALOGI("insert for VR Null %d %d %d", targetReg, targetSpill, k);
+#endif
+            }
+
+            if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg != PhysicalReg_Null) {
+                /* handles VR for case III
+                   insert a xfer order from srcReg to targetReg */
+                insertSrcReg(compileTable[k].physicalReg, targetReg, targetSpill, k);
+            }
+
+            if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg == PhysicalReg_Null) {
+                /* handles VR for case II
+                   insert a xfer order from srcReg to memory */
+                insertSrcReg(compileTable[k].physicalReg, targetReg, targetSpill, k);
+            }
+        }
+
+        if(compileTable[k].physicalReg != targetReg &&
+           !isVirtualReg(compileTable[k].physicalType)) {
+            /* handles non-VR for case I to III */
+
+            if(compileTable[k].physicalReg == PhysicalReg_Null && targetReg != PhysicalReg_Null) {
+                /* handles non-VR for case I */
+                if(compileTable[k].spill_loc_index < 0) {
+                    /* this variable is freed, no need to transfer */
+#ifdef DEBUG_STATE
+                    ALOGW("in transferToState spill_loc_index is negative for temporary %d", compileTable[k].regNum);
+#endif
+                } else {
+                    /* insert a xfer order from memory to targetReg */
+#ifdef DEBUG_STATE
+                    ALOGI("insert Null %d %d %d", targetReg, targetSpill, k);
+#endif
+                    insertSrcReg(PhysicalReg_Null, targetReg, targetSpill, k);
+                }
+            }
+
+            if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg != PhysicalReg_Null) {
+                /* handles non-VR for case III
+                   insert a xfer order from srcReg to targetReg */
+                insertSrcReg(compileTable[k].physicalReg, targetReg, targetSpill, k);
+            }
+
+            if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg == PhysicalReg_Null) {
+                /* handles non-VR for case II */
+                if(targetSpill < 0) {
+                    /* this variable is freed, no need to transfer */
+#ifdef DEBUG_STATE
+                    ALOGW("in transferToState spill_loc_index is negative for temporary %d", compileTable[k].regNum);
+#endif
+                } else {
+                    /* insert a xfer order from srcReg to memory */
+                    insertSrcReg(compileTable[k].physicalReg, targetReg, targetSpill, k);
+                }
+            }
+
+        }
+    }//for compile entries
+
+    int k2;
+#ifdef DEBUG_STATE
+    for(k = 0; k < num_src_regs; k++) {
+        ALOGI("SRCREG %d: ", srcRegs[k].physicalReg);
+        for(k2 = 0; k2 < srcRegs[k].num_dests; k2++) {
+            int index = srcRegs[k].dsts[k2].compileIndex;
+            ALOGI("[%d %d %d: %d %d %d] ", srcRegs[k].dsts[k2].targetReg,
+                   srcRegs[k].dsts[k2].targetSpill, srcRegs[k].dsts[k2].compileIndex,
+                   compileTable[index].regNum, compileTable[index].physicalType,
+                   compileTable[index].spill_loc_index);
+        }
+        ALOGI("");
+    }
+#endif
+
+    /* construct an order: xfers from srcReg first, then xfers from memory */
+    int num_handled = 0;
+    int num_in_order = 0;
+    for(k = 0; k < num_src_regs; k++) {
+        if(srcRegs[k].physicalReg == PhysicalReg_Null) {
+            handledSrc[k] = true;
+            num_handled++;
+        } else {
+            handledSrc[k] = false;
+        }
+    }
+    while(num_handled < num_src_regs) {
+        int prev_handled = num_handled;
+        for(k = 0; k < num_src_regs; k++) {
+            if(handledSrc[k]) continue;
+            bool canHandleNow = true;
+            for(k2 = 0; k2 < srcRegs[k].num_dests; k2++) {
+                if(dstStillInUse(srcRegs[k].dsts[k2].targetReg)) {
+                    canHandleNow = false;
+                    break;
+                }
+            }
+            if(canHandleNow) {
+                handledSrc[k] = true;
+                num_handled++;
+                handledOrder[num_in_order] = k;
+                num_in_order++;
+            }
+        } //for k
+        if(num_handled == prev_handled) {
+            ALOGE("no progress in selecting order");
+            dvmAbort();
+        }
+    } //while
+    for(k = 0; k < num_src_regs; k++) {
+        if(srcRegs[k].physicalReg == PhysicalReg_Null) {
+            handledOrder[num_in_order] = k;
+            num_in_order++;
+        }
+    }
+    if(num_in_order != num_src_regs) {
+        ALOGE("num_in_order != num_src_regs");
+        dvmAbort();
+    }
+#ifdef DEBUG_STATE
+    ALOGI("ORDER: ");
+    for(k = 0; k < num_src_regs; k++) {
+        ALOGI("%d ", handledOrder[k]);
+    }
+    ALOGI("");
+#endif
+}
+//! transfer the state of register allocator to a state specified in a state table
+
+//!
+void transferToState(int stateNum) {
+    freeReg(false); //do not spill GL
+    int k;
+#ifdef DEBUG_STATE
+    ALOGI("STATE: transfer to state %d", stateNum);
+#endif
+    if(stateNum > 4 || stateNum < 1) ALOGE("state table overflow");
+    constructSrcRegs(stateNum);
+    int k4, k3;
+    for(k4 = 0; k4 < num_src_regs; k4++) {
+        int k2 = handledOrder[k4]; //index to srcRegs
+        for(k3 = 0; k3 < srcRegs[k2].num_dests; k3++) {
+            k = srcRegs[k2].dsts[k3].compileIndex;
+            int targetReg = srcRegs[k2].dsts[k3].targetReg;
+            int targetSpill = srcRegs[k2].dsts[k3].targetSpill;
+            if(compileTable[k].physicalReg != targetReg && isVirtualReg(compileTable[k].physicalType)) {
+                OpndSize oSize = getRegSize(compileTable[k].physicalType);
+                bool isSS = ((compileTable[k].physicalType & MASK_FOR_TYPE) == LowOpndRegType_ss);
+                if(compileTable[k].physicalReg == PhysicalReg_Null && targetReg != PhysicalReg_Null) {
+                    if(isSS)
+                        move_ss_mem_to_reg_noalloc(4*compileTable[k].regNum,
+                                                   PhysicalReg_FP, true,
+                                                   MemoryAccess_VR, compileTable[k].regNum,
+                                                   targetReg, true);
+                    else
+                        move_mem_to_reg_noalloc(oSize, 4*compileTable[k].regNum,
+                                                PhysicalReg_FP, true,
+                                                MemoryAccess_VR, compileTable[k].regNum,
+                                                targetReg, true);
+                }
+                if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg != PhysicalReg_Null) {
+                    move_reg_to_reg_noalloc((isSS ? OpndSize_64 : oSize),
+                                            compileTable[k].physicalReg, true,
+                                            targetReg, true);
+                }
+                if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg == PhysicalReg_Null) {
+                    dumpToMem(compileTable[k].regNum, (LowOpndRegType)(compileTable[k].physicalType & MASK_FOR_TYPE),
+                              compileTable[k].physicalReg);
+                }
+            } //VR
+            if(compileTable[k].physicalReg != targetReg && !isVirtualReg(compileTable[k].physicalType)) {
+                OpndSize oSize = getRegSize(compileTable[k].physicalType);
+                if(compileTable[k].physicalReg == PhysicalReg_Null && targetReg != PhysicalReg_Null) {
+                    loadFromSpillRegion(oSize, targetReg,
+                                        compileTable[k].spill_loc_index);
+                }
+                //both are not null, move from one to the other
+                if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg != PhysicalReg_Null) {
+                    move_reg_to_reg_noalloc(oSize, compileTable[k].physicalReg, true,
+                                            targetReg, true);
+                }
+                //current is not null, target is null (move from reg to memory)
+                if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg == PhysicalReg_Null) {
+                    saveToSpillRegion(oSize, compileTable[k].physicalReg, targetSpill);
+                }
+            } //temporary
+        }//for
+    }//for
+    for(k = 0; k < num_memory_vr; k++) {
+        bool targetBool = false;
+        int targetReg = -1;
+        if(stateNum == 1) {
+            targetReg = stateTable2_1[k].regNum;
+            targetBool = stateTable2_1[k].inMemory;
+        }
+        else if(stateNum == 2) {
+            targetReg = stateTable2_2[k].regNum;
+            targetBool = stateTable2_2[k].inMemory;
+        }
+        else if(stateNum == 3) {
+            targetReg = stateTable2_3[k].regNum;
+            targetBool = stateTable2_3[k].inMemory;
+        }
+        else if(stateNum == 4) {
+            targetReg = stateTable2_4[k].regNum;
+            targetBool = stateTable2_4[k].inMemory;
+        }
+        if(targetReg != memVRTable[k].regNum)
+            ALOGE("regNum mismatch in transferToState");
+        if(targetBool && (!memVRTable[k].inMemory)) {
+            //dump to memory, check entries in compileTable: vA gp vA xmm vA ss
+#ifdef DEBUG_STATE
+            ALOGW("inMemory mismatch for VR %d in transferToState", targetReg);
+#endif
+            bool doneXfer = false;
+            int index = searchCompileTable(LowOpndRegType_xmm | LowOpndRegType_virtual, targetReg);
+            if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+                dumpToMem(targetReg, LowOpndRegType_xmm, compileTable[index].physicalReg);
+                doneXfer = true;
+            }
+            if(!doneXfer) { //vA-1, xmm
+                index = searchCompileTable(LowOpndRegType_xmm | LowOpndRegType_virtual, targetReg-1);
+                if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+                    dumpToMem(targetReg-1, LowOpndRegType_xmm, compileTable[index].physicalReg);
+                    doneXfer = true;
+                }
+            }
+            if(!doneXfer) { //vA gp
+                index = searchCompileTable(LowOpndRegType_gp | LowOpndRegType_virtual, targetReg);
+                if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+                    dumpToMem(targetReg, LowOpndRegType_gp, compileTable[index].physicalReg);
+                    doneXfer = true;
+                }
+            }
+            if(!doneXfer) { //vA, ss
+                index = searchCompileTable(LowOpndRegType_ss | LowOpndRegType_virtual, targetReg);
+                if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) {
+                    dumpToMem(targetReg, LowOpndRegType_ss, compileTable[index].physicalReg);
+                    doneXfer = true;
+                }
+            }
+            if(!doneXfer) ALOGW("can't match inMemory of VR %d in transferToState", targetReg);
+        }
+        if((!targetBool) && memVRTable[k].inMemory) {
+            //do nothing
+        }
+    }
+#ifdef DEBUG_STATE
+    ALOGI("END transferToState %d", stateNum);
+#endif
+    goToState(stateNum);
+}
+/* END code to handle state transfers */
diff --git a/vm/compiler/codegen/x86/AnalysisO1.h b/vm/compiler/codegen/x86/AnalysisO1.h
new file mode 100644
index 0000000..7f436d9
--- /dev/null
+++ b/vm/compiler/codegen/x86/AnalysisO1.h
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file ncg_o1_data.h
+    \brief A header file to define data structures used by register allocator & const folding
+*/
+#ifndef _DALVIK_NCG_ANALYSISO1_H
+#define _DALVIK_NCG_ANALYSISO1_H
+
+#include "Dalvik.h"
+#include "enc_wrapper.h"
+#include "Lower.h"
+#ifdef WITH_JIT
+#include "compiler/CompilerIR.h"
+#endif
+
+//! maximal number of edges per basic block
+#define MAX_NUM_EDGE_PER_BB 300
+//! maximal number of basic blocks per method
+#define MAX_NUM_BBS_PER_METHOD 1000
+//! maximal number of virtual registers per basic block
+#define MAX_REG_PER_BASICBLOCK 140
+//! maximal number of virtual registers per bytecode
+#define MAX_REG_PER_BYTECODE 40
+//! maximal number of virtual registers per method
+#define MAX_REG_PER_METHOD 200
+//! maximal number of temporaries per bytecode
+#define MAX_TEMP_REG_PER_BYTECODE 30
+//! maximal number of GG GPR VRs in a method
+#define MAX_GLOBAL_VR      2
+//! maximal number of GG XMM VRs in a method
+#define MAX_GLOBAL_VR_XMM  4
+#define MAX_CONST_REG 150
+
+#define MASK_FOR_TYPE 7 //last 3 bits 111
+
+#define LOOP_COUNT 10
+//! maximal number of entries in compileTable
+#define COMPILE_TABLE_SIZE 200
+//! maximal number of transfer points per basic block
+#define MAX_XFER_PER_BB 1000  //on Jan 4
+#define PC_FOR_END_OF_BB -999
+#define PC_FOR_START_OF_BB -998
+
+//! various cases of overlapping between 2 variables
+typedef enum OverlapCase {
+  OVERLAP_ALIGN = 0,
+  OVERLAP_B_IS_LOW_OF_A,
+  OVERLAP_B_IS_HIGH_OF_A,
+  OVERLAP_LOW_OF_A_IS_HIGH_OF_B,
+  OVERLAP_HIGH_OF_A_IS_LOW_OF_B,
+  OVERLAP_A_IS_LOW_OF_B,
+  OVERLAP_A_IS_HIGH_OF_B,
+  OVERLAP_B_COVER_A,
+  OVERLAP_B_COVER_LOW_OF_A,
+  OVERLAP_B_COVER_HIGH_OF_A,
+  OVERLAP_NO
+} OverlapCase;
+
+//!access type of a variable
+typedef enum RegAccessType {
+  REGACCESS_D = 0,
+  REGACCESS_U,
+  REGACCESS_DU,
+  REGACCESS_UD,
+  REGACCESS_L,
+  REGACCESS_H,
+  REGACCESS_UL,
+  REGACCESS_UH,
+  REGACCESS_LU,
+  REGACCESS_HU,
+  REGACCESS_N, //no access
+  REGACCESS_UNKNOWN
+} RegAccessType;
+//! a variable can be local (L), globally local (GL) or global (GG)
+typedef enum GlobalType {
+  GLOBALTYPE_GG,
+  GLOBALTYPE_GL,
+  GLOBALTYPE_L
+} GlobalType;
+typedef enum VRState {
+  VRSTATE_SPILLED,
+  VRSTATE_UPDATED,
+  VRSTATE_CLEAN
+} VRState;
+//! helper state to determine if freeing VRs needs to be delayed
+enum VRDelayFreeFlags {
+  VRDELAY_NONE = 0, // used when VR can be freed from using physical register if needed
+  VRDELAY_NULLCHECK = 1 << 0, // used when VR is used for null check and freeing must be delayed
+  VRDELAY_BOUNDCHECK = 1 << 1 // used when VR is used for bound check and freeing must be delayed
+};
+typedef enum TRState { //state of temporary registers
+  TRSTATE_SPILLED,
+  TRSTATE_UNSPILLED,
+  TRSTATE_CLEAN
+} TRState;
+//!information about a physical register
+typedef struct RegisterInfo {
+  PhysicalReg physicalReg;
+  bool isUsed;
+  bool isCalleeSaved;
+  int freeTimeStamp;
+} RegisterInfo;
+typedef struct UniqueRegister {
+  LowOpndRegType physicalType;
+  int regNum;
+  int numExposedUsage;
+  PhysicalReg physicalReg;
+} UniqueRegister;
+//!specifies the weight of a VR allocated to a specific physical register
+//!it is used for GPR VR only
+typedef struct RegAllocConstraint {
+  PhysicalReg physicalReg;
+  int count;
+} RegAllocConstraint;
+
+typedef enum XferType {
+  XFER_MEM_TO_XMM, //for usage
+  XFER_DEF_TO_MEM, //def is gp
+  XFER_DEF_TO_GP_MEM,
+  XFER_DEF_TO_GP,
+  XFER_DEF_IS_XMM //def is xmm
+} XferType;
+typedef struct XferPoint {
+  int tableIndex; //generated from a def-use pair
+  XferType xtype;
+  int offsetPC;
+  int regNum; //get or set VR at offsetPC
+  LowOpndRegType physicalType;
+
+  //if XFER_DEF_IS_XMM
+  int vr_gpl; //a gp VR that uses the lower half of the def
+  int vr_gph;
+  bool dumpToXmm;
+  bool dumpToMem;
+} XferPoint;
+
+//!for def: accessType means which part of the VR defined at offestPC is live now
+//!for use: accessType means which part of the usage comes from the reachingDef
+typedef struct DefOrUse {
+  int offsetPC; //!the program point
+  int regNum; //!access the virtual reg
+  LowOpndRegType physicalType; //!xmm or gp or ss
+  RegAccessType accessType; //!D, L, H, N
+} DefOrUse;
+//!a link list of DefOrUse
+typedef struct DefOrUseLink {
+  int offsetPC;
+  int regNum; //access the virtual reg
+  LowOpndRegType physicalType; //xmm or gp
+  RegAccessType accessType; //D, L, H, N
+  struct DefOrUseLink* next;
+} DefOrUseLink;
+//!pair of def and uses
+typedef struct DefUsePair {
+  DefOrUseLink* uses;
+  DefOrUseLink* useTail;
+  int num_uses;
+  DefOrUse def;
+  struct DefUsePair* next;
+} DefUsePair;
+
+//!information associated with a virtual register
+//!the pair <regNum, physicalType> uniquely determines a variable
+typedef struct VirtualRegInfo {
+  int regNum;
+  LowOpndRegType physicalType;
+  int refCount;
+  RegAccessType accessType;
+  GlobalType gType;
+  int physicalReg_GG;
+  RegAllocConstraint allocConstraints[8];
+  RegAllocConstraint allocConstraintsSorted[8];
+
+  DefOrUse reachingDefs[3]; //!reaching defs to the virtual register
+  int num_reaching_defs;
+} VirtualRegInfo;
+//!information of whether a VR is constant and its value
+typedef struct ConstVRInfo {
+  int regNum;
+  int value;
+  bool isConst;
+} ConstVRInfo;
+#define NUM_ACCESS_IN_LIVERANGE 10
+//!specifies one live range
+typedef struct LiveRange {
+  int start;
+  int end; //inclusive
+  //all accesses in the live range
+  int num_access;
+  int num_alloc;
+  int* accessPC;
+  struct LiveRange* next;
+} LiveRange;
+typedef struct BoundCheckIndex {
+  int indexVR;
+  bool checkDone;
+} BoundCheckIndex;
+//!information for a virtual register such as live ranges, in memory
+typedef struct MemoryVRInfo {
+  int regNum;
+  bool inMemory;
+  bool nullCheckDone;
+  BoundCheckIndex boundCheck;
+  int num_ranges;
+  LiveRange* ranges;
+  u4 delayFreeFlags; //! for use with flags defined by VRDelayFreeFlags enum
+} MemoryVRInfo;
+//!information of a temporary
+//!the pair <regNum, physicalType> uniquely determines a variable
+typedef struct TempRegInfo {
+  int regNum;
+  int physicalType;
+  int refCount;
+  int linkageToVR;
+  int versionNum;
+  bool shareWithVR; //for temp. regs updated by get_virtual_reg
+  bool is8Bit;
+} TempRegInfo;
+struct BasicBlock_O1;
+//!all variables accessed
+//!the pair <regNum, physicalType> uniquely determines a variable
+typedef struct compileTableEntry {
+  int regNum;
+  int physicalType; //gp, xmm or scratch, virtual
+  int physicalReg;
+  int physicalReg_prev; //for spilled GG VR
+  RegAccessType accessType;
+
+  bool isConst;
+  int value[2]; //[0]: lower [1]: higher
+  int refCount;
+
+  int linkageToVR; //for temporary registers only
+  GlobalType gType;
+  struct BasicBlock_O1* bb; //bb VR belongs to
+  int indexToInfoBB;
+
+  VRState regState;
+  TRState trState; //for temporary registers only
+  int spill_loc_index; //for temporary registers only
+} compileTableEntry;
+//!to save the state of register allocator
+typedef struct regAllocStateEntry1 {
+  int spill_loc_index;
+  int physicalReg;
+} regAllocStateEntry1;
+typedef struct regAllocStateEntry2 {
+  int regNum; //
+  bool inMemory; //whether 4-byte virtual reg is in memory
+} regAllocStateEntry2;
+//!edge in control flow graph
+typedef struct Edge_O1 {
+  struct BasicBlock_O1* src;
+  struct BasicBlock_O1* dst;
+} Edge_O1;
+//!information associated with a basic block
+typedef struct BasicBlock_O1 {
+  int bb_index;
+  int bb_index2;
+  int pc_start;       //!inclusive
+#ifndef WITH_JIT
+  int pc_end;         //!exclusive
+  Edge_O1* in_edges[MAX_NUM_EDGE_PER_BB]; //array of Edge*
+  int num_in_edges;
+  Edge_O1* out_edges[MAX_NUM_EDGE_PER_BB];
+  int num_out_edges;
+#else
+  int pc_end;
+  BasicBlock* jitBasicBlock;
+#endif
+  VirtualRegInfo infoBasicBlock[MAX_REG_PER_BASICBLOCK];
+  int num_regs;
+
+  RegAllocConstraint allocConstraints[8]; //# of times a hardcoded register is used in this basic block
+  //a physical register that is used many times has a lower priority to get picked in getFreeReg
+  RegAllocConstraint allocConstraintsSorted[8]; //count from low to high
+
+  DefUsePair* defUseTable;
+  DefUsePair* defUseTail;
+  int num_defs;
+  XferPoint xferPoints[MAX_XFER_PER_BB]; //program points where the transfer is required
+  int num_xfer_points;
+
+  bool endsWithReturn;
+  bool hasAccessToGlue;
+} BasicBlock_O1;
+typedef struct CFG_O1 {
+  BasicBlock_O1* head;
+} CFG_O1;
+//!worklist to create a control flow graph
+typedef struct CFGWork {
+  BasicBlock_O1* bb_prev;
+  int targetOff;
+  struct CFGWork* nextItem;
+} CFGWork;
+
+/////////////////////////////////////////
+extern compileTableEntry compileTable[COMPILE_TABLE_SIZE];
+extern int num_compile_entries;
+extern VirtualRegInfo infoByteCode[MAX_REG_PER_BYTECODE];
+extern int num_regs_per_bytecode;
+extern TempRegInfo infoByteCodeTemp[MAX_TEMP_REG_PER_BYTECODE];
+extern int num_temp_regs_per_bytecode;
+extern VirtualRegInfo infoMethod[MAX_REG_PER_METHOD];
+extern int num_regs_per_method;
+extern BasicBlock_O1* currentBB;
+
+extern BasicBlock_O1* method_bbs[MAX_NUM_BBS_PER_METHOD];
+extern int num_bbs_for_method;
+extern BasicBlock_O1* method_bbs_sorted[MAX_NUM_BBS_PER_METHOD];
+extern BasicBlock_O1* bb_entry;
+extern int pc_start;
+extern int pc_end;
+extern int current_bc_size;
+extern int num_exception_handlers;
+extern int exceptionHandlers[10];
+
+extern int num_const_vr;
+extern ConstVRInfo constVRTable[MAX_CONST_REG];
+
+extern int genSet[MAX_REG_PER_BYTECODE];
+extern int killSet[MAX_REG_PER_BYTECODE];
+extern int num_regs_gen; //per bytecode
+extern int num_regs_kill; //per bytecode
+
+extern int genSetBB[MAX_NUM_BBS_PER_METHOD][40];
+extern int killSetBB[MAX_NUM_BBS_PER_METHOD][40]; //same as size of memVRTable
+extern int num_gen_bb[MAX_NUM_BBS_PER_METHOD];
+extern int num_kill_bb[MAX_NUM_BBS_PER_METHOD];
+
+extern int nullCheck_inB[MAX_NUM_BBS_PER_METHOD][40];
+extern int nullCheck_inSize[MAX_NUM_BBS_PER_METHOD];
+extern int nullCheck_outB[MAX_NUM_BBS_PER_METHOD][40];
+extern int nullCheck_outSize[MAX_NUM_BBS_PER_METHOD];
+
+typedef enum GlueVarType {
+  RES_CLASS = 0,
+  RES_METHOD,
+  RES_FIELD,
+  RES_STRING,
+  GLUE_DVMDEX,
+  GLUE_METHOD_CLASS,
+  GLUE_METHOD
+} GlueVarType;
+
+void forwardAnalysis(int type);
+
+//functions in bc_visitor.c
+int getByteCodeSize();
+bool getConstInfo(BasicBlock_O1* bb);
+int getVirtualRegInfo(VirtualRegInfo* infoArray);
+int getTempRegInfo(TempRegInfo* infoArray);
+int createCFGHandler(Method* method);
+
+int findVirtualRegInTable(u2 vA, LowOpndRegType type, bool printError);
+int searchCompileTable(int type, int regNum);
+BasicBlock_O1* createBasicBlock(int src_pc, int end_pc);
+void handleJump(BasicBlock_O1* bb_prev, int relOff);
+void connectBasicBlock(BasicBlock_O1* src, BasicBlock_O1* dst);
+int insertWorklist(BasicBlock_O1* bb_prev, int targetOff);
+
+int collectInfoOfBasicBlock(Method* method, BasicBlock_O1* bb); //update bb->infoBasicBlock
+
+void updateCurrentBBWithConstraints(PhysicalReg reg);
+void updateConstInfo(BasicBlock_O1*);
+OpndSize getRegSize(int type);
+void invalidateVRDueToConst(int reg, OpndSize size);
+#endif
+
diff --git a/vm/compiler/codegen/x86/ArchUtility.cpp b/vm/compiler/codegen/x86/ArchUtility.cpp
deleted file mode 100644
index e7b7d70..0000000
--- a/vm/compiler/codegen/x86/ArchUtility.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "../../CompilerInternals.h"
-#include "libdex/DexOpcodes.h"
-#include "X86LIR.h"
-
-/* Dump instructions and constant pool contents */
-void dvmCompilerCodegenDump(CompilationUnit *cUnit)
-{
-}
-
-/* Target-specific cache flushing (not needed for x86 */
-int dvmCompilerCacheFlush(long start, long end, long flags)
-{
-    return 0;
-}
-
-/* Target-specific cache clearing */
-void dvmCompilerCacheClear(char *start, size_t size)
-{
-    /* 0 is an invalid opcode for x86. */
-    memset(start, 0, size);
-}
diff --git a/vm/compiler/codegen/x86/Assemble.cpp b/vm/compiler/codegen/x86/Assemble.cpp
deleted file mode 100644
index 03edbf1..0000000
--- a/vm/compiler/codegen/x86/Assemble.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Dalvik.h"
-#include "libdex/DexOpcodes.h"
-
-#include "../../CompilerInternals.h"
-#include "X86LIR.h"
-#include "Codegen.h"
-#include <sys/mman.h>           /* for protection change */
-
-#define MAX_ASSEMBLER_RETRIES 10
-
-
-/* Track the number of times that the code cache is patched */
-#if defined(WITH_JIT_TUNING)
-#define UPDATE_CODE_CACHE_PATCHES()    (gDvmJit.codeCachePatches++)
-#else
-#define UPDATE_CODE_CACHE_PATCHES()
-#endif
-
-/*
- * Translation layout in the code cache.  Note that the codeAddress pointer
- * in JitTable will point directly to the code body (field codeAddress).  The
- * chain cell offset codeAddress - 2, and (if present) executionCount is at
- * codeAddress - 6.
- *
- *      +----------------------------+
- *      | Execution count            |  -> [Optional] 4 bytes
- *      +----------------------------+
- *   +--| Offset to chain cell counts|  -> 2 bytes
- *   |  +----------------------------+
- *   |  | Code body                  |  -> Start address for translation
- *   |  |                            |     variable in 2-byte chunks
- *   |  .                            .     (JitTable's codeAddress points here)
- *   |  .                            .
- *   |  |                            |
- *   |  +----------------------------+
- *   |  | Chaining Cells             |  -> 16 bytes each, 8 byte aligned
- *   |  .                            .
- *   |  .                            .
- *   |  |                            |
- *   |  +----------------------------+
- *   |  | Gap for large switch stmt  |  -> # cases >= MAX_CHAINED_SWITCH_CASES
- *   |  +----------------------------+
- *   +->| Chaining cell counts       |  -> 8 bytes, chain cell counts by type
- *      +----------------------------+
- *      | Trace description          |  -> variable sized
- *      .                            .
- *      |                            |
- *      +----------------------------+
- *      | Literal pool               |  -> 4-byte aligned, variable size
- *      .                            .     Note: for x86 literals will
- *      .                            .     generally appear inline.
- *      |                            |
- *      +----------------------------+
- *
- * Go over each instruction in the list and calculate the offset from the top
- * before sending them off to the assembler. If out-of-range branch distance is
- * seen rearrange the instructions a bit to correct it.
- */
-void dvmCompilerAssembleLIR(CompilationUnit *cUnit, JitTranslationInfo *info)
-{
-}
-
-/*
- * Perform translation chain operation.
- */
-void* dvmJitChain(void* tgtAddr, u4* branchAddr)
-{
-    return 0;
-}
-
-/*
- * This method is called from the invoke templates for virtual and interface
- * methods to speculatively setup a chain to the callee. The templates are
- * written in assembly and have setup method, cell, and clazz at r0, r2, and
- * r3 respectively, so there is a unused argument in the list. Upon return one
- * of the following three results may happen:
- *   1) Chain is not setup because the callee is native. Reset the rechain
- *      count to a big number so that it will take a long time before the next
- *      rechain attempt to happen.
- *   2) Chain is not setup because the callee has not been created yet. Reset
- *      the rechain count to a small number and retry in the near future.
- *   3) Enqueue the new content for the chaining cell which will be appled in
- *      next safe point.
- */
-const Method *dvmJitToPatchPredictedChain(const Method *method,
-                                          Thread *self,
-                                          PredictedChainingCell *cell,
-                                          const ClassObject *clazz)
-{
-    return 0;
-}
-
-/*
- * Patch the inline cache content based on the content passed from the work
- * order.
- */
-void dvmCompilerPatchInlineCache(void)
-{
-}
-
-/*
- * Unchain a trace given the starting address of the translation
- * in the code cache.  Refer to the diagram in dvmCompilerAssembleLIR.
- * Returns the address following the last cell unchained.  Note that
- * the incoming codeAddr is a thumb code address, and therefore has
- * the low bit set.
- */
-u4* dvmJitUnchain(void* codeAddr)
-{
-    return 0;
-}
-
-/* Unchain all translation in the cache. */
-void dvmJitUnchainAll()
-{
-}
-
-/* Create a copy of the trace descriptor of an existing compilation */
-JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc,
-                                            const JitEntry *knownEntry)
-{
-    return 0;
-}
-
-/* Sort the trace profile counts and dump them */
-void dvmCompilerSortAndPrintTraceProfiles()
-{
-}
-
-void dvmJitScanAllClassPointers(void (*callback)(void *))
-{
-}
diff --git a/vm/compiler/codegen/x86/BytecodeVisitor.cpp b/vm/compiler/codegen/x86/BytecodeVisitor.cpp
new file mode 100644
index 0000000..1d3c70e
--- /dev/null
+++ b/vm/compiler/codegen/x86/BytecodeVisitor.cpp
@@ -0,0 +1,5468 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file BytecodeVisitor.cpp
+    \brief This file implements visitors of the bytecode
+*/
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "AnalysisO1.h"
+
+//! Returns size of the current bytecode in u2 unit
+
+//!
+int getByteCodeSize() { //uses inst, unit in u2
+    switch (INST_INST(inst)) {
+    case OP_NOP:
+        return 1;
+    case OP_MOVE:
+    case OP_MOVE_OBJECT:
+        return 1;
+    case OP_MOVE_FROM16:
+    case OP_MOVE_OBJECT_FROM16:
+        return 2;
+    case OP_MOVE_16:
+    case OP_MOVE_OBJECT_16:
+        return 3;
+    case OP_MOVE_WIDE:
+        return 1;
+    case OP_MOVE_WIDE_FROM16:
+        return 2;
+    case OP_MOVE_WIDE_16:
+        return 3;
+    case OP_MOVE_RESULT:
+    case OP_MOVE_RESULT_OBJECT:
+        return 1;
+    case OP_MOVE_RESULT_WIDE:
+        return 1;
+    case OP_MOVE_EXCEPTION:
+        return 1;
+    case OP_RETURN_VOID:
+    case OP_RETURN_VOID_BARRIER:
+        return 1;
+    case OP_RETURN:
+    case OP_RETURN_OBJECT:
+        return 1;
+    case OP_RETURN_WIDE:
+        return 1;
+    case OP_CONST_4:
+        return 1;
+    case OP_CONST_16:
+        return 2;
+    case OP_CONST:
+        return 3;
+    case OP_CONST_HIGH16:
+        return 2;
+    case OP_CONST_WIDE_16:
+        return 2;
+    case OP_CONST_WIDE_32:
+        return 3;
+    case OP_CONST_WIDE:
+        return 5;
+    case OP_CONST_WIDE_HIGH16:
+        return 2;
+    case OP_CONST_STRING:
+        return 2;
+    case OP_CONST_STRING_JUMBO:
+        return 3;
+    case OP_CONST_CLASS:
+        return 2;
+    case OP_MONITOR_ENTER:
+        return 1;
+    case OP_MONITOR_EXIT:
+        return 1;
+    case OP_CHECK_CAST:
+        return 2;
+    case OP_INSTANCE_OF:
+        return 2;
+    case OP_ARRAY_LENGTH:
+        return 1;
+    case OP_NEW_INSTANCE:
+        return 2;
+    case OP_NEW_ARRAY:
+        return 2;
+    case OP_FILLED_NEW_ARRAY:
+        return 3;
+    case OP_FILLED_NEW_ARRAY_RANGE:
+        return 3;
+    case OP_FILL_ARRAY_DATA:
+        return 3;
+    case OP_THROW:
+        return 1;
+    case OP_THROW_VERIFICATION_ERROR:
+        return 2;
+    case OP_GOTO:
+        return 1;
+    case OP_GOTO_16:
+        return 2;
+    case OP_GOTO_32:
+        return 3;
+    case OP_PACKED_SWITCH:
+        return 3;
+    case OP_SPARSE_SWITCH:
+        return 3;
+    case OP_CMPL_FLOAT:
+        return 2;
+    case OP_CMPG_FLOAT:
+        return 2;
+    case OP_CMPL_DOUBLE:
+        return 2;
+    case OP_CMPG_DOUBLE:
+        return 2;
+    case OP_CMP_LONG:
+        return 2;
+    case OP_IF_EQ:
+        return 2;
+    case OP_IF_NE:
+        return 2;
+    case OP_IF_LT:
+        return 2;
+    case OP_IF_GE:
+        return 2;
+    case OP_IF_GT:
+        return 2;
+    case OP_IF_LE:
+        return 2;
+    case OP_IF_EQZ:
+        return 2;
+    case OP_IF_NEZ:
+        return 2;
+    case OP_IF_LTZ:
+        return 2;
+    case OP_IF_GEZ:
+        return 2;
+    case OP_IF_GTZ:
+        return 2;
+    case OP_IF_LEZ:
+        return 2;
+    case OP_AGET:
+        return 2;
+    case OP_AGET_WIDE:
+        return 2;
+    case OP_AGET_OBJECT:
+        return 2;
+    case OP_AGET_BOOLEAN:
+        return 2;
+    case OP_AGET_BYTE:
+        return 2;
+    case OP_AGET_CHAR:
+        return 2;
+    case OP_AGET_SHORT:
+        return 2;
+    case OP_APUT:
+        return 2;
+    case OP_APUT_WIDE:
+        return 2;
+    case OP_APUT_OBJECT:
+        return 2;
+    case OP_APUT_BOOLEAN:
+        return 2;
+    case OP_APUT_BYTE:
+        return 2;
+    case OP_APUT_CHAR:
+        return 2;
+    case OP_APUT_SHORT:
+        return 2;
+    case OP_IGET:
+    case OP_IGET_WIDE:
+    case OP_IGET_OBJECT:
+    case OP_IGET_VOLATILE:
+    case OP_IGET_WIDE_VOLATILE:
+    case OP_IGET_OBJECT_VOLATILE:
+    case OP_IGET_BOOLEAN:
+    case OP_IGET_BYTE:
+    case OP_IGET_CHAR:
+    case OP_IGET_SHORT:
+    case OP_IPUT:
+    case OP_IPUT_WIDE:
+    case OP_IPUT_OBJECT:
+    case OP_IPUT_VOLATILE:
+    case OP_IPUT_WIDE_VOLATILE:
+    case OP_IPUT_OBJECT_VOLATILE:
+    case OP_IPUT_BOOLEAN:
+    case OP_IPUT_BYTE:
+    case OP_IPUT_CHAR:
+    case OP_IPUT_SHORT:
+        return 2;
+    case OP_SGET:
+    case OP_SGET_WIDE:
+    case OP_SGET_OBJECT:
+    case OP_SGET_VOLATILE:
+    case OP_SGET_WIDE_VOLATILE:
+    case OP_SGET_OBJECT_VOLATILE:
+    case OP_SGET_BOOLEAN:
+    case OP_SGET_BYTE:
+    case OP_SGET_CHAR:
+    case OP_SGET_SHORT:
+    case OP_SPUT:
+    case OP_SPUT_WIDE:
+    case OP_SPUT_OBJECT:
+    case OP_SPUT_VOLATILE:
+    case OP_SPUT_WIDE_VOLATILE:
+    case OP_SPUT_OBJECT_VOLATILE:
+    case OP_SPUT_BOOLEAN:
+    case OP_SPUT_BYTE:
+    case OP_SPUT_CHAR:
+    case OP_SPUT_SHORT:
+        return 2;
+    case OP_INVOKE_VIRTUAL:
+    case OP_INVOKE_SUPER:
+    case OP_INVOKE_DIRECT:
+    case OP_INVOKE_STATIC:
+    case OP_INVOKE_INTERFACE:
+    case OP_INVOKE_VIRTUAL_RANGE:
+    case OP_INVOKE_SUPER_RANGE:
+    case OP_INVOKE_DIRECT_RANGE:
+    case OP_INVOKE_STATIC_RANGE:
+    case OP_INVOKE_INTERFACE_RANGE:
+        return 3;
+
+    case OP_NEG_INT:
+    case OP_NOT_INT:
+    case OP_NEG_LONG:
+    case OP_NOT_LONG:
+    case OP_NEG_FLOAT:
+    case OP_NEG_DOUBLE:
+    case OP_INT_TO_LONG:
+    case OP_INT_TO_FLOAT:
+    case OP_INT_TO_DOUBLE:
+    case OP_LONG_TO_INT:
+    case OP_LONG_TO_FLOAT:
+    case OP_LONG_TO_DOUBLE:
+    case OP_FLOAT_TO_INT:
+    case OP_FLOAT_TO_LONG:
+    case OP_FLOAT_TO_DOUBLE:
+    case OP_DOUBLE_TO_INT:
+    case OP_DOUBLE_TO_LONG:
+    case OP_DOUBLE_TO_FLOAT:
+    case OP_INT_TO_BYTE:
+    case OP_INT_TO_CHAR:
+    case OP_INT_TO_SHORT:
+        return 1;
+
+    case OP_ADD_INT:
+    case OP_SUB_INT:
+    case OP_MUL_INT:
+    case OP_DIV_INT:
+    case OP_REM_INT:
+    case OP_AND_INT:
+    case OP_OR_INT:
+    case OP_XOR_INT:
+    case OP_SHL_INT:
+    case OP_SHR_INT:
+    case OP_USHR_INT:
+    case OP_ADD_LONG:
+    case OP_SUB_LONG:
+    case OP_MUL_LONG:
+    case OP_DIV_LONG:
+    case OP_REM_LONG:
+    case OP_AND_LONG:
+    case OP_OR_LONG:
+    case OP_XOR_LONG:
+    case OP_SHL_LONG:
+    case OP_SHR_LONG:
+    case OP_USHR_LONG:
+    case OP_ADD_FLOAT:
+    case OP_SUB_FLOAT:
+    case OP_MUL_FLOAT:
+    case OP_DIV_FLOAT:
+    case OP_REM_FLOAT:
+    case OP_ADD_DOUBLE:
+    case OP_SUB_DOUBLE:
+    case OP_MUL_DOUBLE:
+    case OP_DIV_DOUBLE:
+    case OP_REM_DOUBLE:
+        return 2;
+
+    case OP_ADD_INT_2ADDR:
+    case OP_SUB_INT_2ADDR:
+    case OP_MUL_INT_2ADDR:
+    case OP_DIV_INT_2ADDR:
+    case OP_REM_INT_2ADDR:
+    case OP_AND_INT_2ADDR:
+    case OP_OR_INT_2ADDR:
+    case OP_XOR_INT_2ADDR:
+    case OP_SHL_INT_2ADDR:
+    case OP_SHR_INT_2ADDR:
+    case OP_USHR_INT_2ADDR:
+    case OP_ADD_LONG_2ADDR:
+    case OP_SUB_LONG_2ADDR:
+    case OP_MUL_LONG_2ADDR:
+    case OP_DIV_LONG_2ADDR:
+    case OP_REM_LONG_2ADDR:
+    case OP_AND_LONG_2ADDR:
+    case OP_OR_LONG_2ADDR:
+    case OP_XOR_LONG_2ADDR:
+    case OP_SHL_LONG_2ADDR:
+    case OP_SHR_LONG_2ADDR:
+    case OP_USHR_LONG_2ADDR:
+    case OP_ADD_FLOAT_2ADDR:
+    case OP_SUB_FLOAT_2ADDR:
+    case OP_MUL_FLOAT_2ADDR:
+    case OP_DIV_FLOAT_2ADDR:
+    case OP_REM_FLOAT_2ADDR:
+    case OP_ADD_DOUBLE_2ADDR:
+    case OP_SUB_DOUBLE_2ADDR:
+    case OP_MUL_DOUBLE_2ADDR:
+    case OP_DIV_DOUBLE_2ADDR:
+    case OP_REM_DOUBLE_2ADDR:
+        return 1;
+
+    case OP_ADD_INT_LIT16:
+    case OP_RSUB_INT:
+    case OP_MUL_INT_LIT16:
+    case OP_DIV_INT_LIT16:
+    case OP_REM_INT_LIT16:
+    case OP_AND_INT_LIT16:
+    case OP_OR_INT_LIT16:
+    case OP_XOR_INT_LIT16:
+        return 2;
+
+    case OP_ADD_INT_LIT8:
+    case OP_RSUB_INT_LIT8:
+    case OP_MUL_INT_LIT8:
+    case OP_DIV_INT_LIT8:
+    case OP_REM_INT_LIT8:
+    case OP_AND_INT_LIT8:
+    case OP_OR_INT_LIT8:
+    case OP_XOR_INT_LIT8:
+    case OP_SHL_INT_LIT8:
+    case OP_SHR_INT_LIT8:
+    case OP_USHR_INT_LIT8:
+        return 2;
+
+    case OP_EXECUTE_INLINE:
+    case OP_EXECUTE_INLINE_RANGE:
+        return 3;
+#if FIXME
+    case OP_INVOKE_OBJECT_INIT_RANGE:
+        return 3;
+#endif
+
+    case OP_IGET_QUICK:
+    case OP_IGET_WIDE_QUICK:
+    case OP_IGET_OBJECT_QUICK:
+    case OP_IPUT_QUICK:
+    case OP_IPUT_WIDE_QUICK:
+    case OP_IPUT_OBJECT_QUICK:
+        return 2;
+
+    case OP_INVOKE_VIRTUAL_QUICK:
+    case OP_INVOKE_VIRTUAL_QUICK_RANGE:
+    case OP_INVOKE_SUPER_QUICK:
+    case OP_INVOKE_SUPER_QUICK_RANGE:
+        return 3;
+#ifdef SUPPORT_HLO
+    case kExtInstruction:
+        switch(inst) {
+        case OP_X_AGET_QUICK:
+        case OP_X_AGET_WIDE_QUICK:
+        case OP_X_AGET_OBJECT_QUICK:
+    case OP_X_AGET_BOOLEAN_QUICK:
+    case OP_X_AGET_BYTE_QUICK:
+    case OP_X_AGET_CHAR_QUICK:
+    case OP_X_AGET_SHORT_QUICK:
+    case OP_X_APUT_QUICK:
+    case OP_X_APUT_WIDE_QUICK:
+    case OP_X_APUT_OBJECT_QUICK:
+    case OP_X_APUT_BOOLEAN_QUICK:
+    case OP_X_APUT_BYTE_QUICK:
+    case OP_X_APUT_CHAR_QUICK:
+    case OP_X_APUT_SHORT_QUICK:
+        return 3;
+    case OP_X_DEREF_GET:
+    case OP_X_DEREF_GET_OBJECT:
+    case OP_X_DEREF_GET_WIDE:
+    case OP_X_DEREF_GET_BOOLEAN:
+    case OP_X_DEREF_GET_BYTE:
+    case OP_X_DEREF_GET_CHAR:
+    case OP_X_DEREF_GET_SHORT:
+    case OP_X_DEREF_PUT:
+    case OP_X_DEREF_PUT_WIDE:
+    case OP_X_DEREF_PUT_OBJECT:
+    case OP_X_DEREF_PUT_BOOLEAN:
+    case OP_X_DEREF_PUT_BYTE:
+    case OP_X_DEREF_PUT_CHAR:
+    case OP_X_DEREF_PUT_SHORT:
+        return 2;
+    case OP_X_ARRAY_CHECKS:
+    case OP_X_ARRAY_OBJECT_CHECKS:
+        return 3;
+    case OP_X_CHECK_BOUNDS:
+    case OP_X_CHECK_NULL:
+    case OP_X_CHECK_TYPE:
+        return 2;
+    }
+#endif
+    }
+    return -1;
+}
+//! reduces refCount of a virtual register
+
+//!
+void touchOneVR(u2 vA, LowOpndRegType type) {
+    int index = searchCompileTable(LowOpndRegType_virtual | type, vA);
+    if(index < 0) {
+        ALOGE("virtual reg %d type %d not found in touchOneVR", vA, type);
+        return;
+    }
+    compileTable[index].refCount--;
+}
+//! reduces refCount of two virtual registers
+
+//!
+void touchTwoVRs(u2 vA, u2 vB, LowOpndRegType type) {
+    int index = searchCompileTable(LowOpndRegType_virtual | type, vA);
+    if(index < 0) {
+        ALOGE("virtual reg vA %d type %d not found in touchTwoVRs", vA, type);
+        return;
+    }
+    compileTable[index].refCount--;
+    index = searchCompileTable(LowOpndRegType_virtual | type, vB);
+    if(index < 0) {
+        ALOGE("virtual reg vB %d type %d not found in touchTwoVRs", vB, type);
+        return;
+    }
+    compileTable[index].refCount--;
+}
+int num_const_worklist;
+//! worklist to update constVRTable later
+int constWorklist[10];
+
+int num_const_vr; //in a basic block
+//! table to store the constant information for virtual registers
+ConstVRInfo constVRTable[MAX_CONST_REG];
+//! update constVRTable for a given virtual register
+
+//! set "isConst" to false
+void setVRToNonConst(int regNum, OpndSize size) {
+    int k;
+    int indexL = -1;
+    int indexH = -1;
+    for(k = 0; k < num_const_vr; k++) {
+        if(constVRTable[k].regNum == regNum) {
+            indexL = k;
+            continue;
+        }
+        if(constVRTable[k].regNum == regNum + 1 && size == OpndSize_64) {
+            indexH = k;
+            continue;
+        }
+    }
+    if(indexL >= 0) {
+        //remove this entry??
+        constVRTable[indexL].isConst = false;
+    }
+    if(size == OpndSize_64 && indexH >= 0) {
+        constVRTable[indexH].isConst = false;
+    }
+}
+//! update constVRTable for a given virtual register
+
+//! set "isConst" to true
+void setVRToConst(int regNum, OpndSize size, int* tmpValue) {
+    int k;
+    int indexL = -1;
+    int indexH = -1;
+    for(k = 0; k < num_const_vr; k++) {
+        if(constVRTable[k].regNum == regNum) {
+            indexL = k;
+            continue;
+        }
+        if(constVRTable[k].regNum == regNum + 1 && size == OpndSize_64) {
+            indexH = k;
+            continue;
+        }
+    }
+    if(indexL < 0) {
+        indexL = num_const_vr;
+        constVRTable[indexL].regNum = regNum;
+        num_const_vr++;
+    }
+    constVRTable[indexL].isConst = true;
+    constVRTable[indexL].value = tmpValue[0];
+    if(size == OpndSize_64) {
+        if(indexH < 0) {
+            indexH = num_const_vr;
+            constVRTable[indexH].regNum = regNum+1;
+            num_const_vr++;
+        }
+        constVRTable[indexH].isConst = true;
+        constVRTable[indexH].value = tmpValue[1];
+    }
+    if(num_const_vr > MAX_CONST_REG) ALOGE("constVRTable overflows");
+    invalidateVRDueToConst(regNum, size);
+}
+
+//! perform work on constWorklist
+
+//!
+void updateConstInfo(BasicBlock_O1* bb) {
+    if(bb == NULL) return;
+    int k;
+    for(k = 0; k < num_const_worklist; k++) {
+        //int indexOrig = constWorklist[k];
+        //compileTable[indexOrig].isConst = false;
+        //int A = compileTable[indexOrig].regNum;
+        //LowOpndRegType type = compileTable[indexOrig].physicalType & MASK_FOR_TYPE;
+        setVRToNonConst(constWorklist[k], OpndSize_32);
+    }
+}
+//! check whether the current bytecode generates a const
+
+//! if yes, update constVRTable; otherwise, update constWorklist
+//! if a bytecode uses vA (const), and updates vA to non const, getConstInfo will return false and update constWorklist to make sure when lowering the bytecode, vA is treated as constant
+bool getConstInfo(BasicBlock_O1* bb) {
+    compileTableEntry* infoArray = compileTable;
+    u2 inst_op = INST_INST(inst);
+    u2 vA = 0, vB = 0, v1, v2;
+    u2 BBBB;
+    u2 tmp_u2;
+    s4 tmp_s4;
+    u4 tmp_u4;
+    int entry, tmpValue[2], tmpValue2[2];
+    num_const_worklist = 0;
+
+    switch(inst_op) {
+        //for other opcode, if update the register, set isConst to false
+    case OP_MOVE:
+    case OP_MOVE_OBJECT:
+    case OP_MOVE_FROM16:
+    case OP_MOVE_OBJECT_FROM16:
+    case OP_MOVE_16:
+    case OP_MOVE_OBJECT_16:
+        if(inst_op == OP_MOVE || inst_op == OP_MOVE_OBJECT) {
+            vA = INST_A(inst);
+            vB = INST_B(inst);
+        }
+        else if(inst_op == OP_MOVE_FROM16 || inst_op == OP_MOVE_OBJECT_FROM16) {
+            vA = INST_AA(inst);
+            vB = FETCH(1);
+        }
+        else if(inst_op == OP_MOVE_16 || inst_op == OP_MOVE_OBJECT_16) {
+            vA = FETCH(1);
+            vB = FETCH(2);
+        }
+        if(isVirtualRegConstant(vB, LowOpndRegType_gp, tmpValue, false) == 3) {
+            entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+            setVRToConst(vA, OpndSize_32, tmpValue);
+            infoArray[entry].isConst = true;
+            infoArray[entry].value[0] = tmpValue[0];
+            compileTable[entry].refCount--;
+            touchOneVR(vB, LowOpndRegType_gp);
+            return true;
+        } else {
+            constWorklist[num_const_worklist] = vA;
+            num_const_worklist++;
+        }
+        return false;
+    case OP_MOVE_WIDE:
+    case OP_MOVE_WIDE_FROM16:
+    case OP_MOVE_WIDE_16:
+        if(inst_op == OP_MOVE_WIDE) {
+            vA = INST_A(inst);
+            vB = INST_B(inst);
+        }
+        else if(inst_op == OP_MOVE_WIDE_FROM16) {
+            vA = INST_AA(inst);
+            vB = FETCH(1);
+        }
+        else if(inst_op == OP_MOVE_WIDE_16) {
+            vA = FETCH(1);
+            vB = FETCH(2);
+        }
+        if(isVirtualRegConstant(vB, LowOpndRegType_xmm, tmpValue, false) == 3) {
+            entry = findVirtualRegInTable(vA, LowOpndRegType_xmm, true);
+            setVRToConst(vA, OpndSize_64, tmpValue);
+            compileTable[entry].refCount--;
+            touchOneVR(vB, LowOpndRegType_xmm);
+            return true;
+        } else {
+            constWorklist[num_const_worklist] = vA;
+            num_const_worklist++;
+            constWorklist[num_const_worklist] = vA+1;
+            num_const_worklist++;
+        }
+        return false;
+    case OP_MOVE_RESULT:
+    case OP_MOVE_RESULT_OBJECT:
+    case OP_MOVE_EXCEPTION:
+    case OP_CONST_STRING:
+    case OP_CONST_STRING_JUMBO:
+    case OP_CONST_CLASS:
+    case OP_NEW_INSTANCE:
+    case OP_CMPL_FLOAT:
+    case OP_CMPG_FLOAT:
+    case OP_CMPL_DOUBLE:
+    case OP_CMPG_DOUBLE:
+    case OP_AGET:
+    case OP_AGET_OBJECT:
+    case OP_AGET_BOOLEAN:
+    case OP_AGET_BYTE:
+    case OP_AGET_CHAR:
+    case OP_AGET_SHORT:
+    case OP_SGET:
+    case OP_SGET_OBJECT:
+    case OP_SGET_VOLATILE:
+    case OP_SGET_OBJECT_VOLATILE:
+    case OP_SGET_BOOLEAN:
+    case OP_SGET_BYTE:
+    case OP_SGET_CHAR:
+    case OP_SGET_SHORT:
+        vA = INST_AA(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        return false;
+    case OP_MOVE_RESULT_WIDE:
+    case OP_AGET_WIDE:
+    case OP_SGET_WIDE:
+    case OP_SGET_WIDE_VOLATILE:
+        vA = INST_AA(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        constWorklist[num_const_worklist] = vA+1;
+        num_const_worklist++;
+        return false;
+    case OP_INSTANCE_OF:
+    case OP_ARRAY_LENGTH:
+    case OP_NEW_ARRAY:
+    case OP_IGET:
+    case OP_IGET_OBJECT:
+    case OP_IGET_VOLATILE:
+    case OP_IGET_OBJECT_VOLATILE:
+    case OP_IGET_BOOLEAN:
+    case OP_IGET_BYTE:
+    case OP_IGET_CHAR:
+    case OP_IGET_SHORT:
+    case OP_IGET_QUICK:
+    case OP_IGET_OBJECT_QUICK:
+        vA = INST_A(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        return false;
+    case OP_IGET_WIDE:
+    case OP_IGET_WIDE_VOLATILE:
+    case OP_IGET_WIDE_QUICK:
+        vA = INST_A(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        constWorklist[num_const_worklist] = vA+1;
+        num_const_worklist++;
+        return false;
+        //TODO: constant folding for float/double/long ALU
+    case OP_ADD_FLOAT:
+    case OP_SUB_FLOAT:
+    case OP_MUL_FLOAT:
+    case OP_DIV_FLOAT:
+    case OP_REM_FLOAT:
+        vA = INST_AA(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        return false;
+    case OP_ADD_DOUBLE:
+    case OP_SUB_DOUBLE:
+    case OP_MUL_DOUBLE:
+    case OP_DIV_DOUBLE:
+    case OP_REM_DOUBLE:
+        vA = INST_AA(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        constWorklist[num_const_worklist] = vA+1;
+        num_const_worklist++;
+        return false;
+    case OP_NEG_FLOAT:
+    case OP_INT_TO_FLOAT:
+    case OP_LONG_TO_FLOAT:
+    case OP_FLOAT_TO_INT:
+    case OP_DOUBLE_TO_INT:
+    case OP_ADD_FLOAT_2ADDR:
+    case OP_SUB_FLOAT_2ADDR:
+    case OP_MUL_FLOAT_2ADDR:
+    case OP_DIV_FLOAT_2ADDR:
+    case OP_REM_FLOAT_2ADDR:
+    case OP_DOUBLE_TO_FLOAT:
+        vA = INST_A(inst);
+        constWorklist[num_const_worklist] = vA; //change constWorklist to point to vA TODO
+        num_const_worklist++;
+        return false;
+    case OP_FLOAT_TO_LONG:
+    case OP_DOUBLE_TO_LONG:
+    case OP_FLOAT_TO_DOUBLE:
+        vA = INST_A(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        constWorklist[num_const_worklist] = vA+1;
+        num_const_worklist++;
+        return false;
+    case OP_NEG_DOUBLE:
+    case OP_INT_TO_DOUBLE: //fp stack
+    case OP_LONG_TO_DOUBLE:
+    case OP_ADD_DOUBLE_2ADDR:
+    case OP_SUB_DOUBLE_2ADDR:
+    case OP_MUL_DOUBLE_2ADDR:
+    case OP_DIV_DOUBLE_2ADDR:
+    case OP_REM_DOUBLE_2ADDR:
+        //ops on float, double
+        vA = INST_A(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        constWorklist[num_const_worklist] = vA+1;
+        num_const_worklist++;
+        return false;
+    case OP_NEG_INT:
+    case OP_NOT_INT:
+    case OP_LONG_TO_INT:
+    case OP_INT_TO_BYTE:
+    case OP_INT_TO_CHAR:
+    case OP_INT_TO_SHORT:
+        vA = INST_A(inst);
+        vB = INST_B(inst);
+        if(isVirtualRegConstant(vB, LowOpndRegType_gp, tmpValue, false) == 3) {
+            entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+            infoArray[entry].isConst = true;
+            if(inst_op == OP_NEG_INT)
+                infoArray[entry].value[0] = -tmpValue[0];
+            if(inst_op == OP_NOT_INT)
+                infoArray[entry].value[0] = ~tmpValue[0]; //CHECK
+            if(inst_op == OP_LONG_TO_INT)
+                infoArray[entry].value[0] = tmpValue[0];
+            if(inst_op == OP_INT_TO_BYTE)// sar
+                infoArray[entry].value[0] = (tmpValue[0] << 24) >> 24;
+            if(inst_op == OP_INT_TO_CHAR) //shr
+                infoArray[entry].value[0] = ((unsigned int)(tmpValue[0] << 16)) >> 16;
+            if(inst_op == OP_INT_TO_SHORT) //sar
+                infoArray[entry].value[0] = (tmpValue[0] << 16) >> 16;
+            tmpValue[0] = infoArray[entry].value[0];
+            setVRToConst(vA, OpndSize_32, tmpValue);
+            compileTable[entry].refCount--;
+            touchOneVR(vB, LowOpndRegType_gp);
+#ifdef DEBUG_CONST
+            LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+            return true;
+        }
+        else {
+            constWorklist[num_const_worklist] = vA;
+            num_const_worklist++;
+            return false;
+        }
+    case OP_NEG_LONG:
+    case OP_NOT_LONG:
+    case OP_INT_TO_LONG:
+        vA = INST_A(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        constWorklist[num_const_worklist] = vA+1; //fixed on 10/15/2009
+        num_const_worklist++;
+        return false;
+    case OP_DIV_INT_2ADDR:
+    case OP_REM_INT_2ADDR:
+    case OP_REM_INT_LIT16:
+    case OP_DIV_INT_LIT16:
+    case OP_REM_INT_LIT8:
+    case OP_DIV_INT_LIT8:
+    case OP_DIV_INT:
+    case OP_REM_INT:
+        if(inst_op == OP_DIV_INT || inst_op == OP_DIV_INT_LIT8 ||
+           inst_op == OP_REM_INT || inst_op == OP_REM_INT_LIT8)
+            vA = INST_AA(inst);
+        else
+            vA = INST_A(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        return false;
+    case OP_ADD_INT_2ADDR:
+    case OP_SUB_INT_2ADDR:
+    case OP_MUL_INT_2ADDR:
+    case OP_AND_INT_2ADDR:
+    case OP_OR_INT_2ADDR:
+    case OP_XOR_INT_2ADDR:
+    case OP_SHL_INT_2ADDR:
+    case OP_SHR_INT_2ADDR:
+    case OP_USHR_INT_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        if(isVirtualRegConstant(vA, LowOpndRegType_gp, tmpValue, false) == 3 &&
+           isVirtualRegConstant(v2, LowOpndRegType_gp, tmpValue2, false) == 3) {
+            entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+            infoArray[entry].isConst = true;
+            if(inst_op == OP_ADD_INT_2ADDR)
+                infoArray[entry].value[0] = tmpValue[0] + tmpValue2[0];
+            if(inst_op == OP_SUB_INT_2ADDR)
+                infoArray[entry].value[0] = tmpValue[0] - tmpValue2[0];
+            if(inst_op == OP_MUL_INT_2ADDR)
+                infoArray[entry].value[0] = tmpValue[0] * tmpValue2[0];
+            if(inst_op == OP_DIV_INT_2ADDR)
+                infoArray[entry].value[0] = tmpValue[0] / tmpValue2[0];
+            if(inst_op == OP_REM_INT_2ADDR)
+                infoArray[entry].value[0] = tmpValue[0] % tmpValue2[0];
+            if(inst_op == OP_AND_INT_2ADDR)
+                infoArray[entry].value[0] = tmpValue[0] & tmpValue2[0];
+            if(inst_op == OP_OR_INT_2ADDR)
+                infoArray[entry].value[0] = tmpValue[0] | tmpValue2[0];
+            if(inst_op == OP_XOR_INT_2ADDR)
+                infoArray[entry].value[0] = tmpValue[0] ^ tmpValue2[0];
+            if(inst_op == OP_SHL_INT_2ADDR)
+                infoArray[entry].value[0] = tmpValue[0] << tmpValue2[0];
+            if(inst_op == OP_SHR_INT_2ADDR)
+                infoArray[entry].value[0] = tmpValue[0] >> tmpValue2[0];
+            if(inst_op == OP_USHR_INT_2ADDR)
+                infoArray[entry].value[0] = (unsigned int)tmpValue[0] >> tmpValue2[0];
+            tmpValue[0] = infoArray[entry].value[0];
+            setVRToConst(vA, OpndSize_32, tmpValue);
+            compileTable[entry].refCount--;
+            touchOneVR(v2, LowOpndRegType_gp);
+#ifdef DEBUG_CONST
+            LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+            return true;
+        }
+        else {
+            constWorklist[num_const_worklist] = vA;
+            num_const_worklist++;
+            return false;
+        }
+    case OP_ADD_INT_LIT16:
+    case OP_RSUB_INT:
+    case OP_MUL_INT_LIT16:
+    case OP_AND_INT_LIT16:
+    case OP_OR_INT_LIT16:
+    case OP_XOR_INT_LIT16:
+        vA = INST_A(inst);
+        vB = INST_B(inst);
+        tmp_s4 = (s2)FETCH(1);
+        if(isVirtualRegConstant(vB, LowOpndRegType_gp, tmpValue, false) == 3) {
+            entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+            infoArray[entry].isConst = true;
+            if(inst_op == OP_ADD_INT_LIT16)
+                infoArray[entry].value[0] = tmpValue[0] + tmp_s4;
+            if(inst_op == OP_RSUB_INT)
+                infoArray[entry].value[0] = tmp_s4 - tmpValue[0];
+            if(inst_op == OP_MUL_INT_LIT16)
+                infoArray[entry].value[0] = tmpValue[0] * tmp_s4;
+            if(inst_op == OP_DIV_INT_LIT16)
+                infoArray[entry].value[0] = tmpValue[0] / tmp_s4;
+            if(inst_op == OP_REM_INT_LIT16)
+                infoArray[entry].value[0] = tmpValue[0] % tmp_s4;
+            if(inst_op == OP_AND_INT_LIT16)
+                infoArray[entry].value[0] = tmpValue[0] & tmp_s4;
+            if(inst_op == OP_OR_INT_LIT16)
+                infoArray[entry].value[0] = tmpValue[0] | tmp_s4;
+            if(inst_op == OP_XOR_INT_LIT16)
+                infoArray[entry].value[0] = tmpValue[0] ^ tmp_s4;
+            tmpValue[0] = infoArray[entry].value[0];
+            setVRToConst(vA, OpndSize_32, tmpValue);
+            compileTable[entry].refCount--;
+            touchOneVR(vB, LowOpndRegType_gp);
+#ifdef DEBUG_CONST
+            LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+            return true;
+        }
+        else {
+            constWorklist[num_const_worklist] = vA;
+            num_const_worklist++;
+            return false;
+        }
+    case OP_ADD_INT:
+    case OP_SUB_INT:
+    case OP_MUL_INT:
+    case OP_AND_INT:
+    case OP_OR_INT:
+    case OP_XOR_INT:
+    case OP_SHL_INT:
+    case OP_SHR_INT:
+    case OP_USHR_INT:
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        if(isVirtualRegConstant(v1, LowOpndRegType_gp, tmpValue, false) == 3 &&
+           isVirtualRegConstant(v2, LowOpndRegType_gp, tmpValue2, false) == 3) {
+            entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+            infoArray[entry].isConst = true;
+            if(inst_op == OP_ADD_INT)
+                infoArray[entry].value[0] = tmpValue[0] + tmpValue2[0];
+            if(inst_op == OP_SUB_INT)
+                infoArray[entry].value[0] = tmpValue[0] - tmpValue2[0];
+            if(inst_op == OP_MUL_INT)
+                infoArray[entry].value[0] = tmpValue[0] * tmpValue2[0];
+            if(inst_op == OP_DIV_INT)
+                infoArray[entry].value[0] = tmpValue[0] / tmpValue2[0];
+            if(inst_op == OP_REM_INT)
+                infoArray[entry].value[0] = tmpValue[0] % tmpValue2[0];
+            if(inst_op == OP_AND_INT)
+                infoArray[entry].value[0] = tmpValue[0] & tmpValue2[0];
+            if(inst_op == OP_OR_INT)
+                infoArray[entry].value[0] = tmpValue[0] | tmpValue2[0];
+            if(inst_op == OP_XOR_INT)
+                infoArray[entry].value[0] = tmpValue[0] ^ tmpValue2[0];
+            if(inst_op == OP_SHL_INT)
+                infoArray[entry].value[0] = tmpValue[0] << tmpValue2[0];
+            if(inst_op == OP_SHR_INT)
+                infoArray[entry].value[0] = tmpValue[0] >> tmpValue2[0];
+            if(inst_op == OP_USHR_INT)
+                infoArray[entry].value[0] = (unsigned int)tmpValue[0] >> tmpValue2[0];
+            tmpValue[0] = infoArray[entry].value[0];
+            setVRToConst(vA, OpndSize_32, tmpValue);
+            compileTable[entry].refCount--;
+            touchOneVR(v1, LowOpndRegType_gp);
+            touchOneVR(v2, LowOpndRegType_gp);
+#ifdef DEBUG_CONST
+            LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+            return true;
+        }
+        else {
+            constWorklist[num_const_worklist] = vA;
+            num_const_worklist++;
+            return false;
+        }
+    case OP_ADD_INT_LIT8: //INST_AA
+    case OP_RSUB_INT_LIT8:
+    case OP_MUL_INT_LIT8:
+    case OP_AND_INT_LIT8:
+    case OP_OR_INT_LIT8:
+    case OP_XOR_INT_LIT8:
+    case OP_SHL_INT_LIT8:
+    case OP_SHR_INT_LIT8:
+    case OP_USHR_INT_LIT8:
+        vA = INST_AA(inst);
+        vB = (u2)FETCH(1) & 0xff;
+        tmp_s4 = (s2)FETCH(1) >> 8;
+        if(isVirtualRegConstant(vB, LowOpndRegType_gp, tmpValue, false) == 3) {
+            entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+            infoArray[entry].isConst = true;
+            if(inst_op == OP_ADD_INT_LIT8)
+                infoArray[entry].value[0] = tmpValue[0] + tmp_s4;
+            if(inst_op == OP_RSUB_INT_LIT8)
+                infoArray[entry].value[0] = tmp_s4 - tmpValue[0];
+            if(inst_op == OP_MUL_INT_LIT8)
+                infoArray[entry].value[0] = tmpValue[0] * tmp_s4;
+            if(inst_op == OP_DIV_INT_LIT8)
+                infoArray[entry].value[0] = tmpValue[0] / tmp_s4;
+            if(inst_op == OP_REM_INT_LIT8)
+                infoArray[entry].value[0] = tmpValue[0] % tmp_s4;
+            if(inst_op == OP_AND_INT_LIT8)
+                infoArray[entry].value[0] = tmpValue[0] & tmp_s4;
+            if(inst_op == OP_OR_INT_LIT8)
+                infoArray[entry].value[0] = tmpValue[0] | tmp_s4;
+            if(inst_op == OP_XOR_INT_LIT8)
+                infoArray[entry].value[0] = tmpValue[0] ^ tmp_s4;
+            if(inst_op == OP_SHL_INT_LIT8)
+                infoArray[entry].value[0] = tmpValue[0] << tmp_s4;
+            if(inst_op == OP_SHR_INT_LIT8)
+                infoArray[entry].value[0] = tmpValue[0] >> tmp_s4;
+            if(inst_op == OP_USHR_INT_LIT8)
+                infoArray[entry].value[0] = (unsigned int)tmpValue[0] >> tmp_s4;
+            tmpValue[0] = infoArray[entry].value[0];
+            setVRToConst(vA, OpndSize_32, tmpValue);
+            compileTable[entry].refCount--;
+            touchOneVR(vB, LowOpndRegType_gp);
+#ifdef DEBUG_CONST
+            LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+            return true;
+        }
+        else {
+            constWorklist[num_const_worklist] = vA;
+            num_const_worklist++;
+            return false;
+        }
+    case OP_ADD_LONG:
+    case OP_SUB_LONG:
+    case OP_AND_LONG:
+    case OP_OR_LONG:
+    case OP_XOR_LONG:
+    case OP_MUL_LONG:
+    case OP_DIV_LONG:
+    case OP_REM_LONG:
+    case OP_SHL_LONG:
+    case OP_SHR_LONG:
+    case OP_USHR_LONG:
+        //TODO bytecode is not going to update state registers
+        //constant folding
+        vA = INST_AA(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        constWorklist[num_const_worklist] = vA+1;
+        num_const_worklist++;
+        return false;
+    case OP_CMP_LONG:
+        vA = INST_AA(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        return false;
+    case OP_ADD_LONG_2ADDR:
+    case OP_SUB_LONG_2ADDR:
+    case OP_AND_LONG_2ADDR:
+    case OP_OR_LONG_2ADDR:
+    case OP_XOR_LONG_2ADDR:
+    case OP_MUL_LONG_2ADDR:
+    case OP_DIV_LONG_2ADDR:
+    case OP_REM_LONG_2ADDR:
+    case OP_SHL_LONG_2ADDR:
+    case OP_SHR_LONG_2ADDR:
+    case OP_USHR_LONG_2ADDR:
+        vA = INST_A(inst);
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        constWorklist[num_const_worklist] = vA+1;
+        num_const_worklist++;
+        return false;
+    case OP_CONST_4:
+        vA = INST_A(inst);
+        tmp_s4 = (s4) (INST_B(inst) << 28) >> 28;
+        entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = tmp_s4;
+        tmpValue[0] = infoArray[entry].value[0];
+        setVRToConst(vA, OpndSize_32, tmpValue);
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %d", vA, tmp_s4);
+#endif
+        return true;
+    case OP_CONST_16:
+        BBBB = FETCH(1);
+        vA = INST_AA(inst);
+        entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = (s2)BBBB;
+        tmpValue[0] = infoArray[entry].value[0];
+        setVRToConst(vA, OpndSize_32, tmpValue);
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+        return true;
+    case OP_CONST:
+        vA = INST_AA(inst);
+        tmp_u4 = FETCH(1);
+        tmp_u4 |= (u4)FETCH(2) << 16;
+        entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = (s4)tmp_u4;
+        tmpValue[0] = infoArray[entry].value[0];
+        setVRToConst(vA, OpndSize_32, tmpValue);
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+        return true;
+    case OP_CONST_HIGH16:
+        vA = INST_AA(inst);
+        tmp_u2 = FETCH(1);
+        entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = (s4)tmp_u2<<16;
+        tmpValue[0] = infoArray[entry].value[0];
+        setVRToConst(vA, OpndSize_32, tmpValue);
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+        return true;
+    case OP_CONST_WIDE_16:
+        vA = INST_AA(inst);
+        tmp_u2 = FETCH(1);
+        entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = (s2)tmp_u2;
+        tmpValue[0] = infoArray[entry].value[0];
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %x", vA, infoArray[entry].value[0]);
+#endif
+
+        entry = findVirtualRegInTable(vA+1, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = (s2)tmp_u2>>31;
+        tmpValue[1] = infoArray[entry].value[0];
+        setVRToConst(vA, OpndSize_64, tmpValue);
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %x", vA+1, infoArray[entry].value[0]);
+#endif
+        return true;
+    case OP_CONST_WIDE_32:
+        vA = INST_AA(inst);
+        tmp_u4 = FETCH(1);
+        tmp_u4 |= (u4)FETCH(2) << 16;
+        entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = (s4)tmp_u4;
+        tmpValue[0] = infoArray[entry].value[0];
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %x", vA, infoArray[entry].value[0]);
+#endif
+
+        entry = findVirtualRegInTable(vA+1, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = (s4)tmp_u4>>31;
+        tmpValue[1] = infoArray[entry].value[0];
+        setVRToConst(vA, OpndSize_64, tmpValue);
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %x", vA+1, infoArray[entry].value[0]);
+#endif
+        return true;
+    case OP_CONST_WIDE:
+        vA = INST_AA(inst);
+        tmp_u4 = FETCH(1);
+        tmp_u4 |= (u8)FETCH(2) << 16;
+        entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = (s4)tmp_u4;
+        tmpValue[0] = infoArray[entry].value[0];
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %x", vA, infoArray[entry].value[0]);
+#endif
+
+        tmp_u4 = (u8)FETCH(3);
+        tmp_u4 |= (u8)FETCH(4) << 16;
+        entry = findVirtualRegInTable(vA+1, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = (s4)tmp_u4;
+        tmpValue[1] = infoArray[entry].value[0];
+        setVRToConst(vA, OpndSize_64, tmpValue);
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %x", vA+1, infoArray[entry].value[0]);
+#endif
+        return true;
+    case OP_CONST_WIDE_HIGH16:
+        vA = INST_AA(inst);
+        tmp_u2 = FETCH(1);
+        entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = 0;
+        tmpValue[0] = infoArray[entry].value[0];
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %x", vA, infoArray[entry].value[0]);
+#endif
+
+        entry = findVirtualRegInTable(vA+1, LowOpndRegType_gp, true);
+        infoArray[entry].isConst = true;
+        infoArray[entry].value[0] = (s4)tmp_u2<<16;
+        tmpValue[1] = infoArray[entry].value[0];
+        setVRToConst(vA, OpndSize_64, tmpValue);
+        compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+        LOGD("getConstInfo: set VR %d to %x", vA+1, infoArray[entry].value[0]);
+#endif
+        return true;
+#ifdef SUPPORT_HLO
+    case OP_X_AGET_QUICK:
+    case OP_X_AGET_OBJECT_QUICK:
+    case OP_X_AGET_BOOLEAN_QUICK:
+    case OP_X_AGET_BYTE_QUICK:
+    case OP_X_AGET_CHAR_QUICK:
+    case OP_X_AGET_SHORT_QUICK:
+        vA = FETCH(1) & 0xff;
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        return false;
+    case OP_X_AGET_WIDE_QUICK:
+        vA = FETCH(1) & 0xff;
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        constWorklist[num_const_worklist] = vA+1;
+        num_const_worklist++;
+        return false;
+    case OP_X_DEREF_GET:
+    case OP_X_DEREF_GET_OBJECT:
+    case OP_X_DEREF_GET_BOOLEAN:
+    case OP_X_DEREF_GET_BYTE:
+    case OP_X_DEREF_GET_CHAR:
+    case OP_X_DEREF_GET_SHORT:
+        vA = FETCH(1) & 0xff;
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        return false;
+    case OP_X_DEREF_GET_WIDE:
+        vA = FETCH(1) & 0xff;
+        constWorklist[num_const_worklist] = vA;
+        num_const_worklist++;
+        constWorklist[num_const_worklist] = vA+1;
+        num_const_worklist++;
+        return false;
+#endif
+    }
+    return false;
+}
+
+//! This function updates infoArray with virtual registers accessed when lowering the bytecode, and returns size of the bytecode in unit of u2
+
+//! uses of virtual registers are added to infoArray first
+int getVirtualRegInfo(VirtualRegInfo* infoArray) {
+    u2 inst_op = INST_INST(inst);
+    u2 vA = 0, vB = 0, vref, vindex;
+    u2 v1, v2, length, vD, vG, vE, vF, count;
+    u4 v1_u4, v2_u4;
+    int kk, num, num_entry;
+    s4 tmp_s4;
+    s2 tmp_s2;
+    u4 tmp_u4;
+    int codeSize = 0;
+    num_regs_per_bytecode = 0;
+    //update infoArray[xx].allocConstraints
+    for(num = 0; num < MAX_REG_PER_BYTECODE; num++) {
+        for(kk = 0; kk < 8; kk++) {
+            infoArray[num].allocConstraints[kk].physicalReg = (PhysicalReg)kk;
+            infoArray[num].allocConstraints[kk].count = 0;
+        }
+    }
+
+    switch (inst_op) {
+    case OP_NOP:
+        codeSize = 1;
+        break;
+    case OP_MOVE:
+    case OP_MOVE_OBJECT:
+    case OP_MOVE_FROM16:
+    case OP_MOVE_OBJECT_FROM16:
+    case OP_MOVE_16:
+    case OP_MOVE_OBJECT_16:
+        if(inst_op == OP_MOVE || inst_op == OP_MOVE_OBJECT) {
+            vA = INST_A(inst);
+            vB = INST_B(inst);
+            codeSize = 1;
+        }
+        else if(inst_op == OP_MOVE_FROM16 || inst_op == OP_MOVE_OBJECT_FROM16) {
+            vA = INST_AA(inst);
+            vB = FETCH(1);
+            codeSize = 2;
+        }
+        else if(inst_op == OP_MOVE_16 || inst_op == OP_MOVE_OBJECT_16) {
+            vA = FETCH(1);
+            vB = FETCH(2);
+            codeSize = 3;
+        }
+        infoArray[1].regNum = vA; //dst
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = vB; //src
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_MOVE_WIDE:
+    case OP_MOVE_WIDE_FROM16:
+    case OP_MOVE_WIDE_16:
+        if(inst_op == OP_MOVE_WIDE) {
+            vA = INST_A(inst);
+            vB = INST_B(inst);
+            codeSize = 1;
+        }
+        else if(inst_op == OP_MOVE_WIDE_FROM16) {
+            vA = INST_AA(inst);
+            vB = FETCH(1);
+            codeSize = 2;
+        }
+        else if(inst_op == OP_MOVE_WIDE_16) {
+            vA = FETCH(1);
+            vB = FETCH(2);
+            codeSize = 3;
+        }
+        infoArray[1].regNum = vA; //dst
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[0].regNum = vB; //src
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_MOVE_RESULT: //access memory
+    case OP_MOVE_RESULT_OBJECT:
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        codeSize = 1;
+        num_regs_per_bytecode = 1;
+        break;
+    case OP_MOVE_RESULT_WIDE: //note: 2 destinations
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        codeSize = 1;
+        num_regs_per_bytecode = 1;
+        break;
+    case OP_MOVE_EXCEPTION: //access memory
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        codeSize = 1;
+        num_regs_per_bytecode = 1;
+        break;
+    case OP_RETURN_VOID:
+    case OP_RETURN_VOID_BARRIER:
+        codeSize = 1;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        num_regs_per_bytecode = 0;
+        break;
+    case OP_RETURN:
+    case OP_RETURN_OBJECT:
+        vA = INST_AA(inst);
+        codeSize = 1;
+        infoArray[0].regNum = vA; //src
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        num_regs_per_bytecode = 1;
+        break;
+    case OP_RETURN_WIDE:
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //src
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 1;
+        codeSize = 1;
+        break;
+    case OP_CONST_4:
+        vA = INST_A(inst);
+        tmp_s4 = (s4) (INST_B(inst) << 28) >> 28;
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 1;
+        codeSize = 1;
+        break;
+    case OP_CONST_16:
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 1;
+        codeSize = 2;
+        break;
+    case OP_CONST:
+        vA = INST_AA(inst);
+        tmp_u4 = FETCH(1);
+        tmp_u4 |= (u4)FETCH(2) << 16;
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 1;
+        codeSize = 3;
+        break;
+    case OP_CONST_HIGH16:
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 1;
+        codeSize = 2;
+        break;
+    case OP_CONST_WIDE_16:
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = vA+1;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        codeSize = 2;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_CONST_WIDE_32:
+        vA = INST_AA(inst);
+        tmp_u4 = FETCH(1);
+        tmp_u4 |= (u4)FETCH(2) << 16;
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = vA+1;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        codeSize = 3;
+        break;
+    case OP_CONST_WIDE:
+        vA = INST_AA(inst);
+        tmp_u4 = FETCH(1);
+        tmp_u4 |= (u8)FETCH(2) << 16;
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        tmp_u4 = (u8)FETCH(3);
+        tmp_u4 |= (u8)FETCH(4) << 16;
+        infoArray[1].regNum = vA+1;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        codeSize = 5;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_CONST_WIDE_HIGH16:
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = vA+1;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        codeSize = 2;
+        break;
+    case OP_CONST_STRING:
+    case OP_CONST_STRING_JUMBO:
+    case OP_CONST_CLASS:
+        vA = INST_AA(inst);
+        if(inst_op == OP_CONST_STRING || inst_op == OP_CONST_CLASS)
+            codeSize = 2;
+        else if(inst_op == OP_CONST_STRING_JUMBO)
+            codeSize = 3;
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        num_regs_per_bytecode = 1;
+        break;
+    case OP_MONITOR_ENTER:
+        vA = INST_AA(inst);
+        codeSize = 1;
+        infoArray[0].regNum = vA; //src
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 1;
+        break;
+    case OP_MONITOR_EXIT:
+        vA = INST_AA(inst);
+        codeSize = 1;
+        infoArray[0].regNum = vA; //src
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX); //eax is used as return value from c function
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 1;
+        break;
+    case OP_CHECK_CAST:
+        codeSize = 2;
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //src
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_ECX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 1;
+        break;
+    case OP_INSTANCE_OF:
+        codeSize = 2;
+        vA = INST_A(inst);
+        vB = INST_B(inst);
+        infoArray[0].regNum = vB; //src
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = vA; //dst
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_ARRAY_LENGTH:
+        vA = INST_A(inst);
+        vB = INST_B(inst);
+        codeSize = 1;
+        infoArray[0].regNum = vB; //src
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = vA; //dst
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        //%edx is used in this bytecode, update currentBB->allocConstraints
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_NEW_INSTANCE:
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //dst
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_D;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_ECX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 1;
+        codeSize = 2;
+        break;
+    case OP_NEW_ARRAY:
+        vA = INST_A(inst); //destination
+        vB = INST_B(inst); //length
+        infoArray[0].regNum = vB; //src
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = vA; //dst
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 2;
+        codeSize = 2;
+        break;
+    case OP_FILLED_NEW_ARRAY: {//update return value
+        //can use up to 5 registers to fill the content of array
+        length = INST_B(inst);
+        u2 vv = FETCH(2);
+        v1 = vv & 0xf;
+        v2 = (vv >> 4) & 0xf;
+        u2 v3 = (vv >> 8) & 0xf;
+        u2 v4 = (vv >> 12) & 0xf;
+        u2 v5 = INST_A(inst);
+        if(length >= 1) {
+            infoArray[0].regNum = v1; //src
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_gp;
+        }
+        if(length >= 2) {
+            infoArray[1].regNum = v2; //src
+            infoArray[1].refCount = 1;
+            infoArray[1].accessType = REGACCESS_U;
+            infoArray[1].physicalType = LowOpndRegType_gp;
+        }
+        if(length >= 3) {
+            infoArray[2].regNum = v3; //src
+            infoArray[2].refCount = 1;
+            infoArray[2].accessType = REGACCESS_U;
+            infoArray[2].physicalType = LowOpndRegType_gp;
+        }
+        if(length >= 4) {
+            infoArray[3].regNum = v4; //src
+            infoArray[3].refCount = 1;
+            infoArray[3].accessType = REGACCESS_U;
+            infoArray[3].physicalType = LowOpndRegType_gp;
+        }
+        if(length >= 5) {
+            infoArray[4].regNum = v5; //src
+            infoArray[4].refCount = 1;
+            infoArray[4].accessType = REGACCESS_U;
+            infoArray[4].physicalType = LowOpndRegType_gp;
+        }
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = length;
+        codeSize = 3;
+        break;
+    }
+    case OP_FILLED_NEW_ARRAY_RANGE: {//use "length" virtual registers
+        length = INST_AA(inst);
+        u4 vC = (u4)FETCH(2);
+        for(kk = 0; kk < length; kk++) {
+            infoArray[kk].regNum = vC+kk; //src
+            infoArray[kk].refCount = 1;
+            infoArray[kk].accessType = REGACCESS_U;
+            infoArray[kk].physicalType = LowOpndRegType_gp;
+        }
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = length;
+        codeSize = 3;
+        break;
+    }
+    case OP_FILL_ARRAY_DATA: //update content of array, read memory
+        vA = INST_AA(inst); //use virtual register, but has side-effect, update memory
+        infoArray[0].regNum = vA; //use
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 1;
+        codeSize = 3;
+        break;
+    case OP_THROW: //update glue->exception
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //use
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 1;
+        codeSize = 1;
+        break;
+    case OP_THROW_VERIFICATION_ERROR:
+        num_regs_per_bytecode = 0;
+        codeSize = 2;
+        break;
+    case OP_GOTO:
+        codeSize = 1;
+        num_regs_per_bytecode = 0;
+        break;
+    case OP_GOTO_16:
+        codeSize = 2;
+        num_regs_per_bytecode = 0;
+        break;
+    case OP_GOTO_32:
+        codeSize = 3;
+        num_regs_per_bytecode = 0;
+        break;
+    case OP_PACKED_SWITCH:
+    case OP_SPARSE_SWITCH:
+        vA = INST_AA(inst);
+        codeSize = 3;
+        infoArray[0].regNum = vA; //use
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 1;
+        break;
+
+    case OP_CMPL_FLOAT: //move 32 bits from memory to lower part of XMM register
+    case OP_CMPG_FLOAT:
+        codeSize = 2;
+        vA = INST_AA(inst);
+        v1_u4 = FETCH(1) & 0xff;
+        v2_u4 = FETCH(1) >> 8;
+        num_regs_per_bytecode = 1;
+        infoArray[0].regNum = v1_u4; //use ss or sd CHECK
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_ss;
+        infoArray[1].regNum = v2_u4; //use
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_ss;
+        num_regs_per_bytecode = 3;
+        num_entry = 2;
+        infoArray[num_entry].regNum = vA; //define
+        infoArray[num_entry].refCount = 1;
+        infoArray[num_entry].accessType = REGACCESS_D;
+        infoArray[num_entry].physicalType = LowOpndRegType_gp;
+        break;
+    case OP_CMPL_DOUBLE: //move 64 bits from memory to lower part of XMM register
+    case OP_CMPG_DOUBLE:
+    case OP_CMP_LONG: //load v1, v1+1, v2, v2+1 to gpr
+        codeSize = 2;
+        vA = INST_AA(inst);
+        v1_u4 = FETCH(1) & 0xff;
+        v2_u4 = FETCH(1) >> 8;
+        num_regs_per_bytecode = 1;
+        if(inst_op == OP_CMP_LONG) {
+            infoArray[0].regNum = v1_u4; //use
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_gp;
+            infoArray[1].regNum = v1_u4 + 1; //use
+            infoArray[1].refCount = 1;
+            infoArray[1].accessType = REGACCESS_U;
+            infoArray[1].physicalType = LowOpndRegType_gp;
+            infoArray[2].regNum = v2_u4; //use
+            infoArray[2].refCount = 1;
+            infoArray[2].accessType = REGACCESS_U;
+            infoArray[2].physicalType = LowOpndRegType_gp;
+            infoArray[3].regNum = v2_u4 + 1; //use
+            infoArray[3].refCount = 1;
+            infoArray[3].accessType = REGACCESS_U;
+            infoArray[3].physicalType = LowOpndRegType_gp;
+            num_regs_per_bytecode = 5;
+            num_entry = 4;
+            infoArray[num_entry].regNum = vA; //define
+            infoArray[num_entry].refCount = 2;
+            infoArray[num_entry].accessType = REGACCESS_D;
+            infoArray[num_entry].physicalType = LowOpndRegType_gp;
+        }
+        else {
+            infoArray[0].regNum = v1_u4; //use ss or sd CHECK
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_xmm;
+            infoArray[1].regNum = v2_u4; //use
+            infoArray[1].refCount = 1;
+            infoArray[1].accessType = REGACCESS_U;
+            infoArray[1].physicalType = LowOpndRegType_xmm;
+            num_regs_per_bytecode = 3;
+            num_entry = 2;
+            infoArray[num_entry].regNum = vA; //define
+            infoArray[num_entry].refCount = 1;
+            infoArray[num_entry].accessType = REGACCESS_D;
+            infoArray[num_entry].physicalType = LowOpndRegType_gp;
+        }
+        break;
+    case OP_IF_EQ:
+    case OP_IF_NE:
+    case OP_IF_LT:
+    case OP_IF_GE:
+    case OP_IF_GT:
+    case OP_IF_LE:
+        vA = INST_A(inst);
+        vB = INST_B(inst);
+        infoArray[0].regNum = vA; //use
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = vB;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        codeSize =12;
+        break;
+    case OP_IF_EQZ:
+    case OP_IF_NEZ:
+    case OP_IF_LTZ:
+    case OP_IF_GEZ:
+    case OP_IF_GTZ:
+    case OP_IF_LEZ:
+        vA = INST_AA(inst);
+        infoArray[0].regNum = vA; //use
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 1;
+        codeSize = 2;
+        break;
+    case OP_AGET:
+        codeSize = 2;
+    case OP_AGET_WIDE:
+        codeSize = 2;
+    case OP_AGET_OBJECT:
+        codeSize = 2;
+    case OP_AGET_BOOLEAN: //movez 8
+        codeSize = 2;
+    case OP_AGET_BYTE: //moves 8
+        codeSize = 2;
+    case OP_AGET_CHAR: //movez 16
+        codeSize = 2;
+    case OP_AGET_SHORT: //moves 16
+        codeSize = 2;
+        vA = INST_AA(inst);
+        vref = FETCH(1) & 0xff;
+        vindex = FETCH(1) >> 8;
+        if(inst_op == OP_AGET_WIDE) {
+            infoArray[2].regNum = vA;
+            infoArray[2].refCount = 1;
+            infoArray[2].accessType = REGACCESS_D;
+            infoArray[2].physicalType = LowOpndRegType_xmm; //64, 128 not used in lowering
+        } else {
+            infoArray[2].regNum = vA;
+            infoArray[2].refCount = 1;
+            infoArray[2].accessType = REGACCESS_D;
+            infoArray[2].physicalType = LowOpndRegType_gp;
+        }
+        infoArray[0].regNum = vref; //use
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = vindex; //use
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_APUT:
+    case OP_APUT_WIDE:
+    case OP_APUT_OBJECT:
+    case OP_APUT_BOOLEAN:
+    case OP_APUT_BYTE:
+    case OP_APUT_CHAR:
+    case OP_APUT_SHORT:
+        vA = INST_AA(inst);
+        vref = FETCH(1) & 0xff;
+        vindex = FETCH(1) >> 8;
+        codeSize = 2;
+        if(inst_op == OP_APUT_WIDE) {
+            infoArray[0].regNum = vA;
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_xmm; //64, 128 not used in lowering
+        } else {
+            infoArray[0].regNum = vA;
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_gp;
+        }
+        infoArray[1].regNum = vref; //use
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = vindex; //use
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_U;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        if(inst_op == OP_APUT_OBJECT) {
+            updateCurrentBBWithConstraints(PhysicalReg_EAX);
+            updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        }
+        num_regs_per_bytecode = 3;
+        break;
+
+    case OP_IGET:
+    case OP_IGET_WIDE:
+    case OP_IGET_OBJECT:
+    case OP_IGET_VOLATILE:
+    case OP_IGET_WIDE_VOLATILE:
+    case OP_IGET_OBJECT_VOLATILE:
+    case OP_IGET_BOOLEAN:
+    case OP_IGET_BYTE:
+    case OP_IGET_CHAR:
+    case OP_IGET_SHORT:
+    case OP_IGET_QUICK:
+    case OP_IGET_WIDE_QUICK:
+    case OP_IGET_OBJECT_QUICK:
+        vA = INST_A(inst);
+        vB = INST_B(inst);
+        codeSize = 2;
+        if(inst_op == OP_IGET_WIDE || inst_op == OP_IGET_WIDE_QUICK) {
+            infoArray[1].regNum = vA;
+            infoArray[1].refCount = 1;
+            infoArray[1].accessType = REGACCESS_D;
+            infoArray[1].physicalType = LowOpndRegType_xmm; //64
+        } else if(inst_op == OP_IGET_WIDE_VOLATILE) {
+            infoArray[1].regNum = vA;
+            infoArray[1].refCount = 1;
+            infoArray[1].accessType = REGACCESS_D;
+            infoArray[1].physicalType = LowOpndRegType_gp;
+            infoArray[2].regNum = vA+1;
+            infoArray[2].refCount = 1;
+            infoArray[2].accessType = REGACCESS_D;
+            infoArray[2].physicalType = LowOpndRegType_gp;
+        } else {
+            infoArray[1].regNum = vA;
+            infoArray[1].refCount = 1;
+            infoArray[1].accessType = REGACCESS_D;
+            infoArray[1].physicalType = LowOpndRegType_gp;
+        }
+        infoArray[0].regNum = vB; //object instance
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        if(inst_op == OP_IGET_WIDE_VOLATILE)
+            num_regs_per_bytecode = 3;
+        else
+            num_regs_per_bytecode = 2;
+        break;
+    case OP_IPUT:
+    case OP_IPUT_WIDE:
+    case OP_IPUT_OBJECT:
+    case OP_IPUT_VOLATILE:
+    case OP_IPUT_WIDE_VOLATILE:
+    case OP_IPUT_OBJECT_VOLATILE:
+    case OP_IPUT_BOOLEAN:
+    case OP_IPUT_BYTE:
+    case OP_IPUT_CHAR:
+    case OP_IPUT_SHORT:
+    case OP_IPUT_QUICK:
+    case OP_IPUT_WIDE_QUICK:
+    case OP_IPUT_OBJECT_QUICK:
+        vA = INST_A(inst);
+        vB = INST_B(inst);
+        codeSize = 2;
+        if(inst_op == OP_IPUT_WIDE || inst_op == OP_IPUT_WIDE_QUICK || inst_op == OP_IPUT_WIDE_VOLATILE) {
+            infoArray[0].regNum = vA;
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_xmm; //64
+        } else {
+            infoArray[0].regNum = vA;
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_gp;
+        }
+        infoArray[1].regNum = vB; //object instance
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_SGET:
+    case OP_SGET_WIDE:
+    case OP_SGET_OBJECT:
+    case OP_SGET_VOLATILE:
+    case OP_SGET_WIDE_VOLATILE:
+    case OP_SGET_OBJECT_VOLATILE:
+    case OP_SGET_BOOLEAN:
+    case OP_SGET_BYTE:
+    case OP_SGET_CHAR:
+    case OP_SGET_SHORT:
+        vA = INST_AA(inst);
+        codeSize = 2;
+        if(inst_op == OP_SGET_WIDE) {
+            infoArray[0].regNum = vA;
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_D;
+            infoArray[0].physicalType = LowOpndRegType_xmm; //64
+        } else if(inst_op == OP_SGET_WIDE_VOLATILE) {
+            infoArray[0].regNum = vA;
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_D;
+            infoArray[0].physicalType = LowOpndRegType_gp;
+            infoArray[1].regNum = vA+1;
+            infoArray[1].refCount = 1;
+            infoArray[1].accessType = REGACCESS_D;
+            infoArray[1].physicalType = LowOpndRegType_gp;
+        } else {
+            infoArray[0].regNum = vA;
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_D;
+            infoArray[0].physicalType = LowOpndRegType_gp;
+        }
+        if(inst_op == OP_SGET_WIDE_VOLATILE)
+            num_regs_per_bytecode = 2;
+        else
+            num_regs_per_bytecode = 1;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        break;
+    case OP_SPUT:
+    case OP_SPUT_WIDE:
+    case OP_SPUT_OBJECT:
+    case OP_SPUT_VOLATILE:
+    case OP_SPUT_WIDE_VOLATILE:
+    case OP_SPUT_OBJECT_VOLATILE:
+    case OP_SPUT_BOOLEAN:
+    case OP_SPUT_BYTE:
+    case OP_SPUT_CHAR:
+    case OP_SPUT_SHORT:
+        vA = INST_AA(inst);
+        codeSize = 2;
+        if(inst_op == OP_SPUT_WIDE || inst_op == OP_SPUT_WIDE_VOLATILE) {
+            infoArray[0].regNum = vA;
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_xmm; //64
+        } else {
+            infoArray[0].regNum = vA;
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_gp;
+        }
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        num_regs_per_bytecode = 1;
+        break;
+
+    case OP_INVOKE_VIRTUAL:
+    case OP_INVOKE_SUPER:
+    case OP_INVOKE_DIRECT:
+    case OP_INVOKE_STATIC:
+    case OP_INVOKE_INTERFACE:
+    case OP_INVOKE_VIRTUAL_QUICK:
+    case OP_INVOKE_SUPER_QUICK:
+        codeSize = 3;
+        vD = FETCH(2) & 0xf; //object for virtual,direct & interface
+        count = INST_B(inst);
+        vE = (FETCH(2) >> 4) & 0xf;
+        vF = (FETCH(2) >> 8) & 0xf;
+        vG = (FETCH(2) >> 12) & 0xf;
+        vA = INST_A(inst); //5th argument
+        if(count == 0) {
+            if(inst_op == OP_INVOKE_VIRTUAL || inst_op == OP_INVOKE_DIRECT ||
+               inst_op == OP_INVOKE_INTERFACE || inst_op == OP_INVOKE_VIRTUAL_QUICK ||
+               inst_op == OP_INVOKE_SUPER_QUICK) {
+                infoArray[0].regNum = vD;
+                infoArray[0].refCount = 1;
+                infoArray[0].accessType = REGACCESS_U;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                num_regs_per_bytecode = 1;
+            }
+            num_regs_per_bytecode = 0;
+        }
+        else num_regs_per_bytecode = count;
+        if(count >= 1) {
+            infoArray[0].regNum = vD;
+            if(inst_op == OP_INVOKE_VIRTUAL_QUICK ||
+               inst_op == OP_INVOKE_SUPER_QUICK) {
+                infoArray[0].refCount = 2;
+            } else if(inst_op == OP_INVOKE_VIRTUAL || inst_op == OP_INVOKE_DIRECT || inst_op == OP_INVOKE_INTERFACE) {
+                infoArray[0].refCount = 2;
+            } else {
+                infoArray[0].refCount = 1;
+            }
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_gp;
+        }
+        if(count >= 2) {
+            infoArray[1].regNum = vE;
+            infoArray[1].refCount = 1;
+            infoArray[1].accessType = REGACCESS_U;
+            infoArray[1].physicalType = LowOpndRegType_gp;
+        }
+        if(count >= 3) {
+            infoArray[2].regNum = vF;
+            infoArray[2].refCount = 1;
+            infoArray[2].accessType = REGACCESS_U;
+            infoArray[2].physicalType = LowOpndRegType_gp;
+        }
+        if(count >= 4) {
+            infoArray[3].regNum = vG;
+            infoArray[3].refCount = 1;
+            infoArray[3].accessType = REGACCESS_U;
+            infoArray[3].physicalType = LowOpndRegType_gp;
+        }
+        if(count >= 5) {
+            infoArray[4].regNum = vA;
+            infoArray[4].refCount = 1;
+            infoArray[4].accessType = REGACCESS_U;
+            infoArray[4].physicalType = LowOpndRegType_gp;
+        }
+        if(inst_op != OP_INVOKE_VIRTUAL_QUICK && inst_op != OP_INVOKE_SUPER_QUICK)
+            updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_ECX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        break;
+    case OP_INVOKE_VIRTUAL_RANGE:
+    case OP_INVOKE_SUPER_RANGE:
+    case OP_INVOKE_DIRECT_RANGE:
+    case OP_INVOKE_STATIC_RANGE:
+    case OP_INVOKE_INTERFACE_RANGE:
+    case OP_INVOKE_VIRTUAL_QUICK_RANGE:
+    case OP_INVOKE_SUPER_QUICK_RANGE:
+        codeSize = 3;
+        vD = FETCH(2);
+        count = INST_AA(inst);
+        if(count == 0) {
+            if(inst_op == OP_INVOKE_VIRTUAL_RANGE || inst_op == OP_INVOKE_DIRECT_RANGE ||
+               inst_op == OP_INVOKE_INTERFACE_RANGE || inst_op == OP_INVOKE_VIRTUAL_QUICK_RANGE ||
+               inst_op == OP_INVOKE_SUPER_QUICK_RANGE) {
+                infoArray[0].regNum = vD;
+                infoArray[0].refCount = 1;
+                infoArray[0].accessType = REGACCESS_U;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+            }
+        }
+        if(count > 0) { //same for count > 10
+            for(kk = 0; kk < count; kk++) {
+                infoArray[kk].regNum = vD+kk; //src
+                if(kk == 0 && (inst_op == OP_INVOKE_VIRTUAL_QUICK_RANGE ||
+                               inst_op == OP_INVOKE_SUPER_QUICK_RANGE))
+                    infoArray[kk].refCount = 2;
+                else if(kk == 0 && (inst_op == OP_INVOKE_VIRTUAL_RANGE ||
+                                    inst_op == OP_INVOKE_DIRECT_RANGE ||
+                                    inst_op == OP_INVOKE_INTERFACE_RANGE))
+                    infoArray[kk].refCount = 2;
+                else
+                    infoArray[kk].refCount = 1;
+                infoArray[kk].accessType = REGACCESS_U;
+                infoArray[kk].physicalType = LowOpndRegType_gp;
+            }
+        }
+        if(inst_op != OP_INVOKE_VIRTUAL_QUICK_RANGE && inst_op != OP_INVOKE_SUPER_QUICK_RANGE)
+            updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_ECX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = count;
+        break;
+    case OP_NEG_INT:
+    case OP_NOT_INT:
+    case OP_NEG_FLOAT:
+        vA = INST_A(inst); //destination
+        vB = INST_B(inst);
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        codeSize = 1;
+        break;
+    case OP_NEG_LONG:
+    case OP_NOT_LONG:
+    case OP_NEG_DOUBLE:
+        vA = INST_A(inst); //destination
+        vB = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_INT_TO_LONG: //hard-coded registers
+        vA = INST_A(inst); //destination
+        vB = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp; //save from %eax
+        infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1;
+        infoArray[2].regNum = vA+1;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[2].allocConstraints[PhysicalReg_EDX].count = 1;
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_INT_TO_FLOAT: //32 to 32
+    case OP_INT_TO_DOUBLE: //32 to 64
+    case OP_LONG_TO_FLOAT: //64 to 32
+    case OP_LONG_TO_DOUBLE: //64 to 64
+    case OP_FLOAT_TO_DOUBLE: //32 to 64
+    case OP_DOUBLE_TO_FLOAT: //64 to 32
+        vA = INST_A(inst); //destination
+        vB = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        if(inst_op == OP_INT_TO_DOUBLE || inst_op == OP_LONG_TO_DOUBLE || inst_op == OP_FLOAT_TO_DOUBLE)
+            infoArray[1].physicalType = LowOpndRegType_fs;
+        else
+            infoArray[1].physicalType = LowOpndRegType_fs_s;
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        if(inst_op == OP_INT_TO_FLOAT || inst_op == OP_INT_TO_DOUBLE || inst_op == OP_FLOAT_TO_DOUBLE)
+            infoArray[0].physicalType = LowOpndRegType_fs_s; //float
+        else
+            infoArray[0].physicalType = LowOpndRegType_fs;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_LONG_TO_INT:
+        vA = INST_A(inst); //destination
+        vB = INST_B(inst);
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        codeSize = 1;
+        break;
+    case OP_FLOAT_TO_INT:
+    case OP_DOUBLE_TO_INT: //for reaching-def analysis
+        vA = INST_A(inst); //destination
+        vB = INST_B(inst);
+        codeSize = 1;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 3;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_fs_s; //store_int_fp_stack_VR
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        if(inst_op == OP_DOUBLE_TO_INT)
+            infoArray[0].physicalType = LowOpndRegType_fs;
+        else
+            infoArray[0].physicalType = LowOpndRegType_fs_s;
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_FLOAT_TO_LONG:
+    case OP_DOUBLE_TO_LONG:
+        vA = INST_A(inst); //destination
+        vB = INST_B(inst);
+        codeSize = 1;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 3;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_fs;
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        if(inst_op == OP_DOUBLE_TO_LONG)
+            infoArray[0].physicalType = LowOpndRegType_fs;
+        else
+            infoArray[0].physicalType = LowOpndRegType_fs_s;
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_INT_TO_BYTE:
+    case OP_INT_TO_CHAR:
+    case OP_INT_TO_SHORT:
+        vA = INST_A(inst); //destination
+        vB = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        break;
+
+    case OP_ADD_INT:
+    case OP_SUB_INT:
+    case OP_MUL_INT:
+    case OP_AND_INT:
+    case OP_OR_INT:
+    case OP_XOR_INT:
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        codeSize = 2;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_DIV_INT:
+    case OP_REM_INT:
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        codeSize = 2;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 2;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1; //for v1
+        if(inst_op == OP_REM_INT)
+            infoArray[2].allocConstraints[PhysicalReg_EDX].count = 1;//vA
+        else
+            infoArray[2].allocConstraints[PhysicalReg_EAX].count = 1;//vA
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_SHL_INT:
+    case OP_SHR_INT:
+    case OP_USHR_INT:
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        codeSize = 2;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = v2; // in ecx
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[1].allocConstraints[PhysicalReg_ECX].count = 1;
+        updateCurrentBBWithConstraints(PhysicalReg_ECX);
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_ADD_LONG:
+    case OP_SUB_LONG:
+    case OP_AND_LONG:
+    case OP_OR_LONG:
+    case OP_XOR_LONG:
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        codeSize = 2;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_xmm;
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_MUL_LONG: //used int
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = v1+1;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = v2;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_U;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = v2+1;
+        infoArray[3].refCount = 1;
+        infoArray[3].accessType = REGACCESS_U;
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = vA;
+        infoArray[4].refCount = 1;
+        infoArray[4].accessType = REGACCESS_D;
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = vA+1;
+        infoArray[5].refCount = 1;
+        infoArray[5].accessType = REGACCESS_D;
+        infoArray[5].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 6;
+        codeSize = 2;
+        break;
+    case OP_DIV_LONG: //v1: xmm v2,vA:
+    case OP_REM_LONG:
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = v2+1;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_U;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = vA;
+        infoArray[3].refCount = 1;
+        infoArray[3].accessType = REGACCESS_D;
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = vA+1;
+        infoArray[4].refCount = 1;
+        infoArray[4].accessType = REGACCESS_D;
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 5;
+        codeSize = 2;
+        break;
+    case OP_SHL_LONG: //v2: 32, move_ss; v1,vA: xmm CHECK
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_ss;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 3;
+        codeSize = 2;
+        break;
+    case OP_SHR_LONG: //v2: 32, move_ss; v1,vA: xmm CHECK
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_ss;
+        infoArray[2].regNum = v1+1;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_U;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = vA;
+        infoArray[3].refCount = 1;
+        infoArray[3].accessType = REGACCESS_D;
+        infoArray[3].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 4;
+        codeSize = 2;
+        break;
+    case OP_USHR_LONG: //v2: move_ss; v1,vA: move_sd
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm; //sd
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_ss; //ss
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_xmm; //sd
+        num_regs_per_bytecode = 3;
+        codeSize = 2;
+        break;
+    case OP_ADD_FLOAT: //move_ss
+    case OP_SUB_FLOAT:
+    case OP_MUL_FLOAT:
+    case OP_DIV_FLOAT:
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        codeSize = 2;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_ss;
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_ss;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_ss;
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_REM_FLOAT: //32 bit GPR, fp_stack for output
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        codeSize = 2;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_fs_s;
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_ADD_DOUBLE: //move_sd
+    case OP_SUB_DOUBLE:
+    case OP_MUL_DOUBLE:
+    case OP_DIV_DOUBLE:
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        codeSize = 2;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_xmm;
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 3;
+        break;
+    case OP_REM_DOUBLE: //64 bit XMM, fp_stack for output
+        vA = INST_AA(inst);
+        v1 = *((u1*)rPC + 2);
+        v2 = *((u1*)rPC + 3);
+        codeSize = 2;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_D;
+        infoArray[2].physicalType = LowOpndRegType_fs;
+        infoArray[0].regNum = v1;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 3;
+        break;
+
+    case OP_ADD_INT_2ADDR:
+    case OP_SUB_INT_2ADDR:
+    case OP_MUL_INT_2ADDR:
+    case OP_AND_INT_2ADDR:
+    case OP_OR_INT_2ADDR:
+    case OP_XOR_INT_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 2;
+        infoArray[1].accessType = REGACCESS_UD; //use then define
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = v2;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_DIV_INT_2ADDR:
+    case OP_REM_INT_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 3;
+        infoArray[1].accessType = REGACCESS_UD; //use then define
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = v2;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1; //for v1 is vA
+        if(inst_op == OP_REM_INT_2ADDR)
+            infoArray[1].allocConstraints[PhysicalReg_EDX].count = 1;//vA
+        else
+            infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1;//vA
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_SHL_INT_2ADDR:
+    case OP_SHR_INT_2ADDR:
+    case OP_USHR_INT_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 2;
+        infoArray[1].accessType = REGACCESS_UD; //use then define
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = v2;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[0].allocConstraints[PhysicalReg_ECX].count = 1; //v2
+        updateCurrentBBWithConstraints(PhysicalReg_ECX);
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_ADD_LONG_2ADDR:
+    case OP_SUB_LONG_2ADDR:
+    case OP_AND_LONG_2ADDR:
+    case OP_OR_LONG_2ADDR:
+    case OP_XOR_LONG_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 2;
+        infoArray[1].accessType = REGACCESS_UD;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[0].regNum = v2;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_MUL_LONG_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        codeSize = 1;
+        num_regs_per_bytecode = 4;
+        infoArray[0].regNum = v2;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = v2+1;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 2;
+        infoArray[2].accessType = REGACCESS_UD;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = vA+1;
+        infoArray[3].refCount = 2;
+        infoArray[3].accessType = REGACCESS_UD;
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        break;
+    case OP_DIV_LONG_2ADDR: //vA used as xmm, then updated as gps
+    case OP_REM_LONG_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        num_regs_per_bytecode = 5;
+        codeSize = 1;
+        infoArray[0].regNum = vA;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = v2;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = v2+1;
+        infoArray[2].refCount = 1;
+        infoArray[2].accessType = REGACCESS_U;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = vA;
+        infoArray[3].refCount = 1;
+        infoArray[3].accessType = REGACCESS_D;
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = vA+1;
+        infoArray[4].refCount = 1;
+        infoArray[4].accessType = REGACCESS_D;
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        break;
+    case OP_SHL_LONG_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        num_regs_per_bytecode = 2;
+        codeSize = 1;
+        infoArray[0].regNum = v2; //ss
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_ss;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 2;
+        infoArray[1].accessType = REGACCESS_UD;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        break;
+    case OP_SHR_LONG_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        num_regs_per_bytecode = 3;
+        codeSize = 1;
+        infoArray[0].regNum = v2; //ss
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_ss;
+        infoArray[1].regNum = vA+1;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_U;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = vA;
+        infoArray[2].refCount = 2;
+        infoArray[2].accessType = REGACCESS_UD;
+        infoArray[2].physicalType = LowOpndRegType_xmm;
+        break;
+    case OP_USHR_LONG_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        num_regs_per_bytecode = 2;
+        codeSize = 1;
+        infoArray[0].regNum = v2;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_ss; //ss CHECK
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 2;
+        infoArray[1].accessType = REGACCESS_UD;
+        infoArray[1].physicalType = LowOpndRegType_xmm; //sd
+        break;
+    case OP_ADD_FLOAT_2ADDR:
+    case OP_SUB_FLOAT_2ADDR:
+    case OP_MUL_FLOAT_2ADDR:
+    case OP_DIV_FLOAT_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 2;
+        infoArray[1].accessType = REGACCESS_UD;
+        infoArray[1].physicalType = LowOpndRegType_ss;
+        infoArray[0].regNum = v2;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_ss;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_REM_FLOAT_2ADDR: //load vA as GPR, store from fs
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 2;
+        infoArray[1].accessType = REGACCESS_UD;
+        infoArray[1].physicalType = LowOpndRegType_gp; //CHECK
+        infoArray[0].regNum = v2;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_ADD_DOUBLE_2ADDR:
+    case OP_SUB_DOUBLE_2ADDR:
+    case OP_MUL_DOUBLE_2ADDR:
+    case OP_DIV_DOUBLE_2ADDR:
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 2;
+        infoArray[1].accessType = REGACCESS_UD;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[0].regNum = v2;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_REM_DOUBLE_2ADDR: //load to xmm, store from fs
+        vA = INST_A(inst);
+        v2 = INST_B(inst);
+        codeSize = 1;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 2;
+        infoArray[1].accessType = REGACCESS_UD;
+        infoArray[1].physicalType = LowOpndRegType_xmm; //CHECK
+        infoArray[0].regNum = v2;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        num_regs_per_bytecode = 2;
+        break;
+
+    case OP_ADD_INT_LIT16:
+    case OP_RSUB_INT:
+    case OP_MUL_INT_LIT16:
+    case OP_AND_INT_LIT16:
+    case OP_OR_INT_LIT16:
+    case OP_XOR_INT_LIT16:
+        vA = INST_A(inst);
+        vB = INST_B(inst);
+        codeSize = 2;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_DIV_INT_LIT16:
+    case OP_REM_INT_LIT16:
+        vA = INST_A(inst);
+        vB = INST_B(inst);
+        codeSize = 2;
+        tmp_s4 = (s2)FETCH(1);
+        tmp_s2 = tmp_s4;
+        if(tmp_s2 == 0) {
+            num_regs_per_bytecode = 0;
+            break;
+        }
+        infoArray[1].regNum = vA; //in edx for rem, in eax
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = vB; //in eax
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        if(inst_op == OP_DIV_INT_LIT16) {
+            int power = isPowerOfTwo(tmp_s2);
+            if(power >= 1) { /* divide by a power of 2 constant */
+                infoArray[1].refCount = 1;
+                break;
+            }
+        }
+        if(tmp_s2 == -1)
+            infoArray[1].refCount = 2;
+        else
+            infoArray[1].refCount = 1;
+        if(inst_op == OP_REM_INT_LIT16)
+            infoArray[1].allocConstraints[PhysicalReg_EDX].count = 1;
+        else
+            infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1;
+        infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        break;
+    case OP_ADD_INT_LIT8:
+    case OP_RSUB_INT_LIT8:
+    case OP_MUL_INT_LIT8:
+    case OP_AND_INT_LIT8:
+    case OP_OR_INT_LIT8:
+    case OP_XOR_INT_LIT8:
+    case OP_SHL_INT_LIT8:
+    case OP_SHR_INT_LIT8:
+    case OP_USHR_INT_LIT8:
+        codeSize = 2;
+        vA = INST_AA(inst);
+        vB = (u2)FETCH(1) & 0xff;
+        infoArray[1].regNum = vA;
+        infoArray[1].refCount = 1;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        break;
+    case OP_DIV_INT_LIT8:
+    case OP_REM_INT_LIT8:
+        codeSize = 2;
+        vA = INST_AA(inst);
+        vB = (u2)FETCH(1) & 0xff;
+        tmp_s2 = (s2)FETCH(1) >> 8;
+        if(tmp_s2 == 0) {
+            num_regs_per_bytecode = 0;
+            break;
+        }
+
+        infoArray[1].regNum = vA;
+        infoArray[1].accessType = REGACCESS_D;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[0].regNum = vB;
+        infoArray[0].refCount = 1;
+        infoArray[0].accessType = REGACCESS_U;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        num_regs_per_bytecode = 2;
+        if(inst_op == OP_DIV_INT_LIT8) {
+            int power = isPowerOfTwo(tmp_s2);
+            if(power >= 1) { /* divide by a power of 2 constant */
+                infoArray[1].refCount = 1;
+                break;
+            }
+        }
+
+        if(tmp_s2 == -1)
+            infoArray[1].refCount = 2;
+        else
+            infoArray[1].refCount = 1;
+        if(inst_op == OP_REM_INT_LIT8)
+            infoArray[1].allocConstraints[PhysicalReg_EDX].count = 1;
+        else
+            infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1;
+        infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1;
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        break;
+    case OP_EXECUTE_INLINE: //update glue->retval
+    case OP_EXECUTE_INLINE_RANGE:
+        u4 vC;
+        if(inst_op == OP_EXECUTE_INLINE)
+            num = INST_B(inst);
+        else
+            num = INST_AA(inst);
+        if(inst_op == OP_EXECUTE_INLINE) {
+            vC = FETCH(2) & 0xf;
+            vD = (FETCH(2) >> 4) & 0xf;
+            vE = (FETCH(2) >> 8) & 0xf;
+            vF = FETCH(2) >> 12;
+        } else {
+            vC = FETCH(2);
+            vD = vC + 1;
+            vE = vC + 2;
+            vF = vC + 3;
+        }
+        codeSize = 3;
+        if(num >= 1) {
+            infoArray[0].regNum = vC;
+            infoArray[0].refCount = 1;
+            infoArray[0].accessType = REGACCESS_U;
+            infoArray[0].physicalType = LowOpndRegType_gp;
+        }
+        if(num >= 2) {
+            infoArray[1].regNum = vD;
+            infoArray[1].refCount = 1;
+            infoArray[1].accessType = REGACCESS_U;
+            infoArray[1].physicalType = LowOpndRegType_gp;
+        }
+        if(num >= 3) {
+            infoArray[2].regNum = vE;
+            infoArray[2].refCount = 1;
+            infoArray[2].accessType = REGACCESS_U;
+            infoArray[2].physicalType = LowOpndRegType_gp;
+        }
+        if(num >= 4) {
+            infoArray[3].regNum = vF;
+            infoArray[3].refCount = 1;
+            infoArray[3].accessType = REGACCESS_U;
+            infoArray[3].physicalType = LowOpndRegType_gp;
+        }
+        updateCurrentBBWithConstraints(PhysicalReg_EAX);
+        updateCurrentBBWithConstraints(PhysicalReg_EDX);
+        num_regs_per_bytecode = num;
+        break;
+#if FIXME
+    case OP_INVOKE_OBJECT_INIT_RANGE:
+        codeSize = 3;
+        num_regs_per_bytecode = 0;
+        break;
+#endif
+    }
+    return codeSize;
+}
+//! Updates infoArray(TempRegInfo) with temporaries accessed by INVOKE_NO_RANGE
+
+//!
+int updateInvokeNoRange(TempRegInfo* infoArray, int startInd) {
+    int j = startInd;
+    //invokeMethodNoRange
+    int count = INST_B(inst);
+    if(count == 5) {
+        infoArray[j].regNum = 22;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 4) {
+        infoArray[j].regNum = 23;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 3) {
+        infoArray[j].regNum = 24;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 2) {
+        infoArray[j].regNum = 25;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 1) {
+        infoArray[j].regNum = 26;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    return j;
+}
+//! Updates infoArray(TempRegInfo) with temporaries accessed by INVOKE_RANGE
+
+//! LOOP_COUNT is used to indicate a variable is live through a loop
+int updateInvokeRange(TempRegInfo* infoArray, int startIndex) {
+    int j = startIndex;
+    int count = INST_AA(inst);
+    infoArray[j].regNum = 21;
+    if(count <= 10) {
+        infoArray[j].refCount = 1+count; //DU
+    } else {
+        infoArray[j].refCount = 2+3*LOOP_COUNT;
+    }
+    infoArray[j].physicalType = LowOpndRegType_gp;
+    j++;
+    if(count >= 1 && count <= 10) {
+        infoArray[j].regNum = 22;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 2 && count <= 10) {
+        infoArray[j].regNum = 23;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 3 && count <= 10) {
+        infoArray[j].regNum = 24;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 4 && count <= 10) {
+        infoArray[j].regNum = 25;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 5 && count <= 10) {
+        infoArray[j].regNum = 26;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 6 && count <= 10) {
+        infoArray[j].regNum = 27;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 7 && count <= 10) {
+        infoArray[j].regNum = 28;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 8 && count <= 10) {
+        infoArray[j].regNum = 29;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count >= 9 && count <= 10) {
+        infoArray[j].regNum = 30;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count == 10) {
+        infoArray[j].regNum = 31;
+        infoArray[j].refCount = 2; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    if(count > 10) {
+        //NOTE: inside a loop, LOOP_COUNT can't be 1
+        //      if LOOP_COUNT is 1, it is likely that a logical register is freed inside the loop
+        //         and the next iteration will have incorrect result
+        infoArray[j].regNum = 12;
+        infoArray[j].refCount = 1+3*LOOP_COUNT; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+        infoArray[j].regNum = 13;
+        infoArray[j].refCount = 1+LOOP_COUNT; //DU
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+        infoArray[j].regNum = 14;
+        //MUST be 2, otherwise, transferToState will think its state was in memory
+        infoArray[j].refCount = 2; //DU local
+        infoArray[j].physicalType = LowOpndRegType_gp;
+        j++;
+    }
+    return j;
+}
+
+/* update temporaries used by RETURN bytecodes
+   a temporary is represented by <number, type of the temporary>
+   */
+int updateReturnCommon(TempRegInfo* infoArray) {
+    int numTmps;
+    infoArray[0].regNum = 1;
+    infoArray[0].refCount = 4; //DU
+    infoArray[0].physicalType = LowOpndRegType_scratch;
+    infoArray[1].regNum = 2;
+    infoArray[1].refCount = 2; //DU
+    infoArray[1].physicalType = LowOpndRegType_scratch;
+    infoArray[2].regNum = PhysicalReg_EAX;
+    infoArray[2].refCount = 5; //DU
+    infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+    infoArray[3].regNum = 1;
+#if defined(ENABLE_TRACING)//WITH_DEBUGGER is true WITH_PROFILER can be false
+    infoArray[3].refCount = 6+4;
+#else
+    infoArray[3].refCount = 6; //DU
+#endif
+    infoArray[3].physicalType = LowOpndRegType_gp;
+    infoArray[4].regNum = 2;
+    infoArray[4].refCount = 4; //DU
+    infoArray[4].physicalType = LowOpndRegType_gp;
+    infoArray[5].regNum = 5;
+    infoArray[5].refCount = 2; //DU
+    infoArray[5].physicalType = LowOpndRegType_gp;
+    infoArray[6].regNum = 10;
+    infoArray[6].refCount = 3;
+    infoArray[6].physicalType = LowOpndRegType_gp;
+    infoArray[7].regNum = 6;
+    infoArray[7].refCount = 4; //DU
+    infoArray[7].physicalType = LowOpndRegType_gp;
+    infoArray[8].regNum = 3;
+    infoArray[8].refCount = 3;
+    infoArray[8].physicalType = LowOpndRegType_gp;
+    infoArray[9].regNum = 7;
+    infoArray[9].refCount = 2; //DU
+    infoArray[9].physicalType = LowOpndRegType_gp;
+    numTmps = 12;
+#if defined(ENABLE_TRACING)
+    infoArray[12].regNum = 4;
+    infoArray[12].refCount = 3; //DU
+    infoArray[12].physicalType = LowOpndRegType_gp;
+    infoArray[13].regNum = 3;
+    infoArray[13].refCount = 2; //DU
+    infoArray[13].physicalType = LowOpndRegType_scratch;
+    infoArray[14].regNum = 15;
+    infoArray[14].refCount = 2; //DU
+    infoArray[14].physicalType = LowOpndRegType_gp;
+    infoArray[15].regNum = 16;
+    infoArray[15].refCount = 2; //DU
+    infoArray[15].physicalType = LowOpndRegType_gp;
+    infoArray[16].regNum = PhysicalReg_EDX;
+    infoArray[16].refCount = 2; //DU
+    infoArray[16].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+    infoArray[17].regNum = 6;
+    infoArray[17].refCount = 2; //DU
+    infoArray[17].physicalType = LowOpndRegType_scratch;
+    numTmps = 18;
+#endif
+    infoArray[10].regNum = 14;
+    infoArray[10].refCount = 2; //DU
+    infoArray[10].physicalType = LowOpndRegType_gp;
+    infoArray[11].regNum = 4;
+    infoArray[11].refCount = 2; //DU
+    infoArray[11].physicalType = LowOpndRegType_scratch;
+#ifdef DEBUG_CALL_STACK
+    infoArray[numTmps].regNum = 5;
+    infoArray[numTmps].refCount = 2;
+    infoArray[numTmps].physicalType = LowOpndRegType_scratch;
+    numTmps++;
+#endif
+    infoArray[numTmps].regNum = PhysicalReg_EBX;
+    /* used to hold chaining cell
+       updated to be returnAddr
+       then conditionally updated to zero
+       used to update inJitCodeCache
+       compare against zero to determine whether to jump to native code
+       jump to native code (%ebx)
+    */
+    infoArray[numTmps].refCount = 3+1+1;
+    infoArray[numTmps].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+    numTmps++;
+    infoArray[numTmps].regNum = 17;
+    infoArray[numTmps].refCount = 2; //DU
+    infoArray[numTmps].physicalType = LowOpndRegType_gp;
+    numTmps++;
+    infoArray[numTmps].regNum = 7;
+    infoArray[numTmps].refCount = 4; //DU
+    infoArray[numTmps].physicalType = LowOpndRegType_scratch;
+    numTmps++;
+    return numTmps;
+}
+
+/* update temporaries used by predicted INVOKE_VIRTUAL & INVOKE_INTERFACE */
+int updateGenPrediction(TempRegInfo* infoArray, bool isInterface) {
+    infoArray[0].regNum = 40;
+    infoArray[0].physicalType = LowOpndRegType_gp;
+    infoArray[1].regNum = 41;
+    infoArray[1].physicalType = LowOpndRegType_gp;
+    infoArray[2].regNum = 32;
+    infoArray[2].refCount = 2;
+    infoArray[2].physicalType = LowOpndRegType_gp;
+
+    if(isInterface) {
+        infoArray[0].refCount = 2+2;
+        infoArray[1].refCount = 3+2-1; //for temp41, -1 for gingerbread
+        infoArray[3].regNum = 33;
+        infoArray[3].refCount = 4+1;
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = PhysicalReg_EAX;
+        infoArray[4].refCount = 5;
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[5].regNum = PhysicalReg_ECX;
+        infoArray[5].refCount = 1+1+2; //used in ArgsDone (twice)
+        infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[6].regNum = 10;
+        infoArray[6].refCount = 2;
+        infoArray[6].physicalType = LowOpndRegType_scratch;
+        infoArray[7].regNum = 9;
+        infoArray[7].refCount = 2;
+        infoArray[7].physicalType = LowOpndRegType_scratch;
+        infoArray[8].regNum = 8;
+        infoArray[8].refCount = 2;
+        infoArray[8].physicalType = LowOpndRegType_scratch;
+        infoArray[9].regNum = PhysicalReg_EDX; //space holder
+        infoArray[9].refCount = 1;
+        infoArray[9].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[10].regNum = 43;
+        infoArray[10].refCount = 3;
+        infoArray[10].physicalType = LowOpndRegType_gp;
+        infoArray[11].regNum = 44;
+        infoArray[11].refCount = 3;
+        infoArray[11].physicalType = LowOpndRegType_gp;
+        infoArray[12].regNum = 45;
+        infoArray[12].refCount = 2;
+        infoArray[12].physicalType = LowOpndRegType_gp;
+        infoArray[13].regNum = 7;
+        infoArray[13].refCount = 4;
+        infoArray[13].physicalType = LowOpndRegType_scratch;
+        return 14;
+    } else { //virtual or virtual_quick
+        infoArray[0].refCount = 2+2;
+        infoArray[1].refCount = 3+2-2; //for temp41, -2 for gingerbread
+        infoArray[2].refCount++; //for temp32 gingerbread
+        infoArray[3].regNum = 33;
+        infoArray[3].refCount = 4+1;
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 34;
+        infoArray[4].refCount = 2;
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = PhysicalReg_EAX;
+        infoArray[5].refCount = 2;
+        infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[6].regNum = PhysicalReg_ECX;
+        infoArray[6].refCount = 1+3+2;
+        infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[7].regNum = 10;
+        infoArray[7].refCount = 2;
+        infoArray[7].physicalType = LowOpndRegType_scratch;
+        infoArray[8].regNum = PhysicalReg_EDX; //space holder
+        infoArray[8].refCount = 1;
+        infoArray[8].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[9].regNum = 43;
+        infoArray[9].refCount = 3;
+        infoArray[9].physicalType = LowOpndRegType_gp;
+        infoArray[10].regNum = 44;
+        infoArray[10].refCount = 3;
+        infoArray[10].physicalType = LowOpndRegType_gp;
+        infoArray[11].regNum = 7;
+        infoArray[11].refCount = 4;
+        infoArray[11].physicalType = LowOpndRegType_scratch;
+        return 12;
+    }
+}
+
+int updateMarkCard(TempRegInfo* infoArray, int j1/*valReg*/,
+                    int j2/*tgtAddrReg*/, int j3/*scratchReg*/) {
+    infoArray[j3].regNum = 11;
+    infoArray[j3].physicalType = LowOpndRegType_gp;
+    infoArray[j3].refCount = 3;
+    infoArray[j3].is8Bit = true;
+    infoArray[j1].refCount++;
+    infoArray[j2].refCount += 2;
+    infoArray[j3+1].regNum = 6;
+    infoArray[j3+1].physicalType = LowOpndRegType_scratch;
+    infoArray[j3+1].refCount = 2;
+    return j3+2;
+}
+
+int updateMarkCard_notNull(TempRegInfo* infoArray,
+                           int j2/*tgtAddrReg*/, int j3/*scratchReg*/) {
+    infoArray[j3].regNum = 11;
+    infoArray[j3].physicalType = LowOpndRegType_gp;
+    infoArray[j3].refCount = 3;
+    infoArray[j3].is8Bit = true;
+    infoArray[j2].refCount += 2;
+    infoArray[j3+1].regNum = 2;
+    infoArray[j3+1].refCount = 2; //DU
+    infoArray[j3+1].physicalType = LowOpndRegType_scratch;
+    return j3+2;
+}
+
+int iget_obj_inst = -1;
+//! This function updates infoArray with temporaries accessed when lowering the bytecode
+
+//! returns the number of temporaries
+int getTempRegInfo(TempRegInfo* infoArray) { //returns an array of TempRegInfo
+    int k;
+    int numTmps;
+    for(k = 0; k < MAX_TEMP_REG_PER_BYTECODE; k++) {
+        infoArray[k].linkageToVR = -1;
+        infoArray[k].versionNum = 0;
+        infoArray[k].shareWithVR = true;
+        infoArray[k].is8Bit = false;
+    }
+    u2 vA, v1, length, num, tmp;
+    u2 inst_op = INST_INST(inst);
+    s2 tmp_s2;
+    s4 tmp_s4;
+    switch(inst_op) {
+    case OP_APUT_BYTE:
+        for(k = 0; k < MAX_TEMP_REG_PER_BYTECODE; k++)
+            infoArray[k].shareWithVR = true; //false;
+        break;
+    }
+    switch (INST_INST(inst)) {
+    case OP_NOP:
+        return 0;
+    case OP_MOVE:
+    case OP_MOVE_OBJECT:
+    case OP_MOVE_FROM16:
+    case OP_MOVE_OBJECT_FROM16:
+    case OP_MOVE_16:
+    case OP_MOVE_OBJECT_16:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        return 1;
+    case OP_MOVE_WIDE:
+    case OP_MOVE_WIDE_FROM16:
+    case OP_MOVE_WIDE_16:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        return 1;
+    case OP_MOVE_RESULT:
+    case OP_MOVE_RESULT_OBJECT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_scratch;
+        return 2;
+    case OP_MOVE_RESULT_WIDE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_scratch;
+        return 2;
+    case OP_MOVE_EXCEPTION:
+        infoArray[0].regNum = 2;
+        infoArray[0].refCount = 3; //DUU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 3;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 1;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_scratch;
+        return 3;
+
+    case OP_CONST_4:
+    case OP_CONST_16:
+    case OP_CONST:
+    case OP_CONST_HIGH16:
+    case OP_CONST_WIDE_16:
+    case OP_CONST_WIDE_32:
+    case OP_CONST_WIDE:
+    case OP_CONST_WIDE_HIGH16:
+        return 0;
+    case OP_CONST_STRING: //hardcode %eax
+    case OP_CONST_STRING_JUMBO:
+        infoArray[0].regNum = 3;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_scratch;
+        infoArray[2].regNum = 2;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_scratch;
+        infoArray[3].regNum = PhysicalReg_EAX;
+        infoArray[3].refCount = 4;
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 4;
+    case OP_CONST_CLASS:
+        infoArray[0].regNum = 3;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_scratch;
+        infoArray[2].regNum = 2;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_scratch;
+        infoArray[3].regNum = PhysicalReg_EAX;
+        infoArray[3].refCount = 4;
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 4;
+
+    case OP_MONITOR_ENTER:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 3;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 1;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_scratch;
+        infoArray[3].regNum = 2;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_scratch;
+        infoArray[4].regNum = PhysicalReg_EDX;
+        infoArray[4].refCount = 2;
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 5;
+    case OP_MONITOR_EXIT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = PhysicalReg_EAX;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[2].regNum = 1;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_scratch;
+        infoArray[3].regNum = PhysicalReg_EDX;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[4].regNum = 2;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_scratch;
+        infoArray[5].regNum = 3;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_scratch;
+        return 6;
+    case OP_CHECK_CAST:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 4; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 4;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 6;
+        infoArray[2].refCount = 3; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+
+        infoArray[3].regNum = 1;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_scratch;
+        infoArray[4].regNum = 2;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_scratch;
+
+        infoArray[5].regNum = PhysicalReg_EAX;
+        /* %eax has 3 live ranges
+           1> 5 accesses: to resolve the class object
+           2> call dvmInstanceofNonTrivial to define %eax, then use it once
+           3> move exception object to %eax, then jump to throw_exception
+           if WITH_JIT is true, the first live range has 6 accesses
+        */
+        infoArray[5].refCount = 6;
+        infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[6].regNum = PhysicalReg_EDX;
+        infoArray[6].refCount = 2; //export_pc
+        infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[7].regNum = PhysicalReg_ECX;
+        infoArray[7].refCount = 1;
+        infoArray[7].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[8].regNum = 3;
+        infoArray[8].refCount = 2; //DU
+        infoArray[8].physicalType = LowOpndRegType_scratch;
+        return 9;
+    case OP_INSTANCE_OF:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 4; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 3;
+        infoArray[1].refCount = 4; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 4;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 6;
+        infoArray[3].refCount = 3; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+
+        infoArray[4].regNum = 1;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_scratch;
+        infoArray[5].regNum = 2;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_scratch;
+
+        infoArray[6].regNum = PhysicalReg_EAX;
+        infoArray[6].refCount = 6;
+        infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[7].regNum = 3;
+        infoArray[7].refCount = 2; //DU
+        infoArray[7].physicalType = LowOpndRegType_scratch;
+        infoArray[8].regNum = PhysicalReg_EDX;
+        infoArray[8].refCount = 2; //export_pc for class_resolve
+        infoArray[8].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 9;
+
+    case OP_ARRAY_LENGTH:
+        vA = INST_A(inst);
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[1].linkageToVR = vA;
+        infoArray[2].regNum = PhysicalReg_EDX;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 3;
+    case OP_NEW_INSTANCE:
+        infoArray[0].regNum = PhysicalReg_EAX;
+        //6: class object
+        //3: defined by C function, used twice
+        infoArray[0].refCount = 6; //next version has 3 references
+        infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[1].regNum = PhysicalReg_ECX; //before common_throw_message
+        infoArray[1].refCount = 1;
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 5;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[3].is8Bit = true;
+        infoArray[4].regNum = 6;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+
+        infoArray[5].regNum = 1;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_scratch;
+        infoArray[6].regNum = 2;
+        infoArray[6].refCount = 2; //DU
+        infoArray[6].physicalType = LowOpndRegType_scratch;
+        infoArray[7].regNum = 3;
+        infoArray[7].refCount = 2; //DU
+        infoArray[7].physicalType = LowOpndRegType_scratch;
+
+        infoArray[8].regNum = PhysicalReg_EDX; //before common_throw_message
+        infoArray[8].refCount = 2;
+        infoArray[8].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[9].regNum = 4;
+        infoArray[9].refCount = 2; //DU
+        infoArray[9].physicalType = LowOpndRegType_scratch;
+        return 10;
+
+    case OP_NEW_ARRAY:
+        infoArray[0].regNum = PhysicalReg_EAX;
+        //4: class object
+        //3: defined by C function, used twice
+        infoArray[0].refCount = 4; //next version has 3 references
+        infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[1].regNum = PhysicalReg_EDX; //before common_throw_message
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 5;
+        infoArray[3].refCount = 3; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+
+        infoArray[4].regNum = 1;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_scratch;
+        infoArray[5].regNum = 2;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_scratch;
+        infoArray[6].regNum = 3;
+        infoArray[6].refCount = 2; //DU
+        infoArray[6].physicalType = LowOpndRegType_scratch;
+        infoArray[7].regNum = 4;
+        infoArray[7].refCount = 2; //DU
+        infoArray[7].physicalType = LowOpndRegType_scratch;
+        return 8;
+
+    case OP_FILLED_NEW_ARRAY:
+        length = INST_B(inst);
+        infoArray[0].regNum = PhysicalReg_EAX;
+        //4: class object
+        //3: defined by C function, used twice (array object)
+        //length: access array object to update the content
+        infoArray[0].refCount = 4; //next version has 5+length references
+        infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[1].regNum = PhysicalReg_EDX; //before common_throw_message
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 5;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 6;
+        infoArray[4].refCount = 8; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[4].is8Bit = true;
+
+        if(length >= 1) {
+            infoArray[5].regNum = 7;
+            infoArray[5].refCount = 2; //DU
+            infoArray[5].physicalType = LowOpndRegType_gp;
+        }
+        if(length >= 2) {
+            infoArray[6].regNum = 8;
+            infoArray[6].refCount = 2; //DU
+            infoArray[6].physicalType = LowOpndRegType_gp;
+        }
+        if(length >= 3) {
+            infoArray[7].regNum = 9;
+            infoArray[7].refCount = 2; //DU
+            infoArray[7].physicalType = LowOpndRegType_gp;
+        }
+        if(length >= 4) {
+            infoArray[8].regNum = 10;
+            infoArray[8].refCount = 2; //DU
+            infoArray[8].physicalType = LowOpndRegType_gp;
+        }
+        if(length >= 5) {
+            infoArray[9].regNum = 11;
+            infoArray[9].refCount = 2; //DU
+            infoArray[9].physicalType = LowOpndRegType_gp;
+        }
+        infoArray[5+length].regNum = 1;
+        infoArray[5+length].refCount = 2; //DU
+        infoArray[5+length].physicalType = LowOpndRegType_scratch;
+        infoArray[6+length].regNum = 2;
+        infoArray[6+length].refCount = 4; //DU
+        infoArray[6+length].physicalType = LowOpndRegType_scratch;
+        infoArray[7+length].regNum = 3;
+        infoArray[7+length].refCount = 2; //DU
+        infoArray[7+length].physicalType = LowOpndRegType_scratch;
+        infoArray[8+length].regNum = 4;
+        infoArray[8+length].refCount = 5; //DU
+        infoArray[8+length].physicalType = LowOpndRegType_scratch;
+        return 9+length;
+
+    case OP_FILLED_NEW_ARRAY_RANGE:
+        length = INST_AA(inst);
+        infoArray[0].regNum = PhysicalReg_EAX;
+        //4: class object
+        //3: defined by C function, used twice (array object)
+        //if length is 0, no access to array object
+        //else, used inside a loop
+        infoArray[0].refCount = 4; //next version: 5+(length >= 1 ? LOOP_COUNT : 0)
+        infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[1].regNum = PhysicalReg_EDX; //before common_throw_message
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 5;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 6;
+        infoArray[4].refCount = 8; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[4].is8Bit = true;
+
+        infoArray[5].regNum = 1;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_scratch;
+        infoArray[6].regNum = 2;
+        infoArray[6].refCount = 4; //DU
+        infoArray[6].physicalType = LowOpndRegType_scratch;
+        infoArray[7].regNum = 3;
+        infoArray[7].refCount = 2; //DU
+        infoArray[7].physicalType = LowOpndRegType_scratch;
+
+        infoArray[8].regNum = 7;
+        infoArray[8].refCount = 3*(length >= 1 ? LOOP_COUNT : 0);
+        infoArray[8].physicalType = LowOpndRegType_gp;
+        infoArray[9].regNum = 8;
+        infoArray[9].refCount = 3*(length >= 1 ? LOOP_COUNT : 0);
+        infoArray[9].physicalType = LowOpndRegType_gp;
+        infoArray[10].regNum = 9;
+        infoArray[10].refCount = 2*(length >= 1 ? LOOP_COUNT : 0);
+        infoArray[10].physicalType = LowOpndRegType_gp;
+        infoArray[11].regNum = 10;
+        infoArray[11].refCount = 2*(length >= 1 ? LOOP_COUNT : 0);
+        infoArray[11].physicalType = LowOpndRegType_gp;
+        infoArray[12].regNum = 4;
+        infoArray[12].refCount = 5; //DU
+        infoArray[12].physicalType = LowOpndRegType_scratch;
+        return 13;
+
+    case OP_FILL_ARRAY_DATA:
+        infoArray[0].regNum = PhysicalReg_EAX;
+        infoArray[0].refCount = 2;
+        infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[1].regNum = PhysicalReg_EDX; //before common_throw_message
+#if 0//def HARDREG_OPT
+        infoArray[1].refCount = 3; //next version has refCount of 2
+#else
+        infoArray[1].refCount = 5;
+#endif
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[2].regNum =1;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+
+        infoArray[3].regNum = 1;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_scratch;
+        infoArray[4].regNum = 2;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_scratch;
+        return 5;
+
+    case OP_THROW:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = PhysicalReg_EDX; //before common_throw_message
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[2].regNum = 1;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_scratch;
+        infoArray[3].regNum = 2;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_scratch;
+        return 4;
+    case OP_THROW_VERIFICATION_ERROR:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = PhysicalReg_EDX; //export_pc
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[2].regNum = 1;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_scratch;
+        infoArray[3].regNum = 2;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_scratch;
+        return 4;
+
+    case OP_GOTO: //called function common_periodicChecks4
+#if defined(ENABLE_TRACING)
+        tt = INST_AA(inst);
+        tmp_s2 = (s2)((s2)tt << 8) >> 8;
+        if(tmp_s2 < 0) {
+            infoArray[0].regNum = PhysicalReg_EDX;
+            infoArray[0].refCount = 2;
+            infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+            return 1;
+        }
+#endif
+        return 0;
+    case OP_GOTO_16:
+#if defined(ENABLE_TRACING)
+        tmp_s2 = (s2)FETCH(1);
+        if(tmp_s2 < 0) {
+            infoArray[0].regNum = PhysicalReg_EDX;
+            infoArray[0].refCount = 2;
+            infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+            return 1;
+        }
+#endif
+        return 0;
+    case OP_GOTO_32:
+#if defined(ENABLE_TRACING)
+        tmp_u4 = (u4)FETCH(1);
+        tmp_u4 |= (u4)FETCH(2) << 16;
+        if(((s4)tmp_u4) < 0) {
+            infoArray[0].regNum = PhysicalReg_EDX;
+            infoArray[0].refCount = 2;
+            infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+            return 1;
+        }
+#endif
+        return 0;
+    case OP_IF_EQ:
+    case OP_IF_NE:
+    case OP_IF_LT:
+    case OP_IF_GE:
+    case OP_IF_GT:
+    case OP_IF_LE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+#if defined(ENABLE_TRACING)
+        tmp_s2 = (s2)FETCH(1);
+        if(tmp_s2 < 0) {
+            infoArray[1].regNum = PhysicalReg_EDX;
+            infoArray[1].refCount = 2;
+            infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+            return 2;
+        }
+#endif
+        return 1;
+    case OP_IF_EQZ: //called function common_periodicChecks4
+    case OP_IF_NEZ:
+    case OP_IF_LTZ:
+    case OP_IF_GEZ:
+    case OP_IF_GTZ:
+    case OP_IF_LEZ:
+#if defined(ENABLE_TRACING)
+        tmp_s2 = (s2)FETCH(1);
+        if(tmp_s2 < 0) {
+            infoArray[0].regNum = PhysicalReg_EDX;
+            infoArray[0].refCount = 2;
+            infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+            return 1;
+        }
+#endif
+        return 0;
+    case OP_PACKED_SWITCH: //jump common_backwardBranch, which calls common_periodicChecks_entry, then jump_reg %eax
+    case OP_SPARSE_SWITCH: //%edx, %eax
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = PhysicalReg_EDX;
+        infoArray[1].refCount = 6;
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[2].regNum = PhysicalReg_EAX; //return by dvm helper
+        infoArray[2].refCount = 2+1; //2 uses
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[3].regNum = 1;
+        infoArray[3].refCount = 2;
+        infoArray[3].physicalType = LowOpndRegType_scratch;
+        infoArray[4].regNum = 2;
+        infoArray[4].refCount = 2;
+        infoArray[4].physicalType = LowOpndRegType_scratch;
+        return 5;
+
+    case OP_AGET:
+    case OP_AGET_OBJECT:
+    case OP_AGET_BOOLEAN:
+    case OP_AGET_BYTE:
+    case OP_AGET_CHAR:
+    case OP_AGET_SHORT:
+        vA = INST_AA(inst);
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 4; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 4;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[3].linkageToVR = vA;
+        if(inst_op == OP_AGET_BYTE || inst_op == OP_AGET_BOOLEAN)
+            infoArray[3].is8Bit = true;
+        infoArray[4].regNum = PhysicalReg_EDX;
+        infoArray[4].refCount = 2;
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 5;
+    case OP_AGET_WIDE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 4; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 1;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_xmm;
+        infoArray[4].regNum = PhysicalReg_EDX;
+        infoArray[4].refCount = 2;
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 5;
+
+    case OP_APUT:
+    case OP_APUT_BOOLEAN:
+    case OP_APUT_BYTE:
+    case OP_APUT_CHAR:
+    case OP_APUT_SHORT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 4; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 4;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        if(inst_op == OP_APUT_BYTE || inst_op == OP_APUT_BOOLEAN)
+            infoArray[3].is8Bit = true;
+        infoArray[4].regNum = PhysicalReg_EDX;
+        infoArray[4].refCount = 2;
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 5;
+    case OP_APUT_WIDE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 4; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 1;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_xmm;
+        infoArray[4].regNum = PhysicalReg_EDX;
+        infoArray[4].refCount = 2;
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 5;
+    case OP_APUT_OBJECT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 5+1; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2; //live through function call dvmCanPut
+        infoArray[1].refCount = 3+1; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 4;
+        infoArray[3].refCount = 4+1; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 5;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = 6;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_gp;
+
+        infoArray[6].regNum = PhysicalReg_EDX;
+        infoArray[6].refCount = 2; //DU
+        infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[7].regNum = PhysicalReg_EAX;
+        infoArray[7].refCount = 2; //DU
+        infoArray[7].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[8].regNum = 1;
+        infoArray[8].refCount = 2; //DU
+        infoArray[8].physicalType = LowOpndRegType_scratch;
+        infoArray[0].shareWithVR = false;
+        return updateMarkCard_notNull(infoArray,
+                                      0/*index for tgtAddrReg*/, 9);
+
+    case OP_IGET:
+    case OP_IGET_OBJECT:
+    case OP_IGET_VOLATILE:
+    case OP_IGET_OBJECT_VOLATILE:
+    case OP_IGET_BOOLEAN:
+    case OP_IGET_BYTE:
+    case OP_IGET_CHAR:
+    case OP_IGET_SHORT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_scratch;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_scratch;
+
+        infoArray[2].regNum = PhysicalReg_EDX;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[3].regNum = PhysicalReg_EAX;
+        infoArray[3].refCount = 3; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[4].regNum = 3;
+        infoArray[4].refCount = 3; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = 7;
+#ifdef DEBUG_IGET_OBJ
+        //add hack for a specific instance (iget_obj_inst) of IGET_OBJECT within a method
+        if(inst_op == OP_IGET_OBJECT && !strncmp(currentMethod->clazz->descriptor, "Lspec/benchmarks/_228_jack/Parse", 32) &&
+           !strncmp(currentMethod->name, "buildPhase3", 11))
+        {
+#if 0
+          if(iget_obj_inst == 12) {
+            LOGD("increase count for instance %d of %s %s", iget_obj_inst, currentMethod->clazz->descriptor, currentMethod->name);
+            infoArray[5].refCount = 4; //DU
+          }
+          else
+#endif
+            infoArray[5].refCount = 3;
+          iget_obj_inst++;
+        }
+        else
+          infoArray[5].refCount = 3;
+#else
+        infoArray[5].refCount = 3; //DU
+#endif
+        infoArray[5].physicalType = LowOpndRegType_gp;
+        infoArray[6].regNum = 8;
+        infoArray[6].refCount = 2; //DU
+        infoArray[6].physicalType = LowOpndRegType_gp;
+        infoArray[7].regNum = 9;
+        infoArray[7].refCount = 2; //DU
+        infoArray[7].physicalType = LowOpndRegType_gp;
+        return 8;
+    case OP_IPUT:
+    case OP_IPUT_OBJECT:
+    case OP_IPUT_VOLATILE:
+    case OP_IPUT_OBJECT_VOLATILE:
+    case OP_IPUT_BOOLEAN:
+    case OP_IPUT_BYTE:
+    case OP_IPUT_CHAR:
+    case OP_IPUT_SHORT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_scratch;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_scratch;
+
+        infoArray[2].regNum = PhysicalReg_EDX;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[3].regNum = PhysicalReg_EAX;
+        infoArray[3].refCount = 3; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[4].regNum = 3;
+        infoArray[4].refCount = 3; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = 7;
+        infoArray[5].refCount = 3; //DU
+        infoArray[5].physicalType = LowOpndRegType_gp;
+        infoArray[6].regNum = 8;
+        infoArray[6].refCount = 2; //DU
+        infoArray[6].physicalType = LowOpndRegType_gp;
+        infoArray[7].regNum = 9;
+        infoArray[7].refCount = 2; //DU
+        infoArray[7].physicalType = LowOpndRegType_gp;
+        if(inst_op == OP_IPUT_OBJECT || inst_op == OP_IPUT_OBJECT_VOLATILE) {
+            infoArray[5].shareWithVR = false;
+            return updateMarkCard(infoArray, 7/*index for valReg*/,
+                                  5/*index for tgtAddrReg*/, 8);
+        }
+        return 8;
+    case OP_IGET_WIDE:
+    case OP_IGET_WIDE_VOLATILE:
+    case OP_IPUT_WIDE:
+    case OP_IPUT_WIDE_VOLATILE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_scratch;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_scratch;
+
+        infoArray[2].regNum = PhysicalReg_EDX;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[3].regNum = PhysicalReg_EAX;
+        infoArray[3].refCount = 3; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[4].regNum = 3;
+        infoArray[4].refCount = 3; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = 7;
+        infoArray[5].refCount = 3; //DU
+        infoArray[5].physicalType = LowOpndRegType_gp;
+        infoArray[6].regNum = 8;
+        infoArray[6].refCount = 2; //DU
+        infoArray[6].physicalType = LowOpndRegType_gp;
+        infoArray[7].regNum = 1;
+        infoArray[7].refCount = 2; //DU
+        infoArray[7].physicalType = LowOpndRegType_xmm;
+
+        if(inst_op == OP_IPUT_WIDE_VOLATILE || inst_op == OP_IGET_WIDE_VOLATILE) {
+            infoArray[8].regNum = 3;
+            infoArray[8].refCount = 2; //DU
+            infoArray[8].physicalType = LowOpndRegType_scratch;
+            infoArray[9].regNum = 9;
+            infoArray[9].refCount = 2; //DU
+            infoArray[9].physicalType = LowOpndRegType_gp;
+            return 10;
+        }
+        return 8;
+
+    case OP_SGET:
+    case OP_SGET_OBJECT:
+    case OP_SGET_VOLATILE:
+    case OP_SGET_OBJECT_VOLATILE:
+    case OP_SGET_BOOLEAN:
+    case OP_SGET_BYTE:
+    case OP_SGET_CHAR:
+    case OP_SGET_SHORT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_scratch;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_scratch;
+
+        infoArray[2].regNum = PhysicalReg_EAX;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[3].regNum = 3;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 7;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = PhysicalReg_EDX;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 6;
+    case OP_SPUT:
+    case OP_SPUT_OBJECT:
+    case OP_SPUT_VOLATILE:
+    case OP_SPUT_OBJECT_VOLATILE:
+    case OP_SPUT_BOOLEAN:
+    case OP_SPUT_BYTE:
+    case OP_SPUT_CHAR:
+    case OP_SPUT_SHORT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_scratch;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_scratch;
+
+        infoArray[2].regNum = PhysicalReg_EAX;
+        infoArray[2].refCount = 2+1; //access clazz of the field
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[3].regNum = 3;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 7;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = PhysicalReg_EDX;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        if(inst_op == OP_SPUT_OBJECT || inst_op == OP_SPUT_OBJECT_VOLATILE) {
+            infoArray[2].shareWithVR = false;
+            infoArray[6].regNum = 12;
+            infoArray[6].refCount = 1; //1 def, 2 uses in updateMarkCard
+            infoArray[6].physicalType = LowOpndRegType_gp;
+            return updateMarkCard(infoArray, 4/*index for valReg*/,
+                                  6/*index for tgtAddrReg */, 7);
+        }
+        return 6;
+    case OP_SGET_WIDE:
+    case OP_SGET_WIDE_VOLATILE:
+    case OP_SPUT_WIDE:
+    case OP_SPUT_WIDE_VOLATILE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_scratch;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_scratch;
+
+        infoArray[2].regNum = PhysicalReg_EAX;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[3].regNum = 3;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 1;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_xmm;
+        infoArray[5].regNum = PhysicalReg_EDX;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        if(inst_op == OP_SPUT_WIDE_VOLATILE || inst_op == OP_SGET_WIDE_VOLATILE) {
+            infoArray[6].regNum = 3;
+            infoArray[6].refCount = 2; //DU
+            infoArray[6].physicalType = LowOpndRegType_scratch;
+            infoArray[7].regNum = 9;
+            infoArray[7].refCount = 2; //DU
+            infoArray[7].physicalType = LowOpndRegType_gp;
+            return 8;
+        }
+        return 6;
+
+    case OP_IGET_QUICK:
+    case OP_IGET_OBJECT_QUICK:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = PhysicalReg_EDX;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 3;
+    case OP_IPUT_QUICK:
+    case OP_IPUT_OBJECT_QUICK:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = PhysicalReg_EDX;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        if(inst_op == OP_IPUT_OBJECT_QUICK) {
+            infoArray[0].shareWithVR = false;
+            return updateMarkCard(infoArray, 1/*index for valReg*/,
+                                  0/*index for tgtAddrReg*/, 3);
+        }
+        return 3;
+    case OP_IGET_WIDE_QUICK:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[2].regNum = PhysicalReg_EDX;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 3;
+    case OP_IPUT_WIDE_QUICK:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[2].regNum = PhysicalReg_EDX;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 3;
+
+    case OP_RETURN_VOID:
+    case OP_RETURN_VOID_BARRIER:
+        return updateReturnCommon(infoArray);
+    case OP_RETURN:
+    case OP_RETURN_OBJECT:
+        numTmps = updateReturnCommon(infoArray);
+
+        infoArray[numTmps].regNum = 21;
+        infoArray[numTmps].refCount = 2; //DU
+        infoArray[numTmps].physicalType = LowOpndRegType_gp;
+        numTmps++;
+        infoArray[numTmps].regNum = 22;
+        infoArray[numTmps].refCount = 2; //DU
+        infoArray[numTmps].physicalType = LowOpndRegType_gp;
+        numTmps++;
+        return numTmps;
+    case OP_RETURN_WIDE:
+        numTmps = updateReturnCommon(infoArray);
+
+        infoArray[numTmps].regNum = 10;
+        infoArray[numTmps].refCount = 2; //DU
+        infoArray[numTmps].physicalType = LowOpndRegType_scratch;
+        numTmps++;
+        infoArray[numTmps].regNum = 1;
+        infoArray[numTmps].refCount = 2; //DU
+        infoArray[numTmps].physicalType = LowOpndRegType_xmm;
+        numTmps++;
+        return numTmps;
+
+    case OP_INVOKE_VIRTUAL:
+    case OP_INVOKE_VIRTUAL_RANGE:
+#ifdef PREDICTED_CHAINING
+        numTmps = updateGenPrediction(infoArray, false /*not interface*/);
+        infoArray[numTmps].regNum = 5;
+        infoArray[numTmps].refCount = 3; //DU
+        infoArray[numTmps].physicalType = LowOpndRegType_gp;
+        numTmps++;
+        if(inst_op == OP_INVOKE_VIRTUAL)
+            k = updateInvokeNoRange(infoArray, numTmps);
+        else
+            k = updateInvokeRange(infoArray, numTmps);
+        return k;
+#else
+        infoArray[0].regNum = 3;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 7;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 8;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 6;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 5;
+        infoArray[4].refCount = 3; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = PhysicalReg_EDX;
+        infoArray[5].refCount = 2; //2 versions, first version DU is for exception, 2nd version: eip right before jumping to invokeArgsDone
+        infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[6].regNum = PhysicalReg_ECX; //ecx is ued in invokeArgsDone
+        infoArray[6].refCount = 1+1; //used in .invokeArgsDone
+        infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        //when WITH_JIT is true and PREDICTED_CHAINING is false
+        //  temp 8 and EAX are not used; but it is okay to keep it here
+        infoArray[7].regNum = PhysicalReg_EAX;
+        infoArray[7].refCount = 4; //DU
+        infoArray[7].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[8].regNum = 1;
+        infoArray[8].refCount = 2; //DU
+        infoArray[8].physicalType = LowOpndRegType_scratch;
+        infoArray[9].regNum = 2;
+        infoArray[9].refCount = 2; //DU
+        infoArray[9].physicalType = LowOpndRegType_scratch;
+        if(inst_op == OP_INVOKE_VIRTUAL)
+            k = updateInvokeNoRange(infoArray, 10);
+        else
+            k = updateInvokeRange(infoArray, 10);
+        return k;
+#endif
+    case OP_INVOKE_SUPER:
+    case OP_INVOKE_SUPER_RANGE:
+        infoArray[0].regNum = 3;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 7;
+        infoArray[1].refCount = 3; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 8;
+        infoArray[2].refCount = 3; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 6;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 9;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+
+        infoArray[5].regNum = PhysicalReg_EDX;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[6].regNum = PhysicalReg_ECX;
+        infoArray[6].refCount = 1+1; //DU
+        infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[7].regNum = PhysicalReg_EAX;
+        infoArray[7].refCount = 4; //DU
+        infoArray[7].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[8].regNum = 1;
+        infoArray[8].refCount = 2; //DU
+        infoArray[8].physicalType = LowOpndRegType_scratch;
+        infoArray[9].regNum = 2;
+        infoArray[9].refCount = 2; //DU
+        infoArray[9].physicalType = LowOpndRegType_scratch;
+        infoArray[10].regNum = 3;
+        infoArray[10].refCount = 2; //DU
+        infoArray[10].physicalType = LowOpndRegType_scratch;
+        infoArray[11].regNum = 4;
+        infoArray[11].refCount = 2; //DU
+        infoArray[11].physicalType = LowOpndRegType_scratch;
+        if(inst_op == OP_INVOKE_SUPER)
+            k = updateInvokeNoRange(infoArray, 12);
+        else
+            k = updateInvokeRange(infoArray, 12);
+        return k;
+    case OP_INVOKE_DIRECT:
+    case OP_INVOKE_DIRECT_RANGE:
+        infoArray[0].regNum = 3;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 5;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+
+        infoArray[2].regNum = PhysicalReg_EDX;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[3].regNum = PhysicalReg_ECX;
+        infoArray[3].refCount = 2;
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[4].regNum = PhysicalReg_EAX;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[5].regNum = 1;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_scratch;
+        infoArray[6].regNum = 2;
+        infoArray[6].refCount = 2; //DU
+        infoArray[6].physicalType = LowOpndRegType_scratch;
+        if(inst_op == OP_INVOKE_DIRECT)
+            k = updateInvokeNoRange(infoArray, 7);
+        else
+            k = updateInvokeRange(infoArray, 7);
+        return k;
+    case OP_INVOKE_STATIC:
+    case OP_INVOKE_STATIC_RANGE:
+        infoArray[0].regNum = 3;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+
+        infoArray[1].regNum = PhysicalReg_EDX;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[2].regNum = PhysicalReg_ECX;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[3].regNum = PhysicalReg_EAX;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[4].regNum = 1;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_scratch;
+        infoArray[5].regNum = 2;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_scratch;
+        if(inst_op == OP_INVOKE_STATIC)
+            k = updateInvokeNoRange(infoArray, 6);
+        else
+            k = updateInvokeRange(infoArray, 6);
+        return k;
+    case OP_INVOKE_INTERFACE:
+    case OP_INVOKE_INTERFACE_RANGE:
+#ifdef PREDICTED_CHAINING
+        numTmps = updateGenPrediction(infoArray, true /*interface*/);
+        infoArray[numTmps].regNum = 1;
+        infoArray[numTmps].refCount = 3; //DU
+        infoArray[numTmps].physicalType = LowOpndRegType_gp;
+        numTmps++;
+        if(inst_op == OP_INVOKE_INTERFACE)
+            k = updateInvokeNoRange(infoArray, numTmps);
+        else
+            k = updateInvokeRange(infoArray, numTmps);
+        return k;
+#else
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 3;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 4;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 5;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+
+        infoArray[4].regNum = PhysicalReg_EDX;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[5].regNum = PhysicalReg_ECX;
+        infoArray[5].refCount = 1+1; //DU
+        infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[6].regNum = PhysicalReg_EAX;
+        infoArray[6].refCount = 2+1; //2 uses
+        infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[7].regNum = 1;
+        infoArray[7].refCount = 2; //DU
+        infoArray[7].physicalType = LowOpndRegType_scratch;
+        infoArray[8].regNum = 2;
+        infoArray[8].refCount = 2; //DU
+        infoArray[8].physicalType = LowOpndRegType_scratch;
+        infoArray[9].regNum = 3;
+        infoArray[9].refCount = 2; //DU
+        infoArray[9].physicalType = LowOpndRegType_scratch;
+        if(inst_op == OP_INVOKE_INTERFACE)
+            k = updateInvokeNoRange(infoArray, 10);
+        else
+            k = updateInvokeRange(infoArray, 10);
+        return k;
+#endif
+        ////////////////////////////////////////////// ALU
+    case OP_NEG_INT:
+    case OP_NOT_INT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[0].shareWithVR = false;
+        return 1;
+    case OP_NEG_LONG:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //define, use
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 4; //define, update, use
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        return 2;
+    case OP_NOT_LONG:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        return 2;
+    case OP_NEG_FLOAT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[0].shareWithVR = false;
+        return 1;
+    case OP_NEG_DOUBLE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //define, use
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3; //define, update, use
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        return 2;
+    case OP_INT_TO_LONG: //hard-code eax & edx
+        infoArray[0].regNum = PhysicalReg_EAX;
+        infoArray[0].refCount = 2+1;
+        infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = PhysicalReg_EDX;
+        infoArray[1].refCount = 1+1; //cdq accesses edx & eax
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 2;
+    case OP_INT_TO_FLOAT:
+    case OP_INT_TO_DOUBLE:
+    case OP_LONG_TO_FLOAT:
+    case OP_LONG_TO_DOUBLE:
+    case OP_FLOAT_TO_DOUBLE:
+    case OP_DOUBLE_TO_FLOAT:
+        return 0; //fp stack
+    case OP_LONG_TO_INT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        return 1;
+    case OP_FLOAT_TO_INT:
+    case OP_DOUBLE_TO_INT: //fp stack
+        return 0;
+    case OP_FLOAT_TO_LONG:
+    case OP_DOUBLE_TO_LONG:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //define, use
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //define, use
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //define, use
+        infoArray[2].physicalType = LowOpndRegType_xmm;
+        return 3;
+    case OP_INT_TO_BYTE:
+    case OP_INT_TO_CHAR:
+    case OP_INT_TO_SHORT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 4; //define, update, update, use
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[0].shareWithVR = false;
+        return 1;
+
+    case OP_ADD_INT:
+    case OP_SUB_INT:
+    case OP_MUL_INT:
+    case OP_AND_INT:
+    case OP_OR_INT:
+    case OP_XOR_INT:
+    case OP_ADD_INT_2ADDR:
+    case OP_SUB_INT_2ADDR:
+    case OP_MUL_INT_2ADDR:
+    case OP_AND_INT_2ADDR:
+    case OP_OR_INT_2ADDR:
+    case OP_XOR_INT_2ADDR:
+        if(inst_op == OP_ADD_INT || inst_op == OP_SUB_INT || inst_op == OP_MUL_INT ||
+           inst_op == OP_AND_INT || inst_op == OP_OR_INT || inst_op == OP_XOR_INT) {
+            vA = INST_AA(inst);
+            v1 = *((u1*)rPC + 2);
+        } else {
+            vA = INST_A(inst);
+            v1 = vA;
+        }
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        if(vA != v1)
+            infoArray[0].shareWithVR = false;
+        return 1; //common_alu_int
+
+    case OP_SHL_INT:
+    case OP_SHR_INT:
+    case OP_USHR_INT:
+    case OP_SHL_INT_2ADDR:
+    case OP_SHR_INT_2ADDR:
+    case OP_USHR_INT_2ADDR: //use %cl or %ecx?
+        if(inst_op == OP_SHL_INT || inst_op == OP_SHR_INT || inst_op == OP_USHR_INT) {
+            vA = INST_AA(inst);
+            v1 = *((u1*)rPC + 2);
+        } else {
+            vA = INST_A(inst);
+            v1 = vA;
+        }
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        if(vA != v1)
+            infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = PhysicalReg_ECX;
+        infoArray[1].refCount = 2; //define, use
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 2;//common_shift_int
+
+    case OP_DIV_INT:
+    case OP_REM_INT:
+    case OP_DIV_INT_2ADDR:
+    case OP_REM_INT_2ADDR: //hard-code %eax, %edx (dividend in edx:eax; quotient in eax; remainder in edx)
+        infoArray[0].regNum = 2;
+        infoArray[0].refCount = 4; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = PhysicalReg_EAX; //dividend, quotient
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[1].shareWithVR = false;
+        infoArray[2].regNum = PhysicalReg_EDX; //export_pc, output for REM
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[3].regNum = 1;
+        infoArray[3].refCount = 2; //define, use
+        infoArray[3].physicalType = LowOpndRegType_scratch;
+        if(inst_op == OP_DIV_INT || inst_op == OP_DIV_INT_2ADDR) {
+            infoArray[1].refCount = 5;
+            infoArray[2].refCount = 4;
+        } else {
+            infoArray[1].refCount = 4;
+            infoArray[2].refCount = 5;
+        }
+        return 4;
+
+    case OP_ADD_INT_LIT16:
+    case OP_MUL_INT_LIT16:
+    case OP_AND_INT_LIT16:
+    case OP_OR_INT_LIT16:
+    case OP_XOR_INT_LIT16:
+    case OP_ADD_INT_LIT8:
+    case OP_MUL_INT_LIT8:
+    case OP_AND_INT_LIT8:
+    case OP_OR_INT_LIT8:
+    case OP_XOR_INT_LIT8:
+    case OP_SHL_INT_LIT8:
+    case OP_SHR_INT_LIT8:
+    case OP_USHR_INT_LIT8:
+        if(inst_op == OP_ADD_INT_LIT16 || inst_op == OP_MUL_INT_LIT16 ||
+           inst_op == OP_AND_INT_LIT16 || inst_op == OP_OR_INT_LIT16 || inst_op == OP_XOR_INT_LIT16) {
+            vA = INST_A(inst);
+            v1 = INST_B(inst);
+        } else {
+            vA = INST_AA(inst);
+            v1 = (u2)FETCH(1) & 0xff;
+        }
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        if(vA != v1)
+            infoArray[0].shareWithVR = false;
+        return 1;
+
+    case OP_RSUB_INT_LIT8:
+    case OP_RSUB_INT:
+        vA = INST_AA(inst);
+        v1 = (inst_op == OP_RSUB_INT) ? INST_B(inst) : ((u2)FETCH(1) & 0xff);
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        if(vA != v1)
+            infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        if(vA != v1)
+            infoArray[1].shareWithVR = false;
+        return 2;
+
+    case OP_DIV_INT_LIT16:
+    case OP_REM_INT_LIT16:
+    case OP_DIV_INT_LIT8:
+    case OP_REM_INT_LIT8:
+        if(inst_op == OP_DIV_INT_LIT8 || inst_op == OP_REM_INT_LIT8) {
+            tmp_s2 = (s2)FETCH(1) >> 8;
+        }
+        else {
+            tmp_s4 = (s2)FETCH(1);
+            tmp_s2 = tmp_s4;
+        }
+        if((inst_op == OP_DIV_INT_LIT8 || inst_op == OP_DIV_INT_LIT16)) {
+            int power = isPowerOfTwo(tmp_s2);
+            if(power >= 1) { /* divide by a power of 2 constant */
+                infoArray[0].regNum = 2;
+                infoArray[0].refCount = 3; //define, use, use
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 1;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                if(power == 1) infoArray[1].refCount = 5;
+                else infoArray[1].refCount = 6;
+                return 2;
+            }
+        }
+        if(tmp_s2 == 0) {
+            //export_pc
+            infoArray[0].regNum = PhysicalReg_EDX; //export_pc, output for REM
+            infoArray[0].refCount = 2;
+            infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+            return 1;
+        }
+        if(inst_op == OP_DIV_INT_LIT16 || inst_op == OP_DIV_INT_LIT8) {
+            if(tmp_s2 == -1)
+                infoArray[1].refCount = 4+1;
+            else
+                infoArray[1].refCount = 4;
+            infoArray[2].refCount = 2; //edx
+        } else {
+            if(tmp_s2 == -1)
+                infoArray[1].refCount = 3+1;
+            else
+                infoArray[1].refCount = 3;
+            infoArray[2].refCount = 3; //edx
+        }
+        infoArray[0].regNum = 2;
+        infoArray[0].refCount = 2; //define, use
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = PhysicalReg_EAX; //dividend, quotient
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[1].shareWithVR = false;
+        infoArray[2].regNum = PhysicalReg_EDX; //export_pc, output for REM
+        infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 3;
+
+    case OP_ADD_LONG:
+    case OP_SUB_LONG:
+    case OP_AND_LONG:
+    case OP_OR_LONG:
+    case OP_XOR_LONG:
+    case OP_ADD_LONG_2ADDR:
+    case OP_SUB_LONG_2ADDR:
+    case OP_AND_LONG_2ADDR:
+    case OP_OR_LONG_2ADDR:
+    case OP_XOR_LONG_2ADDR:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //define, use
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        return 2;
+
+    case OP_SHL_LONG:
+    case OP_SHL_LONG_2ADDR:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3; //define, update, use
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[1].shareWithVR = false;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //define, use
+        infoArray[2].physicalType = LowOpndRegType_xmm;
+        return 3;
+
+    case OP_SHR_LONG:
+    case OP_SHR_LONG_2ADDR:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 4; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 4; //define, update, use
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[1].shareWithVR = false;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //define, use
+        infoArray[2].physicalType = LowOpndRegType_xmm;
+        infoArray[3].regNum = 4;
+        infoArray[3].refCount = 3;
+        infoArray[3].physicalType = LowOpndRegType_xmm;
+        infoArray[4].regNum = 5;
+        infoArray[4].refCount = 3;
+        infoArray[4].physicalType = LowOpndRegType_xmm;
+        return 5;
+
+    case OP_USHR_LONG:
+    case OP_USHR_LONG_2ADDR:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //define, update, use
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3; //define, update, use
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[1].shareWithVR = false;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //define, use
+        infoArray[2].physicalType = LowOpndRegType_xmm;
+        return 3;
+
+    case OP_MUL_LONG: //general purpose register
+    case OP_MUL_LONG_2ADDR:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 6;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 3;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = PhysicalReg_EAX;
+        infoArray[3].refCount = 2+1; //for mul_opc
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[4].regNum = PhysicalReg_EDX;
+        infoArray[4].refCount = 2; //for mul_opc
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 5;
+
+    case OP_DIV_LONG:
+    case OP_REM_LONG:
+    case OP_DIV_LONG_2ADDR:
+    case OP_REM_LONG_2ADDR:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 1;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_xmm;
+        infoArray[3].regNum = PhysicalReg_EAX;
+        infoArray[3].refCount = 2; //defined by function call
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[4].regNum = PhysicalReg_EDX;
+        infoArray[4].refCount = 2; //next version has 2 references
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[5].regNum = 1;
+        infoArray[5].refCount = 2;
+        infoArray[5].physicalType = LowOpndRegType_scratch;
+        return 6;
+
+    case OP_ADD_FLOAT:
+    case OP_SUB_FLOAT:
+    case OP_MUL_FLOAT:
+    case OP_ADD_FLOAT_2ADDR:
+    case OP_SUB_FLOAT_2ADDR:
+    case OP_MUL_FLOAT_2ADDR:
+    case OP_ADD_DOUBLE: //PhysicalReg_FP TODO
+    case OP_SUB_DOUBLE:
+    case OP_MUL_DOUBLE:
+    case OP_ADD_DOUBLE_2ADDR:
+    case OP_SUB_DOUBLE_2ADDR:
+    case OP_MUL_DOUBLE_2ADDR:
+    case OP_DIV_FLOAT:
+    case OP_DIV_FLOAT_2ADDR:
+    case OP_DIV_DOUBLE:
+    case OP_DIV_DOUBLE_2ADDR:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        //for ALU ops with 2ADDR, the temp variable can share the same physical
+        //reg as the virtual register, since the content of VR is updated by
+        //the content of the temp variable
+        if(inst_op == OP_ADD_FLOAT || inst_op == OP_SUB_FLOAT ||
+           inst_op == OP_MUL_FLOAT || inst_op == OP_ADD_DOUBLE ||
+           inst_op == OP_SUB_DOUBLE || inst_op == OP_MUL_DOUBLE ||
+           inst_op == OP_DIV_FLOAT || inst_op == OP_DIV_DOUBLE)
+        infoArray[0].shareWithVR = false;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        return 2;
+    case OP_REM_FLOAT:
+    case OP_REM_FLOAT_2ADDR:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 1;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_scratch;
+        return 3;
+
+    case OP_REM_DOUBLE:
+    case OP_REM_DOUBLE_2ADDR:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        infoArray[2].regNum = 1;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_scratch;
+        return 3;
+
+    case OP_CMPL_FLOAT:
+    case OP_CMPL_DOUBLE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 2;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 3;
+        infoArray[3].refCount = 2;
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 4; //return
+        infoArray[4].refCount = 5;
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        return 5;
+
+    case OP_CMPG_FLOAT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 2;
+        infoArray[2].refCount = 3;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 3;
+        infoArray[3].refCount = 5;
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        return 4;
+        break;
+    case OP_CMPG_DOUBLE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2;
+        infoArray[0].physicalType = LowOpndRegType_xmm;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 2;
+        infoArray[2].refCount = 3;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 3;
+        infoArray[3].refCount = 5;
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        return 4;
+
+    case OP_CMP_LONG:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 3;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 4;
+        infoArray[3].refCount = 3;
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 5;
+        infoArray[4].refCount = 2;
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = 6;
+        infoArray[5].refCount = 7;
+        infoArray[5].physicalType = LowOpndRegType_gp;
+        return 6;
+
+    case OP_EXECUTE_INLINE:
+    case OP_EXECUTE_INLINE_RANGE:
+        if(inst_op == OP_EXECUTE_INLINE)
+            num = INST_B(inst);
+        else
+            num = INST_AA(inst);
+        tmp = FETCH(1);
+        switch (tmp) {
+            case INLINE_STRING_LENGTH:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 3;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 2;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                infoArray[2].regNum = 3;
+                infoArray[2].refCount = 2;
+                infoArray[2].physicalType = LowOpndRegType_gp;
+                infoArray[3].regNum = 1;
+                infoArray[3].refCount = 2;
+                infoArray[3].physicalType = LowOpndRegType_scratch;
+                return 4;
+            case INLINE_STRING_IS_EMPTY:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 3;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 4;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                infoArray[2].regNum = 1;
+                infoArray[2].refCount = 2;
+                infoArray[2].physicalType = LowOpndRegType_scratch;
+                return 3;
+            case INLINE_STRING_FASTINDEXOF_II:
+#if defined(USE_GLOBAL_STRING_DEFS)
+                break;
+#else
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 14 * LOOP_COUNT;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 3 * LOOP_COUNT;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                infoArray[2].regNum = 3;
+                infoArray[2].refCount = 11 * LOOP_COUNT;
+                infoArray[2].physicalType = LowOpndRegType_gp;
+                infoArray[3].regNum = 4;
+                infoArray[3].refCount = 3 * LOOP_COUNT;
+                infoArray[3].physicalType = LowOpndRegType_gp;
+                infoArray[4].regNum = 5;
+                infoArray[4].refCount = 9 * LOOP_COUNT;
+                infoArray[4].physicalType = LowOpndRegType_gp;
+                infoArray[5].regNum = 6;
+                infoArray[5].refCount = 4 * LOOP_COUNT;
+                infoArray[5].physicalType = LowOpndRegType_gp;
+                infoArray[6].regNum = 7;
+                infoArray[6].refCount = 2;
+                infoArray[6].physicalType = LowOpndRegType_gp;
+                infoArray[7].regNum = 1;
+                infoArray[7].refCount = 2;
+                infoArray[7].physicalType = LowOpndRegType_scratch;
+                return 8;
+#endif
+            case INLINE_MATH_ABS_LONG:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 7;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 2;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                infoArray[2].regNum = 3;
+                infoArray[2].refCount = 3;
+                infoArray[2].physicalType = LowOpndRegType_gp;
+                infoArray[3].regNum = 4;
+                infoArray[3].refCount = 3;
+                infoArray[3].physicalType = LowOpndRegType_gp;
+                infoArray[4].regNum = 5;
+                infoArray[4].refCount = 2;
+                infoArray[4].physicalType = LowOpndRegType_gp;
+                infoArray[5].regNum = 6;
+                infoArray[5].refCount = 5;
+                infoArray[5].physicalType = LowOpndRegType_gp;
+                return 6;
+            case INLINE_MATH_ABS_INT:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 5;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 4;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                infoArray[2].regNum = 3;
+                infoArray[2].refCount = 2;
+                infoArray[2].physicalType = LowOpndRegType_gp;
+                return 3;
+            case INLINE_MATH_MAX_INT:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 4;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 3;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                infoArray[2].regNum = 3;
+                infoArray[2].refCount = 2;
+                infoArray[2].physicalType = LowOpndRegType_gp;
+                return 3;
+            case INLINE_MATH_ABS_FLOAT:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 3;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 2;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                return 2;
+            case INLINE_MATH_ABS_DOUBLE:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 2;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 3;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                infoArray[2].regNum = 3;
+                infoArray[2].refCount = 3;
+                infoArray[2].physicalType = LowOpndRegType_gp;
+                return 3;
+            case INLINE_FLOAT_TO_RAW_INT_BITS:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 2;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 2;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                return 2;
+            case INLINE_INT_BITS_TO_FLOAT:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 2;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 2;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                return 2;
+            case INLINE_DOUBLE_TO_RAW_LONG_BITS:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 2;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 2;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                infoArray[2].regNum = 3;
+                infoArray[2].refCount = 3;
+                infoArray[2].physicalType = LowOpndRegType_gp;
+                return 3;
+            case INLINE_LONG_BITS_TO_DOUBLE:
+                infoArray[0].regNum = 1;
+                infoArray[0].refCount = 2;
+                infoArray[0].physicalType = LowOpndRegType_gp;
+                infoArray[1].regNum = 2;
+                infoArray[1].refCount = 2;
+                infoArray[1].physicalType = LowOpndRegType_gp;
+                infoArray[2].regNum = 3;
+                infoArray[2].refCount = 3;
+                infoArray[2].physicalType = LowOpndRegType_gp;
+                return 3;
+            default:
+                break;
+        }
+
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 4;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        if(num >= 1) {
+            infoArray[1].regNum = 2;
+            infoArray[1].refCount = 2;
+            infoArray[1].physicalType = LowOpndRegType_gp;
+        }
+        if(num >= 2) {
+            infoArray[2].regNum = 3;
+            infoArray[2].refCount = 2;
+            infoArray[2].physicalType = LowOpndRegType_gp;
+        }
+        if(num >= 3) {
+            infoArray[3].regNum = 4;
+            infoArray[3].refCount = 2;
+            infoArray[3].physicalType = LowOpndRegType_gp;
+        }
+        if(num >= 4) {
+            infoArray[4].regNum = 5;
+            infoArray[4].refCount = 2;
+            infoArray[4].physicalType = LowOpndRegType_gp;
+        }
+        infoArray[num+1].regNum = 6;
+        infoArray[num+1].refCount = 2;
+        infoArray[num+1].physicalType = LowOpndRegType_gp;
+        infoArray[num+2].regNum = PhysicalReg_EAX;
+        infoArray[num+2].refCount = 2;
+        infoArray[num+2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[num+3].regNum = PhysicalReg_EDX;
+        infoArray[num+3].refCount = 2;
+        infoArray[num+3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[num+4].regNum = 1;
+        infoArray[num+4].refCount = 4;
+        infoArray[num+4].physicalType = LowOpndRegType_scratch;
+        return num+5;
+#if FIXME
+    case OP_INVOKE_OBJECT_INIT_RANGE:
+        return 0;
+#endif
+    case OP_INVOKE_VIRTUAL_QUICK:
+    case OP_INVOKE_VIRTUAL_QUICK_RANGE:
+#ifdef PREDICTED_CHAINING
+        numTmps = updateGenPrediction(infoArray, false /*not interface*/);
+        infoArray[numTmps].regNum = 1;
+        infoArray[numTmps].refCount = 3; //DU
+        infoArray[numTmps].physicalType = LowOpndRegType_gp;
+        numTmps++;
+        if(inst_op == OP_INVOKE_VIRTUAL_QUICK)
+            k = updateInvokeNoRange(infoArray, numTmps);
+        else
+            k = updateInvokeRange(infoArray, numTmps);
+        return k;
+#else
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+
+        infoArray[3].regNum = PhysicalReg_ECX;
+        infoArray[3].refCount = 1+1;
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[4].regNum = PhysicalReg_EDX;
+        infoArray[4].refCount = 2;
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        if(inst_op == OP_INVOKE_VIRTUAL_QUICK_RANGE)
+            k = updateInvokeRange(infoArray, 5);
+        else
+            k = updateInvokeNoRange(infoArray, 5);
+        return k;
+#endif
+    case OP_INVOKE_SUPER_QUICK:
+    case OP_INVOKE_SUPER_QUICK_RANGE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2;
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 4;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 5;
+        infoArray[2].refCount = 2;
+        infoArray[2].physicalType = LowOpndRegType_gp;
+
+        infoArray[3].regNum = PhysicalReg_ECX;
+        infoArray[3].refCount = 1+1;
+        infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        infoArray[4].regNum = PhysicalReg_EDX;
+        infoArray[4].refCount = 2;
+        infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+        infoArray[5].regNum = 1;
+        infoArray[5].refCount = 2;
+        infoArray[5].physicalType = LowOpndRegType_scratch;
+        infoArray[6].regNum = 2;
+        infoArray[6].refCount = 2;
+        infoArray[6].physicalType = LowOpndRegType_scratch;
+        if(inst_op == OP_INVOKE_SUPER_QUICK_RANGE)
+            k = updateInvokeRange(infoArray, 7);
+        else
+            k = updateInvokeNoRange(infoArray, 7);
+        return k;
+#ifdef SUPPORT_HLO
+    case kExtInstruction:
+        switch(inst) {
+    case OP_X_AGET_QUICK:
+    case OP_X_AGET_OBJECT_QUICK:
+    case OP_X_AGET_BOOLEAN_QUICK:
+    case OP_X_AGET_BYTE_QUICK:
+    case OP_X_AGET_CHAR_QUICK:
+    case OP_X_AGET_SHORT_QUICK:
+        vA = FETCH(1) & 0xff;
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 4;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[3].linkageToVR = vA;
+        if(inst == OP_X_AGET_BYTE_QUICK || inst == OP_X_AGET_BOOLEAN_QUICK)
+            infoArray[3].is8Bit = true;
+        return 4;
+    case OP_X_AGET_WIDE_QUICK:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 1;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_xmm;
+        return 4;
+    case OP_X_APUT_QUICK:
+    case OP_X_APUT_OBJECT_QUICK:
+    case OP_X_APUT_BOOLEAN_QUICK:
+    case OP_X_APUT_BYTE_QUICK:
+    case OP_X_APUT_CHAR_QUICK:
+    case OP_X_APUT_SHORT_QUICK:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 4;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        if(inst == OP_X_APUT_BYTE_QUICK || inst == OP_X_APUT_BOOLEAN_QUICK)
+            infoArray[3].is8Bit = true;
+        return 4;
+    case OP_X_APUT_WIDE_QUICK:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 1;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_xmm;
+        return 4;
+    case OP_X_DEREF_GET:
+    case OP_X_DEREF_GET_OBJECT:
+    case OP_X_DEREF_GET_BOOLEAN:
+    case OP_X_DEREF_GET_BYTE:
+    case OP_X_DEREF_GET_CHAR:
+    case OP_X_DEREF_GET_SHORT:
+        vA = FETCH(1) & 0xff;
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[1].linkageToVR = vA;
+        if(inst == OP_X_DEREF_GET_BYTE || inst == OP_X_DEREF_GET_BOOLEAN)
+            infoArray[1].is8Bit = true;
+        return 2;
+    case OP_X_DEREF_GET_WIDE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        return 2;
+    case OP_X_DEREF_PUT:
+    case OP_X_DEREF_PUT_OBJECT:
+    case OP_X_DEREF_PUT_BOOLEAN:
+    case OP_X_DEREF_PUT_BYTE:
+    case OP_X_DEREF_PUT_CHAR:
+    case OP_X_DEREF_PUT_SHORT:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        if(inst == OP_X_DEREF_PUT_BYTE || inst == OP_X_DEREF_PUT_BOOLEAN)
+            infoArray[1].is8Bit = true;
+        return 2;
+    case OP_X_DEREF_PUT_WIDE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 1;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_xmm;
+        return 2;
+    case OP_X_ARRAY_CHECKS:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        return 2;
+    case OP_X_CHECK_BOUNDS:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 2; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        return 2;
+    case OP_X_CHECK_NULL:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 2; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = PhysicalReg_EDX;
+        infoArray[1].refCount = 2;
+        infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 2;
+    case OP_X_CHECK_TYPE:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 3; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 5;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 6;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 1;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_scratch;
+        infoArray[5].regNum = PhysicalReg_EAX;
+        infoArray[5].refCount = 2;
+        infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 6;
+    case OP_X_ARRAY_OBJECT_CHECKS:
+        infoArray[0].regNum = 1;
+        infoArray[0].refCount = 3; //DU
+        infoArray[0].physicalType = LowOpndRegType_gp;
+        infoArray[1].regNum = 2;
+        infoArray[1].refCount = 4; //DU
+        infoArray[1].physicalType = LowOpndRegType_gp;
+        infoArray[2].regNum = 3;
+        infoArray[2].refCount = 2; //DU
+        infoArray[2].physicalType = LowOpndRegType_gp;
+        infoArray[3].regNum = 5;
+        infoArray[3].refCount = 2; //DU
+        infoArray[3].physicalType = LowOpndRegType_gp;
+        infoArray[4].regNum = 6;
+        infoArray[4].refCount = 2; //DU
+        infoArray[4].physicalType = LowOpndRegType_gp;
+        infoArray[5].regNum = 1;
+        infoArray[5].refCount = 2; //DU
+        infoArray[5].physicalType = LowOpndRegType_scratch;
+        infoArray[6].regNum = PhysicalReg_EAX;
+        infoArray[6].refCount = 2;
+        infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+        return 7;
+    }
+#endif
+    }
+    return -1;
+}
diff --git a/vm/compiler/codegen/x86/CalloutHelper.h b/vm/compiler/codegen/x86/CalloutHelper.h
deleted file mode 100644
index 3490f04..0000000
--- a/vm/compiler/codegen/x86/CalloutHelper.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DALVIK_VM_COMPILER_CODEGEN_X86_CALLOUT_HELPER_H_
-#define DALVIK_VM_COMPILER_CODEGEN_X86_CALLOUT_HELPER_H_
-
-#include "Dalvik.h"
-
-/*
- * Declare/comment prototypes of all native callout functions invoked by the
- * JIT'ed code here and use the LOAD_FUNC_ADDR macro to load the address into
- * a register. In this way we have a centralized place to find out all native
- * helper functions and we can grep for LOAD_FUNC_ADDR to find out all the
- * callsites.
- */
-
-/* Load a statically compiled function address as a constant */
-#define LOAD_FUNC_ADDR(cUnit, reg, addr) loadConstant(cUnit, reg, addr)
-
-/* Originally declared in Sync.h */
-bool dvmUnlockObject(struct Thread* self, struct Object* obj); //OP_MONITOR_EXIT
-
-/* Originally declared in oo/TypeCheck.h */
-bool dvmCanPutArrayElement(const ClassObject* elemClass,   // OP_APUT_OBJECT
-                           const ClassObject* arrayClass);
-int dvmInstanceofNonTrivial(const ClassObject* instance,   // OP_CHECK_CAST &&
-                            const ClassObject* clazz);     // OP_INSTANCE_OF
-
-/* Originally declared in oo/Array.h */
-ArrayObject* dvmAllocArrayByClass(ClassObject* arrayClass, // OP_NEW_ARRAY
-                                  size_t length, int allocFlags);
-
-/* Originally declared in interp/InterpDefs.h */
-bool dvmInterpHandleFillArrayData(ArrayObject* arrayObject,// OP_FILL_ARRAY_DATA
-                                  const u2* arrayData);
-
-/* Originally declared in alloc/Alloc.h */
-Object* dvmAllocObject(ClassObject* clazz, int flags);  // OP_NEW_INSTANCE
-
-/*
- * Functions declared in gDvmInlineOpsTable[] are used for
- * OP_EXECUTE_INLINE & OP_EXECUTE_INLINE_RANGE.
- */
-extern "C" double sqrt(double x);  // INLINE_MATH_SQRT
-
-#endif  // DALVIK_VM_COMPILER_CODEGEN_X86_CALLOUT_HELPER_H_
diff --git a/vm/compiler/codegen/x86/CodegenDriver.cpp b/vm/compiler/codegen/x86/CodegenDriver.cpp
deleted file mode 100644
index 9c7bf1e..0000000
--- a/vm/compiler/codegen/x86/CodegenDriver.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * This file contains codegen and support common to all supported
- * X86 variants.  It is included by:
- *
- *        Codegen-$(TARGET_ARCH_VARIANT).c
- *
- * which combines this common code with specific support found in the
- * applicable directory below this one.
- */
-
-extern X86LIR *loadConstant(CompilationUnit *cUnit, int rDest, int value);
-extern X86LIR *loadWordDisp(CompilationUnit *cUnit, int rBase,
-                            int displacement, int rDest);
-extern void dvmCompilerFlushAllRegs(CompilationUnit *cUnit);
-extern void storeWordDisp(CompilationUnit *cUnit, int rBase,
-                          int displacement, int rSrc);
-extern X86LIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc);
-
-static int opcodeCoverage[kNumPackedOpcodes];
-static intptr_t templateEntryOffsets[TEMPLATE_LAST_MARK];
-
-#if 0   // Avoid compiler warnings when x86 disabled during development
-/*
- * Bail to the interpreter.  Will not return to this trace.
- * On entry, rPC must be set correctly.
- */
-static void genPuntToInterp(CompilationUnit *cUnit, unsigned int offset)
-{
-    dvmCompilerFlushAllRegs(cUnit);
-    loadConstant(cUnit, rPC, (int)(cUnit->method->insns + offset));
-    loadWordDisp(cUnit, rEBP, 0, rECX);  // Get glue
-    loadWordDisp(cUnit, rECX,
-                 offsetof(Thread, jitToInterpEntries.dvmJitToInterpPunt),
-                 rEAX);
-    opReg(cUnit, kOpUncondBr, rEAX);
-}
-
-static void genInterpSingleStep(CompilationUnit *cUnit, MIR *mir)
-{
-    int flags = dexGetFlagsFromOpcode(mir->dalvikInsn.opcode);
-    int flagsToCheck = kInstrCanBranch | kInstrCanSwitch | kInstrCanReturn |
-                       kInstrCanThrow;
-
-    //If already optimized out, just ignore
-    if (mir->dalvikInsn.opcode == OP_NOP)
-        return;
-
-    //Ugly, but necessary.  Flush all Dalvik regs so Interp can find them
-    dvmCompilerFlushAllRegs(cUnit);
-
-    if ((mir->next == NULL) || (flags & flagsToCheck)) {
-       genPuntToInterp(cUnit, mir->offset);
-       return;
-    }
-    int entryAddr = offsetof(Thread,
-                             jitToInterpEntries.dvmJitToInterpSingleStep);
-    loadWordDisp(cUnit, rEBP, 0, rECX);  // Get glue
-    loadWordDisp(cUnit, rECX, entryAddr, rEAX); // rEAX<- entry address
-    /* rPC = dalvik pc */
-    loadConstant(cUnit, rPC, (int) (cUnit->method->insns + mir->offset));
-    /* rECX = dalvik pc of following instruction */
-    loadConstant(cUnit, rECX, (int) (cUnit->method->insns + mir->next->offset));
-    /* Pass on the stack */
-    storeWordDisp(cUnit, rESP, OUT_ARG0, rECX);
-    opReg(cUnit, kOpCall, rEAX);
-}
-#endif
-
-/*
- * The following are the first-level codegen routines that analyze the format
- * of each bytecode then either dispatch special purpose codegen routines
- * or produce corresponding Thumb instructions directly.
- */
-
-#if 0
-static bool handleFmt10t_Fmt20t_Fmt30t(CompilationUnit *cUnit, MIR *mir,
-                                       BasicBlock *bb, X86LIR *labelList)
-{
-    /* For OP_GOTO, OP_GOTO_16, and OP_GOTO_32 */
-    return true;
-}
-
-static bool handleFmt10x(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt11n_Fmt31i(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt21h(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt20bc(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt21c_Fmt31c(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt11x(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt12x(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt21s(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt21t(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb,
-                         X86LIR *labelList)
-{
-    return true;
-}
-
-static bool handleFmt22b_Fmt22s(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt22c(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt22cs(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt22t(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb,
-                         X86LIR *labelList)
-{
-    return true;
-}
-
-static bool handleFmt22x_Fmt32x(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt23x(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt31t(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt35c_3rc(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb,
-                             X86LIR *labelList)
-{
-    return true;
-}
-
-static bool handleFmt35ms_3rms(CompilationUnit *cUnit, MIR *mir,
-                               BasicBlock *bb, X86LIR *labelList)
-{
-    return true;
-}
-
-/*
- * NOTE: Handles both range and non-range versions (arguments
- * have already been normalized by this point).
- */
-static bool handleExecuteInline(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-
-static bool handleFmt51l(CompilationUnit *cUnit, MIR *mir)
-{
-    return true;
-}
-#endif
-
-
-void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
-{
-}
-
-/* Accept the work and start compiling */
-bool dvmCompilerDoWork(CompilerWorkOrder *work)
-{
-    JitTraceDescription *desc;
-    bool res;
-
-    if (gDvmJit.codeCacheFull) {
-        return false;
-    }
-
-    switch (work->kind) {
-        case kWorkOrderTrace:
-            /* Start compilation with maximally allowed trace length */
-            desc = (JitTraceDescription *)work->info;
-            res = dvmCompileTrace(desc, JIT_MAX_TRACE_LEN, &work->result,
-                                  work->bailPtr, 0 /* no hints */);
-            break;
-        case kWorkOrderTraceDebug: {
-            bool oldPrintMe = gDvmJit.printMe;
-            gDvmJit.printMe = true;
-            /* Start compilation with maximally allowed trace length */
-            desc = (JitTraceDescription *)work->info;
-            res = dvmCompileTrace(desc, JIT_MAX_TRACE_LEN, &work->result,
-                                  work->bailPtr, 0 /* no hints */);
-            gDvmJit.printMe = oldPrintMe;
-            break;
-        }
-        default:
-            res = false;
-            ALOGE("Jit: unknown work order type");
-            assert(0);  // Bail if debug build, discard otherwise
-    }
-    return res;
-}
-
-/* Architectural-specific debugging helpers go here */
-void dvmCompilerArchDump(void)
-{
-    /* Print compiled opcode in this VM instance */
-    int i, start, streak;
-    char buf[1024];
-
-    streak = i = 0;
-    buf[0] = 0;
-    while (opcodeCoverage[i] == 0 && i < kNumPackedOpcodes) {
-        i++;
-    }
-    if (i == kNumPackedOpcodes) {
-        return;
-    }
-    for (start = i++, streak = 1; i < kNumPackedOpcodes; i++) {
-        if (opcodeCoverage[i]) {
-            streak++;
-        } else {
-            if (streak == 1) {
-                sprintf(buf+strlen(buf), "%x,", start);
-            } else {
-                sprintf(buf+strlen(buf), "%x-%x,", start, start + streak - 1);
-            }
-            streak = 0;
-            while (opcodeCoverage[i] == 0 && i < kNumPackedOpcodes) {
-                i++;
-            }
-            if (i < kNumPackedOpcodes) {
-                streak = 1;
-                start = i;
-            }
-        }
-    }
-    if (streak) {
-        if (streak == 1) {
-            sprintf(buf+strlen(buf), "%x", start);
-        } else {
-            sprintf(buf+strlen(buf), "%x-%x", start, start + streak - 1);
-        }
-    }
-    if (strlen(buf)) {
-        ALOGD("dalvik.vm.jit.op = %s", buf);
-    }
-}
-
-/* Common initialization routine for an architecture family */
-bool dvmCompilerArchInit()
-{
-    return dvmCompilerArchVariantInit();
-}
-
-void *dvmCompilerGetInterpretTemplate()
-{
-      return (void*) ((int)gDvmJit.codeCache +
-                      templateEntryOffsets[TEMPLATE_INTERPRET]);
-}
-
-JitInstructionSetType dvmCompilerGetInterpretTemplateSet()
-{
-    return DALVIK_JIT_X86;
-}
-
-void dvmCompilerInitializeRegAlloc(CompilationUnit *cUnit)
-{
-}
diff --git a/vm/compiler/codegen/x86/CodegenInterface.cpp b/vm/compiler/codegen/x86/CodegenInterface.cpp
new file mode 100644
index 0000000..aade180
--- /dev/null
+++ b/vm/compiler/codegen/x86/CodegenInterface.cpp
@@ -0,0 +1,1532 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <sys/mman.h>
+#include "Dalvik.h"
+#include "libdex/DexOpcodes.h"
+#include "compiler/Compiler.h"
+#include "compiler/CompilerIR.h"
+#include "interp/Jit.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "NcgAot.h"
+#include "compiler/codegen/CompilerCodegen.h"
+
+/* Init values when a predicted chain is initially assembled */
+/* E7FE is branch to self */
+#define PREDICTED_CHAIN_BX_PAIR_INIT     0xe7fe
+
+/* Target-specific save/restore */
+extern "C" void dvmJitCalleeSave(double *saveArea);
+extern "C" void dvmJitCalleeRestore(double *saveArea);
+
+/*
+ * Determine the initial instruction set to be used for this trace.
+ * Later components may decide to change this.
+ */
+//JitInstructionSetType dvmCompilerInstructionSet(CompilationUnit *cUnit)
+JitInstructionSetType dvmCompilerInstructionSet(void)
+{
+    return DALVIK_JIT_IA32;
+}
+
+JitInstructionSetType dvmCompilerGetInterpretTemplateSet()
+{
+    return DALVIK_JIT_IA32;
+}
+
+/* we don't use template for IA32 */
+void *dvmCompilerGetInterpretTemplate()
+{
+      return NULL;
+}
+
+/* Track the number of times that the code cache is patched */
+#if defined(WITH_JIT_TUNING)
+#define UPDATE_CODE_CACHE_PATCHES()    (gDvmJit.codeCachePatches++)
+#else
+#define UPDATE_CODE_CACHE_PATCHES()
+#endif
+
+bool dvmCompilerArchInit() {
+    /* Target-specific configuration */
+    gDvmJit.jitTableSize = 1 << 12;
+    gDvmJit.jitTableMask = gDvmJit.jitTableSize - 1;
+    gDvmJit.threshold = 255;
+    gDvmJit.codeCacheSize = 512*1024;
+    gDvmJit.optLevel = kJitOptLevelO1;
+
+#if defined(WITH_SELF_VERIFICATION)
+    /* Force into blocking mode */
+    gDvmJit.blockingMode = true;
+    gDvm.nativeDebuggerActive = true;
+#endif
+
+    // Make sure all threads have current values
+    dvmJitUpdateThreadStateAll();
+
+    return true;
+}
+
+void dvmCompilerPatchInlineCache(void)
+{
+    int i;
+    PredictedChainingCell *minAddr, *maxAddr;
+
+    /* Nothing to be done */
+    if (gDvmJit.compilerICPatchIndex == 0) return;
+
+    /*
+     * Since all threads are already stopped we don't really need to acquire
+     * the lock. But race condition can be easily introduced in the future w/o
+     * paying attention so we still acquire the lock here.
+     */
+    dvmLockMutex(&gDvmJit.compilerICPatchLock);
+
+    UNPROTECT_CODE_CACHE(gDvmJit.codeCache, gDvmJit.codeCacheByteUsed);
+
+    //ALOGD("Number of IC patch work orders: %d", gDvmJit.compilerICPatchIndex);
+
+    /* Initialize the min/max address range */
+    minAddr = (PredictedChainingCell *)
+        ((char *) gDvmJit.codeCache + gDvmJit.codeCacheSize);
+    maxAddr = (PredictedChainingCell *) gDvmJit.codeCache;
+
+    for (i = 0; i < gDvmJit.compilerICPatchIndex; i++) {
+        ICPatchWorkOrder *workOrder = &gDvmJit.compilerICPatchQueue[i];
+        PredictedChainingCell *cellAddr = workOrder->cellAddr;
+        PredictedChainingCell *cellContent = &workOrder->cellContent;
+        ClassObject *clazz = dvmFindClassNoInit(workOrder->classDescriptor,
+                                                workOrder->classLoader);
+
+        assert(clazz->serialNumber == workOrder->serialNumber);
+
+        /* Use the newly resolved clazz pointer */
+        cellContent->clazz = clazz;
+
+        if (cellAddr->clazz == NULL) {
+            COMPILER_TRACE_CHAINING(
+                ALOGI("Jit Runtime: predicted chain %p to %s (%s) initialized",
+                      cellAddr,
+                      cellContent->clazz->descriptor,
+                      cellContent->method->name));
+        } else {
+            COMPILER_TRACE_CHAINING(
+                ALOGI("Jit Runtime: predicted chain %p from %s to %s (%s) "
+                      "patched",
+                      cellAddr,
+                      cellAddr->clazz->descriptor,
+                      cellContent->clazz->descriptor,
+                      cellContent->method->name));
+        }
+
+        /* Patch the chaining cell */
+        *cellAddr = *cellContent;
+        minAddr = (cellAddr < minAddr) ? cellAddr : minAddr;
+        maxAddr = (cellAddr > maxAddr) ? cellAddr : maxAddr;
+    }
+
+    PROTECT_CODE_CACHE(gDvmJit.codeCache, gDvmJit.codeCacheByteUsed);
+
+    gDvmJit.compilerICPatchIndex = 0;
+    dvmUnlockMutex(&gDvmJit.compilerICPatchLock);
+}
+
+/* Target-specific cache clearing */
+void dvmCompilerCacheClear(char *start, size_t size)
+{
+    /* "0xFF 0xFF" is an invalid opcode for x86. */
+    memset(start, 0xFF, size);
+}
+
+/* for JIT debugging, to be implemented */
+void dvmJitCalleeSave(double *saveArea) {
+}
+
+void dvmJitCalleeRestore(double *saveArea) {
+}
+
+void dvmJitToInterpSingleStep() {
+}
+
+JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc,
+                                            const JitEntry *knownEntry) {
+    return NULL;
+}
+
+void dvmCompilerCodegenDump(CompilationUnit *cUnit) //in ArchUtility.c
+{
+}
+
+void dvmCompilerArchDump(void)
+{
+}
+
+char *getTraceBase(const JitEntry *p)
+{
+    return NULL;
+}
+
+void dvmCompilerAssembleLIR(CompilationUnit *cUnit, JitTranslationInfo* info)
+{
+}
+
+void dvmJitInstallClassObjectPointers(CompilationUnit *cUnit, char *codeAddress)
+{
+}
+
+void dvmCompilerMethodMIR2LIR(CompilationUnit *cUnit)
+{
+    ALOGE("Method-based JIT not supported for the x86 target");
+    dvmAbort();
+}
+
+void dvmJitScanAllClassPointers(void (*callback)(void *))
+{
+}
+
+/* Handy function to retrieve the profile count */
+static inline int getProfileCount(const JitEntry *entry)
+{
+    if (entry->dPC == 0 || entry->codeAddress == 0)
+        return 0;
+    u4 *pExecutionCount = (u4 *) getTraceBase(entry);
+
+    return pExecutionCount ? *pExecutionCount : 0;
+}
+
+/* qsort callback function */
+static int sortTraceProfileCount(const void *entry1, const void *entry2)
+{
+    const JitEntry *jitEntry1 = (const JitEntry *)entry1;
+    const JitEntry *jitEntry2 = (const JitEntry *)entry2;
+
+    JitTraceCounter_t count1 = getProfileCount(jitEntry1);
+    JitTraceCounter_t count2 = getProfileCount(jitEntry2);
+    return (count1 == count2) ? 0 : ((count1 > count2) ? -1 : 1);
+}
+
+/* Sort the trace profile counts and dump them */
+void dvmCompilerSortAndPrintTraceProfiles() //in Assemble.c
+{
+    JitEntry *sortedEntries;
+    int numTraces = 0;
+    unsigned long counts = 0;
+    unsigned int i;
+
+    /* Make sure that the table is not changing */
+    dvmLockMutex(&gDvmJit.tableLock);
+
+    /* Sort the entries by descending order */
+    sortedEntries = (JitEntry *)malloc(sizeof(JitEntry) * gDvmJit.jitTableSize);
+    if (sortedEntries == NULL)
+        goto done;
+    memcpy(sortedEntries, gDvmJit.pJitEntryTable,
+           sizeof(JitEntry) * gDvmJit.jitTableSize);
+    qsort(sortedEntries, gDvmJit.jitTableSize, sizeof(JitEntry),
+          sortTraceProfileCount);
+
+    /* Dump the sorted entries */
+    for (i=0; i < gDvmJit.jitTableSize; i++) {
+        if (sortedEntries[i].dPC != 0) {
+            numTraces++;
+        }
+    }
+    if (numTraces == 0)
+        numTraces = 1;
+    ALOGI("JIT: Average execution count -> %d",(int)(counts / numTraces));
+
+    free(sortedEntries);
+done:
+    dvmUnlockMutex(&gDvmJit.tableLock);
+    return;
+}
+
+void jumpWithRelOffset(char* instAddr, int relOffset) {
+    stream = instAddr;
+    OpndSize immSize = estOpndSizeFromImm(relOffset);
+    relOffset -= getJmpCallInstSize(immSize, JmpCall_uncond);
+    dump_imm(Mnemonic_JMP, immSize, relOffset);
+}
+
+// works whether instructions for target basic block are generated or not
+LowOp* jumpToBasicBlock(char* instAddr, int targetId) {
+    stream = instAddr;
+    bool unknown;
+    OpndSize size;
+    int relativeNCG = targetId;
+    relativeNCG = getRelativeNCG(targetId, JmpCall_uncond, &unknown, &size);
+    unconditional_jump_int(relativeNCG, size);
+    return NULL;
+}
+
+LowOp* condJumpToBasicBlock(char* instAddr, ConditionCode cc, int targetId) {
+    stream = instAddr;
+    bool unknown;
+    OpndSize size;
+    int relativeNCG = targetId;
+    relativeNCG = getRelativeNCG(targetId, JmpCall_cond, &unknown, &size);
+    conditional_jump_int(cc, relativeNCG, size);
+    return NULL;
+}
+
+/*
+ * Attempt to enqueue a work order to patch an inline cache for a predicted
+ * chaining cell for virtual/interface calls.
+ */
+static bool inlineCachePatchEnqueue(PredictedChainingCell *cellAddr,
+                                    PredictedChainingCell *newContent)
+{
+    bool result = true;
+
+    /*
+     * Make sure only one thread gets here since updating the cell (ie fast
+     * path and queueing the request (ie the queued path) have to be done
+     * in an atomic fashion.
+     */
+    dvmLockMutex(&gDvmJit.compilerICPatchLock);
+
+    /* Fast path for uninitialized chaining cell */
+    if (cellAddr->clazz == NULL &&
+        cellAddr->branch == PREDICTED_CHAIN_BX_PAIR_INIT) {
+        UNPROTECT_CODE_CACHE(cellAddr, sizeof(*cellAddr));
+
+        cellAddr->method = newContent->method;
+        cellAddr->branch = newContent->branch;
+        cellAddr->branch2 = newContent->branch2;
+
+        /*
+         * The update order matters - make sure clazz is updated last since it
+         * will bring the uninitialized chaining cell to life.
+         */
+        android_atomic_release_store((int32_t)newContent->clazz,
+            (volatile int32_t *)(void*) &cellAddr->clazz);
+        //cacheflush((intptr_t) cellAddr, (intptr_t) (cellAddr+1), 0);
+        UPDATE_CODE_CACHE_PATCHES();
+
+        PROTECT_CODE_CACHE(cellAddr, sizeof(*cellAddr));
+
+#if 0
+        MEM_BARRIER();
+        cellAddr->clazz = newContent->clazz;
+        //cacheflush((intptr_t) cellAddr, (intptr_t) (cellAddr+1), 0);
+#endif
+#if defined(IA_JIT_TUNING)
+        gDvmJit.icPatchInit++;
+#endif
+        COMPILER_TRACE_CHAINING(
+            ALOGI("Jit Runtime: FAST predicted chain %p to method %s%s %p",
+                  cellAddr, newContent->clazz->descriptor, newContent->method->name, newContent->method));
+    /* Check if this is a frequently missed clazz */
+    } else if (cellAddr->stagedClazz != newContent->clazz) {
+        /* Not proven to be frequent yet - build up the filter cache */
+        UNPROTECT_CODE_CACHE(cellAddr, sizeof(*cellAddr));
+
+        cellAddr->stagedClazz = newContent->clazz;
+
+        UPDATE_CODE_CACHE_PATCHES();
+        PROTECT_CODE_CACHE(cellAddr, sizeof(*cellAddr));
+
+#if defined(WITH_JIT_TUNING)
+        gDvmJit.icPatchRejected++;
+#endif
+    /*
+     * Different classes but same method implementation - it is safe to just
+     * patch the class value without the need to stop the world.
+     */
+    } else if (cellAddr->method == newContent->method) {
+        UNPROTECT_CODE_CACHE(cellAddr, sizeof(*cellAddr));
+
+        cellAddr->clazz = newContent->clazz;
+        /* No need to flush the cache here since the branch is not patched */
+        UPDATE_CODE_CACHE_PATCHES();
+
+        PROTECT_CODE_CACHE(cellAddr, sizeof(*cellAddr));
+
+#if defined(WITH_JIT_TUNING)
+        gDvmJit.icPatchLockFree++;
+#endif
+    /*
+     * Cannot patch the chaining cell inline - queue it until the next safe
+     * point.
+     */
+    } else if (gDvmJit.compilerICPatchIndex < COMPILER_IC_PATCH_QUEUE_SIZE)  {
+        int index = gDvmJit.compilerICPatchIndex++;
+        const ClassObject *clazz = newContent->clazz;
+
+        gDvmJit.compilerICPatchQueue[index].cellAddr = cellAddr;
+        gDvmJit.compilerICPatchQueue[index].cellContent = *newContent;
+        gDvmJit.compilerICPatchQueue[index].classDescriptor = clazz->descriptor;
+        gDvmJit.compilerICPatchQueue[index].classLoader = clazz->classLoader;
+        /* For verification purpose only */
+        gDvmJit.compilerICPatchQueue[index].serialNumber = clazz->serialNumber;
+
+#if defined(WITH_JIT_TUNING)
+        gDvmJit.icPatchQueued++;
+#endif
+        COMPILER_TRACE_CHAINING(
+            ALOGI("Jit Runtime: QUEUE predicted chain %p to method %s%s",
+                  cellAddr, newContent->clazz->descriptor, newContent->method->name));
+    } else {
+    /* Queue is full - just drop this patch request */
+#if defined(WITH_JIT_TUNING)
+        gDvmJit.icPatchDropped++;
+#endif
+
+        COMPILER_TRACE_CHAINING(
+            ALOGI("Jit Runtime: DROP predicted chain %p to method %s%s",
+                  cellAddr, newContent->clazz->descriptor, newContent->method->name));
+    }
+
+    dvmUnlockMutex(&gDvmJit.compilerICPatchLock);
+    return result;
+}
+
+/*
+ * This method is called from the invoke templates for virtual and interface
+ * methods to speculatively setup a chain to the callee. The templates are
+ * written in assembly and have setup method, cell, and clazz at r0, r2, and
+ * r3 respectively, so there is a unused argument in the list. Upon return one
+ * of the following three results may happen:
+ *   1) Chain is not setup because the callee is native. Reset the rechain
+ *      count to a big number so that it will take a long time before the next
+ *      rechain attempt to happen.
+ *   2) Chain is not setup because the callee has not been created yet. Reset
+ *      the rechain count to a small number and retry in the near future.
+ *   3) Ask all other threads to stop before patching this chaining cell.
+ *      This is required because another thread may have passed the class check
+ *      but hasn't reached the chaining cell yet to follow the chain. If we
+ *      patch the content before halting the other thread, there could be a
+ *      small window for race conditions to happen that it may follow the new
+ *      but wrong chain to invoke a different method.
+ */
+const Method *dvmJitToPatchPredictedChain(const Method *method,
+                                          Thread *self,
+                                          PredictedChainingCell *cell,
+                                          const ClassObject *clazz)
+{
+    int newRechainCount = PREDICTED_CHAIN_COUNTER_RECHAIN;
+    /* Don't come back here for a long time if the method is native */
+    if (dvmIsNativeMethod(method)) {
+        UNPROTECT_CODE_CACHE(cell, sizeof(*cell));
+
+        /*
+         * Put a non-zero/bogus value in the clazz field so that it won't
+         * trigger immediate patching and will continue to fail to match with
+         * a real clazz pointer.
+         */
+        cell->clazz = (ClassObject *) PREDICTED_CHAIN_FAKE_CLAZZ;
+
+        UPDATE_CODE_CACHE_PATCHES();
+        PROTECT_CODE_CACHE(cell, sizeof(*cell));
+        COMPILER_TRACE_CHAINING(
+            ALOGI("Jit Runtime: predicted chain %p to native method %s ignored",
+                  cell, method->name));
+        goto done;
+    }
+    {
+    int tgtAddr = (int) dvmJitGetTraceAddr(method->insns);
+
+    /*
+     * Compilation not made yet for the callee. Reset the counter to a small
+     * value and come back to check soon.
+     */
+    if ((tgtAddr == 0) ||
+        ((void*)tgtAddr == dvmCompilerGetInterpretTemplate())) {
+        COMPILER_TRACE_CHAINING(
+            ALOGI("Jit Runtime: predicted chain %p to method %s%s delayed",
+                  cell, method->clazz->descriptor, method->name));
+        goto done;
+    }
+
+    PredictedChainingCell newCell;
+
+    if (cell->clazz == NULL) {
+        newRechainCount = self->icRechainCount;
+    }
+
+    int relOffset = (int) tgtAddr - (int)cell;
+    OpndSize immSize = estOpndSizeFromImm(relOffset);
+    int jumpSize = getJmpCallInstSize(immSize, JmpCall_uncond);
+    relOffset -= jumpSize;
+    COMPILER_TRACE_CHAINING(
+            ALOGI("inlineCachePatchEnqueue chain %p to method %s%s inst size %d",
+                  cell, method->clazz->descriptor, method->name, jumpSize));
+    //can't use stream here since it is used by the compilation thread
+    dump_imm_with_codeaddr(Mnemonic_JMP, immSize, relOffset, (char*) (&newCell)); //update newCell.branch
+
+    newCell.clazz = clazz;
+    newCell.method = method;
+
+    /*
+     * Enter the work order to the queue and the chaining cell will be patched
+     * the next time a safe point is entered.
+     *
+     * If the enqueuing fails reset the rechain count to a normal value so that
+     * it won't get indefinitely delayed.
+     */
+    inlineCachePatchEnqueue(cell, &newCell);
+    }
+done:
+    self->icRechainCount = newRechainCount;
+    return method;
+}
+
+/*
+ * Unchain a trace given the starting address of the translation
+ * in the code cache.  Refer to the diagram in dvmCompilerAssembleLIR.
+ * For ARM, it returns the address following the last cell unchained.
+ * For IA, it returns NULL since cacheflush is not required for IA.
+ */
+u4* dvmJitUnchain(void* codeAddr)
+{
+    /* codeAddr is 4-byte aligned, so is chain cell count offset */
+    u2* pChainCellCountOffset = (u2*)((char*)codeAddr - 4);
+    u2 chainCellCountOffset = *pChainCellCountOffset;
+    /* chain cell counts information is 4-byte aligned */
+    ChainCellCounts *pChainCellCounts =
+          (ChainCellCounts*)((char*)codeAddr + chainCellCountOffset);
+    u2* pChainCellOffset = (u2*)((char*)codeAddr - 2);
+    u2 chainCellOffset = *pChainCellOffset;
+    u1* pChainCells;
+    int i,j;
+    PredictedChainingCell *predChainCell;
+    int padding;
+
+    /* Locate the beginning of the chain cell region */
+    pChainCells = (u1 *)((char*)codeAddr + chainCellOffset);
+
+    /* The cells are sorted in order - walk through them and reset */
+    for (i = 0; i < kChainingCellGap; i++) {
+        /* for hot, normal, singleton chaining:
+               nop  //padding.
+               jmp 0
+               mov imm32, reg1
+               mov imm32, reg2
+               call reg2
+           after chaining:
+               nop
+               jmp imm
+               mov imm32, reg1
+               mov imm32, reg2
+               call reg2
+           after unchaining:
+               nop
+               jmp 0
+               mov imm32, reg1
+               mov imm32, reg2
+               call reg2
+           Space occupied by the chaining cell in bytes: nop is for padding,
+                jump 0, the target 0 is 4 bytes aligned.
+           Space for predicted chaining: 5 words = 20 bytes
+        */
+        int elemSize = 0;
+        if (i == kChainingCellInvokePredicted) {
+            elemSize = 20;
+        }
+        COMPILER_TRACE_CHAINING(
+            ALOGI("Jit Runtime: unchaining type %d count %d", i, pChainCellCounts->u.count[i]));
+
+        for (j = 0; j < pChainCellCounts->u.count[i]; j++) {
+            switch(i) {
+                case kChainingCellNormal:
+                case kChainingCellHot:
+                case kChainingCellInvokeSingleton:
+                case kChainingCellBackwardBranch:
+                    COMPILER_TRACE_CHAINING(
+                        ALOGI("Jit Runtime: unchaining of normal, hot, or singleton"));
+                    pChainCells = (u1*) (((uint)pChainCells + 4)&(~0x03));
+                    elemSize = 4+5+5+2;
+                    memset(pChainCells, 0, 4);
+                    break;
+                case kChainingCellInvokePredicted:
+                    COMPILER_TRACE_CHAINING(
+                        ALOGI("Jit Runtime: unchaining of predicted"));
+                    /* 4-byte aligned */
+                    padding = (4 - ((u4)pChainCells & 3)) & 3;
+                    pChainCells += padding;
+                    predChainCell = (PredictedChainingCell *) pChainCells;
+                    /*
+                     * There could be a race on another mutator thread to use
+                     * this particular predicted cell and the check has passed
+                     * the clazz comparison. So we cannot safely wipe the
+                     * method and branch but it is safe to clear the clazz,
+                     * which serves as the key.
+                     */
+                    predChainCell->clazz = PREDICTED_CHAIN_CLAZZ_INIT;
+                    break;
+                default:
+                    ALOGE("Unexpected chaining type: %d", i);
+                    dvmAbort();  // dvmAbort OK here - can't safely recover
+            }
+            COMPILER_TRACE_CHAINING(
+                ALOGI("Jit Runtime: unchaining 0x%x", (int)pChainCells));
+            pChainCells += elemSize;  /* Advance by a fixed number of bytes */
+        }
+    }
+    return NULL;
+}
+
+/* Unchain all translation in the cache. */
+void dvmJitUnchainAll()
+{
+    ALOGV("Jit Runtime: unchaining all");
+    if (gDvmJit.pJitEntryTable != NULL) {
+        COMPILER_TRACE_CHAINING(ALOGI("Jit Runtime: unchaining all"));
+        dvmLockMutex(&gDvmJit.tableLock);
+
+        UNPROTECT_CODE_CACHE(gDvmJit.codeCache, gDvmJit.codeCacheByteUsed);
+
+        for (size_t i = 0; i < gDvmJit.jitTableSize; i++) {
+            if (gDvmJit.pJitEntryTable[i].dPC &&
+                !gDvmJit.pJitEntryTable[i].u.info.isMethodEntry &&
+                gDvmJit.pJitEntryTable[i].codeAddress) {
+                      dvmJitUnchain(gDvmJit.pJitEntryTable[i].codeAddress);
+            }
+        }
+
+        PROTECT_CODE_CACHE(gDvmJit.codeCache, gDvmJit.codeCacheByteUsed);
+
+        dvmUnlockMutex(&gDvmJit.tableLock);
+        gDvmJit.translationChains = 0;
+    }
+    gDvmJit.hasNewChain = false;
+}
+
+#define P_GPR_1 PhysicalReg_EBX
+/* Add an additional jump instruction, keep jump target 4 bytes aligned.*/
+static void insertJumpHelp()
+{
+    int rem = (uint)stream % 4;
+    int nop_size = 3 - rem;
+    dump_nop(nop_size);
+    unconditional_jump_int(0, OpndSize_32);
+    return;
+}
+
+/* Chaining cell for code that may need warmup. */
+/* ARM assembly: ldr r0, [r6, #76] (why a single instruction to access member of glue structure?)
+                 blx r0
+                 data 0xb23a //bytecode address: 0x5115b23a
+                 data 0x5115
+   IA32 assembly:
+                  jmp  0 //5 bytes
+                  movl address, %ebx
+                  movl dvmJitToInterpNormal, %eax
+                  call %eax
+                  <-- return address
+*/
+static void handleNormalChainingCell(CompilationUnit *cUnit,
+                                     unsigned int offset, int blockId, LowOpBlockLabel* labelList)
+{
+    ALOGV("in handleNormalChainingCell for method %s block %d BC offset %x NCG offset %x",
+          cUnit->method->name, blockId, offset, stream - streamMethodStart);
+    if(dump_x86_inst)
+        ALOGI("LOWER NormalChainingCell at offsetPC %x offsetNCG %x @%p",
+              offset, stream - streamMethodStart, stream);
+    /* Add one additional "jump 0" instruction, it may be modified during jit chaining. This helps
+     * reslove the multithreading issue.
+     */
+    insertJumpHelp();
+    move_imm_to_reg(OpndSize_32, (int) (cUnit->method->insns + offset), P_GPR_1, true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_dvmJitToInterpNormal();
+    //move_imm_to_reg(OpndSize_32, (int) (cUnit->method->insns + offset), P_GPR_1, true); /* used when unchaining */
+}
+
+/*
+ * Chaining cell for instructions that immediately following already translated
+ * code.
+ */
+static void handleHotChainingCell(CompilationUnit *cUnit,
+                                  unsigned int offset, int blockId, LowOpBlockLabel* labelList)
+{
+    ALOGV("in handleHotChainingCell for method %s block %d BC offset %x NCG offset %x",
+          cUnit->method->name, blockId, offset, stream - streamMethodStart);
+    if(dump_x86_inst)
+        ALOGI("LOWER HotChainingCell at offsetPC %x offsetNCG %x @%p",
+              offset, stream - streamMethodStart, stream);
+    /* Add one additional "jump 0" instruction, it may be modified during jit chaining. This helps
+     * reslove the multithreading issue.
+     */
+    insertJumpHelp();
+    move_imm_to_reg(OpndSize_32, (int) (cUnit->method->insns + offset), P_GPR_1, true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_dvmJitToInterpTraceSelect();
+    //move_imm_to_reg(OpndSize_32, (int) (cUnit->method->insns + offset), P_GPR_1, true); /* used when unchaining */
+}
+
+/* Chaining cell for branches that branch back into the same basic block */
+static void handleBackwardBranchChainingCell(CompilationUnit *cUnit,
+                                     unsigned int offset, int blockId, LowOpBlockLabel* labelList)
+{
+    ALOGV("in handleBackwardBranchChainingCell for method %s block %d BC offset %x NCG offset %x",
+          cUnit->method->name, blockId, offset, stream - streamMethodStart);
+    if(dump_x86_inst)
+        ALOGI("LOWER BackwardBranchChainingCell at offsetPC %x offsetNCG %x @%p",
+              offset, stream - streamMethodStart, stream);
+    /* Add one additional "jump 0" instruction, it may be modified during jit chaining. This helps
+     * reslove the multithreading issue.
+     */
+    insertJumpHelp();
+    move_imm_to_reg(OpndSize_32, (int) (cUnit->method->insns + offset), P_GPR_1, true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_dvmJitToInterpNormal();
+    //move_imm_to_reg(OpndSize_32, (int) (cUnit->method->insns + offset), P_GPR_1, true); /* used when unchaining */
+}
+
+/* Chaining cell for monomorphic method invocations. */
+static void handleInvokeSingletonChainingCell(CompilationUnit *cUnit,
+                                              const Method *callee, int blockId, LowOpBlockLabel* labelList)
+{
+    ALOGV("in handleInvokeSingletonChainingCell for method %s block %d callee %s NCG offset %x",
+          cUnit->method->name, blockId, callee->name, stream - streamMethodStart);
+    if(dump_x86_inst)
+        ALOGI("LOWER InvokeSingletonChainingCell at block %d offsetNCG %x @%p",
+              blockId, stream - streamMethodStart, stream);
+    /* Add one additional "jump 0" instruction, it may be modified during jit chaining. This helps
+     * reslove the multithreading issue.
+     */
+    insertJumpHelp();
+    move_imm_to_reg(OpndSize_32, (int) (callee->insns), P_GPR_1, true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_dvmJitToInterpTraceSelect();
+    //move_imm_to_reg(OpndSize_32, (int) (callee->insns), P_GPR_1, true); /* used when unchaining */
+}
+#undef P_GPR_1
+
+/* Chaining cell for monomorphic method invocations. */
+static void handleInvokePredictedChainingCell(CompilationUnit *cUnit, int blockId)
+{
+    if(dump_x86_inst)
+        ALOGI("LOWER InvokePredictedChainingCell at block %d offsetNCG %x @%p",
+              blockId, stream - streamMethodStart, stream);
+#ifndef PREDICTED_CHAINING
+    //assume rPC for callee->insns in %ebx
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_dvmJitToInterpTraceSelectNoChain();
+#else
+    /* make sure section for predicited chaining cell is 4-byte aligned */
+    //int padding = (4 - ((u4)stream & 3)) & 3;
+    //stream += padding;
+    int* streamData = (int*)stream;
+    /* Should not be executed in the initial state */
+    streamData[0] = PREDICTED_CHAIN_BX_PAIR_INIT;
+    streamData[1] = 0;
+    /* To be filled: class */
+    streamData[2] = PREDICTED_CHAIN_CLAZZ_INIT;
+    /* To be filled: method */
+    streamData[3] = PREDICTED_CHAIN_METHOD_INIT;
+    /*
+     * Rechain count. The initial value of 0 here will trigger chaining upon
+     * the first invocation of this callsite.
+     */
+    streamData[4] = PREDICTED_CHAIN_COUNTER_INIT;
+#if 0
+    ALOGI("--- DATA @ %p: %x %x %x %x", stream, *((int*)stream), *((int*)(stream+4)),
+          *((int*)(stream+8)), *((int*)(stream+12)));
+#endif
+    stream += 20; //5 *4
+#endif
+}
+
+/* Load the Dalvik PC into r0 and jump to the specified target */
+static void handlePCReconstruction(CompilationUnit *cUnit,
+                                   LowOpBlockLabel *targetLabel)
+{
+#if 0
+    LowOp **pcrLabel =
+        (LowOp **) cUnit->pcReconstructionList.elemList;
+    int numElems = cUnit->pcReconstructionList.numUsed;
+    int i;
+    for (i = 0; i < numElems; i++) {
+        dvmCompilerAppendLIR(cUnit, (LIR *) pcrLabel[i]);
+        /* r0 = dalvik PC */
+        loadConstant(cUnit, r0, pcrLabel[i]->operands[0]);
+        genUnconditionalBranch(cUnit, targetLabel);
+    }
+#endif
+}
+
+//use O0 code generator for hoisted checks outside of the loop
+/*
+ * vA = arrayReg;
+ * vB = idxReg;
+ * vC = endConditionReg;
+ * arg[0] = maxC
+ * arg[1] = minC
+ * arg[2] = loopBranchConditionCode
+ */
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+static void genHoistedChecksForCountUpLoop(CompilationUnit *cUnit, MIR *mir)
+{
+    /*
+     * NOTE: these synthesized blocks don't have ssa names assigned
+     * for Dalvik registers.  However, because they dominate the following
+     * blocks we can simply use the Dalvik name w/ subscript 0 as the
+     * ssa name.
+     */
+    DecodedInstruction *dInsn = &mir->dalvikInsn;
+    const int maxC = dInsn->arg[0];
+
+    /* assign array in virtual register to P_GPR_1 */
+    get_virtual_reg(mir->dalvikInsn.vA, OpndSize_32, P_GPR_1, true);
+    /* assign index in virtual register to P_GPR_2 */
+    get_virtual_reg(mir->dalvikInsn.vC, OpndSize_32, P_GPR_2, true);
+    export_pc();
+    compare_imm_reg(OpndSize_32, 0, P_GPR_1, true);
+    condJumpToBasicBlock(stream, Condition_E, cUnit->exceptionBlockId);
+    int delta = maxC;
+    /*
+     * If the loop end condition is ">=" instead of ">", then the largest value
+     * of the index is "endCondition - 1".
+     */
+    if (dInsn->arg[2] == OP_IF_GE) {
+        delta--;
+    }
+
+    if (delta < 0) { //+delta
+        //if P_GPR_2 is mapped to a VR, we can't do this
+        alu_binary_imm_reg(OpndSize_32, sub_opc, -delta, P_GPR_2, true);
+    } else if(delta > 0) {
+        alu_binary_imm_reg(OpndSize_32, add_opc, delta, P_GPR_2, true);
+    }
+    compare_mem_reg(OpndSize_32, offArrayObject_length, P_GPR_1, true, P_GPR_2, true);
+    condJumpToBasicBlock(stream, Condition_NC, cUnit->exceptionBlockId);
+}
+
+/*
+ * vA = arrayReg;
+ * vB = idxReg;
+ * vC = endConditionReg;
+ * arg[0] = maxC
+ * arg[1] = minC
+ * arg[2] = loopBranchConditionCode
+ */
+static void genHoistedChecksForCountDownLoop(CompilationUnit *cUnit, MIR *mir)
+{
+    DecodedInstruction *dInsn = &mir->dalvikInsn;
+    const int maxC = dInsn->arg[0];
+
+    /* assign array in virtual register to P_GPR_1 */
+    get_virtual_reg(mir->dalvikInsn.vA, OpndSize_32, P_GPR_1, true);
+    /* assign index in virtual register to P_GPR_2 */
+    get_virtual_reg(mir->dalvikInsn.vB, OpndSize_32, P_GPR_2, true);
+    export_pc();
+    compare_imm_reg(OpndSize_32, 0, P_GPR_1, true);
+    condJumpToBasicBlock(stream, Condition_E, cUnit->exceptionBlockId);
+
+    if (maxC < 0) {
+        //if P_GPR_2 is mapped to a VR, we can't do this
+        alu_binary_imm_reg(OpndSize_32, sub_opc, -maxC, P_GPR_2, true);
+    } else if(maxC > 0) {
+        alu_binary_imm_reg(OpndSize_32, add_opc, maxC, P_GPR_2, true);
+    }
+    compare_mem_reg(OpndSize_32, offArrayObject_length, P_GPR_1, true, P_GPR_2, true);
+    condJumpToBasicBlock(stream, Condition_NC, cUnit->exceptionBlockId);
+
+}
+#undef P_GPR_1
+#undef P_GPR_2
+
+/*
+ * vA = idxReg;
+ * vB = minC;
+ */
+#define P_GPR_1 PhysicalReg_ECX
+static void genHoistedLowerBoundCheck(CompilationUnit *cUnit, MIR *mir)
+{
+    DecodedInstruction *dInsn = &mir->dalvikInsn;
+    const int minC = dInsn->vB;
+    get_virtual_reg(mir->dalvikInsn.vA, OpndSize_32, P_GPR_1, true); //array
+    export_pc();
+    compare_imm_reg(OpndSize_32, -minC, P_GPR_1, true);
+    condJumpToBasicBlock(stream, Condition_C, cUnit->exceptionBlockId);
+}
+#undef P_GPR_1
+
+#ifdef WITH_JIT_INLINING
+static void genValidationForPredictedInline(CompilationUnit *cUnit, MIR *mir)
+{
+    CallsiteInfo *callsiteInfo = mir->meta.callsiteInfo;
+    if(gDvm.executionMode == kExecutionModeNcgO0) {
+        get_virtual_reg(mir->dalvikInsn.vC, OpndSize_32, PhysicalReg_EBX, true);
+        move_imm_to_reg(OpndSize_32, (int) callsiteInfo->clazz, PhysicalReg_ECX, true);
+        compare_imm_reg(OpndSize_32, 0, PhysicalReg_EBX, true);
+        export_pc(); //use %edx
+        conditional_jump_global_API(, Condition_E, "common_errNullObject", false);
+        move_mem_to_reg(OpndSize_32, offObject_clazz, PhysicalReg_EBX, true, PhysicalReg_EAX, true);
+        compare_reg_reg(PhysicalReg_ECX, true, PhysicalReg_EAX, true);
+    } else {
+        get_virtual_reg(mir->dalvikInsn.vC, OpndSize_32, 5, false);
+        move_imm_to_reg(OpndSize_32, (int) callsiteInfo->clazz, 4, false);
+        nullCheck(5, false, 1, mir->dalvikInsn.vC);
+        move_mem_to_reg(OpndSize_32, offObject_clazz, 5, false, 6, false);
+        compare_reg_reg(4, false, 6, false);
+    }
+
+    //immdiate will be updated later in genLandingPadForMispredictedCallee
+    streamMisPred = stream;
+    callsiteInfo->misPredBranchOver = (LIR*)conditional_jump_int(Condition_NE, 0, OpndSize_8);
+}
+#endif
+
+/* Extended MIR instructions like PHI */
+void handleExtendedMIR(CompilationUnit *cUnit, MIR *mir)
+{
+    ExecutionMode origMode = gDvm.executionMode;
+    gDvm.executionMode = kExecutionModeNcgO0;
+    switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
+        case kMirOpPhi: {
+            break;
+        }
+        case kMirOpNullNRangeUpCheck: {
+            genHoistedChecksForCountUpLoop(cUnit, mir);
+            break;
+        }
+        case kMirOpNullNRangeDownCheck: {
+            genHoistedChecksForCountDownLoop(cUnit, mir);
+            break;
+        }
+        case kMirOpLowerBound: {
+            genHoistedLowerBoundCheck(cUnit, mir);
+            break;
+        }
+        case kMirOpPunt: {
+            break;
+        }
+#ifdef WITH_JIT_INLINING
+        case kMirOpCheckInlinePrediction: { //handled in ncg_o1_data.c
+            genValidationForPredictedInline(cUnit, mir);
+            break;
+        }
+#endif
+        default:
+            break;
+    }
+    gDvm.executionMode = origMode;
+}
+
+static void setupLoopEntryBlock(CompilationUnit *cUnit, BasicBlock *entry,
+                                int bodyId)
+{
+    /*
+     * Next, create two branches - one branch over to the loop body and the
+     * other branch to the PCR cell to punt.
+     */
+    //LowOp* branchToBody = jumpToBasicBlock(stream, bodyId);
+    //setupResourceMasks(branchToBody);
+    //cUnit->loopAnalysis->branchToBody = ((LIR*)branchToBody);
+
+#if 0
+    LowOp *branchToPCR = dvmCompilerNew(sizeof(ArmLIR), true);
+    branchToPCR->opCode = kThumbBUncond;
+    branchToPCR->generic.target = (LIR *) pcrLabel;
+    setupResourceMasks(branchToPCR);
+    cUnit->loopAnalysis->branchToPCR = (LIR *) branchToPCR;
+#endif
+}
+
+/* check whether we can merge the block at index i with its target block */
+bool mergeBlock(BasicBlock *bb) {
+    if(bb->blockType == kDalvikByteCode &&
+       bb->firstMIRInsn != NULL &&
+       (bb->lastMIRInsn->dalvikInsn.opcode == OP_GOTO_16 ||
+        bb->lastMIRInsn->dalvikInsn.opcode == OP_GOTO ||
+        bb->lastMIRInsn->dalvikInsn.opcode == OP_GOTO_32) &&
+       bb->fallThrough == NULL) {// &&
+       //cUnit->hasLoop) {
+        //ALOGI("merge blocks ending with goto at index %d", i);
+        MIR* prevInsn = bb->lastMIRInsn->prev;
+        if(bb->taken == NULL) return false;
+        MIR* mergeInsn = bb->taken->firstMIRInsn;
+        if(mergeInsn == NULL) return false;
+        if(prevInsn == NULL) {//the block has a single instruction
+            bb->firstMIRInsn = mergeInsn;
+        } else {
+            prevInsn->next = mergeInsn; //remove goto from the chain
+        }
+        mergeInsn->prev = prevInsn;
+        bb->lastMIRInsn = bb->taken->lastMIRInsn;
+        bb->taken->firstMIRInsn = NULL; //block being merged in
+        bb->fallThrough = bb->taken->fallThrough;
+        bb->taken = bb->taken->taken;
+        return true;
+    }
+    return false;
+}
+
+static int genTraceProfileEntry(CompilationUnit *cUnit)
+{
+    cUnit->headerSize = 6;
+    if ((gDvmJit.profileMode == kTraceProfilingContinuous) ||
+        (gDvmJit.profileMode == kTraceProfilingDisabled)) {
+        return 12;
+    } else {
+        return 4;
+    }
+
+}
+
+#define PRINT_BUFFER_LEN 1024
+/* Print the code block in code cache in the range of [startAddr, endAddr)
+ * in readable format.
+ */
+void printEmittedCodeBlock(unsigned char *startAddr, unsigned char *endAddr)
+{
+    char strbuf[PRINT_BUFFER_LEN];
+    unsigned char *addr;
+    unsigned char *next_addr;
+    int n;
+
+    if (gDvmJit.printBinary) {
+        // print binary in bytes
+        n = 0;
+        for (addr = startAddr; addr < endAddr; addr++) {
+            n += snprintf(&strbuf[n], PRINT_BUFFER_LEN-n, "0x%x, ", *addr);
+            if (n > PRINT_BUFFER_LEN - 10) {
+                ALOGD("## %s", strbuf);
+                n = 0;
+            }
+        }
+        if (n > 0)
+            ALOGD("## %s", strbuf);
+    }
+
+    // print disassembled instructions
+    addr = startAddr;
+    while (addr < endAddr) {
+        next_addr = reinterpret_cast<unsigned char*>
+            (decoder_disassemble_instr(reinterpret_cast<char*>(addr),
+                                       strbuf, PRINT_BUFFER_LEN));
+        if (addr != next_addr) {
+            ALOGD("**  %p: %s", addr, strbuf);
+        } else {                // check whether this is nop padding
+            if (addr[0] == 0x90) {
+                ALOGD("**  %p: NOP (1 byte)", addr);
+                next_addr += 1;
+            } else if (addr[0] == 0x66 && addr[1] == 0x90) {
+                ALOGD("**  %p: NOP (2 bytes)", addr);
+                next_addr += 2;
+            } else if (addr[0] == 0x0f && addr[1] == 0x1f && addr[2] == 0x00) {
+                ALOGD("**  %p: NOP (3 bytes)", addr);
+                next_addr += 3;
+            } else {
+                ALOGD("** unable to decode binary at %p", addr);
+                break;
+            }
+        }
+        addr = next_addr;
+    }
+}
+
+/* 4 is the number of additional bytes needed for chaining information for trace:
+ * 2 bytes for chaining cell count offset and 2 bytes for chaining cell offset */
+#define EXTRA_BYTES_FOR_CHAINING 4
+
+/* Entry function to invoke the backend of the JIT compiler */
+void dvmCompilerMIR2LIR(CompilationUnit *cUnit, JitTranslationInfo *info)
+{
+    dump_x86_inst = cUnit->printMe;
+    /* Used to hold the labels of each block */
+    LowOpBlockLabel *labelList =
+        (LowOpBlockLabel *)dvmCompilerNew(sizeof(LowOpBlockLabel) * cUnit->numBlocks, true); //Utility.c
+    LowOp *headLIR = NULL;
+    GrowableList chainingListByType[kChainingCellLast];
+    unsigned int i, padding;
+
+    /*
+     * Initialize various types chaining lists.
+     */
+    for (i = 0; i < kChainingCellLast; i++) {
+        dvmInitGrowableList(&chainingListByType[i], 2);
+    }
+
+    /* Clear the visited flag for each block */
+    dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerClearVisitedFlag,
+                                          kAllNodes, false /* isIterative */);
+
+    GrowableListIterator iterator;
+    dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
+
+    /* Traces start with a profiling entry point.  Generate it here */
+    cUnit->profileCodeSize = genTraceProfileEntry(cUnit);
+
+    //BasicBlock **blockList = cUnit->blockList;
+    GrowableList *blockList = &cUnit->blockList;
+    BasicBlock *bb;
+
+    info->codeAddress = NULL;
+    stream = (char*)gDvmJit.codeCache + gDvmJit.codeCacheByteUsed;
+
+    // TODO: compile into a temporary buffer and then copy into the code cache.
+    // That would let us leave the code cache unprotected for a shorter time.
+    size_t unprotected_code_cache_bytes =
+            gDvmJit.codeCacheSize - gDvmJit.codeCacheByteUsed - CODE_CACHE_PADDING;
+    UNPROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+
+    streamStart = stream; /* trace start before alignment */
+    stream += EXTRA_BYTES_FOR_CHAINING; /* This is needed for chaining. Add the bytes before the alignment */
+    stream = (char*)(((unsigned int)stream + 0xF) & ~0xF); /* Align trace to 16-bytes */
+    streamMethodStart = stream; /* code start */
+    for (i = 0; i < ((unsigned int) cUnit->numBlocks); i++) {
+        labelList[i].lop.generic.offset = -1;
+    }
+    cUnit->exceptionBlockId = -1;
+    for (i = 0; i < blockList->numUsed; i++) {
+        bb = (BasicBlock *) blockList->elemList[i];
+        if(bb->blockType == kExceptionHandling)
+            cUnit->exceptionBlockId = i;
+    }
+    startOfTrace(cUnit->method, labelList, cUnit->exceptionBlockId, cUnit);
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        //merge blocks ending with "goto" with the fall through block
+        if (cUnit->jitMode != kJitLoop)
+            for (i = 0; i < blockList->numUsed; i++) {
+                bb = (BasicBlock *) blockList->elemList[i];
+                bool merged = mergeBlock(bb);
+                while(merged) merged = mergeBlock(bb);
+            }
+        for (i = 0; i < blockList->numUsed; i++) {
+            bb = (BasicBlock *) blockList->elemList[i];
+            if(bb->blockType == kDalvikByteCode &&
+               bb->firstMIRInsn != NULL) {
+                preprocessingBB(bb);
+            }
+        }
+        preprocessingTrace();
+    }
+
+    /* Handle the content in each basic block */
+    for (i = 0; ; i++) {
+        MIR *mir;
+        bb = (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
+        if (bb == NULL) break;
+        if (bb->visited == true) continue;
+
+        labelList[i].immOpnd.value = bb->startOffset;
+
+        if (bb->blockType >= kChainingCellLast) {
+            /*
+             * Append the label pseudo LIR first. Chaining cells will be handled
+             * separately afterwards.
+             */
+            dvmCompilerAppendLIR(cUnit, (LIR *) &labelList[i]);
+        }
+
+        if (bb->blockType == kEntryBlock) {
+            labelList[i].lop.opCode2 = ATOM_PSEUDO_ENTRY_BLOCK;
+            if (bb->firstMIRInsn == NULL) {
+                continue;
+            } else {
+              setupLoopEntryBlock(cUnit, bb, bb->fallThrough->id);
+                                  //&labelList[blockList[i]->fallThrough->id]);
+            }
+        } else if (bb->blockType == kExitBlock) {
+            labelList[i].lop.opCode2 = ATOM_PSEUDO_EXIT_BLOCK;
+            labelList[i].lop.generic.offset = (stream - streamMethodStart);
+            goto gen_fallthrough;
+        } else if (bb->blockType == kDalvikByteCode) {
+            if (bb->hidden == true) continue;
+            labelList[i].lop.opCode2 = ATOM_PSEUDO_NORMAL_BLOCK_LABEL;
+            /* Reset the register state */
+#if 0
+            resetRegisterScoreboard(cUnit);
+#endif
+        } else {
+            switch (bb->blockType) {
+                case kChainingCellNormal:
+                    labelList[i].lop.opCode2 = ATOM_PSEUDO_CHAINING_CELL_NORMAL;
+                    /* handle the codegen later */
+                    dvmInsertGrowableList(
+                        &chainingListByType[kChainingCellNormal], i);
+                    break;
+                case kChainingCellInvokeSingleton:
+                    labelList[i].lop.opCode2 =
+                        ATOM_PSEUDO_CHAINING_CELL_INVOKE_SINGLETON;
+                    labelList[i].immOpnd.value =
+                        (int) bb->containingMethod;
+                    /* handle the codegen later */
+                    dvmInsertGrowableList(
+                        &chainingListByType[kChainingCellInvokeSingleton], i);
+                    break;
+                case kChainingCellInvokePredicted:
+                    labelList[i].lop.opCode2 =
+                        ATOM_PSEUDO_CHAINING_CELL_INVOKE_PREDICTED;
+                   /*
+                     * Move the cached method pointer from operand 1 to 0.
+                     * Operand 0 was clobbered earlier in this routine to store
+                     * the block starting offset, which is not applicable to
+                     * predicted chaining cell.
+                     */
+                    //TODO
+                    //labelList[i].operands[0] = labelList[i].operands[1];
+
+                    /* handle the codegen later */
+                    dvmInsertGrowableList(
+                        &chainingListByType[kChainingCellInvokePredicted], i);
+                    break;
+                case kChainingCellHot:
+                    labelList[i].lop.opCode2 =
+                        ATOM_PSEUDO_CHAINING_CELL_HOT;
+                    /* handle the codegen later */
+                    dvmInsertGrowableList(
+                        &chainingListByType[kChainingCellHot], i);
+                    break;
+                case kPCReconstruction:
+                    /* Make sure exception handling block is next */
+                    labelList[i].lop.opCode2 =
+                        ATOM_PSEUDO_PC_RECONSTRUCTION_BLOCK_LABEL;
+                    //assert (i == cUnit->numBlocks - 2);
+                    labelList[i].lop.generic.offset = (stream - streamMethodStart);
+                    handlePCReconstruction(cUnit,
+                                           &labelList[cUnit->puntBlock->id]);
+                    break;
+                case kExceptionHandling:
+                    labelList[i].lop.opCode2 = ATOM_PSEUDO_EH_BLOCK_LABEL;
+                    labelList[i].lop.generic.offset = (stream - streamMethodStart);
+                    //if (cUnit->pcReconstructionList.numUsed) {
+                        scratchRegs[0] = PhysicalReg_EAX;
+                        jumpToInterpPunt();
+                        //call_dvmJitToInterpPunt();
+                    //}
+                    break;
+                case kChainingCellBackwardBranch:
+                    labelList[i].lop.opCode2 = ATOM_PSEUDO_CHAINING_CELL_BACKWARD_BRANCH;
+                    /* handle the codegen later */
+                    dvmInsertGrowableList(
+                        &chainingListByType[kChainingCellBackwardBranch],
+                        i);
+                    break;
+                default:
+                    break;
+            }
+            continue;
+        }
+        {
+        //LowOp *headLIR = NULL;
+        const DexCode *dexCode = dvmGetMethodCode(cUnit->method);
+        const u2 *startCodePtr = dexCode->insns;
+        const u2 *codePtr;
+        labelList[i].lop.generic.offset = (stream - streamMethodStart);
+        ALOGV("get ready to handle JIT bb %d type %d hidden %d",
+              bb->id, bb->blockType, bb->hidden);
+        for (BasicBlock *nextBB = bb; nextBB != NULL; nextBB = cUnit->nextCodegenBlock) {
+            bb = nextBB;
+            bb->visited = true;
+            cUnit->nextCodegenBlock = NULL;
+
+        if(gDvm.executionMode == kExecutionModeNcgO1 &&
+           bb->blockType != kEntryBlock &&
+           bb->firstMIRInsn != NULL) {
+            startOfBasicBlock(bb);
+            int cg_ret = codeGenBasicBlockJit(cUnit->method, bb);
+            endOfBasicBlock(bb);
+            if(cg_ret < 0) {
+                endOfTrace(true/*freeOnly*/);
+                cUnit->baseAddr = NULL;
+                ALOGI("codeGenBasicBlockJit returns negative number");
+                PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+                return;
+            }
+        } else {
+        for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
+            startOfBasicBlock(bb); //why here for O0
+            Opcode dalvikOpCode = mir->dalvikInsn.opcode;
+            if((int)dalvikOpCode >= (int)kMirOpFirst) {
+                handleExtendedMIR(cUnit, mir);
+                continue;
+            }
+            InstructionFormat dalvikFormat =
+                dexGetFormatFromOpcode(dalvikOpCode);
+            ALOGV("ready to handle bytecode at offset %x: opcode %d format %d",
+                  mir->offset, dalvikOpCode, dalvikFormat);
+            LowOpImm *boundaryLIR = dump_special(ATOM_PSEUDO_DALVIK_BYTECODE_BOUNDARY, mir->offset);
+            /* Remember the first LIR for this block */
+            if (headLIR == NULL) {
+                headLIR = (LowOp*)boundaryLIR;
+            }
+            bool notHandled = true;
+            /*
+             * Debugging: screen the opcode first to see if it is in the
+             * do[-not]-compile list
+             */
+            bool singleStepMe =
+                gDvmJit.includeSelectedOp !=
+                ((gDvmJit.opList[dalvikOpCode >> 3] &
+                  (1 << (dalvikOpCode & 0x7))) !=
+                 0);
+            if (singleStepMe || cUnit->allSingleStep) {
+            } else {
+                codePtr = startCodePtr + mir->offset;
+                //lower each byte code, update LIR
+                notHandled = lowerByteCodeJit(cUnit->method, cUnit->method->insns+mir->offset, mir);
+                if(gDvmJit.codeCacheByteUsed + (stream - streamStart) +
+                   CODE_CACHE_PADDING > gDvmJit.codeCacheSize) {
+                    ALOGI("JIT code cache full after lowerByteCodeJit (trace uses %uB)", (stream - streamStart));
+                    gDvmJit.codeCacheFull = true;
+                    cUnit->baseAddr = NULL;
+                    endOfTrace(true/*freeOnly*/);
+                    PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+                    return;
+                }
+            }
+            if (notHandled) {
+                ALOGE("%#06x: Opcode 0x%x (%s) / Fmt %d not handled",
+                     mir->offset,
+                     dalvikOpCode, dexGetOpcodeName(dalvikOpCode),
+                     dalvikFormat);
+                dvmAbort();
+                break;
+            }
+        } // end for
+        } // end else //JIT + O0 code generator
+        }
+        } // end for
+        /* Eliminate redundant loads/stores and delay stores into later slots */
+#if 0
+        dvmCompilerApplyLocalOptimizations(cUnit, (LIR *) headLIR,
+                                           cUnit->lastLIRInsn);
+#endif
+        if (headLIR) headLIR = NULL;
+gen_fallthrough:
+        /*
+         * Check if the block is terminated due to trace length constraint -
+         * insert an unconditional branch to the chaining cell.
+         */
+        if (bb->needFallThroughBranch) {
+            jumpToBasicBlock(stream, bb->fallThrough->id);
+        }
+
+    }
+
+    char* streamChainingStart = (char*)stream;
+    /* Handle the chaining cells in predefined order */
+    for (i = 0; i < kChainingCellGap; i++) {
+        size_t j;
+        int *blockIdList = (int *) chainingListByType[i].elemList;
+
+        cUnit->numChainingCells[i] = chainingListByType[i].numUsed;
+
+        /* No chaining cells of this type */
+        if (cUnit->numChainingCells[i] == 0)
+            continue;
+
+        /* Record the first LIR for a new type of chaining cell */
+        cUnit->firstChainingLIR[i] = (LIR *) &labelList[blockIdList[0]];
+        for (j = 0; j < chainingListByType[i].numUsed; j++) {
+            int blockId = blockIdList[j];
+            BasicBlock *chainingBlock =
+                (BasicBlock *) dvmGrowableListGetElement(&cUnit->blockList,
+                                                         blockId);
+
+            labelList[blockId].lop.generic.offset = (stream - streamMethodStart);
+
+            /* Align this chaining cell first */
+#if 0
+            newLIR0(cUnit, ATOM_PSEUDO_ALIGN4);
+#endif
+            /* Insert the pseudo chaining instruction */
+            dvmCompilerAppendLIR(cUnit, (LIR *) &labelList[blockId]);
+
+
+            switch (chainingBlock->blockType) {
+                case kChainingCellNormal:
+                    handleNormalChainingCell(cUnit,
+                     chainingBlock->startOffset, blockId, labelList);
+                    break;
+                case kChainingCellInvokeSingleton:
+                    handleInvokeSingletonChainingCell(cUnit,
+                        chainingBlock->containingMethod, blockId, labelList);
+                    break;
+                case kChainingCellInvokePredicted:
+                    handleInvokePredictedChainingCell(cUnit, blockId);
+                    break;
+                case kChainingCellHot:
+                    handleHotChainingCell(cUnit,
+                        chainingBlock->startOffset, blockId, labelList);
+                    break;
+                case kChainingCellBackwardBranch:
+                    handleBackwardBranchChainingCell(cUnit,
+                        chainingBlock->startOffset, blockId, labelList);
+                    break;
+                default:
+                    ALOGE("Bad blocktype %d", chainingBlock->blockType);
+                    dvmAbort();
+                    break;
+            }
+
+            if (gDvmJit.codeCacheByteUsed + (stream - streamStart) + CODE_CACHE_PADDING > gDvmJit.codeCacheSize) {
+                ALOGI("JIT code cache full after ChainingCell (trace uses %uB)", (stream - streamStart));
+                gDvmJit.codeCacheFull = true;
+                cUnit->baseAddr = NULL;
+                endOfTrace(true); /* need to free structures */
+                PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+                return;
+            }
+        }
+    }
+#if 0
+    dvmCompilerApplyGlobalOptimizations(cUnit);
+#endif
+    endOfTrace(false);
+
+    if (gDvmJit.codeCacheFull) {
+        /* We hit code cache size limit inside endofTrace(false).
+         * Bail out for this trace!
+         */
+        ALOGI("JIT code cache full after endOfTrace (trace uses %uB)", (stream - streamStart));
+        cUnit->baseAddr = NULL;
+        PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+        return;
+    }
+
+    /* dump section for chaining cell counts, make sure it is 4-byte aligned */
+    padding = (4 - ((u4)stream & 3)) & 3;
+    stream += padding;
+    ChainCellCounts chainCellCounts;
+    /* Install the chaining cell counts */
+    for (i=0; i< kChainingCellGap; i++) {
+        chainCellCounts.u.count[i] = cUnit->numChainingCells[i];
+    }
+    char* streamCountStart = (char*)stream;
+    memcpy((char*)stream, &chainCellCounts, sizeof(chainCellCounts));
+    stream += sizeof(chainCellCounts);
+
+    cUnit->baseAddr = streamMethodStart;
+    cUnit->totalSize = (stream - streamStart);
+    if(gDvmJit.codeCacheByteUsed + cUnit->totalSize + CODE_CACHE_PADDING > gDvmJit.codeCacheSize) {
+        ALOGI("JIT code cache full after ChainingCellCounts (trace uses %uB)", (stream - streamStart));
+        gDvmJit.codeCacheFull = true;
+        cUnit->baseAddr = NULL;
+        PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+        return;
+    }
+
+    /* write chaining cell count offset & chaining cell offset */
+    u2* pOffset = (u2*)(streamMethodStart - EXTRA_BYTES_FOR_CHAINING); /* space was already allocated for this purpose */
+    *pOffset = streamCountStart - streamMethodStart; /* from codeAddr */
+    pOffset[1] = streamChainingStart - streamMethodStart;
+
+    PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+
+    gDvmJit.codeCacheByteUsed += (stream - streamStart);
+    if (cUnit->printMe) {
+        unsigned char* codeBaseAddr = (unsigned char *) cUnit->baseAddr;
+        unsigned char* codeBaseAddrNext = ((unsigned char *) gDvmJit.codeCache) + gDvmJit.codeCacheByteUsed;
+        ALOGD("-------- Built trace for %s%s, JIT code [%p, %p) cache start %p",
+              cUnit->method->clazz->descriptor, cUnit->method->name,
+              codeBaseAddr, codeBaseAddrNext, gDvmJit.codeCache);
+        ALOGD("** %s%s@0x%x:", cUnit->method->clazz->descriptor,
+              cUnit->method->name, cUnit->traceDesc->trace[0].info.frag.startOffset);
+        printEmittedCodeBlock(codeBaseAddr, codeBaseAddrNext);
+    }
+    ALOGV("JIT CODE after trace %p to %p size %x START %p", cUnit->baseAddr,
+          (char *) gDvmJit.codeCache + gDvmJit.codeCacheByteUsed,
+          cUnit->totalSize, gDvmJit.codeCache);
+
+    gDvmJit.numCompilations++;
+
+    info->codeAddress = (char*)cUnit->baseAddr;// + cUnit->headerSize;
+}
+
+/*
+ * Perform translation chain operation.
+ */
+void* dvmJitChain(void* tgtAddr, u4* branchAddr)
+{
+#ifdef JIT_CHAIN
+    int relOffset = (int) tgtAddr - (int)branchAddr;
+
+    if ((gDvmJit.pProfTable != NULL) && (gDvm.sumThreadSuspendCount == 0) &&
+        (gDvmJit.codeCacheFull == false)) {
+
+        gDvmJit.translationChains++;
+
+        //OpndSize immSize = estOpndSizeFromImm(relOffset);
+        //relOffset -= getJmpCallInstSize(immSize, JmpCall_uncond);
+        /* Hard coded the jump opnd size to 32 bits, This instruction will replace the "jump 0" in
+         * the original code sequence.
+         */
+        OpndSize immSize = OpndSize_32;
+        relOffset -= 5;
+        //can't use stream here since it is used by the compilation thread
+        UNPROTECT_CODE_CACHE(branchAddr, sizeof(*branchAddr));
+        dump_imm_with_codeaddr(Mnemonic_JMP, immSize, relOffset, (char*)branchAddr); //dump to branchAddr
+        PROTECT_CODE_CACHE(branchAddr, sizeof(*branchAddr));
+
+        gDvmJit.hasNewChain = true;
+
+        COMPILER_TRACE_CHAINING(
+            ALOGI("Jit Runtime: chaining 0x%x to %p with relOffset %x",
+                  (int) branchAddr, tgtAddr, relOffset));
+    }
+#endif
+    return tgtAddr;
+}
+
+/*
+ * Accept the work and start compiling.  Returns true if compilation
+ * is attempted.
+ */
+bool dvmCompilerDoWork(CompilerWorkOrder *work)
+{
+    JitTraceDescription *desc;
+    bool isCompile;
+    bool success = true;
+
+    if (gDvmJit.codeCacheFull) {
+        return false;
+    }
+
+    switch (work->kind) {
+        case kWorkOrderTrace:
+            isCompile = true;
+            /* Start compilation with maximally allowed trace length */
+            desc = (JitTraceDescription *)work->info;
+            success = dvmCompileTrace(desc, JIT_MAX_TRACE_LEN, &work->result,
+                                        work->bailPtr, 0 /* no hints */);
+            break;
+        case kWorkOrderTraceDebug: {
+            bool oldPrintMe = gDvmJit.printMe;
+            gDvmJit.printMe = true;
+            isCompile = true;
+            /* Start compilation with maximally allowed trace length */
+            desc = (JitTraceDescription *)work->info;
+            success = dvmCompileTrace(desc, JIT_MAX_TRACE_LEN, &work->result,
+                                        work->bailPtr, 0 /* no hints */);
+            gDvmJit.printMe = oldPrintMe;
+            break;
+        }
+        case kWorkOrderProfileMode:
+            dvmJitChangeProfileMode((TraceProfilingModes)(int)work->info);
+            isCompile = false;
+            break;
+        default:
+            isCompile = false;
+            ALOGE("Jit: unknown work order type");
+            assert(0);  // Bail if debug build, discard otherwise
+    }
+    if (!success)
+        work->result.codeAddress = NULL;
+    return isCompile;
+}
+
+void dvmCompilerCacheFlush(long start, long end, long flags) {
+  /* cacheflush is needed for ARM, but not for IA32 (coherent icache) */
+}
+
+//#endif
diff --git a/vm/compiler/codegen/x86/Lower.cpp b/vm/compiler/codegen/x86/Lower.cpp
new file mode 100644
index 0000000..d0e7f92
--- /dev/null
+++ b/vm/compiler/codegen/x86/Lower.cpp
@@ -0,0 +1,982 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file Lower.cpp
+    \brief This file implements the high-level wrapper for lowering
+
+*/
+
+//#include "uthash.h"
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include <math.h>
+#include <sys/mman.h>
+#include "Translator.h"
+#include "Lower.h"
+#include "enc_wrapper.h"
+#include "vm/mterp/Mterp.h"
+#include "NcgHelper.h"
+#include "libdex/DexCatch.h"
+#include "compiler/CompilerIR.h"
+
+//statistics for optimization
+int num_removed_nullCheck;
+
+PhysicalReg scratchRegs[4];
+
+LowOp* ops[BUFFER_SIZE];
+LowOp* op;
+u2* rPC; //PC pointer to bytecode
+u2 inst; //current bytecode
+int offsetPC/*offset in bytecode*/, offsetNCG/*byte offset in native code*/;
+int ncg_rPC;
+//! map from PC in bytecode to PC in native code
+int mapFromBCtoNCG[BYTECODE_SIZE_PER_METHOD]; //initially mapped to -1
+char* streamStart = NULL; //start of the Pure CodeItem?, not include the global symbols
+char* streamCode = NULL; //start of the Pure CodeItem?, not include the global symbols
+char* streamMethodStart; //start of the method
+char* stream; //current stream pointer
+int lowOpTimeStamp = 0;
+Method* currentMethod = NULL;
+int currentExceptionBlockIdx = -1;
+LowOpBlockLabel* traceLabelList = NULL;
+BasicBlock* traceCurrentBB = NULL;
+MIR* traceCurrentMIR = NULL;
+bool scheduling_is_on = false;
+
+int common_invokeMethodNoRange();
+int common_invokeMethodRange();
+int common_invokeArgsDone(ArgsDoneType, bool);
+
+//data section of .ia32:
+char globalData[128];
+
+char strClassCastException[] = "Ljava/lang/ClassCastException;";
+char strInstantiationError[] = "Ljava/lang/InstantiationError;";
+char strInternalError[] = "Ljava/lang/InternalError;";
+char strFilledNewArrayNotImpl[] = "filled-new-array only implemented for 'int'";
+char strArithmeticException[] = "Ljava/lang/ArithmeticException;";
+char strArrayIndexException[] = "Ljava/lang/ArrayIndexOutOfBoundsException;";
+char strArrayStoreException[] = "Ljava/lang/ArrayStoreException;";
+char strDivideByZero[] = "divide by zero";
+char strNegativeArraySizeException[] = "Ljava/lang/NegativeArraySizeException;";
+char strNoSuchMethodError[] = "Ljava/lang/NoSuchMethodError;";
+char strNullPointerException[] = "Ljava/lang/NullPointerException;";
+char strStringIndexOutOfBoundsException[] = "Ljava/lang/StringIndexOutOfBoundsException;";
+
+int LstrClassCastExceptionPtr, LstrInstantiationErrorPtr, LstrInternalError, LstrFilledNewArrayNotImpl;
+int LstrArithmeticException, LstrArrayIndexException, LstrArrayStoreException, LstrStringIndexOutOfBoundsException;
+int LstrDivideByZero, LstrNegativeArraySizeException, LstrNoSuchMethodError, LstrNullPointerException;
+int LdoubNeg, LvaluePosInfLong, LvalueNegInfLong, LvalueNanLong, LshiftMask, Lvalue64, L64bits, LintMax, LintMin;
+
+void initConstDataSec() {
+    char* tmpPtr = globalData;
+
+    LdoubNeg = (int)tmpPtr;
+    *((u4*)tmpPtr) = 0x00000000;
+    tmpPtr += sizeof(u4);
+    *((u4*)tmpPtr) = 0x80000000;
+    tmpPtr += sizeof(u4);
+
+    LvaluePosInfLong = (int)tmpPtr;
+    *((u4*)tmpPtr) = 0xFFFFFFFF;
+    tmpPtr += sizeof(u4);
+    *((u4*)tmpPtr) = 0x7FFFFFFF;
+    tmpPtr += sizeof(u4);
+
+    LvalueNegInfLong = (int)tmpPtr;
+    *((u4*)tmpPtr) = 0x00000000;
+    tmpPtr += sizeof(u4);
+    *((u4*)tmpPtr) = 0x80000000;
+    tmpPtr += sizeof(u4);
+
+    LvalueNanLong = (int)tmpPtr;
+    *((u4*)tmpPtr) = 0;
+    tmpPtr += sizeof(u4);
+    *((u4*)tmpPtr) = 0;
+    tmpPtr += sizeof(u4);
+
+    LshiftMask = (int)tmpPtr;
+    *((u4*)tmpPtr) = 0x3f;
+    tmpPtr += sizeof(u4);
+    *((u4*)tmpPtr) = 0;
+    tmpPtr += sizeof(u4);
+
+    Lvalue64 = (int)tmpPtr;
+    *((u4*)tmpPtr) = 0x40;
+    tmpPtr += sizeof(u4);
+    *((u4*)tmpPtr) = 0;
+    tmpPtr += sizeof(u4);
+
+    L64bits = (int)tmpPtr;
+    *((u4*)tmpPtr) = 0xFFFFFFFF;
+    tmpPtr += sizeof(u4);
+    *((u4*)tmpPtr) = 0xFFFFFFFF;
+    tmpPtr += sizeof(u4);
+
+    LintMin = (int)tmpPtr;
+    *((u4*)tmpPtr) = 0x80000000;
+    tmpPtr += sizeof(u4);
+
+    LintMax = (int)tmpPtr;
+    *((u4*)tmpPtr) = 0x7FFFFFFF;
+    tmpPtr += sizeof(u4);
+
+    LstrClassCastExceptionPtr = (int)strClassCastException;
+    LstrInstantiationErrorPtr = (int)strInstantiationError;
+    LstrInternalError = (int)strInternalError;
+    LstrFilledNewArrayNotImpl = (int)strFilledNewArrayNotImpl;
+    LstrArithmeticException = (int)strArithmeticException;
+    LstrArrayIndexException = (int)strArrayIndexException;
+    LstrArrayStoreException = (int)strArrayStoreException;
+    LstrDivideByZero = (int)strDivideByZero;
+    LstrNegativeArraySizeException = (int)strNegativeArraySizeException;
+    LstrNoSuchMethodError = (int)strNoSuchMethodError;
+    LstrNullPointerException = (int)strNullPointerException;
+    LstrStringIndexOutOfBoundsException = (int)strStringIndexOutOfBoundsException;
+}
+
+//declarations of functions used in this file
+int spill_reg(int reg, bool isPhysical);
+int unspill_reg(int reg, bool isPhysical);
+
+int const_string_resolve();
+int sget_sput_resolve();
+int new_instance_needinit();
+int new_instance_abstract();
+int invoke_virtual_resolve();
+int invoke_direct_resolve();
+int invoke_static_resolve();
+int filled_new_array_notimpl();
+int resolve_class2(
+                   int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/,
+                   bool indexPhysical,
+                   int thirdArg);
+int resolve_method2(
+                    int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/,
+                    bool indexPhysical,
+                    int thirdArg/*VIRTUAL*/);
+int resolve_inst_field2(
+                        int startLR/*logical register index*/, bool isPhysical,
+                        int indexReg/*const pool index*/,
+                        bool indexPhysical);
+int resolve_static_field2(
+                          int startLR/*logical register index*/, bool isPhysical,
+                          int indexReg/*const pool index*/,
+                          bool indexPhysical);
+
+int invokeMethodNoRange_1_helper();
+int invokeMethodNoRange_2_helper();
+int invokeMethodNoRange_3_helper();
+int invokeMethodNoRange_4_helper();
+int invokeMethodNoRange_5_helper();
+int invokeMethodRange_helper();
+
+int invoke_virtual_helper();
+int invoke_virtual_quick_helper();
+int invoke_static_helper();
+int invoke_direct_helper();
+int new_instance_helper();
+int sget_sput_helper(int flag);
+int aput_obj_helper();
+int aget_helper(int flag);
+int aput_helper(int flag);
+int monitor_enter_helper();
+int monitor_exit_helper();
+int throw_helper();
+int const_string_helper();
+int array_length_helper();
+int invoke_super_helper();
+int invoke_interface_helper();
+int iget_iput_helper(int flag);
+int check_cast_helper(bool instance);
+int new_array_helper();
+
+int common_returnFromMethod();
+
+/*!
+\brief dump helper functions
+
+*/
+int performCGWorklist() {
+    filled_new_array_notimpl();
+    freeShortMap();
+    const_string_resolve();
+    freeShortMap();
+
+    resolve_class2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, 0);
+    freeShortMap();
+    resolve_method2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, METHOD_VIRTUAL);
+    freeShortMap();
+    resolve_method2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, METHOD_DIRECT);
+    freeShortMap();
+    resolve_method2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, METHOD_STATIC);
+    freeShortMap();
+    resolve_inst_field2(PhysicalReg_EAX, true, PhysicalReg_EAX, true);
+    freeShortMap();
+    resolve_static_field2(PhysicalReg_EAX, true, PhysicalReg_EAX, true);
+    freeShortMap();
+    throw_exception_message(PhysicalReg_ECX, PhysicalReg_EAX, true, PhysicalReg_Null, true);
+    freeShortMap();
+    throw_exception(PhysicalReg_ECX, PhysicalReg_EAX, PhysicalReg_Null, true);
+    freeShortMap();
+    new_instance_needinit();
+    freeShortMap();
+    return 0;
+}
+
+int aput_object_count;
+int common_periodicChecks_entry();
+int common_periodicChecks4();
+/*!
+\brief for debugging purpose, dump the sequence of native code for each bytecode
+
+*/
+int ncgMethodFake(Method* method) {
+    //to measure code size expansion, no need to patch up labels
+    methodDataWorklist = NULL;
+    globalShortWorklist = NULL;
+    globalNCGWorklist = NULL;
+    streamMethodStart = stream;
+
+    //initialize mapFromBCtoNCG
+    memset(&mapFromBCtoNCG[0], -1, BYTECODE_SIZE_PER_METHOD * sizeof(mapFromBCtoNCG[0]));
+    unsigned int i;
+    u2* rStart = (u2*)malloc(5*sizeof(u2));
+    if(rStart == NULL) {
+        ALOGE("Memory allocation failed");
+        return -1;
+    }
+    rPC = rStart;
+    method->insns = rStart;
+    for(i = 0; i < 5; i++) *rPC++ = 0;
+    for(i = 0; i < 256; i++) {
+        rPC = rStart;
+        //modify the opcode
+        char* tmp = (char*)rStart;
+        *tmp++ = i;
+        *tmp = i;
+        inst = FETCH(0);
+        char* tmpStart = stream;
+        lowerByteCode(method); //use inst, rPC, method, modify rPC
+        int size_in_u2 = rPC - rStart;
+        if(stream - tmpStart  > 0)
+            ALOGI("LOWER bytecode %x size in u2: %d ncg size in byte: %d", i, size_in_u2, stream - tmpStart);
+    }
+    exit(0);
+}
+
+bool existATryBlock(Method* method, int startPC, int endPC) {
+    const DexCode* pCode = dvmGetMethodCode(method);
+    u4 triesSize = pCode->triesSize;
+    const DexTry* pTries = dexGetTries(pCode);
+    unsigned int i;
+    for (i = 0; i < triesSize; i++) {
+        const DexTry* pTry = &pTries[i];
+        u4 start = pTry->startAddr; //offsetPC
+        u4 end = start + pTry->insnCount;
+        //if [start, end] overlaps with [startPC, endPC] returns true
+        if((int)end < startPC || (int)start > endPC) { //no overlap
+        } else {
+            return true;
+        }
+    }
+    return false;
+}
+
+int mm_bytecode_size = 0;
+int mm_ncg_size = 0;
+int mm_relocation_size = 0;
+int mm_map_size = 0;
+void resetCodeSize() {
+    mm_bytecode_size = 0;
+    mm_ncg_size = 0;
+    mm_relocation_size = 0;
+    mm_map_size = 0;
+}
+
+bool bytecodeIsRemoved(const Method* method, u4 bytecodeOffset) {
+    if(gDvm.executionMode == kExecutionModeNcgO0) return false;
+    u4 ncgOff = mapFromBCtoNCG[bytecodeOffset];
+    int k = bytecodeOffset+1;
+    u2 insnsSize = dvmGetMethodInsnsSize(method);
+    while(k < insnsSize) {
+        if(mapFromBCtoNCG[k] < 0) {
+            k++;
+            continue;
+        }
+        if(mapFromBCtoNCG[k] == (int)ncgOff) return true;
+        return false;
+    }
+    return false;
+}
+
+int invoke_super_nsm();
+void init_common(const char* curFileName, DvmDex *pDvmDex, bool forNCG); //forward declaration
+void initGlobalMethods(); //forward declaration
+
+//called once when compiler thread starts up
+void initJIT(const char* curFileName, DvmDex *pDvmDex) {
+    init_common(curFileName, pDvmDex, false);
+}
+
+void init_common(const char* curFileName, DvmDex *pDvmDex, bool forNCG) {
+    if(!gDvm.constInit) {
+        globalMapNum = 0;
+        globalMap = NULL;
+        initConstDataSec();
+        gDvm.constInit = true;
+    }
+
+    //for initJIT: stream is already set
+    if(!gDvm.commonInit) {
+        initGlobalMethods();
+        gDvm.commonInit = true;
+    }
+}
+
+void initGlobalMethods() {
+    dump_x86_inst = false; /* DEBUG */
+    // generate native code for function ncgGetEIP
+    insertLabel("ncgGetEIP", false);
+    move_mem_to_reg(OpndSize_32, 0, PhysicalReg_ESP, true, PhysicalReg_EDX, true);
+    x86_return();
+
+    //generate code for common labels
+    //jumps within a helper function is treated as short labels
+    globalShortMap = NULL;
+    common_periodicChecks_entry();
+    freeShortMap();
+    common_periodicChecks4();
+    freeShortMap();
+    //common_invokeMethodNoRange();
+    //common_invokeMethodRange();
+
+    if(dump_x86_inst) ALOGI("ArgsDone_Normal start");
+    common_invokeArgsDone(ArgsDone_Normal, false);
+    freeShortMap();
+    if(dump_x86_inst) ALOGI("ArgsDone_Native start");
+    common_invokeArgsDone(ArgsDone_Native, false);
+    freeShortMap();
+    if(dump_x86_inst) ALOGI("ArgsDone_Full start");
+    common_invokeArgsDone(ArgsDone_Full, true/*isJitFull*/);
+    if(dump_x86_inst) ALOGI("ArgsDone_Full end");
+    freeShortMap();
+
+    common_backwardBranch();
+    freeShortMap();
+    common_exceptionThrown();
+    freeShortMap();
+    common_errNullObject();
+    freeShortMap();
+    common_errArrayIndex();
+    freeShortMap();
+    common_errArrayStore();
+    freeShortMap();
+    common_errNegArraySize();
+    freeShortMap();
+    common_errNoSuchMethod();
+    freeShortMap();
+    common_errDivideByZero();
+    freeShortMap();
+    common_gotoBail();
+    freeShortMap();
+    common_gotoBail_0();
+    freeShortMap();
+    invoke_super_nsm();
+    freeShortMap();
+
+    performCGWorklist(); //generate code for helper functions
+    performLabelWorklist(); //it is likely that the common labels will jump to other common labels
+
+    dump_x86_inst = false;
+}
+
+ExecutionMode origMode;
+//when to update streamMethodStart
+bool lowerByteCodeJit(const Method* method, const u2* codePtr, MIR* mir) {
+    rPC = (u2*)codePtr;
+    inst = FETCH(0);
+    traceCurrentMIR = mir;
+    int retCode = lowerByteCode(method);
+    traceCurrentMIR = NULL;
+    freeShortMap();
+    if(retCode >= 0) return false; //handled
+    return true; //not handled
+}
+
+void startOfBasicBlock(BasicBlock* bb) {
+    traceCurrentBB = bb;
+    if(gDvm.executionMode == kExecutionModeNcgO0) {
+        isScratchPhysical = true;
+    } else {
+        isScratchPhysical = false;
+    }
+}
+
+void startOfTrace(const Method* method, LowOpBlockLabel* labelList, int exceptionBlockId,
+                  CompilationUnit *cUnit) {
+    origMode = gDvm.executionMode;
+    gDvm.executionMode = kExecutionModeNcgO1;
+    if(gDvm.executionMode == kExecutionModeNcgO0) {
+        isScratchPhysical = true;
+    } else {
+        isScratchPhysical = false;
+    }
+    currentMethod = (Method*)method;
+    currentExceptionBlockIdx = exceptionBlockId;
+    methodDataWorklist = NULL;
+    globalShortWorklist = NULL;
+    globalNCGWorklist = NULL;
+
+    streamMethodStart = stream;
+    //initialize mapFromBCtoNCG
+    memset(&mapFromBCtoNCG[0], -1, BYTECODE_SIZE_PER_METHOD * sizeof(mapFromBCtoNCG[0]));
+    traceLabelList = labelList;
+    if(gDvm.executionMode == kExecutionModeNcgO1)
+        startOfTraceO1(method, labelList, exceptionBlockId, cUnit);
+}
+
+void endOfTrace(bool freeOnly) {
+    if(freeOnly) {
+        freeLabelWorklist();
+        freeNCGWorklist();
+        freeDataWorklist();
+        freeChainingWorklist();
+    }
+    else {
+        performLabelWorklist();
+        performNCGWorklist(); //handle forward jump (GOTO, IF)
+        performDataWorklist(); //handle SWITCH & FILL_ARRAY_DATA
+        performChainingWorklist();
+    }
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        endOfTraceO1();
+    }
+    gDvm.executionMode = origMode;
+}
+
+///////////////////////////////////////////////////////////////////
+//!
+//! each bytecode is translated to a sequence of machine codes
+int lowerByteCode(const Method* method) { //inputs: rPC & inst & stream & streamMethodStart
+    /* offsetPC is used in O1 code generator, where it is defined as the sequence number
+       use a local version to avoid overwriting */
+    int offsetPC = rPC - (u2*)method->insns;
+
+    if(dump_x86_inst)
+        ALOGI("LOWER bytecode %x at offsetPC %x offsetNCG %x @%p",
+              INST_INST(inst), offsetPC, stream - streamMethodStart, stream);
+
+    //update mapFromBCtoNCG
+    offsetNCG = stream - streamMethodStart;
+    if(offsetPC >= BYTECODE_SIZE_PER_METHOD) ALOGE("offsetPC %d exceeds BYTECODE_SIZE_PER_METHOD", offsetPC);
+    mapFromBCtoNCG[offsetPC] = offsetNCG;
+#if defined(ENABLE_TRACING) && defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC, mapFromBCtoNCG[offsetPC], 1);
+#endif
+    //return number of LowOps generated
+    switch (INST_INST(inst)) {
+    case OP_NOP:
+        return op_nop();
+    case OP_MOVE:
+    case OP_MOVE_OBJECT:
+        return op_move();
+    case OP_MOVE_FROM16:
+    case OP_MOVE_OBJECT_FROM16:
+        return op_move_from16();
+    case OP_MOVE_16:
+    case OP_MOVE_OBJECT_16:
+        return op_move_16();
+    case OP_MOVE_WIDE:
+        return op_move_wide();
+    case OP_MOVE_WIDE_FROM16:
+        return op_move_wide_from16();
+    case OP_MOVE_WIDE_16:
+        return op_move_wide_16();
+    case OP_MOVE_RESULT:
+    case OP_MOVE_RESULT_OBJECT:
+        return op_move_result();
+    case OP_MOVE_RESULT_WIDE:
+        return op_move_result_wide();
+    case OP_MOVE_EXCEPTION:
+        return op_move_exception();
+    case OP_RETURN_VOID:
+    case OP_RETURN_VOID_BARRIER:
+        return op_return_void();
+    case OP_RETURN:
+    case OP_RETURN_OBJECT:
+        return op_return();
+    case OP_RETURN_WIDE:
+        return op_return_wide();
+    case OP_CONST_4:
+        return op_const_4();
+    case OP_CONST_16:
+        return op_const_16();
+    case OP_CONST:
+        return op_const();
+    case OP_CONST_HIGH16:
+        return op_const_high16();
+    case OP_CONST_WIDE_16:
+        return op_const_wide_16();
+    case OP_CONST_WIDE_32:
+        return op_const_wide_32();
+    case OP_CONST_WIDE:
+        return op_const_wide();
+    case OP_CONST_WIDE_HIGH16:
+        return op_const_wide_high16();
+    case OP_CONST_STRING:
+        return op_const_string();
+    case OP_CONST_STRING_JUMBO:
+        return op_const_string_jumbo();
+    case OP_CONST_CLASS:
+        return op_const_class();
+    case OP_MONITOR_ENTER:
+        return op_monitor_enter();
+    case OP_MONITOR_EXIT:
+        return op_monitor_exit();
+    case OP_CHECK_CAST:
+        return op_check_cast();
+    case OP_INSTANCE_OF:
+        return op_instance_of();
+    case OP_ARRAY_LENGTH:
+        return op_array_length();
+    case OP_NEW_INSTANCE:
+        return op_new_instance();
+    case OP_NEW_ARRAY:
+        return op_new_array();
+    case OP_FILLED_NEW_ARRAY:
+        return op_filled_new_array();
+    case OP_FILLED_NEW_ARRAY_RANGE:
+        return op_filled_new_array_range();
+    case OP_FILL_ARRAY_DATA:
+        return op_fill_array_data();
+    case OP_THROW:
+        return op_throw();
+    case OP_THROW_VERIFICATION_ERROR:
+        return op_throw_verification_error();
+    case OP_GOTO:
+        return op_goto();
+    case OP_GOTO_16:
+        return op_goto_16();
+    case OP_GOTO_32:
+        return op_goto_32();
+    case OP_PACKED_SWITCH:
+        return op_packed_switch();
+    case OP_SPARSE_SWITCH:
+        return op_sparse_switch();
+    case OP_CMPL_FLOAT:
+        return op_cmpl_float();
+    case OP_CMPG_FLOAT:
+        return op_cmpg_float();
+    case OP_CMPL_DOUBLE:
+        return op_cmpl_double();
+    case OP_CMPG_DOUBLE:
+        return op_cmpg_double();
+    case OP_CMP_LONG:
+        return op_cmp_long();
+    case OP_IF_EQ:
+        return op_if_eq();
+    case OP_IF_NE:
+        return op_if_ne();
+    case OP_IF_LT:
+        return op_if_lt();
+    case OP_IF_GE:
+        return op_if_ge();
+    case OP_IF_GT:
+        return op_if_gt();
+    case OP_IF_LE:
+        return op_if_le();
+    case OP_IF_EQZ:
+        return op_if_eqz();
+    case OP_IF_NEZ:
+        return op_if_nez();
+    case OP_IF_LTZ:
+        return op_if_ltz();
+    case OP_IF_GEZ:
+        return op_if_gez();
+    case OP_IF_GTZ:
+        return op_if_gtz();
+    case OP_IF_LEZ:
+        return op_if_lez();
+    case OP_AGET:
+        return op_aget();
+    case OP_AGET_WIDE:
+        return op_aget_wide();
+    case OP_AGET_OBJECT:
+        return op_aget_object();
+    case OP_AGET_BOOLEAN:
+        return op_aget_boolean();
+    case OP_AGET_BYTE:
+        return op_aget_byte();
+    case OP_AGET_CHAR:
+        return op_aget_char();
+    case OP_AGET_SHORT:
+        return op_aget_short();
+    case OP_APUT:
+        return op_aput();
+    case OP_APUT_WIDE:
+        return op_aput_wide();
+    case OP_APUT_OBJECT:
+        return op_aput_object();
+    case OP_APUT_BOOLEAN:
+        return op_aput_boolean();
+    case OP_APUT_BYTE:
+        return op_aput_byte();
+    case OP_APUT_CHAR:
+        return op_aput_char();
+    case OP_APUT_SHORT:
+        return op_aput_short();
+    case OP_IGET:
+    case OP_IGET_VOLATILE:
+        return op_iget();
+    case OP_IGET_WIDE:
+        return op_iget_wide(false); // isVolatile==false
+    case OP_IGET_WIDE_VOLATILE:
+        return op_iget_wide(true);  // isVolatile==true
+    case OP_IGET_OBJECT:
+    case OP_IGET_OBJECT_VOLATILE:
+        return op_iget_object();
+    case OP_IGET_BOOLEAN:
+        return op_iget_boolean();
+    case OP_IGET_BYTE:
+        return op_iget_byte();
+    case OP_IGET_CHAR:
+        return op_iget_char();
+    case OP_IGET_SHORT:
+        return op_iget_short();
+    case OP_IPUT:
+    case OP_IPUT_VOLATILE:
+        return op_iput();
+    case OP_IPUT_WIDE:
+        return op_iput_wide(false); // isVolatile==false
+    case OP_IPUT_WIDE_VOLATILE:
+        return op_iput_wide(true);  // isVolatile==true
+    case OP_IPUT_OBJECT:
+    case OP_IPUT_OBJECT_VOLATILE:
+        return op_iput_object();
+    case OP_IPUT_BOOLEAN:
+        return op_iput_boolean();
+    case OP_IPUT_BYTE:
+        return op_iput_byte();
+    case OP_IPUT_CHAR:
+        return op_iput_char();
+    case OP_IPUT_SHORT:
+        return op_iput_short();
+    case OP_SGET:
+    case OP_SGET_VOLATILE:
+        return op_sget();
+    case OP_SGET_WIDE:
+        return op_sget_wide(false); // isVolatile==false
+    case OP_SGET_WIDE_VOLATILE:
+        return op_sget_wide(true);  // isVolatile==true
+    case OP_SGET_OBJECT:
+    case OP_SGET_OBJECT_VOLATILE:
+        return op_sget_object();
+    case OP_SGET_BOOLEAN:
+        return op_sget_boolean();
+    case OP_SGET_BYTE:
+        return op_sget_byte();
+    case OP_SGET_CHAR:
+        return op_sget_char();
+    case OP_SGET_SHORT:
+        return op_sget_short();
+    case OP_SPUT:
+    case OP_SPUT_VOLATILE:
+        return op_sput(false);
+    case OP_SPUT_WIDE:
+        return op_sput_wide(false); // isVolatile==false
+    case OP_SPUT_WIDE_VOLATILE:
+        return op_sput_wide(true);  // isVolatile==true
+    case OP_SPUT_OBJECT:
+    case OP_SPUT_OBJECT_VOLATILE:
+        return op_sput_object();
+    case OP_SPUT_BOOLEAN:
+        return op_sput_boolean();
+    case OP_SPUT_BYTE:
+        return op_sput_byte();
+    case OP_SPUT_CHAR:
+        return op_sput_char();
+    case OP_SPUT_SHORT:
+        return op_sput_short();
+    case OP_INVOKE_VIRTUAL:
+        return op_invoke_virtual();
+    case OP_INVOKE_SUPER:
+        return op_invoke_super();
+    case OP_INVOKE_DIRECT:
+        return op_invoke_direct();
+    case OP_INVOKE_STATIC:
+        return op_invoke_static();
+    case OP_INVOKE_INTERFACE:
+        return op_invoke_interface();
+    case OP_INVOKE_VIRTUAL_RANGE:
+        return op_invoke_virtual_range();
+    case OP_INVOKE_SUPER_RANGE:
+        return op_invoke_super_range();
+    case OP_INVOKE_DIRECT_RANGE:
+        return op_invoke_direct_range();
+    case OP_INVOKE_STATIC_RANGE:
+        return op_invoke_static_range();
+    case OP_INVOKE_INTERFACE_RANGE:
+        return op_invoke_interface_range();
+    case OP_NEG_INT:
+        return op_neg_int();
+    case OP_NOT_INT:
+        return op_not_int();
+    case OP_NEG_LONG:
+        return op_neg_long();
+    case OP_NOT_LONG:
+        return op_not_long();
+    case OP_NEG_FLOAT:
+        return op_neg_float();
+    case OP_NEG_DOUBLE:
+        return op_neg_double();
+    case OP_INT_TO_LONG:
+        return op_int_to_long();
+    case OP_INT_TO_FLOAT:
+        return op_int_to_float();
+    case OP_INT_TO_DOUBLE:
+        return op_int_to_double();
+    case OP_LONG_TO_INT:
+        return op_long_to_int();
+    case OP_LONG_TO_FLOAT:
+        return op_long_to_float();
+    case OP_LONG_TO_DOUBLE:
+        return op_long_to_double();
+    case OP_FLOAT_TO_INT:
+        return op_float_to_int();
+    case OP_FLOAT_TO_LONG:
+        return op_float_to_long();
+    case OP_FLOAT_TO_DOUBLE:
+        return op_float_to_double();
+    case OP_DOUBLE_TO_INT:
+        return op_double_to_int();
+    case OP_DOUBLE_TO_LONG:
+        return op_double_to_long();
+    case OP_DOUBLE_TO_FLOAT:
+        return op_double_to_float();
+    case OP_INT_TO_BYTE:
+        return op_int_to_byte();
+    case OP_INT_TO_CHAR:
+        return op_int_to_char();
+    case OP_INT_TO_SHORT:
+        return op_int_to_short();
+    case OP_ADD_INT:
+        return op_add_int();
+    case OP_SUB_INT:
+        return op_sub_int();
+    case OP_MUL_INT:
+        return op_mul_int();
+    case OP_DIV_INT:
+        return op_div_int();
+    case OP_REM_INT:
+        return op_rem_int();
+    case OP_AND_INT:
+        return op_and_int();
+    case OP_OR_INT:
+        return op_or_int();
+    case OP_XOR_INT:
+        return op_xor_int();
+    case OP_SHL_INT:
+        return op_shl_int();
+    case OP_SHR_INT:
+        return op_shr_int();
+    case OP_USHR_INT:
+        return op_ushr_int();
+    case OP_ADD_LONG:
+        return op_add_long();
+    case OP_SUB_LONG:
+        return op_sub_long();
+    case OP_MUL_LONG:
+        return op_mul_long();
+    case OP_DIV_LONG:
+        return op_div_long();
+    case OP_REM_LONG:
+        return op_rem_long();
+    case OP_AND_LONG:
+        return op_and_long();
+    case OP_OR_LONG:
+        return op_or_long();
+    case OP_XOR_LONG:
+        return op_xor_long();
+    case OP_SHL_LONG:
+        return op_shl_long();
+    case OP_SHR_LONG:
+        return op_shr_long();
+    case OP_USHR_LONG:
+        return op_ushr_long();
+    case OP_ADD_FLOAT:
+        return op_add_float();
+    case OP_SUB_FLOAT:
+        return op_sub_float();
+    case OP_MUL_FLOAT:
+        return op_mul_float();
+    case OP_DIV_FLOAT:
+        return op_div_float();
+    case OP_REM_FLOAT:
+        return op_rem_float();
+    case OP_ADD_DOUBLE:
+        return op_add_double();
+    case OP_SUB_DOUBLE:
+        return op_sub_double();
+    case OP_MUL_DOUBLE:
+        return op_mul_double();
+    case OP_DIV_DOUBLE:
+        return op_div_double();
+    case OP_REM_DOUBLE:
+        return op_rem_double();
+    case OP_ADD_INT_2ADDR:
+        return op_add_int_2addr();
+    case OP_SUB_INT_2ADDR:
+        return op_sub_int_2addr();
+    case OP_MUL_INT_2ADDR:
+        return op_mul_int_2addr();
+    case OP_DIV_INT_2ADDR:
+        return op_div_int_2addr();
+    case OP_REM_INT_2ADDR:
+        return op_rem_int_2addr();
+    case OP_AND_INT_2ADDR:
+        return op_and_int_2addr();
+    case OP_OR_INT_2ADDR:
+        return op_or_int_2addr();
+    case OP_XOR_INT_2ADDR:
+        return op_xor_int_2addr();
+    case OP_SHL_INT_2ADDR:
+        return op_shl_int_2addr();
+    case OP_SHR_INT_2ADDR:
+        return op_shr_int_2addr();
+    case OP_USHR_INT_2ADDR:
+        return op_ushr_int_2addr();
+    case OP_ADD_LONG_2ADDR:
+        return op_add_long_2addr();
+    case OP_SUB_LONG_2ADDR:
+        return op_sub_long_2addr();
+    case OP_MUL_LONG_2ADDR:
+        return op_mul_long_2addr();
+    case OP_DIV_LONG_2ADDR:
+        return op_div_long_2addr();
+    case OP_REM_LONG_2ADDR:
+        return op_rem_long_2addr();
+    case OP_AND_LONG_2ADDR:
+        return op_and_long_2addr();
+    case OP_OR_LONG_2ADDR:
+        return op_or_long_2addr();
+    case OP_XOR_LONG_2ADDR:
+        return op_xor_long_2addr();
+    case OP_SHL_LONG_2ADDR:
+        return op_shl_long_2addr();
+    case OP_SHR_LONG_2ADDR:
+        return op_shr_long_2addr();
+    case OP_USHR_LONG_2ADDR:
+        return op_ushr_long_2addr();
+    case OP_ADD_FLOAT_2ADDR:
+        return op_add_float_2addr();
+    case OP_SUB_FLOAT_2ADDR:
+        return op_sub_float_2addr();
+    case OP_MUL_FLOAT_2ADDR:
+        return op_mul_float_2addr();
+    case OP_DIV_FLOAT_2ADDR:
+        return op_div_float_2addr();
+    case OP_REM_FLOAT_2ADDR:
+        return op_rem_float_2addr();
+    case OP_ADD_DOUBLE_2ADDR:
+        return op_add_double_2addr();
+    case OP_SUB_DOUBLE_2ADDR:
+        return op_sub_double_2addr();
+    case OP_MUL_DOUBLE_2ADDR:
+        return op_mul_double_2addr();
+    case OP_DIV_DOUBLE_2ADDR:
+        return op_div_double_2addr();
+    case OP_REM_DOUBLE_2ADDR:
+        return op_rem_double_2addr();
+    case OP_ADD_INT_LIT16:
+        return op_add_int_lit16();
+    case OP_RSUB_INT:
+        return op_rsub_int();
+    case OP_MUL_INT_LIT16:
+        return op_mul_int_lit16();
+    case OP_DIV_INT_LIT16:
+        return op_div_int_lit16();
+    case OP_REM_INT_LIT16:
+        return op_rem_int_lit16();
+    case OP_AND_INT_LIT16:
+        return op_and_int_lit16();
+    case OP_OR_INT_LIT16:
+        return op_or_int_lit16();
+    case OP_XOR_INT_LIT16:
+        return op_xor_int_lit16();
+    case OP_ADD_INT_LIT8:
+        return op_add_int_lit8();
+    case OP_RSUB_INT_LIT8:
+        return op_rsub_int_lit8();
+    case OP_MUL_INT_LIT8:
+        return op_mul_int_lit8();
+    case OP_DIV_INT_LIT8:
+        return op_div_int_lit8();
+    case OP_REM_INT_LIT8:
+        return op_rem_int_lit8();
+    case OP_AND_INT_LIT8:
+        return op_and_int_lit8();
+    case OP_OR_INT_LIT8:
+        return op_or_int_lit8();
+    case OP_XOR_INT_LIT8:
+        return op_xor_int_lit8();
+    case OP_SHL_INT_LIT8:
+        return op_shl_int_lit8();
+    case OP_SHR_INT_LIT8:
+        return op_shr_int_lit8();
+    case OP_USHR_INT_LIT8:
+        return op_ushr_int_lit8();
+    case OP_EXECUTE_INLINE:
+        return op_execute_inline(false);
+    case OP_EXECUTE_INLINE_RANGE:
+        return op_execute_inline(true);
+    case OP_BREAKPOINT:
+        ALOGE("found bytecode OP_BREAKPOINT");
+        dvmAbort();
+    case OP_INVOKE_OBJECT_INIT_RANGE:
+        return op_invoke_object_init_range();
+    case OP_IGET_QUICK:
+        return op_iget_quick();
+    case OP_IGET_WIDE_QUICK:
+        return op_iget_wide_quick();
+    case OP_IGET_OBJECT_QUICK:
+        return op_iget_object_quick();
+    case OP_IPUT_QUICK:
+        return op_iput_quick();
+    case OP_IPUT_WIDE_QUICK:
+        return op_iput_wide_quick();
+    case OP_IPUT_OBJECT_QUICK:
+        return op_iput_object_quick();
+    case OP_INVOKE_VIRTUAL_QUICK:
+        return op_invoke_virtual_quick();
+    case OP_INVOKE_VIRTUAL_QUICK_RANGE:
+        return op_invoke_virtual_quick_range();
+    case OP_INVOKE_SUPER_QUICK:
+        return op_invoke_super_quick();
+    case OP_INVOKE_SUPER_QUICK_RANGE:
+        return op_invoke_super_quick_range();
+    }
+
+    ALOGE("No JIT support for bytecode %x at offsetPC %x",
+          INST_INST(inst), offsetPC);
+    return -1;
+}
+int op_nop() {
+    rPC++;
+    return 0;
+}
diff --git a/vm/compiler/codegen/x86/Lower.h b/vm/compiler/codegen/x86/Lower.h
new file mode 100644
index 0000000..630ccb9
--- /dev/null
+++ b/vm/compiler/codegen/x86/Lower.h
@@ -0,0 +1,1240 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file lower.h
+    \brief A header file to define interface between lowering and register allocator
+*/
+
+#ifndef _DALVIK_LOWER
+#define _DALVIK_LOWER
+
+#define CODE_CACHE_PADDING 1024 //code space for a single bytecode
+// comment out for phase 1 porting
+#define PREDICTED_CHAINING
+#define JIT_CHAIN
+
+#define NUM_DEPENDENCIES 24 /* max number of dependencies from a LowOp */
+//compilaton flags used by NCG O1
+#define DUMP_EXCEPTION //to measure performance, required to have correct exception handling
+/*! multiple versions for hardcoded registers */
+#define HARDREG_OPT
+#define CFG_OPT
+/*! remove redundant move ops when accessing virtual registers */
+#define MOVE_OPT
+/*! remove redundant spill of virtual registers */
+#define SPILL_OPT
+#define XFER_OPT
+//#define DSE_OPT //no perf improvement for cme
+/*! use live range analysis to allocate registers */
+#define LIVERANGE_OPT
+/*! remove redundant null check */
+#define NULLCHECK_OPT
+//#define BOUNDCHECK_OPT
+/*! optimize the access to glue structure */
+#define GLUE_OPT
+#define CALL_FIX
+#define NATIVE_FIX
+#define INVOKE_FIX //optimization
+#define GETVR_FIX //optimization
+
+#include "Dalvik.h"
+#include "enc_wrapper.h"
+#include "AnalysisO1.h"
+#include "compiler/CompilerIR.h"
+
+//compilation flags for debugging
+//#define DEBUG_INFO
+//#define DEBUG_CALL_STACK
+//#define DEBUG_IGET_OBJ
+//#define DEBUG_NCG_CODE_SIZE
+//#define DEBUG_NCG
+//#define DEBUG_NCG_1
+//#define DEBUG_LOADING
+//#define USE_INTERPRETER
+//#define DEBUG_EACH_BYTECODE
+
+/*! registers for functions are hardcoded */
+#define HARDCODE_REG_CALL
+#define HARDCODE_REG_SHARE
+#define HARDCODE_REG_HELPER
+
+#define PhysicalReg_FP PhysicalReg_EDI
+#define PhysicalReg_Glue PhysicalReg_EBP
+
+//COPIED from interp/InterpDefs.h
+#define FETCH(_offset) (rPC[(_offset)])
+#define INST_INST(_inst) ((_inst) & 0xff)
+#define INST_A(_inst)       (((_inst) >> 8) & 0x0f)
+#define INST_B(_inst)       ((_inst) >> 12)
+#define INST_AA(_inst)      ((_inst) >> 8)
+
+//#include "vm/mterp/common/asm-constants.h"
+#define offEBP_self 8
+#define offEBP_spill -56
+#define offThread_exception 68
+#define offClassObject_descriptor 24
+#define offArrayObject_length 8
+#ifdef PROFILE_FIELD_ACCESS
+#define offStaticField_value 24
+#define offInstField_byteOffset 24
+#else
+#define offStaticField_value 16
+#define offInstField_byteOffset 16
+#endif
+
+#ifdef EASY_GDB
+#define offStackSaveArea_prevFrame 4
+#define offStackSaveArea_savedPc 8
+#define offStackSaveArea_method 12
+#define offStackSaveArea_localRefTop 16 // -> StackSaveArea.xtra.locakRefCookie
+#define offStackSaveArea_returnAddr 20
+#define offStackSaveArea_isDebugInterpreted 24
+#define sizeofStackSaveArea 24
+#else
+#define offStackSaveArea_prevFrame 0
+#define offStackSaveArea_savedPc 4
+#define offStackSaveArea_method 8
+#define offStackSaveArea_localRefTop 12 // -> StackSaveArea.xtra.locakRefCookie
+#define offStackSaveArea_returnAddr 16
+#define offStackSaveArea_isDebugInterpreted 20
+#define sizeofStackSaveArea 20
+#endif
+
+#define offClassObject_status 44
+#define offClassObject_accessFlags 32
+#ifdef MTERP_NO_UNALIGN_64
+#define offArrayObject_contents 16
+#else
+#define offArrayObject_contents 12
+#endif
+
+#define offField_clazz 0
+#define offObject_clazz 0
+#define offClassObject_vtable 116
+#define offClassObject_pDvmDex 40
+#define offClassObject_super 72
+#define offClassObject_vtableCount 112
+#define offMethod_name 16
+#define offMethod_accessFlags 4
+#define offMethod_methodIndex 8
+#define offMethod_registersSize 10
+#define offMethod_outsSize 12
+#define offGlue_interpStackEnd 32
+#define offThread_inJitCodeCache 124
+#define offThread_jniLocal_nextEntry 168
+#define offMethod_insns 32
+#ifdef ENABLE_TRACING
+#define offMethod_insns_bytecode 44
+#define offMethod_insns_ncg 48
+#endif
+
+#define offGlue_pc     0
+#define offGlue_fp     4
+#define offGlue_retval 8
+
+#define offThread_curFrame 4
+#define offGlue_method 16
+#define offGlue_methodClassDex 20
+#define offGlue_self 24
+#define offGlue_pSelfSuspendCount 36
+#define offGlue_cardTable 40
+#define offGlue_pDebuggerActive 44
+#define offGlue_pActiveProfilers 48
+#define offGlue_entryPoint 52
+#define offGlue_icRechainCount 84
+#define offGlue_espEntry 88
+#define offGlue_spillRegion 92
+#define offDvmDex_pResStrings 8
+#define offDvmDex_pResClasses 12
+#define offDvmDex_pResMethods 16
+#define offDvmDex_pResFields  20
+#define offMethod_clazz       0
+
+// Definitions must be consistent with vm/mterp/x86/header.S
+#define FRAME_SIZE     124
+
+typedef enum ArgsDoneType {
+    ArgsDone_Normal = 0,
+    ArgsDone_Native,
+    ArgsDone_Full
+} ArgsDoneType;
+
+/*! An enum type
+    to list bytecodes for AGET, APUT
+*/
+typedef enum ArrayAccess {
+    AGET, AGET_WIDE, AGET_CHAR, AGET_SHORT, AGET_BOOLEAN, AGET_BYTE,
+    APUT, APUT_WIDE, APUT_CHAR, APUT_SHORT, APUT_BOOLEAN, APUT_BYTE
+} ArrayAccess;
+/*! An enum type
+    to list bytecodes for IGET, IPUT
+*/
+typedef enum InstanceAccess {
+    IGET, IGET_WIDE, IPUT, IPUT_WIDE
+} InstanceAccess;
+/*! An enum type
+    to list bytecodes for SGET, SPUT
+*/
+typedef enum StaticAccess {
+    SGET, SGET_WIDE, SPUT, SPUT_WIDE
+} StaticAccess;
+
+typedef enum JmpCall_type {
+    JmpCall_uncond = 1,
+    JmpCall_cond,
+    JmpCall_reg, //jump reg32
+    JmpCall_call
+} JmpCall_type;
+
+////////////////////////////////////////////////////////////////
+/* data structure for native codes */
+/* Due to space considation, a lowered op (LowOp) has two operands (LowOpnd), depending on
+   the type of the operand, LowOpndReg or LowOpndImm or LowOpndMem will follow */
+/*! type of an operand can be immediate, register or memory */
+typedef enum LowOpndType {
+  LowOpndType_Imm = 0,
+  LowOpndType_Reg,
+  LowOpndType_Mem,
+  LowOpndType_Label,
+  LowOpndType_NCG,
+  LowOpndType_Chain
+} LowOpndType;
+typedef enum LowOpndDefUse {
+  LowOpndDefUse_Def = 0,
+  LowOpndDefUse_Use,
+  LowOpndDefUse_UseDef
+} LowOpndDefUse;
+
+/*!
+\brief base data structure for an operand */
+typedef struct LowOpnd {
+  LowOpndType type;
+  OpndSize size;
+  LowOpndDefUse defuse;
+} LowOpnd;
+/*!
+\brief data structure for a register operand */
+typedef struct LowOpndReg {
+  LowOpndRegType regType;
+  int logicalReg;
+  int physicalReg;
+} LowOpndReg;
+/*!
+\brief data structure for an immediate operand */
+typedef struct LowOpndImm {
+  union {
+    s4 value;
+    unsigned char bytes[4];
+  };
+} LowOpndImm;
+
+typedef struct LowOpndNCG {
+  union {
+    s4 value;
+    unsigned char bytes[4];
+  };
+} LowOpndNCG;
+
+#define LABEL_SIZE 256
+typedef struct LowOpndLabel {
+  char label[LABEL_SIZE];
+  bool isLocal;
+} LowOpndLabel;
+
+/* get ready for optimizations at LIR
+   add MemoryAccessType & virtualRegNum to memory operands */
+typedef enum MemoryAccessType {
+  MemoryAccess_GLUE,
+  MemoryAccess_VR,
+  MemoryAccess_SPILL,
+  MemoryAccess_Unknown
+} MemoryAccessType;
+typedef enum UseDefEntryType {
+  UseDefType_Ctrl = 0,
+  UseDefType_Float,
+  UseDefType_MemVR,
+  UseDefType_MemSpill,
+  UseDefType_MemUnknown,
+  UseDefType_Reg
+} UseDefEntryType;
+typedef struct UseDefProducerEntry {
+  UseDefEntryType type;
+  int index; //enum PhysicalReg for "Reg" type
+  int producerSlot;
+} UseDefProducerEntry;
+#define MAX_USE_PER_ENTRY 50 /* at most 10 uses for each entry */
+typedef struct UseDefUserEntry {
+  UseDefEntryType type;
+  int index;
+  int useSlots[MAX_USE_PER_ENTRY];
+  int num_uses_per_entry;
+} UseDefUserEntry;
+
+/*!
+\brief data structure for a memory operand */
+typedef struct LowOpndMem {
+  LowOpndImm m_disp;
+  LowOpndImm m_scale;
+  LowOpndReg m_index;
+  LowOpndReg m_base;
+  bool hasScale;
+  MemoryAccessType mType;
+  int index;
+} LowOpndMem;
+
+typedef enum AtomOpCode {
+    ATOM_PSEUDO_CHAINING_CELL_BACKWARD_BRANCH = -15,
+    ATOM_NORMAL_ALU = -14,
+    ATOM_PSEUDO_ENTRY_BLOCK = -13,
+    ATOM_PSEUDO_EXIT_BLOCK = -12,
+    ATOM_PSEUDO_TARGET_LABEL = -11,
+    ATOM_PSEUDO_CHAINING_CELL_HOT = -10,
+    ATOM_PSEUDO_CHAINING_CELL_INVOKE_PREDICTED = -9,
+    ATOM_PSEUDO_CHAINING_CELL_INVOKE_SINGLETON = -8,
+    ATOM_PSEUDO_CHAINING_CELL_NORMAL = -7,
+    ATOM_PSEUDO_DALVIK_BYTECODE_BOUNDARY = -6,
+    ATOM_PSEUDO_ALIGN4 = -5,
+    ATOM_PSEUDO_PC_RECONSTRUCTION_CELL = -4,
+    ATOM_PSEUDO_PC_RECONSTRUCTION_BLOCK_LABEL = -3,
+    ATOM_PSEUDO_EH_BLOCK_LABEL = -2,
+    ATOM_PSEUDO_NORMAL_BLOCK_LABEL = -1,
+    ATOM_NORMAL,
+} AtomOpCode;
+
+typedef enum DependencyType {
+  Dependency_RAW,
+  Dependency_WAW,
+  Dependency_WAR,
+  Dependency_FLAG
+} DependencyType;
+typedef struct DependencyStruct {
+  DependencyType dType;
+  int nodeId;
+  int latency;
+} DependencyStruct;
+
+typedef struct LowOpBlock {
+  LIR generic;
+  Mnemonic opCode;
+  AtomOpCode opCode2;
+} LowOpBlock;
+
+/*!
+\brief data structure for a lowered operation */
+typedef struct LowOp {
+  LIR generic;
+  Mnemonic opCode;
+  AtomOpCode opCode2;
+  LowOpnd opnd1;
+  LowOpnd opnd2;
+  int numOperands;
+} LowOp;
+
+typedef struct LowOpLabel {
+  LowOp lop;
+  LowOpndLabel labelOpnd;
+}LowOpLabel;
+
+typedef struct LowOpNCG {
+  LowOp lop;
+  LowOpndNCG ncgOpnd;
+}LowOpNCG;
+
+typedef struct LowOpBlockLabel {
+  LowOpBlock lop;
+  LowOpndImm immOpnd;
+} LowOpBlockLabel;
+
+typedef struct LowOpImm {
+  LowOp lop;
+  LowOpndImm immOpnd;
+} LowOpImm;
+
+typedef struct LowOpMem {
+  LowOp lop;
+  LowOpndMem memOpnd;
+} LowOpMem;
+
+typedef struct LowOpReg {
+  LowOp lop;
+  LowOpndReg regOpnd;
+} LowOpReg;
+
+typedef struct LowOpImmImm {
+  LowOp lop;
+  LowOpndImm immOpnd1;
+  LowOpndImm immOpnd2;
+} LowOpImmImm;
+
+typedef struct LowOpImmReg {
+  LowOp lop;
+  LowOpndImm immOpnd1;
+  LowOpndReg regOpnd2;
+} LowOpImmReg;
+
+typedef struct LowOpImmMem {
+  LowOp lop;
+  LowOpndImm immOpnd1;
+  LowOpndMem memOpnd2;
+} LowOpImmMem;
+
+typedef struct LowOpRegImm {
+  LowOp lop;
+  LowOpndReg regOpnd1;
+  LowOpndImm immOpnd2;
+} LowOpRegImm;
+
+typedef struct LowOpRegReg {
+  LowOp lop;
+  LowOpndReg regOpnd1;
+  LowOpndReg regOpnd2;
+} LowOpRegReg;
+
+typedef struct LowOpRegMem {
+  LowOp lop;
+  LowOpndReg regOpnd1;
+  LowOpndMem memOpnd2;
+} LowOpRegMem;
+
+typedef struct LowOpMemImm {
+  LowOp lop;
+  LowOpndMem memOpnd1;
+  LowOpndImm immOpnd2;
+} LowOpMemImm;
+
+typedef struct LowOpMemReg {
+  LowOp lop;
+  LowOpndMem memOpnd1;
+  LowOpndReg regOpnd2;
+} LowOpMemReg;
+
+typedef struct LowOpMemMem {
+  LowOp lop;
+  LowOpndMem memOpnd1;
+  LowOpndMem memOpnd2;
+} LowOpMemMem;
+
+/*!
+\brief data structure for labels used when lowering a method
+
+four label maps are defined: globalMap globalShortMap globalWorklist globalShortWorklist
+globalMap: global labels where codePtr points to the label
+           freeLabelMap called in clearNCG
+globalWorklist: global labels where codePtr points to an instruciton using the label
+  standalone NCG -------
+                accessed by insertLabelWorklist & performLabelWorklist
+  code cache ------
+                inserted by performLabelWorklist(false),
+                handled & cleared by generateRelocation in NcgFile.c
+globalShortMap: local labels where codePtr points to the label
+                freeShortMap called after generation of one bytecode
+globalShortWorklist: local labels where codePtr points to an instruction using the label
+                accessed by insertShortWorklist & insertLabel
+definition of local label: life time of the label is within a bytecode or within a helper function
+extra label maps are used by code cache:
+  globalDataWorklist VMAPIWorklist
+*/
+typedef struct LabelMap {
+  char label[LABEL_SIZE];
+  char* codePtr; //code corresponding to the label or code that uses the label
+  struct LabelMap* nextItem;
+  OpndSize size;
+  uint  addend;
+} LabelMap;
+/*!
+\brief data structure to handle forward jump (GOTO, IF)
+
+accessed by insertNCGWorklist & performNCGWorklist
+*/
+typedef struct NCGWorklist {
+  //when WITH_JIT, relativePC stores the target basic block id
+  s4 relativePC; //relative offset in bytecode
+  int offsetPC;  //PC in bytecode
+  int offsetNCG; //PC in native code
+  char* codePtr; //code for native jump instruction
+  struct NCGWorklist* nextItem;
+  OpndSize size;
+}NCGWorklist;
+/*!
+\brief data structure to handle SWITCH & FILL_ARRAY_DATA
+
+two data worklist are defined: globalDataWorklist (used by code cache) & methodDataWorklist
+methodDataWorklist is accessed by insertDataWorklist & performDataWorklist
+*/
+typedef struct DataWorklist {
+  s4 relativePC; //relative offset in bytecode to access the data
+  int offsetPC;  //PC in bytecode
+  int offsetNCG; //PC in native code
+  char* codePtr; //code for native instruction add_imm_reg imm, %edx
+  char* codePtr2;//code for native instruction add_reg_reg %eax, %edx for SWITCH
+                 //                            add_imm_reg imm, %edx for FILL_ARRAY_DATA
+  struct DataWorklist* nextItem;
+}DataWorklist;
+#ifdef ENABLE_TRACING
+typedef struct MapWorklist {
+  u4 offsetPC;
+  u4 offsetNCG;
+  int isStartOfPC; //1 --> true 0 --> false
+  struct MapWorklist* nextItem;
+} MapWorklist;
+#endif
+
+#define BUFFER_SIZE 1024 //# of Low Ops buffered
+//the following three numbers are hardcoded, please CHECK
+#define BYTECODE_SIZE_PER_METHOD 81920
+#define NATIVE_SIZE_PER_DEX 19000000 //FIXME for core.jar: 16M --> 18M for O1
+#define NATIVE_SIZE_FOR_VM_STUBS 100000
+#define MAX_HANDLER_OFFSET 1024 //maximal number of handler offsets
+
+extern int LstrClassCastExceptionPtr, LstrInstantiationErrorPtr, LstrInternalError, LstrFilledNewArrayNotImpl;
+extern int LstrArithmeticException, LstrArrayIndexException, LstrArrayStoreException, LstrStringIndexOutOfBoundsException;
+extern int LstrDivideByZero, LstrNegativeArraySizeException, LstrNoSuchMethodError, LstrNullPointerException;
+extern int LdoubNeg, LvaluePosInfLong, LvalueNegInfLong, LvalueNanLong, LshiftMask, Lvalue64, L64bits, LintMax, LintMin;
+
+extern LabelMap* globalMap;
+extern LabelMap* globalShortMap;
+extern LabelMap* globalWorklist;
+extern LabelMap* globalShortWorklist;
+extern NCGWorklist* globalNCGWorklist;
+extern DataWorklist* methodDataWorklist;
+#ifdef ENABLE_TRACING
+extern MapWorklist* methodMapWorklist;
+#endif
+extern PhysicalReg scratchRegs[4];
+
+#define C_SCRATCH_1 scratchRegs[0]
+#define C_SCRATCH_2 scratchRegs[1]
+#define C_SCRATCH_3 scratchRegs[2] //scratch reg inside callee
+
+extern LowOp* ops[BUFFER_SIZE];
+extern bool isScratchPhysical;
+extern u2* rPC;
+extern u2 inst;
+extern int offsetPC;
+extern int offsetNCG;
+extern int mapFromBCtoNCG[BYTECODE_SIZE_PER_METHOD];
+extern char* streamStart;
+
+extern char* streamCode;
+
+extern char* streamMethodStart; //start of the method
+extern char* stream; //current stream pointer
+extern char* streamMisPred;
+extern int lowOpTimeStamp;
+extern Method* currentMethod;
+extern int currentExceptionBlockIdx;
+
+extern int globalMapNum;
+extern int globalWorklistNum;
+extern int globalDataWorklistNum;
+extern int globalPCWorklistNum;
+extern int chainingWorklistNum;
+extern int VMAPIWorklistNum;
+
+extern LabelMap* globalDataWorklist;
+extern LabelMap* globalPCWorklist;
+extern LabelMap* chainingWorklist;
+extern LabelMap* VMAPIWorklist;
+
+extern int ncgClassNum;
+extern int ncgMethodNum;
+
+extern LowOp* lirTable[200]; //Number of LIRs for all bytecodes do not exceed 200
+extern int num_lirs_in_table;
+
+bool existATryBlock(Method* method, int startPC, int endPC);
+// interface between register allocator & lowering
+extern int num_removed_nullCheck;
+
+int registerAlloc(int type, int reg, bool isPhysical, bool updateRef);
+int registerAllocMove(int reg, int type, bool isPhysical, int srcReg);
+int checkVirtualReg(int reg, LowOpndRegType type, int updateRef); //returns the physical register
+int updateRefCount(int reg, LowOpndRegType type);
+int updateRefCount2(int reg, int type, bool isPhysical);
+int spillVirtualReg(int vrNum, LowOpndRegType type, bool updateTable);
+int isVirtualRegConstant(int regNum, LowOpndRegType type, int* valuePtr, bool updateRef);
+int checkTempReg(int reg, int type, bool isPhysical, int vA);
+bool checkTempReg2(int reg, int type, bool isPhysical, int physicalRegForVR);
+int freeReg(bool spillGL);
+int nextVersionOfHardReg(PhysicalReg pReg, int refCount);
+int updateVirtualReg(int reg, LowOpndRegType type);
+void setVRNullCheck(int regNum, OpndSize size);
+bool isVRNullCheck(int regNum, OpndSize size);
+void setVRBoundCheck(int vr_array, int vr_index);
+bool isVRBoundCheck(int vr_array, int vr_index);
+int requestVRFreeDelay(int regNum, u4 reason);
+void cancelVRFreeDelayRequest(int regNum, u4 reason);
+bool getVRFreeDelayRequested(int regNum);
+bool isGlueHandled(int glue_reg);
+void resetGlue(int glue_reg);
+void updateGlue(int reg, bool isPhysical, int glue_reg);
+int updateVRAtUse(int reg, LowOpndRegType pType, int regAll);
+int touchEcx();
+int touchEax();
+int touchEdx();
+int beforeCall(const char* target);
+int afterCall(const char* target);
+void startBranch();
+void endBranch();
+void rememberState(int);
+void goToState(int);
+void transferToState(int);
+void globalVREndOfBB(const Method*);
+void constVREndOfBB();
+void startNativeCode(int num, int type);
+void endNativeCode();
+void donotSpillReg(int physicalReg);
+void doSpillReg(int physicalReg);
+
+#define XMM_1 PhysicalReg_XMM0
+#define XMM_2 PhysicalReg_XMM1
+#define XMM_3 PhysicalReg_XMM2
+#define XMM_4 PhysicalReg_XMM3
+
+/////////////////////////////////////////////////////////////////////////////////
+//LR[reg] = disp + PR[base_reg] or disp + LR[base_reg]
+void load_effective_addr(int disp, int base_reg, bool isBasePhysical,
+                          int reg, bool isPhysical);
+void load_effective_addr_scale(int base_reg, bool isBasePhysical,
+                                int index_reg, bool isIndexPhysical, int scale,
+                                int reg, bool isPhysical);
+void load_fpu_cw(int disp, int base_reg, bool isBasePhysical);
+void store_fpu_cw(bool checkException, int disp, int base_reg, bool isBasePhysical);
+void convert_integer(OpndSize srcSize, OpndSize dstSize);
+void load_fp_stack(LowOp* op, OpndSize size, int disp, int base_reg, bool isBasePhysical);
+void load_int_fp_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical);
+void load_int_fp_stack_imm(OpndSize size, int imm);
+void store_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical);
+void store_int_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical);
+
+void load_fp_stack_VR(OpndSize size, int vA);
+void load_int_fp_stack_VR(OpndSize size, int vA);
+void store_fp_stack_VR(bool pop, OpndSize size, int vA);
+void store_int_fp_stack_VR(bool pop, OpndSize size, int vA);
+void compare_VR_ss_reg(int vA, int reg, bool isPhysical);
+void compare_VR_sd_reg(int vA, int reg, bool isPhysical);
+void fpu_VR(ALU_Opcode opc, OpndSize size, int vA);
+void compare_reg_mem(LowOp* op, OpndSize size, int reg, bool isPhysical,
+                           int disp, int base_reg, bool isBasePhysical);
+void compare_mem_reg(OpndSize size,
+                           int disp, int base_reg, bool isBasePhysical,
+                           int reg, bool isPhysical);
+void compare_VR_reg(OpndSize size,
+                           int vA,
+                           int reg, bool isPhysical);
+void compare_imm_reg(OpndSize size, int imm,
+                           int reg, bool isPhysical);
+void compare_imm_mem(OpndSize size, int imm,
+                           int disp, int base_reg, bool isBasePhysical);
+void compare_imm_VR(OpndSize size, int imm,
+                           int vA);
+void compare_reg_reg(int reg1, bool isPhysical1,
+                           int reg2, bool isPhysical2);
+void compare_reg_reg_16(int reg1, bool isPhysical1,
+                         int reg2, bool isPhysical2);
+void compare_ss_mem_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
+                              int reg, bool isPhysical);
+void compare_ss_reg_with_reg(LowOp* op, int reg1, bool isPhysical1,
+                              int reg2, bool isPhysical2);
+void compare_sd_mem_with_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
+                              int reg, bool isPhysical);
+void compare_sd_reg_with_reg(LowOp* op, int reg1, bool isPhysical1,
+                              int reg2, bool isPhysical2);
+void compare_fp_stack(bool pop, int reg, bool isDouble);
+void test_imm_reg(OpndSize size, int imm, int reg, bool isPhysical);
+void test_imm_mem(OpndSize size, int imm, int disp, int reg, bool isPhysical);
+
+void conditional_move_reg_to_reg(OpndSize size, ConditionCode cc, int reg1, bool isPhysical1, int reg, bool isPhysical);
+void move_ss_mem_to_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
+                        int reg, bool isPhysical);
+void move_ss_reg_to_mem(LowOp* op, int reg, bool isPhysical,
+                         int disp, int base_reg, bool isBasePhysical);
+LowOpRegMem* move_ss_mem_to_reg_noalloc(int disp, int base_reg, bool isBasePhysical,
+                         MemoryAccessType mType, int mIndex,
+                         int reg, bool isPhysical);
+LowOpMemReg* move_ss_reg_to_mem_noalloc(int reg, bool isPhysical,
+                         int disp, int base_reg, bool isBasePhysical,
+                         MemoryAccessType mType, int mIndex);
+void move_sd_mem_to_reg(int disp, int base_reg, bool isBasePhysical,
+                         int reg, bool isPhysical);
+void move_sd_reg_to_mem(LowOp* op, int reg, bool isPhysical,
+                         int disp, int base_reg, bool isBasePhysical);
+
+void conditional_jump(ConditionCode cc, const char* target, bool isShortTerm);
+void unconditional_jump(const char* target, bool isShortTerm);
+void conditional_jump_int(ConditionCode cc, int target, OpndSize size);
+void unconditional_jump_int(int target, OpndSize size);
+void unconditional_jump_reg(int reg, bool isPhysical);
+void call(const char* target);
+void call_reg(int reg, bool isPhysical);
+void call_reg_noalloc(int reg, bool isPhysical);
+void call_mem(int disp, int reg, bool isPhysical);
+void x86_return();
+
+void alu_unary_reg(OpndSize size, ALU_Opcode opc, int reg, bool isPhysical);
+void alu_unary_mem(LowOp* op, OpndSize size, ALU_Opcode opc, int disp, int base_reg, bool isBasePhysical);
+
+void alu_binary_imm_mem(OpndSize size, ALU_Opcode opc,
+                         int imm, int disp, int base_reg, bool isBasePhysical);
+void alu_binary_imm_reg(OpndSize size, ALU_Opcode opc, int imm, int reg, bool isPhysical);
+void alu_binary_mem_reg(OpndSize size, ALU_Opcode opc,
+                         int disp, int base_reg, bool isBasePhysical,
+                         int reg, bool isPhysical);
+void alu_binary_VR_reg(OpndSize size, ALU_Opcode opc, int vA, int reg, bool isPhysical);
+void alu_sd_binary_VR_reg(ALU_Opcode opc, int vA, int reg, bool isPhysical, bool isSD);
+void alu_binary_reg_reg(OpndSize size, ALU_Opcode opc,
+                         int reg1, bool isPhysical1,
+                         int reg2, bool isPhysical2);
+void alu_binary_reg_mem(OpndSize size, ALU_Opcode opc,
+                         int reg, bool isPhysical,
+                         int disp, int base_reg, bool isBasePhysical);
+
+void fpu_mem(LowOp* op, ALU_Opcode opc, OpndSize size, int disp, int base_reg, bool isBasePhysical);
+void alu_ss_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical,
+                            int reg2, bool isPhysical2);
+void alu_sd_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical,
+                            int reg2, bool isPhysical2);
+
+void push_mem_to_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical);
+void push_reg_to_stack(OpndSize size, int reg, bool isPhysical);
+
+//returns the pointer to end of the native code
+void move_reg_to_mem(OpndSize size,
+                      int reg, bool isPhysical,
+                      int disp, int base_reg, bool isBasePhysical);
+LowOpRegMem* move_mem_to_reg(OpndSize size,
+                      int disp, int base_reg, bool isBasePhysical,
+                      int reg, bool isPhysical);
+void movez_mem_to_reg(OpndSize size,
+                      int disp, int base_reg, bool isBasePhysical,
+                      int reg, bool isPhysical);
+void movez_reg_to_reg(OpndSize size,
+                      int reg, bool isPhysical,
+                      int reg2, bool isPhysical2);
+void moves_mem_to_reg(LowOp* op, OpndSize size,
+                      int disp, int base_reg, bool isBasePhysical,
+                      int reg, bool isPhysical);
+void movez_mem_disp_scale_to_reg(OpndSize size,
+                      int base_reg, bool isBasePhysical,
+                      int disp, int index_reg, bool isIndexPhysical, int scale,
+                      int reg, bool isPhysical);
+void moves_mem_disp_scale_to_reg(OpndSize size,
+                      int base_reg, bool isBasePhysical,
+                      int disp, int index_reg, bool isIndexPhysical, int scale,
+                      int reg, bool isPhysical);
+void move_reg_to_reg(OpndSize size,
+                      int reg, bool isPhysical,
+                      int reg2, bool isPhysical2);
+void move_reg_to_reg_noalloc(OpndSize size,
+                      int reg, bool isPhysical,
+                      int reg2, bool isPhysical2);
+void move_mem_scale_to_reg(OpndSize size,
+                            int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale,
+                            int reg, bool isPhysical);
+void move_mem_disp_scale_to_reg(OpndSize size,
+                int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                int reg, bool isPhysical);
+void move_reg_to_mem_scale(OpndSize size,
+                            int reg, bool isPhysical,
+                            int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale);
+void move_reg_to_mem_disp_scale(OpndSize size,
+                            int reg, bool isPhysical,
+                            int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale);
+void move_imm_to_mem(OpndSize size, int imm,
+                      int disp, int base_reg, bool isBasePhysical);
+void set_VR_to_imm(u2 vA, OpndSize size, int imm);
+void set_VR_to_imm_noalloc(u2 vA, OpndSize size, int imm);
+void set_VR_to_imm_noupdateref(LowOp* op, u2 vA, OpndSize size, int imm);
+void move_imm_to_reg(OpndSize size, int imm, int reg, bool isPhysical);
+void move_imm_to_reg_noalloc(OpndSize size, int imm, int reg, bool isPhysical);
+
+//LR[reg] = VR[vB]
+//or
+//PR[reg] = VR[vB]
+void get_virtual_reg(u2 vB, OpndSize size, int reg, bool isPhysical);
+void get_virtual_reg_noalloc(u2 vB, OpndSize size, int reg, bool isPhysical);
+//VR[v] = LR[reg]
+//or
+//VR[v] = PR[reg]
+void set_virtual_reg(u2 vA, OpndSize size, int reg, bool isPhysical);
+void set_virtual_reg_noalloc(u2 vA, OpndSize size, int reg, bool isPhysical);
+void get_VR_ss(int vB, int reg, bool isPhysical);
+void set_VR_ss(int vA, int reg, bool isPhysical);
+void get_VR_sd(int vB, int reg, bool isPhysical);
+void set_VR_sd(int vA, int reg, bool isPhysical);
+
+int spill_reg(int reg, bool isPhysical);
+int unspill_reg(int reg, bool isPhysical);
+
+void move_reg_to_mem_noalloc(OpndSize size,
+                      int reg, bool isPhysical,
+                      int disp, int base_reg, bool isBasePhysical,
+                      MemoryAccessType mType, int mIndex);
+LowOpRegMem* move_mem_to_reg_noalloc(OpndSize size,
+                      int disp, int base_reg, bool isBasePhysical,
+                      MemoryAccessType mType, int mIndex,
+                      int reg, bool isPhysical);
+
+//////////////////////////////////////////////////////////////
+int insertLabel(const char* label, bool checkDup);
+int export_pc();
+int simpleNullCheck(int reg, bool isPhysical, int vr);
+int nullCheck(int reg, bool isPhysical, int exceptionNum, int vr);
+int handlePotentialException(
+                             ConditionCode code_excep, ConditionCode code_okay,
+                             int exceptionNum, const char* errName);
+int get_currentpc(int reg, bool isPhysical);
+int get_self_pointer(int reg, bool isPhysical);
+int get_res_strings(int reg, bool isPhysical);
+int get_res_classes(int reg, bool isPhysical);
+int get_res_fields(int reg, bool isPhysical);
+int get_res_methods(int reg, bool isPhysical);
+int get_glue_method_class(int reg, bool isPhysical);
+int get_glue_method(int reg, bool isPhysical);
+int set_glue_method(int reg, bool isPhysical);
+int get_glue_dvmdex(int reg, bool isPhysical);
+int set_glue_dvmdex(int reg, bool isPhysical);
+int get_suspendCount(int reg, bool isPhysical);
+int get_return_value(OpndSize size, int reg, bool isPhysical);
+int set_return_value(OpndSize size, int reg, bool isPhysical);
+int clear_exception();
+int get_exception(int reg, bool isPhysical);
+int set_exception(int reg, bool isPhysical);
+int save_pc_fp_to_glue();
+int savearea_from_fp(int reg, bool isPhysical);
+
+int call_moddi3();
+int call_divdi3();
+int call_fmod();
+int call_fmodf();
+int call_dvmFindCatchBlock();
+int call_dvmThrowVerificationError();
+int call_dvmAllocObject();
+int call_dvmAllocArrayByClass();
+int call_dvmResolveMethod();
+int call_dvmResolveClass();
+int call_dvmInstanceofNonTrivial();
+int call_dvmThrow();
+int call_dvmThrowWithMessage();
+int call_dvmCheckSuspendPending();
+int call_dvmLockObject();
+int call_dvmUnlockObject();
+int call_dvmInitClass();
+int call_dvmAllocPrimitiveArray();
+int call_dvmInterpHandleFillArrayData();
+int call_dvmNcgHandlePackedSwitch();
+int call_dvmNcgHandleSparseSwitch();
+int call_dvmJitHandlePackedSwitch();
+int call_dvmJitHandleSparseSwitch();
+int call_dvmJitToInterpTraceSelectNoChain();
+int call_dvmJitToPatchPredictedChain();
+int call_dvmJitToInterpNormal();
+int call_dvmJitToInterpTraceSelect();
+int call_dvmQuasiAtomicSwap64();
+int call_dvmQuasiAtomicRead64();
+int call_dvmCanPutArrayElement();
+int call_dvmFindInterfaceMethodInCache();
+int call_dvmHandleStackOverflow();
+int call_dvmResolveString();
+int call_dvmResolveInstField();
+int call_dvmResolveStaticField();
+
+//labels and branches
+//shared branch to resolve class: 2 specialized versions
+//OPTION 1: call & ret
+//OPTION 2: store jump back label in a fixed register or memory
+//jump to .class_resolve, then jump back
+//OPTION 3: share translator code
+/* global variables: ncg_rPC */
+int resolve_class(
+                  int startLR/*logical register index*/, bool isPhysical, int tmp/*const pool index*/,
+                  int thirdArg);
+/* EXPORT_PC; movl exceptionPtr, -8(%esp); movl descriptor, -4(%esp); lea; call; lea; jmp */
+int throw_exception_message(int exceptionPtr, int obj_reg, bool isPhysical,
+                            int startLR/*logical register index*/, bool startPhysical);
+/* EXPORT_PC; movl exceptionPtr, -8(%esp); movl imm, -4(%esp); lea; call; lea; jmp */
+int throw_exception(int exceptionPtr, int imm,
+                    int startLR/*logical register index*/, bool startPhysical);
+
+void freeShortMap();
+int insertDataWorklist(s4 relativePC, char* codePtr1);
+#ifdef ENABLE_TRACING
+int insertMapWorklist(s4 BCOffset, s4 NCGOffset, int isStartOfPC);
+#endif
+int performNCGWorklist();
+int performDataWorklist();
+void performLabelWorklist();
+void performMethodLabelWorklist();
+void freeLabelMap();
+void performSharedWorklist();
+void performChainingWorklist();
+void freeNCGWorklist();
+void freeDataWorklist();
+void freeLabelWorklist();
+void freeChainingWorklist();
+
+int common_invokeArgsDone(ArgsDoneType form, bool isJitFull);
+int common_backwardBranch();
+int common_exceptionThrown();
+int common_errNullObject();
+int common_errArrayIndex();
+int common_errArrayStore();
+int common_errNegArraySize();
+int common_errNoSuchMethod();
+int common_errDivideByZero();
+int common_periodicChecks_entry();
+int common_periodicChecks4();
+int common_gotoBail();
+int common_gotoBail_0();
+int common_StringIndexOutOfBounds();
+void goto_invokeArgsDone();
+
+//lower a bytecode
+int lowerByteCode(const Method* method);
+
+int op_nop();
+int op_move();
+int op_move_from16();
+int op_move_16();
+int op_move_wide();
+int op_move_wide_from16();
+int op_move_wide_16();
+int op_move_result();
+int op_move_result_wide();
+int op_move_exception();
+
+int op_return_void();
+int op_return();
+int op_return_wide();
+int op_const_4();
+int op_const_16();
+int op_const();
+int op_const_high16();
+int op_const_wide_16();
+int op_const_wide_32();
+int op_const_wide();
+int op_const_wide_high16();
+int op_const_string();
+int op_const_string_jumbo();
+int op_const_class();
+int op_monitor_enter();
+int op_monitor_exit();
+int op_check_cast();
+int op_instance_of();
+
+int op_array_length();
+int op_new_instance();
+int op_new_array();
+int op_filled_new_array();
+int op_filled_new_array_range();
+int op_fill_array_data();
+int op_throw();
+int op_throw_verification_error();
+int op_goto();
+int op_goto_16();
+int op_goto_32();
+int op_packed_switch();
+int op_sparse_switch();
+int op_if_ge();
+int op_aget();
+int op_aget_wide();
+int op_aget_object();
+int op_aget_boolean();
+int op_aget_byte();
+int op_aget_char();
+int op_aget_short();
+int op_aput();
+int op_aput_wide();
+int op_aput_object();
+int op_aput_boolean();
+int op_aput_byte();
+int op_aput_char();
+int op_aput_short();
+int op_iget();
+int op_iget_wide(bool isVolatile);
+int op_iget_object();
+int op_iget_boolean();
+int op_iget_byte();
+int op_iget_char();
+int op_iget_short();
+int op_iput();
+int op_iput_wide(bool isVolatile);
+int op_iput_object();
+int op_iput_boolean();
+int op_iput_byte();
+int op_iput_char();
+int op_iput_short();
+int op_sget();
+int op_sget_wide(bool isVolatile);
+int op_sget_object();
+int op_sget_boolean();
+int op_sget_byte();
+int op_sget_char();
+int op_sget_short();
+int op_sput(bool isObj);
+int op_sput_wide(bool isVolatile);
+int op_sput_object();
+int op_sput_boolean();
+int op_sput_byte();
+int op_sput_char();
+int op_sput_short();
+int op_invoke_virtual();
+int op_invoke_super();
+int op_invoke_direct();
+int op_invoke_static();
+int op_invoke_interface();
+int op_invoke_virtual_range();
+int op_invoke_super_range();
+int op_invoke_direct_range();
+int op_invoke_static_range();
+int op_invoke_interface_range();
+int op_int_to_long();
+int op_add_long_2addr();
+int op_add_int_lit8();
+int op_cmpl_float();
+int op_cmpg_float();
+int op_cmpl_double();
+int op_cmpg_double();
+int op_cmp_long();
+int op_if_eq();
+int op_if_ne();
+int op_if_lt();
+int op_if_gt();
+int op_if_le();
+int op_if_eqz();
+int op_if_nez();
+int op_if_ltz();
+int op_if_gez();
+int op_if_gtz();
+int op_if_lez();
+int op_neg_int();
+int op_not_int();
+int op_neg_long();
+int op_not_long();
+int op_neg_float();
+int op_neg_double();
+int op_int_to_float();
+int op_int_to_double();
+int op_long_to_int();
+int op_long_to_float();
+int op_long_to_double();
+int op_float_to_int();
+int op_float_to_long();
+int op_float_to_double();
+int op_double_to_int();
+int op_double_to_long();
+int op_double_to_float();
+int op_int_to_byte();
+int op_int_to_char();
+int op_int_to_short();
+int op_add_int();
+int op_sub_int();
+int op_mul_int();
+int op_div_int();
+int op_rem_int();
+int op_and_int();
+int op_or_int();
+int op_xor_int();
+int op_shl_int();
+int op_shr_int();
+int op_ushr_int();
+int op_add_long();
+int op_sub_long();
+int op_mul_long();
+int op_div_long();
+int op_rem_long();
+int op_and_long();
+int op_or_long();
+int op_xor_long();
+int op_shl_long();
+int op_shr_long();
+int op_ushr_long();
+int op_add_float();
+int op_sub_float();
+int op_mul_float();
+int op_div_float();
+int op_rem_float();
+int op_add_double();
+int op_sub_double();
+int op_mul_double();
+int op_div_double();
+int op_rem_double();
+int op_add_int_2addr();
+int op_sub_int_2addr();
+int op_mul_int_2addr();
+int op_div_int_2addr();
+int op_rem_int_2addr();
+int op_and_int_2addr();
+int op_or_int_2addr();
+int op_xor_int_2addr();
+int op_shl_int_2addr();
+int op_shr_int_2addr();
+int op_ushr_int_2addr();
+int op_sub_long_2addr();
+int op_mul_long_2addr();
+int op_div_long_2addr();
+int op_rem_long_2addr();
+int op_and_long_2addr();
+int op_or_long_2addr();
+int op_xor_long_2addr();
+int op_shl_long_2addr();
+int op_shr_long_2addr();
+int op_ushr_long_2addr();
+int op_add_float_2addr();
+int op_sub_float_2addr();
+int op_mul_float_2addr();
+int op_div_float_2addr();
+int op_rem_float_2addr();
+int op_add_double_2addr();
+int op_sub_double_2addr();
+int op_mul_double_2addr();
+int op_div_double_2addr();
+int op_rem_double_2addr();
+int op_add_int_lit16();
+int op_rsub_int();
+int op_mul_int_lit16();
+int op_div_int_lit16();
+int op_rem_int_lit16();
+int op_and_int_lit16();
+int op_or_int_lit16();
+int op_xor_int_lit16();
+int op_rsub_int_lit8();
+int op_mul_int_lit8();
+int op_div_int_lit8();
+int op_rem_int_lit8();
+int op_and_int_lit8();
+int op_or_int_lit8();
+int op_xor_int_lit8();
+int op_shl_int_lit8();
+int op_shr_int_lit8();
+int op_ushr_int_lit8();
+int op_execute_inline(bool isRange);
+int op_invoke_object_init_range();
+int op_iget_quick();
+int op_iget_wide_quick();
+int op_iget_object_quick();
+int op_iput_quick();
+int op_iput_wide_quick();
+int op_iput_object_quick();
+int op_invoke_virtual_quick();
+int op_invoke_virtual_quick_range();
+int op_invoke_super_quick();
+int op_invoke_super_quick_range();
+
+///////////////////////////////////////////////
+void set_reg_opnd(LowOpndReg* op_reg, int reg, bool isPhysical, LowOpndRegType type);
+void set_mem_opnd(LowOpndMem* mem, int disp, int base, bool isPhysical);
+void set_mem_opnd_scale(LowOpndMem* mem, int base, bool isPhysical, int disp, int index, bool indexPhysical, int scale);
+LowOpImm* dump_imm(Mnemonic m, OpndSize size,
+               int imm);
+LowOpNCG* dump_ncg(Mnemonic m, OpndSize size, int imm);
+LowOpImm* dump_imm_with_codeaddr(Mnemonic m, OpndSize size,
+               int imm, char* codePtr);
+LowOpImm* dump_special(AtomOpCode cc, int imm);
+LowOpMem* dump_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+               int disp, int base_reg, bool isBasePhysical);
+LowOpReg* dump_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+               int reg, bool isPhysical, LowOpndRegType type);
+LowOpReg* dump_reg_noalloc(Mnemonic m, OpndSize size,
+               int reg, bool isPhysical, LowOpndRegType type);
+LowOpMemImm* dump_imm_mem_noalloc(Mnemonic m, OpndSize size,
+                           int imm,
+                           int disp, int base_reg, bool isBasePhysical,
+                           MemoryAccessType mType, int mIndex);
+LowOpRegReg* dump_reg_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+                   int reg, bool isPhysical,
+                   int reg2, bool isPhysical2, LowOpndRegType type);
+LowOpRegReg* dump_movez_reg_reg(Mnemonic m, OpndSize size,
+                        int reg, bool isPhysical,
+                        int reg2, bool isPhysical2);
+LowOpRegMem* dump_mem_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+                   int disp, int base_reg, bool isBasePhysical,
+                   MemoryAccessType mType, int mIndex,
+                   int reg, bool isPhysical, LowOpndRegType type);
+LowOpRegMem* dump_mem_reg_noalloc(Mnemonic m, OpndSize size,
+                           int disp, int base_reg, bool isBasePhysical,
+                           MemoryAccessType mType, int mIndex,
+                           int reg, bool isPhysical, LowOpndRegType type);
+LowOpRegMem* dump_mem_scale_reg(Mnemonic m, OpndSize size,
+                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                         int reg, bool isPhysical, LowOpndRegType type);
+LowOpMemReg* dump_reg_mem_scale(Mnemonic m, OpndSize size,
+                         int reg, bool isPhysical,
+                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                         LowOpndRegType type);
+LowOpMemReg* dump_reg_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+                   int reg, bool isPhysical,
+                   int disp, int base_reg, bool isBasePhysical,
+                   MemoryAccessType mType, int mIndex, LowOpndRegType type);
+LowOpMemReg* dump_reg_mem_noalloc(Mnemonic m, OpndSize size,
+                           int reg, bool isPhysical,
+                           int disp, int base_reg, bool isBasePhysical,
+                           MemoryAccessType mType, int mIndex, LowOpndRegType type);
+LowOpRegImm* dump_imm_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+                   int imm, int reg, bool isPhysical, LowOpndRegType type, bool chaining);
+LowOpMemImm* dump_imm_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+                   int imm,
+                   int disp, int base_reg, bool isBasePhysical,
+                   MemoryAccessType mType, int mIndex, bool chaining);
+LowOpMemReg* dump_fp_mem(Mnemonic m, OpndSize size, int reg,
+                  int disp, int base_reg, bool isBasePhysical,
+                  MemoryAccessType mType, int mIndex);
+LowOpRegMem* dump_mem_fp(Mnemonic m, OpndSize size,
+                  int disp, int base_reg, bool isBasePhysical,
+                  MemoryAccessType mType, int mIndex,
+                  int reg);
+LowOpLabel* dump_label(Mnemonic m, OpndSize size, int imm,
+               const char* label, bool isLocal);
+
+unsigned getJmpCallInstSize(OpndSize size, JmpCall_type type);
+bool lowerByteCodeJit(const Method* method, const u2* codePtr, MIR* mir);
+void startOfBasicBlock(struct BasicBlock* bb);
+extern LowOpBlockLabel* traceLabelList;
+extern struct BasicBlock* traceCurrentBB;
+extern struct MIR* traceCurrentMIR;
+void startOfTrace(const Method* method, LowOpBlockLabel* labelList, int, CompilationUnit*);
+void endOfTrace(bool freeOnly);
+LowOp* jumpToBasicBlock(char* instAddr, int targetId);
+LowOp* condJumpToBasicBlock(char* instAddr, ConditionCode cc, int targetId);
+bool jumpToException(const char* target);
+int codeGenBasicBlockJit(const Method* method, BasicBlock* bb);
+void endOfBasicBlock(struct BasicBlock* bb);
+void handleExtendedMIR(CompilationUnit *cUnit, MIR *mir);
+int insertChainingWorklist(int bbId, char * codeStart);
+void startOfTraceO1(const Method* method, LowOpBlockLabel* labelList, int exceptionBlockId, CompilationUnit *cUnit);
+void endOfTraceO1();
+int isPowerOfTwo(int imm);
+void move_chain_to_mem(OpndSize size, int imm,
+                        int disp, int base_reg, bool isBasePhysical);
+void move_chain_to_reg(OpndSize size, int imm, int reg, bool isPhysical);
+
+void dumpImmToMem(int vrNum, OpndSize size, int value);
+bool isInMemory(int regNum, OpndSize size);
+int touchEbx();
+int boundCheck(int vr_array, int reg_array, bool isPhysical_array,
+               int vr_index, int reg_index, bool isPhysical_index,
+               int exceptionNum);
+int getRelativeOffset(const char* target, bool isShortTerm, JmpCall_type type, bool* unknown,
+                      OpndSize* immSize);
+int getRelativeNCG(s4 tmp, JmpCall_type type, bool* unknown, OpndSize* size);
+void freeAtomMem();
+OpndSize estOpndSizeFromImm(int target);
+
+void preprocessingBB(BasicBlock* bb);
+void preprocessingTrace();
+void dump_nop(int size);
+#endif
diff --git a/vm/compiler/codegen/x86/LowerAlu.cpp b/vm/compiler/codegen/x86/LowerAlu.cpp
new file mode 100644
index 0000000..2231bac
--- /dev/null
+++ b/vm/compiler/codegen/x86/LowerAlu.cpp
@@ -0,0 +1,1962 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file LowerAlu.cpp
+    \brief This file lowers ALU bytecodes.
+*/
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "NcgAot.h"
+#include "enc_wrapper.h"
+
+/////////////////////////////////////////////
+#define P_GPR_1 PhysicalReg_EBX
+//! lower bytecode NEG_INT
+
+//!
+int op_neg_int() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    alu_unary_reg(OpndSize_32, neg_opc, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode NOT_INT
+
+//!
+int op_not_int() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    alu_unary_reg(OpndSize_32, not_opc, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 1;
+    return 0;
+}
+#undef P_GPR_1
+//! lower bytecode NEG_LONG
+
+//! This implementation uses XMM registers
+int op_neg_long() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_64, 1, false);
+    alu_binary_reg_reg(OpndSize_64, xor_opc, 2, false, 2, false);
+    alu_binary_reg_reg(OpndSize_64, sub_opc, 1, false, 2, false);
+    set_virtual_reg(vA, OpndSize_64, 2, false);
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode NOT_LONG
+
+//! This implementation uses XMM registers
+int op_not_long() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_64, 1, false);
+    load_global_data_API("64bits", OpndSize_64, 2, false);
+    alu_binary_reg_reg(OpndSize_64, andn_opc, 2, false, 1, false);
+    set_virtual_reg(vA, OpndSize_64, 1, false);
+    rPC += 1;
+    return 0;
+}
+#define P_GPR_1 PhysicalReg_EBX
+//! lower bytecode NEG_FLOAT
+
+//! This implementation uses GPR
+int op_neg_float() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    alu_binary_imm_reg(OpndSize_32, add_opc, 0x80000000, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 1;
+    return 0;
+}
+#undef P_GPR_1
+
+//! lower bytecode NEG_DOUBLE
+
+//! This implementation uses XMM registers
+int op_neg_double() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_64, 1, false);
+    load_global_data_API("doubNeg", OpndSize_64, 2, false);
+    alu_binary_reg_reg(OpndSize_64, xor_opc, 1, false, 2, false);
+    set_virtual_reg(vA, OpndSize_64, 2, false);
+    rPC += 1;
+    return 0;
+}
+
+//! lower bytecode INT_TO_LONG
+
+//! It uses native instruction cdq
+int op_int_to_long() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_32, PhysicalReg_EAX, true);
+    convert_integer(OpndSize_32, OpndSize_64);
+    set_virtual_reg(vA, OpndSize_32, PhysicalReg_EAX, true);
+    set_virtual_reg(vA+1, OpndSize_32, PhysicalReg_EDX, true);
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode INT_TO_FLOAT
+
+//! This implementation uses FP stack
+int op_int_to_float() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    load_int_fp_stack_VR(OpndSize_32, vB); //fildl
+    store_fp_stack_VR(true, OpndSize_32, vA); //fstps
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode INT_TO_DOUBLE
+
+//! This implementation uses FP stack
+int op_int_to_double() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    load_int_fp_stack_VR(OpndSize_32, vB); //fildl
+    store_fp_stack_VR(true, OpndSize_64, vA); //fstpl
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode LONG_TO_FLOAT
+
+//! This implementation uses FP stack
+int op_long_to_float() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    load_int_fp_stack_VR(OpndSize_64, vB); //fildll
+    store_fp_stack_VR(true, OpndSize_32, vA); //fstps
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode LONG_TO_DOUBLE
+
+//! This implementation uses FP stack
+int op_long_to_double() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    load_int_fp_stack_VR(OpndSize_64, vB); //fildll
+    store_fp_stack_VR(true, OpndSize_64, vA); //fstpl
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode FLOAT_TO_DOUBLE
+
+//! This implementation uses FP stack
+int op_float_to_double() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    load_fp_stack_VR(OpndSize_32, vB); //flds
+    store_fp_stack_VR(true, OpndSize_64, vA); //fstpl
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode DOUBLE_TO_FLOAT
+
+//! This implementation uses FP stack
+int op_double_to_float() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    load_fp_stack_VR(OpndSize_64, vB); //fldl
+    store_fp_stack_VR(true, OpndSize_32, vA); //fstps
+    rPC += 1;
+    return 0;
+}
+#define P_GPR_1 PhysicalReg_EBX
+//! lower bytecode LONG_TO_INT
+
+//! This implementation uses GPR
+int op_long_to_int() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 1;
+    return 0;
+}
+#undef P_GPR_1
+
+//! common code to convert a float or double to integer
+
+//! It uses FP stack
+int common_fp_to_int(bool isDouble, u2 vA, u2 vB) {
+    if(isDouble) {
+        load_fp_stack_VR(OpndSize_64, vB); //fldl
+    }
+    else {
+        load_fp_stack_VR(OpndSize_32, vB); //flds
+    }
+
+    load_fp_stack_global_data_API("intMax", OpndSize_32);
+    load_fp_stack_global_data_API("intMin", OpndSize_32);
+
+    //ST(0) ST(1) ST(2) --> LintMin LintMax value
+    compare_fp_stack(true, 2, false/*isDouble*/); //ST(2)
+    //ST(0) ST(1) --> LintMax value
+    conditional_jump(Condition_AE, ".float_to_int_negInf", true);
+    rememberState(1);
+    compare_fp_stack(true, 1, false/*isDouble*/); //ST(1)
+    //ST(0) --> value
+    rememberState(2);
+    conditional_jump(Condition_C, ".float_to_int_nanInf", true);
+    //fnstcw, orw, fldcw, xorw
+    load_effective_addr(-2, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    store_fpu_cw(false/*checkException*/, 0, PhysicalReg_ESP, true);
+    alu_binary_imm_mem(OpndSize_16, or_opc, 0xc00, 0, PhysicalReg_ESP, true);
+    load_fpu_cw(0, PhysicalReg_ESP, true);
+    alu_binary_imm_mem(OpndSize_16, xor_opc, 0xc00, 0, PhysicalReg_ESP, true);
+    store_int_fp_stack_VR(true/*pop*/, OpndSize_32, vA); //fistpl
+    //fldcw
+    load_fpu_cw(0, PhysicalReg_ESP, true);
+    load_effective_addr(2, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    rememberState(3);
+    unconditional_jump(".float_to_int_okay", true);
+    insertLabel(".float_to_int_nanInf", true);
+    conditional_jump(Condition_NP, ".float_to_int_posInf", true);
+    //fstps CHECK
+    goToState(2);
+    store_fp_stack_VR(true, OpndSize_32, vA);
+    set_VR_to_imm(vA, OpndSize_32, 0);
+    transferToState(3);
+    unconditional_jump(".float_to_int_okay", true);
+    insertLabel(".float_to_int_posInf", true);
+    //fstps CHECK
+    goToState(2);
+    store_fp_stack_VR(true, OpndSize_32, vA);
+    set_VR_to_imm(vA, OpndSize_32, 0x7fffffff);
+    transferToState(3);
+    unconditional_jump(".float_to_int_okay", true);
+    insertLabel(".float_to_int_negInf", true);
+    goToState(1);
+    //fstps CHECK
+    store_fp_stack_VR(true, OpndSize_32, vA);
+    store_fp_stack_VR(true, OpndSize_32, vA);
+    set_VR_to_imm(vA, OpndSize_32, 0x80000000);
+    transferToState(3);
+    insertLabel(".float_to_int_okay", true);
+    return 0;
+}
+//! lower bytecode FLOAT_TO_INT by calling common_fp_to_int
+
+//!
+int op_float_to_int() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    int retval = common_fp_to_int(false, vA, vB);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode DOUBLE_TO_INT by calling common_fp_to_int
+
+//!
+int op_double_to_int() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    int retval = common_fp_to_int(true, vA, vB);
+    rPC += 1;
+    return retval;
+}
+
+//! common code to convert float or double to long
+
+//! It uses FP stack
+int common_fp_to_long(bool isDouble, u2 vA, u2 vB) {
+    if(isDouble) {
+        load_fp_stack_VR(OpndSize_64, vB); //fldl
+    }
+    else {
+        load_fp_stack_VR(OpndSize_32, vB); //flds
+    }
+
+    load_fp_stack_global_data_API("valuePosInfLong", OpndSize_64);
+    load_fp_stack_global_data_API("valueNegInfLong", OpndSize_64);
+
+    //ST(0) ST(1) ST(2) --> LintMin LintMax value
+    compare_fp_stack(true, 2, false/*isDouble*/); //ST(2)
+    //ST(0) ST(1) --> LintMax value
+    conditional_jump(Condition_AE, ".float_to_long_negInf", true);
+    rememberState(1);
+    compare_fp_stack(true, 1, false/*isDouble*/); //ST(1)
+    rememberState(2);
+    //ST(0) --> value
+    conditional_jump(Condition_C, ".float_to_long_nanInf", true);
+    //fnstcw, orw, fldcw, xorw
+    load_effective_addr(-2, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    store_fpu_cw(false/*checkException*/, 0, PhysicalReg_ESP, true);
+    alu_binary_imm_mem(OpndSize_16, or_opc, 0xc00, 0, PhysicalReg_ESP, true);
+    load_fpu_cw(0, PhysicalReg_ESP, true);
+    alu_binary_imm_mem(OpndSize_16, xor_opc, 0xc00, 0, PhysicalReg_ESP, true);
+    store_int_fp_stack_VR(true/*pop*/, OpndSize_64, vA); //fistpll
+    //fldcw
+    load_fpu_cw(0, PhysicalReg_ESP, true);
+    load_effective_addr(2, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    rememberState(3);
+    unconditional_jump(".float_to_long_okay", true);
+    insertLabel(".float_to_long_nanInf", true);
+    conditional_jump(Condition_NP, ".float_to_long_posInf", true);
+    //fstpl??
+    goToState(2);
+
+    load_global_data_API("valueNanLong", OpndSize_64, 1, false);
+
+    set_virtual_reg(vA, OpndSize_64, 1, false);
+    transferToState(3);
+    unconditional_jump(".float_to_long_okay", true);
+    insertLabel(".float_to_long_posInf", true);
+    //fstpl
+    goToState(2);
+
+    load_global_data_API("valuePosInfLong", OpndSize_64, 2, false);
+    set_virtual_reg(vA, OpndSize_64, 2, false);
+    transferToState(3);
+    unconditional_jump(".float_to_long_okay", true);
+    insertLabel(".float_to_long_negInf", true);
+    //fstpl
+    //fstpl
+    goToState(1);
+
+    load_global_data_API("valueNegInfLong", OpndSize_64, 3, false);
+    set_virtual_reg(vA, OpndSize_64, 3, false);
+    transferToState(3);
+    insertLabel(".float_to_long_okay", true);
+    return 0;
+}
+//! lower bytecode FLOAT_TO_LONG by calling common_fp_to_long
+
+//!
+int op_float_to_long() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    int retval = common_fp_to_long(false, vA, vB);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode DOUBLE_TO_LONG by calling common_fp_to_long
+
+//!
+int op_double_to_long() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    int retval = common_fp_to_long(true, vA, vB);
+    rPC += 1;
+    return retval;
+}
+#define P_GPR_1 PhysicalReg_EBX
+//! lower bytecode INT_TO_BYTE
+
+//! It uses GPR
+int op_int_to_byte() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    alu_binary_imm_reg(OpndSize_32, sal_opc, 24, 1, false);
+    alu_binary_imm_reg(OpndSize_32, sar_opc, 24, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode INT_TO_CHAR
+
+//! It uses GPR
+int op_int_to_char() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    alu_binary_imm_reg(OpndSize_32, sal_opc, 16, 1, false);
+    alu_binary_imm_reg(OpndSize_32, shr_opc, 16, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode INT_TO_SHORT
+
+//! It uses GPR
+int op_int_to_short() {
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    alu_binary_imm_reg(OpndSize_32, sal_opc, 16, 1, false);
+    alu_binary_imm_reg(OpndSize_32, sar_opc, 16, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 1;
+    return 0;
+}
+//! common code to handle integer ALU ops
+
+//! It uses GPR
+int common_alu_int(ALU_Opcode opc, u2 vA, u2 v1, u2 v2) { //except div and rem
+    get_virtual_reg(v1, OpndSize_32, 1, false);
+    //in encoder, reg is first operand, which is the destination
+    //gpr_1 op v2(rFP) --> gpr_1
+    //shift only works with reg cl, v2 should be in %ecx
+    alu_binary_VR_reg(OpndSize_32, opc, v2, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    return 0;
+}
+#undef P_GPR_1
+#define P_GPR_1 PhysicalReg_EBX
+//! common code to handle integer shift ops
+
+//! It uses GPR
+int common_shift_int(ALU_Opcode opc, u2 vA, u2 v1, u2 v2) {
+    get_virtual_reg(v2, OpndSize_32, PhysicalReg_ECX, true);
+    get_virtual_reg(v1, OpndSize_32, 1, false);
+    //in encoder, reg2 is first operand, which is the destination
+    //gpr_1 op v2(rFP) --> gpr_1
+    //shift only works with reg cl, v2 should be in %ecx
+    alu_binary_reg_reg(OpndSize_32, opc, PhysicalReg_ECX, true, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    return 0;
+}
+#undef p_GPR_1
+//! lower bytecode ADD_INT by calling common_alu_int
+
+//!
+int op_add_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_alu_int(add_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SUB_INT by calling common_alu_int
+
+//!
+int op_sub_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_alu_int(sub_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode MUL_INT by calling common_alu_int
+
+//!
+int op_mul_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_alu_int(imul_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode AND_INT by calling common_alu_int
+
+//!
+int op_and_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_alu_int(and_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode OR_INT by calling common_alu_int
+
+//!
+int op_or_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_alu_int(or_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode XOR_INT by calling common_alu_int
+
+//!
+int op_xor_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_alu_int(xor_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SHL_INT by calling common_shift_int
+
+//!
+int op_shl_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_shift_int(shl_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SHR_INT by calling common_shift_int
+
+//!
+int op_shr_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_shift_int(sar_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode USHR_INT by calling common_shift_int
+
+//!
+int op_ushr_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_shift_int(shr_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode ADD_INT_2ADDR by calling common_alu_int
+
+//!
+int op_add_int_2addr() {
+    u2 vA, v1, v2;
+    vA = INST_A(inst);
+    v1 = vA;
+    v2 = INST_B(inst);
+    int retval = common_alu_int(add_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode SUB_INT_2ADDR by calling common_alu_int
+
+//!
+int op_sub_int_2addr() {
+    u2 vA, v1, v2;
+    vA = INST_A(inst);
+    v1 = vA;
+    v2 = INST_B(inst);
+    int retval = common_alu_int(sub_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode MUL_INT_2ADDR by calling common_alu_int
+
+//!
+int op_mul_int_2addr() {
+    u2 vA, v1, v2;
+    vA = INST_A(inst);
+    v1 = vA;
+    v2 = INST_B(inst);
+    int retval = common_alu_int(imul_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode AND_INT_2ADDR by calling common_alu_int
+
+//!
+int op_and_int_2addr() {
+    u2 vA, v1, v2;
+    vA = INST_A(inst);
+    v1 = vA;
+    v2 = INST_B(inst);
+    int retval = common_alu_int(and_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode OR_INT_2ADDR by calling common_alu_int
+
+//!
+int op_or_int_2addr() {
+    u2 vA, v1, v2;
+    vA = INST_A(inst);
+    v1 = vA;
+    v2 = INST_B(inst);
+    int retval = common_alu_int(or_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode XOR_INT_2ADDR by calling common_alu_int
+
+//!
+int op_xor_int_2addr() {
+    u2 vA, v1, v2;
+    vA = INST_A(inst);
+    v1 = vA;
+    v2 = INST_B(inst);
+    int retval = common_alu_int(xor_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode SHL_INT_2ADDR by calling common_shift_int
+
+//!
+int op_shl_int_2addr() {
+    u2 vA, v1, v2;
+    vA = INST_A(inst);
+    v1 = vA;
+    v2 = INST_B(inst);
+    int retval = common_shift_int(shl_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode SHR_INT_2ADDR by calling common_shift_int
+
+//!
+int op_shr_int_2addr() {
+    u2 vA, v1, v2;
+    vA = INST_A(inst);
+    v1 = vA;
+    v2 = INST_B(inst);
+    int retval = common_shift_int(sar_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode USHR_INT_2ADDR by calling common_shift_int
+
+//!
+int op_ushr_int_2addr() {
+    u2 vA, v1, v2;
+    vA = INST_A(inst);
+    v1 = vA;
+    v2 = INST_B(inst);
+    int retval = common_shift_int(shr_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+#define P_GPR_1 PhysicalReg_EBX
+//!common code to handle integer DIV & REM, it used GPR
+
+//!The special case: when op0 == minint && op1 == -1, return 0 for isRem, return 0x80000000 for isDiv
+//!There are two merge points in the control flow for this bytecode
+//!make sure the reg. alloc. state is the same at merge points by calling transferToState
+int common_div_rem_int(bool isRem, u2 vA, u2 v1, u2 v2) {
+    get_virtual_reg(v1, OpndSize_32, PhysicalReg_EAX, true);
+    get_virtual_reg(v2, OpndSize_32, 2, false);
+    compare_imm_reg(OpndSize_32, 0, 2, false);
+    handlePotentialException(
+                                       Condition_E, Condition_NE,
+                                       1, "common_errDivideByZero");
+    /////////////////// handle special cases
+    //conditional move 0 to $edx for rem for the two special cases
+    //conditional move 0x80000000 to $eax for div
+    //handle -1 special case divide error
+    compare_imm_reg(OpndSize_32, -1, 2, false);
+    conditional_jump(Condition_NE, ".common_div_rem_int_normal", true);
+    //handle min int special case divide error
+    rememberState(1);
+    compare_imm_reg(OpndSize_32, 0x80000000, PhysicalReg_EAX, true);
+    transferToState(1);
+    conditional_jump(Condition_E, ".common_div_rem_int_special", true);
+
+    insertLabel(".common_div_rem_int_normal", true); //merge point
+    convert_integer(OpndSize_32, OpndSize_64); //cdq
+    //idiv: dividend in edx:eax; quotient in eax; remainder in edx
+    alu_unary_reg(OpndSize_32, idiv_opc, 2, false);
+    if(isRem)
+        set_virtual_reg(vA, OpndSize_32, PhysicalReg_EDX, true);
+    else //divide: quotient in %eax
+        set_virtual_reg(vA, OpndSize_32, PhysicalReg_EAX, true);
+    rememberState(2);
+    unconditional_jump(".common_div_rem_int_okay", true);
+
+    insertLabel(".common_div_rem_int_special", true);
+    goToState(1);
+    if(isRem)
+        set_VR_to_imm(vA, OpndSize_32, 0);
+    else
+        set_VR_to_imm(vA, OpndSize_32, 0x80000000);
+    transferToState(2);
+    insertLabel(".common_div_rem_int_okay", true); //merge point 2
+    return 0;
+}
+#undef P_GPR_1
+//! lower bytecode DIV_INT by calling common_div_rem_int
+
+//!
+int op_div_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_div_rem_int(false, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode REM_INT by calling common_div_rem_int
+
+//!
+int op_rem_int() {
+    u2 vA, v1, v2;
+    vA = INST_AA(inst);
+    v1 = *((u1*)rPC + 2);
+    v2 = *((u1*)rPC + 3);
+    int retval = common_div_rem_int(true, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode DIV_INT_2ADDR by calling common_div_rem_int
+
+//!
+int op_div_int_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_div_rem_int(false, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode REM_INT_2ADDR by calling common_div_rem_int
+
+//!
+int op_rem_int_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_div_rem_int(true, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+
+#define P_GPR_1 PhysicalReg_EBX
+//! common code to handle integer ALU ops with literal
+
+//! It uses GPR
+int common_alu_int_lit(ALU_Opcode opc, u2 vA, u2 vB, s2 imm) { //except div and rem
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    alu_binary_imm_reg(OpndSize_32, opc, imm, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    return 0;
+}
+//! calls common_alu_int_lit
+int common_shift_int_lit(ALU_Opcode opc, u2 vA, u2 vB, s2 imm) {
+    return common_alu_int_lit(opc, vA, vB, imm);
+}
+#undef p_GPR_1
+//! lower bytecode ADD_INT_LIT16 by calling common_alu_int_lit
+
+//!
+int op_add_int_lit16() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = common_alu_int_lit(add_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+
+int alu_rsub_int(ALU_Opcode opc, u2 vA, s2 imm, u2 vB) {
+    move_imm_to_reg(OpndSize_32, imm, 2, false);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    alu_binary_reg_reg(OpndSize_32, opc, 1, false, 2, false);
+    set_virtual_reg(vA, OpndSize_32, 2, false);
+    return 0;
+}
+
+
+//! lower bytecode RSUB_INT by calling common_alu_int_lit
+
+//!
+int op_rsub_int() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = alu_rsub_int(sub_opc, vA, tmp, vB);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode MUL_INT_LIT16 by calling common_alu_int_lit
+
+//!
+int op_mul_int_lit16() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = common_alu_int_lit(imul_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode AND_INT_LIT16 by calling common_alu_int_lit
+
+//!
+int op_and_int_lit16() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = common_alu_int_lit(and_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode OR_INT_LIT16 by calling common_alu_int_lit
+
+//!
+int op_or_int_lit16() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = common_alu_int_lit(or_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode XOR_INT_LIT16 by calling common_alu_int_lit
+
+//!
+int op_xor_int_lit16() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = common_alu_int_lit(xor_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SHL_INT_LIT16 by calling common_shift_int_lit
+
+//!
+int op_shl_int_lit16() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = common_shift_int_lit(shl_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SHR_INT_LIT16 by calling common_shift_int_lit
+
+//!
+int op_shr_int_lit16() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = common_shift_int_lit(sar_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode USHR_INT_LIT16 by calling common_shift_int_lit
+
+//!
+int op_ushr_int_lit16() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = common_shift_int_lit(shr_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode ADD_INT_LIT8 by calling common_alu_int_lit
+
+//!
+int op_add_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = common_alu_int_lit(add_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode RSUB_INT_LIT8 by calling common_alu_int_lit
+
+//!
+int op_rsub_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = alu_rsub_int(sub_opc, vA, tmp, vB);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode MUL_INT_LIT8 by calling common_alu_int_lit
+
+//!
+int op_mul_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = common_alu_int_lit(imul_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode AND_INT_LIT8 by calling common_alu_int_lit
+
+//!
+int op_and_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = common_alu_int_lit(and_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode OR_INT_LIT8 by calling common_alu_int_lit
+
+//!
+int op_or_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = common_alu_int_lit(or_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode XOR_INT_LIT8 by calling common_alu_int_lit
+
+//!
+int op_xor_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = common_alu_int_lit(xor_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SHL_INT_LIT8 by calling common_shift_int_lit
+
+//!
+int op_shl_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = common_shift_int_lit(shl_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SHR_INT_LIT8 by calling common_shift_int_lit
+
+//!
+int op_shr_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = common_shift_int_lit(sar_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode USHR_INT_LIT8 by calling common_shift_int_lit
+
+//!
+int op_ushr_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = common_shift_int_lit(shr_opc, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+
+int isPowerOfTwo(int imm) {
+    int i;
+    for(i = 1; i < 17; i++) {
+        if(imm == (1 << i)) return i;
+    }
+    return -1;
+}
+
+#define P_GPR_1 PhysicalReg_EBX
+int div_lit_strength_reduction(u2 vA, u2 vB, s2 imm) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        //strength reduction for div by 2,4,8,...
+        int power = isPowerOfTwo(imm);
+        if(power < 1) return 0;
+        //tmp2 is not updated, so it can share with vB
+        get_virtual_reg(vB, OpndSize_32, 2, false);
+        //if imm is 2, power will be 1
+        if(power == 1) {
+            /* mov tmp1, tmp2
+               shrl $31, tmp1
+               addl tmp2, tmp1
+               sarl $1, tmp1 */
+            move_reg_to_reg(OpndSize_32, 2, false, 1, false);
+            alu_binary_imm_reg(OpndSize_32, shr_opc, 31, 1, false);
+            alu_binary_reg_reg(OpndSize_32, add_opc, 2, false, 1, false);
+            alu_binary_imm_reg(OpndSize_32, sar_opc, 1, 1, false);
+            set_virtual_reg(vA, OpndSize_32, 1, false);
+            return 1;
+        }
+        //power > 1
+        /* mov tmp1, tmp2
+           sarl $power-1, tmp1
+           shrl 32-$power, tmp1
+           addl tmp2, tmp1
+           sarl $power, tmp1 */
+        move_reg_to_reg(OpndSize_32, 2, false, 1, false);
+        alu_binary_imm_reg(OpndSize_32, sar_opc, power-1, 1, false);
+        alu_binary_imm_reg(OpndSize_32, shr_opc, 32-power, 1, false);
+        alu_binary_reg_reg(OpndSize_32, add_opc, 2, false, 1, false);
+        alu_binary_imm_reg(OpndSize_32, sar_opc, power, 1, false);
+        set_virtual_reg(vA, OpndSize_32, 1, false);
+        return 1;
+    }
+    return 0;
+}
+
+////////// throws exception!!!
+//! common code to handle integer DIV & REM with literal
+
+//! It uses GPR
+int common_div_rem_int_lit(bool isRem, u2 vA, u2 vB, s2 imm) {
+    if(!isRem) {
+        int retCode = div_lit_strength_reduction(vA, vB, imm);
+        if(retCode > 0) return 0;
+    }
+    if(imm == 0) {
+        export_pc(); //use %edx
+#ifdef DEBUG_EXCEPTION
+        LOGI("EXTRA code to handle exception");
+#endif
+        constVREndOfBB();
+        beforeCall("exception"); //dump GG, GL VRs
+        unconditional_jump_global_API(
+                          "common_errDivideByZero", false);
+
+        return 0;
+    }
+    get_virtual_reg(vB, OpndSize_32, PhysicalReg_EAX, true);
+    //check against -1 for DIV_INT??
+    if(imm == -1) {
+        compare_imm_reg(OpndSize_32, 0x80000000, PhysicalReg_EAX, true);
+        conditional_jump(Condition_E, ".div_rem_int_lit_special", true);
+        rememberState(1);
+    }
+    move_imm_to_reg(OpndSize_32, imm, 2, false);
+    convert_integer(OpndSize_32, OpndSize_64); //cdq
+    //idiv: dividend in edx:eax; quotient in eax; remainder in edx
+    alu_unary_reg(OpndSize_32, idiv_opc, 2, false);
+    if(isRem)
+        set_virtual_reg(vA, OpndSize_32, PhysicalReg_EDX, true);
+    else
+        set_virtual_reg(vA, OpndSize_32, PhysicalReg_EAX, true);
+
+    if(imm == -1) {
+        unconditional_jump(".div_rem_int_lit_okay", true);
+        rememberState(2);
+        insertLabel(".div_rem_int_lit_special", true);
+        goToState(1);
+        if(isRem)
+            set_VR_to_imm(vA, OpndSize_32, 0);
+        else
+            set_VR_to_imm(vA, OpndSize_32, 0x80000000);
+        transferToState(2);
+    }
+
+    insertLabel(".div_rem_int_lit_okay", true); //merge point 2
+    return 0;
+}
+#undef P_GPR_1
+//! lower bytecode DIV_INT_LIT16 by calling common_div_rem_int_lit
+
+//!
+int op_div_int_lit16() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = common_div_rem_int_lit(false, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode REM_INT_LIT16 by calling common_div_rem_int_lit
+
+//!
+int op_rem_int_lit16() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s4 tmp = (s2)FETCH(1);
+    int retval = common_div_rem_int_lit(true, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode DIV_INT_LIT8 by calling common_div_rem_int_lit
+
+//!
+int op_div_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = common_div_rem_int_lit(false, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode REM_INT_LIT8 by calling common_div_rem_int_lit
+
+//!
+int op_rem_int_lit8() {
+    u2 vA = INST_AA(inst);
+    u2 vB = (u2)FETCH(1) & 0xff;
+    s2 tmp = (s2)FETCH(1) >> 8;
+    int retval = common_div_rem_int_lit(true, vA, vB, tmp);
+    rPC += 2;
+    return retval;
+}
+//! common code to hanle long ALU ops
+
+//! It uses XMM
+int common_alu_long(ALU_Opcode opc, u2 vA, u2 v1, u2 v2) { //except div and rem
+    get_virtual_reg(v1, OpndSize_64, 1, false);
+    get_virtual_reg(v2, OpndSize_64, 2, false);
+    alu_binary_reg_reg(OpndSize_64, opc, 2, false, 1, false);
+    set_virtual_reg(vA, OpndSize_64, 1, false);
+    return 0;
+}
+//! lower bytecode ADD_LONG by calling common_alu_long
+
+//!
+int op_add_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_long(add_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SUB_LONG by calling common_alu_long
+
+//!
+int op_sub_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_long(sub_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode AND_LONG by calling common_alu_long
+
+//!
+int op_and_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_long(and_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode OR_LONG by calling common_alu_long
+
+//!
+int op_or_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_long(or_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode XOR_LONG by calling common_alu_long
+
+//!
+int op_xor_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_long(xor_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode ADD_LONG_2ADDR by calling common_alu_long
+
+//!
+int op_add_long_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_long(add_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode SUB_LONG_2ADDR by calling common_alu_long
+
+//!
+int op_sub_long_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_long(sub_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode AND_LONG_2ADDR by calling common_alu_long
+
+//!
+int op_and_long_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_long(and_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode OR_LONG_2ADDR by calling common_alu_long
+
+//!
+int op_or_long_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_long(or_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode XOR_LONG_2ADDR by calling common_alu_long
+
+//!
+int op_xor_long_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_long(xor_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+
+//signed vs unsigned imul and mul?
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_ESI
+//! common code to handle multiplication of long
+
+//! It uses GPR
+int common_mul_long(u2 vA, u2 v1, u2 v2) {
+    get_virtual_reg(v2, OpndSize_32, 1, false);
+    move_reg_to_reg(OpndSize_32, 1, false, PhysicalReg_EAX, true);
+    //imul: 2L * 1H update temporary 1
+    alu_binary_VR_reg(OpndSize_32, imul_opc, (v1+1), 1, false);
+    get_virtual_reg(v1, OpndSize_32, 3, false);
+    move_reg_to_reg(OpndSize_32, 3, false, 2, false);
+    //imul: 1L * 2H
+    alu_binary_VR_reg(OpndSize_32, imul_opc, (v2+1), 2, false);
+    alu_binary_reg_reg(OpndSize_32, add_opc, 2, false, 1, false);
+    alu_unary_reg(OpndSize_32, mul_opc, 3, false);
+    alu_binary_reg_reg(OpndSize_32, add_opc, PhysicalReg_EDX, true, 1, false);
+    set_virtual_reg(vA+1, OpndSize_32, 1, false);
+    set_virtual_reg(vA, OpndSize_32, PhysicalReg_EAX, true);
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+//! lower bytecode MUL_LONG by calling common_mul_long
+
+//!
+int op_mul_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_mul_long(vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode MUL_LONG_2ADDR by calling common_mul_long
+
+//!
+int op_mul_long_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_mul_long(vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+//! common code to handle DIV & REM of long
+
+//! It uses GPR & XMM; and calls call_moddi3 & call_divdi3
+int common_div_rem_long(bool isRem, u2 vA, u2 v1, u2 v2) {
+    get_virtual_reg(v2, OpndSize_32, 1, false);
+    get_virtual_reg(v2+1, OpndSize_32, 2, false);
+    //save to native stack before changing register P_GPR_1
+    load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 1, false, 8, PhysicalReg_ESP, true);
+    alu_binary_reg_reg(OpndSize_32, or_opc, 2, false, 1, false);
+
+    handlePotentialException(
+                                       Condition_E, Condition_NE,
+                                       1, "common_errDivideByZero");
+    move_reg_to_mem(OpndSize_32, 2, false, 12, PhysicalReg_ESP, true);
+    get_virtual_reg(v1, OpndSize_64, 1, false);
+    move_reg_to_mem(OpndSize_64, 1, false, 0, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    nextVersionOfHardReg(PhysicalReg_EDX, 2); //next version has 2 refs
+    if(isRem)
+        call_moddi3();
+    else
+        call_divdi3();
+    load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    set_virtual_reg(vA+1, OpndSize_32,PhysicalReg_EDX, true);
+    set_virtual_reg(vA, OpndSize_32, PhysicalReg_EAX, true);
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+//! lower bytecode DIV_LONG by calling common_div_rem_long
+
+//!
+int op_div_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_div_rem_long(false, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode REM_LONG by calling common_div_rem_long
+
+//!
+int op_rem_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_div_rem_long(true, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode DIV_LONG_2ADDR by calling common_div_rem_long
+
+//!
+int op_div_long_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_div_rem_long(false, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode REM_LONG_2ADDR by calling common_div_rem_long
+
+//!
+int op_rem_long_2addr() { //call __moddi3 instead of __divdi3
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_div_rem_long(true, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+
+//! common code to handle SHL long
+
+//! It uses XMM
+int common_shl_long(u2 vA, u2 v1, u2 v2) {
+    get_VR_ss(v2, 2, false);
+
+    load_global_data_API("shiftMask", OpndSize_64, 3, false);
+
+    get_virtual_reg(v1, OpndSize_64, 1, false);
+    alu_binary_reg_reg(OpndSize_64, and_opc, 3, false, 2, false);
+    alu_binary_reg_reg(OpndSize_64, sll_opc, 2, false, 1, false);
+    set_virtual_reg(vA, OpndSize_64, 1, false);
+    return 0;
+}
+
+//! common code to handle SHR long
+
+//! It uses XMM
+int common_shr_long(u2 vA, u2 v1, u2 v2) {
+    get_VR_ss(v2, 2, false);
+
+    load_global_data_API("shiftMask", OpndSize_64, 3, false);
+
+    get_virtual_reg(v1, OpndSize_64, 1, false);
+    alu_binary_reg_reg(OpndSize_64, and_opc, 3, false, 2, false);
+    alu_binary_reg_reg(OpndSize_64, srl_opc, 2, false, 1, false);
+    compare_imm_VR(OpndSize_32, 0, (v1+1));
+    conditional_jump(Condition_GE, ".common_shr_long_special", true);
+    rememberState(1);
+
+    load_global_data_API("value64", OpndSize_64, 4, false);
+
+    alu_binary_reg_reg(OpndSize_64, sub_opc, 2, false, 4, false);
+
+    load_global_data_API("64bits", OpndSize_64, 5, false);
+
+    alu_binary_reg_reg(OpndSize_64, sll_opc, 4, false, 5, false);
+    alu_binary_reg_reg(OpndSize_64, or_opc, 5, false, 1, false);
+    rememberState(2);
+    //check whether the target is next instruction TODO
+    unconditional_jump(".common_shr_long_done", true);
+
+    insertLabel(".common_shr_long_special", true);
+    goToState(1);
+    transferToState(2);
+    insertLabel(".common_shr_long_done", true);
+    set_virtual_reg(vA, OpndSize_64, 1, false);
+    return 0;
+}
+
+//! common code to handle USHR long
+
+//! It uses XMM
+int common_ushr_long(u2 vA, u2 v1, u2 v2) {
+    get_VR_sd(v1, 1, false);
+    get_VR_ss(v2, 2, false);
+
+    load_sd_global_data_API("shiftMask", 3, false);
+
+    alu_binary_reg_reg(OpndSize_64, and_opc, 3, false, 2, false);
+    alu_binary_reg_reg(OpndSize_64, srl_opc, 2, false, 1, false);
+    set_VR_sd(vA, 1, false);
+    return 0;
+}
+//! lower bytecode SHL_LONG by calling common_shl_long
+
+//!
+int op_shl_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_shl_long(vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SHL_LONG_2ADDR by calling common_shl_long
+
+//!
+int op_shl_long_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_shl_long(vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode SHR_LONG by calling common_shr_long
+
+//!
+int op_shr_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_shr_long(vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SHR_LONG_2ADDR by calling common_shr_long
+
+//!
+int op_shr_long_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_shr_long(vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode USHR_LONG by calling common_ushr_long
+
+//!
+int op_ushr_long() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_ushr_long(vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode USHR_LONG_2ADDR by calling common_ushr_long
+
+//!
+int op_ushr_long_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_ushr_long(vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+#define USE_MEM_OPERAND
+///////////////////////////////////////////
+//! common code to handle ALU of floats
+
+//! It uses XMM
+int common_alu_float(ALU_Opcode opc, u2 vA, u2 v1, u2 v2) {//add, sub, mul
+    get_VR_ss(v1, 1, false);
+#ifdef USE_MEM_OPERAND
+    alu_sd_binary_VR_reg(opc, v2, 1, false, false/*isSD*/);
+#else
+    get_VR_ss(v2, 2, false);
+    alu_ss_binary_reg_reg(opc, 2, false, 1, false);
+#endif
+    set_VR_ss(vA, 1, false);
+    return 0;
+}
+//! lower bytecode ADD_FLOAT by calling common_alu_float
+
+//!
+int op_add_float() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_float(add_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SUB_FLOAT by calling common_alu_float
+
+//!
+int op_sub_float() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_float(sub_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode MUL_FLOAT by calling common_alu_float
+
+//!
+int op_mul_float() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_float(mul_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode ADD_FLOAT_2ADDR by calling common_alu_float
+
+//!
+int op_add_float_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_float(add_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode SUB_FLOAT_2ADDR by calling common_alu_float
+
+//!
+int op_sub_float_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_float(sub_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode MUL_FLOAT_2ADDR by calling common_alu_float
+
+//!
+int op_mul_float_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_float(mul_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! common code to handle DIV of float
+
+//! It uses FP stack
+int common_div_float(u2 vA, u2 v1, u2 v2) {
+    load_fp_stack_VR(OpndSize_32, v1); //flds
+    fpu_VR(div_opc, OpndSize_32, v2);
+    store_fp_stack_VR(true, OpndSize_32, vA); //fstps
+    return 0;
+}
+//! lower bytecode DIV_FLOAT by calling common_div_float
+
+//!
+int op_div_float() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_float(div_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode DIV_FLOAT_2ADDR by calling common_div_float
+
+//!
+int op_div_float_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_float(div_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! common code to handle DIV of double
+
+//! It uses XMM
+int common_alu_double(ALU_Opcode opc, u2 vA, u2 v1, u2 v2) {//add, sub, mul
+    get_VR_sd(v1, 1, false);
+#ifdef USE_MEM_OPERAND
+    alu_sd_binary_VR_reg(opc, v2, 1, false, true /*isSD*/);
+#else
+    get_VR_sd(v2, 2, false);
+    alu_sd_binary_reg_reg(opc, 2, false, 1, false);
+#endif
+    set_VR_sd(vA, 1, false);
+    return 0;
+}
+//! lower bytecode ADD_DOUBLE by calling common_alu_double
+
+//!
+int op_add_double() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_double(add_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SUB_DOUBLE by calling common_alu_double
+
+//!
+int op_sub_double() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_double(sub_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode MUL_DOUBLE by calling common_alu_double
+
+//!
+int op_mul_double() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_double(mul_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode ADD_DOUBLE_2ADDR by calling common_alu_double
+
+//!
+int op_add_double_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_double(add_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode SUB_DOUBLE_2ADDR by calling common_alu_double
+
+//!
+int op_sub_double_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_double(sub_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode MUL_DOUBLE_2ADDR by calling common_alu_double
+
+//!
+int op_mul_double_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_double(mul_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! common code to handle DIV of double
+
+//! It uses FP stack
+int common_div_double(u2 vA, u2 v1, u2 v2) {
+    load_fp_stack_VR(OpndSize_64, v1); //fldl
+    fpu_VR(div_opc, OpndSize_64, v2); //fdivl
+    store_fp_stack_VR(true, OpndSize_64, vA); //fstpl
+    return 0;
+}
+//! lower bytecode DIV_DOUBLE by calling common_div_double
+
+//!
+int op_div_double() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_alu_double(div_opc, vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode DIV_DOUBLE_2ADDR by calling common_div_double
+
+//!
+int op_div_double_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_alu_double(div_opc, vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+//! common code to handle REM of float
+
+//! It uses GPR & calls call_fmodf
+int common_rem_float(u2 vA, u2 v1, u2 v2) {
+    get_virtual_reg(v1, OpndSize_32, 1, false);
+    get_virtual_reg(v2, OpndSize_32, 2, false);
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 1, false, 0, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 2, false, 4, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    call_fmodf(); //(float x, float y) return float
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    store_fp_stack_VR(true, OpndSize_32, vA); //fstps
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+//! lower bytecode REM_FLOAT by calling common_rem_float
+
+//!
+int op_rem_float() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_rem_float(vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode REM_FLOAT_2ADDR by calling common_rem_float
+
+//!
+int op_rem_float_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_rem_float(vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! common code to handle REM of double
+
+//! It uses XMM & calls call_fmod
+int common_rem_double(u2 vA, u2 v1, u2 v2) {
+    get_virtual_reg(v1, OpndSize_64, 1, false);
+    get_virtual_reg(v2, OpndSize_64, 2, false);
+    load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_64, 1, false, 0, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_64, 2, false, 8, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    call_fmod(); //(long double x, long double y) return double
+    load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    store_fp_stack_VR(true, OpndSize_64, vA); //fstpl
+    return 0;
+}
+//! lower bytecode REM_DOUBLE by calling common_rem_double
+
+//!
+int op_rem_double() {
+    u2 vA = INST_AA(inst);
+    u2 v1 = *((u1*)rPC + 2);
+    u2 v2 = *((u1*)rPC + 3);
+    int retval = common_rem_double(vA, v1, v2);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode REM_DOUBLE_2ADDR by calling common_rem_double
+
+//!
+int op_rem_double_2addr() {
+    u2 vA = INST_A(inst);
+    u2 v1 = vA;
+    u2 v2 = INST_B(inst);
+    int retval = common_rem_double(vA, v1, v2);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode CMPL_FLOAT
+
+//!
+int op_cmpl_float() {
+    u2 vA = INST_AA(inst);
+    u4 v1 = FETCH(1) & 0xff;
+    u4 v2 = FETCH(1) >> 8;
+    get_VR_ss(v1, 1, false); //xmm
+    move_imm_to_reg(OpndSize_32, 0, 1, false);
+    move_imm_to_reg(OpndSize_32, 1, 2, false);
+    move_imm_to_reg(OpndSize_32, 0xffffffff, 3, false);
+    compare_VR_ss_reg(v2, 1, false);
+    //default: 0xffffffff??
+    move_imm_to_reg(OpndSize_32,
+                                 0xffffffff, 4, false);
+    //ORDER of cmov matters !!! (Z,P,A)
+    //finalNaN: unordered 0xffffffff
+    conditional_move_reg_to_reg(OpndSize_32, Condition_Z,
+                                             1, false, 4, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_P,
+                                             3, false, 4, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_A,
+                                             2, false, 4, false);
+    set_virtual_reg(vA, OpndSize_32, 4, false);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode CMPG_FLOAT
+
+//!
+int op_cmpg_float() {
+    u2 vA = INST_AA(inst);
+    u4 v1 = FETCH(1) & 0xff;
+    u4 v2 = FETCH(1) >> 8;
+    get_VR_ss(v1, 1, false);
+    compare_VR_ss_reg(v2, 1, false);
+    move_imm_to_reg(OpndSize_32, 0, 1, false);
+    move_imm_to_reg(OpndSize_32, 1, 2, false);
+    //default: 0xffffffff??
+    move_imm_to_reg(OpndSize_32, 0xffffffff, 3, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_Z,
+                                1, false, 3, false);
+    //finalNaN: unordered
+    conditional_move_reg_to_reg(OpndSize_32, Condition_P,
+                                2, false, 3, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_A,
+                                2, false, 3, false);
+    set_virtual_reg(vA, OpndSize_32, 3, false);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode CMPL_DOUBLE
+
+//!
+int op_cmpl_double() {
+    u2 vA = INST_AA(inst);
+    u4 v1 = FETCH(1) & 0xff;
+    u4 v2 = FETCH(1) >> 8;
+    get_VR_sd(v1, 1, false);
+    compare_VR_sd_reg(v2, 1, false);
+    move_imm_to_reg(OpndSize_32, 0, 1, false);
+    move_imm_to_reg(OpndSize_32, 1, 2, false);
+    move_imm_to_reg(OpndSize_32, 0xffffffff, 3, false);
+
+    //default: 0xffffffff??
+    move_imm_to_reg(OpndSize_32, 0xffffffff, 4, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_Z,
+                                             1, false, 4, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_P,
+                                             3, false, 4, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_A,
+                                             2, false, 4, false);
+    set_virtual_reg(vA, OpndSize_32, 4, false);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode CMPG_DOUBLE
+
+//!
+int op_cmpg_double() {
+    u2 vA = INST_AA(inst);
+    u4 v1 = FETCH(1) & 0xff;
+    u4 v2 = FETCH(1) >> 8;
+    get_VR_sd(v1, 1, false);
+    compare_VR_sd_reg(v2, 1, false);
+    move_imm_to_reg(OpndSize_32, 0, 1, false);
+    move_imm_to_reg(OpndSize_32, 1, 2, false);
+
+    //default: 0xffffffff??
+    move_imm_to_reg(OpndSize_32,
+                                 0xffffffff, 3, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_Z,
+                                             1, false, 3, false);
+    //finalNaN: unordered
+    conditional_move_reg_to_reg(OpndSize_32, Condition_P,
+                                             2, false, 3, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_A,
+                                             2, false, 3, false);
+   set_virtual_reg(vA, OpndSize_32, 3, false);
+    rPC += 2;
+    return 0;
+}
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_ESI
+#define P_SCRATCH_1 PhysicalReg_EDX
+#define P_SCRATCH_2 PhysicalReg_EAX
+#define OPTION_OLD //for simpler cfg
+//! lower bytecode CMP_LONG
+
+//!
+int op_cmp_long() {
+    u2 vA = INST_AA(inst);
+    u4 v1 = FETCH(1) & 0xff;
+    u4 v2 = FETCH(1) >> 8;
+    get_virtual_reg(v1+1, OpndSize_32, 2, false);
+#ifdef OPTION_OLD
+    move_imm_to_reg(OpndSize_32, 0xffffffff, 3, false);
+    move_imm_to_reg(OpndSize_32, 1, 4, false);
+    move_imm_to_reg(OpndSize_32, 0, 5, false);
+#endif
+    compare_VR_reg(OpndSize_32,
+                                v2+1, 2, false);
+#ifndef OPTION_OLD
+    conditional_jump(Condition_L, ".cmp_long_less", true);
+    conditional_jump(Condition_G, ".cmp_long_greater", true);
+#else
+    conditional_jump(Condition_E, ".cmp_long_equal", true);
+    rememberState(1);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_L, //below vs less
+                                             3, false, 6, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_G, //above vs greater
+                                             4, false, 6, false);
+    set_virtual_reg(vA, OpndSize_32, 6, false);
+    rememberState(2);
+    unconditional_jump(".cmp_long_okay", true);
+    insertLabel(".cmp_long_equal", true);
+    goToState(1);
+#endif
+
+    get_virtual_reg(v1, OpndSize_32, 1, false);
+    compare_VR_reg(OpndSize_32,
+                                v2, 1, false);
+#ifdef OPTION_OLD
+    conditional_move_reg_to_reg(OpndSize_32, Condition_E,
+                                             5, false, 6, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_B, //below vs less
+                                             3, false, 6, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_A, //above vs greater
+                                             4, false, 6, false);
+    set_virtual_reg(vA, OpndSize_32, 6, false);
+    transferToState(2);
+#else
+    conditional_jump(Condition_A, ".cmp_long_greater", true);
+    conditional_jump(Condition_NE, ".cmp_long_less", true);
+    set_VR_to_imm(vA, OpndSize_32, 0);
+    unconditional_jump(".cmp_long_okay", true);
+
+    insertLabel(".cmp_long_less", true);
+    set_VR_to_imm(vA, OpndSize_32, 0xffffffff);
+    unconditional_jump(".cmp_long_okay", true);
+
+    insertLabel(".cmp_long_greater", true);
+    set_VR_to_imm(vA, OpndSize_32, 1);
+#endif
+    insertLabel(".cmp_long_okay", true);
+    rPC += 2;
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
diff --git a/vm/compiler/codegen/x86/LowerConst.cpp b/vm/compiler/codegen/x86/LowerConst.cpp
new file mode 100644
index 0000000..62e0ed1
--- /dev/null
+++ b/vm/compiler/codegen/x86/LowerConst.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file LowerConst.cpp
+    \brief This file lowers the following bytecodes: CONST_XXX
+
+    Functions are called from the lowered native sequence:
+    1> const_string_resolve
+       INPUT: const pool index in %eax
+       OUTPUT: resolved string in %eax
+       The only register that is still live after this function is ebx
+    2> class_resolve
+       INPUT: const pool index in %eax
+       OUTPUT: resolved class in %eax
+       The only register that is still live after this function is ebx
+*/
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "NcgAot.h"
+#include "enc_wrapper.h"
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+
+//! LOWER bytecode CONST_STRING without usage of helper function
+
+//! It calls const_string_resolve (%ebx is live across the call)
+//! Since the register allocator does not handle control flow within the lowered native sequence,
+//!   we define an interface between the lowering module and register allocator:
+//!     rememberState, gotoState, transferToState
+//!   to make sure at the control flow merge point the state of registers is the same
+int const_string_common_nohelper(u4 tmp, u2 vA) {
+    /* for trace-based JIT, the string is already resolved since this code has been executed */
+    void *strPtr = (void*)
+              (currentMethod->clazz->pDvmDex->pResStrings[tmp]);
+    assert(strPtr != NULL);
+    set_VR_to_imm(vA, OpndSize_32, (int) strPtr );
+    return 0;
+}
+//! dispatcher to select either const_string_common_helper or const_string_common_nohelper
+
+//!
+int const_string_common(u4 tmp, u2 vA) {
+    return const_string_common_nohelper(tmp, vA);
+}
+#undef P_GPR_1
+#undef P_GPR_2
+
+//! lower bytecode CONST_4
+
+//!
+int op_const_4() {
+    u2 vA = INST_A(inst);
+    s4 tmp = (s4) (INST_B(inst) << 28) >> 28;
+    set_VR_to_imm(vA, OpndSize_32, tmp);
+    rPC += 1;
+    return 1;
+}
+//! lower bytecode CONST_16
+
+//!
+int op_const_16() {
+    u2 BBBB = FETCH(1);
+    u2 vA = INST_AA(inst);
+    set_VR_to_imm(vA, OpndSize_32, (s2)BBBB);
+    rPC += 2;
+    return 1;
+}
+//! lower bytecode CONST
+
+//!
+int op_const() {
+    u2 vA = INST_AA(inst);
+    u4 tmp = FETCH(1);
+    tmp |= (u4)FETCH(2) << 16;
+    set_VR_to_imm(vA, OpndSize_32, (s4)tmp);
+    rPC += 3;
+    return 1;
+}
+//! lower bytecode CONST_HIGH16
+
+//!
+int op_const_high16() {
+    u2 vA = INST_AA(inst);
+    u2 tmp = FETCH(1);
+    set_VR_to_imm(vA, OpndSize_32, (s4)tmp<<16); //??
+    rPC += 2;
+    return 1;
+}
+//! lower bytecode CONST_WIDE_16
+
+//!
+int op_const_wide_16() {
+    u2 vA = INST_AA(inst);
+    u2 tmp = FETCH(1);
+    set_VR_to_imm(vA, OpndSize_32, (s2)tmp);
+    set_VR_to_imm(vA+1, OpndSize_32, (s2)tmp>>31);
+    rPC += 2;
+    return 2;
+}
+//! lower bytecode CONST_WIDE_32
+
+//!
+int op_const_wide_32() {
+    u2 vA = INST_AA(inst);
+    u4 tmp = FETCH(1);
+    tmp |= (u4)FETCH(2) << 16;
+    set_VR_to_imm(vA, OpndSize_32, (s4)tmp);
+    set_VR_to_imm(vA+1, OpndSize_32, (s4)tmp>>31);
+    rPC += 3;
+    return 2;
+}
+//! lower bytecode CONST_WIDE
+
+//!
+int op_const_wide() {
+    u2 vA = INST_AA(inst);
+    u4 tmp = FETCH(1);
+    tmp |= (u8)FETCH(2) << 16;
+    set_VR_to_imm(vA, OpndSize_32, (s4)tmp);
+    tmp = (u8)FETCH(3);
+    tmp |= (u8)FETCH(4) << 16;
+    set_VR_to_imm(vA+1, OpndSize_32, (s4)tmp);
+    rPC += 5;
+    return 2;
+}
+//! lower bytecode CONST_WIDE_HIGH16
+
+//!
+int op_const_wide_high16() {
+    u2 vA = INST_AA(inst);
+    u2 tmp = FETCH(1);
+    set_VR_to_imm(vA, OpndSize_32, 0);
+    set_VR_to_imm(vA+1, OpndSize_32, (s4)tmp<<16);
+    rPC += 2;
+    return 2;
+}
+//! lower bytecode CONST_STRING
+
+//!
+int op_const_string() {
+    u2 vB = FETCH(1);
+    u2 vA = INST_AA(inst);
+    u4 tmp = vB;
+    int retval = const_string_common(tmp, vA);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode CONST_STRING_JUMBO
+
+//!
+int op_const_string_jumbo() {
+    u2 vA = INST_AA(inst);
+    u4 tmp = FETCH(1);
+    tmp |= (u4)FETCH(2) << 16;
+    int retval = const_string_common(tmp, vA);
+    rPC += 3;
+    return retval;
+}
+
+#define P_GPR_1 PhysicalReg_EBX
+//! LOWER bytecode CONST_CLASS
+
+//! It calls class_resolve (%ebx is live across the call)
+//! Since the register allocator does not handle control flow within the lowered native sequence,
+//!   we define an interface between the lowering module and register allocator:
+//!     rememberState, gotoState, transferToState
+//!   to make sure at the control flow merge point the state of registers is the same
+int op_const_class() {
+    u2 vA = INST_AA(inst);
+    u4 tmp = (u4)FETCH(1);
+    /* for trace-based JIT, the class is already resolved since this code has been executed */
+    void *classPtr = (void*)
+       (currentMethod->clazz->pDvmDex->pResClasses[tmp]);
+    assert(classPtr != NULL);
+    set_VR_to_imm(vA, OpndSize_32, (int) classPtr );
+    rPC += 2;
+    return 0;
+}
+
+#undef P_GPR_1
+
diff --git a/vm/compiler/codegen/x86/LowerGetPut.cpp b/vm/compiler/codegen/x86/LowerGetPut.cpp
new file mode 100644
index 0000000..c87b174
--- /dev/null
+++ b/vm/compiler/codegen/x86/LowerGetPut.cpp
@@ -0,0 +1,933 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file LowerGetPut.cpp
+    \brief This file lowers the following bytecodes: XGET|PUT_XXX
+*/
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "NcgAot.h"
+#include "enc_wrapper.h"
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_ESI
+#define P_GPR_4 PhysicalReg_EDX
+//! LOWER bytecode AGET without usage of helper function
+
+//! It has null check and length check
+int aget_common_nohelper(int flag, u2 vA, u2 vref, u2 vindex) {
+    ////////////////////////////
+    // Request VR free delays before register allocation for the temporaries
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_NULL_CHECK))
+        requestVRFreeDelay(vref,VRDELAY_NULLCHECK);
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+        requestVRFreeDelay(vref,VRDELAY_BOUNDCHECK);
+        requestVRFreeDelay(vindex,VRDELAY_BOUNDCHECK);
+    }
+
+    get_virtual_reg(vref, OpndSize_32, 1, false); //array
+    get_virtual_reg(vindex, OpndSize_32, 2, false); //index
+
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_NULL_CHECK)) {
+        //last argument is the exception number for this bytecode
+        nullCheck(1, false, 1, vref); //maybe optimized away, if not, call
+        cancelVRFreeDelayRequest(vref,VRDELAY_NULLCHECK);
+    } else {
+        updateRefCount2(1, LowOpndRegType_gp, false); //update reference count for tmp1
+    }
+
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+        boundCheck(vref, 1, false,
+                             vindex, 2, false,
+                             2);
+        cancelVRFreeDelayRequest(vref,VRDELAY_BOUNDCHECK);
+        cancelVRFreeDelayRequest(vindex,VRDELAY_BOUNDCHECK);
+    } else {
+        updateRefCount2(1, LowOpndRegType_gp, false); //update reference count for tmp1
+        updateRefCount2(2, LowOpndRegType_gp, false); //update reference count for tmp2
+    }
+
+    if(flag == AGET) {
+        move_mem_disp_scale_to_reg(OpndSize_32, 1, false, offArrayObject_contents, 2, false, 4, 4, false);
+    }
+    else if(flag == AGET_WIDE) {
+        move_mem_disp_scale_to_reg(OpndSize_64, 1, false, offArrayObject_contents, 2, false, 8, 1, false);
+    }
+    else if(flag == AGET_CHAR) {
+        movez_mem_disp_scale_to_reg(OpndSize_16, 1, false, offArrayObject_contents, 2, false, 2, 4, false);
+    }
+    else if(flag == AGET_SHORT) {
+        moves_mem_disp_scale_to_reg(OpndSize_16, 1, false, offArrayObject_contents, 2, false, 2, 4, false);
+    }
+    else if(flag == AGET_BOOLEAN) {
+        movez_mem_disp_scale_to_reg(OpndSize_8, 1, false, offArrayObject_contents, 2, false, 1, 4, false);
+    }
+    else if(flag == AGET_BYTE) {
+        moves_mem_disp_scale_to_reg(OpndSize_8, 1, false, offArrayObject_contents, 2, false, 1, 4, false);
+    }
+    if(flag == AGET_WIDE) {
+        set_virtual_reg(vA, OpndSize_64, 1, false);
+    }
+    else {
+        set_virtual_reg(vA, OpndSize_32, 4, false);
+    }
+    //////////////////////////////////
+    return 0;
+}
+//! wrapper to call either aget_common_helper or aget_common_nohelper
+
+//!
+int aget_common(int flag, u2 vA, u2 vref, u2 vindex) {
+    return aget_common_nohelper(flag, vA, vref, vindex);
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef P_GPR_4
+//! lower bytecode AGET by calling aget_common
+
+//!
+int op_aget() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aget_common(AGET, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode AGET_WIDE by calling aget_common
+
+//!
+int op_aget_wide() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aget_common(AGET_WIDE, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode AGET_OBJECT by calling aget_common
+
+//!
+int op_aget_object() {
+    return op_aget();
+}
+//! lower bytecode BOOLEAN by calling aget_common
+
+//!
+int op_aget_boolean() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aget_common(AGET_BOOLEAN, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode AGET_BYTE by calling aget_common
+
+//!
+int op_aget_byte() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aget_common(AGET_BYTE, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode AGET_CHAR by calling aget_common
+
+//!
+int op_aget_char() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aget_common(AGET_CHAR, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode AGET_SHORT by calling aget_common
+
+//!
+int op_aget_short() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aget_common(AGET_SHORT, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_ESI
+#define P_GPR_4 PhysicalReg_EDX
+//! LOWER bytecode APUT without usage of helper function
+
+//! It has null check and length check
+int aput_common_nohelper(int flag, u2 vA, u2 vref, u2 vindex) {
+    //////////////////////////////////////
+    // Request VR free delays before register allocation for the temporaries.
+    // No need to request delay for vA since it will be transferred to temporary
+    // after the null check and bound check.
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_NULL_CHECK))
+        requestVRFreeDelay(vref,VRDELAY_NULLCHECK);
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+        requestVRFreeDelay(vref,VRDELAY_BOUNDCHECK);
+        requestVRFreeDelay(vindex,VRDELAY_BOUNDCHECK);
+    }
+
+    get_virtual_reg(vref, OpndSize_32, 1, false); //array
+    get_virtual_reg(vindex, OpndSize_32, 2, false); //index
+
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_NULL_CHECK)) {
+        //last argument is the exception number for this bytecode
+        nullCheck(1, false, 1, vref); //maybe optimized away, if not, call
+        cancelVRFreeDelayRequest(vref,VRDELAY_NULLCHECK);
+    } else {
+        updateRefCount2(1, LowOpndRegType_gp, false); //update reference count for tmp1
+    }
+
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+        boundCheck(vref, 1, false,
+                             vindex, 2, false,
+                             2);
+        cancelVRFreeDelayRequest(vref,VRDELAY_BOUNDCHECK);
+        cancelVRFreeDelayRequest(vindex,VRDELAY_BOUNDCHECK);
+    } else {
+        updateRefCount2(1, LowOpndRegType_gp, false); //update reference count for tmp1
+        updateRefCount2(2, LowOpndRegType_gp, false); //update reference count for tmp2
+    }
+
+    if(flag == APUT_WIDE) {
+        get_virtual_reg(vA, OpndSize_64, 1, false);
+    }
+    else {
+        get_virtual_reg(vA, OpndSize_32, 4, false);
+    }
+    if(flag == APUT)
+        move_reg_to_mem_disp_scale(OpndSize_32, 4, false, 1, false, offArrayObject_contents, 2, false, 4);
+    else if(flag == APUT_WIDE)
+        move_reg_to_mem_disp_scale(OpndSize_64, 1, false, 1, false, offArrayObject_contents, 2, false, 8);
+    else if(flag == APUT_CHAR || flag == APUT_SHORT)
+        move_reg_to_mem_disp_scale(OpndSize_16, 4, false, 1, false, offArrayObject_contents, 2, false, 2);
+    else if(flag == APUT_BOOLEAN || flag == APUT_BYTE)
+        move_reg_to_mem_disp_scale(OpndSize_8, 4, false, 1, false, offArrayObject_contents, 2, false, 1);
+    //////////////////////////////////
+    return 0;
+}
+//! wrapper to call either aput_common_helper or aput_common_nohelper
+
+//!
+int aput_common(int flag, u2 vA, u2 vref, u2 vindex) {
+    return aput_common_nohelper(flag, vA, vref, vindex);
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef P_GPR_4
+//! lower bytecode APUT by calling aput_common
+
+//!
+int op_aput() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aput_common(APUT, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode APUT_WIDE by calling aput_common
+
+//!
+int op_aput_wide() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aput_common(APUT_WIDE, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode APUT_BOOLEAN by calling aput_common
+
+//!
+int op_aput_boolean() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aput_common(APUT_BOOLEAN, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode APUT_BYTE by calling aput_common
+
+//!
+int op_aput_byte() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aput_common(APUT_BYTE, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode APUT_CHAR by calling aput_common
+
+//!
+int op_aput_char() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aput_common(APUT_CHAR, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode APUT_SHORT by calling aput_common
+
+//!
+int op_aput_short() {
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+    int retval = aput_common(APUT_SHORT, vA, vref, vindex);
+    rPC += 2;
+    return retval;
+}
+
+#define P_GPR_1 PhysicalReg_EBX //callee-saved valid after CanPutArray
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_ESI //callee-saved
+#define P_SCRATCH_1 PhysicalReg_EDX
+#define P_SCRATCH_2 PhysicalReg_EAX
+#define P_SCRATCH_3 PhysicalReg_EDX
+
+void markCard_notNull(int tgtAddrReg, int scratchReg, bool isPhysical);
+
+//! lower bytecode APUT_OBJECT
+
+//! Lower the bytecode using helper function ".aput_obj_helper" if helper switch is on
+int op_aput_object() { //type checking
+    u2 vA = INST_AA(inst);
+    u2 vref = FETCH(1) & 0xff;
+    u2 vindex = FETCH(1) >> 8;
+
+    ///////////////////////////
+    // Request VR free delays before register allocation for the temporaries
+    // No need to request delay for vA since it will be transferred to temporary
+    // after the null check and bound check.
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_NULL_CHECK))
+        requestVRFreeDelay(vref,VRDELAY_NULLCHECK);
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+        requestVRFreeDelay(vref,VRDELAY_BOUNDCHECK);
+        requestVRFreeDelay(vindex,VRDELAY_BOUNDCHECK);
+    }
+
+    get_virtual_reg(vref, OpndSize_32, 1, false); //array
+    export_pc(); //use %edx
+
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_NULL_CHECK)) {
+        compare_imm_reg(OpndSize_32, 0, 1, false);
+        conditional_jump_global_API(Condition_E, "common_errNullObject", false);
+        cancelVRFreeDelayRequest(vref,VRDELAY_NULLCHECK);
+    } else {
+        updateRefCount2(1, LowOpndRegType_gp, false); //update reference count for tmp1
+    }
+
+    get_virtual_reg(vindex, OpndSize_32, 2, false); //index
+    if(!(traceCurrentMIR->OptimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+        compare_mem_reg(OpndSize_32, offArrayObject_length, 1, false, 2, false);
+        conditional_jump_global_API(Condition_NC, "common_errArrayIndex", false);
+        cancelVRFreeDelayRequest(vref,VRDELAY_BOUNDCHECK);
+        cancelVRFreeDelayRequest(vindex,VRDELAY_BOUNDCHECK);
+    } else {
+        updateRefCount2(1, LowOpndRegType_gp, false); //update reference count for tmp1
+        updateRefCount2(2, LowOpndRegType_gp, false); //update reference count for tmp2
+    }
+
+    get_virtual_reg(vA, OpndSize_32, 4, false);
+    compare_imm_reg(OpndSize_32, 0, 4, false);
+    conditional_jump(Condition_E, ".aput_object_skip_check", true);
+    rememberState(1);
+    move_mem_to_reg(OpndSize_32, offObject_clazz, 4, false, 5, false);
+    load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 5, false, 0, PhysicalReg_ESP, true);
+    move_mem_to_reg(OpndSize_32, offObject_clazz, 1, false, 6, false);
+    move_reg_to_mem(OpndSize_32, 6, false, 4, PhysicalReg_ESP, true);
+
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    call_dvmCanPutArrayElement(); //scratch??
+    load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump_global_API(Condition_E, "common_errArrayStore", false);
+
+    //NOTE: "2, false" is live through function call
+    move_reg_to_mem_disp_scale(OpndSize_32, 4, false, 1, false, offArrayObject_contents, 2, false, 4);
+    markCard_notNull(1, 11, false);
+    rememberState(2);
+    ////TODO NCG O1 + code cache
+    unconditional_jump(".aput_object_after_check", true);
+
+    insertLabel(".aput_object_skip_check", true);
+    goToState(1);
+    //NOTE: "2, false" is live through function call
+    move_reg_to_mem_disp_scale(OpndSize_32, 4, false, 1, false, offArrayObject_contents, 2, false, 4);
+
+    transferToState(2);
+    insertLabel(".aput_object_after_check", true);
+    ///////////////////////////////
+    rPC += 2;
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef P_SCRATCH_1
+#undef P_SCRATCH_2
+#undef P_SCRATCH_3
+
+//////////////////////////////////////////
+#define P_GPR_1 PhysicalReg_ECX
+#define P_GPR_2 PhysicalReg_EBX //should be callee-saved to avoid overwritten by inst_field_resolve
+#define P_GPR_3 PhysicalReg_ESI
+#define P_SCRATCH_1 PhysicalReg_EDX
+
+/*
+   movl offThread_cardTable(self), scratchReg
+   compare_imm_reg 0, valReg (testl valReg, valReg)
+   je .markCard_skip
+   shrl $GC_CARD_SHIFT, tgtAddrReg
+   movb %, (scratchReg, tgtAddrReg)
+   NOTE: scratchReg can be accessed with the corresponding byte
+         tgtAddrReg will be updated
+   for O1, update the corresponding reference count
+*/
+void markCard(int valReg, int tgtAddrReg, bool targetPhysical, int scratchReg, bool isPhysical) {
+   get_self_pointer(PhysicalReg_SCRATCH_6, isScratchPhysical);
+   move_mem_to_reg(OpndSize_32, offsetof(Thread, cardTable), PhysicalReg_SCRATCH_6, isScratchPhysical, scratchReg, isPhysical);
+   compare_imm_reg(OpndSize_32, 0, valReg, isPhysical);
+   conditional_jump(Condition_E, ".markCard_skip", true);
+   alu_binary_imm_reg(OpndSize_32, shr_opc, GC_CARD_SHIFT, tgtAddrReg, targetPhysical);
+   move_reg_to_mem_disp_scale(OpndSize_8, scratchReg, isPhysical, scratchReg, isPhysical, 0, tgtAddrReg, targetPhysical, 1);
+   insertLabel(".markCard_skip", true);
+}
+
+void markCard_notNull(int tgtAddrReg, int scratchReg, bool isPhysical) {
+   get_self_pointer(PhysicalReg_SCRATCH_2, isScratchPhysical);
+   move_mem_to_reg(OpndSize_32, offsetof(Thread, cardTable), PhysicalReg_SCRATCH_2, isScratchPhysical, scratchReg, isPhysical);
+   alu_binary_imm_reg(OpndSize_32, shr_opc, GC_CARD_SHIFT, tgtAddrReg, isPhysical);
+   move_reg_to_mem_disp_scale(OpndSize_8, scratchReg, isPhysical, scratchReg, isPhysical, 0, tgtAddrReg, isPhysical, 1);
+}
+
+void markCard_filled(int tgtAddrReg, bool isTgtPhysical, int scratchReg, bool isScratchPhysical) {
+   get_self_pointer(PhysicalReg_SCRATCH_2, false/*isPhysical*/);
+   move_mem_to_reg(OpndSize_32, offsetof(Thread, cardTable), PhysicalReg_SCRATCH_2, isScratchPhysical, scratchReg, isScratchPhysical);
+   alu_binary_imm_reg(OpndSize_32, shr_opc, GC_CARD_SHIFT, tgtAddrReg, isTgtPhysical);
+   move_reg_to_mem_disp_scale(OpndSize_8, scratchReg, isScratchPhysical, scratchReg, isScratchPhysical, 0, tgtAddrReg, isTgtPhysical, 1);
+}
+//! LOWER bytecode IGET,IPUT without usage of helper function
+
+//! It has null check and calls assembly function inst_field_resolve
+int iget_iput_common_nohelper(int tmp, int flag, u2 vA, u2 vB, int isObj, bool isVolatile) {
+#ifdef WITH_JIT_INLINING
+    const Method *method = (traceCurrentMIR->OptimizationFlags & MIR_CALLEE) ?
+        traceCurrentMIR->meta.calleeMethod : currentMethod;
+    InstField *pInstField = (InstField *)
+            method->clazz->pDvmDex->pResFields[tmp];
+#else
+    InstField *pInstField = (InstField *)
+            currentMethod->clazz->pDvmDex->pResFields[tmp];
+#endif
+    int fieldOffset;
+
+    assert(pInstField != NULL);
+    fieldOffset = pInstField->byteOffset;
+    move_imm_to_reg(OpndSize_32, fieldOffset, 8, false);
+    // Request VR delay before transfer to temporary. Only vB needs delay.
+    // vA will have non-zero reference count since transfer to temporary for
+    // it happens after null check, thus no delay is needed.
+    requestVRFreeDelay(vB,VRDELAY_NULLCHECK);
+    get_virtual_reg(vB, OpndSize_32, 7, false);
+    nullCheck(7, false, 2, vB); //maybe optimized away, if not, call
+    cancelVRFreeDelayRequest(vB,VRDELAY_NULLCHECK);
+    if(flag == IGET) {
+        move_mem_scale_to_reg(OpndSize_32, 7, false, 8, false, 1, 9, false);
+        set_virtual_reg(vA, OpndSize_32, 9, false);
+#ifdef DEBUG_IGET_OBJ
+        if(isObj > 0) {
+            pushAllRegs();
+            load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+            move_reg_to_mem(OpndSize_32, 9, false, 12, PhysicalReg_ESP, true); //field
+            move_reg_to_mem(OpndSize_32, 7, false, 8, PhysicalReg_ESP, true); //object
+            move_imm_to_mem(OpndSize_32, tmp, 4, PhysicalReg_ESP, true); //field
+            move_imm_to_mem(OpndSize_32, 0, 0, PhysicalReg_ESP, true); //iget
+            call_dvmDebugIgetIput();
+            load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+            popAllRegs();
+        }
+#endif
+    } else if(flag == IGET_WIDE) {
+        if(isVolatile) {
+            /* call dvmQuasiAtomicRead64(addr) */
+            load_effective_addr(fieldOffset, 7, false, 9, false);
+            move_reg_to_mem(OpndSize_32, 9, false, -4, PhysicalReg_ESP, true); //1st argument
+            load_effective_addr(-4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+            nextVersionOfHardReg(PhysicalReg_EAX, 2);
+            nextVersionOfHardReg(PhysicalReg_EDX, 2);
+            scratchRegs[0] = PhysicalReg_SCRATCH_3;
+            call_dvmQuasiAtomicRead64();
+            load_effective_addr(4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+            //memory content in %edx, %eax
+            set_virtual_reg(vA, OpndSize_32, PhysicalReg_EAX, true);
+            set_virtual_reg(vA+1, OpndSize_32, PhysicalReg_EDX, true);
+        } else {
+            move_mem_scale_to_reg(OpndSize_64, 7, false, 8, false, 1, 1, false); //access field
+            set_virtual_reg(vA, OpndSize_64, 1, false);
+        }
+    } else if(flag == IPUT) {
+        get_virtual_reg(vA, OpndSize_32, 9, false);
+        move_reg_to_mem_scale(OpndSize_32, 9, false, 7, false, 8, false, 1); //access field
+        if(isObj) {
+            markCard(9, 7, false, 11, false);
+        }
+    } else if(flag == IPUT_WIDE) {
+        get_virtual_reg(vA, OpndSize_64, 1, false);
+        if(isVolatile) {
+            /* call dvmQuasiAtomicSwap64(val, addr) */
+            load_effective_addr(fieldOffset, 7, false, 9, false);
+            move_reg_to_mem(OpndSize_32, 9, false, -4, PhysicalReg_ESP, true); //2nd argument
+            move_reg_to_mem(OpndSize_64, 1, false, -12, PhysicalReg_ESP, true); //1st argument
+            load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+            scratchRegs[0] = PhysicalReg_SCRATCH_3;
+            call_dvmQuasiAtomicSwap64();
+            load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+        }
+        else {
+            move_reg_to_mem_scale(OpndSize_64, 1, false, 7, false, 8, false, 1);
+        }
+    }
+    ///////////////////////////
+    return 0;
+}
+//! wrapper to call either iget_iput_common_helper or iget_iput_common_nohelper
+
+//!
+int iget_iput_common(int tmp, int flag, u2 vA, u2 vB, int isObj, bool isVolatile) {
+    return iget_iput_common_nohelper(tmp, flag, vA, vB, isObj, isVolatile);
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef P_SCRATCH_1
+//! lower bytecode IGET by calling iget_iput_common
+
+//!
+int op_iget() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    u2 tmp = FETCH(1);
+    int retval = iget_iput_common(tmp, IGET, vA, vB, 0, false);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode IGET_WIDE by calling iget_iput_common
+
+//!
+int op_iget_wide(bool isVolatile) {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    u2 tmp = FETCH(1);
+    int retval = iget_iput_common(tmp, IGET_WIDE, vA, vB, 0, isVolatile);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode IGET_OBJECT by calling iget_iput_common
+
+//!
+int op_iget_object() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    u2 tmp = FETCH(1);
+    int retval = iget_iput_common(tmp, IGET, vA, vB, 1, false);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode IGET_BOOLEAN by calling iget_iput_common
+
+//!
+int op_iget_boolean() {
+    return op_iget();
+}
+//! lower bytecode IGET_BYTE by calling iget_iput_common
+
+//!
+int op_iget_byte() {
+    return op_iget();
+}
+//! lower bytecode IGET_CHAR by calling iget_iput_common
+
+//!
+int op_iget_char() {
+    return op_iget();
+}
+//! lower bytecode IGET_SHORT by calling iget_iput_common
+
+//!
+int op_iget_short() {
+    return op_iget();
+}
+//! lower bytecode IPUT by calling iget_iput_common
+
+//!
+int op_iput() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    u2 tmp = FETCH(1);
+    int retval = iget_iput_common(tmp, IPUT, vA, vB, 0, false);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode IPUT_WIDE by calling iget_iput_common
+
+//!
+int op_iput_wide(bool isVolatile) {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    u2 tmp = FETCH(1);
+    int retval = iget_iput_common(tmp, IPUT_WIDE, vA, vB, 0, isVolatile);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode IPUT_OBJECT by calling iget_iput_common
+
+//!
+int op_iput_object() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    u2 tmp = FETCH(1);
+    int retval = iget_iput_common(tmp, IPUT, vA, vB, 1, false);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode IPUT_BOOLEAN by calling iget_iput_common
+
+//!
+int op_iput_boolean() {
+    return op_iput();
+}
+//! lower bytecode IPUT_BYTE by calling iget_iput_common
+
+//!
+int op_iput_byte() {
+    return op_iput();
+}
+//! lower bytecode IPUT_CHAR by calling iget_iput_common
+
+//!
+int op_iput_char() {
+    return op_iput();
+}
+//! lower bytecode IPUT_SHORT by calling iget_iput_common
+
+//!
+int op_iput_short() {
+    return op_iput();
+}
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_EDX //used by helper only
+
+//! common section to lower IGET & IPUT
+
+//! It will use helper function sget_helper if the switch is on
+int sget_sput_common(int flag, u2 vA, u2 tmp, bool isObj, bool isVolatile) {
+    //call assembly static_field_resolve
+    //no exception
+    //glue: get_res_fields
+    //hard-coded: eax (one version?)
+    //////////////////////////////////////////
+#ifdef WITH_JIT_INLINING
+    const Method *method = (traceCurrentMIR->OptimizationFlags & MIR_CALLEE) ? traceCurrentMIR->meta.calleeMethod : currentMethod;
+    void *fieldPtr = (void*)
+        (method->clazz->pDvmDex->pResFields[tmp]);
+#else
+    void *fieldPtr = (void*)
+        (currentMethod->clazz->pDvmDex->pResFields[tmp]);
+#endif
+    assert(fieldPtr != NULL);
+    move_imm_to_reg(OpndSize_32, (int)fieldPtr, PhysicalReg_EAX, true);
+    if(flag == SGET) {
+        move_mem_to_reg(OpndSize_32, offStaticField_value, PhysicalReg_EAX, true, 7, false); //access field
+        set_virtual_reg(vA, OpndSize_32, 7, false);
+    } else if(flag == SGET_WIDE) {
+        if(isVolatile) {
+            /* call dvmQuasiAtomicRead64(addr) */
+            load_effective_addr(offStaticField_value, PhysicalReg_EAX, true, 9, false);
+            move_reg_to_mem(OpndSize_32, 9, false, -4, PhysicalReg_ESP, true); //1st argument
+            load_effective_addr(-4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+            nextVersionOfHardReg(PhysicalReg_EAX, 2);
+            nextVersionOfHardReg(PhysicalReg_EDX, 2);
+            scratchRegs[0] = PhysicalReg_SCRATCH_3;
+            call_dvmQuasiAtomicRead64();
+            load_effective_addr(4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+            //memory content in %edx, %eax
+            set_virtual_reg(vA, OpndSize_32, PhysicalReg_EAX, true);
+            set_virtual_reg(vA+1, OpndSize_32, PhysicalReg_EDX, true);
+        }
+        else {
+            move_mem_to_reg(OpndSize_64, offStaticField_value, PhysicalReg_EAX, true, 1, false); //access field
+            set_virtual_reg(vA, OpndSize_64, 1, false);
+        }
+    } else if(flag == SPUT) {
+        get_virtual_reg(vA, OpndSize_32, 7, false);
+        move_reg_to_mem(OpndSize_32, 7, false, offStaticField_value, PhysicalReg_EAX, true); //access field
+        if(isObj) {
+            /* get clazz object, then use clazz object to mark card */
+            move_mem_to_reg(OpndSize_32, offField_clazz, PhysicalReg_EAX, true, 12, false);
+            markCard(7/*valReg*/, 12, false, 11, false);
+        }
+    } else if(flag == SPUT_WIDE) {
+        get_virtual_reg(vA, OpndSize_64, 1, false);
+        if(isVolatile) {
+            /* call dvmQuasiAtomicSwap64(val, addr) */
+            load_effective_addr(offStaticField_value, PhysicalReg_EAX, true, 9, false);
+            move_reg_to_mem(OpndSize_32, 9, false, -4, PhysicalReg_ESP, true); //2nd argument
+            move_reg_to_mem(OpndSize_64, 1, false, -12, PhysicalReg_ESP, true); //1st argument
+            load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+            scratchRegs[0] = PhysicalReg_SCRATCH_3;
+            call_dvmQuasiAtomicSwap64();
+            load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+        }
+        else {
+            move_reg_to_mem(OpndSize_64, 1, false, offStaticField_value, PhysicalReg_EAX, true); //access field
+        }
+    }
+    //////////////////////////////////////////////
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+//! lower bytecode SGET by calling sget_sput_common
+
+//!
+int op_sget() {
+    u2 vA = INST_AA(inst);
+    u2 tmp = FETCH(1);
+    int retval = sget_sput_common(SGET, vA, tmp, false, false);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SGET_WIDE by calling sget_sput_common
+
+//!
+int op_sget_wide(bool isVolatile) {
+    u2 vA = INST_AA(inst);
+    u2 tmp = FETCH(1);
+    int retval = sget_sput_common(SGET_WIDE, vA, tmp, false, isVolatile);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SGET_OBJECT by calling sget_sput_common
+
+//!
+int op_sget_object() {
+    return op_sget();
+}
+//! lower bytecode SGET_BOOLEAN by calling sget_sput_common
+
+//!
+int op_sget_boolean() {
+    return op_sget();
+}
+//! lower bytecode SGET_BYTE by calling sget_sput_common
+
+//!
+int op_sget_byte() {
+    return op_sget();
+}
+//! lower bytecode SGET_CHAR by calling sget_sput_common
+
+//!
+int op_sget_char() {
+    return op_sget();
+}
+//! lower bytecode SGET_SHORT by calling sget_sput_common
+
+//!
+int op_sget_short() {
+    return op_sget();
+}
+//! lower bytecode SPUT by calling sget_sput_common
+
+//!
+int op_sput(bool isObj) {
+    u2 vA = INST_AA(inst);
+    u2 tmp = FETCH(1);
+    int retval = sget_sput_common(SPUT, vA, tmp, isObj, false);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SPUT_WIDE by calling sget_sput_common
+
+//!
+int op_sput_wide(bool isVolatile) {
+    u2 vA = INST_AA(inst);
+    u2 tmp = FETCH(1);
+    int retval = sget_sput_common(SPUT_WIDE, vA, tmp, false, isVolatile);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode SPUT_OBJECT by calling sget_sput_common
+
+//!
+int op_sput_object() {
+    return op_sput(true);
+}
+//! lower bytecode SPUT_OBJECT by calling sget_sput_common
+
+//!
+int op_sput_boolean() {
+    return op_sput(false);
+}
+//! lower bytecode SPUT_BOOLEAN by calling sget_sput_common
+
+//!
+int op_sput_byte() {
+    return op_sput(false);
+}
+//! lower bytecode SPUT_BYTE by calling sget_sput_common
+
+//!
+int op_sput_char() {
+    return op_sput(false);
+}
+//! lower bytecode SPUT_SHORT by calling sget_sput_common
+
+//!
+int op_sput_short() {
+    return op_sput(false);
+}
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+//! lower bytecode IGET_QUICK
+
+//!
+int op_iget_quick() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst); //object
+    u2 tmp = FETCH(1);
+
+    requestVRFreeDelay(vB,VRDELAY_NULLCHECK); // Request VR delay before transfer to temporary
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    nullCheck(1, false, 1, vB); //maybe optimized away, if not, call
+    cancelVRFreeDelayRequest(vB,VRDELAY_NULLCHECK);
+
+    move_mem_to_reg(OpndSize_32, tmp, 1, false, 2, false);
+    set_virtual_reg(vA, OpndSize_32, 2, false);
+    rPC += 2;
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#define P_GPR_1 PhysicalReg_EBX
+//! lower bytecode IGET_WIDE_QUICK
+
+//!
+int op_iget_wide_quick() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst); //object
+    u2 tmp = FETCH(1);
+
+    requestVRFreeDelay(vB,VRDELAY_NULLCHECK); // Request VR delay before transfer to temporary
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    nullCheck(1, false, 1, vB); //maybe optimized away, if not, call
+    cancelVRFreeDelayRequest(vB,VRDELAY_NULLCHECK);
+
+    move_mem_to_reg(OpndSize_64, tmp, 1, false, 1, false);
+    set_virtual_reg(vA, OpndSize_64, 1, false);
+    rPC += 2;
+    return 0;
+}
+#undef P_GPR_1
+//! lower bytecode IGET_OBJECT_QUICK
+
+//!
+int op_iget_object_quick() {
+    return op_iget_quick();
+}
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+//! lower bytecode IPUT_QUICK
+
+//!
+int iput_quick_common(bool isObj) {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst); //object
+    u2 tmp = FETCH(1);
+
+    // Request VR delay before transfer to temporary. Only vB needs delay.
+    // vA will have non-zero reference count since transfer to temporary for
+    // it happens after null check, thus no delay is needed.
+    requestVRFreeDelay(vB,VRDELAY_NULLCHECK);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    nullCheck(1, false, 1, vB); //maybe optimized away, if not, call
+    cancelVRFreeDelayRequest(vB,VRDELAY_NULLCHECK);
+
+    get_virtual_reg(vA, OpndSize_32, 2, false);
+    move_reg_to_mem(OpndSize_32, 2, false, tmp, 1, false);
+    if(isObj) {
+        markCard(2/*valReg*/, 1, false, 11, false);
+    }
+    rPC += 2;
+    return 0;
+}
+int op_iput_quick() {
+    return iput_quick_common(false);
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#define P_GPR_1 PhysicalReg_EBX
+//! lower bytecode IPUT_WIDE_QUICK
+
+//!
+int op_iput_wide_quick() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst); //object
+    u2 tmp = FETCH(1); //byte offset
+
+    // Request VR delay before transfer to temporary. Only vB needs delay.
+    // vA will have non-zero reference count since transfer to temporary for
+    // it happens after null check, thus no delay is needed.
+    requestVRFreeDelay(vB,VRDELAY_NULLCHECK);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    nullCheck(1, false, 1, vB); //maybe optimized away, if not, call
+    cancelVRFreeDelayRequest(vB,VRDELAY_NULLCHECK);
+
+    get_virtual_reg(vA, OpndSize_64, 1, false);
+    move_reg_to_mem(OpndSize_64, 1, false, tmp, 1, false);
+    rPC += 2;
+    return 0;
+}
+#undef P_GPR_1
+//! lower bytecode IPUT_OBJECT_QUICK
+
+//!
+int op_iput_object_quick() {
+    return iput_quick_common(true);
+}
+
diff --git a/vm/compiler/codegen/x86/LowerHelper.cpp b/vm/compiler/codegen/x86/LowerHelper.cpp
new file mode 100644
index 0000000..4539064
--- /dev/null
+++ b/vm/compiler/codegen/x86/LowerHelper.cpp
@@ -0,0 +1,2992 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file LowerHelper.cpp
+    \brief This file implements helper functions for lowering
+
+With NCG O0: all registers are hard-coded ;
+With NCG O1: the lowering module will use variables that will be allocated to a physical register by the register allocator.
+
+register types: FS 32-bit or 64-bit;
+                XMM: SS(32-bit) SD (64-bit);
+                GPR: 8-bit, 16-bit, 32-bit;
+LowOpndRegType tells whether it is gpr, xmm or fs;
+OpndSize can be OpndSize_8, OpndSize_16, OpndSize_32, OpndSize_64
+
+A single native instruction can use multiple physical registers.
+  we can't call freeReg in the middle of emitting a native instruction,
+  since it may free the physical register used by an operand and cause two operands being allocated to the same physical register.
+
+When allocating a physical register for an operand, we can't spill the operands that are already allocated. To avoid that, we call startNativeCode before each native instruction, here flag "canSpill" is set to true for each physical register;
+  when a physical register is allocated, we set its flag "canSpill" to false;
+  at end of each native instruction, call endNativeCode to set flag "canSpill" to true.
+*/
+
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "NcgAot.h"
+#include "enc_wrapper.h"
+#include "vm/mterp/Mterp.h"
+#include "NcgHelper.h"
+#include <math.h>
+#include "interp/InterpState.h"
+
+extern "C" int64_t __divdi3(int64_t, int64_t);
+extern "C" int64_t __moddi3(int64_t, int64_t);
+bool isScratchPhysical;
+LowOp* lirTable[200];
+int num_lirs_in_table = 0;
+
+//4 tables are defined: GPR integer ALU ops, ALU ops in FPU, SSE 32-bit, SSE 64-bit
+//the index to the table is the opcode
+//add_opc,    or_opc,     adc_opc,    sbb_opc,
+//and_opc,    sub_opc,    xor_opc,    cmp_opc,
+//mul_opc,    imul_opc,   div_opc,    idiv_opc,
+//sll_opc,    srl_opc,    sra, (SSE)
+//shl_opc,    shr_opc,    sal_opc,    sar_opc, //integer shift
+//neg_opc,    not_opc,    andn_opc, (SSE)
+//n_alu
+//!mnemonic for integer ALU operations
+const  Mnemonic map_of_alu_opcode_2_mnemonic[] = {
+    Mnemonic_ADD,  Mnemonic_OR,   Mnemonic_ADC,  Mnemonic_SBB,
+    Mnemonic_AND,  Mnemonic_SUB,  Mnemonic_XOR,  Mnemonic_CMP,
+    Mnemonic_MUL,  Mnemonic_IMUL, Mnemonic_DIV,  Mnemonic_IDIV,
+    Mnemonic_Null, Mnemonic_Null, Mnemonic_Null,
+    Mnemonic_SHL,  Mnemonic_SHR,  Mnemonic_SAL,  Mnemonic_SAR,
+    Mnemonic_NEG,  Mnemonic_NOT,  Mnemonic_Null,
+    Mnemonic_Null
+};
+//!mnemonic for ALU operations in FPU
+const  Mnemonic map_of_fpu_opcode_2_mnemonic[] = {
+    Mnemonic_FADD,  Mnemonic_Null,  Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_Null,  Mnemonic_FSUB,  Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_FMUL,  Mnemonic_Null,  Mnemonic_FDIV,  Mnemonic_Null,
+    Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_Null,  Mnemonic_Null,  Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_Null,  Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_Null
+};
+//!mnemonic for SSE 32-bit
+const  Mnemonic map_of_sse_opcode_2_mnemonic[] = {
+    Mnemonic_ADDSD,  Mnemonic_Null,  Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_Null,   Mnemonic_SUBSD, Mnemonic_XORPD, Mnemonic_Null,
+    Mnemonic_MULSD,  Mnemonic_Null,  Mnemonic_DIVSD,  Mnemonic_Null,
+    Mnemonic_Null,   Mnemonic_Null,
+    Mnemonic_Null,   Mnemonic_Null,  Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_Null,   Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_Null
+};
+//!mnemonic for SSE 64-bit integer
+const  Mnemonic map_of_64_opcode_2_mnemonic[] = {
+    Mnemonic_PADDQ, Mnemonic_POR,   Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_PAND,  Mnemonic_PSUBQ, Mnemonic_PXOR,  Mnemonic_Null,
+    Mnemonic_Null,  Mnemonic_Null,  Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_PSLLQ, Mnemonic_PSRLQ, Mnemonic_Null,
+    Mnemonic_Null,  Mnemonic_Null,  Mnemonic_Null,  Mnemonic_Null,
+    Mnemonic_Null,  Mnemonic_Null,  Mnemonic_PANDN,
+    Mnemonic_Null
+};
+
+////////////////////////////////////////////////
+//!update fields of LowOpndReg
+
+//!
+void set_reg_opnd(LowOpndReg* op_reg, int reg, bool isPhysical, LowOpndRegType type) {
+    op_reg->regType = type;
+    if(isPhysical) {
+        op_reg->logicalReg = -1;
+        op_reg->physicalReg = reg;
+    }
+    else
+        op_reg->logicalReg = reg;
+    return;
+}
+//!update fields of LowOpndMem
+
+//!
+void set_mem_opnd(LowOpndMem* mem, int disp, int base, bool isPhysical) {
+    mem->m_disp.value = disp;
+    mem->hasScale = false;
+    mem->m_base.regType = LowOpndRegType_gp;
+    if(isPhysical) {
+        mem->m_base.logicalReg = -1;
+        mem->m_base.physicalReg = base;
+    } else {
+        mem->m_base.logicalReg = base;
+    }
+    return;
+}
+//!update fields of LowOpndMem
+
+//!
+void set_mem_opnd_scale(LowOpndMem* mem, int base, bool isPhysical, int disp, int index, bool indexPhysical, int scale) {
+    mem->hasScale = true;
+    mem->m_base.regType = LowOpndRegType_gp;
+    if(isPhysical) {
+        mem->m_base.logicalReg = -1;
+        mem->m_base.physicalReg = base;
+    } else {
+        mem->m_base.logicalReg = base;
+    }
+    if(indexPhysical) {
+        mem->m_index.logicalReg = -1;
+        mem->m_index.physicalReg = index;
+    } else {
+        mem->m_index.logicalReg = index;
+    }
+    mem->m_disp.value = disp;
+    mem->m_scale.value = scale;
+    return;
+}
+//!return either LowOpndRegType_xmm or LowOpndRegType_gp
+
+//!
+inline LowOpndRegType getTypeFromIntSize(OpndSize size) {
+    return size == OpndSize_64 ? LowOpndRegType_xmm : LowOpndRegType_gp;
+}
+
+// copied from JIT compiler
+typedef struct AtomMemBlock {
+    size_t bytesAllocated;
+    struct AtomMemBlock *next;
+    char ptr[0];
+} AtomMemBlock;
+
+#define ATOMBLOCK_DEFAULT_SIZE 4096
+AtomMemBlock *atomMemHead = NULL;
+AtomMemBlock *currentAtomMem = NULL;
+void * atomNew(size_t size) {
+    lowOpTimeStamp++; //one LowOp constructed
+    if(atomMemHead == NULL) {
+        atomMemHead = (AtomMemBlock*)malloc(sizeof(AtomMemBlock) + ATOMBLOCK_DEFAULT_SIZE);
+        if(atomMemHead == NULL) {
+            ALOGE("Memory allocation failed");
+            return NULL;
+        }
+        currentAtomMem = atomMemHead;
+        currentAtomMem->bytesAllocated = 0;
+        currentAtomMem->next = NULL;
+    }
+    size = (size + 3) & ~3;
+    if (size > ATOMBLOCK_DEFAULT_SIZE) {
+        ALOGE("Requesting %d bytes which exceed the maximal size allowed", size);
+        return NULL;
+    }
+retry:
+    if (size + currentAtomMem->bytesAllocated <= ATOMBLOCK_DEFAULT_SIZE) {
+        void *ptr;
+        ptr = &currentAtomMem->ptr[currentAtomMem->bytesAllocated];
+        return ptr;
+    }
+    if (currentAtomMem->next) {
+        currentAtomMem = currentAtomMem->next;
+        goto retry;
+    }
+    /* Time to allocate a new arena */
+    AtomMemBlock *newAtomMem = (AtomMemBlock*)malloc(sizeof(AtomMemBlock) + ATOMBLOCK_DEFAULT_SIZE);
+    if(newAtomMem == NULL) {
+        ALOGE("Memory allocation failed");
+        return NULL;
+    }
+    newAtomMem->bytesAllocated = 0;
+    newAtomMem->next = NULL;
+    currentAtomMem->next = newAtomMem;
+    currentAtomMem = newAtomMem;
+    goto retry;
+    ALOGE("atomNew requesting %d bytes", size);
+    return NULL;
+}
+
+void freeAtomMem() {
+    //LOGI("free all atom memory");
+    AtomMemBlock * tmpMem = atomMemHead;
+    while(tmpMem != NULL) {
+        tmpMem->bytesAllocated = 0;
+        tmpMem = tmpMem->next;
+    }
+    currentAtomMem = atomMemHead;
+}
+
+LowOpImm* dump_special(AtomOpCode cc, int imm) {
+    LowOpImm* op = (LowOpImm*)atomNew(sizeof(LowOpImm));
+    op->lop.opCode = Mnemonic_NULL;
+    op->lop.opCode2 = cc;
+    op->lop.opnd1.type = LowOpndType_Imm;
+    op->lop.numOperands = 1;
+    op->immOpnd.value = imm;
+    //stream = encoder_imm(m, size, imm, stream);
+    return op;
+}
+
+LowOpLabel* lower_label(Mnemonic m, OpndSize size, int imm, const char* label, bool isLocal) {
+    stream = encoder_imm(m, size, imm, stream);
+    return NULL;
+}
+
+LowOpLabel* dump_label(Mnemonic m, OpndSize size, int imm,
+               const char* label, bool isLocal) {
+    return lower_label(m, size, imm, label, isLocal);
+}
+
+LowOpNCG* dump_ncg(Mnemonic m, OpndSize size, int imm) {
+    stream = encoder_imm(m, size, imm, stream);
+    return NULL;
+}
+
+//!update fields of LowOp and generate a x86 instruction with a single immediate operand
+
+//!
+LowOpImm* lower_imm(Mnemonic m, OpndSize size, int imm, bool updateTable) {
+    stream = encoder_imm(m, size, imm, stream);
+    return NULL;
+}
+
+LowOpImm* dump_imm(Mnemonic m, OpndSize size, int imm) {
+    return lower_imm(m, size, imm, true);
+}
+
+LowOpImm* dump_imm_with_codeaddr(Mnemonic m, OpndSize size,
+               int imm, char* codePtr) {
+    encoder_imm(m, size, imm, codePtr);
+    return NULL;
+}
+
+//!update fields of LowOp and generate a x86 instruction that takes a single memory operand
+
+//!With NCG O1, we call freeReg to free up physical registers, then call registerAlloc to allocate a physical register for memory base
+LowOpMem* lower_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+               int disp, int base_reg) {
+    stream = encoder_mem(m, size, disp, base_reg, true, stream);
+    return NULL;
+}
+
+LowOpMem* dump_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+               int disp, int base_reg, bool isBasePhysical) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        freeReg(true);
+        //type of the base is gpr
+        int regAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true);
+        return lower_mem(m, m2, size, disp, regAll);
+    } else {
+        stream = encoder_mem(m, size, disp, base_reg, isBasePhysical, stream);
+        return NULL;
+    }
+}
+//!update fields of LowOp and generate a x86 instruction that takes a single reg operand
+
+//!With NCG O1, wecall freeReg to free up physical registers, then call registerAlloc to allocate a physical register for the single operand
+LowOpReg* lower_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+               int reg, LowOpndRegType type) {
+    stream = encoder_reg(m, size, reg, true, type, stream);
+    return NULL;
+}
+
+LowOpReg* dump_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+               int reg, bool isPhysical, LowOpndRegType type) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        freeReg(true);
+        if(m == Mnemonic_MUL || m == Mnemonic_IDIV) {
+            //these two instructions use eax & edx implicitly
+            touchEax();
+            touchEdx();
+        }
+        int regAll = registerAlloc(type, reg, isPhysical, true);
+        return lower_reg(m, m2, size, regAll, type);
+    } else {
+        stream = encoder_reg(m, size, reg, isPhysical, type, stream);
+        return NULL;
+    }
+}
+LowOpReg* dump_reg_noalloc(Mnemonic m, OpndSize size,
+               int reg, bool isPhysical, LowOpndRegType type) {
+    return lower_reg(m, ATOM_NORMAL, size, reg, type);
+}
+
+LowOpRegReg* lower_reg_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+                 int reg, int reg2, LowOpndRegType type) {
+    if(m == Mnemonic_FUCOMP || m == Mnemonic_FUCOM) {
+        stream = encoder_compare_fp_stack(m == Mnemonic_FUCOMP,
+                                          reg-reg2, size==OpndSize_64, stream);
+    }
+    else {
+        stream = encoder_reg_reg(m, size, reg, true, reg2, true, type, stream);
+    }
+    return NULL;
+}
+
+//!update fields of LowOp and generate a x86 instruction that takes two reg operands
+
+//Here, both registers are physical
+LowOpRegReg* dump_reg_reg_noalloc(Mnemonic m, OpndSize size,
+                           int reg, bool isPhysical,
+                           int reg2, bool isPhysical2, LowOpndRegType type) {
+    return lower_reg_reg(m, ATOM_NORMAL, size, reg, reg2, type);
+}
+
+inline bool isMnemonicMove(Mnemonic m) {
+    return (m == Mnemonic_MOV || m == Mnemonic_MOVQ ||
+            m == Mnemonic_MOVSS || m == Mnemonic_MOVSD);
+}
+//!update fields of LowOp and generate a x86 instruction that takes two reg operands
+
+//!here dst reg is already allocated to a physical reg
+//! we should not spill the physical register for dst when allocating for src
+LowOpRegReg* dump_reg_reg_noalloc_dst(Mnemonic m, OpndSize size,
+                               int reg, bool isPhysical,
+                               int reg2, bool isPhysical2, LowOpndRegType type) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        int regAll = registerAlloc(type, reg, isPhysical, true);
+        /* remove move from one register to the same register */
+        if(isMnemonicMove(m) && regAll == reg2) return NULL;
+        return lower_reg_reg(m, ATOM_NORMAL, size, regAll, reg2, type);
+    } else {
+        stream = encoder_reg_reg(m, size, reg, isPhysical, reg2, isPhysical2, type, stream);
+        return NULL;
+    }
+}
+//!update fields of LowOp and generate a x86 instruction that takes two reg operands
+
+//!here src reg is already allocated to a physical reg
+LowOpRegReg* dump_reg_reg_noalloc_src(Mnemonic m, AtomOpCode m2, OpndSize size,
+                               int reg, bool isPhysical,
+                               int reg2, bool isPhysical2, LowOpndRegType type) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        int regAll2;
+        if(isMnemonicMove(m) && checkTempReg2(reg2, type, isPhysical2, reg)) { //dst reg is logical
+            //only from get_virtual_reg_all
+            regAll2 = registerAllocMove(reg2, type, isPhysical2, reg);
+        } else {
+            regAll2 = registerAlloc(type, reg2, isPhysical2, true);
+            return lower_reg_reg(m, m2, size, reg, regAll2, type);
+        }
+    } else {
+        stream = encoder_reg_reg(m, size, reg, isPhysical, reg2, isPhysical2, type, stream);
+        return NULL;
+    }
+    return NULL;
+}
+//!update fields of LowOp and generate a x86 instruction that takes two reg operands
+
+//!
+LowOpRegReg* dump_reg_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+                   int reg, bool isPhysical,
+                   int reg2, bool isPhysical2, LowOpndRegType type) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        startNativeCode(-1, -1);
+        //reg is source if m is MOV
+        freeReg(true);
+        int regAll = registerAlloc(type, reg, isPhysical, true);
+        int regAll2;
+        LowOpRegReg* op = NULL;
+#ifdef MOVE_OPT2
+        if(isMnemonicMove(m) &&
+           ((reg != PhysicalReg_EDI && reg != PhysicalReg_ESP && reg != PhysicalReg_EBP) || (!isPhysical)) &&
+           isPhysical2 == false) { //dst reg is logical
+            //called from move_reg_to_reg
+            regAll2 = registerAllocMove(reg2, type, isPhysical2, regAll);
+        } else {
+#endif
+            donotSpillReg(regAll);
+            regAll2 = registerAlloc(type, reg2, isPhysical2, true);
+            op = lower_reg_reg(m, m2, size, regAll, regAll2, type);
+#ifdef MOVE_OPT2
+        }
+#endif
+        endNativeCode();
+        return op;
+    }
+    else {
+        stream = encoder_reg_reg(m, size, reg, isPhysical, reg2, isPhysical2, type, stream);
+    }
+    return NULL;
+}
+
+LowOpRegMem* lower_mem_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+                 int disp, int base_reg,
+                 MemoryAccessType mType, int mIndex,
+                 int reg, LowOpndRegType type, bool isMoves) {
+    if(m == Mnemonic_MOVSX) {
+        stream = encoder_moves_mem_to_reg(size, disp, base_reg, true,
+                                          reg, true, stream);
+    }
+    else if(m == Mnemonic_MOVZX) {
+        stream = encoder_movez_mem_to_reg(size, disp, base_reg, true,
+                                          reg, true, stream);
+    }
+    else {
+        stream = encoder_mem_reg(m, size, disp, base_reg, true,
+                                 reg, true, type, stream);
+    }
+    return NULL;
+}
+
+//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand
+
+//!Here, operands are already allocated to physical registers
+LowOpRegMem* dump_mem_reg_noalloc(Mnemonic m, OpndSize size,
+                           int disp, int base_reg, bool isBasePhysical,
+                           MemoryAccessType mType, int mIndex,
+                           int reg, bool isPhysical, LowOpndRegType type) {
+    return lower_mem_reg(m, ATOM_NORMAL, size, disp, base_reg, mType, mIndex, reg, type, false);
+}
+//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand
+
+//!Here, memory operand is already allocated to physical register
+LowOpRegMem* dump_mem_reg_noalloc_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+                               int disp, int base_reg, bool isBasePhysical,
+                               MemoryAccessType mType, int mIndex,
+                               int reg, bool isPhysical, LowOpndRegType type) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        int regAll = registerAlloc(type, reg, isPhysical, true);
+        return lower_mem_reg(m, m2, size, disp, base_reg, mType, mIndex, regAll, type, false);
+    } else {
+        stream = encoder_mem_reg(m, size, disp, base_reg, isBasePhysical,
+                                 reg, isPhysical, type, stream);
+    }
+    return NULL;
+}
+//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand
+
+//!
+LowOpRegMem* dump_mem_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+                   int disp, int base_reg, bool isBasePhysical,
+                   MemoryAccessType mType, int mIndex,
+                   int reg, bool isPhysical, LowOpndRegType type) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true);
+        //it is okay to use the same physical register
+        if(isMnemonicMove(m)) {
+            freeReg(true);
+        } else {
+            donotSpillReg(baseAll);
+        }
+        int regAll = registerAlloc(type, reg, isPhysical, true);
+        endNativeCode();
+        return lower_mem_reg(m, m2, size, disp, baseAll, mType, mIndex, regAll, type, false);
+    } else {
+        stream = encoder_mem_reg(m, size, disp, base_reg, isBasePhysical,
+                                 reg, isPhysical, type, stream);
+    }
+    return NULL;
+}
+//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand
+
+//!
+LowOpRegMem* dump_moves_mem_reg(Mnemonic m, OpndSize size,
+                         int disp, int base_reg, bool isBasePhysical,
+             int reg, bool isPhysical) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true);
+        donotSpillReg(baseAll);
+        int regAll = registerAlloc(LowOpndRegType_gp, reg, isPhysical, true);
+        endNativeCode();
+        return lower_mem_reg(m, ATOM_NORMAL, size, disp, baseAll, MemoryAccess_Unknown, -1,
+            regAll, LowOpndRegType_gp, true/*moves*/);
+    } else {
+        stream = encoder_moves_mem_to_reg(size, disp, base_reg, isBasePhysical, reg, isPhysical, stream);
+    }
+    return NULL;
+}
+//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand
+
+//!
+LowOpRegMem* dump_movez_mem_reg(Mnemonic m, OpndSize size,
+             int disp, int base_reg, bool isBasePhysical,
+             int reg, bool isPhysical) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true);
+        donotSpillReg(baseAll);
+        int regAll = registerAlloc(LowOpndRegType_gp, reg, isPhysical, true);
+        endNativeCode();
+        return lower_mem_reg(m, ATOM_NORMAL, size, disp, baseAll, MemoryAccess_Unknown, -1,
+            regAll, LowOpndRegType_gp, true/*moves*/);
+    } else {
+        stream = encoder_movez_mem_to_reg(size, disp, base_reg, isBasePhysical, reg, isPhysical, stream);
+    }
+    return NULL;
+}
+
+//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one reg operand
+
+//!
+LowOpRegReg* dump_movez_reg_reg(Mnemonic m, OpndSize size,
+             int reg, bool isPhysical,
+             int reg2, bool isPhysical2) {
+    LowOpRegReg* op = (LowOpRegReg*)atomNew(sizeof(LowOpRegReg));
+    op->lop.opCode = m;
+    op->lop.opnd1.size = OpndSize_32;
+    op->lop.opnd1.type = LowOpndType_Reg;
+    op->lop.opnd2.size = size;
+    op->lop.opnd2.type = LowOpndType_Reg;
+    set_reg_opnd(&(op->regOpnd1), reg2, isPhysical2, LowOpndRegType_gp);
+    set_reg_opnd(&(op->regOpnd2), reg, isPhysical, LowOpndRegType_gp);
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        startNativeCode(-1, -1);
+        //reg is source if m is MOV
+        freeReg(true);
+        int regAll = registerAlloc(LowOpndRegType_gp, reg, isPhysical, true);
+        donotSpillReg(regAll);
+        int regAll2 = registerAlloc(LowOpndRegType_gp, reg2, isPhysical2, true);
+        stream = encoder_movez_reg_to_reg(size, regAll, true, regAll2, true,
+                                          LowOpndRegType_gp, stream);
+        endNativeCode();
+    }
+    else {
+        stream = encoder_movez_reg_to_reg(size, reg, isPhysical, reg2,
+                                        isPhysical2, LowOpndRegType_gp, stream);
+    }
+    return NULL;
+}
+
+//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand
+
+//!
+LowOpRegMem* lower_mem_scale_reg(Mnemonic m, OpndSize size, int base_reg, int disp, int index_reg,
+                 int scale, int reg, LowOpndRegType type) {
+    bool isMovzs = (m == Mnemonic_MOVZX || m == Mnemonic_MOVSX);
+    if(isMovzs)
+        stream = encoder_movzs_mem_disp_scale_reg(m, size, base_reg, true, disp, index_reg, true,
+                                                  scale, reg, true, type, stream);
+    else {
+        if(disp == 0)
+            stream = encoder_mem_scale_reg(m, size, base_reg, true, index_reg, true,
+                                           scale, reg, true, type, stream);
+        else
+            stream = encoder_mem_disp_scale_reg(m, size, base_reg, true, disp, index_reg, true,
+                                                scale, reg, true, type, stream);
+    }
+    return NULL;
+}
+
+LowOpRegMem* dump_mem_scale_reg(Mnemonic m, OpndSize size,
+                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                         int reg, bool isPhysical, LowOpndRegType type) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true);
+        donotSpillReg(baseAll); //make sure index will not use the same physical reg
+        int indexAll = registerAlloc(LowOpndRegType_gp, index_reg, isIndexPhysical, true);
+        if(isMnemonicMove(m)) {
+            freeReg(true);
+            doSpillReg(baseAll); //base can be used now
+        } else {
+            donotSpillReg(indexAll);
+        }
+        bool isMovzs = (m == Mnemonic_MOVZX || m == Mnemonic_MOVSX);
+        int regAll = registerAlloc(isMovzs ? LowOpndRegType_gp : type, reg, isPhysical, true);
+        endNativeCode();
+        return lower_mem_scale_reg(m, size, baseAll, disp, indexAll, scale, regAll, type);
+    } else {
+        stream = encoder_mem_scale_reg(m, size, base_reg, isBasePhysical, index_reg,
+                                       isIndexPhysical, scale, reg, isPhysical, type, stream);
+    }
+    return NULL;
+}
+//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand
+
+//!
+LowOpMemReg* lower_reg_mem_scale(Mnemonic m, OpndSize size, int reg,
+                 int base_reg, int disp, int index_reg, int scale, LowOpndRegType type) {
+    if(disp == 0)
+        stream = encoder_reg_mem_scale(m, size, reg, true, base_reg, true,
+                                       index_reg, true, scale, type, stream);
+    else
+        stream = encoder_reg_mem_disp_scale(m, size, reg, true, base_reg, true,
+                                            disp, index_reg, true, scale, type, stream);
+    return NULL;
+}
+
+LowOpMemReg* dump_reg_mem_scale(Mnemonic m, OpndSize size,
+                         int reg, bool isPhysical,
+                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                         LowOpndRegType type) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true);
+        donotSpillReg(baseAll);
+        int indexAll = registerAlloc(LowOpndRegType_gp, index_reg, isIndexPhysical, true);
+        donotSpillReg(indexAll);
+        int regAll = registerAlloc(type, reg, isPhysical, true);
+        endNativeCode();
+        return lower_reg_mem_scale(m, size, regAll, baseAll, disp, indexAll, scale, type);
+    } else {
+        stream = encoder_reg_mem_scale(m, size, reg, isPhysical, base_reg, isBasePhysical,
+                                       index_reg, isIndexPhysical, scale, type, stream);
+    }
+    return NULL;
+}
+//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand
+
+//!Here operands are already allocated
+LowOpMemReg* lower_reg_mem(Mnemonic m, AtomOpCode m2, OpndSize size, int reg,
+                 int disp, int base_reg, MemoryAccessType mType, int mIndex,
+                 LowOpndRegType type) {
+    stream = encoder_reg_mem(m, size, reg, true, disp, base_reg, true, type, stream);
+    return NULL;
+}
+
+LowOpMemReg* dump_reg_mem_noalloc(Mnemonic m, OpndSize size,
+                           int reg, bool isPhysical,
+                           int disp, int base_reg, bool isBasePhysical,
+                           MemoryAccessType mType, int mIndex, LowOpndRegType type) {
+    return lower_reg_mem(m, ATOM_NORMAL, size, reg, disp, base_reg, mType, mIndex, type);
+}
+//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand
+
+//!
+LowOpMemReg* dump_reg_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+                   int reg, bool isPhysical,
+                   int disp, int base_reg, bool isBasePhysical,
+                   MemoryAccessType mType, int mIndex, LowOpndRegType type) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true);
+        donotSpillReg(baseAll);
+        int regAll = registerAlloc(type, reg, isPhysical, true);
+        endNativeCode();
+        return lower_reg_mem(m, m2, size, regAll, disp, baseAll, mType, mIndex, type);
+    } else {
+        stream = encoder_reg_mem(m, size, reg, isPhysical, disp, base_reg, isBasePhysical, type, stream);
+    }
+    return NULL;
+}
+//!update fields of LowOp and generate a x86 instruction that takes one immediate and one reg operand
+
+//!The reg operand is allocated already
+LowOpRegImm* lower_imm_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+                 int imm, int reg, LowOpndRegType type, bool chaining) {
+    stream = encoder_imm_reg(m, size, imm, reg, true, type, stream);
+    return NULL;
+}
+
+LowOpRegImm* dump_imm_reg_noalloc(Mnemonic m, OpndSize size,
+                           int imm, int reg, bool isPhysical, LowOpndRegType type) {
+    return lower_imm_reg(m, ATOM_NORMAL, size, imm, reg, type, false);
+}
+//!update fields of LowOp and generate a x86 instruction that takes one immediate and one reg operand
+
+//!
+LowOpRegImm* dump_imm_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+                   int imm, int reg, bool isPhysical, LowOpndRegType type, bool chaining) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        freeReg(true);
+        int regAll = registerAlloc(type, reg, isPhysical, true);
+        return lower_imm_reg(m, m2, size, imm, regAll, type, chaining);
+    } else {
+        stream = encoder_imm_reg(m, size, imm, reg, isPhysical, type, stream);
+    }
+    return NULL;
+}
+//!update fields of LowOp and generate a x86 instruction that takes one immediate and one mem operand
+
+//!The mem operand is already allocated
+LowOpMemImm* lower_imm_mem(Mnemonic m, AtomOpCode m2, OpndSize size, int imm,
+                 int disp, int base_reg, MemoryAccessType mType, int mIndex,
+                 bool chaining) {
+    stream = encoder_imm_mem(m, size, imm, disp, base_reg, true, stream);
+    return NULL;
+}
+
+LowOpMemImm* dump_imm_mem_noalloc(Mnemonic m, OpndSize size,
+                           int imm,
+                           int disp, int base_reg, bool isBasePhysical,
+                           MemoryAccessType mType, int mIndex) {
+    return lower_imm_mem(m, ATOM_NORMAL, size, imm, disp, base_reg, mType, mIndex, false);
+}
+//!update fields of LowOp and generate a x86 instruction that takes one immediate and one mem operand
+
+//!
+LowOpMemImm* dump_imm_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+                   int imm,
+                   int disp, int base_reg, bool isBasePhysical,
+                   MemoryAccessType mType, int mIndex, bool chaining) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        /* do not free register if the base is %edi, %esp, or %ebp
+           make sure dump_imm_mem will only generate a single instruction */
+        if(!isBasePhysical || (base_reg != PhysicalReg_EDI &&
+                               base_reg != PhysicalReg_ESP &&
+                               base_reg != PhysicalReg_EBP)) {
+            freeReg(true);
+        }
+        int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true);
+        return lower_imm_mem(m, m2, size, imm, disp, baseAll, mType, mIndex, chaining);
+    } else {
+        stream = encoder_imm_mem(m, size, imm, disp, base_reg, isBasePhysical, stream);
+    }
+    return NULL;
+}
+//!update fields of LowOp and generate a x86 instruction that uses the FP stack and takes one mem operand
+
+//!
+LowOpMemReg* lower_fp_mem(Mnemonic m, OpndSize size, int reg,
+                  int disp, int base_reg, MemoryAccessType mType, int mIndex) {
+    stream = encoder_fp_mem(m, size, reg, disp, base_reg, true, stream);
+    return NULL;
+}
+
+LowOpMemReg* dump_fp_mem(Mnemonic m, OpndSize size, int reg,
+                  int disp, int base_reg, bool isBasePhysical,
+                  MemoryAccessType mType, int mIndex) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        freeReg(true);
+        int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true);
+        return lower_fp_mem(m, size, reg, disp, baseAll, mType, mIndex);
+    } else {
+        stream = encoder_fp_mem(m, size, reg, disp, base_reg, isBasePhysical, stream);
+    }
+    return NULL;
+}
+//!update fields of LowOp and generate a x86 instruction that uses the FP stack and takes one mem operand
+
+//!
+LowOpRegMem* lower_mem_fp(Mnemonic m, OpndSize size, int disp, int base_reg,
+                 MemoryAccessType mType, int mIndex, int reg) {
+    stream = encoder_mem_fp(m, size, disp, base_reg, true, reg, stream);
+    return NULL;
+}
+
+LowOpRegMem* dump_mem_fp(Mnemonic m, OpndSize size,
+                  int disp, int base_reg, bool isBasePhysical,
+                  MemoryAccessType mType, int mIndex,
+                  int reg) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        freeReg(true);
+        int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true);
+        return lower_mem_fp(m, size, disp, baseAll, mType, mIndex, reg);
+    } else {
+        stream = encoder_mem_fp(m, size, disp, base_reg, isBasePhysical, reg, stream);
+    }
+    return NULL;
+}
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+//OPERAND ORDER:
+//LowOp same as EncoderBase destination first
+//parameter order of function: src first
+
+////////////////////////////////// IA32 native instructions //////////////
+//! generate a native instruction lea
+
+//!
+void load_effective_addr(int disp, int base_reg, bool isBasePhysical,
+                          int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_LEA;
+    dump_mem_reg(m, ATOM_NORMAL, OpndSize_32, disp, base_reg, isBasePhysical,
+        MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_gp);
+}
+//! generate a native instruction lea
+
+//!
+void load_effective_addr_scale(int base_reg, bool isBasePhysical,
+                int index_reg, bool isIndexPhysical, int scale,
+                int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_LEA;
+    dump_mem_scale_reg(m, OpndSize_32,
+                              base_reg, isBasePhysical, 0/*disp*/, index_reg, isIndexPhysical, scale,
+                              reg, isPhysical, LowOpndRegType_gp);
+}
+//!fldcw
+
+//!
+void load_fpu_cw(int disp, int base_reg, bool isBasePhysical) {
+    Mnemonic m = Mnemonic_FLDCW;
+    dump_mem(m, ATOM_NORMAL, OpndSize_16, disp, base_reg, isBasePhysical);
+}
+//!fnstcw
+
+//!
+void store_fpu_cw(bool checkException, int disp, int base_reg, bool isBasePhysical) {
+    assert(!checkException);
+    Mnemonic m = Mnemonic_FNSTCW;
+    dump_mem(m, ATOM_NORMAL, OpndSize_16, disp, base_reg, isBasePhysical);
+}
+//!cdq
+
+//!
+void convert_integer(OpndSize srcSize, OpndSize dstSize) { //cbw, cwd, cdq
+    assert(srcSize == OpndSize_32 && dstSize == OpndSize_64);
+    Mnemonic m = Mnemonic_CDQ;
+    dump_reg_reg(m, ATOM_NORMAL, OpndSize_32, PhysicalReg_EAX, true, PhysicalReg_EDX, true, LowOpndRegType_gp);
+}
+//!fld: load from memory (float or double) to stack
+
+//!
+void load_fp_stack(LowOp* op, OpndSize size, int disp, int base_reg, bool isBasePhysical) {//fld(s|l)
+    Mnemonic m = Mnemonic_FLD;
+    dump_mem_fp(m, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, 0); //ST0
+}
+//! fild: load from memory (int or long) to stack
+
+//!
+void load_int_fp_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical) {//fild(ll|l)
+    Mnemonic m = Mnemonic_FILD;
+    dump_mem_fp(m, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, 0); //ST0
+}
+//!fild: load from memory (absolute addr)
+
+//!
+void load_int_fp_stack_imm(OpndSize size, int imm) {//fild(ll|l)
+    return load_int_fp_stack(size, imm, PhysicalReg_Null, true);
+}
+//!fst: store from stack to memory (float or double)
+
+//!
+void store_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical) {//fst(p)(s|l)
+    Mnemonic m = pop ? Mnemonic_FSTP : Mnemonic_FST;
+    dump_fp_mem(m, size, 0, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1);
+}
+//!fist: store from stack to memory (int or long)
+
+//!
+void store_int_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical) {//fist(p)(l)
+    Mnemonic m = pop ? Mnemonic_FISTP : Mnemonic_FIST;
+    dump_fp_mem(m, size, 0, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1);
+}
+//!cmp reg, mem
+
+//!
+void compare_reg_mem(LowOp* op, OpndSize size, int reg, bool isPhysical,
+              int disp, int base_reg, bool isBasePhysical) {
+    Mnemonic m = Mnemonic_CMP;
+    dump_reg_mem(m, ATOM_NORMAL, size, reg, isPhysical, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, getTypeFromIntSize(size));
+}
+//!cmp mem, reg
+
+//!
+void compare_mem_reg(OpndSize size,
+              int disp, int base_reg, bool isBasePhysical,
+              int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_CMP;
+    dump_mem_reg(m, ATOM_NORMAL, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, reg, isPhysical, getTypeFromIntSize(size));
+}
+//! compare a VR with a temporary variable
+
+//!
+void compare_VR_reg_all(OpndSize size,
+             int vA,
+             int reg, bool isPhysical, Mnemonic m) {
+    LowOpndRegType type = getTypeFromIntSize(size);
+    LowOpndRegType pType = type;
+    if(m == Mnemonic_COMISS) {
+        size = OpndSize_32;
+        type = LowOpndRegType_ss;
+        pType = LowOpndRegType_xmm;
+    }
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        int tmpValue[2];
+        int isConst = isVirtualRegConstant(vA, type, tmpValue, true/*updateRefCount*/);
+        if(isConst == 3) {
+            if(m == Mnemonic_COMISS) {
+#ifdef DEBUG_NCG_O1
+                LOGI("VR is const and SS in compare_VR_reg");
+#endif
+                dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+                //dumpImmToMem(vA+1, OpndSize_32, 0); //CHECK necessary? will overwrite vA+1!!!
+                dump_mem_reg(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA, reg, isPhysical, pType);
+                return;
+            }
+            else if(size != OpndSize_64) {
+#ifdef DEBUG_NCG_O1
+                LOGI("VR is const and 32 bits in compare_VR_reg");
+#endif
+                dump_imm_reg(m, ATOM_NORMAL, size, tmpValue[0], reg, isPhysical, pType, false);
+                return;
+            }
+            else if(size == OpndSize_64) {
+#ifdef DEBUG_NCG_O1
+                LOGI("VR is const and 64 bits in compare_VR_reg");
+#endif
+                dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+                dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]);
+                dump_mem_reg(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true,
+                    MemoryAccess_VR, vA, reg, isPhysical, pType);
+                return;
+            }
+        }
+        if(isConst == 1) dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+        if(isConst == 2) dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]);
+        freeReg(true);
+        int regAll = checkVirtualReg(vA, type, 0/*do not update*/);
+        if(regAll != PhysicalReg_Null) { //do not spill regAll when allocating register for dst
+            startNativeCode(-1, -1);
+            donotSpillReg(regAll);
+            dump_reg_reg_noalloc_src(m, ATOM_NORMAL, size, regAll, true, reg, isPhysical, pType);
+            endNativeCode();
+        }
+        else {
+            //virtual register is not allocated to a physical register
+            dump_mem_reg_noalloc_mem(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true,
+                MemoryAccess_VR, vA, reg, isPhysical, pType);
+        }
+        updateRefCount(vA, type);
+        return;
+    } else {
+        dump_mem_reg(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true,
+            MemoryAccess_VR, vA, reg, isPhysical, pType);
+        return;
+    }
+}
+void compare_VR_reg(OpndSize size,
+             int vA,
+             int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_CMP;
+    return compare_VR_reg_all(size, vA, reg, isPhysical, m);
+}
+void compare_VR_ss_reg(int vA, int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_COMISS;
+    return compare_VR_reg_all(OpndSize_32, vA, reg, isPhysical, m);
+}
+void compare_VR_sd_reg(int vA, int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_COMISD;
+    return compare_VR_reg_all(OpndSize_64, vA, reg, isPhysical, m);
+}
+//!load VR to stack
+
+//!
+void load_fp_stack_VR_all(OpndSize size, int vB, Mnemonic m) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        //can't load from immediate to fp stack
+        int tmpValue[2];
+        int isConst = isVirtualRegConstant(vB, getTypeFromIntSize(size), tmpValue, false/*updateRefCount*/);
+        if(isConst > 0) {
+            if(size != OpndSize_64) {
+#ifdef DEBUG_NCG_O1
+                LOGI("VR is const and 32 bits in load_fp_stack");
+#endif
+                dumpImmToMem(vB, OpndSize_32, tmpValue[0]);
+            }
+            else {
+#ifdef DEBUG_NCG_O1
+                LOGI("VR is const and 64 bits in load_fp_stack_VR");
+#endif
+                if(isConst == 1 || isConst == 3) dumpImmToMem(vB, OpndSize_32, tmpValue[0]);
+                if(isConst == 2 || isConst == 3) dumpImmToMem(vB+1, OpndSize_32, tmpValue[1]);
+            }
+        }
+        else { //if VR was updated by a def of gp, a xfer point was inserted
+            //if VR was updated by a def of xmm, a xfer point was inserted
+#if 0
+            int regAll = checkVirtualReg(vB, size, 1);
+            if(regAll != PhysicalReg_Null) //dump from register to memory
+                dump_reg_mem_noalloc(m, size, regAll, true, 4*vB, PhysicalReg_FP, true,
+                    MemoryAccess_VR, vB, getTypeFromIntSize(size));
+#endif
+        }
+        dump_mem_fp(m, size, 4*vB, PhysicalReg_FP, true, MemoryAccess_VR, vB, 0);
+    } else {
+        dump_mem_fp(m, size, 4*vB, PhysicalReg_FP, true, MemoryAccess_VR, vB, 0);
+    }
+}
+//!load VR(float or double) to stack
+
+//!
+void load_fp_stack_VR(OpndSize size, int vA) {//fld(s|l)
+    Mnemonic m = Mnemonic_FLD;
+    return load_fp_stack_VR_all(size, vA, m);
+}
+//!load VR(int or long) to stack
+
+//!
+void load_int_fp_stack_VR(OpndSize size, int vA) {//fild(ll|l)
+    Mnemonic m = Mnemonic_FILD;
+    return load_fp_stack_VR_all(size, vA, m);
+}
+//!store from stack to VR (float or double)
+
+//!
+void store_fp_stack_VR(bool pop, OpndSize size, int vA) {//fst(p)(s|l)
+    Mnemonic m = pop ? Mnemonic_FSTP : Mnemonic_FST;
+    dump_fp_mem(m, size, 0, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA);
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        if(size == OpndSize_32)
+            updateVirtualReg(vA, LowOpndRegType_fs_s);
+        else
+            updateVirtualReg(vA, LowOpndRegType_fs);
+    }
+}
+//!store from stack to VR (int or long)
+
+//!
+void store_int_fp_stack_VR(bool pop, OpndSize size, int vA) {//fist(p)(l)
+    Mnemonic m = pop ? Mnemonic_FISTP : Mnemonic_FIST;
+    dump_fp_mem(m, size, 0, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA);
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        if(size == OpndSize_32)
+            updateVirtualReg(vA, LowOpndRegType_fs_s);
+        else
+            updateVirtualReg(vA, LowOpndRegType_fs);
+    }
+}
+//! ALU ops in FPU, one operand is a VR
+
+//!
+void fpu_VR(ALU_Opcode opc, OpndSize size, int vA) {
+    Mnemonic m = map_of_fpu_opcode_2_mnemonic[opc];
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        int tmpValue[2];
+        int isConst = isVirtualRegConstant(vA, getTypeFromIntSize(size), tmpValue, false/*updateRefCount*/);
+        if(isConst > 0) {
+            if(size != OpndSize_64) {
+                //allocate a register for dst
+                dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+            }
+            else {
+                if((isConst == 1 || isConst == 3) && size == OpndSize_64) {
+                    dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+                }
+                if((isConst == 2 || isConst == 3) && size == OpndSize_64) {
+                    dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]);
+                }
+            }
+        }
+        if(!isInMemory(vA, size)) {
+            ALOGE("fpu_VR");
+        }
+        dump_mem_fp(m, size, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA, 0);
+    } else {
+        dump_mem_fp(m, size, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA, 0);
+    }
+}
+//! cmp imm reg
+
+//!
+void compare_imm_reg(OpndSize size, int imm,
+              int reg, bool isPhysical) {
+    if(imm == 0) {
+        LowOpndRegType type = getTypeFromIntSize(size);
+        Mnemonic m = Mnemonic_TEST;
+        if(gDvm.executionMode == kExecutionModeNcgO1) {
+            freeReg(true);
+            int regAll = registerAlloc(type, reg, isPhysical, true);
+            lower_reg_reg(m, ATOM_NORMAL, size, regAll, regAll, type);
+        } else {
+            stream = encoder_reg_reg(m, size, reg, isPhysical, reg, isPhysical, type, stream);
+        }
+        return;
+    }
+    Mnemonic m = Mnemonic_CMP;
+    dump_imm_reg(m, ATOM_NORMAL, size, imm, reg, isPhysical, getTypeFromIntSize(size), false);
+}
+//! cmp imm mem
+
+//!
+void compare_imm_mem(OpndSize size, int imm,
+              int disp, int base_reg, bool isBasePhysical) {
+    Mnemonic m = Mnemonic_CMP;
+    dump_imm_mem(m, ATOM_NORMAL, size, imm, disp,
+                        base_reg, isBasePhysical, MemoryAccess_Unknown, -1, false);
+}
+//! cmp imm VR
+
+//!
+void compare_imm_VR(OpndSize size, int imm,
+             int vA) {
+    Mnemonic m = Mnemonic_CMP;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        if(size != OpndSize_32) ALOGE("only 32 bits supported in compare_imm_VR");
+        int tmpValue[2];
+        int isConst = isVirtualRegConstant(vA, getTypeFromIntSize(size), tmpValue, false/*updateRefCount*/);
+        if(isConst > 0) {
+            dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+        }
+        int regAll = checkVirtualReg(vA, getTypeFromIntSize(size), 0);
+        if(regAll != PhysicalReg_Null)
+            dump_imm_reg_noalloc(m, size, imm, regAll, true, LowOpndRegType_gp);
+        else
+            dump_imm_mem_noalloc(m, size, imm, 4*vA, PhysicalReg_FP, true,
+                MemoryAccess_VR, vA);
+        updateRefCount(vA, getTypeFromIntSize(size));
+    } else {
+        dump_imm_mem(m, ATOM_NORMAL, size, imm, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA, false);
+    }
+}
+//! cmp reg reg
+
+//!
+void compare_reg_reg(int reg1, bool isPhysical1,
+              int reg2, bool isPhysical2) {
+    Mnemonic m = Mnemonic_CMP;
+    dump_reg_reg(m, ATOM_NORMAL, OpndSize_32, reg1, isPhysical1, reg2, isPhysical2, LowOpndRegType_gp);
+}
+void compare_reg_reg_16(int reg1, bool isPhysical1,
+              int reg2, bool isPhysical2) {
+    Mnemonic m = Mnemonic_CMP;
+    dump_reg_reg(m, ATOM_NORMAL, OpndSize_16, reg1, isPhysical1, reg2, isPhysical2, LowOpndRegType_gp);
+}
+
+//! comiss mem reg
+
+//!SSE, XMM: comparison of floating point numbers
+void compare_ss_mem_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
+             int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_COMISS;
+    dump_mem_reg(m, ATOM_NORMAL, OpndSize_32, disp, base_reg, isBasePhysical,
+        MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_xmm);
+}
+//! comiss reg reg
+
+//!
+void compare_ss_reg_with_reg(LowOp* op, int reg1, bool isPhysical1,
+                  int reg2, bool isPhysical2) {
+    Mnemonic m = Mnemonic_COMISS;
+    dump_reg_reg(m,  ATOM_NORMAL, OpndSize_32, reg1, isPhysical1, reg2, isPhysical2, LowOpndRegType_xmm);
+}
+//! comisd mem reg
+
+//!
+void compare_sd_mem_with_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
+                  int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_COMISD;
+    dump_mem_reg(m, ATOM_NORMAL, OpndSize_64, disp, base_reg, isBasePhysical,
+        MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_xmm);
+}
+//! comisd reg reg
+
+//!
+void compare_sd_reg_with_reg(LowOp* op, int reg1, bool isPhysical1,
+                  int reg2, bool isPhysical2) {
+    Mnemonic m = Mnemonic_COMISD;
+    dump_reg_reg(m, ATOM_NORMAL, OpndSize_64, reg1, isPhysical1, reg2, isPhysical2, LowOpndRegType_xmm);
+}
+//! fucom[p]
+
+//!
+void compare_fp_stack(bool pop, int reg, bool isDouble) { //compare ST(0) with ST(reg)
+    Mnemonic m = pop ? Mnemonic_FUCOMP : Mnemonic_FUCOM;
+    lower_reg_reg(m, ATOM_NORMAL, isDouble ? OpndSize_64 : OpndSize_32,
+                  PhysicalReg_ST0+reg, PhysicalReg_ST0, LowOpndRegType_fs);
+}
+/*!
+\brief generate a single return instruction
+
+*/
+LowOp* lower_return() {
+    stream = encoder_return(stream);
+    return NULL;
+}
+
+void x86_return() {
+    lower_return();
+}
+
+//!test imm reg
+
+//!
+void test_imm_reg(OpndSize size, int imm, int reg, bool isPhysical) {
+    dump_imm_reg(Mnemonic_TEST, ATOM_NORMAL, size, imm, reg, isPhysical, getTypeFromIntSize(size), false);
+}
+//!test imm mem
+
+//!
+void test_imm_mem(OpndSize size, int imm, int disp, int reg, bool isPhysical) {
+    dump_imm_mem(Mnemonic_TEST, ATOM_NORMAL, size, imm, disp, reg, isPhysical, MemoryAccess_Unknown, -1, false);
+}
+//!alu unary op with one reg operand
+
+//!
+void alu_unary_reg(OpndSize size, ALU_Opcode opc, int reg, bool isPhysical) {
+    Mnemonic m;
+    if(size == OpndSize_64)
+        m = map_of_64_opcode_2_mnemonic[opc];
+    else
+        m = map_of_alu_opcode_2_mnemonic[opc];
+    dump_reg(m, ATOM_NORMAL_ALU, size, reg, isPhysical, getTypeFromIntSize(size));
+}
+//!alu unary op with one mem operand
+
+//!
+void alu_unary_mem(LowOp* op, OpndSize size, ALU_Opcode opc, int disp, int base_reg, bool isBasePhysical) {
+    Mnemonic m;
+    if(size == OpndSize_64)
+        m = map_of_64_opcode_2_mnemonic[opc];
+    else
+        m = map_of_alu_opcode_2_mnemonic[opc];
+    dump_mem(m, ATOM_NORMAL_ALU, size, disp, base_reg, isBasePhysical);
+}
+//!alu binary op with immediate and one mem operand
+
+//!
+void alu_binary_imm_mem(OpndSize size, ALU_Opcode opc, int imm, int disp, int base_reg, bool isBasePhysical) {
+    Mnemonic m;
+    if(size == OpndSize_64)
+        m = map_of_64_opcode_2_mnemonic[opc];
+    else
+        m = map_of_alu_opcode_2_mnemonic[opc];
+    dump_imm_mem(m, ATOM_NORMAL_ALU, size, imm, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, false);
+}
+//!alu binary op with immediate and one reg operand
+
+//!
+void alu_binary_imm_reg(OpndSize size, ALU_Opcode opc, int imm, int reg, bool isPhysical) {
+    Mnemonic m;
+    if(size == OpndSize_64)
+        m = map_of_64_opcode_2_mnemonic[opc];
+    else
+        m = map_of_alu_opcode_2_mnemonic[opc];
+    dump_imm_reg(m, ATOM_NORMAL_ALU, size, imm, reg, isPhysical, getTypeFromIntSize(size), false);
+}
+//!alu binary op with one mem operand and one reg operand
+
+//!
+void alu_binary_mem_reg(OpndSize size, ALU_Opcode opc,
+             int disp, int base_reg, bool isBasePhysical,
+             int reg, bool isPhysical) {
+    Mnemonic m;
+    if(size == OpndSize_64)
+        m = map_of_64_opcode_2_mnemonic[opc];
+    else
+        m = map_of_alu_opcode_2_mnemonic[opc];
+    dump_mem_reg(m, ATOM_NORMAL_ALU, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, reg, isPhysical, getTypeFromIntSize(size));
+}
+
+void alu_sd_binary_VR_reg(ALU_Opcode opc, int vA, int reg, bool isPhysical, bool isSD) {
+    Mnemonic m;
+    if(isSD) m = map_of_sse_opcode_2_mnemonic[opc];
+    else m = (Mnemonic)(map_of_sse_opcode_2_mnemonic[opc]+1); //from SD to SS
+    OpndSize size = isSD ? OpndSize_64 : OpndSize_32;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        LowOpndRegType type = isSD ? LowOpndRegType_xmm : LowOpndRegType_ss; //type of the mem operand
+        int tmpValue[2];
+        int isConst = isVirtualRegConstant(vA, type, tmpValue,
+                          true/*updateRefCount*/);
+        if(isConst == 3 && !isSD) {
+            //isConst can be 0 or 3, mem32, use xmm
+            dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+            dump_mem_reg(m, ATOM_NORMAL_ALU, OpndSize_32, 4*vA, PhysicalReg_FP, true,
+                       MemoryAccess_VR, vA, reg, isPhysical,
+                       LowOpndRegType_xmm);
+            return;
+        }
+        if(isConst == 3 && isSD) {
+            dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+            dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]);
+            dump_mem_reg(m, ATOM_NORMAL_ALU, OpndSize_64, 4*vA, PhysicalReg_FP, true,
+                       MemoryAccess_VR, vA, reg, isPhysical, LowOpndRegType_xmm);
+            return;
+        }
+        if(isConst == 1) dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+        if(isConst == 2) dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]);
+        freeReg(true);
+
+        int regAll = checkVirtualReg(vA, type, 0/*do not update refCount*/);
+        if(regAll != PhysicalReg_Null) {
+            startNativeCode(-1, -1); //should we use vA, type
+            //CHECK: callupdateVRAtUse
+            donotSpillReg(regAll);
+            dump_reg_reg_noalloc_src(m, ATOM_NORMAL_ALU, size, regAll, true, reg,
+                         isPhysical, LowOpndRegType_xmm);
+            endNativeCode();
+        }
+        else {
+            dump_mem_reg_noalloc_mem(m, ATOM_NORMAL_ALU, size, 4*vA, PhysicalReg_FP, true,
+                         MemoryAccess_VR, vA, reg, isPhysical, LowOpndRegType_xmm);
+        }
+        updateRefCount(vA, type);
+    }
+    else {
+        dump_mem_reg(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true,
+                    MemoryAccess_VR, vA, reg, isPhysical, LowOpndRegType_xmm);
+    }
+}
+
+//!alu binary op with a VR and one reg operand
+
+//!
+void alu_binary_VR_reg(OpndSize size, ALU_Opcode opc, int vA, int reg, bool isPhysical) {
+    Mnemonic m;
+    if(size == OpndSize_64)
+        m = map_of_64_opcode_2_mnemonic[opc];
+    else
+        m = map_of_alu_opcode_2_mnemonic[opc];
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        int tmpValue[2];
+        int isConst = isVirtualRegConstant(vA, getTypeFromIntSize(size), tmpValue,
+                          true/*updateRefCount*/);
+        if(isConst == 3 && size != OpndSize_64) {
+            //allocate a register for dst
+            dump_imm_reg(m, ATOM_NORMAL_ALU, size, tmpValue[0], reg, isPhysical,
+                       getTypeFromIntSize(size), false);
+            return;
+        }
+        if(isConst == 3 && size == OpndSize_64) {
+            dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+            dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]);
+            dump_mem_reg(m, ATOM_NORMAL_ALU, size, 4*vA, PhysicalReg_FP, true,
+                MemoryAccess_VR, vA, reg, isPhysical, getTypeFromIntSize(size));
+            return;
+        }
+        if(isConst == 1) dumpImmToMem(vA, OpndSize_32, tmpValue[0]);
+        if(isConst == 2) dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]);
+
+        freeReg(true);
+        int regAll = checkVirtualReg(vA, getTypeFromIntSize(size), 0);
+        if(regAll != PhysicalReg_Null) {
+            startNativeCode(-1, -1);
+            donotSpillReg(regAll);
+            dump_reg_reg_noalloc_src(m, ATOM_NORMAL_ALU, size, regAll, true, reg,
+                         isPhysical, getTypeFromIntSize(size));
+            endNativeCode();
+        }
+        else {
+            dump_mem_reg_noalloc_mem(m, ATOM_NORMAL_ALU, size, 4*vA, PhysicalReg_FP, true,
+                MemoryAccess_VR, vA, reg, isPhysical, getTypeFromIntSize(size));
+        }
+        updateRefCount(vA, getTypeFromIntSize(size));
+    }
+    else {
+        dump_mem_reg(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true,
+            MemoryAccess_VR, vA, reg, isPhysical, getTypeFromIntSize(size));
+    }
+}
+//!alu binary op with two reg operands
+
+//!
+void alu_binary_reg_reg(OpndSize size, ALU_Opcode opc,
+                         int reg1, bool isPhysical1,
+                         int reg2, bool isPhysical2) {
+    Mnemonic m;
+    if(size == OpndSize_64)
+        m = map_of_64_opcode_2_mnemonic[opc];
+    else
+        m = map_of_alu_opcode_2_mnemonic[opc];
+    dump_reg_reg(m, ATOM_NORMAL_ALU, size, reg1, isPhysical1, reg2, isPhysical2, getTypeFromIntSize(size));
+}
+//!alu binary op with one reg operand and one mem operand
+
+//!
+void alu_binary_reg_mem(OpndSize size, ALU_Opcode opc,
+             int reg, bool isPhysical,
+             int disp, int base_reg, bool isBasePhysical) { //destination is mem!!
+    Mnemonic m;
+    if(size == OpndSize_64)
+        m = map_of_64_opcode_2_mnemonic[opc];
+    else
+        m = map_of_alu_opcode_2_mnemonic[opc];
+    dump_reg_mem(m, ATOM_NORMAL_ALU, size, reg, isPhysical, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, getTypeFromIntSize(size));
+}
+//!FPU ops with one mem operand
+
+//!
+void fpu_mem(LowOp* op, ALU_Opcode opc, OpndSize size, int disp, int base_reg, bool isBasePhysical) {
+    Mnemonic m = map_of_fpu_opcode_2_mnemonic[opc];
+    dump_mem_fp(m, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, 0);
+}
+//!SSE 32-bit ALU
+
+//!
+void alu_ss_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical,
+                int reg2, bool isPhysical2) {
+    Mnemonic m = (Mnemonic)(map_of_sse_opcode_2_mnemonic[opc]+1); //from SD to SS
+    dump_reg_reg(m, ATOM_NORMAL_ALU, OpndSize_32, reg, isPhysical, reg2, isPhysical2, LowOpndRegType_xmm);
+}
+//!SSE 64-bit ALU
+
+//!
+void alu_sd_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical,
+                int reg2, bool isPhysical2) {
+    Mnemonic m = map_of_sse_opcode_2_mnemonic[opc];
+    dump_reg_reg(m, ATOM_NORMAL_ALU, OpndSize_64, reg, isPhysical, reg2, isPhysical2, LowOpndRegType_xmm);
+}
+//!push reg to native stack
+
+//!
+void push_reg_to_stack(OpndSize size, int reg, bool isPhysical) {
+    dump_reg(Mnemonic_PUSH, ATOM_NORMAL, size, reg, isPhysical, getTypeFromIntSize(size));
+}
+//!push mem to native stack
+
+//!
+void push_mem_to_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical) {
+    dump_mem(Mnemonic_PUSH, ATOM_NORMAL, size, disp, base_reg, isBasePhysical);
+}
+//!move from reg to memory
+
+//!
+void move_reg_to_mem(OpndSize size,
+                      int reg, bool isPhysical,
+                      int disp, int base_reg, bool isBasePhysical) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_reg_mem(m, ATOM_NORMAL, size, reg, isPhysical, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, getTypeFromIntSize(size));
+}
+//!move from reg to memory
+
+//!Operands are already allocated
+void move_reg_to_mem_noalloc(OpndSize size,
+                  int reg, bool isPhysical,
+                  int disp, int base_reg, bool isBasePhysical,
+                  MemoryAccessType mType, int mIndex) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_reg_mem_noalloc(m, size, reg, isPhysical, disp, base_reg, isBasePhysical, mType, mIndex, getTypeFromIntSize(size));
+}
+//!move from memory to reg
+
+//!
+LowOpRegMem* move_mem_to_reg(OpndSize size,
+                      int disp, int base_reg, bool isBasePhysical,
+                      int reg, bool isPhysical) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    return dump_mem_reg(m, ATOM_NORMAL, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, reg, isPhysical, getTypeFromIntSize(size));
+}
+//!move from memory to reg
+
+//!Operands are already allocated
+LowOpRegMem* move_mem_to_reg_noalloc(OpndSize size,
+                  int disp, int base_reg, bool isBasePhysical,
+                  MemoryAccessType mType, int mIndex,
+                  int reg, bool isPhysical) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    return dump_mem_reg_noalloc(m, size, disp, base_reg, isBasePhysical, mType, mIndex, reg, isPhysical, getTypeFromIntSize(size));
+}
+//!movss from memory to reg
+
+//!Operands are already allocated
+LowOpRegMem* move_ss_mem_to_reg_noalloc(int disp, int base_reg, bool isBasePhysical,
+                 MemoryAccessType mType, int mIndex,
+                 int reg, bool isPhysical) {
+    return dump_mem_reg_noalloc(Mnemonic_MOVSS, OpndSize_32, disp, base_reg, isBasePhysical, mType, mIndex, reg, isPhysical, LowOpndRegType_xmm);
+}
+//!movss from reg to memory
+
+//!Operands are already allocated
+LowOpMemReg* move_ss_reg_to_mem_noalloc(int reg, bool isPhysical,
+                 int disp, int base_reg, bool isBasePhysical,
+                 MemoryAccessType mType, int mIndex) {
+    return dump_reg_mem_noalloc(Mnemonic_MOVSS, OpndSize_32, reg, isPhysical, disp, base_reg, isBasePhysical, mType, mIndex, LowOpndRegType_xmm);
+}
+//!movzx from memory to reg
+
+//!
+void movez_mem_to_reg(OpndSize size,
+               int disp, int base_reg, bool isBasePhysical,
+               int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_MOVZX;
+    dump_movez_mem_reg(m, size, disp, base_reg, isBasePhysical, reg, isPhysical);
+}
+
+//!movzx from one reg to another reg
+
+//!
+void movez_reg_to_reg(OpndSize size,
+                      int reg, bool isPhysical,
+                      int reg2, bool isPhysical2) {
+    Mnemonic m = Mnemonic_MOVZX;
+    dump_movez_reg_reg(m, size, reg, isPhysical, reg2, isPhysical2);
+}
+
+void movez_mem_disp_scale_to_reg(OpndSize size,
+                 int base_reg, bool isBasePhysical,
+                 int disp, int index_reg, bool isIndexPhysical, int scale,
+                 int reg, bool isPhysical) {
+    dump_mem_scale_reg(Mnemonic_MOVZX, size, base_reg, isBasePhysical,
+                 disp, index_reg, isIndexPhysical, scale,
+                 reg, isPhysical, LowOpndRegType_gp);
+}
+void moves_mem_disp_scale_to_reg(OpndSize size,
+                  int base_reg, bool isBasePhysical,
+                  int disp, int index_reg, bool isIndexPhysical, int scale,
+                  int reg, bool isPhysical) {
+    dump_mem_scale_reg(Mnemonic_MOVSX, size, base_reg, isBasePhysical,
+                  disp, index_reg, isIndexPhysical, scale,
+                  reg, isPhysical, LowOpndRegType_gp);
+}
+
+//!movsx from memory to reg
+
+//!
+void moves_mem_to_reg(LowOp* op, OpndSize size,
+               int disp, int base_reg, bool isBasePhysical,
+               int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_MOVSX;
+    dump_moves_mem_reg(m, size, disp, base_reg, isBasePhysical, reg, isPhysical);
+}
+//!mov from one reg to another reg
+
+//!
+void move_reg_to_reg(OpndSize size,
+                      int reg, bool isPhysical,
+                      int reg2, bool isPhysical2) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_reg_reg(m, ATOM_NORMAL, size, reg, isPhysical, reg2, isPhysical2, getTypeFromIntSize(size));
+}
+//!mov from one reg to another reg
+
+//!Operands are already allocated
+void move_reg_to_reg_noalloc(OpndSize size,
+                  int reg, bool isPhysical,
+                  int reg2, bool isPhysical2) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_reg_reg_noalloc(m, size, reg, isPhysical, reg2, isPhysical2, getTypeFromIntSize(size));
+}
+//!move from memory to reg
+
+//!
+void move_mem_scale_to_reg(OpndSize size,
+                int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale,
+                int reg, bool isPhysical) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_mem_scale_reg(m, size, base_reg, isBasePhysical, 0/*disp*/, index_reg, isIndexPhysical, scale,
+                              reg, isPhysical, getTypeFromIntSize(size));
+}
+void move_mem_disp_scale_to_reg(OpndSize size,
+                int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                int reg, bool isPhysical) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_mem_scale_reg(m, size, base_reg, isBasePhysical, disp, index_reg, isIndexPhysical, scale,
+                              reg, isPhysical, getTypeFromIntSize(size));
+}
+//!move from reg to memory
+
+//!
+void move_reg_to_mem_scale(OpndSize size,
+                int reg, bool isPhysical,
+                int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_reg_mem_scale(m, size, reg, isPhysical,
+                              base_reg, isBasePhysical, 0/*disp*/, index_reg, isIndexPhysical, scale,
+                              getTypeFromIntSize(size));
+}
+void move_reg_to_mem_disp_scale(OpndSize size,
+                int reg, bool isPhysical,
+                int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_reg_mem_scale(m, size, reg, isPhysical,
+                              base_reg, isBasePhysical, disp, index_reg, isIndexPhysical, scale,
+                              getTypeFromIntSize(size));
+}
+
+void move_chain_to_mem(OpndSize size, int imm,
+                        int disp, int base_reg, bool isBasePhysical) {
+    dump_imm_mem(Mnemonic_MOV, ATOM_NORMAL, size, imm, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, true);
+}
+
+//!move an immediate to memory
+
+//!
+void move_imm_to_mem(OpndSize size, int imm,
+                      int disp, int base_reg, bool isBasePhysical) {
+    assert(size != OpndSize_64);
+    if(size == OpndSize_64) ALOGE("move_imm_to_mem with 64 bits");
+    dump_imm_mem(Mnemonic_MOV, ATOM_NORMAL, size, imm, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, false);
+}
+//! set a VR to an immediate
+
+//!
+void set_VR_to_imm(u2 vA, OpndSize size, int imm) {
+    assert(size != OpndSize_64);
+    if(size == OpndSize_64) ALOGE("move_imm_to_mem with 64 bits");
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        int regAll = checkVirtualReg(vA, getTypeFromIntSize(size), 0);
+        if(regAll != PhysicalReg_Null) {
+            dump_imm_reg_noalloc(m, size, imm, regAll, true, LowOpndRegType_gp);
+            updateRefCount(vA, getTypeFromIntSize(size));
+            updateVirtualReg(vA, getTypeFromIntSize(size));
+            return;
+        }
+        //will call freeReg
+        freeReg(true);
+        regAll = registerAlloc(LowOpndRegType_virtual | getTypeFromIntSize(size), vA, false/*dummy*/, true);
+        if(regAll == PhysicalReg_Null) {
+            dump_imm_mem_noalloc(m, size, imm, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA);
+            return;
+        }
+        dump_imm_reg_noalloc(m, size, imm, regAll, true, LowOpndRegType_gp);
+        updateVirtualReg(vA, getTypeFromIntSize(size));
+    }
+    else {
+        dump_imm_mem(m, ATOM_NORMAL, size, imm, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA, false);
+    }
+}
+void set_VR_to_imm_noupdateref(LowOp* op, u2 vA, OpndSize size, int imm) {
+    return;
+}
+//! set a VR to an immediate
+
+//! Do not allocate a physical register for the VR
+void set_VR_to_imm_noalloc(u2 vA, OpndSize size, int imm) {
+    assert(size != OpndSize_64);
+    if(size == OpndSize_64) ALOGE("move_imm_to_mem with 64 bits");
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_imm_mem_noalloc(m, size, imm, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA);
+}
+
+void move_chain_to_reg(OpndSize size, int imm, int reg, bool isPhysical) {
+    dump_imm_reg(Mnemonic_MOV, ATOM_NORMAL, size, imm, reg, isPhysical, LowOpndRegType_gp, true);
+}
+
+//! move an immediate to reg
+
+//!
+void move_imm_to_reg(OpndSize size, int imm, int reg, bool isPhysical) {
+    assert(size != OpndSize_64);
+    if(size == OpndSize_64) ALOGE("move_imm_to_reg with 64 bits");
+    Mnemonic m = Mnemonic_MOV;
+    dump_imm_reg(m, ATOM_NORMAL, size, imm, reg, isPhysical, LowOpndRegType_gp, false);
+}
+//! move an immediate to reg
+
+//! The operand is already allocated
+void move_imm_to_reg_noalloc(OpndSize size, int imm, int reg, bool isPhysical) {
+    assert(size != OpndSize_64);
+    if(size == OpndSize_64) ALOGE("move_imm_to_reg with 64 bits");
+    Mnemonic m = Mnemonic_MOV;
+    dump_imm_reg_noalloc(m, size, imm, reg, isPhysical, LowOpndRegType_gp);
+}
+//!cmov from reg to reg
+
+//!
+void conditional_move_reg_to_reg(OpndSize size, ConditionCode cc, int reg1, bool isPhysical1, int reg, bool isPhysical) {
+    Mnemonic m = (Mnemonic)(Mnemonic_CMOVcc+cc);
+    dump_reg_reg(m, ATOM_NORMAL, size, reg1, isPhysical1, reg, isPhysical, LowOpndRegType_gp);
+}
+//!movss from memory to reg
+
+//!
+void move_ss_mem_to_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
+                         int reg, bool isPhysical) {
+    dump_mem_reg(Mnemonic_MOVSS, ATOM_NORMAL, OpndSize_32, disp, base_reg, isBasePhysical,
+        MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_xmm);
+}
+//!movss from reg to memory
+
+//!
+void move_ss_reg_to_mem(LowOp* op, int reg, bool isPhysical,
+                         int disp, int base_reg, bool isBasePhysical) {
+    dump_reg_mem(Mnemonic_MOVSS, ATOM_NORMAL, OpndSize_32, reg, isPhysical, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, LowOpndRegType_xmm);
+}
+//!movsd from memory to reg
+
+//!
+void move_sd_mem_to_reg(int disp, int base_reg, bool isBasePhysical,
+                         int reg, bool isPhysical) {
+    dump_mem_reg(Mnemonic_MOVSD, ATOM_NORMAL, OpndSize_64, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_xmm);
+}
+//!movsd from reg to memory
+
+//!
+void move_sd_reg_to_mem(LowOp* op, int reg, bool isPhysical,
+                         int disp, int base_reg, bool isBasePhysical) {
+    dump_reg_mem(Mnemonic_MOVSD, ATOM_NORMAL, OpndSize_64, reg, isPhysical,
+                        disp, base_reg, isBasePhysical,
+                        MemoryAccess_Unknown, -1, LowOpndRegType_xmm);
+}
+//!load from VR to a temporary
+
+//!
+void get_virtual_reg_all(u2 vB, OpndSize size, int reg, bool isPhysical, Mnemonic m) {
+    LowOpndRegType type = getTypeFromIntSize(size);
+    LowOpndRegType pType = type;//gp or xmm
+    OpndSize size2 = size;
+    Mnemonic m2 = m;
+    if(m == Mnemonic_MOVSS) {
+        size = OpndSize_32;
+        size2 = OpndSize_64;
+        type = LowOpndRegType_ss;
+        pType = LowOpndRegType_xmm;
+        m2 = Mnemonic_MOVQ; //to move from one xmm register to another
+    }
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        int tmpValue[2];
+        int isConst;
+        isConst = isVirtualRegConstant(vB, type, tmpValue, true/*updateRefCount*/);
+        if(isConst == 3) {
+            if(m == Mnemonic_MOVSS) { //load 32 bits from VR
+                //VR is not mapped to a register but in memory
+                dumpImmToMem(vB, OpndSize_32, tmpValue[0]);
+                //temporary reg has "pType" (which is xmm)
+                dump_mem_reg(m, ATOM_NORMAL, size, 4*vB, PhysicalReg_FP, true,
+                    MemoryAccess_VR, vB, reg, isPhysical, pType);
+                return;
+            }
+            else if(m == Mnemonic_MOVSD || size == OpndSize_64) {
+                //VR is not mapped to a register but in memory
+                dumpImmToMem(vB, OpndSize_32, tmpValue[0]);
+                dumpImmToMem(vB+1, OpndSize_32, tmpValue[1]);
+                dump_mem_reg(m, ATOM_NORMAL, size, 4*vB, PhysicalReg_FP, true,
+                    MemoryAccess_VR, vB, reg, isPhysical, pType);
+                return;
+            }
+            else if(size != OpndSize_64) {
+                //VR is not mapped to a register
+                dump_imm_reg(m, ATOM_NORMAL, size, tmpValue[0], reg, isPhysical, pType, false);
+                return;
+            }
+        }
+        if(isConst == 1) dumpImmToMem(vB, OpndSize_32, tmpValue[0]);
+        if(isConst == 2) dumpImmToMem(vB+1, OpndSize_32, tmpValue[1]);
+        freeReg(true);
+        int regAll = checkVirtualReg(vB, type, 0);
+        if(regAll != PhysicalReg_Null) {
+            startNativeCode(vB, type);
+            donotSpillReg(regAll);
+            //check XFER_MEM_TO_XMM
+            updateVRAtUse(vB, type, regAll);
+            //temporary reg has "pType"
+            dump_reg_reg_noalloc_src(m2, ATOM_NORMAL, size2, regAll, true, reg, isPhysical, pType); //register allocator handles assembly move
+            endNativeCode();
+            updateRefCount(vB, type);
+            return;
+        }
+        //not allocated to a register yet, no need to check XFER_MEM_TO_XMM
+        regAll = registerAlloc(LowOpndRegType_virtual | type, vB, false/*dummy*/, false);
+        if(regAll == PhysicalReg_Null) {
+            dump_mem_reg_noalloc(m, size, 4*vB, PhysicalReg_FP, true,
+                MemoryAccess_VR, vB, reg, isPhysical, pType);
+            return;
+        }
+
+        //temporary reg has pType
+        if(checkTempReg2(reg, pType, isPhysical, regAll)) {
+            registerAllocMove(reg, pType, isPhysical, regAll);
+            dump_mem_reg_noalloc(m, size, 4*vB, PhysicalReg_FP, true,
+                MemoryAccess_VR, vB, regAll, true, pType);
+            updateRefCount(vB, type);
+            return;
+        }
+        else {
+            dump_mem_reg_noalloc(m, size, 4*vB, PhysicalReg_FP, true,
+                MemoryAccess_VR, vB, regAll, true, pType);
+            //xmm with 32 bits
+            startNativeCode(vB, type);
+            donotSpillReg(regAll);
+            dump_reg_reg_noalloc_src(m2, ATOM_NORMAL, size2, regAll, true, reg, isPhysical, pType);
+            endNativeCode();
+            updateRefCount(vB, type);
+            return;
+        }
+    }
+    else {
+        dump_mem_reg(m, ATOM_NORMAL, size, 4*vB, PhysicalReg_FP, true,
+            MemoryAccess_VR, vB, reg, isPhysical, pType);
+    }
+}
+void get_virtual_reg(u2 vB, OpndSize size, int reg, bool isPhysical) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    return get_virtual_reg_all(vB, size, reg, isPhysical, m);
+}
+void get_virtual_reg_noalloc(u2 vB, OpndSize size, int reg, bool isPhysical) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_mem_reg_noalloc(m, size, 4*vB, PhysicalReg_FP, true,
+        MemoryAccess_VR, vB, reg, isPhysical, getTypeFromIntSize(size));
+}
+//3 cases: gp, xmm, ss
+//ss: the temporary register is xmm
+//!load from a temporary to a VR
+
+//!
+void set_virtual_reg_all(u2 vA, OpndSize size, int reg, bool isPhysical, Mnemonic m) {
+    LowOpndRegType type = getTypeFromIntSize(size);
+    LowOpndRegType pType = type;//gp or xmm
+    OpndSize size2 = size;
+    Mnemonic m2 = m;
+    if(m == Mnemonic_MOVSS) {
+        size = OpndSize_32;
+        size2 = OpndSize_64;
+        type = LowOpndRegType_ss;
+        pType = LowOpndRegType_xmm;
+        m2 = Mnemonic_MOVQ;
+    }
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        //3 cases
+        //1: virtual register is already allocated to a physical register
+        //   call dump_reg_reg_noalloc_dst
+        //2: src reg is already allocated, VR is not yet allocated
+        //   allocate VR to the same physical register used by src reg
+        //   [call registerAllocMove]
+        //3: both not yet allocated
+        //   allocate a physical register for the VR
+        //   then call dump_reg_reg_noalloc_dst
+        //may need to convert from gp to xmm or the other way
+        freeReg(true);
+        int regAll = checkVirtualReg(vA, type, 0);
+        if(regAll != PhysicalReg_Null)  { //case 1
+            startNativeCode(-1, -1);
+            donotSpillReg(regAll);
+            dump_reg_reg_noalloc_dst(m2, size2, reg, isPhysical, regAll, true, pType); //temporary reg is "pType"
+            endNativeCode();
+            updateRefCount(vA, type);
+            updateVirtualReg(vA, type); //will dump VR to memory, should happen afterwards
+            return;
+        }
+        regAll = checkTempReg(reg, pType, isPhysical, vA); //vA is not used inside
+        if(regAll != PhysicalReg_Null) { //case 2
+            registerAllocMove(vA, LowOpndRegType_virtual | type, false, regAll);
+            updateVirtualReg(vA, type); //will dump VR to memory, should happen afterwards
+            return; //next native instruction starts at op
+        }
+        //case 3
+        regAll = registerAlloc(LowOpndRegType_virtual | type, vA, false/*dummy*/, false);
+        if(regAll == PhysicalReg_Null) {
+            dump_reg_mem_noalloc(m, size, reg, isPhysical, 4*vA, PhysicalReg_FP, true,
+                MemoryAccess_VR, vA, pType);
+            return;
+        }
+        startNativeCode(-1, -1);
+        donotSpillReg(regAll);
+        dump_reg_reg_noalloc_dst(m2, size2, reg, isPhysical, regAll, true, pType);
+        endNativeCode();
+        updateRefCount(vA, type);
+        updateVirtualReg(vA, type);
+    }
+    else {
+        dump_reg_mem(m, ATOM_NORMAL, size, reg, isPhysical, 4*vA, PhysicalReg_FP, true,
+            MemoryAccess_VR, vA, pType);
+    }
+}
+void set_virtual_reg(u2 vA, OpndSize size, int reg, bool isPhysical) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    return set_virtual_reg_all(vA, size, reg, isPhysical, m);
+}
+void set_virtual_reg_noalloc(u2 vA, OpndSize size, int reg, bool isPhysical) {
+    Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV;
+    dump_reg_mem_noalloc(m, size, reg, isPhysical, 4*vA, PhysicalReg_FP, true,
+        MemoryAccess_VR, vA, getTypeFromIntSize(size));
+}
+void get_VR_ss(int vB, int reg, bool isPhysical) {
+    return get_virtual_reg_all(vB, OpndSize_64, reg, isPhysical, Mnemonic_MOVSS);
+}
+void set_VR_ss(int vA, int reg, bool isPhysical) {
+    return set_virtual_reg_all(vA, OpndSize_64, reg, isPhysical, Mnemonic_MOVSS);
+}
+void get_VR_sd(int vB, int reg, bool isPhysical) {
+    return get_virtual_reg_all(vB, OpndSize_64, reg, isPhysical, Mnemonic_MOVSD);
+}
+void set_VR_sd(int vA, int reg, bool isPhysical) {
+    return set_virtual_reg_all(vA, OpndSize_64, reg, isPhysical, Mnemonic_MOVSD);
+}
+////////////////////////////////// END: IA32 native instructions //////////////
+//! generate native instructions to get current PC in the stack frame
+
+//!
+int get_currentpc(int reg, bool isPhysical) {
+    move_mem_to_reg(OpndSize_32, -sizeofStackSaveArea+offStackSaveArea_localRefTop, PhysicalReg_FP, true, reg, isPhysical);
+    return 1;
+}
+//!generate native code to perform null check
+
+//!This function does not export PC
+int simpleNullCheck(int reg, bool isPhysical, int vr) {
+    if(isVRNullCheck(vr, OpndSize_32)) {
+        updateRefCount2(reg, LowOpndRegType_gp, isPhysical);
+        num_removed_nullCheck++;
+        return 0;
+    }
+    compare_imm_reg(OpndSize_32, 0, reg, isPhysical);
+    conditional_jump_global_API(Condition_E, "common_errNullObject", false);
+    setVRNullCheck(vr, OpndSize_32);
+    return 0;
+}
+
+/* only for O1 code generator */
+int boundCheck(int vr_array, int reg_array, bool isPhysical_array,
+               int vr_index, int reg_index, bool isPhysical_index,
+               int exceptionNum) {
+#ifdef BOUNDCHECK_OPT
+    if(isVRBoundCheck(vr_array, vr_index)) {
+        updateRefCount2(reg_array, LowOpndRegType_gp, isPhysical_array);
+        updateRefCount2(reg_index, LowOpndRegType_gp, isPhysical_index);
+        return 0;
+    }
+#endif
+    compare_mem_reg(OpndSize_32, offArrayObject_length,
+                    reg_array, isPhysical_array,
+                    reg_index, isPhysical_index);
+
+    char errName[256];
+    sprintf(errName, "common_errArrayIndex");
+    handlePotentialException(
+                                       Condition_NC, Condition_C,
+                                       exceptionNum, errName);
+#ifdef BOUNDCHECK_OPT
+    setVRBoundCheck(vr_array, vr_index);
+#endif
+    return 0;
+}
+
+//!generate native code to perform null check
+
+//!
+int nullCheck(int reg, bool isPhysical, int exceptionNum, int vr) {
+    char label[LABEL_SIZE];
+
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        //nullCheck optimization is available in O1 mode only
+        if(isVRNullCheck(vr, OpndSize_32)) {
+            updateRefCount2(reg, LowOpndRegType_gp, isPhysical);
+            if(exceptionNum <= 1) {
+                updateRefCount2(PhysicalReg_EDX, LowOpndRegType_gp, true);
+                updateRefCount2(PhysicalReg_EDX, LowOpndRegType_gp, true);
+            }
+            num_removed_nullCheck++;
+            return 0;
+        }
+        compare_imm_reg(OpndSize_32, 0, reg, isPhysical);
+        rememberState(exceptionNum);
+        snprintf(label, LABEL_SIZE, "after_exception_%d", exceptionNum);
+        conditional_jump(Condition_NE, label, true);
+        if(exceptionNum > 1)
+            nextVersionOfHardReg(PhysicalReg_EDX, 2); //next version has 2 ref count
+        export_pc(); //use %edx
+        constVREndOfBB();
+        beforeCall("exception"); //dump GG, GL VRs
+        unconditional_jump_global_API("common_errNullObject", false);
+        insertLabel(label, true);
+        goToState(exceptionNum);
+        setVRNullCheck(vr, OpndSize_32);
+    } else {
+        compare_imm_reg(OpndSize_32, 0, reg, isPhysical);
+        snprintf(label, LABEL_SIZE, "after_exception_%d", exceptionNum);
+        conditional_jump(Condition_NE, label, true);
+        export_pc(); //use %edx
+        unconditional_jump_global_API("common_errNullObject", false);
+        insertLabel(label, true);
+    }
+    return 0;
+}
+//!generate native code to handle potential exception
+
+//!
+int handlePotentialException(
+                             ConditionCode code_excep, ConditionCode code_okay,
+                             int exceptionNum, const char* errName) {
+    char label[LABEL_SIZE];
+
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        rememberState(exceptionNum);
+        snprintf(label, LABEL_SIZE, "after_exception_%d", exceptionNum);
+        conditional_jump(code_okay, label, true);
+        if(exceptionNum > 1)
+            nextVersionOfHardReg(PhysicalReg_EDX, 2); //next version has 2 ref count
+        export_pc(); //use %edx
+        constVREndOfBB();
+        beforeCall("exception"); //dump GG, GL VRs
+        if(!strcmp(errName, "common_throw_message")) {
+            move_imm_to_reg(OpndSize_32, LstrInstantiationErrorPtr, PhysicalReg_ECX, true);
+        }
+        unconditional_jump_global_API(errName, false);
+        insertLabel(label, true);
+        goToState(exceptionNum);
+    } else {
+        snprintf(label, LABEL_SIZE, "after_exception_%d", exceptionNum);
+        conditional_jump(code_okay, label, true);
+        export_pc(); //use %edx
+        if(!strcmp(errName, "common_throw_message")) {
+            move_imm_to_reg(OpndSize_32, LstrInstantiationErrorPtr, PhysicalReg_ECX, true);
+        }
+        unconditional_jump_global_API(errName, false);
+        insertLabel(label, true);
+    }
+    return 0;
+}
+//!generate native code to get the self pointer from glue
+
+//!It uses one scratch register
+int get_self_pointer(int reg, bool isPhysical) {
+    move_mem_to_reg(OpndSize_32, offEBP_self, PhysicalReg_EBP, true, reg, isPhysical);
+    return 0;
+}
+//!generate native code to get ResStrings from glue
+
+//!It uses two scratch registers
+int get_res_strings(int reg, bool isPhysical) {
+    //if spill_loc_index > 0 || reg != NULL, use registerAlloc
+    if(isGlueHandled(PhysicalReg_GLUE_DVMDEX)) {
+        //if spill_loc_index > 0
+        //  load from spilled location, update spill_loc_index & physicalReg
+#if 0
+        updateRefCount2(C_SCRATCH_1, LowOpndRegType_gp, isScratchPhysical);
+        updateRefCount2(C_SCRATCH_1, LowOpndRegType_gp, isScratchPhysical);
+        updateRefCount2(C_SCRATCH_2, LowOpndRegType_gp, isScratchPhysical);
+        updateRefCount2(C_SCRATCH_2, LowOpndRegType_gp, isScratchPhysical);
+#endif
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int regAll = registerAlloc(LowOpndRegType_gp, PhysicalReg_GLUE_DVMDEX, false, false/*updateRefCount*/);
+        donotSpillReg(regAll);
+        dump_mem_reg_noalloc_mem(Mnemonic_MOV, ATOM_NORMAL, OpndSize_32, offDvmDex_pResStrings, regAll, true, MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_gp);
+        endNativeCode();
+    }
+    else
+        {
+            get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+            move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical);
+            //glue is not in a physical reg nor in a spilled location
+            updateGlue(C_SCRATCH_2, isScratchPhysical, PhysicalReg_GLUE_DVMDEX); //spill_loc_index is -1, set physicalReg
+            move_mem_to_reg(OpndSize_32, offDvmDex_pResStrings, C_SCRATCH_2, isScratchPhysical, reg, isPhysical);
+        }
+    return 0;
+}
+int get_res_classes(int reg, bool isPhysical) {
+    //if spill_loc_index > 0 || reg != NULL, use registerAlloc
+    if(isGlueHandled(PhysicalReg_GLUE_DVMDEX)) {
+        //if spill_loc_index > 0
+        //  load from spilled location, updte spill_loc_index & physicalReg
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int regAll = registerAlloc(LowOpndRegType_gp, PhysicalReg_GLUE_DVMDEX, false, false/*updateRefCount*/);
+        donotSpillReg(regAll);
+        dump_mem_reg_noalloc_mem(Mnemonic_MOV, ATOM_NORMAL, OpndSize_32, offDvmDex_pResClasses, regAll, true, MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_gp);
+        endNativeCode();
+    }
+    else
+        {
+            get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+            move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical);
+            //glue is not in a physical reg nor in a spilled location
+            updateGlue(C_SCRATCH_2, isScratchPhysical, PhysicalReg_GLUE_DVMDEX); //spill_loc_index is -1, set physicalReg
+            move_mem_to_reg(OpndSize_32, offDvmDex_pResClasses, C_SCRATCH_2, isScratchPhysical, reg, isPhysical);
+        }
+    return 0;
+}
+//!generate native code to get ResFields from glue
+
+//!It uses two scratch registers
+int get_res_fields(int reg, bool isPhysical) {
+    //if spill_loc_index > 0 || reg != NULL, use registerAlloc
+    if(isGlueHandled(PhysicalReg_GLUE_DVMDEX)) {
+        //if spill_loc_index > 0
+        //  load from spilled location, updte spill_loc_index & physicalReg
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int regAll = registerAlloc(LowOpndRegType_gp, PhysicalReg_GLUE_DVMDEX, false, false/*updateRefCount*/);
+        donotSpillReg(regAll);
+        dump_mem_reg_noalloc_mem(Mnemonic_MOV, ATOM_NORMAL, OpndSize_32, offDvmDex_pResFields, regAll, true, MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_gp);
+        endNativeCode();
+    }
+    else
+        {
+            get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+            move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical);
+            //glue is not in a physical reg nor in a spilled location
+            updateGlue(C_SCRATCH_2, isScratchPhysical, PhysicalReg_GLUE_DVMDEX); //spill_loc_index is -1, set physicalReg
+            move_mem_to_reg(OpndSize_32, offDvmDex_pResFields, C_SCRATCH_2, isScratchPhysical, reg, isPhysical);
+        }
+    return 0;
+}
+//!generate native code to get ResMethods from glue
+
+//!It uses two scratch registers
+int get_res_methods(int reg, bool isPhysical) {
+    //if spill_loc_index > 0 || reg != NULL, use registerAlloc
+    if(isGlueHandled(PhysicalReg_GLUE_DVMDEX)) {
+        //if spill_loc_index > 0
+        //  load from spilled location, updte spill_loc_index & physicalReg
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int regAll = registerAlloc(LowOpndRegType_gp, PhysicalReg_GLUE_DVMDEX, false, false/*updateRefCount*/);
+        donotSpillReg(regAll);
+        dump_mem_reg_noalloc_mem(Mnemonic_MOV, ATOM_NORMAL, OpndSize_32, offDvmDex_pResMethods, regAll, true, MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_gp);
+        endNativeCode();
+    }
+    else
+        {
+            get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+            move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical);
+            //glue is not in a physical reg nor in a spilled location
+            updateGlue(C_SCRATCH_2, isScratchPhysical, PhysicalReg_GLUE_DVMDEX); //spill_loc_index is -1, set physicalReg
+            move_mem_to_reg(OpndSize_32, offDvmDex_pResMethods, C_SCRATCH_2, isScratchPhysical, reg, isPhysical);
+        }
+    return 0;
+}
+//!generate native code to get the current class object from glue
+
+//!It uses two scratch registers
+int get_glue_method_class(int reg, bool isPhysical) {
+    get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+    move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.method), C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical);
+    move_mem_to_reg(OpndSize_32, offMethod_clazz, C_SCRATCH_2, isScratchPhysical, reg, isPhysical);
+    return 0;
+}
+//!generate native code to get the current method from glue
+
+//!It uses one scratch register
+int get_glue_method(int reg, bool isPhysical) {
+    get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+    move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.method), C_SCRATCH_1, isScratchPhysical, reg, isPhysical);
+    return 0;
+}
+//!generate native code to set the current method in glue
+
+//!It uses one scratch register
+int set_glue_method(int reg, bool isPhysical) {
+    get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+    move_reg_to_mem(OpndSize_32, reg, isPhysical, offsetof(Thread, interpSave.method), C_SCRATCH_1, isScratchPhysical);
+    return 0;
+}
+
+//!generate native code to get DvmDex from glue
+
+//!It uses one scratch register
+int get_glue_dvmdex(int reg, bool isPhysical) {
+    //if spill_loc_index > 0 || reg != NULL, use registerAlloc
+    if(isGlueHandled(PhysicalReg_GLUE_DVMDEX)) {
+        //if spill_loc_index > 0
+        //  load from spilled location, updte spill_loc_index & physicalReg
+        startNativeCode(-1, -1);
+        freeReg(true);
+        int regAll = registerAlloc(LowOpndRegType_gp, PhysicalReg_GLUE_DVMDEX, false, false/*updateRefCount*/);
+        donotSpillReg(regAll);
+        dump_reg_reg_noalloc_src(Mnemonic_MOV, ATOM_NORMAL, OpndSize_32, regAll, true,
+                                          reg, isPhysical, LowOpndRegType_gp);
+        endNativeCode();
+    }
+    else
+        {
+            get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+            move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical, reg, isPhysical);
+            //glue is not in a physical reg nor in a spilled location
+            updateGlue(reg, isPhysical, PhysicalReg_GLUE_DVMDEX); //spill_loc_index is -1, set physicalReg
+        }
+    return 0;
+}
+//!generate native code to set DvmDex in glue
+
+//!It uses one scratch register
+int set_glue_dvmdex(int reg, bool isPhysical) {
+    get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+    move_reg_to_mem(OpndSize_32, reg, isPhysical, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical);
+    return 0;
+}
+//!generate native code to get SuspendCount from glue
+
+//!It uses one scratch register
+int get_suspendCount(int reg, bool isPhysical) {
+    get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+    move_mem_to_reg(OpndSize_32, offsetof(Thread, suspendCount), C_SCRATCH_1, isScratchPhysical, reg, isPhysical);
+    return 0;
+}
+
+//!generate native code to get retval from glue
+
+//!It uses one scratch register
+int get_return_value(OpndSize size, int reg, bool isPhysical) {
+    get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+    move_mem_to_reg(size, offsetof(Thread, interpSave.retval), C_SCRATCH_1, isScratchPhysical, reg, isPhysical);
+    return 0;
+}
+//!generate native code to set retval in glue
+
+//!It uses one scratch register
+int set_return_value(OpndSize size, int reg, bool isPhysical) {
+    get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+    move_reg_to_mem(size, reg, isPhysical, offsetof(Thread, interpSave.retval), C_SCRATCH_1, isScratchPhysical);
+    return 0;
+}
+//!generate native code to clear exception object in glue
+
+//!It uses two scratch registers
+int clear_exception() {
+    get_self_pointer(C_SCRATCH_2, isScratchPhysical);
+    move_imm_to_mem(OpndSize_32, 0, offsetof(Thread, exception), C_SCRATCH_2, isScratchPhysical);
+    return 0;
+}
+//!generate native code to get exception object in glue
+
+//!It uses two scratch registers
+int get_exception(int reg, bool isPhysical) {
+    get_self_pointer(C_SCRATCH_2, isScratchPhysical);
+    move_mem_to_reg(OpndSize_32, offsetof(Thread, exception), C_SCRATCH_2, isScratchPhysical, reg, isPhysical);
+    return 0;
+}
+//!generate native code to set exception object in glue
+
+//!It uses two scratch registers
+int set_exception(int reg, bool isPhysical) {
+    get_self_pointer(C_SCRATCH_2, isScratchPhysical);
+    move_reg_to_mem(OpndSize_32, reg, isPhysical, offsetof(Thread, exception), C_SCRATCH_2, isScratchPhysical);
+    return 0;
+}
+//!generate native code to save frame pointer and current PC in stack frame to glue
+
+//!It uses two scratch registers
+int save_pc_fp_to_glue() {
+    get_self_pointer(C_SCRATCH_1, isScratchPhysical);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_FP, true, offsetof(Thread, interpSave.curFrame), C_SCRATCH_1, isScratchPhysical);
+
+    //from stack-save currentPc
+    move_mem_to_reg(OpndSize_32, -sizeofStackSaveArea+offStackSaveArea_localRefTop, PhysicalReg_FP, true, C_SCRATCH_2, isScratchPhysical);
+    move_reg_to_mem(OpndSize_32, C_SCRATCH_2, isScratchPhysical, offsetof(Thread, interpSave.pc), C_SCRATCH_1, isScratchPhysical);
+    return 0;
+}
+//! get SaveArea pointer
+
+//!
+int savearea_from_fp(int reg, bool isPhysical) {
+    load_effective_addr(-sizeofStackSaveArea, PhysicalReg_FP, true, reg, isPhysical);
+    return 0;
+}
+
+#ifdef DEBUG_CALL_STACK3
+int call_debug_dumpSwitch() {
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = debug_dumpSwitch;
+    callFuncPtr((int)funcPtr, "debug_dumpSwitch");
+    return 0;
+}
+#endif
+
+int call_dvmQuasiAtomicSwap64() {
+    typedef int64_t (*vmHelper)(int64_t, volatile int64_t*);
+    vmHelper funcPtr = dvmQuasiAtomicSwap64;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmQuasiAtomicSwap64");
+        callFuncPtr((int)funcPtr, "dvmQuasiAtomicSwap64");
+        afterCall("dvmQuasiAtomicSwap64");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmQuasiAtomicSwap64");
+    }
+    return 0;
+}
+
+int call_dvmQuasiAtomicRead64() {
+    typedef int64_t (*vmHelper)(volatile const int64_t*);
+    vmHelper funcPtr = dvmQuasiAtomicRead64;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmQuasiAtomiRead64");
+        callFuncPtr((int)funcPtr, "dvmQuasiAtomicRead64");
+        afterCall("dvmQuasiAtomicRead64");
+        touchEax(); //for return value
+        touchEdx();
+    } else {
+        callFuncPtr((int)funcPtr, "dvmQuasiAtomicRead64");
+    }
+    return 0;
+}
+
+int call_dvmJitToInterpPunt() {
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = dvmJitToInterpPunt;
+    callFuncPtr((int)funcPtr, "dvmJitToInterpPunt");
+    return 0;
+}
+
+int call_dvmJitToInterpNormal() {
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = dvmJitToInterpNormal;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmJitToInterpNormal");
+        callFuncPtr((int)funcPtr, "dvmJitToInterpNormal");
+        afterCall("dvmJitToInterpNormal");
+        touchEbx();
+    } else {
+        callFuncPtr((int)funcPtr, "dvmJitToInterpNormal");
+    }
+    return 0;
+}
+
+int call_dvmJitToInterpTraceSelectNoChain() {
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = dvmJitToInterpTraceSelectNoChain;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmJitToInterpTraceSelectNoChain");
+        callFuncPtr((int)funcPtr, "dvmJitToInterpTraceSelectNoChain");
+        afterCall("dvmJitToInterpTraceSelectNoChain");
+        touchEbx();
+    } else {
+        callFuncPtr((int)funcPtr, "dvmJitToInterpTraceSelectNoChain");
+    }
+    return 0;
+}
+
+int call_dvmJitToInterpTraceSelect() {
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = dvmJitToInterpTraceSelect;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmJitToInterpTraceSelect");
+        callFuncPtr((int)funcPtr, "dvmJitToInterpTraceSelect");
+        afterCall("dvmJitToInterpTraceSelect");
+        touchEbx();
+    } else {
+        callFuncPtr((int)funcPtr, "dvmJitToInterpTraceSelect");
+    }
+    return 0;
+}
+
+int call_dvmJitToPatchPredictedChain() {
+    typedef const Method * (*vmHelper)(const Method *method,
+                                       Thread *self,
+                                       PredictedChainingCell *cell,
+                                       const ClassObject *clazz);
+    vmHelper funcPtr = dvmJitToPatchPredictedChain;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmJitToPatchPredictedChain");
+        callFuncPtr((int)funcPtr, "dvmJitToPatchPredictedChain");
+        afterCall("dvmJitToPatchPredictedChain");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmJitToPatchPredictedChain");
+    }
+    return 0;
+}
+
+//!generate native code to call __moddi3
+
+//!
+int call_moddi3() {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("moddi3");
+        callFuncPtr((intptr_t)__moddi3, "__moddi3");
+        afterCall("moddi3");
+    } else {
+        callFuncPtr((intptr_t)__moddi3, "__moddi3");
+    }
+    return 0;
+}
+//!generate native code to call __divdi3
+
+//!
+int call_divdi3() {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("divdi3");
+        callFuncPtr((intptr_t)__divdi3, "__divdi3");
+        afterCall("divdi3");
+    } else {
+        callFuncPtr((intptr_t)__divdi3, "__divdi3");
+    }
+    return 0;
+}
+
+//!generate native code to call fmod
+
+//!
+int call_fmod() {
+    typedef double (*libHelper)(double, double);
+    libHelper funcPtr = fmod;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("fmod");
+        callFuncPtr((int)funcPtr, "fmod");
+        afterCall("fmod");
+    } else {
+        callFuncPtr((int)funcPtr, "fmod");
+    }
+    return 0;
+}
+//!generate native code to call fmodf
+
+//!
+int call_fmodf() {
+    typedef float (*libHelper)(float, float);
+    libHelper funcPtr = fmodf;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("fmodf");
+        callFuncPtr((int)funcPtr, "fmodf");
+        afterCall("fmodf");
+    } else {
+        callFuncPtr((int)funcPtr, "fmodf");
+    }
+    return 0;
+}
+//!generate native code to call dvmFindCatchBlock
+
+//!
+int call_dvmFindCatchBlock() {
+    //int dvmFindCatchBlock(Thread* self, int relPc, Object* exception,
+    //bool doUnroll, void** newFrame)
+    typedef int (*vmHelper)(Thread*, int, Object*, bool, void**);
+    vmHelper funcPtr = dvmFindCatchBlock;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmFindCatchBlock");
+        callFuncPtr((int)funcPtr, "dvmFindCatchBlock");
+        afterCall("dvmFindCatchBlock");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmFindCatchBlock");
+    }
+    return 0;
+}
+//!generate native code to call dvmThrowVerificationError
+
+//!
+int call_dvmThrowVerificationError() {
+    typedef void (*vmHelper)(const Method*, int, int);
+    vmHelper funcPtr = dvmThrowVerificationError;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmThrowVerificationError");
+        callFuncPtr((int)funcPtr, "dvmThrowVerificationError");
+        afterCall("dvmThrowVerificationError");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmThrowVerificationError");
+    }
+    return 0;
+}
+
+//!generate native code to call dvmResolveMethod
+
+//!
+int call_dvmResolveMethod() {
+    //Method* dvmResolveMethod(const ClassObject* referrer, u4 methodIdx, MethodType methodType);
+    typedef Method* (*vmHelper)(const ClassObject*, u4, MethodType);
+    vmHelper funcPtr = dvmResolveMethod;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmResolveMethod");
+        callFuncPtr((int)funcPtr, "dvmResolveMethod");
+        afterCall("dvmResolveMethod");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmResolveMethod");
+    }
+    return 0;
+}
+//!generate native code to call dvmResolveClass
+
+//!
+int call_dvmResolveClass() {
+    //ClassObject* dvmResolveClass(const ClassObject* referrer, u4 classIdx, bool fromUnverifiedConstant)
+    typedef ClassObject* (*vmHelper)(const ClassObject*, u4, bool);
+    vmHelper funcPtr = dvmResolveClass;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmResolveClass");
+        callFuncPtr((int)funcPtr, "dvmResolveClass");
+        afterCall("dvmResolveClass");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmResolveClass");
+    }
+    return 0;
+}
+
+//!generate native code to call dvmInstanceofNonTrivial
+
+//!
+int call_dvmInstanceofNonTrivial() {
+    typedef int (*vmHelper)(const ClassObject*, const ClassObject*);
+    vmHelper funcPtr = dvmInstanceofNonTrivial;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmInstanceofNonTrivial");
+        callFuncPtr((int)funcPtr, "dvmInstanceofNonTrivial");
+        afterCall("dvmInstanceofNonTrivial");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmInstanceofNonTrivial");
+    }
+    return 0;
+}
+//!generate native code to call dvmThrowException
+
+//!
+int call_dvmThrow() {
+    typedef void (*vmHelper)(ClassObject* exceptionClass, const char*);
+    vmHelper funcPtr = dvmThrowException;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmThrowException");
+        callFuncPtr((int)funcPtr, "dvmThrowException");
+        afterCall("dvmThrowException");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmThrowException");
+    }
+    return 0;
+}
+//!generate native code to call dvmThrowExceptionWithClassMessage
+
+//!
+int call_dvmThrowWithMessage() {
+    typedef void (*vmHelper)(ClassObject* exceptionClass, const char*);
+    vmHelper funcPtr = dvmThrowExceptionWithClassMessage;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmThrowExceptionWithClassMessage");
+        callFuncPtr((int)funcPtr, "dvmThrowExceptionWithClassMessage");
+        afterCall("dvmThrowExceptionWithClassMessage");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmThrowExceptionWithClassMessage");
+    }
+    return 0;
+}
+//!generate native code to call dvmCheckSuspendPending
+
+//!
+int call_dvmCheckSuspendPending() {
+    typedef bool (*vmHelper)(Thread*);
+    vmHelper funcPtr = dvmCheckSuspendPending;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmCheckSuspendPending");
+        callFuncPtr((int)funcPtr, "dvmCheckSuspendPending");
+        afterCall("dvmCheckSuspendPending");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmCheckSuspendPending");
+    }
+    return 0;
+}
+//!generate native code to call dvmLockObject
+
+//!
+int call_dvmLockObject() {
+    typedef void (*vmHelper)(struct Thread*, struct Object*);
+    vmHelper funcPtr = dvmLockObject;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmLockObject");
+        callFuncPtr((int)funcPtr, "dvmLockObject");
+        afterCall("dvmLockObject");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmLockObject");
+    }
+    return 0;
+}
+//!generate native code to call dvmUnlockObject
+
+//!
+int call_dvmUnlockObject() {
+    typedef bool (*vmHelper)(Thread*, Object*);
+    vmHelper funcPtr = dvmUnlockObject;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmUnlockObject");
+        callFuncPtr((int)funcPtr, "dvmUnlockObject");
+        afterCall("dvmUnlockObject");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmUnlockObject");
+    }
+    return 0;
+}
+//!generate native code to call dvmInitClass
+
+//!
+int call_dvmInitClass() {
+    typedef bool (*vmHelper)(ClassObject*);
+    vmHelper funcPtr = dvmInitClass;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmInitClass");
+        callFuncPtr((int)funcPtr, "dvmInitClass");
+        afterCall("dvmInitClass");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmInitClass");
+    }
+    return 0;
+}
+//!generate native code to call dvmAllocObject
+
+//!
+int call_dvmAllocObject() {
+    typedef Object* (*vmHelper)(ClassObject*, int);
+    vmHelper funcPtr = dvmAllocObject;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmAllocObject");
+        callFuncPtr((int)funcPtr, "dvmAllocObject");
+        afterCall("dvmAllocObject");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmAllocObject");
+    }
+    return 0;
+}
+//!generate native code to call dvmAllocArrayByClass
+
+//!
+int call_dvmAllocArrayByClass() {
+    typedef ArrayObject* (*vmHelper)(ClassObject*, size_t, int);
+    vmHelper funcPtr = dvmAllocArrayByClass;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmAllocArrayByClass");
+        callFuncPtr((int)funcPtr, "dvmAllocArrayByClass");
+        afterCall("dvmAllocArrayByClass");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmAllocArrayByClass");
+    }
+    return 0;
+}
+//!generate native code to call dvmAllocPrimitiveArray
+
+//!
+int call_dvmAllocPrimitiveArray() {
+    typedef ArrayObject* (*vmHelper)(char, size_t, int);
+    vmHelper funcPtr = dvmAllocPrimitiveArray;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmAllocPrimitiveArray");
+        callFuncPtr((int)funcPtr, "dvmAllocPrimitiveArray");
+        afterCall("dvmAllocPrimitiveArray");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmAllocPrimitiveArray");
+    }
+    return 0;
+}
+//!generate native code to call dvmInterpHandleFillArrayData
+
+//!
+int call_dvmInterpHandleFillArrayData() {
+    typedef bool (*vmHelper)(ArrayObject*, const u2*);
+    vmHelper funcPtr = dvmInterpHandleFillArrayData;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmInterpHandleFillArrayData"); //before move_imm_to_reg to avoid spilling C_SCRATCH_1
+        callFuncPtr((int)funcPtr, "dvmInterpHandleFillArrayData");
+        afterCall("dvmInterpHandleFillArrayData");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmInterpHandleFillArrayData");
+    }
+    return 0;
+}
+
+//!generate native code to call dvmNcgHandlePackedSwitch
+
+//!
+int call_dvmNcgHandlePackedSwitch() {
+    typedef s4 (*vmHelper)(const s4*, s4, u2, s4);
+    vmHelper funcPtr = dvmNcgHandlePackedSwitch;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmNcgHandlePackedSwitch");
+        callFuncPtr((int)funcPtr, "dvmNcgHandlePackedSwitch");
+        afterCall("dvmNcgHandlePackedSwitch");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmNcgHandlePackedSwitch");
+    }
+    return 0;
+}
+
+int call_dvmJitHandlePackedSwitch() {
+    typedef s4 (*vmHelper)(const s4*, s4, u2, s4);
+    vmHelper funcPtr = dvmJitHandlePackedSwitch;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmJitHandlePackedSwitch");
+        callFuncPtr((int)funcPtr, "dvmJitHandlePackedSwitch");
+        afterCall("dvmJitHandlePackedSwitch");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmJitHandlePackedSwitch");
+    }
+    return 0;
+}
+
+//!generate native code to call dvmNcgHandleSparseSwitch
+
+//!
+int call_dvmNcgHandleSparseSwitch() {
+    typedef s4 (*vmHelper)(const s4*, u2, s4);
+    vmHelper funcPtr = dvmNcgHandleSparseSwitch;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmNcgHandleSparseSwitch");
+        callFuncPtr((int)funcPtr, "dvmNcgHandleSparseSwitch");
+        afterCall("dvmNcgHandleSparseSwitch");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmNcgHandleSparseSwitch");
+    }
+    return 0;
+}
+
+int call_dvmJitHandleSparseSwitch() {
+    typedef s4 (*vmHelper)(const s4*, u2, s4);
+    vmHelper funcPtr = dvmJitHandleSparseSwitch;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmJitHandleSparseSwitch");
+        callFuncPtr((int)funcPtr, "dvmJitHandleSparseSwitch");
+        afterCall("dvmJitHandleSparseSwitch");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmJitHandleSparseSwitch");
+    }
+    return 0;
+}
+
+//!generate native code to call dvmCanPutArrayElement
+
+//!
+int call_dvmCanPutArrayElement() {
+    typedef bool (*vmHelper)(const ClassObject*, const ClassObject*);
+    vmHelper funcPtr = dvmCanPutArrayElement;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmCanPutArrayElement");
+        callFuncPtr((int)funcPtr, "dvmCanPutArrayElement");
+        afterCall("dvmCanPutArrayElement");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmCanPutArrayElement");
+    }
+    return 0;
+}
+
+//!generate native code to call dvmFindInterfaceMethodInCache2
+
+//!
+int call_dvmFindInterfaceMethodInCache() {
+    typedef Method* (*vmHelper)(ClassObject*, u4, const Method*, DvmDex*);
+    vmHelper funcPtr = dvmFindInterfaceMethodInCache2;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmFindInterfaceMethodInCache2");
+        callFuncPtr((int)funcPtr, "dvmFindInterfaceMethodInCache2");
+        afterCall("dvmFindInterfaceMethodInCache2");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmFindInterfaceMethodInCache2");
+    }
+    return 0;
+}
+
+//!generate native code to call dvmHandleStackOverflow
+
+//!
+int call_dvmHandleStackOverflow() {
+    typedef void (*vmHelper)(Thread*, const Method*);
+    vmHelper funcPtr = dvmHandleStackOverflow;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmHandleStackOverflow");
+        callFuncPtr((int)funcPtr, "dvmHandleStackOverflow");
+        afterCall("dvmHandleStackOverflow");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmHandleStackOverflow");
+    }
+    return 0;
+}
+//!generate native code to call dvmResolveString
+
+//!
+int call_dvmResolveString() {
+    //StringObject* dvmResolveString(const ClassObject* referrer, u4 stringIdx)
+    typedef StringObject* (*vmHelper)(const ClassObject*, u4);
+    vmHelper funcPtr = dvmResolveString;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmResolveString");
+        callFuncPtr((int)funcPtr, "dvmResolveString");
+        afterCall("dvmResolveString");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmResolveString");
+    }
+    return 0;
+}
+//!generate native code to call dvmResolveInstField
+
+//!
+int call_dvmResolveInstField() {
+    //InstField* dvmResolveInstField(const ClassObject* referrer, u4 ifieldIdx)
+    typedef InstField* (*vmHelper)(const ClassObject*, u4);
+    vmHelper funcPtr = dvmResolveInstField;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmResolveInstField");
+        callFuncPtr((int)funcPtr, "dvmResolveInstField");
+        afterCall("dvmResolveInstField");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmResolveInstField");
+    }
+    return 0;
+}
+//!generate native code to call dvmResolveStaticField
+
+//!
+int call_dvmResolveStaticField() {
+    //StaticField* dvmResolveStaticField(const ClassObject* referrer, u4 sfieldIdx)
+    typedef StaticField* (*vmHelper)(const ClassObject*, u4);
+    vmHelper funcPtr = dvmResolveStaticField;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall("dvmResolveStaticField");
+        callFuncPtr((int)funcPtr, "dvmResolveStaticField");
+        afterCall("dvmResolveStaticField");
+    } else {
+        callFuncPtr((int)funcPtr, "dvmResolveStaticField");
+    }
+    return 0;
+}
+
+#define P_GPR_2 PhysicalReg_ECX
+/*!
+\brief This function is used to resolve a string reference
+
+INPUT: const pool index in %eax
+
+OUTPUT: resolved string in %eax
+
+The registers are hard-coded, 2 physical registers %esi and %edx are used as scratch registers;
+It calls a C function dvmResolveString;
+The only register that is still live after this function is ebx
+*/
+int const_string_resolve() {
+    scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    insertLabel(".const_string_resolve", false);
+    //method stored in glue structure as well as on the interpreted stack
+    get_glue_method_class(P_GPR_2, true);
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_EAX, true, 4, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, P_GPR_2, true, 0, PhysicalReg_ESP, true);
+    call_dvmResolveString();
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    compare_imm_reg( OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump(Condition_E, "common_exceptionThrown", false);
+    x86_return();
+    return 0;
+}
+#undef P_GPR_2
+/*!
+\brief This function is used to resolve a class
+
+INPUT: const pool index in argument "indexReg" (%eax)
+
+OUTPUT: resolved class in %eax
+
+The registers are hard-coded, 3 physical registers (%esi, %edx, startLR:%eax) are used as scratch registers.
+It calls a C function dvmResolveClass;
+The only register that is still live after this function is ebx
+*/
+int resolve_class2(
+           int startLR/*scratch register*/, bool isPhysical, int indexReg/*const pool index*/,
+           bool indexPhysical, int thirdArg) {
+    insertLabel(".class_resolve", false);
+    scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+
+    //push index to stack first, to free indexReg
+    load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, indexReg, indexPhysical, 4, PhysicalReg_ESP, true);
+    get_glue_method_class(startLR, isPhysical);
+    move_imm_to_mem(OpndSize_32, thirdArg, 8, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, startLR, isPhysical, 0, PhysicalReg_ESP, true);
+    call_dvmResolveClass();
+    load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump(Condition_E, "common_exceptionThrown", false);
+
+    x86_return();
+    return 0;
+}
+/*!
+\brief This function is used to resolve a method, and it is called once with %eax for both indexReg and startLR
+
+INPUT: const pool index in argument "indexReg" (%eax)
+
+OUTPUT: resolved method in %eax
+
+The registers are hard-coded, 3 physical registers (%esi, %edx, startLR:%eax) are used as scratch registers.
+It calls a C function dvmResolveMethod;
+The only register that is still live after this function is ebx
+*/
+int resolve_method2(
+            int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/,
+            bool indexPhysical,
+            int thirdArg/*VIRTUAL*/) {
+    if(thirdArg == METHOD_VIRTUAL)
+        insertLabel(".virtual_method_resolve", false);
+    else if(thirdArg == METHOD_DIRECT)
+        insertLabel(".direct_method_resolve", false);
+    else if(thirdArg == METHOD_STATIC)
+        insertLabel(".static_method_resolve", false);
+
+    load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, indexReg, indexPhysical, 4, PhysicalReg_ESP, true);
+
+    scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    get_glue_method_class(startLR, isPhysical);
+
+    move_imm_to_mem(OpndSize_32, thirdArg, 8, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, startLR, isPhysical, 0, PhysicalReg_ESP, true);
+    call_dvmResolveMethod();
+    load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump(Condition_E, "common_exceptionThrown", false);
+
+    x86_return();
+    return 0;
+}
+/*!
+\brief This function is used to resolve an instance field
+
+INPUT: const pool index in argument "indexReg" (%eax)
+
+OUTPUT: resolved field in %eax
+
+The registers are hard-coded, 3 physical registers (%esi, %edx, startLR:%eax) are used as scratch registers.
+It calls a C function dvmResolveInstField;
+The only register that is still live after this function is ebx
+*/
+int resolve_inst_field2(
+            int startLR/*logical register index*/, bool isPhysical,
+            int indexReg/*const pool index*/, bool indexPhysical) {
+    insertLabel(".inst_field_resolve", false);
+    scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, indexReg, indexPhysical, 4, PhysicalReg_ESP, true);
+    //method stored in glue structure as well as interpreted stack
+    get_glue_method_class(startLR, isPhysical);
+    move_reg_to_mem(OpndSize_32, startLR, isPhysical, 0, PhysicalReg_ESP, true);
+    call_dvmResolveInstField();
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump(Condition_E, "common_exceptionThrown", false);
+
+    x86_return();
+    return 0;
+}
+/*!
+\brief This function is used to resolve a static field
+
+INPUT: const pool index in argument "indexReg" (%eax)
+
+OUTPUT: resolved field in %eax
+
+The registers are hard-coded, 3 physical registers (%esi, %edx, startLR:%eax) are used as scratch registers.
+It calls a C function dvmResolveStaticField;
+The only register that is still live after this function is ebx
+*/
+int resolve_static_field2(
+              int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/,
+              bool indexPhysical) {
+    insertLabel(".static_field_resolve", false);
+    scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, indexReg, indexPhysical, 4, PhysicalReg_ESP, true);
+    get_glue_method_class(startLR, isPhysical);
+    move_reg_to_mem(OpndSize_32, startLR, isPhysical, 0, PhysicalReg_ESP, true);
+    call_dvmResolveStaticField();
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump(Condition_E, "common_exceptionThrown", false);
+
+    x86_return();
+    return 0;
+}
+
+int pushAllRegs() {
+    load_effective_addr(-28, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EAX, true, 24, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1);
+    move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EBX, true, 20, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1);
+    move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_ECX, true, 16, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1);
+    move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EDX, true, 12, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1);
+    move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_ESI, true, 8, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1);
+    move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EDI, true, 4, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1);
+    move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EBP, true, 0, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1);
+    return 0;
+}
+int popAllRegs() {
+    move_mem_to_reg_noalloc(OpndSize_32, 24, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_EAX, true);
+    move_mem_to_reg_noalloc(OpndSize_32, 20, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_EBX, true);
+    move_mem_to_reg_noalloc(OpndSize_32, 16, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_ECX, true);
+    move_mem_to_reg_noalloc(OpndSize_32, 12, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_EDX, true);
+    move_mem_to_reg_noalloc(OpndSize_32, 8, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_ESI, true);
+    move_mem_to_reg_noalloc(OpndSize_32, 4, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_EDI, true);
+    move_mem_to_reg_noalloc(OpndSize_32, 0, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_EBP, true);
+    load_effective_addr(28, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    return 0;
+}
+
+void dump_nop(int size) {
+    switch(size) {
+        case 1:
+          *stream = 0x90;
+          break;
+        case 2:
+          *stream = 0x66;
+          *(stream +1) = 0x90;
+          break;
+        case 3:
+          *stream = 0x0f;
+          *(stream + 1) = 0x1f;
+          *(stream + 2) = 0x00;
+          break;
+        default:
+          //TODO: add more cases.
+          break;
+    }
+    stream += size;
+}
diff --git a/vm/compiler/codegen/x86/LowerInvoke.cpp b/vm/compiler/codegen/x86/LowerInvoke.cpp
new file mode 100644
index 0000000..3d02190
--- /dev/null
+++ b/vm/compiler/codegen/x86/LowerInvoke.cpp
@@ -0,0 +1,1661 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file LowerInvoke.cpp
+    \brief This file lowers the following bytecodes: INVOKE_XXX
+*/
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "mterp/Mterp.h"
+#include "Lower.h"
+#include "NcgAot.h"
+#include "enc_wrapper.h"
+
+char* streamMisPred = NULL;
+
+/* according to callee, decide the ArgsDoneType*/
+ArgsDoneType convertCalleeToType(const Method* calleeMethod) {
+    if(calleeMethod == NULL)
+        return ArgsDone_Full;
+    if(dvmIsNativeMethod(calleeMethod))
+        return ArgsDone_Native;
+    return ArgsDone_Normal;
+}
+int common_invokeMethodRange(ArgsDoneType);
+int common_invokeMethodNoRange(ArgsDoneType);
+void gen_predicted_chain(bool isRange, u2 tmp, int IMMC, bool isInterface, int inputReg);
+
+//inputs to common_invokeMethodRange: %ecx
+//          common_errNoSuchMethod: %edx
+#define P_GPR_1 PhysicalReg_ESI
+#define P_GPR_2 PhysicalReg_EBX
+#define P_GPR_3 PhysicalReg_ECX
+#define P_SCRATCH_1 PhysicalReg_EDX
+#define PP_GPR_1 PhysicalReg_EBX
+#define PP_GPR_2 PhysicalReg_ESI
+#define PP_GPR_3 PhysicalReg_EAX
+#define PP_GPR_4 PhysicalReg_EDX
+
+#ifdef WITH_JIT_INLINING
+/*
+ * The function here takes care the
+ * branch over if prediction is correct and the misprediction target for misPredBranchOver.
+ */
+static void genLandingPadForMispredictedCallee(MIR* mir) {
+    BasicBlock *fallThrough = traceCurrentBB->fallThrough;
+    /* Bypass the move-result block if there is one */
+    if (fallThrough->firstMIRInsn) {
+        assert(fallThrough->firstMIRInsn->OptimizationFlags & MIR_INLINED_PRED);
+        fallThrough = fallThrough->fallThrough;
+    }
+    /* Generate a branch over if the predicted inlining is correct */
+    jumpToBasicBlock(stream, fallThrough->id);
+    /* Hook up the target to the verification branch */
+    int relativeNCG = stream - streamMisPred;
+    unsigned instSize = encoder_get_inst_size(streamMisPred);
+    relativeNCG -= instSize; //size of the instruction
+    updateJumpInst(streamMisPred, OpndSize_8, relativeNCG);
+}
+#endif
+
+//! LOWER bytecode INVOKE_VIRTUAL without usage of helper function
+
+//!
+int common_invoke_virtual_nohelper(bool isRange, u2 tmp, u2 vD) {
+#ifdef WITH_JIT_INLINING
+    /*
+     * If the invoke has non-null misPredBranchOver, we need to generate
+     * the non-inlined version of the invoke here to handle the
+     * mispredicted case.
+     */
+    if (traceCurrentMIR->meta.callsiteInfo->misPredBranchOver) {
+        genLandingPadForMispredictedCallee(); //cUnit, mir, bb, labelList);
+    }
+#endif
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    export_pc();
+    constVREndOfBB();
+    beforeCall("exception"); //dump GG, GL VRs
+
+    get_virtual_reg(vD, OpndSize_32, 5, false);
+    simpleNullCheck(5, false, vD);
+#ifndef PREDICTED_CHAINING
+    move_mem_to_reg(OpndSize_32, offObject_clazz, 5, false, 6, false); //clazz of "this"
+    move_mem_to_reg(OpndSize_32, offClassObject_vtable, 6, false, 7, false); //vtable
+    /* method is already resolved in trace-based JIT */
+    int methodIndex =
+                currentMethod->clazz->pDvmDex->pResMethods[tmp]->methodIndex;
+    move_mem_to_reg(OpndSize_32, methodIndex*4, 7, false, PhysicalReg_ECX, true);
+    if(isRange) {
+        common_invokeMethodRange(ArgsDone_Full);
+    }
+    else {
+        common_invokeMethodNoRange(ArgsDone_Full);
+    }
+#else
+    int methodIndex =
+                currentMethod->clazz->pDvmDex->pResMethods[tmp]->methodIndex;
+    gen_predicted_chain(isRange, tmp, methodIndex*4, false, 5/*tmp5*/);
+#endif
+    ///////////////////////////////////
+    return 0;
+}
+//! wrapper to call either common_invoke_virtual_helper or common_invoke_virtual_nohelper
+
+//!
+int common_invoke_virtual(bool isRange, u2 tmp, u2 vD) {
+    return common_invoke_virtual_nohelper(isRange, tmp, vD);
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef P_SCRATCH_1
+#undef PP_GPR_1
+#undef PP_GPR_2
+#undef PP_GPR_3
+#undef PP_GPR_4
+
+#define P_GPR_1 PhysicalReg_ESI
+#define P_GPR_2 PhysicalReg_EBX
+#define P_GPR_3 PhysicalReg_EDX
+#define PP_GPR_1 PhysicalReg_EBX
+#define PP_GPR_2 PhysicalReg_ESI
+#define PP_GPR_3 PhysicalReg_EAX
+#define PP_GPR_4 PhysicalReg_EDX
+//! common section to lower INVOKE_SUPER
+
+//! It will use helper function if the switch is on
+int common_invoke_super(bool isRange, u2 tmp) {
+    export_pc();
+    constVREndOfBB();
+    beforeCall("exception"); //dump GG, GL VRs
+    ///////////////////////
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    /* method is already resolved in trace-based JIT */
+    int mIndex = currentMethod->clazz->pDvmDex->pResMethods[tmp]->methodIndex;
+    const Method *calleeMethod =
+        currentMethod->clazz->super->vtable[mIndex];
+    move_imm_to_reg(OpndSize_32, (int) calleeMethod, PhysicalReg_ECX, true);
+    if(isRange) {
+        common_invokeMethodRange(convertCalleeToType(calleeMethod));
+    }
+    else {
+        common_invokeMethodNoRange(convertCalleeToType(calleeMethod));
+    }
+    ///////////////////////////////
+    return 0;
+}
+#undef PP_GPR_1
+#undef PP_GPR_2
+#undef PP_GPR_3
+#undef PP_GPR_4
+
+//! helper function to handle no such method error
+
+//!
+int invoke_super_nsm() {
+    insertLabel(".invoke_super_nsm", false);
+    //NOTE: it seems that the name in %edx is not used in common_errNoSuchMethod
+    move_mem_to_reg(OpndSize_32, offMethod_name, PhysicalReg_EAX, true, PhysicalReg_EDX, true); //method name
+    unconditional_jump("common_errNoSuchMethod", false);
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ESI
+#define P_GPR_3 PhysicalReg_ECX
+#define PP_GPR_1 PhysicalReg_EBX
+#define PP_GPR_2 PhysicalReg_ESI
+#define PP_GPR_3 PhysicalReg_EAX
+#define PP_GPR_4 PhysicalReg_EDX
+//! common section to lower INVOKE_DIRECT
+
+//! It will use helper function if the switch is on
+int common_invoke_direct(bool isRange, u2 tmp, u2 vD) {
+    //%ecx can be used as scratch when calling export_pc, get_res_methods and resolve_method
+    export_pc();
+    constVREndOfBB();
+    beforeCall("exception"); //dump GG, GL VRs
+    ////////////////////////////////////
+    get_virtual_reg(vD, OpndSize_32, 5, false);
+    simpleNullCheck(5, false, vD);
+    /* method is already resolved in trace-based JIT */
+    const Method *calleeMethod =
+        currentMethod->clazz->pDvmDex->pResMethods[tmp];
+    move_imm_to_reg(OpndSize_32, (int) calleeMethod, PhysicalReg_ECX, true);
+    //%ecx passed to common_invokeMethod...
+    if(isRange) {
+        common_invokeMethodRange(convertCalleeToType(calleeMethod));
+    }
+    else {
+        common_invokeMethodNoRange(convertCalleeToType(calleeMethod));
+    }
+    ////////////////////////////
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef PP_GPR_1
+#undef PP_GPR_2
+#undef PP_GPR_3
+#undef PP_GPR_4
+
+#define P_GPR_1  PhysicalReg_EBX
+#define P_GPR_3  PhysicalReg_ECX
+#define PP_GPR_1 PhysicalReg_EBX
+#define PP_GPR_2 PhysicalReg_ESI
+#define PP_GPR_3 PhysicalReg_EAX
+#define PP_GPR_4 PhysicalReg_EDX
+//! common section to lower INVOKE_STATIC
+
+//! It will use helper function if the switch is on
+int common_invoke_static(bool isRange, u2 tmp) {
+    //%ecx can be used as scratch when calling export_pc, get_res_methods and resolve_method
+    export_pc();
+    constVREndOfBB();
+    beforeCall("exception"); //dump GG, GL VRs
+    ////////////////////////////
+    /* method is already resolved in trace-based JIT */
+    const Method *calleeMethod =
+        currentMethod->clazz->pDvmDex->pResMethods[tmp];
+    move_imm_to_reg(OpndSize_32, (int) calleeMethod, PhysicalReg_ECX, true);
+    //%ecx passed to common_invokeMethod...
+    if(isRange) {
+        common_invokeMethodRange(convertCalleeToType(calleeMethod));
+    }
+    else {
+        common_invokeMethodNoRange(convertCalleeToType(calleeMethod));
+    }
+    ////////////////////////
+    return 0;
+}
+#undef P_GPR_1
+#undef PP_GPR_1
+#undef PP_GPR_2
+#undef PP_GPR_3
+#undef PP_GPR_4
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_EAX //scratch
+#define P_GPR_3 PhysicalReg_ECX
+#define P_SCRATCH_1 PhysicalReg_ESI //clazz of object
+#define PP_GPR_1 PhysicalReg_EBX
+#define PP_GPR_2 PhysicalReg_ESI
+#define PP_GPR_3 PhysicalReg_EAX
+#define PP_GPR_4 PhysicalReg_EDX
+//! common section to lower INVOKE_INTERFACE
+
+//! It will use helper function if the switch is on
+int common_invoke_interface(bool isRange, u2 tmp, u2 vD) {
+#ifdef WITH_JIT_INLINING
+    /*
+     * If the invoke has non-null misPredBranchOver, we need to generate
+     * the non-inlined version of the invoke here to handle the
+     * mispredicted case.
+     */
+    if (traceCurrentMIR->meta.callsiteInfo->misPredBranchOver) {
+        genLandingPadForMispredictedCallee(); //cUnit, mir, bb, labelList);
+    }
+#endif
+    export_pc(); //use %edx
+    constVREndOfBB();
+    beforeCall("exception"); //dump GG, GL VRs
+    ///////////////////////
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    get_virtual_reg(vD, OpndSize_32, 1, false);
+    simpleNullCheck(1, false, vD);
+
+#ifndef PREDICTED_CHAINING
+    load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, tmp, 4, PhysicalReg_ESP, true);
+    /* for trace-based JIT, pDvmDex is a constant at JIT time
+       4th argument to dvmFindInterfaceMethodInCache at -4(%esp) */
+    move_imm_to_mem(OpndSize_32, (int) currentMethod->clazz->pDvmDex, 12, PhysicalReg_ESP, true);
+    move_mem_to_reg(OpndSize_32, offObject_clazz, 1, false, 5, false);
+    /* for trace-based JIT, method is a constant at JIT time
+       3rd argument to dvmFindInterfaceMethodInCache at 8(%esp) */
+    move_imm_to_mem(OpndSize_32, (int) currentMethod, 8, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 5, false, 0, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_3; scratchRegs[1] = PhysicalReg_Null;
+    call_dvmFindInterfaceMethodInCache();
+    load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+
+    conditional_jump_global_API(Condition_E, "common_exceptionThrown", false);
+    move_reg_to_reg(OpndSize_32, PhysicalReg_EAX, true, PhysicalReg_ECX, true);
+    if(isRange) {
+        common_invokeMethodRange(ArgsDone_Full);
+    }
+    else {
+        common_invokeMethodNoRange(ArgsDone_Full);
+    }
+#else
+    gen_predicted_chain(isRange, tmp, -1, true /*interface*/, 1/*tmp1*/);
+#endif
+    ///////////////////////
+    return 0;
+}
+#undef PP_GPR_1
+#undef PP_GPR_2
+#undef PP_GPR_3
+#undef PP_GPR_4
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef P_SCRATCH_1
+//! lower bytecode INVOKE_VIRTUAL by calling common_invoke_virtual
+
+//!
+int op_invoke_virtual() {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+#endif
+    //B|A|op CCCC G|F|E|D
+    //D: the first argument, which is the "this" pointer
+    //B: argument count
+    //D,E,F,G,A: arguments
+    u2 vD = FETCH(2) & 0xf;
+    u2 tmp = FETCH(1); //method index
+    int retval = common_invoke_virtual(false/*not range*/, tmp, vD);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_SUPER by calling common_invoke_super
+
+//!
+int op_invoke_super() {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+#endif
+    //B|A|op CCCC G|F|E|D
+    //D: the first argument
+    //B: argument count
+    //D,E,F,G,A: arguments
+    u2 tmp = FETCH(1); //method index
+    int retval = common_invoke_super(false/*not range*/, tmp);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_DIRECT by calling common_invoke_direct
+
+//!
+int op_invoke_direct() {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+#endif
+    //B|A|op CCCC G|F|E|D
+    //D: the first argument, which is the "this" pointer
+    //B: argument count
+    //D,E,F,G,A: arguments
+    u2 vD = FETCH(2) & 0xf;
+    u2 tmp = FETCH(1); //method index
+    int retval = common_invoke_direct(false/*not range*/, tmp, vD);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_STATIC by calling common_invoke_static
+
+//!
+int op_invoke_static() {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+#endif
+    //B|A|op CCCC G|F|E|D
+    //D: the first argument
+    //B: argument count
+    //D,E,F,G,A: arguments
+    u2 tmp = FETCH(1); //method index
+    int retval = common_invoke_static(false/*not range*/, tmp);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_INTERFACE by calling common_invoke_interface
+
+//!
+int op_invoke_interface() {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+#endif
+    //B|A|op CCCC G|F|E|D
+    //D: the first argument, which is the "this" pointer
+    //B: argument count
+    //D,E,F,G,A: arguments
+    u2 vD = FETCH(2) & 0xf;
+    u2 tmp = FETCH(1); //method index
+    int retval = common_invoke_interface(false/*not range*/, tmp, vD);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_VIRTUAL_RANGE by calling common_invoke_virtual
+
+//!
+int op_invoke_virtual_range() {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+#endif
+    //AA|op BBBB CCCC
+    //CCCC: the first argument, which is the "this" pointer
+    //AA: argument count
+    u2 tmp = FETCH(1); //BBBB, method index
+    u2 vD = FETCH(2); //the first argument
+    int retval = common_invoke_virtual(true/*range*/, tmp, vD);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_SUPER_RANGE by calling common_invoke_super
+
+//!
+int op_invoke_super_range() {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+#endif
+    u2 tmp = FETCH(1); //BBBB, method index
+    int retval = common_invoke_super(true/*range*/, tmp);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_DIRECT_RANGE by calling common_invoke_direct
+
+//!
+int op_invoke_direct_range() {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+#endif
+    u2 tmp = FETCH(1); //BBBB, method index
+    u2 vD = FETCH(2); //the first argument
+    int retval = common_invoke_direct(true/*range*/, tmp, vD);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_STATIC_RANGE by calling common_invoke_static
+
+//!
+int op_invoke_static_range() {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+#endif
+    u2 tmp = FETCH(1); //BBBB, method index
+    int retval = common_invoke_static(true/*range*/, tmp);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_INTERFACE_RANGE by calling common_invoke_interface
+
+//!
+int op_invoke_interface_range() {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+#endif
+    u2 tmp = FETCH(1); //BBBB, method index
+    u2 vD = FETCH(2); //the first argument
+    int retval = common_invoke_interface(true/*range*/, tmp, vD);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+
+//used %ecx, %edi, %esp %ebp
+#define P_GPR_1 PhysicalReg_EBX
+#define P_SCRATCH_1 PhysicalReg_ESI
+#define P_SCRATCH_2 PhysicalReg_EAX
+#define P_SCRATCH_3 PhysicalReg_EDX
+#define P_SCRATCH_4 PhysicalReg_ESI
+#define P_SCRATCH_5 PhysicalReg_EAX
+//! pass the arguments for invoking method without range
+
+//!
+int common_invokeMethodNoRange_noJmp() {
+    u2 count = INST_B(inst);
+    u2 vD = FETCH(2) & 0xf;
+    u2 vE = (FETCH(2) >> 4) & 0xf;
+    u2 vF = (FETCH(2) >> 8) & 0xf;
+    u2 vG = (FETCH(2) >> 12) & 0xf;
+    u2 vA = INST_A(inst); //5th argument
+    int offsetFromSaveArea = -4;
+    if(count == 5) {
+        get_virtual_reg(vA, OpndSize_32, 22, false);
+        move_reg_to_mem(OpndSize_32, 22, false, offsetFromSaveArea-sizeofStackSaveArea, PhysicalReg_FP, true);
+        offsetFromSaveArea -= 4;
+    }
+    if(count >= 4) {
+        get_virtual_reg(vG, OpndSize_32, 23, false);
+        move_reg_to_mem(OpndSize_32, 23, false, offsetFromSaveArea-sizeofStackSaveArea, PhysicalReg_FP, true);
+        offsetFromSaveArea -= 4;
+    }
+    if(count >= 3) {
+        get_virtual_reg(vF, OpndSize_32, 24, false);
+        move_reg_to_mem(OpndSize_32, 24, false, offsetFromSaveArea-sizeofStackSaveArea, PhysicalReg_FP, true);
+        offsetFromSaveArea -= 4;
+    }
+    if(count >= 2) {
+        get_virtual_reg(vE, OpndSize_32, 25, false);
+        move_reg_to_mem(OpndSize_32, 25, false, offsetFromSaveArea-sizeofStackSaveArea, PhysicalReg_FP, true);
+        offsetFromSaveArea -= 4;
+    }
+    if(count >= 1) {
+        get_virtual_reg(vD, OpndSize_32, 26, false);
+        move_reg_to_mem(OpndSize_32, 26, false, offsetFromSaveArea-sizeofStackSaveArea, PhysicalReg_FP, true);
+    }
+    return 0;
+}
+
+int common_invokeMethod_Jmp(ArgsDoneType form) {
+    nextVersionOfHardReg(PhysicalReg_EDX, 1);
+    move_imm_to_reg(OpndSize_32, (int)rPC, PhysicalReg_EDX, true);
+    //arguments needed in ArgsDone:
+    //    start of HotChainingCell for next bytecode: -4(%esp)
+    //    start of InvokeSingletonChainingCell for callee: -8(%esp)
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    insertChainingWorklist(traceCurrentBB->fallThrough->id, stream);
+    move_chain_to_mem(OpndSize_32, traceCurrentBB->fallThrough->id, 4, PhysicalReg_ESP, true);
+    // for honeycomb: JNI call doesn't need a chaining cell, so the taken branch is null
+    if(traceCurrentBB->taken)
+        insertChainingWorklist(traceCurrentBB->taken->id, stream);
+    int takenId = traceCurrentBB->taken ? traceCurrentBB->taken->id : 0;
+    move_chain_to_mem(OpndSize_32, takenId, 0, PhysicalReg_ESP, true);
+    if(form == ArgsDone_Full)
+        unconditional_jump_global_API(".invokeArgsDone_jit", false);
+    else if(form == ArgsDone_Native)
+        unconditional_jump_global_API(".invokeArgsDone_native", false);
+    else
+        unconditional_jump_global_API(".invokeArgsDone_normal", false);
+    return 0;
+}
+
+int common_invokeMethodNoRange(ArgsDoneType form) {
+    common_invokeMethodNoRange_noJmp();
+    common_invokeMethod_Jmp(form);
+    return 0;
+}
+
+#undef P_GPR_1
+#undef P_SCRATCH_1
+#undef P_SCRATCH_2
+#undef P_SCRATCH_3
+#undef P_SCRATCH_4
+#undef P_SCRATCH_5
+
+//input: %ecx (method to call)
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ESI
+#define P_GPR_3 PhysicalReg_EDX //not used with P_SCRATCH_2
+#define P_SCRATCH_1 PhysicalReg_EAX
+#define P_SCRATCH_2 PhysicalReg_EDX
+#define P_SCRATCH_3 PhysicalReg_EAX
+#define P_SCRATCH_4 PhysicalReg_EDX
+#define P_SCRATCH_5 PhysicalReg_EAX
+#define P_SCRATCH_6 PhysicalReg_EDX
+#define P_SCRATCH_7 PhysicalReg_EAX
+#define P_SCRATCH_8 PhysicalReg_EDX
+#define P_SCRATCH_9 PhysicalReg_EAX
+#define P_SCRATCH_10 PhysicalReg_EDX
+//! pass the arguments for invoking method with range
+
+//! loop is unrolled when count <= 10
+int common_invokeMethodRange_noJmp() {
+    u2 count = INST_AA(inst);
+    u2 vD = FETCH(2); //the first argument
+    savearea_from_fp(21, false);
+    //vD to rFP-4*count-20
+    //vD+1 to rFP-4*count-20+4 = rFP-20-4*(count-1)
+    if(count >= 1 && count <= 10) {
+        get_virtual_reg(vD, OpndSize_32, 22, false);
+        move_reg_to_mem(OpndSize_32, 22, false, -4*count, 21, false);
+    }
+    if(count >= 2 && count <= 10) {
+        get_virtual_reg(vD+1, OpndSize_32, 23, false);
+        move_reg_to_mem(OpndSize_32, 23, false, -4*(count-1), 21, false);
+    }
+    if(count >= 3 && count <= 10) {
+        get_virtual_reg(vD+2, OpndSize_32, 24, false);
+        move_reg_to_mem(OpndSize_32, 24, false, -4*(count-2), 21, false);
+    }
+    if(count >= 4 && count <= 10) {
+        get_virtual_reg(vD+3, OpndSize_32, 25, false);
+        move_reg_to_mem(OpndSize_32, 25, false, -4*(count-3), 21, false);
+    }
+    if(count >= 5 && count <= 10) {
+        get_virtual_reg(vD+4, OpndSize_32, 26, false);
+        move_reg_to_mem(OpndSize_32, 26, false, -4*(count-4), 21, false);
+    }
+    if(count >= 6 && count <= 10) {
+        get_virtual_reg(vD+5, OpndSize_32, 27, false);
+        move_reg_to_mem(OpndSize_32, 27, false, -4*(count-5), 21, false);
+    }
+    if(count >= 7 && count <= 10) {
+        get_virtual_reg(vD+6, OpndSize_32, 28, false);
+        move_reg_to_mem(OpndSize_32, 28, false, -4*(count-6), 21, false);
+    }
+    if(count >= 8 && count <= 10) {
+        get_virtual_reg(vD+7, OpndSize_32, 29, false);
+        move_reg_to_mem(OpndSize_32, 29, false, -4*(count-7), 21, false);
+    }
+    if(count >= 9 && count <= 10) {
+        get_virtual_reg(vD+8, OpndSize_32, 30, false);
+        move_reg_to_mem(OpndSize_32, 30, false, -4*(count-8), 21, false);
+    }
+    if(count == 10) {
+        get_virtual_reg(vD+9, OpndSize_32, 31, false);
+        move_reg_to_mem(OpndSize_32, 31, false, -4*(count-9), 21, false);
+    }
+    if(count > 10) {
+        //dump to memory first, should we set physicalReg to Null?
+        //this bytecodes uses a set of virtual registers (update getVirtualInfo)
+        //this is necessary to correctly insert transfer points
+        int k;
+        for(k = 0; k < count; k++) {
+            spillVirtualReg(vD+k, LowOpndRegType_gp, true); //will update refCount
+        }
+        load_effective_addr(4*vD, PhysicalReg_FP, true, 12, false);
+        alu_binary_imm_reg(OpndSize_32, sub_opc, 4*count, 21, false);
+        move_imm_to_reg(OpndSize_32, count, 13, false);
+        insertLabel(".invokeMethod_1", true); //if checkDup: will perform work from ShortWorklist
+        rememberState(1);
+        move_mem_to_reg(OpndSize_32, 0, 12, false, 14, false);
+        move_reg_to_mem(OpndSize_32, 14, false, 0, 21, false);
+        load_effective_addr(4, 12, false, 12, false);
+        alu_binary_imm_reg(OpndSize_32, sub_opc, 1, 13, false);
+        load_effective_addr(4, 21, false, 21, false);
+        transferToState(1);
+        conditional_jump(Condition_NE, ".invokeMethod_1", true); //backward branch
+    }
+    return 0;
+}
+
+int common_invokeMethodRange(ArgsDoneType form) {
+    common_invokeMethodRange_noJmp();
+    common_invokeMethod_Jmp(form);
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef P_SCRATCH_1
+#undef P_SCRATCH_2
+#undef P_SCRATCH_3
+#undef P_SCRATCH_4
+#undef P_SCRATCH_5
+#undef P_SCRATCH_6
+#undef P_SCRATCH_7
+#undef P_SCRATCH_8
+#undef P_SCRATCH_9
+#undef P_SCRATCH_10
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_3 PhysicalReg_ESI
+#define P_SCRATCH_1 PhysicalReg_EAX
+#define P_SCRATCH_2 PhysicalReg_EDX
+#define P_SCRATCH_3 PhysicalReg_EAX
+#define P_SCRATCH_4 PhysicalReg_EDX
+#define P_SCRATCH_5 PhysicalReg_EAX
+#define P_SCRATCH_6 PhysicalReg_EDX
+
+//! spill a register to native stack
+
+//! decrease %esp by 4, then store a register at 0(%esp)
+int spill_reg(int reg, bool isPhysical) {
+    load_effective_addr(-4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, reg, isPhysical, 0, PhysicalReg_ESP, true);
+    return 0;
+}
+//! get a register from native stack
+
+//! load a register from 0(%esp), then increase %esp by 4
+int unspill_reg(int reg, bool isPhysical) {
+    move_mem_to_reg(OpndSize_32, 0, PhysicalReg_ESP, true, reg, isPhysical);
+    load_effective_addr(4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    return 0;
+}
+
+void generate_invokeNative(bool generateForNcg); //forward declaration
+void generate_stackOverflow(); //forward declaration
+
+//! common code to invoke a method after all arguments are handled
+
+//!
+//takes one argument to generate code
+//  for invokeNativeSingle (form == ArgsDone_Native)
+//   or invokeNonNativeSingle (form == ArgsDone_Normal) when WITH_JIT is true
+//   to dynamically determine which one to choose (form == ArgsDone_Full)
+/* common_invokeArgsDone is called at NCG time and
+     at execution time during relocation
+   generate invokeArgsDone for NCG if isJitFull is false && form == Full */
+int common_invokeArgsDone(ArgsDoneType form, bool isJitFull) {
+    bool generateForNcg = false;
+    if(form == ArgsDone_Full) {
+        if(isJitFull)
+            insertLabel(".invokeArgsDone_jit", false);
+        else {
+            insertLabel(".invokeArgsDone", false);
+            generateForNcg = true;
+        }
+    }
+    else if(form == ArgsDone_Normal)
+        insertLabel(".invokeArgsDone_normal", false);
+    else if(form == ArgsDone_Native)
+        insertLabel(".invokeArgsDone_native", false);
+    //%ecx: methodToCall
+    movez_mem_to_reg(OpndSize_16, offMethod_registersSize, PhysicalReg_ECX, true, P_SCRATCH_1, true); //regSize
+    scratchRegs[0] = PhysicalReg_EBX; scratchRegs[1] = PhysicalReg_ESI;
+    scratchRegs[2] = PhysicalReg_EDX; scratchRegs[3] = PhysicalReg_Null;
+    savearea_from_fp(P_GPR_3, true);
+    alu_binary_imm_reg(OpndSize_32, shl_opc, 2, P_SCRATCH_1, true);
+    alu_binary_reg_reg(OpndSize_32, sub_opc, P_SCRATCH_1, true, P_GPR_3, true);
+    //update newSaveArea->savedPc, here P_GPR_3 is new FP
+    move_reg_to_mem(OpndSize_32, PhysicalReg_EDX, true, offStackSaveArea_savedPc-sizeofStackSaveArea, P_GPR_3, true);
+    movez_mem_to_reg(OpndSize_16, offMethod_outsSize, PhysicalReg_ECX, true, P_SCRATCH_2, true); //outsSize
+    move_reg_to_reg(OpndSize_32, P_GPR_3, true, P_GPR_1, true); //new FP
+    alu_binary_imm_reg(OpndSize_32, sub_opc, sizeofStackSaveArea, P_GPR_3, true);
+
+    alu_binary_imm_reg(OpndSize_32, shl_opc, 2, P_SCRATCH_2, true);
+    alu_binary_reg_reg(OpndSize_32, sub_opc, P_SCRATCH_2, true, P_GPR_3, true);
+    get_self_pointer(P_SCRATCH_3, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_FP, true, offStackSaveArea_prevFrame-sizeofStackSaveArea, P_GPR_1, true); //set stack->prevFrame
+    compare_mem_reg(OpndSize_32, offsetof(Thread, interpStackEnd), P_SCRATCH_3, true, P_GPR_3, true);
+    conditional_jump(Condition_L, ".stackOverflow", true);
+
+    if(form == ArgsDone_Full) {
+        test_imm_mem(OpndSize_32, ACC_NATIVE, offMethod_accessFlags, PhysicalReg_ECX, true);
+    }
+    move_reg_to_mem(OpndSize_32, PhysicalReg_ECX, true, offStackSaveArea_method-sizeofStackSaveArea, P_GPR_1, true); //set stack->method
+
+    if(form == ArgsDone_Native || form == ArgsDone_Full) {
+        /* to correctly handle code cache reset:
+           update returnAddr and check returnAddr after done with the native method
+           if returnAddr is set to NULL during code cache reset,
+           the execution will correctly continue with interpreter */
+        //get returnAddr from 4(%esp) and update stack
+        move_mem_to_reg(OpndSize_32, 4, PhysicalReg_ESP, true,
+                        PhysicalReg_EDX, true);
+        move_reg_to_mem(OpndSize_32, PhysicalReg_EDX, true,
+                        offStackSaveArea_returnAddr-sizeofStackSaveArea, P_GPR_1, true);
+    }
+    if(form == ArgsDone_Native) {
+        generate_invokeNative(generateForNcg);
+        return 0;
+    }
+    if(form == ArgsDone_Full) {
+        conditional_jump(Condition_NE, ".invokeNative", true);
+    }
+    move_mem_to_reg(OpndSize_32, offMethod_clazz, PhysicalReg_ECX, true, P_SCRATCH_4, true); //get method->claz
+    move_mem_to_reg(OpndSize_32, offClassObject_pDvmDex, P_SCRATCH_4, true, P_SCRATCH_4, true); //get method->clazz->pDvmDex
+    move_reg_to_reg(OpndSize_32, P_GPR_1, true, PhysicalReg_FP, true); //update rFP
+    get_self_pointer(P_GPR_1, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_ECX, true, offsetof(Thread, interpSave.method), P_GPR_1, true); //glue->method
+    move_reg_to_mem(OpndSize_32, P_SCRATCH_4, true, offsetof(Thread, interpSave.methodClassDex), P_GPR_1, true); //set_glue_dvmdex
+    move_reg_to_mem(OpndSize_32, PhysicalReg_FP, true, offThread_curFrame, P_GPR_1, true); //set glue->self->frame
+    if(!generateForNcg) {
+        /* returnAddr updated already for Full */
+        //get returnAddr from 4(%esp) and update stack
+        if(form == ArgsDone_Normal)
+            move_mem_to_reg(OpndSize_32, 4, PhysicalReg_ESP, true,
+                            PhysicalReg_EDX, true);
+        //for JIT: starting bytecode in %ebx to invoke JitToInterp
+        move_mem_to_reg(OpndSize_32, offMethod_insns, PhysicalReg_ECX, true, PhysicalReg_EBX, true);
+        if(form == ArgsDone_Normal)
+            move_reg_to_mem(OpndSize_32, PhysicalReg_EDX, true,
+                            offStackSaveArea_returnAddr-sizeofStackSaveArea, PhysicalReg_FP, true);
+    }
+
+    insertLabel(".invokeInterp", true);
+    if(!generateForNcg) {
+        bool callNoChain = false;
+#ifdef PREDICTED_CHAINING
+        if(form == ArgsDone_Full) callNoChain = true;
+#endif
+        if(callNoChain) {
+            scratchRegs[0] = PhysicalReg_EAX;
+            load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+            call_dvmJitToInterpTraceSelectNoChain(); //input: rPC in %ebx
+        } else {
+            //jump to the stub at (%esp)
+            move_mem_to_reg(OpndSize_32, 0, PhysicalReg_ESP, true,
+                            PhysicalReg_EDX, true);
+            load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+            unconditional_jump_reg(PhysicalReg_EDX, true);
+        }
+    }
+
+    if(form == ArgsDone_Full) generate_invokeNative(generateForNcg);
+    generate_stackOverflow();
+    return 0;
+}
+
+/* when WITH_JIT is true,
+     JIT'ed code invokes native method, after invoke, execution will continue
+     with the interpreter or with JIT'ed code if chained
+*/
+void generate_invokeNative(bool generateForNcg) {
+    insertLabel(".invokeNative", true);
+    //if(!generateForNcg)
+    //    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    load_effective_addr(-28, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, P_GPR_1, true, 0, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, P_GPR_1, true, 20, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_EDX;
+    get_self_pointer(P_SCRATCH_1, true); //glue->self
+    move_reg_to_mem(OpndSize_32, PhysicalReg_ECX, true, 8, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, P_SCRATCH_1, true, 12, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, P_SCRATCH_1, true, 24, PhysicalReg_ESP, true);
+    move_mem_to_reg(OpndSize_32, offThread_jniLocal_nextEntry, P_SCRATCH_1, true, P_SCRATCH_2, true); //get self->local_next
+    scratchRegs[1] = PhysicalReg_EAX;
+    move_reg_to_mem(OpndSize_32, P_SCRATCH_2, true, offStackSaveArea_localRefTop-sizeofStackSaveArea, P_GPR_1, true); //update jniLocalRef of stack
+    move_reg_to_mem(OpndSize_32, P_GPR_1, true, offThread_curFrame, P_SCRATCH_1, true); //set self->curFrame
+    move_imm_to_mem(OpndSize_32, 0, offThread_inJitCodeCache, P_SCRATCH_1, true); //clear self->inJitCodeCache
+    load_effective_addr(offsetof(Thread, interpSave.retval), P_SCRATCH_1, true, P_SCRATCH_3, true); //self->retval
+    move_reg_to_mem(OpndSize_32, P_SCRATCH_3, true, 4, PhysicalReg_ESP, true);
+    //NOTE: native method checks the interpreted stack for arguments
+    //      The immediate arguments on native stack: address of return value, new FP, self
+    call_mem(40, PhysicalReg_ECX, true);//*40(%ecx)
+    //we can't assume the argument stack is unmodified after the function call
+    //duplicate newFP & glue->self on stack: newFP (-28 & -8) glue->self (-16 & -4)
+    move_mem_to_reg(OpndSize_32, 20, PhysicalReg_ESP, true, P_GPR_3, true); //new FP
+    move_mem_to_reg(OpndSize_32, 24, PhysicalReg_ESP, true, P_GPR_1, true); //glue->self
+    load_effective_addr(28, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_mem_to_reg(OpndSize_32, offStackSaveArea_localRefTop-sizeofStackSaveArea, P_GPR_3, true, P_SCRATCH_1, true); //newSaveArea->jniLocal
+    compare_imm_mem(OpndSize_32, 0, offThread_exception, P_GPR_1, true); //self->exception
+    if(!generateForNcg)
+        load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    //NOTE: PhysicalReg_FP should be callee-saved register
+    move_reg_to_mem(OpndSize_32, PhysicalReg_FP, true, offThread_curFrame, P_GPR_1, true); //set self->curFrame
+    move_reg_to_mem(OpndSize_32, P_SCRATCH_1, true, offThread_jniLocal_nextEntry, P_GPR_1, true); //set self->jniLocal
+    conditional_jump(Condition_NE, "common_exceptionThrown", false);
+    if(!generateForNcg) {
+        //get returnAddr, if it is not NULL,
+        //    return to JIT'ed returnAddr after executing the native method
+        /* to correctly handle code cache reset:
+           update returnAddr and check returnAddr after done with the native method
+           if returnAddr is set to NULL during code cache reset,
+           the execution will correctly continue with interpreter */
+        move_mem_to_reg(OpndSize_32, offStackSaveArea_returnAddr-sizeofStackSaveArea, P_GPR_3, true, P_SCRATCH_2, true);
+        //set self->inJitCodeCache to returnAddr (P_GPR_1 is in %ebx)
+        move_reg_to_mem(OpndSize_32, P_SCRATCH_2, true, offThread_inJitCodeCache, P_GPR_1, true);
+        move_mem_to_reg(OpndSize_32, offStackSaveArea_savedPc-sizeofStackSaveArea, P_GPR_3, true, PhysicalReg_EBX, true); //savedPc
+        compare_imm_reg(OpndSize_32, 0, P_SCRATCH_2, true);
+        conditional_jump(Condition_E, ".nativeToInterp", true);
+        unconditional_jump_reg(P_SCRATCH_2, true);
+        //if returnAddr is NULL, return to interpreter after executing the native method
+        insertLabel(".nativeToInterp", true);
+        //move rPC by 6 (3 bytecode units for INVOKE)
+        alu_binary_imm_reg(OpndSize_32, add_opc, 6, PhysicalReg_EBX, true);
+        scratchRegs[0] = PhysicalReg_EAX;
+        call_dvmJitToInterpTraceSelectNoChain(); //rPC in %ebx
+    }
+    return;
+}
+void generate_stackOverflow() {
+    insertLabel(".stackOverflow", true);
+    //load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_ECX, true, 4, PhysicalReg_ESP, true);
+    get_self_pointer(P_GPR_1, true); //glue->self
+    move_reg_to_mem(OpndSize_32, P_GPR_1, true, 0, PhysicalReg_ESP, true);
+    call_dvmHandleStackOverflow();
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    unconditional_jump("common_exceptionThrown", false);
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef P_SCRATCH_1
+#undef P_SCRATCH_2
+#undef P_SCRATCH_3
+#undef P_SCRATCH_4
+#undef P_SCRATCH_5
+#undef P_SCRATCH_6
+
+/////////////////////////////////////////////
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+#define P_SCRATCH_1 PhysicalReg_ESI
+#define P_SCRATCH_2 PhysicalReg_EDX
+#define P_SCRATCH_3 PhysicalReg_ESI
+#define P_SCRATCH_4 PhysicalReg_EDX
+//! lower bytecode EXECUTE_INLINE
+
+//!
+int op_execute_inline(bool isRange) {
+    //tmp, vC, vD, vE, vF
+    int num;
+    if(!isRange) num = INST_B(inst);
+    else num = INST_AA(inst);
+    u2 tmp = FETCH(1);
+    u2 vC, vD, vE, vF;
+    if(!isRange) {
+        vC = FETCH(2) & 0xf;
+        vD = (FETCH(2) >> 4) & 0xf;
+        vE = (FETCH(2) >> 8) & 0xf;
+        vF = FETCH(2) >> 12;
+    } else {
+        vC = FETCH(2);
+        vD = vC + 1;
+        vE = vC + 2;
+        vF = vC + 3;
+    }
+    export_pc();
+    switch (tmp) {
+        case INLINE_EMPTYINLINEMETHOD:
+            return 0;  /* Nop */
+        case INLINE_STRING_LENGTH:
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            compare_imm_reg(OpndSize_32, 0, 1, false);
+            conditional_jump(Condition_NE, ".do_inlined_string_length", true);
+            scratchRegs[0] = PhysicalReg_SCRATCH_1;
+            jumpToExceptionThrown(1/*exception number*/);
+            insertLabel(".do_inlined_string_length", true);
+            move_mem_to_reg(OpndSize_32, 0x14, 1, false, 2, false);
+            get_self_pointer(3, false);
+            move_reg_to_mem(OpndSize_32, 2, false, offsetof(Thread, interpSave.retval), 3, false);
+            return 0;
+        case INLINE_STRING_IS_EMPTY:
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            compare_imm_reg(OpndSize_32, 0, 1, false);
+            conditional_jump(Condition_NE, ".do_inlined_string_length", true);
+            scratchRegs[0] = PhysicalReg_SCRATCH_1;
+            jumpToExceptionThrown(1/*exception number*/);
+            insertLabel(".do_inlined_string_length", true);
+            compare_imm_mem(OpndSize_32, 0, 0x14, 1, false);
+            conditional_jump(Condition_E, ".inlined_string_length_return_true",
+                             true);
+            get_self_pointer(2, false);
+            move_imm_to_mem(OpndSize_32, 0, offsetof(Thread, interpSave.retval), 2, false);
+            unconditional_jump(".inlined_string_length_done", true);
+            insertLabel(".inlined_string_length_return_true", true);
+            get_self_pointer(2, false);
+            move_imm_to_mem(OpndSize_32, 1, offsetof(Thread, interpSave.retval), 2, false);
+            insertLabel(".inlined_string_length_done", true);
+            return 0;
+        case INLINE_MATH_ABS_INT:
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            move_reg_to_reg(OpndSize_32, 1, false, 2, false);
+            alu_binary_imm_reg(OpndSize_32, sar_opc, 0x1f, 2, false);
+            alu_binary_reg_reg(OpndSize_32, xor_opc, 2, false, 1, false);
+            alu_binary_reg_reg(OpndSize_32, sub_opc, 2, false, 1, false);
+            get_self_pointer(3, false);
+            move_reg_to_mem(OpndSize_32, 1, false, offsetof(Thread, interpSave.retval), 3, false);
+            return 0;
+        case INLINE_MATH_ABS_LONG:
+            get_virtual_reg(vD, OpndSize_32, 1, false);
+            move_reg_to_reg(OpndSize_32, 1, false, 2, false);
+            alu_binary_imm_reg(OpndSize_32, sar_opc, 0x1f, 1, false);
+            move_reg_to_reg(OpndSize_32, 1, false, 3, false);
+            move_reg_to_reg(OpndSize_32, 1, false, 4, false);
+            get_virtual_reg(vC, OpndSize_32, 5, false);
+            alu_binary_reg_reg(OpndSize_32, xor_opc, 5, false, 1, false);
+            get_self_pointer(6, false);
+            move_reg_to_mem(OpndSize_32, 1, false, offsetof(Thread, interpSave.retval), 6, false);
+            alu_binary_reg_reg(OpndSize_32, xor_opc, 2, false, 3, false);
+            move_reg_to_mem(OpndSize_32, 3, false, 4 + offsetof(Thread, interpSave.retval), 6, false);
+            alu_binary_reg_mem(OpndSize_32, sub_opc, 4, false, offsetof(Thread, interpSave.retval), 6, false);
+            alu_binary_reg_mem(OpndSize_32, sbb_opc, 4, false, 4 + offsetof(Thread, interpSave.retval), 6, false);
+            return 0;
+        case INLINE_MATH_MAX_INT:
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            get_virtual_reg(vD, OpndSize_32, 2, false);
+            compare_reg_reg(1, false, 2, false);
+            conditional_move_reg_to_reg(OpndSize_32, Condition_GE, 2,
+                                        false/*src*/, 1, false/*dst*/);
+            get_self_pointer(3, false);
+            move_reg_to_mem(OpndSize_32, 1, false, offsetof(Thread, interpSave.retval), 3, false);
+            return 0;
+        case INLINE_MATH_ABS_FLOAT:
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            alu_binary_imm_reg(OpndSize_32, and_opc, 0x7fffffff, 1, false);
+            get_self_pointer(2, false);
+            move_reg_to_mem(OpndSize_32, 1, false, offsetof(Thread, interpSave.retval), 2, false);
+            return 0;
+        case INLINE_MATH_ABS_DOUBLE:
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            get_virtual_reg(vD, OpndSize_32, 2, false);
+            alu_binary_imm_reg(OpndSize_32, and_opc, 0x7fffffff, 2, false);
+            get_self_pointer(3, false);
+            move_reg_to_mem(OpndSize_32, 1, false, offsetof(Thread, interpSave.retval), 3, false);
+            move_reg_to_mem(OpndSize_32, 2, false, 4 + offsetof(Thread, interpSave.retval), 3, false);
+            return 0;
+        case INLINE_STRING_FASTINDEXOF_II:
+#if defined(USE_GLOBAL_STRING_DEFS)
+            break;
+#else
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            compare_imm_reg(OpndSize_32, 0, 1, false);
+            get_virtual_reg(vD, OpndSize_32, 2, false);
+            get_virtual_reg(vE, OpndSize_32, 3, false);
+            conditional_jump(Condition_NE, ".do_inlined_string_fastIndexof",
+                             true);
+            scratchRegs[0] = PhysicalReg_SCRATCH_1;
+            jumpToExceptionThrown(1/*exception number*/);
+            insertLabel(".do_inlined_string_fastIndexof", true);
+            move_mem_to_reg(OpndSize_32, 0x14, 1, false, 4, false);
+            move_mem_to_reg(OpndSize_32, 0x8, 1, false, 5, false);
+            move_mem_to_reg(OpndSize_32, 0x10, 1, false, 6, false);
+            alu_binary_reg_reg(OpndSize_32, xor_opc, 1, false, 1, false);
+            compare_imm_reg(OpndSize_32, 0, 3, false);
+            conditional_move_reg_to_reg(OpndSize_32, Condition_NS, 3, false, 1,
+                                        false);
+            compare_reg_reg(4, false, 1, false);
+            conditional_jump(Condition_GE,
+                             ".do_inlined_string_fastIndexof_exitfalse", true);
+            dump_mem_scale_reg(Mnemonic_LEA, OpndSize_32, 5, false, 0xc/*disp*/,
+                               6, false, 2, 5, false, LowOpndRegType_gp);
+            movez_mem_disp_scale_to_reg(OpndSize_16, 5, false, 0, 1, false, 2,
+                                        3, false);
+            compare_reg_reg(3, false, 2, false);
+            conditional_jump(Condition_E, ".do_inlined_string_fastIndexof_exit",
+                             true);
+            load_effective_addr(0x1, 1, false, 3, false);
+            load_effective_addr_scale(5, false, 3, false, 2, 5, false);
+            unconditional_jump(".do_inlined_string_fastIndexof_iter", true);
+            insertLabel(".do_inlined_string_fastIndexof_ch_cmp", true);
+            if(gDvm.executionMode == kExecutionModeNcgO1) {
+                rememberState(1);
+            }
+            movez_mem_to_reg(OpndSize_16, 0, 5, false, 6, false);
+            load_effective_addr(0x2, 5, false, 5, false);
+            compare_reg_reg(6, false, 2, false);
+            conditional_jump(Condition_E, ".do_inlined_string_fastIndexof_exit",
+                             true);
+            load_effective_addr(0x1, 3, false, 3, false);
+            insertLabel(".do_inlined_string_fastIndexof_iter", true);
+            compare_reg_reg(4, false, 3, false);
+            move_reg_to_reg(OpndSize_32, 3, false, 1, false);
+            if(gDvm.executionMode == kExecutionModeNcgO1) {
+                transferToState(1);
+            }
+            conditional_jump(Condition_NE,
+                             ".do_inlined_string_fastIndexof_ch_cmp", true);
+            insertLabel(".do_inlined_string_fastIndexof_exitfalse", true);
+            move_imm_to_reg(OpndSize_32, 0xffffffff, 1,  false);
+            insertLabel(".do_inlined_string_fastIndexof_exit", true);
+            get_self_pointer(7, false);
+            move_reg_to_mem(OpndSize_32, 1, false, offsetof(Thread, interpSave.retval), 7, false);
+            return 0;
+        case INLINE_FLOAT_TO_RAW_INT_BITS:
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            get_self_pointer(2, false);
+            move_reg_to_mem(OpndSize_32, 1, false, offsetof(Thread, interpSave.retval), 2, false);
+            return 0;
+        case INLINE_INT_BITS_TO_FLOAT:
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            get_self_pointer(2, false);
+            move_reg_to_mem(OpndSize_32, 1, false, offsetof(Thread, interpSave.retval), 2, false);
+            return 0;
+        case INLINE_DOUBLE_TO_RAW_LONG_BITS:
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            get_self_pointer(3, false);
+            move_reg_to_mem(OpndSize_32, 1, false, offsetof(Thread, interpSave.retval), 3, false);
+            get_virtual_reg(vD, OpndSize_32, 2, false);
+            move_reg_to_mem(OpndSize_32, 2, false, 4 + offsetof(Thread, interpSave.retval), 3, false);
+            return 0;
+        case INLINE_LONG_BITS_TO_DOUBLE:
+            get_virtual_reg(vC, OpndSize_32, 1, false);
+            get_virtual_reg(vD, OpndSize_32, 2, false);
+            get_self_pointer(3, false);
+            move_reg_to_mem(OpndSize_32, 2, false, 4 + offsetof(Thread, interpSave.retval), 3, false);
+            move_reg_to_mem(OpndSize_32, 1, false, offsetof(Thread, interpSave.retval), 3, false);
+            return 0;
+        default:
+                break;
+    }
+#endif
+    get_self_pointer(PhysicalReg_SCRATCH_1, false);
+    load_effective_addr(offsetof(Thread, interpSave.retval), PhysicalReg_SCRATCH_1, false, 1, false);
+    load_effective_addr(-24, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 1, false, 16, PhysicalReg_ESP, true);
+    if(num >= 1) {
+        get_virtual_reg(vC, OpndSize_32, 2, false);
+        move_reg_to_mem(OpndSize_32, 2, false, 0, PhysicalReg_ESP, true);
+    }
+    if(num >= 2) {
+        get_virtual_reg(vD, OpndSize_32, 3, false);
+        move_reg_to_mem(OpndSize_32, 3, false, 4, PhysicalReg_ESP, true);
+    }
+    if(num >= 3) {
+        get_virtual_reg(vE, OpndSize_32, 4, false);
+        move_reg_to_mem(OpndSize_32, 4, false, 8, PhysicalReg_ESP, true);
+    }
+    if(num >= 4) {
+        get_virtual_reg(vF, OpndSize_32, 5, false);
+        move_reg_to_mem(OpndSize_32, 5, false, 12, PhysicalReg_ESP, true);
+    }
+    beforeCall("execute_inline");
+    load_imm_global_data_API("gDvmInlineOpsTable", OpndSize_32, 6, false);
+    call_mem(16*tmp, 6, false);//
+    afterCall("execute_inline");
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+
+    load_effective_addr(24, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    conditional_jump(Condition_NE, ".execute_inline_done", true);
+    //jump to dvmJitToExceptionThrown
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    jumpToExceptionThrown(1/*exception number*/);
+    insertLabel(".execute_inline_done", true);
+    rPC += 3;
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_SCRATCH_1
+#undef P_SCRATCH_2
+#undef P_SCRATCH_3
+#undef P_SCRATCH_4
+
+//! lower bytecode INVOKE_OBJECT_INIT_RANGE
+
+//!
+int op_invoke_object_init_range() {
+    return -1;
+}
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_SCRATCH_1 PhysicalReg_ESI
+#define P_SCRATCH_2 PhysicalReg_EDX
+#define PP_GPR_1 PhysicalReg_EBX
+#define PP_GPR_2 PhysicalReg_ESI
+#define PP_GPR_3 PhysicalReg_EAX
+#define PP_GPR_4 PhysicalReg_EDX
+//! common code for INVOKE_VIRTUAL_QUICK
+
+//! It uses helper function if the switch is on
+int common_invoke_virtual_quick(bool hasRange, u2 vD, u2 IMMC) {
+#ifdef WITH_JIT_INLINING
+    /* An invoke with the MIR_INLINED is effectively a no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return false;
+    /*
+     * If the invoke has non-null misPredBranchOver, we need to generate
+     * the non-inlined version of the invoke here to handle the
+     * mispredicted case.
+     */
+    if (traceCurrentMIR->meta.callsiteInfo->misPredBranchOver) {
+        genLandingPadForMispredictedCallee(); //cUnit, mir, bb, labelList);
+    }
+#endif
+    export_pc();
+    constVREndOfBB();
+    beforeCall("exception"); //dump GG, GL VRs
+    /////////////////////////////////////////////////
+    get_virtual_reg(vD, OpndSize_32, 1, false);
+    simpleNullCheck(1, false, vD);
+#ifndef PREDICTED_CHAINING
+    move_mem_to_reg(OpndSize_32, 0, 1, false, 2, false);
+    move_mem_to_reg(OpndSize_32, offClassObject_vtable, 2, false, 3, false);
+    move_mem_to_reg(OpndSize_32, IMMC, 3, false, PhysicalReg_ECX, true);
+
+    if(hasRange) {
+        common_invokeMethodRange(ArgsDone_Full);
+    }
+    else {
+        common_invokeMethodNoRange(ArgsDone_Full);
+    }
+#else
+    gen_predicted_chain(hasRange, -1, IMMC, false, 1/*tmp1*/);
+#endif
+    ////////////////////////
+    return 0;
+}
+#undef P_GPR_1
+#undef P_SCRATCH_1
+#undef P_SCRATCH_2
+#undef PP_GPR_1
+#undef PP_GPR_2
+#undef PP_GPR_3
+#undef PP_GPR_4
+//! lower bytecode INVOKE_VIRTUAL_QUICK by calling common_invoke_virtual_quick
+
+//!
+int op_invoke_virtual_quick() {
+    u2 vD = FETCH(2) & 0xf;
+    u2 IMMC = 4*FETCH(1);
+    int retval = common_invoke_virtual_quick(false, vD, IMMC);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_VIRTUAL_QUICK_RANGE by calling common_invoke_virtual_quick
+
+//!
+int op_invoke_virtual_quick_range() {
+    u2 vD = FETCH(2);
+    u2 IMMC = 4*FETCH(1);
+    int retval = common_invoke_virtual_quick(true, vD, IMMC);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ESI
+#define P_SCRATCH_1 PhysicalReg_EDX
+//! common code to lower INVOKE_SUPER_QUICK
+
+//!
+int common_invoke_super_quick(bool hasRange, u2 vD, u2 IMMC) {
+    export_pc();
+    constVREndOfBB();
+    beforeCall("exception"); //dump GG, GL VRs
+    compare_imm_VR(OpndSize_32, 0, vD);
+
+    conditional_jump_global_API(Condition_E, "common_errNullObject", false);
+    /* for trace-based JIT, callee is already resolved */
+    int mIndex = IMMC/4;
+    const Method *calleeMethod = currentMethod->clazz->super->vtable[mIndex];
+    move_imm_to_reg(OpndSize_32, (int) calleeMethod, PhysicalReg_ECX, true);
+    if(hasRange) {
+        common_invokeMethodRange(convertCalleeToType(calleeMethod));
+    }
+    else {
+        common_invokeMethodNoRange(convertCalleeToType(calleeMethod));
+    }
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_SCRATCH_1
+//! lower bytecode INVOKE_SUPER_QUICK by calling common_invoke_super_quick
+
+//!
+int op_invoke_super_quick() {
+    u2 vD = FETCH(2) & 0xf;
+    u2 IMMC = 4*FETCH(1);
+    int retval = common_invoke_super_quick(false, vD, IMMC);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+//! lower bytecode INVOKE_SUPER_QUICK_RANGE by calling common_invoke_super_quick
+
+//!
+int op_invoke_super_quick_range() {
+    u2 vD = FETCH(2);
+    u2 IMMC = 4*FETCH(1);
+    int retval = common_invoke_super_quick(true, vD, IMMC);
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC+3, stream - streamMethodStart, 1); //check when helper switch is on
+#endif
+    rPC += 3;
+    return retval;
+}
+/////// code to predict the callee method for invoke_virtual & invoke_interface
+#define offChainingCell_clazz 8
+#define offChainingCell_method 12
+#define offChainingCell_counter 16
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_EAX
+#define P_GPR_3 PhysicalReg_ESI
+#define P_SCRATCH_2 PhysicalReg_EDX
+/* TODO gingerbread: implemented for O1, but not for O0:
+   valid input to JitToPatch & use icRechainCount */
+/* update predicted method for invoke interface */
+// 2 inputs: ChainingCell in P_GPR_1, current class object in P_GPR_3
+void predicted_chain_interface_O0(u2 tmp) {
+    ALOGI("TODO chain_interface_O0");
+
+    /* set up arguments to dvmFindInterfaceMethodInCache */
+    load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, tmp, 4, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, (int) currentMethod->clazz->pDvmDex, 12, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, (int) currentMethod, 8, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, P_GPR_3, true, 0, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_EDX;
+    call_dvmFindInterfaceMethodInCache();
+    load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+
+    /* if dvmFindInterfaceMethodInCache returns NULL, throw exception
+       otherwise, jump to .find_interface_done */
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump(Condition_NE, ".find_interface_done", true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    jumpToExceptionThrown(1/*exception number*/);
+
+    /* the interface method is found */
+    insertLabel(".find_interface_done", true);
+    /* reduce counter in chaining cell by 1 */
+    move_mem_to_reg(OpndSize_32, offChainingCell_counter, P_GPR_1, true, P_SCRATCH_2, true); //counter
+    alu_binary_imm_reg(OpndSize_32, sub_opc, 0x1, P_SCRATCH_2, true);
+    move_reg_to_mem(OpndSize_32, P_SCRATCH_2, true, offChainingCell_counter, P_GPR_1, true);
+
+    /* if counter is still greater than zero, skip prediction
+       if it is zero, update predicted method */
+    compare_imm_reg(OpndSize_32, 0, P_SCRATCH_2, true);
+    conditional_jump(Condition_G, ".skipPrediction", true);
+
+    /* call dvmJitToPatchPredictedChain to update predicted method */
+    //%ecx has callee method for virtual, %eax has callee for interface
+    /* set up arguments for dvmJitToPatchPredictedChain */
+    load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_EAX, true, 0, PhysicalReg_ESP, true);
+    insertChainingWorklist(traceCurrentBB->taken->id, stream);
+    move_chain_to_mem(OpndSize_32, traceCurrentBB->taken->id, 8, PhysicalReg_ESP, true); //predictedChainCell
+    move_reg_to_mem(OpndSize_32, P_GPR_3, true, 12, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_dvmJitToPatchPredictedChain(); //inputs: method, unused, predictedChainCell, clazz
+    load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    insertLabel(".skipPrediction", true);
+    move_reg_to_reg(OpndSize_32, PhysicalReg_EAX, true, PhysicalReg_ECX, true);
+}
+
+// 2 inputs: ChainingCell in temp 41, current class object in temp 40
+void predicted_chain_interface_O1(u2 tmp) {
+
+    /* set up arguments to dvmFindInterfaceMethodInCache */
+    load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, tmp, 4, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, (int) currentMethod->clazz->pDvmDex, 12, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, (int) currentMethod, 8, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 40, false, 0, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_10;
+    call_dvmFindInterfaceMethodInCache();
+    load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+
+    /* if dvmFindInterfaceMethodInCache returns NULL, throw exception
+       otherwise, jump to .find_interface_done */
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump(Condition_NE, ".find_interface_done", true);
+    rememberState(3);
+    scratchRegs[0] = PhysicalReg_SCRATCH_9;
+    jumpToExceptionThrown(1/*exception number*/);
+
+    goToState(3);
+    /* the interface method is found */
+    insertLabel(".find_interface_done", true);
+#if 1 //
+    /* for gingerbread, counter is stored in glue structure
+       if clazz is not initialized, set icRechainCount to 0, otherwise, reduce it by 1 */
+    /* for gingerbread: t43 = 0 t44 = t33 t33-- cmov_ne t43 = t33 cmov_ne t44 = t33 */
+    move_mem_to_reg(OpndSize_32, offChainingCell_clazz, 41, false, 45, false);
+    move_imm_to_reg(OpndSize_32, 0, 43, false);
+    get_self_pointer(PhysicalReg_SCRATCH_7, isScratchPhysical);
+    move_mem_to_reg(OpndSize_32, offsetof(Thread, icRechainCount), PhysicalReg_SCRATCH_7, isScratchPhysical, 33, false); //counter
+    move_reg_to_reg(OpndSize_32, 33, false, 44, false);
+    alu_binary_imm_reg(OpndSize_32, sub_opc, 0x1, 33, false);
+    /* sub_opc will update control flags, so compare_imm_reg must happen after */
+    compare_imm_reg(OpndSize_32, 0, 45, false);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_NZ, 33, false/*src*/, 43, false/*dst*/);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_NZ, 33, false/*src*/, 44, false/*dst*/);
+    move_reg_to_mem(OpndSize_32, 44, false, offsetof(Thread, icRechainCount), PhysicalReg_SCRATCH_7, isScratchPhysical);
+#else
+    /* reduce counter in chaining cell by 1 */
+    move_mem_to_reg(OpndSize_32, offChainingCell_counter, 41, false, 33, false); //counter
+    alu_binary_imm_reg(OpndSize_32, sub_opc, 0x1, 33, false);
+    move_reg_to_mem(OpndSize_32, 33, false, offChainingCell_counter, 41, false);
+#endif
+
+    /* if counter is still greater than zero, skip prediction
+       if it is zero, update predicted method */
+    compare_imm_reg(OpndSize_32, 0, 43, false);
+    conditional_jump(Condition_G, ".skipPrediction", true);
+
+    rememberState(4);
+    /* call dvmJitToPatchPredictedChain to update predicted method */
+    //%ecx has callee method for virtual, %eax has callee for interface
+    /* set up arguments for dvmJitToPatchPredictedChain */
+    load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_EAX, true, 0, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_SCRATCH_7, isScratchPhysical, 4, PhysicalReg_ESP, true);
+    insertChainingWorklist(traceCurrentBB->taken->id, stream);
+    move_chain_to_mem(OpndSize_32, traceCurrentBB->taken->id, 8, PhysicalReg_ESP, true); //predictedChainCell
+    move_reg_to_mem(OpndSize_32, 40, false, 12, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_8;
+    call_dvmJitToPatchPredictedChain(); //inputs: method, unused, predictedChainCell, clazz
+    load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    transferToState(4);
+
+    insertLabel(".skipPrediction", true);
+    move_reg_to_reg(OpndSize_32, PhysicalReg_EAX, true, PhysicalReg_ECX, true);
+}
+
+/* update predicted method for invoke virtual */
+// 2 inputs: ChainingCell in P_GPR_1, current class object in P_GPR_3
+void predicted_chain_virtual_O0(u2 IMMC) {
+    ALOGI("TODO chain_virtual_O0");
+
+    /* reduce counter in chaining cell by 1 */
+    move_mem_to_reg(OpndSize_32, offChainingCell_counter, P_GPR_1, true, P_GPR_2, true); //counter
+    move_mem_to_reg(OpndSize_32, offClassObject_vtable, P_GPR_3, true, P_SCRATCH_2, true);
+    alu_binary_imm_reg(OpndSize_32, sub_opc, 0x1, P_GPR_2, true);
+    move_mem_to_reg(OpndSize_32, IMMC, P_SCRATCH_2, true, PhysicalReg_ECX, true);
+    move_reg_to_mem(OpndSize_32, P_GPR_2, true, offChainingCell_counter, P_GPR_1, true);
+
+    /* if counter is still greater than zero, skip prediction
+       if it is zero, update predicted method */
+    compare_imm_reg(OpndSize_32, 0, P_GPR_2, true);
+    conditional_jump(Condition_G, ".skipPrediction", true);
+
+    /* call dvmJitToPatchPredictedChain to update predicted method */
+    //%ecx has callee method for virtual, %eax has callee for interface
+    /* set up arguments for dvmJitToPatchPredictedChain */
+    load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_ECX, true, 0,  PhysicalReg_ESP, true);
+    insertChainingWorklist(traceCurrentBB->taken->id, stream);
+    move_chain_to_mem(OpndSize_32, traceCurrentBB->taken->id, 8, PhysicalReg_ESP, true); //predictedChainCell
+    move_reg_to_mem(OpndSize_32, P_GPR_3, true, 12, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_dvmJitToPatchPredictedChain(); //inputs: method, unused, predictedChainCell, clazz
+    load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+
+    //callee method in %ecx for invoke virtual
+    move_reg_to_reg(OpndSize_32, PhysicalReg_EAX, true, PhysicalReg_ECX, true);
+    insertLabel(".skipPrediction", true);
+}
+
+// 2 inputs: ChainingCell in temp 41, current class object in temp 40
+// extra input: predicted clazz in temp 32
+void predicted_chain_virtual_O1(u2 IMMC) {
+
+    /* reduce counter in chaining cell by 1 */
+    /* for gingerbread: t43 = 0 t44 = t33 t33-- cmov_ne t43 = t33 cmov_ne t44 = t33 */
+    get_self_pointer(PhysicalReg_SCRATCH_7, isScratchPhysical);
+    move_imm_to_reg(OpndSize_32, 0, 43, false);
+    move_mem_to_reg(OpndSize_32, offsetof(Thread, icRechainCount), PhysicalReg_SCRATCH_7, isScratchPhysical, 33, false); //counter
+    move_mem_to_reg(OpndSize_32, offClassObject_vtable, 40, false, 34, false);
+    move_reg_to_reg(OpndSize_32, 33, false, 44, false);
+    alu_binary_imm_reg(OpndSize_32, sub_opc, 0x1, 33, false);
+    compare_imm_reg(OpndSize_32, 0, 32, false); // after sub_opc
+    move_mem_to_reg(OpndSize_32, IMMC, 34, false, PhysicalReg_ECX, true);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_NZ, 33, false/*src*/, 43, false/*dst*/);
+    conditional_move_reg_to_reg(OpndSize_32, Condition_NZ, 33, false/*src*/, 44, false/*dst*/);
+    move_reg_to_mem(OpndSize_32, 44, false, offsetof(Thread, icRechainCount), PhysicalReg_SCRATCH_7, isScratchPhysical);
+
+    /* if counter is still greater than zero, skip prediction
+       if it is zero, update predicted method */
+    compare_imm_reg(OpndSize_32, 0, 43, false);
+    conditional_jump(Condition_G, ".skipPrediction", true);
+
+    rememberState(2);
+    /* call dvmJitToPatchPredictedChain to update predicted method */
+    //%ecx has callee method for virtual, %eax has callee for interface
+    /* set up arguments for dvmJitToPatchPredictedChain */
+    load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_ECX, true, 0, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_SCRATCH_7, isScratchPhysical, 4, PhysicalReg_ESP, true);
+    if(traceCurrentBB->taken)
+        insertChainingWorklist(traceCurrentBB->taken->id, stream);
+    int traceTakenId = traceCurrentBB->taken ? traceCurrentBB->taken->id : 0;
+    move_chain_to_mem(OpndSize_32, traceTakenId, 8, PhysicalReg_ESP, true); //predictedChainCell
+    move_reg_to_mem(OpndSize_32, 40, false, 12, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_10;
+    call_dvmJitToPatchPredictedChain(); //inputs: method, unused, predictedChainCell, clazz
+    load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+
+    //callee method in %ecx for invoke virtual
+    move_reg_to_reg(OpndSize_32, PhysicalReg_EAX, true, PhysicalReg_ECX, true);
+    transferToState(2);
+
+    insertLabel(".skipPrediction", true);
+}
+
+static int invokeChain_inst = 0;
+/* object "this" is in %ebx */
+void gen_predicted_chain_O0(bool isRange, u2 tmp, int IMMC, bool isInterface, int inputReg) {
+    ALOGI("TODO predicted_chain_O0");
+
+    /* get current class object */
+    move_mem_to_reg(OpndSize_32, offObject_clazz, PhysicalReg_EBX, true,
+             P_GPR_3, true);
+#ifdef DEBUG_CALL_STACK3
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_debug_dumpSwitch(); //%ebx, %eax, %edx
+    move_imm_to_reg(OpndSize_32, 0xdd11, PhysicalReg_EBX, true);
+    call_debug_dumpSwitch();
+#endif
+
+    /* get predicted clazz
+       get predicted method
+    */
+    insertChainingWorklist(traceCurrentBB->taken->id, stream);
+    move_chain_to_reg(OpndSize_32, traceCurrentBB->taken->id, P_GPR_1, true); //predictedChainCell
+    move_mem_to_reg(OpndSize_32, offChainingCell_clazz, P_GPR_1, true, P_SCRATCH_2, true);//predicted clazz
+    move_mem_to_reg(OpndSize_32, offChainingCell_method, P_GPR_1, true, PhysicalReg_ECX, true);//predicted method
+
+#ifdef DEBUG_CALL_STACK3
+    load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, P_GPR_1, true, 8, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, P_SCRATCH_2, true, 4, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, P_GPR_3, true, 0, PhysicalReg_ESP, true);
+
+    move_reg_to_reg(OpndSize_32, P_SCRATCH_2, true, PhysicalReg_EBX, true);
+    call_debug_dumpSwitch();
+    move_imm_to_reg(OpndSize_32, 0xdd22, PhysicalReg_EBX, true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_debug_dumpSwitch(); //%ebx, %eax, %edx
+    move_reg_to_reg(OpndSize_32, P_GPR_3, true, PhysicalReg_EBX, true);
+    call_debug_dumpSwitch();
+    move_reg_to_reg(OpndSize_32, PhysicalReg_ECX, true, PhysicalReg_EBX, true);
+    call_debug_dumpSwitch();
+
+    move_mem_to_reg(OpndSize_32, 8, PhysicalReg_ESP, true, P_GPR_1, true);
+    move_mem_to_reg(OpndSize_32, 4, PhysicalReg_ESP, true, P_SCRATCH_2, true);
+    move_mem_to_reg(OpndSize_32, 0, PhysicalReg_ESP, true, P_GPR_3, true);
+    load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+#endif
+
+    /* compare current class object against predicted clazz
+       if equal, prediction is still valid, jump to .invokeChain */
+    //live registers: P_GPR_1, P_GPR_3, P_SCRATCH_2
+    compare_reg_reg(P_GPR_3, true, P_SCRATCH_2, true);
+    conditional_jump(Condition_E, ".invokeChain", true);
+    invokeChain_inst++;
+
+    //get callee method and update predicted method if necessary
+    if(isInterface) {
+        predicted_chain_interface_O0(tmp);
+    } else {
+        predicted_chain_virtual_O0(IMMC);
+    }
+
+#ifdef DEBUG_CALL_STACK3
+    move_imm_to_reg(OpndSize_32, 0xeeee, PhysicalReg_EBX, true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_debug_dumpSwitch(); //%ebx, %eax, %edx
+    insertChainingWorklist(traceCurrentBB->taken->id, stream);
+    move_chain_to_reg(OpndSize_32, traceCurrentBB->taken->id, PhysicalReg_EBX, true);
+    call_debug_dumpSwitch();
+#endif
+
+    if(isRange) {
+        common_invokeMethodRange(ArgsDone_Full);
+    }
+    else {
+        common_invokeMethodNoRange(ArgsDone_Full);
+    }
+
+    insertLabel(".invokeChain", true);
+#ifdef DEBUG_CALL_STACK3
+    move_imm_to_reg(OpndSize_32, 0xdddd, PhysicalReg_EBX, true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_debug_dumpSwitch(); //%ebx, %eax, %edx
+    insertChainingWorklist(traceCurrentBB->taken->id, stream);
+    move_chain_to_reg(OpndSize_32, traceCurrentBB->taken->id, PhysicalReg_EBX, true);
+    call_debug_dumpSwitch();
+    move_reg_to_reg(OpndSize_32, PhysicalReg_ECX, true, PhysicalReg_EBX, true);
+    call_debug_dumpSwitch();
+#endif
+
+    if(isRange) {
+        common_invokeMethodRange(ArgsDone_Normal);
+    }
+    else {
+        common_invokeMethodNoRange(ArgsDone_Normal);
+    }
+}
+
+/* object "this" is in inputReg: 5 for virtual, 1 for interface, 1 for virtual_quick */
+void gen_predicted_chain_O1(bool isRange, u2 tmp, int IMMC, bool isInterface, int inputReg) {
+
+    /* get current class object */
+    move_mem_to_reg(OpndSize_32, offObject_clazz, inputReg, false,
+             40, false);
+
+    /* get predicted clazz
+       get predicted method
+    */
+    if(traceCurrentBB->taken)
+        insertChainingWorklist(traceCurrentBB->taken->id, stream);
+    int traceTakenId = traceCurrentBB->taken ? traceCurrentBB->taken->id : 0;
+    move_chain_to_reg(OpndSize_32, traceTakenId, 41, false); //predictedChainCell
+    move_mem_to_reg(OpndSize_32, offChainingCell_clazz, 41, false, 32, false);//predicted clazz
+    move_mem_to_reg(OpndSize_32, offChainingCell_method, 41, false, PhysicalReg_ECX, true);//predicted method
+
+    /* update stack with parameters first, then decide the callee */
+    if(isRange) common_invokeMethodRange_noJmp();
+    else common_invokeMethodNoRange_noJmp();
+
+    /* compare current class object against predicted clazz
+       if equal, prediction is still valid, jump to .invokeChain */
+    compare_reg_reg(40, false, 32, false);
+    conditional_jump(Condition_E, ".invokeChain", true);
+    rememberState(1);
+    invokeChain_inst++;
+
+    //get callee method and update predicted method if necessary
+    if(isInterface) {
+        predicted_chain_interface_O1(tmp);
+    } else {
+        predicted_chain_virtual_O1(IMMC);
+    }
+
+    common_invokeMethod_Jmp(ArgsDone_Full); //will touch %ecx
+
+    insertLabel(".invokeChain", true);
+    goToState(1);
+    common_invokeMethod_Jmp(ArgsDone_Normal);
+}
+
+void gen_predicted_chain(bool isRange, u2 tmp, int IMMC, bool isInterface, int inputReg) {
+    return gen_predicted_chain_O1(isRange, tmp, IMMC, isInterface, inputReg);
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef P_SCRATCH_2
diff --git a/vm/compiler/codegen/x86/LowerJump.cpp b/vm/compiler/codegen/x86/LowerJump.cpp
new file mode 100644
index 0000000..2b10d6b
--- /dev/null
+++ b/vm/compiler/codegen/x86/LowerJump.cpp
@@ -0,0 +1,1568 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file LowerJump.cpp
+    \brief This file lowers the following bytecodes: IF_XXX, GOTO
+*/
+#include <math.h>
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "NcgAot.h"
+#include "enc_wrapper.h"
+#include "interp/InterpDefs.h"
+#include "NcgHelper.h"
+
+LabelMap* globalMap;
+LabelMap* globalShortMap;//make sure for each bytecode, there is no duplicated label
+LabelMap* globalWorklist = NULL;
+LabelMap* globalShortWorklist;
+
+int globalMapNum;
+int globalWorklistNum;
+int globalDataWorklistNum;
+int VMAPIWorklistNum;
+int globalPCWorklistNum;
+int chainingWorklistNum;
+
+LabelMap* globalDataWorklist = NULL;
+LabelMap* globalPCWorklist = NULL;
+LabelMap* chainingWorklist = NULL;
+LabelMap* VMAPIWorklist = NULL;
+
+char* ncgClassData;
+char* ncgClassDataPtr;
+char* ncgMethodData;
+char* ncgMethodDataPtr;
+int   ncgClassNum;
+int   ncgMethodNum;
+
+NCGWorklist* globalNCGWorklist;
+DataWorklist* methodDataWorklist;
+#ifdef ENABLE_TRACING
+MapWorklist* methodMapWorklist;
+#endif
+/*!
+\brief search globalShortMap to find the entry for the given label
+
+*/
+LabelMap* findItemForShortLabel(const char* label) {
+    LabelMap* ptr = globalShortMap;
+    while(ptr != NULL) {
+        if(!strcmp(label, ptr->label)) {
+            return ptr;
+        }
+        ptr = ptr->nextItem;
+    }
+    return NULL;
+}
+//assume size of "jump reg" is 2
+#define JUMP_REG_SIZE 2
+#define ADD_REG_REG_SIZE 3
+/*!
+\brief update value of the immediate in the given jump instruction
+
+check whether the immediate is out of range for the pre-set size
+*/
+int updateJumpInst(char* jumpInst, OpndSize immSize, int relativeNCG) {
+#ifdef DEBUG_NCG_JUMP
+    ALOGI("update jump inst @ %p with %d", jumpInst, relativeNCG);
+#endif
+    if(immSize == OpndSize_8) { //-128 to 127
+        if(relativeNCG >= 128 || relativeNCG < -128) {
+            ALOGE("pre-allocated space for a forward jump is not big enough");
+            dvmAbort();
+        }
+    }
+    if(immSize == OpndSize_16) { //-2^16 to 2^16-1
+        if(relativeNCG >= 32768 || relativeNCG < -32768) {
+            ALOGE("pre-allocated space for a forward jump is not big enough");
+            dvmAbort();
+        }
+    }
+    encoder_update_imm(relativeNCG, jumpInst);
+    return 0;
+}
+
+/*!
+\brief insert a label
+
+It takes argument checkDup, if checkDup is true, an entry is created in globalShortMap, entries in globalShortWorklist are checked, if there exists a match, the immediate in the jump instruction is updated and the entry is removed from globalShortWorklist;
+otherwise, an entry is created in globalMap.
+*/
+int insertLabel(const char* label, bool checkDup) {
+    LabelMap* item = NULL;
+    if(!checkDup) {
+        item = (LabelMap*)malloc(sizeof(LabelMap));
+        if(item == NULL) {
+            ALOGE("Memory allocation failed");
+            return -1;
+        }
+        snprintf(item->label, LABEL_SIZE, "%s", label);
+        item->codePtr = stream;
+        item->nextItem = globalMap;
+        globalMap = item;
+#ifdef DEBUG_NCG_CODE_SIZE
+        ALOGI("insert global label %s %p", label, stream);
+#endif
+        globalMapNum++;
+        return 0;
+    }
+
+    item = (LabelMap*)malloc(sizeof(LabelMap));
+    if(item == NULL) {
+        ALOGE("Memory allocation failed");
+        return -1;
+    }
+    snprintf(item->label, LABEL_SIZE, "%s", label);
+    item->codePtr = stream;
+    item->nextItem = globalShortMap;
+    globalShortMap = item;
+#ifdef DEBUG_NCG
+    ALOGI("insert short-term label %s %p", label, stream);
+#endif
+    LabelMap* ptr = globalShortWorklist;
+    LabelMap* ptr_prevItem = NULL;
+    while(ptr != NULL) {
+        if(!strcmp(ptr->label, label)) {
+            //perform work
+            int relativeNCG = stream - ptr->codePtr;
+            unsigned instSize = encoder_get_inst_size(ptr->codePtr);
+            relativeNCG -= instSize; //size of the instruction
+#ifdef DEBUG_NCG
+            ALOGI("perform work short-term %p for label %s relative %d", ptr->codePtr, label, relativeNCG);
+#endif
+            updateJumpInst(ptr->codePtr, ptr->size, relativeNCG);
+            //remove work
+            if(ptr_prevItem == NULL) {
+                globalShortWorklist = ptr->nextItem;
+                free(ptr);
+                ptr = globalShortWorklist; //ptr_prevItem is still NULL
+            }
+            else {
+                ptr_prevItem->nextItem = ptr->nextItem;
+                free(ptr);
+                ptr = ptr_prevItem->nextItem;
+            }
+        }
+        else {
+            ptr_prevItem = ptr;
+            ptr = ptr->nextItem;
+        }
+    } //while
+    return 0;
+}
+/*!
+\brief search globalMap to find the entry for the given label
+
+*/
+char* findCodeForLabel(const char* label) {
+    LabelMap* ptr = globalMap;
+    while(ptr != NULL) {
+        if(!strcmp(label, ptr->label)) {
+            return ptr->codePtr;
+        }
+        ptr = ptr->nextItem;
+    }
+    return NULL;
+}
+/*!
+\brief search globalShortMap to find the entry for the given label
+
+*/
+char* findCodeForShortLabel(const char* label) {
+    LabelMap* ptr = globalShortMap;
+    while(ptr != NULL) {
+        if(!strcmp(label, ptr->label)) {
+            return ptr->codePtr;
+        }
+        ptr = ptr->nextItem;
+    }
+    return NULL;
+}
+int insertLabelWorklist(const char* label, OpndSize immSize) {
+    LabelMap* item = (LabelMap*)malloc(sizeof(LabelMap));
+    if(item == NULL) {
+        ALOGE("Memory allocation failed");
+        return -1;
+    }
+    snprintf(item->label, LABEL_SIZE, "%s", label);
+    item->codePtr = stream;
+    item->size = immSize;
+    item->nextItem = globalWorklist;
+    globalWorklist = item;
+#ifdef DEBUG_NCG
+    ALOGI("insert globalWorklist: %s %p", label, stream);
+#endif
+    return 0;
+}
+
+int insertShortWorklist(const char* label, OpndSize immSize) {
+    LabelMap* item = (LabelMap*)malloc(sizeof(LabelMap));
+    if(item == NULL) {
+        ALOGE("Memory allocation failed");
+        return -1;
+    }
+    snprintf(item->label, LABEL_SIZE, "%s", label);
+    item->codePtr = stream;
+    item->size = immSize;
+    item->nextItem = globalShortWorklist;
+    globalShortWorklist = item;
+#ifdef DEBUG_NCG
+    ALOGI("insert globalShortWorklist: %s %p", label, stream);
+#endif
+    return 0;
+}
+/*!
+\brief free memory allocated for globalMap
+
+*/
+void freeLabelMap() {
+    LabelMap* ptr = globalMap;
+    while(ptr != NULL) {
+        globalMap = ptr->nextItem;
+        free(ptr);
+        ptr = globalMap;
+    }
+}
+/*!
+\brief free memory allocated for globalShortMap
+
+*/
+void freeShortMap() {
+    LabelMap* ptr = globalShortMap;
+    while(ptr != NULL) {
+        globalShortMap = ptr->nextItem;
+        free(ptr);
+        ptr = globalShortMap;
+    }
+    globalShortMap = NULL;
+}
+
+int insertGlobalPCWorklist(char * offset, char * codeStart)
+{
+    LabelMap* item = (LabelMap*)malloc(sizeof(LabelMap));
+    if(item == NULL) {
+        ALOGE("Memory allocation failed");
+        return -1;
+    }
+    snprintf(item->label, LABEL_SIZE, "%s", "export_pc");
+    item->size = OpndSize_32;
+    item->codePtr = offset; //points to the immediate operand
+    item->addend = codeStart - streamMethodStart; //relative code pointer
+    item->nextItem = globalPCWorklist;
+    globalPCWorklist = item;
+    globalPCWorklistNum ++;
+
+#ifdef DEBUG_NCG
+    ALOGI("insert globalPCWorklist: %p %p %p %x %p", globalDvmNcg->streamCode,  codeStart, streamCode, item->addend, item->codePtr);
+#endif
+    return 0;
+}
+
+int insertChainingWorklist(int bbId, char * codeStart)
+{
+    LabelMap* item = (LabelMap*)malloc(sizeof(LabelMap));
+    if(item == NULL) {
+        ALOGE("Memory allocation failed");
+        return -1;
+    }
+    item->size = OpndSize_32;
+    item->codePtr = codeStart; //points to the move instruction
+    item->addend = bbId; //relative code pointer
+    item->nextItem = chainingWorklist;
+    chainingWorklist = item;
+
+#ifdef DEBUG_NCG
+    ALOGI("insertChainingWorklist: %p basic block %d", codeStart, bbId);
+#endif
+    return 0;
+}
+
+int insertGlobalDataWorklist(char * offset, const char* label)
+{
+    LabelMap* item = (LabelMap*)malloc(sizeof(LabelMap));
+    if(item == NULL) {
+        ALOGE("Memory allocation failed");
+        return -1;
+    }
+    snprintf(item->label, LABEL_SIZE, "%s", label);
+    item->codePtr = offset;
+    item->size = OpndSize_32;
+    item->nextItem = globalDataWorklist;
+    globalDataWorklist = item;
+    globalDataWorklistNum ++;
+
+#ifdef DEBUG_NCG
+    ALOGI("insert globalDataWorklist: %s %p", label, offset);
+#endif
+
+    return 0;
+}
+
+int insertVMAPIWorklist(char * offset, const char* label)
+{
+    LabelMap* item = (LabelMap*)malloc(sizeof(LabelMap));
+    if(item == NULL) {
+        ALOGE("Memory allocation failed");
+        return -1;
+    }
+    snprintf(item->label, LABEL_SIZE, "%s", label);
+    item->codePtr = offset;
+    item->size = OpndSize_32;
+
+    item->nextItem = VMAPIWorklist;
+    VMAPIWorklist = item;
+
+    VMAPIWorklistNum ++;
+
+#ifdef DEBUG_NCG
+    ALOGI("insert VMAPIWorklist: %s %p", label, offset);
+#endif
+    return 0;
+}
+////////////////////////////////////////////////
+
+
+int updateImmRMInst(char* moveInst, const char* label, int relativeNCG); //forward declaration
+//////////////////// performLabelWorklist is defined differently for code cache
+void performChainingWorklist() {
+    LabelMap* ptr = chainingWorklist;
+    while(ptr != NULL) {
+        int tmpNCG = traceLabelList[ptr->addend].lop.generic.offset;
+        char* NCGaddr = streamMethodStart + tmpNCG;
+        updateImmRMInst(ptr->codePtr, "", (int)NCGaddr);
+        chainingWorklist = ptr->nextItem;
+        free(ptr);
+        ptr = chainingWorklist;
+    }
+}
+void freeChainingWorklist() {
+    LabelMap* ptr = chainingWorklist;
+    while(ptr != NULL) {
+        chainingWorklist = ptr->nextItem;
+        free(ptr);
+        ptr = chainingWorklist;
+    }
+}
+
+//Work only for initNCG
+void performLabelWorklist() {
+    LabelMap* ptr = globalWorklist;
+    while(ptr != NULL) {
+#ifdef DEBUG_NCG
+        ALOGI("perform work global %p for label %s", ptr->codePtr, ptr->label);
+#endif
+        char* targetCode = findCodeForLabel(ptr->label);
+        assert(targetCode != NULL);
+        int relativeNCG = targetCode - ptr->codePtr;
+        unsigned instSize = encoder_get_inst_size(ptr->codePtr);
+        relativeNCG -= instSize; //size of the instruction
+        updateJumpInst(ptr->codePtr, ptr->size, relativeNCG);
+        globalWorklist = ptr->nextItem;
+        free(ptr);
+        ptr = globalWorklist;
+    }
+}
+void freeLabelWorklist() {
+    LabelMap* ptr = globalWorklist;
+    while(ptr != NULL) {
+        globalWorklist = ptr->nextItem;
+        free(ptr);
+        ptr = globalWorklist;
+    }
+}
+
+///////////////////////////////////////////////////
+/*!
+\brief update value of the immediate in the given move instruction
+
+*/
+int updateImmRMInst(char* moveInst, const char* label, int relativeNCG) {
+#ifdef DEBUG_NCG
+    ALOGI("perform work ImmRM inst @ %p for label %s with %d", moveInst, label, relativeNCG);
+#endif
+    encoder_update_imm_rm(relativeNCG, moveInst);
+    return 0;
+}
+//! maximum instruction size for jump,jcc,call: 6 for jcc rel32
+#define MAX_JCC_SIZE 6
+//! minimum instruction size for jump,jcc,call: 2
+#define MIN_JCC_SIZE 2
+/*!
+\brief estimate size of the immediate
+
+Somehow, 16 bit jump does not work. This function will return either 8 bit or 32 bit
+EXAMPLE:
+  native code at A: ...
+  native code at B: jump relOffset (target is A)
+  native code at B':
+  --> relOffset = A - B' = A - B - size of the jump instruction
+  Argument "target" is equal to A - B. To determine size of the immediate, we check tha value of "target - size of the jump instructoin"
+*/
+OpndSize estOpndSizeFromImm(int target) {
+    if(target-MIN_JCC_SIZE < 128 && target-MAX_JCC_SIZE >= -128) return OpndSize_8;
+#ifdef SUPPORT_IMM_16
+    if(target-MIN_JCC_SIZE < 32768 && target-MAX_JCC_SIZE >= -32768) return OpndSize_16;
+#endif
+    return OpndSize_32;
+}
+/*!
+\brief return size of a jump or call instruction
+
+*/
+unsigned getJmpCallInstSize(OpndSize size, JmpCall_type type) {
+    if(type == JmpCall_uncond) {
+        if(size == OpndSize_8) return 2;
+        if(size == OpndSize_16) return 4;
+        return 5;
+    }
+    if(type == JmpCall_cond) {
+        if(size == OpndSize_8) return 2;
+        if(size == OpndSize_16) return 5;
+        return 6;
+    }
+    if(type == JmpCall_reg) {
+        assert(size == OpndSize_32);
+        return JUMP_REG_SIZE;
+    }
+    if(type == JmpCall_call) {
+        assert(size != OpndSize_8);
+        if(size == OpndSize_16) return 4;
+        return 5;
+    }
+    return 0;
+}
+/*!
+\brief check whether a branch target is already handled, if yes, return the size of the immediate; otherwise, call insertShortWorklist or insertLabelWorklist.
+
+If the branch target is not handled, call insertShortWorklist or insertLabelWorklist depending on isShortTerm, unknown is set to true, immSize is set to 32 if isShortTerm is false, set to 32 if isShortTerm is true and target is check_cast_null, set to 8 otherwise.
+
+If the branch target is handled, call estOpndSizeFromImm to set immSize for jump instruction, returns the value of the immediate
+*/
+int getRelativeOffset(const char* target, bool isShortTerm, JmpCall_type type, bool* unknown, OpndSize* immSize) {
+    char* targetPtrInStream = NULL;
+    if(isShortTerm) targetPtrInStream = findCodeForShortLabel(target);
+    else targetPtrInStream = findCodeForLabel(target);
+
+    int relOffset;
+    *unknown = false;
+    if(targetPtrInStream == NULL) {
+        //branch target is not handled yet
+        relOffset = 0;
+        *unknown = true;
+        if(isShortTerm) {
+            /* for backward jump, at this point, we don't know how far the target is from this jump
+               since the lable is only used within a single bytecode, we assume OpndSize_8 is big enough
+               but there are special cases where we should use 32 bit offset
+            */
+            if(!strcmp(target, ".check_cast_null") || !strcmp(target, ".stackOverflow") ||
+               !strcmp(target, ".invokeChain") ||
+               !strcmp(target, ".new_instance_done") ||
+               !strcmp(target, ".new_array_done") ||
+               !strcmp(target, ".fill_array_data_done") ||
+               !strcmp(target, ".inlined_string_compare_done") ||
+               !strncmp(target, "after_exception", 15)) {
+#ifdef SUPPORT_IMM_16
+                *immSize = OpndSize_16;
+#else
+                *immSize = OpndSize_32;
+#endif
+            } else {
+                *immSize = OpndSize_8;
+            }
+#ifdef DEBUG_NCG_JUMP
+            ALOGI("insert to short worklist %s %d", target, *immSize);
+#endif
+            insertShortWorklist(target, *immSize);
+        }
+        else {
+#ifdef SUPPORT_IMM_16
+            *immSize = OpndSize_16;
+#else
+            *immSize = OpndSize_32;
+#endif
+            insertLabelWorklist(target, *immSize);
+        }
+        if(type == JmpCall_call) { //call sz16 does not work in gdb
+            *immSize = OpndSize_32;
+        }
+        return 0;
+    }
+    else if (!isShortTerm) {
+#ifdef SUPPORT_IMM_16
+        *immSize = OpndSize_16;
+#else
+        *immSize = OpndSize_32;
+#endif
+        insertLabelWorklist(target, *immSize);
+    }
+
+#ifdef DEBUG_NCG
+    ALOGI("backward branch @ %p for label %s", stream, target);
+#endif
+    relOffset = targetPtrInStream - stream;
+    if(type == JmpCall_call) *immSize = OpndSize_32;
+    else
+        *immSize = estOpndSizeFromImm(relOffset);
+
+    relOffset -= getJmpCallInstSize(*immSize, type);
+    return relOffset;
+}
+
+/*!
+\brief generate a single native instruction "jcc imm" to jump to a label
+
+*/
+void conditional_jump(ConditionCode cc, const char* target, bool isShortTerm) {
+    if(jumpToException(target) && currentExceptionBlockIdx >= 0) { //jump to the exceptionThrow block
+        condJumpToBasicBlock(stream, cc, currentExceptionBlockIdx);
+        return;
+    }
+    Mnemonic m = (Mnemonic)(Mnemonic_Jcc + cc);
+    bool unknown;
+    OpndSize size;
+    int imm = 0;
+    imm = getRelativeOffset(target, isShortTerm, JmpCall_cond, &unknown, &size);
+    dump_label(m, size, imm, target, isShortTerm);
+}
+/*!
+\brief generate a single native instruction "jmp imm" to jump to ".invokeArgsDone"
+
+*/
+void goto_invokeArgsDone() {
+    unconditional_jump_global_API(".invokeArgsDone", false);
+}
+/*!
+\brief generate a single native instruction "jmp imm" to jump to a label
+
+If the target is ".invokeArgsDone" and mode is NCG O1, extra work is performed to dump content of virtual registers to memory.
+*/
+void unconditional_jump(const char* target, bool isShortTerm) {
+    if(jumpToException(target) && currentExceptionBlockIdx >= 0) { //jump to the exceptionThrow block
+        jumpToBasicBlock(stream, currentExceptionBlockIdx);
+        return;
+    }
+    Mnemonic m = Mnemonic_JMP;
+    bool unknown;
+    OpndSize size;
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        //for other three labels used by JIT: invokeArgsDone_formal, _native, _jit
+        if(!strncmp(target, ".invokeArgsDone", 15)) {
+            touchEcx(); //keep ecx live, if ecx was spilled, it is loaded here
+            beforeCall(target); //
+        }
+        if(!strcmp(target, ".invokeArgsDone")) {
+            nextVersionOfHardReg(PhysicalReg_EDX, 1); //edx will be used in a function
+            call("ncgGetEIP"); //must be immediately before JMP
+        }
+    }
+    int imm = 0;
+    imm = getRelativeOffset(target, isShortTerm, JmpCall_uncond, &unknown, &size);
+    dump_label(m, size, imm, target, isShortTerm);
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        if(!strncmp(target, ".invokeArgsDone", 15)) {
+            afterCall(target); //un-spill before executing the next bytecode
+        }
+    }
+}
+/*!
+\brief generate a single native instruction "jcc imm"
+
+*/
+void conditional_jump_int(ConditionCode cc, int target, OpndSize size) {
+    Mnemonic m = (Mnemonic)(Mnemonic_Jcc + cc);
+    dump_ncg(m, size, target);
+}
+/*!
+\brief generate a single native instruction "jmp imm"
+
+*/
+void unconditional_jump_int(int target, OpndSize size) {
+    Mnemonic m = Mnemonic_JMP;
+    dump_ncg(m, size, target);
+}
+/*!
+\brief generate a single native instruction "jmp reg"
+
+*/
+void unconditional_jump_reg(int reg, bool isPhysical) {
+    dump_reg(Mnemonic_JMP, ATOM_NORMAL, OpndSize_32, reg, isPhysical, LowOpndRegType_gp);
+}
+
+/*!
+\brief generate a single native instruction to call a function
+
+If mode is NCG O1, extra work is performed to dump content of virtual registers to memory.
+*/
+void call(const char* target) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        beforeCall(target);
+    }
+    Mnemonic m = Mnemonic_CALL;
+    bool dummy;
+    OpndSize size;
+    int relOffset = 0;
+    relOffset = getRelativeOffset(target, false, JmpCall_call, &dummy, &size);
+    dump_label(m, size, relOffset, target, false);
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        afterCall(target);
+    }
+}
+/*!
+\brief generate a single native instruction to call a function
+
+*/
+void call_reg(int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_CALL;
+    dump_reg(m, ATOM_NORMAL, OpndSize_32, reg, isPhysical, LowOpndRegType_gp);
+}
+void call_reg_noalloc(int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_CALL;
+    dump_reg_noalloc(m, OpndSize_32, reg, isPhysical, LowOpndRegType_gp);
+}
+
+/*!
+\brief generate a single native instruction to call a function
+
+*/
+void call_mem(int disp, int reg, bool isPhysical) {
+    Mnemonic m = Mnemonic_CALL;
+    dump_mem(m, ATOM_NORMAL, OpndSize_32, disp, reg, isPhysical);
+}
+
+/*!
+\brief insert an entry to globalNCGWorklist
+
+*/
+int insertNCGWorklist(s4 relativePC, OpndSize immSize) {
+    int offsetNCG2 = stream - streamMethodStart;
+#ifdef DEBUG_NCG
+    ALOGI("insert NCGWorklist (goto forward) @ %p offsetPC %x relativePC %x offsetNCG %x", stream, offsetPC, relativePC, offsetNCG2);
+#endif
+    NCGWorklist* item = (NCGWorklist*)malloc(sizeof(NCGWorklist));
+    if(item == NULL) {
+        ALOGE("Memory allocation failed");
+        return -1;
+    }
+    item->relativePC = relativePC;
+    item->offsetPC = offsetPC;
+    item->offsetNCG = offsetNCG2;
+    item->codePtr = stream;
+    item->size = immSize;
+    item->nextItem = globalNCGWorklist;
+    globalNCGWorklist = item;
+    return 0;
+}
+#ifdef ENABLE_TRACING
+int insertMapWorklist(s4 BCOffset, s4 NCGOffset, int isStartOfPC) {
+    return 0;
+}
+#endif
+/*!
+\brief insert an entry to methodDataWorklist
+
+This function is used by bytecode FILL_ARRAY_DATA, PACKED_SWITCH, SPARSE_SWITCH
+*/
+int insertDataWorklist(s4 relativePC, char* codePtr1) {
+    //insert according to offsetPC+relativePC, smallest at the head
+    DataWorklist* item = (DataWorklist*)malloc(sizeof(DataWorklist));
+    if(item == NULL) {
+        ALOGE("Memory allocation failed");
+        return -1;
+    }
+    item->relativePC = relativePC;
+    item->offsetPC = offsetPC;
+    item->codePtr = codePtr1;
+    item->codePtr2 = stream; //jump_reg for switch
+    DataWorklist* ptr = methodDataWorklist;
+    DataWorklist* prev_ptr = NULL;
+    while(ptr != NULL) {
+        int tmpPC = ptr->offsetPC + ptr->relativePC;
+        int tmpPC2 = relativePC + offsetPC;
+        if(tmpPC2 < tmpPC) {
+            break;
+        }
+        prev_ptr = ptr;
+        ptr = ptr->nextItem;
+    }
+    //insert item before ptr
+    if(prev_ptr != NULL) {
+        prev_ptr->nextItem = item;
+    }
+    else methodDataWorklist = item;
+    item->nextItem = ptr;
+    return 0;
+}
+
+/*!
+\brief work on globalNCGWorklist
+
+*/
+int performNCGWorklist() {
+    NCGWorklist* ptr = globalNCGWorklist;
+    while(ptr != NULL) {
+        ALOGV("perform NCG worklist: @ %p target block %d target NCG %x",
+             ptr->codePtr, ptr->relativePC, traceLabelList[ptr->relativePC].lop.generic.offset);
+        int tmpNCG = traceLabelList[ptr->relativePC].lop.generic.offset;
+        assert(tmpNCG >= 0);
+        int relativeNCG = tmpNCG - ptr->offsetNCG;
+        unsigned instSize = encoder_get_inst_size(ptr->codePtr);
+        relativeNCG -= instSize;
+        updateJumpInst(ptr->codePtr, ptr->size, relativeNCG);
+        globalNCGWorklist = ptr->nextItem;
+        free(ptr);
+        ptr = globalNCGWorklist;
+    }
+    return 0;
+}
+void freeNCGWorklist() {
+    NCGWorklist* ptr = globalNCGWorklist;
+    while(ptr != NULL) {
+        globalNCGWorklist = ptr->nextItem;
+        free(ptr);
+        ptr = globalNCGWorklist;
+    }
+}
+
+/*!
+\brief used by bytecode SWITCH
+
+targetPC points to start of the data section
+Code sequence for SWITCH
+  call ncgGetEIP
+  @codeInst: add_reg_reg %eax, %edx
+  jump_reg %edx
+This function returns the offset in native code between add_reg_reg and the data section
+*/
+int getRelativeNCGForSwitch(int targetPC, char* codeInst) {
+    int tmpNCG = mapFromBCtoNCG[targetPC];
+    int offsetNCG2 = codeInst - streamMethodStart;
+    int relativeOff = tmpNCG - offsetNCG2;
+    return relativeOff;
+}
+/*!
+\brief work on methodDataWorklist
+
+*/
+int performDataWorklist() {
+    DataWorklist* ptr = methodDataWorklist;
+    if(ptr == NULL) return 0;
+
+    char* codeCacheEnd = ((char *) gDvmJit.codeCache) + gDvmJit.codeCacheSize - CODE_CACHE_PADDING;
+    u2 insnsSize = dvmGetMethodInsnsSize(currentMethod); //bytecode
+    //align stream to multiple of 4
+    int alignBytes = (int)stream & 3;
+    if(alignBytes != 0) alignBytes = 4-alignBytes;
+    stream += alignBytes;
+
+    while(ptr != NULL) {
+        int tmpPC = ptr->offsetPC + ptr->relativePC;
+        int endPC = insnsSize;
+        if(ptr->nextItem != NULL) endPC = ptr->nextItem->offsetPC + ptr->nextItem->relativePC;
+        mapFromBCtoNCG[tmpPC] = stream - streamMethodStart; //offsetNCG in byte
+
+        //handle fill_array_data, packed switch & sparse switch
+        u2 tmpInst = *(currentMethod->insns + ptr->offsetPC);
+        u2* sizePtr;
+        s4* entryPtr_bytecode;
+        u2 tSize, iVer;
+        u4 sz;
+
+        if (gDvmJit.codeCacheFull == true) {
+            // We are out of code cache space. Skip writing data/code to
+            //   code cache. Simply free the item.
+            methodDataWorklist = ptr->nextItem;
+            free(ptr);
+            ptr = methodDataWorklist;
+        }
+
+        switch (INST_INST(tmpInst)) {
+        case OP_FILL_ARRAY_DATA:
+            sz = (endPC-tmpPC)*sizeof(u2);
+            if ((stream + sz) < codeCacheEnd) {
+                memcpy(stream, (u2*)currentMethod->insns+tmpPC, sz);
+#ifdef DEBUG_NCG_CODE_SIZE
+                ALOGI("copy data section to stream %p: start at %d, %d bytes", stream, tmpPC, sz);
+#endif
+#ifdef DEBUG_NCG
+                ALOGI("update data section at %p with %d", ptr->codePtr, stream-ptr->codePtr);
+#endif
+                updateImmRMInst(ptr->codePtr, "", stream - ptr->codePtr);
+                stream += sz;
+            } else {
+                gDvmJit.codeCacheFull = true;
+            }
+            break;
+        case OP_PACKED_SWITCH:
+            updateImmRMInst(ptr->codePtr, "", stream-ptr->codePtr);
+            sizePtr = (u2*)currentMethod->insns+tmpPC + 1 /*signature*/;
+            entryPtr_bytecode = (s4*)(sizePtr + 1 /*size*/ + 2 /*firstKey*/);
+            tSize = *(sizePtr);
+            sz = tSize * 4;     /* expected size needed in stream */
+            if ((stream + sz) < codeCacheEnd) {
+                for(iVer = 0; iVer < tSize; iVer++) {
+                    //update entries
+                    s4 relativePC = *entryPtr_bytecode; //relative to ptr->offsetPC
+                    //need stream, offsetPC,
+                    int relativeNCG = getRelativeNCGForSwitch(relativePC+ptr->offsetPC, ptr->codePtr2);
+#ifdef DEBUG_NCG_CODE_SIZE
+                    ALOGI("convert target from %d to %d", relativePC+ptr->offsetPC, relativeNCG);
+#endif
+                    *((s4*)stream) = relativeNCG;
+                    stream += 4;
+                    entryPtr_bytecode++;
+                }
+            } else {
+                gDvmJit.codeCacheFull = true;
+            }
+            break;
+        case OP_SPARSE_SWITCH:
+            updateImmRMInst(ptr->codePtr, "", stream-ptr->codePtr);
+            sizePtr = (u2*)currentMethod->insns+tmpPC + 1 /*signature*/;
+            s4* keyPtr_bytecode = (s4*)(sizePtr + 1 /*size*/);
+            tSize = *(sizePtr);
+            entryPtr_bytecode = (s4*)(keyPtr_bytecode + tSize);
+            sz = tSize * (sizeof(s4) + 4); /* expected size needed in stream */
+            if ((stream + sz) < codeCacheEnd) {
+                memcpy(stream, keyPtr_bytecode, tSize*sizeof(s4));
+                stream += tSize*sizeof(s4);
+                for(iVer = 0; iVer < tSize; iVer++) {
+                    //update entries
+                    s4 relativePC = *entryPtr_bytecode; //relative to ptr->offsetPC
+                    //need stream, offsetPC,
+                    int relativeNCG = getRelativeNCGForSwitch(relativePC+ptr->offsetPC, ptr->codePtr2);
+                    *((s4*)stream) = relativeNCG;
+                    stream += 4;
+                    entryPtr_bytecode++;
+                }
+            } else {
+                gDvmJit.codeCacheFull = true;
+            }
+            break;
+        }
+
+        //remove the item
+        methodDataWorklist = ptr->nextItem;
+        free(ptr);
+        ptr = methodDataWorklist;
+    }
+    return 0;
+}
+void freeDataWorklist() {
+    DataWorklist* ptr = methodDataWorklist;
+    while(ptr != NULL) {
+        methodDataWorklist = ptr->nextItem;
+        free(ptr);
+        ptr = methodDataWorklist;
+    }
+}
+
+//////////////////////////
+/*!
+\brief check whether a branch target (specified by relative offset in bytecode) is already handled, if yes, return the size of the immediate; otherwise, call insertNCGWorklist.
+
+If the branch target is not handled, call insertNCGWorklist, unknown is set to true, immSize is set to 32.
+
+If the branch target is handled, call estOpndSizeFromImm to set immSize for jump instruction, returns the value of the immediate
+*/
+int getRelativeNCG(s4 tmp, JmpCall_type type, bool* unknown, OpndSize* size) {//tmp: relativePC
+    int tmpNCG = traceLabelList[tmp].lop.generic.offset;
+
+    *unknown = false;
+    if(tmpNCG <0) {
+        *unknown = true;
+#ifdef SUPPORT_IMM_16
+        *size = OpndSize_16;
+#else
+        *size = OpndSize_32;
+#endif
+        insertNCGWorklist(tmp, *size);
+        return 0;
+    }
+    int offsetNCG2 = stream - streamMethodStart;
+#ifdef DEBUG_NCG
+    ALOGI("goto backward @ %p offsetPC %d relativePC %d offsetNCG %d relativeNCG %d", stream, offsetPC, tmp, offsetNCG2, tmpNCG-offsetNCG2);
+#endif
+    int relativeOff = tmpNCG - offsetNCG2;
+    *size = estOpndSizeFromImm(relativeOff);
+    return relativeOff - getJmpCallInstSize(*size, type);
+}
+/*!
+\brief a helper function to handle backward branch
+
+input: jump target in %eax; at end of the function, jump to %eax
+*/
+int common_backwardBranch() {
+    insertLabel("common_backwardBranch", false);
+    spill_reg(PhysicalReg_EAX, true);
+    call("common_periodicChecks_entry");
+    unspill_reg(PhysicalReg_EAX, true);
+    unconditional_jump_reg(PhysicalReg_EAX, true);
+    return 0;
+}
+//when this is called from JIT, there is no need to check GC
+int common_goto(s4 tmp) { //tmp: target basic block id
+    bool unknown;
+    OpndSize size;
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+
+    int relativeNCG = tmp;
+    relativeNCG = getRelativeNCG(tmp, JmpCall_uncond, &unknown, &size);
+    unconditional_jump_int(relativeNCG, size);
+    return 1;
+}
+int common_if(s4 tmp, ConditionCode cc_next, ConditionCode cc) {
+    bool unknown;
+    OpndSize size;
+    int relativeNCG = traceCurrentBB->taken ? traceCurrentBB->taken->id : 0;
+
+    if(traceCurrentBB->taken)
+        relativeNCG = getRelativeNCG(traceCurrentBB->taken->id, JmpCall_cond, &unknown, &size);
+    conditional_jump_int(cc, relativeNCG, size);
+    relativeNCG = traceCurrentBB->fallThrough ? traceCurrentBB->fallThrough->id : 0;
+    if(traceCurrentBB->fallThrough)
+        relativeNCG = getRelativeNCG(traceCurrentBB->fallThrough->id, JmpCall_uncond, &unknown, &size);
+    unconditional_jump_int(relativeNCG, size);
+    return 2;
+}
+
+/*!
+\brief helper function to handle null object error
+
+*/
+int common_errNullObject() {
+    insertLabel("common_errNullObject", false);
+    move_imm_to_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    move_imm_to_reg(OpndSize_32, LstrNullPointerException, PhysicalReg_ECX, true);
+    unconditional_jump("common_throw", false);
+    return 0;
+}
+/*!
+\brief helper function to handle string index error
+
+*/
+int common_StringIndexOutOfBounds() {
+    insertLabel("common_StringIndexOutOfBounds", false);
+    move_imm_to_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    move_imm_to_reg(OpndSize_32, LstrStringIndexOutOfBoundsException, PhysicalReg_ECX, true);
+    unconditional_jump("common_throw", false);
+    return 0;
+}
+
+/*!
+\brief helper function to handle array index error
+
+*/
+int common_errArrayIndex() {
+    insertLabel("common_errArrayIndex", false);
+    move_imm_to_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    move_imm_to_reg(OpndSize_32, LstrArrayIndexException, PhysicalReg_ECX, true);
+    unconditional_jump("common_throw", false);
+    return 0;
+}
+/*!
+\brief helper function to handle array store error
+
+*/
+int common_errArrayStore() {
+    insertLabel("common_errArrayStore", false);
+    move_imm_to_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    move_imm_to_reg(OpndSize_32, LstrArrayStoreException, PhysicalReg_ECX, true);
+    unconditional_jump("common_throw", false);
+    return 0;
+}
+/*!
+\brief helper function to handle negative array size error
+
+*/
+int common_errNegArraySize() {
+    insertLabel("common_errNegArraySize", false);
+    move_imm_to_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    move_imm_to_reg(OpndSize_32, LstrNegativeArraySizeException, PhysicalReg_ECX, true);
+    unconditional_jump("common_throw", false);
+    return 0;
+}
+/*!
+\brief helper function to handle divide-by-zero error
+
+*/
+int common_errDivideByZero() {
+    insertLabel("common_errDivideByZero", false);
+    move_imm_to_reg(OpndSize_32, LstrDivideByZero, PhysicalReg_EAX, true);
+    move_imm_to_reg(OpndSize_32, LstrArithmeticException, PhysicalReg_ECX, true);
+    unconditional_jump("common_throw", false);
+    return 0;
+}
+/*!
+\brief helper function to handle no such method error
+
+*/
+int common_errNoSuchMethod() {
+    insertLabel("common_errNoSuchMethod", false);
+    move_imm_to_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    move_imm_to_reg(OpndSize_32, LstrNoSuchMethodError, PhysicalReg_ECX, true);
+    unconditional_jump("common_throw", false);
+    return 0;
+}
+int call_dvmFindCatchBlock();
+
+#define P_GPR_1 PhysicalReg_ESI //self callee-saved
+#define P_GPR_2 PhysicalReg_EBX //exception callee-saved
+#define P_GPR_3 PhysicalReg_EAX //method that caused exception
+/*!
+\brief helper function common_exceptionThrown
+
+*/
+int common_exceptionThrown() {
+    insertLabel("common_exceptionThrown", false);
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = dvmJitToExceptionThrown;
+    move_imm_to_reg(OpndSize_32, (int)funcPtr, C_SCRATCH_1, isScratchPhysical);
+    unconditional_jump_reg(C_SCRATCH_1, isScratchPhysical);
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+
+/*!
+\brief helper function to throw an exception with message
+
+INPUT: obj_reg(%eax), exceptionPtrReg(%ecx)
+SCRATCH: C_SCRATCH_1(%esi) & C_SCRATCH_2(%edx)
+OUTPUT: no
+*/
+int throw_exception_message(int exceptionPtrReg, int obj_reg, bool isPhysical,
+                            int startLR/*logical register index*/, bool startPhysical) {
+    insertLabel("common_throw_message", false);
+    scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+
+    move_mem_to_reg(OpndSize_32, offObject_clazz, obj_reg, isPhysical, C_SCRATCH_1, isScratchPhysical);
+    move_mem_to_reg(OpndSize_32, offClassObject_descriptor, C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical);
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, C_SCRATCH_2, isScratchPhysical, 4, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, exceptionPtrReg, true, 0, PhysicalReg_ESP, true);
+    call_dvmThrowWithMessage();
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    unconditional_jump("common_exceptionThrown", false);
+    return 0;
+}
+/*!
+\brief helper function to throw an exception
+
+scratch: C_SCRATCH_1(%edx)
+*/
+int throw_exception(int exceptionPtrReg, int immReg,
+                    int startLR/*logical register index*/, bool startPhysical) {
+    insertLabel("common_throw", false);
+    scratchRegs[0] = PhysicalReg_EDX; scratchRegs[1] = PhysicalReg_Null;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, immReg, true, 4, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, exceptionPtrReg, true, 0, PhysicalReg_ESP, true);
+    call_dvmThrow();
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    unconditional_jump("common_exceptionThrown", false);
+    return 0;
+}
+
+//! lower bytecode GOTO
+
+//!
+int op_goto() {
+    s2 tmp = traceCurrentBB->taken->id;
+    int retval = common_goto(tmp);
+    rPC += 1;
+    return retval;
+}
+//! lower bytecode GOTO_16
+
+//!
+int op_goto_16() {
+    s2 tmp = traceCurrentBB->taken->id;
+    int retval = common_goto(tmp);
+    rPC += 2;
+    return retval;
+}
+//! lower bytecode GOTO_32
+
+//!
+int op_goto_32() {
+    s2 tmp = traceCurrentBB->taken->id;
+    int retval = common_goto((s4)tmp);
+    rPC += 3;
+    return retval;
+}
+#define P_GPR_1 PhysicalReg_EBX
+//! lower bytecode PACKED_SWITCH
+
+//!
+int op_packed_switch() {
+    u4 tmp = (u4)FETCH(1);
+    tmp |= (u4)FETCH(2) << 16;
+    u2 vA = INST_AA(inst);
+
+#ifdef DEBUG_EACH_BYTECODE
+    u2 tSize = 0;
+    s4 firstKey = 0;
+    s4* entries = NULL;
+#else
+    u2* switchData = rPC + (s4)tmp;
+    if (*switchData++ != kPackedSwitchSignature) {
+        /* should have been caught by verifier */
+        dvmThrowInternalError(
+                          "bad packed switch magic");
+        return 0; //no_op
+    }
+    u2 tSize = *switchData++;
+    assert(tSize > 0);
+    s4 firstKey = *switchData++;
+    firstKey |= (*switchData++) << 16;
+    s4* entries = (s4*) switchData;
+    assert(((u4)entries & 0x3) == 0);
+#endif
+
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    //dvmNcgHandlePackedSwitch: testVal, size, first_key, targets
+    load_effective_addr(-16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, tSize, 8, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, firstKey, 4, PhysicalReg_ESP, true);
+
+    /* "entries" is constant for JIT
+       it is the 1st argument to dvmJitHandlePackedSwitch */
+    move_imm_to_mem(OpndSize_32, (int)entries, 0, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 1, false, 12, PhysicalReg_ESP, true);
+
+    //if value out of range, fall through (no_op)
+    //return targets[testVal - first_key]
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    call_dvmJitHandlePackedSwitch();
+    load_effective_addr(16, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    //TODO: eax should be absolute address, call globalVREndOfBB, constVREndOfBB
+    //conditional_jump_global_API(Condition_LE, "common_backwardBranch", false);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod); //update GG VRs
+    //get rPC, %eax has the relative PC offset
+    alu_binary_imm_reg(OpndSize_32, add_opc, (int)rPC, PhysicalReg_EAX, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_2;
+    jumpToInterpNoChain();
+    rPC += 3;
+    return 0;
+}
+#undef P_GPR_1
+
+#define P_GPR_1 PhysicalReg_EBX
+//! lower bytecode SPARSE_SWITCH
+
+//!
+int op_sparse_switch() {
+    u4 tmp = (u4)FETCH(1);
+    tmp |= (u4)FETCH(2) << 16;
+    u2 vA = INST_AA(inst);
+#ifdef DEBUG_EACH_BYTECODE
+    u2 tSize = 0;
+    const s4* keys = NULL;
+    s4* entries = NULL;
+#else
+    u2* switchData = rPC + (s4)tmp;
+
+    if (*switchData++ != kSparseSwitchSignature) {
+        /* should have been caught by verifier */
+        dvmThrowInternalError(
+                          "bad sparse switch magic");
+        return 0; //no_op
+    }
+    u2 tSize = *switchData++;
+    assert(tSize > 0);
+    const s4* keys = (const s4*) switchData;
+    assert(((u4)keys & 0x3) == 0);
+    s4* entries = (s4*)switchData + tSize;
+    assert(((u4)entries & 0x3) == 0);
+#endif
+
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    //dvmNcgHandleSparseSwitch: keys, size, testVal
+    load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, tSize, 4, PhysicalReg_ESP, true);
+
+    /* "keys" is constant for JIT
+       it is the 1st argument to dvmJitHandleSparseSwitch */
+    move_imm_to_mem(OpndSize_32, (int)keys, 0, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 1, false, 8, PhysicalReg_ESP, true);
+
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    //if testVal is in keys, return the corresponding target
+    //otherwise, fall through (no_op)
+    call_dvmJitHandleSparseSwitch();
+    load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    //TODO: eax should be absolute address, call globalVREndOfBB constVREndOfBB
+    //conditional_jump_global_API(Condition_LE, "common_backwardBranch", false);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    //get rPC, %eax has the relative PC offset
+    alu_binary_imm_reg(OpndSize_32, add_opc, (int)rPC, PhysicalReg_EAX, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_2;
+    jumpToInterpNoChain();
+    rPC += 3;
+    return 0;
+}
+
+#undef P_GPR_1
+
+#define P_GPR_1 PhysicalReg_EBX
+//! lower bytecode IF_EQ
+
+//!
+int op_if_eq() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s2 tmp = (s2)FETCH(1);
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    compare_VR_reg(OpndSize_32, vB, 1, false);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_NE, Condition_E);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode IF_NE
+
+//!
+int op_if_ne() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s2 tmp = (s2)FETCH(1);
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    compare_VR_reg(OpndSize_32, vB, 1, false);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_E, Condition_NE);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode IF_LT
+
+//!
+int op_if_lt() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s2 tmp = (s2)FETCH(1);
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    compare_VR_reg(OpndSize_32, vB, 1, false);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_GE, Condition_L);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode IF_GE
+
+//!
+int op_if_ge() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s2 tmp = (s2)FETCH(1);
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    compare_VR_reg(OpndSize_32, vB, 1, false);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_L, Condition_GE);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode IF_GT
+
+//!
+int op_if_gt() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s2 tmp = (s2)FETCH(1);
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    compare_VR_reg(OpndSize_32, vB, 1, false);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_LE, Condition_G);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode IF_LE
+
+//!
+int op_if_le() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    s2 tmp = (s2)FETCH(1);
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    compare_VR_reg(OpndSize_32, vB, 1, false);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_G, Condition_LE);
+    rPC += 2;
+    return 0;
+}
+#undef P_GPR_1
+//! lower bytecode IF_EQZ
+
+//!
+int op_if_eqz() {
+    u2 vA = INST_AA(inst);
+    s2 tmp = (s2)FETCH(1);
+    compare_imm_VR(OpndSize_32,
+                                  0, vA);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_NE, Condition_E);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode IF_NEZ
+
+//!
+int op_if_nez() {
+    u2 vA = INST_AA(inst);
+    s2 tmp = (s2)FETCH(1);
+    compare_imm_VR(OpndSize_32,
+                                  0, vA);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_E, Condition_NE);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode IF_LTZ
+
+//!
+int op_if_ltz() {
+    u2 vA = INST_AA(inst);
+    s2 tmp = (s2)FETCH(1);
+    compare_imm_VR(OpndSize_32,
+                                  0, vA);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_GE, Condition_L);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode IF_GEZ
+
+//!
+int op_if_gez() {
+    u2 vA = INST_AA(inst);
+    s2 tmp = (s2)FETCH(1);
+    compare_imm_VR(OpndSize_32,
+                                  0, vA);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_L, Condition_GE);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode IF_GTZ
+
+//!
+int op_if_gtz() {
+    u2 vA = INST_AA(inst);
+    s2 tmp = (s2)FETCH(1);
+    compare_imm_VR(OpndSize_32,
+                                  0, vA);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_LE, Condition_G);
+    rPC += 2;
+    return 0;
+}
+//! lower bytecode IF_LEZ
+
+//!
+int op_if_lez() {
+    u2 vA = INST_AA(inst);
+    s2 tmp = (s2)FETCH(1);
+    compare_imm_VR(OpndSize_32,
+                                  0, vA);
+    constVREndOfBB();
+    globalVREndOfBB(currentMethod);
+    common_if(tmp, Condition_G, Condition_LE);
+    rPC += 2;
+    return 0;
+}
+
+#define P_GPR_1 PhysicalReg_ECX
+#define P_GPR_2 PhysicalReg_EBX
+/*!
+\brief helper function common_periodicChecks4 to check GC request
+BCOffset in %edx
+*/
+int common_periodicChecks4() {
+    insertLabel("common_periodicChecks4", false);
+#if (!defined(ENABLE_TRACING))
+    get_self_pointer(PhysicalReg_ECX, true);
+    move_mem_to_reg(OpndSize_32, offsetof(Thread, suspendCount), PhysicalReg_ECX, true, PhysicalReg_EAX, true);
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true); //suspendCount
+    conditional_jump(Condition_NE, "common_handleSuspend4", true); //called once
+    x86_return();
+
+    insertLabel("common_handleSuspend4", true);
+    push_reg_to_stack(OpndSize_32, PhysicalReg_ECX, true);
+    call_dvmCheckSuspendPending();
+    load_effective_addr(4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    x86_return();
+
+#else
+    ///////////////////
+    //get debuggerActive: 3 memory accesses, and $7
+    move_mem_to_reg(OpndSize_32, offGlue_pSelfSuspendCount, PhysicalReg_Glue, true, P_GPR_1, true);
+    move_mem_to_reg(OpndSize_32, offGlue_pIntoDebugger, PhysicalReg_Glue, true, P_GPR_2, true);
+
+    compare_imm_mem(OpndSize_32, 0, 0, P_GPR_1, true); //suspendCount
+    conditional_jump(Condition_NE, "common_handleSuspend4_1", true); //called once
+
+    compare_imm_mem(OpndSize_32, 0, 0, P_GPR_2, true); //debugger active
+
+    conditional_jump(Condition_NE, "common_debuggerActive4", true);
+
+    //recover registers and return
+    x86_return();
+
+    insertLabel("common_handleSuspend4_1", true);
+    push_mem_to_stack(OpndSize_32, offGlue_self, PhysicalReg_Glue, true);
+    call_dvmCheckSuspendPending();
+    load_effective_addr(4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    x86_return();
+
+    insertLabel("common_debuggerActive4", true);
+    //%edx: offsetBC (at run time, get method->insns_bytecode, then calculate BCPointer)
+    move_mem_to_reg(OpndSize_32, offGlue_method, PhysicalReg_Glue, true, P_GPR_1, true);
+    move_mem_to_reg(OpndSize_32, offMethod_insns_bytecode, P_GPR_1, true, P_GPR_2, true);
+    alu_binary_reg_reg(OpndSize_32, add_opc, P_GPR_2, true, PhysicalReg_EDX, true);
+    move_imm_to_mem(OpndSize_32, 0, offGlue_entryPoint, PhysicalReg_Glue, true);
+    unconditional_jump("common_gotoBail", false); //update glue->rPC with edx
+#endif
+    return 0;
+}
+//input: %edx PC adjustment
+//CHECK: should %edx be saved before calling dvmCheckSuspendPending?
+/*!
+\brief helper function common_periodicChecks_entry to check GC request
+
+*/
+int common_periodicChecks_entry() {
+    insertLabel("common_periodicChecks_entry", false);
+    scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EAX;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    get_suspendCount(P_GPR_1, true);
+
+    //get debuggerActive: 3 memory accesses, and $7
+#if 0 //defined(WITH_DEBUGGER)
+    get_debuggerActive(P_GPR_2, true);
+#endif
+
+    compare_imm_reg(OpndSize_32, 0, P_GPR_1, true); //suspendCount
+    conditional_jump(Condition_NE, "common_handleSuspend", true); //called once
+
+#if 0 //defined(WITH_DEBUGGER)
+#ifdef NCG_DEBUG
+    compare_imm_reg(OpndSize_32, 0, P_GPR_2, true); //debugger active
+    conditional_jump(Condition_NE, "common_debuggerActive", true);
+#endif
+#endif
+
+    //recover registers and return
+    x86_return();
+    insertLabel("common_handleSuspend", true);
+    get_self_pointer(P_GPR_1, true);
+    load_effective_addr(-4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, P_GPR_1, true, 0, PhysicalReg_ESP, true);
+    call_dvmCheckSuspendPending();
+    load_effective_addr(4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    x86_return();
+#ifdef NCG_DEBUG
+    insertLabel("common_debuggerActive", true);
+    //adjust PC!!! use 0(%esp) TODO
+    set_glue_entryPoint_imm(0); //kInterpEntryInstr);
+    unconditional_jump("common_gotoBail", false);
+#endif
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+/*!
+\brief helper function common_gotoBail
+  input: %edx: BCPointer %esi: Glue
+  set %eax to 1 (switch interpreter = true), recover the callee-saved registers and return
+*/
+int common_gotoBail() {
+    insertLabel("common_gotoBail", false);
+    //scratchRegs[0] = PhysicalReg_EDX; scratchRegs[1] = PhysicalReg_ESI;
+    //scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    //save_pc_fp_to_glue();
+    get_self_pointer(PhysicalReg_EAX, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_FP, true, offsetof(Thread, interpSave.curFrame), PhysicalReg_EAX, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_EDX, true, offsetof(Thread, interpSave.pc), PhysicalReg_EAX, true);
+
+    move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.bailPtr), PhysicalReg_EAX, true, PhysicalReg_ESP, true);
+    move_reg_to_reg(OpndSize_32, PhysicalReg_ESP, true, PhysicalReg_EBP, true);
+    load_effective_addr(FRAME_SIZE-4, PhysicalReg_EBP, true, PhysicalReg_EBP, true);
+    move_imm_to_reg(OpndSize_32, 1, PhysicalReg_EAX, true); //return value
+    move_mem_to_reg(OpndSize_32, -4, PhysicalReg_EBP, true, PhysicalReg_EDI, true);
+    move_mem_to_reg(OpndSize_32, -8, PhysicalReg_EBP, true, PhysicalReg_ESI, true);
+    move_mem_to_reg(OpndSize_32, -12, PhysicalReg_EBP, true, PhysicalReg_EBX, true);
+    move_reg_to_reg(OpndSize_32, PhysicalReg_EBP, true, PhysicalReg_ESP, true);
+    move_mem_to_reg(OpndSize_32, 0, PhysicalReg_ESP, true, PhysicalReg_EBP, true);
+    load_effective_addr(4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    x86_return();
+    return 0;
+}
+/*!
+\brief helper function common_gotoBail_0
+
+  set %eax to 0, recover the callee-saved registers and return
+*/
+int common_gotoBail_0() {
+    insertLabel("common_gotoBail_0", false);
+
+    get_self_pointer(PhysicalReg_EAX, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_FP, true, offsetof(Thread, interpSave.curFrame), PhysicalReg_EAX, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_EDX, true, offsetof(Thread, interpSave.pc), PhysicalReg_EAX, true);
+
+    /*
+    movl    offThread_bailPtr(%ecx),%esp # Restore "setjmp" esp
+    movl    %esp,%ebp
+    addl    $(FRAME_SIZE-4), %ebp       # Restore %ebp at point of setjmp
+    movl    EDI_SPILL(%ebp),%edi
+    movl    ESI_SPILL(%ebp),%esi
+    movl    EBX_SPILL(%ebp),%ebx
+    movl    %ebp, %esp                   # strip frame
+    pop     %ebp                         # restore caller's ebp
+    ret                                  # return to dvmMterpStdRun's caller
+    */
+    move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.bailPtr), PhysicalReg_EAX, true, PhysicalReg_ESP, true);
+    move_reg_to_reg(OpndSize_32, PhysicalReg_ESP, true, PhysicalReg_EBP, true);
+    load_effective_addr(FRAME_SIZE-4, PhysicalReg_EBP, true, PhysicalReg_EBP, true);
+    move_imm_to_reg(OpndSize_32, 0, PhysicalReg_EAX, true); //return value
+    move_mem_to_reg(OpndSize_32, -4, PhysicalReg_EBP, true, PhysicalReg_EDI, true);
+    move_mem_to_reg(OpndSize_32, -8, PhysicalReg_EBP, true, PhysicalReg_ESI, true);
+    move_mem_to_reg(OpndSize_32, -12, PhysicalReg_EBP, true, PhysicalReg_EBX, true);
+    move_reg_to_reg(OpndSize_32, PhysicalReg_EBP, true, PhysicalReg_ESP, true);
+    move_mem_to_reg(OpndSize_32, 0, PhysicalReg_ESP, true, PhysicalReg_EBP, true);
+    load_effective_addr(4, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    x86_return();
+    return 0;
+}
diff --git a/vm/compiler/codegen/x86/LowerMove.cpp b/vm/compiler/codegen/x86/LowerMove.cpp
new file mode 100644
index 0000000..2f0b5bc
--- /dev/null
+++ b/vm/compiler/codegen/x86/LowerMove.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file LowerMove.cpp
+    \brief This file lowers the following bytecodes: MOVE_XXX
+*/
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "enc_wrapper.h"
+
+#define P_GPR_1 PhysicalReg_EBX
+//! lower bytecode MOVE
+
+//!
+int op_move() {
+    u2 vA, vB;
+    vA = INST_A(inst);
+    vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_32, 1, false/*isPhysical*/);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 1;
+    return 2;
+}
+//! lower bytecode MOVE_FROM16
+
+//!
+int op_move_from16() {
+    u2 vA, vB;
+    vA = INST_AA(inst);
+    vB = FETCH(1);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 2;
+    return 2;
+}
+//! lower bytecode MOVE_16
+
+//!
+int op_move_16() {
+    u2 vA, vB;
+    vA = FETCH(1);
+    vB = FETCH(2);
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 3;
+    return 2;
+}
+#undef P_GPR_1
+//! lower bytecode MOVE_WIDE
+
+//!
+int op_move_wide() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    get_virtual_reg(vB, OpndSize_64, 1, false);
+    set_virtual_reg(vA, OpndSize_64, 1, false);
+    rPC += 1;
+    return 2;
+}
+//! lower bytecode MOVE_WIDE_FROM16
+
+//!
+int op_move_wide_from16() {
+    u2 vA = INST_AA(inst);
+    u2 vB = FETCH(1);
+    get_virtual_reg(vB, OpndSize_64, 1, false);
+    set_virtual_reg(vA, OpndSize_64, 1, false);
+    rPC += 2;
+    return 2;
+}
+//! lower bytecode MOVE_WIDE_16
+
+//!
+int op_move_wide_16() {
+    u2 vA = FETCH(1);
+    u2 vB = FETCH(2);
+    get_virtual_reg(vB, OpndSize_64, 1, false);
+    set_virtual_reg(vA, OpndSize_64, 1, false);
+    rPC += 3;
+    return 2;
+}
+//! lower bytecode MOVE_RESULT.
+
+//! the return value from bytecode INVOKE is stored in the glue structure
+int op_move_result() {
+#ifdef WITH_JIT_INLINING
+    /* An inlined move result is effectively no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return 0;
+#endif
+    u2 vA = INST_AA(inst);
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    get_return_value(OpndSize_32, 1, false);
+    set_virtual_reg(vA, OpndSize_32, 1, false);
+    rPC += 1;
+    return 0;
+}
+//! lower bytecode MOVE_RESULT_WIDE.
+
+//! the return value from bytecode INVOKE is stored in the glue structure
+int op_move_result_wide() {
+#ifdef WITH_JIT_INLINING
+    /* An inlined move result is effectively no-op */
+    if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
+        return 0;
+#endif
+    u2 vA = INST_AA(inst);
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    get_return_value(OpndSize_64, 1, false);
+    set_virtual_reg(vA, OpndSize_64, 1, false);
+    rPC += 1;
+    return 0;
+}
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+//!lower bytecode MOVE_RESULT_EXCEPTION
+
+//!update a virtual register with exception from glue structure;
+//!clear the exception from glue structure
+int op_move_exception() {
+    u2 vA = INST_AA(inst);
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    scratchRegs[0] = PhysicalReg_SCRATCH_1; scratchRegs[1] = PhysicalReg_Null;
+    get_self_pointer(2, false);
+    move_mem_to_reg(OpndSize_32, offThread_exception, 2, false, 3, false);
+    move_imm_to_mem(OpndSize_32, 0, offThread_exception, 2, false);
+    set_virtual_reg(vA, OpndSize_32, 3, false);
+    rPC += 1;
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+
diff --git a/vm/compiler/codegen/x86/LowerObject.cpp b/vm/compiler/codegen/x86/LowerObject.cpp
new file mode 100644
index 0000000..67c4044
--- /dev/null
+++ b/vm/compiler/codegen/x86/LowerObject.cpp
@@ -0,0 +1,682 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*! \file LowerObject.cpp
+    \brief This file lowers the following bytecodes: CHECK_CAST,
+*/
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "NcgAot.h"
+#include "enc_wrapper.h"
+
+extern void markCard_filled(int tgtAddrReg, bool isTgtPhysical, int scratchReg, bool isScratchPhysical);
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_ESI
+//! LOWER bytecode CHECK_CAST and INSTANCE_OF
+//!   CALL class_resolve (%ebx is live across the call)
+//!        dvmInstanceofNonTrivial
+//!   NO register is live through function check_cast_helper
+int check_cast_nohelper(u2 vA, u4 tmp, bool instance, u2 vDest) {
+    get_virtual_reg(vA, OpndSize_32, 1, false); //object
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    /* for trace-based JIT, it is likely that the class is already resolved */
+    bool needToResolve = true;
+    ClassObject *classPtr =
+                (currentMethod->clazz->pDvmDex->pResClasses[tmp]);
+    ALOGV("in check_cast, class is resolved to %p", classPtr);
+    if(classPtr != NULL) {
+        needToResolve = false;
+        ALOGV("check_cast class %s", classPtr->descriptor);
+    }
+    if(needToResolve) {
+        //get_res_classes is moved here for NCG O1 to improve performance of GLUE optimization
+        scratchRegs[0] = PhysicalReg_SCRATCH_1; scratchRegs[1] = PhysicalReg_SCRATCH_2;
+        get_res_classes(4, false);
+    }
+    compare_imm_reg(OpndSize_32, 0, 1, false);
+
+    rememberState(1);
+    //for private code cache, previously it jumped to .instance_of_okay_1
+    //if object reference is null, jump to the handler for this special case
+    if(instance) {
+        conditional_jump(Condition_E, ".instance_of_null", true);
+    }
+    else {
+        conditional_jump(Condition_E, ".check_cast_null", true);
+    }
+    //check whether the class is already resolved
+    //if yes, jump to check_cast_resolved
+    //if not, call class_resolve
+    if(needToResolve) {
+        move_mem_to_reg(OpndSize_32, tmp*4, 4, false, PhysicalReg_EAX, true);
+        compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+        if(instance)
+            conditional_jump(Condition_NE, ".instance_of_resolved", true);
+        else
+            conditional_jump(Condition_NE, ".check_cast_resolved", true);
+        //try to resolve the class
+        rememberState(2);
+        move_imm_to_reg(OpndSize_32, tmp, PhysicalReg_EAX, true);
+        export_pc(); //trying to resolve the class
+        call_helper_API(".class_resolve");
+        transferToState(2);
+    } //needToResolve
+    else {
+        /* the class is already resolved and is constant */
+        move_imm_to_reg(OpndSize_32, (int)classPtr, PhysicalReg_EAX, true);
+    }
+    //class is resolved, and it is in %eax
+    if(!instance) {
+        insertLabel(".check_cast_resolved", true);
+    }
+    else insertLabel(".instance_of_resolved", true);
+
+    move_mem_to_reg(OpndSize_32, offObject_clazz, 1, false, 6, false); //object->clazz
+
+    //%eax: resolved class
+    //compare resolved class and object->clazz
+    //if the same, jump to the handler for this special case
+    compare_reg_reg(PhysicalReg_EAX, true, 6, false);
+    rememberState(3);
+    if(instance) {
+        conditional_jump(Condition_E, ".instance_of_equal", true);
+    } else {
+        conditional_jump(Condition_E, ".check_cast_equal", true);
+    }
+
+    //prepare to call dvmInstanceofNonTrivial
+    //INPUT: the resolved class & object reference
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 6, false, 0, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_EAX, true, 4, PhysicalReg_ESP, true); //resolved class
+    scratchRegs[0] = PhysicalReg_SCRATCH_3;
+    nextVersionOfHardReg(PhysicalReg_EAX, 2); //next version has 2 refs
+    call_dvmInstanceofNonTrivial();
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    //
+    if(instance) {
+        //move return value to P_GPR_2
+        move_reg_to_reg(OpndSize_32, PhysicalReg_EAX, true, 3, false);
+        rememberState(4);
+        unconditional_jump(".instance_of_okay", true);
+    } else {
+        //if return value of dvmInstanceofNonTrivial is zero, throw exception
+        compare_imm_reg(OpndSize_32, 0,  PhysicalReg_EAX, true);
+        rememberState(4);
+        conditional_jump(Condition_NE, ".check_cast_okay", true);
+        //two inputs for common_throw_message: object reference in eax, exception pointer in ecx
+        nextVersionOfHardReg(PhysicalReg_EAX, 1); //next version has 1 ref
+        move_reg_to_reg(OpndSize_32, 1, false, PhysicalReg_EAX, true);
+
+        load_imm_global_data_API("strClassCastExceptionPtr", OpndSize_32, PhysicalReg_ECX, true);
+
+        nextVersionOfHardReg(PhysicalReg_EDX, 2); //next version has 2 ref count
+        export_pc();
+
+        unconditional_jump_global_API("common_throw_message", false);
+    }
+    //handler for speical case where object reference is null
+    if(instance)
+        insertLabel(".instance_of_null", true);
+    else insertLabel(".check_cast_null", true);
+    goToState(1);
+    if(instance) {
+        move_imm_to_reg(OpndSize_32, 0, 3, false);
+    }
+    transferToState(4);
+    if(instance)
+        unconditional_jump(".instance_of_okay", true);
+    else
+        unconditional_jump(".check_cast_okay", true);
+
+    //handler for special case where class of object is the same as the resolved class
+    if(instance)
+        insertLabel(".instance_of_equal", true);
+    else insertLabel(".check_cast_equal", true);
+    goToState(3);
+    if(instance) {
+        move_imm_to_reg(OpndSize_32, 1, 3, false);
+    }
+    transferToState(4);
+    if(instance)
+        insertLabel(".instance_of_okay", true);
+    else insertLabel(".check_cast_okay", true);
+    //all cases merge here and the value is put to virtual register
+    if(instance) {
+        set_virtual_reg(vDest, OpndSize_32, 3, false);
+    }
+    return 0;
+}
+//! common code to lower CHECK_CAST & INSTANCE_OF
+
+//!
+int common_check_cast_instance_of(u2 vA, u4 tmp, bool instance, u2 vDest) {
+    return check_cast_nohelper(vA, tmp, instance, vDest);
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+
+//! LOWER bytecode CHECK_CAST
+
+//!
+int op_check_cast() {
+    u2 vA = INST_AA(inst);
+    u4 tmp = (u4)FETCH(1);
+    common_check_cast_instance_of(vA, tmp, false, 0);
+    rPC += 2;
+    return 0;
+}
+//!LOWER bytecode INSTANCE_OF
+
+//!
+int op_instance_of() {
+    u2 vB = INST_B(inst);
+    u2 vA = INST_A(inst);
+    u4 tmp = (u4)FETCH(1);
+    common_check_cast_instance_of(vB, tmp, true, vA);
+    rPC += 2;
+    return 0;
+}
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+//! LOWER bytecode MONITOR_ENTER without usage of helper function
+
+//!   CALL dvmLockObject
+int monitor_enter_nohelper(u2 vA) {
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+
+    requestVRFreeDelay(vA,VRDELAY_NULLCHECK); // Request VR delay before transfer to temporary
+    //get_self_pointer is separated
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    //to optimize redundant null check, NCG O1 wraps up null check in a function: nullCheck
+    get_self_pointer(3, false);
+    nullCheck(1, false, 1, vA); //maybe optimized away
+    cancelVRFreeDelayRequest(vA,VRDELAY_NULLCHECK);
+
+    /////////////////////////////
+    //prepare to call dvmLockObject, inputs: object reference and self
+    // TODO: Should reset inJitCodeCache before calling dvmLockObject
+    //       so that code cache can be reset if needed when locking object
+    //       taking a long time. Not resetting inJitCodeCache may delay
+    //       code cache reset when code cache is full, preventing traces from
+    //       JIT compilation. This has performance implication.
+    //       However, after resetting inJitCodeCache, the code should be
+    //       wrapped in a helper instead of directly inlined in code cache.
+    //       If the code after dvmLockObject call is in code cache and the code
+    //       cache is reset during dvmLockObject call, execution after
+    //       dvmLockObject will return to a cleared code cache region,
+    //       resulting in seg fault.
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 1, false, 4, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 3, false, 0, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_2;
+    call_dvmLockObject();
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    /////////////////////////////
+    return 0;
+}
+//! lower bytecode MONITOR_ENTER
+
+//! It will use helper function if switch is on
+int op_monitor_enter() {
+    u2 vA = INST_AA(inst);
+    export_pc();
+    monitor_enter_nohelper(vA);
+    rPC += 1;
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+//! lower bytecode MONITOR_EXIT
+
+//! It will use helper function if switch is on
+int op_monitor_exit() {
+    u2 vA = INST_AA(inst);
+    ////////////////////
+    //LOWER bytecode MONITOR_EXIT without helper function
+    //   CALL dvmUnlockObject
+    scratchRegs[0] = PhysicalReg_SCRATCH_1; scratchRegs[1] = PhysicalReg_SCRATCH_2;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    requestVRFreeDelay(vA,VRDELAY_NULLCHECK); // Request VR delay before transfer to temporary
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    nullCheck(1, false, 1, vA); //maybe optimized away
+    cancelVRFreeDelayRequest(vA,VRDELAY_NULLCHECK);
+
+    /////////////////////////////
+    //prepare to call dvmUnlockObject, inputs: object reference and self
+    push_reg_to_stack(OpndSize_32, 1, false);
+    push_mem_to_stack(OpndSize_32, offEBP_self, PhysicalReg_EBP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_2;
+    call_dvmUnlockObject();
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+
+    conditional_jump(Condition_NE, ".unlock_object_done", true);
+    //jump to dvmJitToExceptionThrown
+    scratchRegs[0] = PhysicalReg_SCRATCH_3;
+    jumpToExceptionThrown(2/*exception number*/);
+    insertLabel(".unlock_object_done", true);
+    ///////////////////////////
+    rPC += 1;
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_EDX /*vA*/
+//! LOWER bytecode ARRAY_LENGTH
+
+//! It will use helper function if switch is on
+int op_array_length() {
+    u2 vA = INST_A(inst);
+    u2 vB = INST_B(inst);
+    ////////////////////
+    //no usage of helper function
+    requestVRFreeDelay(vB,VRDELAY_NULLCHECK); // Request VR delay before transfer to temporary
+    get_virtual_reg(vB, OpndSize_32, 1, false);
+    nullCheck(1, false, 1, vB); //maybe optimized away
+    cancelVRFreeDelayRequest(vB,VRDELAY_NULLCHECK);
+
+    move_mem_to_reg(OpndSize_32, offArrayObject_length, 1, false, 2, false);
+    set_virtual_reg(vA, OpndSize_32, 2, false);
+    ///////////////////////
+    rPC += 1;
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_ESI
+//! lower bytecode NEW_INSTANCE
+
+//! It will use helper function if switch is on
+int op_new_instance() {
+    u4 tmp = (u4)FETCH(1);
+    u2 vA = INST_AA(inst);
+    export_pc();
+    /* for trace-based JIT, class is already resolved */
+    ClassObject *classPtr =
+        (currentMethod->clazz->pDvmDex->pResClasses[tmp]);
+    assert(classPtr != NULL);
+    assert(classPtr->status & CLASS_INITIALIZED);
+    /*
+     * If it is going to throw, it should not make to the trace to begin
+     * with.  However, Alloc might throw, so we need to genExportPC()
+     */
+    assert((classPtr->accessFlags & (ACC_INTERFACE|ACC_ABSTRACT)) == 0);
+    //prepare to call dvmAllocObject, inputs: resolved class & flag ALLOC_DONT_TRACK
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    /* 1st argument to dvmAllocObject at -8(%esp) */
+    move_imm_to_mem(OpndSize_32, (int)classPtr, 0, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, ALLOC_DONT_TRACK, 4, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_3;
+    nextVersionOfHardReg(PhysicalReg_EAX, 3); //next version has 3 refs
+    call_dvmAllocObject();
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    //return value of dvmAllocObject is in %eax
+    //if return value is null, throw exception
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump(Condition_NE, ".new_instance_done", true);
+    //jump to dvmJitToExceptionThrown
+    scratchRegs[0] = PhysicalReg_SCRATCH_4;
+    jumpToExceptionThrown(3/*exception number*/);
+    insertLabel(".new_instance_done", true);
+    set_virtual_reg(vA, OpndSize_32, PhysicalReg_EAX, true);
+    rPC += 2;
+    return 0;
+}
+
+//! function to initialize a class
+
+//!INPUT: %eax (class object) %eax is recovered before return
+//!OUTPUT: none
+//!CALL: dvmInitClass
+//!%eax, %esi, %ebx are live through function new_instance_needinit
+int new_instance_needinit() {
+    insertLabel(".new_instance_needinit", false);
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_EAX, true, 0, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, PhysicalReg_EAX, true, 4, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_ECX;
+    call_dvmInitClass();
+    //if return value of dvmInitClass is zero, throw exception
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    //recover EAX with the class object
+    move_mem_to_reg(OpndSize_32, 4, PhysicalReg_ESP, true, PhysicalReg_EAX, true);
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    conditional_jump(Condition_E, "common_exceptionThrown", false);
+    x86_return();
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+
+#define P_GPR_1 PhysicalReg_EBX //live through C function, must in callee-saved reg
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_EDX
+//! lower bytecode NEW_ARRAY
+
+//! It will use helper function if switch is on
+int op_new_array() {
+    u4 tmp = (u4)FETCH(1);
+    u2 vA = INST_A(inst); //destination
+    u2 vB = INST_B(inst); //length
+    /////////////////////////
+    //   REGS used: %esi, %eax, P_GPR_1, P_GPR_2
+    //   CALL class_resolve, dvmAllocArrayByClass
+    export_pc(); //use %edx
+    //check size of the array, if negative, throw exception
+    get_virtual_reg(vB, OpndSize_32, 5, false);
+    compare_imm_reg(OpndSize_32, 0, 5, false);
+    handlePotentialException(Condition_S, Condition_NS,
+                             1, "common_errNegArraySize");
+    void *classPtr = (void*)
+        (currentMethod->clazz->pDvmDex->pResClasses[tmp]);
+    assert(classPtr != NULL);
+    //here, class is already resolved, the class object is in %eax
+    //prepare to call dvmAllocArrayByClass with inputs: resolved class, array length, flag ALLOC_DONT_TRACK
+    insertLabel(".new_array_resolved", true);
+    load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    /* 1st argument to dvmAllocArrayByClass at 0(%esp) */
+    move_imm_to_mem(OpndSize_32, (int)classPtr, 0, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 5, false, 4, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, ALLOC_DONT_TRACK, 8, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_3;
+    nextVersionOfHardReg(PhysicalReg_EAX, 3); //next version has 3 refs
+    call_dvmAllocArrayByClass();
+    load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+
+    //the allocated object is in %eax
+    //check whether it is null, throw exception if null
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump(Condition_NE, ".new_array_done", true);
+    //jump to dvmJitToExceptionThrown
+    scratchRegs[0] = PhysicalReg_SCRATCH_4;
+    jumpToExceptionThrown(2/*exception number*/);
+    insertLabel(".new_array_done", true);
+    set_virtual_reg(vA, OpndSize_32, PhysicalReg_EAX, true);
+    //////////////////////////////////////
+    rPC += 2;
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+
+#define P_GPR_1 PhysicalReg_EBX
+#define P_GPR_2 PhysicalReg_ECX
+#define P_GPR_3 PhysicalReg_ESI
+//! common code to lower FILLED_NEW_ARRAY
+
+//! call: class_resolve call_dvmAllocPrimitiveArray
+//! exception: filled_new_array_notimpl common_exceptionThrown
+int common_filled_new_array(u2 length, u4 tmp, bool hasRange) {
+    ClassObject *classPtr =
+              (currentMethod->clazz->pDvmDex->pResClasses[tmp]);
+    if(classPtr != NULL) ALOGI("FILLED_NEW_ARRAY class %s", classPtr->descriptor);
+    //check whether class is resolved, if yes, jump to resolved
+    //if not, call class_resolve
+    scratchRegs[0] = PhysicalReg_SCRATCH_1; scratchRegs[1] = PhysicalReg_SCRATCH_2;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    get_res_classes(3, false);
+    move_mem_to_reg(OpndSize_32, tmp*4, 3, false, PhysicalReg_EAX, true);
+    export_pc();
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true); //resolved class
+    conditional_jump(Condition_NE, ".filled_new_array_resolved", true);
+    rememberState(1);
+    move_imm_to_reg(OpndSize_32, tmp, PhysicalReg_EAX, true);
+    call_helper_API(".class_resolve");
+    transferToState(1);
+    //here, class is already resolved
+    insertLabel(".filled_new_array_resolved", true);
+    //check descriptor of the class object, if not implemented, throws exception
+    move_mem_to_reg(OpndSize_32, 24, PhysicalReg_EAX, true, 5, false);
+    //load a single byte of the descriptor
+    movez_mem_to_reg(OpndSize_8, 1, 5, false, 6, false);
+    compare_imm_reg(OpndSize_32, 'I', 6, false);
+    conditional_jump(Condition_E, ".filled_new_array_impl", true);
+    compare_imm_reg(OpndSize_32, 'L', 6, false);
+    conditional_jump(Condition_E, ".filled_new_array_impl", true);
+    compare_imm_reg(OpndSize_32, '[', 6, false);
+    conditional_jump(Condition_NE, ".filled_new_array_notimpl", false);
+
+    insertLabel(".filled_new_array_impl", true);
+    //prepare to call dvmAllocArrayByClass with inputs: classObject, length, flag ALLOC_DONT_TRACK
+    load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, (int)classPtr, 0, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, length, 4, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, ALLOC_DONT_TRACK, 8, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_3; scratchRegs[1] = PhysicalReg_Null;
+    if(hasRange) {
+        nextVersionOfHardReg(PhysicalReg_EAX, 5+(length >= 1 ? LOOP_COUNT : 0)); //next version
+    }
+    else {
+        nextVersionOfHardReg(PhysicalReg_EAX, 5+length); //next version
+    }
+    call_dvmAllocArrayByClass();
+    load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    //return value of dvmAllocPrimitiveArray is in %eax
+    //if the return value is null, throw exception
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    handlePotentialException(
+                                       Condition_E, Condition_NE,
+                                       3, "common_exceptionThrown");
+
+    /* we need to mark the card of the new array, if it's not an int */
+    compare_imm_reg(OpndSize_32, 'I', 6, false);
+    conditional_jump(Condition_E, ".dont_mark_filled_new_array", true);
+
+    // Need to make copy of EAX, because it's used later in op_filled_new_array()
+    move_reg_to_reg(OpndSize_32, PhysicalReg_EAX, true, 6, false);
+
+    markCard_filled(6, false, PhysicalReg_SCRATCH_4, false);
+
+    insertLabel(".dont_mark_filled_new_array", true);
+
+    //return value of bytecode FILLED_NEW_ARRAY is in GLUE structure
+    scratchRegs[0] = PhysicalReg_SCRATCH_4; scratchRegs[1] = PhysicalReg_Null;
+    set_return_value(OpndSize_32, PhysicalReg_EAX, true);
+    return 0;
+}
+//! LOWER bytecode FILLED_NEW_ARRAY
+
+//!
+int op_filled_new_array() {
+    u2 length = INST_B(inst);
+    u4 tmp = (u4)FETCH(1);
+    u2 v5 = INST_A(inst);
+    u2 vv = FETCH(2);
+    u2 v1 = vv & 0xf;
+    u2 v2 = (vv >> 4) & 0xf;
+    u2 v3 = (vv >> 8) & 0xf;
+    u2 v4 = (vv >> 12) & 0xf;
+    common_filled_new_array(length, tmp, false);
+    if(length >= 1) {
+        //move from virtual register to contents of array object
+        get_virtual_reg(v1, OpndSize_32, 7, false);
+        move_reg_to_mem(OpndSize_32, 7, false, offArrayObject_contents, PhysicalReg_EAX, true);
+    }
+    if(length >= 2) {
+        //move from virtual register to contents of array object
+        get_virtual_reg(v2, OpndSize_32, 8, false);
+        move_reg_to_mem(OpndSize_32, 8, false, offArrayObject_contents+4, PhysicalReg_EAX, true);
+    }
+    if(length >= 3) {
+        //move from virtual register to contents of array object
+        get_virtual_reg(v3, OpndSize_32, 9, false);
+        move_reg_to_mem(OpndSize_32, 9, false, offArrayObject_contents+8, PhysicalReg_EAX, true);
+    }
+    if(length >= 4) {
+        //move from virtual register to contents of array object
+        get_virtual_reg(v4, OpndSize_32, 10, false);
+        move_reg_to_mem(OpndSize_32, 10, false, offArrayObject_contents+12, PhysicalReg_EAX, true);
+    }
+    if(length >= 5) {
+        //move from virtual register to contents of array object
+        get_virtual_reg(v5, OpndSize_32, 11, false);
+        move_reg_to_mem(OpndSize_32, 11, false, offArrayObject_contents+16, PhysicalReg_EAX, true);
+    }
+    rPC += 3;
+    return 0;
+}
+//! function to handle the error of array not implemented
+
+//!
+int filled_new_array_notimpl() {
+    //two inputs for common_throw:
+    insertLabel(".filled_new_array_notimpl", false);
+    move_imm_to_reg(OpndSize_32, LstrFilledNewArrayNotImpl, PhysicalReg_EAX, true);
+    move_imm_to_reg(OpndSize_32, (int) gDvm.exInternalError, PhysicalReg_ECX, true);
+    unconditional_jump("common_throw", false);
+    return 0;
+}
+
+#define P_SCRATCH_1 PhysicalReg_EDX
+//! LOWER bytecode FILLED_NEW_ARRAY_RANGE
+
+//!
+int op_filled_new_array_range() {
+    u2 length = INST_AA(inst);
+    u4 tmp = (u4)FETCH(1);
+    u4 vC = (u4)FETCH(2);
+    common_filled_new_array(length, tmp, true/*hasRange*/);
+    //here, %eax points to the array object
+    if(length >= 1) {
+        //dump all virtual registers used by this bytecode to stack, for NCG O1
+        int k;
+        for(k = 0; k < length; k++) {
+            spillVirtualReg(vC+k, LowOpndRegType_gp, true); //will update refCount
+        }
+        //address of the first virtual register that will be moved to the array object
+        load_effective_addr(vC*4, PhysicalReg_FP, true, 7, false); //addr
+        //start address for contents of the array object
+        load_effective_addr(offArrayObject_contents, PhysicalReg_EAX, true, 8, false); //addr
+        //loop counter
+        move_imm_to_reg(OpndSize_32, length-1, 9, false); //counter
+        //start of the loop
+        insertLabel(".filled_new_array_range_loop1", true);
+        rememberState(1);
+        move_mem_to_reg(OpndSize_32, 0, 7, false, 10, false);
+        load_effective_addr(4, 7, false, 7, false);
+        move_reg_to_mem(OpndSize_32, 10, false, 0, 8, false);
+        load_effective_addr(4, 8, false, 8, false);
+        alu_binary_imm_reg(OpndSize_32, sub_opc, 1, 9, false);
+        transferToState(1);
+        //jump back to the loop start
+        conditional_jump(Condition_NS, ".filled_new_array_range_loop1", true);
+    }
+    rPC += 3;
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_GPR_3
+#undef P_SCRATCH_1
+
+#define P_GPR_1 PhysicalReg_EBX
+//! LOWER bytecode FILL_ARRAY_DATA
+
+//!use 1 GPR and scratch regs (export_pc dvmInterpHandleFillArrayData)
+//!CALL: dvmInterpHandleFillArrayData
+int op_fill_array_data() {
+    u2 vA = INST_AA(inst);
+    u4 tmp = (u4)FETCH(1);
+    tmp |= (u4)FETCH(2) << 16;
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    scratchRegs[1] = PhysicalReg_Null;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    //prepare to call dvmInterpHandleFillArrayData, input: array object, address of the data
+    load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 1, false, 0, PhysicalReg_ESP, true);
+    /* 2nd argument to dvmInterpHandleFillArrayData at 4(%esp) */
+    move_imm_to_mem(OpndSize_32, (int)(rPC+tmp), 4, PhysicalReg_ESP, true);
+    call_dvmInterpHandleFillArrayData();
+    load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+
+    //check return value of dvmInterpHandleFillArrayData, if zero, throw exception
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true);
+    conditional_jump(Condition_NE, ".fill_array_data_done", true);
+    //jump to dvmJitToExceptionThrown
+    scratchRegs[0] = PhysicalReg_SCRATCH_2;
+    jumpToExceptionThrown(2/*exception number*/);
+    insertLabel(".fill_array_data_done", true);
+    rPC += 3;
+    return 0;
+}
+#undef P_GPR_1
+
+#define P_GPR_1 PhysicalReg_EBX
+//! LOWER bytecode THROW
+
+//!
+int op_throw() {
+    u2 vA = INST_AA(inst);
+    export_pc();
+    get_virtual_reg(vA, OpndSize_32, 1, false);
+    //null check
+    compare_imm_reg(OpndSize_32, 0, 1, false);
+    conditional_jump(Condition_E, "common_errNullObject", false);
+    //set glue->exception & throw exception
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    scratchRegs[0] = PhysicalReg_SCRATCH_1; scratchRegs[1] = PhysicalReg_SCRATCH_2;
+    set_exception(1, false);
+    unconditional_jump("common_exceptionThrown", false);
+    rPC += 1;
+    return 0;
+}
+#undef P_GPR_1
+#define P_GPR_1 PhysicalReg_EBX
+//! LOWER bytecode THROW_VERIFICATION_ERROR
+
+//! op AA, ref@BBBB
+int op_throw_verification_error() {
+    u2 vA, vB;
+    vA = INST_AA(inst);
+    vB = FETCH(1);
+
+    export_pc();
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    get_glue_method(1, false);
+
+    load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, vB, 8, PhysicalReg_ESP, true);
+    move_imm_to_mem(OpndSize_32, vA, 4, PhysicalReg_ESP, true);
+    move_reg_to_mem(OpndSize_32, 1, false, 0, PhysicalReg_ESP, true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_2;
+    call_dvmThrowVerificationError();
+    load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true);
+
+    unconditional_jump("common_exceptionThrown", false);
+    rPC += 2;
+    return 0;
+}
+#undef P_GPR_1
diff --git a/vm/compiler/codegen/x86/LowerReturn.cpp b/vm/compiler/codegen/x86/LowerReturn.cpp
new file mode 100644
index 0000000..928c05c
--- /dev/null
+++ b/vm/compiler/codegen/x86/LowerReturn.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file LowerReturn.cpp
+    \brief This file lowers the following bytecodes: RETURN
+
+*/
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "mterp/Mterp.h"
+#include "Lower.h"
+#include "enc_wrapper.h"
+#include "NcgHelper.h"
+
+//4 GPRs and scratch registers used in get_self_pointer, set_glue_method and set_glue_dvmdex
+//will jump to "gotoBail" if caller method is NULL or if debugger is active
+//what is %edx for each case? for the latter case, it is 1
+#define P_GPR_1 PhysicalReg_ECX //must be ecx
+#define P_GPR_2 PhysicalReg_EBX
+#define P_SCRATCH_1 PhysicalReg_EDX
+#define P_OLD_FP PhysicalReg_EAX
+/*!
+\brief common section to return from a method
+
+If the helper switch is on, this will generate a helper function
+*/
+int common_returnFromMethod() {
+#if defined(ENABLE_TRACING) && !defined(TRACING_OPTION2)
+    insertMapWorklist(offsetPC, mapFromBCtoNCG[offsetPC], 1); //check when helper switch is on
+#endif
+
+    scratchRegs[0] = PhysicalReg_SCRATCH_7;
+    get_self_pointer(2, false);
+
+    //update rFP to caller stack frame
+    move_reg_to_reg(OpndSize_32, PhysicalReg_FP, true, 10, false);
+    move_mem_to_reg(OpndSize_32, -sizeofStackSaveArea+offStackSaveArea_prevFrame, PhysicalReg_FP, true, PhysicalReg_FP, true); //update rFP
+    //get caller method by accessing the stack save area
+    move_mem_to_reg(OpndSize_32, -sizeofStackSaveArea+offStackSaveArea_method, PhysicalReg_FP, true, 6, false);
+    compare_imm_reg(OpndSize_32, 0, 6, false);
+    conditional_jump(Condition_E, "common_gotoBail_0", false);
+    get_self_pointer(3, false);
+    //update glue->method
+    move_reg_to_mem(OpndSize_32, 6, false, offsetof(Thread, interpSave.method), 2, false);
+    //get clazz of caller method
+    move_mem_to_reg(OpndSize_32, offMethod_clazz, 6, false, 14, false);
+    //update self->frame
+    move_reg_to_mem(OpndSize_32, PhysicalReg_FP, true, offThread_curFrame, 3, false);
+    //get method->clazz->pDvmDex
+    move_mem_to_reg(OpndSize_32, offClassObject_pDvmDex, 14, false, 7, false);
+    move_reg_to_mem(OpndSize_32, 7, false, offsetof(Thread, interpSave.methodClassDex), 2, false);
+
+    compare_imm_mem(OpndSize_32, 0, offsetof(Thread, suspendCount), 2, false); /* suspendCount */
+    move_mem_to_reg(OpndSize_32, -sizeofStackSaveArea+offStackSaveArea_returnAddr, 10, false, PhysicalReg_EBX, true);
+    move_imm_to_reg(OpndSize_32, 0, 17, false);
+    /* if suspendCount is not zero, clear the chaining cell address */
+    conditional_move_reg_to_reg(OpndSize_32, Condition_NZ, 17, false/*src*/, PhysicalReg_EBX, true/*dst*/);
+    move_mem_to_reg(OpndSize_32, -sizeofStackSaveArea+offStackSaveArea_savedPc, 10, false, PhysicalReg_EAX, true);
+    //if returnAddr is not NULL, the thread is still in code cache
+    move_reg_to_mem(OpndSize_32, PhysicalReg_EBX, true, offThread_inJitCodeCache, 3, false);
+
+    insertLabel(".LreturnToInterp", true); //local label
+    //move rPC by 6 (3 bytecode units for INVOKE)
+    alu_binary_imm_reg(OpndSize_32, add_opc, 6, PhysicalReg_EAX, true);
+
+    //returnAddr in %ebx, if not zero, jump to returnAddr
+    compare_imm_reg(OpndSize_32, 0, PhysicalReg_EBX, true);
+    conditional_jump(Condition_E, ".LcontinueToInterp", true);
+#ifdef DEBUG_CALL_STACK3
+    move_reg_to_reg(OpndSize_32, PhysicalReg_EBX, true, PhysicalReg_ESI, true);
+    move_imm_to_reg(OpndSize_32, 0xaabb, PhysicalReg_EBX, true);
+    scratchRegs[0] = PhysicalReg_EAX;
+    call_debug_dumpSwitch(); //%ebx, %eax, %edx
+    move_reg_to_reg(OpndSize_32, PhysicalReg_ESI, true, PhysicalReg_EBX, true);
+    call_debug_dumpSwitch();
+    move_reg_to_reg(OpndSize_32, PhysicalReg_ESI, true, PhysicalReg_EBX, true);
+#endif
+    unconditional_jump_reg(PhysicalReg_EBX, true);
+    insertLabel(".LcontinueToInterp", true);
+    scratchRegs[0] = PhysicalReg_SCRATCH_4;
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = dvmJitToInterpNoChainNoProfile; //%eax is the input
+    move_imm_to_reg(OpndSize_32, (int)funcPtr, C_SCRATCH_1, isScratchPhysical);
+
+    unconditional_jump_reg(C_SCRATCH_1, isScratchPhysical);
+    touchEax();
+    return 0;
+}
+#undef P_GPR_1
+#undef P_GPR_2
+#undef P_SCRATCH_1
+
+//! lower bytecode RETURN_VOID
+
+//! It seems that shared code cache does not support helper switch
+int op_return_void() {
+    int retval;
+    retval = common_returnFromMethod();
+    rPC += 1;
+    return retval;
+}
+
+//! lower bytecode RETURN
+
+//! It seems that shared code cache does not support helper switch
+//! The return value is stored to glue->retval first
+int op_return() {
+    u2 vA = INST_AA(inst);
+
+    get_virtual_reg(vA, OpndSize_32, 22, false);
+    scratchRegs[0] = PhysicalReg_SCRATCH_1;
+    set_return_value(OpndSize_32, 22, false);
+
+    common_returnFromMethod();
+    rPC += 1;
+    return 0;
+}
+
+//! lower bytecode RETURN_WIDE
+
+//! It seems that shared code cache does not support helper switch
+//! The return value is stored to glue->retval first
+int op_return_wide() {
+    u2 vA = INST_AA(inst);
+    get_virtual_reg(vA, OpndSize_64, 1, false);
+    scratchRegs[0] = PhysicalReg_SCRATCH_10; scratchRegs[1] = PhysicalReg_Null;
+    scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
+    set_return_value(OpndSize_64, 1, false);
+
+    common_returnFromMethod();
+    rPC += 1;
+    return 0;
+}
diff --git a/vm/compiler/codegen/x86/NcgAot.cpp b/vm/compiler/codegen/x86/NcgAot.cpp
new file mode 100644
index 0000000..7c29b6d
--- /dev/null
+++ b/vm/compiler/codegen/x86/NcgAot.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "Lower.h"
+#include "NcgAot.h"
+#include "NcgHelper.h"
+
+//returns # of ops generated by this function
+//entries relocatable: eip + relativePC
+int get_eip_API() {
+    call("ncgGetEIP");//%edx //will push eip to stack
+    return 1;
+}
+#define NEW_EXPORT_PC
+//!update current PC in the stack frame with %eip
+
+//!
+int export_pc() {
+    /* for trace-based JIT, pc points to bytecode
+       for NCG, pc points to native code */
+    move_imm_to_mem(OpndSize_32, (int)rPC,
+                    -sizeofStackSaveArea+offStackSaveArea_localRefTop, PhysicalReg_FP, true);
+    return 1; //return number of ops
+}
+
+/* jump from JIT'ed code to interpreter without chaining */
+int jumpToInterpNoChain() {
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = dvmJitToInterpNoChain;
+    move_imm_to_reg(OpndSize_32, (int)funcPtr, C_SCRATCH_1, isScratchPhysical);
+
+    unconditional_jump_reg(C_SCRATCH_1, isScratchPhysical);
+    if(gDvm.executionMode == kExecutionModeNcgO1) touchEax();
+    return 0;
+}
+
+/* jump from JIT'ed code to interpreter becaues of exception */
+int jumpToInterpPunt() {
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = dvmJitToInterpPunt;
+    move_imm_to_reg(OpndSize_32, (int)funcPtr, C_SCRATCH_1, isScratchPhysical);
+
+    unconditional_jump_reg(C_SCRATCH_1, isScratchPhysical);
+    //if(gDvm.executionMode == kExecutionModeNcgO1) touchEax();
+    return 0;
+}
+
+/* jump to common_exceptionThrown from JIT'ed code */
+int jumpToExceptionThrown(int exceptionNum) {
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        rememberState(exceptionNum);
+        export_pc();
+        constVREndOfBB();
+        beforeCall("exception"); //dump GG, GL VRs
+    }
+
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = dvmJitToExceptionThrown;
+    move_imm_to_reg(OpndSize_32, (int)funcPtr, C_SCRATCH_1, isScratchPhysical);
+    unconditional_jump_reg(C_SCRATCH_1, isScratchPhysical);
+
+    if(gDvm.executionMode == kExecutionModeNcgO1) {
+        goToState(exceptionNum);
+    }
+    return 0;
+}
+
+//! generate native code to call dvmNcgInvokeInterpreter
+
+//!the interpreter will start execution from %eax
+int invokeInterpreter(bool fromApp)
+{
+    typedef void (*vmHelper)(int);
+    vmHelper funcPtr = dvmNcgInvokeInterpreter;
+
+    move_imm_to_reg(OpndSize_32, (int)funcPtr, C_SCRATCH_1, isScratchPhysical);
+
+    unconditional_jump_reg(C_SCRATCH_1, isScratchPhysical);
+    if(gDvm.executionMode == kExecutionModeNcgO1) touchEax();
+    return 0;
+}
+
+//!work to do before calling a function pointer with code cache enabled
+
+//!
+void callFuncPtr(int funcPtr, const char* funcName) {
+
+    move_imm_to_reg(OpndSize_32, (int)funcPtr, C_SCRATCH_1, isScratchPhysical);
+    call_reg(C_SCRATCH_1, isScratchPhysical);
+}
+//.const_string_resolve: input in %eax, output in %eax
+//.const_string_helper:
+//.class_resolve: input in %eax, output in %eax
+int call_helper_API(const char* helperName) {
+    call(helperName);
+    return 1;
+}
+
+/* check whether we are throwing an exception */
+bool jumpToException(const char* target) {
+    bool isException = false;
+    if(!strncmp(target, "common_err", 10)) isException = true;
+    if(!strncmp(target, "common_throw", 12)) isException = true;
+    if(!strncmp(target, "common_exception", 16)) isException = true;
+    return isException;
+}
+
+int conditional_jump_global_API(
+                                ConditionCode cc, const char* target,
+                                bool isShortTerm) {
+    if(jumpToException(target) && currentExceptionBlockIdx >= 0) { //jump to the exceptionThrow block
+        condJumpToBasicBlock(stream, cc, currentExceptionBlockIdx);
+        return 1; //return number of ops
+    }
+    conditional_jump(cc, target, isShortTerm);
+    return 1;
+}
+int unconditional_jump_global_API(
+                                  const char* target, bool isShortTerm) {
+    if(jumpToException(target) && currentExceptionBlockIdx >= 0) { //jump to the exceptionThrow block
+        jumpToBasicBlock(stream, currentExceptionBlockIdx);
+        return 1; //return number of ops
+    }
+    unconditional_jump(target, isShortTerm);
+    return 1;
+}
+int getGlobalDataAddr(const char* dataName) {
+    int dataAddr = -1;
+    if(!strcmp(dataName, "doubNeg")) dataAddr = LdoubNeg;
+    else if(!strcmp(dataName, "intMax")) dataAddr = LintMax;
+    else if(!strcmp(dataName, "intMin")) dataAddr = LintMin;
+    else if(!strcmp(dataName, "valueNanLong")) dataAddr = LvalueNanLong;
+    else if(!strcmp(dataName, "valuePosInfLong")) dataAddr = LvaluePosInfLong;
+    else if(!strcmp(dataName, "valueNegInfLong")) dataAddr = LvalueNegInfLong;
+    else if(!strcmp(dataName, "shiftMask")) dataAddr = LshiftMask;
+    else if(!strcmp(dataName, "value64")) dataAddr = Lvalue64;
+    else if(!strcmp(dataName, "64bits")) dataAddr = L64bits;
+    else if(!strcmp(dataName, "strClassCastExceptionPtr")) dataAddr = LstrClassCastExceptionPtr;
+    else if(!strcmp(dataName, "strInstantiationError")) dataAddr = LstrInstantiationErrorPtr;
+    else if(!strcmp(dataName, "gDvmInlineOpsTable")) dataAddr = (int)gDvmInlineOpsTable;
+    else ALOGE("global data %s not supported", dataName);
+    return dataAddr;
+}
+
+//for shared code cache, we use scratchRegs[0] & [1]
+int load_imm_global_data_API(const char* dataName,
+                         OpndSize size,
+                         int reg, bool isPhysical) {
+
+    //find the address from name
+    int dataAddr = getGlobalDataAddr(dataName);
+    move_imm_to_reg(size, dataAddr, reg, isPhysical);
+    return 0;
+}
+//for shared code cache, we use scratchRegs[0] & [1] & [2]
+//FIXME: [2] is assumed to be hard-coded register
+int load_global_data_API(const char* dataName,
+                         OpndSize size,
+                         int reg, bool isPhysical) {
+
+    //find the address from name
+    int dataAddr = getGlobalDataAddr(dataName);
+    move_mem_to_reg(size, dataAddr, PhysicalReg_Null, true, reg, isPhysical);
+    return 0;
+}
+int load_sd_global_data_API(const char* dataName,
+                            int reg, bool isPhysical) {
+
+    //find the address from name
+    int dataAddr = getGlobalDataAddr(dataName);
+    move_sd_mem_to_reg(dataAddr, PhysicalReg_Null, true, reg, isPhysical);
+    return 0;
+}
+
+int load_fp_stack_global_data_API(const char* dataName,
+                                  OpndSize size) {
+
+    int dataAddr = getGlobalDataAddr(dataName);
+    load_int_fp_stack_imm(size, dataAddr); //fildl
+    return 0;
+}
diff --git a/vm/compiler/codegen/x86/NcgAot.h b/vm/compiler/codegen/x86/NcgAot.h
new file mode 100644
index 0000000..99bcc13
--- /dev/null
+++ b/vm/compiler/codegen/x86/NcgAot.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#ifndef _DALVIK_NCG_AOT
+#define _DALVIK_NCG_AOT
+int ncgAppGetEIP();
+int get_eip_API();
+int invokeInterpreter(bool fromApp);
+int invokeNcg(bool fromApp);
+int jumpToInterpNoChain();
+int jumpToInterpPunt();
+int jumpToExceptionThrown(int exceptionNum);
+void callFuncPtr(int funcPtr, const char* funcName);
+int call_helper_API(const char* helperName);
+int conditional_jump_global_API(
+                                ConditionCode cc, const char* target,
+                                bool isShortTerm);
+int unconditional_jump_global_API(
+                                  const char* target, bool isShortTerm);
+int load_imm_global_data_API(const char* dataName,
+                             OpndSize size,
+                             int reg, bool isPhysical);
+int load_global_data_API(const char* dataName,
+                         OpndSize size,
+                         int reg, bool isPhysical);
+int load_sd_global_data_API(const char* dataName,
+                            int reg, bool isPhysical);
+int load_fp_stack_global_data_API(const char* dataName,
+                                  OpndSize size);
+#endif
+
diff --git a/vm/compiler/codegen/x86/NcgHelper.cpp b/vm/compiler/codegen/x86/NcgHelper.cpp
new file mode 100644
index 0000000..f9192db
--- /dev/null
+++ b/vm/compiler/codegen/x86/NcgHelper.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "Dalvik.h"
+#include "NcgHelper.h"
+#include "interp/InterpDefs.h"
+
+
+/*
+ * Find the matching case.  Returns the offset to the handler instructions.
+ *
+ * Returns 3 if we don't find a match (it's the size of the packed-switch
+ * instruction).
+ */
+s4 dvmNcgHandlePackedSwitch(const s4* entries, s4 firstKey, u2 size, s4 testVal)
+{
+    //skip add_reg_reg (ADD_REG_REG_SIZE) and jump_reg (JUMP_REG_SIZE)
+    const int kInstrLen = 4; //default to next bytecode
+    if (testVal < firstKey || testVal >= firstKey + size) {
+        LOGVV("Value %d not found in switch (%d-%d)",
+            testVal, firstKey, firstKey+size-1);
+        return kInstrLen;
+    }
+
+    assert(testVal - firstKey >= 0 && testVal - firstKey < size);
+    LOGVV("Value %d found in slot %d (goto 0x%02x)",
+        testVal, testVal - firstKey,
+        s4FromSwitchData(&entries[testVal - firstKey]));
+    return s4FromSwitchData(&entries[testVal - firstKey]);
+
+}
+/* return the number of bytes to increase the bytecode pointer by */
+s4 dvmJitHandlePackedSwitch(const s4* entries, s4 firstKey, u2 size, s4 testVal)
+{
+    if (testVal < firstKey || testVal >= firstKey + size) {
+        LOGVV("Value %d not found in switch (%d-%d)",
+            testVal, firstKey, firstKey+size-1);
+        return 2*3;//bytecode packed_switch is 6(2*3) bytes long
+    }
+
+    LOGVV("Value %d found in slot %d (goto 0x%02x)",
+        testVal, testVal - firstKey,
+        s4FromSwitchData(&entries[testVal - firstKey]));
+    return 2*s4FromSwitchData(&entries[testVal - firstKey]); //convert from u2 to byte
+
+}
+/*
+ * Find the matching case.  Returns the offset to the handler instructions.
+ *
+ * Returns 3 if we don't find a match (it's the size of the sparse-switch
+ * instruction).
+ */
+s4 dvmNcgHandleSparseSwitch(const s4* keys, u2 size, s4 testVal)
+{
+    const int kInstrLen = 4; //CHECK
+    const s4* entries = keys + size;
+    int i;
+    for (i = 0; i < size; i++) {
+        s4 k = s4FromSwitchData(&keys[i]);
+        if (k == testVal) {
+            LOGVV("Value %d found in entry %d (goto 0x%02x)",
+                testVal, i, s4FromSwitchData(&entries[i]));
+            return s4FromSwitchData(&entries[i]);
+        } else if (k > testVal) {
+            break;
+        }
+    }
+
+    LOGVV("Value %d not found in switch", testVal);
+    return kInstrLen;
+}
+/* return the number of bytes to increase the bytecode pointer by */
+s4 dvmJitHandleSparseSwitch(const s4* keys, u2 size, s4 testVal)
+{
+    const s4* entries = keys + size;
+    int i;
+    for (i = 0; i < size; i++) {
+        s4 k = s4FromSwitchData(&keys[i]);
+        if (k == testVal) {
+            LOGVV("Value %d found in entry %d (goto 0x%02x)",
+                testVal, i, s4FromSwitchData(&entries[i]));
+            return 2*s4FromSwitchData(&entries[i]); //convert from u2 to byte
+        } else if (k > testVal) {
+            break;
+        }
+    }
+
+    LOGVV("Value %d not found in switch", testVal);
+    return 2*3; //bytecode sparse_switch is 6(2*3) bytes long
+}
+/*
+ * Look up an interface on a class using the cache.
+ */
+/*INLINE*/ Method* dvmFindInterfaceMethodInCache2(ClassObject* thisClass,
+    u4 methodIdx, const Method* method, DvmDex* methodClassDex)
+{
+#define ATOMIC_CACHE_CALC \
+    dvmInterpFindInterfaceMethod(thisClass, methodIdx, method, methodClassDex)
+
+    return (Method*) ATOMIC_CACHE_LOOKUP(methodClassDex->pInterfaceCache,
+                DEX_INTERFACE_CACHE_SIZE, thisClass, methodIdx);
+
+#undef ATOMIC_CACHE_CALC
+}
diff --git a/vm/compiler/codegen/x86/NcgHelper.h b/vm/compiler/codegen/x86/NcgHelper.h
new file mode 100644
index 0000000..888cb61
--- /dev/null
+++ b/vm/compiler/codegen/x86/NcgHelper.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef _DALVIK_NCG_HELPER
+#define _DALVIK_NCG_HELPER
+#include "mterp/Mterp.h"
+s4 dvmNcgHandlePackedSwitch(const s4*, s4, u2, s4);
+s4 dvmNcgHandleSparseSwitch(const s4*, u2, s4);
+s4 dvmJitHandlePackedSwitch(const s4*, s4, u2, s4);
+s4 dvmJitHandleSparseSwitch(const s4*, u2, s4);
+/*
+ * Look up an interface on a class using the cache.
+ */
+Method* dvmFindInterfaceMethodInCache2(ClassObject* thisClass,
+    u4 methodIdx, const Method* method, DvmDex* methodClassDex);
+/*
+ * Find an interface method.
+ */
+#if 0
+bool dvmNcgStdRun(MterpGlue* glue);
+#endif
+extern "C" void dvmNcgInvokeInterpreter(int pc); //interpreter to execute at pc
+extern "C" void dvmNcgInvokeNcg(int pc);
+extern "C" void dvmJitToInterpNormal(int targetpc); //in %ebx
+extern "C" void dvmJitToInterpTraceSelect(int targetpc); //in %ebx
+extern "C" void dvmJitToInterpTraceSelectNoChain(int targetpc); //in %ebx
+extern "C" void dvmJitToInterpNoChain(int targetpc); //in %eax
+extern "C" void dvmJitToInterpNoChainNoProfile(int targetpc); //in %eax
+extern "C" void dvmJitToInterpPunt(int targetpc); //in currentPc
+extern "C" void dvmJitToExceptionThrown(int targetpc); //in currentPc
+#ifdef DEBUG_CALL_STACK3
+void debug_dumpSwitch(int); //in %ebx
+#endif
+
+const Method *dvmJitToPatchPredictedChain(const Method *method,
+                                          Thread *self,
+                                          PredictedChainingCell *cell,
+                                          const ClassObject *clazz);
+#endif /*_DALVIK_NCG_HELPER*/
diff --git a/vm/compiler/codegen/x86/Codegen.h b/vm/compiler/codegen/x86/Translator.h
similarity index 68%
rename from vm/compiler/codegen/x86/Codegen.h
rename to vm/compiler/codegen/x86/Translator.h
index 1ccdad3..0d7ef32 100644
--- a/vm/compiler/codegen/x86/Codegen.h
+++ b/vm/compiler/codegen/x86/Translator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,13 +14,15 @@
  * limitations under the License.
  */
 
-/*
- * This file contains register alloction support and is intended to be
- * included by:
- *
- *        Codegen-$(TARGET_ARCH_VARIANT).c
- *
- */
 
-#include "compiler/CompilerIR.h"
-#include "CalloutHelper.h"
+
+#ifndef _DALVIK_TRANSLATOR
+#define _DALVIK_TRANSLATOR
+
+#include "Dalvik.h"
+#include "enc_wrapper.h"
+
+/* initialization for trace-based JIT */
+void initJIT(const char* curFileName, DvmDex *pDvmDex);
+
+#endif
diff --git a/vm/compiler/codegen/x86/X86LIR.h b/vm/compiler/codegen/x86/X86LIR.h
deleted file mode 100644
index 863aeab..0000000
--- a/vm/compiler/codegen/x86/X86LIR.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DALVIK_VM_COMPILER_CODEGEN_X86_X86LIR_H_
-#define DALVIK_VM_COMPILER_CODEGEN_X86_X86LIR_H_
-
-#include "Dalvik.h"
-#include "compiler/CompilerInternals.h"
-
-/*
- * For both JIT & interpreter:
- *     esi is Dalvik FP
- *     ebp is native FP
- *     esp is native SP
- *
- * For interpreter:
- *     edi is Dalvik PC (rPC)
- *     ebx is rINST
- *
- * For JIT:
- *     eax, edx, ecx are scratch & caller-save
- *     ebx, edi are scratch & callee-save
- *
- * Calling conventions:
- *     32-bit return in eax
- *     64-bit return in edx:eax
- *     fp on top of fp stack st(0)
- *     Parameters passed on stack, pushed left to right
- *     On entry to target, first parm is at 4(%esp).
- *     For performance, we'll maintain 16-byte stack alignment
- *
- * When transitioning from code cache to interp:
- *       materialize Dalvik PC of target in rPC/%edx
- *       Preload rINST/%ebx such that high 24 bits are zero and
- *           bl contains the non-opcode 8-bits of the 16-bit Dalvik
- *           instruction at (rPC)
- */
-
-/* Keys for target-specific scheduling and other optimizations here */
-typedef enum X86TargetOptHints {
-   kMaxHoistDistance,
-} X86TargetOptHints;
-
- /*
- * Data structure tracking the mapping between a Dalvik register (pair) and a
- * native register (pair). The idea is to reuse the previously loaded value
- * if possible, otherwise to keep the value in a native register as long as
- * possible.
- */
-typedef struct RegisterInfo {
-    int reg;                    // Reg number
-    bool inUse;                 // Has it been allocated?
-    bool pair;                  // Part of a register pair?
-    int partner;                // If pair, other reg of pair
-    bool live;                  // Is there an associated SSA name?
-    bool dirty;                 // If live, is it dirty?
-    int sReg;                   // Name of live value
-    struct LIR *defStart;       // Starting inst in last def sequence
-    struct LIR *defEnd;         // Ending inst in last def sequence
-} RegisterInfo;
-
-typedef struct RegisterPool {
-    BitVector *nullCheckedRegs; // Track which registers have been null-checked
-    int numCoreTemps;
-    RegisterInfo *coreTemps;
-    int nextCoreTemp;
-    int numFPTemps;
-    RegisterInfo *FPTemps;
-    int nextFPTemp;
-} RegisterPool;
-
-typedef enum OpSize {
-    kWord,
-    kLong,
-    kSingle,
-    kDouble,
-    kUnsignedHalf,
-    kSignedHalf,
-    kUnsignedByte,
-    kSignedByte,
-} OpSize;
-
-typedef enum OpKind {
-    kOpMov,
-    kOpCmp,
-    kOpLsl,
-    kOpLsr,
-    kOpAsr,
-    kOpRor,
-    kOpNot,
-    kOpAnd,
-    kOpOr,
-    kOpXor,
-    kOpNeg,
-    kOpAdd,
-    kOpAdc,
-    kOpSub,
-    kOpSbc,
-    kOpMul,
-    kOpDiv,
-    kOpRem,
-    kOpTst,
-    kOpCall,
-    kOpPush,
-    kOpPop,
-    kOp2Char,
-    kOp2Short,
-    kOp2Byte,
-    kOpCondBr,
-    kOpUncondBr,
-} OpKind;
-
-#define FP_REG_OFFSET 8
-
-typedef enum NativeRegisterPool {
-    rEAX = 0,
-    rECX = 1,
-    rEDX = 2,
-    rEBX = 3,
-    rESP = 4,
-    rEBP = 5,
-    rESI = 6,
-    rEDI = 7,
-    rXMM0 = 0 + FP_REG_OFFSET,
-    rXMM1 = 1 + FP_REG_OFFSET,
-    rXMM2 = 2 + FP_REG_OFFSET,
-    rXMM3 = 3 + FP_REG_OFFSET,
-    rXMM4 = 4 + FP_REG_OFFSET,
-    rXMM5 = 5 + FP_REG_OFFSET,
-    rXMM6 = 6 + FP_REG_OFFSET,
-    rXMM7 = 7 + FP_REG_OFFSET,
-} NativeRegisterPool;
-
-#define rPC rEDI
-#define rFP rESI
-#define rINST rEBX
-
-#define OUT_ARG0 0
-#define OUT_ARG1 4
-#define OUT_ARG2 8
-#define OUT_ARG3 12
-#define OUT_ARG4 16
-
-typedef struct X86LIR {
-    LIR generic;
-    //X86Opcode opcode;
-    int operands[4];    // [0..3] = [dest, src1, src2, extra]
-    bool isNop;         // LIR is optimized away
-    bool branchInsertSV;// mark for insertion of branch before this instruction,
-                        // used to identify mem ops for self verification mode
-    int age;            // default is 0, set lazily by the optimizer
-    int aliasInfo;      // For Dalvik register access & litpool disambiguation
-    u8 useMask;         // Resource mask for use
-    u8 defMask;         // Resource mask for def
-} X86LIR;
-
-/* Utility macros to traverse the LIR/X86LIR list */
-#define NEXT_LIR(lir) ((X86LIR *) lir->generic.next)
-#define PREV_LIR(lir) ((X86LIR *) lir->generic.prev)
-
-#define NEXT_LIR_LVALUE(lir) (lir)->generic.next
-#define PREV_LIR_LVALUE(lir) (lir)->generic.prev
-
-#define CHAIN_CELL_OFFSET_TAG   0xcdab
-
-#define CHAIN_CELL_NORMAL_SIZE 12
-#define CHAIN_CELL_PREDICTED_SIZE 16
-
-#endif  // DALVIK_VM_COMPILER_CODEGEN_X86_X86LIR_H_
diff --git a/vm/compiler/codegen/x86/ia32/ArchVariant.cpp b/vm/compiler/codegen/x86/ia32/ArchVariant.cpp
deleted file mode 100644
index ff97d95..0000000
--- a/vm/compiler/codegen/x86/ia32/ArchVariant.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-extern "C" void dvmCompilerTemplateStart(void);
-
-/*
- * This file is included by Codegen-x86.c, and implements architecture
- * variant-specific code.
- */
-
-/*
- * Determine the initial instruction set to be used for this trace.
- * Later components may decide to change this.
- */
-JitInstructionSetType dvmCompilerInstructionSet(void)
-{
-    return DALVIK_JIT_IA32;
-}
-
-/* First, declare dvmCompiler_TEMPLATE_XXX for each template */
-#define JIT_TEMPLATE(X) extern "C" void dvmCompiler_TEMPLATE_##X();
-#include "../../../template/ia32/TemplateOpList.h"
-#undef JIT_TEMPLATE
-
-/* Architecture-specific initializations and checks go here */
-bool dvmCompilerArchVariantInit(void)
-{
-    int i = 0;
-
-    /*
-     * Then, populate the templateEntryOffsets array with the offsets from the
-     * the dvmCompilerTemplateStart symbol for each template.
-     */
-#define JIT_TEMPLATE(X) templateEntryOffsets[i++] = \
-    (intptr_t) dvmCompiler_TEMPLATE_##X - (intptr_t) dvmCompilerTemplateStart;
-#include "../../../template/ia32/TemplateOpList.h"
-#undef JIT_TEMPLATE
-
-    /* Target-specific configuration */
-    gDvmJit.jitTableSize = 1 << 9; // 512
-    gDvmJit.jitTableMask = gDvmJit.jitTableSize - 1;
-    gDvmJit.threshold = 200;
-    gDvmJit.codeCacheSize = 512*1024;
-
-#if defined(WITH_SELF_VERIFICATION)
-    /* Force into blocking mode */
-    gDvmJit.blockingMode = true;
-    gDvm.nativeDebuggerActive = true;
-#endif
-
-    /* Codegen-specific assumptions */
-    assert(OFFSETOF_MEMBER(ClassObject, vtable) < 128 &&
-           (OFFSETOF_MEMBER(ClassObject, vtable) & 0x3) == 0);
-    assert(OFFSETOF_MEMBER(ArrayObject, length) < 128 &&
-           (OFFSETOF_MEMBER(ArrayObject, length) & 0x3) == 0);
-    assert(OFFSETOF_MEMBER(ArrayObject, contents) < 256);
-
-    /* Up to 5 args are pushed on top of FP - sizeofStackSaveArea */
-    assert(sizeof(StackSaveArea) < 236);
-
-    /*
-     * EA is calculated by doing "Rn + imm5 << 2", make sure that the last
-     * offset from the struct is less than 128.
-     */
-    assert((offsetof(Thread, jitToInterpEntries) +
-            sizeof(struct JitToInterpEntries)) <= 128);
-
-    // Make sure all threads have current values
-    dvmJitUpdateThreadStateAll();
-    return true;
-}
-
-int dvmCompilerTargetOptHint(int key)
-{
-    int res;
-    switch (key) {
-        case kMaxHoistDistance:
-            res = 2;
-            break;
-        default:
-            ALOGE("Unknown target optimization hint key: %d",key);
-            res = 0;
-    }
-    return res;
-}
-
-void dvmCompilerGenMemBarrier(CompilationUnit *cUnit, int barrierKind)
-{
-}
diff --git a/vm/compiler/codegen/x86/ia32/ArchVariant.h b/vm/compiler/codegen/x86/ia32/ArchVariant.h
deleted file mode 100644
index f1c21d3..0000000
--- a/vm/compiler/codegen/x86/ia32/ArchVariant.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DALVIK_VM_COMPILER_CODEGEN_X86_IA32_ARCHVARIANT_H_
-#define DALVIK_VM_COMPILER_CODEGEN_X86_IA32_ARCHVARIANT_H_
-
-/* Create the TemplateOpcode enum */
-#define JIT_TEMPLATE(X) TEMPLATE_##X,
-enum TemplateOpcode {
-#include "../../../template/ia32/TemplateOpList.h"
-/*
- * For example,
- *     TEMPLATE_CMP_LONG,
- *     TEMPLATE_RETURN,
- *     ...
- */
-    TEMPLATE_LAST_MARK,
-};
-#undef JIT_TEMPLATE
-
-#endif  // DALVIK_VM_COMPILER_CODEGEN_X86_IA32_ARCHVARIANT_H_
diff --git a/vm/compiler/codegen/x86/ia32/CallingConvention.S b/vm/compiler/codegen/x86/ia32/CallingConvention.S
deleted file mode 100644
index cc4187a..0000000
--- a/vm/compiler/codegen/x86/ia32/CallingConvention.S
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Save & restore for callee-save FP registers.
- * On entry:
- *    tos : pointer to save area of JIT_CALLEE_SAVE_WORD_SIZE
- */
-    .text
-    .align 2
-    .global dvmJitCalleeSave
-    .type dvmJitCalleeSave, %function
-dvmJitCalleeSave:
-    ret
-
-    .global dvmJitCalleeRestore
-    .type dvmJitCalleeRestore, %function
-dvmJitCalleeRestore:
-    ret
diff --git a/vm/compiler/codegen/x86/ia32/Codegen.cpp b/vm/compiler/codegen/x86/ia32/Codegen.cpp
deleted file mode 100644
index ae55cd1..0000000
--- a/vm/compiler/codegen/x86/ia32/Codegen.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define _CODEGEN_C
-#define _IA32
-
-#include "Dalvik.h"
-#include "interp/InterpDefs.h"
-#include "libdex/DexOpcodes.h"
-#include "compiler/CompilerInternals.h"
-#include "compiler/codegen/x86/X86LIR.h"
-#include "mterp/common/FindInterface.h"
-//#include "compiler/codegen/x86/Ralloc.h"
-#include "compiler/codegen/x86/Codegen.h"
-#include "compiler/Loop.h"
-#include "ArchVariant.h"
-
-/* Architectural independent building blocks */
-//#include "../CodegenCommon.cpp"
-
-/* Architectural independent building blocks */
-//#include "../Thumb/Factory.cpp"
-/* Factory utilities dependent on arch-specific features */
-//#include "../CodegenFactory.cpp"
-
-/* ia32 register allocation */
-//#include "../ia32/Ralloc.cpp"
-
-/* MIR2LIR dispatcher and architectural independent codegen routines */
-#include "../CodegenDriver.cpp"
-
-/* Architecture manifest */
-#include "ArchVariant.cpp"
diff --git a/vm/compiler/codegen/x86/libenc/Android.mk b/vm/compiler/codegen/x86/libenc/Android.mk
new file mode 100644
index 0000000..6fe9cdb
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/Android.mk
@@ -0,0 +1,65 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Only include the x86 encoder/decoder for x86 architecture
+ifeq ($(TARGET_ARCH),x86)
+
+LOCAL_PATH:= $(call my-dir)
+
+ifneq ($(LIBENC_INCLUDED),true)
+
+LIBENC_INCLUDED := true
+
+enc_src_files := \
+        enc_base.cpp \
+        dec_base.cpp \
+        enc_wrapper.cpp \
+        enc_tabl.cpp
+
+enc_include_files :=
+
+##
+##
+## Build the device version of libenc
+##
+##
+ifneq ($(SDK_ONLY),true)  # SDK_only doesn't need device version
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(enc_src_files)
+LOCAL_C_INCLUDES += $(enc_include_files)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libenc
+include $(BUILD_STATIC_LIBRARY)
+
+endif # !SDK_ONLY
+
+
+##
+##
+## Build the host version of libenc
+##
+##
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(enc_src_files)
+LOCAL_C_INCLUDES += $(enc_include_files)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libenc
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+endif   # ifneq ($(LIBENC_INCLUDED),true)
+
+endif   # ifeq ($(TARGET_ARCH),x86)
diff --git a/vm/compiler/codegen/x86/libenc/README.txt b/vm/compiler/codegen/x86/libenc/README.txt
new file mode 100644
index 0000000..30df760
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/README.txt
@@ -0,0 +1,26 @@
+Original source from Apache Harmony 5.0M15 (r991518 from 2010-09-01) at
+http://harmony.apache.org/.
+
+The following files are from drlvm/vm/port/src/encoder/ia32_em64t.
+
+    dec_base.cpp
+    dec_base.h
+    enc_base.cpp
+    enc_base.h
+    enc_defs.h
+    enc_prvt.h
+    enc_tabl.cpp
+    encoder.cpp
+    encoder.h
+    encoder.inl
+
+The following files are derived partially from the original Apache
+Harmony files.
+
+    enc_defs_ext.h -- derived from enc_defs.h
+    enc_wrapper.h  -- derived from encoder.h
+
+
+
+
+
diff --git a/vm/compiler/codegen/x86/libenc/dec_base.cpp b/vm/compiler/codegen/x86/libenc/dec_base.cpp
new file mode 100644
index 0000000..e0edc10
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/dec_base.cpp
@@ -0,0 +1,540 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+
+/**
+ * @file
+ * @brief Main decoding (disassembling) routines implementation.
+ */
+
+#include "dec_base.h"
+#include "enc_prvt.h"
+#include <stdio.h>
+//#include "open/common.h"
+
+bool DecoderBase::is_prefix(const unsigned char * bytes)
+{
+    unsigned char b0 = *bytes;
+    unsigned char b1 = *(bytes+1);
+    if (b0 == 0xF0) { // LOCK
+        return true;
+    }
+    if (b0==0xF2 || b0==0xF3) { // REPNZ/REPZ prefixes
+        if (b1 == 0x0F) {   // .... but may be a part of SIMD opcode
+            return false;
+        }
+        return true;
+    }
+    if (b0 == 0x2E || b0 == 0x36 || b0==0x3E || b0==0x26 || b0==0x64 || b0==0x3E) {
+        // branch hints, segment prefixes
+        return true;
+    }
+    if (b0==0x66) { // operand-size prefix
+        if (b1 == 0x0F) {   // .... but may be a part of SIMD opcode
+            return false;
+        }
+        return false; //XXX - currently considered as part of opcode//true;
+    }
+    if (b0==0x67) { // address size prefix
+        return true;
+    }
+    return false;
+}
+
+// Returns prefix count from 0 to 4, or ((unsigned int)-1) on error
+unsigned int DecoderBase::fill_prefs(const unsigned char * bytes, Inst * pinst)
+{
+    const unsigned char * my_bytes = bytes;
+
+    while( 1 )
+    {
+        unsigned char by1 = *my_bytes;
+        unsigned char by2 = *(my_bytes + 1);
+        Inst::PrefGroups where;
+
+        switch( by1 )
+        {
+        case InstPrefix_REPNE:
+        case InstPrefix_REP:
+        {
+            if( 0x0F == by2)
+            {
+                return pinst->prefc;
+            }
+        }
+        case InstPrefix_LOCK:
+        {
+            where = Inst::Group1;
+            break;
+        }
+        case InstPrefix_CS:
+        case InstPrefix_SS:
+        case InstPrefix_DS:
+        case InstPrefix_ES:
+        case InstPrefix_FS:
+        case InstPrefix_GS:
+//      case InstPrefix_HintTaken: the same as CS override
+//      case InstPrefix_HintNotTaken: the same as DS override
+        {
+            where = Inst::Group2;
+            break;
+        }
+        case InstPrefix_OpndSize:
+        {
+//NOTE:   prefix does not work for JMP Sz16, the opcode is 0x66 0xe9
+//        here 0x66 will be treated as prefix, try_mn will try to match the code starting at 0xe9
+//        it will match JMP Sz32 ...
+//HACK:   assume it is the last prefix, return any way
+            if( 0x0F == by2)
+            {
+                return pinst->prefc;
+            }
+            return pinst->prefc;
+            where = Inst::Group3;
+            break;
+        }
+        case InstPrefix_AddrSize:
+        {
+            where = Inst::Group4;
+            break;
+        }
+        default:
+        {
+            return pinst->prefc;
+        }
+        }
+        // Assertions are not allowed here.
+        // Error situations should result in returning error status
+        if (InstPrefix_Null != pinst->pref[where]) //only one prefix in each group
+            return (unsigned int)-1;
+
+        pinst->pref[where] = (InstPrefix)by1;
+
+        if (pinst->prefc >= 4) //no more than 4 prefixes
+            return (unsigned int)-1;
+
+        pinst->prefc++;
+        ++my_bytes;
+    }
+}
+
+
+
+unsigned DecoderBase::decode(const void * addr, Inst * pinst)
+{
+    Inst tmp;
+
+    //assert( *(unsigned char*)addr != 0x66);
+
+    const unsigned char * bytes = (unsigned char*)addr;
+
+    // Load up to 4 prefixes
+    // for each Mnemonic
+    unsigned int pref_count = fill_prefs(bytes, &tmp);
+
+    if (pref_count == (unsigned int)-1) // Wrong prefix sequence, or >4 prefixes
+        return 0; // Error
+
+    bytes += pref_count;
+
+    //  for each opcodedesc
+    //      if (raw_len == 0) memcmp(, raw_len)
+    //  else check the mixed state which is one of the following:
+    //      /digit /i /rw /rd /rb
+
+    bool found = false;
+    const unsigned char * saveBytes = bytes;
+    for (unsigned mn=1; mn<Mnemonic_Count; mn++) {
+        bytes = saveBytes;
+        found=try_mn((Mnemonic)mn, &bytes, &tmp);
+        if (found) {
+            tmp.mn = (Mnemonic)mn;
+            break;
+        }
+    }
+    if (!found) {
+        // Unknown opcode
+        return 0;
+    }
+    tmp.size = (unsigned)(bytes-(const unsigned char*)addr);
+    if (pinst) {
+        *pinst = tmp;
+    }
+    return tmp.size;
+}
+
+#ifdef _EM64T_
+#define EXTEND_REG(reg, flag)                        \
+    ((NULL == rex || 0 == rex->flag) ? reg : (reg + 8))
+#else
+#define EXTEND_REG(reg, flag) (reg)
+#endif
+
+//don't know the use of rex, seems not used when _EM64T_ is not enabled
+bool DecoderBase::decode_aux(const EncoderBase::OpcodeDesc& odesc, unsigned aux,
+    const unsigned char ** pbuf, Inst * pinst
+#ifdef _EM64T_
+    , const Rex UNREF *rex
+#endif
+    )
+{
+    OpcodeByteKind kind = (OpcodeByteKind)(aux & OpcodeByteKind_KindMask);
+    unsigned byte = (aux & OpcodeByteKind_OpcodeMask);
+    unsigned data_byte = **pbuf;
+    EncoderBase::Operand& opnd = pinst->operands[pinst->argc];
+    const EncoderBase::OpndDesc& opndDesc = odesc.opnds[pinst->argc];
+
+    switch (kind) {
+    case OpcodeByteKind_SlashR:
+        {
+            RegName reg;
+            OpndKind okind;
+            const ModRM& modrm = *(ModRM*)*pbuf;
+            if (opndDesc.kind & OpndKind_Mem) { // 1st operand is memory
+#ifdef _EM64T_
+                decodeModRM(odesc, pbuf, pinst, rex);
+#else
+                decodeModRM(odesc, pbuf, pinst);
+#endif
+                ++pinst->argc;
+                const EncoderBase::OpndDesc& opndDesc2 = odesc.opnds[pinst->argc];
+                okind = ((opndDesc2.kind & OpndKind_XMMReg) || opndDesc2.size==OpndSize_64) ? OpndKind_XMMReg : OpndKind_GPReg;
+                EncoderBase::Operand& regOpnd = pinst->operands[pinst->argc];
+                reg = getRegName(okind, opndDesc2.size, EXTEND_REG(modrm.reg, r));
+                regOpnd = EncoderBase::Operand(reg);
+            } else {                            // 2nd operand is memory
+                okind = ((opndDesc.kind & OpndKind_XMMReg) || opndDesc.size==OpndSize_64) ? OpndKind_XMMReg : OpndKind_GPReg;
+                EncoderBase::Operand& regOpnd = pinst->operands[pinst->argc];
+                reg = getRegName(okind, opndDesc.size, EXTEND_REG(modrm.reg, r));
+                regOpnd = EncoderBase::Operand(reg);
+                ++pinst->argc;
+#ifdef _EM64T_
+                decodeModRM(odesc, pbuf, pinst, rex);
+#else
+                decodeModRM(odesc, pbuf, pinst);
+#endif
+            }
+            ++pinst->argc;
+        }
+        return true;
+    case OpcodeByteKind_rb:
+    case OpcodeByteKind_rw:
+    case OpcodeByteKind_rd:
+        {
+            // Gregory -
+            // Here we don't parse register because for current needs
+            // disassembler doesn't require to parse all operands
+            unsigned regid = data_byte - byte;
+            if (regid>7) {
+                return false;
+            }
+            OpndSize opnd_size;
+            switch(kind)
+            {
+            case OpcodeByteKind_rb:
+            {
+                opnd_size = OpndSize_8;
+                break;
+            }
+            case OpcodeByteKind_rw:
+            {
+                opnd_size = OpndSize_16;
+                break;
+            }
+            case OpcodeByteKind_rd:
+            {
+                opnd_size = OpndSize_32;
+                break;
+            }
+            default:
+                opnd_size = OpndSize_32;  // so there is no compiler warning
+                assert( false );
+            }
+            opnd = EncoderBase::Operand( getRegName(OpndKind_GPReg, opnd_size, regid) );
+
+            ++pinst->argc;
+            ++*pbuf;
+            return true;
+        }
+    case OpcodeByteKind_cb:
+        {
+        char offset = *(char*)*pbuf;
+        *pbuf += 1;
+        opnd = EncoderBase::Operand(offset);
+        ++pinst->argc;
+        //pinst->direct_addr = (void*)(pinst->offset + *pbuf);
+        }
+        return true;
+    case OpcodeByteKind_cw:
+        // not an error, but not expected in current env
+        // Android x86
+        {
+        short offset = *(short*)*pbuf;
+        *pbuf += 2;
+        opnd = EncoderBase::Operand(offset);
+        ++pinst->argc;
+        }
+        return true;
+        //return false;
+    case OpcodeByteKind_cd:
+        {
+        int offset = *(int*)*pbuf;
+        *pbuf += 4;
+        opnd = EncoderBase::Operand(offset);
+        ++pinst->argc;
+        }
+        return true;
+    case OpcodeByteKind_SlashNum:
+        {
+        const ModRM& modrm = *(ModRM*)*pbuf;
+        if (modrm.reg != byte) {
+            return false;
+        }
+        decodeModRM(odesc, pbuf, pinst
+#ifdef _EM64T_
+                        , rex
+#endif
+                        );
+        ++pinst->argc;
+        }
+        return true;
+    case OpcodeByteKind_ib:
+        {
+        char ival = *(char*)*pbuf;
+        opnd = EncoderBase::Operand(ival);
+        ++pinst->argc;
+        *pbuf += 1;
+        }
+        return true;
+    case OpcodeByteKind_iw:
+        {
+        short ival = *(short*)*pbuf;
+        opnd = EncoderBase::Operand(ival);
+        ++pinst->argc;
+        *pbuf += 2;
+        }
+        return true;
+    case OpcodeByteKind_id:
+        {
+        int ival = *(int*)*pbuf;
+        opnd = EncoderBase::Operand(ival);
+        ++pinst->argc;
+        *pbuf += 4;
+        }
+        return true;
+#ifdef _EM64T_
+    case OpcodeByteKind_io:
+        {
+        long long int ival = *(long long int*)*pbuf;
+        opnd = EncoderBase::Operand(OpndSize_64, ival);
+        ++pinst->argc;
+        *pbuf += 8;
+        }
+        return true;
+#endif
+    case OpcodeByteKind_plus_i:
+        {
+            unsigned regid = data_byte - byte;
+            if (regid>7) {
+                return false;
+            }
+            ++*pbuf;
+            return true;
+        }
+    case OpcodeByteKind_ZeroOpcodeByte: // cant be here
+        return false;
+    default:
+        // unknown kind ? how comes ?
+        break;
+    }
+    return false;
+}
+
+bool DecoderBase::try_mn(Mnemonic mn, const unsigned char ** pbuf, Inst * pinst) {
+    const unsigned char * save_pbuf = *pbuf;
+    EncoderBase::OpcodeDesc * opcodes = EncoderBase::opcodes[mn];
+
+    for (unsigned i=0; !opcodes[i].last; i++) {
+        const EncoderBase::OpcodeDesc& odesc = opcodes[i];
+        char *opcode_ptr = const_cast<char *>(odesc.opcode);
+        int opcode_len = odesc.opcode_len;
+#ifdef _EM64T_
+        Rex *prex = NULL;
+        Rex rex;
+#endif
+
+        *pbuf = save_pbuf;
+#ifdef _EM64T_
+        // Match REX prefixes
+        unsigned char rex_byte = (*pbuf)[0];
+        if ((rex_byte & 0xf0) == 0x40)
+        {
+            if ((rex_byte & 0x08) != 0)
+            {
+                // Have REX.W
+                if (opcode_len > 0 && opcode_ptr[0] == 0x48)
+                {
+                    // Have REX.W in opcode. All mnemonics that allow
+                    // REX.W have to have specified it in opcode,
+                    // otherwise it is not allowed
+                    rex = *(Rex *)*pbuf;
+                    prex = &rex;
+                    (*pbuf)++;
+                    opcode_ptr++;
+                    opcode_len--;
+                }
+            }
+            else
+            {
+                // No REX.W, so it doesn't have to be in opcode. We
+                // have REX.B, REX.X, REX.R or their combination, but
+                // not in opcode, they may extend any part of the
+                // instruction
+                rex = *(Rex *)*pbuf;
+                prex = &rex;
+                (*pbuf)++;
+            }
+        }
+#endif
+        if (opcode_len != 0) {
+            if (memcmp(*pbuf, opcode_ptr, opcode_len)) {
+                continue;
+            }
+            *pbuf += opcode_len;
+        }
+        if (odesc.aux0 != 0) {
+
+            if (!decode_aux(odesc, odesc.aux0, pbuf, pinst
+#ifdef _EM64T_
+                            , prex
+#endif
+                            )) {
+                continue;
+            }
+            if (odesc.aux1 != 0) {
+                if (!decode_aux(odesc, odesc.aux1, pbuf, pinst
+#ifdef _EM64T_
+                            , prex
+#endif
+                            )) {
+                    continue;
+                }
+            }
+            pinst->odesc = &opcodes[i];
+            return true;
+        }
+        else {
+            // Can't have empty opcode
+            assert(opcode_len != 0);
+            pinst->odesc = &opcodes[i];
+            return true;
+        }
+    }
+    return false;
+}
+
+bool DecoderBase::decodeModRM(const EncoderBase::OpcodeDesc& odesc,
+    const unsigned char ** pbuf, Inst * pinst
+#ifdef _EM64T_
+    , const Rex *rex
+#endif
+    )
+{
+    EncoderBase::Operand& opnd = pinst->operands[pinst->argc];
+    const EncoderBase::OpndDesc& opndDesc = odesc.opnds[pinst->argc];
+
+    //XXX debug ///assert(0x66 != *(*pbuf-2));
+    const ModRM& modrm = *(ModRM*)*pbuf;
+    *pbuf += 1;
+
+    RegName base = RegName_Null;
+    RegName index = RegName_Null;
+    int disp = 0;
+    unsigned scale = 0;
+
+    // On x86_64 all mnemonics that allow REX.W have REX.W in opcode.
+    // Therefore REX.W is simply ignored, and opndDesc.size is used
+
+    if (modrm.mod == 3) {
+        // we have only modrm. no sib, no disp.
+        // Android x86: Use XMMReg for 64b operand.
+        OpndKind okind = ((opndDesc.kind & OpndKind_XMMReg) || opndDesc.size == OpndSize_64) ? OpndKind_XMMReg : OpndKind_GPReg;
+        RegName reg = getRegName(okind, opndDesc.size, EXTEND_REG(modrm.rm, b));
+        opnd = EncoderBase::Operand(reg);
+        return true;
+    }
+    //Android x86: m16, m32, m64: mean a byte[word|doubleword] operand in memory
+    //base and index should be 32 bits!!!
+    const SIB& sib = *(SIB*)*pbuf;
+    // check whether we have a sib
+    if (modrm.rm == 4) {
+        // yes, we have SIB
+        *pbuf += 1;
+        // scale = sib.scale == 0 ? 0 : (1<<sib.scale);
+        scale = (1<<sib.scale);
+        if (sib.index != 4) {
+            index = getRegName(OpndKind_GPReg, OpndSize_32, EXTEND_REG(sib.index, x)); //Android x86: OpndDesc.size
+        } else {
+            // (sib.index == 4) => no index
+            //%esp can't be sib.index
+        }
+
+        if (sib.base != 5 || modrm.mod != 0) {
+            base = getRegName(OpndKind_GPReg, OpndSize_32, EXTEND_REG(sib.base, b)); //Android x86: OpndDesc.size
+        } else {
+            // (sib.base == 5 && modrm.mod == 0) => no base
+        }
+    }
+    else {
+        if (modrm.mod != 0 || modrm.rm != 5) {
+            base = getRegName(OpndKind_GPReg, OpndSize_32, EXTEND_REG(modrm.rm, b)); //Android x86: OpndDesc.size
+        }
+        else {
+            // mod=0 && rm == 5 => only disp32
+        }
+    }
+
+    //update disp and pbuf
+    if (modrm.mod == 2) {
+        // have disp32
+        disp = *(int*)*pbuf;
+        *pbuf += 4;
+    }
+    else if (modrm.mod == 1) {
+        // have disp8
+        disp = *(char*)*pbuf;
+        *pbuf += 1;
+    }
+    else {
+        assert(modrm.mod == 0);
+        if (modrm.rm == 5) {
+            // have disp32 w/o sib
+            disp = *(int*)*pbuf;
+            *pbuf += 4;
+        }
+        else if (modrm.rm == 4 && sib.base == 5) {
+            // have disp32 with SI in sib
+            disp = *(int*)*pbuf;
+            *pbuf += 4;
+        }
+    }
+    opnd = EncoderBase::Operand(opndDesc.size, base, index, scale, disp);
+    return true;
+}
+
diff --git a/vm/compiler/codegen/x86/libenc/dec_base.h b/vm/compiler/codegen/x86/libenc/dec_base.h
new file mode 100644
index 0000000..909c743
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/dec_base.h
@@ -0,0 +1,136 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+
+/**
+ * @file
+ * @brief Main decoding (disassembling) routines and structures.
+ *
+ * @note Quick and rough implementation, subject for a change.
+ */
+
+#ifndef __DEC_BASE_H_INCLUDED__
+#define __DEC_BASE_H_INCLUDED__
+
+
+#include "enc_base.h"
+#include "enc_prvt.h"
+
+#ifdef ENCODER_ISOLATE
+using namespace enc_ia32;
+#endif
+
+#define IF_CONDITIONAL  (0x00000000)
+#define IF_SYMMETRIC    (0x00000000)
+#define IF_BRANCH       (0x00000000)
+
+struct Inst {
+    Inst() {
+        mn = Mnemonic_Null;
+        prefc = 0;
+        size = 0;
+        flags = 0;
+        //offset = 0;
+        //direct_addr = NULL;
+        argc = 0;
+        for(int i = 0; i < 4; ++i)
+        {
+            pref[i] = InstPrefix_Null;
+        }
+    }
+    /**
+     * Mnemonic of the instruction.s
+     */
+    Mnemonic mn;
+    /**
+     * Enumerating of indexes in the pref array.
+     */
+    enum PrefGroups
+    {
+        Group1 = 0,
+        Group2,
+        Group3,
+        Group4
+    };
+    /**
+     * Number of prefixes (1 byte each).
+     */
+    unsigned int prefc;
+    /**
+     * Instruction prefixes. Prefix should be placed here according to its group.
+     */
+    InstPrefix pref[4];
+    /**
+     * Size, in bytes, of the instruction.
+     */
+    unsigned size;
+    /**
+     * Flags of the instruction.
+     * @see MF_
+     */
+    unsigned flags;
+    /**
+     * An offset of target address, in case of 'CALL offset',
+     * 'JMP/Jcc offset'.
+     */
+    //int      offset;
+    /**
+     * Direct address of the target (on Intel64/IA-32 is 'instruction IP' +
+     * 'instruction length' + offset).
+     */
+    //void *   direct_addr;
+    /**
+     * Number of arguments of the instruction.
+     */
+    unsigned argc;
+    //
+    EncoderBase::Operand operands[3];
+    //
+    const EncoderBase::OpcodeDesc * odesc;
+};
+
+inline bool is_jcc(Mnemonic mn)
+{
+    return Mnemonic_JO <= mn && mn<=Mnemonic_JG;
+}
+
+class DecoderBase {
+public:
+    static unsigned decode(const void * addr, Inst * pinst);
+private:
+    static bool decodeModRM(const EncoderBase::OpcodeDesc& odesc,
+        const unsigned char ** pbuf, Inst * pinst
+#ifdef _EM64T_
+        , const Rex *rex
+#endif
+        );
+    static bool decode_aux(const EncoderBase::OpcodeDesc& odesc,
+        unsigned aux, const unsigned char ** pbuf,
+        Inst * pinst
+#ifdef _EM64T_
+        , const Rex *rex
+#endif
+        );
+    static bool try_mn(Mnemonic mn, const unsigned char ** pbuf, Inst * pinst);
+    static unsigned int fill_prefs( const unsigned char * bytes, Inst * pinst);
+    static bool is_prefix(const unsigned char * bytes);
+};
+
+#endif  // ~ __DEC_BASE_H_INCLUDED__
+
diff --git a/vm/compiler/codegen/x86/libenc/enc_base.cpp b/vm/compiler/codegen/x86/libenc/enc_base.cpp
new file mode 100644
index 0000000..d141e1f
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/enc_base.cpp
@@ -0,0 +1,1153 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+#include "enc_base.h"
+//#include <climits>
+#include <string.h>
+#define USE_ENCODER_DEFINES
+#include "enc_prvt.h"
+#include <stdio.h>
+
+//#define JET_PROTO
+
+#ifdef JET_PROTO
+#include "dec_base.h"
+#include "jvmti_dasm.h"
+#endif
+
+ENCODER_NAMESPACE_START
+
+/**
+ * @file
+ * @brief Main encoding routines and structures.
+ */
+
+#ifndef _WIN32
+    #define strcmpi strcasecmp
+#endif
+
+int EncoderBase::dummy = EncoderBase::buildTable();
+
+const unsigned char EncoderBase::size_hash[OpndSize_64+1] = {
+    //
+    0xFF,   // OpndSize_Null        = 0,
+    3,              // OpndSize_8           = 0x1,
+    2,              // OpndSize_16          = 0x2,
+    0xFF,   // 0x3
+    1,              // OpndSize_32          = 0x4,
+    0xFF,   // 0x5
+    0xFF,   // 0x6
+    0xFF,   // 0x7
+    0,              // OpndSize_64          = 0x8,
+    //
+};
+
+const unsigned char EncoderBase::kind_hash[OpndKind_Mem+1] = {
+    //
+    //gp reg                -> 000 = 0
+    //memory                -> 001 = 1
+    //immediate             -> 010 = 2
+    //xmm reg               -> 011 = 3
+    //segment regs  -> 100 = 4
+    //fp reg                -> 101 = 5
+    //mmx reg               -> 110 = 6
+    //
+    0xFF,                          // 0    OpndKind_Null=0,
+    0<<2,                          // 1    OpndKind_GPReg =
+                                   //           OpndKind_MinRegKind=0x1,
+    4<<2,                          // 2    OpndKind_SReg=0x2,
+
+#ifdef _HAVE_MMX_
+    6<<2,                          // 3
+#else
+    0xFF,                          // 3
+#endif
+
+    5<<2,                          // 4    OpndKind_FPReg=0x4,
+    0xFF, 0xFF, 0xFF,              // 5, 6, 7
+    3<<2,                                   //      OpndKind_XMMReg=0x8,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 9, 0xA, 0xB, 0xC, 0xD,
+                                              // 0xE, 0xF
+    0xFF,                          // OpndKind_MaxRegKind =
+                                   // OpndKind_StatusReg =
+                                   // OpndKind_OtherReg=0x10,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x11-0x18
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,               // 0x19-0x1F
+    2<<2,                                   // OpndKind_Immediate=0x20,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x21-0x28
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x29-0x30
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x31-0x38
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,               // 0x39-0x3F
+    1<<2,                                   // OpndKind_Memory=0x40
+};
+
+char * EncoderBase::curRelOpnd[3];
+
+char* EncoderBase::encode_aux(char* stream, unsigned aux,
+                              const Operands& opnds, const OpcodeDesc * odesc,
+                              unsigned * pargsCount, Rex * prex)
+{
+    const unsigned byte = aux;
+    OpcodeByteKind kind = (OpcodeByteKind)(byte & OpcodeByteKind_KindMask);
+    // The '>>' here is to force the switch to be table-based) instead of
+    // set of CMP+Jcc.
+    if (*pargsCount >= COUNTOF(opnds)) {
+        assert(false);
+        return stream;
+    }
+    switch(kind>>8) {
+    case OpcodeByteKind_SlashR>>8:
+        // /r - Indicates that the ModR/M byte of the instruction contains
+        // both a register operand and an r/m operand.
+        {
+        assert(opnds.count() > 1);
+    // not true anymore for MOVQ xmm<->r
+        //assert((odesc->opnds[0].kind & OpndKind_Mem) ||
+        //       (odesc->opnds[1].kind & OpndKind_Mem));
+        unsigned memidx = odesc->opnds[0].kind & OpndKind_Mem ? 0 : 1;
+        unsigned regidx = memidx == 0 ? 1 : 0;
+        memidx += *pargsCount;
+        regidx += *pargsCount;
+        ModRM& modrm = *(ModRM*)stream;
+        if (memidx >= COUNTOF(opnds) || regidx >= COUNTOF(opnds)) {
+            assert(false);
+            break;
+        }
+        if (opnds[memidx].is_mem()) {
+            stream = encodeModRM(stream, opnds, memidx, odesc, prex);
+        }
+        else {
+            modrm.mod = 3; // 11
+            modrm.rm = getHWRegIndex(opnds[memidx].reg());
+#ifdef _EM64T_
+            if (opnds[memidx].need_rex() && needs_rex_r(opnds[memidx].reg())) {
+                prex->b = 1;
+            }
+#endif
+            ++stream;
+        }
+        modrm.reg = getHWRegIndex(opnds[regidx].reg());
+#ifdef _EM64T_
+        if (opnds[regidx].need_rex() && needs_rex_r(opnds[regidx].reg())) {
+            prex->r = 1;
+        }
+#endif
+        *pargsCount += 2;
+        }
+        break;
+    case OpcodeByteKind_SlashNum>>8:
+        //  /digit - A digit between 0 and 7 indicates that the
+        //  ModR/M byte of the instruction uses only the r/m
+        //  (register or memory) operand. The reg field contains
+        //  the digit that provides an extension to the instruction's
+        //  opcode.
+        {
+        const unsigned lowByte = (byte & OpcodeByteKind_OpcodeMask);
+        assert(lowByte <= 7);
+        ModRM& modrm = *(ModRM*)stream;
+        unsigned idx = *pargsCount;
+        assert(opnds[idx].is_mem() || opnds[idx].is_reg());
+        if (opnds[idx].is_mem()) {
+            stream = encodeModRM(stream, opnds, idx, odesc, prex);
+        }
+        else {
+            modrm.mod = 3; // 11
+            modrm.rm = getHWRegIndex(opnds[idx].reg());
+#ifdef _EM64T_
+            if (opnds[idx].need_rex() && needs_rex_r(opnds[idx].reg())) {
+                prex->b = 1;
+            }
+#endif
+            ++stream;
+        }
+        modrm.reg = (char)lowByte;
+        *pargsCount += 1;
+        }
+        break;
+    case OpcodeByteKind_plus_i>>8:
+        //  +i - A number used in floating-point instructions when one
+        //  of the operands is ST(i) from the FPU register stack. The
+        //  number i (which can range from 0 to 7) is added to the
+        //  hexadecimal byte given at the left of the plus sign to form
+        //  a single opcode byte.
+        {
+            unsigned idx = *pargsCount;
+            const unsigned lowByte = (byte & OpcodeByteKind_OpcodeMask);
+            *stream = (char)lowByte + getHWRegIndex(opnds[idx].reg());
+            ++stream;
+            *pargsCount += 1;
+        }
+        break;
+    case OpcodeByteKind_ib>>8:
+    case OpcodeByteKind_iw>>8:
+    case OpcodeByteKind_id>>8:
+#ifdef _EM64T_
+    case OpcodeByteKind_io>>8:
+#endif //_EM64T_
+        //  ib, iw, id - A 1-byte (ib), 2-byte (iw), or 4-byte (id)
+        //  immediate operand to the instruction that follows the
+        //  opcode, ModR/M bytes or scale-indexing bytes. The opcode
+        //  determines if the operand is a signed value. All words
+        //  and double words are given with the low-order byte first.
+        {
+            unsigned idx = *pargsCount;
+            *pargsCount += 1;
+            assert(opnds[idx].is_imm());
+            if (kind == OpcodeByteKind_ib) {
+                *(unsigned char*)stream = (unsigned char)opnds[idx].imm();
+                curRelOpnd[idx] = stream;
+                stream += 1;
+            }
+            else if (kind == OpcodeByteKind_iw) {
+                *(unsigned short*)stream = (unsigned short)opnds[idx].imm();
+                curRelOpnd[idx] = stream;
+                stream += 2;
+            }
+            else if (kind == OpcodeByteKind_id) {
+                *(unsigned*)stream = (unsigned)opnds[idx].imm();
+                curRelOpnd[idx] = stream;
+                stream += 4;
+            }
+#ifdef _EM64T_
+            else {
+                assert(kind == OpcodeByteKind_io);
+                *(long long*)stream = (long long)opnds[idx].imm();
+                curRelOpnd[idx] = stream;
+                stream += 8;
+            }
+#else
+            else {
+                assert(false);
+            }
+#endif
+        }
+        break;
+    case OpcodeByteKind_cb>>8:
+        assert(opnds[*pargsCount].is_imm());
+        *(unsigned char*)stream = (unsigned char)opnds[*pargsCount].imm();
+        curRelOpnd[*pargsCount]= stream;
+        stream += 1;
+        *pargsCount += 1;
+        break;
+    case OpcodeByteKind_cw>>8:
+        assert(opnds[*pargsCount].is_imm());
+        *(unsigned short*)stream = (unsigned short)opnds[*pargsCount].imm();
+        curRelOpnd[*pargsCount]= stream;
+        stream += 2;
+        *pargsCount += 1;
+        break;
+    case OpcodeByteKind_cd>>8:
+        assert(opnds[*pargsCount].is_imm());
+        *(unsigned*)stream = (unsigned)opnds[*pargsCount].imm();
+        curRelOpnd[*pargsCount]= stream;
+        stream += 4;
+        *pargsCount += 1;
+        break;
+    //OpcodeByteKind_cp                             = 0x0B00,
+    //OpcodeByteKind_co                             = 0x0C00,
+    //OpcodeByteKind_ct                             = 0x0D00,
+    case OpcodeByteKind_rb>>8:
+    case OpcodeByteKind_rw>>8:
+    case OpcodeByteKind_rd>>8:
+        //  +rb, +rw, +rd - A register code, from 0 through 7,
+        //  added to the hexadecimal byte given at the left of
+        //  the plus sign to form a single opcode byte.
+        assert(opnds.count() > 0);
+        assert(opnds[*pargsCount].is_reg());
+        {
+        const unsigned lowByte = (byte & OpcodeByteKind_OpcodeMask);
+        *(unsigned char*)stream = (unsigned char)lowByte +
+                                   getHWRegIndex(opnds[*pargsCount].reg());
+#ifdef _EM64T_
+        if (opnds[*pargsCount].need_rex() && needs_rex_r(opnds[*pargsCount].reg())) {
+        prex->b = 1;
+        }
+#endif
+        ++stream;
+        *pargsCount += 1;
+        }
+        break;
+    default:
+        assert(false);
+        break;
+    }
+    return stream;
+}
+
+char * EncoderBase::encode(char * stream, Mnemonic mn, const Operands& opnds)
+{
+#ifdef _DEBUG
+    if (opnds.count() > 0) {
+        if (opnds[0].is_mem()) {
+            assert(getRegKind(opnds[0].base()) != OpndKind_SReg);
+        }
+        else if (opnds.count() >1 && opnds[1].is_mem()) {
+            assert(getRegKind(opnds[1].base()) != OpndKind_SReg);
+        }
+    }
+#endif
+
+#ifdef JET_PROTO
+    char* saveStream = stream;
+#endif
+
+    const OpcodeDesc * odesc = lookup(mn, opnds);
+#if !defined(_EM64T_)
+    bool copy_opcode = true;
+    Rex *prex = NULL;
+#else
+    // We need rex if
+    //  either of registers used as operand or address form is new extended register
+    //  it's explicitly specified by opcode
+    // So, if we don't have REX in opcode but need_rex, then set rex here
+    // otherwise, wait until opcode is set, and then update REX
+
+    bool copy_opcode = true;
+    unsigned char _1st = odesc->opcode[0];
+
+    Rex *prex = (Rex*)stream;
+    if (opnds.need_rex() &&
+        ((_1st == 0x66) || (_1st == 0xF2 || _1st == 0xF3) && odesc->opcode[1] == 0x0F)) {
+        // Special processing
+        //
+        copy_opcode = false;
+        //
+        *(unsigned char*)stream = _1st;
+        ++stream;
+        //
+        prex = (Rex*)stream;
+        prex->dummy = 4;
+        prex->w = 0;
+        prex->b = 0;
+        prex->x = 0;
+        prex->r = 0;
+        ++stream;
+        //
+        memcpy(stream, &odesc->opcode[1], odesc->opcode_len-1);
+        stream += odesc->opcode_len-1;
+    }
+    else if (_1st != 0x48 && opnds.need_rex()) {
+        prex = (Rex*)stream;
+        prex->dummy = 4;
+        prex->w = 0;
+        prex->b = 0;
+        prex->x = 0;
+        prex->r = 0;
+        ++stream;
+    }
+#endif  // ifndef EM64T
+
+    if (copy_opcode) {
+        if (odesc->opcode_len==1) {
+        *(unsigned char*)stream = *(unsigned char*)&odesc->opcode;
+        }
+        else if (odesc->opcode_len==2) {
+        *(unsigned short*)stream = *(unsigned short*)&odesc->opcode;
+        }
+        else if (odesc->opcode_len==3) {
+        *(unsigned short*)stream = *(unsigned short*)&odesc->opcode;
+        *(unsigned char*)(stream+2) = odesc->opcode[2];
+        }
+        else if (odesc->opcode_len==4) {
+        *(unsigned*)stream = *(unsigned*)&odesc->opcode;
+        }
+        stream += odesc->opcode_len;
+    }
+
+    unsigned argsCount = odesc->first_opnd;
+
+    if (odesc->aux0) {
+        stream = encode_aux(stream, odesc->aux0, opnds, odesc, &argsCount, prex);
+        if (odesc->aux1) {
+            stream = encode_aux(stream, odesc->aux1, opnds, odesc, &argsCount, prex);
+        }
+    }
+#ifdef JET_PROTO
+    //saveStream
+    Inst inst;
+    unsigned len = DecoderBase::decode(saveStream, &inst);
+    assert(inst.mn == mn);
+    assert(len == (unsigned)(stream-saveStream));
+    if (mn == Mnemonic_CALL || mn == Mnemonic_JMP ||
+        Mnemonic_RET == mn ||
+        (Mnemonic_JO<=mn && mn<=Mnemonic_JG)) {
+        assert(inst.argc == opnds.count());
+
+        InstructionDisassembler idi(saveStream);
+
+        for (unsigned i=0; i<inst.argc; i++) {
+            const EncoderBase::Operand& original = opnds[i];
+            const EncoderBase::Operand& decoded = inst.operands[i];
+            assert(original.kind() == decoded.kind());
+            assert(original.size() == decoded.size());
+            if (original.is_imm()) {
+                assert(original.imm() == decoded.imm());
+                assert(idi.get_opnd(0).kind == InstructionDisassembler::Kind_Imm);
+                if (mn == Mnemonic_CALL) {
+                    assert(idi.get_type() == InstructionDisassembler::RELATIVE_CALL);
+                }
+                else if (mn == Mnemonic_JMP) {
+                    assert(idi.get_type() == InstructionDisassembler::RELATIVE_JUMP);
+                }
+                else if (mn == Mnemonic_RET) {
+                    assert(idi.get_type() == InstructionDisassembler::RET);
+                }
+                else {
+                    assert(idi.get_type() == InstructionDisassembler::RELATIVE_COND_JUMP);
+                }
+            }
+            else if (original.is_mem()) {
+                assert(original.base() == decoded.base());
+                assert(original.index() == decoded.index());
+                assert(original.scale() == decoded.scale());
+                assert(original.disp() == decoded.disp());
+                assert(idi.get_opnd(0).kind == InstructionDisassembler::Kind_Mem);
+                if (mn == Mnemonic_CALL) {
+                    assert(idi.get_type() == InstructionDisassembler::INDIRECT_CALL);
+                }
+                else if (mn == Mnemonic_JMP) {
+                    assert(idi.get_type() == InstructionDisassembler::INDIRECT_JUMP);
+                }
+                else {
+                    assert(false);
+                }
+            }
+            else {
+                assert(original.is_reg());
+                assert(original.reg() == decoded.reg());
+                assert(idi.get_opnd(0).kind == InstructionDisassembler::Kind_Reg);
+                if (mn == Mnemonic_CALL) {
+                    assert(idi.get_type() == InstructionDisassembler::INDIRECT_CALL);
+                }
+                else if (mn == Mnemonic_JMP) {
+                    assert(idi.get_type() == InstructionDisassembler::INDIRECT_JUMP);
+                }
+                else {
+                    assert(false);
+                }
+            }
+        }
+
+        Inst inst2;
+        len = DecoderBase::decode(saveStream, &inst2);
+    }
+
+ //   if(idi.get_length_with_prefix() != (int)len) {
+	//__asm { int 3 };
+ //   }
+#endif
+
+    return stream;
+}
+
+char* EncoderBase::encodeModRM(char* stream, const Operands& opnds,
+                               unsigned idx, const OpcodeDesc * odesc,
+                               Rex * prex)
+{
+    const Operand& op = opnds[idx];
+    assert(op.is_mem());
+    assert(idx < COUNTOF(curRelOpnd));
+    ModRM& modrm = *(ModRM*)stream;
+    ++stream;
+    SIB& sib = *(SIB*)stream;
+
+    // we need SIB if
+    //      we have index & scale (nb: having index w/o base and w/o scale
+    //      treated as error)
+    //      the base is EBP w/o disp, BUT let's use a fake disp8
+    //      the base is ESP (nb: cant have ESP as index)
+
+    RegName base = op.base();
+    // only disp ?..
+    if (base == RegName_Null && op.index() == RegName_Null) {
+        assert(op.scale() == 0); // 'scale!=0' has no meaning without index
+        // ... yes - only have disp
+        // On EM64T, the simply [disp] addressing means 'RIP-based' one -
+        // must have to use SIB to encode 'DS: based'
+#ifdef _EM64T_
+        modrm.mod = 0;  // 00 - ..
+        modrm.rm = 4;   // 100 - have SIB
+
+        sib.base = 5;   // 101 - none
+        sib.index = 4;  // 100 - none
+        sib.scale = 0;  //
+        ++stream; // bypass SIB
+#else
+        // ignore disp_fits8, always use disp32.
+        modrm.mod = 0;
+        modrm.rm = 5;
+#endif
+        *(unsigned*)stream = (unsigned)op.disp();
+        curRelOpnd[idx]= stream;
+        stream += 4;
+        return stream;
+    }
+
+    //climits: error when targeting compal
+#define CHAR_MIN -127
+#define CHAR_MAX 127
+    const bool disp_fits8 = CHAR_MIN <= op.disp() && op.disp() <= CHAR_MAX;
+    /*&& op.base() != RegName_Null - just checked above*/
+    if (op.index() == RegName_Null && getHWRegIndex(op.base()) != getHWRegIndex(REG_STACK)) {
+        assert(op.scale() == 0); // 'scale!=0' has no meaning without index
+        // ... luckily no SIB, only base and may be a disp
+
+        // EBP base is a special case. Need to use [EBP] + disp8 form
+        if (op.disp() == 0  && getHWRegIndex(op.base()) != getHWRegIndex(RegName_EBP)) {
+            modrm.mod = 0; // mod=00, no disp et all
+        }
+        else if (disp_fits8) {
+            modrm.mod = 1; // mod=01, use disp8
+            *(unsigned char*)stream = (unsigned char)op.disp();
+            curRelOpnd[idx]= stream;
+            ++stream;
+        }
+        else {
+            modrm.mod = 2; // mod=10, use disp32
+            *(unsigned*)stream = (unsigned)op.disp();
+            curRelOpnd[idx]= stream;
+            stream += 4;
+        }
+        modrm.rm = getHWRegIndex(op.base());
+    if (is_em64t_extra_reg(op.base())) {
+        prex->b = 1;
+    }
+        return stream;
+    }
+
+    // cool, we do have SIB.
+    ++stream; // bypass SIB in stream
+
+    // {E|R}SP cannot be scaled index, however, R12 which has the same index in modrm - can
+    assert(op.index() == RegName_Null || !equals(op.index(), REG_STACK));
+
+    // Only GPRegs can be encoded in the SIB
+    assert(op.base() == RegName_Null ||
+            getRegKind(op.base()) == OpndKind_GPReg);
+    assert(op.index() == RegName_Null ||
+            getRegKind(op.index()) == OpndKind_GPReg);
+
+    modrm.rm = 4;   // r/m = 100, means 'we have SIB here'
+    if (op.base() == RegName_Null) {
+        // no base.
+        // already checked above if
+        // the first if() //assert(op.index() != RegName_Null);
+
+        modrm.mod = 0;  // mod=00 - here it means 'no base, but disp32'
+        sib.base = 5;   // 101 with mod=00  ^^^
+
+        // encode at least fake disp32 to avoid having [base=ebp]
+        *(unsigned*)stream = op.disp();
+        curRelOpnd[idx]= stream;
+        stream += 4;
+
+        unsigned sc = op.scale();
+        if (sc == 1 || sc==0)   { sib.scale = 0; }    // SS=00
+        else if (sc == 2)       { sib.scale = 1; }    // SS=01
+        else if (sc == 4)       { sib.scale = 2; }    // SS=10
+        else if (sc == 8)       { sib.scale = 3; }    // SS=11
+        sib.index = getHWRegIndex(op.index());
+    if (is_em64t_extra_reg(op.index())) {
+        prex->x = 1;
+    }
+
+        return stream;
+    }
+
+    if (op.disp() == 0 && getHWRegIndex(op.base()) != getHWRegIndex(RegName_EBP)) {
+        modrm.mod = 0;  // mod=00, no disp
+    }
+    else if (disp_fits8) {
+        modrm.mod = 1;  // mod=01, use disp8
+        *(unsigned char*)stream = (unsigned char)op.disp();
+        curRelOpnd[idx]= stream;
+        stream += 1;
+    }
+    else {
+        modrm.mod = 2;  // mod=10, use disp32
+        *(unsigned*)stream = (unsigned)op.disp();
+        curRelOpnd[idx]= stream;
+        stream += 4;
+    }
+
+    if (op.index() == RegName_Null) {
+        assert(op.scale() == 0); // 'scale!=0' has no meaning without index
+        // the only reason we're here without index, is that we have {E|R}SP
+        // or R12 as a base. Another possible reason - EBP without a disp -
+        // is handled above by adding a fake disp8
+#ifdef _EM64T_
+        assert(op.base() != RegName_Null && (equals(op.base(), REG_STACK) ||
+                                             equals(op.base(), RegName_R12)));
+#else  // _EM64T_
+        assert(op.base() != RegName_Null && equals(op.base(), REG_STACK));
+#endif //_EM64T_
+        sib.scale = 0;  // SS = 00
+        sib.index = 4;  // SS + index=100 means 'no index'
+    }
+    else {
+        unsigned sc = op.scale();
+        if (sc == 1 || sc==0)   { sib.scale = 0; }    // SS=00
+        else if (sc == 2)       { sib.scale = 1; }    // SS=01
+        else if (sc == 4)       { sib.scale = 2; }    // SS=10
+        else if (sc == 8)       { sib.scale = 3; }    // SS=11
+        sib.index = getHWRegIndex(op.index());
+    if (is_em64t_extra_reg(op.index())) {
+        prex->x = 1;
+    }
+        // not an error by itself, but the usage of [index*1] instead
+        // of [base] is discouraged
+        assert(op.base() != RegName_Null || op.scale() != 1);
+    }
+    sib.base = getHWRegIndex(op.base());
+    if (is_em64t_extra_reg(op.base())) {
+    prex->b = 1;
+    }
+    return stream;
+}
+
+char * EncoderBase::nops(char * stream, unsigned howMany)
+{
+    // Recommended multi-byte NOPs from the Intel architecture manual
+    static const unsigned char nops[10][9] = {
+        { 0, },                                                     // 0, this line is dummy and not used in the loop below
+        { 0x90, },                                                  // 1-byte NOP
+        { 0x66, 0x90, },                                            // 2
+        { 0x0F, 0x1F, 0x00, },                                      // 3
+        { 0x0F, 0x1F, 0x40, 0x00, },                                // 4
+        { 0x0F, 0x1F, 0x44, 0x00, 0x00, },                          // 5
+        { 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00, },                    // 6
+        { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, },              // 7
+        { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, },        // 8
+        { 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 },   // 9-byte NOP
+    };
+
+    // Start from delivering the longest possible NOPs, then proceed with shorter ones
+    for (unsigned nopSize=9; nopSize!=0; nopSize--) {
+        while(howMany>=nopSize) {
+            const unsigned char* nopBytes = nops[nopSize];
+            for (unsigned i=0; i<nopSize; i++) {
+                stream[i] = nopBytes[i];
+            }
+            stream += nopSize;
+            howMany -= nopSize;
+        }
+    }
+    char* end = stream + howMany;
+    return end;
+}
+
+char * EncoderBase::prefix(char* stream, InstPrefix pref)
+{
+    if (pref== InstPrefix_Null) {
+        // nothing to do
+        return stream;
+    }
+    *stream = (char)pref;
+    return stream + 1;
+}
+
+
+/**
+ *
+ */
+bool EncoderBase::extAllowed(OpndExt opndExt, OpndExt instExt) {
+    if (instExt == opndExt || instExt == OpndExt_Any || opndExt == OpndExt_Any) {
+            return true;
+    }
+//asm("int3");
+assert(0);
+    return false;
+}
+
+/**
+ *
+ */
+static bool match(const EncoderBase::OpcodeDesc& odesc,
+                      const EncoderBase::Operands& opnds) {
+
+    assert(odesc.roles.count == opnds.count());
+
+    for(unsigned j = 0; j < odesc.roles.count; j++) {
+        const EncoderBase::OpndDesc& desc = odesc.opnds[j];
+        const EncoderBase::Operand& op = opnds[j];
+        // location must match exactly
+        if ((desc.kind & op.kind()) != op.kind()) {
+//assert(0);
+            return false;
+        }
+        // size must match exactly
+        if (desc.size != op.size()) {
+//assert(0);
+            return false;
+        }
+        // extentions should be consistent
+        if (!EncoderBase::extAllowed(op.ext(), desc.ext)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+
+static bool try_match(const EncoderBase::OpcodeDesc& odesc,
+                      const EncoderBase::Operands& opnds, bool strict) {
+
+    assert(odesc.roles.count == opnds.count());
+
+    for(unsigned j=0; j<odesc.roles.count; j++) {
+        // - the location must match exactly
+        if ((odesc.opnds[j].kind & opnds[j].kind()) != opnds[j].kind()) {
+            return false;
+        }
+        if (strict) {
+            // the size must match exactly
+            if (odesc.opnds[j].size != opnds[j].size()) {
+                return false;
+            }
+        }
+        else {
+            // must match only for def operands, and dont care about use ones
+            // situations like 'mov r8, imm32/mov r32, imm8' so the
+            // destination operand defines the overall size
+            if (EncoderBase::getOpndRoles(odesc.roles, j) & OpndRole_Def) {
+                if (odesc.opnds[j].size != opnds[j].size()) {
+                    return false;
+                }
+            }
+        }
+    }
+    return true;
+}
+
+//
+//Subhash implementaion - may be useful in case of many misses during fast
+//opcode lookup.
+//
+
+#ifdef ENCODER_USE_SUBHASH
+static unsigned subHash[32];
+
+static unsigned find(Mnemonic mn, unsigned hash)
+{
+    unsigned key = hash % COUNTOF(subHash);
+    unsigned pack = subHash[key];
+    unsigned _hash = pack & 0xFFFF;
+    if (_hash != hash) {
+        stat.miss(mn);
+        return EncoderBase::NOHASH;
+    }
+    unsigned _mn = (pack >> 24)&0xFF;
+    if (_mn != _mn) {
+        stat.miss(mn);
+        return EncoderBase::NOHASH;
+    }
+    unsigned idx = (pack >> 16) & 0xFF;
+    stat.hit(mn);
+    return idx;
+}
+
+static void put(Mnemonic mn, unsigned hash, unsigned idx)
+{
+    unsigned pack = hash | (idx<<16) | (mn << 24);
+    unsigned key = hash % COUNTOF(subHash);
+    subHash[key] = pack;
+}
+#endif
+
+const EncoderBase::OpcodeDesc *
+EncoderBase::lookup(Mnemonic mn, const Operands& opnds)
+{
+    const unsigned hash = opnds.hash();
+    unsigned opcodeIndex = opcodesHashMap[mn][hash];
+#ifdef ENCODER_USE_SUBHASH
+    if (opcodeIndex == NOHASH) {
+        opcodeIndex = find(mn, hash);
+    }
+#endif
+
+    if (opcodeIndex == NOHASH) {
+        // fast-path did no work. try to lookup sequentially
+        const OpcodeDesc * odesc = opcodes[mn];
+        int idx = -1;
+        bool found = false;
+        for (idx=0; !odesc[idx].last; idx++) {
+            const OpcodeDesc& opcode = odesc[idx];
+            if (opcode.platf == OpcodeInfo::decoder) {
+                continue;
+            }
+            if (opcode.roles.count != opnds.count()) {
+                continue;
+            }
+            if (try_match(opcode, opnds, true)) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            for (idx=0; !odesc[idx].last; idx++) {
+                const OpcodeDesc& opcode = odesc[idx];
+                if (opcode.platf == OpcodeInfo::decoder) {
+                    continue;
+                }
+                if (opcode.roles.count != opnds.count()) {
+                    continue;
+                }
+                if (try_match(opcode, opnds, false)) {
+                    found = true;
+                    break;
+                }
+            }
+        }
+        assert(found);
+        opcodeIndex = idx;
+#ifdef ENCODER_USE_SUBHASH
+        put(mn, hash, opcodeIndex);
+#endif
+    }
+    assert(opcodeIndex != NOHASH);
+    const OpcodeDesc * odesc = &opcodes[mn][opcodeIndex];
+    assert(!odesc->last);
+    assert(odesc->roles.count == opnds.count());
+    assert(odesc->platf != OpcodeInfo::decoder);
+#if !defined(_EM64T_)
+    // tuning was done for IA32 only, so no size restriction on EM64T
+    //assert(sizeof(OpcodeDesc)==128);
+#endif
+    return odesc;
+}
+
+char* EncoderBase::getOpndLocation(int index) {
+     assert(index < 3);
+     return curRelOpnd[index];
+}
+
+
+Mnemonic EncoderBase::str2mnemonic(const char * mn_name)
+{
+    for (unsigned m = 1; m<Mnemonic_Count; m++) {
+        if (!strcmpi(mnemonics[m].name, mn_name)) {
+            return (Mnemonic)m;
+        }
+    }
+    return Mnemonic_Null;
+}
+
+static const char * conditionStrings[ConditionMnemonic_Count] = {
+    "O",
+    "NO",
+    "B",
+    "AE",
+    "Z",
+    "NZ",
+    "BE",
+    "A",
+
+    "S",
+    "NS",
+    "P",
+    "NP",
+    "L",
+    "GE",
+    "LE",
+    "G",
+};
+
+const char * getConditionString(ConditionMnemonic cm) {
+    return conditionStrings[cm];
+}
+
+static const struct {
+        char            sizeString[12];
+        OpndSize        size;
+}
+sizes[] = {
+    { "Sz8", OpndSize_8 },
+    { "Sz16", OpndSize_16 },
+    { "Sz32", OpndSize_32 },
+    { "Sz64", OpndSize_64 },
+#if !defined(TESTING_ENCODER)
+    { "Sz80", OpndSize_80 },
+    { "Sz128", OpndSize_128 },
+#endif
+    { "SzAny", OpndSize_Any },
+};
+
+
+OpndSize getOpndSize(const char * sizeString)
+{
+    assert(sizeString);
+    for (unsigned i = 0; i<COUNTOF(sizes); i++) {
+        if (!strcmpi(sizeString, sizes[i].sizeString)) {
+            return sizes[i].size;
+        }
+    }
+    return OpndSize_Null;
+}
+
+const char * getOpndSizeString(OpndSize size) {
+    for( unsigned i = 0; i<COUNTOF(sizes); i++ ) {
+        if( sizes[i].size==size ) {
+            return sizes[i].sizeString;
+        }
+    }
+    return NULL;
+}
+
+static const struct {
+    char            kindString[16];
+    OpndKind        kind;
+}
+kinds[] = {
+    { "Null", OpndKind_Null },
+    { "GPReg", OpndKind_GPReg },
+    { "SReg", OpndKind_SReg },
+    { "FPReg", OpndKind_FPReg },
+    { "XMMReg", OpndKind_XMMReg },
+#ifdef _HAVE_MMX_
+    { "MMXReg", OpndKind_MMXReg },
+#endif
+    { "StatusReg", OpndKind_StatusReg },
+    { "Reg", OpndKind_Reg },
+    { "Imm", OpndKind_Imm },
+    { "Mem", OpndKind_Mem },
+    { "Any", OpndKind_Any },
+};
+
+const char * getOpndKindString(OpndKind kind)
+{
+    for (unsigned i = 0; i<COUNTOF(kinds); i++) {
+        if (kinds[i].kind==kind) {
+            return kinds[i].kindString;
+        }
+    }
+    return NULL;
+}
+
+OpndKind getOpndKind(const char * kindString)
+{
+    assert(kindString);
+    for (unsigned i = 0; i<COUNTOF(kinds); i++) {
+        if (!strcmpi(kindString, kinds[i].kindString)) {
+            return kinds[i].kind;
+        }
+    }
+    return OpndKind_Null;
+}
+
+/**
+ * A mapping between register string representation and its RegName constant.
+ */
+static const struct {
+        char    regstring[7];
+        RegName regname;
+}
+
+registers[] = {
+#ifdef _EM64T_
+    {"RAX",         RegName_RAX},
+    {"RBX",         RegName_RBX},
+    {"RCX",         RegName_RCX},
+    {"RDX",         RegName_RDX},
+    {"RBP",         RegName_RBP},
+    {"RSI",         RegName_RSI},
+    {"RDI",         RegName_RDI},
+    {"RSP",         RegName_RSP},
+    {"R8",          RegName_R8},
+    {"R9",          RegName_R9},
+    {"R10",         RegName_R10},
+    {"R11",         RegName_R11},
+    {"R12",         RegName_R12},
+    {"R13",         RegName_R13},
+    {"R14",         RegName_R14},
+    {"R15",         RegName_R15},
+#endif
+
+    {"EAX",         RegName_EAX},
+    {"ECX",         RegName_ECX},
+    {"EDX",         RegName_EDX},
+    {"EBX",         RegName_EBX},
+    {"ESP",         RegName_ESP},
+    {"EBP",         RegName_EBP},
+    {"ESI",         RegName_ESI},
+    {"EDI",         RegName_EDI},
+#ifdef _EM64T_
+    {"R8D",         RegName_R8D},
+    {"R9D",         RegName_R9D},
+    {"R10D",        RegName_R10D},
+    {"R11D",        RegName_R11D},
+    {"R12D",        RegName_R12D},
+    {"R13D",        RegName_R13D},
+    {"R14D",        RegName_R14D},
+    {"R15D",        RegName_R15D},
+#endif
+
+    {"AX",          RegName_AX},
+    {"CX",          RegName_CX},
+    {"DX",          RegName_DX},
+    {"BX",          RegName_BX},
+    {"SP",          RegName_SP},
+    {"BP",          RegName_BP},
+    {"SI",          RegName_SI},
+    {"DI",          RegName_DI},
+
+    {"AL",          RegName_AL},
+    {"CL",          RegName_CL},
+    {"DL",          RegName_DL},
+    {"BL",          RegName_BL},
+#if !defined(_EM64T_)
+    {"AH",          RegName_AH},
+    {"CH",          RegName_CH},
+    {"DH",          RegName_DH},
+    {"BH",          RegName_BH},
+#else
+    {"SPL",         RegName_SPL},
+    {"BPL",         RegName_BPL},
+    {"SIL",         RegName_SIL},
+    {"DIL",         RegName_DIL},
+    {"R8L",         RegName_R8L},
+    {"R9L",         RegName_R9L},
+    {"R10L",        RegName_R10L},
+    {"R11L",        RegName_R11L},
+    {"R12L",        RegName_R12L},
+    {"R13L",        RegName_R13L},
+    {"R14L",        RegName_R14L},
+    {"R15L",        RegName_R15L},
+#endif
+    {"ES",          RegName_ES},
+    {"CS",          RegName_CS},
+    {"SS",          RegName_SS},
+    {"DS",          RegName_DS},
+    {"FS",          RegName_FS},
+    {"GS",          RegName_GS},
+
+    {"FP0",         RegName_FP0},
+/*
+    {"FP1",         RegName_FP1},
+    {"FP2",         RegName_FP2},
+    {"FP3",         RegName_FP3},
+    {"FP4",         RegName_FP4},
+    {"FP5",         RegName_FP5},
+    {"FP6",         RegName_FP6},
+    {"FP7",         RegName_FP7},
+*/
+    {"FP0S",        RegName_FP0S},
+    {"FP1S",        RegName_FP1S},
+    {"FP2S",        RegName_FP2S},
+    {"FP3S",        RegName_FP3S},
+    {"FP4S",        RegName_FP4S},
+    {"FP5S",        RegName_FP5S},
+    {"FP6S",        RegName_FP6S},
+    {"FP7S",        RegName_FP7S},
+
+    {"FP0D",        RegName_FP0D},
+    {"FP1D",        RegName_FP1D},
+    {"FP2D",        RegName_FP2D},
+    {"FP3D",        RegName_FP3D},
+    {"FP4D",        RegName_FP4D},
+    {"FP5D",        RegName_FP5D},
+    {"FP6D",        RegName_FP6D},
+    {"FP7D",        RegName_FP7D},
+
+    {"XMM0",        RegName_XMM0},
+    {"XMM1",        RegName_XMM1},
+    {"XMM2",        RegName_XMM2},
+    {"XMM3",        RegName_XMM3},
+    {"XMM4",        RegName_XMM4},
+    {"XMM5",        RegName_XMM5},
+    {"XMM6",        RegName_XMM6},
+    {"XMM7",        RegName_XMM7},
+#ifdef _EM64T_
+    {"XMM8",       RegName_XMM8},
+    {"XMM9",       RegName_XMM9},
+    {"XMM10",      RegName_XMM10},
+    {"XMM11",      RegName_XMM11},
+    {"XMM12",      RegName_XMM12},
+    {"XMM13",      RegName_XMM13},
+    {"XMM14",      RegName_XMM14},
+    {"XMM15",      RegName_XMM15},
+#endif
+
+
+    {"XMM0S",       RegName_XMM0S},
+    {"XMM1S",       RegName_XMM1S},
+    {"XMM2S",       RegName_XMM2S},
+    {"XMM3S",       RegName_XMM3S},
+    {"XMM4S",       RegName_XMM4S},
+    {"XMM5S",       RegName_XMM5S},
+    {"XMM6S",       RegName_XMM6S},
+    {"XMM7S",       RegName_XMM7S},
+#ifdef _EM64T_
+    {"XMM8S",       RegName_XMM8S},
+    {"XMM9S",       RegName_XMM9S},
+    {"XMM10S",      RegName_XMM10S},
+    {"XMM11S",      RegName_XMM11S},
+    {"XMM12S",      RegName_XMM12S},
+    {"XMM13S",      RegName_XMM13S},
+    {"XMM14S",      RegName_XMM14S},
+    {"XMM15S",      RegName_XMM15S},
+#endif
+
+    {"XMM0D",       RegName_XMM0D},
+    {"XMM1D",       RegName_XMM1D},
+    {"XMM2D",       RegName_XMM2D},
+    {"XMM3D",       RegName_XMM3D},
+    {"XMM4D",       RegName_XMM4D},
+    {"XMM5D",       RegName_XMM5D},
+    {"XMM6D",       RegName_XMM6D},
+    {"XMM7D",       RegName_XMM7D},
+#ifdef _EM64T_
+    {"XMM8D",       RegName_XMM8D},
+    {"XMM9D",       RegName_XMM9D},
+    {"XMM10D",      RegName_XMM10D},
+    {"XMM11D",      RegName_XMM11D},
+    {"XMM12D",      RegName_XMM12D},
+    {"XMM13D",      RegName_XMM13D},
+    {"XMM14D",      RegName_XMM14D},
+    {"XMM15D",      RegName_XMM15D},
+#endif
+
+    {"EFLGS",       RegName_EFLAGS},
+};
+
+
+const char * getRegNameString(RegName reg)
+{
+    for (unsigned i = 0; i<COUNTOF(registers); i++) {
+        if (registers[i].regname == reg) {
+            return registers[i].regstring;
+        }
+    }
+    return NULL;
+}
+
+RegName getRegName(const char * regname)
+{
+    if (NULL == regname) {
+        return RegName_Null;
+    }
+
+    for (unsigned i = 0; i<COUNTOF(registers); i++) {
+        if (!strcmpi(regname,registers[i].regstring)) {
+            return registers[i].regname;
+        }
+    }
+    return RegName_Null;
+}
+
+ENCODER_NAMESPACE_END
diff --git a/vm/compiler/codegen/x86/libenc/enc_base.h b/vm/compiler/codegen/x86/libenc/enc_base.h
new file mode 100644
index 0000000..e90ad2b
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/enc_base.h
@@ -0,0 +1,740 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+
+/**
+ * @file
+ * @brief Main encoding routines and structures.
+ */
+
+#ifndef __ENC_BASE_H_INCLUDED__
+#define __ENC_BASE_H_INCLUDED__
+
+#include "enc_defs.h"
+
+
+#include <stdlib.h>
+#include <assert.h>
+#include <memory.h>
+
+ENCODER_NAMESPACE_START
+struct MnemonicInfo;
+struct OpcodeInfo;
+struct Rex;
+
+/**
+ * @brief Basic facilities for generation of processor's instructions.
+ *
+ * The class EncoderBase represents the basic facilities for the encoding of
+ * processor's instructions on IA32 and EM64T platforms.
+ *
+ * The class provides general interface to generate the instructions as well
+ * as to retrieve some static data about instructions (number of arguments,
+ * their roles, etc).
+ *
+ * Currently, the EncoderBase class is used for both LIL and Jitrino code
+ * generators. Each of these code generators has its own wrapper to adapt
+ * this general interface for specific needs - see encoder.h for LIL wrappers
+ * and Ia32Encoder.h for Jitrino's adapter.
+ *
+ * Interface is provided through static methods, no instances of EncoderBase
+ * to be created.
+ *
+ * @todo RIP-based addressing on EM64T - it's not yet supported currently.
+ */
+class EncoderBase {
+public:
+    class Operands;
+    struct MnemonicDesc;
+    /**
+     * @brief Generates processor's instruction.
+     *
+     * @param stream - a buffer to generate into
+     * @param mn - \link Mnemonic mnemonic \endlink of the instruction
+     * @param opnds - operands for the instruction
+     * @returns (stream + length of the just generated instruction)
+     */
+    static char * encode(char * stream, Mnemonic mn, const Operands& opnds);
+    static char * getOpndLocation(int index);
+
+    /**
+     * @brief Generates the smallest possible number of NOP-s.
+     *
+     * Effectively generates the smallest possible number of instructions,
+     * which are NOP-s for CPU. Normally used to make a code alignment.
+     *
+     * The method inserts exactly number of bytes specified. It's a caller's
+     * responsibility to make sure the buffer is big enough.
+     *
+     * @param stream - buffer where to generate code into, can not be NULL
+     * @param howMany - how many bytes to fill with NOP-s
+     * @return \c (stream+howMany)
+     */
+    static char * nops(char * stream, unsigned howMany);
+
+    /**
+     * @brief Inserts a prefix into the code buffer.
+     *
+     * The method writes no more than one byte into the buffer. This is a
+     * caller's responsibility to make sure the buffer is big enough.
+     *
+     * @param stream - buffer where to insert the prefix
+     * @param pref - prefix to be inserted. If it's InstPrefix_Null, then
+     *        no action performed and return value is \c stream.
+     * @return \c (stream+1) if pref is not InstPrefix_Null, or \c stream
+     *         otherwise
+     */
+     static char * prefix(char* stream, InstPrefix pref);
+
+    /**
+     * @brief Determines if operand with opndExt suites the position with instExt.
+     */
+    static bool extAllowed(OpndExt opndExt, OpndExt instExt);
+
+    /**
+     * @brief Returns #MnemonicDesc by the given Mnemonic.
+     */
+    static const MnemonicDesc * getMnemonicDesc(Mnemonic mn)
+    {
+        assert(mn < Mnemonic_Count);
+        return mnemonics + mn;
+    }
+
+    /**
+     * @brief Returns a Mnemonic for the given name.
+     *
+     * The lookup is case insensitive, if no mnemonic found for the given
+     * string, then Mnemonic_Null returned.
+     */
+    static Mnemonic str2mnemonic(const char * mn_name);
+
+    /**
+     * @brief Returns a string representation of the given Mnemonic.
+     *
+     * If invalid mnemonic passed, then the behavior is unpredictable.
+     */
+    static const char * getMnemonicString(Mnemonic mn)
+    {
+        return getMnemonicDesc(mn)->name;
+    }
+
+    static const char * toStr(Mnemonic mn)
+    {
+        return getMnemonicDesc(mn)->name;
+    }
+
+
+    /**
+     * @brief Description of operand.
+     *
+     * Description of an operand in opcode - its kind, size or RegName if
+     * operand must be a particular register.
+     */
+    struct OpndDesc {
+        /**
+         * @brief Location of the operand.
+         *
+         * May be a mask, i.e. OpndKind_Imm|OpndKind_Mem.
+         */
+        OpndKind        kind;
+        /**
+         * @brief Size of the operand.
+         */
+        OpndSize        size;
+        /**
+         * @brief Extention of the operand.
+         */
+        OpndExt         ext;
+        /**
+         * @brief Appropriate RegName if operand must reside on a particular
+         *        register (i.e. CWD/CDQ instructions), RegName_Null
+         *        otherwise.
+         */
+        RegName         reg;
+    };
+
+    /**
+     * @brief Description of operands' roles in instruction.
+     */
+    struct OpndRolesDesc {
+        /**
+         * @brief Total number of operands in the operation.
+         */
+        unsigned                count;
+        /**
+         * @brief Number of defs in the operation.
+         */
+        unsigned                defCount;
+        /**
+         * @brief Number of uses in the operation.
+         */
+        unsigned                useCount;
+        /**
+         * @brief Operand roles, bit-packed.
+         *
+         * A bit-packed info about operands' roles. Each operand's role is
+         * described by two bits, counted from right-to-left - the less
+         * significant bits (0,1) represent operand#0.
+         *
+         * The mask is build by ORing #OpndRole_Def and #OpndRole_Use
+         * appropriately and shifting left, i.e. operand#0's role would be
+         * - '(OpndRole_Def|OpndRole_Use)'
+         * - opnd#1's role would be 'OpndRole_Use<<2'
+         * - and operand#2's role would be, say, 'OpndRole_Def<<4'.
+         */
+        unsigned                roles;
+    };
+
+    /**
+     * @brief Extracts appropriate OpndRole for a given operand.
+     *
+     * The order of operands is left-to-right, i.e. for MOV, it
+     * would be 'MOV op0, op1'
+     */
+    static OpndRole getOpndRoles(OpndRolesDesc ord, unsigned idx)
+    {
+        assert(idx < ord.count);
+        return (OpndRole)(ord.roles>>((ord.count-1-idx)*2) & 0x3);
+    }
+
+    /**
+     * @brief Info about single opcode - its opcode bytes, operands,
+     *        operands' roles.
+     */
+   union OpcodeDesc {
+       char dummy[128]; // To make total size a power of 2
+
+       struct {
+           /**
+           * @brief Raw opcode bytes.
+           *
+           * 'Raw' opcode bytes which do not require any analysis and are
+           * independent from arguments/sizes/etc (may include opcode size
+           * prefix).
+           */
+           char        opcode[5];
+           unsigned    opcode_len;
+           unsigned    aux0;
+           unsigned    aux1;
+           /**
+           * @brief Info about opcode's operands.
+           *
+           * The [3] mostly comes from IDIV/IMUL which both may have up to 3
+           * operands.
+           */
+           OpndDesc        opnds[3];
+           unsigned        first_opnd;
+           /**
+           * @brief Info about operands - total number, number of uses/defs,
+           *        operands' roles.
+           */
+           OpndRolesDesc   roles;
+           /**
+           * @brief If not zero, then this is final OpcodeDesc structure in
+           *        the list of opcodes for a given mnemonic.
+           */
+           char            last;
+           char            platf;
+       };
+   };
+public:
+    /**
+     * @brief General info about mnemonic.
+     */
+    struct MnemonicDesc {
+        /**
+        * @brief The mnemonic itself.
+        */
+        Mnemonic        mn;
+        /**
+        * Various characteristics of mnemonic.
+        * @see MF_
+         */
+        unsigned    flags;
+        /**
+         * @brief Operation's operand's count and roles.
+         *
+         * For the operations whose opcodes may use different number of
+         * operands (i.e. IMUL/SHL) either most common value used, or empty
+         * value left.
+         */
+        OpndRolesDesc   roles;
+        /**
+         * @brief Print name of the mnemonic.
+         */
+        const char *    name;
+    };
+
+
+    /**
+     * @brief Magic number, shows a maximum value a hash code can take.
+     *
+     * For meaning and arithmetics see enc_tabl.cpp.
+     *
+     * The value was increased from '5155' to '8192' to make it aligned
+     * for faster access in EncoderBase::lookup().
+     */
+    static const unsigned int               HASH_MAX = 8192; //5155;
+    /**
+     * @brief Empty value, used in hash-to-opcode map to show an empty slot.
+     */
+    static const unsigned char              NOHASH = 0xFF;
+    /**
+     * @brief The name says it all.
+     */
+    static const unsigned char              HASH_BITS_PER_OPERAND = 5;
+
+    /**
+     * @brief Contains info about a single instructions's operand - its
+     *        location, size and a value for immediate or RegName for
+     *        register operands.
+     */
+    class Operand {
+    public:
+        /**
+         * @brief Initializes the instance with empty size and kind.
+         */
+        Operand() : m_kind(OpndKind_Null), m_size(OpndSize_Null), m_ext(OpndExt_None), m_need_rex(false) {}
+        /**
+         * @brief Creates register operand from given RegName.
+         */
+        Operand(RegName reg, OpndExt ext = OpndExt_None) : m_kind(getRegKind(reg)),
+                               m_size(getRegSize(reg)),
+                               m_ext(ext), m_reg(reg)
+        {
+            hash_it();
+        }
+        /**
+         * @brief Creates register operand from given RegName and with the
+         *        specified size and kind.
+         *
+         * Used to speedup Operand creation as there is no need to extract
+         * size and kind from the RegName.
+         * The provided size and kind must match the RegName's ones though.
+         */
+        Operand(OpndSize sz, OpndKind kind, RegName reg, OpndExt ext = OpndExt_None) :
+            m_kind(kind), m_size(sz), m_ext(ext), m_reg(reg)
+        {
+            assert(m_size == getRegSize(reg));
+            assert(m_kind == getRegKind(reg));
+            hash_it();
+        }
+        /**
+         * @brief Creates immediate operand with the given size and value.
+         */
+        Operand(OpndSize size, long long ival, OpndExt ext = OpndExt_None) :
+            m_kind(OpndKind_Imm), m_size(size), m_ext(ext), m_imm64(ival)
+        {
+            hash_it();
+        }
+        /**
+         * @brief Creates immediate operand of OpndSize_32.
+         */
+        Operand(int ival, OpndExt ext = OpndExt_None) :
+            m_kind(OpndKind_Imm), m_size(OpndSize_32), m_ext(ext), m_imm64(ival)
+        {
+            hash_it();
+        }
+        /**
+         * @brief Creates immediate operand of OpndSize_16.
+         */
+        Operand(short ival, OpndExt ext = OpndExt_None) :
+            m_kind(OpndKind_Imm), m_size(OpndSize_16), m_ext(ext), m_imm64(ival)
+        {
+            hash_it();
+        }
+
+        /**
+         * @brief Creates immediate operand of OpndSize_8.
+         */
+        Operand(char ival, OpndExt ext = OpndExt_None) :
+            m_kind(OpndKind_Imm), m_size(OpndSize_8), m_ext(ext), m_imm64(ival)
+        {
+            hash_it();
+        }
+
+        /**
+         * @brief Creates memory operand.
+         */
+        Operand(OpndSize size, RegName base, RegName index, unsigned scale,
+                int disp, OpndExt ext = OpndExt_None) : m_kind(OpndKind_Mem), m_size(size), m_ext(ext)
+        {
+            m_base = base;
+            m_index = index;
+            m_scale = scale;
+            m_disp = disp;
+            hash_it();
+        }
+
+        /**
+         * @brief Creates memory operand with only base and displacement.
+         */
+        Operand(OpndSize size, RegName base, int disp, OpndExt ext = OpndExt_None) :
+            m_kind(OpndKind_Mem), m_size(size), m_ext(ext)
+        {
+            m_base = base;
+            m_index = RegName_Null;
+            m_scale = 0;
+            m_disp = disp;
+            hash_it();
+        }
+        //
+        // general info
+        //
+        /**
+         * @brief Returns kind of the operand.
+         */
+        OpndKind kind(void) const { return m_kind; }
+        /**
+         * @brief Returns size of the operand.
+         */
+        OpndSize size(void) const { return m_size; }
+        /**
+         * @brief Returns extention of the operand.
+         */
+        OpndExt ext(void) const { return m_ext; }
+        /**
+         * @brief Returns hash of the operand.
+         */
+        unsigned hash(void) const { return m_hash; }
+        //
+#ifdef _EM64T_
+        bool need_rex(void) const { return m_need_rex; }
+#else
+        bool need_rex(void) const { return false; }
+#endif
+        /**
+         * @brief Tests whether operand is memory operand.
+         */
+        bool is_mem(void) const { return is_placed_in(OpndKind_Mem); }
+        /**
+         * @brief Tests whether operand is immediate operand.
+         */
+        bool is_imm(void) const { return is_placed_in(OpndKind_Imm); }
+        /**
+         * @brief Tests whether operand is register operand.
+         */
+        bool is_reg(void) const { return is_placed_in(OpndKind_Reg); }
+        /**
+         * @brief Tests whether operand is general-purpose register operand.
+         */
+        bool is_gpreg(void) const { return is_placed_in(OpndKind_GPReg); }
+        /**
+         * @brief Tests whether operand is float-point pseudo-register operand.
+         */
+        bool is_fpreg(void) const { return is_placed_in(OpndKind_FPReg); }
+        /**
+         * @brief Tests whether operand is XMM register operand.
+         */
+        bool is_xmmreg(void) const { return is_placed_in(OpndKind_XMMReg); }
+#ifdef _HAVE_MMX_
+        /**
+         * @brief Tests whether operand is MMX register operand.
+         */
+        bool is_mmxreg(void) const { return is_placed_in(OpndKind_MMXReg); }
+#endif
+        /**
+         * @brief Tests whether operand is signed immediate operand.
+         */
+        //bool is_signed(void) const { assert(is_imm()); return m_is_signed; }
+
+        /**
+         * @brief Returns base of memory operand (RegName_Null if not memory).
+         */
+        RegName base(void) const { return is_mem() ? m_base : RegName_Null; }
+        /**
+         * @brief Returns index of memory operand (RegName_Null if not memory).
+         */
+        RegName index(void) const { return is_mem() ? m_index : RegName_Null; }
+        /**
+         * @brief Returns scale of memory operand (0 if not memory).
+         */
+        unsigned scale(void) const { return is_mem() ? m_scale : 0; }
+        /**
+         * @brief Returns displacement of memory operand (0 if not memory).
+         */
+        int disp(void) const { return is_mem() ? m_disp : 0; }
+        /**
+         * @brief Returns RegName of register operand (RegName_Null if not
+         *        register).
+         */
+        RegName reg(void) const { return is_reg() ? m_reg : RegName_Null; }
+        /**
+         * @brief Returns value of immediate operand (0 if not immediate).
+         */
+        long long imm(void) const { return is_imm() ? m_imm64 : 0; }
+    private:
+        bool is_placed_in(OpndKind kd) const
+        {
+                return kd == OpndKind_Reg ?
+                        m_kind == OpndKind_GPReg ||
+#ifdef _HAVE_MMX_
+                        m_kind == OpndKind_MMXReg ||
+#endif
+                        m_kind == OpndKind_FPReg ||
+                        m_kind == OpndKind_XMMReg
+                        : kd == m_kind;
+        }
+        void hash_it(void)
+        {
+            m_hash = get_size_hash(m_size) | get_kind_hash(m_kind);
+#ifdef _EM64T_
+            m_need_rex = false;
+            if (is_reg() && is_em64t_extra_reg(m_reg)) {
+                m_need_rex = true;
+            }
+            else if (is_mem() && (is_em64t_extra_reg(m_base) ||
+                                  is_em64t_extra_reg(m_index))) {
+                m_need_rex = true;
+            }
+#endif
+        }
+        // general info
+        OpndKind    m_kind;
+        OpndSize    m_size;
+        OpndExt     m_ext;
+        // complex address form support
+        RegName     m_base;
+        RegName     m_index;
+        unsigned    m_scale;
+        union {
+            int         m_disp;
+            RegName     m_reg;
+            long long   m_imm64;
+        };
+        unsigned    m_hash;
+        bool        m_need_rex;
+        friend class EncoderBase::Operands;
+    };
+    /**
+     * @brief Simple container for up to 3 Operand-s.
+     */
+    class Operands {
+    public:
+        Operands(void)
+        {
+            clear();
+        }
+        Operands(const Operand& op0)
+        {
+            clear();
+            add(op0);
+        }
+
+        Operands(const Operand& op0, const Operand& op1)
+        {
+            clear();
+            add(op0); add(op1);
+        }
+
+        Operands(const Operand& op0, const Operand& op1, const Operand& op2)
+        {
+            clear();
+            add(op0); add(op1); add(op2);
+        }
+
+        unsigned count(void) const { return m_count; }
+        unsigned hash(void) const { return m_hash; }
+        const Operand& operator[](unsigned idx) const
+        {
+            assert(idx<m_count);
+            return m_operands[idx];
+        }
+
+        void add(const Operand& op)
+        {
+            assert(m_count < COUNTOF(m_operands));
+            m_hash = (m_hash<<HASH_BITS_PER_OPERAND) | op.hash();
+            m_operands[m_count++] = op;
+            m_need_rex = m_need_rex || op.m_need_rex;
+        }
+#ifdef _EM64T_
+        bool need_rex(void) const { return m_need_rex; }
+#else
+        bool need_rex(void) const { return false; }
+#endif
+        void clear(void)
+        {
+            m_count = 0; m_hash = 0; m_need_rex = false;
+        }
+    private:
+        unsigned    m_count;
+        Operand     m_operands[COUNTOF( ((OpcodeDesc*)NULL)->opnds )];
+        unsigned    m_hash;
+        bool        m_need_rex;
+    };
+public:
+#ifdef _DEBUG
+    /**
+     * Verifies some presumptions about encoding data table.
+     * Called automaticaly during statics initialization.
+     */
+    static int verify(void);
+#endif
+
+private:
+    /**
+     * @brief Returns found OpcodeDesc by the given Mnemonic and operands.
+     */
+    static const OpcodeDesc * lookup(Mnemonic mn, const Operands& opnds);
+    /**
+     * @brief Encodes mod/rm byte.
+     */
+    static char* encodeModRM(char* stream, const Operands& opnds,
+                             unsigned idx, const OpcodeDesc * odesc, Rex * prex);
+    /**
+     * @brief Encodes special things of opcode description - '/r', 'ib', etc.
+     */
+    static char* encode_aux(char* stream, unsigned aux,
+                            const Operands& opnds, const OpcodeDesc * odesc,
+                            unsigned * pargsCount, Rex* prex);
+#ifdef _EM64T_
+    /**
+     * @brief Returns true if the 'reg' argument represents one of the new
+     *        EM64T registers - R8(D)-R15(D).
+     *
+     * The 64 bits versions of 'old-fashion' registers, i.e. RAX are not
+     * considered as 'extra'.
+     */
+    static bool is_em64t_extra_reg(const RegName reg)
+    {
+        if (needs_rex_r(reg)) {
+            return true;
+        }
+        if (RegName_SPL <= reg && reg <= RegName_R15L) {
+            return true;
+        }
+        return false;
+    }
+    static bool needs_rex_r(const RegName reg)
+    {
+        if (RegName_R8 <= reg && reg <= RegName_R15) {
+            return true;
+        }
+        if (RegName_R8D <= reg && reg <= RegName_R15D) {
+            return true;
+        }
+        if (RegName_R8S <= reg && reg <= RegName_R15S) {
+            return true;
+        }
+        if (RegName_R8L <= reg && reg <= RegName_R15L) {
+            return true;
+        }
+        if (RegName_XMM8 <= reg && reg <= RegName_XMM15) {
+            return true;
+        }
+        if (RegName_XMM8D <= reg && reg <= RegName_XMM15D) {
+            return true;
+        }
+        if (RegName_XMM8S <= reg && reg <= RegName_XMM15S) {
+            return true;
+        }
+        return false;
+    }
+    /**
+     * @brief Returns an 'processor's index' of the register - the index
+     *        used to encode the register in ModRM/SIB bytes.
+     *
+     * For the new EM64T registers the 'HW index' differs from the index
+     * encoded in RegName. For old-fashion registers it's effectively the
+     * same as ::getRegIndex(RegName).
+     */
+    static unsigned char getHWRegIndex(const RegName reg)
+    {
+        if (getRegKind(reg) != OpndKind_GPReg) {
+            return getRegIndex(reg);
+        }
+        if (RegName_SPL <= reg && reg<=RegName_DIL) {
+            return getRegIndex(reg);
+        }
+        if (RegName_R8L<= reg && reg<=RegName_R15L) {
+            return getRegIndex(reg) - getRegIndex(RegName_R8L);
+        }
+        return is_em64t_extra_reg(reg) ?
+                getRegIndex(reg)-getRegIndex(RegName_R8D) : getRegIndex(reg);
+    }
+#else
+    static unsigned char getHWRegIndex(const RegName reg)
+    {
+        return getRegIndex(reg);
+    }
+    static bool is_em64t_extra_reg(const RegName reg)
+    {
+        return false;
+    }
+#endif
+public:
+    static unsigned char get_size_hash(OpndSize size) {
+        return (size <= OpndSize_64) ? size_hash[size] : 0xFF;
+    }
+    static unsigned char get_kind_hash(OpndKind kind) {
+        return (kind <= OpndKind_Mem) ? kind_hash[kind] : 0xFF;
+    }
+
+    /**
+     * @brief A table used for the fast computation of hash value.
+     *
+     * A change must be strictly balanced with hash-related functions and data
+     * in enc_base.h/.cpp.
+     */
+    static const unsigned char size_hash[OpndSize_64+1];
+    /**
+     * @brief A table used for the fast computation of hash value.
+     *
+     * A change must be strictly balanced with hash-related functions and data
+     * in enc_base.h/.cpp.
+     */
+    static const unsigned char kind_hash[OpndKind_Mem+1];
+    /**
+     * @brief Maximum number of opcodes used for a single mnemonic.
+     *
+     * No arithmetics behind the number, simply estimated.
+     */
+    static const unsigned int   MAX_OPCODES = 32; //20;
+    /**
+     * @brief Mapping between operands hash code and operands.
+     */
+    static unsigned char    opcodesHashMap[Mnemonic_Count][HASH_MAX];
+    /**
+     * @brief Array of mnemonics.
+     */
+    static MnemonicDesc         mnemonics[Mnemonic_Count];
+    /**
+     * @brief Array of available opcodes.
+     */
+    static OpcodeDesc opcodes[Mnemonic_Count][MAX_OPCODES];
+
+    static int buildTable(void);
+    static void buildMnemonicDesc(const MnemonicInfo * minfo);
+    /**
+     * @brief Computes hash value for the given operands.
+     */
+    static unsigned short getHash(const OpcodeInfo* odesc);
+    /**
+     * @brief Dummy variable, for automatic invocation of buildTable() at
+     *        startup.
+     */
+    static int dummy;
+
+    static char * curRelOpnd[3];
+};
+
+ENCODER_NAMESPACE_END
+
+#endif // ifndef __ENC_BASE_H_INCLUDED__
diff --git a/vm/compiler/codegen/x86/libenc/enc_defs.h b/vm/compiler/codegen/x86/libenc/enc_defs.h
new file mode 100644
index 0000000..ac0bb3b
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/enc_defs.h
@@ -0,0 +1,786 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+#ifndef _ENCODER_DEFS_H_
+#define _ENCODER_DEFS_H_
+
+
+// Used to isolate experimental or being tuned encoder into a separate
+// namespace so it can coexist with a stable one in the same bundle.
+#ifdef ENCODER_ISOLATE
+    #define ENCODER_NAMESPACE_START namespace enc_ia32 {
+    #define ENCODER_NAMESPACE_END };
+#else
+    #define ENCODER_NAMESPACE_START
+    #define ENCODER_NAMESPACE_END
+#endif
+
+#include <assert.h>
+#include "enc_defs_ext.h"
+
+#ifndef COUNTOF
+    /**
+     * Number of items in an array.
+     */
+    #define COUNTOF(a)      (sizeof(a)/sizeof(a[0]))
+#endif
+
+#ifdef _EM64T_
+    /**
+     * A stack pointer of default platform's size.
+     */
+    #define REG_STACK       RegName_RSP
+    /**
+     * A max GP register (with a highest index number)
+     */
+    #define REG_MAX         RegName_R15
+    /**
+     * Total number of GP registers including stack pointer.
+     */
+    #define MAX_REGS        15
+#else
+    #define REG_STACK       RegName_ESP
+    #define REG_MAX         RegName_EDI
+    #define MAX_REGS        8
+#endif
+
+ENCODER_NAMESPACE_START
+
+/**
+ * A number of bytes 'eaten' by an ordinary PUSH/POP.
+ */
+#define STACK_SLOT_SIZE (sizeof(void*))
+
+
+/**
+ * A recommended by Intel Arch Manual aligment for instructions that
+ * are targets for jmps.
+ */
+#define JMP_TARGET_ALIGMENT     (16)
+/**
+ * A maximum possible size of native instruction.
+ */
+#define MAX_NATIVE_INST_SIZE (15)
+/**
+ * The enum OpndKind describes an operand's location - memory, immediate or a register.
+ * It can be used as a bit mask.
+ */
+typedef enum OpndKind {
+    /**
+     * A change must be balanced with at least the following places:
+     *              Ia32::Constraint-s use the OpndKind as a mask
+     *              encoder.cpp & encoder_master_info.cpp uses OpndKind as an index for hashing
+     *              - perhaps there are much more places
+     *
+     * NOTE: an MMXReg kind is incompatible with the current constraints framework,
+     *              as it's not encoded as a mask.
+     */
+    OpndKind_Null=0,
+    OpndKind_GPReg          = 0x01, OpndKind_MinRegKind = OpndKind_GPReg,
+    OpndKind_SReg           = 0x02,
+#ifdef _HAVE_MMX_
+    OpndKind_MMXReg         = 0x03,
+#endif
+    OpndKind_FPReg          = 0x04,
+    OpndKind_XMMReg         = 0x08,
+    OpndKind_OtherReg       = 0x10,
+    OpndKind_StatusReg      = OpndKind_OtherReg,
+    OpndKind_MaxRegKind     = OpndKind_StatusReg,   // a max existing kind of register
+    OpndKind_MaxReg,                                // -'- + 1 to be used in array defs
+    //
+    OpndKind_Immediate      = 0x20, OpndKind_Imm=OpndKind_Immediate,
+    OpndKind_Memory         = 0x40, OpndKind_Mem=OpndKind_Memory,
+    //
+    OpndKind_Reg            = 0x1F,
+    OpndKind_Any            = 0x7F,
+    // syntetic constants. Normally not used anywhere, but are used for
+    // human-readable showing under the debugger
+    OpndKind_GPReg_Mem      = OpndKind_GPReg|OpndKind_Mem,
+#ifdef _HAVE_MMX_
+    OpndKind_MMXReg_Mem     = OpndKind_MMXReg|OpndKind_Mem,
+#endif
+    OpndKind_XMMReg_Mem     = OpndKind_XMMReg|OpndKind_Mem,
+} OpndKind;
+
+/**
+ * Defines type of extention allowed for particular operand.
+ * For example imul r32,r_m32,imm8 sign extend imm8 before performing multiplication.
+ * To satisfy instruction constraints immediate operand should be either OpndExt_Signed
+ * or OpndExt_Any.
+ */
+typedef enum OpndExt {
+    OpndExt_None    = 0x0,
+    OpndExt_Signed  = 0x1,
+    OpndExt_Zero    = 0x2,
+    OpndExt_Any     = 0x3,
+}OpndExt;
+
+/**
+ * enum OpndRole defines the role of an operand in an instruction
+ * Can be used as mask to combine def and use. The complete def+use
+ * info can be combined in 2 bits which is used, say in Encoder::OpndRole.
+ */
+//TODO: this duplicates an Role used in the Ia32::Inst. That duplicate enum should be removed.
+typedef enum OpndRole {
+    OpndRole_Null=0,
+    OpndRole_Use=0x1,
+    OpndRole_Def=0x2,
+    OpndRole_UseDef=OpndRole_Use|OpndRole_Def,
+    OpndRole_All=0xffff,
+} OpndRole;
+
+
+#define REGNAME(k,s,i) ( ((k & OpndKind_Any)<<24) | ((s & OpndSize_Any)<<16) | (i&0xFF) )
+
+// Gregory -
+// It is critical that all register indexes (3rd number) inside of the
+// following table go in ascending order. That is R8 goes after
+// RDI. It is necessary for decoder when extending registers from RAX-RDI
+// to R8-R15 by simply adding 8 to the index on EM64T architecture
+typedef enum RegName {
+
+    RegName_Null = 0,
+
+#ifdef _EM64T_
+    /*
+    An index part of the RegName-s for RAX-RDI, EAX-ESI, AX-SI and AL-BH is
+    the same as the index used during instructions encoding. The same rule
+    applies for XMM regsters for IA32.
+    For new EM64T registers (both GP and XMM) the index need to be corrected to
+    obtain the index used in processor's instructions.
+    */
+    RegName_RAX = REGNAME(OpndKind_GPReg,OpndSize_64,0),
+    RegName_RCX = REGNAME(OpndKind_GPReg,OpndSize_64,1),
+    RegName_RDX = REGNAME(OpndKind_GPReg,OpndSize_64,2),
+    RegName_RBX = REGNAME(OpndKind_GPReg,OpndSize_64,3),
+    RegName_RSP = REGNAME(OpndKind_GPReg,OpndSize_64,4),
+    RegName_RBP = REGNAME(OpndKind_GPReg,OpndSize_64,5),
+    RegName_RSI = REGNAME(OpndKind_GPReg,OpndSize_64,6),
+    RegName_RDI = REGNAME(OpndKind_GPReg,OpndSize_64,7),
+
+    RegName_R8  = REGNAME(OpndKind_GPReg,OpndSize_64,8),
+    RegName_R9  = REGNAME(OpndKind_GPReg,OpndSize_64,9),
+    RegName_R10 = REGNAME(OpndKind_GPReg,OpndSize_64,10),
+    RegName_R11 = REGNAME(OpndKind_GPReg,OpndSize_64,11),
+    RegName_R12 = REGNAME(OpndKind_GPReg,OpndSize_64,12),
+    RegName_R13 = REGNAME(OpndKind_GPReg,OpndSize_64,13),
+    RegName_R14 = REGNAME(OpndKind_GPReg,OpndSize_64,14),
+    RegName_R15 = REGNAME(OpndKind_GPReg,OpndSize_64,15),
+#endif //~_EM64T_
+
+    RegName_EAX=REGNAME(OpndKind_GPReg,OpndSize_32,0),
+    RegName_ECX=REGNAME(OpndKind_GPReg,OpndSize_32,1),
+    RegName_EDX=REGNAME(OpndKind_GPReg,OpndSize_32,2),
+    RegName_EBX=REGNAME(OpndKind_GPReg,OpndSize_32,3),
+    RegName_ESP=REGNAME(OpndKind_GPReg,OpndSize_32,4),
+    RegName_EBP=REGNAME(OpndKind_GPReg,OpndSize_32,5),
+    RegName_ESI=REGNAME(OpndKind_GPReg,OpndSize_32,6),
+    RegName_EDI=REGNAME(OpndKind_GPReg,OpndSize_32,7),
+
+#ifdef _EM64T_
+    RegName_R8D  = REGNAME(OpndKind_GPReg,OpndSize_32,8),
+    RegName_R9D  = REGNAME(OpndKind_GPReg,OpndSize_32,9),
+    RegName_R10D = REGNAME(OpndKind_GPReg,OpndSize_32,10),
+    RegName_R11D = REGNAME(OpndKind_GPReg,OpndSize_32,11),
+    RegName_R12D = REGNAME(OpndKind_GPReg,OpndSize_32,12),
+    RegName_R13D = REGNAME(OpndKind_GPReg,OpndSize_32,13),
+    RegName_R14D = REGNAME(OpndKind_GPReg,OpndSize_32,14),
+    RegName_R15D = REGNAME(OpndKind_GPReg,OpndSize_32,15),
+#endif //~_EM64T_
+
+    RegName_AX=REGNAME(OpndKind_GPReg,OpndSize_16,0),
+    RegName_CX=REGNAME(OpndKind_GPReg,OpndSize_16,1),
+    RegName_DX=REGNAME(OpndKind_GPReg,OpndSize_16,2),
+    RegName_BX=REGNAME(OpndKind_GPReg,OpndSize_16,3),
+    RegName_SP=REGNAME(OpndKind_GPReg,OpndSize_16,4),
+    RegName_BP=REGNAME(OpndKind_GPReg,OpndSize_16,5),
+    RegName_SI=REGNAME(OpndKind_GPReg,OpndSize_16,6),
+    RegName_DI=REGNAME(OpndKind_GPReg,OpndSize_16,7),
+
+#ifdef _EM64T_
+    RegName_R8S  = REGNAME(OpndKind_GPReg,OpndSize_16,8),
+    RegName_R9S  = REGNAME(OpndKind_GPReg,OpndSize_16,9),
+    RegName_R10S = REGNAME(OpndKind_GPReg,OpndSize_16,10),
+    RegName_R11S = REGNAME(OpndKind_GPReg,OpndSize_16,11),
+    RegName_R12S = REGNAME(OpndKind_GPReg,OpndSize_16,12),
+    RegName_R13S = REGNAME(OpndKind_GPReg,OpndSize_16,13),
+    RegName_R14S = REGNAME(OpndKind_GPReg,OpndSize_16,14),
+    RegName_R15S = REGNAME(OpndKind_GPReg,OpndSize_16,15),
+#endif //~_EM64T_
+
+    RegName_AL=REGNAME(OpndKind_GPReg,OpndSize_8,0),
+    RegName_CL=REGNAME(OpndKind_GPReg,OpndSize_8,1),
+    RegName_DL=REGNAME(OpndKind_GPReg,OpndSize_8,2),
+    RegName_BL=REGNAME(OpndKind_GPReg,OpndSize_8,3),
+    // FIXME: Used in enc_tabl.cpp
+    // AH is not accessible on EM64T, instead encoded register is SPL, so decoded
+    // register will return incorrect enum
+    RegName_AH=REGNAME(OpndKind_GPReg,OpndSize_8,4),
+#if !defined(_EM64T_)
+    RegName_CH=REGNAME(OpndKind_GPReg,OpndSize_8,5),
+    RegName_DH=REGNAME(OpndKind_GPReg,OpndSize_8,6),
+    RegName_BH=REGNAME(OpndKind_GPReg,OpndSize_8,7),
+#else
+    RegName_SPL=REGNAME(OpndKind_GPReg,OpndSize_8,4),
+    RegName_BPL=REGNAME(OpndKind_GPReg,OpndSize_8,5),
+    RegName_SIL=REGNAME(OpndKind_GPReg,OpndSize_8,6),
+    RegName_DIL=REGNAME(OpndKind_GPReg,OpndSize_8,7),
+    RegName_R8L=REGNAME(OpndKind_GPReg,OpndSize_8,8),
+    RegName_R9L=REGNAME(OpndKind_GPReg,OpndSize_8,9),
+    RegName_R10L=REGNAME(OpndKind_GPReg,OpndSize_8,10),
+    RegName_R11L=REGNAME(OpndKind_GPReg,OpndSize_8,11),
+    RegName_R12L=REGNAME(OpndKind_GPReg,OpndSize_8,12),
+    RegName_R13L=REGNAME(OpndKind_GPReg,OpndSize_8,13),
+    RegName_R14L=REGNAME(OpndKind_GPReg,OpndSize_8,14),
+    RegName_R15L=REGNAME(OpndKind_GPReg,OpndSize_8,15),
+#endif
+
+    RegName_ES=REGNAME(OpndKind_SReg,OpndSize_16,0),
+    RegName_CS=REGNAME(OpndKind_SReg,OpndSize_16,1),
+    RegName_SS=REGNAME(OpndKind_SReg,OpndSize_16,2),
+    RegName_DS=REGNAME(OpndKind_SReg,OpndSize_16,3),
+    RegName_FS=REGNAME(OpndKind_SReg,OpndSize_16,4),
+    RegName_GS=REGNAME(OpndKind_SReg,OpndSize_16,5),
+
+    RegName_EFLAGS=REGNAME(OpndKind_StatusReg,OpndSize_32,0),
+
+#if !defined(TESTING_ENCODER)
+    RegName_FP0=REGNAME(OpndKind_FPReg,OpndSize_80,0),
+    RegName_FP1=REGNAME(OpndKind_FPReg,OpndSize_80,1),
+    RegName_FP2=REGNAME(OpndKind_FPReg,OpndSize_80,2),
+    RegName_FP3=REGNAME(OpndKind_FPReg,OpndSize_80,3),
+    RegName_FP4=REGNAME(OpndKind_FPReg,OpndSize_80,4),
+    RegName_FP5=REGNAME(OpndKind_FPReg,OpndSize_80,5),
+    RegName_FP6=REGNAME(OpndKind_FPReg,OpndSize_80,6),
+    RegName_FP7=REGNAME(OpndKind_FPReg,OpndSize_80,7),
+#endif
+    RegName_FP0S=REGNAME(OpndKind_FPReg,OpndSize_32,0),
+    RegName_FP1S=REGNAME(OpndKind_FPReg,OpndSize_32,1),
+    RegName_FP2S=REGNAME(OpndKind_FPReg,OpndSize_32,2),
+    RegName_FP3S=REGNAME(OpndKind_FPReg,OpndSize_32,3),
+    RegName_FP4S=REGNAME(OpndKind_FPReg,OpndSize_32,4),
+    RegName_FP5S=REGNAME(OpndKind_FPReg,OpndSize_32,5),
+    RegName_FP6S=REGNAME(OpndKind_FPReg,OpndSize_32,6),
+    RegName_FP7S=REGNAME(OpndKind_FPReg,OpndSize_32,7),
+
+    RegName_FP0D=REGNAME(OpndKind_FPReg,OpndSize_64,0),
+    RegName_FP1D=REGNAME(OpndKind_FPReg,OpndSize_64,1),
+    RegName_FP2D=REGNAME(OpndKind_FPReg,OpndSize_64,2),
+    RegName_FP3D=REGNAME(OpndKind_FPReg,OpndSize_64,3),
+    RegName_FP4D=REGNAME(OpndKind_FPReg,OpndSize_64,4),
+    RegName_FP5D=REGNAME(OpndKind_FPReg,OpndSize_64,5),
+    RegName_FP6D=REGNAME(OpndKind_FPReg,OpndSize_64,6),
+    RegName_FP7D=REGNAME(OpndKind_FPReg,OpndSize_64,7),
+
+#if !defined(TESTING_ENCODER)
+    RegName_XMM0=REGNAME(OpndKind_XMMReg,OpndSize_128,0),
+    RegName_XMM1=REGNAME(OpndKind_XMMReg,OpndSize_128,1),
+    RegName_XMM2=REGNAME(OpndKind_XMMReg,OpndSize_128,2),
+    RegName_XMM3=REGNAME(OpndKind_XMMReg,OpndSize_128,3),
+    RegName_XMM4=REGNAME(OpndKind_XMMReg,OpndSize_128,4),
+    RegName_XMM5=REGNAME(OpndKind_XMMReg,OpndSize_128,5),
+    RegName_XMM6=REGNAME(OpndKind_XMMReg,OpndSize_128,6),
+    RegName_XMM7=REGNAME(OpndKind_XMMReg,OpndSize_128,7),
+
+#ifdef _EM64T_
+    RegName_XMM8  = REGNAME(OpndKind_XMMReg,OpndSize_128,0),
+    RegName_XMM9  = REGNAME(OpndKind_XMMReg,OpndSize_128,1),
+    RegName_XMM10 = REGNAME(OpndKind_XMMReg,OpndSize_128,2),
+    RegName_XMM11 = REGNAME(OpndKind_XMMReg,OpndSize_128,3),
+    RegName_XMM12 = REGNAME(OpndKind_XMMReg,OpndSize_128,4),
+    RegName_XMM13 = REGNAME(OpndKind_XMMReg,OpndSize_128,5),
+    RegName_XMM14 = REGNAME(OpndKind_XMMReg,OpndSize_128,6),
+    RegName_XMM15 = REGNAME(OpndKind_XMMReg,OpndSize_128,7),
+#endif //~_EM64T_
+
+#endif  // ~TESTING_ENCODER
+
+    RegName_XMM0S=REGNAME(OpndKind_XMMReg,OpndSize_32,0),
+    RegName_XMM1S=REGNAME(OpndKind_XMMReg,OpndSize_32,1),
+    RegName_XMM2S=REGNAME(OpndKind_XMMReg,OpndSize_32,2),
+    RegName_XMM3S=REGNAME(OpndKind_XMMReg,OpndSize_32,3),
+    RegName_XMM4S=REGNAME(OpndKind_XMMReg,OpndSize_32,4),
+    RegName_XMM5S=REGNAME(OpndKind_XMMReg,OpndSize_32,5),
+    RegName_XMM6S=REGNAME(OpndKind_XMMReg,OpndSize_32,6),
+    RegName_XMM7S=REGNAME(OpndKind_XMMReg,OpndSize_32,7),
+#ifdef _EM64T_
+    RegName_XMM8S=REGNAME(OpndKind_XMMReg,OpndSize_32,8),
+    RegName_XMM9S=REGNAME(OpndKind_XMMReg,OpndSize_32,9),
+    RegName_XMM10S=REGNAME(OpndKind_XMMReg,OpndSize_32,10),
+    RegName_XMM11S=REGNAME(OpndKind_XMMReg,OpndSize_32,11),
+    RegName_XMM12S=REGNAME(OpndKind_XMMReg,OpndSize_32,12),
+    RegName_XMM13S=REGNAME(OpndKind_XMMReg,OpndSize_32,13),
+    RegName_XMM14S=REGNAME(OpndKind_XMMReg,OpndSize_32,14),
+    RegName_XMM15S=REGNAME(OpndKind_XMMReg,OpndSize_32,15),
+#endif // ifdef _EM64T_
+    RegName_XMM0D=REGNAME(OpndKind_XMMReg,OpndSize_64,0),
+    RegName_XMM1D=REGNAME(OpndKind_XMMReg,OpndSize_64,1),
+    RegName_XMM2D=REGNAME(OpndKind_XMMReg,OpndSize_64,2),
+    RegName_XMM3D=REGNAME(OpndKind_XMMReg,OpndSize_64,3),
+    RegName_XMM4D=REGNAME(OpndKind_XMMReg,OpndSize_64,4),
+    RegName_XMM5D=REGNAME(OpndKind_XMMReg,OpndSize_64,5),
+    RegName_XMM6D=REGNAME(OpndKind_XMMReg,OpndSize_64,6),
+    RegName_XMM7D=REGNAME(OpndKind_XMMReg,OpndSize_64,7),
+#ifdef _EM64T_
+    RegName_XMM8D=REGNAME(OpndKind_XMMReg,OpndSize_64,8),
+    RegName_XMM9D=REGNAME(OpndKind_XMMReg,OpndSize_64,9),
+    RegName_XMM10D=REGNAME(OpndKind_XMMReg,OpndSize_64,10),
+    RegName_XMM11D=REGNAME(OpndKind_XMMReg,OpndSize_64,11),
+    RegName_XMM12D=REGNAME(OpndKind_XMMReg,OpndSize_64,12),
+    RegName_XMM13D=REGNAME(OpndKind_XMMReg,OpndSize_64,13),
+    RegName_XMM14D=REGNAME(OpndKind_XMMReg,OpndSize_64,14),
+    RegName_XMM15D=REGNAME(OpndKind_XMMReg,OpndSize_64,15),
+#endif // ifdef _EM64T_
+#ifdef _HAVE_MMX_
+    RegName_MMX0=REGNAME(OpndKind_MMXReg,OpndSize_64,0),
+    RegName_MMX1=REGNAME(OpndKind_MMXReg,OpndSize_64,1),
+    RegName_MMX2=REGNAME(OpndKind_MMXReg,OpndSize_64,2),
+    RegName_MMX3=REGNAME(OpndKind_MMXReg,OpndSize_64,3),
+    RegName_MMX4=REGNAME(OpndKind_MMXReg,OpndSize_64,4),
+    RegName_MMX5=REGNAME(OpndKind_MMXReg,OpndSize_64,5),
+    RegName_MMX6=REGNAME(OpndKind_MMXReg,OpndSize_64,6),
+    RegName_MMX7=REGNAME(OpndKind_MMXReg,OpndSize_64,7),
+#endif  // _HAVE_MMX_
+} RegName;
+
+#if 0   // Android x86: use mnemonics defined in enc_defs_ext.h
+/**
+ * Conditional mnemonics.
+ * The values match the 'real' (==processor's) values of the appropriate
+ * condition values used in the opcodes.
+ */
+enum ConditionMnemonic {
+
+    ConditionMnemonic_O=0,
+    ConditionMnemonic_NO=1,
+    ConditionMnemonic_B=2, ConditionMnemonic_NAE=ConditionMnemonic_B, ConditionMnemonic_C=ConditionMnemonic_B,
+    ConditionMnemonic_NB=3, ConditionMnemonic_AE=ConditionMnemonic_NB, ConditionMnemonic_NC=ConditionMnemonic_NB,
+    ConditionMnemonic_Z=4, ConditionMnemonic_E=ConditionMnemonic_Z,
+    ConditionMnemonic_NZ=5, ConditionMnemonic_NE=ConditionMnemonic_NZ,
+    ConditionMnemonic_BE=6, ConditionMnemonic_NA=ConditionMnemonic_BE,
+    ConditionMnemonic_NBE=7, ConditionMnemonic_A=ConditionMnemonic_NBE,
+
+    ConditionMnemonic_S=8,
+    ConditionMnemonic_NS=9,
+    ConditionMnemonic_P=10, ConditionMnemonic_PE=ConditionMnemonic_P,
+    ConditionMnemonic_NP=11, ConditionMnemonic_PO=ConditionMnemonic_NP,
+    ConditionMnemonic_L=12, ConditionMnemonic_NGE=ConditionMnemonic_L,
+    ConditionMnemonic_NL=13, ConditionMnemonic_GE=ConditionMnemonic_NL,
+    ConditionMnemonic_LE=14, ConditionMnemonic_NG=ConditionMnemonic_LE,
+    ConditionMnemonic_NLE=15, ConditionMnemonic_G=ConditionMnemonic_NLE,
+    ConditionMnemonic_Count=16
+};
+
+
+#define CCM(prefix,cond) Mnemonic_##prefix##cond=Mnemonic_##prefix##cc+ConditionMnemonic_##cond
+
+//=========================================================================================================
+enum Mnemonic {
+
+Mnemonic_NULL=0, Mnemonic_Null=Mnemonic_NULL,
+Mnemonic_ADC,                           // Add with Carry
+Mnemonic_ADD,                           // Add
+Mnemonic_ADDSD,                         // Add Scalar Double-Precision Floating-Point Values
+Mnemonic_ADDSS,                         // Add Scalar Single-Precision Floating-Point Values
+Mnemonic_AND,                           // Logical AND
+
+Mnemonic_BSF,                           // Bit scan forward
+Mnemonic_BSR,                           // Bit scan reverse
+
+Mnemonic_CALL,                          // Call Procedure
+Mnemonic_CMC,                           // Complement Carry Flag
+Mnemonic_CWD, Mnemonic_CDQ=Mnemonic_CWD,// Convert Word to Doubleword/Convert Doubleword to Qua T dword
+Mnemonic_CMOVcc,                        // Conditional Move
+    CCM(CMOV,O),
+    CCM(CMOV,NO),
+    CCM(CMOV,B), CCM(CMOV,NAE), CCM(CMOV,C),
+    CCM(CMOV,NB), CCM(CMOV,AE), CCM(CMOV,NC),
+    CCM(CMOV,Z), CCM(CMOV,E),
+    CCM(CMOV,NZ), CCM(CMOV,NE),
+    CCM(CMOV,BE), CCM(CMOV,NA),
+    CCM(CMOV,NBE), CCM(CMOV,A),
+
+    CCM(CMOV,S),
+    CCM(CMOV,NS),
+    CCM(CMOV,P), CCM(CMOV,PE),
+    CCM(CMOV,NP), CCM(CMOV,PO),
+    CCM(CMOV,L), CCM(CMOV,NGE),
+    CCM(CMOV,NL), CCM(CMOV,GE),
+    CCM(CMOV,LE), CCM(CMOV,NG),
+    CCM(CMOV,NLE), CCM(CMOV,G),
+
+Mnemonic_CMP,                           // Compare Two Operands
+Mnemonic_CMPXCHG,                       // Compare and exchange
+Mnemonic_CMPXCHG8B,                     // Compare and Exchange 8 Bytes
+Mnemonic_CMPSB,                         // Compare Two Bytes at DS:ESI and ES:EDI
+Mnemonic_CMPSW,                         // Compare Two Words at DS:ESI and ES:EDI
+Mnemonic_CMPSD,                         // Compare Two Doublewords at DS:ESI and ES:EDI
+//
+// double -> float
+Mnemonic_CVTSD2SS,                      // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value
+// double -> I_32
+Mnemonic_CVTSD2SI,                      // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer
+// double [truncated] -> I_32
+Mnemonic_CVTTSD2SI,                     // Convert with Truncation Scalar Double-Precision Floating-Point Value to Signed Doubleword Integer
+//
+// float -> double
+Mnemonic_CVTSS2SD,                      // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value
+// float -> I_32
+Mnemonic_CVTSS2SI,                      // Convert Scalar Single-Precision Floating-Point Value to Doubleword Integer
+// float [truncated] -> I_32
+Mnemonic_CVTTSS2SI,                     // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer
+//
+// I_32 -> double
+Mnemonic_CVTSI2SD,                      // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value
+// I_32 -> float
+Mnemonic_CVTSI2SS,                      // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value
+
+Mnemonic_COMISD,                        // Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
+Mnemonic_COMISS,                        // Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS
+Mnemonic_DEC,                           // Decrement by 1
+//Mnemonic_DIV,                         // Unsigned Divide
+Mnemonic_DIVSD,                         // Divide Scalar Double-Precision Floating-Point Values
+Mnemonic_DIVSS,                         // Divide Scalar Single-Precision Floating-Point Values
+
+#ifdef _HAVE_MMX_
+Mnemonic_EMMS,                          // Empty MMX Technology State
+#endif
+
+Mnemonic_ENTER,                         // ENTER-Make Stack Frame for Procedure Parameters
+Mnemonic_FLDCW,                         // Load FPU control word
+Mnemonic_FADDP,
+Mnemonic_FLDZ,
+Mnemonic_FADD,
+Mnemonic_FSUBP,
+Mnemonic_FSUB,
+Mnemonic_FISUB,
+Mnemonic_FMUL,
+Mnemonic_FMULP,
+Mnemonic_FDIVP,
+Mnemonic_FDIV,
+Mnemonic_FUCOMPP,
+Mnemonic_FRNDINT,
+Mnemonic_FNSTCW,                        // Store FPU control word
+Mnemonic_FSTSW,                         // Store FPU status word
+Mnemonic_FNSTSW,                         // Store FPU status word
+//Mnemonic_FDECSTP,                     // Decrement Stack-Top Pointer
+Mnemonic_FILD,                          // Load Integer
+Mnemonic_FLD,                           // Load Floating Point Value
+Mnemonic_FLDLG2,
+Mnemonic_FLDLN2,
+Mnemonic_FLD1,
+
+Mnemonic_FCLEX,                         // Clear Exceptions
+Mnemonic_FCHS,                          // Change sign of ST0
+Mnemonic_FNCLEX,                        // Clear Exceptions
+
+//Mnemonic_FINCSTP,                     // Increment Stack-Top Pointer
+Mnemonic_FIST,                          // Store Integer
+Mnemonic_FISTP,                         // Store Integer, pop FPU stack
+Mnemonic_FISTTP,                        // Store Integer with Truncation
+Mnemonic_FPREM,                         // Partial Remainder
+Mnemonic_FPREM1,                        // Partial Remainder
+Mnemonic_FST,                           // Store Floating Point Value
+Mnemonic_FSTP,                          // Store Floating Point Value and pop the FP stack
+Mnemonic_FSQRT,                         //Computes the square root of the source value in the stack and pop the FP stack
+Mnemonic_FABS,                          //Computes the absolute value of the source value in the stack and pop the FP stack
+Mnemonic_FSIN,                          //Computes the sine of the source value in the stack and pop the FP stack
+Mnemonic_FCOS,                          //Computes the cosine of the source value in the stack and pop the FP stack
+Mnemonic_FPTAN,                         //Computes the tangent of the source value in the stack and pop the FP stack
+Mnemonic_FYL2X,
+Mnemonic_FYL2XP1,
+Mnemonic_F2XM1,
+Mnemonic_FPATAN,
+Mnemonic_FXCH,
+Mnemonic_FSCALE,
+
+Mnemonic_XCHG,
+Mnemonic_DIV,                           // Unsigned Divide
+Mnemonic_IDIV,                          // Signed Divide
+Mnemonic_MUL,                           // Unsigned Multiply
+Mnemonic_IMUL,                          // Signed Multiply
+Mnemonic_INC,                           // Increment by 1
+Mnemonic_INT3,                          // Call break point
+Mnemonic_Jcc,                           // Jump if Condition Is Met
+    CCM(J,O),
+    CCM(J,NO),
+    CCM(J,B), CCM(J,NAE), CCM(J,C),
+    CCM(J,NB), CCM(J,AE), CCM(J,NC),
+    CCM(J,Z), CCM(J,E),
+    CCM(J,NZ), CCM(J,NE),
+    CCM(J,BE), CCM(J,NA),
+    CCM(J,NBE), CCM(J,A),
+    CCM(J,S),
+    CCM(J,NS),
+    CCM(J,P), CCM(J,PE),
+    CCM(J,NP), CCM(J,PO),
+    CCM(J,L), CCM(J,NGE),
+    CCM(J,NL), CCM(J,GE),
+    CCM(J,LE), CCM(J,NG),
+    CCM(J,NLE), CCM(J,G),
+Mnemonic_JMP,                           // Jump
+Mnemonic_LEA,                           // Load Effective Address
+Mnemonic_LEAVE,                         // High Level Procedure Exit
+Mnemonic_LOOP,                          // Loop according to ECX counter
+Mnemonic_LOOPE,                          // Loop according to ECX counter
+Mnemonic_LOOPNE, Mnemonic_LOOPNZ = Mnemonic_LOOPNE, // Loop according to ECX
+Mnemonic_LAHF,                          // Load Flags into AH
+Mnemonic_MOV,                           // Move
+Mnemonic_MOVD,                          // Move Double word
+Mnemonic_MOVQ,                          // Move Quadword
+/*Mnemonic_MOVS,                        // Move Data from String to String*/
+// MOVS is a special case: see encoding table for more details,
+Mnemonic_MOVS8, Mnemonic_MOVS16, Mnemonic_MOVS32, Mnemonic_MOVS64,
+//
+Mnemonic_MOVAPD,                         // Move Scalar Double-Precision Floating-Point Value
+Mnemonic_MOVSD,                         // Move Scalar Double-Precision Floating-Point Value
+Mnemonic_MOVSS,                         // Move Scalar Single-Precision Floating-Point Values
+Mnemonic_MOVSX,                         // Move with Sign-Extension
+Mnemonic_MOVZX,                         // Move with Zero-Extend
+//Mnemonic_MUL,                         // Unsigned Multiply
+Mnemonic_MULSD,                         // Multiply Scalar Double-Precision Floating-Point Values
+Mnemonic_MULSS,                         // Multiply Scalar Single-Precision Floating-Point Values
+Mnemonic_NEG,                           // Two's Complement Negation
+Mnemonic_NOP,                           // No Operation
+Mnemonic_NOT,                           // One's Complement Negation
+Mnemonic_OR,                            // Logical Inclusive OR
+Mnemonic_PREFETCH,                      // prefetch
+
+#ifdef _HAVE_MMX_
+    Mnemonic_PADDQ,                     // Add Packed Quadword Integers
+    Mnemonic_PAND,                      // Logical AND
+    Mnemonic_POR,                       // Bitwise Logical OR
+    Mnemonic_PSUBQ,                     // Subtract Packed Quadword Integers
+#endif
+
+Mnemonic_PXOR,                          // Logical Exclusive OR
+Mnemonic_POP,                           // Pop a Value from the Stack
+Mnemonic_POPFD,                         // Pop a Value of EFLAGS register from the Stack
+Mnemonic_PUSH,                          // Push Word or Doubleword Onto the Stack
+Mnemonic_PUSHFD,                        // Push EFLAGS Doubleword Onto the Stack
+Mnemonic_RET,                           // Return from Procedure
+
+Mnemonic_SETcc,                         // Set Byte on Condition
+    CCM(SET,O),
+    CCM(SET,NO),
+    CCM(SET,B), CCM(SET,NAE), CCM(SET,C),
+    CCM(SET,NB), CCM(SET,AE), CCM(SET,NC),
+    CCM(SET,Z), CCM(SET,E),
+    CCM(SET,NZ), CCM(SET,NE),
+    CCM(SET,BE), CCM(SET,NA),
+    CCM(SET,NBE), CCM(SET,A),
+    CCM(SET,S),
+    CCM(SET,NS),
+    CCM(SET,P), CCM(SET,PE),
+    CCM(SET,NP), CCM(SET,PO),
+    CCM(SET,L), CCM(SET,NGE),
+    CCM(SET,NL), CCM(SET,GE),
+    CCM(SET,LE), CCM(SET,NG),
+    CCM(SET,NLE), CCM(SET,G),
+
+Mnemonic_SAL, Mnemonic_SHL=Mnemonic_SAL,// Shift left
+Mnemonic_SAR,                           // Shift right
+Mnemonic_ROR,                           // Rotate right
+Mnemonic_RCR,                           // Rotate right through CARRY flag
+Mnemonic_ROL,                           // Rotate left
+Mnemonic_RCL,                           // Rotate left through CARRY flag
+Mnemonic_SHR,                           // Unsigned shift right
+Mnemonic_SHRD,                          // Double Precision Shift Right
+Mnemonic_SHLD,                          // Double Precision Shift Left
+
+Mnemonic_SBB,                           // Integer Subtraction with Borrow
+Mnemonic_SUB,                           // Subtract
+Mnemonic_SUBSD,                         // Subtract Scalar Double-Precision Floating-Point Values
+Mnemonic_SUBSS,                         // Subtract Scalar Single-Precision Floating-Point Values
+
+Mnemonic_TEST,                          // Logical Compare
+
+Mnemonic_UCOMISD,                       // Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS
+Mnemonic_UCOMISS,                       // Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS
+
+Mnemonic_XOR,                           // Logical Exclusive OR
+//
+// packed things,
+//
+Mnemonic_XORPD,                         // Bitwise Logical XOR for Double-Precision Floating-Point Values
+Mnemonic_XORPS,                         // Bitwise Logical XOR for Single-Precision Floating-Point Values
+
+Mnemonic_CVTDQ2PD,                      // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values
+Mnemonic_CVTTPD2DQ,                     // Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
+
+Mnemonic_CVTDQ2PS,                      // Convert Packed Doubleword Integers to Packed Single-Precision Floating-Point Values
+Mnemonic_CVTTPS2DQ,                     // Convert with Truncation Packed Single-Precision Floating-Point Values to Packed Doubleword Integers
+//
+// String operations
+//
+Mnemonic_STD,                           // Set direction flag
+Mnemonic_CLD,                           // Clear direction flag
+Mnemonic_SCAS,                          // Scan string
+Mnemonic_STOS,                          // Store string
+
+//
+Mnemonic_WAIT,                          // Check pending pending unmasked floating-point exception
+//
+Mnemonic_Count
+};
+
+#undef CCM
+#endif
+
+/**
+ * @brief Instruction prefixes, according to arch manual.
+ */
+typedef enum InstPrefix {
+    InstPrefix_Null = 0,
+    // Group 1
+    InstPrefix_LOCK = 0xF0,
+    InstPrefix_REPNE = 0xF2,
+    InstPrefix_REPNZ = InstPrefix_REPNE,
+    InstPrefix_REP = 0xF3, InstPrefix_REPZ = InstPrefix_REP,
+    // Group 2
+    InstPrefix_CS = 0x2E,
+    InstPrefix_SS = 0x36,
+    InstPrefix_DS = 0x3E,
+    InstPrefix_ES = 0x26,
+    InstPrefix_FS = 0x64,
+    InstPrefix_GS = 0x65,
+    //
+    InstPrefix_HintTaken = 0x3E,
+    InstPrefix_HintNotTaken = 0x2E,
+    // Group 3
+    InstPrefix_OpndSize = 0x66,
+    // Group 4
+    InstPrefix_AddrSize = 0x67
+} InstPrefix;
+
+inline unsigned getSizeBytes(OpndSize sz)
+{
+    if (sz==OpndSize_64) { return 8; }
+    if (sz==OpndSize_32) { return 4; }
+    if (sz==OpndSize_16) { return 2; }
+    if (sz==OpndSize_8)  { return 1; }
+    assert(false);
+    return 0;
+}
+
+inline bool isRegKind(OpndKind kind)
+{
+    return OpndKind_GPReg<= kind && kind<=OpndKind_MaxRegKind;
+}
+
+/**
+ * @brief Returns #RegName for a given name.
+ *
+ * Name is case-insensitive.
+ * @param regname - string name of a register
+ * @return #RegName for the given name, or #RegName_Null if name is invalid
+ */
+RegName         getRegName(const char * regname);
+/**
+ * Constructs RegName from the given OpndKind, size and index.
+ */
+inline RegName  getRegName(OpndKind k, OpndSize s, int idx)
+{
+    return (RegName)REGNAME(k,s,idx);
+}
+/**
+ * Extracts a bit mask with a bit set at the position of the register's index.
+ */
+inline unsigned getRegMask(RegName reg)
+{
+    return 1<<(reg&0xff);
+}
+/**
+ * @brief Extracts #RegKind from the #RegName.
+ */
+inline OpndKind getRegKind(RegName reg)
+{
+    return (OpndKind)(reg>>24);
+}
+/**
+ * @brief Extracts #OpndSize from #RegName.
+ */
+inline OpndSize getRegSize(RegName reg)
+{
+    return (OpndSize)((reg>>16)&0xFF);
+}
+/**
+ * Extracts an index from the given RegName.
+ */
+inline unsigned char getRegIndex(RegName reg)
+{
+    return (unsigned char)(reg&0xFF);
+}
+/**
+ * Returns a string name of the given RegName. The name returned is in upper-case.
+ * Returns NULL if invalid RegName specified.
+ */
+const char *    getRegNameString(RegName reg);
+/**
+ * Returns string name of a given OpndSize.
+ * Returns NULL if invalid OpndSize passed.
+ */
+const char *    getOpndSizeString(OpndSize size);
+/**
+ * Returns OpndSize passed by its string representation (case insensitive).
+ * Returns OpndSize_Null if invalid string specified.
+ * The 'sizeString' can not be NULL.
+ */
+OpndSize        getOpndSize(const char * sizeString);
+/**
+ * Returns string name of a given OpndKind.
+ * Returns NULL if the passed kind is invalid.
+ */
+const char *    getOpndKindString(OpndKind kind);
+/**
+ * Returns OpndKind found by its string representation (case insensitive).
+ * Returns OpndKind_Null if the name is invalid.
+ * The 'kindString' can not be NULL.
+ */
+OpndKind        getOpndKind(const char * kindString);
+/**
+ *
+ */
+const char *    getConditionString(ConditionMnemonic cm);
+
+/**
+ * Constructs an RegName with the same index and kind, but with a different size from
+ * the given RegName (i.e. getRegAlias(EAX, OpndSize_16) => AX; getRegAlias(BL, OpndSize_32) => EBX).
+ * The constructed RegName is not checked in any way and thus may be invalid.
+ * Note, that the aliasing does not work for at least AH,BH,CH,DH, ESI, EDI, ESP and EBP regs.
+ */
+inline RegName getAliasReg(RegName reg, OpndSize sz)
+{
+    return (RegName)REGNAME(getRegKind(reg), sz, getRegIndex(reg));
+}
+
+/**
+ * brief Tests two RegName-s of the same kind for equality.
+ *
+ * @note Does work for 8 bit general purpose registers (AH, AL, BH, BL, etc).
+ */
+inline bool equals(RegName r0, RegName r1)
+{
+    return getRegKind(r0) == getRegKind(r1) &&
+           getRegIndex(r0) == getRegIndex(r1);
+}
+
+ENCODER_NAMESPACE_END
+
+#endif  // ifndef _ENCODER_DEFS_H_
diff --git a/vm/compiler/codegen/x86/libenc/enc_defs_ext.h b/vm/compiler/codegen/x86/libenc/enc_defs_ext.h
new file mode 100644
index 0000000..3592513
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/enc_defs_ext.h
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ENCODER_DEFS_EXT_H_
+#define _ENCODER_DEFS_EXT_H_
+
+
+// Used to isolate experimental or being tuned encoder into a separate
+// namespace so it can coexist with a stable one in the same bundle.
+#ifdef ENCODER_ISOLATE
+    #define ENCODER_NAMESPACE_START namespace enc_ia32 {
+    #define ENCODER_NAMESPACE_END };
+#else
+    #define ENCODER_NAMESPACE_START
+    #define ENCODER_NAMESPACE_END
+#endif
+
+ENCODER_NAMESPACE_START
+typedef enum OpndSize {
+    /**
+     * A change must be balanced with at least the following places:
+     *              Ia32IRConstants.h :: getByteSize() uses some presumptions about OpndSize_ values
+     *              Ia32::Constraint-s use the OpndSize as a mask
+     *              encoder.cpp & encoder_master_info.cpp uses OpndSize as an index for hashing
+     *              - perhaps there are much more places
+     */
+    OpndSize_Null           = 0,
+    OpndSize_8             = 0x01,
+    OpndSize_16            = 0x02,
+    OpndSize_32            = 0x04,
+    OpndSize_64            = 0x08,
+#if !defined(TESTING_ENCODER)
+    OpndSize_80            = 0x10,
+    OpndSize_128           = 0x20,
+#endif
+    OpndSize_Max,
+    OpndSize_Any            = 0x3F,
+    OpndSize_Default        = OpndSize_Any
+} OpndSize;
+
+/**
+ * Conditional mnemonics.
+ * The values match the 'real' (==processor's) values of the appropriate
+ * condition values used in the opcodes.
+ */
+typedef enum ConditionMnemonic {
+
+    ConditionMnemonic_O=0,
+    ConditionMnemonic_NO=1,
+    ConditionMnemonic_B=2, ConditionMnemonic_NAE=ConditionMnemonic_B, ConditionMnemonic_C=ConditionMnemonic_B,
+    ConditionMnemonic_NB=3, ConditionMnemonic_AE=ConditionMnemonic_NB, ConditionMnemonic_NC=ConditionMnemonic_NB,
+    ConditionMnemonic_Z=4, ConditionMnemonic_E=ConditionMnemonic_Z,
+    ConditionMnemonic_NZ=5, ConditionMnemonic_NE=ConditionMnemonic_NZ,
+    ConditionMnemonic_BE=6, ConditionMnemonic_NA=ConditionMnemonic_BE,
+    ConditionMnemonic_NBE=7, ConditionMnemonic_A=ConditionMnemonic_NBE,
+
+    ConditionMnemonic_S=8,
+    ConditionMnemonic_NS=9,
+    ConditionMnemonic_P=10, ConditionMnemonic_PE=ConditionMnemonic_P,
+    ConditionMnemonic_NP=11, ConditionMnemonic_PO=ConditionMnemonic_NP,
+    ConditionMnemonic_L=12, ConditionMnemonic_NGE=ConditionMnemonic_L,
+    ConditionMnemonic_NL=13, ConditionMnemonic_GE=ConditionMnemonic_NL,
+    ConditionMnemonic_LE=14, ConditionMnemonic_NG=ConditionMnemonic_LE,
+    ConditionMnemonic_NLE=15, ConditionMnemonic_G=ConditionMnemonic_NLE,
+    ConditionMnemonic_Count=16
+} ConditionMnemonic;
+
+
+#define CCM(prefix,cond) Mnemonic_##prefix##cond=Mnemonic_##prefix##cc+ConditionMnemonic_##cond
+
+//=========================================================================================================
+typedef enum Mnemonic {
+
+Mnemonic_NULL=0, Mnemonic_Null=Mnemonic_NULL,
+Mnemonic_ADC,                           // Add with Carry
+Mnemonic_ADD,                           // Add
+Mnemonic_ADDSD,                         // Add Scalar Double-Precision Floating-Point Values
+Mnemonic_ADDSS,                         // Add Scalar Single-Precision Floating-Point Values
+Mnemonic_AND,                           // Logical AND
+
+Mnemonic_BSF,                           // Bit scan forward
+Mnemonic_BSR,                           // Bit scan reverse
+
+Mnemonic_CALL,                          // Call Procedure
+Mnemonic_CMC,                           // Complement Carry Flag
+Mnemonic_CWD, Mnemonic_CDQ=Mnemonic_CWD,// Convert Word to Doubleword/Convert Doubleword to Qua T dword
+Mnemonic_CMOVcc,                        // Conditional Move
+    CCM(CMOV,O),
+    CCM(CMOV,NO),
+    CCM(CMOV,B), CCM(CMOV,NAE), CCM(CMOV,C),
+    CCM(CMOV,NB), CCM(CMOV,AE), CCM(CMOV,NC),
+    CCM(CMOV,Z), CCM(CMOV,E),
+    CCM(CMOV,NZ), CCM(CMOV,NE),
+    CCM(CMOV,BE), CCM(CMOV,NA),
+    CCM(CMOV,NBE), CCM(CMOV,A),
+
+    CCM(CMOV,S),
+    CCM(CMOV,NS),
+    CCM(CMOV,P), CCM(CMOV,PE),
+    CCM(CMOV,NP), CCM(CMOV,PO),
+    CCM(CMOV,L), CCM(CMOV,NGE),
+    CCM(CMOV,NL), CCM(CMOV,GE),
+    CCM(CMOV,LE), CCM(CMOV,NG),
+    CCM(CMOV,NLE), CCM(CMOV,G),
+
+Mnemonic_CMP,                           // Compare Two Operands
+Mnemonic_CMPXCHG,                       // Compare and exchange
+Mnemonic_CMPXCHG8B,                     // Compare and Exchange 8 Bytes
+Mnemonic_CMPSB,                         // Compare Two Bytes at DS:ESI and ES:EDI
+Mnemonic_CMPSW,                         // Compare Two Words at DS:ESI and ES:EDI
+Mnemonic_CMPSD,                         // Compare Two Doublewords at DS:ESI and ES:EDI
+//
+// double -> float
+Mnemonic_CVTSD2SS,                      // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value
+// double -> I_32
+Mnemonic_CVTSD2SI,                      // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer
+// double [truncated] -> I_32
+Mnemonic_CVTTSD2SI,                     // Convert with Truncation Scalar Double-Precision Floating-Point Value to Signed Doubleword Integer
+//
+// float -> double
+Mnemonic_CVTSS2SD,                      // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value
+// float -> I_32
+Mnemonic_CVTSS2SI,                      // Convert Scalar Single-Precision Floating-Point Value to Doubleword Integer
+// float [truncated] -> I_32
+Mnemonic_CVTTSS2SI,                     // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer
+//
+// I_32 -> double
+Mnemonic_CVTSI2SD,                      // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value
+// I_32 -> float
+Mnemonic_CVTSI2SS,                      // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value
+
+Mnemonic_COMISD,                        // Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
+Mnemonic_COMISS,                        // Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS
+Mnemonic_DEC,                           // Decrement by 1
+//Mnemonic_DIV,                         // Unsigned Divide
+Mnemonic_DIVSD,                         // Divide Scalar Double-Precision Floating-Point Values
+Mnemonic_DIVSS,                         // Divide Scalar Single-Precision Floating-Point Values
+
+#ifdef _HAVE_MMX_
+Mnemonic_EMMS,                          // Empty MMX Technology State
+#endif
+
+Mnemonic_ENTER,                         // ENTER-Make Stack Frame for Procedure Parameters
+Mnemonic_FLDCW,                         // Load FPU control word
+Mnemonic_FADDP,
+Mnemonic_FLDZ,
+Mnemonic_FADD,
+Mnemonic_FSUBP,
+Mnemonic_FSUB,
+Mnemonic_FISUB,
+Mnemonic_FMUL,
+Mnemonic_FMULP,
+Mnemonic_FDIVP,
+Mnemonic_FDIV,
+Mnemonic_FUCOM,
+Mnemonic_FUCOMI,
+Mnemonic_FUCOMP,
+Mnemonic_FUCOMIP,
+Mnemonic_FUCOMPP,
+Mnemonic_FRNDINT,
+Mnemonic_FNSTCW,                        // Store FPU control word
+Mnemonic_FSTSW,                         // Store FPU status word
+Mnemonic_FNSTSW,                         // Store FPU status word
+//Mnemonic_FDECSTP,                     // Decrement Stack-Top Pointer
+Mnemonic_FILD,                          // Load Integer
+Mnemonic_FLD,                           // Load Floating Point Value
+Mnemonic_FLDLG2,
+Mnemonic_FLDLN2,
+Mnemonic_FLD1,
+
+Mnemonic_FCLEX,                         // Clear Exceptions
+Mnemonic_FCHS,                          // Change sign of ST0
+Mnemonic_FNCLEX,                        // Clear Exceptions
+
+//Mnemonic_FINCSTP,                     // Increment Stack-Top Pointer
+Mnemonic_FIST,                          // Store Integer
+Mnemonic_FISTP,                         // Store Integer, pop FPU stack
+Mnemonic_FISTTP,                        // Store Integer with Truncation
+Mnemonic_FPREM,                         // Partial Remainder
+Mnemonic_FPREM1,                        // Partial Remainder
+Mnemonic_FST,                           // Store Floating Point Value
+Mnemonic_FSTP,                          // Store Floating Point Value and pop the FP stack
+Mnemonic_FSQRT,                         //Computes the square root of the source value in the stack and pop the FP stack
+Mnemonic_FABS,                          //Computes the absolute value of the source value in the stack and pop the FP stack
+Mnemonic_FSIN,                          //Computes the sine of the source value in the stack and pop the FP stack
+Mnemonic_FCOS,                          //Computes the cosine of the source value in the stack and pop the FP stack
+Mnemonic_FPTAN,                         //Computes the tangent of the source value in the stack and pop the FP stack
+Mnemonic_FYL2X,
+Mnemonic_FYL2XP1,
+Mnemonic_F2XM1,
+Mnemonic_FPATAN,
+Mnemonic_FXCH,
+Mnemonic_FSCALE,
+
+Mnemonic_XCHG,
+Mnemonic_DIV,                           // Unsigned Divide
+Mnemonic_IDIV,                          // Signed Divide
+Mnemonic_MUL,                           // Unsigned Multiply
+Mnemonic_IMUL,                          // Signed Multiply
+Mnemonic_INC,                           // Increment by 1
+Mnemonic_INT3,                          // Call break point
+Mnemonic_Jcc,                           // Jump if Condition Is Met
+    CCM(J,O),
+    CCM(J,NO),
+    CCM(J,B), CCM(J,NAE), CCM(J,C),
+    CCM(J,NB), CCM(J,AE), CCM(J,NC),
+    CCM(J,Z), CCM(J,E),
+    CCM(J,NZ), CCM(J,NE),
+    CCM(J,BE), CCM(J,NA),
+    CCM(J,NBE), CCM(J,A),
+    CCM(J,S),
+    CCM(J,NS),
+    CCM(J,P), CCM(J,PE),
+    CCM(J,NP), CCM(J,PO),
+    CCM(J,L), CCM(J,NGE),
+    CCM(J,NL), CCM(J,GE),
+    CCM(J,LE), CCM(J,NG),
+    CCM(J,NLE), CCM(J,G),
+Mnemonic_JMP,                           // Jump
+Mnemonic_LEA,                           // Load Effective Address
+Mnemonic_LEAVE,                         // High Level Procedure Exit
+Mnemonic_LOOP,                          // Loop according to ECX counter
+Mnemonic_LOOPE,                          // Loop according to ECX counter
+Mnemonic_LOOPNE, Mnemonic_LOOPNZ = Mnemonic_LOOPNE, // Loop according to ECX
+Mnemonic_LAHF,                          // Load Flags into AH
+Mnemonic_MOV,                           // Move
+Mnemonic_MOVD,                          // Move Double word
+Mnemonic_MOVQ,                          // Move Quadword
+/*Mnemonic_MOVS,                        // Move Data from String to String*/
+// MOVS is a special case: see encoding table for more details,
+Mnemonic_MOVS8, Mnemonic_MOVS16, Mnemonic_MOVS32, Mnemonic_MOVS64,
+//
+Mnemonic_MOVAPD,                         // Move Scalar Double-Precision Floating-Point Value
+Mnemonic_MOVSD,                         // Move Scalar Double-Precision Floating-Point Value
+Mnemonic_MOVSS,                         // Move Scalar Single-Precision Floating-Point Values
+Mnemonic_MOVSX,                         // Move with Sign-Extension
+Mnemonic_MOVZX,                         // Move with Zero-Extend
+//Mnemonic_MUL,                         // Unsigned Multiply
+Mnemonic_MULSD,                         // Multiply Scalar Double-Precision Floating-Point Values
+Mnemonic_MULSS,                         // Multiply Scalar Single-Precision Floating-Point Values
+Mnemonic_NEG,                           // Two's Complement Negation
+Mnemonic_NOP,                           // No Operation
+Mnemonic_NOT,                           // One's Complement Negation
+Mnemonic_OR,                            // Logical Inclusive OR
+Mnemonic_PREFETCH,                      // prefetch
+
+#if 1 //def _HAVE_MMX_
+    Mnemonic_PADDQ,                     // Add Packed Quadword Integers
+    Mnemonic_PAND,                      // Logical AND
+    Mnemonic_POR,                       // Bitwise Logical OR
+    Mnemonic_PSUBQ,                     // Subtract Packed Quadword Integers
+#endif
+Mnemonic_PANDN,
+Mnemonic_PSLLQ,
+Mnemonic_PSRLQ,
+Mnemonic_PXOR,                          // Logical Exclusive OR
+Mnemonic_POP,                           // Pop a Value from the Stack
+Mnemonic_POPFD,                         // Pop a Value of EFLAGS register from the Stack
+Mnemonic_PUSH,                          // Push Word or Doubleword Onto the Stack
+Mnemonic_PUSHFD,                        // Push EFLAGS Doubleword Onto the Stack
+Mnemonic_RET,                           // Return from Procedure
+
+Mnemonic_SETcc,                         // Set Byte on Condition
+    CCM(SET,O),
+    CCM(SET,NO),
+    CCM(SET,B), CCM(SET,NAE), CCM(SET,C),
+    CCM(SET,NB), CCM(SET,AE), CCM(SET,NC),
+    CCM(SET,Z), CCM(SET,E),
+    CCM(SET,NZ), CCM(SET,NE),
+    CCM(SET,BE), CCM(SET,NA),
+    CCM(SET,NBE), CCM(SET,A),
+    CCM(SET,S),
+    CCM(SET,NS),
+    CCM(SET,P), CCM(SET,PE),
+    CCM(SET,NP), CCM(SET,PO),
+    CCM(SET,L), CCM(SET,NGE),
+    CCM(SET,NL), CCM(SET,GE),
+    CCM(SET,LE), CCM(SET,NG),
+    CCM(SET,NLE), CCM(SET,G),
+
+Mnemonic_SAL, Mnemonic_SHL=Mnemonic_SAL,// Shift left
+Mnemonic_SAR,                           // Unsigned shift right
+Mnemonic_ROR,                           // Rotate right
+Mnemonic_RCR,                           // Rotate right through CARRY flag
+Mnemonic_ROL,                           // Rotate left
+Mnemonic_RCL,                           // Rotate left through CARRY flag
+Mnemonic_SHR,                           // Signed shift right
+Mnemonic_SHRD,                          // Double Precision Shift Right
+Mnemonic_SHLD,                          // Double Precision Shift Left
+
+Mnemonic_SBB,                           // Integer Subtraction with Borrow
+Mnemonic_SUB,                           // Subtract
+Mnemonic_SUBSD,                         // Subtract Scalar Double-Precision Floating-Point Values
+Mnemonic_SUBSS,                         // Subtract Scalar Single-Precision Floating-Point Values
+
+Mnemonic_TEST,                          // Logical Compare
+
+Mnemonic_UCOMISD,                       // Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS
+Mnemonic_UCOMISS,                       // Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS
+
+Mnemonic_XOR,                           // Logical Exclusive OR
+//
+// packed things,
+//
+Mnemonic_XORPD,                         // Bitwise Logical XOR for Double-Precision Floating-Point Values
+Mnemonic_XORPS,                         // Bitwise Logical XOR for Single-Precision Floating-Point Values
+
+Mnemonic_CVTDQ2PD,                      // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values
+Mnemonic_CVTTPD2DQ,                     // Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
+
+Mnemonic_CVTDQ2PS,                      // Convert Packed Doubleword Integers to Packed Single-Precision Floating-Point Values
+Mnemonic_CVTTPS2DQ,                     // Convert with Truncation Packed Single-Precision Floating-Point Values to Packed Doubleword Integers
+//
+// String operations
+//
+Mnemonic_STD,                           // Set direction flag
+Mnemonic_CLD,                           // Clear direction flag
+Mnemonic_SCAS,                          // Scan string
+Mnemonic_STOS,                          // Store string
+
+//
+Mnemonic_WAIT,                          // Check pending pending unmasked floating-point exception
+//
+Mnemonic_Count
+} Mnemonic;
+
+#undef CCM
+
+ENCODER_NAMESPACE_END
+
+#endif  // ifndef _ENCODER_DEFS_EXT_H_
diff --git a/vm/compiler/codegen/x86/libenc/enc_prvt.h b/vm/compiler/codegen/x86/libenc/enc_prvt.h
new file mode 100644
index 0000000..4300574
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/enc_prvt.h
@@ -0,0 +1,382 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+#ifndef __ENC_PRVT_H_INCLUDED__
+#define __ENC_PRVT_H_INCLUDED__
+
+#include "enc_base.h"
+
+ENCODER_NAMESPACE_START
+/*
+ * @file
+ * @brief Contains some definitions/constants and other stuff used by the
+ *        Encoder internally.
+ */
+
+enum OpcodeByteKind {
+    //OpcodeByteKind_Opcode = 0x0000,
+    OpcodeByteKind_ZeroOpcodeByte           = 0x0100,
+    //
+    // The names _SlashR,  _SlahsNum, _ib, _iw, etc
+    // represent the appropriate abbreviations used
+    // in the mnemonic descriptions in the Intel's arch manual.
+    //
+    OpcodeByteKind_SlashR                   = 0x0200,
+    OpcodeByteKind_SlashNum                 = 0x0300,
+    OpcodeByteKind_ib                       = 0x0400,
+    OpcodeByteKind_iw                       = 0x0500,
+    OpcodeByteKind_id                       = 0x0600,
+#ifdef _EM64T_
+    OpcodeByteKind_io                       = 0x0700,
+#endif
+    OpcodeByteKind_cb                       = 0x0800,
+    OpcodeByteKind_cw                       = 0x0900,
+    OpcodeByteKind_cd                       = 0x0A00,
+    //OpcodeByteKind_cp                     = 0x0B00,
+    //OpcodeByteKind_co                     = 0x0C00,
+    //OpcodeByteKind_ct                     = 0x0D00,
+
+    OpcodeByteKind_rb                       = 0x0E00,
+    OpcodeByteKind_rw                       = 0x0F00,
+    OpcodeByteKind_rd                       = 0x1000,
+#ifdef _EM64T_
+    OpcodeByteKind_ro                       = 0x1100,
+    //OpcodeByteKind_REX                    = 0x1200,
+    OpcodeByteKind_REX_W                    = 0x1300,
+#endif
+    OpcodeByteKind_plus_i                   = 0x1400,
+    /**
+        * a special marker, means 'no opcode on the given position'
+        * used in opcodes array, to specify the empty slot, say
+        * to fill an em64t-specific opcode on ia32.
+        * last 'e' made lowercase to avoid a mess with 'F' in
+        * OpcodeByteKind_LAST .
+        */
+    OpcodeByteKind_EMPTY                    = 0xFFFE,
+    /**
+        * a special marker, means 'no more opcodes in the array'
+        * used in in opcodes array to show that there are no more
+        * opcodes in the array for a given mnemonic.
+        */
+    OpcodeByteKind_LAST                     = 0xFFFF,
+    /**
+        * a mask to extract the OpcodeByteKind
+        */
+    OpcodeByteKind_KindMask                 = 0xFF00,
+    /**
+        * a mask to extract the opcode byte when presented
+        */
+    OpcodeByteKind_OpcodeMask               = 0x00FF
+};
+
+#ifdef USE_ENCODER_DEFINES
+
+#define N           {0, 0, 0, 0 }
+#define U           {1, 0, 1, OpndRole_Use }
+#define D           {1, 1, 0, OpndRole_Def }
+#define DU          {1, 1, 1, OpndRole_Def|OpndRole_Use }
+
+#define U_U         {2, 0, 2, OpndRole_Use<<2 | OpndRole_Use }
+#define D_U         {2, 1, 1, OpndRole_Def<<2 | OpndRole_Use }
+#define D_DU        {2, 2, 1, OpndRole_Def<<2 | (OpndRole_Def|OpndRole_Use) }
+#define DU_U        {2, 1, 2, ((OpndRole_Def|OpndRole_Use)<<2 | OpndRole_Use) }
+#define DU_DU       {2, 2, 2, ((OpndRole_Def|OpndRole_Use)<<2 | (OpndRole_Def|OpndRole_Use)) }
+
+#define DU_DU_DU    {3, 3, 3, ((OpndRole_Def|OpndRole_Use)<<4) | ((OpndRole_Def|OpndRole_Use)<<2) | (OpndRole_Def|OpndRole_Use) }
+#define DU_DU_U     {3, 2, 3, (((OpndRole_Def|OpndRole_Use)<<4) | ((OpndRole_Def|OpndRole_Use)<<2) | OpndRole_Use) }
+#define D_DU_U      {3, 2, 2, (((OpndRole_Def)<<4) | ((OpndRole_Def|OpndRole_Use)<<2) | OpndRole_Use) }
+#define D_U_U       {3, 1, 2, (((OpndRole_Def)<<4) | ((OpndRole_Use)<<2) | OpndRole_Use) }
+
+// Special encoding of 0x00 opcode byte. Note: it's all O-s, not zeros.
+#define OxOO        OpcodeByteKind_ZeroOpcodeByte
+
+#define Size16      InstPrefix_OpndSize
+
+#define _r          OpcodeByteKind_SlashR
+
+#define _0          OpcodeByteKind_SlashNum|0
+#define _1          OpcodeByteKind_SlashNum|1
+#define _2          OpcodeByteKind_SlashNum|2
+#define _3          OpcodeByteKind_SlashNum|3
+#define _4          OpcodeByteKind_SlashNum|4
+#define _5          OpcodeByteKind_SlashNum|5
+#define _6          OpcodeByteKind_SlashNum|6
+#define _7          OpcodeByteKind_SlashNum|7
+
+// '+i' for floating-point instructions
+#define _i          OpcodeByteKind_plus_i
+
+
+#define ib          OpcodeByteKind_ib
+#define iw          OpcodeByteKind_iw
+#define id          OpcodeByteKind_id
+
+#define cb          OpcodeByteKind_cb
+#define cw          OpcodeByteKind_cw
+#define cd          OpcodeByteKind_cd
+
+#define rb          OpcodeByteKind_rb
+#define rw          OpcodeByteKind_rw
+#define rd          OpcodeByteKind_rd
+
+#define AL          {OpndKind_GPReg, OpndSize_8, OpndExt_Any, RegName_AL}
+#define AH          {OpndKind_GPReg, OpndSize_8, OpndExt_Any, RegName_AH}
+#define AX          {OpndKind_GPReg, OpndSize_16, OpndExt_Any, RegName_AX}
+#define EAX         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_EAX}
+#ifdef _EM64T_
+    #define RAX     {OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RAX }
+#endif
+
+#define CL          {OpndKind_GPReg, OpndSize_8, OpndExt_Any, RegName_CL}
+#define ECX         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_ECX}
+#ifdef _EM64T_
+    #define RCX         {OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RCX}
+#endif
+
+#define DX          {OpndKind_GPReg, OpndSize_16, OpndExt_Any, RegName_DX}
+#define EDX         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_EDX}
+#ifdef _EM64T_
+    #define RDX     { OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RDX }
+#endif
+
+#define ESI         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_ESI}
+#ifdef _EM64T_
+    #define RSI     { OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RSI }
+#endif
+
+#define EDI         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_EDI}
+#ifdef _EM64T_
+    #define RDI     { OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RDI }
+#endif
+
+#define r8          {OpndKind_GPReg, OpndSize_8, OpndExt_Any, RegName_Null}
+#define r16         {OpndKind_GPReg, OpndSize_16, OpndExt_Any, RegName_Null}
+#define r32         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_Null}
+#ifdef _EM64T_
+    #define r64     { OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_Null }
+#endif
+
+#define r_m8        {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_8, OpndExt_Any, RegName_Null}
+#define r_m16       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, OpndExt_Any, RegName_Null}
+#define r_m32       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, OpndExt_Any, RegName_Null}
+
+#define r_m8s        {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_8, OpndExt_Signed, RegName_Null}
+#define r_m16s       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, OpndExt_Signed, RegName_Null}
+#define r_m32s       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, OpndExt_Signed, RegName_Null}
+
+#define r_m8u        {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_8, OpndExt_Zero, RegName_Null}
+#define r_m16u       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, OpndExt_Zero, RegName_Null}
+#define r_m32u       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, OpndExt_Zero, RegName_Null}
+
+//'m' was only used in LEA mnemonic, but is replaced with
+// set of exact sizes. See more comments for LEA instruction in TheTable.
+//#define m           {OpndKind_Mem, OpndSize_Null, RegName_Null}
+#define m8          {OpndKind_Mem, OpndSize_8, OpndExt_Any, RegName_Null}
+#define m16         {OpndKind_Mem, OpndSize_16, OpndExt_Any, RegName_Null}
+#define m32         {OpndKind_Mem, OpndSize_32, OpndExt_Any, RegName_Null}
+#define m64         {OpndKind_Mem, OpndSize_64, OpndExt_Any, RegName_Null}
+#ifdef _EM64T_
+    #define r_m64   { (OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_64, OpndExt_Any, RegName_Null }
+#endif
+
+#define imm8        {OpndKind_Imm, OpndSize_8, OpndExt_Any, RegName_Null}
+#define imm16       {OpndKind_Imm, OpndSize_16, OpndExt_Any, RegName_Null}
+#define imm32       {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null}
+
+#define imm8s        {OpndKind_Imm, OpndSize_8, OpndExt_Signed, RegName_Null}
+#define imm16s       {OpndKind_Imm, OpndSize_16, OpndExt_Signed, RegName_Null}
+#define imm32s       {OpndKind_Imm, OpndSize_32, OpndExt_Signed, RegName_Null}
+
+#define imm8u        {OpndKind_Imm, OpndSize_8, OpndExt_Zero, RegName_Null}
+#define imm16u       {OpndKind_Imm, OpndSize_16, OpndExt_Zero, RegName_Null}
+#define imm32u       {OpndKind_Imm, OpndSize_32, OpndExt_Zero, RegName_Null}
+
+#ifdef _EM64T_
+    #define imm64   {OpndKind_Imm, OpndSize_64, OpndExt_Any, RegName_Null }
+#endif
+
+//FIXME: moff-s are in fact memory refs, but presented as immediate.
+// Need to specify this in OpndDesc.
+#define moff8        {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null}
+#define moff16       {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null}
+#define moff32       {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null}
+#ifdef _EM64T_
+    #define moff64       {OpndKind_Imm, OpndSize_64, OpndExt_Any, RegName_Null}
+#endif
+
+
+#define rel8        {OpndKind_Imm, OpndSize_8, OpndExt_Any, RegName_Null}
+#define rel16       {OpndKind_Imm, OpndSize_16, OpndExt_Any, RegName_Null}
+#define rel32       {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null}
+
+#define mm64        {OpndKind_MMXReg, OpndSize_64, OpndExt_Any, RegName_Null}
+#define mm_m64      {(OpndKind)(OpndKind_MMXReg|OpndKind_Mem), OpndSize_64, OpndExt_Any, RegName_Null}
+
+#define xmm64       {OpndKind_XMMReg, OpndSize_64, OpndExt_Any, RegName_Null}
+#define xmm_m64     {(OpndKind)(OpndKind_XMMReg|OpndKind_Mem), OpndSize_64, OpndExt_Any, RegName_Null}
+
+#define xmm32       {OpndKind_XMMReg, OpndSize_32, OpndExt_Any, RegName_Null}
+#define xmm_m32     {(OpndKind)(OpndKind_XMMReg|OpndKind_Mem), OpndSize_32, OpndExt_Any, RegName_Null}
+
+#define FP0S        {OpndKind_FPReg, OpndSize_32, OpndExt_Any, RegName_FP0S}
+#define FP0D        {OpndKind_FPReg, OpndSize_64, OpndExt_Any, RegName_FP0D}
+#define FP1S        {OpndKind_FPReg, OpndSize_32, OpndExt_Any, RegName_FP1S}
+#define FP1D        {OpndKind_FPReg, OpndSize_64, OpndExt_Any, RegName_FP1D}
+#define fp32        {OpndKind_FPReg, OpndSize_32, OpndExt_Any, RegName_Null}
+#define fp64        {OpndKind_FPReg, OpndSize_64, OpndExt_Any, RegName_Null}
+
+#ifdef _EM64T_
+    #define io      OpcodeByteKind_io
+    #define REX_W   OpcodeByteKind_REX_W
+
+#endif
+
+#endif // USE_ENCODER_DEFINES
+
+/**
+ * @brief Represents the REX part of instruction.
+ */
+struct  Rex {
+    unsigned char b : 1;
+    unsigned char x : 1;
+    unsigned char r : 1;
+    unsigned char w : 1;
+    unsigned char dummy : 4;        // must be '0100'b
+    unsigned int  :24;
+};
+
+/**
+ * @brief Describes SIB (scale,index,base) byte.
+ */
+struct SIB {
+    unsigned char base:3;
+    unsigned char index:3;
+    unsigned char scale:2;
+    unsigned int  padding:24;
+};
+/**
+ * @brief Describes ModRM byte.
+ */
+struct ModRM
+{
+    unsigned char rm:3;
+    unsigned char reg:3;
+    unsigned char mod:2;
+    unsigned int  padding:24;
+};
+
+
+
+/**
+* exactly the same as EncoderBase::OpcodeDesc, but also holds info about
+* platform on which the opcode is applicable.
+*/
+struct OpcodeInfo {
+    enum platform {
+        /// an opcode is valid on all platforms
+        all,
+        // opcode is valid on IA-32 only
+        em64t,
+        // opcode is valid on Intel64 only
+        ia32,
+        // opcode is added for the sake of disassembling, should not be used in encoding
+        decoder,
+        // only appears in master table, replaced with 'decoder' in hashed version
+        decoder32,
+        // only appears in master table, replaced with 'decoder' in hashed version
+        decoder64,
+    };
+    platform                        platf;
+    unsigned                        opcode[4+1+1];
+    EncoderBase::OpndDesc           opnds[3];
+    EncoderBase::OpndRolesDesc      roles;
+};
+
+/**
+ * @defgroup MF_ Mnemonic flags
+*/
+
+    /**
+ * Operation has no special properties.
+    */
+#define MF_NONE             (0x00000000)
+    /**
+ * Operation affects flags
+    */
+#define MF_AFFECTS_FLAGS    (0x00000001)
+    /**
+ * Operation uses flags - conditional operations, ADC/SBB/ETC
+    */
+#define MF_USES_FLAGS       (0x00000002)
+    /**
+ * Operation is conditional - MOVcc/SETcc/Jcc/ETC
+    */
+#define MF_CONDITIONAL      (0x00000004)
+/**
+ * Operation is symmetric - its args can be swapped (ADD/MUL/etc).
+ */
+#define MF_SYMMETRIC        (0x00000008)
+/**
+ * Operation is XOR-like - XOR, SUB - operations of 'arg,arg' is pure def,
+ * without use.
+ */
+#define MF_SAME_ARG_NO_USE  (0x00000010)
+
+///@} // ~MNF
+
+/**
+ * @see same structure as EncoderBase::MnemonicDesc, but carries
+ * MnemonicInfo::OpcodeInfo[] instead of OpcodeDesc[].
+ * Only used during prebuilding the encoding tables, thus it's hidden under
+ * the appropriate define.
+ */
+struct MnemonicInfo {
+    /**
+    * The mnemonic itself
+    */
+    Mnemonic    mn;
+    /**
+     * Various characteristics of mnemonic.
+     * @see MF_
+     */
+    unsigned    flags;
+    /**
+     * Number of args/des/uses/roles for the operation. For the operations
+     * which may use different number of operands (i.e. IMUL/SHL) use the
+     * most common value, or leave '0' if you are sure this info is not
+     * required.
+     */
+    EncoderBase::OpndRolesDesc              roles;
+    /**
+     * Print name of the mnemonic
+     */
+    const char *                            name;
+    /**
+     * Array of opcodes.
+     * The terminating opcode description always have OpcodeByteKind_LAST
+     * at the opcodes[i].opcode[0].
+     * The size of '25' has nothing behind it, just counted the max
+     * number of opcodes currently used (MOV instruction).
+     */
+    OpcodeInfo                              opcodes[25];
+};
+
+ENCODER_NAMESPACE_END
+
+#endif  // ~__ENC_PRVT_H_INCLUDED__
diff --git a/vm/compiler/codegen/x86/libenc/enc_tabl.cpp b/vm/compiler/codegen/x86/libenc/enc_tabl.cpp
new file mode 100644
index 0000000..8a0789a
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/enc_tabl.cpp
@@ -0,0 +1,1975 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h> //qsort
+#include <string.h>
+#include <memory.h>
+#include <errno.h>
+#include <stdlib.h>
+
+
+// need to use EM64T-specifics - new registers, defines from enc_prvt, etc...
+#if !defined(_EM64T_)
+    #define UNDEF_EM64T
+    #define _EM64T_
+#endif
+
+#define USE_ENCODER_DEFINES
+#include "enc_prvt.h"
+#include "enc_defs.h"
+
+#ifdef UNDEF_EM64T
+    #undef _EM64T_
+#endif
+
+//Android x86
+#if 0 //!defined(_HAVE_MMX_)
+    #define Mnemonic_PADDQ  Mnemonic_Null
+    #define Mnemonic_PAND   Mnemonic_Null
+    #define Mnemonic_POR    Mnemonic_Null
+    #define Mnemonic_PSUBQ  Mnemonic_Null
+#endif
+
+ENCODER_NAMESPACE_START
+
+
+EncoderBase::MnemonicDesc EncoderBase::mnemonics[Mnemonic_Count];
+EncoderBase::OpcodeDesc EncoderBase::opcodes[Mnemonic_Count][MAX_OPCODES];
+unsigned char EncoderBase::opcodesHashMap[Mnemonic_Count][HASH_MAX];
+
+
+/**
+ * @file
+ * @brief 'Master' copy of encoding data.
+ */
+
+/*
+This file contains a 'master copy' of encoding table - this is the info used
+by both generator of native instructions (EncoderBase class) and by
+disassembling routines. The first one uses an info how to encode the
+instruction, and the second does an opposite - several separate tables are
+built at runtime from this main table.
+
+=============================================================================
+
+The table was designed for easy support and maintenance. Thus, it was made as
+much close as possible to the Intel's IA32 Architecture Manual descriptions.
+The info is based on the latest (at the moment of writing) revision which is
+June 2005, order number 253666-016.
+
+Normally, almost all of opcodes in the 'master' table represented exactly as
+they are shown in the Intel's Architecture manual (well, with slashes
+replaced with underscore). There are several exclusions especially marked.
+
+Normally, to add an opcode/instruction, one only need to copy the whole
+string from the manual, and simply replace '/' with '_'.
+
+I.e., TheManual reads for DEC:
+    (1)     FE /1 DEC r/m8 Valid Valid Decrement r/m8 by 1.
+    (2)     REX + FE /1 DEC r/m8* Valid N.E. Decrement r/m8 by 1.
+    (3)     REX.W + FF /1 DEC r/m64 Valid N.E. Decrement r/m64 by 1.
+
+1. Note, that there is no need to explicitly specify REX-based opcodes for
+    instruction to handle additional registers on EM64T:
+
+    (1)     FE /1 DEC r/m8 Valid Valid Decrement r/m8 by 1.
+    (3)     REX.W + FF /1 DEC r/m64 Valid N.E. Decrement r/m64 by 1.
+
+2. Copy the string, strip off the text comments, replace '/'=>'_'. Note, that
+    the second line is for EM64T only
+
+    (1)     FE /1 DEC r/m8
+    (3)     REX.W + FF /1 DEC r/m64
+
+3. Fill out the mnemonic, opcode parameters parts
+
+    BEGIN_MNEMONIC(DEC, MF_AFFECTS_FLAGS, DU)
+    BEGIN_OPCODES()
+        {OpcodeInfo::all,   {0xFE, _1},         {r_m8},         DU },
+        {OpcodeInfo::em64t, {REX_W, 0xFF, _1},  {r_m64},        DU },
+
+    DU here - one argument, it's used and defined
+
+4. That's it, that simple !
+
+The operand roles (DU here) are used by Jitrino's optimizing engine to
+perform data flow analysis. It also used to store/obtain number of operands.
+
+Special cases are (see the table for details):
+LEA
+Some FPU operations (i.e. FSTP)
+packed things (XORPD, XORPS, CVTDQ2PD, CVTTPD2DQ)
+
+Also, the Jitrino's needs require to specify all operands - including
+implicit ones (see IMUL).
+
+The master table iself does not need to be ordered - it's get sorted before
+processing. It's recommended (though it's not a law) to group similar
+instructions together - i.e. FPU instructions, MMX, etc.
+
+=============================================================================
+
+The encoding engine builds several tables basing on the 'master' one (here
+'mnemonic' is a kind of synonim for 'instruction'):
+
+- list of mnemonics which holds general info about instructions
+    (EncoderBase::mnemonics)
+- an array of opcodes descriptions (EncodeBase::opcodes)
+- a mapping between a hash value and an opcode description record for a given
+    mnemonic (EncoderBase::opcodesHashMap)
+
+The EncoderBase::mnemonics holds general info about instructions.
+The EncoderBase::opcodesHashMap is used for fast opcode selection basing on
+a hash value.
+The EncodeBase::opcodes is used for the encoding itself.
+
+=============================================================================
+The hash value is calculated and used as follows:
+
+JIT-ted code uses the following operand sizes: 8-, 16-, 32- and 64-bits and
+size for an operand can be encoded in just 2 bits.
+
+The following operand locations are available: one of registers - GP, FP,
+MMX, XMM (not taking segment registers), a memory and an immediate, which
+gives us 6 variants and can be enumerated in 3 bits.
+
+As a grand total, the the whole operand's info needed for opcode selection
+can be packed in 5 bits. Taking into account the IMUL mnemonic with its 3
+operands (including implicit ones), we're getting 15 bits per instruction and
+the complete table is about 32768 items per single instruction.
+
+Seems too many, but luckily, the 15 bit limit will never be reached: the
+worst case is IMUL with its 3 operands:
+(IMUL r64, r/m64, imm32)/(IMUL r32, r/m32, imm32).
+So, assigning lowest value to GP register, the max value of hash can be
+reduced.
+
+The hash values to use are:
+sizes:
+        8               -> 11
+        16              -> 10
+        32              -> 01
+        64              -> 00
+locations:
+        gp reg          -> 000
+        memory          -> 001
+        fp reg          -> 010
+        mmx reg         -> 011
+        xmm reg         -> 100
+        immediate       -> 101
+and the grand total for the worst case would be
+[ GP 32] [GP  32] [Imm 32]
+[000-01] [000-01] [101 01] = 1077
+
+However, the implicit operands adds additional value, and the worstest case
+is 'SHLD r_m32, r32, CL=r8'. This gives us the maximum number of:
+
+[mem 32] [GP  32] [GP  8b]
+[001-01] [000-01] [000-11] = 5155.
+
+The max number is pretty big and the hash functions is quite rare, thus it
+is not resonable to use a direct addressing i.e.
+OpcodeDesc[mnemonic][hash_code] - there would be a huge waste of space.
+
+Instead, we use a kind of mapping: the opcodes info is stored in packed
+(here: non rare) array. The max number of opcodes will not exceed 255 for
+each instruction. And we have an index array in which we store a mapping
+between a hash code value and opcode position for each given instruction.
+
+Sounds a bit sophisticated, but in real is simple, the opcode gets selected
+in 2 simple steps:
+
+1. Select [hash,mnemonic] => 'n'.
+
+The array is pretty rare - many cells contain 0xFF which
+means 'invalid hash - no opcode with given characteristics'
+
+char EnbcoderBase::opcodesHashMap[Mnemonic_Count][HASH_MAX] =
+
++----+----+----+----+----+----+
+| 00 | 05 | FF | FF | 03 | 12 | ...
+|---------+-------------------+
+| 12 | FF | FF |  n | 04 | 25 | ...   <- Mnemonic
+|-----------------------------+
+| FF | 11 | FF | 10 | 13 | .. | ...
++-----------------------------+
+     ...         ^
+                 |
+                hash
+
+2. Select [n,mnemonic] => 'opcode_desc11'
+
+OpcodeDesc      EncoderBase::opcodes[Mnemonic_Count][MAX_OPCODES] =
+
++---------------+---------------+---------------+---------------+
+| opcode_desc00 | opcode_desc01 | opcode_desc02 | last_opcode   | ...
++---------------+---------------+---------------+---------------+
+| opcode_desc10 | opcode_desc11 | last_opcode   | xxx           | <- Mnemonic
++---------------+---------------+---------------+---------------+
+| opcode_desc20 | opcode_desc21 | opcode_desc22 | opcode_desc23 | ...
++---------------+---------------+---------------+---------------+
+     ...
+                      ^
+                      |
+                      n
+
+Now, use 'opcode_desc11'.
+
+=============================================================================
+The array of opcodes descriptions (EncodeBase::opcodes) is specially prepared
+to maximize performance - the EncoderBase::encode() is quite hot on client
+applications for the Jitrino/Jitrino.JET.
+The preparation is that opcode descriptions from the 'master' encoding table
+are preprocessed and a special set of OpcodeDesc prepared:
+First, the 'raw' opcode bytes are extracted. Here, 'raw' means the bytes that
+do not depened on any operands values, do not require any analysis and can be
+simply copied into the output buffer during encoding. Also, number of these
+'raw' bytes is counted. The fields are OpcodeDesc::opcode and
+OpcodeDesc::opcode_len.
+
+Then the fisrt non-implicit operand found and its index is stored in
+OpcodeDesc::first_opnd.
+
+The bytes that require processing and analysis ('/r', '+i', etc) are
+extracted and stored in OpcodeDesc::aux0 and OpcodeDesc::aux1 fields.
+
+Here, a special trick is performed:
+    Some opcodes have register/memory operand, but this is not reflected in
+    opcode column - for example, (MOVQ xmm64, xmm_m64). In this case, a fake
+    '_r' added to OpcodeDesc::aux field.
+    Some other opcodes have immediate operands, but this is again not
+    reflected in opcode column - for example, CALL cd or PUSH imm32.
+    In this case, a fake '/cd' or fake '/id' added to appropriate
+    OpcodeDesc::aux field.
+
+The OpcodeDesc::last is non-zero for the final OpcodeDesc record (which does
+not have valid data itself).
+*/
+
+// TODO: To extend flexibility, replace bool fields in MnemonicDesc &
+// MnemonicInfo with a set of flags packed into integer field.
+
+unsigned short EncoderBase::getHash(const OpcodeInfo* odesc)
+{
+    /*
+    NOTE: any changes in the hash computation must be stricty balanced with
+    EncoderBase::Operand::hash_it and EncoderBase::Operands()
+    */
+    unsigned short hash = 0;
+    // The hash computation, uses fast way - table selection instead of if-s.
+    if (odesc->roles.count > 0) {
+        OpndKind kind = odesc->opnds[0].kind;
+        OpndSize size = odesc->opnds[0].size;
+        assert(kind<COUNTOF(kind_hash));
+        assert(size<COUNTOF(size_hash));
+        hash = get_kind_hash(kind) | get_size_hash(size);
+    }
+
+    if (odesc->roles.count > 1) {
+        OpndKind kind = odesc->opnds[1].kind;
+        OpndSize size = odesc->opnds[1].size;
+        assert(kind<COUNTOF(kind_hash));
+        assert(size<COUNTOF(size_hash));
+        hash = (hash<<HASH_BITS_PER_OPERAND) |
+               (get_kind_hash(kind) | get_size_hash(size));
+    }
+
+    if (odesc->roles.count > 2) {
+        OpndKind kind = odesc->opnds[2].kind;
+        OpndSize size = odesc->opnds[2].size;
+        assert(kind<COUNTOF(kind_hash));
+        assert(size<COUNTOF(size_hash));
+        hash = (hash<<HASH_BITS_PER_OPERAND) |
+            (get_kind_hash(kind) | get_size_hash(size));
+    }
+    assert(hash <= HASH_MAX);
+    return hash;
+}
+
+
+#define BEGIN_MNEMONIC(mn, flags, roles)     \
+        { Mnemonic_##mn, flags, roles, #mn,
+#define END_MNEMONIC() },
+#define BEGIN_OPCODES() {
+#define END_OPCODES()   { OpcodeInfo::all, {OpcodeByteKind_LAST} }}
+
+//#define BEGIN_MNEMONIC(mn, affflags, ulags, cond, symm, roles)     \
+//        { Mnemonic_##mn, affflags, ulags, cond, symm, roles, #mn,
+
+
+static MnemonicInfo masterEncodingTable[] = {
+//
+// Null
+//
+BEGIN_MNEMONIC(Null, MF_NONE, N)
+BEGIN_OPCODES()
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(LAHF, MF_USES_FLAGS, D)
+BEGIN_OPCODES()
+// TheManual says it's not always supported in em64t mode, thus excluding it
+    {OpcodeInfo::ia32,    {0x9F},         {EAX}, D },
+END_OPCODES()
+END_MNEMONIC()
+//
+// ALU mnemonics - add, adc, or, xor, and, cmp, sub, sbb
+// as they differ only in the opcode extention (/digit) number and
+// in which number the opcode start from, the opcode definitions
+// for those instructions are packed together
+//
+// The 'opcode_starts_from' and 'opcode_ext' in DEFINE_ALU_OPCODES()
+// are enough to define OpcodeInfo::all opcodes and the 'first_opcode'
+// parameter is only due to ADD instruction, which requires an zero opcode
+// byte which, in turn, is coded especially in the current coding scheme.
+//
+
+#define DEFINE_ALU_OPCODES( opc_ext, opcode_starts_from, first_opcode, def_use ) \
+\
+    {OpcodeInfo::decoder,   {opcode_starts_from + 4, ib},           {AL,    imm8},  DU_U },\
+    {OpcodeInfo::decoder,   {Size16, opcode_starts_from + 5, iw},   {AX,    imm16}, DU_U },\
+    {OpcodeInfo::decoder,   {opcode_starts_from + 5, id},           {EAX,   imm32}, DU_U },\
+    {OpcodeInfo::decoder64, {REX_W, opcode_starts_from+5, id},      {RAX,   imm32s},DU_U },\
+\
+    {OpcodeInfo::all,       {0x80, opc_ext, ib},          {r_m8,  imm8},    def_use },\
+    {OpcodeInfo::all,       {Size16, 0x81, opc_ext, iw},  {r_m16, imm16},   def_use },\
+    {OpcodeInfo::all,       {0x81, opc_ext, id},          {r_m32, imm32},   def_use },\
+    {OpcodeInfo::em64t,     {REX_W, 0x81, opc_ext, id},   {r_m64, imm32s},  def_use },\
+\
+    {OpcodeInfo::all,       {Size16, 0x83, opc_ext, ib},  {r_m16, imm8s},   def_use },\
+    {OpcodeInfo::all,       {0x83, opc_ext, ib},          {r_m32, imm8s},   def_use },\
+    {OpcodeInfo::em64t,     {REX_W, 0x83, opc_ext, ib},   {r_m64, imm8s},   def_use },\
+\
+    {OpcodeInfo::all,       {first_opcode,  _r},          {r_m8,  r8},      def_use },\
+\
+    {OpcodeInfo::all,       {Size16, opcode_starts_from+1,  _r},  {r_m16, r16},   def_use },\
+    {OpcodeInfo::all,       {opcode_starts_from+1,  _r},  {r_m32, r32},   def_use },\
+    {OpcodeInfo::em64t,     {REX_W, opcode_starts_from+1, _r},    {r_m64, r64},   def_use },\
+\
+    {OpcodeInfo::all,       {opcode_starts_from+2,  _r},  {r8,    r_m8},  def_use },\
+\
+    {OpcodeInfo::all,       {Size16, opcode_starts_from+3,  _r},  {r16,   r_m16}, def_use },\
+    {OpcodeInfo::all,       {opcode_starts_from+3,  _r},  {r32,   r_m32}, def_use },\
+    {OpcodeInfo::em64t,     {REX_W, opcode_starts_from+3, _r},    {r64,   r_m64}, def_use },
+
+BEGIN_MNEMONIC(ADD, MF_AFFECTS_FLAGS|MF_SYMMETRIC, DU_U)
+BEGIN_OPCODES()
+    DEFINE_ALU_OPCODES(_0, 0x00, OxOO, DU_U )
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(OR, MF_AFFECTS_FLAGS|MF_SYMMETRIC, DU_U)
+BEGIN_OPCODES()
+    DEFINE_ALU_OPCODES(_1, 0x08, 0x08, DU_U )
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(ADC, MF_AFFECTS_FLAGS|MF_USES_FLAGS|MF_SYMMETRIC, DU_U)
+BEGIN_OPCODES()
+    DEFINE_ALU_OPCODES(_2, 0x10, 0x10, DU_U )
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(SBB, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U)
+BEGIN_OPCODES()
+    DEFINE_ALU_OPCODES(_3, 0x18, 0x18, DU_U )
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(AND, MF_AFFECTS_FLAGS|MF_SYMMETRIC, DU_U)
+BEGIN_OPCODES()
+    DEFINE_ALU_OPCODES(_4, 0x20, 0x20, DU_U )
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(SUB, MF_AFFECTS_FLAGS|MF_SAME_ARG_NO_USE, DU_U)
+BEGIN_OPCODES()
+    DEFINE_ALU_OPCODES(_5, 0x28, 0x28, DU_U )
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(XOR, MF_AFFECTS_FLAGS|MF_SYMMETRIC|MF_SAME_ARG_NO_USE, DU_U)
+BEGIN_OPCODES()
+    DEFINE_ALU_OPCODES( _6, 0x30, 0x30, DU_U )
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CMP, MF_AFFECTS_FLAGS, U_U)
+BEGIN_OPCODES()
+    DEFINE_ALU_OPCODES( _7, 0x38, 0x38, U_U )
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CMPXCHG, MF_AFFECTS_FLAGS, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x0F, 0xB0, _r},           {r_m8, r8, AL},     DU_DU_DU },
+    {OpcodeInfo::all,   {Size16, 0x0F, 0xB1, _r},   {r_m16, r16, AX},   DU_DU_DU },
+    {OpcodeInfo::all,   {0x0F, 0xB1, _r},           {r_m32, r32, EAX},  DU_DU_DU},
+    {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB1, _r},    {r_m64, r64, RAX},  DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CMPXCHG8B, MF_AFFECTS_FLAGS, D)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x0F, 0xC7, _1},         {m64},     DU },
+END_OPCODES()
+END_MNEMONIC()
+
+#undef DEFINE_ALU_OPCODES
+//
+//
+//
+BEGIN_MNEMONIC(ADDSD, MF_NONE, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF2, 0x0F, 0x58, _r},   {xmm64, xmm_m64},   DU_U},
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(ADDSS, MF_NONE, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF3, 0x0F, 0x58, _r},   {xmm32, xmm_m32},   DU_U},
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(BSF, MF_AFFECTS_FLAGS, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x0F, 0xBC},   {r32, r_m32},   D_U},
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(BSR, MF_AFFECTS_FLAGS, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x0F, 0xBD},   {r32, r_m32},   D_U},
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(CALL, MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xE8, cd},        {rel32},     U },
+    {OpcodeInfo::ia32,  {Size16, 0xE8, cw}, {rel16},    U },
+    {OpcodeInfo::ia32,  {0xFF, _2},        {r_m32},     U },
+    {OpcodeInfo::em64t, {0xFF, _2},        {r_m64},     U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CMC, MF_USES_FLAGS|MF_AFFECTS_FLAGS, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::decoder,   {0xF5},         {},     N },
+END_OPCODES()
+END_MNEMONIC()
+
+//TODO: Workaround. Actually, it's D_DU, but Jitrino's CG thinks it's D_U
+BEGIN_MNEMONIC(CDQ, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,       {0x99},         {DX, AX},       D_U },
+    {OpcodeInfo::all,       {0x99},         {EDX, EAX},     D_U },
+    {OpcodeInfo::em64t,     {REX_W, 0x99},  {RDX, RAX},     D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+#define DEFINE_CMOVcc_MNEMONIC( cc ) \
+        BEGIN_MNEMONIC(CMOV##cc, MF_USES_FLAGS|MF_CONDITIONAL, DU_U ) \
+BEGIN_OPCODES() \
+    {OpcodeInfo::all,   {Size16, 0x0F, 0x40 + ConditionMnemonic_##cc, _r},  {r16, r_m16},   DU_U }, \
+    {OpcodeInfo::all,   {0x0F, 0x40 + ConditionMnemonic_##cc, _r},          {r32, r_m32},   DU_U }, \
+    {OpcodeInfo::em64t, {REX_W, 0x0F, 0x40 + ConditionMnemonic_##cc, _r},   {r64, r_m64},   DU_U }, \
+END_OPCODES() \
+END_MNEMONIC()
+
+DEFINE_CMOVcc_MNEMONIC(O)
+DEFINE_CMOVcc_MNEMONIC(NO)
+DEFINE_CMOVcc_MNEMONIC(B)
+DEFINE_CMOVcc_MNEMONIC(NB)
+DEFINE_CMOVcc_MNEMONIC(Z)
+DEFINE_CMOVcc_MNEMONIC(NZ)
+DEFINE_CMOVcc_MNEMONIC(BE)
+DEFINE_CMOVcc_MNEMONIC(NBE)
+DEFINE_CMOVcc_MNEMONIC(S)
+DEFINE_CMOVcc_MNEMONIC(NS)
+DEFINE_CMOVcc_MNEMONIC(P)
+DEFINE_CMOVcc_MNEMONIC(NP)
+DEFINE_CMOVcc_MNEMONIC(L)
+DEFINE_CMOVcc_MNEMONIC(NL)
+DEFINE_CMOVcc_MNEMONIC(LE)
+DEFINE_CMOVcc_MNEMONIC(NLE)
+
+#undef DEFINE_CMOVcc_MNEMONIC
+
+/*****************************************************************************
+                                ***** SSE conversion routines *****
+*****************************************************************************/
+//
+// double -> float
+BEGIN_MNEMONIC(CVTSD2SS, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF2, 0x0F, 0x5A, _r},   {xmm32, xmm_m64}, D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+// double -> I_32
+BEGIN_MNEMONIC(CVTSD2SI, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF2, 0x0F, 0x2D, _r},         {r32, xmm_m64}, D_U },
+    {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2D, _r},  {r64, xmm_m64}, D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+// double [truncated] -> I_32
+BEGIN_MNEMONIC(CVTTSD2SI, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF2, 0x0F, 0x2C, _r},         {r32, xmm_m64}, D_U },
+    {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2C, _r},  {r64, xmm_m64}, D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+// float -> double
+BEGIN_MNEMONIC(CVTSS2SD, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF3, 0x0F, 0x5A, _r},         {xmm64, xmm_m32}, D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+// float -> I_32
+BEGIN_MNEMONIC(CVTSS2SI, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF3, 0x0F, 0x2D, _r},         {r32, xmm_m32}, D_U},
+    {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2D, _r},  {r64, xmm_m32}, D_U},
+END_OPCODES()
+END_MNEMONIC()
+
+// float [truncated] -> I_32
+BEGIN_MNEMONIC(CVTTSS2SI, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF3, 0x0F, 0x2C, _r},         {r32, xmm_m32}, D_U},
+    {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2C, _r},  {r64, xmm_m32}, D_U},
+END_OPCODES()
+END_MNEMONIC()
+
+// I_32 -> double
+BEGIN_MNEMONIC(CVTSI2SD, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF2, 0x0F, 0x2A, _r},         {xmm64, r_m32}, D_U},
+    {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2A, _r},  {xmm64, r_m64}, D_U},
+END_OPCODES()
+END_MNEMONIC()
+
+// I_32 -> float
+BEGIN_MNEMONIC(CVTSI2SS, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF3, 0x0F, 0x2A, _r},         {xmm32, r_m32}, D_U},
+    {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2A, _r},  {xmm32, r_m64}, D_U},
+END_OPCODES()
+END_MNEMONIC()
+
+//
+// ~ SSE conversions
+//
+
+BEGIN_MNEMONIC(DEC, MF_AFFECTS_FLAGS, DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xFE, _1},         {r_m8},     DU },
+
+    {OpcodeInfo::all,   {Size16, 0xFF, _1}, {r_m16},    DU },
+    {OpcodeInfo::all,   {0xFF, _1},         {r_m32},    DU },
+    {OpcodeInfo::em64t, {REX_W, 0xFF, _1},  {r_m64},    DU },
+
+    {OpcodeInfo::ia32,  {Size16, 0x48|rw},  {r16},      DU },
+    {OpcodeInfo::ia32,  {0x48|rd},          {r32},      DU },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(DIVSD, MF_NONE, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all, {0xF2, 0x0F, 0x5E, _r},   {xmm64, xmm_m64},   DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(DIVSS, MF_NONE, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all, {0xF3, 0x0F, 0x5E, _r},   {xmm32, xmm_m32},   DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+/****************************************************************************
+                 ***** FPU operations *****
+****************************************************************************/
+
+BEGIN_MNEMONIC(FADDP, MF_NONE, DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDE, 0xC1},       {FP0D}, DU },
+    {OpcodeInfo::all,   {0xDE, 0xC1},       {FP0S}, DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FLDZ,  MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, 0xEE},   {FP0D}, D },
+    {OpcodeInfo::all,   {0xD9, 0xEE},   {FP0S}, D },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FADD,  MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDC, _0},     {FP0D, m64}, DU_U },
+    {OpcodeInfo::all,   {0xD8, _0},     {FP0S, m32}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FSUBP, MF_NONE, DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDE, 0xE9},   {FP0D}, DU },
+    {OpcodeInfo::all,   {0xDE, 0xE9},   {FP0S}, DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FSUB,   MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDC, _4},     {FP0D, m64}, DU_U },
+    {OpcodeInfo::all,   {0xD8, _4},     {FP0S, m32}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FISUB,   MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDA, _4},       {FP0S, m32}, DU_U },
+//    {OpcodeInfo::all,   {0xDE, _4},       {FP0S, m16}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
+
+BEGIN_MNEMONIC(FMUL,   MF_NONE, DU_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD8, _1},     {FP0S, m32}, DU_U },
+    {OpcodeInfo::all,   {0xDC, _1},     {FP0D, m64}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FMULP, MF_NONE, DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDE, 0xC9},   {FP0D}, DU },
+    {OpcodeInfo::all,   {0xDE, 0xC9},   {FP0S}, DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FDIVP, MF_NONE, DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDE, 0xF9},   {FP0D}, DU },
+    {OpcodeInfo::all,   {0xDE, 0xF9},   {FP0S}, DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FDIV,   MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDC, _6},     {FP0D, m64}, DU_U },
+    {OpcodeInfo::all,   {0xD8, _6},     {FP0S, m32}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(FUCOM, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDD, 0xE1},         {FP0D, FP1D},    DU_U },
+    {OpcodeInfo::all,   {0xDD, 0xE1},         {FP0S, FP1S},    DU_U },
+    // A little trick: actually, these 2 opcodes take only index of the
+    // needed register. To make the things similar to other instructions
+    // we encode here as if they took FPREG.
+    {OpcodeInfo::all,   {0xDD, 0xE0|_i},    {fp32},         DU },
+    {OpcodeInfo::all,   {0xDD, 0xE0|_i},    {fp64},         DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FUCOMI, MF_NONE, D_U )
+BEGIN_OPCODES()
+    // A little trick: actually, these 2 opcodes take only index of the
+    // needed register. To make the things similar to other instructions
+    // we encode here as if they took FPREG.
+    {OpcodeInfo::all,   {0xDB, 0xE8|_i},    {fp32},         DU },
+    {OpcodeInfo::all,   {0xDB, 0xE8|_i},    {fp64},         DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FUCOMP, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDD, 0xE9},             {FP0D, FP1D},    DU_U },
+    {OpcodeInfo::all,   {0xDD, 0xE9},             {FP0S, FP1S},    DU_U },
+    // A little trick: actually, these 2 opcodes take only index of the
+    // needed register. To make the things similar to other instructions
+    // we encode here as if they took FPREG.
+    {OpcodeInfo::all,   {0xDD, 0xE8|_i},        {fp32},         DU },
+    {OpcodeInfo::all,   {0xDD, 0xE8|_i},        {fp64},         DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FUCOMIP, MF_NONE, D_U )
+BEGIN_OPCODES()
+    // A little trick: actually, these 2 opcodes take only index of the
+    // needed register. To make the things similar to other instructions
+    // we encode here as if they took FPREG.
+    {OpcodeInfo::all,   {0xDF, 0xE8|_i},        {fp32},         DU },
+    {OpcodeInfo::all,   {0xDF, 0xE8|_i},        {fp64},         DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FUCOMPP, MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDA, 0xE9},   {FP0D, FP1D}, DU_U },
+    {OpcodeInfo::all,   {0xDA, 0xE9},   {FP0S, FP1S}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FLDCW, MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, _5},     {m16},  U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FNSTCW, MF_NONE, D)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, _7},     {m16},  D },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FSTSW, MF_NONE, D)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x9B, 0xDF, 0xE0}, {EAX},  D },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FNSTSW, MF_NONE, D)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDF, 0xE0},   {EAX},  D },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FCHS, MF_NONE, DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, 0xE0},   {FP0D}, DU },
+    {OpcodeInfo::all,   {0xD9, 0xE0},   {FP0S}, DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FCLEX, MF_NONE, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x9B, 0xDB, 0xE2}, {}, N },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FNCLEX, MF_NONE, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDB, 0xE2},       {}, N },
+END_OPCODES()
+END_MNEMONIC()
+
+//BEGIN_MNEMONIC(FDECSTP, MF_NONE, N)
+//  BEGIN_OPCODES()
+//          {OpcodeInfo::all, {0xD9, 0xF6},       {},     N },
+//  END_OPCODES()
+//END_MNEMONIC()
+
+BEGIN_MNEMONIC(FILD, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDB, _0}, {FP0S, m32},    D_U },
+    {OpcodeInfo::all,   {0xDF, _5}, {FP0D, m64},    D_U },
+    {OpcodeInfo::all,   {0xDB, _0}, {FP0S, m32},    D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+//BEGIN_MNEMONIC(FINCSTP, MF_NONE, N)
+//  BEGIN_OPCODES()
+//          {OpcodeInfo::all, {0xD9, 0xF7},       {},     N },
+//  END_OPCODES()
+//END_MNEMONIC()
+
+BEGIN_MNEMONIC(FIST, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDB, _2}, {m32, FP0S},    D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FISTP, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDB, _3}, {m32, FP0S},    D_U },
+    {OpcodeInfo::all,   {0xDF, _7}, {m64, FP0D},    D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FISTTP, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xDD, _1}, {m64, FP0D},    D_U },
+    {OpcodeInfo::all,   {0xDB, _1}, {m32, FP0S},    D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FRNDINT, MF_NONE, DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, 0xFC}, {FP0S},    DU },
+    {OpcodeInfo::all,   {0xD9, 0xFC}, {FP0D},    DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FLD, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, _0}, {FP0S, m32},    D_U },
+    {OpcodeInfo::all,   {0xDD, _0}, {FP0D, m64},    D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FLDLG2, MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, 0xEC}, {FP0S},    D },
+    {OpcodeInfo::all,   {0xD9, 0xEC}, {FP0D},    D },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FLDLN2, MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, 0xED}, {FP0S},    D },
+    {OpcodeInfo::all,   {0xD9, 0xED}, {FP0D},    D },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FLD1, MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, 0xE8}, {FP0S},    D },
+    {OpcodeInfo::all,   {0xD9, 0xE8}, {FP0D},    D },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(FPREM, MF_NONE, N)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xF8},       {},     N },
+  END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FPREM1, MF_NONE, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, 0xF5},       {},     N },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FST, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, _2},         {m32, FP0S},    D_U },
+    {OpcodeInfo::all,   {0xDD, _2},         {m64, FP0D},    D_U },
+    // A little trick: actually, these 2 opcodes take only index of the
+    // needed register. To make the things similar to other instructions
+    // we encode here as if they took FPREG.
+    {OpcodeInfo::all,   {0xDD, 0xD0|_i},    {fp32},         D },
+    {OpcodeInfo::all,   {0xDD, 0xD0|_i},    {fp64},         D },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FSTP, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xD9, _3},             {m32, FP0S},    D_U },
+    {OpcodeInfo::all,   {0xDD, _3},             {m64, FP0D},    D_U },
+    // A little trick: actually, these 2 opcodes take only index of the
+    // needed register. To make the things similar to other instructions
+    // we encode here as if they took FPREG.
+    {OpcodeInfo::all,   {0xDD, 0xD8|_i},        {fp32},         D },
+    {OpcodeInfo::all,   {0xDD, 0xD8|_i},        {fp64},         D },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FSQRT, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xFA},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xFA},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(FYL2X, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xF1},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xF1},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(FYL2XP1, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xF9},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xF9},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(F2XM1, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xF0},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xF0},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FPATAN, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xF3},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xF3},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FXCH, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xC9},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xC9},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FSCALE, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xFD},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xFD},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FABS, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xE1},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xE1},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FSIN, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xFE},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xFE},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FCOS, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xFF},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xFF},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(FPTAN, MF_NONE, DU)
+  BEGIN_OPCODES()
+          {OpcodeInfo::all, {0xD9, 0xF2},       {FP0S},     DU   },
+          {OpcodeInfo::all, {0xD9, 0xF2},       {FP0D},     DU   },
+  END_OPCODES()
+END_MNEMONIC()
+
+//
+// ~ FPU
+//
+
+BEGIN_MNEMONIC(DIV, MF_AFFECTS_FLAGS, DU_DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF7, _6},         {EDX, EAX, r_m32},  DU_DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(IDIV, MF_AFFECTS_FLAGS, DU_DU_U)
+BEGIN_OPCODES()
+#if !defined(_EM64T_)
+    {OpcodeInfo::all,   {0xF6, _7},         {AH, AL, r_m8},     DU_DU_U },
+    {OpcodeInfo::all,   {Size16, 0xF7, _7}, {DX, AX, r_m16},    DU_DU_U },
+#endif
+    {OpcodeInfo::all,   {0xF7, _7},         {EDX, EAX, r_m32},  DU_DU_U },
+    {OpcodeInfo::em64t, {REX_W, 0xF7, _7},  {RDX, RAX, r_m64},  DU_DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(IMUL, MF_AFFECTS_FLAGS, D_DU_U)
+BEGIN_OPCODES()
+    /*{OpcodeInfo::all,   {0xF6, _5},               {AH, AL,        r_m8},  D_DU_U },
+    {OpcodeInfo::all,     {Size16, 0xF7, _5},       {DX, AX,        r_m16}, D_DU_U },
+    */
+    //
+    {OpcodeInfo::all,     {0xF7, _5},               {EDX, EAX, r_m32},  D_DU_U },
+    //todo: this opcode's hash conflicts with IMUL r64,r_m64 - they're both 0.
+    // this particular is not currently used, so we may safely drop it, but need to
+    // revisit the hash implementation
+    // {OpcodeInfo::em64t,   {REX_W, 0xF7, _5},        {RDX, RAX, r_m64},  D_DU_U },
+    //
+    {OpcodeInfo::all,   {Size16, 0x0F, 0xAF, _r}, {r16,r_m16},        DU_U },
+    {OpcodeInfo::all,   {0x0F, 0xAF, _r},         {r32,r_m32},        DU_U },
+    {OpcodeInfo::em64t, {REX_W, 0x0F, 0xAF, _r},  {r64,r_m64},        DU_U },
+    {OpcodeInfo::all,   {Size16, 0x6B, _r, ib},   {r16,r_m16,imm8s},  D_DU_U },
+    {OpcodeInfo::all,   {0x6B, _r, ib},           {r32,r_m32,imm8s},  D_DU_U },
+    {OpcodeInfo::em64t, {REX_W, 0x6B, _r, ib},    {r64,r_m64,imm8s},  D_DU_U },
+    {OpcodeInfo::all,   {Size16, 0x6B, _r, ib},   {r16,imm8s},        DU_U },
+    {OpcodeInfo::all,   {0x6B, _r, ib},           {r32,imm8s},        DU_U },
+    {OpcodeInfo::em64t, {REX_W, 0x6B, _r, ib},    {r64,imm8s},        DU_U },
+    {OpcodeInfo::all,   {Size16, 0x69, _r, iw},   {r16,r_m16,imm16},  D_U_U },
+    {OpcodeInfo::all,   {0x69, _r, id},           {r32,r_m32,imm32},  D_U_U },
+    {OpcodeInfo::em64t, {REX_W, 0x69, _r, id},    {r64,r_m64,imm32s}, D_U_U },
+    {OpcodeInfo::all,   {Size16, 0x69, _r, iw},   {r16,imm16},        DU_U },
+    {OpcodeInfo::all,   {0x69, _r, id},           {r32,imm32},        DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(MUL, MF_AFFECTS_FLAGS, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF6, _4},           {AX, AL, r_m8},     D_DU_U },
+    {OpcodeInfo::all,   {Size16, 0xF7, _4},   {DX, AX, r_m16},    D_DU_U },
+    {OpcodeInfo::all,   {0xF7, _4},           {EDX, EAX, r_m32},  D_DU_U },
+    {OpcodeInfo::em64t, {REX_W, 0xF7, _4},    {RDX, RAX, r_m64},  D_DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(INC, MF_AFFECTS_FLAGS, DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xFE, _0},           {r_m8},         DU },
+    {OpcodeInfo::all,   {Size16, 0xFF, _0},   {r_m16},        DU },
+    {OpcodeInfo::all,   {0xFF, _0},           {r_m32},        DU },
+    {OpcodeInfo::em64t, {REX_W, 0xFF, _0},    {r_m64},        DU },
+    {OpcodeInfo::ia32,  {Size16, 0x40|rw},    {r16},          DU },
+    {OpcodeInfo::ia32,  {0x40|rd},            {r32},          DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(INT3, MF_NONE, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xCC},     {},     N },
+END_OPCODES()
+END_MNEMONIC()
+
+#define DEFINE_Jcc_MNEMONIC( cc ) \
+        BEGIN_MNEMONIC(J##cc, MF_USES_FLAGS|MF_CONDITIONAL, U ) \
+BEGIN_OPCODES() \
+    {OpcodeInfo::all,   {0x70 + ConditionMnemonic_##cc, cb },           { rel8 },       U }, \
+    {OpcodeInfo::ia32,  {Size16, 0x0F, 0x80 + ConditionMnemonic_##cc, cw},      { rel16 },      U }, \
+    {OpcodeInfo::all,   {0x0F, 0x80 + ConditionMnemonic_##cc, cd},      { rel32 },      U }, \
+END_OPCODES() \
+END_MNEMONIC()
+
+
+DEFINE_Jcc_MNEMONIC(O)
+DEFINE_Jcc_MNEMONIC(NO)
+DEFINE_Jcc_MNEMONIC(B)
+DEFINE_Jcc_MNEMONIC(NB)
+DEFINE_Jcc_MNEMONIC(Z)
+DEFINE_Jcc_MNEMONIC(NZ)
+DEFINE_Jcc_MNEMONIC(BE)
+DEFINE_Jcc_MNEMONIC(NBE)
+
+DEFINE_Jcc_MNEMONIC(S)
+DEFINE_Jcc_MNEMONIC(NS)
+DEFINE_Jcc_MNEMONIC(P)
+DEFINE_Jcc_MNEMONIC(NP)
+DEFINE_Jcc_MNEMONIC(L)
+DEFINE_Jcc_MNEMONIC(NL)
+DEFINE_Jcc_MNEMONIC(LE)
+DEFINE_Jcc_MNEMONIC(NLE)
+
+#undef DEFINE_Jcc_MNEMONIC
+
+BEGIN_MNEMONIC(JMP, MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xEB, cb},         {rel8},     U },
+    {OpcodeInfo::ia32,  {Size16, 0xE9, cw}, {rel16},    U },
+    {OpcodeInfo::all,   {0xE9, cd},         {rel32},    U },
+    {OpcodeInfo::ia32,  {Size16, 0xFF, _4}, {r_m16},    U },
+    {OpcodeInfo::ia32,  {0xFF, _4},         {r_m32},    U },
+    {OpcodeInfo::em64t, {0xFF, _4},         {r_m64},    U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(LEA, MF_NONE, D_U )
+BEGIN_OPCODES()
+    /*
+    A special case: the LEA instruction itself does not care about size of
+    second operand. This is obviuos why it is, and thus in The Manual, a
+    simple 'm' without size is used.
+    However, in the Jitrino's instrucitons we'll have an operand with a size.
+    Also, the hashing scheme is not supposed to handle OpndSize_Null, and
+    making it to do so will lead to unnecessary complication of hashing
+    scheme. Thus, instead of handling it as a special case, we simply make
+    copies of the opcodes with sizes set.
+        {OpcodeInfo::all,     {0x8D, _r},             {r32, m},       D_U },
+        {OpcodeInfo::em64t, {0x8D, _r},               {r64, m},       D_U },
+    */
+    //Android x86: keep r32, m32 only, otherwise, will have decoding error
+    //{OpcodeInfo::all,   {0x8D, _r},     {r32, m8},      D_U },
+    {OpcodeInfo::em64t, {REX_W, 0x8D, _r},     {r64, m8},      D_U },
+    //{OpcodeInfo::all,   {0x8D, _r},     {r32, m16},     D_U },
+    {OpcodeInfo::em64t, {REX_W, 0x8D, _r},     {r64, m16},     D_U },
+    {OpcodeInfo::all,   {0x8D, _r},     {r32, m32},     D_U },
+    {OpcodeInfo::em64t, {REX_W, 0x8D, _r},     {r64, m32},     D_U },
+    {OpcodeInfo::all,   {0x8D, _r},     {r32, m64},     D_U },
+    {OpcodeInfo::em64t, {REX_W, 0x8D, _r},     {r64, m64},     D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(LOOP, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xE2, cb},     {ECX, rel8},    DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(LOOPE, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xE1, cb},     {ECX, rel8},    DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(LOOPNE, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xE0, cb},     {ECX, rel8},    DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(MOV, MF_NONE, D_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x88, _r},         {r_m8,r8},      D_U },
+
+    {OpcodeInfo::all,   {Size16, 0x89, _r}, {r_m16,r16},    D_U },
+    {OpcodeInfo::all,   {0x89, _r},         {r_m32,r32},    D_U },
+    {OpcodeInfo::em64t, {REX_W, 0x89, _r},  {r_m64,r64},    D_U },
+    {OpcodeInfo::all,   {0x8A, _r},         {r8,r_m8},      D_U },
+
+    {OpcodeInfo::all,   {Size16, 0x8B, _r}, {r16,r_m16},    D_U },
+    {OpcodeInfo::all,   {0x8B, _r},         {r32,r_m32},    D_U },
+    {OpcodeInfo::em64t, {REX_W, 0x8B, _r},  {r64,r_m64},    D_U },
+
+    {OpcodeInfo::all,   {0xB0|rb},          {r8,imm8},      D_U },
+
+    {OpcodeInfo::all,   {Size16, 0xB8|rw},  {r16,imm16},    D_U },
+    {OpcodeInfo::all,   {0xB8|rd},          {r32,imm32},    D_U },
+    {OpcodeInfo::em64t, {REX_W, 0xB8|rd},   {r64,imm64},    D_U },
+    {OpcodeInfo::all,   {0xC6, _0},         {r_m8,imm8},    D_U },
+
+    {OpcodeInfo::all,   {Size16, 0xC7, _0}, {r_m16,imm16},  D_U },
+    {OpcodeInfo::all,   {0xC7, _0},         {r_m32,imm32},  D_U },
+    {OpcodeInfo::em64t, {REX_W, 0xC7, _0},  {r_m64,imm32s}, D_U },
+
+    {OpcodeInfo::decoder,   {0xA0},         {AL,  moff8},  D_U },
+    {OpcodeInfo::decoder,   {Size16, 0xA1}, {AX,  moff16},  D_U },
+    {OpcodeInfo::decoder,   {0xA1},         {EAX, moff32},  D_U },
+    //{OpcodeInfo::decoder64,   {REX_W, 0xA1},  {RAX, moff64},  D_U },
+
+    {OpcodeInfo::decoder,   {0xA2},         {moff8, AL},  D_U },
+    {OpcodeInfo::decoder,   {Size16, 0xA3}, {moff16, AX},  D_U },
+    {OpcodeInfo::decoder,   {0xA3},         {moff32, EAX},  D_U },
+    //{OpcodeInfo::decoder64,   {REX_W, 0xA3},  {moff64, RAX},  D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
+
+BEGIN_MNEMONIC(XCHG, MF_NONE, DU_DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x87, _r},   {r_m32,r32},    DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(MOVQ, MF_NONE, D_U )
+BEGIN_OPCODES()
+#ifdef _HAVE_MMX_
+    {OpcodeInfo::all,   {0x0F, 0x6F, _r},   {mm64, mm_m64}, D_U },
+    {OpcodeInfo::all,   {0x0F, 0x7F, _r},   {mm_m64, mm64}, D_U },
+#endif
+    {OpcodeInfo::all,   {0xF3, 0x0F, 0x7E },  {xmm64, xmm_m64},       D_U },
+    {OpcodeInfo::all,   {0x66, 0x0F, 0xD6 },  {xmm_m64, xmm64},       D_U },
+//    {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x6E, _r},  {xmm64, r_m64}, D_U },
+//    {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x7E, _r},  {r_m64, xmm64}, D_U },
+    {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x6E, _r},  {xmm64, r64}, D_U },
+    {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x7E, _r},  {r64, xmm64}, D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(MOVD, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x66, 0x0F, 0x6E, _r}, {xmm32, r_m32}, D_U },
+    {OpcodeInfo::all,   {0x66, 0x0F, 0x7E, _r}, {r_m32, xmm32}, D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+//
+// A bunch of MMX instructions
+//
+#ifdef _HAVE_MMX_
+
+BEGIN_MNEMONIC(EMMS, MF_NONE, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x0F, 0x77},       {},             N },
+END_OPCODES()
+END_MNEMONIC()
+
+#endif
+
+BEGIN_MNEMONIC(PADDQ, MF_NONE, DU_U)
+BEGIN_OPCODES()
+#ifdef _HAVE_MMX_
+    {OpcodeInfo::all,   {0x0F, 0xD4, _r},   {mm64, mm_m64}, DU_U },
+#endif
+    {OpcodeInfo::all,   {0x66, 0x0F, 0xD4, _r},   {xmm64, xmm_m64}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(PAND, MF_NONE, DU_U)
+BEGIN_OPCODES()
+#ifdef _HAVE_MMX_
+    {OpcodeInfo::all,   {0x0F, 0xDB, _r},   {mm64, mm_m64}, DU_U },
+#endif
+    {OpcodeInfo::all,   {0x66, 0x0F, 0xDB, _r},   {xmm64, xmm_m64}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(POR, MF_NONE, DU_U)
+BEGIN_OPCODES()
+#ifdef _HAVE_MMX_
+    {OpcodeInfo::all,   {0x0F, 0xEB, _r},   {mm64, mm_m64}, DU_U },
+#endif
+    {OpcodeInfo::all,   {0x66, 0x0F, 0xEB, _r},   {xmm64, xmm_m64}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(PSUBQ, MF_NONE, DU_U)
+BEGIN_OPCODES()
+#ifdef _HAVE_MMX_
+    {OpcodeInfo::all,   {0x0F, 0xFB, _r},   {mm64, mm_m64}, DU_U },
+#endif
+    {OpcodeInfo::all,   {0x66, 0x0F, 0xFB, _r},   {xmm64, xmm_m64}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(PANDN, MF_NONE, DU_U)
+BEGIN_OPCODES()
+#ifdef _HAVE_MMX_
+    {OpcodeInfo::all,   {0x0F, 0xDF, _r},   {mm64, mm_m64}, DU_U },
+#endif
+    {OpcodeInfo::all,   {0x66, 0x0F, 0xDF, _r}, {xmm64, xmm_m64},   DU_U },
+END_OPCODES()
+END_MNEMONIC()
+BEGIN_MNEMONIC(PSLLQ, MF_NONE, DU_U)
+BEGIN_OPCODES()
+#ifdef _HAVE_MMX_
+    {OpcodeInfo::all,   {0x0F, 0xF3, _r},   {mm64, mm_m64}, DU_U },
+#endif
+    {OpcodeInfo::all,   {0x66, 0x0F, 0xF3, _r}, {xmm64, xmm_m64},   DU_U },
+END_OPCODES()
+END_MNEMONIC()
+BEGIN_MNEMONIC(PSRLQ, MF_NONE, DU_U)
+BEGIN_OPCODES()
+#ifdef _HAVE_MMX_
+    {OpcodeInfo::all,   {0x0F, 0xD3, _r},   {mm64, mm_m64}, DU_U },
+#endif
+    {OpcodeInfo::all,   {0x66, 0x0F, 0xD3, _r}, {xmm64, xmm_m64},   DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(PXOR, MF_NONE, DU_U)
+BEGIN_OPCODES()
+#ifdef _HAVE_MMX_
+    {OpcodeInfo::all,   {0x0F, 0xEF, _r},   {mm64, mm_m64}, DU_U },
+#endif
+    {OpcodeInfo::all,   {0x66, 0x0F, 0xEF, _r}, {xmm64, xmm_m64},   DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(MOVAPD, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x66, 0x0F, 0x28, _r},   {xmm64, xmm_m64},   D_U },
+    {OpcodeInfo::all,   {0x66, 0x0F, 0x29, _r},   {xmm_m64, xmm64},   D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(MOVSD, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all, {0xF2, 0x0F, 0x10, _r},   {xmm64, xmm_m64},   D_U },
+    {OpcodeInfo::all, {0xF2, 0x0F, 0x11, _r},   {xmm_m64, xmm64},   D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(MOVSS, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all, {0xF3, 0x0F, 0x10, _r},   {xmm32, xmm_m32}, D_U },
+    {OpcodeInfo::all, {0xF3, 0x0F, 0x11, _r},   {xmm_m32, xmm32}, D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(MOVSX, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,       {Size16, 0x0F, 0xBE, _r}, {r16, r_m8s},     D_U },
+    {OpcodeInfo::all,       {0x0F, 0xBE, _r},         {r32, r_m8s},     D_U },
+    {OpcodeInfo::em64t,     {REX_W, 0x0F, 0xBE, _r},  {r64, r_m8s},     D_U },
+
+    {OpcodeInfo::all,       {0x0F, 0xBF, _r},         {r32, r_m16s},    D_U },
+    {OpcodeInfo::em64t,     {REX_W, 0x0F, 0xBF, _r},  {r64, r_m16s},    D_U },
+
+    {OpcodeInfo::em64t,     {REX_W, 0x63, _r},        {r64, r_m32s},    D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(MOVZX, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,       {Size16, 0x0F, 0xB6, _r}, {r16, r_m8u},     D_U },
+    {OpcodeInfo::all,       {0x0F, 0xB6, _r},         {r32, r_m8u},     D_U },
+    {OpcodeInfo::em64t,     {REX_W, 0x0F, 0xB6, _r},  {r64, r_m8u},     D_U },
+
+    {OpcodeInfo::all,       {0x0F, 0xB7, _r},         {r32, r_m16u},    D_U },
+    {OpcodeInfo::em64t,     {REX_W, 0x0F, 0xB7, _r},  {r64, r_m16u},    D_U },
+    //workaround to get r/rm32->r64 ZX mov functionality:
+    //simple 32bit reg copying zeros high bits in 64bit reg
+    {OpcodeInfo::em64t,     {0x8B, _r},               {r64, r_m32u},    D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(MULSD, MF_NONE, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF2, 0x0F, 0x59, _r}, {xmm64, xmm_m64},   DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(MULSS, MF_NONE, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF3, 0x0F, 0x59, _r}, {xmm32, xmm_m32}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(NEG, MF_AFFECTS_FLAGS, DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF6, _3},         {r_m8},         DU },
+
+    {OpcodeInfo::all,   {Size16, 0xF7, _3}, {r_m16},        DU },
+    {OpcodeInfo::all,   {0xF7, _3},         {r_m32},        DU },
+    {OpcodeInfo::em64t, {REX_W, 0xF7, _3},  {r_m64},        DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(NOP, MF_NONE, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x90}, {},     N },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(NOT, MF_AFFECTS_FLAGS, DU )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF6, _2},           {r_m8},         DU },
+    {OpcodeInfo::all,   {Size16, 0xF7, _2},   {r_m16},        DU },
+    {OpcodeInfo::all,   {0xF7, _2},           {r_m32},        DU },
+    {OpcodeInfo::em64t, {REX_W, 0xF7, _2},    {r_m64},        DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(POP, MF_NONE, D)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {Size16, 0x8F, _0}, {r_m16},    D },
+    {OpcodeInfo::ia32,  {0x8F, _0},         {r_m32},    D },
+    {OpcodeInfo::em64t, {0x8F, _0},         {r_m64},    D },
+
+    {OpcodeInfo::all,   {Size16, 0x58|rw }, {r16},      D },
+    {OpcodeInfo::ia32,  {0x58|rd },         {r32},      D },
+    {OpcodeInfo::em64t, {0x58|rd },         {r64},      D },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(POPFD, MF_AFFECTS_FLAGS, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x9D},     {},         N },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(PREFETCH, MF_NONE, U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x0F, 0x18, _0},   {m8},         U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(PUSH, MF_NONE, U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {Size16, 0xFF, _6}, {r_m16},    U },
+    {OpcodeInfo::ia32,  {0xFF, _6},         {r_m32},    U },
+    {OpcodeInfo::em64t, {0xFF, _6},         {r_m64},    U },
+
+    {OpcodeInfo::all,   {Size16, 0x50|rw }, {r16},      U },
+    {OpcodeInfo::ia32,  {0x50|rd },         {r32},      U },
+    {OpcodeInfo::em64t, {0x50|rd },         {r64},      U },
+
+    {OpcodeInfo::all,   {0x6A},         {imm8},     U },
+    {OpcodeInfo::all,   {Size16, 0x68}, {imm16},    U },
+    {OpcodeInfo::ia32,  {0x68},         {imm32},    U },
+//          {OpcodeInfo::em64t,   {0x68},   {imm64},    U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(PUSHFD, MF_USES_FLAGS, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x9C},             {},        N },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(RET, MF_NONE, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xC3},       {},         N },
+    {OpcodeInfo::all,   {0xC2, iw},   {imm16},    U },
+END_OPCODES()
+END_MNEMONIC()
+
+#define DEFINE_SETcc_MNEMONIC( cc ) \
+        BEGIN_MNEMONIC(SET##cc, MF_USES_FLAGS|MF_CONDITIONAL, DU) \
+BEGIN_OPCODES() \
+    {OpcodeInfo::all,   {0x0F,     0x90 + ConditionMnemonic_##cc}, {r_m8},  DU }, \
+END_OPCODES() \
+END_MNEMONIC()
+
+DEFINE_SETcc_MNEMONIC(O)
+DEFINE_SETcc_MNEMONIC(NO)
+DEFINE_SETcc_MNEMONIC(B)
+DEFINE_SETcc_MNEMONIC(NB)
+DEFINE_SETcc_MNEMONIC(Z)
+DEFINE_SETcc_MNEMONIC(NZ)
+DEFINE_SETcc_MNEMONIC(BE)
+DEFINE_SETcc_MNEMONIC(NBE)
+
+DEFINE_SETcc_MNEMONIC(S)
+DEFINE_SETcc_MNEMONIC(NS)
+DEFINE_SETcc_MNEMONIC(P)
+DEFINE_SETcc_MNEMONIC(NP)
+DEFINE_SETcc_MNEMONIC(L)
+DEFINE_SETcc_MNEMONIC(NL)
+DEFINE_SETcc_MNEMONIC(LE)
+DEFINE_SETcc_MNEMONIC(NLE)
+
+#undef DEFINE_SETcc_MNEMONIC
+
+#define DEFINE_SHIFT_MNEMONIC(nam, slash_num, flags) \
+BEGIN_MNEMONIC(nam, flags, DU_U) \
+BEGIN_OPCODES()\
+    /* D0 & D1 opcodes are added w/o 2nd operand (1) because */\
+    /* they are used for decoding only so only instruction length is needed */\
+    {OpcodeInfo::decoder,   {0xD0, slash_num},            {r_m8/*,const_1*/},   DU },\
+    {OpcodeInfo::all,       {0xD2, slash_num},              {r_m8,  CL},        DU_U },\
+    {OpcodeInfo::all,       {0xC0, slash_num, ib},          {r_m8,  imm8},      DU_U },\
+\
+    {OpcodeInfo::decoder,   {Size16, 0xD1, slash_num},    {r_m16/*,const_1*/},  DU },\
+    {OpcodeInfo::all,       {Size16, 0xD3, slash_num},      {r_m16, CL},        DU_U },\
+    {OpcodeInfo::all,       {Size16, 0xC1, slash_num, ib},  {r_m16, imm8 },     DU_U },\
+\
+    {OpcodeInfo::decoder,   {0xD1, slash_num},              {r_m32/*,const_1*/}, DU },\
+    {OpcodeInfo::decoder64, {REX_W, 0xD1, slash_num},       {r_m64/*,const_1*/}, DU },\
+\
+    {OpcodeInfo::all,       {0xD3, slash_num},              {r_m32, CL},        DU_U },\
+    {OpcodeInfo::em64t,     {REX_W, 0xD3, slash_num},       {r_m64, CL},        DU_U },\
+\
+    {OpcodeInfo::all,       {0xC1, slash_num, ib},          {r_m32, imm8},      DU_U },\
+    {OpcodeInfo::em64t,     {REX_W, 0xC1, slash_num, ib},   {r_m64, imm8},      DU_U },\
+END_OPCODES()\
+END_MNEMONIC()
+
+
+DEFINE_SHIFT_MNEMONIC(ROL, _0, MF_AFFECTS_FLAGS)
+DEFINE_SHIFT_MNEMONIC(ROR, _1, MF_AFFECTS_FLAGS)
+DEFINE_SHIFT_MNEMONIC(RCL, _2, MF_AFFECTS_FLAGS|MF_USES_FLAGS)
+DEFINE_SHIFT_MNEMONIC(RCR, _3, MF_AFFECTS_FLAGS|MF_USES_FLAGS)
+
+DEFINE_SHIFT_MNEMONIC(SAL, _4, MF_AFFECTS_FLAGS)
+DEFINE_SHIFT_MNEMONIC(SHR, _5, MF_AFFECTS_FLAGS)
+DEFINE_SHIFT_MNEMONIC(SAR, _7, MF_AFFECTS_FLAGS)
+
+#undef DEFINE_SHIFT_MNEMONIC
+
+BEGIN_MNEMONIC(SHLD, MF_AFFECTS_FLAGS, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x0F, 0xA5},   {r_m32, r32, CL}, DU_DU_U },
+    {OpcodeInfo::all,   {0x0F, 0xA4},   {r_m32, r32, imm8}, DU_DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(SHRD, MF_AFFECTS_FLAGS, N)
+// TODO: the def/use info is wrong
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x0F, 0xAD},   {r_m32, r32, CL}, DU_DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(SUBSD, MF_NONE, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF2, 0x0F, 0x5C, _r}, {xmm64, xmm_m64}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(SUBSS, MF_NONE, DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xF3, 0x0F, 0x5C, _r}, {xmm32, xmm_m32}, DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(TEST, MF_AFFECTS_FLAGS, U_U)
+BEGIN_OPCODES()
+
+    {OpcodeInfo::decoder,   {0xA8, ib},             { AL, imm8},    U_U },
+    {OpcodeInfo::decoder,   {0xA9, iw},             { AX, imm16},   U_U },
+    {OpcodeInfo::decoder,   {0xA9, id},             { EAX, imm32},  U_U },
+    {OpcodeInfo::decoder64, {REX_W, 0xA9, id},      { RAX, imm32s}, U_U },
+
+    {OpcodeInfo::all,       {0xF6, _0, ib},         {r_m8,imm8},    U_U },
+
+    {OpcodeInfo::all,       {Size16, 0xF7, _0, iw}, {r_m16,imm16},  U_U },
+    {OpcodeInfo::all,       {0xF7, _0, id},         {r_m32,imm32},  U_U },
+    {OpcodeInfo::em64t,     {REX_W, 0xF7, _0, id},  {r_m64,imm32s}, U_U },
+
+    {OpcodeInfo::all,       {0x84, _r},             {r_m8,r8},      U_U },
+
+    {OpcodeInfo::all,       {Size16, 0x85, _r},     {r_m16,r16},    U_U },
+    {OpcodeInfo::all,       {0x85, _r},             {r_m32,r32},    U_U },
+    {OpcodeInfo::em64t,     {REX_W, 0x85, _r},      {r_m64,r64},    U_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(UCOMISD, MF_AFFECTS_FLAGS, U_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x66, 0x0F, 0x2E, _r}, {xmm64, xmm_m64}, U_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(UCOMISS, MF_AFFECTS_FLAGS, U_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x0F, 0x2E, _r},       {xmm32, xmm_m32}, U_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(COMISD, MF_AFFECTS_FLAGS, U_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x66, 0x0F, 0x2F, _r}, {xmm64, xmm_m64}, U_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(COMISS, MF_AFFECTS_FLAGS, U_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x0F, 0x2F, _r},       {xmm32, xmm_m32}, U_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(XORPD, MF_SAME_ARG_NO_USE|MF_SYMMETRIC, DU_U)
+BEGIN_OPCODES()
+    //Note: they're actually 128 bits
+    {OpcodeInfo::all,   {0x66, 0x0F, 0x57, _r},   {xmm64, xmm_m64},   DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(XORPS, MF_SAME_ARG_NO_USE|MF_SYMMETRIC, DU_U)
+BEGIN_OPCODES()
+    //Note: they're actually 128 bits
+    {OpcodeInfo::all,   {0x0F, 0x57, _r},   {xmm32, xmm_m32},       DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CVTDQ2PD, MF_NONE, D_U )
+BEGIN_OPCODES()
+    //Note: they're actually 128 bits
+    {OpcodeInfo::all,   {0xF3, 0x0F, 0xE6}, {xmm64, xmm_m64},   D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CVTDQ2PS, MF_NONE, D_U )
+BEGIN_OPCODES()
+    //Note: they're actually 128 bits
+    {OpcodeInfo::all,   {0x0F, 0x5B, _r},   {xmm32, xmm_m32},   D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CVTTPD2DQ, MF_NONE, D_U )
+BEGIN_OPCODES()
+    //Note: they're actually 128 bits
+    {OpcodeInfo::all,   {0x66, 0x0F, 0xE6}, {xmm64, xmm_m64},   D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CVTTPS2DQ, MF_NONE, D_U )
+BEGIN_OPCODES()
+    //Note: they're actually 128 bits
+    {OpcodeInfo::all,   {0xF3, 0x0F, 0x5B, _r},   {xmm32, xmm_m32},   D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+//
+// String operations
+//
+BEGIN_MNEMONIC(STD, MF_AFFECTS_FLAGS, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xFD},         {},     N },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CLD, MF_AFFECTS_FLAGS, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xFC},         {},     N },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(SCAS, MF_AFFECTS_FLAGS, N)
+// to be symmetric, this mnemonic must have either m32 or RegName_EAX
+// but as long, as Jitrino's CG does not use the mnemonic, leaving it
+// in its natural form
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xAF},         {},     N },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(STOS, MF_AFFECTS_FLAGS, DU_DU_U)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0xAB},         {EDI, ECX, EAX},   DU_DU_U },
+    {OpcodeInfo::all,   {0xAA},         {EDI, ECX, AL},    DU_DU_U },
+    {OpcodeInfo::em64t, {REX_W, 0xAB},  {RDI, RCX, RAX},   DU_DU_U },
+END_OPCODES()
+END_MNEMONIC()
+
+/*
+MOVS and CMPS are the special cases.
+Most the code in both CG and Encoder do not expect 2 memory operands.
+Also, they are not supposed to setup constrains on which register the
+memory reference must reside - m8,m8 or m32,m32 is not the choice.
+We can't use r8,r8 either - will have problem with 8bit EDI, ESI.
+So, as the workaround we do r32,r32 and specify size of the operand through
+the specific mnemonic - the same is in the codegen.
+*/
+BEGIN_MNEMONIC(MOVS8, MF_NONE, DU_DU_DU)
+BEGIN_OPCODES()
+    {OpcodeInfo::ia32,  {0xA4},         {r32,r32,ECX},    DU_DU_DU },
+    {OpcodeInfo::em64t, {0xA4},         {r64,r64,RCX},    DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(MOVS16, MF_NONE, DU_DU_DU)
+BEGIN_OPCODES()
+    {OpcodeInfo::ia32,  {Size16, 0xA5}, {r32,r32,ECX},  DU_DU_DU },
+    {OpcodeInfo::em64t, {Size16, 0xA5}, {r64,r64,RCX},  DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(MOVS32, MF_NONE, DU_DU_DU)
+BEGIN_OPCODES()
+    {OpcodeInfo::ia32,  {0xA5},         {r32,r32,ECX},  DU_DU_DU },
+    {OpcodeInfo::em64t, {0xA5},         {r64,r64,RCX},  DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(MOVS64, MF_NONE, DU_DU_DU)
+BEGIN_OPCODES()
+    {OpcodeInfo::em64t, {REX_W,0xA5},   {r64,r64,RCX},  DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CMPSB, MF_AFFECTS_FLAGS, DU_DU_DU)
+BEGIN_OPCODES()
+    {OpcodeInfo::ia32,  {0xA6},         {ESI,EDI,ECX},    DU_DU_DU },
+    {OpcodeInfo::em64t, {0xA6},         {RSI,RDI,RCX},    DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CMPSW, MF_AFFECTS_FLAGS, DU_DU_DU)
+BEGIN_OPCODES()
+    {OpcodeInfo::ia32,  {Size16, 0xA7}, {ESI,EDI,ECX},  DU_DU_DU },
+    {OpcodeInfo::em64t, {Size16, 0xA7}, {RSI,RDI,RCX},  DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CMPSD, MF_AFFECTS_FLAGS, DU_DU_DU)
+BEGIN_OPCODES()
+    {OpcodeInfo::ia32,  {0xA7},         {ESI,EDI,ECX},  DU_DU_DU },
+    {OpcodeInfo::em64t, {0xA7},         {RSI,RDI,RCX},  DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+
+BEGIN_MNEMONIC(WAIT, MF_AFFECTS_FLAGS, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::all,   {0x9B},         {},       N },
+END_OPCODES()
+END_MNEMONIC()
+
+//
+// ~String operations
+//
+
+//
+//Note: the instructions below added for the sake of disassembling routine.
+// They need to have flags, params and params usage to be defined more precisely.
+//
+BEGIN_MNEMONIC(LEAVE, MF_NONE, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::decoder,   {0xC9},         {},       N },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(ENTER, MF_NONE, N)
+BEGIN_OPCODES()
+    {OpcodeInfo::decoder,   {0xC8, iw, ib},           {imm16, imm8},  N },
+END_OPCODES()
+END_MNEMONIC()
+
+};      // ~masterEncodingTable[]
+
+ENCODER_NAMESPACE_END
+
+//#include <algorithm>
+
+ENCODER_NAMESPACE_START
+
+static bool mnemonic_info_comparator(const MnemonicInfo& one,
+                                     const MnemonicInfo& two)
+{
+    return one.mn < two.mn;
+}
+
+
+static int compareMnemonicInfo(const void* info1, const void* info2)
+{
+    Mnemonic id1, id2;
+
+    id1 = ((const MnemonicInfo*) info1)->mn;
+    id2 = ((const MnemonicInfo*) info2)->mn;
+    if (id1 < id2)
+        return -1;
+    if (id1 > id2)
+        return 1;
+    return 0;
+}
+
+int EncoderBase::buildTable(void)
+{
+    // A check: all mnemonics must be covered
+    assert(COUNTOF(masterEncodingTable) == Mnemonic_Count);
+    // sort out the mnemonics so the list become ordered
+#if 0 //Android x86
+    std::sort(masterEncodingTable, masterEncodingTable+Mnemonic_Count,
+              mnemonic_info_comparator);
+#else
+    qsort(masterEncodingTable, Mnemonic_Count, sizeof(MnemonicInfo), compareMnemonicInfo);
+#endif
+    //
+    // clear the things
+    //
+    memset(opcodesHashMap, NOHASH, sizeof(opcodesHashMap));
+    memset(opcodes, 0, sizeof(opcodes));
+    //
+    // and, finally, build it
+    for (unsigned i=0; i<Mnemonic_Count; i++) {
+        assert((Mnemonic)i == (masterEncodingTable + i)->mn);
+        buildMnemonicDesc(masterEncodingTable+i);
+    }
+    return 0;
+}
+
+void EncoderBase::buildMnemonicDesc(const MnemonicInfo * minfo)
+{
+    MnemonicDesc& mdesc = mnemonics[minfo->mn];
+    mdesc.mn = minfo->mn;
+    mdesc.flags = minfo->flags;
+    mdesc.roles = minfo->roles;
+    mdesc.name = minfo->name;
+
+    //
+    // fill the used opcodes
+    //
+    for (unsigned i=0, oindex=0; i<COUNTOF(minfo->opcodes); i++) {
+
+        const OpcodeInfo& oinfo = minfo->opcodes[i];
+        OpcodeDesc& odesc = opcodes[minfo->mn][oindex];
+        // last opcode ?
+        if (oinfo.opcode[0] == OpcodeByteKind_LAST) {
+            // mark the opcode 'last', exit
+            odesc.opcode_len = 0;
+            odesc.last = 1;
+            break;
+        }
+        odesc.last = 0;
+#ifdef _EM64T_
+        if (oinfo.platf == OpcodeInfo::ia32) { continue; }
+        if (oinfo.platf == OpcodeInfo::decoder32) { continue; }
+#else
+        if (oinfo.platf == OpcodeInfo::em64t) { continue; }
+        if (oinfo.platf == OpcodeInfo::decoder64) { continue; }
+#endif
+        if (oinfo.platf == OpcodeInfo::decoder64 ||
+            oinfo.platf == OpcodeInfo::decoder32) {
+             odesc.platf = OpcodeInfo::decoder;
+        }
+        else {
+            odesc.platf = (char)oinfo.platf;
+        }
+        //
+        // fill out opcodes
+        //
+        unsigned j = 0;
+        odesc.opcode_len = 0;
+        for(; oinfo.opcode[j]; j++) {
+            unsigned opcod = oinfo.opcode[j];
+            unsigned kind = opcod&OpcodeByteKind_KindMask;
+            if (kind == OpcodeByteKind_REX_W) {
+                odesc.opcode[odesc.opcode_len++] = (unsigned char)0x48;
+                continue;
+            }
+            else if(kind != 0 && kind != OpcodeByteKind_ZeroOpcodeByte) {
+                break;
+            }
+            unsigned lowByte = (opcod & OpcodeByteKind_OpcodeMask);
+            odesc.opcode[odesc.opcode_len++] = (unsigned char)lowByte;
+        }
+        assert(odesc.opcode_len<5);
+        odesc.aux0 = odesc.aux1 = 0;
+        if (oinfo.opcode[j] != 0) {
+            odesc.aux0 = oinfo.opcode[j];
+            assert((odesc.aux0 & OpcodeByteKind_KindMask) != 0);
+            ++j;
+            if(oinfo.opcode[j] != 0) {
+                odesc.aux1 = oinfo.opcode[j];
+                assert((odesc.aux1 & OpcodeByteKind_KindMask) != 0);
+            }
+        }
+        else if (oinfo.roles.count>=2) {
+            if (((oinfo.opnds[0].kind&OpndKind_Mem) &&
+                 (isRegKind(oinfo.opnds[1].kind))) ||
+                ((oinfo.opnds[1].kind&OpndKind_Mem) &&
+                 (isRegKind(oinfo.opnds[0].kind)))) {
+                 // Example: MOVQ xmm1, xmm/m64 has only opcodes
+                 // same with SHRD
+                 // Adding fake /r
+                 odesc.aux0 = _r;
+            }
+        }
+        else if (oinfo.roles.count==1) {
+            if (oinfo.opnds[0].kind&OpndKind_Mem) {
+                 // Example: SETcc r/m8, adding fake /0
+                 odesc.aux0 = _0;
+            }
+        }
+        // check imm
+        if (oinfo.roles.count > 0 &&
+            (oinfo.opnds[0].kind == OpndKind_Imm ||
+            oinfo.opnds[oinfo.roles.count-1].kind == OpndKind_Imm)) {
+            // Example: CALL cd, PUSH imm32 - they fit both opnds[0] and
+            // opnds[oinfo.roles.count-1].
+            // The A3 opcode fits only opnds[0] - it's currently have
+            // MOV imm32, EAX. Looks ridiculous, but this is how the
+            // moffset is currently implemented. Will need to fix together
+            // with other usages of moff.
+            // adding fake /cd or fake /id
+            unsigned imm_opnd_index =
+                oinfo.opnds[0].kind == OpndKind_Imm ? 0 : oinfo.roles.count-1;
+            OpndSize sz = oinfo.opnds[imm_opnd_index].size;
+            unsigned imm_encode, coff_encode;
+            if (sz==OpndSize_8) {imm_encode = ib; coff_encode=cb; }
+            else if (sz==OpndSize_16) {imm_encode = iw; coff_encode=cw;}
+            else if (sz==OpndSize_32) {imm_encode = id; coff_encode=cd; }
+            else if (sz==OpndSize_64) {imm_encode = io; coff_encode=0xCC; }
+            else { assert(false); imm_encode=0xCC; coff_encode=0xCC; }
+            if (odesc.aux1 == 0) {
+                if (odesc.aux0==0) {
+                    odesc.aux0 = imm_encode;
+                }
+                else {
+                    if (odesc.aux0 != imm_encode && odesc.aux0 != coff_encode) {
+                        odesc.aux1 = imm_encode;
+                    }
+                }
+            }
+            else {
+                assert(odesc.aux1==imm_encode);
+            }
+
+        }
+
+        assert(sizeof(odesc.opnds) == sizeof(oinfo.opnds));
+        memcpy(odesc.opnds, oinfo.opnds, sizeof(odesc.opnds));
+        odesc.roles = oinfo.roles;
+        odesc.first_opnd = 0;
+        if (odesc.opnds[0].reg != RegName_Null) {
+            ++odesc.first_opnd;
+            if (odesc.opnds[1].reg != RegName_Null) {
+                ++odesc.first_opnd;
+            }
+        }
+
+        if (odesc.platf == OpcodeInfo::decoder) {
+            // if the opcode is only for decoding info, then do not hash it.
+            ++oindex;
+            continue;
+        }
+
+        //
+        // check whether the operand info is a mask (i.e. r_m*).
+        // in this case, split the info to have separate entries for 'r'
+        // and for 'm'.
+        // the good news is that there can be only one such operand.
+        //
+        int opnd2split = -1;
+        for (unsigned k=0; k<oinfo.roles.count; k++) {
+            if ((oinfo.opnds[k].kind & OpndKind_Mem) &&
+                (OpndKind_Mem != oinfo.opnds[k].kind)) {
+                opnd2split = k;
+                break;
+            }
+        };
+
+        if (opnd2split == -1) {
+            // not a mask, hash it, store it, continue.
+            unsigned short hash = getHash(&oinfo);
+            opcodesHashMap[minfo->mn][hash] = (unsigned char)oindex;
+            ++oindex;
+            continue;
+        };
+
+        OpcodeInfo storeItem = oinfo;
+        unsigned short hash;
+
+        // remove the memory part of the mask, and store only 'r' part
+        storeItem.opnds[opnd2split].kind = (OpndKind)(storeItem.opnds[opnd2split].kind & ~OpndKind_Mem);
+        hash = getHash(&storeItem);
+        if (opcodesHashMap[minfo->mn][hash] == NOHASH) {
+            opcodesHashMap[minfo->mn][hash] = (unsigned char)oindex;
+        }
+        // else {
+        // do not overwrite if there is something there, just check that operands match
+        // the reason is that for some instructions there are several possibilities:
+        // say 'DEC r' may be encode as either '48+r' or 'FF /1', and I believe
+        // the first one is better for 'dec r'.
+        // as we're currently processing an opcode with memory part in operand,
+        // leave already filled items intact, so if there is 'OP reg' there, this
+        // better choice will be left in the table instead of 'OP r_m'
+        // }
+
+        // compute hash of memory-based operand, 'm' part in 'r_m'
+        storeItem.opnds[opnd2split].kind = OpndKind_Mem;
+        hash = getHash(&storeItem);
+        // should not happen: for the r_m opcodes, there is a possibility
+        // that hash value of 'r' part intersects with 'OP r' value, but it's
+        // impossible for 'm' part.
+        assert(opcodesHashMap[minfo->mn][hash] == NOHASH);
+        opcodesHashMap[minfo->mn][hash] = (unsigned char)oindex;
+
+        ++oindex;
+    }
+}
+
+ENCODER_NAMESPACE_END
diff --git a/vm/compiler/codegen/x86/libenc/enc_wrapper.cpp b/vm/compiler/codegen/x86/libenc/enc_wrapper.cpp
new file mode 100644
index 0000000..cf53cea
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/enc_wrapper.cpp
@@ -0,0 +1,558 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include "enc_base.h"
+#include "enc_wrapper.h"
+#include "dec_base.h"
+#include "utils/Log.h"
+
+//#define PRINT_ENCODER_STREAM
+bool dump_x86_inst = false;
+//map_reg
+const RegName map_of_regno_2_regname[] = {
+    RegName_EAX,    RegName_EBX,    RegName_ECX,    RegName_EDX,
+    RegName_EDI,    RegName_ESI,    RegName_ESP,    RegName_EBP,
+    RegName_XMM0,   RegName_XMM1,   RegName_XMM2,   RegName_XMM3,
+    RegName_XMM4,   RegName_XMM5,   RegName_XMM6,   RegName_XMM7,
+    RegName_Null,   RegName_Null,   RegName_Null,   RegName_Null,
+    RegName_Null,   RegName_Null,   RegName_Null,   RegName_Null,
+    RegName_Null,
+    RegName_Null,   RegName_Null,   RegName_Null,   RegName_Null,   RegName_Null,
+    RegName_Null,   RegName_Null,   RegName_Null,   RegName_Null,
+    RegName_Null,   RegName_Null,   RegName_Null,   RegName_Null,
+    RegName_Null,   RegName_Null,   //SCRATCH
+    RegName_Null,   RegName_Null,   RegName_Null,   RegName_Null
+};
+
+//getRegSize, getAliasReg:
+//OpndSize, RegName, OpndExt: enum enc_defs.h
+inline void add_r(EncoderBase::Operands & args, int physicalReg, OpndSize sz, OpndExt ext = OpndExt_None) {
+    RegName reg = map_of_regno_2_regname[physicalReg];
+    if (sz != getRegSize(reg)) {
+       reg = getAliasReg(reg, sz);
+    }
+    args.add(EncoderBase::Operand(reg, ext));
+}
+inline void add_m(EncoderBase::Operands & args, int baseReg, int disp, OpndSize sz, OpndExt ext = OpndExt_None) {
+    args.add(EncoderBase::Operand(sz,
+                                  map_of_regno_2_regname[baseReg],
+                                  RegName_Null, 0,
+                                  disp, ext));
+}
+inline void add_m_scale(EncoderBase::Operands & args, int baseReg, int indexReg, int scale,
+                        OpndSize sz, OpndExt ext = OpndExt_None) {
+    args.add(EncoderBase::Operand(sz,
+                                  map_of_regno_2_regname[baseReg],
+                                  map_of_regno_2_regname[indexReg], scale,
+                                  0, ext));
+}
+inline void add_m_disp_scale(EncoderBase::Operands & args, int baseReg, int disp, int indexReg, int scale,
+                        OpndSize sz, OpndExt ext = OpndExt_None) {
+    args.add(EncoderBase::Operand(sz,
+                                  map_of_regno_2_regname[baseReg],
+                                  map_of_regno_2_regname[indexReg], scale,
+                                  disp, ext));
+}
+
+inline void add_fp(EncoderBase::Operands & args, unsigned i, bool dbl) {
+    return args.add((RegName)( (dbl ? RegName_FP0D : RegName_FP0S) + i));
+}
+inline void add_imm(EncoderBase::Operands & args, OpndSize sz, int value, bool is_signed) {
+    //assert(n_size != imm.get_size());
+    args.add(EncoderBase::Operand(sz, value,
+             is_signed ? OpndExt_Signed : OpndExt_Zero));
+}
+
+#define MAX_DECODED_STRING_LEN 1024
+char tmpBuffer[MAX_DECODED_STRING_LEN];
+
+void printOperand(const EncoderBase::Operand & opnd) {
+    unsigned int sz;
+    if(!dump_x86_inst) return;
+    sz = strlen(tmpBuffer);
+    if(opnd.size() != OpndSize_32) {
+        sz += snprintf(&tmpBuffer[sz], MAX_DECODED_STRING_LEN-sz, "%s ",
+                       getOpndSizeString(opnd.size()));
+    }
+    if(opnd.is_mem()) {
+        if(opnd.scale() != 0) {
+            sz += snprintf(&tmpBuffer[sz], MAX_DECODED_STRING_LEN-sz,
+                           "%d(%s,%s,%d)", opnd.disp(),
+                           getRegNameString(opnd.base()),
+                           getRegNameString(opnd.index()), opnd.scale());
+        } else {
+            sz += snprintf(&tmpBuffer[sz], MAX_DECODED_STRING_LEN-sz, "%d(%s)",
+                           opnd.disp(), getRegNameString(opnd.base()));
+        }
+    }
+    if(opnd.is_imm()) {
+        sz += snprintf(&tmpBuffer[sz], MAX_DECODED_STRING_LEN-sz, "#%x",
+                       (int)opnd.imm());
+    }
+    if(opnd.is_reg()) {
+        sz += snprintf(&tmpBuffer[sz], MAX_DECODED_STRING_LEN-sz, "%s",
+                       getRegNameString(opnd.reg()));
+    }
+}
+//TODO: the order of operands
+//to make the printout have the same order as assembly in .S
+//I reverse the order here
+void printDecoderInst(Inst & decInst) {
+    unsigned int sz;
+    if(!dump_x86_inst) return;
+    sz = strlen(tmpBuffer);
+    sz += snprintf(&tmpBuffer[sz], MAX_DECODED_STRING_LEN-sz, "%s ",
+                   EncoderBase::toStr(decInst.mn));
+    for(unsigned int k = 0; k < decInst.argc; k++) {
+        if(k > 0) {
+            sz = strlen(tmpBuffer);
+            sz += snprintf(&tmpBuffer[sz], MAX_DECODED_STRING_LEN-sz, ", ");
+        }
+        printOperand(decInst.operands[decInst.argc-1-k]);
+    }
+    ALOGE("%s", tmpBuffer);
+}
+void printOperands(EncoderBase::Operands& opnds) {
+    unsigned int sz;
+    if(!dump_x86_inst) return;
+    for(unsigned int k = 0; k < opnds.count(); k++) {
+        if(k > 0) {
+            sz = strlen(tmpBuffer);
+            sz += snprintf(&tmpBuffer[sz], MAX_DECODED_STRING_LEN-sz, ", ");
+        }
+        printOperand(opnds[opnds.count()-1-k]);
+    }
+}
+void printEncoderInst(Mnemonic m, EncoderBase::Operands& opnds) {
+    if(!dump_x86_inst) return;
+    snprintf(tmpBuffer, MAX_DECODED_STRING_LEN, "--- ENC %s ",
+             EncoderBase::toStr(m));
+    printOperands(opnds);
+    ALOGE("%s", tmpBuffer);
+}
+int decodeThenPrint(char* stream_start) {
+    if(!dump_x86_inst) return 0;
+    snprintf(tmpBuffer, MAX_DECODED_STRING_LEN, "--- INST @ %p: ",
+             stream_start);
+    Inst decInst;
+    unsigned numBytes = DecoderBase::decode(stream_start, &decInst);
+    printDecoderInst(decInst);
+    return numBytes;
+}
+
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_imm(Mnemonic m, OpndSize size, int imm, char * stream) {
+    EncoderBase::Operands args;
+    //assert(imm.get_size() == size_32);
+    add_imm(args, size, imm, true/*is_signed*/);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT unsigned encoder_get_inst_size(char * stream) {
+    Inst decInst;
+    unsigned numBytes = DecoderBase::decode(stream, &decInst);
+    return numBytes;
+}
+
+extern "C" ENCODER_DECLARE_EXPORT unsigned encoder_get_cur_operand_offset(int opnd_id)
+{
+    return (unsigned)EncoderBase::getOpndLocation(opnd_id);
+}
+
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_update_imm(int imm, char * stream) {
+    Inst decInst;
+    unsigned numBytes = DecoderBase::decode(stream, &decInst);
+    EncoderBase::Operands args;
+    //assert(imm.get_size() == size_32);
+    add_imm(args, decInst.operands[0].size(), imm, true/*is_signed*/);
+    char* stream_next = (char *)EncoderBase::encode(stream, decInst.mn, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(decInst.mn, args);
+    decodeThenPrint(stream);
+#endif
+    return stream_next;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_mem(Mnemonic m, OpndSize size,
+               int disp, int base_reg, bool isBasePhysical, char * stream) {
+    EncoderBase::Operands args;
+    add_m(args, base_reg, disp, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_reg(Mnemonic m, OpndSize size,
+               int reg, bool isPhysical, LowOpndRegType type, char * stream) {
+    EncoderBase::Operands args;
+    if(m == Mnemonic_IDIV || m == Mnemonic_MUL || m == Mnemonic_IMUL) {
+      add_r(args, 0/*eax*/, size);
+      add_r(args, 3/*edx*/, size);
+    }
+    add_r(args, reg, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+//both operands have same size
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_reg_reg(Mnemonic m, OpndSize size,
+                   int reg, bool isPhysical,
+                   int reg2, bool isPhysical2, LowOpndRegType type, char * stream) {
+    if((m == Mnemonic_MOV || m == Mnemonic_MOVQ) && reg == reg2) return stream;
+    EncoderBase::Operands args;
+    add_r(args, reg2, size); //destination
+    if(m == Mnemonic_SAL || m == Mnemonic_SHR || m == Mnemonic_SHL || m == Mnemonic_SAR)
+      add_r(args, reg, OpndSize_8);
+    else
+      add_r(args, reg, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_mem_reg(Mnemonic m, OpndSize size,
+                   int disp, int base_reg, bool isBasePhysical,
+                   int reg, bool isPhysical, LowOpndRegType type, char * stream) {
+    EncoderBase::Operands args;
+    add_r(args, reg, size);
+    add_m(args, base_reg, disp, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_mem_scale_reg(Mnemonic m, OpndSize size,
+                         int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale,
+                         int reg, bool isPhysical, LowOpndRegType type, char * stream) {
+    EncoderBase::Operands args;
+    add_r(args, reg, size);
+    add_m_scale(args, base_reg, index_reg, scale, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_reg_mem_scale(Mnemonic m, OpndSize size,
+                         int reg, bool isPhysical,
+                         int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale,
+                         LowOpndRegType type, char * stream) {
+    EncoderBase::Operands args;
+    add_m_scale(args, base_reg, index_reg, scale, size);
+    add_r(args, reg, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_mem_disp_scale_reg(Mnemonic m, OpndSize size,
+                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                         int reg, bool isPhysical, LowOpndRegType type, char * stream) {
+    EncoderBase::Operands args;
+    add_r(args, reg, size);
+    add_m_disp_scale(args, base_reg, disp, index_reg, scale, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_movzs_mem_disp_scale_reg(Mnemonic m, OpndSize size,
+                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                         int reg, bool isPhysical, LowOpndRegType type, char * stream) {
+    EncoderBase::Operands args;
+    add_r(args, reg, OpndSize_32);
+    add_m_disp_scale(args, base_reg, disp, index_reg, scale, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+
+extern "C" ENCODER_DECLARE_EXPORT char* encoder_reg_mem_disp_scale(Mnemonic m, OpndSize size,
+                         int reg, bool isPhysical,
+                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                         LowOpndRegType type, char* stream) {
+    EncoderBase::Operands args;
+    add_m_disp_scale(args, base_reg, disp, index_reg, scale, size);
+    add_r(args, reg, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_reg_mem(Mnemonic m, OpndSize size,
+                   int reg, bool isPhysical,
+                   int disp, int base_reg, bool isBasePhysical, LowOpndRegType type, char * stream) {
+    EncoderBase::Operands args;
+    add_m(args, base_reg, disp, size);
+    add_r(args, reg, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_imm_reg(Mnemonic m, OpndSize size,
+                   int imm, int reg, bool isPhysical, LowOpndRegType type, char * stream) {
+    EncoderBase::Operands args;
+    add_r(args, reg, size); //dst
+    if(m == Mnemonic_IMUL) add_r(args, reg, size); //src CHECK
+    if(m == Mnemonic_SAL || m == Mnemonic_SHR || m == Mnemonic_SHL
+       || m == Mnemonic_SAR || m == Mnemonic_ROR)  //fix for shift opcodes
+      add_imm(args, OpndSize_8, imm, true/*is_signed*/);
+    else
+      add_imm(args, size, imm, true/*is_signed*/);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_update_imm_rm(int imm, char * stream) {
+    Inst decInst;
+    unsigned numBytes = DecoderBase::decode(stream, &decInst);
+    EncoderBase::Operands args;
+    args.add(decInst.operands[0]);
+    add_imm(args, decInst.operands[1].size(), imm, true/*is_signed*/);
+    char* stream_next = (char *)EncoderBase::encode(stream, decInst.mn, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(decInst.mn, args);
+    decodeThenPrint(stream);
+#endif
+    return stream_next;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_imm_mem(Mnemonic m, OpndSize size,
+                   int imm,
+                   int disp, int base_reg, bool isBasePhysical, char * stream) {
+    EncoderBase::Operands args;
+    add_m(args, base_reg, disp, size);
+    if (m == Mnemonic_SAL || m == Mnemonic_SHR || m == Mnemonic_SHL
+        || m == Mnemonic_SAR || m == Mnemonic_ROR)
+        size = OpndSize_8;
+    add_imm(args, size, imm, true);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_fp_mem(Mnemonic m, OpndSize size, int reg,
+                  int disp, int base_reg, bool isBasePhysical, char * stream) {
+    EncoderBase::Operands args;
+    add_m(args, base_reg, disp, size);
+    // a fake FP register as operand
+    add_fp(args, reg, size == OpndSize_64/*is_double*/);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_mem_fp(Mnemonic m, OpndSize size,
+                  int disp, int base_reg, bool isBasePhysical,
+                  int reg, char * stream) {
+    EncoderBase::Operands args;
+    // a fake FP register as operand
+    add_fp(args, reg, size == OpndSize_64/*is_double*/);
+    add_m(args, base_reg, disp, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_return(char * stream) {
+    EncoderBase::Operands args;
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, Mnemonic_RET, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(Mnemonic_RET, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_compare_fp_stack(bool pop, int reg, bool isDouble, char * stream) {
+    //Mnemonic m = pop ? Mnemonic_FUCOMP : Mnemonic_FUCOM;
+    Mnemonic m = pop ? Mnemonic_FUCOMIP : Mnemonic_FUCOMI;
+    //a single operand or 2 operands?
+    //FST ST(i) has a single operand in encoder.inl?
+    EncoderBase::Operands args;
+    add_fp(args, reg, isDouble);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, m, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(m, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_movez_mem_to_reg(OpndSize size,
+                      int disp, int base_reg, bool isBasePhysical,
+                      int reg, bool isPhysical, char * stream) {
+    EncoderBase::Operands args;
+    add_r(args, reg, OpndSize_32);
+    add_m(args, base_reg, disp, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, Mnemonic_MOVZX, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(Mnemonic_MOVZX, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_moves_mem_to_reg(OpndSize size,
+                      int disp, int base_reg, bool isBasePhysical,
+                      int reg, bool isPhysical, char * stream) {
+    EncoderBase::Operands args;
+    add_r(args, reg, OpndSize_32);
+    add_m(args, base_reg, disp, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, Mnemonic_MOVSX, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(Mnemonic_MOVSX, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_movez_reg_to_reg(OpndSize size,
+                      int reg, bool isPhysical, int reg2,
+                      bool isPhysical2, LowOpndRegType type, char * stream) {
+    EncoderBase::Operands args;
+    add_r(args, reg2, OpndSize_32); //destination
+    add_r(args, reg, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, Mnemonic_MOVZX, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(Mnemonic_MOVZX, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+extern "C" ENCODER_DECLARE_EXPORT char * encoder_moves_reg_to_reg(OpndSize size,
+                      int reg, bool isPhysical,int reg2,
+                      bool isPhysical2, LowOpndRegType type, char * stream) {
+    EncoderBase::Operands args;
+    add_r(args, reg2, OpndSize_32); //destination
+    add_r(args, reg, size);
+    char* stream_start = stream;
+    stream = (char *)EncoderBase::encode(stream, Mnemonic_MOVSX, args);
+#ifdef PRINT_ENCODER_STREAM
+    printEncoderInst(Mnemonic_MOVSX, args);
+    decodeThenPrint(stream_start);
+#endif
+    return stream;
+}
+
+// Disassemble the operand "opnd" and put the readable format in "strbuf"
+// up to a string length of "len".
+unsigned int DisassembleOperandToBuf(const EncoderBase::Operand& opnd, char* strbuf, unsigned int len)
+{
+    unsigned int sz = 0;
+    if(opnd.size() != OpndSize_32) {
+        sz += snprintf(&strbuf[sz], len-sz, "%s ",
+                       getOpndSizeString(opnd.size()));
+    }
+    if(opnd.is_mem()) {
+        if(opnd.scale() != 0) {
+            sz += snprintf(&strbuf[sz], len-sz, "%d(%s,%s,%d)", opnd.disp(),
+                           getRegNameString(opnd.base()),
+                           getRegNameString(opnd.index()), opnd.scale());
+        } else {
+            sz += snprintf(&strbuf[sz], len-sz, "%d(%s)",
+                           opnd.disp(), getRegNameString(opnd.base()));
+        }
+    } else if(opnd.is_imm()) {
+        sz += snprintf(&strbuf[sz], len-sz, "#%x", (int)opnd.imm());
+    } else if(opnd.is_reg()) {
+        sz += snprintf(&strbuf[sz], len-sz, "%s",
+                       getRegNameString(opnd.reg()));
+    }
+    return sz;
+}
+
+// Disassemble the instruction "decInst" and put the readable format
+// in "strbuf" up to a string length of "len".
+void DisassembleInstToBuf(Inst& decInst, char* strbuf, unsigned int len)
+{
+    unsigned int sz = 0;
+    int k;
+    sz += snprintf(&strbuf[sz], len-sz, "%s ", EncoderBase::toStr(decInst.mn));
+    if (decInst.argc > 0) {
+        sz += DisassembleOperandToBuf(decInst.operands[decInst.argc-1],
+                                 &strbuf[sz], len-sz);
+        for(k = decInst.argc-2; k >= 0; k--) {
+            sz += snprintf(&strbuf[sz], len-sz, ", ");
+            sz += DisassembleOperandToBuf(decInst.operands[k], &strbuf[sz], len-sz);
+        }
+    }
+}
+
+// Disassmble the x86 instruction pointed to by code pointer "stream."
+// Put the disassemble text in the "strbuf" up to string length "len".
+// Return the code pointer after the disassemble x86 instruction.
+extern "C" ENCODER_DECLARE_EXPORT
+char* decoder_disassemble_instr(char* stream, char* strbuf, unsigned int len)
+{
+    Inst decInst;
+    unsigned numBytes = DecoderBase::decode(stream, &decInst);
+    DisassembleInstToBuf(decInst, strbuf, len);
+    return (stream + numBytes);
+}
diff --git a/vm/compiler/codegen/x86/libenc/enc_wrapper.h b/vm/compiler/codegen/x86/libenc/enc_wrapper.h
new file mode 100644
index 0000000..a2a223e
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/enc_wrapper.h
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _VM_ENC_WRAPPER_H_
+#define _VM_ENC_WRAPPER_H_
+
+#include "enc_defs_ext.h"
+
+extern bool dump_x86_inst;
+typedef enum PhysicalReg {
+  PhysicalReg_EAX = 0, PhysicalReg_EBX, PhysicalReg_ECX, PhysicalReg_EDX,
+  PhysicalReg_EDI, PhysicalReg_ESI, PhysicalReg_ESP, PhysicalReg_EBP,
+  PhysicalReg_XMM0, PhysicalReg_XMM1, PhysicalReg_XMM2, PhysicalReg_XMM3,
+  PhysicalReg_XMM4, PhysicalReg_XMM5, PhysicalReg_XMM6, PhysicalReg_XMM7,
+  PhysicalReg_ST0,  PhysicalReg_ST1, PhysicalReg_ST2,  PhysicalReg_ST3,
+  PhysicalReg_ST4, PhysicalReg_ST5, PhysicalReg_ST6, PhysicalReg_ST7,
+  PhysicalReg_Null,
+  //used as scratch logical register in NCG O1
+  //should not overlap with regular logical register, start from 100
+  PhysicalReg_SCRATCH_1 = 100, PhysicalReg_SCRATCH_2, PhysicalReg_SCRATCH_3, PhysicalReg_SCRATCH_4,
+  PhysicalReg_SCRATCH_5, PhysicalReg_SCRATCH_6, PhysicalReg_SCRATCH_7, PhysicalReg_SCRATCH_8,
+  PhysicalReg_SCRATCH_9, PhysicalReg_SCRATCH_10,
+  PhysicalReg_GLUE_DVMDEX = 900,
+  PhysicalReg_GLUE = 901
+} PhysicalReg;
+
+typedef enum Reg_No {
+#ifdef _EM64T_
+    rax_reg = 0,rbx_reg,    rcx_reg,    rdx_reg,
+    rdi_reg,    rsi_reg,    rsp_reg,    rbp_reg,
+    r8_reg,     r9_reg,     r10_reg,    r11_reg,
+    r12_reg,    r13_reg,    r14_reg,    r15_reg,
+    xmm0_reg,   xmm1_reg,   xmm2_reg,   xmm3_reg,
+    xmm4_reg,   xmm5_reg,   xmm6_reg,   xmm7_reg,
+    xmm8_reg,   xmm9_reg,   xmm10_reg,  xmm11_reg,
+    xmm12_reg,  xmm13_reg,  xmm14_reg,  xmm15_reg,
+
+#else   // !defined(_EM64T_)
+
+    eax_reg = 0,ebx_reg,    ecx_reg,    edx_reg,
+    edi_reg,    esi_reg,    esp_reg,    ebp_reg,
+    xmm0_reg,   xmm1_reg,   xmm2_reg,   xmm3_reg,
+    xmm4_reg,   xmm5_reg,   xmm6_reg,   xmm7_reg,
+    fs_reg,
+#endif
+    /** @brief Total number of registers.*/
+    n_reg
+} Reg_No;
+//
+// instruction operand sizes: 8,16,32,64 bits
+//
+typedef enum Opnd_Size {
+    size_8 = 0,
+    size_16,
+    size_32,
+    size_64,
+    n_size,
+#ifdef _EM64T_
+    size_platf = size_64
+#else
+    size_platf = size_32
+#endif
+} Opnd_Size;
+
+//
+// opcodes for alu instructions
+//
+typedef enum ALU_Opcode {
+    add_opc = 0,or_opc,     adc_opc,    sbb_opc,
+    and_opc,    sub_opc,    xor_opc,    cmp_opc,
+    mul_opc,    imul_opc,   div_opc,    idiv_opc,
+    sll_opc,    srl_opc,    sra_opc, //shift right arithmetic
+    shl_opc,    shr_opc,
+    sal_opc,    sar_opc,
+    neg_opc,    not_opc,    andn_opc,
+    n_alu
+} ALU_Opcode;
+
+typedef enum ConditionCode {
+    Condition_O     = 0,
+    Condition_NO    = 1,
+    Condition_B     = 2,
+    Condition_NAE   = Condition_B,
+    Condition_C     = Condition_B,
+    Condition_NB    = 3,
+    Condition_AE    = Condition_NB,
+    Condition_NC    = Condition_NB,
+    Condition_Z     = 4,
+    Condition_E     = Condition_Z,
+    Condition_NZ    = 5,
+    Condition_NE    = Condition_NZ,
+    Condition_BE    = 6,
+    Condition_NA    = Condition_BE,
+    Condition_NBE   = 7,
+    Condition_A     = Condition_NBE,
+
+    Condition_S     = 8,
+    Condition_NS    = 9,
+    Condition_P     = 10,
+    Condition_PE    = Condition_P,
+    Condition_NP    = 11,
+    Condition_PO    = Condition_NP,
+    Condition_L     = 12,
+    Condition_NGE   = Condition_L,
+    Condition_NL    = 13,
+    Condition_GE    = Condition_NL,
+    Condition_LE    = 14,
+    Condition_NG    = Condition_LE,
+    Condition_NLE   = 15,
+    Condition_G     = Condition_NLE,
+    Condition_Count = 16
+} ConditionCode;
+
+//
+// prefix code
+//
+typedef enum InstrPrefix {
+    no_prefix,
+    lock_prefix                     = 0xF0,
+    hint_branch_taken_prefix        = 0x2E,
+    hint_branch_not_taken_prefix    = 0x3E,
+    prefix_repne                    = 0xF2,
+    prefix_repnz                    = prefix_repne,
+    prefix_repe                     = 0xF3,
+    prefix_repz                     = prefix_repe,
+    prefix_rep                      = 0xF3,
+    prefix_cs                       = 0x2E,
+    prefix_ss                       = 0x36,
+    prefix_ds                       = 0x3E,
+    prefix_es                       = 0x26,
+    prefix_fs                       = 0x64,
+    prefix_gs                       = 0x65
+} InstrPrefix;
+
+//last 2 bits: decide xmm, gp, fs
+//virtual, scratch, temp, hard match with ncg_o1_data.h
+typedef enum LowOpndRegType {
+  LowOpndRegType_gp = 0,
+  LowOpndRegType_fs = 1,
+  LowOpndRegType_xmm = 2,
+  LowOpndRegType_fs_s = 3,
+  LowOpndRegType_ss = 4,
+  LowOpndRegType_scratch = 8, //used by NCG O1
+  LowOpndRegType_temp = 16,
+  LowOpndRegType_hard = 32,   //NCG O1
+  LowOpndRegType_virtual = 64, //used by NCG O1
+  LowOpndRegType_glue = 128
+} LowOpndRegType;
+
+//if inline, separte enc_wrapper.cpp into two files, one of them is .inl
+//           enc_wrapper.cpp needs to handle both cases
+#ifdef ENCODER_INLINE
+    #define ENCODER_DECLARE_EXPORT inline
+    #include "enc_wrapper.inl"
+#else
+    #define ENCODER_DECLARE_EXPORT
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ENCODER_DECLARE_EXPORT char* encoder_imm(Mnemonic m, OpndSize size,
+                  int imm, char* stream);
+ENCODER_DECLARE_EXPORT unsigned encoder_get_inst_size(char * stream);
+ENCODER_DECLARE_EXPORT char* encoder_update_imm(int imm, char * stream);
+ENCODER_DECLARE_EXPORT char* encoder_mem(Mnemonic m, OpndSize size,
+               int disp, int base_reg, bool isBasePhysical, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_reg(Mnemonic m, OpndSize size,
+               int reg, bool isPhysical, LowOpndRegType type, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_reg_reg(Mnemonic m, OpndSize size,
+                   int reg, bool isPhysical,
+                   int reg2, bool isPhysical2, LowOpndRegType type, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_mem_reg(Mnemonic m, OpndSize size,
+                   int disp, int base_reg, bool isBasePhysical,
+                   int reg, bool isPhysical, LowOpndRegType type, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_mem_scale_reg(Mnemonic m, OpndSize size,
+                         int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale,
+                         int reg, bool isPhysical, LowOpndRegType type, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_reg_mem_scale(Mnemonic m, OpndSize size,
+                         int reg, bool isPhysical,
+                         int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale,
+                         LowOpndRegType type, char* stream);
+ENCODER_DECLARE_EXPORT char * encoder_mem_disp_scale_reg(Mnemonic m, OpndSize size,
+                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                         int reg, bool isPhysical, LowOpndRegType type, char * stream);
+ENCODER_DECLARE_EXPORT char * encoder_movzs_mem_disp_scale_reg(Mnemonic m, OpndSize size,
+                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                         int reg, bool isPhysical, LowOpndRegType type, char * stream);
+ENCODER_DECLARE_EXPORT char* encoder_reg_mem_disp_scale(Mnemonic m, OpndSize size,
+                         int reg, bool isPhysical,
+                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+                         LowOpndRegType type, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_reg_mem(Mnemonic m, OpndSize size,
+                   int reg, bool isPhysical,
+                   int disp, int base_reg, bool isBasePhysical, LowOpndRegType type, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_imm_reg(Mnemonic m, OpndSize size,
+                   int imm, int reg, bool isPhysical, LowOpndRegType type, char* stream);
+ENCODER_DECLARE_EXPORT char * encoder_update_imm_rm(int imm, char * stream);
+ENCODER_DECLARE_EXPORT char* encoder_imm_mem(Mnemonic m, OpndSize size,
+                   int imm,
+                   int disp, int base_reg, bool isBasePhysical, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_fp_mem(Mnemonic m, OpndSize size, int reg,
+                  int disp, int base_reg, bool isBasePhysical, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_mem_fp(Mnemonic m, OpndSize size,
+                  int disp, int base_reg, bool isBasePhysical,
+                  int reg, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_return(char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_compare_fp_stack(bool pop, int reg, bool isDouble, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_movez_mem_to_reg(OpndSize size,
+                      int disp, int base_reg, bool isBasePhysical,
+                      int reg, bool isPhysical, char* stream);
+ENCODER_DECLARE_EXPORT char* encoder_moves_mem_to_reg(OpndSize size,
+                      int disp, int base_reg, bool isBasePhysical,
+                      int reg, bool isPhysical, char* stream);
+ENCODER_DECLARE_EXPORT char * encoder_movez_reg_to_reg(OpndSize size,
+                      int reg, bool isPhysical, int reg2,
+                      bool isPhysical2, LowOpndRegType type, char * stream);
+ENCODER_DECLARE_EXPORT char * encoder_moves_reg_to_reg(OpndSize size,
+                      int reg, bool isPhysical, int reg2,
+                      bool isPhysical2, LowOpndRegType type, char * stream);
+ENCODER_DECLARE_EXPORT int decodeThenPrint(char* stream_start);
+ENCODER_DECLARE_EXPORT char* decoder_disassemble_instr(char* stream, char* strbuf, unsigned int len);
+#ifdef __cplusplus
+}
+#endif
+#endif // _VM_ENC_WRAPPER_H_
diff --git a/vm/compiler/codegen/x86/libenc/encoder.cpp b/vm/compiler/codegen/x86/libenc/encoder.cpp
new file mode 100644
index 0000000..ef08a4d
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/encoder.cpp
@@ -0,0 +1,155 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+#include <stdio.h>
+#include <assert.h>
+
+#include <limits.h>
+
+#include "enc_base.h"
+
+#ifdef NO_ENCODER_INLINE
+    #include "encoder.h"
+    #include "encoder.inl"
+#else
+    #define NO_ENCODER_INLINE
+    #include "encoder.h"
+    #undef NO_ENCODER_INLINE
+#endif
+
+
+
+#ifdef _EM64T_
+
+R_Opnd rax_opnd(rax_reg);
+R_Opnd rcx_opnd(rcx_reg);
+R_Opnd rdx_opnd(rdx_reg);
+R_Opnd rbx_opnd(rbx_reg);
+R_Opnd rsp_opnd(rsp_reg);
+R_Opnd rbp_opnd(rbp_reg);
+R_Opnd rsi_opnd(rsi_reg);
+R_Opnd rdi_opnd(rdi_reg);
+
+R_Opnd r8_opnd(r8_reg);
+R_Opnd r9_opnd(r9_reg);
+R_Opnd r10_opnd(r10_reg);
+R_Opnd r11_opnd(r11_reg);
+R_Opnd r12_opnd(r12_reg);
+R_Opnd r13_opnd(r13_reg);
+R_Opnd r14_opnd(r14_reg);
+R_Opnd r15_opnd(r15_reg);
+
+XMM_Opnd xmm8_opnd(xmm8_reg);
+XMM_Opnd xmm9_opnd(xmm9_reg);
+XMM_Opnd xmm10_opnd(xmm10_reg);
+XMM_Opnd xmm11_opnd(xmm11_reg);
+XMM_Opnd xmm12_opnd(xmm12_reg);
+XMM_Opnd xmm13_opnd(xmm13_reg);
+XMM_Opnd xmm14_opnd(xmm14_reg);
+XMM_Opnd xmm15_opnd(xmm15_reg);
+
+#else
+
+R_Opnd eax_opnd(eax_reg);
+R_Opnd ecx_opnd(ecx_reg);
+R_Opnd edx_opnd(edx_reg);
+R_Opnd ebx_opnd(ebx_reg);
+R_Opnd esp_opnd(esp_reg);
+R_Opnd ebp_opnd(ebp_reg);
+R_Opnd esi_opnd(esi_reg);
+R_Opnd edi_opnd(edi_reg);
+
+#endif //_EM64T_
+
+XMM_Opnd xmm0_opnd(xmm0_reg);
+XMM_Opnd xmm1_opnd(xmm1_reg);
+XMM_Opnd xmm2_opnd(xmm2_reg);
+XMM_Opnd xmm3_opnd(xmm3_reg);
+XMM_Opnd xmm4_opnd(xmm4_reg);
+XMM_Opnd xmm5_opnd(xmm5_reg);
+XMM_Opnd xmm6_opnd(xmm6_reg);
+XMM_Opnd xmm7_opnd(xmm7_reg);
+
+
+#define countof(a)      (sizeof(a)/sizeof(a[0]))
+
+extern const RegName map_of_regno_2_regname[];
+extern const OpndSize map_of_EncoderOpndSize_2_RealOpndSize[];
+extern const Mnemonic map_of_alu_opcode_2_mnemonic[];
+extern const Mnemonic map_of_shift_opcode_2_mnemonic[];
+
+const RegName map_of_regno_2_regname [] = {
+#ifdef _EM64T_
+    RegName_RAX,    RegName_RBX,    RegName_RCX,    RegName_RDX,
+    RegName_RDI,    RegName_RSI,    RegName_RSP,    RegName_RBP,
+    RegName_R8,     RegName_R9,     RegName_R10,    RegName_R11,
+    RegName_R12,    RegName_R13,    RegName_R14,    RegName_R15,
+    RegName_XMM0,   RegName_XMM1,   RegName_XMM2,   RegName_XMM3,
+    RegName_XMM4,   RegName_XMM5,   RegName_XMM6,   RegName_XMM7,
+    RegName_XMM8,   RegName_XMM9,   RegName_XMM10,  RegName_XMM11,
+    RegName_XMM12,  RegName_XMM13,   RegName_XMM14, RegName_XMM15,
+
+#else
+    RegName_EAX,    RegName_EBX,    RegName_ECX,    RegName_EDX,
+    RegName_EDI,    RegName_ESI,    RegName_ESP,    RegName_EBP,
+    RegName_XMM0,   RegName_XMM1,   RegName_XMM2,   RegName_XMM3,
+    RegName_XMM4,   RegName_XMM5,   RegName_XMM6,   RegName_XMM7,
+    RegName_FS,
+#endif  // _EM64T_
+
+    RegName_Null,
+};
+
+const OpndSize map_of_EncoderOpndSize_2_RealOpndSize[] = {
+    OpndSize_8, OpndSize_16, OpndSize_32, OpndSize_64, OpndSize_Any
+};
+
+const Mnemonic map_of_alu_opcode_2_mnemonic[] = {
+    //add_opc=0,  or_opc,           adc_opc,        sbb_opc,
+    //and_opc,      sub_opc,        xor_opc,        cmp_opc,
+    //n_alu
+    Mnemonic_ADD,   Mnemonic_OR,    Mnemonic_ADC,   Mnemonic_SBB,
+    Mnemonic_AND,   Mnemonic_SUB,   Mnemonic_XOR,   Mnemonic_CMP,
+};
+
+const Mnemonic map_of_shift_opcode_2_mnemonic[] = {
+    //shld_opc, shrd_opc,
+    // shl_opc, shr_opc, sar_opc, ror_opc, max_shift_opcode=6,
+    // n_shift = 6
+    Mnemonic_SHLD,  Mnemonic_SHRD,
+    Mnemonic_SHL,   Mnemonic_SHR,   Mnemonic_SAR, Mnemonic_ROR
+};
+
+#ifdef _DEBUG
+
+static int debug_check() {
+    // Checks some assumptions.
+
+    // 1. all items of Encoder.h:enum Reg_No  must be mapped plus n_reg->RegName_Null
+    assert(countof(map_of_regno_2_regname) == n_reg + 1);
+    assert(countof(map_of_alu_opcode_2_mnemonic) == n_alu);
+    assert(countof(map_of_shift_opcode_2_mnemonic) == n_shift);
+    return 0;
+}
+
+static int dummy = debug_check();
+
+// can have this - initialization order problems.... static int dummy_run_the_debug_test = debug_check();
+
+#endif
diff --git a/vm/compiler/codegen/x86/libenc/encoder.h b/vm/compiler/codegen/x86/libenc/encoder.h
new file mode 100644
index 0000000..e29efce
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/encoder.h
@@ -0,0 +1,716 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+/**
+ * @file
+ * @brief Simple interface for generating processor instructions.
+ *
+ * The interface works for both IA32 and EM64T. By default, only IA32
+ * capabilities are presented. To enable EM64T feature, the _EM64T_ macro
+ * must be defined (and, of course, a proper library version to be used).
+ *
+ * The interface is based on the original ia32.h encoder interface,
+ * with some simplifications and add-ons - EM64T-specific, SSE and SSE2.
+ *
+ * The interface mostly intended for existing legacy code like LIL code
+ * generator. From the implementation point of view, it's just a wrapper
+ * around the EncoderBase functionality.
+ */
+
+#ifndef _VM_ENCODER_H_
+#define _VM_ENCODER_H_
+
+#include <limits.h>
+#include "enc_base.h"
+//#include "open/types.h"
+
+#ifdef _EM64T_
+// size of general-purpose value on the stack in bytes
+#define GR_STACK_SIZE 8
+// size of floating-point value on the stack in bytes
+#define FR_STACK_SIZE 8
+
+#if defined(WIN32) || defined(_WIN64)
+    // maximum number of GP registers for inputs
+    const int MAX_GR = 4;
+    // maximum number of FP registers for inputs
+    const int MAX_FR = 4;
+    // WIN64 reserves 4 words for shadow space
+    const int SHADOW = 4 * GR_STACK_SIZE;
+#else
+    // maximum number of GP registers for inputs
+    const int MAX_GR = 6;
+    // maximum number of FP registers for inputs
+    const int MAX_FR = 8;
+    // Linux x64 doesn't reserve shadow space
+    const int SHADOW = 0;
+#endif
+
+#else
+// size of general-purpose value on the stack in bytes
+#define GR_STACK_SIZE 4
+// size of general-purpose value on the stack in bytes
+#define FR_STACK_SIZE 8
+
+// maximum number of GP registers for inputs
+const int MAX_GR = 0;
+// maximum number of FP registers for inputs
+const int MAX_FR = 0;
+#endif
+
+typedef enum Reg_No {
+#ifdef _EM64T_
+    rax_reg = 0,rbx_reg,    rcx_reg,    rdx_reg,
+    rdi_reg,    rsi_reg,    rsp_reg,    rbp_reg,
+    r8_reg,     r9_reg,     r10_reg,    r11_reg,
+    r12_reg,    r13_reg,    r14_reg,    r15_reg,
+    xmm0_reg,   xmm1_reg,   xmm2_reg,   xmm3_reg,
+    xmm4_reg,   xmm5_reg,   xmm6_reg,   xmm7_reg,
+    xmm8_reg,   xmm9_reg,   xmm10_reg,  xmm11_reg,
+    xmm12_reg,  xmm13_reg,  xmm14_reg,  xmm15_reg,
+
+#else   // !defined(_EM64T_)
+
+    eax_reg = 0,ebx_reg,    ecx_reg,    edx_reg,
+    edi_reg,    esi_reg,    esp_reg,    ebp_reg,
+    xmm0_reg,   xmm1_reg,   xmm2_reg,   xmm3_reg,
+    xmm4_reg,   xmm5_reg,   xmm6_reg,   xmm7_reg,
+    fs_reg,
+#endif
+    /** @brief Total number of registers.*/
+    n_reg
+} Reg_No;
+//
+// instruction operand sizes: 8,16,32,64 bits
+//
+typedef enum Opnd_Size {
+    size_8 = 0,
+    size_16,
+    size_32,
+    size_64,
+    n_size,
+#ifdef _EM64T_
+    size_platf = size_64
+#else
+    size_platf = size_32
+#endif
+} Opnd_Size;
+
+//
+// opcodes for alu instructions
+//
+typedef enum ALU_Opcode {
+    add_opc = 0,or_opc,     adc_opc,    sbb_opc,
+    and_opc,    sub_opc,    xor_opc,    cmp_opc,
+    n_alu
+} ALU_Opcode;
+
+//
+// opcodes for shift instructions
+//
+typedef enum Shift_Opcode {
+    shld_opc,   shrd_opc,   shl_opc,    shr_opc,
+    sar_opc,    ror_opc, max_shift_opcode=6,     n_shift = 6
+} Shift_Opcode;
+
+typedef enum ConditionCode {
+    Condition_O     = 0,
+    Condition_NO    = 1,
+    Condition_B     = 2,
+    Condition_NAE   = Condition_B,
+    Condition_C     = Condition_B,
+    Condition_NB    = 3,
+    Condition_AE    = Condition_NB,
+    Condition_NC    = Condition_NB,
+    Condition_Z     = 4,
+    Condition_E     = Condition_Z,
+    Condition_NZ    = 5,
+    Condition_NE    = Condition_NZ,
+    Condition_BE    = 6,
+    Condition_NA    = Condition_BE,
+    Condition_NBE   = 7,
+    Condition_A     = Condition_NBE,
+
+    Condition_S     = 8,
+    Condition_NS    = 9,
+    Condition_P     = 10,
+    Condition_PE    = Condition_P,
+    Condition_NP    = 11,
+    Condition_PO    = Condition_NP,
+    Condition_L     = 12,
+    Condition_NGE   = Condition_L,
+    Condition_NL    = 13,
+    Condition_GE    = Condition_NL,
+    Condition_LE    = 14,
+    Condition_NG    = Condition_LE,
+    Condition_NLE   = 15,
+    Condition_G     = Condition_NLE,
+    Condition_Count = 16
+} ConditionCode;
+
+//
+// prefix code
+//
+typedef enum InstrPrefix {
+    no_prefix,
+    lock_prefix                     = 0xF0,
+    hint_branch_taken_prefix        = 0x2E,
+    hint_branch_not_taken_prefix    = 0x3E,
+    prefix_repne                    = 0xF2,
+    prefix_repnz                    = prefix_repne,
+    prefix_repe                     = 0xF3,
+    prefix_repz                     = prefix_repe,
+    prefix_rep                      = 0xF3,
+    prefix_cs                       = 0x2E,
+    prefix_ss                       = 0x36,
+    prefix_ds                       = 0x3E,
+    prefix_es                       = 0x26,
+    prefix_fs                       = 0x64,
+    prefix_gs                       = 0x65
+} InstrPrefix;
+
+
+//
+// an instruction operand
+//
+class Opnd {
+
+protected:
+    enum Tag { SignedImm, UnsignedImm, Reg, Mem, FP, XMM };
+
+    const Tag  tag;
+
+    Opnd(Tag t): tag(t) {}
+
+public:
+    void * operator new(size_t, void * mem) {
+        return mem;
+    }
+
+    void operator delete(void *) {}
+
+    void operator delete(void *, void *) {}
+
+private:
+    // disallow copying
+    Opnd(const Opnd &): tag(Mem) { assert(false); }
+    Opnd& operator=(const Opnd &) { assert(false); return *this; }
+};
+typedef int I_32;
+class Imm_Opnd: public Opnd {
+
+protected:
+    union {
+#ifdef _EM64T_
+        int64           value;
+        unsigned char   bytes[8];
+#else
+        I_32           value;
+        unsigned char   bytes[4];
+#endif
+    };
+    Opnd_Size           size;
+
+public:
+    Imm_Opnd(I_32 val, bool isSigned = true):
+        Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(size_32) {
+        if (isSigned) {
+            if (CHAR_MIN <= val && val <= CHAR_MAX) {
+                size = size_8;
+            } else if (SHRT_MIN <= val && val <= SHRT_MAX) {
+                size = size_16;
+            }
+        } else {
+            assert(val >= 0);
+            if (val <= UCHAR_MAX) {
+                size = size_8;
+            } else if (val <= USHRT_MAX) {
+                size = size_16;
+            }
+        }
+    }
+    Imm_Opnd(const Imm_Opnd& that): Opnd(that.tag), value(that.value), size(that.size) {};
+
+#ifdef _EM64T_
+    Imm_Opnd(Opnd_Size sz, int64 val, bool isSigned = true):
+        Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(sz) {
+#ifndef NDEBUG
+        switch (size) {
+        case size_8:
+            assert(val == (int64)(I_8)val);
+            break;
+        case size_16:
+            assert(val == (int64)(int16)val);
+            break;
+        case size_32:
+            assert(val == (int64)(I_32)val);
+            break;
+        case size_64:
+            break;
+        case n_size:
+            assert(false);
+            break;
+        }
+#endif // NDEBUG
+    }
+
+    int64 get_value() const { return value; }
+
+#else
+
+    Imm_Opnd(Opnd_Size sz, I_32 val, int isSigned = true):
+        Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(sz) {
+#ifndef NDEBUG
+        switch (size) {
+        case size_8:
+            assert((I_32)val == (I_32)(I_8)val);
+            break;
+        case size_16:
+            assert((I_32)val == (I_32)(int16)val);
+            break;
+        case size_32:
+            break;
+        case size_64:
+        case n_size:
+            assert(false);
+            break;
+        }
+#endif // NDEBUG
+    }
+
+    I_32 get_value() const { return value; }
+
+#endif
+    Opnd_Size get_size() const { return size; }
+    bool      is_signed() const { return tag == SignedImm; }
+};
+
+class RM_Opnd: public Opnd {
+
+public:
+    bool is_reg() const { return tag != SignedImm && tag != UnsignedImm && tag != Mem; }
+
+protected:
+    RM_Opnd(Tag t): Opnd(t) {}
+
+private:
+    // disallow copying
+    RM_Opnd(const RM_Opnd &): Opnd(Reg) { assert(false); }
+};
+
+class R_Opnd: public RM_Opnd {
+
+protected:
+    Reg_No      _reg_no;
+
+public:
+    R_Opnd(Reg_No r): RM_Opnd(Reg), _reg_no(r) {}
+    Reg_No  reg_no() const { return _reg_no; }
+
+private:
+    // disallow copying
+    R_Opnd(const R_Opnd &): RM_Opnd(Reg) { assert(false); }
+};
+
+//
+// a memory operand with displacement
+// Can also serve as a full memory operand with base,index, displacement and scale.
+// Use n_reg to specify 'no register', say, for index.
+class M_Opnd: public RM_Opnd {
+
+protected:
+    Imm_Opnd        m_disp;
+    Imm_Opnd        m_scale;
+    R_Opnd          m_index;
+    R_Opnd          m_base;
+
+public:
+    //M_Opnd(Opnd_Size sz): RM_Opnd(Mem, K_M, sz), m_disp(0), m_scale(0), m_index(n_reg), m_base(n_reg) {}
+    M_Opnd(I_32 disp):
+        RM_Opnd(Mem), m_disp(disp), m_scale(0), m_index(n_reg), m_base(n_reg) {}
+    M_Opnd(Reg_No rbase, I_32 rdisp):
+        RM_Opnd(Mem), m_disp(rdisp), m_scale(0), m_index(n_reg), m_base(rbase) {}
+    M_Opnd(I_32 disp, Reg_No rbase, Reg_No rindex, unsigned scale):
+        RM_Opnd(Mem), m_disp(disp), m_scale(scale), m_index(rindex), m_base(rbase) {}
+    M_Opnd(const M_Opnd & that) : RM_Opnd(Mem),
+        m_disp((int)that.m_disp.get_value()), m_scale((int)that.m_scale.get_value()),
+        m_index(that.m_index.reg_no()), m_base(that.m_base.reg_no())
+        {}
+    //
+    inline const R_Opnd & base(void) const { return m_base; }
+    inline const R_Opnd & index(void) const { return m_index; }
+    inline const Imm_Opnd & scale(void) const { return m_scale; }
+    inline const Imm_Opnd & disp(void) const { return m_disp; }
+};
+
+//
+//  a memory operand with base register and displacement
+//
+class M_Base_Opnd: public M_Opnd {
+
+public:
+    M_Base_Opnd(Reg_No base, I_32 disp) : M_Opnd(disp, base, n_reg, 0) {}
+
+private:
+    // disallow copying - but it leads to ICC errors #734 in encoder.inl
+    // M_Base_Opnd(const M_Base_Opnd &): M_Opnd(0) { assert(false); }
+};
+
+//
+//  a memory operand with base register, scaled index register
+//  and displacement.
+//
+class M_Index_Opnd : public M_Opnd {
+
+public:
+    M_Index_Opnd(Reg_No base, Reg_No index, I_32 disp, unsigned scale):
+        M_Opnd(disp, base, index, scale) {}
+
+private:
+    // disallow copying - but it leads to ICC errors #734 in encoder.inl
+    // M_Index_Opnd(const M_Index_Opnd &): M_Opnd(0) { assert(false); }
+};
+
+class XMM_Opnd : public Opnd {
+
+protected:
+    unsigned        m_idx;
+
+public:
+    XMM_Opnd(unsigned _idx): Opnd(XMM), m_idx(_idx) {};
+    unsigned get_idx( void ) const { return m_idx; };
+
+private:
+    // disallow copying
+    XMM_Opnd(const XMM_Opnd &): Opnd(XMM) { assert(false); }
+};
+
+//
+// operand structures for ia32 registers
+//
+#ifdef _EM64T_
+
+extern R_Opnd rax_opnd;
+extern R_Opnd rcx_opnd;
+extern R_Opnd rdx_opnd;
+extern R_Opnd rbx_opnd;
+extern R_Opnd rdi_opnd;
+extern R_Opnd rsi_opnd;
+extern R_Opnd rsp_opnd;
+extern R_Opnd rbp_opnd;
+
+extern R_Opnd r8_opnd;
+extern R_Opnd r9_opnd;
+extern R_Opnd r10_opnd;
+extern R_Opnd r11_opnd;
+extern R_Opnd r12_opnd;
+extern R_Opnd r13_opnd;
+extern R_Opnd r14_opnd;
+extern R_Opnd r15_opnd;
+
+extern XMM_Opnd xmm8_opnd;
+extern XMM_Opnd xmm9_opnd;
+extern XMM_Opnd xmm10_opnd;
+extern XMM_Opnd xmm11_opnd;
+extern XMM_Opnd xmm12_opnd;
+extern XMM_Opnd xmm13_opnd;
+extern XMM_Opnd xmm14_opnd;
+extern XMM_Opnd xmm15_opnd;
+#else
+
+extern R_Opnd eax_opnd;
+extern R_Opnd ecx_opnd;
+extern R_Opnd edx_opnd;
+extern R_Opnd ebx_opnd;
+extern R_Opnd esp_opnd;
+extern R_Opnd ebp_opnd;
+extern R_Opnd esi_opnd;
+extern R_Opnd edi_opnd;
+
+#endif // _EM64T_
+
+extern XMM_Opnd xmm0_opnd;
+extern XMM_Opnd xmm1_opnd;
+extern XMM_Opnd xmm2_opnd;
+extern XMM_Opnd xmm3_opnd;
+extern XMM_Opnd xmm4_opnd;
+extern XMM_Opnd xmm5_opnd;
+extern XMM_Opnd xmm6_opnd;
+extern XMM_Opnd xmm7_opnd;
+
+#ifdef NO_ENCODER_INLINE
+    #define ENCODER_DECLARE_EXPORT
+#else
+    #define ENCODER_DECLARE_EXPORT inline
+    #include "encoder.inl"
+#endif
+
+// prefix
+ENCODER_DECLARE_EXPORT char * prefix(char * stream, InstrPrefix p);
+
+// stack push and pop instructions
+ENCODER_DECLARE_EXPORT char * push(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * push(char * stream, const Imm_Opnd & imm);
+ENCODER_DECLARE_EXPORT char * pop(char * stream,  const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+// cmpxchg or xchg
+ENCODER_DECLARE_EXPORT char * cmpxchg(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * xchg(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf);
+
+// inc(rement), dec(rement), not, neg(ate) instructions
+ENCODER_DECLARE_EXPORT char * inc(char * stream,  const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * dec(char * stream,  const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * _not(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * neg(char * stream,  const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * nop(char * stream);
+ENCODER_DECLARE_EXPORT char * int3(char * stream);
+
+// alu instructions: add, or, adc, sbb, and, sub, xor, cmp
+ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const M_Opnd & m, const R_Opnd & r, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+// test instruction
+ENCODER_DECLARE_EXPORT char * test(char * stream, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * test(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf);
+
+// shift instructions: shl, shr, sar, shld, shrd, ror
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, const R_Opnd & r, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf);
+
+// multiply instructions: mul, imul
+ENCODER_DECLARE_EXPORT char * mul(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const RM_Opnd & rm, const Imm_Opnd& imm, Opnd_Size sz = size_platf);
+
+// divide instructions: div, idiv
+ENCODER_DECLARE_EXPORT char * idiv(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+// data movement: mov
+ENCODER_DECLARE_EXPORT char * mov(char * stream, const M_Opnd & m,  const R_Opnd & r, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * mov(char * stream, const R_Opnd & r,  const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * mov(char * stream, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+
+ENCODER_DECLARE_EXPORT char * movsx( char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * movzx( char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+ENCODER_DECLARE_EXPORT char * movd(char * stream, const RM_Opnd & rm, const XMM_Opnd & xmm);
+ENCODER_DECLARE_EXPORT char * movd(char * stream, const XMM_Opnd & xmm, const RM_Opnd & rm);
+ENCODER_DECLARE_EXPORT char * movq(char * stream, const RM_Opnd & rm, const XMM_Opnd & xmm);
+ENCODER_DECLARE_EXPORT char * movq(char * stream, const XMM_Opnd & xmm, const RM_Opnd & rm);
+
+// sse mov
+ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const M_Opnd & mem, const XMM_Opnd & xmm, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+
+// sse add, sub, mul, div
+ENCODER_DECLARE_EXPORT char * sse_add(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_add(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+
+ENCODER_DECLARE_EXPORT char * sse_sub(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_sub(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+
+ENCODER_DECLARE_EXPORT char * sse_mul(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_mul(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+
+ENCODER_DECLARE_EXPORT char * sse_div(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_div(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+
+// xor, compare
+ENCODER_DECLARE_EXPORT char * sse_xor(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1);
+
+ENCODER_DECLARE_EXPORT char * sse_compare(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_compare(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem, bool dbl);
+
+// sse conversions
+ENCODER_DECLARE_EXPORT char * sse_cvt_si(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_cvtt2si(char * stream, const R_Opnd & reg, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_cvtt2si(char * stream, const R_Opnd & reg, const XMM_Opnd & xmm, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_cvt_fp2dq(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_cvt_dq2fp(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_d2s(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem64);
+ENCODER_DECLARE_EXPORT char * sse_d2s(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1);
+ENCODER_DECLARE_EXPORT char * sse_s2d(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem32);
+ENCODER_DECLARE_EXPORT char * sse_s2d(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1);
+
+// condition operations
+ENCODER_DECLARE_EXPORT char * cmov(char * stream, ConditionCode cc, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * setcc(char * stream, ConditionCode cc, const RM_Opnd & rm8);
+
+// load effective address: lea
+ENCODER_DECLARE_EXPORT char * lea(char * stream, const R_Opnd & r, const M_Opnd & m, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * cdq(char * stream);
+ENCODER_DECLARE_EXPORT char * wait(char * stream);
+
+// control-flow instructions
+ENCODER_DECLARE_EXPORT char * loop(char * stream, const Imm_Opnd & imm);
+
+// jump with 8-bit relative
+ENCODER_DECLARE_EXPORT char * jump8(char * stream, const Imm_Opnd & imm);
+
+// jump with 32-bit relative
+ENCODER_DECLARE_EXPORT char * jump32(char * stream, const Imm_Opnd & imm);
+
+// register indirect jump
+ENCODER_DECLARE_EXPORT char * jump(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+// jump to target address
+ENCODER_DECLARE_EXPORT char *jump(char * stream, char *target);
+
+// jump with displacement
+//char * jump(char * stream, I_32 disp);
+
+// conditional branch with 8-bit branch offset
+ENCODER_DECLARE_EXPORT char * branch8(char * stream, ConditionCode cc, const Imm_Opnd & imm, InstrPrefix prefix = no_prefix);
+
+// conditional branch with 32-bit branch offset
+ENCODER_DECLARE_EXPORT char * branch32(char * stream, ConditionCode cc, const Imm_Opnd & imm, InstrPrefix prefix = no_prefix);
+
+// conditional branch with target label address
+//char * branch(char * stream, ConditionCode cc, const char * target, InstrPrefix prefix = no_prefix);
+
+// conditional branch with displacement immediate
+ENCODER_DECLARE_EXPORT char * branch(char * stream, ConditionCode cc, I_32 disp, InstrPrefix prefix = no_prefix);
+
+// call with displacement
+ENCODER_DECLARE_EXPORT char * call(char * stream, const Imm_Opnd & imm);
+
+// indirect call through register or memory location
+ENCODER_DECLARE_EXPORT char * call(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+// call target address
+ENCODER_DECLARE_EXPORT char * call(char * stream, const char * target);
+
+// return instruction
+ENCODER_DECLARE_EXPORT char * ret(char * stream);
+ENCODER_DECLARE_EXPORT char * ret(char * stream, unsigned short pop);
+ENCODER_DECLARE_EXPORT char * ret(char * stream, const Imm_Opnd & imm);
+
+// string operations
+ENCODER_DECLARE_EXPORT char * set_d(char * stream, bool set);
+ENCODER_DECLARE_EXPORT char * scas(char * stream, unsigned char prefix);
+ENCODER_DECLARE_EXPORT char * stos(char * stream, unsigned char prefix);
+
+// floating-point instructions
+
+// st(0) = st(0) fp_op m{32,64}real
+//!char * fp_op_mem(char * stream, FP_Opcode opc,const M_Opnd& mem,int is_double);
+
+// st(0) = st(0) fp_op st(i)
+//!char *fp_op(char * stream, FP_Opcode opc,unsigned i);
+
+// st(i) = st(i) fp_op st(0)    ; optionally pop stack
+//!char * fp_op(char * stream, FP_Opcode opc,unsigned i,unsigned pop_stk);
+
+// compare st(0),st(1) and pop stack twice
+//!char * fcompp(char * stream);
+ENCODER_DECLARE_EXPORT char * fldcw(char * stream, const M_Opnd & mem);
+ENCODER_DECLARE_EXPORT char * fnstcw(char * stream, const M_Opnd & mem);
+ENCODER_DECLARE_EXPORT char * fnstsw(char * stream);
+//!char * fchs(char * stream);
+//!char * frem(char * stream);
+//!char * fxch(char * stream,unsigned i);
+//!char * fcomip(char * stream, unsigned i);
+
+// load from memory (as fp) into fp register stack
+ENCODER_DECLARE_EXPORT char * fld(char * stream, const M_Opnd & m, bool is_double);
+//!char *fld80(char * stream,const M_Opnd& mem);
+
+// load from memory (as int) into fp register stack
+//!char * fild(char * stream,const M_Opnd& mem,int is_long);
+
+// push st(i) onto fp register stack
+//!char * fld(char * stream,unsigned i);
+
+// push the constants 0.0 and 1.0 onto the fp register stack
+//!char * fldz(char * stream);
+//!char * fld1(char * stream);
+
+// store stack to memory (as int), always popping the stack
+ENCODER_DECLARE_EXPORT char * fist(char * stream, const M_Opnd & mem, bool is_long, bool pop_stk);
+// store stack to to memory (as fp), optionally popping the stack
+ENCODER_DECLARE_EXPORT char * fst(char * stream, const M_Opnd & m, bool is_double, bool pop_stk);
+// store ST(0) to ST(i), optionally popping the stack. Takes 1 clock
+ENCODER_DECLARE_EXPORT char * fst(char * stream, unsigned i, bool pop_stk);
+
+//!char * pushad(char * stream);
+//!char * pushfd(char * stream);
+//!char * popad(char * stream);
+//!char * popfd(char * stream);
+
+// stack frame allocation instructions: enter & leave
+//
+//    enter frame_size
+//
+//    is equivalent to:
+//
+//    push    ebp
+//    mov     ebp,esp
+//    sub     esp,frame_size
+//
+//!char *enter(char * stream,const Imm_Opnd& imm);
+
+// leave
+// is equivalent to:
+//
+// mov        esp,ebp
+// pop        ebp
+//!char *leave(char * stream);
+
+// sahf  loads SF, ZF, AF, PF, and CF flags from eax
+//!char *sahf(char * stream);
+
+// Intrinsic FP math functions
+
+//!char *math_fsin(char * stream);
+//!char *math_fcos(char * stream);
+//!char *math_fabs(char * stream);
+//!char *math_fpatan(char * stream);
+ENCODER_DECLARE_EXPORT char * fprem(char * stream);
+ENCODER_DECLARE_EXPORT char * fprem1(char * stream);
+//!char *math_frndint(char * stream);
+//!char *math_fptan(char * stream);
+
+//
+// Add 1-7 bytes padding, with as few instructions as possible,
+// with no effect on the processor state (e.g., registers, flags)
+//
+//!char *padding(char * stream, unsigned num);
+
+// prolog and epilog code generation
+//- char *prolog(char * stream,unsigned frame_size,unsigned reg_save_mask);
+//- char *epilog(char * stream,unsigned reg_save_mask);
+
+//!extern R_Opnd reg_operand_array[];
+
+// fsave and frstor
+//!char *fsave(char * stream);
+//!char *frstor(char * stream);
+
+// lahf : Load Status Flags into AH Register
+//!char *lahf(char * stream);
+
+// mfence : Memory Fence
+//!char *mfence(char * stream);
+
+#endif // _VM_ENCODER_H_
diff --git a/vm/compiler/codegen/x86/libenc/encoder.inl b/vm/compiler/codegen/x86/libenc/encoder.inl
new file mode 100644
index 0000000..663d492
--- /dev/null
+++ b/vm/compiler/codegen/x86/libenc/encoder.inl
@@ -0,0 +1,850 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+
+extern const RegName map_of_regno_2_regname[];
+extern const OpndSize map_of_EncoderOpndSize_2_RealOpndSize[];
+extern const Mnemonic map_of_alu_opcode_2_mnemonic[];
+extern const Mnemonic map_of_shift_opcode_2_mnemonic[];
+
+// S_ stands for 'Signed'
+extern const Mnemonic S_map_of_condition_code_2_branch_mnemonic[];
+// U_ stands for 'Unsigned'
+extern const Mnemonic U_map_of_condition_code_2_branch_mnemonic[];
+
+inline static RegName map_reg(Reg_No r) {
+    assert(r >= 0 && r <= n_reg);
+    return map_of_regno_2_regname[r];
+}
+
+inline static OpndSize map_size(Opnd_Size o_size) {
+    assert(o_size >= 0 && o_size <= n_size);
+    return map_of_EncoderOpndSize_2_RealOpndSize[o_size];
+}
+
+inline static Mnemonic map_alu(ALU_Opcode alu) {
+    assert(alu >= 0 && alu < n_alu);
+    return map_of_alu_opcode_2_mnemonic[alu];
+}
+
+inline static Mnemonic map_shift(Shift_Opcode shc) {
+    assert(shc >= 0 && shc < n_shift);
+    return map_of_shift_opcode_2_mnemonic[shc];
+}
+
+inline bool fit8(int64 val) {
+    return (CHAR_MIN <= val) && (val <= CHAR_MAX);
+}
+
+inline bool fit32(int64 val) {
+    return (INT_MIN <= val) && (val <= INT_MAX);
+}
+
+inline static void add_r(EncoderBase::Operands & args, const R_Opnd & r, Opnd_Size sz, OpndExt ext = OpndExt_None) {
+    RegName reg = map_reg(r.reg_no());
+    if (sz != n_size) {
+        OpndSize size = map_size(sz);
+        if (size != getRegSize(reg)) {
+            reg = getAliasReg(reg, size);
+        }
+    }
+    args.add(EncoderBase::Operand(reg, ext));
+}
+
+inline static void add_m(EncoderBase::Operands & args, const M_Opnd & m, Opnd_Size sz, OpndExt ext = OpndExt_None) {
+        assert(n_size != sz);
+        args.add(EncoderBase::Operand(map_size(sz),
+            map_reg(m.base().reg_no()), map_reg(m.index().reg_no()),
+            (unsigned)m.scale().get_value(), (int)m.disp().get_value(), ext));
+}
+
+inline static void add_rm(EncoderBase::Operands & args, const RM_Opnd & rm, Opnd_Size sz, OpndExt ext = OpndExt_None) {
+    rm.is_reg() ? add_r(args, (R_Opnd &)rm, sz, ext) : add_m(args, (M_Opnd &)rm, sz, ext);
+}
+
+inline static void add_xmm(EncoderBase::Operands & args, const XMM_Opnd & xmm, bool dbl) {
+    // Gregory -
+    // XMM registers indexes in Reg_No enum are shifted by xmm0_reg, their indexes
+    // don't start with 0, so it is necessary to subtract xmm0_reg index from
+    // xmm.get_idx() value
+    assert(xmm.get_idx() >= xmm0_reg);
+    return args.add((RegName)( (dbl ? RegName_XMM0D : RegName_XMM0S) + xmm.get_idx() -
+            xmm0_reg));
+}
+
+inline static void add_fp(EncoderBase::Operands & args, unsigned i, bool dbl) {
+    return args.add((RegName)( (dbl ? RegName_FP0D : RegName_FP0S) + i));
+}
+
+inline static void add_imm(EncoderBase::Operands & args, const Imm_Opnd & imm) {
+    assert(n_size != imm.get_size());
+    args.add(EncoderBase::Operand(map_size(imm.get_size()), imm.get_value(),
+        imm.is_signed() ? OpndExt_Signed : OpndExt_Zero));
+}
+
+ENCODER_DECLARE_EXPORT char * prefix(char * stream, InstrPrefix p) {
+    *stream = (char)p;
+    return stream + 1;
+}
+
+// stack push and pop instructions
+ENCODER_DECLARE_EXPORT char * push(char * stream, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_PUSH, args);
+}
+
+ENCODER_DECLARE_EXPORT char * push(char * stream, const Imm_Opnd & imm) {
+    EncoderBase::Operands args;
+#ifdef _EM64T_
+    add_imm(args, imm);
+#else
+    // we need this workaround to be compatible with the former ia32 encoder implementation
+    add_imm(args, Imm_Opnd(size_32, imm.get_value()));
+#endif
+    return EncoderBase::encode(stream, Mnemonic_PUSH, args);
+}
+
+ENCODER_DECLARE_EXPORT char * pop(char * stream, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_POP, args);
+}
+
+// cmpxchg or xchg
+ENCODER_DECLARE_EXPORT char * cmpxchg(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    add_r(args, r, sz);
+    RegName implicitReg = getAliasReg(RegName_EAX, map_size(sz));
+    args.add(implicitReg);
+    return (char*)EncoderBase::encode(stream, Mnemonic_CMPXCHG, args);
+}
+
+ENCODER_DECLARE_EXPORT char * xchg(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    add_r(args, r, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_XCHG, args);
+}
+
+// inc(rement), dec(rement), not, neg(ate) instructions
+ENCODER_DECLARE_EXPORT char * inc(char * stream, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_INC, args);
+}
+
+ENCODER_DECLARE_EXPORT char * dec(char * stream, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_DEC, args);
+}
+
+ENCODER_DECLARE_EXPORT char * _not(char * stream, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_NOT, args);
+}
+
+ENCODER_DECLARE_EXPORT char * neg(char * stream, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_NEG, args);
+}
+
+ENCODER_DECLARE_EXPORT char * nop(char * stream) {
+    EncoderBase::Operands args;
+    return (char*)EncoderBase::encode(stream, Mnemonic_NOP, args);
+}
+
+ENCODER_DECLARE_EXPORT char * int3(char * stream) {
+    EncoderBase::Operands args;
+    return (char*)EncoderBase::encode(stream, Mnemonic_INT3, args);
+}
+
+// alu instructions: add, or, adc, sbb, and, sub, xor, cmp
+ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, map_alu(opc), args);
+};
+
+ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const M_Opnd & m, const R_Opnd & r, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, m, sz);
+    add_rm(args, r, sz);
+    return (char*)EncoderBase::encode(stream, map_alu(opc), args);
+}
+
+ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, r, sz);
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, map_alu(opc), args);
+}
+
+// test instruction
+ENCODER_DECLARE_EXPORT char * test(char * stream, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    assert(imm.get_size() <= sz);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, Mnemonic_TEST, args);
+}
+
+ENCODER_DECLARE_EXPORT char * test(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    add_r(args, r, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_TEST, args);
+}
+
+// shift instructions: shl, shr, sar, shld, shrd
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode shc, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, map_shift(shc), args);
+}
+
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode shc, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    args.add(RegName_CL);
+    return (char*)EncoderBase::encode(stream, map_shift(shc), args);
+}
+
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode shc, const RM_Opnd & rm,
+                            const R_Opnd & r, const Imm_Opnd & imm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    assert(shc == shld_opc || shc == shrd_opc);
+    add_rm(args, rm, sz);
+    add_r(args, r, sz);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, map_shift(shc), args);
+}
+
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode shc, const RM_Opnd & rm,
+                            const R_Opnd & r, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    assert(shc == shld_opc || shc == shrd_opc);
+    add_rm(args, rm, sz);
+    add_r(args, r, sz);
+    args.add(RegName_CL);
+    return (char*)EncoderBase::encode(stream, map_shift(shc), args);
+}
+
+// multiply instructions: mul, imul
+ENCODER_DECLARE_EXPORT char * mul(char * stream, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    args.add(RegName_EDX);
+    args.add(RegName_EAX);
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_MUL, args);
+}
+
+ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_r(args, r, sz);
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_IMUL, args);
+}
+
+ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const Imm_Opnd & imm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_r(args, r, sz);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, Mnemonic_IMUL, args);
+}
+
+ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const RM_Opnd & rm,
+                           const Imm_Opnd & imm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_r(args, r, sz);
+    add_rm(args, rm, sz);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, Mnemonic_IMUL, args);
+}
+
+// divide instructions: div, idiv
+ENCODER_DECLARE_EXPORT char * idiv(char * stream, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+#ifdef _EM64T_
+    add_r(args, rdx_opnd, sz);
+    add_r(args, rax_opnd, sz);
+#else
+    add_r(args, edx_opnd, sz);
+    add_r(args, eax_opnd, sz);
+#endif
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_IDIV, args);
+}
+
+// data movement: mov
+ENCODER_DECLARE_EXPORT char * mov(char * stream, const M_Opnd & m, const R_Opnd & r, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_m(args, m, sz);
+    add_r(args, r, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_MOV, args);
+}
+
+ENCODER_DECLARE_EXPORT char * mov(char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_r(args, r, sz);
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_MOV, args);
+}
+
+ENCODER_DECLARE_EXPORT char * mov(char * stream, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, Mnemonic_MOV, args);
+}
+
+ENCODER_DECLARE_EXPORT char * movd(char * stream, const RM_Opnd & rm, const XMM_Opnd & xmm) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, size_32);
+    add_xmm(args, xmm, false);
+    return (char*)EncoderBase::encode(stream, Mnemonic_MOVD, args);
+}
+
+ENCODER_DECLARE_EXPORT char * movd(char * stream, const XMM_Opnd & xmm, const RM_Opnd & rm) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm, false);
+    add_rm(args, rm, size_32);
+    return (char*)EncoderBase::encode(stream, Mnemonic_MOVD, args);
+}
+
+ENCODER_DECLARE_EXPORT char * movq(char * stream, const RM_Opnd & rm, const XMM_Opnd & xmm) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, size_64);
+    add_xmm(args, xmm, true);
+    return (char*)EncoderBase::encode(stream, Mnemonic_MOVQ, args);
+}
+
+ENCODER_DECLARE_EXPORT char * movq(char * stream, const XMM_Opnd & xmm, const RM_Opnd & rm) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm, true);
+    add_rm(args, rm, size_64);
+    return (char*)EncoderBase::encode(stream, Mnemonic_MOVQ, args);
+}
+
+ENCODER_DECLARE_EXPORT char * movsx(char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_r(args, r, n_size);
+    add_rm(args, rm, sz, OpndExt_Signed);
+    return (char*)EncoderBase::encode(stream, Mnemonic_MOVSX, args);
+}
+
+ENCODER_DECLARE_EXPORT char * movzx(char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_r(args, r, n_size);
+    // movzx r64, r/m32 is not available on em64t
+    // mov r32, r/m32 should zero out upper bytes
+    assert(sz <= size_16);
+    add_rm(args, rm, sz, OpndExt_Zero);
+    return (char*)EncoderBase::encode(stream, Mnemonic_MOVZX, args);
+}
+
+// sse mov
+ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm, dbl);
+    add_m(args, mem, dbl ? size_64 : size_32);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_MOVSD : Mnemonic_MOVSS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const M_Opnd &  mem, const XMM_Opnd & xmm, bool dbl) {
+    EncoderBase::Operands args;
+    add_m(args, mem, dbl ? size_64 : size_32);
+    add_xmm(args, xmm, dbl);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_MOVSD : Mnemonic_MOVSS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, dbl);
+    add_xmm(args, xmm1, dbl);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_MOVSD : Mnemonic_MOVSS, args );
+}
+
+// sse add, sub, mul, div
+ENCODER_DECLARE_EXPORT char * sse_add(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm, dbl);
+    add_m(args, mem, dbl ? size_64 : size_32);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_ADDSD : Mnemonic_ADDSS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_add(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, dbl);
+    add_xmm(args, xmm1, dbl);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_ADDSD : Mnemonic_ADDSS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_sub(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm, dbl);
+    add_m(args, mem, dbl ? size_64 : size_32);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_SUBSD : Mnemonic_SUBSS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_sub(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, dbl);
+    add_xmm(args, xmm1, dbl);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_SUBSD : Mnemonic_SUBSS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_mul( char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm, dbl);
+    add_m(args, mem, dbl ? size_64 : size_32);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_MULSD : Mnemonic_MULSS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_mul(char * stream, const XMM_Opnd& xmm0, const XMM_Opnd& xmm1, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args,  xmm0, dbl);
+    add_xmm(args,  xmm1, dbl);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_MULSD : Mnemonic_MULSS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_div(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm, dbl);
+    add_m(args, mem, dbl ? size_64 : size_32);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_DIVSD : Mnemonic_DIVSS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_div(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, dbl);
+    add_xmm(args, xmm1, dbl);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_DIVSD : Mnemonic_DIVSS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_xor(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, true);
+    add_xmm(args, xmm1, true);
+    return (char*)EncoderBase::encode(stream, Mnemonic_PXOR, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_compare(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, true);
+    add_xmm(args, xmm1, true);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_COMISD : Mnemonic_COMISS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_compare(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, dbl);
+    add_m(args, mem, dbl ? size_64 : size_32);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_COMISD : Mnemonic_COMISS, args);
+}
+
+// sse conversions
+ENCODER_DECLARE_EXPORT char * sse_cvt_si(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm, dbl);
+    add_m(args, mem, size_32);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_CVTSI2SD : Mnemonic_CVTSI2SS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_cvtt2si(char * stream, const R_Opnd & reg, const M_Opnd & mem, bool dbl) {
+    EncoderBase::Operands args;
+    add_rm(args, reg, size_32);
+    add_m(args, mem, dbl ? size_64 : size_32);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_CVTTSD2SI : Mnemonic_CVTTSS2SI, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_cvtt2si(char * stream, const R_Opnd & reg, const XMM_Opnd & xmm, bool dbl) {
+    EncoderBase::Operands args;
+    add_rm(args, reg, size_32);
+    add_xmm(args, xmm, dbl);
+    return (char*)EncoderBase::encode(stream, dbl ? Mnemonic_CVTTSD2SI : Mnemonic_CVTTSS2SI, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_cvt_fp2dq(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, dbl);
+    add_xmm(args, xmm1, dbl);
+    return (char*)EncoderBase::encode(stream, dbl ?  Mnemonic_CVTTPD2DQ : Mnemonic_CVTTPS2DQ, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_cvt_dq2fp(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, dbl);
+    add_xmm(args, xmm1, dbl);
+    return (char*)EncoderBase::encode(stream, dbl ?  Mnemonic_CVTDQ2PD : Mnemonic_CVTDQ2PS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_d2s(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem64) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, false);
+    add_m(args, mem64, size_64);
+    return (char*)EncoderBase::encode(stream, Mnemonic_CVTSD2SS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_d2s(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, false);
+    add_xmm(args, xmm1, true);
+    return (char*)EncoderBase::encode(stream, Mnemonic_CVTSD2SS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_s2d(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem32) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, true);
+    add_m(args, mem32, size_32);
+    return (char*)EncoderBase::encode(stream, Mnemonic_CVTSS2SD, args);
+}
+
+ENCODER_DECLARE_EXPORT char * sse_s2d(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1) {
+    EncoderBase::Operands args;
+    add_xmm(args, xmm0, true);
+    add_xmm(args, xmm1, false);
+    return (char*)EncoderBase::encode(stream, Mnemonic_CVTSS2SD, args);
+}
+
+// condition operations
+ENCODER_DECLARE_EXPORT char *cmov(char * stream, ConditionCode cc, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_r(args, r, sz);
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, (Mnemonic)(Mnemonic_CMOVcc + cc), args);
+}
+
+ENCODER_DECLARE_EXPORT char * setcc(char * stream, ConditionCode cc, const RM_Opnd & rm8) {
+    EncoderBase::Operands args;
+    add_rm(args, rm8, size_8);
+    return (char*)EncoderBase::encode(stream, (Mnemonic)(Mnemonic_SETcc + cc), args);
+}
+
+// load effective address: lea
+ENCODER_DECLARE_EXPORT char * lea(char * stream, const R_Opnd & r, const M_Opnd & m, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_r(args, r, sz);
+    add_m(args, m, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_LEA, args);
+}
+
+ENCODER_DECLARE_EXPORT char * cdq(char * stream) {
+    EncoderBase::Operands args;
+    args.add(RegName_EDX);
+    args.add(RegName_EAX);
+    return (char*)EncoderBase::encode(stream, Mnemonic_CDQ, args);
+}
+
+ENCODER_DECLARE_EXPORT char * wait(char * stream) {
+    return (char*)EncoderBase::encode(stream, Mnemonic_WAIT, EncoderBase::Operands());
+}
+
+// control-flow instructions
+
+// loop
+ENCODER_DECLARE_EXPORT char * loop(char * stream, const Imm_Opnd & imm) {
+    EncoderBase::Operands args;
+    assert(imm.get_size() == size_8);
+    args.add(RegName_ECX);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, Mnemonic_LOOP, args);
+}
+
+// jump
+ENCODER_DECLARE_EXPORT char * jump8(char * stream, const Imm_Opnd & imm) {
+    EncoderBase::Operands args;
+    assert(imm.get_size() == size_8);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, Mnemonic_JMP, args);
+}
+
+ENCODER_DECLARE_EXPORT char * jump32(char * stream, const Imm_Opnd & imm) {
+    EncoderBase::Operands args;
+    assert(imm.get_size() == size_32);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, Mnemonic_JMP, args);
+}
+
+ENCODER_DECLARE_EXPORT char * jump(char * stream, const RM_Opnd & rm, Opnd_Size sz) {
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_JMP, args);
+}
+
+/**
+ * @note On EM64T: if target lies beyond 2G (does not fit into 32 bit
+ *       offset) then generates indirect jump using RAX (whose content is
+ *       destroyed).
+ */
+ENCODER_DECLARE_EXPORT char * jump(char * stream, char * target) {
+#ifdef _EM64T_
+    int64 offset = target - stream;
+    // sub 2 bytes for the short version
+    offset -= 2;
+    if (fit8(offset)) {
+        // use 8-bit signed relative form
+        return jump8(stream, Imm_Opnd(size_8, offset));
+    } else if (fit32(offset)) {
+        // sub 5 (3 + 2)bytes for the long version
+        offset -= 3;
+        // use 32-bit signed relative form
+        return jump32(stream, Imm_Opnd(size_32, offset));
+    }
+    // need to use absolute indirect jump
+    stream = mov(stream, rax_opnd, Imm_Opnd(size_64, (int64)target), size_64);
+    return jump(stream, rax_opnd, size_64);
+#else
+    I_32 offset = target - stream;
+    // sub 2 bytes for the short version
+    offset -= 2;
+    if (fit8(offset)) {
+        // use 8-bit signed relative form
+        return jump8(stream, Imm_Opnd(size_8, offset));
+    }
+    // sub 5 (3 + 2) bytes for the long version
+    offset -= 3;
+    // use 32-bit signed relative form
+    return jump32(stream, Imm_Opnd(size_32, offset));
+#endif
+}
+
+// branch
+ENCODER_DECLARE_EXPORT char * branch8(char * stream, ConditionCode cond,
+                                      const Imm_Opnd & imm,
+                                      InstrPrefix pref)
+{
+    if (pref != no_prefix) {
+        assert(pref == hint_branch_taken_prefix || pref == hint_branch_taken_prefix);
+        stream = prefix(stream, pref);
+    }
+    Mnemonic m = (Mnemonic)(Mnemonic_Jcc + cond);
+    EncoderBase::Operands args;
+    assert(imm.get_size() == size_8);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, m, args);
+}
+
+ENCODER_DECLARE_EXPORT char * branch32(char * stream, ConditionCode cond,
+                                       const Imm_Opnd & imm,
+                                       InstrPrefix pref)
+{
+    if (pref != no_prefix) {
+        assert(pref == hint_branch_taken_prefix || pref == hint_branch_taken_prefix);
+        stream = prefix(stream, pref);
+    }
+    Mnemonic m = (Mnemonic)(Mnemonic_Jcc + cond);
+    EncoderBase::Operands args;
+    assert(imm.get_size() == size_32);
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, m, args);
+}
+
+/*
+ENCODER_DECLARE_EXPORT char * branch(char * stream, ConditionCode cc, const char * target, InstrPrefix prefix) {
+// sub 2 bytes for the short version
+int64 offset = stream-target-2;
+if( fit8(offset) ) {
+return branch8(stream, cc, Imm_Opnd(size_8, (char)offset), is_signed);
+}
+return branch32(stream, cc, Imm_Opnd(size_32, (int)offset), is_signed);
+}
+*/
+
+// call
+ENCODER_DECLARE_EXPORT char * call(char * stream, const Imm_Opnd & imm)
+{
+    EncoderBase::Operands args;
+    add_imm(args, imm);
+    return (char*)EncoderBase::encode(stream, Mnemonic_CALL, args);
+}
+
+ENCODER_DECLARE_EXPORT char * call(char * stream, const RM_Opnd & rm,
+                                   Opnd_Size sz)
+{
+    EncoderBase::Operands args;
+    add_rm(args, rm, sz);
+    return (char*)EncoderBase::encode(stream, Mnemonic_CALL, args);
+}
+
+/**
+* @note On EM64T: if target lies beyond 2G (does not fit into 32 bit
+*       offset) then generates indirect jump using RAX (whose content is
+*       destroyed).
+*/
+ENCODER_DECLARE_EXPORT char * call(char * stream, const char * target)
+{
+#ifdef _EM64T_
+    int64 offset = target - stream;
+    if (fit32(offset)) {
+        offset -= 5; // sub 5 bytes for this instruction
+        Imm_Opnd imm(size_32, offset);
+        return call(stream, imm);
+    }
+    // need to use absolute indirect call
+    stream = mov(stream, rax_opnd, Imm_Opnd(size_64, (int64)target), size_64);
+    return call(stream, rax_opnd, size_64);
+#else
+    I_32 offset = target - stream;
+    offset -= 5; // sub 5 bytes for this instruction
+    Imm_Opnd imm(size_32, offset);
+    return call(stream, imm);
+#endif
+}
+
+// return instruction
+ENCODER_DECLARE_EXPORT char * ret(char * stream)
+{
+    EncoderBase::Operands args;
+    return (char*)EncoderBase::encode(stream, Mnemonic_RET, args);
+}
+
+ENCODER_DECLARE_EXPORT char * ret(char * stream, const Imm_Opnd & imm)
+{
+    EncoderBase::Operands args;
+    // TheManual says imm can be 16-bit only
+    //assert(imm.get_size() <= size_16);
+    args.add(EncoderBase::Operand(map_size(size_16), imm.get_value()));
+    return (char*)EncoderBase::encode(stream, Mnemonic_RET, args);
+}
+
+ENCODER_DECLARE_EXPORT char * ret(char * stream, unsigned short pop)
+{
+    // TheManual says it can only be imm16
+    EncoderBase::Operands args(EncoderBase::Operand(OpndSize_16, pop, OpndExt_Zero));
+    return (char*)EncoderBase::encode(stream, Mnemonic_RET, args);
+}
+
+// floating-point instructions
+ENCODER_DECLARE_EXPORT char * fld(char * stream, const M_Opnd & m,
+                                  bool is_double) {
+    EncoderBase::Operands args;
+    // a fake FP register as operand
+    add_fp(args, 0, is_double);
+    add_m(args, m, is_double ? size_64 : size_32);
+    return (char*)EncoderBase::encode(stream, Mnemonic_FLD, args);
+}
+
+ENCODER_DECLARE_EXPORT char * fist(char * stream, const M_Opnd & mem,
+                                   bool is_long, bool pop_stk)
+{
+    EncoderBase::Operands args;
+    if (pop_stk) {
+        add_m(args, mem, is_long ? size_64 : size_32);
+        // a fake FP register as operand
+        add_fp(args, 0, is_long);
+        return (char*)EncoderBase::encode(stream,  Mnemonic_FISTP, args);
+    }
+    // only 32-bit operands are supported
+    assert(is_long == false);
+    add_m(args, mem, size_32);
+    add_fp(args, 0, false);
+    return (char*)EncoderBase::encode(stream,  Mnemonic_FIST, args);
+}
+
+ENCODER_DECLARE_EXPORT char * fst(char * stream, const M_Opnd & m,
+                                  bool is_double, bool pop_stk)
+{
+    EncoderBase::Operands args;
+    add_m(args, m, is_double ? size_64 : size_32);
+    // a fake FP register as operand
+    add_fp(args, 0, is_double);
+    return (char*)EncoderBase::encode(stream,
+                                    pop_stk ? Mnemonic_FSTP : Mnemonic_FST,
+                                    args);
+}
+
+ENCODER_DECLARE_EXPORT char * fst(char * stream, unsigned i, bool pop_stk)
+{
+    EncoderBase::Operands args;
+    add_fp(args, i, true);
+    return (char*)EncoderBase::encode(stream,
+                                    pop_stk ? Mnemonic_FSTP : Mnemonic_FST,
+                                    args);
+}
+
+ENCODER_DECLARE_EXPORT char * fldcw(char * stream, const M_Opnd & mem) {
+    EncoderBase::Operands args;
+    add_m(args, mem, size_16);
+    return (char*)EncoderBase::encode(stream, Mnemonic_FLDCW, args);
+}
+
+ENCODER_DECLARE_EXPORT char * fnstcw(char * stream, const M_Opnd & mem) {
+    EncoderBase::Operands args;
+    add_m(args, mem, size_16);
+    return (char*)EncoderBase::encode(stream, Mnemonic_FNSTCW, args);
+}
+
+ENCODER_DECLARE_EXPORT char * fnstsw(char * stream)
+{
+    return (char*)EncoderBase::encode(stream, Mnemonic_FNSTCW,
+                                      EncoderBase::Operands());
+}
+
+// string operations
+ENCODER_DECLARE_EXPORT char * set_d(char * stream, bool set) {
+    EncoderBase::Operands args;
+    return (char*)EncoderBase::encode(stream,
+                                      set ? Mnemonic_STD : Mnemonic_CLD,
+                                      args);
+}
+
+ENCODER_DECLARE_EXPORT char * scas(char * stream, unsigned char prefix)
+{
+	EncoderBase::Operands args;
+    if (prefix != no_prefix) {
+        assert(prefix == prefix_repnz || prefix == prefix_repz);
+        *stream = prefix;
+        ++stream;
+    }
+    return (char*)EncoderBase::encode(stream, Mnemonic_SCAS, args);
+}
+
+ENCODER_DECLARE_EXPORT char * stos(char * stream, unsigned char prefix)
+{
+    if (prefix != no_prefix) {
+        assert(prefix == prefix_rep);
+        *stream = prefix;
+        ++stream;
+    }
+
+	EncoderBase::Operands args;
+	return (char*)EncoderBase::encode(stream, Mnemonic_STOS, args);
+}
+
+// Intrinsic FP math functions
+
+ENCODER_DECLARE_EXPORT char * fprem(char * stream) {
+    return (char*)EncoderBase::encode(stream, Mnemonic_FPREM,
+                                      EncoderBase::Operands());
+}
+
+ENCODER_DECLARE_EXPORT char * fprem1(char * stream) {
+    return (char*)EncoderBase::encode(stream, Mnemonic_FPREM1,
+                                      EncoderBase::Operands());
+}
diff --git a/vm/interp/Interp.cpp b/vm/interp/Interp.cpp
index 13ed7ae..8f8596b 100644
--- a/vm/interp/Interp.cpp
+++ b/vm/interp/Interp.cpp
@@ -991,24 +991,6 @@
  */
 
 /*
- * Construct an s4 from two consecutive half-words of switch data.
- * This needs to check endianness because the DEX optimizer only swaps
- * half-words in instruction stream.
- *
- * "switchData" must be 32-bit aligned.
- */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-static inline s4 s4FromSwitchData(const void* switchData) {
-    return *(s4*) switchData;
-}
-#else
-static inline s4 s4FromSwitchData(const void* switchData) {
-    u2* data = switchData;
-    return data[0] | (((s4) data[1]) << 16);
-}
-#endif
-
-/*
  * Find the matching case.  Returns the offset to the handler instructions.
  *
  * Returns 3 if we don't find a match (it's the size of the packed-switch
@@ -1962,7 +1944,9 @@
     if (gDvm.executionMode == kExecutionModeInterpFast)
         stdInterp = dvmMterpStd;
 #if defined(WITH_JIT)
-    else if (gDvm.executionMode == kExecutionModeJit)
+    else if (gDvm.executionMode == kExecutionModeJit ||
+             gDvm.executionMode == kExecutionModeNcgO0 ||
+             gDvm.executionMode == kExecutionModeNcgO1)
         stdInterp = dvmMterpStd;
 #endif
     else
diff --git a/vm/interp/InterpDefs.h b/vm/interp/InterpDefs.h
index acec648..a053f6d 100644
--- a/vm/interp/InterpDefs.h
+++ b/vm/interp/InterpDefs.h
@@ -105,4 +105,22 @@
 
 #endif
 
+/*
+ * Construct an s4 from two consecutive half-words of switch data.
+ * This needs to check endianness because the DEX optimizer only swaps
+ * half-words in instruction stream.
+ *
+ * "switchData" must be 32-bit aligned.
+ */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+static inline s4 s4FromSwitchData(const void* switchData) {
+    return *(s4*) switchData;
+}
+#else
+static inline s4 s4FromSwitchData(const void* switchData) {
+    u2* data = switchData;
+    return data[0] | (((s4) data[1]) << 16);
+}
+#endif
+
 #endif  // DALVIK_INTERP_DEFS_H_
diff --git a/vm/interp/InterpState.h b/vm/interp/InterpState.h
index 37b7fdd..cc0a13f 100644
--- a/vm/interp/InterpState.h
+++ b/vm/interp/InterpState.h
@@ -25,6 +25,13 @@
 #define DALVIK_INTERP_STATE_H_
 
 /*
+ * For x86 JIT. In the lowered code sequences for bytecodes, at most 10
+ * temporary variables may be live at the same time. Therefore, at most
+ * 10 temporary variables can be spilled at the same time.
+*/
+#define MAX_SPILL_JIT_IA 10
+
+/*
  * Execution mode, e.g. interpreter vs. JIT.
  */
 enum ExecutionMode {
@@ -34,6 +41,10 @@
 #if defined(WITH_JIT)
     kExecutionModeJit,
 #endif
+#if defined(WITH_JIT)  /* IA only */
+    kExecutionModeNcgO0,
+    kExecutionModeNcgO1,
+#endif
 };
 
 /*
@@ -232,6 +243,15 @@
     u4 unused:31;
 };
 
+#if defined(ARCH_IA32)
+/*
+ * JIT code genarator optimization level
+ */
+enum JitOptLevel {
+    kJitOptLevelO0 = 0,
+    kJitOptLevelO1 = 1,
+};
+#endif  // #if defined(ARCH_IA32)
 #endif
 
 #endif  // DALVIK_INTERP_STATE_H_
diff --git a/vm/interp/Jit.cpp b/vm/interp/Jit.cpp
index 9f87705..6d53954 100644
--- a/vm/interp/Jit.cpp
+++ b/vm/interp/Jit.cpp
@@ -643,6 +643,8 @@
              */
             android_atomic_release_store((int32_t)dPC,
                  (volatile int32_t *)(void *)&gDvmJit.pJitEntryTable[idx].dPC);
+            /* for simulator mode, we need to initialized codeAddress to null */
+            gDvmJit.pJitEntryTable[idx].codeAddress = NULL;
             gDvmJit.pJitEntryTable[idx].dPC = dPC;
             gDvmJit.jitTableEntriesUsed++;
         } else {
@@ -796,7 +798,15 @@
             if (lastPC == NULL) break;
             /* Grow the trace around the last PC if jitState is kJitTSelect */
             dexDecodeInstruction(lastPC, &decInsn);
-
+#if TRACE_OPCODE_FILTER
+            /* Only add JIT support opcode to trace. End the trace if
+             * this opcode is not supported.
+             */
+            if (!dvmIsOpcodeSupportedByJit(decInsn.opcode)) {
+                self->jitState = kJitTSelectEnd;
+                break;
+            }
+#endif
             /*
              * Treat {PACKED,SPARSE}_SWITCH as trace-ending instructions due
              * to the amount of space it takes to generate the chaining
diff --git a/vm/mterp/c/OP_EXECUTE_INLINE.cpp b/vm/mterp/c/OP_EXECUTE_INLINE.cpp
index 8d20764..288ccc9 100644
--- a/vm/mterp/c/OP_EXECUTE_INLINE.cpp
+++ b/vm/mterp/c/OP_EXECUTE_INLINE.cpp
@@ -47,7 +47,7 @@
             ;
         }
 
-        if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
+        if (self->interpBreak.ctl.subMode & kSubModeDebugProfile) {
             if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
                 GOTO_exceptionThrown();
         } else {
diff --git a/vm/mterp/c/OP_EXECUTE_INLINE_RANGE.cpp b/vm/mterp/c/OP_EXECUTE_INLINE_RANGE.cpp
index 664ada4..467f0e9 100644
--- a/vm/mterp/c/OP_EXECUTE_INLINE_RANGE.cpp
+++ b/vm/mterp/c/OP_EXECUTE_INLINE_RANGE.cpp
@@ -31,7 +31,7 @@
             ;
         }
 
-        if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
+        if (self->interpBreak.ctl.subMode & kSubModeDebugProfile) {
             if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
                 GOTO_exceptionThrown();
         } else {
diff --git a/vm/mterp/config-x86-atom b/vm/mterp/config-x86-atom
deleted file mode 100644
index 8cf427c..0000000
--- a/vm/mterp/config-x86-atom
+++ /dev/null
@@ -1,306 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Specifies the size of the assembly region in bytes
-handler-style computed-goto
-handler-size 64
-
-# source for the instruction table stub
-asm-stub x86-atom/stub.S
-
-# file header, macros and definitions
-import c/header.cpp
-import x86-atom/header.S
-
-# common defs for the C helper; include this before the instruction handlers
-import cstubs/stubdefs.cpp
-import c/opcommon.cpp
-
-# start of opcode list; command gives default directory location of instruction files
-op-start x86-atom
-
-#op OP_ADD_DOUBLE_2ADDR c
-#op OP_ADD_DOUBLE c
-#op OP_ADD_FLOAT_2ADDR c
-#op OP_ADD_FLOAT c
-#op OP_ADD_INT_2ADDR c
-#op OP_ADD_INT_LIT16 c
-#op OP_ADD_INT_LIT8 c
-#op OP_ADD_INT c
-#op OP_ADD_LONG_2ADDR c
-#op OP_ADD_LONG c
-#op OP_AGET_BOOLEAN c
-#op OP_AGET_BYTE c
-#op OP_AGET_CHAR c
-#op OP_AGET_OBJECT c
-#op OP_AGET c
-#op OP_AGET_SHORT c
-#op OP_AGET_WIDE c
-#op OP_AND_INT_2ADDR c
-#op OP_AND_INT_LIT16 c
-#op OP_AND_INT_LIT8 c
-#op OP_AND_INT c
-#op OP_AND_LONG_2ADDR c
-#op OP_AND_LONG c
-#op OP_APUT_BOOLEAN c
-#op OP_APUT_BYTE c
-#op OP_APUT_CHAR c
-#op OP_APUT_OBJECT c
-#op OP_APUT c
-#op OP_APUT_SHORT c
-#op OP_APUT_WIDE c
-#op OP_ARRAY_LENGTH c
-#op OP_CHECK_CAST c
-#op OP_CMPG_DOUBLE c
-#op OP_CMPG_FLOAT c
-#op OP_CMPL_DOUBLE c
-#op OP_CMPL_FLOAT c
-#op OP_CMP_LONG c
-#op OP_CONST_16 c
-#op OP_CONST_4 c
-#op OP_CONST_CLASS c
-#op OP_CONST_HIGH16 c
-#op OP_CONST c
-#op OP_CONST_STRING_JUMBO c
-#op OP_CONST_STRING c
-#op OP_CONST_WIDE_16 c
-#op OP_CONST_WIDE_32 c
-#op OP_CONST_WIDE_HIGH16 c
-#op OP_CONST_WIDE c
-#op OP_DIV_DOUBLE_2ADDR c
-#op OP_DIV_DOUBLE c
-#op OP_DIV_FLOAT_2ADDR c
-#op OP_DIV_FLOAT c
-#op OP_DIV_INT_2ADDR c
-#op OP_DIV_INT_LIT16 c
-#op OP_DIV_INT_LIT8 c
-#op OP_DIV_INT c
-#op OP_DIV_LONG_2ADDR c
-#op OP_DIV_LONG c
-#op OP_DOUBLE_TO_FLOAT c
-#op OP_DOUBLE_TO_INT c
-#op OP_DOUBLE_TO_LONG c
-#op OP_EXECUTE_INLINE c
-#op OP_FILL_ARRAY_DATA c
-#op OP_FILLED_NEW_ARRAY_RANGE c
-#op OP_FILLED_NEW_ARRAY c
-#op OP_FLOAT_TO_DOUBLE c
-#op OP_FLOAT_TO_INT c
-#op OP_FLOAT_TO_LONG c
-#op OP_GOTO_16 c
-#op OP_GOTO_32 c
-#op OP_GOTO c
-#op OP_IF_EQ c
-#op OP_IF_EQZ c
-#op OP_IF_GE c
-#op OP_IF_GEZ c
-#op OP_IF_GT c
-#op OP_IF_GTZ c
-#op OP_IF_LE c
-#op OP_IF_LEZ c
-#op OP_IF_LT c
-#op OP_IF_LTZ c
-#op OP_IF_NE c
-#op OP_IF_NEZ c
-#op OP_IGET_BOOLEAN c
-#op OP_IGET_BYTE c
-#op OP_IGET_CHAR c
-#op OP_IGET_OBJECT_QUICK c
-#op OP_IGET_OBJECT c
-#op OP_IGET_QUICK c
-#op OP_IGET c
-#op OP_IGET_SHORT c
-#op OP_IGET_WIDE_QUICK c
-#op OP_IGET_WIDE c
-#op OP_INSTANCE_OF c
-#op OP_INT_TO_BYTE c
-#op OP_INT_TO_CHAR c
-#op OP_INT_TO_DOUBLE c
-#op OP_INT_TO_FLOAT c
-#op OP_INT_TO_LONG c
-#op OP_INT_TO_SHORT c
-#op OP_INVOKE_DIRECT_EMPTY c
-#op OP_INVOKE_DIRECT_RANGE c
-#op OP_INVOKE_DIRECT c
-#op OP_INVOKE_INTERFACE_RANGE c
-#op OP_INVOKE_INTERFACE c
-#op OP_INVOKE_STATIC_RANGE c
-#op OP_INVOKE_STATIC c
-#op OP_INVOKE_SUPER_QUICK_RANGE c
-#op OP_INVOKE_SUPER_QUICK c
-#op OP_INVOKE_SUPER_RANGE c
-#op OP_INVOKE_SUPER c
-#op OP_INVOKE_VIRTUAL_QUICK_RANGE c
-#op OP_INVOKE_VIRTUAL_QUICK c
-#op OP_INVOKE_VIRTUAL_RANGE c
-#op OP_INVOKE_VIRTUAL c
-#op OP_IPUT_BOOLEAN c
-#op OP_IPUT_BYTE c
-#op OP_IPUT_CHAR c
-#op OP_IPUT_OBJECT_QUICK c
-#op OP_IPUT_OBJECT c
-#op OP_IPUT_QUICK c
-#op OP_IPUT c
-#op OP_IPUT_SHORT c
-#op OP_IPUT_WIDE_QUICK c
-#op OP_IPUT_WIDE c
-#op OP_LONG_TO_DOUBLE c
-#op OP_LONG_TO_FLOAT c
-#op OP_LONG_TO_INT c
-#op OP_MONITOR_ENTER c
-#op OP_MONITOR_EXIT c
-#op OP_MOVE_16 c
-#op OP_MOVE_EXCEPTION c
-#op OP_MOVE_FROM16 c
-#op OP_MOVE_OBJECT_16 c
-#op OP_MOVE_OBJECT_FROM16 c
-#op OP_MOVE_OBJECT c
-#op OP_MOVE_RESULT_OBJECT c
-#op OP_MOVE_RESULT c
-#op OP_MOVE_RESULT_WIDE c
-#op OP_MOVE c
-#op OP_MOVE_WIDE_16 c
-#op OP_MOVE_WIDE_FROM16 c
-#op OP_MOVE_WIDE c
-#op OP_MUL_DOUBLE_2ADDR c
-#op OP_MUL_DOUBLE c
-#op OP_MUL_FLOAT_2ADDR c
-#op OP_MUL_FLOAT c
-#op OP_MUL_INT_2ADDR c
-#op OP_MUL_INT_LIT16 c
-#op OP_MUL_INT_LIT8 c
-#op OP_MUL_INT c
-#op OP_MUL_LONG_2ADDR c
-#op OP_MUL_LONG c
-#op OP_NEG_DOUBLE c
-#op OP_NEG_FLOAT c
-#op OP_NEG_INT c
-#op OP_NEG_LONG c
-#op OP_NEW_ARRAY c
-#op OP_NEW_INSTANCE c
-#op OP_NOP c
-#op OP_NOT_INT c
-#op OP_NOT_LONG c
-#op OP_OR_INT_2ADDR c
-#op OP_OR_INT_LIT16 c
-#op OP_OR_INT_LIT8 c
-#op OP_OR_INT c
-#op OP_OR_LONG_2ADDR c
-#op OP_OR_LONG c
-#op OP_PACKED_SWITCH c
-#op OP_REM_DOUBLE_2ADDR c
-#op OP_REM_DOUBLE c
-#op OP_REM_FLOAT_2ADDR c
-#op OP_REM_FLOAT c
-#op OP_REM_INT_2ADDR c
-#op OP_REM_INT_LIT16 c
-#op OP_REM_INT_LIT8 c
-#op OP_REM_INT c
-#op OP_REM_LONG_2ADDR c
-#op OP_REM_LONG c
-#op OP_RETURN_OBJECT c
-#op OP_RETURN c
-#op OP_RETURN_VOID c
-#op OP_RETURN_WIDE c
-#op OP_RSUB_INT_LIT8 c
-#op OP_RSUB_INT c
-#op OP_SGET_BOOLEAN c
-#op OP_SGET_BYTE c
-#op OP_SGET_CHAR c
-#op OP_SGET_OBJECT c
-#op OP_SGET c
-#op OP_SGET_SHORT c
-#op OP_SGET_WIDE c
-#op OP_SHL_INT_2ADDR c
-#op OP_SHL_INT_LIT8 c
-#op OP_SHL_INT c
-#op OP_SHL_LONG_2ADDR c
-#op OP_SHL_LONG c
-#op OP_SHR_INT_2ADDR c
-#op OP_SHR_INT_LIT8 c
-#op OP_SHR_INT c
-#op OP_SHR_LONG_2ADDR c
-#op OP_SHR_LONG c
-#op OP_SPARSE_SWITCH c
-#op OP_SPUT_BOOLEAN c
-#op OP_SPUT_BYTE c
-#op OP_SPUT_CHAR c
-#op OP_SPUT_OBJECT c
-#op OP_SPUT c
-#op OP_SPUT_SHORT c
-#op OP_SPUT_WIDE c
-#op OP_SUB_DOUBLE_2ADDR c
-#op OP_SUB_DOUBLE c
-#op OP_SUB_FLOAT_2ADDR c
-#op OP_SUB_FLOAT c
-#op OP_SUB_INT_2ADDR c
-#op OP_SUB_INT c
-#op OP_SUB_LONG_2ADDR c
-#op OP_SUB_LONG c
-#op OP_THROW c
-#op OP_UNUSED_3E c
-#op OP_UNUSED_3F c
-#op OP_UNUSED_40 c
-#op OP_UNUSED_41 c
-#op OP_UNUSED_42 c
-#op OP_UNUSED_43 c
-#op OP_UNUSED_73 c
-#op OP_UNUSED_79 c
-#op OP_UNUSED_7A c
-#op OP_UNUSED_F1 c
-#op OP_UNUSED_FC c
-#op OP_UNUSED_FD c
-#op OP_UNUSED_FE c
-#op OP_UNUSED_FF c
-#op OP_USHR_INT_2ADDR c
-#op OP_USHR_INT_LIT8 c
-#op OP_USHR_INT c
-#op OP_USHR_LONG_2ADDR c
-#op OP_USHR_LONG c
-#op OP_XOR_INT_2ADDR c
-#op OP_XOR_INT_LIT16 c
-#op OP_XOR_INT_LIT8 c
-#op OP_XOR_INT c
-#op OP_XOR_LONG_2ADDR c
-#op OP_XOR_LONG c
-
-# TODO: provide native implementations
-op OP_BREAKPOINT c
-op OP_EXECUTE_INLINE_RANGE c
-op OP_IGET_VOLATILE c
-op OP_IPUT_VOLATILE c
-op OP_SGET_VOLATILE c
-op OP_SPUT_VOLATILE c
-op OP_IGET_OBJECT_VOLATILE c
-op OP_IPUT_OBJECT_VOLATILE c
-op OP_SGET_OBJECT_VOLATILE c
-op OP_SPUT_OBJECT_VOLATILE c
-op OP_IGET_WIDE_VOLATILE c
-op OP_IPUT_WIDE_VOLATILE c
-op OP_SGET_WIDE_VOLATILE c
-op OP_SPUT_WIDE_VOLATILE c
-op OP_RETURN_VOID_BARRIER c
-op OP_INVOKE_OBJECT_INIT_RANGE c
-
-op-end
-
-# arch-specific entry point to interpreter
-import x86-atom/entry.S
-
-# "helper" code for C; include this after the instruction handlers
-import c/gotoTargets.cpp
-import cstubs/enddefs.cpp
-
-# common subroutines for asm
-import x86-atom/footer.S
diff --git a/vm/mterp/out/InterpAsm-x86-atom.S b/vm/mterp/out/InterpAsm-x86-atom.S
deleted file mode 100644
index 56b029d..0000000
--- a/vm/mterp/out/InterpAsm-x86-atom.S
+++ /dev/null
@@ -1,18508 +0,0 @@
-/*
- * This file was generated automatically by gen-mterp.py for 'x86-atom'.
- *
- * --> DO NOT EDIT <--
- */
-
-/* File: x86-atom/header.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: header.S
-    */
-
-   /*
-    * IA32 calling convention and general notes:
-    *
-    * EAX, ECX, EDX - general purpose scratch registers (caller-saved);
-    *
-    * The stack (%esp) - used to pass arguments to functions
-    *
-    * EAX - holds the first 4 bytes of a return
-    * EDX - holds the second 4 bytes of a return
-    *
-    * EBX, ESI, EDI, EBP - are callee saved
-    *
-    * CS, DS, SS - are segment registers
-    * ES, FS, GS - are segment registers. We will try to avoid using these registers
-    *
-    * The stack is "full descending". Only the arguments that do not fit    * in the first two arg registers are placed on the stack.
-    * "%esp" points to the first stacked argument (i.e. the 3rd arg).
-    */
-
-   /*
-    * Mterp and IA32 notes
-    *
-    * mem          nick      purpose
-    * (%ebp)       rGLUE     InterpState base pointer (A.K.A. MterpGlue Pointer)
-    * %esi         rPC       interpreted program counter, used for fetching
-    *                        instructions
-    * %ebx         rINST     first 16-bit code unit of current instruction
-    * %edi         rFP       interpreted frame pointer, used for accessing
-    *                        locals and args
-    */
-
-   /*
-    * Includes
-    */
-
-#include "../common/asm-constants.h"
-
-   /*
-    * Reserved registers
-    */
-
-#define rGLUE  (%ebp)
-#define rINST   %ebx
-#define rINSTbl  %bl
-#define rINSTbh  %bh
-#define rINSTw  %bx
-#define rPC     %esi
-#define rFP     %edi
-
-   /*
-    * Temporary register used when finishing an opcode
-    */
-
-#define rFinish %edx
-
-   /*
-    * Stack locations used for temporary data. For convenience.
-    */
-
-#define sReg0    4(%ebp)
-#define sReg1    8(%ebp)
-#define sReg2   12(%ebp)
-#define sReg3   16(%ebp)
-
-   /*
-    * Save the PC and FP to the glue struct
-    */
-
-    .macro      SAVE_PC_FP_TO_GLUE _reg
-    movl        rGLUE, \_reg
-    movl        rPC, offGlue_pc(\_reg)
-    movl        rFP, offGlue_fp(\_reg)
-    .endm
-
-   /*
-    * Restore the PC and FP from the glue struct
-    */
-
-    .macro      LOAD_PC_FP_FROM_GLUE
-    movl        rGLUE, rFP
-    movl        offGlue_pc(rFP), rPC
-    movl        offGlue_fp(rFP), rFP
-    .endm
-
-   /*
-    * "Export" the PC to the stack frame, f/b/o future exception objects. This must
-    * be done *before* something calls dvmThrowException.
-    *
-    * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e.
-    * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc)
-    *
-    * It's okay to do this more than once.
-    */
-
-    .macro      EXPORT_PC
-    movl        rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP)
-    .endm
-
-   /*
-    * Given a frame pointer, find the stack save area.
-    * In C this is "((StackSaveArea*)(_fp) -1)".
-    */
-
-    .macro      SAVEAREA_FROM_FP  _reg
-    lea         -sizeofStackSaveArea(rFP), \_reg
-    .endm
-
-   /*
-    * Get the 32-bit value from a dalvik register.
-    */
-
-    .macro      GET_VREG _vreg
-    movl        (rFP,\_vreg, 4), \_vreg
-    .endm
-
-   /*
-    * Set the 32-bit value from a dalvik register.
-    */
-
-    .macro      SET_VREG _reg _vreg
-    movl        \_reg, (rFP,\_vreg, 4)
-    .endm
-
-   /*
-    * Fetch the next instruction from rPC into rINST. Does not advance rPC.
-    */
-
-    .macro      FETCH_INST
-    movzwl      (rPC), rINST
-    .endm
-
-   /*
-    * Fetch the next instruction from the specified offset. Advances rPC
-    * to point to the next instruction. "_count" is in 16-bit code units.
-    *
-    * This must come AFTER anything that can throw an exception, or the
-    * exception catch may miss. (This also implies that it must come after
-    * EXPORT_PC())
-    */
-
-    .macro      FETCH_ADVANCE_INST _count
-    add         $(\_count*2), rPC
-    movzwl      (rPC), rINST
-    .endm
-
-   /*
-    * Fetch the next instruction from an offset specified by _reg. Updates
-    * rPC to point to the next instruction. "_reg" must specify the distance
-    * in bytes, *not* 16-bit code units, and may be a signed value.
-    */
-
-    .macro      FETCH_ADVANCE_INST_RB _reg
-    addl        \_reg, rPC
-    movzwl      (rPC), rINST
-    .endm
-
-   /*
-    * Fetch a half-word code unit from an offset past the current PC. The
-    * "_count" value is in 16-bit code units. Does not advance rPC.
-    * For example, given instruction of format: AA|op BBBB, it
-    * fetches BBBB.
-    */
-
-    .macro      FETCH _count _reg
-    movzwl      (\_count*2)(rPC), \_reg
-    .endm
-
-   /*
-    * Fetch a half-word code unit from an offset past the current PC. The
-    * "_count" value is in 16-bit code units. Does not advance rPC.
-    * This variant treats the value as signed.
-    */
-
-    .macro      FETCHs _count _reg
-    movswl      (\_count*2)(rPC), \_reg
-    .endm
-
-   /*
-    * Fetch the first byte from an offset past the current PC. The
-    * "_count" value is in 16-bit code units. Does not advance rPC.
-    * For example, given instruction of format: AA|op CC|BB, it
-    * fetches BB.
-    */
-
-    .macro      FETCH_BB _count _reg
-    movzbl      (\_count*2)(rPC), \_reg
-    .endm
-
-    /*
-    * Fetch the second byte from an offset past the current PC. The
-    * "_count" value is in 16-bit code units. Does not advance rPC.
-    * For example, given instruction of format: AA|op CC|BB, it
-    * fetches CC.
-    */
-
-    .macro      FETCH_CC _count _reg
-    movzbl      (\_count*2 + 1)(rPC), \_reg
-    .endm
-
-   /*
-    * Fetch the second byte from an offset past the current PC. The
-    * "_count" value is in 16-bit code units. Does not advance rPC.
-    * This variant treats the value as signed.
-    */
-
-    .macro      FETCH_CCs _count _reg
-    movsbl      (\_count*2 + 1)(rPC), \_reg
-    .endm
-
-
-   /*
-    * Fetch one byte from an offset past the current PC.  Pass in the same
-    * "_count" as you would for FETCH, and an additional 0/1 indicating which
-    * byte of the halfword you want (lo/hi).
-    */
-
-    .macro      FETCH_B _reg  _count  _byte
-    movzbl      (\_count*2+\_byte)(rPC), \_reg
-    .endm
-
-   /*
-    * Put the instruction's opcode field into the specified register.
-    */
-
-    .macro      GET_INST_OPCODE _reg
-    movzbl      rINSTbl, \_reg
-    .endm
-
-   /*
-    * Begin executing the opcode in _reg.
-    */
-
-    .macro      GOTO_OPCODE _reg
-    shl         $6, \_reg
-    addl        $dvmAsmInstructionStart,\_reg
-    jmp         *\_reg
-    .endm
-
-
-
-   /*
-    * Macros pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
-    * by using a jump table. _rFinish should must be the same register for
-    * both macros.
-    */
-
-    .macro      FFETCH _rFinish
-    movzbl      (rPC), \_rFinish
-    .endm
-
-    .macro      FGETOP_JMPa _rFinish
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-   /*
-    * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
-    * by using a jump table. _rFinish and _count should must be the same register for
-    * both macros.
-    */
-
-    .macro      FFETCH_ADV _count _rFinish
-    movzbl      (\_count*2)(rPC), \_rFinish
-    .endm
-
-    .macro      FGETOP_JMP _count _rFinish
-    movzbl      (\_count*2 + 1)(rPC), rINST
-    addl        $(\_count*2), rPC
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-   /*
-    * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
-    * by using a jump table. _rFinish and _reg should must be the same register for
-    * both macros.
-    */
-
-    .macro      FFETCH_ADV_RB _reg _rFinish
-    movzbl      (\_reg, rPC), \_rFinish
-    .endm
-
-    .macro      FGETOP_RB_JMP _reg _rFinish
-    movzbl      1(\_reg, rPC), rINST
-    addl        \_reg, rPC
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-   /*
-    * Attempts to speed up FETCH_INST, GET_INST_OPCODE using
-    * a jump table. This macro should be called before FINISH_JMP where
-    * rFinish should be the same register containing the opcode value.
-    * This is an attempt to split up FINISH in order to reduce or remove
-    * potential stalls due to the wait for rFINISH.
-    */
-
-    .macro      FINISH_FETCH _rFinish
-    movzbl      (rPC), \_rFinish
-    movzbl      1(rPC), rINST
-    .endm
-
-
-   /*
-    * Attempts to speed up FETCH_ADVANCE_INST, GET_INST_OPCODE using
-    * a jump table. This macro should be called before FINISH_JMP where
-    * rFinish should be the same register containing the opcode value.
-    * This is an attempt to split up FINISH in order to reduce or remove
-    * potential stalls due to the wait for rFINISH.
-    */
-
-    .macro      FINISH_FETCH_ADVANCE _count _rFinish
-    movzbl      (\_count*2)(rPC), \_rFinish
-    movzbl      (\_count*2 + 1)(rPC), rINST
-    addl        $(\_count*2), rPC
-    .endm
-
-   /*
-    * Attempts to speed up FETCH_ADVANCE_INST_RB, GET_INST_OPCODE using
-    * a jump table. This macro should be called before FINISH_JMP where
-    * rFinish should be the same register containing the opcode value.
-    * This is an attempt to split up FINISH in order to reduce or remove
-    * potential stalls due to the wait for rFINISH.
-    */
-
-    .macro      FINISH_FETCH_ADVANCE_RB _reg _rFinish
-    movzbl      (\_reg, rPC), \_rFinish
-    movzbl      1(\_reg, rPC), rINST
-    addl        \_reg, rPC
-    .endm
-
-   /*
-    * Attempts to speed up GOTO_OPCODE using a jump table. This macro should
-    * be called after a FINISH_FETCH* instruction where rFinish should be the
-    * same register containing the opcode value. This is an attempt to split up
-    * FINISH in order to reduce or remove potential stalls due to the wait for rFINISH.
-    */
-
-    .macro      FINISH_JMP _rFinish
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-   /*
-    * Attempts to speed up FETCH_INST, GET_INST_OPCODE, GOTO_OPCODE by using
-    * a jump table. Uses a single macro - but it should be faster if we
-    * split up the fetch for rFinish and the jump using rFinish.
-    */
-
-    .macro      FINISH_A
-    movzbl      (rPC), rFinish
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(,rFinish, 4)
-    .endm
-
-   /*
-    * Attempts to speed up FETCH_ADVANCE_INST, GET_INST_OPCODE,
-    * GOTO_OPCODE by using a jump table. Uses a single macro -
-    * but it should be faster if we split up the fetch for rFinish
-    * and the jump using rFinish.
-    */
-
-    .macro      FINISH _count
-    movzbl      (\_count*2)(rPC), rFinish
-    movzbl      (\_count*2 + 1)(rPC), rINST
-    addl        $(\_count*2), rPC
-    jmp         *dvmAsmInstructionJmpTable(,rFinish, 4)
-    .endm
-
-   /*
-    * Attempts to speed up FETCH_ADVANCE_INST_RB, GET_INST_OPCODE,
-    * GOTO_OPCODE by using a jump table. Uses a single macro -
-    * but it should be faster if we split up the fetch for rFinish
-    * and the jump using rFinish.
-    */
-
-    .macro      FINISH_RB _reg _rFinish
-    movzbl      (\_reg, rPC), \_rFinish
-    movzbl      1(\_reg, rPC), rINST
-    addl        \_reg, rPC
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-   /*
-    * Hard coded helper values.
-    */
-
-.balign 16
-
-.LdoubNeg:
-    .quad       0x8000000000000000
-
-.L64bits:
-    .quad       0xFFFFFFFFFFFFFFFF
-
-.LshiftMask2:
-    .quad       0x0000000000000000
-.LshiftMask:
-    .quad       0x000000000000003F
-
-.Lvalue64:
-    .quad       0x0000000000000040
-
-.LvaluePosInfLong:
-    .quad       0x7FFFFFFFFFFFFFFF
-
-.LvalueNegInfLong:
-    .quad       0x8000000000000000
-
-.LvalueNanLong:
-    .quad       0x0000000000000000
-
-.LintMin:
-.long   0x80000000
-
-.LintMax:
-.long   0x7FFFFFFF
-
-
-    .global dvmAsmInstructionStart
-    .type   dvmAsmInstructionStart, %function
-dvmAsmInstructionStart = .L_OP_NOP
-    .text
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_NOP: /* 0x00 */
-/* File: x86-atom/OP_NOP.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NOP.S
-    *
-    * Code: Use a cycle. Uses no substitutions.
-    *
-    * For: nop
-    *
-    * Description: No operation. Use a cycle
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    FINISH      1                       # jump to next instruction
-
-#ifdef ASSIST_DEBUGGER
-
-   /*
-    * insert fake function header to help gdb find the stack frame
-    */
-
-    .type       dalvik_inst, %function
-dalvik_inst:
-    MTERP_ENTRY
-#endif
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE: /* 0x01 */
-/* File: x86-atom/OP_MOVE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE.S
-    *
-    * Code: Copies contents from one register to another. Uses no
-    *       substitutions.
-    *
-    * For: move, move-object, long-to-int
-    *
-    * Description: Copies contents from one non-object register to another.
-    *              vA<- vB; fp[A]<- fp[B]
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, rINST              # rINST<- B
-    and         $15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vB
-    SET_VREG    rINST, %ecx             # vA<- vB; %edx
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_FROM16: /* 0x02 */
-/* File: x86-atom/OP_MOVE_FROM16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_FROM16.S
-    *
-    * Code: Copies contents from one register to another
-    *
-    * For: move/from16, move-object/from16
-    *
-    * Description: Copies contents from one non-object register to another.
-    *              vA<- vB; fp[A]<- fp[B]
-    *
-    * Format: AA|op BBBB (22x)
-    *
-    * Syntax: op vAA, vBBBB
-    */
-
-    FETCH       1, %edx                 # %edx<- BBBB
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    SET_VREG    %edx, rINST             # vA<- vB; %edx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_16: /* 0x03 */
-/* File: x86-atom/OP_MOVE_16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_16.S
-    *
-    * Code: Copies contents from one register to another
-    *
-    * For: move/16, move-object/16
-    *
-    * Description: Copies contents from one non-object register to another.
-    *              fp[A]<- fp[B]
-    *
-    * Format: ØØ|op AAAA BBBB (32x)
-    *
-    * Syntax: op vAAAA, vBBBB
-    */
-
-    FETCH       2, %edx                 # %edx<- BBBB
-    FETCH       1, %ecx                 # %ecx<- AAAA
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    SET_VREG    %edx, %ecx              # vA<- vB; %edx
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_WIDE: /* 0x04 */
-/* File: x86-atom/OP_MOVE_WIDE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_WIDE.S
-    *
-    * Code: Copies contents from one register to another. Uses no
-    *       substitutions.
-    *
-    * For: move-wide
-    *
-    * Description: Copies contents from one non-object register to another.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA+
-    shr         $4, %edx               # %edx<- B
-    and         $15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vB
-    movq        %xmm0, (rFP, rINST, 4)  # vA<- vB
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
-/* File: x86-atom/OP_MOVE_WIDE_FROM16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_WIDE_FROM16.S
-    *
-    * Code: Copies contents from one register to another
-    *
-    * For: move-wide/from16
-    *
-    * Description: Copies contents from one non-object register to another.
-    *
-    * Format: AA|op BBBB (22x)
-    *
-    * Syntax: op vAA, vBBBB
-    */
-
-    FETCH       1, %edx                 # %edx<- BBBB
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vB
-    movq        %xmm0, (rFP, rINST, 4)  # vA<- vB
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_WIDE_16: /* 0x06 */
-/* File: x86-atom/OP_MOVE_WIDE_16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_WIDE_16.S
-    *
-    * Code: Copies contents from one register to another. Uses no
-    *       substitutions.
-    *
-    * For: move-wide/16
-    *
-    * Description: Copies contents from one non-object register to another.
-    *
-    * Format: ØØ|op AAAA BBBB (32x)
-    *
-    * Syntax: op vAAAA, vBBBB
-    */
-
-    FETCH       2, %edx                 # %edx<- BBBB
-    FETCH       1, %ecx                 # %ecx<- AAAA
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vB
-    movq        %xmm0, (rFP, %ecx, 4)   # vA<- vB; %xmm0
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_OBJECT: /* 0x07 */
-/* File: x86-atom/OP_MOVE_OBJECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_OBJECT.S
-    */
-
-/* File: x86-atom/OP_MOVE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE.S
-    *
-    * Code: Copies contents from one register to another. Uses no
-    *       substitutions.
-    *
-    * For: move, move-object, long-to-int
-    *
-    * Description: Copies contents from one non-object register to another.
-    *              vA<- vB; fp[A]<- fp[B]
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, rINST              # rINST<- B
-    and         $15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vB
-    SET_VREG    rINST, %ecx             # vA<- vB; %edx
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
-/* File: x86-atom/OP_MOVE_OBJECT_FROM16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_OBJECT_FROM16.S
-    */
-
-/* File: x86-atom/OP_MOVE_FROM16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_FROM16.S
-    *
-    * Code: Copies contents from one register to another
-    *
-    * For: move/from16, move-object/from16
-    *
-    * Description: Copies contents from one non-object register to another.
-    *              vA<- vB; fp[A]<- fp[B]
-    *
-    * Format: AA|op BBBB (22x)
-    *
-    * Syntax: op vAA, vBBBB
-    */
-
-    FETCH       1, %edx                 # %edx<- BBBB
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    SET_VREG    %edx, rINST             # vA<- vB; %edx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_OBJECT_16: /* 0x09 */
-/* File: x86-atom/OP_MOVE_OBJECT_16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_OBJECT_16.S
-    */
-
-/* File: x86-atom/OP_MOVE_16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_16.S
-    *
-    * Code: Copies contents from one register to another
-    *
-    * For: move/16, move-object/16
-    *
-    * Description: Copies contents from one non-object register to another.
-    *              fp[A]<- fp[B]
-    *
-    * Format: ØØ|op AAAA BBBB (32x)
-    *
-    * Syntax: op vAAAA, vBBBB
-    */
-
-    FETCH       2, %edx                 # %edx<- BBBB
-    FETCH       1, %ecx                 # %ecx<- AAAA
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    SET_VREG    %edx, %ecx              # vA<- vB; %edx
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_RESULT: /* 0x0a */
-/* File: x86-atom/OP_MOVE_RESULT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_RESULT.S
-    *
-    * Code: Copies a return value to a register
-    *
-    * For: move-result, move-result-object
-    *
-    * Description: Move the single-word non-object result of the most
-    *              recent method invocation into the indicated register. This
-    *              must be done as the instruction immediately after a
-    *              method invocation whose (single-word, non-object) result
-    *              is not to be ignored; anywhere else is invalid.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    FFETCH_ADV  1, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    movl        offGlue_retval(%eax), %edx # %edx<- glue->retval
-    SET_VREG    %edx, rINST             # vA<- glue->retval
-    FGETOP_JMP  1, %ecx                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
-/* File: x86-atom/OP_MOVE_RESULT_WIDE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_RESULT_WIDE.S
-    *
-    * Code: Copies a return value to a register
-    *
-    * For: move-result-wide
-    *
-    * Description: Move the double-word non-object result of the most
-    *              recent method invocation into the indicated register. This
-    *              must be done as the instruction immediately after a
-    *              method invocation whose (single-word, non-object) result
-    *              is not to be ignored; anywhere else is invalid.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movq        offGlue_retval(%eax), %xmm0 # %xmm0<- glue->retval
-    movq        %xmm0, (rFP, rINST, 4)  # vA<- glue->retval
-    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
-/* File: x86-atom/OP_MOVE_RESULT_OBJECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_RESULT_OBJECT.S
-    */
-
-/* File: x86-atom/OP_MOVE_RESULT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_RESULT.S
-    *
-    * Code: Copies a return value to a register
-    *
-    * For: move-result, move-result-object
-    *
-    * Description: Move the single-word non-object result of the most
-    *              recent method invocation into the indicated register. This
-    *              must be done as the instruction immediately after a
-    *              method invocation whose (single-word, non-object) result
-    *              is not to be ignored; anywhere else is invalid.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    FFETCH_ADV  1, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    movl        offGlue_retval(%eax), %edx # %edx<- glue->retval
-    SET_VREG    %edx, rINST             # vA<- glue->retval
-    FGETOP_JMP  1, %ecx                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MOVE_EXCEPTION: /* 0x0d */
-/* File: x86-atom/OP_MOVE_EXCEPTION.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_EXCEPTION.S
-    *
-    * Code: Moves an exception to a register
-    *
-    * For: move-exception
-    *
-    * Description: Save a just-caught exception into the given register. This
-    *              instruction is only valid as the first instruction of an
-    *              exception handler.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_self(%eax), %ecx # %ecx<- glue->self
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl        offThread_exception(%ecx), %edx # %edx<- glue->self->exception
-    movl        $0, offThread_exception(%ecx) # clear exception
-    SET_VREG    %edx, rINST             # vAA<- glue->self->exception
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_RETURN_VOID: /* 0x0e */
-/* File: x86-atom/OP_RETURN_VOID.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN_VOID.S
-    */
-
-    jmp         common_returnFromMethod
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_RETURN: /* 0x0f */
-/* File: x86-atom/OP_RETURN.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN.S
-    */
-
-/* File: x86-atom/OP_RETURN_COMMON.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN_COMMON.S
-    *
-    * Code: Return a 32-bit value. Uses no substitutions.
-    *
-    * For: return, return-object
-    *
-    * Description: Copies the return value into the "glue"
-    *              structure, then jumps to the return handler.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, offGlue_retval(%edx) # glue->retval<- vAA
-    jmp         common_returnFromMethod # jump to common return code
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_RETURN_WIDE: /* 0x10 */
-/* File: x86-atom/OP_RETURN_WIDE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN_WIDE.S
-    *
-    * Code: Return a 64-bit value. Uses no substitutions.
-    *
-    * For: return-wide
-    *
-    * Description: Copies the return value into the "glue"
-    *              structure, then jumps to the return handler.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vAA
-    movq        %xmm0, offGlue_retval(%edx)# glue->retval<- vAA
-    jmp         common_returnFromMethod # jump to common return code
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_RETURN_OBJECT: /* 0x11 */
-/* File: x86-atom/OP_RETURN_OBJECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN_OBJECT.S
-    */
-
-/* File: x86-atom/OP_RETURN_COMMON.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN_COMMON.S
-    *
-    * Code: Return a 32-bit value. Uses no substitutions.
-    *
-    * For: return, return-object
-    *
-    * Description: Copies the return value into the "glue"
-    *              structure, then jumps to the return handler.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, offGlue_retval(%edx) # glue->retval<- vAA
-    jmp         common_returnFromMethod # jump to common return code
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST_4: /* 0x12 */
-/* File: x86-atom/OP_CONST_4.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_4.S
-    *
-    * Code: Moves a literal to a register. Uses no substitutions.
-    *
-    * For: const/4
-    *
-    * Description: Move the given literal value (right-zero-extended to 32
-    *              bits) into the specified register.
-    *
-    * Format: B|A|op (11n)
-    *
-    * Syntax: op vA, #+B
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    andl        $15, rINST             # rINST<- A
-    shl         $24, %edx              # %edx<- B000
-    sar         $28, %edx              # %edx<- right-zero-extended B
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    SET_VREG    %edx, rINST             # vA<- %edx; literal
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST_16: /* 0x13 */
-/* File: x86-atom/OP_CONST_16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_16.S
-    *
-    * Code: Moves a literal to a register. Uses no substitutions.
-    *
-    * For: const/16
-    *
-    * Description: Move the given literal value (right-zero-extended to 32
-    *              bits) into the specified register
-    *
-    * Format: AA|op BBBB (21s)
-    *
-    * Syntax: op vAA, #+BBBB
-    */
-
-    FETCHs      1, %edx                 # %edx<- BBBB
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    SET_VREG    %edx rINST              # vAA<- BBBB; literal
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST: /* 0x14 */
-/* File: x86-atom/OP_CONST.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST.S
-    *
-    * Code: Move a literal to a register. Uses no substitutions.
-    *
-    * For: const
-    *
-    * Description: Move the given literal value into the specified register
-    *
-    * Format: AA|op BBBBlo BBBBhi (31i)
-    *
-    * Syntax: op vAA, #+BBBBBBBB
-    */
-
-    FETCH       2, %edx                 # %edx<- BBBBhi
-    FETCH       1, %ecx                 # %ecx<- BBBBlo
-    shl         $16, %edx              # move BBBB to high bits
-    or          %edx, %ecx              # %ecx<- #+BBBBBBBB
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; literal
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST_HIGH16: /* 0x15 */
-/* File: x86-atom/OP_CONST_HIGH16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_HIGH16.S
-    *
-    * Code: Move a literal to a register. Uses no substitutions.
-    *
-    * For: const/high16
-    *
-    * Description: Move the given literal value (right-zero-extended to 32
-    *              bits) into the specified register
-    *
-    * Format: AA|op BBBB (21h)
-    *
-    * Syntax: op vAA, #+BBBB0000
-    */
-
-    FETCH       1, %ecx                 # %ecx<- 0000BBBB (zero-extended)
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    shl         $16, %ecx              # %ecx<- BBBB0000
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; BBBB0000
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST_WIDE_16: /* 0x16 */
-/* File: x86-atom/OP_CONST_WIDE_16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_WIDE_16.S
-    *
-    * Code: Move a literal to a register. Uses no substitutions.
-    *
-    * For: const-wide/16
-    *
-    * Description: Move the given literal value (sign-extended to 64 bits)
-    *              into the specified register-pair
-    *
-    * Format: AA|op BBBB (21s)
-    *
-    * Syntax: op vAA, #+BBBB
-    */
-
-    FETCHs      1, %ecx                 # %ecx<- ssssBBBB (sign-extended)
-    movl        %ecx, %edx              # %edx<- ssssBBBB (sign-extended)
-    sar         $31, %ecx              # %ecx<- sign bit
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl        %edx, (rFP, rINST, 4)   # vAA<- ssssBBBB
-    movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- ssssssss
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST_WIDE_32: /* 0x17 */
-/* File: x86-atom/OP_CONST_WIDE_32.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_WIDE_32.S
-    *
-    * Code: Move a literal to a register. Uses no substitutions.
-    *
-    * For: const-wide/32
-    *
-    * Description: Move the given literal value (sign-extended to 64 bits)
-    *              into the specified register-pair
-    *
-    * Format: AA|op BBBBlo BBBBhi (31i)
-    *
-    * Syntax: op vAA, #+BBBBBBBB
-    */
-
-    FETCH       1,  %edx                # %edx<- BBBBlo
-    FETCHs      2, %ecx                 # %ecx<- BBBBhi
-    shl         $16, %ecx              # prepare to create #+BBBBBBBB
-    or          %ecx, %edx              # %edx<- %edx<- #+BBBBBBBB
-    sar         $31, %ecx              # %ecx<- sign bit
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl        %edx, (rFP, rINST, 4)   # vAA<-  BBBBBBBB
-    movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- ssssssss
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST_WIDE: /* 0x18 */
-/* File: x86-atom/OP_CONST_WIDE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_WIDE.S
-    *
-    * Code: Move a literal to a register. Uses no substitutions.
-    *
-    * For: const-wide
-    *
-    * Description: Move the given literal value into the specified
-    *              register pair
-    *
-    * Format: AA|op BBBBlolo BBBBlohi BBBBhilo BBBBhihi (51l)
-    *
-    * Syntax: op vAA, #+BBBBBBBBBBBBBBBB
-    */
-
-    FETCH       1, %ecx                 # %ecx<- BBBBlolo
-    FETCH       2, %edx                 # %edx<- BBBBlohi
-    shl         $16, %edx              # %edx<- prepare to create #+BBBBBBBBlo
-    or          %edx, %ecx              # %ecx<- #+BBBBBBBBlo
-    movl        %ecx, (rFP, rINST, 4)   # vAA <- #+BBBBBBBBlo
-    FETCH       3, %ecx                 # %ecx<- BBBBhilo
-    FETCH       4, %edx                 # %edx<- BBBBhihi
-    FFETCH_ADV  5, %eax                 # %eax<- next instruction hi; fetch, advance
-    shl         $16, %edx              # %edx<- prepare to create #+BBBBBBBBhi
-    or          %edx, %ecx              # %ecx<- #+BBBBBBBBhi
-    movl        %ecx, 4(rFP, rINST, 4)  # vAA+1 <- #+BBBBBBBBlo
-    FGETOP_JMP  5, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
-/* File: x86-atom/OP_CONST_WIDE_HIGH16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_WIDE_HIGH16.S
-    *
-    * Code: Move a literal value to a register. Uses no substitutions.
-    *
-    * For: const-wide/high16
-    *
-    * Description: Move the given literal value (right-zero-extended to 64
-    *              bits) into the specified register
-    *
-    * Format: AA|op BBBB (21h)
-    *
-    * Syntax: op vAA, #+BBBB000000000000
-    */
-
-    FETCH       1, %ecx                 # %ecx<- 0000BBBB (zero-extended)
-    shl         $16, %ecx              # rINST<- AA
-    movl        $0, (rFP, rINST, 4)    # vAAlow<- 00000000
-    movl        %ecx, 4(rFP, rINST, 4)  # vAAhigh<- %ecx; BBBB0000
-    FINISH      2                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST_STRING: /* 0x1a */
-/* File: x86-atom/OP_CONST_STRING.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_STRING.S
-    *
-    * Code: Move a string reference to a register. Uses no substitutions.
-    *
-    * For: const/string
-    *
-    * Description: Move a referece to the string specified by the given
-    *              index into the specified register. vAA <- pResString[BBBB]
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    movl        rGLUE, %edx             # get MterpGlue pointer
-    movl        offGlue_methodClassDex(%edx), %eax # %eax<- glue->methodClassDex
-    movl        offDvmDex_pResStrings(%eax), %eax # %eax<- glue->methodClassDex->pResStrings
-    movl        (%eax, %ecx, 4), %eax   # %eax<- pResStrings[BBBB]
-    cmp         $0, %eax               # check if string is resolved
-    je          .LOP_CONST_STRING_resolve     # resolve string reference
-    SET_VREG    %eax, rINST             # vAA<- %eax; pResString[BBBB]
-    FINISH      2                       # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST_STRING_JUMBO: /* 0x1b */
-/* File: x86-atom/OP_CONST_STRING_JUMBO.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_STRING_JUMBO.S
-    *
-    * Code: Move a string reference to a register. Uses no substitutions.
-    *
-    * For: const/string-jumbo
-    *
-    * Description: Move a reference to the string specified by the given
-    *              index into the specified register. vAA <- pResString[BBBB]
-    *
-    * Format: AA|op BBBBlo BBBBhi (31c)
-    *
-    * Syntax: op vAA, string@BBBBBBBB
-    */
-
-    movl        rGLUE, %edx             # get MterpGlue pointer
-    movl        offGlue_methodClassDex(%edx), %eax # %eax<- glue->methodClassDex
-    movl        offDvmDex_pResStrings(%eax), %eax # %eax<- glue->methodClassDex->pResStrings
-    FETCH       1, %ecx                 # %ecx<- BBBBlo
-    FETCH       2, %edx                 # %edx<- BBBBhi
-    shl         $16, %edx              # %edx<- prepare to create &BBBBBBBB
-    or          %edx, %ecx              # %ecx<- &BBBBBBBB
-    movl        (%eax, %ecx, 4), %eax   # %eax<- pResStrings[BBBB]
-    cmp         $0, %eax               # check if string is resolved
-    je          .LOP_CONST_STRING_JUMBO_resolve     # resolve string reference
-    SET_VREG    %eax, rINST             # vAA<- %eax; pResString[BBBB]
-    FINISH      3                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CONST_CLASS: /* 0x1c */
-/* File: x86-atom/OP_CONST_CLASS.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_CLASS.S
-    *
-    * Code: Move a class reference to a register. Uses no substitutions.
-    *
-    * For: const/class
-    *
-    * Description: Move a reference to the class specified
-    *              by the given index into the specified register.
-    *              In the case where the indicated type is primitive,
-    *              this will store a reference to the primitive type's
-    *              degenerate class.
-    *
-    * Format: AA|op BBBBlo BBBBhi (21c)
-    *
-    * Syntax: op vAA, field@BBBB
-    */
-
-    movl        rGLUE, %edx             # get MterpGlue pointer
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    movl        offGlue_methodClassDex(%edx), %eax # %eax<- pDvmDex
-    movl        offDvmDex_pResClasses(%eax), %eax # %eax<- pDvmDex->pResClasses
-    movl        (%eax, %ecx, 4), %eax   # %eax<- resolved class
-    cmp         $0, %eax               # check if classes is resolved before?
-    je          .LOP_CONST_CLASS_resolve     # resolve class
-    SET_VREG    %eax, rINST             # vAA<- resolved class
-    FINISH      2                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MONITOR_ENTER: /* 0x1d */
-/* File: x86-atom/OP_MONITOR_ENTER.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MONITOR_ENTER.S
-    *
-    * Code: Aquire a monitor
-    *
-    * For: monitor-enter
-    *
-    * Description: Aquire a monitor for the indicated object.
-    *
-    *
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    GET_VREG    rINST                   # rINST<- vAA
-    cmp         $0, rINST              # check for null object
-    movl        offGlue_self(%eax), %eax # %eax<- glue->self
-    EXPORT_PC   # need for precise GC
-    je          common_errNullObject    # handle null object
-#    jmp         .LOP_MONITOR_ENTER_finish
-#%break
-#.LOP_MONITOR_ENTER_finish:
-    movl        rINST, -4(%esp)         # push parameter reference
-    movl        %eax, -8(%esp)          # push parameter
-    lea         -8(%esp), %esp
-    call        dvmLockObject           # call: (struct Thread* self,
-                                        #       struct Object* obj)
-                                        # return: void
-    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
-    lea         8(%esp), %esp
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MONITOR_EXIT: /* 0x1e */
-/* File: x86-atom/OP_MONITOR_EXIT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MONITOR_EXIT.S
-    *
-    * Code: Release a monitor
-    *
-    * For: monitor-exit
-    *
-    * Description: Release a monitor for the indicated object. If this instruction needs
-    *              to throw an execption, it must do so as if the pc has already
-    *              advanced pased the instruction.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    EXPORT_PC                           # export the pc
-    GET_VREG    rINST                   # rINST<- vAA
-    cmp         $0, rINST              # rINST<- check for null object
-    je          common_errNullObject    # handle null object
-    push        rINST                   # push parameter object
-    push        offGlue_self(%eax)      # push parameter self
-    call        dvmUnlockObject         # call: (struct Thread* self,
-                                        #       struct Object* obj)
-                                        # return: bool
-    FINISH_FETCH_ADVANCE 1, %edx        # advance pc before exception
-    cmp         $0, %eax               # check for success
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # handle exception
-    FINISH_JMP  %edx                    # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CHECK_CAST: /* 0x1f */
-/* File: x86-atom/OP_CHECK_CAST.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CHECK_CAST.S
-    *
-    * Code: Checks to see if a cast is allowed. Uses no substitutions.
-    *
-    * For: check-cast
-    *
-    * Description: Throw if the reference in the given register cannot be
-    *              cast to the indicated type. The type must be a reference
-    *              type (not a primitive type).
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, type@BBBB
-    */
-
-    movl        rGLUE, %edx             # get MterpGlue pointer
-    movl        offGlue_methodClassDex(%edx), %eax # %eax<- pDvmDex
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        offDvmDex_pResClasses(%eax), %eax # %eax<- pDvmDex->pResClasses
-    cmp         $0, rINST              # check for null reference object
-    je          .LOP_CHECK_CAST_okay        # can always cast null object
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    movl        (%eax, %ecx, 4), %ecx   # %ecx<- resolved class
-    cmp         $0, %ecx               # check if classes is resolved before?
-    je          .LOP_CHECK_CAST_resolve     # resolve class
-    jmp         .LOP_CHECK_CAST_resolved    # continue
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INSTANCE_OF: /* 0x20 */
-/* File: x86-atom/OP_INSTANCE_OF.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INSTANCE_OF.S
-    *
-    * Code: Checks if object is instance of a class. Uses no substitutions.
-    *
-    * For: instance-of
-    *
-    * Description: Store in the given destination register 1 if the indicated
-    *              reference is an instance of the given type, or 0 if not.
-    *              The type must be a reference type (not a primitive type).
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    GET_VREG    %edx                    # %edx<- vB
-    cmp         $0, %edx               # check for null object
-    je          .LOP_INSTANCE_OF_store       # null object
-    jmp         .LOP_INSTANCE_OF_break
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ARRAY_LENGTH: /* 0x21 */
-/* File: x86-atom/OP_ARRAY_LENGTH.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ARRAY_LENGTH.S
-    *
-    * Code: 32-bit array length operation.
-    *
-    * For: array-length
-    *
-    * Description: Store the length of the indicated array in the given
-    *              destination register. vB <- offArrayObject_length(vA)
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $4, %eax               # %eax<- B
-    andl        $15, rINST             # rINST<- A
-    GET_VREG    %eax                    # %eax<- vB
-    cmp         $0, %eax               # check for null array object
-    je          common_errNullObject    # handle null array object
-    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl        offArrayObject_length(%eax), %eax # %eax<- array length
-    movl        %eax, (rFP, rINST, 4)   # vA<- %eax; array length
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_NEW_INSTANCE: /* 0x22 */
-/* File: x86-atom/OP_NEW_INSTANCE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEW_INSTANCE.S
-    *
-    * Code: Create a new instance of a given type. Uses no substitutions.
-    *
-    * For: new-instance
-    *
-    * Description: Construct a new instance of the indicated type,
-    *              storing a reference to it in the destination.
-    *              The type must refer to a non-array class.
-    *
-    *
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, type@BBBB
-    *         op vAA, field@BBBB
-    *         op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %edx                 # %edx<- BBBB
-    movl        offDvmDex_pResClasses(%ecx), %ecx # %ecx<- glue->pDvmDex->pResClasses
-    movl        (%ecx, %edx, 4), %edx   # %edx<- vB
-    EXPORT_PC                           # required for resolve
-    cmp         $0, %edx               # check for null
-    je          .LOP_NEW_INSTANCE_resolve     # need to resolve
-
-   /*
-    *  %edx holds class object
-    */
-
-.LOP_NEW_INSTANCE_resolved:
-    movzbl      offClassObject_status(%edx), %eax # %eax<- class status
-    cmp         $CLASS_INITIALIZED, %eax # check if class is initialized
-    jne         .LOP_NEW_INSTANCE_needinit    # initialize class
-
-   /*
-    *  %edx holds class object
-    */
-
-.LOP_NEW_INSTANCE_initialized:
-    testl       $(ACC_INTERFACE|ACC_ABSTRACT), offClassObject_accessFlags(%edx)
-    mov         $ALLOC_DONT_TRACK, %eax # %eax<- flag for alloc call
-    je          .LOP_NEW_INSTANCE_finish      # continue
-    jmp         .LOP_NEW_INSTANCE_abstract    # handle abstract or interface
-
-   /*
-    *  %edx holds class object
-    *  %eax holds flags for alloc call
-    */
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_NEW_ARRAY: /* 0x23 */
-/* File: x86-atom/OP_NEW_ARRAY.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEW_ARRAY.S
-    *
-    * Code: Create a new array. Uses no substitutions.
-    *
-    * For: new-array
-    *
-    * Description: Construct a new array of the indicated type and size.
-    *              The type must be an array type.
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    movl        offGlue_methodClassDex(%eax), %eax # %eax<- glue->pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    GET_VREG    %edx                    # %edx<- vB
-    movl        offDvmDex_pResClasses(%eax), %eax # %eax<- glue->pDvmDex->pResClasses
-    cmp         $0, %edx               # check for negative length
-    movl        (%eax, %ecx, 4), %eax   # %eax<- resolved class
-    js          common_errNegativeArraySize # handle negative array length
-    cmp         $0, %eax               # check for null
-    EXPORT_PC                           # required for resolve
-    jne         .LOP_NEW_ARRAY_finish      # already resovled so continue
-    jmp         .LOP_NEW_ARRAY_resolve     # need to resolve
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
-/* File: x86-atom/OP_FILLED_NEW_ARRAY.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FILLED_NEW_ARRAY.S
-    *
-    * Code: Constructs and fills an array with the given data. Provides
-    *
-    * For: float-to-int
-    *
-    * Description: Construct an array of the given type and size,
-    *              filling it with the supplied contents. The type
-    *              must be an array type. The array's contents
-    *              must be single-word. The constructed instance
-    *              is stored as a result in the same way that the
-    *              method invocation instructions store their results,
-    *              so the constructed instance must be moved to a
-    *              register with a subsequent move-result-object
-    *              instruction.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc) (range)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, vtaboff@CCCC
-    *         [B=4] op {vD, vE, vF, vG}, vtaboff@CCCC
-    *         [B=3] op {vD, vE, vF}, vtaboff@CCCC
-    *         [B=2] op {vD, vE}, vtaboff@CCCC
-    *         [B=1] op {vD}, vtaboff@CCCC
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB
-    *         op {vCCCC .. vNNNN}, type@BBBB
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- MterpGlue pointer
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- glue->methodClassDex
-    movl        offDvmDex_pResClasses(%edx), %edx # %edx<- glue->methodClassDex->pResClasses
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    EXPORT_PC
-    movl (%edx, %ecx, 4), %eax # %eax<- possibly resolved class
-    cmp         $0, %eax               # %eax<- check if already resolved
-    jne         .LOP_FILLED_NEW_ARRAY_continue
-    jmp         .LOP_FILLED_NEW_ARRAY_break
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
-/* File: x86-atom/OP_FILLED_NEW_ARRAY_RANGE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FILLED_NEW_ARRAY_RANGE.S
-    */
-
-/* File: x86-atom/OP_FILLED_NEW_ARRAY.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FILLED_NEW_ARRAY.S
-    *
-    * Code: Constructs and fills an array with the given data. Provides
-    *
-    * For: float-to-int
-    *
-    * Description: Construct an array of the given type and size,
-    *              filling it with the supplied contents. The type
-    *              must be an array type. The array's contents
-    *              must be single-word. The constructed instance
-    *              is stored as a result in the same way that the
-    *              method invocation instructions store their results,
-    *              so the constructed instance must be moved to a
-    *              register with a subsequent move-result-object
-    *              instruction.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc) (range)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, vtaboff@CCCC
-    *         [B=4] op {vD, vE, vF, vG}, vtaboff@CCCC
-    *         [B=3] op {vD, vE, vF}, vtaboff@CCCC
-    *         [B=2] op {vD, vE}, vtaboff@CCCC
-    *         [B=1] op {vD}, vtaboff@CCCC
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB
-    *         op {vCCCC .. vNNNN}, type@BBBB
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- MterpGlue pointer
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- glue->methodClassDex
-    movl        offDvmDex_pResClasses(%edx), %edx # %edx<- glue->methodClassDex->pResClasses
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    EXPORT_PC
-    movl (%edx, %ecx, 4), %eax # %eax<- possibly resolved class
-    cmp         $0, %eax               # %eax<- check if already resolved
-    jne         .LOP_FILLED_NEW_ARRAY_RANGE_continue
-    jmp         .LOP_FILLED_NEW_ARRAY_RANGE_break
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_FILL_ARRAY_DATA: /* 0x26 */
-/* File: x86-atom/OP_FILL_ARRAY_DATA.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FILL_ARRAY_DATA.S
-    *
-    * Code: Fills an array with given data. Uses no substitutions.
-    *
-    * For: fill-array-data
-    *
-    * Description: Fill the given array with the idicated data. The reference
-    *              must be an array of primitives, and the data table must
-    *              match it in type and size
-    *
-    * Format: AA|op BBBBlo BBBBhi (31t)
-    *
-    * Syntax: op vAA, +BBBBBBBB
-    */
-
-    FETCH       1, %ecx                 # %ecx<- BBBBlo
-    FETCH       2, %edx                 # %edx<- BBBBhi
-    shl         $16, %edx              # prepare to create +BBBBBBBB
-    or          %ecx, %edx              # %edx<- +BBBBBBBB
-    lea         (rPC, %edx, 2), %edx    # %edx<- PC + +BBBBBBBB; array data location
-    EXPORT_PC
-    push        %edx
-    push        (rFP, rINST, 4)
-    call        dvmInterpHandleFillArrayData # call: (ArrayObject* arrayObject, const u2* arrayData)
-                                             # return: bool
-    FFETCH_ADV  3, %edx                 # %edx<- next instruction hi; fetch, advance
-    cmp         $0, %eax
-    lea         8(%esp), %esp
-    je          common_exceptionThrown
-    FGETOP_JMP  3, %edx                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_THROW: /* 0x27 */
-/* File: x86-atom/OP_THROW.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_THROW.S
-    *
-    * Code: Throw an exception
-    *
-    * For: throw
-    *
-    * Description: Throw an exception object in the current thread.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    EXPORT_PC                           # export the pc
-    GET_VREG    rINST                   # rINST<- vAA
-    cmp         $0, rINST              # check for null
-    movl        offGlue_self(%eax), %ecx # %ecx<- glue->self
-    je          common_errNullObject    # handle null object
-    movl        rINST, offThread_exception(%ecx) # thread->exception<- object
-    jmp         common_exceptionThrown  # handle exception
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_GOTO: /* 0x28 */
-/* File: x86-atom/OP_GOTO.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_GOTO.S
-    *
-    * Code: Do an unconditional branch. Uses no substitutions.
-    *
-    * For: goto
-    *
-    * Description: Performs an unconditionally jump to the indicated instruction.
-    *              The branch uses an 8-bit offset that cannot be zero.
-    *
-    * Format: AA|op (10t)
-    *
-    * Syntax: op +AA
-    */
-
-LOP_GOTO.S:
-
-    movsbl      rINSTbl, %edx           # %edx<- +AA
-    shl         $1, %edx               # %edx is shifted for byte offset
-    js          common_periodicChecks_backwardBranch  # do check on backwards branch
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_GOTO_16: /* 0x29 */
-/* File: x86-atom/OP_GOTO_16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_GOTO_16.S
-    *
-    * Code: Do an unconditional branch. Uses no substitutions.
-    *
-    * For: goto/16
-    *
-    * Description: Performs an unconditionally jump to the indicated instruction.
-    *              The branch uses a 16-bit offset that cannot be zero.
-    *
-    * Format: ØØ|op AAAA (20t)
-    *
-    * Syntax: op +AAAA
-    */
-
-    FETCHs      1, %edx                 # %edx<- ssssAAAA (sign-extended)
-    shl         $1, %edx               # %edx is doubled to get the byte offset
-    js          common_periodicChecks_backwardBranch  # do check on backwards branch
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_GOTO_32: /* 0x2a */
-/* File: x86-atom/OP_GOTO_32.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_GOTO_32.S
-    *
-    * Code: Do an unconditional branch. Uses no substitutions.
-    *
-    * For: goto/32
-    *
-    * Description:  Performs an unconditionally jump to the indicated instruction.
-    *               The branch uses a 32-bit offset that can be zero.
-    *
-    * Format: ØØ|op AAAAlo AAAAhi (30t)
-    *
-    * Syntax: op +AAAAAAAA
-    */
-
-    FETCH       1, %edx                 # %edx<- AAAAlo
-    FETCH       2, %ecx                 # %ecx<- AAAAhi
-    shl         $16, %ecx              # prepare to create +AAAAAAAA
-    or          %ecx, %edx              # %edx<- +AAAAAAAA
-    shl         $1, %edx               # %edx is doubled to get the byte offset
-    jle          common_periodicChecks_backwardBranch  # do check on backwards branch
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_PACKED_SWITCH: /* 0x2b */
-/* File: x86-atom/OP_PACKED_SWITCH.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_PACKED_SWITCH.S
-    *
-    * Code: Jump to a new instruction using a jump table
-    *
-    * For: packed-switch, sparse-switch
-    *
-    * Description: Jump to a new instruction based on the value in the given
-    *              register, using a table of offsets corresponding to each
-    *              value in a particular integral range, or fall through to
-    *              the next instruction if there is no match.
-    *
-    * Format: AA|op BBBBlo BBBBhi (31t)
-    *
-    * Syntax: op vAA, +BBBBBBBB
-    */
-
-
-    FETCH       1, %ecx                 # %ecx<- BBBBlo
-    FETCH       2, %edx                 # %edx<- BBBBhi
-    shl         $16, %edx              # prepare to create +BBBBBBBB
-    or          %edx, %ecx              # %ecx<- +BBBBBBBB
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, -4(%esp)         # push parameter vAA
-    lea         (rPC, %ecx, 2), %ecx    # %ecx<- PC + +BBBBBBBB*2
-    movl        %ecx, -8(%esp)          # push parameter PC + +BBBBBBBB*2
-    lea         -8(%esp), %esp
-    call        dvmInterpHandlePackedSwitch                   # call code-unit branch offset
-    shl         $1, %eax               # shift for byte offset
-    movl        %eax, %edx              # %edx<- offset
-    lea         8(%esp), %esp
-    jle         common_periodicChecks_backwardBranch  # do backward branch
-    jmp         .LOP_PACKED_SWITCH_finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPARSE_SWITCH: /* 0x2c */
-/* File: x86-atom/OP_SPARSE_SWITCH.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPARSE_SWITCH.S
-    */
-
-/* File: x86-atom/OP_PACKED_SWITCH.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_PACKED_SWITCH.S
-    *
-    * Code: Jump to a new instruction using a jump table
-    *
-    * For: packed-switch, sparse-switch
-    *
-    * Description: Jump to a new instruction based on the value in the given
-    *              register, using a table of offsets corresponding to each
-    *              value in a particular integral range, or fall through to
-    *              the next instruction if there is no match.
-    *
-    * Format: AA|op BBBBlo BBBBhi (31t)
-    *
-    * Syntax: op vAA, +BBBBBBBB
-    */
-
-
-    FETCH       1, %ecx                 # %ecx<- BBBBlo
-    FETCH       2, %edx                 # %edx<- BBBBhi
-    shl         $16, %edx              # prepare to create +BBBBBBBB
-    or          %edx, %ecx              # %ecx<- +BBBBBBBB
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, -4(%esp)         # push parameter vAA
-    lea         (rPC, %ecx, 2), %ecx    # %ecx<- PC + +BBBBBBBB*2
-    movl        %ecx, -8(%esp)          # push parameter PC + +BBBBBBBB*2
-    lea         -8(%esp), %esp
-    call        dvmInterpHandleSparseSwitch                   # call code-unit branch offset
-    shl         $1, %eax               # shift for byte offset
-    movl        %eax, %edx              # %edx<- offset
-    lea         8(%esp), %esp
-    jle         common_periodicChecks_backwardBranch  # do backward branch
-    jmp         .LOP_SPARSE_SWITCH_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CMPL_FLOAT: /* 0x2d */
-/* File: x86-atom/OP_CMPL_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPL_FLOAT.S
-    *
-    * Code: Provides a "nan" variable to specify the return value for
-    *       NaN. Provides a variable "sod" which appends a "s" or a "d"
-    *       to the move and comparison instructions, depending on if we
-    *       are working with a float or a double. For instructions
-    *       cmpx-float and cmpx-double, the x will be eiher a g or a l
-    *       to specify positive or negative bias for NaN.
-    *
-    * For: cmpg-double, dmpg-float, cmpl-double, cmpl-float
-    *
-    * Description: Perform the indicated floating point or long comparison,
-    *              storing 0 if the two arguments are equal, 1 if the second
-    *              argument is larger, or -1 if the first argument is larger.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movss    (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    comiss   (rFP, %edx, 4), %xmm0   # do comparison
-    ja          .LOP_CMPL_FLOAT_greater
-    jp          .LOP_CMPL_FLOAT_finalNan
-    jz          .LOP_CMPL_FLOAT_final
-
-.LOP_CMPL_FLOAT_less:
-    movl        $0xFFFFFFFF, (rFP, rINST, 4) # vAA<- less than
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CMPG_FLOAT: /* 0x2e */
-/* File: x86-atom/OP_CMPG_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPG_FLOAT.S
-    */
-
-/* File: x86-atom/OP_CMPL_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPL_FLOAT.S
-    *
-    * Code: Provides a "nan" variable to specify the return value for
-    *       NaN. Provides a variable "sod" which appends a "s" or a "d"
-    *       to the move and comparison instructions, depending on if we
-    *       are working with a float or a double. For instructions
-    *       cmpx-float and cmpx-double, the x will be eiher a g or a l
-    *       to specify positive or negative bias for NaN.
-    *
-    * For: cmpg-double, dmpg-float, cmpl-double, cmpl-float
-    *
-    * Description: Perform the indicated floating point or long comparison,
-    *              storing 0 if the two arguments are equal, 1 if the second
-    *              argument is larger, or -1 if the first argument is larger.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movss    (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    comiss   (rFP, %edx, 4), %xmm0   # do comparison
-    ja          .LOP_CMPG_FLOAT_greater
-    jp          .LOP_CMPG_FLOAT_finalNan
-    jz          .LOP_CMPG_FLOAT_final
-
-.LOP_CMPG_FLOAT_less:
-    movl        $0xFFFFFFFF, (rFP, rINST, 4) # vAA<- less than
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CMPL_DOUBLE: /* 0x2f */
-/* File: x86-atom/OP_CMPL_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPL_DOUBLE.S
-    */
-
-/* File: x86-atom/OP_CMPL_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPL_FLOAT.S
-    *
-    * Code: Provides a "nan" variable to specify the return value for
-    *       NaN. Provides a variable "sod" which appends a "s" or a "d"
-    *       to the move and comparison instructions, depending on if we
-    *       are working with a float or a double. For instructions
-    *       cmpx-float and cmpx-double, the x will be eiher a g or a l
-    *       to specify positive or negative bias for NaN.
-    *
-    * For: cmpg-double, dmpg-float, cmpl-double, cmpl-float
-    *
-    * Description: Perform the indicated floating point or long comparison,
-    *              storing 0 if the two arguments are equal, 1 if the second
-    *              argument is larger, or -1 if the first argument is larger.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movsd    (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    comisd   (rFP, %edx, 4), %xmm0   # do comparison
-    ja          .LOP_CMPL_DOUBLE_greater
-    jp          .LOP_CMPL_DOUBLE_finalNan
-    jz          .LOP_CMPL_DOUBLE_final
-
-.LOP_CMPL_DOUBLE_less:
-    movl        $0xFFFFFFFF, (rFP, rINST, 4) # vAA<- less than
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CMPG_DOUBLE: /* 0x30 */
-/* File: x86-atom/OP_CMPG_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPG_DOUBLE.S
-    */
-
-/* File: x86-atom/OP_CMPL_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPL_FLOAT.S
-    *
-    * Code: Provides a "nan" variable to specify the return value for
-    *       NaN. Provides a variable "sod" which appends a "s" or a "d"
-    *       to the move and comparison instructions, depending on if we
-    *       are working with a float or a double. For instructions
-    *       cmpx-float and cmpx-double, the x will be eiher a g or a l
-    *       to specify positive or negative bias for NaN.
-    *
-    * For: cmpg-double, dmpg-float, cmpl-double, cmpl-float
-    *
-    * Description: Perform the indicated floating point or long comparison,
-    *              storing 0 if the two arguments are equal, 1 if the second
-    *              argument is larger, or -1 if the first argument is larger.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movsd    (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    comisd   (rFP, %edx, 4), %xmm0   # do comparison
-    ja          .LOP_CMPG_DOUBLE_greater
-    jp          .LOP_CMPG_DOUBLE_finalNan
-    jz          .LOP_CMPG_DOUBLE_final
-
-.LOP_CMPG_DOUBLE_less:
-    movl        $0xFFFFFFFF, (rFP, rINST, 4) # vAA<- less than
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_CMP_LONG: /* 0x31 */
-/* File: x86-atom/OP_CMP_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMP_LONG.S
-    *
-    * Code: Compare floating point values. Uses no substitutions.
-    *
-    * For: cmp-long
-    *
-    * Description: Perform a long comparison, storing 0 if the two
-    *              arguments are equal, 1 if the second argument is larger
-    *              or -1 if the first argument is larger.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    movl        4(rFP, %ecx, 4), %eax   # %eax<- vBBhi
-    cmp         4(rFP, %edx, 4), %eax   # compare vCChi and vBBhi
-    jl          .LOP_CMP_LONG_less
-    jg          .LOP_CMP_LONG_greater
-    movl        (rFP, %ecx, 4), %eax    # %eax<- vBBlo
-    cmp         (rFP, %edx, 4), %eax    # compare vCClo and vBBlo
-    ja          .LOP_CMP_LONG_greater
-    jne         .LOP_CMP_LONG_less
-    jmp         .LOP_CMP_LONG_final
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_EQ: /* 0x32 */
-/* File: x86-atom/OP_IF_EQ.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_EQ.S
-    */
-
-/* File: x86-atom/bincmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: bincmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform.
-    *
-    * For: if-eq, if-ge, if-gt, if-le, if-lt, if-ne
-    *
-    * Description: Branch to the given destination if the comparison
-    *              test between the given registers values is true.
-    *
-    * Format: B|A|op CCCC (22t)
-    *
-    * Syntax: op vA, vB, +CCCC
-    */
-
-    movl        rINST,  %eax            # %eax<- BA
-    andl        $15, rINST             # rINST<- A
-    shr         $4, %eax               # %eax<- B
-    GET_VREG    rINST                   # rINST<- vA
-    movl        $4, %edx               # %edx<- 4
-    cmp         (rFP, %eax, 4), rINST   # compare vA and vB
-    jne  1f                      # goto next instruction if reverse
-                                        # comparison is true
-    FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
-    sal         $1, %edx
-    js          common_periodicChecks_backwardBranch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_NE: /* 0x33 */
-/* File: x86-atom/OP_IF_NE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_NE.S
-    */
-
-/* File: x86-atom/bincmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: bincmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform.
-    *
-    * For: if-eq, if-ge, if-gt, if-le, if-lt, if-ne
-    *
-    * Description: Branch to the given destination if the comparison
-    *              test between the given registers values is true.
-    *
-    * Format: B|A|op CCCC (22t)
-    *
-    * Syntax: op vA, vB, +CCCC
-    */
-
-    movl        rINST,  %eax            # %eax<- BA
-    andl        $15, rINST             # rINST<- A
-    shr         $4, %eax               # %eax<- B
-    GET_VREG    rINST                   # rINST<- vA
-    movl        $4, %edx               # %edx<- 4
-    cmp         (rFP, %eax, 4), rINST   # compare vA and vB
-    je  1f                      # goto next instruction if reverse
-                                        # comparison is true
-    FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
-    sal         $1, %edx
-    js          common_periodicChecks_backwardBranch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_LT: /* 0x34 */
-/* File: x86-atom/OP_IF_LT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_LT.S
-    */
-
-/* File: x86-atom/bincmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: bincmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform.
-    *
-    * For: if-eq, if-ge, if-gt, if-le, if-lt, if-ne
-    *
-    * Description: Branch to the given destination if the comparison
-    *              test between the given registers values is true.
-    *
-    * Format: B|A|op CCCC (22t)
-    *
-    * Syntax: op vA, vB, +CCCC
-    */
-
-    movl        rINST,  %eax            # %eax<- BA
-    andl        $15, rINST             # rINST<- A
-    shr         $4, %eax               # %eax<- B
-    GET_VREG    rINST                   # rINST<- vA
-    movl        $4, %edx               # %edx<- 4
-    cmp         (rFP, %eax, 4), rINST   # compare vA and vB
-    jge  1f                      # goto next instruction if reverse
-                                        # comparison is true
-    FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
-    sal         $1, %edx
-    js          common_periodicChecks_backwardBranch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_GE: /* 0x35 */
-/* File: x86-atom/OP_IF_GE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_GE.S
-    */
-
-/* File: x86-atom/bincmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: bincmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform.
-    *
-    * For: if-eq, if-ge, if-gt, if-le, if-lt, if-ne
-    *
-    * Description: Branch to the given destination if the comparison
-    *              test between the given registers values is true.
-    *
-    * Format: B|A|op CCCC (22t)
-    *
-    * Syntax: op vA, vB, +CCCC
-    */
-
-    movl        rINST,  %eax            # %eax<- BA
-    andl        $15, rINST             # rINST<- A
-    shr         $4, %eax               # %eax<- B
-    GET_VREG    rINST                   # rINST<- vA
-    movl        $4, %edx               # %edx<- 4
-    cmp         (rFP, %eax, 4), rINST   # compare vA and vB
-    jl  1f                      # goto next instruction if reverse
-                                        # comparison is true
-    FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
-    sal         $1, %edx
-    js          common_periodicChecks_backwardBranch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_GT: /* 0x36 */
-/* File: x86-atom/OP_IF_GT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_GT.S
-    */
-
-/* File: x86-atom/bincmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: bincmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform.
-    *
-    * For: if-eq, if-ge, if-gt, if-le, if-lt, if-ne
-    *
-    * Description: Branch to the given destination if the comparison
-    *              test between the given registers values is true.
-    *
-    * Format: B|A|op CCCC (22t)
-    *
-    * Syntax: op vA, vB, +CCCC
-    */
-
-    movl        rINST,  %eax            # %eax<- BA
-    andl        $15, rINST             # rINST<- A
-    shr         $4, %eax               # %eax<- B
-    GET_VREG    rINST                   # rINST<- vA
-    movl        $4, %edx               # %edx<- 4
-    cmp         (rFP, %eax, 4), rINST   # compare vA and vB
-    jle  1f                      # goto next instruction if reverse
-                                        # comparison is true
-    FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
-    sal         $1, %edx
-    js          common_periodicChecks_backwardBranch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_LE: /* 0x37 */
-/* File: x86-atom/OP_IF_LE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_LE.S
-    */
-
-/* File: x86-atom/bincmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: bincmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform.
-    *
-    * For: if-eq, if-ge, if-gt, if-le, if-lt, if-ne
-    *
-    * Description: Branch to the given destination if the comparison
-    *              test between the given registers values is true.
-    *
-    * Format: B|A|op CCCC (22t)
-    *
-    * Syntax: op vA, vB, +CCCC
-    */
-
-    movl        rINST,  %eax            # %eax<- BA
-    andl        $15, rINST             # rINST<- A
-    shr         $4, %eax               # %eax<- B
-    GET_VREG    rINST                   # rINST<- vA
-    movl        $4, %edx               # %edx<- 4
-    cmp         (rFP, %eax, 4), rINST   # compare vA and vB
-    jg  1f                      # goto next instruction if reverse
-                                        # comparison is true
-    FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
-    sal         $1, %edx
-    js          common_periodicChecks_backwardBranch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_EQZ: /* 0x38 */
-/* File: x86-atom/OP_IF_EQZ.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_EQZ.S
-    */
-
-/* File: x86-atom/zcmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: zcmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform
-    *
-    * For: if-eqz, if-gez, if-gtz, if-lez, if-ltz, if-nez
-    *
-    * Description: Branch to the given destination if the given register's
-    *              value compares with 0 as specified.
-    *
-    * Format: AA|op BBBB (21t)
-    *
-    * Syntax: op vAA, +BBBB
-    */
-
-    cmp         $0, (rFP, rINST, 4)    # compare vAA with zero
-    jne  OP_IF_EQZ_2f                    # goto next instruction or branch
-    FETCHs      1, %edx                 # %edx<- BBBB; branch offset
-    sal         $1, %edx               # %edx<- adjust byte offset
-
-   /*
-    * Inline common_backwardBranch
-    */
-
-    js          common_periodicChecks_backwardBranch  # jump on backwards branch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-   /*
-    * FINISH code
-    */
-
-OP_IF_EQZ_2f:
-    movzbl      4(rPC), %edx            # grab the next opcode
-    movzbl      5(rPC), rINST           # update the instruction
-    addl        $4, rPC                # update the program counter
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4) # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_NEZ: /* 0x39 */
-/* File: x86-atom/OP_IF_NEZ.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_NEZ.S
-    */
-
-/* File: x86-atom/zcmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: zcmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform
-    *
-    * For: if-eqz, if-gez, if-gtz, if-lez, if-ltz, if-nez
-    *
-    * Description: Branch to the given destination if the given register's
-    *              value compares with 0 as specified.
-    *
-    * Format: AA|op BBBB (21t)
-    *
-    * Syntax: op vAA, +BBBB
-    */
-
-    cmp         $0, (rFP, rINST, 4)    # compare vAA with zero
-    je  OP_IF_NEZ_2f                    # goto next instruction or branch
-    FETCHs      1, %edx                 # %edx<- BBBB; branch offset
-    sal         $1, %edx               # %edx<- adjust byte offset
-
-   /*
-    * Inline common_backwardBranch
-    */
-
-    js          common_periodicChecks_backwardBranch  # jump on backwards branch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-   /*
-    * FINISH code
-    */
-
-OP_IF_NEZ_2f:
-    movzbl      4(rPC), %edx            # grab the next opcode
-    movzbl      5(rPC), rINST           # update the instruction
-    addl        $4, rPC                # update the program counter
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4) # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_LTZ: /* 0x3a */
-/* File: x86-atom/OP_IF_LTZ.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_LTZ.S
-    */
-
-/* File: x86-atom/zcmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: zcmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform
-    *
-    * For: if-eqz, if-gez, if-gtz, if-lez, if-ltz, if-nez
-    *
-    * Description: Branch to the given destination if the given register's
-    *              value compares with 0 as specified.
-    *
-    * Format: AA|op BBBB (21t)
-    *
-    * Syntax: op vAA, +BBBB
-    */
-
-    cmp         $0, (rFP, rINST, 4)    # compare vAA with zero
-    jge  OP_IF_LTZ_2f                    # goto next instruction or branch
-    FETCHs      1, %edx                 # %edx<- BBBB; branch offset
-    sal         $1, %edx               # %edx<- adjust byte offset
-
-   /*
-    * Inline common_backwardBranch
-    */
-
-    js          common_periodicChecks_backwardBranch  # jump on backwards branch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-   /*
-    * FINISH code
-    */
-
-OP_IF_LTZ_2f:
-    movzbl      4(rPC), %edx            # grab the next opcode
-    movzbl      5(rPC), rINST           # update the instruction
-    addl        $4, rPC                # update the program counter
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4) # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_GEZ: /* 0x3b */
-/* File: x86-atom/OP_IF_GEZ.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_GEZ.S
-    */
-
-/* File: x86-atom/zcmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: zcmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform
-    *
-    * For: if-eqz, if-gez, if-gtz, if-lez, if-ltz, if-nez
-    *
-    * Description: Branch to the given destination if the given register's
-    *              value compares with 0 as specified.
-    *
-    * Format: AA|op BBBB (21t)
-    *
-    * Syntax: op vAA, +BBBB
-    */
-
-    cmp         $0, (rFP, rINST, 4)    # compare vAA with zero
-    jl  OP_IF_GEZ_2f                    # goto next instruction or branch
-    FETCHs      1, %edx                 # %edx<- BBBB; branch offset
-    sal         $1, %edx               # %edx<- adjust byte offset
-
-   /*
-    * Inline common_backwardBranch
-    */
-
-    js          common_periodicChecks_backwardBranch  # jump on backwards branch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-   /*
-    * FINISH code
-    */
-
-OP_IF_GEZ_2f:
-    movzbl      4(rPC), %edx            # grab the next opcode
-    movzbl      5(rPC), rINST           # update the instruction
-    addl        $4, rPC                # update the program counter
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4) # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_GTZ: /* 0x3c */
-/* File: x86-atom/OP_IF_GTZ.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_GTZ.S
-    */
-
-/* File: x86-atom/zcmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: zcmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform
-    *
-    * For: if-eqz, if-gez, if-gtz, if-lez, if-ltz, if-nez
-    *
-    * Description: Branch to the given destination if the given register's
-    *              value compares with 0 as specified.
-    *
-    * Format: AA|op BBBB (21t)
-    *
-    * Syntax: op vAA, +BBBB
-    */
-
-    cmp         $0, (rFP, rINST, 4)    # compare vAA with zero
-    jle  OP_IF_GTZ_2f                    # goto next instruction or branch
-    FETCHs      1, %edx                 # %edx<- BBBB; branch offset
-    sal         $1, %edx               # %edx<- adjust byte offset
-
-   /*
-    * Inline common_backwardBranch
-    */
-
-    js          common_periodicChecks_backwardBranch  # jump on backwards branch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-   /*
-    * FINISH code
-    */
-
-OP_IF_GTZ_2f:
-    movzbl      4(rPC), %edx            # grab the next opcode
-    movzbl      5(rPC), rINST           # update the instruction
-    addl        $4, rPC                # update the program counter
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4) # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IF_LEZ: /* 0x3d */
-/* File: x86-atom/OP_IF_LEZ.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_LEZ.S
-    */
-
-/* File: x86-atom/zcmp.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: zcmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform
-    *
-    * For: if-eqz, if-gez, if-gtz, if-lez, if-ltz, if-nez
-    *
-    * Description: Branch to the given destination if the given register's
-    *              value compares with 0 as specified.
-    *
-    * Format: AA|op BBBB (21t)
-    *
-    * Syntax: op vAA, +BBBB
-    */
-
-    cmp         $0, (rFP, rINST, 4)    # compare vAA with zero
-    jg  OP_IF_LEZ_2f                    # goto next instruction or branch
-    FETCHs      1, %edx                 # %edx<- BBBB; branch offset
-    sal         $1, %edx               # %edx<- adjust byte offset
-
-   /*
-    * Inline common_backwardBranch
-    */
-
-    js          common_periodicChecks_backwardBranch  # jump on backwards branch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-   /*
-    * FINISH code
-    */
-
-OP_IF_LEZ_2f:
-    movzbl      4(rPC), %edx            # grab the next opcode
-    movzbl      5(rPC), rINST           # update the instruction
-    addl        $4, rPC                # update the program counter
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4) # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_UNUSED_3E: /* 0x3e */
-/* File: x86-atom/OP_UNUSED_3E.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_3E.S
-    */
-
-/* File: x86-atom/unused.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_UNUSED_3F: /* 0x3f */
-/* File: x86-atom/OP_UNUSED_3F.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_3F.S
-    */
-
-/* File: x86-atom/unused.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_UNUSED_40: /* 0x40 */
-/* File: x86-atom/OP_UNUSED_40.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_40.S
-    */
-
-/* File: x86-atom/unused.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_UNUSED_41: /* 0x41 */
-/* File: x86-atom/OP_UNUSED_41.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_41.S
-    */
-
-/* File: x86-atom/unused.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_UNUSED_42: /* 0x42 */
-/* File: x86-atom/OP_UNUSED_42.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_42.S
-    */
-
-/* File: x86-atom/unused.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_UNUSED_43: /* 0x43 */
-/* File: x86-atom/OP_UNUSED_43.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_43.S
-    */
-
-/* File: x86-atom/unused.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AGET: /* 0x44 */
-/* File: x86-atom/OP_AGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET.S
-    *
-    * Code: Generic 32-bit array "get" operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       mov performed also dependent on the type of the array element.
-    *
-    * For: aget, aget-boolean, aget-byte, aget-char, aget-object, sget, aget-short
-    *
-    * Description: Perform an array get operation at the identified index
-    *              of a given array; load the array value into the value
-    *              register. vAA <- vBB[vCC].
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    lea         (%ecx, %edx, 4), %ecx # %ecx<- &vBB[vCC]
-                                           # trying: lea (%ecx, %edx, scale), %ecx
-                                           # to reduce code size
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl offArrayObject_contents(%ecx), %edx # %edx<- vBB[vCC]
-                                                # doing this and the previous instr
-                                                # with one instr was not faster
-    SET_VREG    %edx  rINST             # vAA<- %edx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AGET_WIDE: /* 0x45 */
-/* File: x86-atom/OP_AGET_WIDE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_WIDE.S
-    *
-    * Code: 64-bit array get operation.
-    *
-    * For: aget-wide
-    *
-    * Description: Perform an array get operation at the identified index
-    *              of a given array; load the array value into the destination
-    *              register. vAA <- vBB[vCC].
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        offArrayObject_contents(%ecx, %edx, 8), %xmm0 # %xmm0<- vBB[vCC]
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AGET_OBJECT: /* 0x46 */
-/* File: x86-atom/OP_AGET_OBJECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_OBJECT.S
-    */
-
-/* File: x86-atom/OP_AGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET.S
-    *
-    * Code: Generic 32-bit array "get" operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       mov performed also dependent on the type of the array element.
-    *
-    * For: aget, aget-boolean, aget-byte, aget-char, aget-object, sget, aget-short
-    *
-    * Description: Perform an array get operation at the identified index
-    *              of a given array; load the array value into the value
-    *              register. vAA <- vBB[vCC].
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    lea         (%ecx, %edx, 4), %ecx # %ecx<- &vBB[vCC]
-                                           # trying: lea (%ecx, %edx, scale), %ecx
-                                           # to reduce code size
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl offArrayObject_contents(%ecx), %edx # %edx<- vBB[vCC]
-                                                # doing this and the previous instr
-                                                # with one instr was not faster
-    SET_VREG    %edx  rINST             # vAA<- %edx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AGET_BOOLEAN: /* 0x47 */
-/* File: x86-atom/OP_AGET_BOOLEAN.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_BOOLEAN.S
-    */
-
-/* File: x86-atom/OP_AGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET.S
-    *
-    * Code: Generic 32-bit array "get" operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       mov performed also dependent on the type of the array element.
-    *
-    * For: aget, aget-boolean, aget-byte, aget-char, aget-object, sget, aget-short
-    *
-    * Description: Perform an array get operation at the identified index
-    *              of a given array; load the array value into the value
-    *              register. vAA <- vBB[vCC].
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    lea         (%ecx, %edx, 1), %ecx # %ecx<- &vBB[vCC]
-                                           # trying: lea (%ecx, %edx, scale), %ecx
-                                           # to reduce code size
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movzbl offArrayObject_contents(%ecx), %edx # %edx<- vBB[vCC]
-                                                # doing this and the previous instr
-                                                # with one instr was not faster
-    SET_VREG    %edx  rINST             # vAA<- %edx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AGET_BYTE: /* 0x48 */
-/* File: x86-atom/OP_AGET_BYTE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_BYTE.S
-    */
-
-/* File: x86-atom/OP_AGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET.S
-    *
-    * Code: Generic 32-bit array "get" operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       mov performed also dependent on the type of the array element.
-    *
-    * For: aget, aget-boolean, aget-byte, aget-char, aget-object, sget, aget-short
-    *
-    * Description: Perform an array get operation at the identified index
-    *              of a given array; load the array value into the value
-    *              register. vAA <- vBB[vCC].
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    lea         (%ecx, %edx, 1), %ecx # %ecx<- &vBB[vCC]
-                                           # trying: lea (%ecx, %edx, scale), %ecx
-                                           # to reduce code size
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movsbl offArrayObject_contents(%ecx), %edx # %edx<- vBB[vCC]
-                                                # doing this and the previous instr
-                                                # with one instr was not faster
-    SET_VREG    %edx  rINST             # vAA<- %edx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AGET_CHAR: /* 0x49 */
-/* File: x86-atom/OP_AGET_CHAR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_CHAR.S
-    */
-
-/* File: x86-atom/OP_AGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET.S
-    *
-    * Code: Generic 32-bit array "get" operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       mov performed also dependent on the type of the array element.
-    *
-    * For: aget, aget-boolean, aget-byte, aget-char, aget-object, sget, aget-short
-    *
-    * Description: Perform an array get operation at the identified index
-    *              of a given array; load the array value into the value
-    *              register. vAA <- vBB[vCC].
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    lea         (%ecx, %edx, 2), %ecx # %ecx<- &vBB[vCC]
-                                           # trying: lea (%ecx, %edx, scale), %ecx
-                                           # to reduce code size
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movzwl offArrayObject_contents(%ecx), %edx # %edx<- vBB[vCC]
-                                                # doing this and the previous instr
-                                                # with one instr was not faster
-    SET_VREG    %edx  rINST             # vAA<- %edx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AGET_SHORT: /* 0x4a */
-/* File: x86-atom/OP_AGET_SHORT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_SHORT.S
-    */
-
-/* File: x86-atom/OP_AGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET.S
-    *
-    * Code: Generic 32-bit array "get" operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       mov performed also dependent on the type of the array element.
-    *
-    * For: aget, aget-boolean, aget-byte, aget-char, aget-object, sget, aget-short
-    *
-    * Description: Perform an array get operation at the identified index
-    *              of a given array; load the array value into the value
-    *              register. vAA <- vBB[vCC].
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    lea         (%ecx, %edx, 2), %ecx # %ecx<- &vBB[vCC]
-                                           # trying: lea (%ecx, %edx, scale), %ecx
-                                           # to reduce code size
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movswl offArrayObject_contents(%ecx), %edx # %edx<- vBB[vCC]
-                                                # doing this and the previous instr
-                                                # with one instr was not faster
-    SET_VREG    %edx  rINST             # vAA<- %edx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_APUT: /* 0x4b */
-/* File: x86-atom/OP_APUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT.S
-    *
-    * Code: Generic 32-bit array put operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       move performed also dependent on the type of the array element.
-    *       Provides a "value" register to specify the source of the move
-    *
-    * For: aput-boolean, aput-byte, aput-char, aput-object, aput-short
-    *
-    * Description: Perform an array put operation from the value register;
-    *              store the value register at the identified index of a
-    *              given array. vBB[vCC] <- vAA
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    lea         (%ecx, %edx, 4), %ecx # %ecx<- &vBB[vCC]
-    GET_VREG    rINST                   # rINST<- vAA
-    movl     rINST, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_APUT_WIDE: /* 0x4c */
-/* File: x86-atom/OP_APUT_WIDE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_WIDE.S
-    *
-    * Code: 64-bit array put operation.
-    *
-    * For: aput-wide
-    *
-    * Description: Perform an array put operation from the value register;
-    *              store the value register at the identified index of a
-    *              given array. vBB[vCC] <- vAA.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vAA
-    movq        %xmm0, offArrayObject_contents(%ecx, %edx, 8) # vBB[vCC]<- %xmm0; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_APUT_OBJECT: /* 0x4d */
-/* File: x86-atom/OP_APUT_OBJECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_OBJECT.S
-    *
-    * Code: 32-bit array put operation.  Provides an "scale" variable
-    *       specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       mov performed also dependent on the type of the array element.
-    *       Provides a "value" register to specify the source of the mov
-    *
-    * For: aput-boolean, aput-byte, aput-char, aput-object, aput-short
-    *
-    * Description: Perform an array put operation from the value register;
-    *              store the value register at the identified index of a
-    *              given array. vBB[vCC] <- vAA
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %eax                 # %eax<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %eax                    # %eax<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %eax               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%eax), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    GET_VREG    rINST                   # rINST<- vAA
-    lea         (%eax, %edx, 4), %edx   # %edx<- &vBB[vCC]
-    cmp         $0, rINST              # check for null reference
-    je          .LOP_APUT_OBJECT_skip_check  # reference is null so skip type check
-    jmp         .LOP_APUT_OBJECT_finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_APUT_BOOLEAN: /* 0x4e */
-/* File: x86-atom/OP_APUT_BOOLEAN.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_BOOLEAN.S
-    */
-
-/* File: x86-atom/OP_APUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT.S
-    *
-    * Code: Generic 32-bit array put operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       move performed also dependent on the type of the array element.
-    *       Provides a "value" register to specify the source of the move
-    *
-    * For: aput-boolean, aput-byte, aput-char, aput-object, aput-short
-    *
-    * Description: Perform an array put operation from the value register;
-    *              store the value register at the identified index of a
-    *              given array. vBB[vCC] <- vAA
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    lea         (%ecx, %edx, 1), %ecx # %ecx<- &vBB[vCC]
-    GET_VREG    rINST                   # rINST<- vAA
-    movb     rINSTbl, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_APUT_BYTE: /* 0x4f */
-/* File: x86-atom/OP_APUT_BYTE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_BYTE.S
-    */
-
-/* File: x86-atom/OP_APUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT.S
-    *
-    * Code: Generic 32-bit array put operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       move performed also dependent on the type of the array element.
-    *       Provides a "value" register to specify the source of the move
-    *
-    * For: aput-boolean, aput-byte, aput-char, aput-object, aput-short
-    *
-    * Description: Perform an array put operation from the value register;
-    *              store the value register at the identified index of a
-    *              given array. vBB[vCC] <- vAA
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    lea         (%ecx, %edx, 1), %ecx # %ecx<- &vBB[vCC]
-    GET_VREG    rINST                   # rINST<- vAA
-    movb     rINSTbl, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_APUT_CHAR: /* 0x50 */
-/* File: x86-atom/OP_APUT_CHAR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_CHAR.S
-    */
-
-/* File: x86-atom/OP_APUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT.S
-    *
-    * Code: Generic 32-bit array put operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       move performed also dependent on the type of the array element.
-    *       Provides a "value" register to specify the source of the move
-    *
-    * For: aput-boolean, aput-byte, aput-char, aput-object, aput-short
-    *
-    * Description: Perform an array put operation from the value register;
-    *              store the value register at the identified index of a
-    *              given array. vBB[vCC] <- vAA
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    lea         (%ecx, %edx, 2), %ecx # %ecx<- &vBB[vCC]
-    GET_VREG    rINST                   # rINST<- vAA
-    movw     rINSTw, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_APUT_SHORT: /* 0x51 */
-/* File: x86-atom/OP_APUT_SHORT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_SHORT.S
-    */
-
-/* File: x86-atom/OP_APUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT.S
-    *
-    * Code: Generic 32-bit array put operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       move performed also dependent on the type of the array element.
-    *       Provides a "value" register to specify the source of the move
-    *
-    * For: aput-boolean, aput-byte, aput-char, aput-object, aput-short
-    *
-    * Description: Perform an array put operation from the value register;
-    *              store the value register at the identified index of a
-    *              given array. vBB[vCC] <- vAA
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    lea         (%ecx, %edx, 2), %ecx # %ecx<- &vBB[vCC]
-    GET_VREG    rINST                   # rINST<- vAA
-    movw     rINSTw, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET: /* 0x52 */
-/* File: x86-atom/OP_IGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET.S
-    *
-    * Code: Generic 32-bit instance field "get" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iget's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iget-boolean, iget-byte, iget-char, iget-object, iget
-    *      iget-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IGET_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %edx # %edx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    jmp         .LOP_IGET_finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_WIDE: /* 0x53 */
-/* File: x86-atom/OP_IGET_WIDE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_WIDE.S
-    *
-    * Code: 64 bit instance field "get" operation. Uses no substitutions.
-    *
-    * For: iget-wide
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    * Format:  B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-    movl        rGLUE, %eax             # %eax<- MterpGlue pointer
-    movl        offGlue_methodClassDex(%eax), %ecx # %ecx<- pDvmDex
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- CCCC
-    FETCH       1, %edx                 # %edx<- pDvmDex->pResFields
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved InstField ptr
-    cmp         $0, %ecx               # check for null ptr; resolved InstField ptr
-    jne         .LOP_IGET_WIDE_finish
-    movl        offGlue_method(%eax), %ecx # %ecx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%ecx), %ecx # %ecx<- method->clazz
-    movl        %ecx, -8(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -4(%esp)          # push parameter method->clazz
-    jmp         .LOP_IGET_WIDE_finish2
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_OBJECT: /* 0x54 */
-/* File: x86-atom/OP_IGET_OBJECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_OBJECT.S
-    */
-
-/* File: x86-atom/OP_IGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET.S
-    *
-    * Code: Generic 32-bit instance field "get" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iget's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iget-boolean, iget-byte, iget-char, iget-object, iget
-    *      iget-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IGET_OBJECT_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %edx # %edx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    jmp         .LOP_IGET_OBJECT_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_BOOLEAN: /* 0x55 */
-/* File: x86-atom/OP_IGET_BOOLEAN.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_BOOLEAN.S
-    */
-
-/* File: x86-atom/OP_IGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET.S
-    *
-    * Code: Generic 32-bit instance field "get" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iget's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iget-boolean, iget-byte, iget-char, iget-object, iget
-    *      iget-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IGET_BOOLEAN_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %edx # %edx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    jmp         .LOP_IGET_BOOLEAN_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_BYTE: /* 0x56 */
-/* File: x86-atom/OP_IGET_BYTE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_BYTE.S
-    */
-
-/* File: x86-atom/OP_IGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET.S
-    *
-    * Code: Generic 32-bit instance field "get" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iget's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iget-boolean, iget-byte, iget-char, iget-object, iget
-    *      iget-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IGET_BYTE_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %edx # %edx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    jmp         .LOP_IGET_BYTE_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_CHAR: /* 0x57 */
-/* File: x86-atom/OP_IGET_CHAR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_CHAR.S
-    */
-
-/* File: x86-atom/OP_IGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET.S
-    *
-    * Code: Generic 32-bit instance field "get" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iget's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iget-boolean, iget-byte, iget-char, iget-object, iget
-    *      iget-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IGET_CHAR_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %edx # %edx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    jmp         .LOP_IGET_CHAR_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_SHORT: /* 0x58 */
-/* File: x86-atom/OP_IGET_SHORT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_SHORT.S
-    */
-
-/* File: x86-atom/OP_IGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET.S
-    *
-    * Code: Generic 32-bit instance field "get" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iget's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iget-boolean, iget-byte, iget-char, iget-object, iget
-    *      iget-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IGET_SHORT_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %edx # %edx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    jmp         .LOP_IGET_SHORT_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT: /* 0x59 */
-/* File: x86-atom/OP_IPUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-    /*
-    * File: OP_IPUT.S
-    *
-    * Code: Generic 32-bit instance field "put" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iput's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iput-boolean, iput-byte, iput-char, iput-object, iput
-    *      iput-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IPUT_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    jmp         .LOP_IPUT_finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_WIDE: /* 0x5a */
-/* File: x86-atom/OP_IPUT_WIDE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_WIDE.S
-    *
-    * Code: 64 bit instance field "put" operation. Uses no substitutions.
-    *
-    * For: iget-wide
-    *
-    * Description: Perform the object instance field "put" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    * Format:  B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-    movl        rGLUE, %eax             # %eax<- MterpGlue pointer
-    movl        offGlue_methodClassDex(%eax), %ecx # %ecx<- pDvmDex
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- CCCC
-    FETCH       1, %edx                 # %edx<- pDvmDex->pResFields
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved InstField ptr
-    cmp         $0, %ecx               # check for null ptr; resolved InstField ptr
-    jne         .LOP_IPUT_WIDE_finish
-    movl        offGlue_method(%eax), %ecx # %ecx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%ecx), %ecx # %ecx<- method->clazz
-    movl        %ecx, -8(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -4(%esp)          # push parameter method->clazz
-    jmp         .LOP_IPUT_WIDE_finish2
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_OBJECT: /* 0x5b */
-/* File: x86-atom/OP_IPUT_OBJECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-    /*
-    * File: OP_IPUT.S
-    *
-    * Code: Generic 32-bit instance field "put" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iput's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iput-boolean, iput-byte, iput-char, iput-object, iput
-    *      iput-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IPUT_OBJECT_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    jmp         .LOP_IPUT_OBJECT_finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_BOOLEAN: /* 0x5c */
-/* File: x86-atom/OP_IPUT_BOOLEAN.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_BOOLEAN.S
-    */
-
-/* File: x86-atom/OP_IPUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-    /*
-    * File: OP_IPUT.S
-    *
-    * Code: Generic 32-bit instance field "put" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iput's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iput-boolean, iput-byte, iput-char, iput-object, iput
-    *      iput-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IPUT_BOOLEAN_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    jmp         .LOP_IPUT_BOOLEAN_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_BYTE: /* 0x5d */
-/* File: x86-atom/OP_IPUT_BYTE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_BYTE.S
-    */
-
-/* File: x86-atom/OP_IPUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-    /*
-    * File: OP_IPUT.S
-    *
-    * Code: Generic 32-bit instance field "put" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iput's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iput-boolean, iput-byte, iput-char, iput-object, iput
-    *      iput-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IPUT_BYTE_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    jmp         .LOP_IPUT_BYTE_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_CHAR: /* 0x5e */
-/* File: x86-atom/OP_IPUT_CHAR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_CHAR.S
-    */
-
-/* File: x86-atom/OP_IPUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-    /*
-    * File: OP_IPUT.S
-    *
-    * Code: Generic 32-bit instance field "put" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iput's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iput-boolean, iput-byte, iput-char, iput-object, iput
-    *      iput-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IPUT_CHAR_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    jmp         .LOP_IPUT_CHAR_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_SHORT: /* 0x5f */
-/* File: x86-atom/OP_IPUT_SHORT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_SHORT.S
-    */
-
-/* File: x86-atom/OP_IPUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-    /*
-    * File: OP_IPUT.S
-    *
-    * Code: Generic 32-bit instance field "put" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iput's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iput-boolean, iput-byte, iput-char, iput-object, iput
-    *      iput-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .LOP_IPUT_SHORT_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    jmp         .LOP_IPUT_SHORT_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SGET: /* 0x60 */
-/* File: x86-atom/OP_SGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET.S
-    *
-    * Code: Generic 32-bit static field "get" operation. Uses no substitutions.
-    *
-    * For: sget-boolean, sget-byte, sget-char, sget-object, sget, sget-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; load the field value
-    *              into the value register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SGET_resolve
-    jmp         .LOP_SGET_finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SGET_WIDE: /* 0x61 */
-/* File: x86-atom/OP_SGET_WIDE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_WIDE.S
-    *
-    * Code: 64-bit static field "get" operation. Uses no substitutions.
-    *
-    * For: sget-wide
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field, loading or storing
-    *              into the value register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_methodClassDex(%eax), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %edx                 # %edx<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %edx, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SGET_WIDE_resolve
-
-.LOP_SGET_WIDE_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        offStaticField_value(%ecx), %xmm0 # %xmm0<- field value
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- field value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SGET_OBJECT: /* 0x62 */
-/* File: x86-atom/OP_SGET_OBJECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_OBJECT.S
-    */
-
-/* File: x86-atom/OP_SGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET.S
-    *
-    * Code: Generic 32-bit static field "get" operation. Uses no substitutions.
-    *
-    * For: sget-boolean, sget-byte, sget-char, sget-object, sget, sget-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; load the field value
-    *              into the value register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SGET_OBJECT_resolve
-    jmp         .LOP_SGET_OBJECT_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SGET_BOOLEAN: /* 0x63 */
-/* File: x86-atom/OP_SGET_BOOLEAN.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_BOOLEAN.S
-    */
-
-/* File: x86-atom/OP_SGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET.S
-    *
-    * Code: Generic 32-bit static field "get" operation. Uses no substitutions.
-    *
-    * For: sget-boolean, sget-byte, sget-char, sget-object, sget, sget-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; load the field value
-    *              into the value register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SGET_BOOLEAN_resolve
-    jmp         .LOP_SGET_BOOLEAN_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SGET_BYTE: /* 0x64 */
-/* File: x86-atom/OP_SGET_BYTE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_BYTE.S
-    */
-
-/* File: x86-atom/OP_SGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET.S
-    *
-    * Code: Generic 32-bit static field "get" operation. Uses no substitutions.
-    *
-    * For: sget-boolean, sget-byte, sget-char, sget-object, sget, sget-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; load the field value
-    *              into the value register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SGET_BYTE_resolve
-    jmp         .LOP_SGET_BYTE_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SGET_CHAR: /* 0x65 */
-/* File: x86-atom/OP_SGET_CHAR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_CHAR.S
-    */
-
-/* File: x86-atom/OP_SGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET.S
-    *
-    * Code: Generic 32-bit static field "get" operation. Uses no substitutions.
-    *
-    * For: sget-boolean, sget-byte, sget-char, sget-object, sget, sget-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; load the field value
-    *              into the value register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SGET_CHAR_resolve
-    jmp         .LOP_SGET_CHAR_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SGET_SHORT: /* 0x66 */
-/* File: x86-atom/OP_SGET_SHORT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_SHORT.S
-    */
-
-/* File: x86-atom/OP_SGET.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET.S
-    *
-    * Code: Generic 32-bit static field "get" operation. Uses no substitutions.
-    *
-    * For: sget-boolean, sget-byte, sget-char, sget-object, sget, sget-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; load the field value
-    *              into the value register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SGET_SHORT_resolve
-    jmp         .LOP_SGET_SHORT_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPUT: /* 0x67 */
-/* File: x86-atom/OP_SPUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT.S
-    *
-    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
-    *
-    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; store the field value
-    *              register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SPUT_resolve
-    jmp         .LOP_SPUT_finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPUT_WIDE: /* 0x68 */
-/* File: x86-atom/OP_SPUT_WIDE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_WIDE.S
-    *
-    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
-    *
-    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; store the field value
-    *              register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_methodClassDex(%eax), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %edx                 # %edx<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %edx, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SPUT_WIDE_resolve
-
-.LOP_SPUT_WIDE_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vAA
-    movq        %xmm0, offStaticField_value(%ecx) # field value<- field value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPUT_OBJECT: /* 0x69 */
-/* File: x86-atom/OP_SPUT_OBJECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_OBJECT.S
-    *
-    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
-    *
-    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; store the field value
-    *              register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField
-    je          .LOP_SPUT_OBJECT_resolve
-    jmp         .LOP_SPUT_OBJECT_finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPUT_BOOLEAN: /* 0x6a */
-/* File: x86-atom/OP_SPUT_BOOLEAN.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_BOOLEAN.S
-    */
-
-/* File: x86-atom/OP_SPUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT.S
-    *
-    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
-    *
-    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; store the field value
-    *              register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SPUT_BOOLEAN_resolve
-    jmp         .LOP_SPUT_BOOLEAN_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPUT_BYTE: /* 0x6b */
-/* File: x86-atom/OP_SPUT_BYTE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_BYTE.S
-    */
-
-/* File: x86-atom/OP_SPUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT.S
-    *
-    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
-    *
-    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; store the field value
-    *              register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SPUT_BYTE_resolve
-    jmp         .LOP_SPUT_BYTE_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPUT_CHAR: /* 0x6c */
-/* File: x86-atom/OP_SPUT_CHAR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_CHAR.S
-    */
-
-/* File: x86-atom/OP_SPUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT.S
-    *
-    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
-    *
-    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; store the field value
-    *              register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SPUT_CHAR_resolve
-    jmp         .LOP_SPUT_CHAR_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPUT_SHORT: /* 0x6d */
-/* File: x86-atom/OP_SPUT_SHORT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_SHORT.S
-    */
-
-/* File: x86-atom/OP_SPUT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT.S
-    *
-    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
-    *
-    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; store the field value
-    *              register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .LOP_SPUT_SHORT_resolve
-    jmp         .LOP_SPUT_SHORT_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_VIRTUAL: /* 0x6e */
-/* File: x86-atom/OP_INVOKE_VIRTUAL.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_VIRTUAL.S
-    *
-    * Code: Call a virtual method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_direct that allows up to 255 arguments.
-    *
-    * For: invoke-virtual, invoke-virtual/range
-    *
-    * Description: invoke-virtual is used to invoke a normal virtual method;
-    *              a method that is not static or final, and is not a constructor.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    EXPORT_PC                           # must export pc for invoke
-    movl        offGlue_methodClassDex(%eax), %eax # %eax<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- method index
-    movl        offDvmDex_pResMethods(%eax), %eax # %eax<- pDvmDex->pResMethods
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    .if         (!0)
-    and         $15, %edx              # %edx<- D if not range
-    .endif
-    cmp         $0, (%eax, %ecx, 4)    # check if already resolved
-    je          .LOP_INVOKE_VIRTUAL_break
-    movl        (%eax, %ecx, 4), %eax   # %eax<- resolved base method
-    jmp         .LOP_INVOKE_VIRTUAL_continue
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_SUPER: /* 0x6f */
-/* File: x86-atom/OP_INVOKE_SUPER.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_SUPER.S
-    *
-    * Code: Call super method.
-    *
-    * For: invoke-super, invoke-super/range
-    *
-    * Description: invoke-super is used to invoke the closest superclass's virtual
-    *              method (as opposed to the one with the same method_id in the
-    *              calling class).
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    FETCH       2, %eax                 # %eax<- GFED or CCCC
-    movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex
-    .if         (!0)
-    and         $15, %eax              # %eax<- D if not range
-    .endif
-    FETCH       1, %edx                 # %edx<- method index
-    movl        offDvmDex_pResMethods(%ecx), %ecx # %ecx<- pDvmDex->pResMethods
-    cmp         $0, (rFP, %eax, 4)     # check for null object
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved base method
-    je          common_errNullObject    # handle null object
-    jmp         .LOP_INVOKE_SUPER_continue2
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_DIRECT: /* 0x70 */
-/* File: x86-atom/OP_INVOKE_DIRECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_DIRECT.S
-    *
-    * Code: Call a non-static direct method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_direct that allows up to 255 arguments.
-    *
-    * For: invoke-direct, invoke-direct/range
-    *
-    * Description: invoke-direct is used to invoke a non-static direct method;
-    *              an instance method that is non-overridable, for example,
-    *              either a private instance method or a constructor.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- method index
-    movl        offDvmDex_pResMethods(%ecx), %ecx # %ecx<- pDvmDex->pResMethods
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved method to call
-    .if         (!0)
-    andl        $15, %edx              # %edx<- D if not range
-    .endif
-    EXPORT_PC                           # must export for invoke
-    movl        %edx, -4(%esp)          # save "this" pointer register
-    cmp         $0, %ecx               # check if already resolved
-    GET_VREG    %edx                    # %edx<- "this" pointer
-    je          .LOP_INVOKE_DIRECT_resolve     # handle resolve
-
-.LOP_INVOKE_DIRECT_finish:
-    cmp         $0, %edx               # check for null "this"
-    jne         common_invokeMethodNoRange # invoke method common code
-    jmp         common_errNullObject
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_STATIC: /* 0x71 */
-/* File: x86-atom/OP_INVOKE_STATIC.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_STATIC.S
-    *
-    * Code: Call static direct method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_static that allows up to 255 arguments.
-    *
-    * For: invoke-static, invoke-static/range
-    *
-    * Description: invoke-static is used to invoke static direct method.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %edx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- method index
-    movl        offDvmDex_pResMethods(%ecx), %ecx # %edx<- pDvmDex->pResMethods
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved method to call
-    cmp         $0, %ecx               # check if already resolved
-    EXPORT_PC                           # must export for invoke
-    jne         common_invokeMethodNoRange # invoke method common code
-    jmp         .LOP_INVOKE_STATIC_break
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_INTERFACE: /* 0x72 */
-/* File: x86-atom/OP_INVOKE_INTERFACE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_INTERFACE.S
-    *
-    * Code: Call at method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_interface that allows up to 255 arguments.
-    *
-    * For: invoke-interface, invoke-interface-range
-    *
-    * Description: invoke-interface is used to invoke an interface method; on an
-    *              object whose concrete class isn't known, using a method_id that
-    *              refers to an interface.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    FETCH       1, %ecx                 # %ecx<- method index
-    movl        %ecx, -12(%esp)         # push argument method index
-    .if         (!0)
-    and         $15, %edx              # %edx<- D if not range
-    .endif
-    EXPORT_PC                           # must export for invoke
-    GET_VREG    %edx                    # %edx<- first arg "this pointer"
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_methodClassDex(%eax), %eax # %eax<- glue->pDvmDex
-    movl        %eax, -4(%esp)          # push parameter class
-    cmp         $0, %edx               # check for null object
-    je          common_errNullObject    # handle null object
-    jmp         .LOP_INVOKE_INTERFACE_break
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_UNUSED_73: /* 0x73 */
-/* File: x86-atom/OP_UNUSED_73.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_73.S
-    */
-
-/* File: x86-atom/unused.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
-/* File: x86-atom/OP_INVOKE_VIRTUAL_RANGE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_VIRTUAL_RANGE.S
-    */
-
-/* File: x86-atom/OP_INVOKE_VIRTUAL.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_VIRTUAL.S
-    *
-    * Code: Call a virtual method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_direct that allows up to 255 arguments.
-    *
-    * For: invoke-virtual, invoke-virtual/range
-    *
-    * Description: invoke-virtual is used to invoke a normal virtual method;
-    *              a method that is not static or final, and is not a constructor.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    EXPORT_PC                           # must export pc for invoke
-    movl        offGlue_methodClassDex(%eax), %eax # %eax<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- method index
-    movl        offDvmDex_pResMethods(%eax), %eax # %eax<- pDvmDex->pResMethods
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    .if         (!1)
-    and         $15, %edx              # %edx<- D if not range
-    .endif
-    cmp         $0, (%eax, %ecx, 4)    # check if already resolved
-    je          .LOP_INVOKE_VIRTUAL_RANGE_break
-    movl        (%eax, %ecx, 4), %eax   # %eax<- resolved base method
-    jmp         .LOP_INVOKE_VIRTUAL_RANGE_continue
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
-/* File: x86-atom/OP_INVOKE_SUPER_RANGE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_SUPER_RANGE.S
-    */
-
-/* File: x86-atom/OP_INVOKE_SUPER.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_SUPER.S
-    *
-    * Code: Call super method.
-    *
-    * For: invoke-super, invoke-super/range
-    *
-    * Description: invoke-super is used to invoke the closest superclass's virtual
-    *              method (as opposed to the one with the same method_id in the
-    *              calling class).
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    FETCH       2, %eax                 # %eax<- GFED or CCCC
-    movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex
-    .if         (!1)
-    and         $15, %eax              # %eax<- D if not range
-    .endif
-    FETCH       1, %edx                 # %edx<- method index
-    movl        offDvmDex_pResMethods(%ecx), %ecx # %ecx<- pDvmDex->pResMethods
-    cmp         $0, (rFP, %eax, 4)     # check for null object
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved base method
-    je          common_errNullObject    # handle null object
-    jmp         .LOP_INVOKE_SUPER_RANGE_continue2
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
-/* File: x86-atom/OP_INVOKE_DIRECT_RANGE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_DIRECT_RANGE.S
-    */
-
-/* File: x86-atom/OP_INVOKE_DIRECT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_DIRECT.S
-    *
-    * Code: Call a non-static direct method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_direct that allows up to 255 arguments.
-    *
-    * For: invoke-direct, invoke-direct/range
-    *
-    * Description: invoke-direct is used to invoke a non-static direct method;
-    *              an instance method that is non-overridable, for example,
-    *              either a private instance method or a constructor.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- method index
-    movl        offDvmDex_pResMethods(%ecx), %ecx # %ecx<- pDvmDex->pResMethods
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved method to call
-    .if         (!1)
-    andl        $15, %edx              # %edx<- D if not range
-    .endif
-    EXPORT_PC                           # must export for invoke
-    movl        %edx, -4(%esp)          # save "this" pointer register
-    cmp         $0, %ecx               # check if already resolved
-    GET_VREG    %edx                    # %edx<- "this" pointer
-    je          .LOP_INVOKE_DIRECT_RANGE_resolve     # handle resolve
-
-.LOP_INVOKE_DIRECT_RANGE_finish:
-    cmp         $0, %edx               # check for null "this"
-    jne         common_invokeMethodRange # invoke method common code
-    jmp         common_errNullObject
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
-/* File: x86-atom/OP_INVOKE_STATIC_RANGE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_STATIC_RANGE.S
-    */
-
-/* File: x86-atom/OP_INVOKE_STATIC.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_STATIC.S
-    *
-    * Code: Call static direct method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_static that allows up to 255 arguments.
-    *
-    * For: invoke-static, invoke-static/range
-    *
-    * Description: invoke-static is used to invoke static direct method.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %edx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- method index
-    movl        offDvmDex_pResMethods(%ecx), %ecx # %edx<- pDvmDex->pResMethods
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved method to call
-    cmp         $0, %ecx               # check if already resolved
-    EXPORT_PC                           # must export for invoke
-    jne         common_invokeMethodRange # invoke method common code
-    jmp         .LOP_INVOKE_STATIC_RANGE_break
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
-/* File: x86-atom/OP_INVOKE_INTERFACE_RANGE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_INTERFACE_RANGE.S
-    */
-
-/* File: x86-atom/OP_INVOKE_INTERFACE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_INTERFACE.S
-    *
-    * Code: Call at method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_interface that allows up to 255 arguments.
-    *
-    * For: invoke-interface, invoke-interface-range
-    *
-    * Description: invoke-interface is used to invoke an interface method; on an
-    *              object whose concrete class isn't known, using a method_id that
-    *              refers to an interface.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    FETCH       1, %ecx                 # %ecx<- method index
-    movl        %ecx, -12(%esp)         # push argument method index
-    .if         (!1)
-    and         $15, %edx              # %edx<- D if not range
-    .endif
-    EXPORT_PC                           # must export for invoke
-    GET_VREG    %edx                    # %edx<- first arg "this pointer"
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_methodClassDex(%eax), %eax # %eax<- glue->pDvmDex
-    movl        %eax, -4(%esp)          # push parameter class
-    cmp         $0, %edx               # check for null object
-    je          common_errNullObject    # handle null object
-    jmp         .LOP_INVOKE_INTERFACE_RANGE_break
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_UNUSED_79: /* 0x79 */
-/* File: x86-atom/OP_UNUSED_79.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_79.S
-    */
-
-/* File: x86-atom/unused.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_UNUSED_7A: /* 0x7a */
-/* File: x86-atom/OP_UNUSED_7A.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_7A.S
-    */
-
-/* File: x86-atom/unused.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_NEG_INT: /* 0x7b */
-/* File: x86-atom/OP_NEG_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEG_INT.S
-    */
-
-/* File: x86-atom/unop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unop.S
-    *
-    * Code: Generic 32-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%ecx = op %edx".
-    *
-    * For: int-to-byte, int-to-char, int-to-short, neg-float, neg-int, not-int
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-                               # do operation part 1
-    neg        %ecx                              # do operation part 2
-    SET_VREG    %ecx, rINST             # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_NOT_INT: /* 0x7c */
-/* File: x86-atom/OP_NOT_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NOT_INT.S
-    */
-
-/* File: x86-atom/unop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unop.S
-    *
-    * Code: Generic 32-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%ecx = op %edx".
-    *
-    * For: int-to-byte, int-to-char, int-to-short, neg-float, neg-int, not-int
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-                               # do operation part 1
-    not        %ecx                              # do operation part 2
-    SET_VREG    %ecx, rINST             # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_NEG_LONG: /* 0x7d */
-/* File: x86-atom/OP_NEG_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEG_LONG.S
-    */
-
-/* File: x86-atom/unopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unopWide.S
-    *
-    * Code: Generic 64-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%xmm0 = op %xmm1".
-    *
-    * For:  neg-double, neg-long, not-long
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, rINST              # rINST<- B
-    and         $15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vB
-    xorps %xmm1, %xmm1                           # do operation part 1
-    psubq %xmm0, %xmm1                              # do operation part 2
-    movq        %xmm1, (rFP, %ecx, 4) # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_NOT_LONG: /* 0x7e */
-/* File: x86-atom/OP_NOT_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NOT_LONG.S
-    */
-
-/* File: x86-atom/unopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unopWide.S
-    *
-    * Code: Generic 64-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%xmm0 = op %xmm1".
-    *
-    * For:  neg-double, neg-long, not-long
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, rINST              # rINST<- B
-    and         $15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vB
-                               # do operation part 1
-    pandn  0xFFFFFFFF, %xmm0                              # do operation part 2
-    movq        %xmm0, (rFP, %ecx, 4) # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_NEG_FLOAT: /* 0x7f */
-/* File: x86-atom/OP_NEG_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEG_FLOAT.S
-    */
-
-/* File: x86-atom/unop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unop.S
-    *
-    * Code: Generic 32-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%ecx = op %edx".
-    *
-    * For: int-to-byte, int-to-char, int-to-short, neg-float, neg-int, not-int
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-                               # do operation part 1
-    addl      $0x80000000, %ecx                              # do operation part 2
-    SET_VREG    %ecx, rINST             # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_NEG_DOUBLE: /* 0x80 */
-/* File: x86-atom/OP_NEG_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEG_DOUBLE.S
-    */
-
-/* File: x86-atom/unopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unopWide.S
-    *
-    * Code: Generic 64-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%xmm0 = op %xmm1".
-    *
-    * For:  neg-double, neg-long, not-long
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, rINST              # rINST<- B
-    and         $15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vB
-    movq .LdoubNeg, %xmm1                           # do operation part 1
-    pxor %xmm1, %xmm0                              # do operation part 2
-    movq        %xmm0, (rFP, %ecx, 4) # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INT_TO_LONG: /* 0x81 */
-/* File: x86-atom/OP_INT_TO_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_LONG.S
-    *
-    * Code:  Convert an int to a long. Uses no substitutions.
-    *
-    * For:
-    *
-    * Description: Convert an int in the source register, to a long, and
-    *              stores the result in the destintation register. vA<- (long) vB
-    *
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %eax             # %eax<- BA+
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %eax               # %eax<- B
-    andl        $15, %ecx              # %ecx<- A
-    GET_VREG    %eax                    # %eax<- vB
-    cdq                                 # %edx:%eax<- sign-extend of %eax
-    movl        %eax, (rFP, %ecx, 4)    # vA<- lo part
-    movl        %edx, 4(rFP, %ecx, 4)   # vA+1<- hi part
-    FINISH      1                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INT_TO_FLOAT: /* 0x82 */
-/* File: x86-atom/OP_INT_TO_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_FLOAT.S
-    *
-    * Code: Convert an int to a float. Uses no substitutions.
-    *
-    * For: int-to-float
-    *
-    * Description: Convert an int in the source register, to a float, and
-    *              stores the result in the destintation register. vA<- (float) vB
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %eax             # %eax<- BA+
-    shr         $4, %eax               # %eax<- B
-    andl        $15,  rINST            # rINST<- A
-    cvtsi2ss    (rFP,%eax,4), %xmm0     # %xmm0<- vB
-    movss       %xmm0, (rFP, rINST, 4)  # vA<- %xmm0
-    FINISH      1                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INT_TO_DOUBLE: /* 0x83 */
-/* File: x86-atom/OP_INT_TO_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_DOUBLE.S
-    *
-    * Code: Convert an int to a double. Uses no substitutions.
-    *
-    * For: int-to-double
-    *
-    * Description: Converts an int in the source register, to a double, and
-    *              stores the result in the destination register. vA<- (double) vB
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %eax             # %eax<- BA+
-    shr         $4, %eax               # %eax<- B
-    andl        $15, rINST             # rINST<- A
-    cvtsi2sd    (rFP, %eax, 4), %xmm0   # %xmm0<- vB
-    movq        %xmm0, (rFP, rINST, 4)  # vA<- %xmm0; (double) vB
-    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_LONG_TO_INT: /* 0x84 */
-/* File: x86-atom/OP_LONG_TO_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_LONG_TO_INT.S
-    */
-
-/* File: x86-atom/OP_MOVE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE.S
-    *
-    * Code: Copies contents from one register to another. Uses no
-    *       substitutions.
-    *
-    * For: move, move-object, long-to-int
-    *
-    * Description: Copies contents from one non-object register to another.
-    *              vA<- vB; fp[A]<- fp[B]
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, rINST              # rINST<- B
-    and         $15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vB
-    SET_VREG    rINST, %ecx             # vA<- vB; %edx
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_LONG_TO_FLOAT: /* 0x85 */
-/* File: x86-atom/OP_LONG_TO_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_LONG_TO_FLOAT.S
-    *
-    * Code: Convert a long to a float. Uses no substitutions.
-    *
-    * For: int-to-float
-    *
-    * Description: Converts a float in the source register, to a float, and
-    *              stores the result in the destination register. vA<- (double) vB
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, rINST              # rINST<- B
-    and         $15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    fildll      (rFP, rINST, 4)         # FPU<- vB
-    fstps       (rFP, %ecx, 4)          # vA<- FPU; (float) vB
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_LONG_TO_DOUBLE: /* 0x86 */
-/* File: x86-atom/OP_LONG_TO_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_LONG_TO_DOUBLE.S
-    *
-    * Code: Convert a long to a dobule. Uses no substitutions.
-    *
-    * For: long-to-double
-    *
-    * Description: Converts a long in the source register to a double, and
-    *              stores the result in the destination register. vA<- (double) vB
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, rINST              # rINST<- B
-    and         $15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    fildll      (rFP, rINST, 4)         # FPU<- vB
-    fstpl       (rFP, %ecx, 4)          # vA<- FPU; (double) vB
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_FLOAT_TO_INT: /* 0x87 */
-/* File: x86-atom/OP_FLOAT_TO_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FLOAT_TO_INT.S
-    *
-    * Code: Converts a float to a int. Uses no substitutions.
-    *
-    * For: float-to-int
-    *
-    * Description: Convert the float in source register to a int
-    *              and store the result in the destintation register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    and         $15, %edx              # %edx<- A
-    flds        (rFP, rINST, 4)         # push vB to floating point stack
-    fildl       .LintMax                # push max int value
-    fildl       .LintMin                # push min int value
-    fucomip     %st(2), %st(0)          # check for negInf
-    jae         .LOP_FLOAT_TO_INT_negInf      # handle negInf
-    fucomip     %st(1), %st(0)          # check for posInf or NaN
-    jc          .LOP_FLOAT_TO_INT_nanInf      # handle posInf or NaN
-    jmp         .LOP_FLOAT_TO_INT_break       # do conversion
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_FLOAT_TO_LONG: /* 0x88 */
-/* File: x86-atom/OP_FLOAT_TO_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FLOAT_TO_LONG.S
-    *
-    * Code: Converts a float to a long. Uses no substitutions.
-    *
-    * For: float-to-long
-    *
-    * Description: Convert the float in source register to a long
-    *              and store the result in the destintation register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    and         $15, %edx              # %edx<- A
-    flds        (rFP, rINST, 4)         # push vB to floating point stack
-    fildll      .LvaluePosInfLong       # push max int value
-    fildll      .LvalueNegInfLong       # push min int value
-    fucomip     %st(2), %st(0)          # check for negInf
-    jae         .LOP_FLOAT_TO_LONG_negInf      # handle negInf
-    fucomip     %st(1), %st(0)          # check for posInf or NaN
-    jc          .LOP_FLOAT_TO_LONG_nanInf      # handle posInf or NaN
-    jmp         .LOP_FLOAT_TO_LONG_break       # do conversion
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
-/* File: x86-atom/OP_FLOAT_TO_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FLOAT_TO_DOUBLE.S
-    *
-    * Code: Converts a float to a double. Uses no substitutions.
-    *
-    * For: float-to-double
-    *
-    * Description: Convert the float in source register to a double
-    *              and store the result in the destintation register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    and         $15, %edx              # %edx<- A
-    flds        (rFP, rINST, 4)         # load float
-    fstpl       (rFP, %edx, 4)          # store double
-    FINISH      1                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DOUBLE_TO_INT: /* 0x8a */
-/* File: x86-atom/OP_DOUBLE_TO_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DOUBLE_TO_INT.S
-    *
-    * Code: Converts a double to an integer. Uses no substitutions.
-    *
-    * For: double-to-int
-    *
-    * Description: Convert the source register (a double) to an integer
-    *              and store the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    and         $15, %edx              # %edx<- A
-    fldl        (rFP, rINST, 4)         # load &vB
-    fildl       .LintMax                # push max int value
-    fildl       .LintMin                # push min int value
-    fucomip     %st(2), %st(0)          # check for negInf
-    jae         .LOP_DOUBLE_TO_INT_negInf      # handle negInf
-    fucomip     %st(1), %st(0)          # check for posInf or NaN
-    jc          .LOP_DOUBLE_TO_INT_nanInf      # handle posInf or NaN
-    jmp         .LOP_DOUBLE_TO_INT_break       # do conversion
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DOUBLE_TO_LONG: /* 0x8b */
-/* File: x86-atom/OP_DOUBLE_TO_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DOUBLE_TO_LONG.S
-    *
-    * Code: Converts a double to a long. Uses no substitutions.
-    *
-    * For: double-to-long
-    *
-    * Description: Convert the double in source register to a long
-    *              and store in the destintation register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %ecx<- BA
-    shr         $4, rINST              # rINST<- B
-    and         $15, %edx              # %ecx<- A
-    fldl        (rFP, rINST, 4)         # push vB to floating point stack
-    fildll      .LvaluePosInfLong       # push max int value
-    fildll      .LvalueNegInfLong       # push min int value
-    fucomip     %st(2), %st(0)          # check for negInf
-    jae         .LOP_DOUBLE_TO_LONG_negInf      # handle negInf
-    fucomip     %st(1), %st(0)          # check for posInf or NaN
-    jc          .LOP_DOUBLE_TO_LONG_nanInf      # handle posInf or NaN
-    jmp         .LOP_DOUBLE_TO_LONG_break       # do conversion
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
-/* File: x86-atom/OP_DOUBLE_TO_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DOUBLE_TO_FLOAT.S
-    *
-    * Code: Converts a double to a float. Uses no substitutions.
-    *
-    * For: double-to-float
-    *
-    * Description: Convert the source register (a double) to a float
-    *              and store the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    and         $15, %edx              # %edx<- A
-    fldl        (rFP, rINST, 4)         # load &vB
-    fstps       (rFP, %edx, 4)          # store float
-    FINISH      1                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INT_TO_BYTE: /* 0x8d */
-/* File: x86-atom/OP_INT_TO_BYTE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_BYTE.S
-    */
-
-/* File: x86-atom/unop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unop.S
-    *
-    * Code: Generic 32-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%ecx = op %edx".
-    *
-    * For: int-to-byte, int-to-char, int-to-short, neg-float, neg-int, not-int
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    sal $24, %ecx                           # do operation part 1
-    sar $24, %ecx                              # do operation part 2
-    SET_VREG    %ecx, rINST             # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INT_TO_CHAR: /* 0x8e */
-/* File: x86-atom/OP_INT_TO_CHAR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_CHAR.S
-    */
-
-/* File: x86-atom/unop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unop.S
-    *
-    * Code: Generic 32-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%ecx = op %edx".
-    *
-    * For: int-to-byte, int-to-char, int-to-short, neg-float, neg-int, not-int
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    sal $16, %ecx                           # do operation part 1
-    shr $16, %ecx                              # do operation part 2
-    SET_VREG    %ecx, rINST             # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INT_TO_SHORT: /* 0x8f */
-/* File: x86-atom/OP_INT_TO_SHORT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_SHORT.S
-    */
-
-/* File: x86-atom/unop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unop.S
-    *
-    * Code: Generic 32-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%ecx = op %edx".
-    *
-    * For: int-to-byte, int-to-char, int-to-short, neg-float, neg-int, not-int
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    sal $16, %ecx                           # do operation part 1
-    sar $16, %ecx                              # do operation part 2
-    SET_VREG    %ecx, rINST             # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ADD_INT: /* 0x90 */
-/* File: x86-atom/OP_ADD_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_INT.S
-    */
-
-/* File: x86-atom/binop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    * For: add-int, and-int, mul-int, or-int, sub-int, xor-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    addl     %edx, %ecx                              # %ecx<- vBB op vCC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SUB_INT: /* 0x91 */
-/* File: x86-atom/OP_SUB_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_INT.S
-    */
-
-/* File: x86-atom/binop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    * For: add-int, and-int, mul-int, or-int, sub-int, xor-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    subl     %edx, %ecx                              # %ecx<- vBB op vCC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MUL_INT: /* 0x92 */
-/* File: x86-atom/OP_MUL_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_INT.S
-    */
-
-/* File: x86-atom/binop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    * For: add-int, and-int, mul-int, or-int, sub-int, xor-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    imul     %edx, %ecx                              # %ecx<- vBB op vCC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DIV_INT: /* 0x93 */
-/* File: x86-atom/OP_DIV_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_INT.S
-    */
-
-/* File: x86-atom/binopD.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopD.S
-    *
-    * Code: 32-bit integer divide operation. If "div" is set, the code
-    *       returns the quotient, else it returns the remainder.
-    *       Also, a divide-by-zero check is done.
-    *
-    * For: div-int, rem-int
-    *
-    * Description: Perform a binary operation on two source
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %eax                 # %eax<- BB
-    FETCH_CC    1, %ecx                 # %ecx<- CC
-    GET_VREG    %eax                    # %eax<- vBB
-    GET_VREG    %ecx                    # %ecx<- vCC
-    cmp         $0, %ecx               # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    cmpl        $-1, %ecx              # handle -1 special case divide error
-    jne         .LOP_DIV_INT_noerror
-    cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je         .LOP_DIV_INT_break
-.LOP_DIV_INT_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-    .if  1
-    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    .endif
-    jmp         .LOP_DIV_INT_break2
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_REM_INT: /* 0x94 */
-/* File: x86-atom/OP_REM_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_INT.S
-    */
-
-/* File: x86-atom/binopD.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopD.S
-    *
-    * Code: 32-bit integer divide operation. If "div" is set, the code
-    *       returns the quotient, else it returns the remainder.
-    *       Also, a divide-by-zero check is done.
-    *
-    * For: div-int, rem-int
-    *
-    * Description: Perform a binary operation on two source
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_BB    1, %eax                 # %eax<- BB
-    FETCH_CC    1, %ecx                 # %ecx<- CC
-    GET_VREG    %eax                    # %eax<- vBB
-    GET_VREG    %ecx                    # %ecx<- vCC
-    cmp         $0, %ecx               # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    cmpl        $-1, %ecx              # handle -1 special case divide error
-    jne         .LOP_REM_INT_noerror
-    cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je         .LOP_REM_INT_break
-.LOP_REM_INT_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-    .if  0
-    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    .endif
-    jmp         .LOP_REM_INT_break2
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AND_INT: /* 0x95 */
-/* File: x86-atom/OP_AND_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_INT.S
-    */
-
-/* File: x86-atom/binop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    * For: add-int, and-int, mul-int, or-int, sub-int, xor-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    andl     %edx, %ecx                              # %ecx<- vBB op vCC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_OR_INT: /* 0x96 */
-/* File: x86-atom/OP_OR_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_INT.S
-    */
-
-/* File: x86-atom/binop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    * For: add-int, and-int, mul-int, or-int, sub-int, xor-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    or %edx, %ecx                              # %ecx<- vBB op vCC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_XOR_INT: /* 0x97 */
-/* File: x86-atom/OP_XOR_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_INT.S
-    */
-
-/* File: x86-atom/binop.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    * For: add-int, and-int, mul-int, or-int, sub-int, xor-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    xor     %edx, %ecx                              # %ecx<- vBB op vCC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SHL_INT: /* 0x98 */
-/* File: x86-atom/OP_SHL_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHL_INT.S
-    */
-
-/* File: x86-atom/binopS.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopS.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%edx = %edx op %cl"
-    *
-    * For: shl-int, shr-int, ushr-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %edx                 # %edx<- BB
-    FETCH_CC    1, %ecx                 # %ecx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vBB
-    GET_VREG    %ecx                    # %ecx<- vCC
-    sal     %cl, %edx                              # %edx<- vBB op +CC
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SHR_INT: /* 0x99 */
-/* File: x86-atom/OP_SHR_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHR_INT.S
-    */
-
-/* File: x86-atom/binopS.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopS.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%edx = %edx op %cl"
-    *
-    * For: shl-int, shr-int, ushr-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %edx                 # %edx<- BB
-    FETCH_CC    1, %ecx                 # %ecx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vBB
-    GET_VREG    %ecx                    # %ecx<- vCC
-    sar     %cl, %edx                              # %edx<- vBB op +CC
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_USHR_INT: /* 0x9a */
-/* File: x86-atom/OP_USHR_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_USHR_INT.S
-    */
-
-/* File: x86-atom/binopS.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopS.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%edx = %edx op %cl"
-    *
-    * For: shl-int, shr-int, ushr-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %edx                 # %edx<- BB
-    FETCH_CC    1, %ecx                 # %ecx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vBB
-    GET_VREG    %ecx                    # %ecx<- vCC
-    shr     %cl, %edx                              # %edx<- vBB op +CC
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ADD_LONG: /* 0x9b */
-/* File: x86-atom/OP_ADD_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_LONG.S
-    */
-
-/* File: x86-atom/binopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide.S
-    *
-    * Code: Generic 64-bit binary operation.  Provides an "instr" variable to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-double, add-long, and-long, mul-double, or-long,
-    *      sub-double, sub-long, xor-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    paddq   %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SUB_LONG: /* 0x9c */
-/* File: x86-atom/OP_SUB_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_LONG.S
-    */
-
-/* File: x86-atom/binopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide.S
-    *
-    * Code: Generic 64-bit binary operation.  Provides an "instr" variable to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-double, add-long, and-long, mul-double, or-long,
-    *      sub-double, sub-long, xor-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    psubq    %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MUL_LONG: /* 0x9d */
-/* File: x86-atom/OP_MUL_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_LONG.S
-    *
-    * Code: 64-bit integer multiply
-    *
-    * For: mul-long
-    *
-    * Description: Multiply two source registers and store the
-    *              result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-   /*
-    * Signed 64-bit integer multiply.
-    *
-    * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
-    *        WX
-    *      x YZ
-    *  --------
-    *     ZW ZX
-    *  YW YX
-    *
-    * The low word of the result holds ZX, the high word holds
-    * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
-    * it doesn't fit in the low 64 bits.
-    */
-
-    movl        rINST, -4(%esp)         # -4(%esp)<- AA+
-    FETCH_BB    1, rINST                # rINST<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    jmp         .LOP_MUL_LONG_finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DIV_LONG: /* 0x9e */
-/* File: x86-atom/OP_DIV_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_LONG.S
-    */
-
-/* File: x86-atom/binopDivRemLong.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDivRemLong.S
-    *
-    * Code: 64-bit long divide operation. Variable
-    *       "func" defines the function called to do the operation.
-    *
-    * For: div-long, rem-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_CC    1, %edx                 # %edx<- CC
-    movl        (rFP, %edx, 4), %eax    # %eax<- vCC
-    movl        4(rFP, %edx, 4), %ecx   # %ecx<- vCC+1
-    movl        %eax, -8(%esp)          # push arg vCC
-    or          %ecx, %eax              # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    FETCH_BB    1, %edx                 # %edx<- BB
-    movl        %ecx, -4(%esp)          # push arg vCC+1
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vBB,vBB+1
-    jmp         .LOP_DIV_LONG_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_REM_LONG: /* 0x9f */
-/* File: x86-atom/OP_REM_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_LONG.S
-    */
-
-/* File: x86-atom/binopDivRemLong.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDivRemLong.S
-    *
-    * Code: 64-bit long divide operation. Variable
-    *       "func" defines the function called to do the operation.
-    *
-    * For: div-long, rem-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-
-    FETCH_CC    1, %edx                 # %edx<- CC
-    movl        (rFP, %edx, 4), %eax    # %eax<- vCC
-    movl        4(rFP, %edx, 4), %ecx   # %ecx<- vCC+1
-    movl        %eax, -8(%esp)          # push arg vCC
-    or          %ecx, %eax              # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    FETCH_BB    1, %edx                 # %edx<- BB
-    movl        %ecx, -4(%esp)          # push arg vCC+1
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vBB,vBB+1
-    jmp         .LOP_REM_LONG_finish
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AND_LONG: /* 0xa0 */
-/* File: x86-atom/OP_AND_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_LONG.S
-    */
-
-/* File: x86-atom/binopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide.S
-    *
-    * Code: Generic 64-bit binary operation.  Provides an "instr" variable to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-double, add-long, and-long, mul-double, or-long,
-    *      sub-double, sub-long, xor-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    pand   %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_OR_LONG: /* 0xa1 */
-/* File: x86-atom/OP_OR_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_LONG.S
-    */
-
-/* File: x86-atom/binopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide.S
-    *
-    * Code: Generic 64-bit binary operation.  Provides an "instr" variable to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-double, add-long, and-long, mul-double, or-long,
-    *      sub-double, sub-long, xor-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    por %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_XOR_LONG: /* 0xa2 */
-/* File: x86-atom/OP_XOR_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_LONG.S
-    */
-
-/* File: x86-atom/binopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide.S
-    *
-    * Code: Generic 64-bit binary operation.  Provides an "instr" variable to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-double, add-long, and-long, mul-double, or-long,
-    *      sub-double, sub-long, xor-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    pxor   %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SHL_LONG: /* 0xa3 */
-/* File: x86-atom/OP_SHL_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHL_LONG.S
-    *
-    * Code: Performs a shift left long. Uses no substitutions.
-    *
-    * For: shl-long
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where one is the shift amount and the other is the value to shift.
-    *              Store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_CC    1, %eax                 # %eax<- CC
-    FETCH_BB    1, %edx                 # %edx<- BB
-    movq        .LshiftMask, %xmm2      # %xmm2<- mask for the shift bits
-    movss       (rFP, %eax, 4), %xmm0   # %xmm0<- vCC
-    pand        %xmm2, %xmm0            # %xmm0<- masked shift bits
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vBB
-    psllq       %xmm0, %xmm1            # %xmm1<- shifted vBB
-    movq        %xmm1, (rFP, rINST, 4)  # vAA<- shifted vBB
-    FINISH      2                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SHR_LONG: /* 0xa4 */
-/* File: x86-atom/OP_SHR_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHR_LONG.S
-    *
-    * Code: Performs a shift right long
-    *
-    * For: shl-long
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where one is the shift amount and the other is the value to shift.
-    *              Store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %edx                 # %edx<- BB
-    FETCH_CC    1, %eax                 # %eax<- CC
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vBB
-    movss       (rFP, %eax, 4), %xmm0   # %xmm0<- vCC
-    movq        .LshiftMask, %xmm2
-    pand        %xmm2, %xmm0            # %xmm0<- masked for the shift bits
-    psrlq       %xmm0, %xmm1            # %xmm1<- shifted vBB
-    cmpl        $0, 4(rFP, %edx, 4)    # check if we need to consider sign
-    jl          .LOP_SHR_LONG_finish      # consider sign
-    jmp         .LOP_SHR_LONG_final       # sign is fine, finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_USHR_LONG: /* 0xa5 */
-/* File: x86-atom/OP_USHR_LONG.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_USHR_LONG.S
-    *
-    * Code: Performs an unsigned shift right long operation. Uses no substitutions.
-    *
-    * For: ushr-long
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where one is the shift amount and the other is the value to shift.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_CC    1, %eax                 # %eax<- CC
-    FETCH_BB    1, %edx                 # %edx<- BB
-    movsd        .LshiftMask, %xmm2     # %xmm2<- mask for the shift bits
-    movss       (rFP, %eax, 4), %xmm0   # %xmm0<- vCC
-    pand        %xmm2, %xmm0            # %xmm0<- masked shift bits
-    movsd       (rFP, %edx, 4), %xmm1   # %xmm1<- vBB
-    psrlq       %xmm0, %xmm1            # %xmm1<- shifted vBB
-    movsd       %xmm1, (rFP, rINST, 4)  # vAA<- shifted vBB
-    FINISH      2                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ADD_FLOAT: /* 0xa6 */
-/* File: x86-atom/OP_ADD_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_FLOAT.S
-    */
-
-/* File: x86-atom/binopF.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopF.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-float, mul-float, sub-float
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movss       (rFP, %ecx, 4), %xmm0   # %xmm0<-vBB
-    movss       (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    addss     %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movss       %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SUB_FLOAT: /* 0xa7 */
-/* File: x86-atom/OP_SUB_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_FLOAT.S
-    */
-
-/* File: x86-atom/binopF.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopF.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-float, mul-float, sub-float
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movss       (rFP, %ecx, 4), %xmm0   # %xmm0<-vBB
-    movss       (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    subss     %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movss       %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MUL_FLOAT: /* 0xa8 */
-/* File: x86-atom/OP_MUL_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_FLOAT.S
-    */
-
-/* File: x86-atom/binopF.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopF.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-float, mul-float, sub-float
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movss       (rFP, %ecx, 4), %xmm0   # %xmm0<-vBB
-    movss       (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    mulss %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movss       %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DIV_FLOAT: /* 0xa9 */
-/* File: x86-atom/OP_DIV_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_FLOAT.S
-    *
-    * Code: Divides floats. Uses no substitutions.
-    *
-    * For: div-float
-    *
-    * Description: Divide operation on two source registers, storing
-    *              the result in a destiniation register
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %eax                 # %eax<- BB
-    FETCH_CC    1, %ecx                 # %ecx<- CC
-    flds        (rFP, %eax, 4)          # floating point stack vBB
-    fdivs       (rFP, %ecx, 4)          # divide double; vBB/vCC
-    fstps       (rFP, rINST, 4)         # vAA<- result
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_REM_FLOAT: /* 0xaa */
-/* File: x86-atom/OP_REM_FLOAT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_FLOAT.S
-    *
-    * Code: Computes the remainder of a division. Performs no substitutions.
-    *
-    * For: rem-float
-    *
-    * Description: Calls fmod to compute the remainder of the result of dividing a
-    *              source register by a second, and stores the result in a
-    *              destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    movl        %ecx, -8(%esp)          # push parameter float
-    movl        %edx, -4(%esp)          # push parameter float
-    lea         -8(%esp), %esp
-    call        fmodf                   # call: (float x, float y)
-                                        # return: float
-    lea         8(%esp), %esp
-    fstps       (rFP, rINST, 4)         # vAA<- remainder; return of fmod
-    FINISH      2                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ADD_DOUBLE: /* 0xab */
-/* File: x86-atom/OP_ADD_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_DOUBLE.S
-    */
-
-/* File: x86-atom/binopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide.S
-    *
-    * Code: Generic 64-bit binary operation.  Provides an "instr" variable to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-double, add-long, and-long, mul-double, or-long,
-    *      sub-double, sub-long, xor-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    addsd   %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SUB_DOUBLE: /* 0xac */
-/* File: x86-atom/OP_SUB_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_DOUBLE.S
-    */
-
-/* File: x86-atom/binopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide.S
-    *
-    * Code: Generic 64-bit binary operation.  Provides an "instr" variable to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-double, add-long, and-long, mul-double, or-long,
-    *      sub-double, sub-long, xor-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    subsd   %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MUL_DOUBLE: /* 0xad */
-/* File: x86-atom/OP_MUL_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_DOUBLE.S
-    */
-
-/* File: x86-atom/binopWide.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide.S
-    *
-    * Code: Generic 64-bit binary operation.  Provides an "instr" variable to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-double, add-long, and-long, mul-double, or-long,
-    *      sub-double, sub-long, xor-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    mulsd   %xmm1, %xmm0                              # %xmm0<- vBB op vCC
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DIV_DOUBLE: /* 0xae */
-/* File: x86-atom/OP_DIV_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_DOUBLE.S
-    *
-    * Code: Divides doubles. Uses no substitutions.
-    *
-    * For: div-double
-    *
-    * Description: Divide operation on two source registers, storing
-    *              the result in a destination register
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    fldl        (rFP, %ecx, 4)          # floating point stack vBB
-    fdivl       (rFP, %edx, 4)          # divide double; vBB/vCC
-    fstpl       (rFP, rINST, 4)         # vAA<- result
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_REM_DOUBLE: /* 0xaf */
-/* File: x86-atom/OP_REM_DOUBLE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_DOUBLE.S
-    *
-    * Code: Computes the remainder of a division. Performs no substitutions.
-    *
-    * For: rem-double
-    *
-    * Description: Calls fmod to compute the remainder of the result of dividing a
-    *              source register by a second, and stores the result in a
-    *              destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    movl        (rFP, %ecx, 4), %eax    # %eax<- vBBlo
-    movl        %eax, -16(%esp)         # push parameter double lo
-    movl        4(rFP, %ecx, 4), %eax   # %eax<- vBBhi
-    movl        %eax, -12(%esp)         # push parameter double hi
-    movl        (rFP, %edx, 4), %eax    # %eax<- vCClo
-    movl        %eax, -8(%esp)          # push parameter double lo
-    movl        4(rFP, %edx, 4), %eax   # %eax<- vCChi
-    movl        %eax, -4(%esp)          # push parameter double hi
-    lea         -16(%esp), %esp
-    jmp         .LOP_REM_DOUBLE_break
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ADD_INT_2ADDR: /* 0xb0 */
-/* File: x86-atom/OP_ADD_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binop2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%ecx = %ecx op %edx".
-    *
-    * For: add-int/2addr, and-int/2addr, mul-int/2addr, or-int/2addr,
-    *      sub-int/2addr, xor-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    movl        rINST, %ecx             # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    GET_VREG    %ecx                    # %ecx<- vA
-    addl     %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SUB_INT_2ADDR: /* 0xb1 */
-/* File: x86-atom/OP_SUB_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binop2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%ecx = %ecx op %edx".
-    *
-    * For: add-int/2addr, and-int/2addr, mul-int/2addr, or-int/2addr,
-    *      sub-int/2addr, xor-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    movl        rINST, %ecx             # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    GET_VREG    %ecx                    # %ecx<- vA
-    subl     %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MUL_INT_2ADDR: /* 0xb2 */
-/* File: x86-atom/OP_MUL_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binop2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%ecx = %ecx op %edx".
-    *
-    * For: add-int/2addr, and-int/2addr, mul-int/2addr, or-int/2addr,
-    *      sub-int/2addr, xor-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    movl        rINST, %ecx             # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    GET_VREG    %ecx                    # %ecx<- vA
-    imul     %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DIV_INT_2ADDR: /* 0xb3 */
-/* File: x86-atom/OP_DIV_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binopD2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopD2addr.S
-    *
-    * Code: 32-bit "/2addr" integer divde operation. If "div"
-    *       is set, the code returns the quotient, else it returns
-    *       the remainder. Also, a divide-by-zero check is done.
-    *
-    * For: div-int/2addr, rem-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    andl        $15, rINST             # rINST<- A, to be used as dest
-    movl        rINST, %eax             # %eax<- A
-    shr         $4, %ecx               # %ecx<- B
-    GET_VREG    %eax                    # %eax<- vA
-    GET_VREG    %ecx                    # %edx<- vB
-    cmp         $0, %ecx               # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    cmpl        $-1, %ecx              # handle -1 special case divide error
-    jne         .LOP_DIV_INT_2ADDR_noerror
-    cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je         .LOP_DIV_INT_2ADDR_break
-.LOP_DIV_INT_2ADDR_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-     .if  1
-    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    .endif
-    jmp         .LOP_DIV_INT_2ADDR_break2
-    #FFETCH_ADV 1, %edx  # %ecx<- next instruction hi; fetch, advance
-    #FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_REM_INT_2ADDR: /* 0xb4 */
-/* File: x86-atom/OP_REM_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binopD2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopD2addr.S
-    *
-    * Code: 32-bit "/2addr" integer divde operation. If "div"
-    *       is set, the code returns the quotient, else it returns
-    *       the remainder. Also, a divide-by-zero check is done.
-    *
-    * For: div-int/2addr, rem-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    andl        $15, rINST             # rINST<- A, to be used as dest
-    movl        rINST, %eax             # %eax<- A
-    shr         $4, %ecx               # %ecx<- B
-    GET_VREG    %eax                    # %eax<- vA
-    GET_VREG    %ecx                    # %edx<- vB
-    cmp         $0, %ecx               # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    cmpl        $-1, %ecx              # handle -1 special case divide error
-    jne         .LOP_REM_INT_2ADDR_noerror
-    cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je         .LOP_REM_INT_2ADDR_break
-.LOP_REM_INT_2ADDR_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-     .if  0
-    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    .endif
-    jmp         .LOP_REM_INT_2ADDR_break2
-    #FFETCH_ADV 1, %edx  # %ecx<- next instruction hi; fetch, advance
-    #FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AND_INT_2ADDR: /* 0xb5 */
-/* File: x86-atom/OP_AND_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binop2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%ecx = %ecx op %edx".
-    *
-    * For: add-int/2addr, and-int/2addr, mul-int/2addr, or-int/2addr,
-    *      sub-int/2addr, xor-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    movl        rINST, %ecx             # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    GET_VREG    %ecx                    # %ecx<- vA
-    andl     %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_OR_INT_2ADDR: /* 0xb6 */
-/* File: x86-atom/OP_OR_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binop2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%ecx = %ecx op %edx".
-    *
-    * For: add-int/2addr, and-int/2addr, mul-int/2addr, or-int/2addr,
-    *      sub-int/2addr, xor-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    movl        rINST, %ecx             # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    GET_VREG    %ecx                    # %ecx<- vA
-    or %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_XOR_INT_2ADDR: /* 0xb7 */
-/* File: x86-atom/OP_XOR_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binop2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%ecx = %ecx op %edx".
-    *
-    * For: add-int/2addr, and-int/2addr, mul-int/2addr, or-int/2addr,
-    *      sub-int/2addr, xor-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    movl        rINST, %ecx             # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    GET_VREG    %ecx                    # %ecx<- vA
-    xor     %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SHL_INT_2ADDR: /* 0xb8 */
-/* File: x86-atom/OP_SHL_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHL_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binopS2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopS2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%edx = %edx op %cl".
-    *
-    * For: shl-int/2addr, shr-int/2addr, ushr-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    andl        $15, rINST             # rINST<- A
-    movl        rINST, %edx             # %edx<- A
-    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    GET_VREG    %edx                    # %edx<- vA
-    sal     %cl, %edx                              # %edx<- vA op vB
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SHR_INT_2ADDR: /* 0xb9 */
-/* File: x86-atom/OP_SHR_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHR_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binopS2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopS2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%edx = %edx op %cl".
-    *
-    * For: shl-int/2addr, shr-int/2addr, ushr-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    andl        $15, rINST             # rINST<- A
-    movl        rINST, %edx             # %edx<- A
-    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    GET_VREG    %edx                    # %edx<- vA
-    sar     %cl, %edx                              # %edx<- vA op vB
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_USHR_INT_2ADDR: /* 0xba */
-/* File: x86-atom/OP_USHR_INT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_USHR_INT_2ADDR.S
-    */
-
-/* File: x86-atom/binopS2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopS2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%edx = %edx op %cl".
-    *
-    * For: shl-int/2addr, shr-int/2addr, ushr-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    andl        $15, rINST             # rINST<- A
-    movl        rINST, %edx             # %edx<- A
-    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    GET_VREG    %edx                    # %edx<- vA
-    shr     %cl, %edx                              # %edx<- vA op vB
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ADD_LONG_2ADDR: /* 0xbb */
-/* File: x86-atom/OP_ADD_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_LONG_2ADDR.S
-    */
-
-/* File: x86-atom/binopWide2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide2addr.S
-    *
-    * Code: Generic 64-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0= %xmm0 op %xmm1".
-    *
-    * For: add-double/2addr, add-long/2addr, and-long/2addr, mul-long/2addr,
-    *      or-long/2addr, sub-double/2addr, sub-long/2addr, xor-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    andl        $15, %edx              # %edx<- A
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
-    paddq   %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    FINISH      1                       # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SUB_LONG_2ADDR: /* 0xbc */
-/* File: x86-atom/OP_SUB_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_LONG_2ADDR.S
-    */
-
-/* File: x86-atom/binopWide2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide2addr.S
-    *
-    * Code: Generic 64-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0= %xmm0 op %xmm1".
-    *
-    * For: add-double/2addr, add-long/2addr, and-long/2addr, mul-long/2addr,
-    *      or-long/2addr, sub-double/2addr, sub-long/2addr, xor-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    andl        $15, %edx              # %edx<- A
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
-    psubq    %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    FINISH      1                       # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MUL_LONG_2ADDR: /* 0xbd */
-/* File: x86-atom/OP_MUL_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_LONG_2ADDR.S
-    *
-    * Code:  64-bit integer multiply
-    *
-    * For: mul-long/2addr
-    *
-    * Description: Multiply two sources registers and store the result
-    *              in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-   /*
-    * Signed 64-bit integer multiply.
-    *
-    * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
-    *        WX
-    *      x YZ
-    *  --------
-    *     ZW ZX
-    *  YW YX
-    *
-    * The low word of the result holds ZX, the high word holds
-    * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
-    * it doesn't fit in the low 64 bits.
-    */
-
-    movl        rINST, %edx             # %edx<- BA+
-    shr         $4, rINST              # rINST<- B
-    andl        $15, %edx              # %edx<- A
-    movl        %edx, sReg0             # sReg0<- A
-    jmp         .LOP_MUL_LONG_2ADDR_finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DIV_LONG_2ADDR: /* 0xbe */
-/* File: x86-atom/OP_DIV_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_LONG_2ADDR.S
-    */
-
-/* File: x86-atom/binopDivRemLong2Addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDivRemLong2Addr.S
-    *
-    * Code: 64-bit "/2addr" long divide operation. Variable
-    *       "func" defines the function called to do the operation.
-    *
-    * For: div-long/2addr, rem-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    and         $15, rINST             # rINST<- A
-    movl        (rFP, %edx, 4), %eax    # %eax<- vB
-    movl        %eax, -12(%esp)         # push arg vB
-    movl        4(rFP, %edx, 4), %ecx   # %ecx<- vB+1
-    or          %ecx, %eax              # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    movl        %ecx, -8(%esp)          # push arg vB+1
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vA,vA+1
-    jmp         .LOP_DIV_LONG_2ADDR_break
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_REM_LONG_2ADDR: /* 0xbf */
-/* File: x86-atom/OP_REM_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_LONG_2ADDR.S
-    */
-
-/* File: x86-atom/binopDivRemLong2Addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDivRemLong2Addr.S
-    *
-    * Code: 64-bit "/2addr" long divide operation. Variable
-    *       "func" defines the function called to do the operation.
-    *
-    * For: div-long/2addr, rem-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    and         $15, rINST             # rINST<- A
-    movl        (rFP, %edx, 4), %eax    # %eax<- vB
-    movl        %eax, -12(%esp)         # push arg vB
-    movl        4(rFP, %edx, 4), %ecx   # %ecx<- vB+1
-    or          %ecx, %eax              # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    movl        %ecx, -8(%esp)          # push arg vB+1
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vA,vA+1
-    jmp         .LOP_REM_LONG_2ADDR_break
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AND_LONG_2ADDR: /* 0xc0 */
-/* File: x86-atom/OP_AND_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_LONG_2ADDR.S
-    */
-
-/* File: x86-atom/binopWide2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide2addr.S
-    *
-    * Code: Generic 64-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0= %xmm0 op %xmm1".
-    *
-    * For: add-double/2addr, add-long/2addr, and-long/2addr, mul-long/2addr,
-    *      or-long/2addr, sub-double/2addr, sub-long/2addr, xor-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    andl        $15, %edx              # %edx<- A
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
-    pand   %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    FINISH      1                       # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_OR_LONG_2ADDR: /* 0xc1 */
-/* File: x86-atom/OP_OR_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_LONG_2ADDR.S
-    */
-
-/* File: x86-atom/binopWide2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide2addr.S
-    *
-    * Code: Generic 64-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0= %xmm0 op %xmm1".
-    *
-    * For: add-double/2addr, add-long/2addr, and-long/2addr, mul-long/2addr,
-    *      or-long/2addr, sub-double/2addr, sub-long/2addr, xor-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    andl        $15, %edx              # %edx<- A
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
-    por %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    FINISH      1                       # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
-/* File: x86-atom/OP_XOR_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_LONG_2ADDR.S
-    */
-
-/* File: x86-atom/binopWide2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide2addr.S
-    *
-    * Code: Generic 64-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0= %xmm0 op %xmm1".
-    *
-    * For: add-double/2addr, add-long/2addr, and-long/2addr, mul-long/2addr,
-    *      or-long/2addr, sub-double/2addr, sub-long/2addr, xor-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    andl        $15, %edx              # %edx<- A
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
-    pxor   %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    FINISH      1                       # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
-/* File: x86-atom/OP_SHL_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHL_LONG_2ADDR.S
-    *
-    * Code: Performs a shift left long. Uses no substitutions.
-    *
-    * For: shl-long/2addr
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where the fist is the value to shift and the second is the
-    *              shift amount. Store the result in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    movss       (rFP, %edx, 4),  %xmm0  # %xmm0<- vB
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vA
-    movq        .LshiftMask, %xmm2      # %xmm2<- mask for the shift bits
-    pand        %xmm2, %xmm0            # %xmm0<- masked shift bits
-    psllq       %xmm0, %xmm1            # %xmm1<- shifted vA
-    movq        %xmm1, (rFP, rINST, 4)  # vA<- shifted vA
-    FINISH      1                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
-/* File: x86-atom/OP_SHR_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHR_LONG_2ADDR.S
-    *
-    * Code: Performs a shift left long
-    *
-    * For: shl-long/2addr
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where the fist is the value to shift and the second is the
-    *              shift amount. Store the result in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- BA
-    movss       (rFP, %edx, 4),  %xmm0  # %xmm0<- vB
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vA
-    movq        .LshiftMask, %xmm2
-    pand        %xmm2, %xmm0            # %xmm0<- masked for the shift bits
-    psrlq       %xmm0, %xmm1            # %xmm1<- shifted vBB
-    cmpl        $0, 4(rFP, rINST, 4)   # check if we need to consider sign
-    jl          .LOP_SHR_LONG_2ADDR_finish      # consider sign
-    jmp         .LOP_SHR_LONG_2ADDR_final       # sign is fine, finish
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
-/* File: x86-atom/OP_USHR_LONG_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_USHR_LONG_2ADDR.S
-    *
-    * Code: Performs an unsigned shift right long operation. Uses no substiutions.
-    *
-    * For: ushr-long/2addr
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where the fist is the value to shift and the second is the
-    *              shift amount. Store the result in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    movq        .LshiftMask, %xmm2      # %xmm2<- mask for the shift bits
-    movss       (rFP, %edx, 4),  %xmm0  # %xmm0<- vB
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vA
-    pand        %xmm2, %xmm0            # %xmm0<- masked shift bits
-    psrlq       %xmm0, %xmm1            # %xmm1<- shifted vA
-    movq        %xmm1, (rFP, rINST, 4)  # vA<- shifted vA
-    FINISH      1                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
-/* File: x86-atom/OP_ADD_FLOAT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_FLOAT_2ADDR.S
-    */
-
-/* File: x86-atom/binopF2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopF2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0 = %xmm0 op %xmm1".
-    *
-    * For: add-float/2addr, mul-float/2addr, sub-float/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    andl        $15, %ecx              # %ecx<- A
-    shr         $4, rINST              # rINST<- B
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
-    movss       (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
-    movss       (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    addss     %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movss       %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
-/* File: x86-atom/OP_SUB_FLOAT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_FLOAT_2ADDR.S
-    */
-
-/* File: x86-atom/binopF2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopF2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0 = %xmm0 op %xmm1".
-    *
-    * For: add-float/2addr, mul-float/2addr, sub-float/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    andl        $15, %ecx              # %ecx<- A
-    shr         $4, rINST              # rINST<- B
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
-    movss       (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
-    movss       (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    subss     %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movss       %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
-/* File: x86-atom/OP_MUL_FLOAT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_FLOAT_2ADDR.S
-    */
-
-/* File: x86-atom/binopF2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopF2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0 = %xmm0 op %xmm1".
-    *
-    * For: add-float/2addr, mul-float/2addr, sub-float/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    andl        $15, %ecx              # %ecx<- A
-    shr         $4, rINST              # rINST<- B
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
-    movss       (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
-    movss       (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    mulss %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movss       %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
-/* File: x86-atom/OP_DIV_FLOAT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_FLOAT_2ADDR.S
-    *
-    * Code: Divides floats. Uses no substitutions.
-    *
-    * For: div-float/2addr
-    *
-    * Description: Divide operation on two source registers, storing
-    *              the result in the first source reigster
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    andl        $15, %ecx              # %ecx<- A
-    shr         $4, rINST              # rINST<- B
-    flds        (rFP, %ecx, 4)          # %xmm0<- vA
-    fdivs       (rFP, rINST, 4)         # divide double; vA/vB
-    fstps       (rFP, %ecx, 4)          # vAA<- result
-    FINISH      1                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_REM_FLOAT_2ADDR: /* 0xca */
-/* File: x86-atom/OP_REM_FLOAT_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_FLOAT_2ADDR.S
-    *
-    * Code: Computes the remainder of a division. Performs no substitutions.
-    *
-    * For: rem-float/2addr
-    *
-    * Description: Calls fmod to compute the remainder of the result of dividing a
-    *              source register by a second, and stores the result in the first
-    *              source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    GET_VREG    %edx                    # %edx<- vB
-    movl        (rFP, rINST, 4), %ecx   # %ecx<- vA
-    movl        %ecx, -8(%esp)          # push parameter vA
-    movl        %edx, -4(%esp)          # push parameter vB
-    lea         -8(%esp), %esp
-    call        fmodf                   # call: (float x, float y)
-                                        # return: float
-    lea         8(%esp), %esp
-    fstps       (rFP, rINST, 4)
-    FINISH      1                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
-/* File: x86-atom/OP_ADD_DOUBLE_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_DOUBLE_2ADDR.S
-    */
-
-/* File: x86-atom/binopWide2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide2addr.S
-    *
-    * Code: Generic 64-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0= %xmm0 op %xmm1".
-    *
-    * For: add-double/2addr, add-long/2addr, and-long/2addr, mul-long/2addr,
-    *      or-long/2addr, sub-double/2addr, sub-long/2addr, xor-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    andl        $15, %edx              # %edx<- A
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
-    addsd   %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    FINISH      1                       # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
-/* File: x86-atom/OP_SUB_DOUBLE_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_DOUBLE_2ADDR.S
-    */
-
-/* File: x86-atom/binopWide2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide2addr.S
-    *
-    * Code: Generic 64-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0= %xmm0 op %xmm1".
-    *
-    * For: add-double/2addr, add-long/2addr, and-long/2addr, mul-long/2addr,
-    *      or-long/2addr, sub-double/2addr, sub-long/2addr, xor-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    andl        $15, %edx              # %edx<- A
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
-    subsd   %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    FINISH      1                       # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
-/* File: x86-atom/OP_MUL_DOUBLE_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_DOUBLE_2ADDR.S
-    */
-
-/* File: x86-atom/binopWide2addr.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide2addr.S
-    *
-    * Code: Generic 64-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0= %xmm0 op %xmm1".
-    *
-    * For: add-double/2addr, add-long/2addr, and-long/2addr, mul-long/2addr,
-    *      or-long/2addr, sub-double/2addr, sub-long/2addr, xor-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, rINST              # rINST<- B
-    andl        $15, %edx              # %edx<- A
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
-    mulsd   %xmm1, %xmm0                              # %xmm0<- vA op vB
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    FINISH      1                       # jump to next instruction
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
-/* File: x86-atom/OP_DIV_DOUBLE_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_DOUBLE_2ADDR.S
-    *
-    * Code: Divides doubles. Uses no substitutions.
-    *
-    * For: div-double/2addr
-    *
-    * Description: Divide operation on two source registers, storing
-    *              the result in the first source reigster
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    andl        $15, %edx              # %edx<- A
-    shr         $4, rINST              # rINST<- B
-    fldl        (rFP, %edx, 4)          # %xmm0<- vA
-    fdivl       (rFP, rINST, 4)         # divide double; vA/vB
-    fstpl       (rFP, %edx, 4)          # vAA<- result
-    FINISH      1                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
-/* File: x86-atom/OP_REM_DOUBLE_2ADDR.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_DOUBLE_2ADDR.S
-    *
-    * Code: Computes the remainder of a division. Performs no substitutions.
-    *
-    * For: rem-double/2addr
-    *
-    * Description: Calls fmod to compute the remainder of the result of dividing a
-    *              source register by a second, and stores the result in the first
-    *              source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    and         $15, rINST             # rINST<- A
-    shr         $4, %edx               # %edx<- B
-    movl        (rFP, rINST, 4), %eax   # %eax<- vAlo
-    movl        %eax, -20(%esp)         # push parameter vAAlo
-    movl        4(rFP, rINST, 4), %eax  # %eax<- vAhi
-    movl        %eax, -16(%esp)         # push parameter vAAhi
-    movl        (rFP, %edx, 4), %eax    # %eax<- vBlo
-    movl        %eax, -12(%esp)         # push parameter vBBlo
-    movl        4(rFP, %edx, 4), %eax   # %eax<- vBhi
-    movl        %eax, -8(%esp)          # push parameter vBBhi
-    lea         -20(%esp), %esp
-    jmp         .LOP_REM_DOUBLE_2ADDR_break
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ADD_INT_LIT16: /* 0xd0 */
-/* File: x86-atom/OP_ADD_INT_LIT16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_INT_LIT16.S
-    */
-
-/* File: x86-atom/binopLit16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit16.S
-    *
-    * Code: 32-bit "lit16" operation. Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit16, and-int/lit16, mul-int/lit16, or-int/lit16
-    *      xor-int/lit16
-    *
-    * Description: Perform a binary operation on a register and a
-    *              sign extended 16-bit literal value and store the
-    *              result in a destination register.
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    andl        $15, rINST             # rINST<- A
-    FETCHs      1, %edx                 # %edx<- +CCCC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    addl     %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_RSUB_INT: /* 0xd1 */
-/* File: x86-atom/OP_RSUB_INT.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RSUB_INT.S
-    *
-    * Code: 32-bit reverse-subtraction. Uses no substitutions.
-    *
-    * For: rsub-int
-    *
-    * Description: Perform a reverse subtraction on a register and a
-    *              signed extended 16-bit literal value and store the
-    *              result in a destination register.
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    andl        $15, rINST             # rINST<- A
-    FETCHs      1, %edx                 # %edx<- +CCCC, sign-extended literal
-    GET_VREG    %ecx                    # %ecx<- vB
-    subl        %ecx, %edx              # %edx<- +CCCC sub vB
-    SET_VREG    %edx, rINST             # vA<- %edx; result
-    FINISH      2                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MUL_INT_LIT16: /* 0xd2 */
-/* File: x86-atom/OP_MUL_INT_LIT16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_INT_LIT16.S
-    */
-
-/* File: x86-atom/binopLit16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit16.S
-    *
-    * Code: 32-bit "lit16" operation. Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit16, and-int/lit16, mul-int/lit16, or-int/lit16
-    *      xor-int/lit16
-    *
-    * Description: Perform a binary operation on a register and a
-    *              sign extended 16-bit literal value and store the
-    *              result in a destination register.
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    andl        $15, rINST             # rINST<- A
-    FETCHs      1, %edx                 # %edx<- +CCCC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    imul     %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DIV_INT_LIT16: /* 0xd3 */
-/* File: x86-atom/OP_DIV_INT_LIT16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_INT_LIT16.S
-    */
-
-/* File: x86-atom/binopDLit16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDLit16.S
-    *
-    * Code: 32-bit "lit16" divide operation. If "div" is set, the code
-    *       returns the quotient, else it returns the remainder.
-    *       Also, a divide-by-zero check is done.
-    *
-    * For: div-int/lit16, rem-int/lit16
-    *
-    * Description: Perform a binary operation on a register and a
-    *              sign extended 16-bit literal value
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $4, %eax               # %eax<- B
-    FETCHs      1, %ecx                 # %ecx<- +CCCC, sign-extended literal
-    cmp         $0, %ecx               # check for divide by zero
-    GET_VREG    %eax                    # %eax<- vB
-    je          common_errDivideByZero  # handle divide by zero
-    andl        $15, rINST             # rINST<- A
-    cmpl        $-1, %ecx              # handle -1 special case divide error
-    jne         .LOP_DIV_INT_LIT16_noerror
-    cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je         .LOP_DIV_INT_LIT16_break
-.LOP_DIV_INT_LIT16_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    .if  1
-    SET_VREG    %eax rINST              # vA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vA<- %edx (remainder)
-    .endif
-    jmp         .LOP_DIV_INT_LIT16_break2
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_REM_INT_LIT16: /* 0xd4 */
-/* File: x86-atom/OP_REM_INT_LIT16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_INT_LIT16.S
-    */
-
-/* File: x86-atom/binopDLit16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDLit16.S
-    *
-    * Code: 32-bit "lit16" divide operation. If "div" is set, the code
-    *       returns the quotient, else it returns the remainder.
-    *       Also, a divide-by-zero check is done.
-    *
-    * For: div-int/lit16, rem-int/lit16
-    *
-    * Description: Perform a binary operation on a register and a
-    *              sign extended 16-bit literal value
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $4, %eax               # %eax<- B
-    FETCHs      1, %ecx                 # %ecx<- +CCCC, sign-extended literal
-    cmp         $0, %ecx               # check for divide by zero
-    GET_VREG    %eax                    # %eax<- vB
-    je          common_errDivideByZero  # handle divide by zero
-    andl        $15, rINST             # rINST<- A
-    cmpl        $-1, %ecx              # handle -1 special case divide error
-    jne         .LOP_REM_INT_LIT16_noerror
-    cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je         .LOP_REM_INT_LIT16_break
-.LOP_REM_INT_LIT16_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    .if  0
-    SET_VREG    %eax rINST              # vA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vA<- %edx (remainder)
-    .endif
-    jmp         .LOP_REM_INT_LIT16_break2
-
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AND_INT_LIT16: /* 0xd5 */
-/* File: x86-atom/OP_AND_INT_LIT16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_INT_LIT16.S
-    */
-
-/* File: x86-atom/binopLit16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit16.S
-    *
-    * Code: 32-bit "lit16" operation. Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit16, and-int/lit16, mul-int/lit16, or-int/lit16
-    *      xor-int/lit16
-    *
-    * Description: Perform a binary operation on a register and a
-    *              sign extended 16-bit literal value and store the
-    *              result in a destination register.
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    andl        $15, rINST             # rINST<- A
-    FETCHs      1, %edx                 # %edx<- +CCCC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    andl     %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_OR_INT_LIT16: /* 0xd6 */
-/* File: x86-atom/OP_OR_INT_LIT16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_INT_LIT16.S
-    */
-
-/* File: x86-atom/binopLit16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit16.S
-    *
-    * Code: 32-bit "lit16" operation. Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit16, and-int/lit16, mul-int/lit16, or-int/lit16
-    *      xor-int/lit16
-    *
-    * Description: Perform a binary operation on a register and a
-    *              sign extended 16-bit literal value and store the
-    *              result in a destination register.
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    andl        $15, rINST             # rINST<- A
-    FETCHs      1, %edx                 # %edx<- +CCCC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    or %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_XOR_INT_LIT16: /* 0xd7 */
-/* File: x86-atom/OP_XOR_INT_LIT16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_INT_LIT16.S
-    */
-
-/* File: x86-atom/binopLit16.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit16.S
-    *
-    * Code: 32-bit "lit16" operation. Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit16, and-int/lit16, mul-int/lit16, or-int/lit16
-    *      xor-int/lit16
-    *
-    * Description: Perform a binary operation on a register and a
-    *              sign extended 16-bit literal value and store the
-    *              result in a destination register.
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    andl        $15, rINST             # rINST<- A
-    FETCHs      1, %edx                 # %edx<- +CCCC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    xor     %edx, %ecx                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_ADD_INT_LIT8: /* 0xd8 */
-/* File: x86-atom/OP_ADD_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_INT_LIT8.S
-    */
-
-/* File: x86-atom/binopLit8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit8.S
-    *
-    * Code: 32-bit "lit8" divide operation. Provides an "instr" line
-    *       to specify an instruction that performs  "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit8, and-int/lit8, mul-int/lit8, or-int/lit8
-    *      xor-int/lit8
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signed extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CCs   1, %edx                 # %edx<- +CC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    addl     %edx, %ecx                              # %ecx<- vBB op +CC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_RSUB_INT_LIT8: /* 0xd9 */
-/* File: x86-atom/OP_RSUB_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RSUB_INT_LIT8.S
-    *
-    * Code: 32-bit reverse-subtraction. Uses no substitutions.
-    *
-    * For: rsub-int/lit8
-    *
-    * Description: Perform a reverse subtraction on a register and a
-    *              signed extended 8-bit literal value.
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CCs   1, %edx                 # %edx<- +CC, sign-extended literal
-    GET_VREG    %ecx                    # %ecx<- vBB
-    sub         %ecx, %edx              # %edx<- +CC sub vBB
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FINISH      2                       # jump to next instruction
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_MUL_INT_LIT8: /* 0xda */
-/* File: x86-atom/OP_MUL_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_INT_LIT8.S
-    */
-
-/* File: x86-atom/binopLit8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit8.S
-    *
-    * Code: 32-bit "lit8" divide operation. Provides an "instr" line
-    *       to specify an instruction that performs  "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit8, and-int/lit8, mul-int/lit8, or-int/lit8
-    *      xor-int/lit8
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signed extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CCs   1, %edx                 # %edx<- +CC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    imul     %edx, %ecx                              # %ecx<- vBB op +CC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_DIV_INT_LIT8: /* 0xdb */
-/* File: x86-atom/OP_DIV_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_INT_LIT8.S
-    */
-
-/* File: x86-atom/binopDLit8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDLit8.S
-    *
-    * Code: 32-bit "lit8" divide operation. If "div" is set, the code
-    *       returns the quotient, else it returns the remainder.
-    *       Also, a divide-by-zero check is done.
-    *
-    * For: div-int/lit8, rem-int/lit8
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signe extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-
-    FETCH_BB    1, %eax                 # %eax<- BB
-    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
-    cmp         $0, %ecx               # check for divide by zero
-    GET_VREG    %eax                    # %eax<- vBB
-    je          common_errDivideByZero  # handle divide by zero
-
-    cmpl        $-1, %ecx              # handle -1 special case divide error
-    jne         .LOP_DIV_INT_LIT8_noerror
-    cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je         .LOP_DIV_INT_LIT8_break
-.LOP_DIV_INT_LIT8_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    .if  1
-    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    .endif
-    jmp         .LOP_DIV_INT_LIT8_break2
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_REM_INT_LIT8: /* 0xdc */
-/* File: x86-atom/OP_REM_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_INT_LIT8.S
-    */
-
-/* File: x86-atom/binopDLit8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDLit8.S
-    *
-    * Code: 32-bit "lit8" divide operation. If "div" is set, the code
-    *       returns the quotient, else it returns the remainder.
-    *       Also, a divide-by-zero check is done.
-    *
-    * For: div-int/lit8, rem-int/lit8
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signe extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-
-    FETCH_BB    1, %eax                 # %eax<- BB
-    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
-    cmp         $0, %ecx               # check for divide by zero
-    GET_VREG    %eax                    # %eax<- vBB
-    je          common_errDivideByZero  # handle divide by zero
-
-    cmpl        $-1, %ecx              # handle -1 special case divide error
-    jne         .LOP_REM_INT_LIT8_noerror
-    cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je         .LOP_REM_INT_LIT8_break
-.LOP_REM_INT_LIT8_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    .if  0
-    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    .endif
-    jmp         .LOP_REM_INT_LIT8_break2
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_AND_INT_LIT8: /* 0xdd */
-/* File: x86-atom/OP_AND_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_INT_LIT8.S
-    */
-
-/* File: x86-atom/binopLit8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit8.S
-    *
-    * Code: 32-bit "lit8" divide operation. Provides an "instr" line
-    *       to specify an instruction that performs  "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit8, and-int/lit8, mul-int/lit8, or-int/lit8
-    *      xor-int/lit8
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signed extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CCs   1, %edx                 # %edx<- +CC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    andl     %edx, %ecx                              # %ecx<- vBB op +CC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_OR_INT_LIT8: /* 0xde */
-/* File: x86-atom/OP_OR_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_INT_LIT8.S
-    */
-
-/* File: x86-atom/binopLit8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit8.S
-    *
-    * Code: 32-bit "lit8" divide operation. Provides an "instr" line
-    *       to specify an instruction that performs  "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit8, and-int/lit8, mul-int/lit8, or-int/lit8
-    *      xor-int/lit8
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signed extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CCs   1, %edx                 # %edx<- +CC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    or %edx, %ecx                              # %ecx<- vBB op +CC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_XOR_INT_LIT8: /* 0xdf */
-/* File: x86-atom/OP_XOR_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_INT_LIT8.S
-    */
-
-/* File: x86-atom/binopLit8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit8.S
-    *
-    * Code: 32-bit "lit8" divide operation. Provides an "instr" line
-    *       to specify an instruction that performs  "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit8, and-int/lit8, mul-int/lit8, or-int/lit8
-    *      xor-int/lit8
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signed extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CCs   1, %edx                 # %edx<- +CC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    xor     %edx, %ecx                              # %ecx<- vBB op +CC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SHL_INT_LIT8: /* 0xe0 */
-/* File: x86-atom/OP_SHL_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHL_INT_LIT8.S
-    */
-
-/* File: x86-atom/binopLit8S.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit8S.S
-    *
-    * Code: 32-bit "lit8" divide operation. Provides an "instr" line
-    *       to specify an instruction that performs "%edx = %edx op %cl"
-    *
-    *
-    * For: shl-int/lit8, shr-int/lit8, ushr-int/lit8
-    *
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signed extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %edx                 # %edx<- BB
-    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vBB
-    sal     %cl, %edx                              # %edx<- vBB op +CC
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_SHR_INT_LIT8: /* 0xe1 */
-/* File: x86-atom/OP_SHR_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHR_INT_LIT8.S
-    */
-
-/* File: x86-atom/binopLit8S.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit8S.S
-    *
-    * Code: 32-bit "lit8" divide operation. Provides an "instr" line
-    *       to specify an instruction that performs "%edx = %edx op %cl"
-    *
-    *
-    * For: shl-int/lit8, shr-int/lit8, ushr-int/lit8
-    *
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signed extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %edx                 # %edx<- BB
-    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vBB
-    sar     %cl, %edx                              # %edx<- vBB op +CC
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_USHR_INT_LIT8: /* 0xe2 */
-/* File: x86-atom/OP_USHR_INT_LIT8.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_USHR_INT_LIT8.S
-    */
-
-/* File: x86-atom/binopLit8S.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit8S.S
-    *
-    * Code: 32-bit "lit8" divide operation. Provides an "instr" line
-    *       to specify an instruction that performs "%edx = %edx op %cl"
-    *
-    *
-    * For: shl-int/lit8, shr-int/lit8, ushr-int/lit8
-    *
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signed extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %edx                 # %edx<- BB
-    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vBB
-    shr     %cl, %edx                              # %edx<- vBB op +CC
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_VOLATILE: /* 0xe3 */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_IGET_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_VOLATILE: /* 0xe4 */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_IPUT_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_SGET_VOLATILE: /* 0xe5 */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_SGET_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPUT_VOLATILE: /* 0xe6 */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_SPUT_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_IGET_OBJECT_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_IGET_WIDE_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_IPUT_WIDE_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_SGET_WIDE_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_SPUT_WIDE_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_BREAKPOINT: /* 0xec */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_BREAKPOINT      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
-/* File: x86-atom/OP_THROW_VERIFICATION_ERROR.S */
-   /* Copyright (C) 2009 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_THROW_VERIFICATION_ERROR.S
-    *
-    * Code:
-    *
-    * For: throw-verification-error
-    *
-    * Description: Throws an exception for an error discovered during verification.
-    *              The exception is indicated by AA with details provided by BBBB.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, ref@BBBB
-    */
-
-    movl        rGLUE, %edx                  # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %ecx   # %ecx<- glue->method
-    EXPORT_PC                                # in case an exception is thrown
-    FETCH       1, %eax                      # %eax<- BBBB
-    movl        %eax, -4(%esp)               # push parameter BBBB; ref
-    movl        rINST, -8(%esp)              # push parameter AA
-    movl        %ecx, -12(%esp)              # push parameter glue->method
-    lea         -12(%esp), %esp
-    call        dvmThrowVerificationError    # call: (const Method* method, int kind, int ref)
-    jmp         common_exceptionThrown       # failed; handle exception
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_EXECUTE_INLINE: /* 0xee */
-/* File: x86-atom/OP_EXECUTE_INLINE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_EXECUTE_INLINE.S
-    *
-    * Code: Executes a "native inline" instruction. Uses no substitutions.
-    *
-    * For: execute-inline
-    *
-    * Description: Executes a "native inline" instruction. This instruction
-    *              is generated by the optimizer.
-    *
-    * Format:
-    *
-    * Syntax: vAA, {vC, vD, vE, vF}, inline@BBBB
-    */
-
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    movl        rGLUE, %eax             # %eax<- MterpGlue pointer
-    addl        $offGlue_retval, %eax  # %eax<- &glue->retval
-    EXPORT_PC
-    shr         $4, rINST              # rINST<- B
-    movl        %eax, -8(%esp)          # push parameter glue->retval
-    lea         -24(%esp), %esp
-    jmp         .LOP_EXECUTE_INLINE_continue
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_EXECUTE_INLINE_RANGE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_INVOKE_OBJECT_INIT_RANGE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_RETURN_VOID_BARRIER      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_QUICK: /* 0xf2 */
-/* File: x86-atom/OP_IGET_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_QUICK.S
-    *
-    * Code: Optimization for iget
-    *
-    * For: iget-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $4, %eax               # %eax<- B
-    and         $15, rINST             # rINST<- A
-    GET_VREG    %eax                    # %eax<- vB; object to operate on
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    cmp         $0, %eax               # check if object is null
-    je          common_errNullObject    # handle null object
-    FFETCH_ADV  2, %edx                 # %eax<- next instruction hi; fetch, advance
-    movl        (%ecx, %eax), %eax      # %eax<- object field
-    SET_VREG    %eax, rINST             # fp[A]<- %eax
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
-/* File: x86-atom/OP_IGET_WIDE_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_WIDE_QUICK.S
-    *
-    * Code: Optimization for iget
-    *
-    * For: iget/wide-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    GET_VREG    %edx                    # %edx<- vB; object to operate on
-    cmp         $0, %edx               # check if object is null
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    je          common_errNullObject    # handle null object
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    movq        (%ecx, %edx), %xmm0     # %xmm0<- object field
-    movq        %xmm0, (rFP, rINST, 4)  # fp[A]<- %xmm0
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
-/* File: x86-atom/OP_IGET_OBJECT_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_OBJECT_QUICK.S
-    */
-
-/* File: x86-atom/OP_IGET_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_QUICK.S
-    *
-    * Code: Optimization for iget
-    *
-    * For: iget-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $4, %eax               # %eax<- B
-    and         $15, rINST             # rINST<- A
-    GET_VREG    %eax                    # %eax<- vB; object to operate on
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    cmp         $0, %eax               # check if object is null
-    je          common_errNullObject    # handle null object
-    FFETCH_ADV  2, %edx                 # %eax<- next instruction hi; fetch, advance
-    movl        (%ecx, %eax), %eax      # %eax<- object field
-    SET_VREG    %eax, rINST             # fp[A]<- %eax
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_QUICK: /* 0xf5 */
-/* File: x86-atom/OP_IPUT_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_QUICK.S
-    * Code: Optimization for iput
-    *
-    * For: iput-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $4, %eax               # %eax<- B
-    and         $15, rINST             # rINST<- A
-    GET_VREG    %eax                    # %eax<- vB; object to operate on
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    cmp         $0, %eax               # check if object is null
-    je          common_errNullObject    # handle null object
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vA
-    movl        rINST, (%eax, %ecx)     # object field<- vA
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
-/* File: x86-atom/OP_IPUT_WIDE_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_WIDE_QUICK.S
-    *
-    * Code: Optimization for iput
-    *
-    * For: iput/wide-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    GET_VREG    %edx                    # %edx<- vB; object to operate on
-    cmp         $0, %edx               # check if object is null
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    je          common_errNullObject    # handle null object
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- fp[A]
-    movq        %xmm0, (%edx, %ecx)     # object field<- %xmm0; fp[A]
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
-/* File: x86-atom/OP_IPUT_OBJECT_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_QUICK.S
-    * Code: Optimization for iput
-    *
-    * For: iput-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $4, %eax               # %eax<- B
-    and         $15, rINST             # rINST<- A
-    GET_VREG    %eax                    # %eax<- vB; object to operate on
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    cmp         $0, %eax               # check if object is null
-    je          common_errNullObject    # handle null object
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vA
-    movl        rINST, (%eax, %ecx)     # object field<- vA
-    testl       rINST, rINST            # did we write a null object
-    je          1f
-    movl        rGLUE, %ecx             # get glue
-    movl        offGlue_cardTable(%ecx), %ecx # get card table base
-    shrl        $GC_CARD_SHIFT, %eax   # get gc card index
-    movb        %cl, (%eax, %ecx)       # mark gc card in table
-1:
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
-/* File: x86-atom/OP_INVOKE_VIRTUAL_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_VIRTUAL_QUICK.S
-    *
-    * Code: Optimization for invoke-virtual and invoke-virtual/range
-    *
-    * For: invoke-virtual/quick, invoke-virtual/quick-range
-    */
-
-
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    .if (!0)
-    and         $15, %edx              # %edx<- D if not range
-    .endif
-    FETCH       1, %ecx                 # %ecx<- method index
-    GET_VREG    %edx                    # %edx<- "this" ptr
-    cmp         $0, %edx               # %edx<- check for null "this"
-    EXPORT_PC                           # must export pc for invoke
-    je          common_errNullObject
-    movl        offObject_clazz(%edx), %edx # %edx<- thisPtr->clazz
-    movl        offClassObject_vtable(%edx), %edx # %edx<- thisPtr->clazz->vtable
-    movl        (%edx, %ecx, 4), %ecx   # %ecx<- vtable[methodIndex]
-    jmp         common_invokeMethodNoRange # invoke method common code
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
-/* File: x86-atom/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_VIRTUAL_QUICK_RANGE.S
-    */
-
-/* File: x86-atom/OP_INVOKE_VIRTUAL_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_VIRTUAL_QUICK.S
-    *
-    * Code: Optimization for invoke-virtual and invoke-virtual/range
-    *
-    * For: invoke-virtual/quick, invoke-virtual/quick-range
-    */
-
-
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    .if (!1)
-    and         $15, %edx              # %edx<- D if not range
-    .endif
-    FETCH       1, %ecx                 # %ecx<- method index
-    GET_VREG    %edx                    # %edx<- "this" ptr
-    cmp         $0, %edx               # %edx<- check for null "this"
-    EXPORT_PC                           # must export pc for invoke
-    je          common_errNullObject
-    movl        offObject_clazz(%edx), %edx # %edx<- thisPtr->clazz
-    movl        offClassObject_vtable(%edx), %edx # %edx<- thisPtr->clazz->vtable
-    movl        (%edx, %ecx, 4), %ecx   # %ecx<- vtable[methodIndex]
-    jmp         common_invokeMethodRange # invoke method common code
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
-/* File: x86-atom/OP_INVOKE_SUPER_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_SUPER_QUICK.S
-    *
-    * Code: Optimization for invoke-super and invoke-super/range
-    *
-    * For: invoke-super/quick, invoke-super/quick-range
-    */
-
-
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_method(%ecx), %eax # %eax<- glue->method
-    .if         (!0)
-    and         $15, %edx              #  %edx<- D if not range
-    .endif
-    FETCH       1, %ecx                 # %ecx<- method index
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    movl        offClassObject_super(%eax), %eax # %eax<- glue->method->clazz->super
-    EXPORT_PC                           # must export for invoke
-    movl        offClassObject_vtable(%eax), %eax # %edx<- glue->method->clazz->super->vtable
-    cmp         $0, (rFP, %edx, 4)     # check for null object
-    movl        (%eax, %ecx, 4), %ecx   # %ecx<- vtable[methodIndex]
-    je          common_errNullObject    # handle null object
-    jmp         common_invokeMethodNoRange # invoke method common code
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
-/* File: x86-atom/OP_INVOKE_SUPER_QUICK_RANGE.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_SUPER_QUICK_RANGE.S
-    */
-
-/* File: x86-atom/OP_INVOKE_SUPER_QUICK.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_SUPER_QUICK.S
-    *
-    * Code: Optimization for invoke-super and invoke-super/range
-    *
-    * For: invoke-super/quick, invoke-super/quick-range
-    */
-
-
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_method(%ecx), %eax # %eax<- glue->method
-    .if         (!1)
-    and         $15, %edx              #  %edx<- D if not range
-    .endif
-    FETCH       1, %ecx                 # %ecx<- method index
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    movl        offClassObject_super(%eax), %eax # %eax<- glue->method->clazz->super
-    EXPORT_PC                           # must export for invoke
-    movl        offClassObject_vtable(%eax), %eax # %edx<- glue->method->clazz->super->vtable
-    cmp         $0, (rFP, %edx, 4)     # check for null object
-    movl        (%eax, %ecx, 4), %ecx   # %ecx<- vtable[methodIndex]
-    je          common_errNullObject    # handle null object
-    jmp         common_invokeMethodRange # invoke method common code
-
-
-/* ------------------------------ */
-    .balign 64
-.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_IPUT_OBJECT_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_SGET_OBJECT_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_OP_SPUT_OBJECT_VOLATILE      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
-/* ------------------------------ */
-    .balign 64
-.L_OP_UNUSED_FF: /* 0xff */
-/* File: x86-atom/OP_UNUSED_FF.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-/* File: x86-atom/unused.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
-
-
-    .balign 64
-    .size   dvmAsmInstructionStart, .-dvmAsmInstructionStart
-    .global dvmAsmInstructionEnd
-dvmAsmInstructionEnd:
-
-/*
- * ===========================================================================
- *  Sister implementations
- * ===========================================================================
- */
-    .global dvmAsmSisterStart
-    .type   dvmAsmSisterStart, %function
-    .text
-    .balign 4
-dvmAsmSisterStart:
-
-/* continuation for OP_CONST_STRING */
-
-
-   /*
-    * Continuation if the Class has not yet been resolved.
-    *  %ecx: BBBB (Class ref)
-    *  need: target register
-    */
-
-.LOP_CONST_STRING_resolve:
-    EXPORT_PC
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %ecx, -4(%esp)          # push parameter class ref
-    movl        %edx, -8(%esp)          # push parameter glue->method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveString        # resolve string reference
-                                        # call: (const ClassObject* referrer, u4 stringIdx)
-                                        # return: StringObject*
-    lea         8(%esp), %esp
-    cmp         $0, %eax               # check if resolved string failed
-    je          common_exceptionThrown  # resolve failed; exception thrown
-    SET_VREG    %eax, rINST             # vAA<- %eax; pResString[BBBB]
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_CONST_STRING_JUMBO */
-
-
-   /*
-    * Continuation if the Class has not yet been resolved.
-    *  %ecx: BBBB (Class ref)
-    *  need: target register
-    */
-.LOP_CONST_STRING_JUMBO_resolve:
-    EXPORT_PC
-    movl        rGLUE, %edx             # get MterpGlue pointer
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        offMethod_clazz(%edx), %edx # %edx <- glue->method->clazz
-    movl        %ecx, -4(%esp)          # push parameter class ref
-    movl        %edx, -8(%esp)          # push parameter glue->method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveString        # resolve string reference
-                                        # call: (const ClassObject* referrer, u4 stringIdx)
-                                        # return: StringObject*
-    lea         8(%esp), %esp
-    cmp         $0, %eax               # check if resolved string failed
-    je          common_exceptionThrown  # resolve failed; exception thrown
-    SET_VREG    %eax, rINST             # vAA<- %eax; pResString[BBBB]
-    FINISH      3                       # jump to next instruction
-
-/* continuation for OP_CONST_CLASS */
-
-   /*
-    * Continuation if the Class has not yet been resolved.
-    *  %ecx: BBBB (Class ref)
-    *  need: target register
-    */
-
-.LOP_CONST_CLASS_resolve:
-    EXPORT_PC
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        $1, -4(%esp)           # push parameter true
-    movl        %ecx, -8(%esp)          # push parameter
-    movl        %edx, -12(%esp)         # push parameter glue->method->clazz
-    lea         -12(%esp), %esp
-    call        dvmResolveClass         # resolve ClassObject pointer
-                                        # class: (const ClassObject* referrer, u4 classIdx,
-                                        #         bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    lea         12(%esp), %esp
-    cmp         $0, %eax               # check for null pointer
-    je          common_exceptionThrown  # handle exception
-    SET_VREG    %eax, rINST             # vAA<- resolved class
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_CHECK_CAST */
-
-.LOP_CHECK_CAST_resolved:
-    cmp         %ecx, offObject_clazz(rINST) # check for same class
-    jne         .LOP_CHECK_CAST_fullcheck   # not same class; do full check
-
-.LOP_CHECK_CAST_okay:
-    FINISH      2                       # jump to next instruction
-
-   /*
-    *  Trivial test failed, need to perform full check.
-    *  offObject_clazz(rINST) holds obj->clazz
-    *  %ecx holds class resolved from BBBB
-    *  rINST holds object
-    */
-
-.LOP_CHECK_CAST_fullcheck:
-    movl        offObject_clazz(rINST), %eax  # %eax<- obj->clazz
-    movl        %eax, -12(%esp)         # push parameter obj->clazz
-    movl        %ecx, -8(%esp)          # push parameter # push parameter resolved class
-    lea         -12(%esp), %esp
-    call        dvmInstanceofNonTrivial # call: (ClassObject* instance, ClassObject* clazz)
-                                        # return: int
-    lea         12(%esp), %esp
-    cmp         $0, %eax               # failed?
-    jne         .LOP_CHECK_CAST_okay        # success
-
-   /*
-    * A cast has failed.  We need to throw a ClassCastException with the
-    * class of the object that failed to be cast.
-    */
-
-    EXPORT_PC                           # we will throw an exception
-#error BIT ROT!!!
-    /*
-     * TODO: Code here needs to call dvmThrowClassCastException with two
-     * arguments.
-     */
-#if 0
-    /* old obsolete code that called dvmThrowExceptionWithClassMessage */
-    movl        $.LstrClassCastExceptionPtr, -8(%esp) # push parameter message
-    movl        offObject_clazz(rINST), rINST # rINST<- obj->clazz
-    movl        offClassObject_descriptor(rINST), rINST # rINST<- obj->clazz->descriptor
-    movl        rINST, -4(%esp)         # push parameter obj->clazz->descriptor
-    lea         -8(%esp), %esp
-    call        dvmThrowExceptionWithClassMessage # call: (const char* exceptionDescriptor,
-                                                  #       const char* messageDescriptor, Object* cause)
-                                                  # return: void
-#endif
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown
-
-   /*
-    * Resolution required.  This is the least-likely path.
-    *
-    *  rINST holds object
-    */
-
-.LOP_CHECK_CAST_resolve:
-    movl        offGlue_method(%edx), %eax # %eax<- glue->method
-    FETCH       1, %ecx                 # %ecx holds BBBB
-    EXPORT_PC                           # in case we throw an exception
-    movl        $0, -8(%esp)           # push parameter false
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    movl        %ecx, -12(%esp)         # push parameter BBBB
-    movl        %eax, -16(%esp)         # push parameter glue->method>clazz
-    lea         -16(%esp), %esp
-    call        dvmResolveClass         # resolve ClassObject pointer
-                                        # call: (const ClassObject* referrer, u4 classIdx,
-                                        #        bool fromUnverifiedConstant)
-                                        # return ClassObject*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check for null pointer
-    je          common_exceptionThrown  # handle excpetion
-    movl        %eax, %ecx              # %ecx<- resolved class
-    jmp         .LOP_CHECK_CAST_resolved
-
-/* continuation for OP_INSTANCE_OF */
-
-.LOP_INSTANCE_OF_break:
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- CCCC
-    movl        offDvmDex_pResClasses(%ecx), %ecx # %ecx<- pDvmDex->pResClasses
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved class
-    movl        offObject_clazz(%edx), %edx # %edx<- obj->clazz
-    cmp         $0, %ecx               # check if already resovled
-    je          .LOP_INSTANCE_OF_resolve     # not resolved before, so resolve now
-
-.LOP_INSTANCE_OF_resolved:
-    cmp         %ecx, %edx              # check if same class
-    je          .LOP_INSTANCE_OF_trivial     # yes, finish
-    jmp         .LOP_INSTANCE_OF_fullcheck   # no, do full check
-
-   /*
-    * The trivial test failed, we need to perform a full check.
-    * %edx holds obj->clazz
-    * %ecx holds class resolved from BBBB
-    */
-
-.LOP_INSTANCE_OF_fullcheck:
-    movl        %edx, -8(%esp)          # push parameter obj->clazz
-    movl        %ecx, -4(%esp)          # push parameter resolved class
-    lea         -8(%esp), %esp
-    call        dvmInstanceofNonTrivial # perform full check
-                                        # call: (ClassObject* instance, ClassObject* clazz)
-                                        # return: int
-    andl        $15, rINST             # rINST<- A
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    lea         8(%esp), %esp
-    SET_VREG    %eax, rINST             # vA<- r0
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-   /*
-    * %edx holds boolean result
-    */
-
-.LOP_INSTANCE_OF_store:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    andl        $15, rINST             # rINST<- A
-    SET_VREG    %edx, rINST             # vA<- r0
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-   /*
-    * Trivial test succeeded, save and bail.
-    */
-
-.LOP_INSTANCE_OF_trivial:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    andl        $15, rINST             # rINST<- A
-    SET_VREG    $1, rINST              # vA<- r0
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-   /*
-    * Resolution required.  This is the least-likely path.
-    * %eax holds BBBB
-    */
-
-.LOP_INSTANCE_OF_resolve:
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    EXPORT_PC
-    movl        offGlue_method(%ecx), %ecx # %ecx<- glue->method
-    movl        offMethod_clazz(%ecx), %ecx # %ecx<- glue->method->clazz
-    movl        %ecx, -12(%esp)         # push parameter glue->method->clazz
-    movl        %eax, -8(%esp)          # push parameter CCCC; type index
-    movl        $1, -4(%esp)           # push parameter true
-    lea         -12(%esp), %esp
-    call        dvmResolveClass         # call: (const ClassObject* referrer, u4 classIdx,
-                                        #        bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    lea         12(%esp), %esp
-    cmp         $0, %eax               # check for null
-    je          common_exceptionThrown  # handle exception
-    movl        rINST, %edx             # %edx<- BA+
-    shr         $4, %edx               # %edx<- B
-    movl        %eax, %ecx              # need class in %ecx
-    GET_VREG    %edx                    # %edx<- vB
-    movl        offObject_clazz(%edx), %edx # %edx<- obj->clazz
-    jmp         .LOP_INSTANCE_OF_resolved    # clazz resolved, continue
-
-/* continuation for OP_NEW_INSTANCE */
-.balign 32
-.LOP_NEW_INSTANCE_finish:
-    movl        %edx, -8(%esp)          # push parameter object
-    movl        %eax, -4(%esp)          # push parameter flags
-    lea         -8(%esp), %esp
-    call        dvmAllocObject          # call: (ClassObject* clazz, int flags)
-                                        # return: Object*
-    cmp         $0, %eax               # check for failure
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # handle exception
-    SET_VREG    %eax, rINST             # vAA<- pObject
-    FINISH      2                       # jump to next instruction
-
-   /*
-    * Class initialization required.
-    *
-    *  %edx holds class object
-    */
-
-.LOP_NEW_INSTANCE_needinit:
-    movl        %edx, -4(%esp)          # push parameter object
-    lea         -4(%esp), %esp
-    call        dvmInitClass            # call: (ClassObject* clazz)
-                                        # return: bool
-    lea         4(%esp), %esp
-    cmp         $0, %eax               # check for failure
-    movl        -4(%esp), %edx          # %edx<- object
-    je          common_exceptionThrown  # handle exception
-    testl       $(ACC_INTERFACE|ACC_ABSTRACT), offClassObject_accessFlags(%edx)
-    mov         $ALLOC_DONT_TRACK, %eax # %eax<- flag for alloc call
-    je          .LOP_NEW_INSTANCE_finish      # continue
-    jmp         .LOP_NEW_INSTANCE_abstract    # handle abstract or interface
-
-   /*
-    * Resolution required.  This is the least-likely path.
-    *
-    *  BBBB in %eax
-    */
-
-.LOP_NEW_INSTANCE_resolve:
-
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offGlue_method(%ecx), %ecx # %ecx<- glue->method
-    movl        offMethod_clazz(%ecx), %ecx # %ecx<- glue->method->clazz
-    movl        %ecx, -12(%esp)         # push parameter clazz
-    movl        $0, -4(%esp)           # push parameter false
-    movl        %eax, -8(%esp)          # push parameter BBBB
-    lea         -12(%esp), %esp
-    call        dvmResolveClass         # call: (const ClassObject* referrer,
-                                        #       u4 classIdx, bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    lea         12(%esp), %esp
-    movl        %eax, %edx              # %edx<- pObject
-    cmp         $0, %edx               # check for failure
-    jne         .LOP_NEW_INSTANCE_resolved    # continue
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * We can't instantiate an abstract class or interface, so throw an
-    * InstantiationError with the class descriptor as the message.
-    *
-    *  %edx holds class object
-    */
-
-.LOP_NEW_INSTANCE_abstract:
-    movl        offClassObject_descriptor(%edx), %ecx # %ecx<- descriptor
-    movl        %ecx, -4(%esp)          # push parameter descriptor
-    movl        $.LstrInstantiationErrorPtr, -8(%esp) # push parameter message
-    lea         -8(%esp), %esp
-    call        dvmThrowExceptionWithClassMessage # call: (const char* exceptionDescriptor,
-                                                  #        const char* messageDescriptor)
-                                                  # return: void
-    jmp         common_exceptionThrown  # handle exception
-
-.LstrInstantiationErrorPtr:
-.asciz      "Ljava/lang/InstantiationError;"
-
-/* continuation for OP_NEW_ARRAY */
-
-   /*
-    * Resolve class.  (This is an uncommon case.)
-    *
-    *  %edx holds array length
-    *  %ecx holds class ref CCCC
-    */
-
-.LOP_NEW_ARRAY_resolve:
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_method(%eax), %eax # %eax<- glue->method
-    movl        %edx, -4(%esp)          # save length
-    movl        $0, -8(%esp)           # push parameter false
-    movl        %ecx, -12(%esp)         # push parameter class ref
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    movl        %eax, -16(%esp)         # push parameter clazz
-    lea         -16(%esp), %esp
-    call        dvmResolveClass         # call: (const ClassObject* referrer,
-                                        #       u4 classIdx, bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    cmp         $0, %eax               # check for failure
-    lea         16(%esp), %esp
-    je          common_exceptionThrown  # handle exception
-    movl        -4(%esp), %edx          # %edx<- length
-
-   /*
-    * Finish allocation.
-    *
-    *  %eax holds class
-    *  %edx holds array length
-    */
-
-.LOP_NEW_ARRAY_finish:
-    movl        %eax, -12(%esp)         # push parameter class
-    movl        %edx, -8(%esp)          # push parameter length
-    movl        $ALLOC_DONT_TRACK, -4(%esp)
-    lea         -12(%esp), %esp
-    call        dvmAllocArrayByClass    # call: (ClassObject* arrayClass,
-                                        # size_t length, int allocFlags)
-                                        # return: ArrayObject*
-    and         $15, rINST             # rINST<- A
-    cmp         $0, %eax               # check for allocation failure
-    lea         12(%esp), %esp
-    je          common_exceptionThrown  # handle exception
-    SET_VREG    %eax, rINST             # vA<- pArray
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_FILLED_NEW_ARRAY */
-
-.LOP_FILLED_NEW_ARRAY_break:
-    movl        $0, -8(%esp)           # push parameter false
-    movl        %ecx, -12(%esp)         # push parameter BBBB
-    movl        rGLUE, %edx             # %edx<- MterpGlue pointer
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, -16(%esp)         # push parameter glue->method->clazz
-    lea         -16(%esp), %esp
-    call        dvmResolveClass         # call: (const ClassObject* referrer, u4 classIdx,
-                                        #        bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check for null return
-    je          common_exceptionThrown  # handle exception
-
-   /*
-    * On entry:
-    *  %eax holds array class
-    *  rINST holds BA or AA
-    */
-
-.LOP_FILLED_NEW_ARRAY_continue:
-    movl        offClassObject_descriptor(%eax), %eax # %eax<- arrayClass->descriptor
-    movzbl      1(%eax), %eax           # %eax<- descriptor[1]
-    cmpb        $'I', %al             # check if array of ints
-    je          1f
-    cmpb        $'L', %al
-    je          1f
-    cmpb        $'[', %al
-    jne         .LOP_FILLED_NEW_ARRAY_notimpl     # jump to not implemented
-1:
-    movl        %eax, sReg0             # save type
-    movl        rINST, -12(%esp)        # push parameter length
-    movl        %eax, -16(%esp)         # push parameter descriptor[1]
-    movl        $ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags
-    .if         (!0)
-    shrl        $4, -12(%esp)          # parameter length is B
-    .endif
-    lea         -16(%esp), %esp
-    call        dvmAllocPrimitiveArray  # call: (char type, size_t length, int allocFlags)
-                                        # return: ArrayObject*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check for null return
-    je          common_exceptionThrown  # handle exception
-
-    FETCH       2, %edx                 # %edx<- FEDC or CCCC
-    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
-    movl        %eax, offGlue_retval(%ecx) # retval<- new array
-    lea         offArrayObject_contents(%eax), %eax # %eax<- newArray->contents
-    subl        $1, -12(%esp)          # length--; check for negative
-    js          2f                      # if length was zero, finish
-
-   /*
-    * copy values from registers into the array
-    * %eax=array, %edx=CCCC/FEDC, -12(%esp)=length (from AA or B), rINST=AA/BA
-    */
-
-    .if         0
-    lea         (rFP, %edx, 4), %ecx    # %ecx<- &fpp[CCCC]
-1:
-    movl        (%ecx), %edx            # %edx<- %ecx++
-    lea         4(%ecx), %ecx           # %ecx++
-    movl        %edx, (%eax)            # *contents<- vX
-    lea         4(%eax), %eax           # %eax++; contents++
-    subl        $1, -12(%esp)          # length--
-    jns         1b                      # or continue at 2
-    .else
-    cmp         $4, -12(%esp)          # check length
-    jne         1f                      # has four args
-    and         $15, rINST             # rINST<- A
-    GET_VREG    rINST                   # rINST<- vA
-    subl        $1, -12(%esp)          # count--
-    movl        rINST, 16(%eax)         # contents[4]<- vA
-1:
-    movl        %edx, %ecx              # %ecx<- %edx; ecx for temp
-    andl        $15, %ecx              # %ecx<- G/F/E/D
-    GET_VREG    %ecx                    # %ecx<- vG/vF/vE/vD
-    shr         $4, %edx               # %edx<- put next reg in low 4
-    subl        $1, -12(%esp)          # count--
-    movl        %ecx, (%eax)            # *contents<- vX
-    lea         4(%eax), %eax           # %eax++; contents++
-    jns         1b                      # or continue at 2
-    .endif
-2:
-    cmpb        $'I', sReg0            # check for int array
-    je          3f
-    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
-    movl        offGlue_retval(%ecx), %eax # Object head
-    movl        offGlue_cardTable(%ecx), %ecx # card table base
-    shrl        $GC_CARD_SHIFT, %eax   # convert to card num
-    movb        %cl,(%ecx, %eax)        # mark card based on object head
-3:
-    FINISH      3                       # jump to next instruction
-
-   /*
-    * Throw an exception to indicate this mode of filled-new-array
-    * has not been implemented.
-    */
-
-.LOP_FILLED_NEW_ARRAY_notimpl:
-    movl        $.LstrInternalError, -8(%esp)
-    movl        $.LstrFilledNewArrayNotImpl, -4(%esp)
-    lea         -8(%esp), %esp
-    call        dvmThrowException # call: (const char* exceptionDescriptor,
-                                  #        const char* msg)
-                                  # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown
-
-.if         (!0)                 # define in one or the other, not both
-.LstrFilledNewArrayNotImpl:
-.asciz      "filled-new-array only implemented for 'int'"
-.LstrInternalError:
-.asciz  "Ljava/lang/InternalError;"
-.endif
-
-/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
-
-.LOP_FILLED_NEW_ARRAY_RANGE_break:
-    movl        $0, -8(%esp)           # push parameter false
-    movl        %ecx, -12(%esp)         # push parameter BBBB
-    movl        rGLUE, %edx             # %edx<- MterpGlue pointer
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, -16(%esp)         # push parameter glue->method->clazz
-    lea         -16(%esp), %esp
-    call        dvmResolveClass         # call: (const ClassObject* referrer, u4 classIdx,
-                                        #        bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check for null return
-    je          common_exceptionThrown  # handle exception
-
-   /*
-    * On entry:
-    *  %eax holds array class
-    *  rINST holds BA or AA
-    */
-
-.LOP_FILLED_NEW_ARRAY_RANGE_continue:
-    movl        offClassObject_descriptor(%eax), %eax # %eax<- arrayClass->descriptor
-    movzbl      1(%eax), %eax           # %eax<- descriptor[1]
-    cmpb        $'I', %al             # check if array of ints
-    je          1f
-    cmpb        $'L', %al
-    je          1f
-    cmpb        $'[', %al
-    jne         .LOP_FILLED_NEW_ARRAY_RANGE_notimpl     # jump to not implemented
-1:
-    movl        %eax, sReg0             # save type
-    movl        rINST, -12(%esp)        # push parameter length
-    movl        %eax, -16(%esp)         # push parameter descriptor[1]
-    movl        $ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags
-    .if         (!1)
-    shrl        $4, -12(%esp)          # parameter length is B
-    .endif
-    lea         -16(%esp), %esp
-    call        dvmAllocPrimitiveArray  # call: (char type, size_t length, int allocFlags)
-                                        # return: ArrayObject*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check for null return
-    je          common_exceptionThrown  # handle exception
-
-    FETCH       2, %edx                 # %edx<- FEDC or CCCC
-    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
-    movl        %eax, offGlue_retval(%ecx) # retval<- new array
-    lea         offArrayObject_contents(%eax), %eax # %eax<- newArray->contents
-    subl        $1, -12(%esp)          # length--; check for negative
-    js          2f                      # if length was zero, finish
-
-   /*
-    * copy values from registers into the array
-    * %eax=array, %edx=CCCC/FEDC, -12(%esp)=length (from AA or B), rINST=AA/BA
-    */
-
-    .if         1
-    lea         (rFP, %edx, 4), %ecx    # %ecx<- &fpp[CCCC]
-1:
-    movl        (%ecx), %edx            # %edx<- %ecx++
-    lea         4(%ecx), %ecx           # %ecx++
-    movl        %edx, (%eax)            # *contents<- vX
-    lea         4(%eax), %eax           # %eax++; contents++
-    subl        $1, -12(%esp)          # length--
-    jns         1b                      # or continue at 2
-    .else
-    cmp         $4, -12(%esp)          # check length
-    jne         1f                      # has four args
-    and         $15, rINST             # rINST<- A
-    GET_VREG    rINST                   # rINST<- vA
-    subl        $1, -12(%esp)          # count--
-    movl        rINST, 16(%eax)         # contents[4]<- vA
-1:
-    movl        %edx, %ecx              # %ecx<- %edx; ecx for temp
-    andl        $15, %ecx              # %ecx<- G/F/E/D
-    GET_VREG    %ecx                    # %ecx<- vG/vF/vE/vD
-    shr         $4, %edx               # %edx<- put next reg in low 4
-    subl        $1, -12(%esp)          # count--
-    movl        %ecx, (%eax)            # *contents<- vX
-    lea         4(%eax), %eax           # %eax++; contents++
-    jns         1b                      # or continue at 2
-    .endif
-2:
-    cmpb        $'I', sReg0            # check for int array
-    je          3f
-    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
-    movl        offGlue_retval(%ecx), %eax # Object head
-    movl        offGlue_cardTable(%ecx), %ecx # card table base
-    shrl        $GC_CARD_SHIFT, %eax   # convert to card num
-    movb        %cl,(%ecx, %eax)        # mark card based on object head
-3:
-    FINISH      3                       # jump to next instruction
-
-   /*
-    * Throw an exception to indicate this mode of filled-new-array
-    * has not been implemented.
-    */
-
-.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
-    movl        $.LstrInternalError, -8(%esp)
-    movl        $.LstrFilledNewArrayNotImpl, -4(%esp)
-    lea         -8(%esp), %esp
-    call        dvmThrowException # call: (const char* exceptionDescriptor,
-                                  #        const char* msg)
-                                  # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown
-
-.if         (!1)                 # define in one or the other, not both
-.LstrFilledNewArrayNotImpl:
-.asciz      "filled-new-array only implemented for 'int'"
-.LstrInternalError:
-.asciz  "Ljava/lang/InternalError;"
-.endif
-
-/* continuation for OP_PACKED_SWITCH */
-.LOP_PACKED_SWITCH_finish:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-/* continuation for OP_SPARSE_SWITCH */
-.LOP_SPARSE_SWITCH_finish:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-/* continuation for OP_CMPL_FLOAT */
-.LOP_CMPL_FLOAT_greater:
-    movl        $0x1, (rFP, rINST, 4)  # vAA<- greater than
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-.LOP_CMPL_FLOAT_final:
-    movl        $0x0, (rFP, rINST, 4)  # vAA<- equal
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-.LOP_CMPL_FLOAT_finalNan:
-    movl        $0xFFFFFFFF, (rFP, rINST, 4)   # vAA<- NaN
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_CMPG_FLOAT */
-.LOP_CMPG_FLOAT_greater:
-    movl        $0x1, (rFP, rINST, 4)  # vAA<- greater than
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-.LOP_CMPG_FLOAT_final:
-    movl        $0x0, (rFP, rINST, 4)  # vAA<- equal
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-.LOP_CMPG_FLOAT_finalNan:
-    movl        $0x1, (rFP, rINST, 4)   # vAA<- NaN
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_CMPL_DOUBLE */
-.LOP_CMPL_DOUBLE_greater:
-    movl        $0x1, (rFP, rINST, 4)  # vAA<- greater than
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-.LOP_CMPL_DOUBLE_final:
-    movl        $0x0, (rFP, rINST, 4)  # vAA<- equal
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-.LOP_CMPL_DOUBLE_finalNan:
-    movl        $0xFFFFFFFF, (rFP, rINST, 4)   # vAA<- NaN
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_CMPG_DOUBLE */
-.LOP_CMPG_DOUBLE_greater:
-    movl        $0x1, (rFP, rINST, 4)  # vAA<- greater than
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-.LOP_CMPG_DOUBLE_final:
-    movl        $0x0, (rFP, rINST, 4)  # vAA<- equal
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-.LOP_CMPG_DOUBLE_finalNan:
-    movl        $0x1, (rFP, rINST, 4)   # vAA<- NaN
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_CMP_LONG */
-
-.LOP_CMP_LONG_final:
-    movl        $0x0, (rFP, rINST, 4)  # vAA<- equal
-    FINISH      2                       # jump to next instruction
-
-.LOP_CMP_LONG_less:
-    movl        $0xFFFFFFFF, (rFP, rINST, 4) # vAA<- less than
-    FINISH      2                       # jump to next instruction
-
-.LOP_CMP_LONG_greater:
-    movl        $0x1, (rFP, rINST, 4)  # vAA<- greater than
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_APUT_OBJECT */
-
-.LOP_APUT_OBJECT_finish:
-    movl        %edx, sReg0             # save &vBB[vCC]
-    movl        %eax, sReg1             # save object head
-    movl        offObject_clazz(rINST), %edx # %edx<- obj->clazz
-    movl        %edx, -8(%esp)          # push parameter obj->clazz
-    movl        offObject_clazz(%eax), %eax # %eax<- arrayObj->clazz
-    movl        %eax, -4(%esp)          # push parameter arrayObj->clazz
-    lea         -8(%esp), %esp
-    call        dvmCanPutArrayElement   # test object type vs. array type
-                                        # call: ClassObject* elemClass, ClassObject* arrayClass)
-                                        # return: bool
-    lea         8(%esp), %esp
-    testl       %eax, %eax              # check for invalid array value
-    je          common_errArrayStore    # handle invalid array value
-    movl        sReg0, %edx             # restore &vBB[vCC]
-    movl        rINST, offArrayObject_contents(%edx)
-    movl        rGLUE, %eax
-    FFETCH_ADV  2, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    movl        offGlue_cardTable(%eax), %eax # get card table base
-    movl        sReg1, %edx             # restore object head
-    shrl        $GC_CARD_SHIFT, %edx   # object head to card number
-    movb        %al, (%eax, %edx)       # mark card using object head
-    FGETOP_JMP  2, %ecx                 # jump to next instruction; getop, jmp
-.LOP_APUT_OBJECT_skip_check:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl        rINST, offArrayObject_contents(%edx)
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IGET */
-
-.LOP_IGET_finish:
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    cmp         $0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # not resolved; handle exception
-
-    /*
-     *  %eax holds resolved field
-     */
-
-.LOP_IGET_finish2:
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl     (%ecx, %edx), %edx      # %edx<- object field
-    SET_VREG    %edx, rINST             # vA<- %edx; object field
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IGET_WIDE */
-
-.LOP_IGET_WIDE_finish2:
-    lea         -8(%esp), %esp
-    call        dvmResolveInstField     # resolve InstField ptr
-                                        # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    cmp         $0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    movl        %eax, %ecx              # %ecx<- %eax; %ecx expected to hold field
-    je          common_exceptionThrown
-
-   /*
-    *  %ecx holds resolved field
-    */
-
-.LOP_IGET_WIDE_finish:
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    GET_VREG    %edx                    # %edx<- vB
-    cmp         $0, %edx               # check for null object
-    je          common_errNullObject
-    movl        offInstField_byteOffset(%ecx), %ecx # %ecx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (%ecx, %edx), %xmm0     # %xmm0<- object field
-    movq        %xmm0, (rFP, rINST, 4)  # vA<- %xmm0; object field
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IGET_OBJECT */
-
-.LOP_IGET_OBJECT_finish:
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    cmp         $0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # not resolved; handle exception
-
-    /*
-     *  %eax holds resolved field
-     */
-
-.LOP_IGET_OBJECT_finish2:
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl     (%ecx, %edx), %edx      # %edx<- object field
-    SET_VREG    %edx, rINST             # vA<- %edx; object field
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IGET_BOOLEAN */
-
-.LOP_IGET_BOOLEAN_finish:
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    cmp         $0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # not resolved; handle exception
-
-    /*
-     *  %eax holds resolved field
-     */
-
-.LOP_IGET_BOOLEAN_finish2:
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl     (%ecx, %edx), %edx      # %edx<- object field
-    SET_VREG    %edx, rINST             # vA<- %edx; object field
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IGET_BYTE */
-
-.LOP_IGET_BYTE_finish:
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    cmp         $0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # not resolved; handle exception
-
-    /*
-     *  %eax holds resolved field
-     */
-
-.LOP_IGET_BYTE_finish2:
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl     (%ecx, %edx), %edx      # %edx<- object field
-    SET_VREG    %edx, rINST             # vA<- %edx; object field
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IGET_CHAR */
-
-.LOP_IGET_CHAR_finish:
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    cmp         $0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # not resolved; handle exception
-
-    /*
-     *  %eax holds resolved field
-     */
-
-.LOP_IGET_CHAR_finish2:
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl     (%ecx, %edx), %edx      # %edx<- object field
-    SET_VREG    %edx, rINST             # vA<- %edx; object field
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IGET_SHORT */
-
-.LOP_IGET_SHORT_finish:
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    cmp         $0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # not resolved; handle exception
-
-    /*
-     *  %eax holds resolved field
-     */
-
-.LOP_IGET_SHORT_finish2:
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl     (%ecx, %edx), %edx      # %edx<- object field
-    SET_VREG    %edx, rINST             # vA<- %edx; object field
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IPUT */
-
-.LOP_IPUT_finish:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    lea         -8(%esp), %esp
-    movl        %edx, (%esp)            # push parameter method->clazz
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    lea         8(%esp), %esp
-    cmp         $0, %eax               # check if resolved
-    jne         .LOP_IPUT_finish2
-    jmp         common_exceptionThrown  # not resolved; handle exception
-
-.LOP_IPUT_finish2:
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vA
-    movl     rINST, (%edx, %ecx)     # object field<- vA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IPUT_WIDE */
-
-.LOP_IPUT_WIDE_finish2:
-    lea         -8(%esp), %esp
-    call        dvmResolveInstField     # resolve InstField ptr
-    cmp         $0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    movl        %eax, %ecx              # %ecx<- %eax; %ecx expected to hold field
-    jne         .LOP_IPUT_WIDE_finish
-    jmp         common_exceptionThrown
-
-   /*
-    * Currently:
-    *  %ecx holds resolved field
-    *  %edx does not hold object yet
-    */
-
-.LOP_IPUT_WIDE_finish:
-    movl        rINST, %edx             # %edx<- BA
-    shr         $4, %edx               # %edx<- B
-    andl        $15, rINST             # rINST<- A
-    GET_VREG    %edx                    # %edx<- vB
-    cmp         $0, %edx               # check for null object
-    je          common_errNullObject
-    movl        offInstField_byteOffset(%ecx), %ecx # %ecx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vA
-    movq        %xmm0, (%ecx, %edx)     # object field<- %xmm0; vA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IPUT_OBJECT */
-
-.LOP_IPUT_OBJECT_finish:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    lea         -8(%esp), %esp
-    movl        %edx, (%esp)            # push parameter method->clazz
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    lea         8(%esp), %esp
-    cmp         $0, %eax               # check if resolved
-    jne         .LOP_IPUT_OBJECT_finish2
-    jmp         common_exceptionThrown  # not resolved; handle exception
-
-.LOP_IPUT_OBJECT_finish2:
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    GET_VREG    rINST                   # rINST<- vA
-    movl        rINST, (%edx, %ecx)     # object field<- vA
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl     rGLUE, %eax             # get glue
-    movl        offGlue_cardTable(%eax), %eax # get card table base
-    testl       rINST, rINST            # test if we stored a null value
-    je          1f                     # skip card mark if null stored
-    shrl        $GC_CARD_SHIFT, %ecx   # set obeject head to card number
-    movb        %al, (%eax, %ecx)
-1:
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IPUT_BOOLEAN */
-
-.LOP_IPUT_BOOLEAN_finish:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    lea         -8(%esp), %esp
-    movl        %edx, (%esp)            # push parameter method->clazz
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    lea         8(%esp), %esp
-    cmp         $0, %eax               # check if resolved
-    jne         .LOP_IPUT_BOOLEAN_finish2
-    jmp         common_exceptionThrown  # not resolved; handle exception
-
-.LOP_IPUT_BOOLEAN_finish2:
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vA
-    movl     rINST, (%edx, %ecx)     # object field<- vA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IPUT_BYTE */
-
-.LOP_IPUT_BYTE_finish:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    lea         -8(%esp), %esp
-    movl        %edx, (%esp)            # push parameter method->clazz
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    lea         8(%esp), %esp
-    cmp         $0, %eax               # check if resolved
-    jne         .LOP_IPUT_BYTE_finish2
-    jmp         common_exceptionThrown  # not resolved; handle exception
-
-.LOP_IPUT_BYTE_finish2:
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vA
-    movl     rINST, (%edx, %ecx)     # object field<- vA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IPUT_CHAR */
-
-.LOP_IPUT_CHAR_finish:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    lea         -8(%esp), %esp
-    movl        %edx, (%esp)            # push parameter method->clazz
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    lea         8(%esp), %esp
-    cmp         $0, %eax               # check if resolved
-    jne         .LOP_IPUT_CHAR_finish2
-    jmp         common_exceptionThrown  # not resolved; handle exception
-
-.LOP_IPUT_CHAR_finish2:
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vA
-    movl     rINST, (%edx, %ecx)     # object field<- vA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_IPUT_SHORT */
-
-.LOP_IPUT_SHORT_finish:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    lea         -8(%esp), %esp
-    movl        %edx, (%esp)            # push parameter method->clazz
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    lea         8(%esp), %esp
-    cmp         $0, %eax               # check if resolved
-    jne         .LOP_IPUT_SHORT_finish2
-    jmp         common_exceptionThrown  # not resolved; handle exception
-
-.LOP_IPUT_SHORT_finish2:
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $4, %ecx               # %ecx<- B
-    and         $15, rINST             # rINST<- A
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vA
-    movl     rINST, (%edx, %ecx)     # object field<- vA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SGET */
-
-.LOP_SGET_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    mov         %eax, %ecx              # %ecx<- result
-
-.LOP_SGET_finish:
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl offStaticField_value(%ecx), %eax # %eax<- field value
-    SET_VREG    %eax, rINST             # vAA<- field value
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SGET_WIDE */
-
-   /*
-    * Continuation if the field has not yet been resolved.
-    *  %edx: BBBB field ref
-    */
-
-.LOP_SGET_WIDE_resolve:
-    movl        offGlue_method(%eax), %eax # %eax <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %edx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%eax), %eax # %eax<- method->clazz
-    movl        %eax, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    lea         8(%esp), %esp
-    cmp         $0, %eax               # check if initalization failed
-    movl        %eax, %ecx              # %ecx<- result
-    jne         .LOP_SGET_WIDE_finish      # success, continue
-    jmp         common_exceptionThrown  # failed; handle exception
-
-/* continuation for OP_SGET_OBJECT */
-
-.LOP_SGET_OBJECT_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    mov         %eax, %ecx              # %ecx<- result
-
-.LOP_SGET_OBJECT_finish:
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl offStaticField_value(%ecx), %eax # %eax<- field value
-    SET_VREG    %eax, rINST             # vAA<- field value
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SGET_BOOLEAN */
-
-.LOP_SGET_BOOLEAN_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    mov         %eax, %ecx              # %ecx<- result
-
-.LOP_SGET_BOOLEAN_finish:
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl offStaticField_value(%ecx), %eax # %eax<- field value
-    SET_VREG    %eax, rINST             # vAA<- field value
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SGET_BYTE */
-
-.LOP_SGET_BYTE_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    mov         %eax, %ecx              # %ecx<- result
-
-.LOP_SGET_BYTE_finish:
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl offStaticField_value(%ecx), %eax # %eax<- field value
-    SET_VREG    %eax, rINST             # vAA<- field value
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SGET_CHAR */
-
-.LOP_SGET_CHAR_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    mov         %eax, %ecx              # %ecx<- result
-
-.LOP_SGET_CHAR_finish:
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl offStaticField_value(%ecx), %eax # %eax<- field value
-    SET_VREG    %eax, rINST             # vAA<- field value
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SGET_SHORT */
-
-.LOP_SGET_SHORT_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    mov         %eax, %ecx              # %ecx<- result
-
-.LOP_SGET_SHORT_finish:
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl offStaticField_value(%ecx), %eax # %eax<- field value
-    SET_VREG    %eax, rINST             # vAA<- field value
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SPUT */
-
-.LOP_SPUT_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    movl        %eax, %ecx              # %ecx<- result
-
-.LOP_SPUT_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, offStaticField_value(%ecx) # field value<- vAA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SPUT_WIDE */
-
-   /*
-    * Continuation if the field has not yet been resolved.
-    *  %edx: BBBB field ref
-    */
-
-.LOP_SPUT_WIDE_resolve:
-    movl        offGlue_method(%eax), %eax # %eax <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %edx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%eax), %eax # %eax<- method->clazz
-    movl        %eax, -8(%esp)
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    lea         8(%esp), %esp
-    cmp         $0, %eax               # check if initalization failed
-    movl        %eax, %ecx              # %ecx<- result
-    jne         .LOP_SPUT_WIDE_finish      # success, continue
-    jmp         common_exceptionThrown  # failed; handle exception
-
-/* continuation for OP_SPUT_OBJECT */
-
-.LOP_SPUT_OBJECT_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    movl        %eax, %ecx              # %ecx<- result
-
-.LOP_SPUT_OBJECT_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vAA
-
-
-    movl        rINST, offStaticField_value(%ecx) # field value<- vAA
-    testl       rINST, rINST            # stored null object ptr?
-    je          1f
-    movl        rGLUE, %edx             # get glue
-    movl        offField_clazz(%ecx), %ecx # ecx<- field->clazz
-    movl        offGlue_cardTable(%edx), %edx # get card table base
-    shrl        $GC_CARD_SHIFT, %ecx   # head to card number
-    movb        %dl, (%edx, %ecx)       # mark card
-1:
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SPUT_BOOLEAN */
-
-.LOP_SPUT_BOOLEAN_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    movl        %eax, %ecx              # %ecx<- result
-
-.LOP_SPUT_BOOLEAN_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, offStaticField_value(%ecx) # field value<- vAA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SPUT_BYTE */
-
-.LOP_SPUT_BYTE_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    movl        %eax, %ecx              # %ecx<- result
-
-.LOP_SPUT_BYTE_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, offStaticField_value(%ecx) # field value<- vAA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SPUT_CHAR */
-
-.LOP_SPUT_CHAR_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    movl        %eax, %ecx              # %ecx<- result
-
-.LOP_SPUT_CHAR_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, offStaticField_value(%ecx) # field value<- vAA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_SPUT_SHORT */
-
-.LOP_SPUT_SHORT_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    movl        %eax, %ecx              # %ecx<- result
-
-.LOP_SPUT_SHORT_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, offStaticField_value(%ecx) # field value<- vAA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_INVOKE_VIRTUAL */
-
-.LOP_INVOKE_VIRTUAL_break:
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        %edx, -4(%esp)          # save "this" pointer register
-    movl        offGlue_method(%eax), %eax # %eax<- glue->method
-    movl        $METHOD_VIRTUAL, -8(%esp) # push parameter method type
-    movl        %ecx, -12(%esp)         # push paramter method index
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    lea         -16(%esp), %esp
-    movl        %eax, (%esp)            # push parameter clazz
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check for null method return
-    movl        -4(%esp), %edx          # get "this" pointer register
-    jne         .LOP_INVOKE_VIRTUAL_continue
-    jmp         common_exceptionThrown  # null pointer; handle exception
-
-   /*
-    * At this point:
-    *  %eax = resolved base method
-    *  %edx = D or CCCC (index of first arg, which is the "this" ptr)
-    */
-
-.LOP_INVOKE_VIRTUAL_continue:
-    GET_VREG    %edx                    # %edx<- "this" ptr
-    movzwl      offMethod_methodIndex(%eax), %eax # %eax<- baseMethod->methodIndex
-    cmp         $0, %edx               # %edx<- check for null "this"
-    je          common_errNullObject    # handle null object
-    movl        offObject_clazz(%edx), %edx # %edx<- thisPtr->clazz
-    movl        offClassObject_vtable(%edx), %edx # %edx<- thisPtr->clazz->vtable
-    movl        (%edx, %eax, 4), %ecx   # %ecx<- vtable[methodIndex]
-    jmp         common_invokeMethodNoRange # invoke method common code
-
-/* continuation for OP_INVOKE_SUPER */
-
-.LOP_INVOKE_SUPER_continue2:
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_method(%eax), %eax # %eax<- glue->method
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    EXPORT_PC                           # must export for invoke
-    cmp         $0, %ecx               # check if already resolved
-    jne         .LOP_INVOKE_SUPER_continue
-    jmp         .LOP_INVOKE_SUPER_resolve     # handle resolve
-
-   /*
-    *  %ecx = resolved base method
-    *  %eax = method->clazz
-    */
-
-.LOP_INVOKE_SUPER_continue:
-    movl        offClassObject_super(%eax), %edx # %edx<- glue->method->clazz->super
-    movzwl      offMethod_methodIndex(%ecx), %ecx # %ecx<-  baseMethod->methodIndex
-    cmp          offClassObject_vtableCount(%edx), %ecx # compare vtableCount with methodIndex
-    EXPORT_PC                           # must export for invoke
-    jnc         .LOP_INVOKE_SUPER_nsm         # handle method not present
-    movl        offClassObject_vtable(%edx), %edx # %edx<- glue->method->clazz->super->vtable
-    movl        (%edx, %ecx, 4), %ecx   # %ecx<- vtable[methodIndex]
-    jmp         common_invokeMethodNoRange # invoke method common code
-
-.LOP_INVOKE_SUPER_resolve:
-    movl        %eax, -12(%esp)         # push parameter clazz
-    movl        %edx, -8(%esp)          # push parameter method index
-    movl        $METHOD_VIRTUAL, -4(%esp) # push parameter method type
-    lea         -12(%esp), %esp
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         12(%esp), %esp
-    movl        %eax, %ecx              # %ecx<- method
-    cmp         $0, %ecx               # check for null method return
-    movl        -12(%esp), %eax         # %eax<- glue->method->clazz
-    jne         .LOP_INVOKE_SUPER_continue
-    jmp         common_exceptionThrown  # null pointer; handle exception
-
-   /*
-    * Throw a NoSuchMethodError with the method name as the message.
-    * %ecx = resolved base method
-    */
-
-.LOP_INVOKE_SUPER_nsm:
-    movl        offMethod_name(%ecx), %edx # %edx<- method name
-    jmp         common_errNoSuchMethod
-
-/* continuation for OP_INVOKE_DIRECT */
-
-   /*
-    * %eax = reference (BBBB or CCCC)
-    * -4(%esp) = "this" register
-    */
-
-.LOP_INVOKE_DIRECT_resolve:
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        $METHOD_DIRECT, -8(%esp) # push parameter method type
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        %eax, -12(%esp)         # push parameter reference
-    lea         -16(%esp), %esp
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, (%esp)            # push parameter clazz
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check for null method return
-    movl        -4(%esp), %edx          # get "this" pointer register
-    GET_VREG    %edx                    # get "this" pointer
-    je          common_exceptionThrown  # null pointer; handle exception
-    cmp         $0, %edx               # check for null "this"
-    movl        %eax, %ecx              # %ecx<- method
-    jne         common_invokeMethodNoRange # invoke method common code
-    jmp         common_errNullObject    # handle null object
-
-/* continuation for OP_INVOKE_STATIC */
-
-.LOP_INVOKE_STATIC_break:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        $METHOD_STATIC, -4(%esp) # resolver method type
-    movl        %eax, -8(%esp)          # push parameter method index
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, -12(%esp)         # push parameter method
-    lea         -12(%esp), %esp
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         12(%esp), %esp
-    cmp         $0, %eax               # check for null method
-    je          common_exceptionThrown
-    movl        %eax, %ecx              # %ecx<- method
-    jmp         common_invokeMethodNoRange # invoke method common code
-
-/* continuation for OP_INVOKE_INTERFACE */
-.LOP_INVOKE_INTERFACE_break:
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_method(%ecx), %ecx # %ecx<- glue->method
-    movl        %ecx, -8(%esp)          # push parameter method
-    movl        offObject_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, -16(%esp)         # push parameter
-    lea         -16(%esp), %esp
-    call        dvmFindInterfaceMethodInCache # call: (ClassObject* thisClass, u4 methodIdx,
-                                              #       const Method* method, DvmDex* methodClassDex)
-                                              # return: Method*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check if find failed
-    je          common_exceptionThrown  # handle exception
-    movl        %eax, %ecx              # %ecx<- method
-    jmp         common_invokeMethodNoRange # invoke method common code
-
-/* continuation for OP_INVOKE_VIRTUAL_RANGE */
-
-.LOP_INVOKE_VIRTUAL_RANGE_break:
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        %edx, -4(%esp)          # save "this" pointer register
-    movl        offGlue_method(%eax), %eax # %eax<- glue->method
-    movl        $METHOD_VIRTUAL, -8(%esp) # push parameter method type
-    movl        %ecx, -12(%esp)         # push paramter method index
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    lea         -16(%esp), %esp
-    movl        %eax, (%esp)            # push parameter clazz
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check for null method return
-    movl        -4(%esp), %edx          # get "this" pointer register
-    jne         .LOP_INVOKE_VIRTUAL_RANGE_continue
-    jmp         common_exceptionThrown  # null pointer; handle exception
-
-   /*
-    * At this point:
-    *  %eax = resolved base method
-    *  %edx = D or CCCC (index of first arg, which is the "this" ptr)
-    */
-
-.LOP_INVOKE_VIRTUAL_RANGE_continue:
-    GET_VREG    %edx                    # %edx<- "this" ptr
-    movzwl      offMethod_methodIndex(%eax), %eax # %eax<- baseMethod->methodIndex
-    cmp         $0, %edx               # %edx<- check for null "this"
-    je          common_errNullObject    # handle null object
-    movl        offObject_clazz(%edx), %edx # %edx<- thisPtr->clazz
-    movl        offClassObject_vtable(%edx), %edx # %edx<- thisPtr->clazz->vtable
-    movl        (%edx, %eax, 4), %ecx   # %ecx<- vtable[methodIndex]
-    jmp         common_invokeMethodRange # invoke method common code
-
-/* continuation for OP_INVOKE_SUPER_RANGE */
-
-.LOP_INVOKE_SUPER_RANGE_continue2:
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_method(%eax), %eax # %eax<- glue->method
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    EXPORT_PC                           # must export for invoke
-    cmp         $0, %ecx               # check if already resolved
-    jne         .LOP_INVOKE_SUPER_RANGE_continue
-    jmp         .LOP_INVOKE_SUPER_RANGE_resolve     # handle resolve
-
-   /*
-    *  %ecx = resolved base method
-    *  %eax = method->clazz
-    */
-
-.LOP_INVOKE_SUPER_RANGE_continue:
-    movl        offClassObject_super(%eax), %edx # %edx<- glue->method->clazz->super
-    movzwl      offMethod_methodIndex(%ecx), %ecx # %ecx<-  baseMethod->methodIndex
-    cmp          offClassObject_vtableCount(%edx), %ecx # compare vtableCount with methodIndex
-    EXPORT_PC                           # must export for invoke
-    jnc         .LOP_INVOKE_SUPER_RANGE_nsm         # handle method not present
-    movl        offClassObject_vtable(%edx), %edx # %edx<- glue->method->clazz->super->vtable
-    movl        (%edx, %ecx, 4), %ecx   # %ecx<- vtable[methodIndex]
-    jmp         common_invokeMethodRange # invoke method common code
-
-.LOP_INVOKE_SUPER_RANGE_resolve:
-    movl        %eax, -12(%esp)         # push parameter clazz
-    movl        %edx, -8(%esp)          # push parameter method index
-    movl        $METHOD_VIRTUAL, -4(%esp) # push parameter method type
-    lea         -12(%esp), %esp
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         12(%esp), %esp
-    movl        %eax, %ecx              # %ecx<- method
-    cmp         $0, %ecx               # check for null method return
-    movl        -12(%esp), %eax         # %eax<- glue->method->clazz
-    jne         .LOP_INVOKE_SUPER_RANGE_continue
-    jmp         common_exceptionThrown  # null pointer; handle exception
-
-   /*
-    * Throw a NoSuchMethodError with the method name as the message.
-    * %ecx = resolved base method
-    */
-
-.LOP_INVOKE_SUPER_RANGE_nsm:
-    movl        offMethod_name(%ecx), %edx # %edx<- method name
-    jmp         common_errNoSuchMethod
-
-/* continuation for OP_INVOKE_DIRECT_RANGE */
-
-   /*
-    * %eax = reference (BBBB or CCCC)
-    * -4(%esp) = "this" register
-    */
-
-.LOP_INVOKE_DIRECT_RANGE_resolve:
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        $METHOD_DIRECT, -8(%esp) # push parameter method type
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        %eax, -12(%esp)         # push parameter reference
-    lea         -16(%esp), %esp
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, (%esp)            # push parameter clazz
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check for null method return
-    movl        -4(%esp), %edx          # get "this" pointer register
-    GET_VREG    %edx                    # get "this" pointer
-    je          common_exceptionThrown  # null pointer; handle exception
-    cmp         $0, %edx               # check for null "this"
-    movl        %eax, %ecx              # %ecx<- method
-    jne         common_invokeMethodRange # invoke method common code
-    jmp         common_errNullObject    # handle null object
-
-/* continuation for OP_INVOKE_STATIC_RANGE */
-
-.LOP_INVOKE_STATIC_RANGE_break:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        $METHOD_STATIC, -4(%esp) # resolver method type
-    movl        %eax, -8(%esp)          # push parameter method index
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, -12(%esp)         # push parameter method
-    lea         -12(%esp), %esp
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         12(%esp), %esp
-    cmp         $0, %eax               # check for null method
-    je          common_exceptionThrown
-    movl        %eax, %ecx              # %ecx<- method
-    jmp         common_invokeMethodRange # invoke method common code
-
-/* continuation for OP_INVOKE_INTERFACE_RANGE */
-.LOP_INVOKE_INTERFACE_RANGE_break:
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_method(%ecx), %ecx # %ecx<- glue->method
-    movl        %ecx, -8(%esp)          # push parameter method
-    movl        offObject_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, -16(%esp)         # push parameter
-    lea         -16(%esp), %esp
-    call        dvmFindInterfaceMethodInCache # call: (ClassObject* thisClass, u4 methodIdx,
-                                              #       const Method* method, DvmDex* methodClassDex)
-                                              # return: Method*
-    lea         16(%esp), %esp
-    cmp         $0, %eax               # check if find failed
-    je          common_exceptionThrown  # handle exception
-    movl        %eax, %ecx              # %ecx<- method
-    jmp         common_invokeMethodRange # invoke method common code
-
-/* continuation for OP_FLOAT_TO_INT */
-
-.LOP_FLOAT_TO_INT_break:
-    fnstcw      -2(%esp)                # save control word
-    orl         $0xc00, -2(%esp)       # reset control
-    fldcw       -2(%esp)                # load control word
-    xorl        $0xc00, -2(%esp)       # reset control
-    fistpl      (rFP, %edx, 4)          # move converted int
-    fldcw       -2(%esp)                # load saved control word
-    FINISH      1                       # jump to next instruction
-
-.LOP_FLOAT_TO_INT_nanInf:
-    jnp         .LOP_FLOAT_TO_INT_posInf      # handle posInf
-    fstps       (rFP, %edx, 4)          # pop floating point stack
-    movl        $0x00000000,  (rFP, %edx, 4) # vA<- NaN
-    FINISH      1                       # jump to next instruction
-
-.LOP_FLOAT_TO_INT_posInf:
-    fstps       (rFP, %edx, 4)          # pop floating point stack
-    movl        $0x7FFFFFFF,  (rFP, %edx, 4) # vA<- posInf
-    FINISH      1                       # jump to next instruction
-
-.LOP_FLOAT_TO_INT_negInf:
-    fstps       (rFP, %edx, 4)          # pop floating point stack
-    fstps       (rFP, %edx, 4)          # pop floating point stack
-    movl        $0x80000000, (rFP, %edx, 4) # vA<- negInf
-    FINISH      1                       # jump to next instruction
-
-/* continuation for OP_FLOAT_TO_LONG */
-
-.LOP_FLOAT_TO_LONG_break:
-    fnstcw      -2(%esp)                # save control word
-    orl         $0xc00, -2(%esp)       # update control
-    fldcw       -2(%esp)                # load control word
-    xorl        $0xc00, -2(%esp)       # reset control
-    fistpll     (rFP, %edx, 4)          # move converted int
-    fldcw       -2(%esp)                # load saved control word
-    FINISH      1                       # jump to next instruction
-
-.LOP_FLOAT_TO_LONG_nanInf:
-    jnp         .LOP_FLOAT_TO_LONG_posInf
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvalueNanLong, %xmm0   # %xmm0<- NaN
-    movq        %xmm0,  (rFP, %edx, 4)  # vA<- %xmm0; NaN
-    FINISH      1                       # jump to next instruction
-
-.LOP_FLOAT_TO_LONG_posInf:
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvaluePosInfLong, %xmm0 # %xmm0<- posInf
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; posInf
-    FINISH      1                       # jump to next instruction
-
-.LOP_FLOAT_TO_LONG_negInf:
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvalueNegInfLong, %xmm0 # %xmm0<- negInf
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; negInf
-    FINISH      1                       # jump to next instruction
-
-/* continuation for OP_DOUBLE_TO_INT */
-
-.LOP_DOUBLE_TO_INT_break:
-    fnstcw      -2(%esp)                # save control word
-    orl         $0xc00, -2(%esp)       # reset control
-    fldcw       -2(%esp)                # load control word
-    xorl        $0xc00, -2(%esp)       # reset control
-    fistpl      (rFP, %edx, 4)          # move converted int
-    fldcw       -2(%esp)                # load saved control word
-    FINISH      1                       # jump to next instruction
-
-.LOP_DOUBLE_TO_INT_nanInf:
-    jnp         .LOP_DOUBLE_TO_INT_posInf
-    fstps       (rFP, %edx, 4)
-    movl        $0x00000000,  (rFP, %edx, 4) # vA<- NaN
-    FINISH      1                       # jump to next instruction
-
-.LOP_DOUBLE_TO_INT_posInf:
-    fstps       (rFP, %edx, 4)
-    movl        $0x7FFFFFFF,  (rFP, %edx, 4) # vA<- posInf
-    FINISH      1                       # jump to next instruction
-
-.LOP_DOUBLE_TO_INT_negInf:
-    fstps       (rFP, %edx, 4)
-    fstps       (rFP, %edx, 4)
-    movl        $0x80000000,  (rFP, %edx, 4) # vA<- negInf
-    FINISH      1                       # jump to next instruction
-
-/* continuation for OP_DOUBLE_TO_LONG */
-
-.LOP_DOUBLE_TO_LONG_break:
-    fnstcw      -2(%esp)                # save control word
-    orl         $0xc00, -2(%esp)       # reset control
-    fldcw       -2(%esp)                # load control word
-    xorl        $0xc00, -2(%esp)       # reset control
-    fistpll     (rFP, %edx, 4)          # move converted int
-    fldcw       -2(%esp)                # load saved control word
-    FINISH      1                       # jump to next instruction
-
-.LOP_DOUBLE_TO_LONG_nanInf:
-    jnp         .LOP_DOUBLE_TO_LONG_posInf
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvalueNanLong, %xmm0   # %xmm0<- NaN
-    movq        %xmm0,  (rFP, %edx, 4)  # vA<- %xmm0; NaN
-    FINISH      1                       # jump to next instruction
-
-.LOP_DOUBLE_TO_LONG_posInf:
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvaluePosInfLong, %xmm0 # %xmm0<- posInf
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; posInf
-    FINISH      1                       # jump to next instruction
-
-.LOP_DOUBLE_TO_LONG_negInf:
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvalueNegInfLong, %xmm0 # %xmm0<- negInf
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; negInf
-    FINISH      1                       # jump to next instruction
-
-/* continuation for OP_DIV_INT */
-.LOP_DIV_INT_break:
-    .if  1
-    movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-.LOP_DIV_INT_break2:
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_REM_INT */
-.LOP_REM_INT_break:
-    .if  0
-    movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-.LOP_REM_INT_break2:
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_MUL_LONG */
-
-   /*
-    * X = (rFP, rINST, 4)
-    * W = 4(rFP, rINST, 4)
-    * Z = (rFP, %edx, 4)
-    * Y = 4(rFP, %edx, 4)
-    */
-
-.LOP_MUL_LONG_finish:
-    movl        4(rFP, rINST, 4), %ecx  # %ecx<- W
-    imull       (rFP, %edx, 4),  %ecx   # %ecx<- WxZ
-    mov         4(rFP, %edx, 4), %eax   # %ecx<- Y
-    imull       (rFP, rINST, 4), %eax   # %eax<- XxY
-    addl        %eax, %ecx              # %ecx<- (WZ + XY)
-    movl        (rFP, %edx, 4), %eax    # %eax<- Z
-    mull        (rFP, rINST, 4)         # %edx:eax<- XZ
-    movzbl      -4(%esp), rINST         # rINST<- AA
-    addl        %edx, %ecx              # %ecx<- carry + (WZ + XY)
-    movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- results hi
-    movl        %eax, (rFP, rINST, 4)   # vAA<- results lo
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_DIV_LONG */
-.LOP_DIV_LONG_finish:
-    movq        %xmm0, -16(%esp)        # push arg vBB,vBB+1
-    lea         -16(%esp), %esp
-    call        __divdi3                   # call func
-    lea         16(%esp), %esp
-    movl        %eax, (rFP, rINST, 4)   # vAA<- return low
-    movl        %edx, 4(rFP, rINST, 4)  # vAA+1<- return high
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_REM_LONG */
-.LOP_REM_LONG_finish:
-    movq        %xmm0, -16(%esp)        # push arg vBB,vBB+1
-    lea         -16(%esp), %esp
-    call        __moddi3                   # call func
-    lea         16(%esp), %esp
-    movl        %eax, (rFP, rINST, 4)   # vAA<- return low
-    movl        %edx, 4(rFP, rINST, 4)  # vAA+1<- return high
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_SHR_LONG */
-
-.LOP_SHR_LONG_finish:
-    movq        .Lvalue64, %xmm3        # %xmm3<- 64
-    psubq       %xmm0, %xmm3            # %xmm3<- 64 - shift amount
-    movq        .L64bits, %xmm4         # %xmm4<- lower 64 bits set
-    psllq       %xmm3, %xmm4            # %xmm4<- correct mask for sign bits
-    por         %xmm4, %xmm1            # %xmm1<- signed and shifted vBB
-
-.LOP_SHR_LONG_final:
-    movq        %xmm1, (rFP, rINST, 4)  # vAA<- shifted vBB
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_REM_DOUBLE */
-
-.LOP_REM_DOUBLE_break:
-    call        fmod                    # call: (long double x, long double y)
-                                        # return: double
-    lea         16(%esp), %esp
-    fstpl       (rFP, rINST, 4)         # vAA<- remainder; return of fmod
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_DIV_INT_2ADDR */
-.LOP_DIV_INT_2ADDR_break:
-    .if  1
-    movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-.LOP_DIV_INT_2ADDR_break2:
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-
-/* continuation for OP_REM_INT_2ADDR */
-.LOP_REM_INT_2ADDR_break:
-    .if  0
-    movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-.LOP_REM_INT_2ADDR_break2:
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-
-/* continuation for OP_MUL_LONG_2ADDR */
-
-   /*
-    * X = (rFP, rINST, 4)
-    * W = 4(rFP, rINST, 4)
-    * Z = (rFP, %edx, 4)
-    * Y = 4(rFP, %edx, 4)
-    */
-
-.LOP_MUL_LONG_2ADDR_finish:
-    movl        4(rFP, rINST, 4), %ecx  # %ecx<- W
-    imull       (rFP, %edx, 4), %ecx    # %ecx<- WxZ
-    movl                4(rFP, %edx, 4), %eax   # %eax<- Y
-    imull       (rFP, rINST, 4), %eax   # %eax<- X*Y
-    addl        %eax, %ecx              # %ecx<- (WZ + XY)
-    movl        (rFP, %edx, 4), %eax    # %eax<- Z
-    mull        (rFP, rINST, 4)         # %edx:eax<- XZ
-    addl        %edx, %ecx              # %ecx<- carry + (WZ + XY)
-    movl        sReg0, %edx             # %edx<- A
-    movl        %ecx, 4(rFP, %edx, 4)   # vA+1<- results hi
-    movl        %eax, (rFP, %edx, 4)    # vA<- results lo
-    FINISH      1                       # jump to next instruction
-
-/* continuation for OP_DIV_LONG_2ADDR */
-.LOP_DIV_LONG_2ADDR_break:
-    movq        %xmm0, -20(%esp)        # push arg vA, vA+1
-    lea         -20(%esp), %esp
-    call        __divdi3                   # call func
-    lea         20(%esp), %esp
-    movl        %eax, (rFP, rINST, 4)   # vA<- return low
-    movl        %edx, 4(rFP, rINST, 4)  # vA<- return high
-    FFETCH_ADV  1, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    FGETOP_JMP 1, %ecx                  # jump to next instruction; getop, jmp
-
-/* continuation for OP_REM_LONG_2ADDR */
-.LOP_REM_LONG_2ADDR_break:
-    movq        %xmm0, -20(%esp)        # push arg vA, vA+1
-    lea         -20(%esp), %esp
-    call        __moddi3                   # call func
-    lea         20(%esp), %esp
-    movl        %eax, (rFP, rINST, 4)   # vA<- return low
-    movl        %edx, 4(rFP, rINST, 4)  # vA<- return high
-    FFETCH_ADV  1, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    FGETOP_JMP 1, %ecx                  # jump to next instruction; getop, jmp
-
-/* continuation for OP_SHR_LONG_2ADDR */
-
-.LOP_SHR_LONG_2ADDR_finish:
-    movq        .Lvalue64, %xmm3        # %xmm3<- 64
-    psubq       %xmm0, %xmm3            # %xmm3<- 64 - shift amount
-    movq        .L64bits, %xmm4         # %xmm4<- lower 64 bits set
-    psllq       %xmm3, %xmm4            # %xmm4<- correct mask for sign bits
-    por         %xmm4, %xmm1            # %xmm1<- signed and shifted vBB
-
-.LOP_SHR_LONG_2ADDR_final:
-    movq        %xmm1, (rFP, rINST, 4)  # vAA<- shifted vBB
-    FINISH      1                       # jump to next instruction
-
-/* continuation for OP_REM_DOUBLE_2ADDR */
-
-.LOP_REM_DOUBLE_2ADDR_break:
-    call        fmod                    # call: (long double x, long double y)
-                                        # return: double
-    lea         20(%esp), %esp
-    fstpl       (rFP, rINST, 4)         # vAA<- remainder; return of fmod
-    FINISH      1                       # jump to next instruction
-
-/* continuation for OP_DIV_INT_LIT16 */
-.LOP_DIV_INT_LIT16_break:
-    .if  1
-    movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-.LOP_DIV_INT_LIT16_break2:
-
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_REM_INT_LIT16 */
-.LOP_REM_INT_LIT16_break:
-    .if  0
-    movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-.LOP_REM_INT_LIT16_break2:
-
-    FINISH      2                       # jump to next instruction
-
-/* continuation for OP_DIV_INT_LIT8 */
-.LOP_DIV_INT_LIT8_break:
-    .if  1
-    movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-
-.LOP_DIV_INT_LIT8_break2:
-    FINISH      2                       # jump to next instruction
-    #FGETOP_JMP 2, %ecx                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_REM_INT_LIT8 */
-.LOP_REM_INT_LIT8_break:
-    .if  0
-    movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-
-.LOP_REM_INT_LIT8_break2:
-    FINISH      2                       # jump to next instruction
-    #FGETOP_JMP 2, %ecx                 # jump to next instruction; getop, jmp
-
-/* continuation for OP_EXECUTE_INLINE */
-
-   /*
-    * Extract args, call function.
-    *  rINST = #of args (0-4)
-    *  %ecx = call index
-    */
-
-.LOP_EXECUTE_INLINE_continue:
-    FETCH       2, %edx                 # %edx<- FEDC
-    cmp         $1, rINST              # determine number of arguments
-    jl          0f                      # handle zero args
-    je          1f                      # handle one arg
-    cmp         $3, rINST
-    jl          2f                      # handle two args
-    je          3f                      # handle three args
-4:
-    movl        %edx, rINST             # rINST<- FEDC
-    and         $0xf000, rINST         # isolate F
-    shr         $10, rINST
-    movl        (rFP, rINST), rINST     # rINST<- vF
-    movl        rINST, 12(%esp)         # push parameter vF
-3:
-    movl        %edx, rINST             # rINST<- FEDC
-    and         $0x0f00, rINST         # isolate E
-    shr         $6, rINST
-    movl        (rFP, rINST), rINST     # rINST<- vE
-    movl        rINST, 8(%esp)          # push parameter E
-2:
-    movl        %edx, rINST             # rINST<- FEDC
-    and         $0x00f0, rINST         # isolate D
-    shr         $2, rINST
-    movl        (rFP, rINST), rINST     # rINST<- vD
-    movl        rINST, 4(%esp)          # push parameter D
-1:
-    and         $0x000f, %edx          # isolate C
-    movl        (rFP, %edx, 4), %edx    # rINST<- vC
-    movl        %edx, (%esp)            # push parameter C
-0:
-    shl         $4, %ecx
-    movl        $gDvmInlineOpsTable, %eax # %eax<- address for table of inline operations
-    call        *(%eax, %ecx)           # call function
-
-    cmp         $0, %eax               # check boolean result of inline
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    lea         24(%esp), %esp          # update stack pointer
-    je          common_exceptionThrown  # handle exception
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
-
-    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
-    .global dvmAsmSisterEnd
-dvmAsmSisterEnd:
-
-/* File: x86-atom/entry.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: entry.S
-    */
-
-#define ASSIST_DEBUGGER 1
-    .text
-    .align      2
-    .global     dvmMterpStdRun
-    .type       dvmMterpStdRun, %function
-
-   /*
-    * Save registers, initialize sp and fp.
-    * On entry:
-    *     bool MterpGlue(glue *)
-    */
-
-    .macro      MTERP_ENTRY
-    movl        4(%esp), %ecx           # get first argument
-    movl        %ebp, -4(%esp)          # save caller base pointer
-    movl        %ebx, -8(%esp)          # save %ebx
-    movl        %esi, -12(%esp)         # save %esi
-    movl        %edi, -16(%esp)         # save %edi
-    lea         -40(%esp), %ebp         # set callee base pointer
-    lea         -40(%esp), %esp         # set callee stack pointer
-    .endm
-
-   /*
-    * Restore registers.
-    * This function returns a boolean "changeInterp" value.
-    * The return value is from dvmMterpStdBail().
-    */
-
-    .macro      MTERP_EXIT
-    lea         40(%esp), %esp          # correct stack pointer
-    movl        -16(%esp), %edi         # restore %edi
-    movl        -12(%esp), %esi         # restore %esi
-    movl        -8(%esp), %ebx          # restore %ebx
-    movl        -4(%esp), %ebp          # restore caller base pointer
-    ret                                 # return
-    .endm
-
-   /*
-    * DvmMterpStdRun entry point: save stack pointer, setup memory locations, get
-    * entry point, start executing instructions.
-    */
-
-dvmMterpStdRun:
-    MTERP_ENTRY
-    movl        %ecx, rGLUE             # save value for pMterpGlue
-    movl        offGlue_pc(%ecx), rPC   # get program counter
-    cmp         $kInterpEntryInstr, offGlue_entryPoint(%ecx) # check instruction
-    movl        offGlue_fp(%ecx), rFP   # get frame pointer
-    movl        %esp, offGlue_bailPtr(%ecx) # save SP for eventual return
-    FFETCH      %edx                    # %edx<- opcode
-    jne         .Lnot_instr             # no, handle it
-    FGETOP_JMPa %edx                    # start executing the instruction at rPC
-
-   /*
-    * Not an instruction. Are we returning from a method?
-    */
-
-.Lnot_instr:
-    cmpl        $kInterpEntryReturn, offGlue_entryPoint(%ecx)
-    je          common_returnFromMethod
-
-   /*
-    * No, are we throwing an exception?
-    */
-
-.Lnot_return:
-    cmpl        $kInterpEntryThrow, offGlue_entryPoint(%ecx)
-    je          common_exceptionThrown
-
-   /*
-    * No, then we must abort.
-    */
-
-.Lbad_arg:
-    pushl       offGlue_entryPoint(%ecx)
-    movl        $.LstrBadEntryPoint, -4(%esp)
-    lea         -4(%esp), %esp
-    call        printf
-    lea         8(%esp), %esp
-    call        dvmAbort                # call (void)
-
-   /*
-    * Restore the stack pointer and PC from the save point established on entry and
-    * return to whoever called dvmMterpStdRun.
-    *
-    * On entry:
-    *  4(%esp) MterpGlue* glue
-    *  8(%esp) bool changeInterp
-    */
-
-    .global     dvmMterpStdBail
-    .type       dvmMterpStdBail, %function
-
-dvmMterpStdBail:
-    movl        4(%esp), %ecx           # get first argument
-    movl        8(%esp), %eax           # get second argument
-    movl        offGlue_bailPtr(%ecx), %esp # sp <- saved SP
-    MTERP_EXIT
-
-   /*
-    * String references.
-    */
-
-.LstrBadEntryPoint:
-    .asciz "Bad entry point %d\n"
-
-
-dvmAsmInstructionJmpTable = .LdvmAsmInstructionJmpTable
-.LdvmAsmInstructionJmpTable:
-.long .L_OP_NOP
-.long .L_OP_MOVE
-.long .L_OP_MOVE_FROM16
-.long .L_OP_MOVE_16
-.long .L_OP_MOVE_WIDE
-.long .L_OP_MOVE_WIDE_FROM16
-.long .L_OP_MOVE_WIDE_16
-.long .L_OP_MOVE_OBJECT
-.long .L_OP_MOVE_OBJECT_FROM16
-.long .L_OP_MOVE_OBJECT_16
-.long .L_OP_MOVE_RESULT
-.long .L_OP_MOVE_RESULT_WIDE
-.long .L_OP_MOVE_RESULT_OBJECT
-.long .L_OP_MOVE_EXCEPTION
-.long .L_OP_RETURN_VOID
-.long .L_OP_RETURN
-.long .L_OP_RETURN_WIDE
-.long .L_OP_RETURN_OBJECT
-.long .L_OP_CONST_4
-.long .L_OP_CONST_16
-.long .L_OP_CONST
-.long .L_OP_CONST_HIGH16
-.long .L_OP_CONST_WIDE_16
-.long .L_OP_CONST_WIDE_32
-.long .L_OP_CONST_WIDE
-.long .L_OP_CONST_WIDE_HIGH16
-.long .L_OP_CONST_STRING
-.long .L_OP_CONST_STRING_JUMBO
-.long .L_OP_CONST_CLASS
-.long .L_OP_MONITOR_ENTER
-.long .L_OP_MONITOR_EXIT
-.long .L_OP_CHECK_CAST
-.long .L_OP_INSTANCE_OF
-.long .L_OP_ARRAY_LENGTH
-.long .L_OP_NEW_INSTANCE
-.long .L_OP_NEW_ARRAY
-.long .L_OP_FILLED_NEW_ARRAY
-.long .L_OP_FILLED_NEW_ARRAY_RANGE
-.long .L_OP_FILL_ARRAY_DATA
-.long .L_OP_THROW
-.long .L_OP_GOTO
-.long .L_OP_GOTO_16
-.long .L_OP_GOTO_32
-.long .L_OP_PACKED_SWITCH
-.long .L_OP_SPARSE_SWITCH
-.long .L_OP_CMPL_FLOAT
-.long .L_OP_CMPG_FLOAT
-.long .L_OP_CMPL_DOUBLE
-.long .L_OP_CMPG_DOUBLE
-.long .L_OP_CMP_LONG
-.long .L_OP_IF_EQ
-.long .L_OP_IF_NE
-.long .L_OP_IF_LT
-.long .L_OP_IF_GE
-.long .L_OP_IF_GT
-.long .L_OP_IF_LE
-.long .L_OP_IF_EQZ
-.long .L_OP_IF_NEZ
-.long .L_OP_IF_LTZ
-.long .L_OP_IF_GEZ
-.long .L_OP_IF_GTZ
-.long .L_OP_IF_LEZ
-.long .L_OP_UNUSED_3E
-.long .L_OP_UNUSED_3F
-.long .L_OP_UNUSED_40
-.long .L_OP_UNUSED_41
-.long .L_OP_UNUSED_42
-.long .L_OP_UNUSED_43
-.long .L_OP_AGET
-.long .L_OP_AGET_WIDE
-.long .L_OP_AGET_OBJECT
-.long .L_OP_AGET_BOOLEAN
-.long .L_OP_AGET_BYTE
-.long .L_OP_AGET_CHAR
-.long .L_OP_AGET_SHORT
-.long .L_OP_APUT
-.long .L_OP_APUT_WIDE
-.long .L_OP_APUT_OBJECT
-.long .L_OP_APUT_BOOLEAN
-.long .L_OP_APUT_BYTE
-.long .L_OP_APUT_CHAR
-.long .L_OP_APUT_SHORT
-.long .L_OP_IGET
-.long .L_OP_IGET_WIDE
-.long .L_OP_IGET_OBJECT
-.long .L_OP_IGET_BOOLEAN
-.long .L_OP_IGET_BYTE
-.long .L_OP_IGET_CHAR
-.long .L_OP_IGET_SHORT
-.long .L_OP_IPUT
-.long .L_OP_IPUT_WIDE
-.long .L_OP_IPUT_OBJECT
-.long .L_OP_IPUT_BOOLEAN
-.long .L_OP_IPUT_BYTE
-.long .L_OP_IPUT_CHAR
-.long .L_OP_IPUT_SHORT
-.long .L_OP_SGET
-.long .L_OP_SGET_WIDE
-.long .L_OP_SGET_OBJECT
-.long .L_OP_SGET_BOOLEAN
-.long .L_OP_SGET_BYTE
-.long .L_OP_SGET_CHAR
-.long .L_OP_SGET_SHORT
-.long .L_OP_SPUT
-.long .L_OP_SPUT_WIDE
-.long .L_OP_SPUT_OBJECT
-.long .L_OP_SPUT_BOOLEAN
-.long .L_OP_SPUT_BYTE
-.long .L_OP_SPUT_CHAR
-.long .L_OP_SPUT_SHORT
-.long .L_OP_INVOKE_VIRTUAL
-.long .L_OP_INVOKE_SUPER
-.long .L_OP_INVOKE_DIRECT
-.long .L_OP_INVOKE_STATIC
-.long .L_OP_INVOKE_INTERFACE
-.long .L_OP_UNUSED_73
-.long .L_OP_INVOKE_VIRTUAL_RANGE
-.long .L_OP_INVOKE_SUPER_RANGE
-.long .L_OP_INVOKE_DIRECT_RANGE
-.long .L_OP_INVOKE_STATIC_RANGE
-.long .L_OP_INVOKE_INTERFACE_RANGE
-.long .L_OP_UNUSED_79
-.long .L_OP_UNUSED_7A
-.long .L_OP_NEG_INT
-.long .L_OP_NOT_INT
-.long .L_OP_NEG_LONG
-.long .L_OP_NOT_LONG
-.long .L_OP_NEG_FLOAT
-.long .L_OP_NEG_DOUBLE
-.long .L_OP_INT_TO_LONG
-.long .L_OP_INT_TO_FLOAT
-.long .L_OP_INT_TO_DOUBLE
-.long .L_OP_LONG_TO_INT
-.long .L_OP_LONG_TO_FLOAT
-.long .L_OP_LONG_TO_DOUBLE
-.long .L_OP_FLOAT_TO_INT
-.long .L_OP_FLOAT_TO_LONG
-.long .L_OP_FLOAT_TO_DOUBLE
-.long .L_OP_DOUBLE_TO_INT
-.long .L_OP_DOUBLE_TO_LONG
-.long .L_OP_DOUBLE_TO_FLOAT
-.long .L_OP_INT_TO_BYTE
-.long .L_OP_INT_TO_CHAR
-.long .L_OP_INT_TO_SHORT
-.long .L_OP_ADD_INT
-.long .L_OP_SUB_INT
-.long .L_OP_MUL_INT
-.long .L_OP_DIV_INT
-.long .L_OP_REM_INT
-.long .L_OP_AND_INT
-.long .L_OP_OR_INT
-.long .L_OP_XOR_INT
-.long .L_OP_SHL_INT
-.long .L_OP_SHR_INT
-.long .L_OP_USHR_INT
-.long .L_OP_ADD_LONG
-.long .L_OP_SUB_LONG
-.long .L_OP_MUL_LONG
-.long .L_OP_DIV_LONG
-.long .L_OP_REM_LONG
-.long .L_OP_AND_LONG
-.long .L_OP_OR_LONG
-.long .L_OP_XOR_LONG
-.long .L_OP_SHL_LONG
-.long .L_OP_SHR_LONG
-.long .L_OP_USHR_LONG
-.long .L_OP_ADD_FLOAT
-.long .L_OP_SUB_FLOAT
-.long .L_OP_MUL_FLOAT
-.long .L_OP_DIV_FLOAT
-.long .L_OP_REM_FLOAT
-.long .L_OP_ADD_DOUBLE
-.long .L_OP_SUB_DOUBLE
-.long .L_OP_MUL_DOUBLE
-.long .L_OP_DIV_DOUBLE
-.long .L_OP_REM_DOUBLE
-.long .L_OP_ADD_INT_2ADDR
-.long .L_OP_SUB_INT_2ADDR
-.long .L_OP_MUL_INT_2ADDR
-.long .L_OP_DIV_INT_2ADDR
-.long .L_OP_REM_INT_2ADDR
-.long .L_OP_AND_INT_2ADDR
-.long .L_OP_OR_INT_2ADDR
-.long .L_OP_XOR_INT_2ADDR
-.long .L_OP_SHL_INT_2ADDR
-.long .L_OP_SHR_INT_2ADDR
-.long .L_OP_USHR_INT_2ADDR
-.long .L_OP_ADD_LONG_2ADDR
-.long .L_OP_SUB_LONG_2ADDR
-.long .L_OP_MUL_LONG_2ADDR
-.long .L_OP_DIV_LONG_2ADDR
-.long .L_OP_REM_LONG_2ADDR
-.long .L_OP_AND_LONG_2ADDR
-.long .L_OP_OR_LONG_2ADDR
-.long .L_OP_XOR_LONG_2ADDR
-.long .L_OP_SHL_LONG_2ADDR
-.long .L_OP_SHR_LONG_2ADDR
-.long .L_OP_USHR_LONG_2ADDR
-.long .L_OP_ADD_FLOAT_2ADDR
-.long .L_OP_SUB_FLOAT_2ADDR
-.long .L_OP_MUL_FLOAT_2ADDR
-.long .L_OP_DIV_FLOAT_2ADDR
-.long .L_OP_REM_FLOAT_2ADDR
-.long .L_OP_ADD_DOUBLE_2ADDR
-.long .L_OP_SUB_DOUBLE_2ADDR
-.long .L_OP_MUL_DOUBLE_2ADDR
-.long .L_OP_DIV_DOUBLE_2ADDR
-.long .L_OP_REM_DOUBLE_2ADDR
-.long .L_OP_ADD_INT_LIT16
-.long .L_OP_RSUB_INT
-.long .L_OP_MUL_INT_LIT16
-.long .L_OP_DIV_INT_LIT16
-.long .L_OP_REM_INT_LIT16
-.long .L_OP_AND_INT_LIT16
-.long .L_OP_OR_INT_LIT16
-.long .L_OP_XOR_INT_LIT16
-.long .L_OP_ADD_INT_LIT8
-.long .L_OP_RSUB_INT_LIT8
-.long .L_OP_MUL_INT_LIT8
-.long .L_OP_DIV_INT_LIT8
-.long .L_OP_REM_INT_LIT8
-.long .L_OP_AND_INT_LIT8
-.long .L_OP_OR_INT_LIT8
-.long .L_OP_XOR_INT_LIT8
-.long .L_OP_SHL_INT_LIT8
-.long .L_OP_SHR_INT_LIT8
-.long .L_OP_USHR_INT_LIT8
-.long .L_OP_IGET_VOLATILE
-.long .L_OP_IPUT_VOLATILE
-.long .L_OP_SGET_VOLATILE
-.long .L_OP_SPUT_VOLATILE
-.long .L_OP_IGET_OBJECT_VOLATILE
-.long .L_OP_IGET_WIDE_VOLATILE
-.long .L_OP_IPUT_WIDE_VOLATILE
-.long .L_OP_SGET_WIDE_VOLATILE
-.long .L_OP_SPUT_WIDE_VOLATILE
-.long .L_OP_BREAKPOINT
-.long .L_OP_THROW_VERIFICATION_ERROR
-.long .L_OP_EXECUTE_INLINE
-.long .L_OP_EXECUTE_INLINE_RANGE
-.long .L_OP_INVOKE_OBJECT_INIT_RANGE
-.long .L_OP_RETURN_VOID_BARRIER
-.long .L_OP_IGET_QUICK
-.long .L_OP_IGET_WIDE_QUICK
-.long .L_OP_IGET_OBJECT_QUICK
-.long .L_OP_IPUT_QUICK
-.long .L_OP_IPUT_WIDE_QUICK
-.long .L_OP_IPUT_OBJECT_QUICK
-.long .L_OP_INVOKE_VIRTUAL_QUICK
-.long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE
-.long .L_OP_INVOKE_SUPER_QUICK
-.long .L_OP_INVOKE_SUPER_QUICK_RANGE
-.long .L_OP_IPUT_OBJECT_VOLATILE
-.long .L_OP_SGET_OBJECT_VOLATILE
-.long .L_OP_SPUT_OBJECT_VOLATILE
-.long .L_OP_UNUSED_FF
-
-/* File: x86-atom/footer.S */
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: footer.S
-    */
-
-    .text
-    .align      2
-
-   /*
-    * Check to see if the thread needs to be suspended or debugger/profiler
-    * activity has begun.
-    *
-    * On entry:
-    *  %ecx is reentry type, e.g. kInterpEntryInstr
-    *  %edx is PC adjustment in bytes
-    */
-
-common_periodicChecks:
-    movl        %edx, -8(%esp)          # save pc adjustments
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        %ebx, -4(%esp)          # save %ebx to the stack
-    movl        offGlue_pSelfSuspendCount(%edx), %ebx # %ebx<- pSuspendCount (int)
-4:
-    movl        offGlue_pDebuggerActive(%edx), %eax # %eax<- pDebuggerActive
-    testl       %eax, %eax
-    je          5f
-    movzbl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
-5:
-    cmp         $0, (%ebx)             # check if suspend is pending
-    jne         2f                      # handle suspend
-    movl        offGlue_pActiveProfilers(%edx), %ebx # %ebx<- activeProfilers (int)
-    orl         (%ebx), %eax            # %eax<- merge activeProfilers and debuggerActive
-    movl        -8(%esp), %edx          # %edx<- restore %edx
-    jne         3f                      # debugger or profiler active; switch interp
-    movl        -4(%esp), %ebx          # %ebx<- restore %ebx
-    ret                                 # return
-2:                                      # check suspended
-    EXPORT_PC
-    movl        offGlue_self(%edx), %eax # %eax<- glue->self
-    movl        %eax, -12(%esp)         # push parameter boolean
-    lea         -12(%esp), %esp
-    call        dvmCheckSuspendPending  # call: (Thread* self)
-                                        # return: bool
-    movl        4(%esp), %edx           # %edx<- restore %edx
-    movl        8(%esp), %ebx           # %ebx<- restore %ebx
-    lea         12(%esp), %esp
-    ret
-3:                                      # debugger/profiler enabled, bail out
-    leal        (rPC, %edx, 2), rPC     # adjust pc to show target
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movb        $kInterpEntryInstr, offGlue_entryPoint(%ecx)
-    movl        $1, %edx               # switch interpreter
-    jmp         common_gotoBail         # bail
-
-   /*
-    * Check to see if the thread needs to be suspended or debugger/profiler
-    * activity has begun. With this variant, the reentry type is hard coded
-    * as kInterpEntryInstr.
-    *
-    * On entry:
-    *  %edx is PC adjustment in bytes
-    */
-
-common_periodicChecks_backwardBranch:
-    EXPORT_PC
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_pSelfSuspendCount(%ecx), rINST # %ebx<- pSuspendCount (int)
-4:
-    movl        offGlue_pDebuggerActive(%ecx), %eax # %eax<- pDebuggerActive
-    testl       %eax, %eax              # test for NULL pointer
-    je          5f
-    movzbl      (%eax), %eax            # %eax<- get debuggerActive count
-5:
-    cmp         $0, (rINST)            # check if suspend is pending
-    jne         2f                      # handle suspend
-    movl        offGlue_pActiveProfilers(%ecx), rINST # %edx<- activeProfilers (int)
-    orl          (rINST), %eax           # %eax<- merge activeProfilers and debuggerActive
-    jne         3f                      # debugger or profiler active; switch interp
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-2:                                      # check suspended
-    movl        offGlue_self(%ecx), %eax# %eax<- glue->self
-    movl        %edx, rINST
-    movl        %eax, -12(%esp)         # push parameter boolean
-    lea         -12(%esp), %esp
-    call        dvmCheckSuspendPending  # call: (Thread* self)
-                                        # return: bool
-    movl        rINST, %edx             # %edx<- restore %edx
-    lea         12(%esp), %esp
-    FINISH_RB   %edx, %ecx
-3:                                      # debugger/profiler enabled, bail out
-    leal        (rPC, %edx, 2), rPC     # adjust pc to show target
-    movb        $kInterpEntryInstr, offGlue_entryPoint(%ecx)
-    movl        $1, %edx               # switch interpreter
-    jmp         common_gotoBail         # bail
-
-   /*
-    * The equivalent of "goto bail", this calls through the "bail handler".
-    * State registers will be saved to the "glue" area before bailing.
-    *
-    * On entry:
-    *  %edx is "bool changeInterp", indicating if we want to switch to the
-    *     other interpreter or just bail all the way out
-    */
-
-common_gotoBail:
-    SAVE_PC_FP_TO_GLUE %ecx             # save program counter and frame pointer
-
-   /*
-    * Inlined dvmMterpStdBail
-    */
-
-    lea         40(%ebp), %esp
-    movl        %edx, %eax
-    movl        24(%ebp), %edi
-    movl        28(%ebp), %esi
-    movl        32(%ebp), %ebx
-    movl        36(%ebp), %ebp
-    ret
-
-   /*
-    * Common code for method invocation with range.
-    *
-    * On entry:
-    *  %ecx is "Method* methodToCall", the method we're trying to call
-    */
-
-common_invokeMethodRange:
-.LinvokeNewRange:
-
-   /*
-    * prepare to copy args to "outs" area of current frame
-    */
-
-    SAVEAREA_FROM_FP %eax               # %eax<- &outs; &StackSaveArea
-    test        rINST, rINST            # test for no args
-    movl        rINST, sReg0            # sReg0<- AA
-    jz          .LinvokeArgsDone        # no args; jump to args done
-    FETCH       2, %edx                 # %edx<- CCCC
-
-   /*
-    * %ecx=methodToCall, %edx=CCCC, sReg0=count, %eax=&outs (&stackSaveArea)
-    * (very few methods have > 10 args; could unroll for common cases)
-    */
-
-    movl        %ebx, sReg1             # sReg1<- save %ebx
-    lea         (rFP, %edx, 4), %edx    # %edx<- &vCCCC
-    shll        $2, sReg0              # sReg0<- offset
-    subl        sReg0, %eax             # %eax<- update &outs
-    shrl        $2, sReg0              # sReg0<- offset
-1:
-    movl        (%edx), %ebx            # %ebx<- vCCCC
-    lea         4(%edx), %edx           # %edx<- &vCCCC++
-    subl        $1, sReg0              # sReg<- sReg--
-    movl        %ebx, (%eax)            # *outs<- vCCCC
-    lea         4(%eax), %eax           # outs++
-    jne         1b                      # loop if count (sReg0) not zero
-    movl        sReg1, %ebx             # %ebx<- restore %ebx
-    jmp         .LinvokeArgsDone        # continue
-
-   /*
-    * %ecx is "Method* methodToCall", the method we're trying to call
-    * prepare to copy args to "outs" area of current frame
-    */
-
-common_invokeMethodNoRange:
-.LinvokeNewNoRange:
-    movl        rINST, sReg0            # sReg0<- BA
-    shrl        $4, sReg0              # sReg0<- B
-    je          .LinvokeArgsDone        # no args; jump to args done
-    SAVEAREA_FROM_FP %eax               # %eax<- &outs; &StackSaveArea
-    FETCH       2, %edx                 # %edx<- GFED
-
-   /*
-    * %ecx=methodToCall, %edx=GFED, sReg0=count, %eax=outs
-    */
-
-.LinvokeNonRange:
-    cmp         $2, sReg0              # compare sReg0 to 2
-    movl        %edx, sReg1             # sReg1<- GFED
-    jl          1f                      # handle 1 arg
-    je          2f                      # handle 2 args
-    cmp         $4, sReg0              # compare sReg0 to 4
-    jl          3f                      # handle 3 args
-    je          4f                      # handle 4 args
-5:
-    andl        $15, rINST             # rINST<- A
-    lea         -4(%eax), %eax          # %eax<- update &outs; &outs--
-    movl        (rFP, rINST, 4), %edx   # %edx<- vA
-    movl        %edx, (%eax)            # *outs<- vA
-    movl        sReg1, %edx             # %edx<- GFED
-4:
-    shr         $12, %edx              # %edx<- G
-    lea         -4(%eax), %eax          # %eax<- update &outs; &outs--
-    movl        (rFP, %edx, 4), %edx    # %edx<- vG
-    movl        %edx, (%eax)            # *outs<- vG
-    movl        sReg1, %edx             # %edx<- GFED
-3:
-    and         $0x0f00, %edx          # %edx<- 0F00
-    shr         $6, %edx               # %edx<- F at correct offset
-    lea         -4(%eax), %eax          # %eax<- update &outs; &outs--
-    movl        (rFP, %edx), %edx       # %edx<- vF
-    movl        %edx, (%eax)            # *outs<- vF
-    movl        sReg1, %edx             # %edx<- GFED
-2:
-    and         $0x00f0, %edx          # %edx<- 00E0
-    shr         $2, %edx               # %edx<- E at correct offset
-    lea         -4(%eax), %eax          # %eax<- update &outs; &outs--
-    movl        (rFP, %edx), %edx       # %edx<- vE
-    movl        %edx, (%eax)            # *outs<- vE
-    movl        sReg1, %edx             # %edx<- GFED
-1:
-    and         $0x000f, %edx          # %edx<- 000D
-    movl        (rFP, %edx, 4), %edx    # %edx<- vD
-    movl        %edx, -4(%eax)          # *--outs<- vD
-0:
-
-   /*
-    * %ecx is "Method* methodToCall", the method we're trying to call
-    * find space for the new stack frame, check for overflow
-    */
-
-.LinvokeArgsDone:
-    movzwl      offMethod_registersSize(%ecx), %eax # %eax<- methodToCall->regsSize
-    movzwl      offMethod_outsSize(%ecx), %edx # %edx<- methodToCall->outsSize
-    movl        %ecx, sReg0             # sReg<- methodToCall
-    shl         $2, %eax               # %eax<- update offset
-    SAVEAREA_FROM_FP %ecx               # %ecx<- &outs; &StackSaveArea
-    subl        %eax, %ecx              # %ecx<- newFP; (old savearea - regsSize)
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        %ecx, sReg1             # sReg1<- &outs
-    subl        $sizeofStackSaveArea, %ecx # %ecx<- newSaveArea (stack save area using newFP)
-    movl        offGlue_interpStackEnd(%eax), %eax # %eax<- glue->interpStackEnd
-    movl        %eax, sReg2             # sReg2<- glue->interpStackEnd
-    shl         $2, %edx               # %edx<- update offset for outsSize
-    movl        %ecx, %eax              # %eax<- newSaveArea
-    sub         %edx, %ecx              # %ecx<- bottom; (newSaveArea - outsSize)
-    cmp         sReg2, %ecx             # compare interpStackEnd and bottom
-    movl        sReg0, %ecx             # %ecx<- restore methodToCall
-    jl          .LstackOverflow         # handle frame overflow
-
-   /*
-    * set up newSaveArea
-    */
-
-#ifdef EASY_GDB
-    SAVEAREA_FROM_FP %edx               # %edx<- &outs; &StackSaveArea
-    movl        %edx, offStackSaveArea_prevSave(%eax) # newSaveArea->prevSave<- &outs
-#endif
-    movl        rFP, offStackSaveArea_prevFrame(%eax) # newSaveArea->prevFrame<- rFP
-    movl        rPC, offStackSaveArea_savedPc(%eax) # newSaveArea->savedPc<- rPC
-    testl       $ACC_NATIVE, offMethod_accessFlags(%ecx) # check for native call
-    movl        %ecx, offStackSaveArea_method(%eax) # newSaveArea->method<- method to call
-    jne         .LinvokeNative          # handle native call
-
-   /*
-    * Update "glue" values for the new method
-    * %ecx=methodToCall, sReg1=newFp
-    */
-
-    movl        offMethod_clazz(%ecx), %edx # %edx<- method->clazz
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        %ecx, offGlue_method(%eax) # glue->method<- methodToCall
-    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
-    movl        offMethod_insns(%ecx), rPC # rPC<- methodToCall->insns
-    movl        %edx, offGlue_methodClassDex(%eax) # glue->methodClassDex<- method->clazz->pDvmDex
-    movl        offGlue_self(%eax), %ecx # %ecx<- glue->self
-    movl        sReg1, rFP              # rFP<- newFP
-    movl        rFP, offThread_curFrame(%ecx) # glue->self->curFrame<- newFP
-    FINISH_A                            # jump to methodToCall->insns
-
-   /*
-    * Prep for the native call
-    * %ecx=methodToCall, sReg1=newFP, %eax=newSaveArea
-    */
-
-.LinvokeNative:
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        %ecx, -20(%esp)         # push parameter methodToCall
-    movl        offGlue_self(%edx), %edx # %edx<- glue->self
-    movl        offThread_jniLocal_topCookie(%edx), %ecx # %ecx<- glue->self->thread->refNext
-    movl        %ecx, offStackSaveArea_localRefCookie(%eax) # newSaveArea->localRefCookie<- refNext
-    movl        %eax, -4(%esp)          # save newSaveArea
-    movl        sReg1, %eax             # %eax<- newFP
-    movl        %eax, offThread_curFrame(%edx) # glue->self->curFrame<- newFP
-    movl        %edx, -8(%esp)          # save glue->self
-    movl        %edx, -16(%esp)         # push parameter glue->self
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        -20(%esp), %ecx         # %ecx<- methodToCall
-    lea         offGlue_retval(%edx), %edx # %edx<- &retval
-    movl        %edx, -24(%esp)         # push parameter pMterpGlue
-    movl        %eax, -28(%esp)         # push parameter newFP
-    lea         -28(%esp), %esp
-
-#ifdef ASSIST_DEBUGGER
-    jmp         .Lskip
-    .type       dalvik_mterp, %function
-dalvik_mterp:
-    MTERP_ENTRY
-.Lskip:
-#endif
-    call        *offMethod_nativeFunc(%ecx) # call methodToCall->nativeFunc
-    lea         28(%esp), %esp
-    movl        -4(%esp), %edx          # %edx<- newSaveArea
-    movl        -8(%esp), %ecx          # %ecx<- glue->self
-    movl        offStackSaveArea_localRefCookie(%edx), %eax  # %eax<- newSaveArea->localRefCookie
-    FFETCH_ADV  3, %edx                 # %edx<- next instruction hi; fetch, advance
-    cmp         $0, offThread_exception(%ecx) # check for exception
-    movl        rFP, offThread_curFrame(%ecx) # glue->self->curFrame<- rFP
-    movl        %eax, offThread_jniLocal_topCookie(%ecx) # glue->self<- newSaveArea->localRefCookie
-    jne         common_exceptionThrown  # handle exception
-    FGETOP_JMP  3, %edx                 # jump to next instruction; getop, jmp
-
-.LstackOverflow:
-    movl        %ecx, -4(%esp)          # push method to call
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_self(%ecx), %ecx # %ecx<- glue->self
-    movl        %ecx, -8(%esp)          # push parameter self
-    lea         -8(%esp), %esp
-    call        dvmHandleStackOverflow  # call: (Thread* self, Method *meth)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-#ifdef ASSIST_DEBUGGER
-#endif
-
-   /*
-    * Common code for handling a return instruction.
-    *
-    * This does not return.
-    */
-
-common_returnFromMethod:
-.LreturnNew:
-
-   /*
-    * Inline common periodic checks
-    */
-
-    movl        rGLUE, rINST            # %ecx<- pMterpGlue
-    movl        offGlue_pSelfSuspendCount(rINST), %edx # %ebx<- pSuspendCount (int)
-    movl        offGlue_pDebuggerActive(rINST), %eax # %eax<- pDebuggerActive
-    testl       %eax, %eax
-    je          5f
-    movl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
-5:
-    and         $7, %eax               # %eax<- mask for boolean (just how many bits does it take?)
-    cmp         $0, (%edx)             # check if suspend is pending
-    jne         2f                      # handle suspend
-    movl        offGlue_pActiveProfilers(rINST), %edx # %edx<- activeProfilers (int)
-    or          (%edx), %eax            # %eax<- merge activeProfilers and debuggerActive
-    cmp         $0, %eax               # check for debuggerActive
-    jne         3f                      # debugger or profiler active; switch interp
-    jmp         4f
-2:                                      # check suspended
-    movl        offGlue_self(rINST), %eax# %eax<- glue->self
-    movl        %eax, -12(%esp)         # push parameter boolean
-    lea         -12(%esp), %esp
-    call        dvmCheckSuspendPending  # call: (Thread* self)
-                                        # return: bool
-    lea         12(%esp), %esp
-    jmp         4f
-3:                                      # debugger/profiler enabled, bail out
-    movl        $kInterpEntryInstr, offGlue_entryPoint(rINST) # glue->entryPoint<- reentry type
-    movl        $1, %edx               # switch to interp<- true
-    jmp         common_gotoBail         # bail
-
-
-   /*
-    * Get save area; rGLUE is %ebx, rFP is %eax
-    */
-4:
-    SAVEAREA_FROM_FP %ecx               # %ecx<- saveArea(old)
-    movl        offStackSaveArea_prevFrame(%ecx), rFP # rFP<- saveArea->PrevFrame
-    movl        (offStackSaveArea_method - sizeofStackSaveArea)(rFP), %edx # %edx<- method we are returning to
-    cmpl        $0, %edx               # check for break frame
-    je          common_gotoBail         # bail if break frame
-    movl        offStackSaveArea_savedPc(%ecx), rPC # rPC<- saveAreaOld->savedPc
-    movl        offGlue_self(rINST), %ecx # %eax<- glue->self
-    movl        %edx, offGlue_method(rINST) # glue->method<- newSave->method
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    FFETCH_ADV  3, %eax                 # %ecx<- next instruction hi; fetch, advance
-    movl        rFP, offThread_curFrame(%ecx) # glue->self->curFrame<- rFP
-    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
-    movl        %edx, offGlue_methodClassDex(rINST) # glue->pDvmDex<- method->clazz->pDvmDex
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
-
-   /*
-    * Handle thrown an exception. If the exception processing code
-    * returns to us (instead of falling out of the interpreter),
-    * continue with whatever the next instruction now happens to be.
-    * This does not return.
-    */
-
-common_exceptionThrown:
-.LexceptionNew:
-    movl        $kInterpEntryThrow, %ecx # %ecx<- reentry type
-    movl        $0, %edx               # %edx<- pc adjustment
-    call        common_periodicChecks
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_self(%eax), %edx # %edx<- glue->self
-    movl        offThread_exception(%edx), %ecx # %ecx<- pMterpGlue->self->exception
-    movl        %edx, -4(%esp)          # push parameter self
-    movl        %ecx, -8(%esp)          # push parameter obj
-    lea         -8(%esp), %esp
-    call        dvmAddTrackedAlloc      # don't allow the exception to be GC'd
-                                        # call: (Object* obj, Thread* self)
-                                        # return: void
-    movl        4(%esp), %edx           # %edx<- glue->self
-    movl        $0, offThread_exception(%edx) # glue->self->exception<- NULL
-
-   /*
-    * set up args and a local for &fp
-    */
-
-    movl        rFP, -4(%esp)           # move fp to stack
-    lea         -4(%esp), %esp          # update %esp
-    movl        %esp, -4(%esp)          # push parameter 4<- &fp
-    movl        $0, -8(%esp)           # push parameter 3<- false
-    movl        4(%esp), %edx
-    movl        %edx, -12(%esp)         # push parameter 2<- glue->self->exception
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_method(%eax), %edx # %edx<- glue->method
-    movl        offMethod_insns(%edx), %edx # %edx<- glue->method->insns
-    movl        rPC, %ecx               # %ecx<- rPC
-    subl        %edx, %ecx              # %ecx<- pc - glue->method->insns
-    sar         $1, %ecx               # %ecx<- adjust %ecx for offset
-    movl        %ecx, -16(%esp)         # push parameter 1<- glue->method->insns
-    movl        8(%esp), %edx
-    movl        %edx, -20(%esp)         # push parameter 0<- glue->self
-    lea         -20(%esp), %esp
-
-   /*
-    * call dvmFindCatchBlock, %eax gets catchRelPc (a code-unit offset)
-    */
-
-    call        dvmFindCatchBlock       # call: (Thread* self, int relPc, Object* exception,
-                                        #      bool doUnroll, void** newFrame)
-                                        # return: int
-    lea         32(%esp), %esp
-    movl        -12(%esp), rFP          # rFP<- updated rFP
-    cmp         $0, %eax               # check for catchRelPc < 0
-    jl          .LnotCaughtLocally      # handle not caught locally
-
-   /*
-    * fix stack overflow if necessary
-    */
-
-    movl        -4(%esp), %ecx          # %ecx<- glue->self
-    cmp         $0, offThread_stackOverflowed(%ecx)
-    je          1f
-    movl        %eax, -4(%esp)          # save %eax for later
-    movl        %ecx, -12(%esp)         # push parameter 2 glue->self
-    lea         -12(%esp), %esp
-    call        dvmCleanupStackOverflow # call: (Thread* self, Object* exception)
-                                        # return: void
-    lea         12(%esp), %esp
-    movl        -4(%esp), %eax          # %eax<- restore %eax
-    jmp         2f
-1:
-    movl        %ecx, -12(%esp)         # push parameter 2 glue->self
-2:
-
-   /*
-    * adjust locals to match self->curFrame and updated PC
-    *
-    */
-
-    SAVEAREA_FROM_FP %edx               # %edx<- get newSaveArea
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offStackSaveArea_method(%edx), rPC # rPC<- newMethod
-    movl        rPC, offGlue_method(%ecx) # glue->method<- newMethod
-    movl        offMethod_clazz(rPC), %edx # %edx<- method->clazz
-    movl        offMethod_insns(rPC), rPC # rPC<- method->insns
-    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
-    lea         (rPC, %eax, 2), rPC     # rPC<- method->insns + catchRelPc
-    movl        %edx, offGlue_methodClassDex(%ecx) # glue->pDvmDex<- method->clazz->pDvmDex
-    movl        -8(%esp), %eax
-    movl        %eax, -16(%esp)         # push parameter 1 obj
-    lea         -16(%esp), %esp
-    call        dvmReleaseTrackedAlloc  # call: (Object* obj, Thread* self)
-                                        # return: void
-    lea         16(%esp), %esp
-    FINISH_FETCH %eax
-    cmp         $OP_MOVE_EXCEPTION, %eax # is it a move exception
-    jne         1f
-    movl        -12(%esp), %edx         # %edx<- glue->self
-    movl        -8(%esp), %ecx          # %ecx<- exception
-    movl        %ecx, offThread_exception(%edx) # restore the exception
-1:
-    FINISH_JMP  %eax
-
-   /*
-    * -8(%esp) = exception, -4(%esp) = self
-    */
-
-.LnotCaughtLocally:
-    movl        -4(%esp), %edx          # %edx<- glue->self
-    movzb       offThread_stackOverflowed(%edx), %eax # %eax<- self->stackOverflowed
-    cmp         $0, %eax               # check for stack overflow;
-                                        # maybe should use cmpb
-    je          1f                      #
-    movl        %edx, -12(%esp)         # push parameter 1 glue->self
-    lea         -12(%esp), %esp
-    call        dvmCleanupStackOverflow # call: (Thread* self, Object* exception)
-                                        # return: void
-    lea         12(%esp), %esp
-
-   /*
-    * Release the exception
-    * -8(%esp) = exception, -4(%esp) = self
-    */
-1:
-    movl        -8(%esp), %ecx          # %ecx<- exception
-    movl        -4(%esp), %edx          # %edx<- glue->self
-    movl        %ecx, offThread_exception(%edx) # glue->self<- exception
-    lea         -8(%esp), %esp
-    call        dvmReleaseTrackedAlloc  # call: (Object* obj, Thread* self)
-                                        # return: void
-    lea         8(%esp), %esp
-    movl        $0, %edx               # switch to interp<- false
-    jmp         common_gotoBail         # bail
-
-   /*
-    * After returning from a "glued" function, pull out the updated
-    * values and start executing at the next instruction.
-    */
-
-common_resumeAfterGlueCall:
-    LOAD_PC_FP_FROM_GLUE                # pull rPC and rFP out of glue
-    FINISH_A                            # jump to next instruction
-
-   /*
-    * For debugging, cause an immediate fault.
-    */
-
-common_abort:
-    jmp         .LdeadFood
-
-.LdeadFood:
-.int 0xdeadf00d
-
-   /*
-    * Invalid array index.
-    */
-
-common_errArrayIndex:
-    EXPORT_PC
-    movl        $.LstrArrayIndexException, -8(%esp) # push parameter description
-    movl        $0, -4(%esp)           # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * Invalid array value.
-    */
-
-common_errArrayStore:
-    EXPORT_PC
-    movl        $.LstrArrayStoreException, -8(%esp) # push parameter description
-    movl        $0, -4(%esp)           # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * Integer divide or mod by zero.
-    */
-
-common_errDivideByZero:
-    EXPORT_PC
-    movl        $.LstrArithmeticException, -8(%esp) # push parameter description
-    movl        $.LstrDivideByZero, -4(%esp) # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * Attempt to allocate an array with a negative size.
-    */
-
-common_errNegativeArraySize:
-    EXPORT_PC
-    movl        $.LstrNegativeArraySizeException, -8(%esp) # push parameter description
-    movl        $0, -4(%esp)           # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * Invocation of a non-existent method.
-    */
-
-common_errNoSuchMethod:
-    EXPORT_PC
-    movl        $.LstrNoSuchMethodError, -8(%esp) # push parameter description
-    movl        $0, -4(%esp)           # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * Unexpected null object.
-    */
-
-common_errNullObject:
-    EXPORT_PC
-    movl        $.LstrNullPointerException, -8(%esp) # push parameter description
-    movl        $0, -4(%esp)           # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * String references
-    */
-
-    .align 4
-    .section .rodata
-.LstrArithmeticException:
-    .asciz "Ljava/lang/ArithmeticException;"
-.LstrArrayIndexException:
-    .asciz "Ljava/lang/ArrayIndexOutOfBoundsException;"
-.LstrArrayStoreException:
-    .asciz "Ljava/lang/ArrayStoreException;"
-.LstrDivideByZero:
-    .asciz "divide by zero"
-.LstrInstantiationError:
-    .asciz "Ljava/lang/InstantiationError;"
-.LstrNegativeArraySizeException:
-    .asciz "Ljava/lang/NegativeArraySizeException;"
-.LstrNoSuchMethodError:
-    .asciz "Ljava/lang/NoSuchMethodError;"
-.LstrNullPointerException:
-    .asciz "Ljava/lang/NullPointerException;"
-.LstrExceptionNotCaughtLocally:
-    .asciz "Exception %s from %s:%d not caught locally\n"
-
diff --git a/vm/mterp/out/InterpAsm-x86.S b/vm/mterp/out/InterpAsm-x86.S
index 9fcebf6..0aa94eb 100644
--- a/vm/mterp/out/InterpAsm-x86.S
+++ b/vm/mterp/out/InterpAsm-x86.S
@@ -58,8 +58,8 @@
 to callee save registers).
 
   nick     reg   purpose
-  rPC      edi   interpreted program counter, used for fetching instructions
-  rFP      esi   interpreted frame pointer, used for accessing locals and args
+  rPC      esi   interpreted program counter, used for fetching instructions
+  rFP      edi   interpreted frame pointer, used for accessing locals and args
   rINSTw   bx    first 16-bit code of current instruction
   rINSTbl  bl    opcode portion of instruction word
   rINSTbh  bh    high byte of inst word, usually contains src/tgt reg names
@@ -106,7 +106,14 @@
 #define OUT_ARG2       (  8)
 #define OUT_ARG1       (  4)
 #define OUT_ARG0       (  0)  /* <- dvmMterpStdRun esp */
+#if defined(WITH_JIT)
+/* for spill region: increase size by 48 (to keep 16-byte alignment) */
+/* 76 + 48 = 124 */
+#define JIT_SPILL      (-56)
+#define FRAME_SIZE     124
+#else
 #define FRAME_SIZE     76
+#endif
 
 #define SPILL(reg) movl reg##,reg##_SPILL(%ebp)
 #define UNSPILL(reg) movl reg##_SPILL(%ebp),reg
@@ -156,6 +163,10 @@
     movl     rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP)
 .endm
 
+.macro GET_PC
+    movl     (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP), rPC
+.endm
+
 /*
  * Given a frame pointer, find the stack save area.
  *
@@ -257,6 +268,13 @@
 #define sReg2 LOCAL2_OFFSET(%ebp)
 
    /*
+    * x86 JIT Helpers
+    */
+
+    .macro dumpSwitch _regData _regScratch1 _regScratch2
+    .endm
+
+   /*
     * Hard coded helper values.
     */
 
@@ -1007,8 +1025,12 @@
     movzwl    2(rPC),%eax               # eax<- BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
     SPILL(rIBASE)
+    SPILL_TMP2(%ebx)
     movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
     EXPORT_PC
+#if defined(WITH_JIT)
+    lea       (%ecx,%eax,4),%ebx        # ebx <- &resolved class
+#endif
     movl      (%ecx,%eax,4),%ecx        # ecx<- resolved class
     testl     %ecx,%ecx                 # resolved?
     je        .LOP_NEW_INSTANCE_resolve       # no, go do it
@@ -1019,14 +1041,48 @@
     movl      $ALLOC_DONT_TRACK,OUT_ARG1(%esp)
     movl     %ecx,OUT_ARG0(%esp)
     call     dvmAllocObject             # eax<- new object
-    FETCH_INST_OPCODE 2 %ecx
-    UNSPILL(rIBASE)
     testl    %eax,%eax                  # success?
     je       common_exceptionThrown     # no, bail out
+#if defined(WITH_JIT)
+        /*
+     * The JIT needs the class to be fully resolved before it can
+     * include this instruction in a trace.
+     */
+    movl    rSELF, %ecx
+    movl    offThread_subMode(%ecx), %ecx
+    andl    $kSubModeJitTraceBuild, %ecx # under construction?
+    jne     .LOP_NEW_INSTANCE_jitCheck
+#endif
+.LOP_NEW_INSTANCE_end:
+    UNSPILL_TMP2(%ebx)
     SET_VREG %eax rINST
+    UNSPILL(rIBASE)
+    FETCH_INST_OPCODE 2 %ecx
     ADVANCE_PC 2
     GOTO_NEXT_R %ecx
 
+#if defined(WITH_JIT)
+    /*
+     * Check to see if we need to stop the trace building early.
+     * eax: new object
+     */
+.LOP_NEW_INSTANCE_jitCheck:
+    cmp     $0, (%ebx)                   # okay?
+    jne     .LOP_NEW_INSTANCE_end        # yes, finish
+    SPILL_TMP1(%eax)                     # preserve new object
+    movl    rSELF, %ecx
+    movl    %ecx, OUT_ARG0(%esp)
+    movl    rPC, OUT_ARG1(%esp)
+    call    dvmJitEndTraceSelect         # (self, pc)
+    UNSPILL_TMP1(%eax)
+    UNSPILL_TMP2(%ebx)
+    SET_VREG %eax rINST                  # vAA <- new object
+    UNSPILL(rIBASE)
+    FETCH_INST_OPCODE 2 %ecx
+    ADVANCE_PC 2
+    GOTO_NEXT_R %ecx
+#endif
+
     /*
      * Class initialization required.
      *
@@ -1435,6 +1491,11 @@
     movl    offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 /* ------------------------------ */
@@ -1451,6 +1512,11 @@
     movl    offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 /* ------------------------------ */
@@ -1467,6 +1533,11 @@
     movl    offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 /* ------------------------------ */
@@ -1492,6 +1563,11 @@
     ADVANCE_PC_INDEXED %eax
     movl    offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 /* ------------------------------ */
@@ -1518,6 +1594,11 @@
     ADVANCE_PC_INDEXED %eax
     movl    offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1722,6 +1803,11 @@
     movl     offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1750,6 +1836,11 @@
     movl     offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1778,6 +1869,11 @@
     movl     offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1806,6 +1902,11 @@
     movl     offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1834,6 +1935,11 @@
     movl     offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1862,6 +1968,11 @@
     movl     offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1878,14 +1989,19 @@
      */
     /* if-cmp vAA, +BBBB */
     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
+    movl     rSELF,%ecx
     movl     $2,%eax              # assume branch not taken
     jne   1f
-    movl     rSELF,%ecx
     movswl   2(rPC),%eax           # fetch signed displacement
     movl     offThread_curHandlerTable(%ecx),rIBASE
 1:
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1902,14 +2018,19 @@
      */
     /* if-cmp vAA, +BBBB */
     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
+    movl     rSELF,%ecx
     movl     $2,%eax              # assume branch not taken
     je   1f
-    movl     rSELF,%ecx
     movswl   2(rPC),%eax           # fetch signed displacement
     movl     offThread_curHandlerTable(%ecx),rIBASE
 1:
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1926,14 +2047,19 @@
      */
     /* if-cmp vAA, +BBBB */
     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
+    movl     rSELF,%ecx
     movl     $2,%eax              # assume branch not taken
     jge   1f
-    movl     rSELF,%ecx
     movswl   2(rPC),%eax           # fetch signed displacement
     movl     offThread_curHandlerTable(%ecx),rIBASE
 1:
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1950,14 +2076,19 @@
      */
     /* if-cmp vAA, +BBBB */
     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
+    movl     rSELF,%ecx
     movl     $2,%eax              # assume branch not taken
     jl   1f
-    movl     rSELF,%ecx
     movswl   2(rPC),%eax           # fetch signed displacement
     movl     offThread_curHandlerTable(%ecx),rIBASE
 1:
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1974,14 +2105,19 @@
      */
     /* if-cmp vAA, +BBBB */
     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
+    movl     rSELF,%ecx
     movl     $2,%eax              # assume branch not taken
     jle   1f
-    movl     rSELF,%ecx
     movswl   2(rPC),%eax           # fetch signed displacement
     movl     offThread_curHandlerTable(%ecx),rIBASE
 1:
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -1998,14 +2134,19 @@
      */
     /* if-cmp vAA, +BBBB */
     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
+    movl     rSELF,%ecx
     movl     $2,%eax              # assume branch not taken
     jg   1f
-    movl     rSELF,%ecx
     movswl   2(rPC),%eax           # fetch signed displacement
     movl     offThread_curHandlerTable(%ecx),rIBASE
 1:
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
 
 
@@ -3246,6 +3387,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SGET_resolve                # if not, make it so
@@ -3271,8 +3418,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SGET_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SGET_finish                 # success, continue
 
 /* ------------------------------ */
 .L_OP_SGET_WIDE: /* 0x61 */
@@ -3286,6 +3439,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SGET_WIDE_resolve                # if not, make it so
@@ -3313,8 +3472,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SGET_WIDE_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SGET_WIDE_finish                 # success, continue
 
 /* ------------------------------ */
 .L_OP_SGET_OBJECT: /* 0x62 */
@@ -3330,6 +3495,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SGET_OBJECT_resolve                # if not, make it so
@@ -3355,8 +3526,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SGET_OBJECT_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SGET_OBJECT_finish                 # success, continue
 
 
 /* ------------------------------ */
@@ -3373,6 +3550,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SGET_BOOLEAN_resolve                # if not, make it so
@@ -3398,8 +3581,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SGET_BOOLEAN_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SGET_BOOLEAN_finish                 # success, continue
 
 
 /* ------------------------------ */
@@ -3416,6 +3605,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SGET_BYTE_resolve                # if not, make it so
@@ -3441,8 +3636,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SGET_BYTE_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SGET_BYTE_finish                 # success, continue
 
 
 /* ------------------------------ */
@@ -3459,6 +3660,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SGET_CHAR_resolve                # if not, make it so
@@ -3484,8 +3691,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SGET_CHAR_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SGET_CHAR_finish                 # success, continue
 
 
 /* ------------------------------ */
@@ -3502,6 +3715,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SGET_SHORT_resolve                # if not, make it so
@@ -3527,8 +3746,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SGET_SHORT_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SGET_SHORT_finish                 # success, continue
 
 
 /* ------------------------------ */
@@ -3544,6 +3769,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SPUT_resolve                # if not, make it so
@@ -3560,7 +3791,7 @@
 .LOP_SPUT_resolve:
     movl     rSELF,%ecx
     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
-    movl     offThread_method(%ecx),%ecx          # ecx<- current method
+    movl     offThread_method(%ecx),%ecx        # ecx<- current method
     EXPORT_PC                                   # could throw, need to export
     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
     movl     %eax,OUT_ARG1(%esp)
@@ -3569,9 +3800,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SPUT_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
-
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SPUT_finish                 # success, continue
 /* ------------------------------ */
 .L_OP_SPUT_WIDE: /* 0x68 */
 /* File: x86/OP_SPUT_WIDE.S */
@@ -3585,6 +3821,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SPUT_WIDE_resolve                # if not, make it so
@@ -3612,8 +3854,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SPUT_WIDE_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SPUT_WIDE_finish                 # success, continue
 
 /* ------------------------------ */
 .L_OP_SPUT_OBJECT: /* 0x69 */
@@ -3626,6 +3874,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SPUT_OBJECT_resolve                # if not, make it so
@@ -3657,8 +3911,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SPUT_OBJECT_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SPUT_OBJECT_finish                 # success, continue
 
 /* ------------------------------ */
 .L_OP_SPUT_BOOLEAN: /* 0x6a */
@@ -3674,6 +3934,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SPUT_BOOLEAN_resolve                # if not, make it so
@@ -3690,7 +3956,7 @@
 .LOP_SPUT_BOOLEAN_resolve:
     movl     rSELF,%ecx
     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
-    movl     offThread_method(%ecx),%ecx          # ecx<- current method
+    movl     offThread_method(%ecx),%ecx        # ecx<- current method
     EXPORT_PC                                   # could throw, need to export
     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
     movl     %eax,OUT_ARG1(%esp)
@@ -3699,9 +3965,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SPUT_BOOLEAN_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
-
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SPUT_BOOLEAN_finish                 # success, continue
 
 /* ------------------------------ */
 .L_OP_SPUT_BYTE: /* 0x6b */
@@ -3717,6 +3988,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SPUT_BYTE_resolve                # if not, make it so
@@ -3733,7 +4010,7 @@
 .LOP_SPUT_BYTE_resolve:
     movl     rSELF,%ecx
     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
-    movl     offThread_method(%ecx),%ecx          # ecx<- current method
+    movl     offThread_method(%ecx),%ecx        # ecx<- current method
     EXPORT_PC                                   # could throw, need to export
     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
     movl     %eax,OUT_ARG1(%esp)
@@ -3742,9 +4019,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SPUT_BYTE_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
-
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SPUT_BYTE_finish                 # success, continue
 
 /* ------------------------------ */
 .L_OP_SPUT_CHAR: /* 0x6c */
@@ -3760,6 +4042,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SPUT_CHAR_resolve                # if not, make it so
@@ -3776,7 +4064,7 @@
 .LOP_SPUT_CHAR_resolve:
     movl     rSELF,%ecx
     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
-    movl     offThread_method(%ecx),%ecx          # ecx<- current method
+    movl     offThread_method(%ecx),%ecx        # ecx<- current method
     EXPORT_PC                                   # could throw, need to export
     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
     movl     %eax,OUT_ARG1(%esp)
@@ -3785,9 +4073,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SPUT_CHAR_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
-
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SPUT_CHAR_finish                 # success, continue
 
 /* ------------------------------ */
 .L_OP_SPUT_SHORT: /* 0x6d */
@@ -3803,6 +4096,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SPUT_SHORT_resolve                # if not, make it so
@@ -3819,7 +4118,7 @@
 .LOP_SPUT_SHORT_resolve:
     movl     rSELF,%ecx
     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
-    movl     offThread_method(%ecx),%ecx          # ecx<- current method
+    movl     offThread_method(%ecx),%ecx        # ecx<- current method
     EXPORT_PC                                   # could throw, need to export
     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
     movl     %eax,OUT_ARG1(%esp)
@@ -3828,9 +4127,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SPUT_SHORT_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
-
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SPUT_SHORT_finish                 # success, continue
 
 /* ------------------------------ */
 .L_OP_INVOKE_VIRTUAL: /* 0x6e */
@@ -3875,9 +4179,9 @@
     movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
     testl     %ecx,%ecx                 # null this?
     je        common_errNullObject      # go if so
-    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
-    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
-    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
+    movl      offObject_clazz(%ecx),%edx  # edx<- thisPtr->clazz
+    movl      offClassObject_vtable(%edx),%edx # edx<- thisPtr->clazz->vtable
+    movl      (%edx,%eax,4),%eax        # eax<- vtable[methodIndex]
     jmp       common_invokeMethodNoRange
 
 /* ------------------------------ */
@@ -3901,8 +4205,9 @@
     .if       (!0)
     andl      $0xf,rINST               # rINST<- D (or stays CCCC)
     .endif
-    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
-    testl     rINST,rINST               # null "this"?
+    GET_VREG_R  %edx rINST             # %edx<- "this" ptr
+    testl     %edx,%edx                # null "this"?
+    SPILL_TMP1(%edx)
     je        common_errNullObject      # yes, throw
     movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
     testl     %ecx,%ecx                 # already resolved?
@@ -3914,11 +4219,13 @@
      */
 .LOP_INVOKE_SUPER_continue:
     movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
-    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
-    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
+    movzwl  offMethod_methodIndex(%ecx),%edx  # edx<- baseMthod->methodIndex
+    cmpl    offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount)
     jae     .LOP_INVOKE_SUPER_nsm           # method not present in superclass
     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
-    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
+    movl    (%eax,%edx,4),%eax        # eax<- vtable[methodIndex]
+    UNSPILL_TMP1(%edx)
+    movl    %edx, %ecx
     jmp     common_invokeMethodNoRange
 
 
@@ -3927,7 +4234,7 @@
      * eax = method->clazz
     */
 .LOP_INVOKE_SUPER_resolve:
-    SPILL_TMP1(%eax)                    # method->clazz
+    SPILL_TMP2(%eax)                    # method->clazz
     movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
     movzwl  2(rPC),%ecx                 # ecx<- BBBB
     movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
@@ -3935,7 +4242,7 @@
     call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
     testl   %eax,%eax                   # got null?
     movl    %eax,%ecx                   # ecx<- resolved base method
-    UNSPILL_TMP1(%eax)                  # restore method->clazz
+    UNSPILL_TMP2(%eax)                  # restore method->clazz
     jne     .LOP_INVOKE_SUPER_continue        # good to go - continue
     jmp     common_exceptionThrown      # handle exception
 
@@ -4016,9 +4323,17 @@
     movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
     EXPORT_PC
     movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
+#if defined(WITH_JIT)
+    movl     %edx, TMP_SPILL1(%ebp)
+    lea      (%ecx,%eax,4), %edx
+    movl     %edx, TMP_SPILL2(%ebp)
+    movl     TMP_SPILL1(%ebp), %edx
+#endif
     movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
+    movl      $0, %ecx                 # make "this" null
     testl     %eax,%eax
     jne       common_invokeMethodNoRange
+
     movl      rSELF,%ecx
     movl      offThread_method(%ecx),%ecx # ecx<- self->method
     movzwl    2(rPC),%eax
@@ -4027,10 +4342,40 @@
     movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
     movl      $METHOD_STATIC,%eax
     movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
+    SPILL(rIBASE)
     call      dvmResolveMethod          # call(clazz,ref,flags)
+    UNSPILL(rIBASE)
     testl     %eax,%eax                 # got null?
+#if defined(WITH_JIT)
+    movl      TMP_SPILL1(%ebp), %edx
+    movl      rSELF,%ecx
+    movzwl    offThread_subMode(%ecx), %ecx
+    je        common_exceptionThrown    # null, handle exception
+    andl      $kSubModeJitTraceBuild, %ecx # is trace under construction?
+    movl      $0, %ecx                 # make "this" null
+    je        common_invokeMethodNoRange # no (%eax=method, %ecx="this")
+    movl      TMP_SPILL2(%ebp), %edx
+    cmpl      $0, (%edx)                  # finished resolving
+    movl      TMP_SPILL1(%ebp), %edx
+    jne        common_invokeMethodNoRange # yes (%eax=method, %ecx="this")
+    movl      rSELF, %edx
+    movl      %edx, OUT_ARG0(%esp)
+    movl      rPC, OUT_ARG1(%esp)
+    movl      %eax, TMP_SPILL2(%ebp)
+    movl      %ecx, TMP_SPILL3(%ebp)
+    SPILL(rIBASE)
+    call      dvmJitEndTraceSelect
+    UNSPILL(rIBASE)
+    movl      TMP_SPILL1(%ebp), %edx
+    movl      TMP_SPILL2(%ebp), %eax
+    movl      TMP_SPILL3(%ebp), %ecx
+    jmp       common_invokeMethodNoRange
+#else
+    movl      $0, %ecx                 # make "this" null
     jne       common_invokeMethodNoRange
     jmp       common_exceptionThrown
+#endif
+
 
 /* ------------------------------ */
 .L_OP_INVOKE_INTERFACE: /* 0x72 */
@@ -4051,6 +4396,7 @@
     EXPORT_PC
     testl      %eax,%eax                # null this?
     je         common_errNullObject     # yes, fail
+    movl       %eax, TMP_SPILL1(%ebp)
     movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
     movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
     movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
@@ -4062,6 +4408,7 @@
     call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
     testl      %eax,%eax
     je         common_exceptionThrown
+    movl       TMP_SPILL1(%ebp), %ecx
     jmp        common_invokeMethodNoRange
 
 /* ------------------------------ */
@@ -4115,9 +4462,9 @@
     movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
     testl     %ecx,%ecx                 # null this?
     je        common_errNullObject      # go if so
-    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
-    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
-    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
+    movl      offObject_clazz(%ecx),%edx  # edx<- thisPtr->clazz
+    movl      offClassObject_vtable(%edx),%edx # edx<- thisPtr->clazz->vtable
+    movl      (%edx,%eax,4),%eax        # eax<- vtable[methodIndex]
     jmp       common_invokeMethodRange
 
 
@@ -4143,8 +4490,9 @@
     .if       (!1)
     andl      $0xf,rINST               # rINST<- D (or stays CCCC)
     .endif
-    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
-    testl     rINST,rINST               # null "this"?
+    GET_VREG_R  %edx rINST             # %edx<- "this" ptr
+    testl     %edx,%edx                # null "this"?
+    SPILL_TMP1(%edx)
     je        common_errNullObject      # yes, throw
     movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
     testl     %ecx,%ecx                 # already resolved?
@@ -4156,11 +4504,13 @@
      */
 .LOP_INVOKE_SUPER_RANGE_continue:
     movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
-    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
-    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
+    movzwl  offMethod_methodIndex(%ecx),%edx  # edx<- baseMthod->methodIndex
+    cmpl    offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount)
     jae     .LOP_INVOKE_SUPER_RANGE_nsm           # method not present in superclass
     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
-    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
+    movl    (%eax,%edx,4),%eax        # eax<- vtable[methodIndex]
+    UNSPILL_TMP1(%edx)
+    movl    %edx, %ecx
     jmp     common_invokeMethodRange
 
 
@@ -4169,7 +4519,7 @@
      * eax = method->clazz
     */
 .LOP_INVOKE_SUPER_RANGE_resolve:
-    SPILL_TMP1(%eax)                    # method->clazz
+    SPILL_TMP2(%eax)                    # method->clazz
     movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
     movzwl  2(rPC),%ecx                 # ecx<- BBBB
     movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
@@ -4177,7 +4527,7 @@
     call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
     testl   %eax,%eax                   # got null?
     movl    %eax,%ecx                   # ecx<- resolved base method
-    UNSPILL_TMP1(%eax)                  # restore method->clazz
+    UNSPILL_TMP2(%eax)                  # restore method->clazz
     jne     .LOP_INVOKE_SUPER_RANGE_continue        # good to go - continue
     jmp     common_exceptionThrown      # handle exception
 
@@ -4262,9 +4612,17 @@
     movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
     EXPORT_PC
     movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
+#if defined(WITH_JIT)
+    movl     %edx, TMP_SPILL1(%ebp)
+    lea      (%ecx,%eax,4), %edx
+    movl     %edx, TMP_SPILL2(%ebp)
+    movl     TMP_SPILL1(%ebp), %edx
+#endif
     movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
+    movl      $0, %ecx                 # make "this" null
     testl     %eax,%eax
     jne       common_invokeMethodRange
+
     movl      rSELF,%ecx
     movl      offThread_method(%ecx),%ecx # ecx<- self->method
     movzwl    2(rPC),%eax
@@ -4273,10 +4631,40 @@
     movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
     movl      $METHOD_STATIC,%eax
     movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
+    SPILL(rIBASE)
     call      dvmResolveMethod          # call(clazz,ref,flags)
+    UNSPILL(rIBASE)
     testl     %eax,%eax                 # got null?
+#if defined(WITH_JIT)
+    movl      TMP_SPILL1(%ebp), %edx
+    movl      rSELF,%ecx
+    movzwl    offThread_subMode(%ecx), %ecx
+    je        common_exceptionThrown    # null, handle exception
+    andl      $kSubModeJitTraceBuild, %ecx # is trace under construction?
+    movl      $0, %ecx                 # make "this" null
+    je        common_invokeMethodRange # no (%eax=method, %ecx="this")
+    movl      TMP_SPILL2(%ebp), %edx
+    cmpl      $0, (%edx)                  # finished resolving
+    movl      TMP_SPILL1(%ebp), %edx
+    jne        common_invokeMethodRange # yes (%eax=method, %ecx="this")
+    movl      rSELF, %edx
+    movl      %edx, OUT_ARG0(%esp)
+    movl      rPC, OUT_ARG1(%esp)
+    movl      %eax, TMP_SPILL2(%ebp)
+    movl      %ecx, TMP_SPILL3(%ebp)
+    SPILL(rIBASE)
+    call      dvmJitEndTraceSelect
+    UNSPILL(rIBASE)
+    movl      TMP_SPILL1(%ebp), %edx
+    movl      TMP_SPILL2(%ebp), %eax
+    movl      TMP_SPILL3(%ebp), %ecx
+    jmp       common_invokeMethodRange
+#else
+    movl      $0, %ecx                 # make "this" null
     jne       common_invokeMethodRange
     jmp       common_exceptionThrown
+#endif
+
 
 
 /* ------------------------------ */
@@ -4299,6 +4687,7 @@
     EXPORT_PC
     testl      %eax,%eax                # null this?
     je         common_errNullObject     # yes, fail
+    movl       %eax, TMP_SPILL1(%ebp)
     movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
     movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
     movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
@@ -4310,6 +4699,7 @@
     call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
     testl      %eax,%eax
     je         common_exceptionThrown
+    movl       TMP_SPILL1(%ebp), %ecx
     jmp        common_invokeMethodRange
 
 
@@ -5650,62 +6040,56 @@
 /* ------------------------------ */
 .L_OP_ADD_DOUBLE: /* 0xab */
 /* File: x86/OP_ADD_DOUBLE.S */
-/* File: x86/binflop.S */
-    /*
-     * Generic 32-bit binary float operation.
-     *
-     * For: add-fp, sub-fp, mul-fp, div-fp
-     */
-    /* binop vAA, vBB, vCC */
-    movzbl   2(rPC),%eax          # eax<- CC
-    movzbl   3(rPC),%ecx          # ecx<- BB
-    fldl    (rFP,%eax,4)         # vCC to fp stack
-    faddl   (rFP,%ecx,4)         # ex: faddp
+   /*
+    * File: OP_ADD_DOUBLE.S
+    */
+
+    movzbl   2(rPC),%eax                # eax<- BB
+    movzbl   3(rPC),%ecx                # ecx<- CC
+    movq     (rFP, %eax, 4), %xmm0      # %xmm0<- vBB
+    movq     (rFP, %ecx, 4), %xmm1      # %xmm1<- vCC
     FETCH_INST_OPCODE 2 %ecx
+    addsd    %xmm1, %xmm0
     ADVANCE_PC 2
-    fstpl   (rFP,rINST,4)         # %st to vAA
+    movq     %xmm0, (rFP, rINST, 4)     # vAA<- vBB * vCC
     GOTO_NEXT_R %ecx
 
 
 /* ------------------------------ */
 .L_OP_SUB_DOUBLE: /* 0xac */
 /* File: x86/OP_SUB_DOUBLE.S */
-/* File: x86/binflop.S */
-    /*
-     * Generic 32-bit binary float operation.
-     *
-     * For: add-fp, sub-fp, mul-fp, div-fp
-     */
-    /* binop vAA, vBB, vCC */
-    movzbl   2(rPC),%eax          # eax<- CC
-    movzbl   3(rPC),%ecx          # ecx<- BB
-    fldl    (rFP,%eax,4)         # vCC to fp stack
-    fsubl   (rFP,%ecx,4)         # ex: faddp
-    FETCH_INST_OPCODE 2 %ecx
-    ADVANCE_PC 2
-    fstpl   (rFP,rINST,4)         # %st to vAA
-    GOTO_NEXT_R %ecx
+   /*
+    * File: OP_SUB_DOUBLE.S
+    */
 
+    movzbl   2(rPC),%eax                # eax<- BB
+    movzbl   3(rPC),%ecx                # ecx<- CC
+    # TODO: movsd?
+    movq        (rFP, %eax, 4), %xmm0   # %xmm0<- vBB
+    movq        (rFP, %ecx, 4), %xmm1   # %xmm1<- vCC
+    FETCH_INST_OPCODE 2 %ecx
+    subsd       %xmm1, %xmm0
+    ADVANCE_PC 2
+    movq        %xmm0, (rFP, rINST, 4)  # vAA<- vBB - vCC
+    GOTO_NEXT_R %ecx
 
 /* ------------------------------ */
 .L_OP_MUL_DOUBLE: /* 0xad */
 /* File: x86/OP_MUL_DOUBLE.S */
-/* File: x86/binflop.S */
-    /*
-     * Generic 32-bit binary float operation.
-     *
-     * For: add-fp, sub-fp, mul-fp, div-fp
-     */
-    /* binop vAA, vBB, vCC */
-    movzbl   2(rPC),%eax          # eax<- CC
-    movzbl   3(rPC),%ecx          # ecx<- BB
-    fldl    (rFP,%eax,4)         # vCC to fp stack
-    fmull   (rFP,%ecx,4)         # ex: faddp
-    FETCH_INST_OPCODE 2 %ecx
-    ADVANCE_PC 2
-    fstpl   (rFP,rINST,4)         # %st to vAA
-    GOTO_NEXT_R %ecx
+   /*
+    * File: OP_MUL_DOUBLE.S
+    */
 
+    movzbl   2(rPC),%eax                # eax<- BB
+    movzbl   3(rPC),%ecx                # ecx<- CC
+    # TODO: movsd?
+    movq        (rFP, %eax, 4), %xmm0   # %xmm0<- vBB
+    movq        (rFP, %ecx, 4), %xmm1   # %xmm1<- vCC
+    FETCH_INST_OPCODE 2 %ecx
+    mulsd       %xmm1, %xmm0
+    ADVANCE_PC 2
+    movq        %xmm0, (rFP, rINST, 4)  # vAA<- vBB * vCC
+    GOTO_NEXT_R %ecx
 
 /* ------------------------------ */
 .L_OP_DIV_DOUBLE: /* 0xae */
@@ -5753,11 +6137,7 @@
     /*
      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
      * that specifies an instruction that performs "result = r0 op r1".
-     * This could be an ARM instruction or a function call.  (If the result
-     * comes back in a register other than r0, you can override "result".)
-     *
-     * If "chkzero" is set to 1, we perform a divide-by-zero check on
-     * vCC (r1).  Useful for integer division and modulus.
+     * This could be an instruction or a function call.
      *
      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
@@ -5766,7 +6146,7 @@
      */
     /* binop/2addr vA, vB */
     movzx   rINSTbl,%ecx               # ecx<- A+
-    sarl    $4,rINST                 # rINST<- B
+    sarl    $4,rINST                  # rINST<- B
     GET_VREG_R %eax rINST              # eax<- vB
     andb    $0xf,%cl                  # ecx<- A
     addl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
@@ -5782,11 +6162,7 @@
     /*
      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
      * that specifies an instruction that performs "result = r0 op r1".
-     * This could be an ARM instruction or a function call.  (If the result
-     * comes back in a register other than r0, you can override "result".)
-     *
-     * If "chkzero" is set to 1, we perform a divide-by-zero check on
-     * vCC (r1).  Useful for integer division and modulus.
+     * This could be an instruction or a function call.
      *
      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
@@ -5795,7 +6171,7 @@
      */
     /* binop/2addr vA, vB */
     movzx   rINSTbl,%ecx               # ecx<- A+
-    sarl    $4,rINST                 # rINST<- B
+    sarl    $4,rINST                  # rINST<- B
     GET_VREG_R %eax rINST              # eax<- vB
     andb    $0xf,%cl                  # ecx<- A
     subl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
@@ -5903,11 +6279,7 @@
     /*
      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
      * that specifies an instruction that performs "result = r0 op r1".
-     * This could be an ARM instruction or a function call.  (If the result
-     * comes back in a register other than r0, you can override "result".)
-     *
-     * If "chkzero" is set to 1, we perform a divide-by-zero check on
-     * vCC (r1).  Useful for integer division and modulus.
+     * This could be an instruction or a function call.
      *
      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
@@ -5916,7 +6288,7 @@
      */
     /* binop/2addr vA, vB */
     movzx   rINSTbl,%ecx               # ecx<- A+
-    sarl    $4,rINST                 # rINST<- B
+    sarl    $4,rINST                  # rINST<- B
     GET_VREG_R %eax rINST              # eax<- vB
     andb    $0xf,%cl                  # ecx<- A
     andl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
@@ -5932,11 +6304,7 @@
     /*
      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
      * that specifies an instruction that performs "result = r0 op r1".
-     * This could be an ARM instruction or a function call.  (If the result
-     * comes back in a register other than r0, you can override "result".)
-     *
-     * If "chkzero" is set to 1, we perform a divide-by-zero check on
-     * vCC (r1).  Useful for integer division and modulus.
+     * This could be an instruction or a function call.
      *
      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
@@ -5945,7 +6313,7 @@
      */
     /* binop/2addr vA, vB */
     movzx   rINSTbl,%ecx               # ecx<- A+
-    sarl    $4,rINST                 # rINST<- B
+    sarl    $4,rINST                  # rINST<- B
     GET_VREG_R %eax rINST              # eax<- vB
     andb    $0xf,%cl                  # ecx<- A
     orl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
@@ -5961,11 +6329,7 @@
     /*
      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
      * that specifies an instruction that performs "result = r0 op r1".
-     * This could be an ARM instruction or a function call.  (If the result
-     * comes back in a register other than r0, you can override "result".)
-     *
-     * If "chkzero" is set to 1, we perform a divide-by-zero check on
-     * vCC (r1).  Useful for integer division and modulus.
+     * This could be an instruction or a function call.
      *
      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
@@ -5974,7 +6338,7 @@
      */
     /* binop/2addr vA, vB */
     movzx   rINSTbl,%ecx               # ecx<- A+
-    sarl    $4,rINST                 # rINST<- B
+    sarl    $4,rINST                  # rINST<- B
     GET_VREG_R %eax rINST              # eax<- vB
     andb    $0xf,%cl                  # ecx<- A
     xorl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
@@ -6490,69 +6854,59 @@
 /* ------------------------------ */
 .L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
 /* File: x86/OP_ADD_DOUBLE_2ADDR.S */
-/* File: x86/binflop2addr.S */
-    /*
-     * Generic 32-bit binary float operation.
-     *
-     * For: add-fp, sub-fp, mul-fp, div-fp
-     */
+   /*
+    * File: OP_ADD_DOUBLE_2ADDR.S
+    */
 
-    /* binop/2addr vA, vB */
-    movzx   rINSTbl,%ecx           # ecx<- A+
-    andb    $0xf,%cl              # ecx<- A
-    fldl    (rFP,%ecx,4)          # vAA to fp stack
-    sarl    $4,rINST             # rINST<- B
-    faddl   (rFP,rINST,4)         # ex: faddp
+    movzx       rINSTbl,%ecx            # ecx<- A+
+    andb        $0xf,%cl               # ecx<- A
+    sarl        $4,rINST               # rINST<- B
+    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
+    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
     FETCH_INST_OPCODE 1 %eax
+    addsd       %xmm1, %xmm0            # %xmm0<- vA op vB
     ADVANCE_PC 1
-    fstpl    (rFP,%ecx,4)         # %st to vA
+    movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
     GOTO_NEXT_R %eax
 
-
 /* ------------------------------ */
 .L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
 /* File: x86/OP_SUB_DOUBLE_2ADDR.S */
-/* File: x86/binflop2addr.S */
-    /*
-     * Generic 32-bit binary float operation.
-     *
-     * For: add-fp, sub-fp, mul-fp, div-fp
-     */
+   /*
+    * File: OP_SUB_DOUBLE_2ADDR.S
+    */
 
-    /* binop/2addr vA, vB */
-    movzx   rINSTbl,%ecx           # ecx<- A+
-    andb    $0xf,%cl              # ecx<- A
-    fldl    (rFP,%ecx,4)          # vAA to fp stack
-    sarl    $4,rINST             # rINST<- B
-    fsubl   (rFP,rINST,4)         # ex: faddp
+    movzx       rINSTbl,%ecx            # ecx<- A+
+    andb        $0xf,%cl               # ecx<- A
+    sarl        $4,rINST               # rINST<- B
+    # TODO: movsd?
+    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
+    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
     FETCH_INST_OPCODE 1 %eax
+    subsd       %xmm1, %xmm0            # %xmm0<- vA op vB
     ADVANCE_PC 1
-    fstpl    (rFP,%ecx,4)         # %st to vA
+    movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
     GOTO_NEXT_R %eax
 
-
 /* ------------------------------ */
 .L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
 /* File: x86/OP_MUL_DOUBLE_2ADDR.S */
-/* File: x86/binflop2addr.S */
-    /*
-     * Generic 32-bit binary float operation.
-     *
-     * For: add-fp, sub-fp, mul-fp, div-fp
-     */
+   /*
+    * File: OP_MUL_DOUBLE_2ADDR.S
+    */
 
-    /* binop/2addr vA, vB */
-    movzx   rINSTbl,%ecx           # ecx<- A+
-    andb    $0xf,%cl              # ecx<- A
-    fldl    (rFP,%ecx,4)          # vAA to fp stack
-    sarl    $4,rINST             # rINST<- B
-    fmull   (rFP,rINST,4)         # ex: faddp
+    movzx       rINSTbl,%ecx            # ecx<- A+
+    andb        $0xf,%cl               # ecx<- A
+    sarl        $4,rINST               # rINST<- B
+    # TODO: movsd?
+    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
+    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
     FETCH_INST_OPCODE 1 %eax
+    mulsd       %xmm1, %xmm0            # %xmm0<- vA op vB
     ADVANCE_PC 1
-    fstpl    (rFP,%ecx,4)         # %st to vA
+    movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
     GOTO_NEXT_R %eax
 
-
 /* ------------------------------ */
 .L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
 /* File: x86/OP_DIV_DOUBLE_2ADDR.S */
@@ -7229,6 +7583,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SGET_VOLATILE_resolve                # if not, make it so
@@ -7254,8 +7614,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SGET_VOLATILE_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SGET_VOLATILE_finish                 # success, continue
 
 
 /* ------------------------------ */
@@ -7272,6 +7638,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SPUT_VOLATILE_resolve                # if not, make it so
@@ -7288,7 +7660,7 @@
 .LOP_SPUT_VOLATILE_resolve:
     movl     rSELF,%ecx
     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
-    movl     offThread_method(%ecx),%ecx          # ecx<- current method
+    movl     offThread_method(%ecx),%ecx        # ecx<- current method
     EXPORT_PC                                   # could throw, need to export
     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
     movl     %eax,OUT_ARG1(%esp)
@@ -7297,9 +7669,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SPUT_VOLATILE_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
-
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SPUT_VOLATILE_finish                 # success, continue
 
 /* ------------------------------ */
 .L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
@@ -7456,14 +7833,18 @@
     movl      rSELF,%ecx
     EXPORT_PC
     movzwl    2(rPC),%eax               # eax<- BBBB
-    leal      offThread_retval(%ecx),%ecx # ecx<- & self->retval
     SPILL(rIBASE)                       # preserve rIBASE
+    movl      offThread_subMode(%ecx), %edx # edx<- submode flags
+    andl      $kSubModeDebugProfile, %edx # debug or profile mode active?
+    jnz       .LOP_EXECUTE_INLINE_debugprofile   # yes, take slow path
+.LOP_EXECUTE_INLINE_resume:
+    leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
     movl      %ecx,OUT_ARG4(%esp)
     call      .LOP_EXECUTE_INLINE_continue      # make call; will return after
     UNSPILL(rIBASE)                     # restore rIBASE
     testl     %eax,%eax                 # successful?
+    jz        common_exceptionThrown    # no, handle exception
     FETCH_INST_OPCODE 3 %ecx
-    je        common_exceptionThrown    # no, handle exception
     ADVANCE_PC 3
     GOTO_NEXT_R %ecx
 
@@ -7507,6 +7888,42 @@
     jmp       *gDvmInlineOpsTable(%eax)
     # will return to caller of .LOP_EXECUTE_INLINE_continue
 
+    /*
+     * We're debugging or profiling.
+     * eax: opIndex
+     */
+.LOP_EXECUTE_INLINE_debugprofile:
+    movl      %eax,OUT_ARG0(%esp)       # arg0<- BBBB
+    SPILL_TMP1(%eax)                    # save opIndex
+    call      dvmResolveInlineNative    # dvmResolveInlineNative(opIndex)
+    movl      rSELF,%ecx                # restore self
+    testl     %eax,%eax                 # method resolved?
+    movl      %eax,%edx                 # save possibly resolved method in edx
+    UNSPILL_TMP1(%eax)                  # in case not resolved, restore opIndex
+    jz        .LOP_EXECUTE_INLINE_resume        # not resolved, just move on
+    SPILL_TMP2(%edx)                    # save method
+    movl      %edx,OUT_ARG0(%esp)       # arg0<- method
+    movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
+    call      dvmFastMethodTraceEnter   # dvmFastMethodTraceEnter(method,self)
+    movl      rSELF,%ecx                # restore self
+    UNSPILL_TMP1(%eax)                  # restore opIndex
+    leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
+    movl      %ecx,OUT_ARG4(%esp)       # needed for pResult of inline operation handler
+    call      .LOP_EXECUTE_INLINE_continue      # make call; will return after
+    SPILL_TMP1(%eax)                    # save result of inline
+    UNSPILL_TMP2(%eax)                  # restore method
+    movl      rSELF,%ecx                # restore self
+    movl      %eax,OUT_ARG0(%esp)       # arg0<- method
+    movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
+    call      dvmFastNativeMethodTraceExit # dvmFastNativeMethodTraceExit(method,self)
+    UNSPILL(rIBASE)                     # restore rIBASE
+    UNSPILL_TMP1(%eax)                  # restore result of inline
+    testl     %eax,%eax                 # successful?
+    jz        common_exceptionThrown    # no, handle exception
+    FETCH_INST_OPCODE 3 %ecx
+    ADVANCE_PC 3
+    GOTO_NEXT_R %ecx
+
 /* ------------------------------ */
 .L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
     /* (stub) */
@@ -7673,18 +8090,18 @@
      */
     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
-    movzwl    4(rPC),%eax               # eax<- FEDC or CCCC
-    movzwl    2(rPC),%ecx               # ecx<- BBBB
+    movzwl    4(rPC),%ecx               # eax<- FEDC or CCCC
+    movzwl    2(rPC),%edx               # ecx<- BBBB
     .if     (!0)
-    andl      $0xf,%eax                # eax<- C (or stays CCCC)
+    andl      $0xf,%ecx                # eax<- C (or stays CCCC)
     .endif
-    GET_VREG_R  %eax %eax               # eax<- vC ("this" ptr)
-    testl     %eax,%eax                 # null?
+    GET_VREG_R  %ecx %ecx               # ecx<- vC ("this" ptr)
+    testl     %ecx,%ecx                 # null?
     je        common_errNullObject      # yep, throw exception
-    movl      offObject_clazz(%eax),%eax # eax<- thisPtr->clazz
+    movl      offObject_clazz(%ecx),%eax # eax<- thisPtr->clazz
     movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
     EXPORT_PC                           # might throw later - get ready
-    movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
+    movl      (%eax,%edx,4),%eax        # eax<- vtable[BBBB]
     jmp       common_invokeMethodNoRange
 
 /* ------------------------------ */
@@ -7698,18 +8115,18 @@
      */
     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
-    movzwl    4(rPC),%eax               # eax<- FEDC or CCCC
-    movzwl    2(rPC),%ecx               # ecx<- BBBB
+    movzwl    4(rPC),%ecx               # eax<- FEDC or CCCC
+    movzwl    2(rPC),%edx               # ecx<- BBBB
     .if     (!1)
-    andl      $0xf,%eax                # eax<- C (or stays CCCC)
+    andl      $0xf,%ecx                # eax<- C (or stays CCCC)
     .endif
-    GET_VREG_R  %eax %eax               # eax<- vC ("this" ptr)
-    testl     %eax,%eax                 # null?
+    GET_VREG_R  %ecx %ecx               # ecx<- vC ("this" ptr)
+    testl     %ecx,%ecx                 # null?
     je        common_errNullObject      # yep, throw exception
-    movl      offObject_clazz(%eax),%eax # eax<- thisPtr->clazz
+    movl      offObject_clazz(%ecx),%eax # eax<- thisPtr->clazz
     movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
     EXPORT_PC                           # might throw later - get ready
-    movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
+    movl      (%eax,%edx,4),%eax        # eax<- vtable[BBBB]
     jmp       common_invokeMethodRange
 
 
@@ -7734,10 +8151,12 @@
     movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
     testl     %eax,%eax                 # null "this"?
     je        common_errNullObject      # "this" is null, throw exception
+    movl       %eax, TMP_SPILL1(%ebp)
     movzwl    2(rPC),%eax               # eax<- BBBB
     movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
     EXPORT_PC
     movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
+    movl      TMP_SPILL1(%ebp), %ecx
     jmp       common_invokeMethodNoRange
 
 /* ------------------------------ */
@@ -7762,10 +8181,12 @@
     movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
     testl     %eax,%eax                 # null "this"?
     je        common_errNullObject      # "this" is null, throw exception
+    movl       %eax, TMP_SPILL1(%ebp)
     movzwl    2(rPC),%eax               # eax<- BBBB
     movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
     EXPORT_PC
     movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
+    movl      TMP_SPILL1(%ebp), %ecx
     jmp       common_invokeMethodRange
 
 
@@ -7844,6 +8265,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SGET_OBJECT_VOLATILE_resolve                # if not, make it so
@@ -7869,8 +8296,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SGET_OBJECT_VOLATILE_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SGET_OBJECT_VOLATILE_finish                 # success, continue
 
 
 /* ------------------------------ */
@@ -7885,6 +8318,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SPUT_OBJECT_VOLATILE_resolve                # if not, make it so
@@ -7916,8 +8355,14 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .LOP_SPUT_OBJECT_VOLATILE_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .LOP_SPUT_OBJECT_VOLATILE_finish                 # success, continue
 
 
 /* ------------------------------ */
@@ -15164,11 +15609,19 @@
     movl    offThread_curFrame(%ecx),rFP
     movl    offThread_curHandlerTable(%ecx),rIBASE
 
-/* Remember %esp for future "longjmp" */
+    /* Remember %esp for future "longjmp" */
     movl    %esp,offThread_bailPtr(%ecx)
 
-   /* Normal case: start executing the instruction at rPC */
+    /* Fetch next instruction before potential jump */
     FETCH_INST
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    movl        $0, offThread_inJitCodeCache(%ecx)
+    cmpl        $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
+
+   /* Normal case: start executing the instruction at rPC */
     GOTO_NEXT
 
     .global dvmMterpStdBail
@@ -15190,7 +15643,7 @@
 dvmMterpStdBail:
     movl    4(%esp),%ecx                 # grab self
     movl    8(%esp),%eax                 # changeInterp to return reg
-    movl    offThread_bailPtr(%ecx),%esp   # Restore "setjmp" esp
+    movl    offThread_bailPtr(%ecx),%esp # Restore "setjmp" esp
     movl    %esp,%ebp
     addl    $(FRAME_SIZE-4), %ebp       # Restore %ebp at point of setjmp
     movl    EDI_SPILL(%ebp),%edi
@@ -15201,6 +15654,18 @@
     ret                                  # return to dvmMterpStdRun's caller
 
 
+#ifdef WITH_JIT
+    .global     dvmNcgInvokeInterpreter
+    .type       dvmNcgInvokeInterpreter, %function
+/* input: start of method in %eax */
+dvmNcgInvokeInterpreter:
+    movl        %eax, rPC
+    movl   rSELF, %ecx
+    movl   offThread_curHandlerTable(%ecx),rIBASE
+    FETCH_INST_R %ecx                    # %edx<- opcode
+    GOTO_NEXT_R %ecx                    # start executing the instruction at rPC
+#endif
+
 /*
  * Strings
  */
@@ -15247,12 +15712,14 @@
  * the interpreter and code cache. rPC must be set on entry.
  */
 dvmJitToInterpPunt:
+    GET_PC
 #if defined(WITH_JIT_TUNING)
     movl   rPC, OUT_ARG0(%esp)
     call   dvmBumpPunt
 #endif
     movl   rSELF, %ecx
     movl   offThread_curHandlerTable(%ecx),rIBASE
+    movl        $0, offThread_inJitCodeCache(%ecx)
     FETCH_INST_R %ecx
     GOTO_NEXT_R %ecx
 
@@ -15289,17 +15756,19 @@
 #if defined(WITH_JIT_TUNING)
     call   dvmBumpNoChain
 #endif
+    movl   %eax, rPC
     movl   rSELF, %eax
     movl   rPC,OUT_ARG0(%esp)
     movl   %eax,OUT_ARG1(%esp)
-    call   dvmJitGetTraceAddrThread        # (pc, self)
+    call   dvmJitGetTraceAddrThread  # (pc, self)
     movl   rSELF,%ecx                # ecx <- self
     movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
     cmpl   $0, %eax
     jz     1f
-    call   *%eax                     # exec translation if we've got one
+    jmp    *%eax                     # exec translation if we've got one
     # won't return
 1:
+    EXPORT_PC
     movl   rSELF, %ecx
     movl   offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_R %ecx
@@ -15307,7 +15776,7 @@
 
 /*
  * Return from the translation cache and immediately request a
- * translation fro the exit target, but don't attempt to chain.
+ * translation from the exit target, but don't attempt to chain.
  * rPC set on entry.
  */
     .global dvmJitToInterpTraceSelectNoChain
@@ -15315,15 +15784,17 @@
 #if defined(WITH_JIT_TUNING)
     call   dvmBumpNoChain
 #endif
+    movl   %ebx, rPC
+    lea    4(%esp), %esp #to recover the esp update due to function call
     movl   rSELF, %eax
     movl   rPC,OUT_ARG0(%esp)
     movl   %eax,OUT_ARG1(%esp)
-    call   dvmJitGetTraceAddrThread # (pc, self)
+    call   dvmJitGetTraceAddrThread  # (pc, self)
     movl   rSELF,%ecx
     cmpl   $0,%eax
     movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
     jz     1f
-    call   *%eax              # jump to tranlation
+    jmp    *%eax              # jump to tranlation
     # won't return
 
 /* No Translation - request one */
@@ -15336,7 +15807,8 @@
     FETCH_INST_R %ecx         # Continue interpreting if not
     GOTO_NEXT_R %ecx
 2:
-    movl   $kJitTSelectRequestHot,rINST  # ask for trace select
+    ## Looks like an EXPORT_PC is needed here. Now jmp to common_selectTrace2
+    movl   $kJitTSelectRequestHot,%eax # ask for trace select
     jmp    common_selectTrace
 
 /*
@@ -15346,21 +15818,32 @@
  */
     .global dvmJitToInterpTraceSelect
 dvmJitToInterpTraceSelect:
-    pop    rINST           # save chain cell address in callee save reg
-    movl   (rINST),rPC
+    movl   0(%esp), %eax          # get return address
+    movl   %ebx, rPC              # get first argument (target rPC)
+
+    ## TODO, need to clean up stack manipulation ... this isn't signal safe and
+    ## doesn't use the calling conventions of header.S
+    lea    4(%esp), %esp #to recover the esp update due to function call
+
+    ## An additional 5B instruction "jump 0" was added for a thread-safe
+    ## chaining cell update in JIT code cache. So the offset is now -17=-12-5.
+    lea    -17(%eax), %ebx #$JIT_OFFSET_CHAIN_START(%eax), %ebx
+    lea    -4(%esp), %esp
     movl   rSELF, %eax
     movl   rPC,OUT_ARG0(%esp)
     movl   %eax,OUT_ARG1(%esp)
     call   dvmJitGetTraceAddrThread # (pc, self)
+    lea    4(%esp), %esp
     cmpl   $0,%eax
+    movl   rSELF, %ecx
+    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
     jz     1b                 # no - ask for one
     movl   %eax,OUT_ARG0(%esp)
-# TODO - need to adjust rINST to beginning of sequence
     movl   rINST,OUT_ARG1(%esp)
     call   dvmJitChain        # Attempt dvmJitChain(codeAddr,chainAddr)
     cmpl   $0,%eax           # Success?
     jz     toInterpreter      # didn't chain - interpret
-    call   *%eax
+    jmp    *%eax
     # won't return
 
 /*
@@ -15368,71 +15851,210 @@
  */
     .global dvmJitToInterpBackwardBranch
 dvmJitToInterpBackwardBranch:
+
+    .global     dvmJitToExceptionThrown
+dvmJitToExceptionThrown: //rPC in
+    movl   rSELF, %edx
+    GET_PC
+    movl   $0, offThread_inJitCodeCache(%edx)
+    jmp common_exceptionThrown
+
     .global dvmJitToInterpNormal
 dvmJitToInterpNormal:
+/* one input: the target rPC value */
+    movl        0(%esp), %eax          # get return address
+    movl        %ebx, rPC              # get first argument (target rPC)
+
+    ## TODO, need to clean up stack manipulation ... this isn't signal safe and
+    ## doesn't use the calling conventions of header.S
+
+    ## An additional 5B instruction "jump 0" was added for a thread-safe
+    ## chaining cell update in JIT code cache. So the offset is now -17=-12-5.
+    lea         -17(%eax), %ebx #$JIT_OFFSET_CHAIN_START(%eax), %ebx
+    lea         4(%esp), %esp
+    movl        rPC, OUT_ARG0(%esp)
+    movl        rSELF, %ecx
+    movl        %ecx, OUT_ARG1(%esp)
+    call        dvmJitGetTraceAddrThread
+    ## Here is the change from using rGLUE to rSELF for accessing the
+    ## JIT code cache flag
+    movl        rSELF, %ecx
+    movl        %eax, offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
+    #lea         4(%esp), %esp
+    cmp         $0, %eax
+    je          toInterpreter
+    #lea         -8(%esp), %esp
+    movl        %ebx, OUT_ARG1(%esp)    # %ebx live thorugh dvmJitGetTraceAddrThread
+    movl        %eax, OUT_ARG0(%esp)    # first argument
+    call        dvmJitChain
+    #lea         8(%esp), %esp
+    cmp         $0, %eax
+    je          toInterpreter
+    jmp         *%eax                   #to native address
+
     .global dvmJitToInterpNoChain
 dvmJitToInterpNoChain:
+dvmJitToInterpNoChain: #rPC in eax
+    ## TODO, need to clean up stack manipulation ... this isn't signal safe and
+    ## doesn't use the calling conventions of header.S
+    movl        %eax, rPC
+    movl        rPC, OUT_ARG0(%esp)
+    movl        rSELF, %ecx
+    movl        %ecx, OUT_ARG1(%esp)
+    call        dvmJitGetTraceAddrThread
+    ## Here is the change from using rGLUE to rSELF for accessing the
+    ## JIT code cache flag
+    movl        rSELF, %ecx
+    movl        %eax, offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
+    cmp         $0, %eax
+    je          toInterpreter
+    jmp         *%eax                   #to native address
+
 toInterpreter:
-    jmp  common_abort
+    EXPORT_PC
+    movl        rSELF, %ecx
+    movl        offThread_curHandlerTable(%ecx), rIBASE
+    FETCH_INST
+    movl        offThread_pJitProfTable(%ecx), %eax
+    #Fallthrough
+
+/* ebx holds the pointer to the jit profile table
+   edx has the opCode */
+common_testUpdateProfile:
+    cmp         $0, %eax
+    je          4f
+/* eax holds the pointer to the jit profile table
+   edx has the opCode
+   rPC points to the next bytecode */
 
 common_updateProfile:
     # quick & dirty hash
-    movl   rPC, %eax
-    shrl   $12, %eax
-    xorl   rPC, %eax
-    andl   $((1<<JIT_PROF_SIZE_LOG_2)-1),%eax
-    decb   (%edx,%eax)
+    movl   rPC, %ecx
+    shrl   $12, %ecx
+    xorl   rPC, %ecx
+    andl   $((1<<JIT_PROF_SIZE_LOG_2)-1), %ecx
+    decb   (%ecx,%eax)
+    #jmp    1f # remove
     jz     2f
 1:
     GOTO_NEXT
 2:
+common_Profile:
 /*
  * Here, we switch to the debug interpreter to request
  * trace selection.  First, though, check to see if there
  * is already a native translation in place (and, if so,
  * jump to it now.
  */
-    GET_JIT_THRESHOLD %ecx rINST  # leaves rSELF in %ecx
+    SPILL(rIBASE)
+    SPILL_TMP1(rINST)
+    movl        rSELF, rIBASE
+    GET_JIT_THRESHOLD rIBASE rINST  # leaves rSELF in %ecx
     EXPORT_PC
-    movb   rINSTbl,(%edx,%eax)   # reset counter
-    movl   %ecx,rINST            # preserve rSELF
+    movb   rINSTbl,(%ecx,%eax)   # reset counter
+    movl   rIBASE,rINST            # preserve rSELF
     movl   rSELF, %eax
     movl   rPC,OUT_ARG0(%esp)
-    movl   %eax,OUT_ARG1(%esp)
-    call   dvmJitGetTraceAddr  # (pc, self)
+    movl   rIBASE,OUT_ARG1(%esp)
+    call   dvmJitGetTraceAddrThread  # (pc, self)
+    UNSPILL(rIBASE)
     movl   %eax,offThread_inJitCodeCache(rINST)   # set the inJitCodeCache flag
+    UNSPILL_TMP1(rINST)
     cmpl   $0,%eax
+    #jmp    1f # remove
     jz     1f
-    call   *%eax        # TODO: decide call vs/ jmp!.  No return either way
+    jmp   *%eax        # TODO: decide call vs/ jmp!.  No return either way
 1:
     movl   $kJitTSelectRequest,%eax
     # On entry, eax<- jitState, rPC valid
 common_selectTrace:
-/* TODO */
-    call   dvmAbort
-#if 0
-    movl   rSELF,%ecx
-    movl   %eax,offThread_jitState(%ecx)
-    movl   $kInterpEntryInstr,offThread_entryPoint(%ecx)
-    movl   $1,rINST
-    jmp    common_gotoBail
-#endif
-#endif
+    mov         %ebx, EBX_SPILL(%ebp)
+    movl        rSELF, %ebx
+    movzwl      offThread_subMode(%ebx), %ecx
+    and         $(kSubModeJitTraceBuild | kSubModeJitSV), %ecx
+    jne         3f                     # already doing JIT work, continue
+    movl        %eax, offThread_jitState(%ebx)
+    movl        rSELF, %eax
+    movl       %eax, OUT_ARG0(%esp)
+
+/*
+ * Call out to validate trace-building request. If successful, rIBASE will be swapped
+ * to send us into single-steppign trace building mode, so we need to refresh before
+ * we continue.
+ */
+
+   EXPORT_PC
+   SAVE_PC_FP_TO_SELF %ecx
+   call dvmJitCheckTraceRequest
+3:
+   mov          EBX_SPILL(%ebp), %ebx
+   FETCH_INST
+   movl rSELF, %ecx
+   movl offThread_curHandlerTable(%ecx), rIBASE
+4:
+   GOTO_NEXT
+
+common_selectTrace2:
+    mov         %ebx, EBX_SPILL(%ebp)
+    movl        rSELF, %ebx
+    movl        %ebx, OUT_ARG0(%esp)
+    movl        %eax, offThread_jitState(%ebx)
+    movzwl      offThread_subMode(%ebx), %ecx
+    mov         EBX_SPILL(%ebp), %ebx
+    and         (kSubModeJitTraceBuild | kSubModeJitSV), %ecx
+    jne         3f                     # already doing JIT work, continue
 
 
 
 /*
+ * Call out to validate trace-building request. If successful, rIBASE will be swapped
+ * to send us into single-steppign trace building mode, so we need to refresh before
+ * we continue.
+ */
+
+   EXPORT_PC
+   SAVE_PC_FP_TO_SELF %ecx
+   call dvmJitCheckTraceRequest
+3:
+   FETCH_INST
+   movl rSELF, %ecx
+   movl offThread_curHandlerTable(%ecx), rIBASE
+4:
+   GOTO_NEXT
+
+#endif
+
+/*
+ * For the invoke codes we need to know what register holds the "this" pointer. However
+ * it seems the this pointer is assigned consistently most times it is in %ecx but other
+ * times it is in OP_INVOKE_INTERFACE_JUMBO OP_INVOKE_INTERFACE OP_INVOKE_SUPER_QUICK and
+ * OP_INVOKE_VIRTUAL_QUICK
+*/
+
+/*
  * Common code for method invocation with range.
  *
  * On entry:
  *   eax = Method* methodToCall
+ *   ecx = "this"
  *   rINSTw trashed, must reload
  *   rIBASE trashed, must reload before resuming interpreter
  */
 
 common_invokeMethodRange:
 .LinvokeNewRange:
-
+#if defined(WITH_JIT)
+    SPILL_TMP1(%edx)
+    SPILL_TMP2(%ebx)
+    movl        rSELF, %edx
+    movzwl      offThread_subMode(%edx), %ebx
+    and         $kSubModeJitTraceBuild, %ebx
+    jz          6f
+    call        save_callsiteinfo
+6:
+    UNSPILL_TMP2(%ebx)
+    UNSPILL_TMP1(%edx)
+#endif
    /*
     * prepare to copy args to "outs" area of current frame
     */
@@ -15474,6 +16096,18 @@
     */
 
 common_invokeMethodNoRange:
+#if defined(WITH_JIT)
+    SPILL_TMP1(%edx)
+    SPILL_TMP2(%ebx)
+    movl        rSELF, %edx
+    movzwl      offThread_subMode(%edx), %ebx
+    and         $kSubModeJitTraceBuild, %ebx
+    jz          6f
+    call        save_callsiteinfo
+6:
+    UNSPILL_TMP2(%ebx)
+    UNSPILL_TMP1(%edx)
+#endif
 .LinvokeNewNoRange:
     movzbl      1(rPC),rINST       # rINST<- BA
     movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA
@@ -15561,6 +16195,9 @@
     movl        rSELF,%ecx              # %ecx<- pthread
     movl        rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP
     movl        rPC, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC
+#if defined(WITH_JIT)
+    movl        $0, offStackSaveArea_returnAddr(%edx)
+#endif
 
     /* Any special actions to take? */
     cmpw        $0, offThread_subMode(%ecx)
@@ -15584,6 +16221,12 @@
     movl        rFP, offThread_curFrame(%ecx) # curFrame<-newFP
     movl        offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST
+#if defined(WITH_JIT)
+    /* rPC is already updated */
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT                           # jump to methodToCall->insns
 
 2:
@@ -15643,8 +16286,8 @@
      */
     SPILL_TMP1(%eax)                    # save methodTocall
     movl        rPC, offThread_pc(%ecx)
-    movl        %eax, OUT_ARG0(%esp)
     movl        %ecx, OUT_ARG1(%esp)
+    movl        %eax, OUT_ARG0(%esp)
     movl        rFP, OUT_ARG2(%esp)
     call        dvmReportPreNativeInvoke # (methodToCall, self, fp)
     UNSPILL_TMP1(%eax)                  # restore methodToCall
@@ -15660,8 +16303,8 @@
 
     UNSPILL_TMP1(%eax)                  # restore methodToCall
     movl        rSELF, %ecx
-    movl        %eax, OUT_ARG0(%esp)
     movl        %ecx, OUT_ARG1(%esp)
+    movl        %eax, OUT_ARG0(%esp)
     movl        rFP, OUT_ARG2(%esp)
     call        dvmReportPostNativeInvoke # (methodToCall, self, fp)
     jmp         7b                      # rejoin
@@ -15678,36 +16321,68 @@
  * Common code for handling a return instruction
  */
 common_returnFromMethod:
-    movl    rSELF,%ecx
-    SAVEAREA_FROM_FP %eax                         # eax<- saveArea (old)
+    movl    rSELF, %ecx
+    SAVEAREA_FROM_FP %eax                       # %eax<- saveArea(old)
     cmpw    $0, offThread_subMode(%ecx)          # special action needed?
     jne     19f                                   # go if so
 14:
-    movl    offStackSaveArea_prevFrame(%eax),rFP  # rFP<- prevFrame
-    movl    (offStackSaveArea_method-sizeofStackSaveArea)(rFP),rINST
-    cmpl    $0,rINST                             # break?
-    je      common_gotoBail    # break frame, bail out completely
 
-    movl    offStackSaveArea_savedPc(%eax),rPC # pc<- saveArea->savedPC
-    movl    rINST,offThread_method(%ecx)       # self->method = newSave->meethod
-    movl    rFP,offThread_curFrame(%ecx)       # curFrame = fp
-    movl    offMethod_clazz(rINST),%eax        # eax<- method->clazz
-    movl    offThread_curHandlerTable(%ecx),rIBASE
-    movl    offClassObject_pDvmDex(%eax),rINST # rINST<- method->clazz->pDvmDex
-    FETCH_INST_OPCODE 3 %eax
-    movl    rINST,offThread_methodClassDex(%ecx)
+    movl        offStackSaveArea_prevFrame(%eax), rFP # rFP<- saveArea->PrevFrame
+    movl        (offStackSaveArea_method - sizeofStackSaveArea)(rFP), rINST # rINST<- method we are returning to
+    cmpl        $0, rINST               # check for break frame
+    je          common_gotoBail         # bail if break frame
+    movl        offThread_curHandlerTable(%ecx),rIBASE
+    movl        offStackSaveArea_savedPc(%eax), rPC # rPC<- saveAreaOld->savedPc
+#if defined(WITH_JIT)
+    movl        offStackSaveArea_returnAddr(%eax), %ecx
+#endif
+    movl        rSELF, %eax
+    movl        rINST, offThread_method(%eax) # glue->method<- newSave->method
+    movl        offMethod_clazz(rINST), rINST # rINST<- method->clazz
+    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- rFP
+#if defined(WITH_JIT)
+    //update self->offThread_inJitCodeCache
+    movl        %ecx, offThread_inJitCodeCache(%eax)
+#endif
+    movl        offClassObject_pDvmDex(rINST), rINST # rINST<- method->clazz->pDvmDex
+    movl        rINST, offThread_methodClassDex(%eax) # glue->pDvmDex<- method->clazz->pDvmDex
+#if defined(WITH_JIT)
+    cmp         $0, %ecx
+    je          .returnToBC
+    movl        %ecx, %eax
+    jmp         *%eax
+#endif
+
+.returnToBC:
+
+#if defined(WITH_JIT)
+    FETCH_INST_OPCODE  3, %ecx                 # %eax<- next instruction hi; fetch, advance
+    // %ecx has the opcode
+    addl         $6, rPC               # 3*2 = 6
+    SPILL_TMP1   (%ecx)
+    movl         rSELF, %ecx
+    FETCH_INST
+    UNSPILL_TMP1   (%ecx)
+    movzbl      1(rPC), rINST
+    jmp     *(rIBASE,%ecx,4)
+#else
+    FETCH_INST_WORD 3
     ADVANCE_PC 3
-    GOTO_NEXT_R %eax
+    GOTO_NEXT
+#endif
 
 19:
     /*
      * Handle special subMode actions
      * On entry, rFP: prevFP, %ecx: self, %eax: saveArea
      */
-    movl     rFP, offThread_curFrame(%ecx)    # update interpSave.curFrame
+    SPILL_TMP1(%ebx)
+    movl     offStackSaveArea_prevFrame(%eax), %ebx # %ebx<- saveArea->PrevFrame
     movl     rPC, offThread_pc(%ecx)          # update interpSave.pc
+    movl     %ebx, offThread_curFrame(%ecx)    # update interpSave.curFrame
     movl     %ecx, OUT_ARG0(%esp)             # parameter self
     call     dvmReportReturn                  # (self)
+    UNSPILL_TMP1(%ebx)
     movl     rSELF, %ecx                      # restore self
     SAVEAREA_FROM_FP %eax                     # restore saveArea
     jmp      14b
@@ -15730,12 +16405,74 @@
     movl   rINST,OUT_ARG1(%esp)     # changeInterp in arg1
     call   dvmMterpStdBail          # bail out....
 
+/*
+ * The JIT's invoke method needs to remember the callsite class and
+ * target pair.  Save them here so that they are available to
+ * dvmCheckJit following the interpretation of this invoke.
+ *
+ * eax = Method* methodToCall
+ * ecx = "this"
+ * edx = rSELF
+ * ebx = free to use
+ */
+#if defined(WITH_JIT)
+save_callsiteinfo:
+    cmp     $0, %ecx
+    je      2f
+    movl    offObject_clazz(%ecx), %ecx
+2:
+    movl    rSELF, %ebx
+    movl    %eax, offThread_methodToCall(%ebx)
+    movl    %ecx, offThread_callsiteClass(%ebx)
+    ret
+#endif
+
+#if defined(WITH_JIT)
+
+    /*
+     * If the JIT is actively building a trace we need to make sure
+     * that the field is fully resolved before including the current
+     * instruction.
+     *
+     * On entry:
+     *     %ecx: &dvmDex->pResFields[field]
+     *     %eax:  field pointer (must preserve)
+     */
+common_verifyField:
+    movl    %ebx, TMP_SPILL1(%ebp)
+    movl     rSELF, %ebx
+    movzwl   offThread_subMode(%ebx), %ebx
+    andl     $kSubModeJitTraceBuild, %ebx
+    movl    TMP_SPILL1(%ebp), %ebx
+    jne      1f
+    ret
+1:
+    movl    (%ecx), %ecx
+    cmp     $0, %ecx
+    je      1f
+    ret
+1:
+    SPILL_TMP1(%eax)
+    SPILL_TMP2(%edx)
+    movl     rSELF, %ecx
+    # Because we call into this helper from a bytecode, we have
+    # to be careful not to write over the return address when using
+    # the OUT_ARG macros
+    lea      -8(%esp), %esp
+    movl     %ecx, OUT_ARG0(%esp)
+    movl     rPC, OUT_ARG1(%esp)
+    call     dvmJitEndTraceSelect
+    lea      8(%esp), %esp
+    UNSPILL_TMP2(%edx)
+    UNSPILL_TMP1(%eax)
+    ret
+#endif
 
 /*
  * After returning from a "selfd" function, pull out the updated values
  * and start executing at the next instruction.
  */
- common_resumeAfterGlueCall:
+common_resumeAfterGlueCall:
      movl  rSELF, %eax
      movl  offThread_pc(%eax),rPC
      movl  offThread_curFrame(%eax),rFP
@@ -15768,7 +16505,6 @@
  * On entry, method name in eax
  */
 common_errNoSuchMethod:
-
     EXPORT_PC
     movl    %eax,OUT_ARG0(%esp)
     call    dvmThrowNoSuchMethodError
@@ -15811,12 +16547,132 @@
  * This does not return.
  */
 common_exceptionThrown:
-    movl    rSELF,%ecx
-    movl    rPC,offThread_pc(%ecx)
-    movl    rFP,offThread_curFrame(%ecx)
-    movl    %ecx,OUT_ARG0(%esp)
-    call    dvmMterp_exceptionThrown
-    jmp     common_resumeAfterGlueCall
+.LexceptionNew:
+
+    EXPORT_PC
+    movl       rSELF, %ecx
+    movl       %ecx, OUT_ARG0(%esp)
+    call       dvmCheckSuspendPending
+
+    movl       rSELF, %ecx
+    movl       offThread_exception(%ecx), %edx   # %edx <- self->exception
+    movl       %edx, OUT_ARG0(%esp)
+    movl       %ecx, OUT_ARG1(%esp)
+    SPILL_TMP1(%edx)
+    call       dvmAddTrackedAlloc      # don't let the exception be GCed
+    UNSPILL_TMP1(%edx)
+    movl       rSELF, %ecx
+    movl       offThread_subMode(%ecx), %eax    # get subMode flags
+    movl       $0, offThread_exception(%ecx)
+
+    # Special subMode?
+    cmpl       $0, %eax                # any special subMode handling needed?
+    je         8f                      # go if so
+
+    # Manage debugger bookkeeping
+    movl       rPC, offThread_pc(%ecx) # update interpSave.pc
+    movl       rFP, offThread_curFrame(%ecx) # update interpSave.curFrame
+    movl       %ecx, OUT_ARG0(%esp)
+    movl       %edx, OUT_ARG1(%esp)
+    SPILL_TMP1(%edx)
+    call       dvmReportExceptionThrow # (self, exception)
+    UNSPILL_TMP1(%edx)
+    movl       rSELF, %ecx
+
+8:
+    /*
+    * set up args and a local for &fp
+    */
+    lea        20(%esp), %esp          # raise %esp
+    movl       rFP, (%esp)               # save fp
+    movl       %esp, %eax              # %eax = &fp
+    lea        -20(%esp), %esp         # reset %esp
+    movl       %eax, OUT_ARG4(%esp)    # Arg 4 = &fp
+    movl       $0, OUT_ARG3(%esp)      # Arg 3 = false
+    movl       %edx, OUT_ARG2(%esp)    # Arg 2 = exception
+    movl       %ecx, OUT_ARG0(%esp)    # Arg 0 = self
+
+    movl       offThread_method(%ecx), %eax # %eax = self->method
+    movl       offMethod_insns(%eax), %eax  # %eax = self->method->insn
+    # ldrh    lr, [rSELF, #offThread_subMode]  @ lr<- subMode flags  # TODO
+    movl       rPC, %ecx
+    subl       %eax, %ecx              # %ecx = pc - self->method->insn
+    sar        $1, %ecx                # adjust %ecx for code offset
+    movl       %ecx, OUT_ARG1(%esp)    # Arg 1 = %ecx
+
+    /* call, %eax gets catchRelPc (a code-unit offset) */
+    SPILL_TMP1(%edx)                   # save exception
+    call       dvmFindCatchBlock       # call(self, relPc, exc, scan?, &fp)
+    UNSPILL_TMP1(%edx)                 # restore exception
+
+    /* fix earlier stack overflow if necessary; may trash rFP */
+    movl       rSELF, %ecx
+    cmpl       $0, offThread_stackOverflowed(%ecx) # did we overflow?
+    je         1f                         # no, skip ahead
+    movl       %eax, rFP                  # save relPc result in rFP
+    movl       %ecx, OUT_ARG0(%esp)       # Arg 0 = self
+    movl       %edx, OUT_ARG1(%esp)       # Arg 1 = exception
+    SPILL_TMP1(%edx)
+    call       dvmCleanupStackOverflow    # call(self, exception)
+    UNSPILL_TMP1(%edx)
+    movl       rFP, %eax                  # restore result
+    movl       rSELF, %ecx
+1:
+
+    /* update frame pointer and check result from dvmFindCatchBlock */
+    movl       20(%esp), rFP              # retrieve the updated rFP
+    cmpl       $0, %eax                  # is catchRelPc < 0?
+    jl         .LnotCaughtLocally
+
+    /* adjust locals to match self->interpSave.curFrame and updated PC */
+    SAVEAREA_FROM_FP rINST             # rINST<- new save area
+    movl       offStackSaveArea_method(rINST), rINST # rINST<- new method
+    movl       rINST, offThread_method(%ecx)         # self->method = new method
+    movl       offMethod_clazz(rINST), %ecx          # %ecx = method->clazz
+    movl       offMethod_insns(rINST), rINST         # rINST = method->insn
+    movl       offClassObject_pDvmDex(%ecx), %ecx    # %ecx = method->clazz->pDvmDex
+    lea        (rINST, %eax, 2), rPC      # rPC<- method->insns + catchRelPc
+    movl       rSELF, rINST
+    movl       %ecx, offThread_methodClassDex(rINST) # self->pDvmDex = method->clazz->pDvmDex
+
+    /* release the tracked alloc on the exception */
+    movl       %edx, OUT_ARG0(%esp)       # Arg 0 = exception
+    movl       rINST, OUT_ARG1(%esp)      # Arg 1 = self
+    SPILL_TMP1(%edx)
+    call       dvmReleaseTrackedAlloc     # release the exception
+    UNSPILL_TMP1(%edx)
+
+    /* restore the exception if the handler wants it */
+    movl       rSELF, %ecx
+    FETCH_INST
+    movzbl     rINSTbl, %eax
+    cmpl       $OP_MOVE_EXCEPTION, %eax   # is it "move-exception"?
+    jne        1f
+    movl       %edx, offThread_exception(%ecx) # restore exception
+1:
+    movl       offThread_curHandlerTable(%ecx), rIBASE # refresh rIBASE
+    GOTO_NEXT
+
+.LnotCaughtLocally: # %edx = exception
+    /* fix stack overflow if necessary */
+    movl       rSELF, %ecx
+    movl       offThread_stackOverflowed(%ecx), %eax
+    cmpl       $0, %eax                   # did we overflow earlier?
+    je         1f
+    movl       %ecx, OUT_ARG0(%esp)
+    movl       %edx, OUT_ARG1(%esp)
+    SPILL_TMP1(%edx)
+    call       dvmCleanupStackOverflow
+    UNSPILL_TMP1(%edx)
+
+1:
+    movl       rSELF, %ecx
+    movl       %edx, offThread_exception(%ecx) #restore exception
+    movl       %edx, OUT_ARG0(%esp)
+    movl       %ecx, OUT_ARG1(%esp)
+    call       dvmReleaseTrackedAlloc     # release the exception
+    movl       rSELF, %ecx
+    jmp        common_gotoBail            # bail out
 
 common_abort:
     movl    $0xdeadf00d,%eax
diff --git a/vm/mterp/out/InterpC-allstubs.cpp b/vm/mterp/out/InterpC-allstubs.cpp
index c69e2ce..0e91b55 100644
--- a/vm/mterp/out/InterpC-allstubs.cpp
+++ b/vm/mterp/out/InterpC-allstubs.cpp
@@ -2857,7 +2857,7 @@
             ;
         }
 
-        if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
+        if (self->interpBreak.ctl.subMode & kSubModeDebugProfile) {
             if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
                 GOTO_exceptionThrown();
         } else {
@@ -2902,7 +2902,7 @@
             ;
         }
 
-        if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
+        if (self->interpBreak.ctl.subMode & kSubModeDebugProfile) {
             if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
                 GOTO_exceptionThrown();
         } else {
diff --git a/vm/mterp/out/InterpC-portable.cpp b/vm/mterp/out/InterpC-portable.cpp
index 4d40eb5..4055c0b 100644
--- a/vm/mterp/out/InterpC-portable.cpp
+++ b/vm/mterp/out/InterpC-portable.cpp
@@ -2868,7 +2868,7 @@
             ;
         }
 
-        if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
+        if (self->interpBreak.ctl.subMode & kSubModeDebugProfile) {
             if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
                 GOTO_exceptionThrown();
         } else {
@@ -2913,7 +2913,7 @@
             ;
         }
 
-        if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
+        if (self->interpBreak.ctl.subMode & kSubModeDebugProfile) {
             if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
                 GOTO_exceptionThrown();
         } else {
diff --git a/vm/mterp/out/InterpC-x86-atom.cpp b/vm/mterp/out/InterpC-x86-atom.cpp
deleted file mode 100644
index 400ba66..0000000
--- a/vm/mterp/out/InterpC-x86-atom.cpp
+++ /dev/null
@@ -1,2308 +0,0 @@
-/*
- * This file was generated automatically by gen-mterp.py for 'x86-atom'.
- *
- * --> DO NOT EDIT <--
- */
-
-/* File: c/header.cpp */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* common includes */
-#include "Dalvik.h"
-#include "interp/InterpDefs.h"
-#include "mterp/Mterp.h"
-#include <math.h>                   // needed for fmod, fmodf
-#include "mterp/common/FindInterface.h"
-
-/*
- * Configuration defines.  These affect the C implementations, i.e. the
- * portable interpreter(s) and C stubs.
- *
- * Some defines are controlled by the Makefile, e.g.:
- *   WITH_INSTR_CHECKS
- *   WITH_TRACKREF_CHECKS
- *   EASY_GDB
- *   NDEBUG
- */
-
-#ifdef WITH_INSTR_CHECKS            /* instruction-level paranoia (slow!) */
-# define CHECK_BRANCH_OFFSETS
-# define CHECK_REGISTER_INDICES
-#endif
-
-/*
- * Some architectures require 64-bit alignment for access to 64-bit data
- * types.  We can't just use pointers to copy 64-bit values out of our
- * interpreted register set, because gcc may assume the pointer target is
- * aligned and generate invalid code.
- *
- * There are two common approaches:
- *  (1) Use a union that defines a 32-bit pair and a 64-bit value.
- *  (2) Call memcpy().
- *
- * Depending upon what compiler you're using and what options are specified,
- * one may be faster than the other.  For example, the compiler might
- * convert a memcpy() of 8 bytes into a series of instructions and omit
- * the call.  The union version could cause some strange side-effects,
- * e.g. for a while ARM gcc thought it needed separate storage for each
- * inlined instance, and generated instructions to zero out ~700 bytes of
- * stack space at the top of the interpreter.
- *
- * The default is to use memcpy().  The current gcc for ARM seems to do
- * better with the union.
- */
-#if defined(__ARM_EABI__)
-# define NO_UNALIGN_64__UNION
-#endif
-/*
- * MIPS ABI requires 64-bit alignment for access to 64-bit data types.
- *
- * Use memcpy() to do the transfer
- */
-#if defined(__mips__)
-/* # define NO_UNALIGN_64__UNION */
-#endif
-
-
-//#define LOG_INSTR                   /* verbose debugging */
-/* set and adjust ANDROID_LOG_TAGS='*:i jdwp:i dalvikvm:i dalvikvmi:i' */
-
-/*
- * Export another copy of the PC on every instruction; this is largely
- * redundant with EXPORT_PC and the debugger code.  This value can be
- * compared against what we have stored on the stack with EXPORT_PC to
- * help ensure that we aren't missing any export calls.
- */
-#if WITH_EXTRA_GC_CHECKS > 1
-# define EXPORT_EXTRA_PC() (self->currentPc2 = pc)
-#else
-# define EXPORT_EXTRA_PC()
-#endif
-
-/*
- * Adjust the program counter.  "_offset" is a signed int, in 16-bit units.
- *
- * Assumes the existence of "const u2* pc" and "const u2* curMethod->insns".
- *
- * We don't advance the program counter until we finish an instruction or
- * branch, because we do want to have to unroll the PC if there's an
- * exception.
- */
-#ifdef CHECK_BRANCH_OFFSETS
-# define ADJUST_PC(_offset) do {                                            \
-        int myoff = _offset;        /* deref only once */                   \
-        if (pc + myoff < curMethod->insns ||                                \
-            pc + myoff >= curMethod->insns + dvmGetMethodInsnsSize(curMethod)) \
-        {                                                                   \
-            char* desc;                                                     \
-            desc = dexProtoCopyMethodDescriptor(&curMethod->prototype);     \
-            ALOGE("Invalid branch %d at 0x%04x in %s.%s %s",                 \
-                myoff, (int) (pc - curMethod->insns),                       \
-                curMethod->clazz->descriptor, curMethod->name, desc);       \
-            free(desc);                                                     \
-            dvmAbort();                                                     \
-        }                                                                   \
-        pc += myoff;                                                        \
-        EXPORT_EXTRA_PC();                                                  \
-    } while (false)
-#else
-# define ADJUST_PC(_offset) do {                                            \
-        pc += _offset;                                                      \
-        EXPORT_EXTRA_PC();                                                  \
-    } while (false)
-#endif
-
-/*
- * If enabled, log instructions as we execute them.
- */
-#ifdef LOG_INSTR
-# define ILOGD(...) ILOG(LOG_DEBUG, __VA_ARGS__)
-# define ILOGV(...) ILOG(LOG_VERBOSE, __VA_ARGS__)
-# define ILOG(_level, ...) do {                                             \
-        char debugStrBuf[128];                                              \
-        snprintf(debugStrBuf, sizeof(debugStrBuf), __VA_ARGS__);            \
-        if (curMethod != NULL)                                              \
-            ALOG(_level, LOG_TAG"i", "%-2d|%04x%s",                          \
-                self->threadId, (int)(pc - curMethod->insns), debugStrBuf); \
-        else                                                                \
-            ALOG(_level, LOG_TAG"i", "%-2d|####%s",                          \
-                self->threadId, debugStrBuf);                               \
-    } while(false)
-void dvmDumpRegs(const Method* method, const u4* framePtr, bool inOnly);
-# define DUMP_REGS(_meth, _frame, _inOnly) dvmDumpRegs(_meth, _frame, _inOnly)
-static const char kSpacing[] = "            ";
-#else
-# define ILOGD(...) ((void)0)
-# define ILOGV(...) ((void)0)
-# define DUMP_REGS(_meth, _frame, _inOnly) ((void)0)
-#endif
-
-/* get a long from an array of u4 */
-static inline s8 getLongFromArray(const u4* ptr, int idx)
-{
-#if defined(NO_UNALIGN_64__UNION)
-    union { s8 ll; u4 parts[2]; } conv;
-
-    ptr += idx;
-    conv.parts[0] = ptr[0];
-    conv.parts[1] = ptr[1];
-    return conv.ll;
-#else
-    s8 val;
-    memcpy(&val, &ptr[idx], 8);
-    return val;
-#endif
-}
-
-/* store a long into an array of u4 */
-static inline void putLongToArray(u4* ptr, int idx, s8 val)
-{
-#if defined(NO_UNALIGN_64__UNION)
-    union { s8 ll; u4 parts[2]; } conv;
-
-    ptr += idx;
-    conv.ll = val;
-    ptr[0] = conv.parts[0];
-    ptr[1] = conv.parts[1];
-#else
-    memcpy(&ptr[idx], &val, 8);
-#endif
-}
-
-/* get a double from an array of u4 */
-static inline double getDoubleFromArray(const u4* ptr, int idx)
-{
-#if defined(NO_UNALIGN_64__UNION)
-    union { double d; u4 parts[2]; } conv;
-
-    ptr += idx;
-    conv.parts[0] = ptr[0];
-    conv.parts[1] = ptr[1];
-    return conv.d;
-#else
-    double dval;
-    memcpy(&dval, &ptr[idx], 8);
-    return dval;
-#endif
-}
-
-/* store a double into an array of u4 */
-static inline void putDoubleToArray(u4* ptr, int idx, double dval)
-{
-#if defined(NO_UNALIGN_64__UNION)
-    union { double d; u4 parts[2]; } conv;
-
-    ptr += idx;
-    conv.d = dval;
-    ptr[0] = conv.parts[0];
-    ptr[1] = conv.parts[1];
-#else
-    memcpy(&ptr[idx], &dval, 8);
-#endif
-}
-
-/*
- * If enabled, validate the register number on every access.  Otherwise,
- * just do an array access.
- *
- * Assumes the existence of "u4* fp".
- *
- * "_idx" may be referenced more than once.
- */
-#ifdef CHECK_REGISTER_INDICES
-# define GET_REGISTER(_idx) \
-    ( (_idx) < curMethod->registersSize ? \
-        (fp[(_idx)]) : (assert(!"bad reg"),1969) )
-# define SET_REGISTER(_idx, _val) \
-    ( (_idx) < curMethod->registersSize ? \
-        (fp[(_idx)] = (u4)(_val)) : (assert(!"bad reg"),1969) )
-# define GET_REGISTER_AS_OBJECT(_idx)       ((Object *)GET_REGISTER(_idx))
-# define SET_REGISTER_AS_OBJECT(_idx, _val) SET_REGISTER(_idx, (s4)_val)
-# define GET_REGISTER_INT(_idx) ((s4) GET_REGISTER(_idx))
-# define SET_REGISTER_INT(_idx, _val) SET_REGISTER(_idx, (s4)_val)
-# define GET_REGISTER_WIDE(_idx) \
-    ( (_idx) < curMethod->registersSize-1 ? \
-        getLongFromArray(fp, (_idx)) : (assert(!"bad reg"),1969) )
-# define SET_REGISTER_WIDE(_idx, _val) \
-    ( (_idx) < curMethod->registersSize-1 ? \
-        (void)putLongToArray(fp, (_idx), (_val)) : assert(!"bad reg") )
-# define GET_REGISTER_FLOAT(_idx) \
-    ( (_idx) < curMethod->registersSize ? \
-        (*((float*) &fp[(_idx)])) : (assert(!"bad reg"),1969.0f) )
-# define SET_REGISTER_FLOAT(_idx, _val) \
-    ( (_idx) < curMethod->registersSize ? \
-        (*((float*) &fp[(_idx)]) = (_val)) : (assert(!"bad reg"),1969.0f) )
-# define GET_REGISTER_DOUBLE(_idx) \
-    ( (_idx) < curMethod->registersSize-1 ? \
-        getDoubleFromArray(fp, (_idx)) : (assert(!"bad reg"),1969.0) )
-# define SET_REGISTER_DOUBLE(_idx, _val) \
-    ( (_idx) < curMethod->registersSize-1 ? \
-        (void)putDoubleToArray(fp, (_idx), (_val)) : assert(!"bad reg") )
-#else
-# define GET_REGISTER(_idx)                 (fp[(_idx)])
-# define SET_REGISTER(_idx, _val)           (fp[(_idx)] = (_val))
-# define GET_REGISTER_AS_OBJECT(_idx)       ((Object*) fp[(_idx)])
-# define SET_REGISTER_AS_OBJECT(_idx, _val) (fp[(_idx)] = (u4)(_val))
-# define GET_REGISTER_INT(_idx)             ((s4)GET_REGISTER(_idx))
-# define SET_REGISTER_INT(_idx, _val)       SET_REGISTER(_idx, (s4)_val)
-# define GET_REGISTER_WIDE(_idx)            getLongFromArray(fp, (_idx))
-# define SET_REGISTER_WIDE(_idx, _val)      putLongToArray(fp, (_idx), (_val))
-# define GET_REGISTER_FLOAT(_idx)           (*((float*) &fp[(_idx)]))
-# define SET_REGISTER_FLOAT(_idx, _val)     (*((float*) &fp[(_idx)]) = (_val))
-# define GET_REGISTER_DOUBLE(_idx)          getDoubleFromArray(fp, (_idx))
-# define SET_REGISTER_DOUBLE(_idx, _val)    putDoubleToArray(fp, (_idx), (_val))
-#endif
-
-/*
- * Get 16 bits from the specified offset of the program counter.  We always
- * want to load 16 bits at a time from the instruction stream -- it's more
- * efficient than 8 and won't have the alignment problems that 32 might.
- *
- * Assumes existence of "const u2* pc".
- */
-#define FETCH(_offset)     (pc[(_offset)])
-
-/*
- * Extract instruction byte from 16-bit fetch (_inst is a u2).
- */
-#define INST_INST(_inst)    ((_inst) & 0xff)
-
-/*
- * Replace the opcode (used when handling breakpoints).  _opcode is a u1.
- */
-#define INST_REPLACE_OP(_inst, _opcode) (((_inst) & 0xff00) | _opcode)
-
-/*
- * Extract the "vA, vB" 4-bit registers from the instruction word (_inst is u2).
- */
-#define INST_A(_inst)       (((_inst) >> 8) & 0x0f)
-#define INST_B(_inst)       ((_inst) >> 12)
-
-/*
- * Get the 8-bit "vAA" 8-bit register index from the instruction word.
- * (_inst is u2)
- */
-#define INST_AA(_inst)      ((_inst) >> 8)
-
-/*
- * The current PC must be available to Throwable constructors, e.g.
- * those created by the various exception throw routines, so that the
- * exception stack trace can be generated correctly.  If we don't do this,
- * the offset within the current method won't be shown correctly.  See the
- * notes in Exception.c.
- *
- * This is also used to determine the address for precise GC.
- *
- * Assumes existence of "u4* fp" and "const u2* pc".
- */
-#define EXPORT_PC()         (SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc)
-
-/*
- * Check to see if "obj" is NULL.  If so, throw an exception.  Assumes the
- * pc has already been exported to the stack.
- *
- * Perform additional checks on debug builds.
- *
- * Use this to check for NULL when the instruction handler calls into
- * something that could throw an exception (so we have already called
- * EXPORT_PC at the top).
- */
-static inline bool checkForNull(Object* obj)
-{
-    if (obj == NULL) {
-        dvmThrowNullPointerException(NULL);
-        return false;
-    }
-#ifdef WITH_EXTRA_OBJECT_VALIDATION
-    if (!dvmIsHeapAddress(obj)) {
-        ALOGE("Invalid object %p", obj);
-        dvmAbort();
-    }
-#endif
-#ifndef NDEBUG
-    if (obj->clazz == NULL || ((u4) obj->clazz) <= 65536) {
-        /* probable heap corruption */
-        ALOGE("Invalid object class %p (in %p)", obj->clazz, obj);
-        dvmAbort();
-    }
-#endif
-    return true;
-}
-
-/*
- * Check to see if "obj" is NULL.  If so, export the PC into the stack
- * frame and throw an exception.
- *
- * Perform additional checks on debug builds.
- *
- * Use this to check for NULL when the instruction handler doesn't do
- * anything else that can throw an exception.
- */
-static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc)
-{
-    if (obj == NULL) {
-        EXPORT_PC();
-        dvmThrowNullPointerException(NULL);
-        return false;
-    }
-#ifdef WITH_EXTRA_OBJECT_VALIDATION
-    if (!dvmIsHeapAddress(obj)) {
-        ALOGE("Invalid object %p", obj);
-        dvmAbort();
-    }
-#endif
-#ifndef NDEBUG
-    if (obj->clazz == NULL || ((u4) obj->clazz) <= 65536) {
-        /* probable heap corruption */
-        ALOGE("Invalid object class %p (in %p)", obj->clazz, obj);
-        dvmAbort();
-    }
-#endif
-    return true;
-}
-
-/* File: cstubs/stubdefs.cpp */
-/*
- * In the C mterp stubs, "goto" is a function call followed immediately
- * by a return.
- */
-
-#define GOTO_TARGET_DECL(_target, ...)                                      \
-    extern "C" void dvmMterp_##_target(Thread* self, ## __VA_ARGS__);
-
-/* (void)xxx to quiet unused variable compiler warnings. */
-#define GOTO_TARGET(_target, ...)                                           \
-    void dvmMterp_##_target(Thread* self, ## __VA_ARGS__) {                 \
-        u2 ref, vsrc1, vsrc2, vdst;                                         \
-        u2 inst = FETCH(0);                                                 \
-        const Method* methodToCall;                                         \
-        StackSaveArea* debugSaveArea;                                       \
-        (void)ref; (void)vsrc1; (void)vsrc2; (void)vdst; (void)inst;        \
-        (void)methodToCall; (void)debugSaveArea;
-
-#define GOTO_TARGET_END }
-
-/*
- * Redefine what used to be local variable accesses into Thread struct
- * references.  (These are undefined down in "footer.cpp".)
- */
-#define retval                  self->interpSave.retval
-#define pc                      self->interpSave.pc
-#define fp                      self->interpSave.curFrame
-#define curMethod               self->interpSave.method
-#define methodClassDex          self->interpSave.methodClassDex
-#define debugTrackedRefStart    self->interpSave.debugTrackedRefStart
-
-/* ugh */
-#define STUB_HACK(x) x
-#if defined(WITH_JIT)
-#define JIT_STUB_HACK(x) x
-#else
-#define JIT_STUB_HACK(x)
-#endif
-
-/*
- * InterpSave's pc and fp must be valid when breaking out to a
- * "Reportxxx" routine.  Because the portable interpreter uses local
- * variables for these, we must flush prior.  Stubs, however, use
- * the interpSave vars directly, so this is a nop for stubs.
- */
-#define PC_FP_TO_SELF()
-#define PC_TO_SELF()
-
-/*
- * Opcode handler framing macros.  Here, each opcode is a separate function
- * that takes a "self" argument and returns void.  We can't declare
- * these "static" because they may be called from an assembly stub.
- * (void)xxx to quiet unused variable compiler warnings.
- */
-#define HANDLE_OPCODE(_op)                                                  \
-    extern "C" void dvmMterp_##_op(Thread* self);                           \
-    void dvmMterp_##_op(Thread* self) {                                     \
-        u4 ref;                                                             \
-        u2 vsrc1, vsrc2, vdst;                                              \
-        u2 inst = FETCH(0);                                                 \
-        (void)ref; (void)vsrc1; (void)vsrc2; (void)vdst; (void)inst;
-
-#define OP_END }
-
-/*
- * Like the "portable" FINISH, but don't reload "inst", and return to caller
- * when done.  Further, debugger/profiler checks are handled
- * before handler execution in mterp, so we don't do them here either.
- */
-#if defined(WITH_JIT)
-#define FINISH(_offset) {                                                   \
-        ADJUST_PC(_offset);                                                 \
-        if (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) {        \
-            dvmCheckJit(pc, self);                                          \
-        }                                                                   \
-        return;                                                             \
-    }
-#else
-#define FINISH(_offset) {                                                   \
-        ADJUST_PC(_offset);                                                 \
-        return;                                                             \
-    }
-#endif
-
-#define FINISH_BKPT(_opcode)       /* FIXME? */
-#define DISPATCH_EXTENDED(_opcode) /* FIXME? */
-
-/*
- * The "goto label" statements turn into function calls followed by
- * return statements.  Some of the functions take arguments, which in the
- * portable interpreter are handled by assigning values to globals.
- */
-
-#define GOTO_exceptionThrown()                                              \
-    do {                                                                    \
-        dvmMterp_exceptionThrown(self);                                     \
-        return;                                                             \
-    } while(false)
-
-#define GOTO_returnFromMethod()                                             \
-    do {                                                                    \
-        dvmMterp_returnFromMethod(self);                                    \
-        return;                                                             \
-    } while(false)
-
-#define GOTO_invoke(_target, _methodCallRange)                              \
-    do {                                                                    \
-        dvmMterp_##_target(self, _methodCallRange);                         \
-        return;                                                             \
-    } while(false)
-
-#define GOTO_invokeMethod(_methodCallRange, _methodToCall, _vsrc1, _vdst)   \
-    do {                                                                    \
-        dvmMterp_invokeMethod(self, _methodCallRange, _methodToCall,        \
-            _vsrc1, _vdst);                                                 \
-        return;                                                             \
-    } while(false)
-
-/*
- * As a special case, "goto bail" turns into a longjmp.
- */
-#define GOTO_bail()                                                         \
-    dvmMterpStdBail(self)
-
-/*
- * Periodically check for thread suspension.
- *
- * While we're at it, see if a debugger has attached or the profiler has
- * started.
- */
-#define PERIODIC_CHECKS(_pcadj) {                              \
-        if (dvmCheckSuspendQuick(self)) {                                   \
-            EXPORT_PC();  /* need for precise GC */                         \
-            dvmCheckSuspendPending(self);                                   \
-        }                                                                   \
-    }
-
-/* File: c/opcommon.cpp */
-/* forward declarations of goto targets */
-GOTO_TARGET_DECL(filledNewArray, bool methodCallRange);
-GOTO_TARGET_DECL(invokeVirtual, bool methodCallRange);
-GOTO_TARGET_DECL(invokeSuper, bool methodCallRange);
-GOTO_TARGET_DECL(invokeInterface, bool methodCallRange);
-GOTO_TARGET_DECL(invokeDirect, bool methodCallRange);
-GOTO_TARGET_DECL(invokeStatic, bool methodCallRange);
-GOTO_TARGET_DECL(invokeVirtualQuick, bool methodCallRange);
-GOTO_TARGET_DECL(invokeSuperQuick, bool methodCallRange);
-GOTO_TARGET_DECL(invokeMethod, bool methodCallRange, const Method* methodToCall,
-    u2 count, u2 regs);
-GOTO_TARGET_DECL(returnFromMethod);
-GOTO_TARGET_DECL(exceptionThrown);
-
-/*
- * ===========================================================================
- *
- * What follows are opcode definitions shared between multiple opcodes with
- * minor substitutions handled by the C pre-processor.  These should probably
- * use the mterp substitution mechanism instead, with the code here moved
- * into common fragment files (like the asm "binop.S"), although it's hard
- * to give up the C preprocessor in favor of the much simpler text subst.
- *
- * ===========================================================================
- */
-
-#define HANDLE_NUMCONV(_opcode, _opname, _fromtype, _totype)                \
-    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        ILOGV("|%s v%d,v%d", (_opname), vdst, vsrc1);                       \
-        SET_REGISTER##_totype(vdst,                                         \
-            GET_REGISTER##_fromtype(vsrc1));                                \
-        FINISH(1);
-
-#define HANDLE_FLOAT_TO_INT(_opcode, _opname, _fromvtype, _fromrtype,       \
-        _tovtype, _tortype)                                                 \
-    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
-    {                                                                       \
-        /* spec defines specific handling for +/- inf and NaN values */     \
-        _fromvtype val;                                                     \
-        _tovtype intMin, intMax, result;                                    \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        ILOGV("|%s v%d,v%d", (_opname), vdst, vsrc1);                       \
-        val = GET_REGISTER##_fromrtype(vsrc1);                              \
-        intMin = (_tovtype) 1 << (sizeof(_tovtype) * 8 -1);                 \
-        intMax = ~intMin;                                                   \
-        result = (_tovtype) val;                                            \
-        if (val >= intMax)          /* +inf */                              \
-            result = intMax;                                                \
-        else if (val <= intMin)     /* -inf */                              \
-            result = intMin;                                                \
-        else if (val != val)        /* NaN */                               \
-            result = 0;                                                     \
-        else                                                                \
-            result = (_tovtype) val;                                        \
-        SET_REGISTER##_tortype(vdst, result);                               \
-    }                                                                       \
-    FINISH(1);
-
-#define HANDLE_INT_TO_SMALL(_opcode, _opname, _type)                        \
-    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        ILOGV("|int-to-%s v%d,v%d", (_opname), vdst, vsrc1);                \
-        SET_REGISTER(vdst, (_type) GET_REGISTER(vsrc1));                    \
-        FINISH(1);
-
-/* NOTE: the comparison result is always a signed 4-byte integer */
-#define HANDLE_OP_CMPX(_opcode, _opname, _varType, _type, _nanVal)          \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
-    {                                                                       \
-        int result;                                                         \
-        u2 regs;                                                            \
-        _varType val1, val2;                                                \
-        vdst = INST_AA(inst);                                               \
-        regs = FETCH(1);                                                    \
-        vsrc1 = regs & 0xff;                                                \
-        vsrc2 = regs >> 8;                                                  \
-        ILOGV("|cmp%s v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);         \
-        val1 = GET_REGISTER##_type(vsrc1);                                  \
-        val2 = GET_REGISTER##_type(vsrc2);                                  \
-        if (val1 == val2)                                                   \
-            result = 0;                                                     \
-        else if (val1 < val2)                                               \
-            result = -1;                                                    \
-        else if (val1 > val2)                                               \
-            result = 1;                                                     \
-        else                                                                \
-            result = (_nanVal);                                             \
-        ILOGV("+ result=%d", result);                                       \
-        SET_REGISTER(vdst, result);                                         \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_OP_IF_XX(_opcode, _opname, _cmp)                             \
-    HANDLE_OPCODE(_opcode /*vA, vB, +CCCC*/)                                \
-        vsrc1 = INST_A(inst);                                               \
-        vsrc2 = INST_B(inst);                                               \
-        if ((s4) GET_REGISTER(vsrc1) _cmp (s4) GET_REGISTER(vsrc2)) {       \
-            int branchOffset = (s2)FETCH(1);    /* sign-extended */         \
-            ILOGV("|if-%s v%d,v%d,+0x%04x", (_opname), vsrc1, vsrc2,        \
-                branchOffset);                                              \
-            ILOGV("> branch taken");                                        \
-            if (branchOffset < 0)                                           \
-                PERIODIC_CHECKS(branchOffset);                              \
-            FINISH(branchOffset);                                           \
-        } else {                                                            \
-            ILOGV("|if-%s v%d,v%d,-", (_opname), vsrc1, vsrc2);             \
-            FINISH(2);                                                      \
-        }
-
-#define HANDLE_OP_IF_XXZ(_opcode, _opname, _cmp)                            \
-    HANDLE_OPCODE(_opcode /*vAA, +BBBB*/)                                   \
-        vsrc1 = INST_AA(inst);                                              \
-        if ((s4) GET_REGISTER(vsrc1) _cmp 0) {                              \
-            int branchOffset = (s2)FETCH(1);    /* sign-extended */         \
-            ILOGV("|if-%s v%d,+0x%04x", (_opname), vsrc1, branchOffset);    \
-            ILOGV("> branch taken");                                        \
-            if (branchOffset < 0)                                           \
-                PERIODIC_CHECKS(branchOffset);                              \
-            FINISH(branchOffset);                                           \
-        } else {                                                            \
-            ILOGV("|if-%s v%d,-", (_opname), vsrc1);                        \
-            FINISH(2);                                                      \
-        }
-
-#define HANDLE_UNOP(_opcode, _opname, _pfx, _sfx, _type)                    \
-    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        ILOGV("|%s v%d,v%d", (_opname), vdst, vsrc1);                       \
-        SET_REGISTER##_type(vdst, _pfx GET_REGISTER##_type(vsrc1) _sfx);    \
-        FINISH(1);
-
-#define HANDLE_OP_X_INT(_opcode, _opname, _op, _chkdiv)                     \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
-    {                                                                       \
-        u2 srcRegs;                                                         \
-        vdst = INST_AA(inst);                                               \
-        srcRegs = FETCH(1);                                                 \
-        vsrc1 = srcRegs & 0xff;                                             \
-        vsrc2 = srcRegs >> 8;                                               \
-        ILOGV("|%s-int v%d,v%d", (_opname), vdst, vsrc1);                   \
-        if (_chkdiv != 0) {                                                 \
-            s4 firstVal, secondVal, result;                                 \
-            firstVal = GET_REGISTER(vsrc1);                                 \
-            secondVal = GET_REGISTER(vsrc2);                                \
-            if (secondVal == 0) {                                           \
-                EXPORT_PC();                                                \
-                dvmThrowArithmeticException("divide by zero");              \
-                GOTO_exceptionThrown();                                     \
-            }                                                               \
-            if ((u4)firstVal == 0x80000000 && secondVal == -1) {            \
-                if (_chkdiv == 1)                                           \
-                    result = firstVal;  /* division */                      \
-                else                                                        \
-                    result = 0;         /* remainder */                     \
-            } else {                                                        \
-                result = firstVal _op secondVal;                            \
-            }                                                               \
-            SET_REGISTER(vdst, result);                                     \
-        } else {                                                            \
-            /* non-div/rem case */                                          \
-            SET_REGISTER(vdst,                                              \
-                (s4) GET_REGISTER(vsrc1) _op (s4) GET_REGISTER(vsrc2));     \
-        }                                                                   \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_OP_SHX_INT(_opcode, _opname, _cast, _op)                     \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
-    {                                                                       \
-        u2 srcRegs;                                                         \
-        vdst = INST_AA(inst);                                               \
-        srcRegs = FETCH(1);                                                 \
-        vsrc1 = srcRegs & 0xff;                                             \
-        vsrc2 = srcRegs >> 8;                                               \
-        ILOGV("|%s-int v%d,v%d", (_opname), vdst, vsrc1);                   \
-        SET_REGISTER(vdst,                                                  \
-            _cast GET_REGISTER(vsrc1) _op (GET_REGISTER(vsrc2) & 0x1f));    \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_OP_X_INT_LIT16(_opcode, _opname, _op, _chkdiv)               \
-    HANDLE_OPCODE(_opcode /*vA, vB, #+CCCC*/)                               \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        vsrc2 = FETCH(1);                                                   \
-        ILOGV("|%s-int/lit16 v%d,v%d,#+0x%04x",                             \
-            (_opname), vdst, vsrc1, vsrc2);                                 \
-        if (_chkdiv != 0) {                                                 \
-            s4 firstVal, result;                                            \
-            firstVal = GET_REGISTER(vsrc1);                                 \
-            if ((s2) vsrc2 == 0) {                                          \
-                EXPORT_PC();                                                \
-                dvmThrowArithmeticException("divide by zero");              \
-                GOTO_exceptionThrown();                                     \
-            }                                                               \
-            if ((u4)firstVal == 0x80000000 && ((s2) vsrc2) == -1) {         \
-                /* won't generate /lit16 instr for this; check anyway */    \
-                if (_chkdiv == 1)                                           \
-                    result = firstVal;  /* division */                      \
-                else                                                        \
-                    result = 0;         /* remainder */                     \
-            } else {                                                        \
-                result = firstVal _op (s2) vsrc2;                           \
-            }                                                               \
-            SET_REGISTER(vdst, result);                                     \
-        } else {                                                            \
-            /* non-div/rem case */                                          \
-            SET_REGISTER(vdst, GET_REGISTER(vsrc1) _op (s2) vsrc2);         \
-        }                                                                   \
-        FINISH(2);
-
-#define HANDLE_OP_X_INT_LIT8(_opcode, _opname, _op, _chkdiv)                \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, #+CC*/)                               \
-    {                                                                       \
-        u2 litInfo;                                                         \
-        vdst = INST_AA(inst);                                               \
-        litInfo = FETCH(1);                                                 \
-        vsrc1 = litInfo & 0xff;                                             \
-        vsrc2 = litInfo >> 8;       /* constant */                          \
-        ILOGV("|%s-int/lit8 v%d,v%d,#+0x%02x",                              \
-            (_opname), vdst, vsrc1, vsrc2);                                 \
-        if (_chkdiv != 0) {                                                 \
-            s4 firstVal, result;                                            \
-            firstVal = GET_REGISTER(vsrc1);                                 \
-            if ((s1) vsrc2 == 0) {                                          \
-                EXPORT_PC();                                                \
-                dvmThrowArithmeticException("divide by zero");              \
-                GOTO_exceptionThrown();                                     \
-            }                                                               \
-            if ((u4)firstVal == 0x80000000 && ((s1) vsrc2) == -1) {         \
-                if (_chkdiv == 1)                                           \
-                    result = firstVal;  /* division */                      \
-                else                                                        \
-                    result = 0;         /* remainder */                     \
-            } else {                                                        \
-                result = firstVal _op ((s1) vsrc2);                         \
-            }                                                               \
-            SET_REGISTER(vdst, result);                                     \
-        } else {                                                            \
-            SET_REGISTER(vdst,                                              \
-                (s4) GET_REGISTER(vsrc1) _op (s1) vsrc2);                   \
-        }                                                                   \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_OP_SHX_INT_LIT8(_opcode, _opname, _cast, _op)                \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, #+CC*/)                               \
-    {                                                                       \
-        u2 litInfo;                                                         \
-        vdst = INST_AA(inst);                                               \
-        litInfo = FETCH(1);                                                 \
-        vsrc1 = litInfo & 0xff;                                             \
-        vsrc2 = litInfo >> 8;       /* constant */                          \
-        ILOGV("|%s-int/lit8 v%d,v%d,#+0x%02x",                              \
-            (_opname), vdst, vsrc1, vsrc2);                                 \
-        SET_REGISTER(vdst,                                                  \
-            _cast GET_REGISTER(vsrc1) _op (vsrc2 & 0x1f));                  \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_OP_X_INT_2ADDR(_opcode, _opname, _op, _chkdiv)               \
-    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        ILOGV("|%s-int-2addr v%d,v%d", (_opname), vdst, vsrc1);             \
-        if (_chkdiv != 0) {                                                 \
-            s4 firstVal, secondVal, result;                                 \
-            firstVal = GET_REGISTER(vdst);                                  \
-            secondVal = GET_REGISTER(vsrc1);                                \
-            if (secondVal == 0) {                                           \
-                EXPORT_PC();                                                \
-                dvmThrowArithmeticException("divide by zero");              \
-                GOTO_exceptionThrown();                                     \
-            }                                                               \
-            if ((u4)firstVal == 0x80000000 && secondVal == -1) {            \
-                if (_chkdiv == 1)                                           \
-                    result = firstVal;  /* division */                      \
-                else                                                        \
-                    result = 0;         /* remainder */                     \
-            } else {                                                        \
-                result = firstVal _op secondVal;                            \
-            }                                                               \
-            SET_REGISTER(vdst, result);                                     \
-        } else {                                                            \
-            SET_REGISTER(vdst,                                              \
-                (s4) GET_REGISTER(vdst) _op (s4) GET_REGISTER(vsrc1));      \
-        }                                                                   \
-        FINISH(1);
-
-#define HANDLE_OP_SHX_INT_2ADDR(_opcode, _opname, _cast, _op)               \
-    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        ILOGV("|%s-int-2addr v%d,v%d", (_opname), vdst, vsrc1);             \
-        SET_REGISTER(vdst,                                                  \
-            _cast GET_REGISTER(vdst) _op (GET_REGISTER(vsrc1) & 0x1f));     \
-        FINISH(1);
-
-#define HANDLE_OP_X_LONG(_opcode, _opname, _op, _chkdiv)                    \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
-    {                                                                       \
-        u2 srcRegs;                                                         \
-        vdst = INST_AA(inst);                                               \
-        srcRegs = FETCH(1);                                                 \
-        vsrc1 = srcRegs & 0xff;                                             \
-        vsrc2 = srcRegs >> 8;                                               \
-        ILOGV("|%s-long v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);       \
-        if (_chkdiv != 0) {                                                 \
-            s8 firstVal, secondVal, result;                                 \
-            firstVal = GET_REGISTER_WIDE(vsrc1);                            \
-            secondVal = GET_REGISTER_WIDE(vsrc2);                           \
-            if (secondVal == 0LL) {                                         \
-                EXPORT_PC();                                                \
-                dvmThrowArithmeticException("divide by zero");              \
-                GOTO_exceptionThrown();                                     \
-            }                                                               \
-            if ((u8)firstVal == 0x8000000000000000ULL &&                    \
-                secondVal == -1LL)                                          \
-            {                                                               \
-                if (_chkdiv == 1)                                           \
-                    result = firstVal;  /* division */                      \
-                else                                                        \
-                    result = 0;         /* remainder */                     \
-            } else {                                                        \
-                result = firstVal _op secondVal;                            \
-            }                                                               \
-            SET_REGISTER_WIDE(vdst, result);                                \
-        } else {                                                            \
-            SET_REGISTER_WIDE(vdst,                                         \
-                (s8) GET_REGISTER_WIDE(vsrc1) _op (s8) GET_REGISTER_WIDE(vsrc2)); \
-        }                                                                   \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_OP_SHX_LONG(_opcode, _opname, _cast, _op)                    \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
-    {                                                                       \
-        u2 srcRegs;                                                         \
-        vdst = INST_AA(inst);                                               \
-        srcRegs = FETCH(1);                                                 \
-        vsrc1 = srcRegs & 0xff;                                             \
-        vsrc2 = srcRegs >> 8;                                               \
-        ILOGV("|%s-long v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);       \
-        SET_REGISTER_WIDE(vdst,                                             \
-            _cast GET_REGISTER_WIDE(vsrc1) _op (GET_REGISTER(vsrc2) & 0x3f)); \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_OP_X_LONG_2ADDR(_opcode, _opname, _op, _chkdiv)              \
-    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        ILOGV("|%s-long-2addr v%d,v%d", (_opname), vdst, vsrc1);            \
-        if (_chkdiv != 0) {                                                 \
-            s8 firstVal, secondVal, result;                                 \
-            firstVal = GET_REGISTER_WIDE(vdst);                             \
-            secondVal = GET_REGISTER_WIDE(vsrc1);                           \
-            if (secondVal == 0LL) {                                         \
-                EXPORT_PC();                                                \
-                dvmThrowArithmeticException("divide by zero");              \
-                GOTO_exceptionThrown();                                     \
-            }                                                               \
-            if ((u8)firstVal == 0x8000000000000000ULL &&                    \
-                secondVal == -1LL)                                          \
-            {                                                               \
-                if (_chkdiv == 1)                                           \
-                    result = firstVal;  /* division */                      \
-                else                                                        \
-                    result = 0;         /* remainder */                     \
-            } else {                                                        \
-                result = firstVal _op secondVal;                            \
-            }                                                               \
-            SET_REGISTER_WIDE(vdst, result);                                \
-        } else {                                                            \
-            SET_REGISTER_WIDE(vdst,                                         \
-                (s8) GET_REGISTER_WIDE(vdst) _op (s8)GET_REGISTER_WIDE(vsrc1));\
-        }                                                                   \
-        FINISH(1);
-
-#define HANDLE_OP_SHX_LONG_2ADDR(_opcode, _opname, _cast, _op)              \
-    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        ILOGV("|%s-long-2addr v%d,v%d", (_opname), vdst, vsrc1);            \
-        SET_REGISTER_WIDE(vdst,                                             \
-            _cast GET_REGISTER_WIDE(vdst) _op (GET_REGISTER(vsrc1) & 0x3f)); \
-        FINISH(1);
-
-#define HANDLE_OP_X_FLOAT(_opcode, _opname, _op)                            \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
-    {                                                                       \
-        u2 srcRegs;                                                         \
-        vdst = INST_AA(inst);                                               \
-        srcRegs = FETCH(1);                                                 \
-        vsrc1 = srcRegs & 0xff;                                             \
-        vsrc2 = srcRegs >> 8;                                               \
-        ILOGV("|%s-float v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);      \
-        SET_REGISTER_FLOAT(vdst,                                            \
-            GET_REGISTER_FLOAT(vsrc1) _op GET_REGISTER_FLOAT(vsrc2));       \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_OP_X_DOUBLE(_opcode, _opname, _op)                           \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
-    {                                                                       \
-        u2 srcRegs;                                                         \
-        vdst = INST_AA(inst);                                               \
-        srcRegs = FETCH(1);                                                 \
-        vsrc1 = srcRegs & 0xff;                                             \
-        vsrc2 = srcRegs >> 8;                                               \
-        ILOGV("|%s-double v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);     \
-        SET_REGISTER_DOUBLE(vdst,                                           \
-            GET_REGISTER_DOUBLE(vsrc1) _op GET_REGISTER_DOUBLE(vsrc2));     \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_OP_X_FLOAT_2ADDR(_opcode, _opname, _op)                      \
-    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        ILOGV("|%s-float-2addr v%d,v%d", (_opname), vdst, vsrc1);           \
-        SET_REGISTER_FLOAT(vdst,                                            \
-            GET_REGISTER_FLOAT(vdst) _op GET_REGISTER_FLOAT(vsrc1));        \
-        FINISH(1);
-
-#define HANDLE_OP_X_DOUBLE_2ADDR(_opcode, _opname, _op)                     \
-    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);                                               \
-        ILOGV("|%s-double-2addr v%d,v%d", (_opname), vdst, vsrc1);          \
-        SET_REGISTER_DOUBLE(vdst,                                           \
-            GET_REGISTER_DOUBLE(vdst) _op GET_REGISTER_DOUBLE(vsrc1));      \
-        FINISH(1);
-
-#define HANDLE_OP_AGET(_opcode, _opname, _type, _regsize)                   \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
-    {                                                                       \
-        ArrayObject* arrayObj;                                              \
-        u2 arrayInfo;                                                       \
-        EXPORT_PC();                                                        \
-        vdst = INST_AA(inst);                                               \
-        arrayInfo = FETCH(1);                                               \
-        vsrc1 = arrayInfo & 0xff;    /* array ptr */                        \
-        vsrc2 = arrayInfo >> 8;      /* index */                            \
-        ILOGV("|aget%s v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);        \
-        arrayObj = (ArrayObject*) GET_REGISTER(vsrc1);                      \
-        if (!checkForNull((Object*) arrayObj))                              \
-            GOTO_exceptionThrown();                                         \
-        if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
-            dvmThrowArrayIndexOutOfBoundsException(                         \
-                arrayObj->length, GET_REGISTER(vsrc2));                     \
-            GOTO_exceptionThrown();                                         \
-        }                                                                   \
-        SET_REGISTER##_regsize(vdst,                                        \
-            ((_type*)(void*)arrayObj->contents)[GET_REGISTER(vsrc2)]);      \
-        ILOGV("+ AGET[%d]=%#x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));   \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_OP_APUT(_opcode, _opname, _type, _regsize)                   \
-    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
-    {                                                                       \
-        ArrayObject* arrayObj;                                              \
-        u2 arrayInfo;                                                       \
-        EXPORT_PC();                                                        \
-        vdst = INST_AA(inst);       /* AA: source value */                  \
-        arrayInfo = FETCH(1);                                               \
-        vsrc1 = arrayInfo & 0xff;   /* BB: array ptr */                     \
-        vsrc2 = arrayInfo >> 8;     /* CC: index */                         \
-        ILOGV("|aput%s v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);        \
-        arrayObj = (ArrayObject*) GET_REGISTER(vsrc1);                      \
-        if (!checkForNull((Object*) arrayObj))                              \
-            GOTO_exceptionThrown();                                         \
-        if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
-            dvmThrowArrayIndexOutOfBoundsException(                         \
-                arrayObj->length, GET_REGISTER(vsrc2));                     \
-            GOTO_exceptionThrown();                                         \
-        }                                                                   \
-        ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
-        ((_type*)(void*)arrayObj->contents)[GET_REGISTER(vsrc2)] =          \
-            GET_REGISTER##_regsize(vdst);                                   \
-    }                                                                       \
-    FINISH(2);
-
-/*
- * It's possible to get a bad value out of a field with sub-32-bit stores
- * because the -quick versions always operate on 32 bits.  Consider:
- *   short foo = -1  (sets a 32-bit register to 0xffffffff)
- *   iput-quick foo  (writes all 32 bits to the field)
- *   short bar = 1   (sets a 32-bit register to 0x00000001)
- *   iput-short      (writes the low 16 bits to the field)
- *   iget-quick foo  (reads all 32 bits from the field, yielding 0xffff0001)
- * This can only happen when optimized and non-optimized code has interleaved
- * access to the same field.  This is unlikely but possible.
- *
- * The easiest way to fix this is to always read/write 32 bits at a time.  On
- * a device with a 16-bit data bus this is sub-optimal.  (The alternative
- * approach is to have sub-int versions of iget-quick, but now we're wasting
- * Dalvik instruction space and making it less likely that handler code will
- * already be in the CPU i-cache.)
- */
-#define HANDLE_IGET_X(_opcode, _opname, _ftype, _regsize)                   \
-    HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/)                           \
-    {                                                                       \
-        InstField* ifield;                                                  \
-        Object* obj;                                                        \
-        EXPORT_PC();                                                        \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);   /* object ptr */                            \
-        ref = FETCH(1);         /* field ref */                             \
-        ILOGV("|iget%s v%d,v%d,field@0x%04x", (_opname), vdst, vsrc1, ref); \
-        obj = (Object*) GET_REGISTER(vsrc1);                                \
-        if (!checkForNull(obj))                                             \
-            GOTO_exceptionThrown();                                         \
-        ifield = (InstField*) dvmDexGetResolvedField(methodClassDex, ref);  \
-        if (ifield == NULL) {                                               \
-            ifield = dvmResolveInstField(curMethod->clazz, ref);            \
-            if (ifield == NULL)                                             \
-                GOTO_exceptionThrown();                                     \
-        }                                                                   \
-        SET_REGISTER##_regsize(vdst,                                        \
-            dvmGetField##_ftype(obj, ifield->byteOffset));                  \
-        ILOGV("+ IGET '%s'=0x%08llx", ifield->name,                         \
-            (u8) GET_REGISTER##_regsize(vdst));                             \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_IGET_X_QUICK(_opcode, _opname, _ftype, _regsize)             \
-    HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/)                           \
-    {                                                                       \
-        Object* obj;                                                        \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);   /* object ptr */                            \
-        ref = FETCH(1);         /* field offset */                          \
-        ILOGV("|iget%s-quick v%d,v%d,field@+%u",                            \
-            (_opname), vdst, vsrc1, ref);                                   \
-        obj = (Object*) GET_REGISTER(vsrc1);                                \
-        if (!checkForNullExportPC(obj, fp, pc))                             \
-            GOTO_exceptionThrown();                                         \
-        SET_REGISTER##_regsize(vdst, dvmGetField##_ftype(obj, ref));        \
-        ILOGV("+ IGETQ %d=0x%08llx", ref,                                   \
-            (u8) GET_REGISTER##_regsize(vdst));                             \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_IPUT_X(_opcode, _opname, _ftype, _regsize)                   \
-    HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/)                           \
-    {                                                                       \
-        InstField* ifield;                                                  \
-        Object* obj;                                                        \
-        EXPORT_PC();                                                        \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);   /* object ptr */                            \
-        ref = FETCH(1);         /* field ref */                             \
-        ILOGV("|iput%s v%d,v%d,field@0x%04x", (_opname), vdst, vsrc1, ref); \
-        obj = (Object*) GET_REGISTER(vsrc1);                                \
-        if (!checkForNull(obj))                                             \
-            GOTO_exceptionThrown();                                         \
-        ifield = (InstField*) dvmDexGetResolvedField(methodClassDex, ref);  \
-        if (ifield == NULL) {                                               \
-            ifield = dvmResolveInstField(curMethod->clazz, ref);            \
-            if (ifield == NULL)                                             \
-                GOTO_exceptionThrown();                                     \
-        }                                                                   \
-        dvmSetField##_ftype(obj, ifield->byteOffset,                        \
-            GET_REGISTER##_regsize(vdst));                                  \
-        ILOGV("+ IPUT '%s'=0x%08llx", ifield->name,                         \
-            (u8) GET_REGISTER##_regsize(vdst));                             \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_IPUT_X_QUICK(_opcode, _opname, _ftype, _regsize)             \
-    HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/)                           \
-    {                                                                       \
-        Object* obj;                                                        \
-        vdst = INST_A(inst);                                                \
-        vsrc1 = INST_B(inst);   /* object ptr */                            \
-        ref = FETCH(1);         /* field offset */                          \
-        ILOGV("|iput%s-quick v%d,v%d,field@0x%04x",                         \
-            (_opname), vdst, vsrc1, ref);                                   \
-        obj = (Object*) GET_REGISTER(vsrc1);                                \
-        if (!checkForNullExportPC(obj, fp, pc))                             \
-            GOTO_exceptionThrown();                                         \
-        dvmSetField##_ftype(obj, ref, GET_REGISTER##_regsize(vdst));        \
-        ILOGV("+ IPUTQ %d=0x%08llx", ref,                                   \
-            (u8) GET_REGISTER##_regsize(vdst));                             \
-    }                                                                       \
-    FINISH(2);
-
-/*
- * The JIT needs dvmDexGetResolvedField() to return non-null.
- * Because the portable interpreter is not involved with the JIT
- * and trace building, we only need the extra check here when this
- * code is massaged into a stub called from an assembly interpreter.
- * This is controlled by the JIT_STUB_HACK maco.
- */
-
-#define HANDLE_SGET_X(_opcode, _opname, _ftype, _regsize)                   \
-    HANDLE_OPCODE(_opcode /*vAA, field@BBBB*/)                              \
-    {                                                                       \
-        StaticField* sfield;                                                \
-        vdst = INST_AA(inst);                                               \
-        ref = FETCH(1);         /* field ref */                             \
-        ILOGV("|sget%s v%d,sfield@0x%04x", (_opname), vdst, ref);           \
-        sfield = (StaticField*)dvmDexGetResolvedField(methodClassDex, ref); \
-        if (sfield == NULL) {                                               \
-            EXPORT_PC();                                                    \
-            sfield = dvmResolveStaticField(curMethod->clazz, ref);          \
-            if (sfield == NULL)                                             \
-                GOTO_exceptionThrown();                                     \
-            if (dvmDexGetResolvedField(methodClassDex, ref) == NULL) {      \
-                JIT_STUB_HACK(dvmJitEndTraceSelect(self,pc));               \
-            }                                                               \
-        }                                                                   \
-        SET_REGISTER##_regsize(vdst, dvmGetStaticField##_ftype(sfield));    \
-        ILOGV("+ SGET '%s'=0x%08llx",                                       \
-            sfield->name, (u8)GET_REGISTER##_regsize(vdst));                \
-    }                                                                       \
-    FINISH(2);
-
-#define HANDLE_SPUT_X(_opcode, _opname, _ftype, _regsize)                   \
-    HANDLE_OPCODE(_opcode /*vAA, field@BBBB*/)                              \
-    {                                                                       \
-        StaticField* sfield;                                                \
-        vdst = INST_AA(inst);                                               \
-        ref = FETCH(1);         /* field ref */                             \
-        ILOGV("|sput%s v%d,sfield@0x%04x", (_opname), vdst, ref);           \
-        sfield = (StaticField*)dvmDexGetResolvedField(methodClassDex, ref); \
-        if (sfield == NULL) {                                               \
-            EXPORT_PC();                                                    \
-            sfield = dvmResolveStaticField(curMethod->clazz, ref);          \
-            if (sfield == NULL)                                             \
-                GOTO_exceptionThrown();                                     \
-            if (dvmDexGetResolvedField(methodClassDex, ref) == NULL) {      \
-                JIT_STUB_HACK(dvmJitEndTraceSelect(self,pc));               \
-            }                                                               \
-        }                                                                   \
-        dvmSetStaticField##_ftype(sfield, GET_REGISTER##_regsize(vdst));    \
-        ILOGV("+ SPUT '%s'=0x%08llx",                                       \
-            sfield->name, (u8)GET_REGISTER##_regsize(vdst));                \
-    }                                                                       \
-    FINISH(2);
-
-/* File: c/OP_IGET_VOLATILE.cpp */
-HANDLE_IGET_X(OP_IGET_VOLATILE,         "-volatile", IntVolatile, )
-OP_END
-
-/* File: c/OP_IPUT_VOLATILE.cpp */
-HANDLE_IPUT_X(OP_IPUT_VOLATILE,         "-volatile", IntVolatile, )
-OP_END
-
-/* File: c/OP_SGET_VOLATILE.cpp */
-HANDLE_SGET_X(OP_SGET_VOLATILE,         "-volatile", IntVolatile, )
-OP_END
-
-/* File: c/OP_SPUT_VOLATILE.cpp */
-HANDLE_SPUT_X(OP_SPUT_VOLATILE,         "-volatile", IntVolatile, )
-OP_END
-
-/* File: c/OP_IGET_OBJECT_VOLATILE.cpp */
-HANDLE_IGET_X(OP_IGET_OBJECT_VOLATILE,  "-object-volatile", ObjectVolatile, _AS_OBJECT)
-OP_END
-
-/* File: c/OP_IGET_WIDE_VOLATILE.cpp */
-HANDLE_IGET_X(OP_IGET_WIDE_VOLATILE,    "-wide-volatile", LongVolatile, _WIDE)
-OP_END
-
-/* File: c/OP_IPUT_WIDE_VOLATILE.cpp */
-HANDLE_IPUT_X(OP_IPUT_WIDE_VOLATILE,    "-wide-volatile", LongVolatile, _WIDE)
-OP_END
-
-/* File: c/OP_SGET_WIDE_VOLATILE.cpp */
-HANDLE_SGET_X(OP_SGET_WIDE_VOLATILE,    "-wide-volatile", LongVolatile, _WIDE)
-OP_END
-
-/* File: c/OP_SPUT_WIDE_VOLATILE.cpp */
-HANDLE_SPUT_X(OP_SPUT_WIDE_VOLATILE,    "-wide-volatile", LongVolatile, _WIDE)
-OP_END
-
-/* File: c/OP_BREAKPOINT.cpp */
-HANDLE_OPCODE(OP_BREAKPOINT)
-    {
-        /*
-         * Restart this instruction with the original opcode.  We do
-         * this by simply jumping to the handler.
-         *
-         * It's probably not necessary to update "inst", but we do it
-         * for the sake of anything that needs to do disambiguation in a
-         * common handler with INST_INST.
-         *
-         * The breakpoint itself is handled over in updateDebugger(),
-         * because we need to detect other events (method entry, single
-         * step) and report them in the same event packet, and we're not
-         * yet handling those through breakpoint instructions.  By the
-         * time we get here, the breakpoint has already been handled and
-         * the thread resumed.
-         */
-        u1 originalOpcode = dvmGetOriginalOpcode(pc);
-        ALOGV("+++ break 0x%02x (0x%04x -> 0x%04x)", originalOpcode, inst,
-            INST_REPLACE_OP(inst, originalOpcode));
-        inst = INST_REPLACE_OP(inst, originalOpcode);
-        FINISH_BKPT(originalOpcode);
-    }
-OP_END
-
-/* File: c/OP_EXECUTE_INLINE_RANGE.cpp */
-HANDLE_OPCODE(OP_EXECUTE_INLINE_RANGE /*{vCCCC..v(CCCC+AA-1)}, inline@BBBB*/)
-    {
-        u4 arg0, arg1, arg2, arg3;
-        arg0 = arg1 = arg2 = arg3 = 0;      /* placate gcc */
-
-        EXPORT_PC();
-
-        vsrc1 = INST_AA(inst);      /* #of args */
-        ref = FETCH(1);             /* inline call "ref" */
-        vdst = FETCH(2);            /* range base */
-        ILOGV("|execute-inline-range args=%d @%d {regs=v%d-v%d}",
-            vsrc1, ref, vdst, vdst+vsrc1-1);
-
-        assert((vdst >> 16) == 0);  // 16-bit type -or- high 16 bits clear
-        assert(vsrc1 <= 4);
-
-        switch (vsrc1) {
-        case 4:
-            arg3 = GET_REGISTER(vdst+3);
-            /* fall through */
-        case 3:
-            arg2 = GET_REGISTER(vdst+2);
-            /* fall through */
-        case 2:
-            arg1 = GET_REGISTER(vdst+1);
-            /* fall through */
-        case 1:
-            arg0 = GET_REGISTER(vdst+0);
-            /* fall through */
-        default:        // case 0
-            ;
-        }
-
-        if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
-            if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
-                GOTO_exceptionThrown();
-        } else {
-            if (!dvmPerformInlineOp4Std(arg0, arg1, arg2, arg3, &retval, ref))
-                GOTO_exceptionThrown();
-        }
-    }
-    FINISH(3);
-OP_END
-
-/* File: c/OP_INVOKE_OBJECT_INIT_RANGE.cpp */
-HANDLE_OPCODE(OP_INVOKE_OBJECT_INIT_RANGE /*{vCCCC..v(CCCC+AA-1)}, meth@BBBB*/)
-    {
-        Object* obj;
-
-        vsrc1 = FETCH(2);               /* reg number of "this" pointer */
-        obj = GET_REGISTER_AS_OBJECT(vsrc1);
-
-        if (!checkForNullExportPC(obj, fp, pc))
-            GOTO_exceptionThrown();
-
-        /*
-         * The object should be marked "finalizable" when Object.<init>
-         * completes normally.  We're going to assume it does complete
-         * (by virtue of being nothing but a return-void) and set it now.
-         */
-        if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISFINALIZABLE)) {
-            EXPORT_PC();
-            dvmSetFinalizable(obj);
-            if (dvmGetException(self))
-                GOTO_exceptionThrown();
-        }
-
-        if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
-            /* behave like OP_INVOKE_DIRECT_RANGE */
-            GOTO_invoke(invokeDirect, true);
-        }
-        FINISH(3);
-    }
-OP_END
-
-/* File: c/OP_RETURN_VOID_BARRIER.cpp */
-HANDLE_OPCODE(OP_RETURN_VOID_BARRIER /**/)
-    ILOGV("|return-void");
-#ifndef NDEBUG
-    retval.j = 0xababababULL;   /* placate valgrind */
-#endif
-    ANDROID_MEMBAR_STORE();
-    GOTO_returnFromMethod();
-OP_END
-
-/* File: c/OP_IPUT_OBJECT_VOLATILE.cpp */
-HANDLE_IPUT_X(OP_IPUT_OBJECT_VOLATILE,  "-object-volatile", ObjectVolatile, _AS_OBJECT)
-OP_END
-
-/* File: c/OP_SGET_OBJECT_VOLATILE.cpp */
-HANDLE_SGET_X(OP_SGET_OBJECT_VOLATILE,  "-object-volatile", ObjectVolatile, _AS_OBJECT)
-OP_END
-
-/* File: c/OP_SPUT_OBJECT_VOLATILE.cpp */
-HANDLE_SPUT_X(OP_SPUT_OBJECT_VOLATILE,  "-object-volatile", ObjectVolatile, _AS_OBJECT)
-OP_END
-
-/* File: c/gotoTargets.cpp */
-/*
- * C footer.  This has some common code shared by the various targets.
- */
-
-/*
- * Everything from here on is a "goto target".  In the basic interpreter
- * we jump into these targets and then jump directly to the handler for
- * next instruction.  Here, these are subroutines that return to the caller.
- */
-
-GOTO_TARGET(filledNewArray, bool methodCallRange, bool)
-    {
-        ClassObject* arrayClass;
-        ArrayObject* newArray;
-        u4* contents;
-        char typeCh;
-        int i;
-        u4 arg5;
-
-        EXPORT_PC();
-
-        ref = FETCH(1);             /* class ref */
-        vdst = FETCH(2);            /* first 4 regs -or- range base */
-
-        if (methodCallRange) {
-            vsrc1 = INST_AA(inst);  /* #of elements */
-            arg5 = -1;              /* silence compiler warning */
-            ILOGV("|filled-new-array-range args=%d @0x%04x {regs=v%d-v%d}",
-                vsrc1, ref, vdst, vdst+vsrc1-1);
-        } else {
-            arg5 = INST_A(inst);
-            vsrc1 = INST_B(inst);   /* #of elements */
-            ILOGV("|filled-new-array args=%d @0x%04x {regs=0x%04x %x}",
-               vsrc1, ref, vdst, arg5);
-        }
-
-        /*
-         * Resolve the array class.
-         */
-        arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
-        if (arrayClass == NULL) {
-            arrayClass = dvmResolveClass(curMethod->clazz, ref, false);
-            if (arrayClass == NULL)
-                GOTO_exceptionThrown();
-        }
-        /*
-        if (!dvmIsArrayClass(arrayClass)) {
-            dvmThrowRuntimeException(
-                "filled-new-array needs array class");
-            GOTO_exceptionThrown();
-        }
-        */
-        /* verifier guarantees this is an array class */
-        assert(dvmIsArrayClass(arrayClass));
-        assert(dvmIsClassInitialized(arrayClass));
-
-        /*
-         * Create an array of the specified type.
-         */
-        LOGVV("+++ filled-new-array type is '%s'", arrayClass->descriptor);
-        typeCh = arrayClass->descriptor[1];
-        if (typeCh == 'D' || typeCh == 'J') {
-            /* category 2 primitives not allowed */
-            dvmThrowRuntimeException("bad filled array req");
-            GOTO_exceptionThrown();
-        } else if (typeCh != 'L' && typeCh != '[' && typeCh != 'I') {
-            /* TODO: requires multiple "fill in" loops with different widths */
-            ALOGE("non-int primitives not implemented");
-            dvmThrowInternalError(
-                "filled-new-array not implemented for anything but 'int'");
-            GOTO_exceptionThrown();
-        }
-
-        newArray = dvmAllocArrayByClass(arrayClass, vsrc1, ALLOC_DONT_TRACK);
-        if (newArray == NULL)
-            GOTO_exceptionThrown();
-
-        /*
-         * Fill in the elements.  It's legal for vsrc1 to be zero.
-         */
-        contents = (u4*)(void*)newArray->contents;
-        if (methodCallRange) {
-            for (i = 0; i < vsrc1; i++)
-                contents[i] = GET_REGISTER(vdst+i);
-        } else {
-            assert(vsrc1 <= 5);
-            if (vsrc1 == 5) {
-                contents[4] = GET_REGISTER(arg5);
-                vsrc1--;
-            }
-            for (i = 0; i < vsrc1; i++) {
-                contents[i] = GET_REGISTER(vdst & 0x0f);
-                vdst >>= 4;
-            }
-        }
-        if (typeCh == 'L' || typeCh == '[') {
-            dvmWriteBarrierArray(newArray, 0, newArray->length);
-        }
-
-        retval.l = (Object*)newArray;
-    }
-    FINISH(3);
-GOTO_TARGET_END
-
-
-GOTO_TARGET(invokeVirtual, bool methodCallRange, bool)
-    {
-        Method* baseMethod;
-        Object* thisPtr;
-
-        EXPORT_PC();
-
-        vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
-        ref = FETCH(1);             /* method ref */
-        vdst = FETCH(2);            /* 4 regs -or- first reg */
-
-        /*
-         * The object against which we are executing a method is always
-         * in the first argument.
-         */
-        if (methodCallRange) {
-            assert(vsrc1 > 0);
-            ILOGV("|invoke-virtual-range args=%d @0x%04x {regs=v%d-v%d}",
-                vsrc1, ref, vdst, vdst+vsrc1-1);
-            thisPtr = (Object*) GET_REGISTER(vdst);
-        } else {
-            assert((vsrc1>>4) > 0);
-            ILOGV("|invoke-virtual args=%d @0x%04x {regs=0x%04x %x}",
-                vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
-            thisPtr = (Object*) GET_REGISTER(vdst & 0x0f);
-        }
-
-        if (!checkForNull(thisPtr))
-            GOTO_exceptionThrown();
-
-        /*
-         * Resolve the method.  This is the correct method for the static
-         * type of the object.  We also verify access permissions here.
-         */
-        baseMethod = dvmDexGetResolvedMethod(methodClassDex, ref);
-        if (baseMethod == NULL) {
-            baseMethod = dvmResolveMethod(curMethod->clazz, ref,METHOD_VIRTUAL);
-            if (baseMethod == NULL) {
-                ILOGV("+ unknown method or access denied");
-                GOTO_exceptionThrown();
-            }
-        }
-
-        /*
-         * Combine the object we found with the vtable offset in the
-         * method.
-         */
-        assert(baseMethod->methodIndex < thisPtr->clazz->vtableCount);
-        methodToCall = thisPtr->clazz->vtable[baseMethod->methodIndex];
-
-#if defined(WITH_JIT) && defined(MTERP_STUB)
-        self->methodToCall = methodToCall;
-        self->callsiteClass = thisPtr->clazz;
-#endif
-
-#if 0
-        if (dvmIsAbstractMethod(methodToCall)) {
-            /*
-             * This can happen if you create two classes, Base and Sub, where
-             * Sub is a sub-class of Base.  Declare a protected abstract
-             * method foo() in Base, and invoke foo() from a method in Base.
-             * Base is an "abstract base class" and is never instantiated
-             * directly.  Now, Override foo() in Sub, and use Sub.  This
-             * Works fine unless Sub stops providing an implementation of
-             * the method.
-             */
-            dvmThrowAbstractMethodError("abstract method not implemented");
-            GOTO_exceptionThrown();
-        }
-#else
-        assert(!dvmIsAbstractMethod(methodToCall) ||
-            methodToCall->nativeFunc != NULL);
-#endif
-
-        LOGVV("+++ base=%s.%s virtual[%d]=%s.%s",
-            baseMethod->clazz->descriptor, baseMethod->name,
-            (u4) baseMethod->methodIndex,
-            methodToCall->clazz->descriptor, methodToCall->name);
-        assert(methodToCall != NULL);
-
-#if 0
-        if (vsrc1 != methodToCall->insSize) {
-            ALOGW("WRONG METHOD: base=%s.%s virtual[%d]=%s.%s",
-                baseMethod->clazz->descriptor, baseMethod->name,
-                (u4) baseMethod->methodIndex,
-                methodToCall->clazz->descriptor, methodToCall->name);
-            //dvmDumpClass(baseMethod->clazz);
-            //dvmDumpClass(methodToCall->clazz);
-            dvmDumpAllClasses(0);
-        }
-#endif
-
-        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
-    }
-GOTO_TARGET_END
-
-GOTO_TARGET(invokeSuper, bool methodCallRange)
-    {
-        Method* baseMethod;
-        u2 thisReg;
-
-        EXPORT_PC();
-
-        vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
-        ref = FETCH(1);             /* method ref */
-        vdst = FETCH(2);            /* 4 regs -or- first reg */
-
-        if (methodCallRange) {
-            ILOGV("|invoke-super-range args=%d @0x%04x {regs=v%d-v%d}",
-                vsrc1, ref, vdst, vdst+vsrc1-1);
-            thisReg = vdst;
-        } else {
-            ILOGV("|invoke-super args=%d @0x%04x {regs=0x%04x %x}",
-                vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
-            thisReg = vdst & 0x0f;
-        }
-
-        /* impossible in well-formed code, but we must check nevertheless */
-        if (!checkForNull((Object*) GET_REGISTER(thisReg)))
-            GOTO_exceptionThrown();
-
-        /*
-         * Resolve the method.  This is the correct method for the static
-         * type of the object.  We also verify access permissions here.
-         * The first arg to dvmResolveMethod() is just the referring class
-         * (used for class loaders and such), so we don't want to pass
-         * the superclass into the resolution call.
-         */
-        baseMethod = dvmDexGetResolvedMethod(methodClassDex, ref);
-        if (baseMethod == NULL) {
-            baseMethod = dvmResolveMethod(curMethod->clazz, ref,METHOD_VIRTUAL);
-            if (baseMethod == NULL) {
-                ILOGV("+ unknown method or access denied");
-                GOTO_exceptionThrown();
-            }
-        }
-
-        /*
-         * Combine the object we found with the vtable offset in the
-         * method's class.
-         *
-         * We're using the current method's class' superclass, not the
-         * superclass of "this".  This is because we might be executing
-         * in a method inherited from a superclass, and we want to run
-         * in that class' superclass.
-         */
-        if (baseMethod->methodIndex >= curMethod->clazz->super->vtableCount) {
-            /*
-             * Method does not exist in the superclass.  Could happen if
-             * superclass gets updated.
-             */
-            dvmThrowNoSuchMethodError(baseMethod->name);
-            GOTO_exceptionThrown();
-        }
-        methodToCall = curMethod->clazz->super->vtable[baseMethod->methodIndex];
-
-#if 0
-        if (dvmIsAbstractMethod(methodToCall)) {
-            dvmThrowAbstractMethodError("abstract method not implemented");
-            GOTO_exceptionThrown();
-        }
-#else
-        assert(!dvmIsAbstractMethod(methodToCall) ||
-            methodToCall->nativeFunc != NULL);
-#endif
-        LOGVV("+++ base=%s.%s super-virtual=%s.%s",
-            baseMethod->clazz->descriptor, baseMethod->name,
-            methodToCall->clazz->descriptor, methodToCall->name);
-        assert(methodToCall != NULL);
-
-        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
-    }
-GOTO_TARGET_END
-
-GOTO_TARGET(invokeInterface, bool methodCallRange)
-    {
-        Object* thisPtr;
-        ClassObject* thisClass;
-
-        EXPORT_PC();
-
-        vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
-        ref = FETCH(1);             /* method ref */
-        vdst = FETCH(2);            /* 4 regs -or- first reg */
-
-        /*
-         * The object against which we are executing a method is always
-         * in the first argument.
-         */
-        if (methodCallRange) {
-            assert(vsrc1 > 0);
-            ILOGV("|invoke-interface-range args=%d @0x%04x {regs=v%d-v%d}",
-                vsrc1, ref, vdst, vdst+vsrc1-1);
-            thisPtr = (Object*) GET_REGISTER(vdst);
-        } else {
-            assert((vsrc1>>4) > 0);
-            ILOGV("|invoke-interface args=%d @0x%04x {regs=0x%04x %x}",
-                vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
-            thisPtr = (Object*) GET_REGISTER(vdst & 0x0f);
-        }
-
-        if (!checkForNull(thisPtr))
-            GOTO_exceptionThrown();
-
-        thisClass = thisPtr->clazz;
-
-        /*
-         * Given a class and a method index, find the Method* with the
-         * actual code we want to execute.
-         */
-        methodToCall = dvmFindInterfaceMethodInCache(thisClass, ref, curMethod,
-                        methodClassDex);
-#if defined(WITH_JIT) && defined(MTERP_STUB)
-        self->callsiteClass = thisClass;
-        self->methodToCall = methodToCall;
-#endif
-        if (methodToCall == NULL) {
-            assert(dvmCheckException(self));
-            GOTO_exceptionThrown();
-        }
-
-        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
-    }
-GOTO_TARGET_END
-
-GOTO_TARGET(invokeDirect, bool methodCallRange)
-    {
-        u2 thisReg;
-
-        EXPORT_PC();
-
-        vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
-        ref = FETCH(1);             /* method ref */
-        vdst = FETCH(2);            /* 4 regs -or- first reg */
-
-        if (methodCallRange) {
-            ILOGV("|invoke-direct-range args=%d @0x%04x {regs=v%d-v%d}",
-                vsrc1, ref, vdst, vdst+vsrc1-1);
-            thisReg = vdst;
-        } else {
-            ILOGV("|invoke-direct args=%d @0x%04x {regs=0x%04x %x}",
-                vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
-            thisReg = vdst & 0x0f;
-        }
-
-        if (!checkForNull((Object*) GET_REGISTER(thisReg)))
-            GOTO_exceptionThrown();
-
-        methodToCall = dvmDexGetResolvedMethod(methodClassDex, ref);
-        if (methodToCall == NULL) {
-            methodToCall = dvmResolveMethod(curMethod->clazz, ref,
-                            METHOD_DIRECT);
-            if (methodToCall == NULL) {
-                ILOGV("+ unknown direct method");     // should be impossible
-                GOTO_exceptionThrown();
-            }
-        }
-        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
-    }
-GOTO_TARGET_END
-
-GOTO_TARGET(invokeStatic, bool methodCallRange)
-    EXPORT_PC();
-
-    vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
-    ref = FETCH(1);             /* method ref */
-    vdst = FETCH(2);            /* 4 regs -or- first reg */
-
-    if (methodCallRange)
-        ILOGV("|invoke-static-range args=%d @0x%04x {regs=v%d-v%d}",
-            vsrc1, ref, vdst, vdst+vsrc1-1);
-    else
-        ILOGV("|invoke-static args=%d @0x%04x {regs=0x%04x %x}",
-            vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
-
-    methodToCall = dvmDexGetResolvedMethod(methodClassDex, ref);
-    if (methodToCall == NULL) {
-        methodToCall = dvmResolveMethod(curMethod->clazz, ref, METHOD_STATIC);
-        if (methodToCall == NULL) {
-            ILOGV("+ unknown method");
-            GOTO_exceptionThrown();
-        }
-
-#if defined(WITH_JIT) && defined(MTERP_STUB)
-        /*
-         * The JIT needs dvmDexGetResolvedMethod() to return non-null.
-         * Include the check if this code is being used as a stub
-         * called from the assembly interpreter.
-         */
-        if ((self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) &&
-            (dvmDexGetResolvedMethod(methodClassDex, ref) == NULL)) {
-            /* Class initialization is still ongoing */
-            dvmJitEndTraceSelect(self,pc);
-        }
-#endif
-    }
-    GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
-GOTO_TARGET_END
-
-GOTO_TARGET(invokeVirtualQuick, bool methodCallRange)
-    {
-        Object* thisPtr;
-
-        EXPORT_PC();
-
-        vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
-        ref = FETCH(1);             /* vtable index */
-        vdst = FETCH(2);            /* 4 regs -or- first reg */
-
-        /*
-         * The object against which we are executing a method is always
-         * in the first argument.
-         */
-        if (methodCallRange) {
-            assert(vsrc1 > 0);
-            ILOGV("|invoke-virtual-quick-range args=%d @0x%04x {regs=v%d-v%d}",
-                vsrc1, ref, vdst, vdst+vsrc1-1);
-            thisPtr = (Object*) GET_REGISTER(vdst);
-        } else {
-            assert((vsrc1>>4) > 0);
-            ILOGV("|invoke-virtual-quick args=%d @0x%04x {regs=0x%04x %x}",
-                vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
-            thisPtr = (Object*) GET_REGISTER(vdst & 0x0f);
-        }
-
-        if (!checkForNull(thisPtr))
-            GOTO_exceptionThrown();
-
-
-        /*
-         * Combine the object we found with the vtable offset in the
-         * method.
-         */
-        assert(ref < (unsigned int) thisPtr->clazz->vtableCount);
-        methodToCall = thisPtr->clazz->vtable[ref];
-#if defined(WITH_JIT) && defined(MTERP_STUB)
-        self->callsiteClass = thisPtr->clazz;
-        self->methodToCall = methodToCall;
-#endif
-
-#if 0
-        if (dvmIsAbstractMethod(methodToCall)) {
-            dvmThrowAbstractMethodError("abstract method not implemented");
-            GOTO_exceptionThrown();
-        }
-#else
-        assert(!dvmIsAbstractMethod(methodToCall) ||
-            methodToCall->nativeFunc != NULL);
-#endif
-
-        LOGVV("+++ virtual[%d]=%s.%s",
-            ref, methodToCall->clazz->descriptor, methodToCall->name);
-        assert(methodToCall != NULL);
-
-        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
-    }
-GOTO_TARGET_END
-
-GOTO_TARGET(invokeSuperQuick, bool methodCallRange)
-    {
-        u2 thisReg;
-
-        EXPORT_PC();
-
-        vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
-        ref = FETCH(1);             /* vtable index */
-        vdst = FETCH(2);            /* 4 regs -or- first reg */
-
-        if (methodCallRange) {
-            ILOGV("|invoke-super-quick-range args=%d @0x%04x {regs=v%d-v%d}",
-                vsrc1, ref, vdst, vdst+vsrc1-1);
-            thisReg = vdst;
-        } else {
-            ILOGV("|invoke-super-quick args=%d @0x%04x {regs=0x%04x %x}",
-                vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
-            thisReg = vdst & 0x0f;
-        }
-        /* impossible in well-formed code, but we must check nevertheless */
-        if (!checkForNull((Object*) GET_REGISTER(thisReg)))
-            GOTO_exceptionThrown();
-
-#if 0   /* impossible in optimized + verified code */
-        if (ref >= curMethod->clazz->super->vtableCount) {
-            dvmThrowNoSuchMethodError(NULL);
-            GOTO_exceptionThrown();
-        }
-#else
-        assert(ref < (unsigned int) curMethod->clazz->super->vtableCount);
-#endif
-
-        /*
-         * Combine the object we found with the vtable offset in the
-         * method's class.
-         *
-         * We're using the current method's class' superclass, not the
-         * superclass of "this".  This is because we might be executing
-         * in a method inherited from a superclass, and we want to run
-         * in the method's class' superclass.
-         */
-        methodToCall = curMethod->clazz->super->vtable[ref];
-
-#if 0
-        if (dvmIsAbstractMethod(methodToCall)) {
-            dvmThrowAbstractMethodError("abstract method not implemented");
-            GOTO_exceptionThrown();
-        }
-#else
-        assert(!dvmIsAbstractMethod(methodToCall) ||
-            methodToCall->nativeFunc != NULL);
-#endif
-        LOGVV("+++ super-virtual[%d]=%s.%s",
-            ref, methodToCall->clazz->descriptor, methodToCall->name);
-        assert(methodToCall != NULL);
-        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
-    }
-GOTO_TARGET_END
-
-
-    /*
-     * General handling for return-void, return, and return-wide.  Put the
-     * return value in "retval" before jumping here.
-     */
-GOTO_TARGET(returnFromMethod)
-    {
-        StackSaveArea* saveArea;
-
-        /*
-         * We must do this BEFORE we pop the previous stack frame off, so
-         * that the GC can see the return value (if any) in the local vars.
-         *
-         * Since this is now an interpreter switch point, we must do it before
-         * we do anything at all.
-         */
-        PERIODIC_CHECKS(0);
-
-        ILOGV("> retval=0x%llx (leaving %s.%s %s)",
-            retval.j, curMethod->clazz->descriptor, curMethod->name,
-            curMethod->shorty);
-        //DUMP_REGS(curMethod, fp);
-
-        saveArea = SAVEAREA_FROM_FP(fp);
-
-#ifdef EASY_GDB
-        debugSaveArea = saveArea;
-#endif
-
-        /* back up to previous frame and see if we hit a break */
-        fp = (u4*)saveArea->prevFrame;
-        assert(fp != NULL);
-
-        /* Handle any special subMode requirements */
-        if (self->interpBreak.ctl.subMode != 0) {
-            PC_FP_TO_SELF();
-            dvmReportReturn(self);
-        }
-
-        if (dvmIsBreakFrame(fp)) {
-            /* bail without popping the method frame from stack */
-            LOGVV("+++ returned into break frame");
-            GOTO_bail();
-        }
-
-        /* update thread FP, and reset local variables */
-        self->interpSave.curFrame = fp;
-        curMethod = SAVEAREA_FROM_FP(fp)->method;
-        self->interpSave.method = curMethod;
-        //methodClass = curMethod->clazz;
-        methodClassDex = curMethod->clazz->pDvmDex;
-        pc = saveArea->savedPc;
-        ILOGD("> (return to %s.%s %s)", curMethod->clazz->descriptor,
-            curMethod->name, curMethod->shorty);
-
-        /* use FINISH on the caller's invoke instruction */
-        //u2 invokeInstr = INST_INST(FETCH(0));
-        if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
-            invokeInstr <= OP_INVOKE_INTERFACE*/)
-        {
-            FINISH(3);
-        } else {
-            //ALOGE("Unknown invoke instr %02x at %d",
-            //    invokeInstr, (int) (pc - curMethod->insns));
-            assert(false);
-        }
-    }
-GOTO_TARGET_END
-
-
-    /*
-     * Jump here when the code throws an exception.
-     *
-     * By the time we get here, the Throwable has been created and the stack
-     * trace has been saved off.
-     */
-GOTO_TARGET(exceptionThrown)
-    {
-        Object* exception;
-        int catchRelPc;
-
-        PERIODIC_CHECKS(0);
-
-        /*
-         * We save off the exception and clear the exception status.  While
-         * processing the exception we might need to load some Throwable
-         * classes, and we don't want class loader exceptions to get
-         * confused with this one.
-         */
-        assert(dvmCheckException(self));
-        exception = dvmGetException(self);
-        dvmAddTrackedAlloc(exception, self);
-        dvmClearException(self);
-
-        ALOGV("Handling exception %s at %s:%d",
-            exception->clazz->descriptor, curMethod->name,
-            dvmLineNumFromPC(curMethod, pc - curMethod->insns));
-
-        /*
-         * Report the exception throw to any "subMode" watchers.
-         *
-         * TODO: if the exception was thrown by interpreted code, control
-         * fell through native, and then back to us, we will report the
-         * exception at the point of the throw and again here.  We can avoid
-         * this by not reporting exceptions when we jump here directly from
-         * the native call code above, but then we won't report exceptions
-         * that were thrown *from* the JNI code (as opposed to *through* it).
-         *
-         * The correct solution is probably to ignore from-native exceptions
-         * here, and have the JNI exception code do the reporting to the
-         * debugger.
-         */
-        if (self->interpBreak.ctl.subMode != 0) {
-            PC_FP_TO_SELF();
-            dvmReportExceptionThrow(self, exception);
-        }
-
-        /*
-         * We need to unroll to the catch block or the nearest "break"
-         * frame.
-         *
-         * A break frame could indicate that we have reached an intermediate
-         * native call, or have gone off the top of the stack and the thread
-         * needs to exit.  Either way, we return from here, leaving the
-         * exception raised.
-         *
-         * If we do find a catch block, we want to transfer execution to
-         * that point.
-         *
-         * Note this can cause an exception while resolving classes in
-         * the "catch" blocks.
-         */
-        catchRelPc = dvmFindCatchBlock(self, pc - curMethod->insns,
-                    exception, false, (void**)(void*)&fp);
-
-        /*
-         * Restore the stack bounds after an overflow.  This isn't going to
-         * be correct in all circumstances, e.g. if JNI code devours the
-         * exception this won't happen until some other exception gets
-         * thrown.  If the code keeps pushing the stack bounds we'll end
-         * up aborting the VM.
-         *
-         * Note we want to do this *after* the call to dvmFindCatchBlock,
-         * because that may need extra stack space to resolve exception
-         * classes (e.g. through a class loader).
-         *
-         * It's possible for the stack overflow handling to cause an
-         * exception (specifically, class resolution in a "catch" block
-         * during the call above), so we could see the thread's overflow
-         * flag raised but actually be running in a "nested" interpreter
-         * frame.  We don't allow doubled-up StackOverflowErrors, so
-         * we can check for this by just looking at the exception type
-         * in the cleanup function.  Also, we won't unroll past the SOE
-         * point because the more-recent exception will hit a break frame
-         * as it unrolls to here.
-         */
-        if (self->stackOverflowed)
-            dvmCleanupStackOverflow(self, exception);
-
-        if (catchRelPc < 0) {
-            /* falling through to JNI code or off the bottom of the stack */
-#if DVM_SHOW_EXCEPTION >= 2
-            ALOGD("Exception %s from %s:%d not caught locally",
-                exception->clazz->descriptor, dvmGetMethodSourceFile(curMethod),
-                dvmLineNumFromPC(curMethod, pc - curMethod->insns));
-#endif
-            dvmSetException(self, exception);
-            dvmReleaseTrackedAlloc(exception, self);
-            GOTO_bail();
-        }
-
-#if DVM_SHOW_EXCEPTION >= 3
-        {
-            const Method* catchMethod = SAVEAREA_FROM_FP(fp)->method;
-            ALOGD("Exception %s thrown from %s:%d to %s:%d",
-                exception->clazz->descriptor, dvmGetMethodSourceFile(curMethod),
-                dvmLineNumFromPC(curMethod, pc - curMethod->insns),
-                dvmGetMethodSourceFile(catchMethod),
-                dvmLineNumFromPC(catchMethod, catchRelPc));
-        }
-#endif
-
-        /*
-         * Adjust local variables to match self->interpSave.curFrame and the
-         * updated PC.
-         */
-        //fp = (u4*) self->interpSave.curFrame;
-        curMethod = SAVEAREA_FROM_FP(fp)->method;
-        self->interpSave.method = curMethod;
-        //methodClass = curMethod->clazz;
-        methodClassDex = curMethod->clazz->pDvmDex;
-        pc = curMethod->insns + catchRelPc;
-        ILOGV("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
-            curMethod->name, curMethod->shorty);
-        DUMP_REGS(curMethod, fp, false);            // show all regs
-
-        /*
-         * Restore the exception if the handler wants it.
-         *
-         * The Dalvik spec mandates that, if an exception handler wants to
-         * do something with the exception, the first instruction executed
-         * must be "move-exception".  We can pass the exception along
-         * through the thread struct, and let the move-exception instruction
-         * clear it for us.
-         *
-         * If the handler doesn't call move-exception, we don't want to
-         * finish here with an exception still pending.
-         */
-        if (INST_INST(FETCH(0)) == OP_MOVE_EXCEPTION)
-            dvmSetException(self, exception);
-
-        dvmReleaseTrackedAlloc(exception, self);
-        FINISH(0);
-    }
-GOTO_TARGET_END
-
-
-
-    /*
-     * General handling for invoke-{virtual,super,direct,static,interface},
-     * including "quick" variants.
-     *
-     * Set "methodToCall" to the Method we're calling, and "methodCallRange"
-     * depending on whether this is a "/range" instruction.
-     *
-     * For a range call:
-     *  "vsrc1" holds the argument count (8 bits)
-     *  "vdst" holds the first argument in the range
-     * For a non-range call:
-     *  "vsrc1" holds the argument count (4 bits) and the 5th argument index
-     *  "vdst" holds four 4-bit register indices
-     *
-     * The caller must EXPORT_PC before jumping here, because any method
-     * call can throw a stack overflow exception.
-     */
-GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall,
-    u2 count, u2 regs)
-    {
-        STUB_HACK(vsrc1 = count; vdst = regs; methodToCall = _methodToCall;);
-
-        //printf("range=%d call=%p count=%d regs=0x%04x\n",
-        //    methodCallRange, methodToCall, count, regs);
-        //printf(" --> %s.%s %s\n", methodToCall->clazz->descriptor,
-        //    methodToCall->name, methodToCall->shorty);
-
-        u4* outs;
-        int i;
-
-        /*
-         * Copy args.  This may corrupt vsrc1/vdst.
-         */
-        if (methodCallRange) {
-            // could use memcpy or a "Duff's device"; most functions have
-            // so few args it won't matter much
-            assert(vsrc1 <= curMethod->outsSize);
-            assert(vsrc1 == methodToCall->insSize);
-            outs = OUTS_FROM_FP(fp, vsrc1);
-            for (i = 0; i < vsrc1; i++)
-                outs[i] = GET_REGISTER(vdst+i);
-        } else {
-            u4 count = vsrc1 >> 4;
-
-            assert(count <= curMethod->outsSize);
-            assert(count == methodToCall->insSize);
-            assert(count <= 5);
-
-            outs = OUTS_FROM_FP(fp, count);
-#if 0
-            if (count == 5) {
-                outs[4] = GET_REGISTER(vsrc1 & 0x0f);
-                count--;
-            }
-            for (i = 0; i < (int) count; i++) {
-                outs[i] = GET_REGISTER(vdst & 0x0f);
-                vdst >>= 4;
-            }
-#else
-            // This version executes fewer instructions but is larger
-            // overall.  Seems to be a teensy bit faster.
-            assert((vdst >> 16) == 0);  // 16 bits -or- high 16 bits clear
-            switch (count) {
-            case 5:
-                outs[4] = GET_REGISTER(vsrc1 & 0x0f);
-            case 4:
-                outs[3] = GET_REGISTER(vdst >> 12);
-            case 3:
-                outs[2] = GET_REGISTER((vdst & 0x0f00) >> 8);
-            case 2:
-                outs[1] = GET_REGISTER((vdst & 0x00f0) >> 4);
-            case 1:
-                outs[0] = GET_REGISTER(vdst & 0x0f);
-            default:
-                ;
-            }
-#endif
-        }
-    }
-
-    /*
-     * (This was originally a "goto" target; I've kept it separate from the
-     * stuff above in case we want to refactor things again.)
-     *
-     * At this point, we have the arguments stored in the "outs" area of
-     * the current method's stack frame, and the method to call in
-     * "methodToCall".  Push a new stack frame.
-     */
-    {
-        StackSaveArea* newSaveArea;
-        u4* newFp;
-
-        ILOGV("> %s%s.%s %s",
-            dvmIsNativeMethod(methodToCall) ? "(NATIVE) " : "",
-            methodToCall->clazz->descriptor, methodToCall->name,
-            methodToCall->shorty);
-
-        newFp = (u4*) SAVEAREA_FROM_FP(fp) - methodToCall->registersSize;
-        newSaveArea = SAVEAREA_FROM_FP(newFp);
-
-        /* verify that we have enough space */
-        if (true) {
-            u1* bottom;
-            bottom = (u1*) newSaveArea - methodToCall->outsSize * sizeof(u4);
-            if (bottom < self->interpStackEnd) {
-                /* stack overflow */
-                ALOGV("Stack overflow on method call (start=%p end=%p newBot=%p(%d) size=%d '%s')",
-                    self->interpStackStart, self->interpStackEnd, bottom,
-                    (u1*) fp - bottom, self->interpStackSize,
-                    methodToCall->name);
-                dvmHandleStackOverflow(self, methodToCall);
-                assert(dvmCheckException(self));
-                GOTO_exceptionThrown();
-            }
-            //ALOGD("+++ fp=%p newFp=%p newSave=%p bottom=%p",
-            //    fp, newFp, newSaveArea, bottom);
-        }
-
-#ifdef LOG_INSTR
-        if (methodToCall->registersSize > methodToCall->insSize) {
-            /*
-             * This makes valgrind quiet when we print registers that
-             * haven't been initialized.  Turn it off when the debug
-             * messages are disabled -- we want valgrind to report any
-             * used-before-initialized issues.
-             */
-            memset(newFp, 0xcc,
-                (methodToCall->registersSize - methodToCall->insSize) * 4);
-        }
-#endif
-
-#ifdef EASY_GDB
-        newSaveArea->prevSave = SAVEAREA_FROM_FP(fp);
-#endif
-        newSaveArea->prevFrame = fp;
-        newSaveArea->savedPc = pc;
-#if defined(WITH_JIT) && defined(MTERP_STUB)
-        newSaveArea->returnAddr = 0;
-#endif
-        newSaveArea->method = methodToCall;
-
-        if (self->interpBreak.ctl.subMode != 0) {
-            /*
-             * We mark ENTER here for both native and non-native
-             * calls.  For native calls, we'll mark EXIT on return.
-             * For non-native calls, EXIT is marked in the RETURN op.
-             */
-            PC_TO_SELF();
-            dvmReportInvoke(self, methodToCall);
-        }
-
-        if (!dvmIsNativeMethod(methodToCall)) {
-            /*
-             * "Call" interpreted code.  Reposition the PC, update the
-             * frame pointer and other local state, and continue.
-             */
-            curMethod = methodToCall;
-            self->interpSave.method = curMethod;
-            methodClassDex = curMethod->clazz->pDvmDex;
-            pc = methodToCall->insns;
-            fp = newFp;
-            self->interpSave.curFrame = fp;
-#ifdef EASY_GDB
-            debugSaveArea = SAVEAREA_FROM_FP(newFp);
-#endif
-            self->debugIsMethodEntry = true;        // profiling, debugging
-            ILOGD("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
-                curMethod->name, curMethod->shorty);
-            DUMP_REGS(curMethod, fp, true);         // show input args
-            FINISH(0);                              // jump to method start
-        } else {
-            /* set this up for JNI locals, even if not a JNI native */
-            newSaveArea->xtra.localRefCookie = self->jniLocalRefTable.segmentState.all;
-
-            self->interpSave.curFrame = newFp;
-
-            DUMP_REGS(methodToCall, newFp, true);   // show input args
-
-            if (self->interpBreak.ctl.subMode != 0) {
-                dvmReportPreNativeInvoke(methodToCall, self, newSaveArea->prevFrame);
-            }
-
-            ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
-                  methodToCall->name, methodToCall->shorty);
-
-            /*
-             * Jump through native call bridge.  Because we leave no
-             * space for locals on native calls, "newFp" points directly
-             * to the method arguments.
-             */
-            (*methodToCall->nativeFunc)(newFp, &retval, methodToCall, self);
-
-            if (self->interpBreak.ctl.subMode != 0) {
-                dvmReportPostNativeInvoke(methodToCall, self, newSaveArea->prevFrame);
-            }
-
-            /* pop frame off */
-            dvmPopJniLocals(self, newSaveArea);
-            self->interpSave.curFrame = newSaveArea->prevFrame;
-            fp = newSaveArea->prevFrame;
-
-            /*
-             * If the native code threw an exception, or interpreted code
-             * invoked by the native call threw one and nobody has cleared
-             * it, jump to our local exception handling.
-             */
-            if (dvmCheckException(self)) {
-                ALOGV("Exception thrown by/below native code");
-                GOTO_exceptionThrown();
-            }
-
-            ILOGD("> retval=0x%llx (leaving native)", retval.j);
-            ILOGD("> (return from native %s.%s to %s.%s %s)",
-                methodToCall->clazz->descriptor, methodToCall->name,
-                curMethod->clazz->descriptor, curMethod->name,
-                curMethod->shorty);
-
-            //u2 invokeInstr = INST_INST(FETCH(0));
-            if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
-                invokeInstr <= OP_INVOKE_INTERFACE*/)
-            {
-                FINISH(3);
-            } else {
-                //ALOGE("Unknown invoke instr %02x at %d",
-                //    invokeInstr, (int) (pc - curMethod->insns));
-                assert(false);
-            }
-        }
-    }
-    assert(false);      // should not get here
-GOTO_TARGET_END
-
-/* File: cstubs/enddefs.cpp */
-
-/* undefine "magic" name remapping */
-#undef retval
-#undef pc
-#undef fp
-#undef curMethod
-#undef methodClassDex
-#undef self
-#undef debugTrackedRefStart
-
diff --git a/vm/mterp/out/InterpC-x86.cpp b/vm/mterp/out/InterpC-x86.cpp
index 8b32ce0..77dc888 100644
--- a/vm/mterp/out/InterpC-x86.cpp
+++ b/vm/mterp/out/InterpC-x86.cpp
@@ -1212,7 +1212,7 @@
             ;
         }
 
-        if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
+        if (self->interpBreak.ctl.subMode & kSubModeDebugProfile) {
             if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
                 GOTO_exceptionThrown();
         } else {
diff --git a/vm/mterp/rebuild.sh b/vm/mterp/rebuild.sh
index e550a5d..80419a5 100755
--- a/vm/mterp/rebuild.sh
+++ b/vm/mterp/rebuild.sh
@@ -20,7 +20,7 @@
 #
 set -e
 
-for arch in portable allstubs armv5te armv5te-vfp armv7-a armv7-a-neon mips x86 x86-atom; do TARGET_ARCH_EXT=$arch make -f Makefile-mterp; done
+for arch in portable allstubs armv5te armv5te-vfp armv7-a armv7-a-neon mips x86; do TARGET_ARCH_EXT=$arch make -f Makefile-mterp; done
 
 # These aren't actually used, so just go ahead and remove them.  The correct
 # approach is to prevent them from being generated in the first place, but
diff --git a/vm/mterp/x86-atom/OP_ADD_DOUBLE.S b/vm/mterp/x86-atom/OP_ADD_DOUBLE.S
deleted file mode 100644
index 22f3938..0000000
--- a/vm/mterp/x86-atom/OP_ADD_DOUBLE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_DOUBLE.S
-    */
-
-%include "x86-atom/binopWide.S" {"instr":"addsd   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_ADD_DOUBLE_2ADDR.S b/vm/mterp/x86-atom/OP_ADD_DOUBLE_2ADDR.S
deleted file mode 100644
index 0b2bf4f..0000000
--- a/vm/mterp/x86-atom/OP_ADD_DOUBLE_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_DOUBLE_2ADDR.S
-    */
-
-%include "x86-atom/binopWide2addr.S" {"instr":"addsd   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_ADD_FLOAT.S b/vm/mterp/x86-atom/OP_ADD_FLOAT.S
deleted file mode 100644
index aa3aa22..0000000
--- a/vm/mterp/x86-atom/OP_ADD_FLOAT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_FLOAT.S
-    */
-
-%include "x86-atom/binopF.S" {"instr":"addss     %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_ADD_FLOAT_2ADDR.S b/vm/mterp/x86-atom/OP_ADD_FLOAT_2ADDR.S
deleted file mode 100644
index 3d62703..0000000
--- a/vm/mterp/x86-atom/OP_ADD_FLOAT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_FLOAT_2ADDR.S
-    */
-
-%include "x86-atom/binopF2addr.S" {"instr":"addss     %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_ADD_INT.S b/vm/mterp/x86-atom/OP_ADD_INT.S
deleted file mode 100644
index a423e75..0000000
--- a/vm/mterp/x86-atom/OP_ADD_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_INT.S
-    */
-
-%include "x86-atom/binop.S" {"instr":"addl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_ADD_INT_2ADDR.S b/vm/mterp/x86-atom/OP_ADD_INT_2ADDR.S
deleted file mode 100644
index 2a91f41..0000000
--- a/vm/mterp/x86-atom/OP_ADD_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_INT_2ADDR.S
-    */
-
-%include "x86-atom/binop2addr.S" {"instr":"addl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_ADD_INT_LIT16.S b/vm/mterp/x86-atom/OP_ADD_INT_LIT16.S
deleted file mode 100644
index 72479ba..0000000
--- a/vm/mterp/x86-atom/OP_ADD_INT_LIT16.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_INT_LIT16.S
-    */
-
-%include "x86-atom/binopLit16.S" {"instr":"addl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_ADD_INT_LIT8.S b/vm/mterp/x86-atom/OP_ADD_INT_LIT8.S
deleted file mode 100644
index eabd4b5..0000000
--- a/vm/mterp/x86-atom/OP_ADD_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_INT_LIT8.S
-    */
-
-%include "x86-atom/binopLit8.S" {"instr":"addl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_ADD_LONG.S b/vm/mterp/x86-atom/OP_ADD_LONG.S
deleted file mode 100644
index 7e31d35..0000000
--- a/vm/mterp/x86-atom/OP_ADD_LONG.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_LONG.S
-    */
-
-%include "x86-atom/binopWide.S" {"instr":"paddq   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_ADD_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_ADD_LONG_2ADDR.S
deleted file mode 100644
index 4c65a45..0000000
--- a/vm/mterp/x86-atom/OP_ADD_LONG_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ADD_LONG_2ADDR.S
-    */
-
-%include "x86-atom/binopWide2addr.S" {"instr":"paddq   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_AGET.S b/vm/mterp/x86-atom/OP_AGET.S
deleted file mode 100644
index 73a27ab..0000000
--- a/vm/mterp/x86-atom/OP_AGET.S
+++ /dev/null
@@ -1,53 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET.S
-    *
-    * Code: Generic 32-bit array "get" operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       mov performed also dependent on the type of the array element.
-    *
-    * For: aget, aget-boolean, aget-byte, aget-char, aget-object, sget, aget-short
-    *
-    * Description: Perform an array get operation at the identified index
-    *              of a given array; load the array value into the value
-    *              register. vAA <- vBB[vCC].
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-%default { "mov":"l","scale":"4"}
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $$0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    lea         (%ecx, %edx, $scale), %ecx # %ecx<- &vBB[vCC]
-                                           # trying: lea (%ecx, %edx, scale), %ecx
-                                           # to reduce code size
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    mov$mov offArrayObject_contents(%ecx), %edx # %edx<- vBB[vCC]
-                                                # doing this and the previous instr
-                                                # with one instr was not faster
-    SET_VREG    %edx  rINST             # vAA<- %edx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_AGET_BOOLEAN.S b/vm/mterp/x86-atom/OP_AGET_BOOLEAN.S
deleted file mode 100644
index 1d28745..0000000
--- a/vm/mterp/x86-atom/OP_AGET_BOOLEAN.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_BOOLEAN.S
-    */
-
-%include "x86-atom/OP_AGET.S" { "mov":"zbl", "scale":"1" }
diff --git a/vm/mterp/x86-atom/OP_AGET_BYTE.S b/vm/mterp/x86-atom/OP_AGET_BYTE.S
deleted file mode 100644
index 60e4266..0000000
--- a/vm/mterp/x86-atom/OP_AGET_BYTE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_BYTE.S
-    */
-
-%include "x86-atom/OP_AGET.S" {  "mov":"sbl", "scale":"1" }
diff --git a/vm/mterp/x86-atom/OP_AGET_CHAR.S b/vm/mterp/x86-atom/OP_AGET_CHAR.S
deleted file mode 100644
index 114d02d..0000000
--- a/vm/mterp/x86-atom/OP_AGET_CHAR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_CHAR.S
-    */
-
-%include "x86-atom/OP_AGET.S" {  "mov":"zwl", "scale":"2" }
diff --git a/vm/mterp/x86-atom/OP_AGET_OBJECT.S b/vm/mterp/x86-atom/OP_AGET_OBJECT.S
deleted file mode 100644
index 0ed02c3..0000000
--- a/vm/mterp/x86-atom/OP_AGET_OBJECT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_OBJECT.S
-    */
-
-%include "x86-atom/OP_AGET.S"
diff --git a/vm/mterp/x86-atom/OP_AGET_SHORT.S b/vm/mterp/x86-atom/OP_AGET_SHORT.S
deleted file mode 100644
index 3ddb9b9..0000000
--- a/vm/mterp/x86-atom/OP_AGET_SHORT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_SHORT.S
-    */
-
-%include "x86-atom/OP_AGET.S" {  "mov":"swl", "scale":"2" }
diff --git a/vm/mterp/x86-atom/OP_AGET_WIDE.S b/vm/mterp/x86-atom/OP_AGET_WIDE.S
deleted file mode 100644
index db5a930..0000000
--- a/vm/mterp/x86-atom/OP_AGET_WIDE.S
+++ /dev/null
@@ -1,43 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AGET_WIDE.S
-    *
-    * Code: 64-bit array get operation.
-    *
-    * For: aget-wide
-    *
-    * Description: Perform an array get operation at the identified index
-    *              of a given array; load the array value into the destination
-    *              register. vAA <- vBB[vCC].
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $$0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        offArrayObject_contents(%ecx, %edx, 8), %xmm0 # %xmm0<- vBB[vCC]
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_AND_INT.S b/vm/mterp/x86-atom/OP_AND_INT.S
deleted file mode 100644
index 10d223b..0000000
--- a/vm/mterp/x86-atom/OP_AND_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_INT.S
-    */
-
-%include "x86-atom/binop.S" {"instr":"andl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_AND_INT_2ADDR.S b/vm/mterp/x86-atom/OP_AND_INT_2ADDR.S
deleted file mode 100644
index dcbd531..0000000
--- a/vm/mterp/x86-atom/OP_AND_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_INT_2ADDR.S
-    */
-
-%include "x86-atom/binop2addr.S" {"instr":"andl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_AND_INT_LIT16.S b/vm/mterp/x86-atom/OP_AND_INT_LIT16.S
deleted file mode 100644
index 7e6493d..0000000
--- a/vm/mterp/x86-atom/OP_AND_INT_LIT16.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_INT_LIT16.S
-    */
-
-%include "x86-atom/binopLit16.S" {"instr":"andl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_AND_INT_LIT8.S b/vm/mterp/x86-atom/OP_AND_INT_LIT8.S
deleted file mode 100644
index 511e3ae..0000000
--- a/vm/mterp/x86-atom/OP_AND_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_INT_LIT8.S
-    */
-
-%include "x86-atom/binopLit8.S" {"instr":"andl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_AND_LONG.S b/vm/mterp/x86-atom/OP_AND_LONG.S
deleted file mode 100644
index e62e312..0000000
--- a/vm/mterp/x86-atom/OP_AND_LONG.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_LONG.S
-    */
-
-%include "x86-atom/binopWide.S" {"instr":"pand   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_AND_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_AND_LONG_2ADDR.S
deleted file mode 100644
index 90e77e6..0000000
--- a/vm/mterp/x86-atom/OP_AND_LONG_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_AND_LONG_2ADDR.S
-    */
-
-%include "x86-atom/binopWide2addr.S" {"instr":"pand   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_APUT.S b/vm/mterp/x86-atom/OP_APUT.S
deleted file mode 100644
index 93b3866..0000000
--- a/vm/mterp/x86-atom/OP_APUT.S
+++ /dev/null
@@ -1,50 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT.S
-    *
-    * Code: Generic 32-bit array put operation.  Provides a "scale" variable
-    *       to specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       move performed also dependent on the type of the array element.
-    *       Provides a "value" register to specify the source of the move
-    *
-    * For: aput-boolean, aput-byte, aput-char, aput-object, aput-short
-    *
-    * Description: Perform an array put operation from the value register;
-    *              store the value register at the identified index of a
-    *              given array. vBB[vCC] <- vAA
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-%default { "mov":"l","scale":"4", "value": "rINST"}
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $$0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    lea         (%ecx, %edx, $scale), %ecx # %ecx<- &vBB[vCC]
-    GET_VREG    rINST                   # rINST<- vAA
-    mov$mov     $value, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_APUT_BOOLEAN.S b/vm/mterp/x86-atom/OP_APUT_BOOLEAN.S
deleted file mode 100644
index d9afd6d..0000000
--- a/vm/mterp/x86-atom/OP_APUT_BOOLEAN.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_BOOLEAN.S
-    */
-
-%include "x86-atom/OP_APUT.S" { "mov":"b", "scale":"1", "value":"rINSTbl" }
diff --git a/vm/mterp/x86-atom/OP_APUT_BYTE.S b/vm/mterp/x86-atom/OP_APUT_BYTE.S
deleted file mode 100644
index 29cb708..0000000
--- a/vm/mterp/x86-atom/OP_APUT_BYTE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_BYTE.S
-    */
-
-%include "x86-atom/OP_APUT.S" { "mov":"b", "scale":"1", "value":"rINSTbl" }
diff --git a/vm/mterp/x86-atom/OP_APUT_CHAR.S b/vm/mterp/x86-atom/OP_APUT_CHAR.S
deleted file mode 100644
index d43e540..0000000
--- a/vm/mterp/x86-atom/OP_APUT_CHAR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_CHAR.S
-    */
-
-%include "x86-atom/OP_APUT.S" { "mov":"w", "scale":"2", "value":"rINSTw" }
diff --git a/vm/mterp/x86-atom/OP_APUT_OBJECT.S b/vm/mterp/x86-atom/OP_APUT_OBJECT.S
deleted file mode 100644
index 0e23d71..0000000
--- a/vm/mterp/x86-atom/OP_APUT_OBJECT.S
+++ /dev/null
@@ -1,77 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_OBJECT.S
-    *
-    * Code: 32-bit array put operation.  Provides an "scale" variable
-    *       specify a scale value which depends on the width of the array
-    *       elements. Provides a "mov" variable which determines the type of
-    *       mov performed also dependent on the type of the array element.
-    *       Provides a "value" register to specify the source of the mov
-    *
-    * For: aput-boolean, aput-byte, aput-char, aput-object, aput-short
-    *
-    * Description: Perform an array put operation from the value register;
-    *              store the value register at the identified index of a
-    *              given array. vBB[vCC] <- vAA
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %eax                 # %eax<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %eax                    # %eax<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $$0, %eax               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%eax), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    GET_VREG    rINST                   # rINST<- vAA
-    lea         (%eax, %edx, 4), %edx   # %edx<- &vBB[vCC]
-    cmp         $$0, rINST              # check for null reference
-    je          .L${opcode}_skip_check  # reference is null so skip type check
-    jmp         .L${opcode}_finish
-%break
-
-.L${opcode}_finish:
-    movl        %edx, sReg0             # save &vBB[vCC]
-    movl        %eax, sReg1             # save object head
-    movl        offObject_clazz(rINST), %edx # %edx<- obj->clazz
-    movl        %edx, -8(%esp)          # push parameter obj->clazz
-    movl        offObject_clazz(%eax), %eax # %eax<- arrayObj->clazz
-    movl        %eax, -4(%esp)          # push parameter arrayObj->clazz
-    lea         -8(%esp), %esp
-    call        dvmCanPutArrayElement   # test object type vs. array type
-                                        # call: ClassObject* elemClass, ClassObject* arrayClass)
-                                        # return: bool
-    lea         8(%esp), %esp
-    testl       %eax, %eax              # check for invalid array value
-    je          common_errArrayStore    # handle invalid array value
-    movl        sReg0, %edx             # restore &vBB[vCC]
-    movl        rINST, offArrayObject_contents(%edx)
-    movl        rGLUE, %eax
-    FFETCH_ADV  2, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    movl        offGlue_cardTable(%eax), %eax # get card table base
-    movl        sReg1, %edx             # restore object head
-    shrl        $$GC_CARD_SHIFT, %edx   # object head to card number
-    movb        %al, (%eax, %edx)       # mark card using object head
-    FGETOP_JMP  2, %ecx                 # jump to next instruction; getop, jmp
-.L${opcode}_skip_check:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl        rINST, offArrayObject_contents(%edx)
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_APUT_SHORT.S b/vm/mterp/x86-atom/OP_APUT_SHORT.S
deleted file mode 100644
index daef0d8..0000000
--- a/vm/mterp/x86-atom/OP_APUT_SHORT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_SHORT.S
-    */
-
-%include "x86-atom/OP_APUT.S" { "mov":"w", "scale":"2", "value":"rINSTw" }
diff --git a/vm/mterp/x86-atom/OP_APUT_WIDE.S b/vm/mterp/x86-atom/OP_APUT_WIDE.S
deleted file mode 100644
index b1b9e6a..0000000
--- a/vm/mterp/x86-atom/OP_APUT_WIDE.S
+++ /dev/null
@@ -1,43 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_APUT_WIDE.S
-    *
-    * Code: 64-bit array put operation.
-    *
-    * For: aput-wide
-    *
-    * Description: Perform an array put operation from the value register;
-    *              store the value register at the identified index of a
-    *              given array. vBB[vCC] <- vAA.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    cmp         $$0, %ecx               # check for null array object
-    je          common_errNullObject    # handle null array object
-    cmp         offArrayObject_length(%ecx), %edx # compare index to arrayObj->length
-    jnc         common_errArrayIndex    # handle index >= length, bail
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vAA
-    movq        %xmm0, offArrayObject_contents(%ecx, %edx, 8) # vBB[vCC]<- %xmm0; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_ARRAY_LENGTH.S b/vm/mterp/x86-atom/OP_ARRAY_LENGTH.S
deleted file mode 100644
index 485f815..0000000
--- a/vm/mterp/x86-atom/OP_ARRAY_LENGTH.S
+++ /dev/null
@@ -1,40 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_ARRAY_LENGTH.S
-    *
-    * Code: 32-bit array length operation.
-    *
-    * For: array-length
-    *
-    * Description: Store the length of the indicated array in the given
-    *              destination register. vB <- offArrayObject_length(vA)
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $$4, %eax               # %eax<- B
-    andl        $$15, rINST             # rINST<- A
-    GET_VREG    %eax                    # %eax<- vB
-    cmp         $$0, %eax               # check for null array object
-    je          common_errNullObject    # handle null array object
-    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl        offArrayObject_length(%eax), %eax # %eax<- array length
-    movl        %eax, (rFP, rINST, 4)   # vA<- %eax; array length
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_BREAKPOINT.S b/vm/mterp/x86-atom/OP_BREAKPOINT.S
deleted file mode 100644
index e69de29..0000000
--- a/vm/mterp/x86-atom/OP_BREAKPOINT.S
+++ /dev/null
diff --git a/vm/mterp/x86-atom/OP_CHECK_CAST.S b/vm/mterp/x86-atom/OP_CHECK_CAST.S
deleted file mode 100644
index c78f336..0000000
--- a/vm/mterp/x86-atom/OP_CHECK_CAST.S
+++ /dev/null
@@ -1,118 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CHECK_CAST.S
-    *
-    * Code: Checks to see if a cast is allowed. Uses no substitutions.
-    *
-    * For: check-cast
-    *
-    * Description: Throw if the reference in the given register cannot be
-    *              cast to the indicated type. The type must be a reference
-    *              type (not a primitive type).
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, type@BBBB
-    */
-
-    movl        rGLUE, %edx             # get MterpGlue pointer
-    movl        offGlue_methodClassDex(%edx), %eax # %eax<- pDvmDex
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        offDvmDex_pResClasses(%eax), %eax # %eax<- pDvmDex->pResClasses
-    cmp         $$0, rINST              # check for null reference object
-    je          .L${opcode}_okay        # can always cast null object
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    movl        (%eax, %ecx, 4), %ecx   # %ecx<- resolved class
-    cmp         $$0, %ecx               # check if classes is resolved before?
-    je          .L${opcode}_resolve     # resolve class
-    jmp         .L${opcode}_resolved    # continue
-%break
-
-.L${opcode}_resolved:
-    cmp         %ecx, offObject_clazz(rINST) # check for same class
-    jne         .L${opcode}_fullcheck   # not same class; do full check
-
-.L${opcode}_okay:
-    FINISH      2                       # jump to next instruction
-
-   /*
-    *  Trivial test failed, need to perform full check.
-    *  offObject_clazz(rINST) holds obj->clazz
-    *  %ecx holds class resolved from BBBB
-    *  rINST holds object
-    */
-
-.L${opcode}_fullcheck:
-    movl        offObject_clazz(rINST), %eax  # %eax<- obj->clazz
-    movl        %eax, -12(%esp)         # push parameter obj->clazz
-    movl        %ecx, -8(%esp)          # push parameter # push parameter resolved class
-    lea         -12(%esp), %esp
-    call        dvmInstanceofNonTrivial # call: (ClassObject* instance, ClassObject* clazz)
-                                        # return: int
-    lea         12(%esp), %esp
-    cmp         $$0, %eax               # failed?
-    jne         .L${opcode}_okay        # success
-
-   /*
-    * A cast has failed.  We need to throw a ClassCastException with the
-    * class of the object that failed to be cast.
-    */
-
-    EXPORT_PC                           # we will throw an exception
-#error BIT ROT!!!
-    /*
-     * TODO: Code here needs to call dvmThrowClassCastException with two
-     * arguments.
-     */
-#if 0
-    /* old obsolete code that called dvmThrowExceptionWithClassMessage */
-    movl        $$.LstrClassCastExceptionPtr, -8(%esp) # push parameter message
-    movl        offObject_clazz(rINST), rINST # rINST<- obj->clazz
-    movl        offClassObject_descriptor(rINST), rINST # rINST<- obj->clazz->descriptor
-    movl        rINST, -4(%esp)         # push parameter obj->clazz->descriptor
-    lea         -8(%esp), %esp
-    call        dvmThrowExceptionWithClassMessage # call: (const char* exceptionDescriptor,
-                                                  #       const char* messageDescriptor, Object* cause)
-                                                  # return: void
-#endif
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown
-
-   /*
-    * Resolution required.  This is the least-likely path.
-    *
-    *  rINST holds object
-    */
-
-.L${opcode}_resolve:
-    movl        offGlue_method(%edx), %eax # %eax<- glue->method
-    FETCH       1, %ecx                 # %ecx holds BBBB
-    EXPORT_PC                           # in case we throw an exception
-    movl        $$0, -8(%esp)           # push parameter false
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    movl        %ecx, -12(%esp)         # push parameter BBBB
-    movl        %eax, -16(%esp)         # push parameter glue->method>clazz
-    lea         -16(%esp), %esp
-    call        dvmResolveClass         # resolve ClassObject pointer
-                                        # call: (const ClassObject* referrer, u4 classIdx,
-                                        #        bool fromUnverifiedConstant)
-                                        # return ClassObject*
-    lea         16(%esp), %esp
-    cmp         $$0, %eax               # check for null pointer
-    je          common_exceptionThrown  # handle excpetion
-    movl        %eax, %ecx              # %ecx<- resolved class
-    jmp         .L${opcode}_resolved
diff --git a/vm/mterp/x86-atom/OP_CMPG_DOUBLE.S b/vm/mterp/x86-atom/OP_CMPG_DOUBLE.S
deleted file mode 100644
index 87f8a3b..0000000
--- a/vm/mterp/x86-atom/OP_CMPG_DOUBLE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPG_DOUBLE.S
-    */
-
-%include "x86-atom/OP_CMPL_FLOAT.S" { "nan":"$0x1", "sod":"d"}
diff --git a/vm/mterp/x86-atom/OP_CMPG_FLOAT.S b/vm/mterp/x86-atom/OP_CMPG_FLOAT.S
deleted file mode 100644
index de42969..0000000
--- a/vm/mterp/x86-atom/OP_CMPG_FLOAT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPG_FLOAT.S
-    */
-
-%include "x86-atom/OP_CMPL_FLOAT.S" { "nan":"$0x1" }
diff --git a/vm/mterp/x86-atom/OP_CMPL_DOUBLE.S b/vm/mterp/x86-atom/OP_CMPL_DOUBLE.S
deleted file mode 100644
index 2a603a4..0000000
--- a/vm/mterp/x86-atom/OP_CMPL_DOUBLE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPL_DOUBLE.S
-    */
-
-%include "x86-atom/OP_CMPL_FLOAT.S" { "sod":"d" }
diff --git a/vm/mterp/x86-atom/OP_CMPL_FLOAT.S b/vm/mterp/x86-atom/OP_CMPL_FLOAT.S
deleted file mode 100644
index 5cb3ec7..0000000
--- a/vm/mterp/x86-atom/OP_CMPL_FLOAT.S
+++ /dev/null
@@ -1,63 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMPL_FLOAT.S
-    *
-    * Code: Provides a "nan" variable to specify the return value for
-    *       NaN. Provides a variable "sod" which appends a "s" or a "d"
-    *       to the move and comparison instructions, depending on if we
-    *       are working with a float or a double. For instructions
-    *       cmpx-float and cmpx-double, the x will be eiher a g or a l
-    *       to specify positive or negative bias for NaN.
-    *
-    * For: cmpg-double, dmpg-float, cmpl-double, cmpl-float
-    *
-    * Description: Perform the indicated floating point or long comparison,
-    *              storing 0 if the two arguments are equal, 1 if the second
-    *              argument is larger, or -1 if the first argument is larger.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-%default { "nan":"$0xFFFFFFFF" , "sod":"s" }
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movs$sod    (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    comis$sod   (rFP, %edx, 4), %xmm0   # do comparison
-    ja          .L${opcode}_greater
-    jp          .L${opcode}_finalNan
-    jz          .L${opcode}_final
-
-.L${opcode}_less:
-    movl        $$0xFFFFFFFF, (rFP, rINST, 4) # vAA<- less than
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-%break
-.L${opcode}_greater:
-    movl        $$0x1, (rFP, rINST, 4)  # vAA<- greater than
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-.L${opcode}_final:
-    movl        $$0x0, (rFP, rINST, 4)  # vAA<- equal
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-.L${opcode}_finalNan:
-    movl        $nan, (rFP, rINST, 4)   # vAA<- NaN
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CMP_LONG.S b/vm/mterp/x86-atom/OP_CMP_LONG.S
deleted file mode 100644
index cf021a3..0000000
--- a/vm/mterp/x86-atom/OP_CMP_LONG.S
+++ /dev/null
@@ -1,55 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CMP_LONG.S
-    *
-    * Code: Compare floating point values. Uses no substitutions.
-    *
-    * For: cmp-long
-    *
-    * Description: Perform a long comparison, storing 0 if the two
-    *              arguments are equal, 1 if the second argument is larger
-    *              or -1 if the first argument is larger.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    movl        4(rFP, %ecx, 4), %eax   # %eax<- vBBhi
-    cmp         4(rFP, %edx, 4), %eax   # compare vCChi and vBBhi
-    jl          .L${opcode}_less
-    jg          .L${opcode}_greater
-    movl        (rFP, %ecx, 4), %eax    # %eax<- vBBlo
-    cmp         (rFP, %edx, 4), %eax    # compare vCClo and vBBlo
-    ja          .L${opcode}_greater
-    jne         .L${opcode}_less
-    jmp         .L${opcode}_final
-%break
-
-.L${opcode}_final:
-    movl        $$0x0, (rFP, rINST, 4)  # vAA<- equal
-    FINISH      2                       # jump to next instruction
-
-.L${opcode}_less:
-    movl        $$0xFFFFFFFF, (rFP, rINST, 4) # vAA<- less than
-    FINISH      2                       # jump to next instruction
-
-.L${opcode}_greater:
-    movl        $$0x1, (rFP, rINST, 4)  # vAA<- greater than
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_CONST.S b/vm/mterp/x86-atom/OP_CONST.S
deleted file mode 100644
index 7ff4c23..0000000
--- a/vm/mterp/x86-atom/OP_CONST.S
+++ /dev/null
@@ -1,36 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST.S
-    *
-    * Code: Move a literal to a register. Uses no substitutions.
-    *
-    * For: const
-    *
-    * Description: Move the given literal value into the specified register
-    *
-    * Format: AA|op BBBBlo BBBBhi (31i)
-    *
-    * Syntax: op vAA, #+BBBBBBBB
-    */
-
-    FETCH       2, %edx                 # %edx<- BBBBhi
-    FETCH       1, %ecx                 # %ecx<- BBBBlo
-    shl         $$16, %edx              # move BBBB to high bits
-    or          %edx, %ecx              # %ecx<- #+BBBBBBBB
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; literal
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_16.S b/vm/mterp/x86-atom/OP_CONST_16.S
deleted file mode 100644
index f340696..0000000
--- a/vm/mterp/x86-atom/OP_CONST_16.S
+++ /dev/null
@@ -1,34 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_16.S
-    *
-    * Code: Moves a literal to a register. Uses no substitutions.
-    *
-    * For: const/16
-    *
-    * Description: Move the given literal value (right-zero-extended to 32
-    *              bits) into the specified register
-    *
-    * Format: AA|op BBBB (21s)
-    *
-    * Syntax: op vAA, #+BBBB
-    */
-
-    FETCHs      1, %edx                 # %edx<- BBBB
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    SET_VREG    %edx rINST              # vAA<- BBBB; literal
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_4.S b/vm/mterp/x86-atom/OP_CONST_4.S
deleted file mode 100644
index 5396d72..0000000
--- a/vm/mterp/x86-atom/OP_CONST_4.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_4.S
-    *
-    * Code: Moves a literal to a register. Uses no substitutions.
-    *
-    * For: const/4
-    *
-    * Description: Move the given literal value (right-zero-extended to 32
-    *              bits) into the specified register.
-    *
-    * Format: B|A|op (11n)
-    *
-    * Syntax: op vA, #+B
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    andl        $$15, rINST             # rINST<- A
-    shl         $$24, %edx              # %edx<- B000
-    sar         $$28, %edx              # %edx<- right-zero-extended B
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    SET_VREG    %edx, rINST             # vA<- %edx; literal
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_CLASS.S b/vm/mterp/x86-atom/OP_CONST_CLASS.S
deleted file mode 100644
index bc6657c..0000000
--- a/vm/mterp/x86-atom/OP_CONST_CLASS.S
+++ /dev/null
@@ -1,67 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_CLASS.S
-    *
-    * Code: Move a class reference to a register. Uses no substitutions.
-    *
-    * For: const/class
-    *
-    * Description: Move a reference to the class specified
-    *              by the given index into the specified register.
-    *              In the case where the indicated type is primitive,
-    *              this will store a reference to the primitive type's
-    *              degenerate class.
-    *
-    * Format: AA|op BBBBlo BBBBhi (21c)
-    *
-    * Syntax: op vAA, field@BBBB
-    */
-
-    movl        rGLUE, %edx             # get MterpGlue pointer
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    movl        offGlue_methodClassDex(%edx), %eax # %eax<- pDvmDex
-    movl        offDvmDex_pResClasses(%eax), %eax # %eax<- pDvmDex->pResClasses
-    movl        (%eax, %ecx, 4), %eax   # %eax<- resolved class
-    cmp         $$0, %eax               # check if classes is resolved before?
-    je          .L${opcode}_resolve     # resolve class
-    SET_VREG    %eax, rINST             # vAA<- resolved class
-    FINISH      2                       # jump to next instruction
-%break
-
-   /*
-    * Continuation if the Class has not yet been resolved.
-    *  %ecx: BBBB (Class ref)
-    *  need: target register
-    */
-
-.L${opcode}_resolve:
-    EXPORT_PC
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        $$1, -4(%esp)           # push parameter true
-    movl        %ecx, -8(%esp)          # push parameter
-    movl        %edx, -12(%esp)         # push parameter glue->method->clazz
-    lea         -12(%esp), %esp
-    call        dvmResolveClass         # resolve ClassObject pointer
-                                        # class: (const ClassObject* referrer, u4 classIdx,
-                                        #         bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    lea         12(%esp), %esp
-    cmp         $$0, %eax               # check for null pointer
-    je          common_exceptionThrown  # handle exception
-    SET_VREG    %eax, rINST             # vAA<- resolved class
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_CONST_HIGH16.S b/vm/mterp/x86-atom/OP_CONST_HIGH16.S
deleted file mode 100644
index f47d34b..0000000
--- a/vm/mterp/x86-atom/OP_CONST_HIGH16.S
+++ /dev/null
@@ -1,35 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_HIGH16.S
-    *
-    * Code: Move a literal to a register. Uses no substitutions.
-    *
-    * For: const/high16
-    *
-    * Description: Move the given literal value (right-zero-extended to 32
-    *              bits) into the specified register
-    *
-    * Format: AA|op BBBB (21h)
-    *
-    * Syntax: op vAA, #+BBBB0000
-    */
-
-    FETCH       1, %ecx                 # %ecx<- 0000BBBB (zero-extended)
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    shl         $$16, %ecx              # %ecx<- BBBB0000
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; BBBB0000
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_STRING.S b/vm/mterp/x86-atom/OP_CONST_STRING.S
deleted file mode 100644
index c958ed4..0000000
--- a/vm/mterp/x86-atom/OP_CONST_STRING.S
+++ /dev/null
@@ -1,65 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_STRING.S
-    *
-    * Code: Move a string reference to a register. Uses no substitutions.
-    *
-    * For: const/string
-    *
-    * Description: Move a referece to the string specified by the given
-    *              index into the specified register. vAA <- pResString[BBBB]
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    movl        rGLUE, %edx             # get MterpGlue pointer
-    movl        offGlue_methodClassDex(%edx), %eax # %eax<- glue->methodClassDex
-    movl        offDvmDex_pResStrings(%eax), %eax # %eax<- glue->methodClassDex->pResStrings
-    movl        (%eax, %ecx, 4), %eax   # %eax<- pResStrings[BBBB]
-    cmp         $$0, %eax               # check if string is resolved
-    je          .L${opcode}_resolve     # resolve string reference
-    SET_VREG    %eax, rINST             # vAA<- %eax; pResString[BBBB]
-    FINISH      2                       # jump to next instruction
-
-%break
-
-
-   /*
-    * Continuation if the Class has not yet been resolved.
-    *  %ecx: BBBB (Class ref)
-    *  need: target register
-    */
-
-.L${opcode}_resolve:
-    EXPORT_PC
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %ecx, -4(%esp)          # push parameter class ref
-    movl        %edx, -8(%esp)          # push parameter glue->method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveString        # resolve string reference
-                                        # call: (const ClassObject* referrer, u4 stringIdx)
-                                        # return: StringObject*
-    lea         8(%esp), %esp
-    cmp         $$0, %eax               # check if resolved string failed
-    je          common_exceptionThrown  # resolve failed; exception thrown
-    SET_VREG    %eax, rINST             # vAA<- %eax; pResString[BBBB]
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_STRING_JUMBO.S b/vm/mterp/x86-atom/OP_CONST_STRING_JUMBO.S
deleted file mode 100644
index 09d045d..0000000
--- a/vm/mterp/x86-atom/OP_CONST_STRING_JUMBO.S
+++ /dev/null
@@ -1,66 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_STRING_JUMBO.S
-    *
-    * Code: Move a string reference to a register. Uses no substitutions.
-    *
-    * For: const/string-jumbo
-    *
-    * Description: Move a reference to the string specified by the given
-    *              index into the specified register. vAA <- pResString[BBBB]
-    *
-    * Format: AA|op BBBBlo BBBBhi (31c)
-    *
-    * Syntax: op vAA, string@BBBBBBBB
-    */
-
-    movl        rGLUE, %edx             # get MterpGlue pointer
-    movl        offGlue_methodClassDex(%edx), %eax # %eax<- glue->methodClassDex
-    movl        offDvmDex_pResStrings(%eax), %eax # %eax<- glue->methodClassDex->pResStrings
-    FETCH       1, %ecx                 # %ecx<- BBBBlo
-    FETCH       2, %edx                 # %edx<- BBBBhi
-    shl         $$16, %edx              # %edx<- prepare to create &BBBBBBBB
-    or          %edx, %ecx              # %ecx<- &BBBBBBBB
-    movl        (%eax, %ecx, 4), %eax   # %eax<- pResStrings[BBBB]
-    cmp         $$0, %eax               # check if string is resolved
-    je          .L${opcode}_resolve     # resolve string reference
-    SET_VREG    %eax, rINST             # vAA<- %eax; pResString[BBBB]
-    FINISH      3                       # jump to next instruction
-%break
-
-
-   /*
-    * Continuation if the Class has not yet been resolved.
-    *  %ecx: BBBB (Class ref)
-    *  need: target register
-    */
-.L${opcode}_resolve:
-    EXPORT_PC
-    movl        rGLUE, %edx             # get MterpGlue pointer
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        offMethod_clazz(%edx), %edx # %edx <- glue->method->clazz
-    movl        %ecx, -4(%esp)          # push parameter class ref
-    movl        %edx, -8(%esp)          # push parameter glue->method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveString        # resolve string reference
-                                        # call: (const ClassObject* referrer, u4 stringIdx)
-                                        # return: StringObject*
-    lea         8(%esp), %esp
-    cmp         $$0, %eax               # check if resolved string failed
-    je          common_exceptionThrown  # resolve failed; exception thrown
-    SET_VREG    %eax, rINST             # vAA<- %eax; pResString[BBBB]
-    FINISH      3                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_CONST_WIDE.S b/vm/mterp/x86-atom/OP_CONST_WIDE.S
deleted file mode 100644
index 1ce7c76..0000000
--- a/vm/mterp/x86-atom/OP_CONST_WIDE.S
+++ /dev/null
@@ -1,42 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_WIDE.S
-    *
-    * Code: Move a literal to a register. Uses no substitutions.
-    *
-    * For: const-wide
-    *
-    * Description: Move the given literal value into the specified
-    *              register pair
-    *
-    * Format: AA|op BBBBlolo BBBBlohi BBBBhilo BBBBhihi (51l)
-    *
-    * Syntax: op vAA, #+BBBBBBBBBBBBBBBB
-    */
-
-    FETCH       1, %ecx                 # %ecx<- BBBBlolo
-    FETCH       2, %edx                 # %edx<- BBBBlohi
-    shl         $$16, %edx              # %edx<- prepare to create #+BBBBBBBBlo
-    or          %edx, %ecx              # %ecx<- #+BBBBBBBBlo
-    movl        %ecx, (rFP, rINST, 4)   # vAA <- #+BBBBBBBBlo
-    FETCH       3, %ecx                 # %ecx<- BBBBhilo
-    FETCH       4, %edx                 # %edx<- BBBBhihi
-    FFETCH_ADV  5, %eax                 # %eax<- next instruction hi; fetch, advance
-    shl         $$16, %edx              # %edx<- prepare to create #+BBBBBBBBhi
-    or          %edx, %ecx              # %ecx<- #+BBBBBBBBhi
-    movl        %ecx, 4(rFP, rINST, 4)  # vAA+1 <- #+BBBBBBBBlo
-    FGETOP_JMP  5, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_WIDE_16.S b/vm/mterp/x86-atom/OP_CONST_WIDE_16.S
deleted file mode 100644
index c980f10..0000000
--- a/vm/mterp/x86-atom/OP_CONST_WIDE_16.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_WIDE_16.S
-    *
-    * Code: Move a literal to a register. Uses no substitutions.
-    *
-    * For: const-wide/16
-    *
-    * Description: Move the given literal value (sign-extended to 64 bits)
-    *              into the specified register-pair
-    *
-    * Format: AA|op BBBB (21s)
-    *
-    * Syntax: op vAA, #+BBBB
-    */
-
-    FETCHs      1, %ecx                 # %ecx<- ssssBBBB (sign-extended)
-    movl        %ecx, %edx              # %edx<- ssssBBBB (sign-extended)
-    sar         $$31, %ecx              # %ecx<- sign bit
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl        %edx, (rFP, rINST, 4)   # vAA<- ssssBBBB
-    movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- ssssssss
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_WIDE_32.S b/vm/mterp/x86-atom/OP_CONST_WIDE_32.S
deleted file mode 100644
index 92f8450..0000000
--- a/vm/mterp/x86-atom/OP_CONST_WIDE_32.S
+++ /dev/null
@@ -1,39 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_WIDE_32.S
-    *
-    * Code: Move a literal to a register. Uses no substitutions.
-    *
-    * For: const-wide/32
-    *
-    * Description: Move the given literal value (sign-extended to 64 bits)
-    *              into the specified register-pair
-    *
-    * Format: AA|op BBBBlo BBBBhi (31i)
-    *
-    * Syntax: op vAA, #+BBBBBBBB
-    */
-
-    FETCH       1,  %edx                # %edx<- BBBBlo
-    FETCHs      2, %ecx                 # %ecx<- BBBBhi
-    shl         $$16, %ecx              # prepare to create #+BBBBBBBB
-    or          %ecx, %edx              # %edx<- %edx<- #+BBBBBBBB
-    sar         $$31, %ecx              # %ecx<- sign bit
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl        %edx, (rFP, rINST, 4)   # vAA<-  BBBBBBBB
-    movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- ssssssss
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_WIDE_HIGH16.S b/vm/mterp/x86-atom/OP_CONST_WIDE_HIGH16.S
deleted file mode 100644
index 5b4b4f1..0000000
--- a/vm/mterp/x86-atom/OP_CONST_WIDE_HIGH16.S
+++ /dev/null
@@ -1,35 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_CONST_WIDE_HIGH16.S
-    *
-    * Code: Move a literal value to a register. Uses no substitutions.
-    *
-    * For: const-wide/high16
-    *
-    * Description: Move the given literal value (right-zero-extended to 64
-    *              bits) into the specified register
-    *
-    * Format: AA|op BBBB (21h)
-    *
-    * Syntax: op vAA, #+BBBB000000000000
-    */
-
-    FETCH       1, %ecx                 # %ecx<- 0000BBBB (zero-extended)
-    shl         $$16, %ecx              # rINST<- AA
-    movl        $$0, (rFP, rINST, 4)    # vAAlow<- 00000000
-    movl        %ecx, 4(rFP, rINST, 4)  # vAAhigh<- %ecx; BBBB0000
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_DIV_DOUBLE.S b/vm/mterp/x86-atom/OP_DIV_DOUBLE.S
deleted file mode 100644
index 418a230..0000000
--- a/vm/mterp/x86-atom/OP_DIV_DOUBLE.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_DOUBLE.S
-    *
-    * Code: Divides doubles. Uses no substitutions.
-    *
-    * For: div-double
-    *
-    * Description: Divide operation on two source registers, storing
-    *              the result in a destination register
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    fldl        (rFP, %ecx, 4)          # floating point stack vBB
-    fdivl       (rFP, %edx, 4)          # divide double; vBB/vCC
-    fstpl       (rFP, rINST, 4)         # vAA<- result
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_DIV_DOUBLE_2ADDR.S b/vm/mterp/x86-atom/OP_DIV_DOUBLE_2ADDR.S
deleted file mode 100644
index 7003e30..0000000
--- a/vm/mterp/x86-atom/OP_DIV_DOUBLE_2ADDR.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_DOUBLE_2ADDR.S
-    *
-    * Code: Divides doubles. Uses no substitutions.
-    *
-    * For: div-double/2addr
-    *
-    * Description: Divide operation on two source registers, storing
-    *              the result in the first source reigster
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    andl        $$15, %edx              # %edx<- A
-    shr         $$4, rINST              # rINST<- B
-    fldl        (rFP, %edx, 4)          # %xmm0<- vA
-    fdivl       (rFP, rINST, 4)         # divide double; vA/vB
-    fstpl       (rFP, %edx, 4)          # vAA<- result
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_DIV_FLOAT.S b/vm/mterp/x86-atom/OP_DIV_FLOAT.S
deleted file mode 100644
index a7aabd7..0000000
--- a/vm/mterp/x86-atom/OP_DIV_FLOAT.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_FLOAT.S
-    *
-    * Code: Divides floats. Uses no substitutions.
-    *
-    * For: div-float
-    *
-    * Description: Divide operation on two source registers, storing
-    *              the result in a destiniation register
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %eax                 # %eax<- BB
-    FETCH_CC    1, %ecx                 # %ecx<- CC
-    flds        (rFP, %eax, 4)          # floating point stack vBB
-    fdivs       (rFP, %ecx, 4)          # divide double; vBB/vCC
-    fstps       (rFP, rINST, 4)         # vAA<- result
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_DIV_FLOAT_2ADDR.S b/vm/mterp/x86-atom/OP_DIV_FLOAT_2ADDR.S
deleted file mode 100644
index 471f30a..0000000
--- a/vm/mterp/x86-atom/OP_DIV_FLOAT_2ADDR.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_FLOAT_2ADDR.S
-    *
-    * Code: Divides floats. Uses no substitutions.
-    *
-    * For: div-float/2addr
-    *
-    * Description: Divide operation on two source registers, storing
-    *              the result in the first source reigster
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    andl        $$15, %ecx              # %ecx<- A
-    shr         $$4, rINST              # rINST<- B
-    flds        (rFP, %ecx, 4)          # %xmm0<- vA
-    fdivs       (rFP, rINST, 4)         # divide double; vA/vB
-    fstps       (rFP, %ecx, 4)          # vAA<- result
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_DIV_INT.S b/vm/mterp/x86-atom/OP_DIV_INT.S
deleted file mode 100644
index c7f5b27..0000000
--- a/vm/mterp/x86-atom/OP_DIV_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_INT.S
-    */
-
-%include "x86-atom/binopD.S"
diff --git a/vm/mterp/x86-atom/OP_DIV_INT_2ADDR.S b/vm/mterp/x86-atom/OP_DIV_INT_2ADDR.S
deleted file mode 100644
index 762d82f..0000000
--- a/vm/mterp/x86-atom/OP_DIV_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_INT_2ADDR.S
-    */
-
-%include "x86-atom/binopD2addr.S"
diff --git a/vm/mterp/x86-atom/OP_DIV_INT_LIT16.S b/vm/mterp/x86-atom/OP_DIV_INT_LIT16.S
deleted file mode 100644
index 9c2ce55..0000000
--- a/vm/mterp/x86-atom/OP_DIV_INT_LIT16.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_INT_LIT16.S
-    */
-
-%include "x86-atom/binopDLit16.S"
diff --git a/vm/mterp/x86-atom/OP_DIV_INT_LIT8.S b/vm/mterp/x86-atom/OP_DIV_INT_LIT8.S
deleted file mode 100644
index ef0ea7b..0000000
--- a/vm/mterp/x86-atom/OP_DIV_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_INT_LIT8.S
-    */
-
-%include "x86-atom/binopDLit8.S"
diff --git a/vm/mterp/x86-atom/OP_DIV_LONG.S b/vm/mterp/x86-atom/OP_DIV_LONG.S
deleted file mode 100644
index 38ade6a..0000000
--- a/vm/mterp/x86-atom/OP_DIV_LONG.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_LONG.S
-    */
-
-%include "x86-atom/binopDivRemLong.S"
diff --git a/vm/mterp/x86-atom/OP_DIV_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_DIV_LONG_2ADDR.S
deleted file mode 100644
index 41e5430..0000000
--- a/vm/mterp/x86-atom/OP_DIV_LONG_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DIV_LONG_2ADDR.S
-    */
-
-%include "x86-atom/binopDivRemLong2Addr.S"
diff --git a/vm/mterp/x86-atom/OP_DOUBLE_TO_FLOAT.S b/vm/mterp/x86-atom/OP_DOUBLE_TO_FLOAT.S
deleted file mode 100644
index 516a2e6..0000000
--- a/vm/mterp/x86-atom/OP_DOUBLE_TO_FLOAT.S
+++ /dev/null
@@ -1,36 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DOUBLE_TO_FLOAT.S
-    *
-    * Code: Converts a double to a float. Uses no substitutions.
-    *
-    * For: double-to-float
-    *
-    * Description: Convert the source register (a double) to a float
-    *              and store the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, rINST              # rINST<- B
-    and         $$15, %edx              # %edx<- A
-    fldl        (rFP, rINST, 4)         # load &vB
-    fstps       (rFP, %edx, 4)          # store float
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_DOUBLE_TO_INT.S b/vm/mterp/x86-atom/OP_DOUBLE_TO_INT.S
deleted file mode 100644
index f377762..0000000
--- a/vm/mterp/x86-atom/OP_DOUBLE_TO_INT.S
+++ /dev/null
@@ -1,68 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DOUBLE_TO_INT.S
-    *
-    * Code: Converts a double to an integer. Uses no substitutions.
-    *
-    * For: double-to-int
-    *
-    * Description: Convert the source register (a double) to an integer
-    *              and store the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, rINST              # rINST<- B
-    and         $$15, %edx              # %edx<- A
-    fldl        (rFP, rINST, 4)         # load &vB
-    fildl       .LintMax                # push max int value
-    fildl       .LintMin                # push min int value
-    fucomip     %st(2), %st(0)          # check for negInf
-    jae         .L${opcode}_negInf      # handle negInf
-    fucomip     %st(1), %st(0)          # check for posInf or NaN
-    jc          .L${opcode}_nanInf      # handle posInf or NaN
-    jmp         .L${opcode}_break       # do conversion
-%break
-
-.L${opcode}_break:
-    fnstcw      -2(%esp)                # save control word
-    orl         $$0xc00, -2(%esp)       # reset control
-    fldcw       -2(%esp)                # load control word
-    xorl        $$0xc00, -2(%esp)       # reset control
-    fistpl      (rFP, %edx, 4)          # move converted int
-    fldcw       -2(%esp)                # load saved control word
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_nanInf:
-    jnp         .L${opcode}_posInf
-    fstps       (rFP, %edx, 4)
-    movl        $$0x00000000,  (rFP, %edx, 4) # vA<- NaN
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_posInf:
-    fstps       (rFP, %edx, 4)
-    movl        $$0x7FFFFFFF,  (rFP, %edx, 4) # vA<- posInf
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_negInf:
-    fstps       (rFP, %edx, 4)
-    fstps       (rFP, %edx, 4)
-    movl        $$0x80000000,  (rFP, %edx, 4) # vA<- negInf
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_DOUBLE_TO_LONG.S b/vm/mterp/x86-atom/OP_DOUBLE_TO_LONG.S
deleted file mode 100644
index 2ce9bcc..0000000
--- a/vm/mterp/x86-atom/OP_DOUBLE_TO_LONG.S
+++ /dev/null
@@ -1,71 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_DOUBLE_TO_LONG.S
-    *
-    * Code: Converts a double to a long. Uses no substitutions.
-    *
-    * For: double-to-long
-    *
-    * Description: Convert the double in source register to a long
-    *              and store in the destintation register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %ecx<- BA
-    shr         $$4, rINST              # rINST<- B
-    and         $$15, %edx              # %ecx<- A
-    fldl        (rFP, rINST, 4)         # push vB to floating point stack
-    fildll      .LvaluePosInfLong       # push max int value
-    fildll      .LvalueNegInfLong       # push min int value
-    fucomip     %st(2), %st(0)          # check for negInf
-    jae         .L${opcode}_negInf      # handle negInf
-    fucomip     %st(1), %st(0)          # check for posInf or NaN
-    jc          .L${opcode}_nanInf      # handle posInf or NaN
-    jmp         .L${opcode}_break       # do conversion
-%break
-
-.L${opcode}_break:
-    fnstcw      -2(%esp)                # save control word
-    orl         $$0xc00, -2(%esp)       # reset control
-    fldcw       -2(%esp)                # load control word
-    xorl        $$0xc00, -2(%esp)       # reset control
-    fistpll     (rFP, %edx, 4)          # move converted int
-    fldcw       -2(%esp)                # load saved control word
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_nanInf:
-    jnp         .L${opcode}_posInf
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvalueNanLong, %xmm0   # %xmm0<- NaN
-    movq        %xmm0,  (rFP, %edx, 4)  # vA<- %xmm0; NaN
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_posInf:
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvaluePosInfLong, %xmm0 # %xmm0<- posInf
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; posInf
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_negInf:
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvalueNegInfLong, %xmm0 # %xmm0<- negInf
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; negInf
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_EXECUTE_INLINE.S b/vm/mterp/x86-atom/OP_EXECUTE_INLINE.S
deleted file mode 100644
index 4f01cef..0000000
--- a/vm/mterp/x86-atom/OP_EXECUTE_INLINE.S
+++ /dev/null
@@ -1,86 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_EXECUTE_INLINE.S
-    *
-    * Code: Executes a "native inline" instruction. Uses no substitutions.
-    *
-    * For: execute-inline
-    *
-    * Description: Executes a "native inline" instruction. This instruction
-    *              is generated by the optimizer.
-    *
-    * Format:
-    *
-    * Syntax: vAA, {vC, vD, vE, vF}, inline@BBBB
-    */
-
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    movl        rGLUE, %eax             # %eax<- MterpGlue pointer
-    addl        $$offGlue_retval, %eax  # %eax<- &glue->retval
-    EXPORT_PC
-    shr         $$4, rINST              # rINST<- B
-    movl        %eax, -8(%esp)          # push parameter glue->retval
-    lea         -24(%esp), %esp
-    jmp         .L${opcode}_continue
-%break
-
-   /*
-    * Extract args, call function.
-    *  rINST = #of args (0-4)
-    *  %ecx = call index
-    */
-
-.L${opcode}_continue:
-    FETCH       2, %edx                 # %edx<- FEDC
-    cmp         $$1, rINST              # determine number of arguments
-    jl          0f                      # handle zero args
-    je          1f                      # handle one arg
-    cmp         $$3, rINST
-    jl          2f                      # handle two args
-    je          3f                      # handle three args
-4:
-    movl        %edx, rINST             # rINST<- FEDC
-    and         $$0xf000, rINST         # isolate F
-    shr         $$10, rINST
-    movl        (rFP, rINST), rINST     # rINST<- vF
-    movl        rINST, 12(%esp)         # push parameter vF
-3:
-    movl        %edx, rINST             # rINST<- FEDC
-    and         $$0x0f00, rINST         # isolate E
-    shr         $$6, rINST
-    movl        (rFP, rINST), rINST     # rINST<- vE
-    movl        rINST, 8(%esp)          # push parameter E
-2:
-    movl        %edx, rINST             # rINST<- FEDC
-    and         $$0x00f0, rINST         # isolate D
-    shr         $$2, rINST
-    movl        (rFP, rINST), rINST     # rINST<- vD
-    movl        rINST, 4(%esp)          # push parameter D
-1:
-    and         $$0x000f, %edx          # isolate C
-    movl        (rFP, %edx, 4), %edx    # rINST<- vC
-    movl        %edx, (%esp)            # push parameter C
-0:
-    shl         $$4, %ecx
-    movl        $$gDvmInlineOpsTable, %eax # %eax<- address for table of inline operations
-    call        *(%eax, %ecx)           # call function
-
-    cmp         $$0, %eax               # check boolean result of inline
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    lea         24(%esp), %esp          # update stack pointer
-    je          common_exceptionThrown  # handle exception
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_EXECUTE_INLINE_RANGE.S b/vm/mterp/x86-atom/OP_EXECUTE_INLINE_RANGE.S
deleted file mode 100644
index cd5a048..0000000
--- a/vm/mterp/x86-atom/OP_EXECUTE_INLINE_RANGE.S
+++ /dev/null
@@ -1,75 +0,0 @@
-   /* Copyright (C) 2010 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_EXECUTE_INLINE_RANGE.S
-    *
-    * Code: Executes a "native inline" instruction. Uses no substitutions.
-    *
-    * For: execute-inline
-    *
-    * Description: Executes a "native inline" instruction. This instruction
-    *              is generated by the optimizer.
-    *
-    * Format:
-    *
-    * Syntax: AA, {vCCCC..v(CCCC+AA-1)}, inline@BBBB
-    */
-
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    movl        rGLUE, %eax             # %eax<- MterpGlue pointer
-    addl        $$offGlue_retval, %eax  # %eax<- &glue->retval
-    EXPORT_PC
-    movl        %eax, -8(%esp)          # push parameter glue->retval
-    lea         -24(%esp), %esp
-    jmp         .L${opcode}_continue
-%break
-
-   /*
-    * Extract args, call function.
-    *  rINST = #of args (0-4)
-    *  %ecx = call index
-    */
-
-.L${opcode}_continue:
-    FETCH       2, %edx                 # %edx<- FEDC
-    cmp         $$1, rINST              # determine number of arguments
-    jl          0f                      # handle zero args
-    je          1f                      # handle one arg
-    cmp         $$3, rINST
-    jl          2f                      # handle two args
-    je          3f                      # handle three args
-4:
-    movl        12(rFP, %edx, 4), rINST     # rINST<- vF
-    movl        rINST, 12(%esp)         # push parameter vF
-3:
-    movl        8(rFP, %edx, 4), rINST     # rINST<- vE
-    movl        rINST, 8(%esp)          # push parameter E
-2:
-    movl        4(rFP, %edx, 4), rINST     # rINST<- vD
-    movl        rINST, 4(%esp)          # push parameter D
-1:
-    movl        (rFP, %edx, 4), %edx    # rINST<- vC
-    movl        %edx, (%esp)            # push parameter C
-0:
-    shl         $$4, %ecx
-    movl        $$gDvmInlineOpsTable, %eax # %eax<- address for table of inline operations
-    call        *(%eax, %ecx)           # call function
-
-    cmp         $$0, %eax               # check boolean result of inline
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    lea         24(%esp), %esp          # update stack pointer
-    je          common_exceptionThrown  # handle exception
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_FILLED_NEW_ARRAY.S b/vm/mterp/x86-atom/OP_FILLED_NEW_ARRAY.S
deleted file mode 100644
index f804f3e..0000000
--- a/vm/mterp/x86-atom/OP_FILLED_NEW_ARRAY.S
+++ /dev/null
@@ -1,173 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FILLED_NEW_ARRAY.S
-    *
-    * Code: Constructs and fills an array with the given data. Provides
-    *
-    * For: float-to-int
-    *
-    * Description: Construct an array of the given type and size,
-    *              filling it with the supplied contents. The type
-    *              must be an array type. The array's contents
-    *              must be single-word. The constructed instance
-    *              is stored as a result in the same way that the
-    *              method invocation instructions store their results,
-    *              so the constructed instance must be moved to a
-    *              register with a subsequent move-result-object
-    *              instruction.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc) (range)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, vtaboff@CCCC
-    *         [B=4] op {vD, vE, vF, vG}, vtaboff@CCCC
-    *         [B=3] op {vD, vE, vF}, vtaboff@CCCC
-    *         [B=2] op {vD, vE}, vtaboff@CCCC
-    *         [B=1] op {vD}, vtaboff@CCCC
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB
-    *         op {vCCCC .. vNNNN}, type@BBBB
-    */
-
-%default { "isrange":"0" }
-
-    movl        rGLUE, %edx             # %edx<- MterpGlue pointer
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- glue->methodClassDex
-    movl        offDvmDex_pResClasses(%edx), %edx # %edx<- glue->methodClassDex->pResClasses
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    EXPORT_PC
-    movl (%edx, %ecx, 4), %eax # %eax<- possibly resolved class
-    cmp         $$0, %eax               # %eax<- check if already resolved
-    jne         .L${opcode}_continue
-    jmp         .L${opcode}_break
-%break
-
-.L${opcode}_break:
-    movl        $$0, -8(%esp)           # push parameter false
-    movl        %ecx, -12(%esp)         # push parameter BBBB
-    movl        rGLUE, %edx             # %edx<- MterpGlue pointer
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, -16(%esp)         # push parameter glue->method->clazz
-    lea         -16(%esp), %esp
-    call        dvmResolveClass         # call: (const ClassObject* referrer, u4 classIdx,
-                                        #        bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    lea         16(%esp), %esp
-    cmp         $$0, %eax               # check for null return
-    je          common_exceptionThrown  # handle exception
-
-   /*
-    * On entry:
-    *  %eax holds array class
-    *  rINST holds BA or AA
-    */
-
-.L${opcode}_continue:
-    movl        offClassObject_descriptor(%eax), %eax # %eax<- arrayClass->descriptor
-    movzbl      1(%eax), %eax           # %eax<- descriptor[1]
-    cmpb        $$'I', %al             # check if array of ints
-    je          1f
-    cmpb        $$'L', %al
-    je          1f
-    cmpb        $$'[', %al
-    jne         .L${opcode}_notimpl     # jump to not implemented
-1:
-    movl        %eax, sReg0             # save type
-    movl        rINST, -12(%esp)        # push parameter length
-    movl        %eax, -16(%esp)         # push parameter descriptor[1]
-    movl        $$ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags
-    .if         (!$isrange)
-    shrl        $$4, -12(%esp)          # parameter length is B
-    .endif
-    lea         -16(%esp), %esp
-    call        dvmAllocPrimitiveArray  # call: (char type, size_t length, int allocFlags)
-                                        # return: ArrayObject*
-    lea         16(%esp), %esp
-    cmp         $$0, %eax               # check for null return
-    je          common_exceptionThrown  # handle exception
-
-    FETCH       2, %edx                 # %edx<- FEDC or CCCC
-    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
-    movl        %eax, offGlue_retval(%ecx) # retval<- new array
-    lea         offArrayObject_contents(%eax), %eax # %eax<- newArray->contents
-    subl        $$1, -12(%esp)          # length--; check for negative
-    js          2f                      # if length was zero, finish
-
-   /*
-    * copy values from registers into the array
-    * %eax=array, %edx=CCCC/FEDC, -12(%esp)=length (from AA or B), rINST=AA/BA
-    */
-
-    .if         $isrange
-    lea         (rFP, %edx, 4), %ecx    # %ecx<- &fpp[CCCC]
-1:
-    movl        (%ecx), %edx            # %edx<- %ecx++
-    lea         4(%ecx), %ecx           # %ecx++
-    movl        %edx, (%eax)            # *contents<- vX
-    lea         4(%eax), %eax           # %eax++; contents++
-    subl        $$1, -12(%esp)          # length--
-    jns         1b                      # or continue at 2
-    .else
-    cmp         $$4, -12(%esp)          # check length
-    jne         1f                      # has four args
-    and         $$15, rINST             # rINST<- A
-    GET_VREG    rINST                   # rINST<- vA
-    subl        $$1, -12(%esp)          # count--
-    movl        rINST, 16(%eax)         # contents[4]<- vA
-1:
-    movl        %edx, %ecx              # %ecx<- %edx; ecx for temp
-    andl        $$15, %ecx              # %ecx<- G/F/E/D
-    GET_VREG    %ecx                    # %ecx<- vG/vF/vE/vD
-    shr         $$4, %edx               # %edx<- put next reg in low 4
-    subl        $$1, -12(%esp)          # count--
-    movl        %ecx, (%eax)            # *contents<- vX
-    lea         4(%eax), %eax           # %eax++; contents++
-    jns         1b                      # or continue at 2
-    .endif
-2:
-    cmpb        $$'I', sReg0            # check for int array
-    je          3f
-    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
-    movl        offGlue_retval(%ecx), %eax # Object head
-    movl        offGlue_cardTable(%ecx), %ecx # card table base
-    shrl        $$GC_CARD_SHIFT, %eax   # convert to card num
-    movb        %cl,(%ecx, %eax)        # mark card based on object head
-3:
-    FINISH      3                       # jump to next instruction
-
-   /*
-    * Throw an exception to indicate this mode of filled-new-array
-    * has not been implemented.
-    */
-
-.L${opcode}_notimpl:
-    movl        $$.LstrInternalError, -8(%esp)
-    movl        $$.LstrFilledNewArrayNotImpl, -4(%esp)
-    lea         -8(%esp), %esp
-    call        dvmThrowException # call: (const char* exceptionDescriptor,
-                                  #        const char* msg)
-                                  # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown
-
-.if         (!$isrange)                 # define in one or the other, not both
-.LstrFilledNewArrayNotImpl:
-.asciz      "filled-new-array only implemented for 'int'"
-.LstrInternalError:
-.asciz  "Ljava/lang/InternalError;"
-.endif
diff --git a/vm/mterp/x86-atom/OP_FILLED_NEW_ARRAY_RANGE.S b/vm/mterp/x86-atom/OP_FILLED_NEW_ARRAY_RANGE.S
deleted file mode 100644
index fd8b0c5..0000000
--- a/vm/mterp/x86-atom/OP_FILLED_NEW_ARRAY_RANGE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FILLED_NEW_ARRAY_RANGE.S
-    */
-
-%include "x86-atom/OP_FILLED_NEW_ARRAY.S" { "isrange":"1" }
diff --git a/vm/mterp/x86-atom/OP_FILL_ARRAY_DATA.S b/vm/mterp/x86-atom/OP_FILL_ARRAY_DATA.S
deleted file mode 100644
index de808d9..0000000
--- a/vm/mterp/x86-atom/OP_FILL_ARRAY_DATA.S
+++ /dev/null
@@ -1,46 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FILL_ARRAY_DATA.S
-    *
-    * Code: Fills an array with given data. Uses no substitutions.
-    *
-    * For: fill-array-data
-    *
-    * Description: Fill the given array with the idicated data. The reference
-    *              must be an array of primitives, and the data table must
-    *              match it in type and size
-    *
-    * Format: AA|op BBBBlo BBBBhi (31t)
-    *
-    * Syntax: op vAA, +BBBBBBBB
-    */
-
-    FETCH       1, %ecx                 # %ecx<- BBBBlo
-    FETCH       2, %edx                 # %edx<- BBBBhi
-    shl         $$16, %edx              # prepare to create +BBBBBBBB
-    or          %ecx, %edx              # %edx<- +BBBBBBBB
-    lea         (rPC, %edx, 2), %edx    # %edx<- PC + +BBBBBBBB; array data location
-    EXPORT_PC
-    push        %edx
-    push        (rFP, rINST, 4)
-    call        dvmInterpHandleFillArrayData # call: (ArrayObject* arrayObject, const u2* arrayData)
-                                             # return: bool
-    FFETCH_ADV  3, %edx                 # %edx<- next instruction hi; fetch, advance
-    cmp         $$0, %eax
-    lea         8(%esp), %esp
-    je          common_exceptionThrown
-    FGETOP_JMP  3, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_FLOAT_TO_DOUBLE.S b/vm/mterp/x86-atom/OP_FLOAT_TO_DOUBLE.S
deleted file mode 100644
index 91866a4..0000000
--- a/vm/mterp/x86-atom/OP_FLOAT_TO_DOUBLE.S
+++ /dev/null
@@ -1,36 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FLOAT_TO_DOUBLE.S
-    *
-    * Code: Converts a float to a double. Uses no substitutions.
-    *
-    * For: float-to-double
-    *
-    * Description: Convert the float in source register to a double
-    *              and store the result in the destintation register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, rINST              # rINST<- B
-    and         $$15, %edx              # %edx<- A
-    flds        (rFP, rINST, 4)         # load float
-    fstpl       (rFP, %edx, 4)          # store double
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_FLOAT_TO_INT.S b/vm/mterp/x86-atom/OP_FLOAT_TO_INT.S
deleted file mode 100644
index 615f187..0000000
--- a/vm/mterp/x86-atom/OP_FLOAT_TO_INT.S
+++ /dev/null
@@ -1,68 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FLOAT_TO_INT.S
-    *
-    * Code: Converts a float to a int. Uses no substitutions.
-    *
-    * For: float-to-int
-    *
-    * Description: Convert the float in source register to a int
-    *              and store the result in the destintation register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, rINST              # rINST<- B
-    and         $$15, %edx              # %edx<- A
-    flds        (rFP, rINST, 4)         # push vB to floating point stack
-    fildl       .LintMax                # push max int value
-    fildl       .LintMin                # push min int value
-    fucomip     %st(2), %st(0)          # check for negInf
-    jae         .L${opcode}_negInf      # handle negInf
-    fucomip     %st(1), %st(0)          # check for posInf or NaN
-    jc          .L${opcode}_nanInf      # handle posInf or NaN
-    jmp         .L${opcode}_break       # do conversion
-%break
-
-.L${opcode}_break:
-    fnstcw      -2(%esp)                # save control word
-    orl         $$0xc00, -2(%esp)       # reset control
-    fldcw       -2(%esp)                # load control word
-    xorl        $$0xc00, -2(%esp)       # reset control
-    fistpl      (rFP, %edx, 4)          # move converted int
-    fldcw       -2(%esp)                # load saved control word
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_nanInf:
-    jnp         .L${opcode}_posInf      # handle posInf
-    fstps       (rFP, %edx, 4)          # pop floating point stack
-    movl        $$0x00000000,  (rFP, %edx, 4) # vA<- NaN
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_posInf:
-    fstps       (rFP, %edx, 4)          # pop floating point stack
-    movl        $$0x7FFFFFFF,  (rFP, %edx, 4) # vA<- posInf
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_negInf:
-    fstps       (rFP, %edx, 4)          # pop floating point stack
-    fstps       (rFP, %edx, 4)          # pop floating point stack
-    movl        $$0x80000000, (rFP, %edx, 4) # vA<- negInf
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_FLOAT_TO_LONG.S b/vm/mterp/x86-atom/OP_FLOAT_TO_LONG.S
deleted file mode 100644
index 9a50b78..0000000
--- a/vm/mterp/x86-atom/OP_FLOAT_TO_LONG.S
+++ /dev/null
@@ -1,71 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_FLOAT_TO_LONG.S
-    *
-    * Code: Converts a float to a long. Uses no substitutions.
-    *
-    * For: float-to-long
-    *
-    * Description: Convert the float in source register to a long
-    *              and store the result in the destintation register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, rINST              # rINST<- B
-    and         $$15, %edx              # %edx<- A
-    flds        (rFP, rINST, 4)         # push vB to floating point stack
-    fildll      .LvaluePosInfLong       # push max int value
-    fildll      .LvalueNegInfLong       # push min int value
-    fucomip     %st(2), %st(0)          # check for negInf
-    jae         .L${opcode}_negInf      # handle negInf
-    fucomip     %st(1), %st(0)          # check for posInf or NaN
-    jc          .L${opcode}_nanInf      # handle posInf or NaN
-    jmp         .L${opcode}_break       # do conversion
-%break
-
-.L${opcode}_break:
-    fnstcw      -2(%esp)                # save control word
-    orl         $$0xc00, -2(%esp)       # update control
-    fldcw       -2(%esp)                # load control word
-    xorl        $$0xc00, -2(%esp)       # reset control
-    fistpll     (rFP, %edx, 4)          # move converted int
-    fldcw       -2(%esp)                # load saved control word
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_nanInf:
-    jnp         .L${opcode}_posInf
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvalueNanLong, %xmm0   # %xmm0<- NaN
-    movq        %xmm0,  (rFP, %edx, 4)  # vA<- %xmm0; NaN
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_posInf:
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvaluePosInfLong, %xmm0 # %xmm0<- posInf
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; posInf
-    FINISH      1                       # jump to next instruction
-
-.L${opcode}_negInf:
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        .LvalueNegInfLong, %xmm0 # %xmm0<- negInf
-    fstpl       (rFP, %edx, 4)          # move converted int
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; negInf
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_GOTO.S b/vm/mterp/x86-atom/OP_GOTO.S
deleted file mode 100644
index 7bd9956..0000000
--- a/vm/mterp/x86-atom/OP_GOTO.S
+++ /dev/null
@@ -1,36 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_GOTO.S
-    *
-    * Code: Do an unconditional branch. Uses no substitutions.
-    *
-    * For: goto
-    *
-    * Description: Performs an unconditionally jump to the indicated instruction.
-    *              The branch uses an 8-bit offset that cannot be zero.
-    *
-    * Format: AA|op (10t)
-    *
-    * Syntax: op +AA
-    */
-
-LOP_GOTO.S:
-
-    movsbl      rINSTbl, %edx           # %edx<- +AA
-    shl         $$1, %edx               # %edx is shifted for byte offset
-    js          common_periodicChecks_backwardBranch  # do check on backwards branch
-    FINISH_RB   %edx, %ecx              # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_GOTO_16.S b/vm/mterp/x86-atom/OP_GOTO_16.S
deleted file mode 100644
index 931d215..0000000
--- a/vm/mterp/x86-atom/OP_GOTO_16.S
+++ /dev/null
@@ -1,34 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_GOTO_16.S
-    *
-    * Code: Do an unconditional branch. Uses no substitutions.
-    *
-    * For: goto/16
-    *
-    * Description: Performs an unconditionally jump to the indicated instruction.
-    *              The branch uses a 16-bit offset that cannot be zero.
-    *
-    * Format: ØØ|op AAAA (20t)
-    *
-    * Syntax: op +AAAA
-    */
-
-    FETCHs      1, %edx                 # %edx<- ssssAAAA (sign-extended)
-    shl         $$1, %edx               # %edx is doubled to get the byte offset
-    js          common_periodicChecks_backwardBranch  # do check on backwards branch
-    FINISH_RB   %edx, %ecx              # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_GOTO_32.S b/vm/mterp/x86-atom/OP_GOTO_32.S
deleted file mode 100644
index d00c3a4..0000000
--- a/vm/mterp/x86-atom/OP_GOTO_32.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_GOTO_32.S
-    *
-    * Code: Do an unconditional branch. Uses no substitutions.
-    *
-    * For: goto/32
-    *
-    * Description:  Performs an unconditionally jump to the indicated instruction.
-    *               The branch uses a 32-bit offset that can be zero.
-    *
-    * Format: ØØ|op AAAAlo AAAAhi (30t)
-    *
-    * Syntax: op +AAAAAAAA
-    */
-
-    FETCH       1, %edx                 # %edx<- AAAAlo
-    FETCH       2, %ecx                 # %ecx<- AAAAhi
-    shl         $$16, %ecx              # prepare to create +AAAAAAAA
-    or          %ecx, %edx              # %edx<- +AAAAAAAA
-    shl         $$1, %edx               # %edx is doubled to get the byte offset
-    jle          common_periodicChecks_backwardBranch  # do check on backwards branch
-    FINISH_RB   %edx, %ecx              # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_IF_EQ.S b/vm/mterp/x86-atom/OP_IF_EQ.S
deleted file mode 100644
index 61781a0..0000000
--- a/vm/mterp/x86-atom/OP_IF_EQ.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_EQ.S
-    */
-
-%include "x86-atom/bincmp.S" { "revcmp":"ne" }
diff --git a/vm/mterp/x86-atom/OP_IF_EQZ.S b/vm/mterp/x86-atom/OP_IF_EQZ.S
deleted file mode 100644
index 2f7c140..0000000
--- a/vm/mterp/x86-atom/OP_IF_EQZ.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_EQZ.S
-    */
-
-%include "x86-atom/zcmp.S" { "revcmp":"ne" }
diff --git a/vm/mterp/x86-atom/OP_IF_GE.S b/vm/mterp/x86-atom/OP_IF_GE.S
deleted file mode 100644
index e90a1e5..0000000
--- a/vm/mterp/x86-atom/OP_IF_GE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_GE.S
-    */
-
-%include "x86-atom/bincmp.S" { "revcmp":"l" }
diff --git a/vm/mterp/x86-atom/OP_IF_GEZ.S b/vm/mterp/x86-atom/OP_IF_GEZ.S
deleted file mode 100644
index 8ee71a8..0000000
--- a/vm/mterp/x86-atom/OP_IF_GEZ.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_GEZ.S
-    */
-
-%include "x86-atom/zcmp.S" { "revcmp":"l" }
diff --git a/vm/mterp/x86-atom/OP_IF_GT.S b/vm/mterp/x86-atom/OP_IF_GT.S
deleted file mode 100644
index 7f19db9..0000000
--- a/vm/mterp/x86-atom/OP_IF_GT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_GT.S
-    */
-
-%include "x86-atom/bincmp.S" { "revcmp":"le" }
diff --git a/vm/mterp/x86-atom/OP_IF_GTZ.S b/vm/mterp/x86-atom/OP_IF_GTZ.S
deleted file mode 100644
index 3f8039f..0000000
--- a/vm/mterp/x86-atom/OP_IF_GTZ.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_GTZ.S
-    */
-
-%include "x86-atom/zcmp.S" { "revcmp":"le" }
diff --git a/vm/mterp/x86-atom/OP_IF_LE.S b/vm/mterp/x86-atom/OP_IF_LE.S
deleted file mode 100644
index 287bd0d..0000000
--- a/vm/mterp/x86-atom/OP_IF_LE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_LE.S
-    */
-
-%include "x86-atom/bincmp.S" { "revcmp":"g" }
diff --git a/vm/mterp/x86-atom/OP_IF_LEZ.S b/vm/mterp/x86-atom/OP_IF_LEZ.S
deleted file mode 100644
index b7d31d1..0000000
--- a/vm/mterp/x86-atom/OP_IF_LEZ.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_LEZ.S
-    */
-
-%include "x86-atom/zcmp.S" { "revcmp":"g" }
diff --git a/vm/mterp/x86-atom/OP_IF_LT.S b/vm/mterp/x86-atom/OP_IF_LT.S
deleted file mode 100644
index 7e58e18..0000000
--- a/vm/mterp/x86-atom/OP_IF_LT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_LT.S
-    */
-
-%include "x86-atom/bincmp.S" { "revcmp":"ge" }
diff --git a/vm/mterp/x86-atom/OP_IF_LTZ.S b/vm/mterp/x86-atom/OP_IF_LTZ.S
deleted file mode 100644
index 0a3e56b..0000000
--- a/vm/mterp/x86-atom/OP_IF_LTZ.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_LTZ.S
-    */
-
-%include "x86-atom/zcmp.S" { "revcmp":"ge" }
diff --git a/vm/mterp/x86-atom/OP_IF_NE.S b/vm/mterp/x86-atom/OP_IF_NE.S
deleted file mode 100644
index 929bd05..0000000
--- a/vm/mterp/x86-atom/OP_IF_NE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_NE.S
-    */
-
-%include "x86-atom/bincmp.S" { "revcmp":"e" }
diff --git a/vm/mterp/x86-atom/OP_IF_NEZ.S b/vm/mterp/x86-atom/OP_IF_NEZ.S
deleted file mode 100644
index 07f2c87..0000000
--- a/vm/mterp/x86-atom/OP_IF_NEZ.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IF_NEZ.S
-    */
-
-%include "x86-atom/zcmp.S" { "revcmp":"e" }
diff --git a/vm/mterp/x86-atom/OP_IGET.S b/vm/mterp/x86-atom/OP_IGET.S
deleted file mode 100644
index e3a72f7..0000000
--- a/vm/mterp/x86-atom/OP_IGET.S
+++ /dev/null
@@ -1,80 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET.S
-    *
-    * Code: Generic 32-bit instance field "get" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iget's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iget-boolean, iget-byte, iget-char, iget-object, iget
-    *      iget-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-%default { "mov":"l" }
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $$0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .L${opcode}_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %edx # %edx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    jmp         .L${opcode}_finish
-%break
-
-.L${opcode}_finish:
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    cmp         $$0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # not resolved; handle exception
-
-    /*
-     *  %eax holds resolved field
-     */
-
-.L${opcode}_finish2:
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $$4, %ecx               # %ecx<- B
-    and         $$15, rINST             # rINST<- A
-
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $$0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    mov$mov     (%ecx, %edx), %edx      # %edx<- object field
-    SET_VREG    %edx, rINST             # vA<- %edx; object field
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_IGET_BOOLEAN.S b/vm/mterp/x86-atom/OP_IGET_BOOLEAN.S
deleted file mode 100644
index 12100f9..0000000
--- a/vm/mterp/x86-atom/OP_IGET_BOOLEAN.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_BOOLEAN.S
-    */
-
-%include "x86-atom/OP_IGET.S"
diff --git a/vm/mterp/x86-atom/OP_IGET_BYTE.S b/vm/mterp/x86-atom/OP_IGET_BYTE.S
deleted file mode 100644
index 6d6b870..0000000
--- a/vm/mterp/x86-atom/OP_IGET_BYTE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_BYTE.S
-    */
-
-%include "x86-atom/OP_IGET.S"
diff --git a/vm/mterp/x86-atom/OP_IGET_CHAR.S b/vm/mterp/x86-atom/OP_IGET_CHAR.S
deleted file mode 100644
index 8f285d7..0000000
--- a/vm/mterp/x86-atom/OP_IGET_CHAR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_CHAR.S
-    */
-
-%include "x86-atom/OP_IGET.S"
diff --git a/vm/mterp/x86-atom/OP_IGET_OBJECT.S b/vm/mterp/x86-atom/OP_IGET_OBJECT.S
deleted file mode 100644
index 369e1b9..0000000
--- a/vm/mterp/x86-atom/OP_IGET_OBJECT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_OBJECT.S
-    */
-
-%include "x86-atom/OP_IGET.S"
diff --git a/vm/mterp/x86-atom/OP_IGET_OBJECT_QUICK.S b/vm/mterp/x86-atom/OP_IGET_OBJECT_QUICK.S
deleted file mode 100644
index 36b7f0e..0000000
--- a/vm/mterp/x86-atom/OP_IGET_OBJECT_QUICK.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_OBJECT_QUICK.S
-    */
-
-%include "x86-atom/OP_IGET_QUICK.S"
diff --git a/vm/mterp/x86-atom/OP_IGET_OBJECT_VOLATILE.S b/vm/mterp/x86-atom/OP_IGET_OBJECT_VOLATILE.S
deleted file mode 100644
index 5de2fa3..0000000
--- a/vm/mterp/x86-atom/OP_IGET_OBJECT_VOLATILE.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "x86/OP_IGET.S"
diff --git a/vm/mterp/x86-atom/OP_IGET_QUICK.S b/vm/mterp/x86-atom/OP_IGET_QUICK.S
deleted file mode 100644
index 8ec86ec..0000000
--- a/vm/mterp/x86-atom/OP_IGET_QUICK.S
+++ /dev/null
@@ -1,38 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_QUICK.S
-    *
-    * Code: Optimization for iget
-    *
-    * For: iget-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $$4, %eax               # %eax<- B
-    and         $$15, rINST             # rINST<- A
-    GET_VREG    %eax                    # %eax<- vB; object to operate on
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    cmp         $$0, %eax               # check if object is null
-    je          common_errNullObject    # handle null object
-    FFETCH_ADV  2, %edx                 # %eax<- next instruction hi; fetch, advance
-    movl        (%ecx, %eax), %eax      # %eax<- object field
-    SET_VREG    %eax, rINST             # fp[A]<- %eax
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_IGET_SHORT.S b/vm/mterp/x86-atom/OP_IGET_SHORT.S
deleted file mode 100644
index 968b815..0000000
--- a/vm/mterp/x86-atom/OP_IGET_SHORT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_SHORT.S
-    */
-
-%include "x86-atom/OP_IGET.S"
diff --git a/vm/mterp/x86-atom/OP_IGET_VOLATILE.S b/vm/mterp/x86-atom/OP_IGET_VOLATILE.S
deleted file mode 100644
index 5de2fa3..0000000
--- a/vm/mterp/x86-atom/OP_IGET_VOLATILE.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "x86/OP_IGET.S"
diff --git a/vm/mterp/x86-atom/OP_IGET_WIDE.S b/vm/mterp/x86-atom/OP_IGET_WIDE.S
deleted file mode 100644
index 370b0b0..0000000
--- a/vm/mterp/x86-atom/OP_IGET_WIDE.S
+++ /dev/null
@@ -1,74 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_WIDE.S
-    *
-    * Code: 64 bit instance field "get" operation. Uses no substitutions.
-    *
-    * For: iget-wide
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    * Format:  B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-    movl        rGLUE, %eax             # %eax<- MterpGlue pointer
-    movl        offGlue_methodClassDex(%eax), %ecx # %ecx<- pDvmDex
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- CCCC
-    FETCH       1, %edx                 # %edx<- pDvmDex->pResFields
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved InstField ptr
-    cmp         $$0, %ecx               # check for null ptr; resolved InstField ptr
-    jne         .L${opcode}_finish
-    movl        offGlue_method(%eax), %ecx # %ecx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%ecx), %ecx # %ecx<- method->clazz
-    movl        %ecx, -8(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -4(%esp)          # push parameter method->clazz
-    jmp         .L${opcode}_finish2
-%break
-
-.L${opcode}_finish2:
-    lea         -8(%esp), %esp
-    call        dvmResolveInstField     # resolve InstField ptr
-                                        # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    cmp         $$0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    movl        %eax, %ecx              # %ecx<- %eax; %ecx expected to hold field
-    je          common_exceptionThrown
-
-   /*
-    *  %ecx holds resolved field
-    */
-
-.L${opcode}_finish:
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    andl        $$15, rINST             # rINST<- A
-    GET_VREG    %edx                    # %edx<- vB
-    cmp         $$0, %edx               # check for null object
-    je          common_errNullObject
-    movl        offInstField_byteOffset(%ecx), %ecx # %ecx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (%ecx, %edx), %xmm0     # %xmm0<- object field
-    movq        %xmm0, (rFP, rINST, 4)  # vA<- %xmm0; object field
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_IGET_WIDE_QUICK.S b/vm/mterp/x86-atom/OP_IGET_WIDE_QUICK.S
deleted file mode 100644
index 08a57f6..0000000
--- a/vm/mterp/x86-atom/OP_IGET_WIDE_QUICK.S
+++ /dev/null
@@ -1,38 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IGET_WIDE_QUICK.S
-    *
-    * Code: Optimization for iget
-    *
-    * For: iget/wide-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    andl        $$15, rINST             # rINST<- A
-    GET_VREG    %edx                    # %edx<- vB; object to operate on
-    cmp         $$0, %edx               # check if object is null
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    je          common_errNullObject    # handle null object
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    movq        (%ecx, %edx), %xmm0     # %xmm0<- object field
-    movq        %xmm0, (rFP, rINST, 4)  # fp[A]<- %xmm0
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_INSTANCE_OF.S b/vm/mterp/x86-atom/OP_INSTANCE_OF.S
deleted file mode 100644
index 4dde31c..0000000
--- a/vm/mterp/x86-atom/OP_INSTANCE_OF.S
+++ /dev/null
@@ -1,121 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INSTANCE_OF.S
-    *
-    * Code: Checks if object is instance of a class. Uses no substitutions.
-    *
-    * For: instance-of
-    *
-    * Description: Store in the given destination register 1 if the indicated
-    *              reference is an instance of the given type, or 0 if not.
-    *              The type must be a reference type (not a primitive type).
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    GET_VREG    %edx                    # %edx<- vB
-    cmp         $$0, %edx               # check for null object
-    je          .L${opcode}_store       # null object
-    jmp         .L${opcode}_break
-%break
-
-.L${opcode}_break:
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- CCCC
-    movl        offDvmDex_pResClasses(%ecx), %ecx # %ecx<- pDvmDex->pResClasses
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved class
-    movl        offObject_clazz(%edx), %edx # %edx<- obj->clazz
-    cmp         $$0, %ecx               # check if already resovled
-    je          .L${opcode}_resolve     # not resolved before, so resolve now
-
-.L${opcode}_resolved:
-    cmp         %ecx, %edx              # check if same class
-    je          .L${opcode}_trivial     # yes, finish
-    jmp         .L${opcode}_fullcheck   # no, do full check
-
-   /*
-    * The trivial test failed, we need to perform a full check.
-    * %edx holds obj->clazz
-    * %ecx holds class resolved from BBBB
-    */
-
-.L${opcode}_fullcheck:
-    movl        %edx, -8(%esp)          # push parameter obj->clazz
-    movl        %ecx, -4(%esp)          # push parameter resolved class
-    lea         -8(%esp), %esp
-    call        dvmInstanceofNonTrivial # perform full check
-                                        # call: (ClassObject* instance, ClassObject* clazz)
-                                        # return: int
-    andl        $$15, rINST             # rINST<- A
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    lea         8(%esp), %esp
-    SET_VREG    %eax, rINST             # vA<- r0
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
-
-   /*
-    * %edx holds boolean result
-    */
-
-.L${opcode}_store:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    andl        $$15, rINST             # rINST<- A
-    SET_VREG    %edx, rINST             # vA<- r0
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-   /*
-    * Trivial test succeeded, save and bail.
-    */
-
-.L${opcode}_trivial:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    andl        $$15, rINST             # rINST<- A
-    SET_VREG    $$1, rINST              # vA<- r0
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-
-   /*
-    * Resolution required.  This is the least-likely path.
-    * %eax holds BBBB
-    */
-
-.L${opcode}_resolve:
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    EXPORT_PC
-    movl        offGlue_method(%ecx), %ecx # %ecx<- glue->method
-    movl        offMethod_clazz(%ecx), %ecx # %ecx<- glue->method->clazz
-    movl        %ecx, -12(%esp)         # push parameter glue->method->clazz
-    movl        %eax, -8(%esp)          # push parameter CCCC; type index
-    movl        $$1, -4(%esp)           # push parameter true
-    lea         -12(%esp), %esp
-    call        dvmResolveClass         # call: (const ClassObject* referrer, u4 classIdx,
-                                        #        bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    lea         12(%esp), %esp
-    cmp         $$0, %eax               # check for null
-    je          common_exceptionThrown  # handle exception
-    movl        rINST, %edx             # %edx<- BA+
-    shr         $$4, %edx               # %edx<- B
-    movl        %eax, %ecx              # need class in %ecx
-    GET_VREG    %edx                    # %edx<- vB
-    movl        offObject_clazz(%edx), %edx # %edx<- obj->clazz
-    jmp         .L${opcode}_resolved    # clazz resolved, continue
diff --git a/vm/mterp/x86-atom/OP_INT_TO_BYTE.S b/vm/mterp/x86-atom/OP_INT_TO_BYTE.S
deleted file mode 100644
index 27cafe9..0000000
--- a/vm/mterp/x86-atom/OP_INT_TO_BYTE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_BYTE.S
-    */
-
-%include "x86-atom/unop.S" { "preinstr":"sal $24, %ecx", "instr":"sar $24, %ecx" }
diff --git a/vm/mterp/x86-atom/OP_INT_TO_CHAR.S b/vm/mterp/x86-atom/OP_INT_TO_CHAR.S
deleted file mode 100644
index a28602d..0000000
--- a/vm/mterp/x86-atom/OP_INT_TO_CHAR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_CHAR.S
-    */
-
-%include "x86-atom/unop.S" {"preinstr":"sal $16, %ecx", "instr":"shr $16, %ecx" }
diff --git a/vm/mterp/x86-atom/OP_INT_TO_DOUBLE.S b/vm/mterp/x86-atom/OP_INT_TO_DOUBLE.S
deleted file mode 100644
index cd16eea..0000000
--- a/vm/mterp/x86-atom/OP_INT_TO_DOUBLE.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_DOUBLE.S
-    *
-    * Code: Convert an int to a double. Uses no substitutions.
-    *
-    * For: int-to-double
-    *
-    * Description: Converts an int in the source register, to a double, and
-    *              stores the result in the destination register. vA<- (double) vB
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %eax             # %eax<- BA+
-    shr         $$4, %eax               # %eax<- B
-    andl        $$15, rINST             # rINST<- A
-    cvtsi2sd    (rFP, %eax, 4), %xmm0   # %xmm0<- vB
-    movq        %xmm0, (rFP, rINST, 4)  # vA<- %xmm0; (double) vB
-    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_INT_TO_FLOAT.S b/vm/mterp/x86-atom/OP_INT_TO_FLOAT.S
deleted file mode 100644
index 52ce729..0000000
--- a/vm/mterp/x86-atom/OP_INT_TO_FLOAT.S
+++ /dev/null
@@ -1,36 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_FLOAT.S
-    *
-    * Code: Convert an int to a float. Uses no substitutions.
-    *
-    * For: int-to-float
-    *
-    * Description: Convert an int in the source register, to a float, and
-    *              stores the result in the destintation register. vA<- (float) vB
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %eax             # %eax<- BA+
-    shr         $$4, %eax               # %eax<- B
-    andl        $$15,  rINST            # rINST<- A
-    cvtsi2ss    (rFP,%eax,4), %xmm0     # %xmm0<- vB
-    movss       %xmm0, (rFP, rINST, 4)  # vA<- %xmm0
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_INT_TO_LONG.S b/vm/mterp/x86-atom/OP_INT_TO_LONG.S
deleted file mode 100644
index 1bc125b..0000000
--- a/vm/mterp/x86-atom/OP_INT_TO_LONG.S
+++ /dev/null
@@ -1,40 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_LONG.S
-    *
-    * Code:  Convert an int to a long. Uses no substitutions.
-    *
-    * For:
-    *
-    * Description: Convert an int in the source register, to a long, and
-    *              stores the result in the destintation register. vA<- (long) vB
-    *
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %eax             # %eax<- BA+
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $$4, %eax               # %eax<- B
-    andl        $$15, %ecx              # %ecx<- A
-    GET_VREG    %eax                    # %eax<- vB
-    cdq                                 # %edx:%eax<- sign-extend of %eax
-    movl        %eax, (rFP, %ecx, 4)    # vA<- lo part
-    movl        %edx, 4(rFP, %ecx, 4)   # vA+1<- hi part
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_INT_TO_SHORT.S b/vm/mterp/x86-atom/OP_INT_TO_SHORT.S
deleted file mode 100644
index f2b0b87..0000000
--- a/vm/mterp/x86-atom/OP_INT_TO_SHORT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INT_TO_SHORT.S
-    */
-
-%include "x86-atom/unop.S" { "preinstr":"sal $16, %ecx", "instr":"sar $16, %ecx" }
diff --git a/vm/mterp/x86-atom/OP_INVOKE_DIRECT.S b/vm/mterp/x86-atom/OP_INVOKE_DIRECT.S
deleted file mode 100644
index 78b6c06..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_DIRECT.S
+++ /dev/null
@@ -1,92 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_DIRECT.S
-    *
-    * Code: Call a non-static direct method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_direct that allows up to 255 arguments.
-    *
-    * For: invoke-direct, invoke-direct/range
-    *
-    * Description: invoke-direct is used to invoke a non-static direct method;
-    *              an instance method that is non-overridable, for example,
-    *              either a private instance method or a constructor.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-%default { "isrange":"0", "routine":"NoRange" }
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- method index
-    movl        offDvmDex_pResMethods(%ecx), %ecx # %ecx<- pDvmDex->pResMethods
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved method to call
-    .if         (!$isrange)
-    andl        $$15, %edx              # %edx<- D if not range
-    .endif
-    EXPORT_PC                           # must export for invoke
-    movl        %edx, -4(%esp)          # save "this" pointer register
-    cmp         $$0, %ecx               # check if already resolved
-    GET_VREG    %edx                    # %edx<- "this" pointer
-    je          .L${opcode}_resolve     # handle resolve
-
-.L${opcode}_finish:
-    cmp         $$0, %edx               # check for null "this"
-    jne         common_invokeMethod${routine} # invoke method common code
-    jmp         common_errNullObject
-%break
-
-   /*
-    * %eax = reference (BBBB or CCCC)
-    * -4(%esp) = "this" register
-    */
-
-.L${opcode}_resolve:
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        $$METHOD_DIRECT, -8(%esp) # push parameter method type
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        %eax, -12(%esp)         # push parameter reference
-    lea         -16(%esp), %esp
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, (%esp)            # push parameter clazz
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         16(%esp), %esp
-    cmp         $$0, %eax               # check for null method return
-    movl        -4(%esp), %edx          # get "this" pointer register
-    GET_VREG    %edx                    # get "this" pointer
-    je          common_exceptionThrown  # null pointer; handle exception
-    cmp         $$0, %edx               # check for null "this"
-    movl        %eax, %ecx              # %ecx<- method
-    jne         common_invokeMethod${routine} # invoke method common code
-    jmp         common_errNullObject    # handle null object
diff --git a/vm/mterp/x86-atom/OP_INVOKE_DIRECT_RANGE.S b/vm/mterp/x86-atom/OP_INVOKE_DIRECT_RANGE.S
deleted file mode 100644
index 3ad26e1..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_DIRECT_RANGE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_DIRECT_RANGE.S
-    */
-
-%include "x86-atom/OP_INVOKE_DIRECT.S" { "isrange":"1", "routine":"Range" }
diff --git a/vm/mterp/x86-atom/OP_INVOKE_INTERFACE.S b/vm/mterp/x86-atom/OP_INVOKE_INTERFACE.S
deleted file mode 100644
index cbd7b31..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_INTERFACE.S
+++ /dev/null
@@ -1,76 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_INTERFACE.S
-    *
-    * Code: Call at method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_interface that allows up to 255 arguments.
-    *
-    * For: invoke-interface, invoke-interface-range
-    *
-    * Description: invoke-interface is used to invoke an interface method; on an
-    *              object whose concrete class isn't known, using a method_id that
-    *              refers to an interface.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-%default { "isrange":"0", "routine":"NoRange" }
-
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    FETCH       1, %ecx                 # %ecx<- method index
-    movl        %ecx, -12(%esp)         # push argument method index
-    .if         (!$isrange)
-    and         $$15, %edx              # %edx<- D if not range
-    .endif
-    EXPORT_PC                           # must export for invoke
-    GET_VREG    %edx                    # %edx<- first arg "this pointer"
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_methodClassDex(%eax), %eax # %eax<- glue->pDvmDex
-    movl        %eax, -4(%esp)          # push parameter class
-    cmp         $$0, %edx               # check for null object
-    je          common_errNullObject    # handle null object
-    jmp         .L${opcode}_break
-%break
-.L${opcode}_break:
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_method(%ecx), %ecx # %ecx<- glue->method
-    movl        %ecx, -8(%esp)          # push parameter method
-    movl        offObject_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, -16(%esp)         # push parameter
-    lea         -16(%esp), %esp
-    call        dvmFindInterfaceMethodInCache # call: (ClassObject* thisClass, u4 methodIdx,
-                                              #       const Method* method, DvmDex* methodClassDex)
-                                              # return: Method*
-    lea         16(%esp), %esp
-    cmp         $$0, %eax               # check if find failed
-    je          common_exceptionThrown  # handle exception
-    movl        %eax, %ecx              # %ecx<- method
-    jmp         common_invokeMethod${routine} # invoke method common code
diff --git a/vm/mterp/x86-atom/OP_INVOKE_INTERFACE_RANGE.S b/vm/mterp/x86-atom/OP_INVOKE_INTERFACE_RANGE.S
deleted file mode 100644
index b323ba0..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_INTERFACE_RANGE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_INTERFACE_RANGE.S
-    */
-
-%include "x86-atom/OP_INVOKE_INTERFACE.S" { "isrange":"1", "routine":"Range" }
diff --git a/vm/mterp/x86-atom/OP_INVOKE_OBJECT_INIT_RANGE.S b/vm/mterp/x86-atom/OP_INVOKE_OBJECT_INIT_RANGE.S
deleted file mode 100644
index 2459a3c..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_OBJECT_INIT_RANGE.S
+++ /dev/null
@@ -1,29 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_OBJECT_INIT.S
-    *
-    * Code: TODO
-    *
-    * For: invoke-object-init
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    */
-
-<<<<<<< HEAD:vm/mterp/x86-atom/OP_INVOKE_OBJECT_INIT_RANGE.S
-=======
-    FINISH 3
->>>>>>> 10185db0:vm/mterp/x86-atom/OP_INVOKE_DIRECT_EMPTY.S
diff --git a/vm/mterp/x86-atom/OP_INVOKE_STATIC.S b/vm/mterp/x86-atom/OP_INVOKE_STATIC.S
deleted file mode 100644
index 30b6d8c..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_STATIC.S
+++ /dev/null
@@ -1,70 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_STATIC.S
-    *
-    * Code: Call static direct method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_static that allows up to 255 arguments.
-    *
-    * For: invoke-static, invoke-static/range
-    *
-    * Description: invoke-static is used to invoke static direct method.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-%default { "routine":"NoRange" }
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %edx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- method index
-    movl        offDvmDex_pResMethods(%ecx), %ecx # %edx<- pDvmDex->pResMethods
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved method to call
-    cmp         $$0, %ecx               # check if already resolved
-    EXPORT_PC                           # must export for invoke
-    jne         common_invokeMethod${routine} # invoke method common code
-    jmp         .L${opcode}_break
-%break
-
-.L${opcode}_break:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    movl        $$METHOD_STATIC, -4(%esp) # resolver method type
-    movl        %eax, -8(%esp)          # push parameter method index
-    movl        offMethod_clazz(%edx), %edx # %edx<- glue->method->clazz
-    movl        %edx, -12(%esp)         # push parameter method
-    lea         -12(%esp), %esp
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         12(%esp), %esp
-    cmp         $$0, %eax               # check for null method
-    je          common_exceptionThrown
-    movl        %eax, %ecx              # %ecx<- method
-    jmp         common_invokeMethod${routine} # invoke method common code
diff --git a/vm/mterp/x86-atom/OP_INVOKE_STATIC_RANGE.S b/vm/mterp/x86-atom/OP_INVOKE_STATIC_RANGE.S
deleted file mode 100644
index ce39e13..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_STATIC_RANGE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_STATIC_RANGE.S
-    */
-
-%include "x86-atom/OP_INVOKE_STATIC.S" { "routine":"Range" }
diff --git a/vm/mterp/x86-atom/OP_INVOKE_SUPER.S b/vm/mterp/x86-atom/OP_INVOKE_SUPER.S
deleted file mode 100644
index 539bea1..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_SUPER.S
+++ /dev/null
@@ -1,105 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_SUPER.S
-    *
-    * Code: Call super method.
-    *
-    * For: invoke-super, invoke-super/range
-    *
-    * Description: invoke-super is used to invoke the closest superclass's virtual
-    *              method (as opposed to the one with the same method_id in the
-    *              calling class).
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-%default { "isrange":"0", "routine":"NoRange" }
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    FETCH       2, %eax                 # %eax<- GFED or CCCC
-    movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex
-    .if         (!$isrange)
-    and         $$15, %eax              # %eax<- D if not range
-    .endif
-    FETCH       1, %edx                 # %edx<- method index
-    movl        offDvmDex_pResMethods(%ecx), %ecx # %ecx<- pDvmDex->pResMethods
-    cmp         $$0, (rFP, %eax, 4)     # check for null object
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved base method
-    je          common_errNullObject    # handle null object
-    jmp         .L${opcode}_continue2
-%break
-
-.L${opcode}_continue2:
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_method(%eax), %eax # %eax<- glue->method
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    EXPORT_PC                           # must export for invoke
-    cmp         $$0, %ecx               # check if already resolved
-    jne         .L${opcode}_continue
-    jmp         .L${opcode}_resolve     # handle resolve
-
-   /*
-    *  %ecx = resolved base method
-    *  %eax = method->clazz
-    */
-
-.L${opcode}_continue:
-    movl        offClassObject_super(%eax), %edx # %edx<- glue->method->clazz->super
-    movzwl      offMethod_methodIndex(%ecx), %ecx # %ecx<-  baseMethod->methodIndex
-    cmp          offClassObject_vtableCount(%edx), %ecx # compare vtableCount with methodIndex
-    EXPORT_PC                           # must export for invoke
-    jnc         .L${opcode}_nsm         # handle method not present
-    movl        offClassObject_vtable(%edx), %edx # %edx<- glue->method->clazz->super->vtable
-    movl        (%edx, %ecx, 4), %ecx   # %ecx<- vtable[methodIndex]
-    jmp         common_invokeMethod${routine} # invoke method common code
-
-.L${opcode}_resolve:
-    movl        %eax, -12(%esp)         # push parameter clazz
-    movl        %edx, -8(%esp)          # push parameter method index
-    movl        $$METHOD_VIRTUAL, -4(%esp) # push parameter method type
-    lea         -12(%esp), %esp
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         12(%esp), %esp
-    movl        %eax, %ecx              # %ecx<- method
-    cmp         $$0, %ecx               # check for null method return
-    movl        -12(%esp), %eax         # %eax<- glue->method->clazz
-    jne         .L${opcode}_continue
-    jmp         common_exceptionThrown  # null pointer; handle exception
-
-   /*
-    * Throw a NoSuchMethodError with the method name as the message.
-    * %ecx = resolved base method
-    */
-
-.L${opcode}_nsm:
-    movl        offMethod_name(%ecx), %edx # %edx<- method name
-    jmp         common_errNoSuchMethod
diff --git a/vm/mterp/x86-atom/OP_INVOKE_SUPER_QUICK.S b/vm/mterp/x86-atom/OP_INVOKE_SUPER_QUICK.S
deleted file mode 100644
index 55c7e94..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_SUPER_QUICK.S
+++ /dev/null
@@ -1,40 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_SUPER_QUICK.S
-    *
-    * Code: Optimization for invoke-super and invoke-super/range
-    *
-    * For: invoke-super/quick, invoke-super/quick-range
-    */
-
-%default { "isrange":"0", "routine":"NoRange" }
-
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_method(%ecx), %eax # %eax<- glue->method
-    .if         (!$isrange)
-    and         $$15, %edx              #  %edx<- D if not range
-    .endif
-    FETCH       1, %ecx                 # %ecx<- method index
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    movl        offClassObject_super(%eax), %eax # %eax<- glue->method->clazz->super
-    EXPORT_PC                           # must export for invoke
-    movl        offClassObject_vtable(%eax), %eax # %edx<- glue->method->clazz->super->vtable
-    cmp         $$0, (rFP, %edx, 4)     # check for null object
-    movl        (%eax, %ecx, 4), %ecx   # %ecx<- vtable[methodIndex]
-    je          common_errNullObject    # handle null object
-    jmp         common_invokeMethod${routine} # invoke method common code
diff --git a/vm/mterp/x86-atom/OP_INVOKE_SUPER_QUICK_RANGE.S b/vm/mterp/x86-atom/OP_INVOKE_SUPER_QUICK_RANGE.S
deleted file mode 100644
index 9e9f311..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_SUPER_QUICK_RANGE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_SUPER_QUICK_RANGE.S
-    */
-
-%include "x86-atom/OP_INVOKE_SUPER_QUICK.S" { "isrange":"1", "routine":"Range" }
diff --git a/vm/mterp/x86-atom/OP_INVOKE_SUPER_RANGE.S b/vm/mterp/x86-atom/OP_INVOKE_SUPER_RANGE.S
deleted file mode 100644
index 6e77c02..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_SUPER_RANGE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_SUPER_RANGE.S
-    */
-
-%include "x86-atom/OP_INVOKE_SUPER.S" { "isrange":"1", "routine":"Range" }
diff --git a/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL.S b/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL.S
deleted file mode 100644
index 46c9265..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL.S
+++ /dev/null
@@ -1,93 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_VIRTUAL.S
-    *
-    * Code: Call a virtual method. Provides an "isrange" variable and
-    *       a "routine" variable to specify this is the "range" version of
-    *       invoke_direct that allows up to 255 arguments.
-    *
-    * For: invoke-virtual, invoke-virtual/range
-    *
-    * Description: invoke-virtual is used to invoke a normal virtual method;
-    *              a method that is not static or final, and is not a constructor.
-    *
-    * Format: B|A|op CCCC G|F|E|D (35c)
-    *         AA|op BBBB CCCC (3rc)
-    *
-    * Syntax: [B=5] op {vD, vE, vF, vG, vA}, meth@CCCC (35c)
-    *         [B=5] op {vD, vE, vF, vG, vA}, type@CCCC (35c)
-    *         [B=4] op {vD, vE, vF, vG}, kind@CCCC (35c)
-    *         [B=3] op {vD, vE, vF}, kind@CCCC (35c)
-    *         [B=2] op {vD, vE}, kind@CCCC (35c)
-    *         [B=1] op {vD}, kind@CCCC (35c)
-    *         [B=0] op {}, kind@CCCC (35c)
-    *
-    *         op {vCCCC .. vNNNN}, meth@BBBB (3rc) (where NNNN = CCCC+AA-1, that
-    *         op {vCCCC .. vNNNN}, type@BBBB (3rc) is A determines the count 0..255,
-    *                                              and C determines the first register)
-    */
-
-%default { "isrange":"0", "routine":"NoRange" }
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    EXPORT_PC                           # must export pc for invoke
-    movl        offGlue_methodClassDex(%eax), %eax # %eax<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- method index
-    movl        offDvmDex_pResMethods(%eax), %eax # %eax<- pDvmDex->pResMethods
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    .if         (!$isrange)
-    and         $$15, %edx              # %edx<- D if not range
-    .endif
-    cmp         $$0, (%eax, %ecx, 4)    # check if already resolved
-    je          .L${opcode}_break
-    movl        (%eax, %ecx, 4), %eax   # %eax<- resolved base method
-    jmp         .L${opcode}_continue
-%break
-
-.L${opcode}_break:
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        %edx, -4(%esp)          # save "this" pointer register
-    movl        offGlue_method(%eax), %eax # %eax<- glue->method
-    movl        $$METHOD_VIRTUAL, -8(%esp) # push parameter method type
-    movl        %ecx, -12(%esp)         # push paramter method index
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    lea         -16(%esp), %esp
-    movl        %eax, (%esp)            # push parameter clazz
-    call        dvmResolveMethod        # call: (const ClassObject* referrer,
-                                        #       u4 methodIdx, MethodType methodType)
-                                        # return: Method*
-    lea         16(%esp), %esp
-    cmp         $$0, %eax               # check for null method return
-    movl        -4(%esp), %edx          # get "this" pointer register
-    jne         .L${opcode}_continue
-    jmp         common_exceptionThrown  # null pointer; handle exception
-
-   /*
-    * At this point:
-    *  %eax = resolved base method
-    *  %edx = D or CCCC (index of first arg, which is the "this" ptr)
-    */
-
-.L${opcode}_continue:
-    GET_VREG    %edx                    # %edx<- "this" ptr
-    movzwl      offMethod_methodIndex(%eax), %eax # %eax<- baseMethod->methodIndex
-    cmp         $$0, %edx               # %edx<- check for null "this"
-    je          common_errNullObject    # handle null object
-    movl        offObject_clazz(%edx), %edx # %edx<- thisPtr->clazz
-    movl        offClassObject_vtable(%edx), %edx # %edx<- thisPtr->clazz->vtable
-    movl        (%edx, %eax, 4), %ecx   # %ecx<- vtable[methodIndex]
-    jmp         common_invokeMethod${routine} # invoke method common code
diff --git a/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL_QUICK.S b/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL_QUICK.S
deleted file mode 100644
index 16a4e40..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL_QUICK.S
+++ /dev/null
@@ -1,38 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_VIRTUAL_QUICK.S
-    *
-    * Code: Optimization for invoke-virtual and invoke-virtual/range
-    *
-    * For: invoke-virtual/quick, invoke-virtual/quick-range
-    */
-
-%default { "isrange":"0", "routine":"NoRange" }
-
-    FETCH       2, %edx                 # %edx<- GFED or CCCC
-    .if (!$isrange)
-    and         $$15, %edx              # %edx<- D if not range
-    .endif
-    FETCH       1, %ecx                 # %ecx<- method index
-    GET_VREG    %edx                    # %edx<- "this" ptr
-    cmp         $$0, %edx               # %edx<- check for null "this"
-    EXPORT_PC                           # must export pc for invoke
-    je          common_errNullObject
-    movl        offObject_clazz(%edx), %edx # %edx<- thisPtr->clazz
-    movl        offClassObject_vtable(%edx), %edx # %edx<- thisPtr->clazz->vtable
-    movl        (%edx, %ecx, 4), %ecx   # %ecx<- vtable[methodIndex]
-    jmp         common_invokeMethod${routine} # invoke method common code
diff --git a/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL_QUICK_RANGE.S b/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL_QUICK_RANGE.S
deleted file mode 100644
index 888bcc0..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL_QUICK_RANGE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_VIRTUAL_QUICK_RANGE.S
-    */
-
-%include "x86-atom/OP_INVOKE_VIRTUAL_QUICK.S" { "isrange":"1", "routine":"Range" }
diff --git a/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL_RANGE.S b/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL_RANGE.S
deleted file mode 100644
index d548a22..0000000
--- a/vm/mterp/x86-atom/OP_INVOKE_VIRTUAL_RANGE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_INVOKE_VIRTUAL_RANGE.S
-    */
-
-%include "x86-atom/OP_INVOKE_VIRTUAL.S" { "isrange":"1", "routine":"Range" }
diff --git a/vm/mterp/x86-atom/OP_IPUT.S b/vm/mterp/x86-atom/OP_IPUT.S
deleted file mode 100644
index 4c029be..0000000
--- a/vm/mterp/x86-atom/OP_IPUT.S
+++ /dev/null
@@ -1,76 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-    /*
-    * File: OP_IPUT.S
-    *
-    * Code: Generic 32-bit instance field "put" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iput's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iput-boolean, iput-byte, iput-char, iput-object, iput
-    *      iput-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-%default { "mov":"l" }
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $$0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .L${opcode}_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    jmp         .L${opcode}_finish
-%break
-
-.L${opcode}_finish:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    lea         -8(%esp), %esp
-    movl        %edx, (%esp)            # push parameter method->clazz
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    lea         8(%esp), %esp
-    cmp         $$0, %eax               # check if resolved
-    jne         .L${opcode}_finish2
-    jmp         common_exceptionThrown  # not resolved; handle exception
-
-.L${opcode}_finish2:
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $$4, %ecx               # %ecx<- B
-    and         $$15, rINST             # rINST<- A
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $$0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vA
-    mov$mov     rINST, (%edx, %ecx)     # object field<- vA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_IPUT_BOOLEAN.S b/vm/mterp/x86-atom/OP_IPUT_BOOLEAN.S
deleted file mode 100644
index 46c2932..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_BOOLEAN.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_BOOLEAN.S
-    */
-
-%include "x86-atom/OP_IPUT.S"
diff --git a/vm/mterp/x86-atom/OP_IPUT_BYTE.S b/vm/mterp/x86-atom/OP_IPUT_BYTE.S
deleted file mode 100644
index d23f492..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_BYTE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_BYTE.S
-    */
-
-%include "x86-atom/OP_IPUT.S"
diff --git a/vm/mterp/x86-atom/OP_IPUT_CHAR.S b/vm/mterp/x86-atom/OP_IPUT_CHAR.S
deleted file mode 100644
index d645fae..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_CHAR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_CHAR.S
-    */
-
-%include "x86-atom/OP_IPUT.S"
diff --git a/vm/mterp/x86-atom/OP_IPUT_OBJECT.S b/vm/mterp/x86-atom/OP_IPUT_OBJECT.S
deleted file mode 100644
index 302cf44..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_OBJECT.S
+++ /dev/null
@@ -1,81 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-    /*
-    * File: OP_IPUT.S
-    *
-    * Code: Generic 32-bit instance field "put" operation. Provides a
-    *       "mov" variable which determines the type of mov performed.
-    *       Currently, none of the iput's use this variable - may want
-    *       to change this, but seems ok for now.
-    *
-    * For: iput-boolean, iput-byte, iput-char, iput-object, iput
-    *      iput-short
-    *
-    * Description: Perform the object instance field "get" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
-    cmp         $$0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
-    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
-    jne         .L${opcode}_finish2
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    jmp         .L${opcode}_finish
-%break
-
-.L${opcode}_finish:
-    movl        offGlue_method(%edx), %edx # %edx<- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    lea         -8(%esp), %esp
-    movl        %edx, (%esp)            # push parameter method->clazz
-    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: InstField*
-    lea         8(%esp), %esp
-    cmp         $$0, %eax               # check if resolved
-    jne         .L${opcode}_finish2
-    jmp         common_exceptionThrown  # not resolved; handle exception
-
-.L${opcode}_finish2:
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $$4, %ecx               # %ecx<- B
-    and         $$15, rINST             # rINST<- A
-    GET_VREG    %ecx                    # %ecx<- vB
-    cmp         $$0, %ecx               # check for null object
-    je          common_errNullObject    # handle null object
-    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    GET_VREG    rINST                   # rINST<- vA
-    movl        rINST, (%edx, %ecx)     # object field<- vA
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl     rGLUE, %eax             # get glue
-    movl        offGlue_cardTable(%eax), %eax # get card table base
-    testl       rINST, rINST            # test if we stored a null value
-    je          1f                     # skip card mark if null stored
-    shrl        $$GC_CARD_SHIFT, %ecx   # set obeject head to card number
-    movb        %al, (%eax, %ecx)
-1:
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_IPUT_OBJECT_QUICK.S b/vm/mterp/x86-atom/OP_IPUT_OBJECT_QUICK.S
deleted file mode 100644
index eee88e9..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_OBJECT_QUICK.S
+++ /dev/null
@@ -1,44 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_QUICK.S
-    * Code: Optimization for iput
-    *
-    * For: iput-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $$4, %eax               # %eax<- B
-    and         $$15, rINST             # rINST<- A
-    GET_VREG    %eax                    # %eax<- vB; object to operate on
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    cmp         $$0, %eax               # check if object is null
-    je          common_errNullObject    # handle null object
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vA
-    movl        rINST, (%eax, %ecx)     # object field<- vA
-    testl       rINST, rINST            # did we write a null object
-    je          1f
-    movl        rGLUE, %ecx             # get glue
-    movl        offGlue_cardTable(%ecx), %ecx # get card table base
-    shrl        $$GC_CARD_SHIFT, %eax   # get gc card index
-    movb        %cl, (%eax, %ecx)       # mark gc card in table
-1:
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_IPUT_OBJECT_VOLATILE.S b/vm/mterp/x86-atom/OP_IPUT_OBJECT_VOLATILE.S
deleted file mode 100644
index 4b024d0..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_OBJECT_VOLATILE.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "x86/OP_IPUT_OBJECT.S"
diff --git a/vm/mterp/x86-atom/OP_IPUT_QUICK.S b/vm/mterp/x86-atom/OP_IPUT_QUICK.S
deleted file mode 100644
index 572291e..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_QUICK.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_QUICK.S
-    * Code: Optimization for iput
-    *
-    * For: iput-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $$4, %eax               # %eax<- B
-    and         $$15, rINST             # rINST<- A
-    GET_VREG    %eax                    # %eax<- vB; object to operate on
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    cmp         $$0, %eax               # check if object is null
-    je          common_errNullObject    # handle null object
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vA
-    movl        rINST, (%eax, %ecx)     # object field<- vA
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_IPUT_SHORT.S b/vm/mterp/x86-atom/OP_IPUT_SHORT.S
deleted file mode 100644
index 9836283..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_SHORT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_SHORT.S
-    */
-
-%include "x86-atom/OP_IPUT.S"
diff --git a/vm/mterp/x86-atom/OP_IPUT_VOLATILE.S b/vm/mterp/x86-atom/OP_IPUT_VOLATILE.S
deleted file mode 100644
index 475a0c5..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_VOLATILE.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "x86/OP_IPUT.S"
diff --git a/vm/mterp/x86-atom/OP_IPUT_WIDE.S b/vm/mterp/x86-atom/OP_IPUT_WIDE.S
deleted file mode 100644
index 1686219..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_WIDE.S
+++ /dev/null
@@ -1,74 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_WIDE.S
-    *
-    * Code: 64 bit instance field "put" operation. Uses no substitutions.
-    *
-    * For: iget-wide
-    *
-    * Description: Perform the object instance field "put" operation
-    *              with the identified field; load the instance value into
-    *              the value register.
-    *
-    * Format:  B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-    movl        rGLUE, %eax             # %eax<- MterpGlue pointer
-    movl        offGlue_methodClassDex(%eax), %ecx # %ecx<- pDvmDex
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- CCCC
-    FETCH       1, %edx                 # %edx<- pDvmDex->pResFields
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved InstField ptr
-    cmp         $$0, %ecx               # check for null ptr; resolved InstField ptr
-    jne         .L${opcode}_finish
-    movl        offGlue_method(%eax), %ecx # %ecx <- current method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        offMethod_clazz(%ecx), %ecx # %ecx<- method->clazz
-    movl        %ecx, -8(%esp)          # push parameter CCCC; field ref
-    movl        %edx, -4(%esp)          # push parameter method->clazz
-    jmp         .L${opcode}_finish2
-%break
-
-.L${opcode}_finish2:
-    lea         -8(%esp), %esp
-    call        dvmResolveInstField     # resolve InstField ptr
-    cmp         $$0, %eax               # check if resolved
-    lea         8(%esp), %esp
-    movl        %eax, %ecx              # %ecx<- %eax; %ecx expected to hold field
-    jne         .L${opcode}_finish
-    jmp         common_exceptionThrown
-
-   /*
-    * Currently:
-    *  %ecx holds resolved field
-    *  %edx does not hold object yet
-    */
-
-.L${opcode}_finish:
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    andl        $$15, rINST             # rINST<- A
-    GET_VREG    %edx                    # %edx<- vB
-    cmp         $$0, %edx               # check for null object
-    je          common_errNullObject
-    movl        offInstField_byteOffset(%ecx), %ecx # %ecx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vA
-    movq        %xmm0, (%ecx, %edx)     # object field<- %xmm0; vA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_IPUT_WIDE_QUICK.S b/vm/mterp/x86-atom/OP_IPUT_WIDE_QUICK.S
deleted file mode 100644
index 5880231..0000000
--- a/vm/mterp/x86-atom/OP_IPUT_WIDE_QUICK.S
+++ /dev/null
@@ -1,38 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_IPUT_WIDE_QUICK.S
-    *
-    * Code: Optimization for iput
-    *
-    * For: iput/wide-quick
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, offset@CCCC
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    andl        $$15, rINST             # rINST<- A
-    GET_VREG    %edx                    # %edx<- vB; object to operate on
-    cmp         $$0, %edx               # check if object is null
-    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
-    je          common_errNullObject    # handle null object
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- fp[A]
-    movq        %xmm0, (%edx, %ecx)     # object field<- %xmm0; fp[A]
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_LONG_TO_DOUBLE.S b/vm/mterp/x86-atom/OP_LONG_TO_DOUBLE.S
deleted file mode 100644
index 5705e25..0000000
--- a/vm/mterp/x86-atom/OP_LONG_TO_DOUBLE.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_LONG_TO_DOUBLE.S
-    *
-    * Code: Convert a long to a dobule. Uses no substitutions.
-    *
-    * For: long-to-double
-    *
-    * Description: Converts a long in the source register to a double, and
-    *              stores the result in the destination register. vA<- (double) vB
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $$4, rINST              # rINST<- B
-    and         $$15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    fildll      (rFP, rINST, 4)         # FPU<- vB
-    fstpl       (rFP, %ecx, 4)          # vA<- FPU; (double) vB
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_LONG_TO_FLOAT.S b/vm/mterp/x86-atom/OP_LONG_TO_FLOAT.S
deleted file mode 100644
index 1bb8779..0000000
--- a/vm/mterp/x86-atom/OP_LONG_TO_FLOAT.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_LONG_TO_FLOAT.S
-    *
-    * Code: Convert a long to a float. Uses no substitutions.
-    *
-    * For: int-to-float
-    *
-    * Description: Converts a float in the source register, to a float, and
-    *              stores the result in the destination register. vA<- (double) vB
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $$4, rINST              # rINST<- B
-    and         $$15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    fildll      (rFP, rINST, 4)         # FPU<- vB
-    fstps       (rFP, %ecx, 4)          # vA<- FPU; (float) vB
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_LONG_TO_INT.S b/vm/mterp/x86-atom/OP_LONG_TO_INT.S
deleted file mode 100644
index 0984bc0..0000000
--- a/vm/mterp/x86-atom/OP_LONG_TO_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_LONG_TO_INT.S
-    */
-
-%include "x86-atom/OP_MOVE.S"
diff --git a/vm/mterp/x86-atom/OP_MONITOR_ENTER.S b/vm/mterp/x86-atom/OP_MONITOR_ENTER.S
deleted file mode 100644
index 39d0e7b..0000000
--- a/vm/mterp/x86-atom/OP_MONITOR_ENTER.S
+++ /dev/null
@@ -1,49 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MONITOR_ENTER.S
-    *
-    * Code: Aquire a monitor
-    *
-    * For: monitor-enter
-    *
-    * Description: Aquire a monitor for the indicated object.
-    *
-    *
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    GET_VREG    rINST                   # rINST<- vAA
-    cmp         $$0, rINST              # check for null object
-    movl        offGlue_self(%eax), %eax # %eax<- glue->self
-    EXPORT_PC   # need for precise GC
-    je          common_errNullObject    # handle null object
-#    jmp         .L${opcode}_finish
-#%break
-#.L${opcode}_finish:
-    movl        rINST, -4(%esp)         # push parameter reference
-    movl        %eax, -8(%esp)          # push parameter
-    lea         -8(%esp), %esp
-    call        dvmLockObject           # call: (struct Thread* self,
-                                        #       struct Object* obj)
-                                        # return: void
-    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
-    lea         8(%esp), %esp
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MONITOR_EXIT.S b/vm/mterp/x86-atom/OP_MONITOR_EXIT.S
deleted file mode 100644
index 37738d5..0000000
--- a/vm/mterp/x86-atom/OP_MONITOR_EXIT.S
+++ /dev/null
@@ -1,46 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MONITOR_EXIT.S
-    *
-    * Code: Release a monitor
-    *
-    * For: monitor-exit
-    *
-    * Description: Release a monitor for the indicated object. If this instruction needs
-    *              to throw an execption, it must do so as if the pc has already
-    *              advanced pased the instruction.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    EXPORT_PC                           # export the pc
-    GET_VREG    rINST                   # rINST<- vAA
-    cmp         $$0, rINST              # rINST<- check for null object
-    je          common_errNullObject    # handle null object
-    push        rINST                   # push parameter object
-    push        offGlue_self(%eax)      # push parameter self
-    call        dvmUnlockObject         # call: (struct Thread* self,
-                                        #       struct Object* obj)
-                                        # return: bool
-    FINISH_FETCH_ADVANCE 1, %edx        # advance pc before exception
-    cmp         $$0, %eax               # check for success
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # handle exception
-    FINISH_JMP  %edx                    # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_MOVE.S b/vm/mterp/x86-atom/OP_MOVE.S
deleted file mode 100644
index 9982ced..0000000
--- a/vm/mterp/x86-atom/OP_MOVE.S
+++ /dev/null
@@ -1,38 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE.S
-    *
-    * Code: Copies contents from one register to another. Uses no
-    *       substitutions.
-    *
-    * For: move, move-object, long-to-int
-    *
-    * Description: Copies contents from one non-object register to another.
-    *              vA<- vB; fp[A]<- fp[B]
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $$4, rINST              # rINST<- B
-    and         $$15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vB
-    SET_VREG    rINST, %ecx             # vA<- vB; %edx
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MOVE_16.S b/vm/mterp/x86-atom/OP_MOVE_16.S
deleted file mode 100644
index 013a11b..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_16.S
+++ /dev/null
@@ -1,36 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_16.S
-    *
-    * Code: Copies contents from one register to another
-    *
-    * For: move/16, move-object/16
-    *
-    * Description: Copies contents from one non-object register to another.
-    *              fp[A]<- fp[B]
-    *
-    * Format: ØØ|op AAAA BBBB (32x)
-    *
-    * Syntax: op vAAAA, vBBBB
-    */
-
-    FETCH       2, %edx                 # %edx<- BBBB
-    FETCH       1, %ecx                 # %ecx<- AAAA
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    SET_VREG    %edx, %ecx              # vA<- vB; %edx
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MOVE_EXCEPTION.S b/vm/mterp/x86-atom/OP_MOVE_EXCEPTION.S
deleted file mode 100644
index 76e700d..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_EXCEPTION.S
+++ /dev/null
@@ -1,38 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_EXCEPTION.S
-    *
-    * Code: Moves an exception to a register
-    *
-    * For: move-exception
-    *
-    * Description: Save a just-caught exception into the given register. This
-    *              instruction is only valid as the first instruction of an
-    *              exception handler.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_self(%eax), %ecx # %ecx<- glue->self
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    movl        offThread_exception(%ecx), %edx # %edx<- glue->self->exception
-    movl        $$0, offThread_exception(%ecx) # clear exception
-    SET_VREG    %edx, rINST             # vAA<- glue->self->exception
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MOVE_FROM16.S b/vm/mterp/x86-atom/OP_MOVE_FROM16.S
deleted file mode 100644
index 55a6e96..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_FROM16.S
+++ /dev/null
@@ -1,35 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_FROM16.S
-    *
-    * Code: Copies contents from one register to another
-    *
-    * For: move/from16, move-object/from16
-    *
-    * Description: Copies contents from one non-object register to another.
-    *              vA<- vB; fp[A]<- fp[B]
-    *
-    * Format: AA|op BBBB (22x)
-    *
-    * Syntax: op vAA, vBBBB
-    */
-
-    FETCH       1, %edx                 # %edx<- BBBB
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    SET_VREG    %edx, rINST             # vA<- vB; %edx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MOVE_OBJECT.S b/vm/mterp/x86-atom/OP_MOVE_OBJECT.S
deleted file mode 100644
index 1cd22cb..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_OBJECT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_OBJECT.S
-    */
-
-%include "x86-atom/OP_MOVE.S"
diff --git a/vm/mterp/x86-atom/OP_MOVE_OBJECT_16.S b/vm/mterp/x86-atom/OP_MOVE_OBJECT_16.S
deleted file mode 100644
index a61162c..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_OBJECT_16.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_OBJECT_16.S
-    */
-
-%include "x86-atom/OP_MOVE_16.S"
diff --git a/vm/mterp/x86-atom/OP_MOVE_OBJECT_FROM16.S b/vm/mterp/x86-atom/OP_MOVE_OBJECT_FROM16.S
deleted file mode 100644
index bfca7da..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_OBJECT_FROM16.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_OBJECT_FROM16.S
-    */
-
-%include "x86-atom/OP_MOVE_FROM16.S"
diff --git a/vm/mterp/x86-atom/OP_MOVE_RESULT.S b/vm/mterp/x86-atom/OP_MOVE_RESULT.S
deleted file mode 100644
index 1d13bf5..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_RESULT.S
+++ /dev/null
@@ -1,38 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_RESULT.S
-    *
-    * Code: Copies a return value to a register
-    *
-    * For: move-result, move-result-object
-    *
-    * Description: Move the single-word non-object result of the most
-    *              recent method invocation into the indicated register. This
-    *              must be done as the instruction immediately after a
-    *              method invocation whose (single-word, non-object) result
-    *              is not to be ignored; anywhere else is invalid.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    FFETCH_ADV  1, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    movl        offGlue_retval(%eax), %edx # %edx<- glue->retval
-    SET_VREG    %edx, rINST             # vA<- glue->retval
-    FGETOP_JMP  1, %ecx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MOVE_RESULT_OBJECT.S b/vm/mterp/x86-atom/OP_MOVE_RESULT_OBJECT.S
deleted file mode 100644
index 6d1fa75..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_RESULT_OBJECT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_RESULT_OBJECT.S
-    */
-
-%include "x86-atom/OP_MOVE_RESULT.S"
diff --git a/vm/mterp/x86-atom/OP_MOVE_RESULT_WIDE.S b/vm/mterp/x86-atom/OP_MOVE_RESULT_WIDE.S
deleted file mode 100644
index 8f15264..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_RESULT_WIDE.S
+++ /dev/null
@@ -1,38 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_RESULT_WIDE.S
-    *
-    * Code: Copies a return value to a register
-    *
-    * For: move-result-wide
-    *
-    * Description: Move the double-word non-object result of the most
-    *              recent method invocation into the indicated register. This
-    *              must be done as the instruction immediately after a
-    *              method invocation whose (single-word, non-object) result
-    *              is not to be ignored; anywhere else is invalid.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movq        offGlue_retval(%eax), %xmm0 # %xmm0<- glue->retval
-    movq        %xmm0, (rFP, rINST, 4)  # vA<- glue->retval
-    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MOVE_WIDE.S b/vm/mterp/x86-atom/OP_MOVE_WIDE.S
deleted file mode 100644
index 909243b..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_WIDE.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_WIDE.S
-    *
-    * Code: Copies contents from one register to another. Uses no
-    *       substitutions.
-    *
-    * For: move-wide
-    *
-    * Description: Copies contents from one non-object register to another.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA+
-    shr         $$4, %edx               # %edx<- B
-    and         $$15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vB
-    movq        %xmm0, (rFP, rINST, 4)  # vA<- vB
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MOVE_WIDE_16.S b/vm/mterp/x86-atom/OP_MOVE_WIDE_16.S
deleted file mode 100644
index af266fe..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_WIDE_16.S
+++ /dev/null
@@ -1,36 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_WIDE_16.S
-    *
-    * Code: Copies contents from one register to another. Uses no
-    *       substitutions.
-    *
-    * For: move-wide/16
-    *
-    * Description: Copies contents from one non-object register to another.
-    *
-    * Format: ØØ|op AAAA BBBB (32x)
-    *
-    * Syntax: op vAAAA, vBBBB
-    */
-
-    FETCH       2, %edx                 # %edx<- BBBB
-    FETCH       1, %ecx                 # %ecx<- AAAA
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vB
-    movq        %xmm0, (rFP, %ecx, 4)   # vA<- vB; %xmm0
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MOVE_WIDE_FROM16.S b/vm/mterp/x86-atom/OP_MOVE_WIDE_FROM16.S
deleted file mode 100644
index 4056b34..0000000
--- a/vm/mterp/x86-atom/OP_MOVE_WIDE_FROM16.S
+++ /dev/null
@@ -1,34 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MOVE_WIDE_FROM16.S
-    *
-    * Code: Copies contents from one register to another
-    *
-    * For: move-wide/from16
-    *
-    * Description: Copies contents from one non-object register to another.
-    *
-    * Format: AA|op BBBB (22x)
-    *
-    * Syntax: op vAA, vBBBB
-    */
-
-    FETCH       1, %edx                 # %edx<- BBBB
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vB
-    movq        %xmm0, (rFP, rINST, 4)  # vA<- vB
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MUL_DOUBLE.S b/vm/mterp/x86-atom/OP_MUL_DOUBLE.S
deleted file mode 100644
index cecbf05..0000000
--- a/vm/mterp/x86-atom/OP_MUL_DOUBLE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_DOUBLE.S
-    */
-
-%include "x86-atom/binopWide.S" {"instr":"mulsd   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_MUL_DOUBLE_2ADDR.S b/vm/mterp/x86-atom/OP_MUL_DOUBLE_2ADDR.S
deleted file mode 100644
index adc61d6..0000000
--- a/vm/mterp/x86-atom/OP_MUL_DOUBLE_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_DOUBLE_2ADDR.S
-    */
-
-%include "x86-atom/binopWide2addr.S" {"instr":"mulsd   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_MUL_FLOAT.S b/vm/mterp/x86-atom/OP_MUL_FLOAT.S
deleted file mode 100644
index 34eba58..0000000
--- a/vm/mterp/x86-atom/OP_MUL_FLOAT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_FLOAT.S
-    */
-
-%include "x86-atom/binopF.S" {"instr":"mulss %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_MUL_FLOAT_2ADDR.S b/vm/mterp/x86-atom/OP_MUL_FLOAT_2ADDR.S
deleted file mode 100644
index dbd615d..0000000
--- a/vm/mterp/x86-atom/OP_MUL_FLOAT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_FLOAT_2ADDR.S
-    */
-
-%include "x86-atom/binopF2addr.S" {"instr":"mulss %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_MUL_INT.S b/vm/mterp/x86-atom/OP_MUL_INT.S
deleted file mode 100644
index 8f5dac5..0000000
--- a/vm/mterp/x86-atom/OP_MUL_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_INT.S
-    */
-
-%include "x86-atom/binop.S" {"instr":"imul     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_MUL_INT_2ADDR.S b/vm/mterp/x86-atom/OP_MUL_INT_2ADDR.S
deleted file mode 100644
index b544df7..0000000
--- a/vm/mterp/x86-atom/OP_MUL_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_INT_2ADDR.S
-    */
-
-%include "x86-atom/binop2addr.S" {"instr":"imul     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_MUL_INT_LIT16.S b/vm/mterp/x86-atom/OP_MUL_INT_LIT16.S
deleted file mode 100644
index 241531f..0000000
--- a/vm/mterp/x86-atom/OP_MUL_INT_LIT16.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_INT_LIT16.S
-    */
-
-%include "x86-atom/binopLit16.S" {"instr":"imul     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_MUL_INT_LIT8.S b/vm/mterp/x86-atom/OP_MUL_INT_LIT8.S
deleted file mode 100644
index efcffe1..0000000
--- a/vm/mterp/x86-atom/OP_MUL_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_INT_LIT8.S
-    */
-
-%include "x86-atom/binopLit8.S" {"instr":"imul     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_MUL_LONG.S b/vm/mterp/x86-atom/OP_MUL_LONG.S
deleted file mode 100644
index 85cccf2..0000000
--- a/vm/mterp/x86-atom/OP_MUL_LONG.S
+++ /dev/null
@@ -1,71 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_LONG.S
-    *
-    * Code: 64-bit integer multiply
-    *
-    * For: mul-long
-    *
-    * Description: Multiply two source registers and store the
-    *              result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-   /*
-    * Signed 64-bit integer multiply.
-    *
-    * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
-    *        WX
-    *      x YZ
-    *  --------
-    *     ZW ZX
-    *  YW YX
-    *
-    * The low word of the result holds ZX, the high word holds
-    * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
-    * it doesn't fit in the low 64 bits.
-    */
-
-    movl        rINST, -4(%esp)         # -4(%esp)<- AA+
-    FETCH_BB    1, rINST                # rINST<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    jmp         .L${opcode}_finish
-%break
-
-   /*
-    * X = (rFP, rINST, 4)
-    * W = 4(rFP, rINST, 4)
-    * Z = (rFP, %edx, 4)
-    * Y = 4(rFP, %edx, 4)
-    */
-
-.L${opcode}_finish:
-    movl        4(rFP, rINST, 4), %ecx  # %ecx<- W
-    imull       (rFP, %edx, 4),  %ecx   # %ecx<- WxZ
-    mov         4(rFP, %edx, 4), %eax   # %ecx<- Y
-    imull       (rFP, rINST, 4), %eax   # %eax<- XxY
-    addl        %eax, %ecx              # %ecx<- (WZ + XY)
-    movl        (rFP, %edx, 4), %eax    # %eax<- Z
-    mull        (rFP, rINST, 4)         # %edx:eax<- XZ
-    movzbl      -4(%esp), rINST         # rINST<- AA
-    addl        %edx, %ecx              # %ecx<- carry + (WZ + XY)
-    movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- results hi
-    movl        %eax, (rFP, rINST, 4)   # vAA<- results lo
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_MUL_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_MUL_LONG_2ADDR.S
deleted file mode 100644
index d6b8c16..0000000
--- a/vm/mterp/x86-atom/OP_MUL_LONG_2ADDR.S
+++ /dev/null
@@ -1,72 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_MUL_LONG_2ADDR.S
-    *
-    * Code:  64-bit integer multiply
-    *
-    * For: mul-long/2addr
-    *
-    * Description: Multiply two sources registers and store the result
-    *              in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-   /*
-    * Signed 64-bit integer multiply.
-    *
-    * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
-    *        WX
-    *      x YZ
-    *  --------
-    *     ZW ZX
-    *  YW YX
-    *
-    * The low word of the result holds ZX, the high word holds
-    * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
-    * it doesn't fit in the low 64 bits.
-    */
-
-    movl        rINST, %edx             # %edx<- BA+
-    shr         $$4, rINST              # rINST<- B
-    andl        $$15, %edx              # %edx<- A
-    movl        %edx, sReg0             # sReg0<- A
-    jmp         .L${opcode}_finish
-%break
-
-   /*
-    * X = (rFP, rINST, 4)
-    * W = 4(rFP, rINST, 4)
-    * Z = (rFP, %edx, 4)
-    * Y = 4(rFP, %edx, 4)
-    */
-
-.L${opcode}_finish:
-    movl        4(rFP, rINST, 4), %ecx  # %ecx<- W
-    imull       (rFP, %edx, 4), %ecx    # %ecx<- WxZ
-    movl                4(rFP, %edx, 4), %eax   # %eax<- Y
-    imull       (rFP, rINST, 4), %eax   # %eax<- X*Y
-    addl        %eax, %ecx              # %ecx<- (WZ + XY)
-    movl        (rFP, %edx, 4), %eax    # %eax<- Z
-    mull        (rFP, rINST, 4)         # %edx:eax<- XZ
-    addl        %edx, %ecx              # %ecx<- carry + (WZ + XY)
-    movl        sReg0, %edx             # %edx<- A
-    movl        %ecx, 4(rFP, %edx, 4)   # vA+1<- results hi
-    movl        %eax, (rFP, %edx, 4)    # vA<- results lo
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_NEG_DOUBLE.S b/vm/mterp/x86-atom/OP_NEG_DOUBLE.S
deleted file mode 100644
index b6fb070..0000000
--- a/vm/mterp/x86-atom/OP_NEG_DOUBLE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEG_DOUBLE.S
-    */
-
-%include "x86-atom/unopWide.S" { "preinstr":"movq .LdoubNeg, %xmm1", "instr":"pxor %xmm1, %xmm0" }
diff --git a/vm/mterp/x86-atom/OP_NEG_FLOAT.S b/vm/mterp/x86-atom/OP_NEG_FLOAT.S
deleted file mode 100644
index 418fc0a..0000000
--- a/vm/mterp/x86-atom/OP_NEG_FLOAT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEG_FLOAT.S
-    */
-
-%include "x86-atom/unop.S" { "instr":"addl      $0x80000000, %ecx" }
diff --git a/vm/mterp/x86-atom/OP_NEG_INT.S b/vm/mterp/x86-atom/OP_NEG_INT.S
deleted file mode 100644
index 68acb89..0000000
--- a/vm/mterp/x86-atom/OP_NEG_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEG_INT.S
-    */
-
-%include "x86-atom/unop.S" {"instr":"neg        %ecx"}
diff --git a/vm/mterp/x86-atom/OP_NEG_LONG.S b/vm/mterp/x86-atom/OP_NEG_LONG.S
deleted file mode 100644
index 3f500bb..0000000
--- a/vm/mterp/x86-atom/OP_NEG_LONG.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEG_LONG.S
-    */
-
-%include "x86-atom/unopWide.S" {"preinstr":"xorps %xmm1, %xmm1", "instr":"psubq %xmm0, %xmm1", "result":"%xmm1"}
diff --git a/vm/mterp/x86-atom/OP_NEW_ARRAY.S b/vm/mterp/x86-atom/OP_NEW_ARRAY.S
deleted file mode 100644
index a6d5fd3..0000000
--- a/vm/mterp/x86-atom/OP_NEW_ARRAY.S
+++ /dev/null
@@ -1,92 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEW_ARRAY.S
-    *
-    * Code: Create a new array. Uses no substitutions.
-    *
-    * For: new-array
-    *
-    * Description: Construct a new array of the indicated type and size.
-    *              The type must be an array type.
-    *
-    * Format: B|A|op CCCC (22c)
-    *
-    * Syntax: op vA, vB, type@CCCC
-    *         op vA, vB, field@CCCC
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    movl        offGlue_methodClassDex(%eax), %eax # %eax<- glue->pDvmDex
-    FETCH       1, %ecx                 # %ecx<- CCCC
-    GET_VREG    %edx                    # %edx<- vB
-    movl        offDvmDex_pResClasses(%eax), %eax # %eax<- glue->pDvmDex->pResClasses
-    cmp         $$0, %edx               # check for negative length
-    movl        (%eax, %ecx, 4), %eax   # %eax<- resolved class
-    js          common_errNegativeArraySize # handle negative array length
-    cmp         $$0, %eax               # check for null
-    EXPORT_PC                           # required for resolve
-    jne         .L${opcode}_finish      # already resovled so continue
-    jmp         .L${opcode}_resolve     # need to resolve
-%break
-
-   /*
-    * Resolve class.  (This is an uncommon case.)
-    *
-    *  %edx holds array length
-    *  %ecx holds class ref CCCC
-    */
-
-.L${opcode}_resolve:
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_method(%eax), %eax # %eax<- glue->method
-    movl        %edx, -4(%esp)          # save length
-    movl        $$0, -8(%esp)           # push parameter false
-    movl        %ecx, -12(%esp)         # push parameter class ref
-    movl        offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz
-    movl        %eax, -16(%esp)         # push parameter clazz
-    lea         -16(%esp), %esp
-    call        dvmResolveClass         # call: (const ClassObject* referrer,
-                                        #       u4 classIdx, bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    cmp         $$0, %eax               # check for failure
-    lea         16(%esp), %esp
-    je          common_exceptionThrown  # handle exception
-    movl        -4(%esp), %edx          # %edx<- length
-
-   /*
-    * Finish allocation.
-    *
-    *  %eax holds class
-    *  %edx holds array length
-    */
-
-.L${opcode}_finish:
-    movl        %eax, -12(%esp)         # push parameter class
-    movl        %edx, -8(%esp)          # push parameter length
-    movl        $$ALLOC_DONT_TRACK, -4(%esp)
-    lea         -12(%esp), %esp
-    call        dvmAllocArrayByClass    # call: (ClassObject* arrayClass,
-                                        # size_t length, int allocFlags)
-                                        # return: ArrayObject*
-    and         $$15, rINST             # rINST<- A
-    cmp         $$0, %eax               # check for allocation failure
-    lea         12(%esp), %esp
-    je          common_exceptionThrown  # handle exception
-    SET_VREG    %eax, rINST             # vA<- pArray
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_NEW_INSTANCE.S b/vm/mterp/x86-atom/OP_NEW_INSTANCE.S
deleted file mode 100644
index d65afb7..0000000
--- a/vm/mterp/x86-atom/OP_NEW_INSTANCE.S
+++ /dev/null
@@ -1,147 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NEW_INSTANCE.S
-    *
-    * Code: Create a new instance of a given type. Uses no substitutions.
-    *
-    * For: new-instance
-    *
-    * Description: Construct a new instance of the indicated type,
-    *              storing a reference to it in the destination.
-    *              The type must refer to a non-array class.
-    *
-    *
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, type@BBBB
-    *         op vAA, field@BBBB
-    *         op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_methodClassDex(%ecx), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %edx                 # %edx<- BBBB
-    movl        offDvmDex_pResClasses(%ecx), %ecx # %ecx<- glue->pDvmDex->pResClasses
-    movl        (%ecx, %edx, 4), %edx   # %edx<- vB
-    EXPORT_PC                           # required for resolve
-    cmp         $$0, %edx               # check for null
-    je          .L${opcode}_resolve     # need to resolve
-
-   /*
-    *  %edx holds class object
-    */
-
-.L${opcode}_resolved:
-    movzbl      offClassObject_status(%edx), %eax # %eax<- class status
-    cmp         $$CLASS_INITIALIZED, %eax # check if class is initialized
-    jne         .L${opcode}_needinit    # initialize class
-
-   /*
-    *  %edx holds class object
-    */
-
-.L${opcode}_initialized:
-    testl       $$(ACC_INTERFACE|ACC_ABSTRACT), offClassObject_accessFlags(%edx)
-    mov         $$ALLOC_DONT_TRACK, %eax # %eax<- flag for alloc call
-    je          .L${opcode}_finish      # continue
-    jmp         .L${opcode}_abstract    # handle abstract or interface
-
-   /*
-    *  %edx holds class object
-    *  %eax holds flags for alloc call
-    */
-
-%break
-.balign 32
-.L${opcode}_finish:
-    movl        %edx, -8(%esp)          # push parameter object
-    movl        %eax, -4(%esp)          # push parameter flags
-    lea         -8(%esp), %esp
-    call        dvmAllocObject          # call: (ClassObject* clazz, int flags)
-                                        # return: Object*
-    cmp         $$0, %eax               # check for failure
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # handle exception
-    SET_VREG    %eax, rINST             # vAA<- pObject
-    FINISH      2                       # jump to next instruction
-
-   /*
-    * Class initialization required.
-    *
-    *  %edx holds class object
-    */
-
-.L${opcode}_needinit:
-    movl        %edx, -4(%esp)          # push parameter object
-    lea         -4(%esp), %esp
-    call        dvmInitClass            # call: (ClassObject* clazz)
-                                        # return: bool
-    lea         4(%esp), %esp
-    cmp         $$0, %eax               # check for failure
-    movl        -4(%esp), %edx          # %edx<- object
-    je          common_exceptionThrown  # handle exception
-    testl       $$(ACC_INTERFACE|ACC_ABSTRACT), offClassObject_accessFlags(%edx)
-    mov         $$ALLOC_DONT_TRACK, %eax # %eax<- flag for alloc call
-    je          .L${opcode}_finish      # continue
-    jmp         .L${opcode}_abstract    # handle abstract or interface
-
-   /*
-    * Resolution required.  This is the least-likely path.
-    *
-    *  BBBB in %eax
-    */
-
-.L${opcode}_resolve:
-
-
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offGlue_method(%ecx), %ecx # %ecx<- glue->method
-    movl        offMethod_clazz(%ecx), %ecx # %ecx<- glue->method->clazz
-    movl        %ecx, -12(%esp)         # push parameter clazz
-    movl        $$0, -4(%esp)           # push parameter false
-    movl        %eax, -8(%esp)          # push parameter BBBB
-    lea         -12(%esp), %esp
-    call        dvmResolveClass         # call: (const ClassObject* referrer,
-                                        #       u4 classIdx, bool fromUnverifiedConstant)
-                                        # return: ClassObject*
-    lea         12(%esp), %esp
-    movl        %eax, %edx              # %edx<- pObject
-    cmp         $$0, %edx               # check for failure
-    jne         .L${opcode}_resolved    # continue
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * We can't instantiate an abstract class or interface, so throw an
-    * InstantiationError with the class descriptor as the message.
-    *
-    *  %edx holds class object
-    */
-
-.L${opcode}_abstract:
-    movl        offClassObject_descriptor(%edx), %ecx # %ecx<- descriptor
-    movl        %ecx, -4(%esp)          # push parameter descriptor
-    movl        $$.LstrInstantiationErrorPtr, -8(%esp) # push parameter message
-    lea         -8(%esp), %esp
-    call        dvmThrowExceptionWithClassMessage # call: (const char* exceptionDescriptor,
-                                                  #        const char* messageDescriptor)
-                                                  # return: void
-    jmp         common_exceptionThrown  # handle exception
-
-.LstrInstantiationErrorPtr:
-.asciz      "Ljava/lang/InstantiationError;"
diff --git a/vm/mterp/x86-atom/OP_NOP.S b/vm/mterp/x86-atom/OP_NOP.S
deleted file mode 100644
index 9911da3..0000000
--- a/vm/mterp/x86-atom/OP_NOP.S
+++ /dev/null
@@ -1,41 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NOP.S
-    *
-    * Code: Use a cycle. Uses no substitutions.
-    *
-    * For: nop
-    *
-    * Description: No operation. Use a cycle
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    FINISH      1                       # jump to next instruction
-
-#ifdef ASSIST_DEBUGGER
-
-   /*
-    * insert fake function header to help gdb find the stack frame
-    */
-
-    .type       dalvik_inst, %function
-dalvik_inst:
-    MTERP_ENTRY
-#endif
diff --git a/vm/mterp/x86-atom/OP_NOT_INT.S b/vm/mterp/x86-atom/OP_NOT_INT.S
deleted file mode 100644
index b82e5b6..0000000
--- a/vm/mterp/x86-atom/OP_NOT_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NOT_INT.S
-    */
-
-%include "x86-atom/unop.S" {"instr":"not        %ecx"}
diff --git a/vm/mterp/x86-atom/OP_NOT_LONG.S b/vm/mterp/x86-atom/OP_NOT_LONG.S
deleted file mode 100644
index 98ff80b..0000000
--- a/vm/mterp/x86-atom/OP_NOT_LONG.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_NOT_LONG.S
-    */
-
-%include "x86-atom/unopWide.S" {"instr":"pandn  0xFFFFFFFF, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_OR_INT.S b/vm/mterp/x86-atom/OP_OR_INT.S
deleted file mode 100644
index 0ece38c..0000000
--- a/vm/mterp/x86-atom/OP_OR_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_INT.S
-    */
-
-%include "x86-atom/binop.S" {"instr":"or %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_OR_INT_2ADDR.S b/vm/mterp/x86-atom/OP_OR_INT_2ADDR.S
deleted file mode 100644
index 693e099..0000000
--- a/vm/mterp/x86-atom/OP_OR_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_INT_2ADDR.S
-    */
-
-%include "x86-atom/binop2addr.S" {"instr":"or %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_OR_INT_LIT16.S b/vm/mterp/x86-atom/OP_OR_INT_LIT16.S
deleted file mode 100644
index 5c63867..0000000
--- a/vm/mterp/x86-atom/OP_OR_INT_LIT16.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_INT_LIT16.S
-    */
-
-%include "x86-atom/binopLit16.S" {"instr":"or %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_OR_INT_LIT8.S b/vm/mterp/x86-atom/OP_OR_INT_LIT8.S
deleted file mode 100644
index aacd6c3..0000000
--- a/vm/mterp/x86-atom/OP_OR_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_INT_LIT8.S
-    */
-
-%include "x86-atom/binopLit8.S" {"instr":"or %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_OR_LONG.S b/vm/mterp/x86-atom/OP_OR_LONG.S
deleted file mode 100644
index f698e54..0000000
--- a/vm/mterp/x86-atom/OP_OR_LONG.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_LONG.S
-    */
-
-%include "x86-atom/binopWide.S" {"instr":"por %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_OR_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_OR_LONG_2ADDR.S
deleted file mode 100644
index 12a88ec..0000000
--- a/vm/mterp/x86-atom/OP_OR_LONG_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_OR_LONG_2ADDR.S
-    */
-
-%include "x86-atom/binopWide2addr.S" {"instr":"por %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_PACKED_SWITCH.S b/vm/mterp/x86-atom/OP_PACKED_SWITCH.S
deleted file mode 100644
index debac02..0000000
--- a/vm/mterp/x86-atom/OP_PACKED_SWITCH.S
+++ /dev/null
@@ -1,52 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_PACKED_SWITCH.S
-    *
-    * Code: Jump to a new instruction using a jump table
-    *
-    * For: packed-switch, sparse-switch
-    *
-    * Description: Jump to a new instruction based on the value in the given
-    *              register, using a table of offsets corresponding to each
-    *              value in a particular integral range, or fall through to
-    *              the next instruction if there is no match.
-    *
-    * Format: AA|op BBBBlo BBBBhi (31t)
-    *
-    * Syntax: op vAA, +BBBBBBBB
-    */
-
-%default { "func":"dvmInterpHandlePackedSwitch" }
-
-    FETCH       1, %ecx                 # %ecx<- BBBBlo
-    FETCH       2, %edx                 # %edx<- BBBBhi
-    shl         $$16, %edx              # prepare to create +BBBBBBBB
-    or          %edx, %ecx              # %ecx<- +BBBBBBBB
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, -4(%esp)         # push parameter vAA
-    lea         (rPC, %ecx, 2), %ecx    # %ecx<- PC + +BBBBBBBB*2
-    movl        %ecx, -8(%esp)          # push parameter PC + +BBBBBBBB*2
-    lea         -8(%esp), %esp
-    call        $func                   # call code-unit branch offset
-    shl         $$1, %eax               # shift for byte offset
-    movl        %eax, %edx              # %edx<- offset
-    lea         8(%esp), %esp
-    jle         common_periodicChecks_backwardBranch  # do backward branch
-    jmp         .L${opcode}_finish
-%break
-.L${opcode}_finish:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_REM_DOUBLE.S b/vm/mterp/x86-atom/OP_REM_DOUBLE.S
deleted file mode 100644
index aa7d332..0000000
--- a/vm/mterp/x86-atom/OP_REM_DOUBLE.S
+++ /dev/null
@@ -1,51 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_DOUBLE.S
-    *
-    * Code: Computes the remainder of a division. Performs no substitutions.
-    *
-    * For: rem-double
-    *
-    * Description: Calls fmod to compute the remainder of the result of dividing a
-    *              source register by a second, and stores the result in a
-    *              destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    movl        (rFP, %ecx, 4), %eax    # %eax<- vBBlo
-    movl        %eax, -16(%esp)         # push parameter double lo
-    movl        4(rFP, %ecx, 4), %eax   # %eax<- vBBhi
-    movl        %eax, -12(%esp)         # push parameter double hi
-    movl        (rFP, %edx, 4), %eax    # %eax<- vCClo
-    movl        %eax, -8(%esp)          # push parameter double lo
-    movl        4(rFP, %edx, 4), %eax   # %eax<- vCChi
-    movl        %eax, -4(%esp)          # push parameter double hi
-    lea         -16(%esp), %esp
-    jmp         .L${opcode}_break
-%break
-
-.L${opcode}_break:
-    call        fmod                    # call: (long double x, long double y)
-                                        # return: double
-    lea         16(%esp), %esp
-    fstpl       (rFP, rINST, 4)         # vAA<- remainder; return of fmod
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_REM_DOUBLE_2ADDR.S b/vm/mterp/x86-atom/OP_REM_DOUBLE_2ADDR.S
deleted file mode 100644
index 434c878..0000000
--- a/vm/mterp/x86-atom/OP_REM_DOUBLE_2ADDR.S
+++ /dev/null
@@ -1,52 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_DOUBLE_2ADDR.S
-    *
-    * Code: Computes the remainder of a division. Performs no substitutions.
-    *
-    * For: rem-double/2addr
-    *
-    * Description: Calls fmod to compute the remainder of the result of dividing a
-    *              source register by a second, and stores the result in the first
-    *              source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    and         $$15, rINST             # rINST<- A
-    shr         $$4, %edx               # %edx<- B
-    movl        (rFP, rINST, 4), %eax   # %eax<- vAlo
-    movl        %eax, -20(%esp)         # push parameter vAAlo
-    movl        4(rFP, rINST, 4), %eax  # %eax<- vAhi
-    movl        %eax, -16(%esp)         # push parameter vAAhi
-    movl        (rFP, %edx, 4), %eax    # %eax<- vBlo
-    movl        %eax, -12(%esp)         # push parameter vBBlo
-    movl        4(rFP, %edx, 4), %eax   # %eax<- vBhi
-    movl        %eax, -8(%esp)          # push parameter vBBhi
-    lea         -20(%esp), %esp
-    jmp         .L${opcode}_break
-%break
-
-.L${opcode}_break:
-    call        fmod                    # call: (long double x, long double y)
-                                        # return: double
-    lea         20(%esp), %esp
-    fstpl       (rFP, rINST, 4)         # vAA<- remainder; return of fmod
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_REM_FLOAT.S b/vm/mterp/x86-atom/OP_REM_FLOAT.S
deleted file mode 100644
index de5e161..0000000
--- a/vm/mterp/x86-atom/OP_REM_FLOAT.S
+++ /dev/null
@@ -1,43 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_FLOAT.S
-    *
-    * Code: Computes the remainder of a division. Performs no substitutions.
-    *
-    * For: rem-float
-    *
-    * Description: Calls fmod to compute the remainder of the result of dividing a
-    *              source register by a second, and stores the result in a
-    *              destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    movl        %ecx, -8(%esp)          # push parameter float
-    movl        %edx, -4(%esp)          # push parameter float
-    lea         -8(%esp), %esp
-    call        fmodf                   # call: (float x, float y)
-                                        # return: float
-    lea         8(%esp), %esp
-    fstps       (rFP, rINST, 4)         # vAA<- remainder; return of fmod
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_REM_FLOAT_2ADDR.S b/vm/mterp/x86-atom/OP_REM_FLOAT_2ADDR.S
deleted file mode 100644
index 5ff5af5..0000000
--- a/vm/mterp/x86-atom/OP_REM_FLOAT_2ADDR.S
+++ /dev/null
@@ -1,44 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_FLOAT_2ADDR.S
-    *
-    * Code: Computes the remainder of a division. Performs no substitutions.
-    *
-    * For: rem-float/2addr
-    *
-    * Description: Calls fmod to compute the remainder of the result of dividing a
-    *              source register by a second, and stores the result in the first
-    *              source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    andl        $$15, rINST             # rINST<- A
-    GET_VREG    %edx                    # %edx<- vB
-    movl        (rFP, rINST, 4), %ecx   # %ecx<- vA
-    movl        %ecx, -8(%esp)          # push parameter vA
-    movl        %edx, -4(%esp)          # push parameter vB
-    lea         -8(%esp), %esp
-    call        fmodf                   # call: (float x, float y)
-                                        # return: float
-    lea         8(%esp), %esp
-    fstps       (rFP, rINST, 4)
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_REM_INT.S b/vm/mterp/x86-atom/OP_REM_INT.S
deleted file mode 100644
index 5f62d66..0000000
--- a/vm/mterp/x86-atom/OP_REM_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_INT.S
-    */
-
-%include "x86-atom/binopD.S" {"div":"0"}
diff --git a/vm/mterp/x86-atom/OP_REM_INT_2ADDR.S b/vm/mterp/x86-atom/OP_REM_INT_2ADDR.S
deleted file mode 100644
index 369ea5c..0000000
--- a/vm/mterp/x86-atom/OP_REM_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_INT_2ADDR.S
-    */
-
-%include "x86-atom/binopD2addr.S" {"div":"0"}
diff --git a/vm/mterp/x86-atom/OP_REM_INT_LIT16.S b/vm/mterp/x86-atom/OP_REM_INT_LIT16.S
deleted file mode 100644
index 0c9afa3a..0000000
--- a/vm/mterp/x86-atom/OP_REM_INT_LIT16.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_INT_LIT16.S
-    */
-
-%include "x86-atom/binopDLit16.S" {"div":"0"}
diff --git a/vm/mterp/x86-atom/OP_REM_INT_LIT8.S b/vm/mterp/x86-atom/OP_REM_INT_LIT8.S
deleted file mode 100644
index 6578c7c..0000000
--- a/vm/mterp/x86-atom/OP_REM_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_INT_LIT8.S
-    */
-
-%include "x86-atom/binopDLit8.S" {"div":"0"}
diff --git a/vm/mterp/x86-atom/OP_REM_LONG.S b/vm/mterp/x86-atom/OP_REM_LONG.S
deleted file mode 100644
index 3e3b200..0000000
--- a/vm/mterp/x86-atom/OP_REM_LONG.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_LONG.S
-    */
-
-%include "x86-atom/binopDivRemLong.S" {"func":"__moddi3"}
diff --git a/vm/mterp/x86-atom/OP_REM_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_REM_LONG_2ADDR.S
deleted file mode 100644
index f494caf..0000000
--- a/vm/mterp/x86-atom/OP_REM_LONG_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_REM_LONG_2ADDR.S
-    */
-
-%include "x86-atom/binopDivRemLong2Addr.S" {"func":"__moddi3"}
diff --git a/vm/mterp/x86-atom/OP_RETURN.S b/vm/mterp/x86-atom/OP_RETURN.S
deleted file mode 100644
index 48d7e34..0000000
--- a/vm/mterp/x86-atom/OP_RETURN.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN.S
-    */
-
-%include "x86-atom/OP_RETURN_COMMON.S"
diff --git a/vm/mterp/x86-atom/OP_RETURN_COMMON.S b/vm/mterp/x86-atom/OP_RETURN_COMMON.S
deleted file mode 100644
index d58a16c..0000000
--- a/vm/mterp/x86-atom/OP_RETURN_COMMON.S
+++ /dev/null
@@ -1,34 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN_COMMON.S
-    *
-    * Code: Return a 32-bit value. Uses no substitutions.
-    *
-    * For: return, return-object
-    *
-    * Description: Copies the return value into the "glue"
-    *              structure, then jumps to the return handler.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, offGlue_retval(%edx) # glue->retval<- vAA
-    jmp         common_returnFromMethod # jump to common return code
diff --git a/vm/mterp/x86-atom/OP_RETURN_OBJECT.S b/vm/mterp/x86-atom/OP_RETURN_OBJECT.S
deleted file mode 100644
index 3b9c10c..0000000
--- a/vm/mterp/x86-atom/OP_RETURN_OBJECT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN_OBJECT.S
-    */
-
-%include "x86-atom/OP_RETURN_COMMON.S"
diff --git a/vm/mterp/x86-atom/OP_RETURN_VOID.S b/vm/mterp/x86-atom/OP_RETURN_VOID.S
deleted file mode 100644
index 4d8c92b..0000000
--- a/vm/mterp/x86-atom/OP_RETURN_VOID.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN_VOID.S
-    */
-
-    jmp         common_returnFromMethod
diff --git a/vm/mterp/x86-atom/OP_RETURN_WIDE.S b/vm/mterp/x86-atom/OP_RETURN_WIDE.S
deleted file mode 100644
index 8069e85..0000000
--- a/vm/mterp/x86-atom/OP_RETURN_WIDE.S
+++ /dev/null
@@ -1,34 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RETURN_WIDE.S
-    *
-    * Code: Return a 64-bit value. Uses no substitutions.
-    *
-    * For: return-wide
-    *
-    * Description: Copies the return value into the "glue"
-    *              structure, then jumps to the return handler.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vAA
-    movq        %xmm0, offGlue_retval(%edx)# glue->retval<- vAA
-    jmp         common_returnFromMethod # jump to common return code
diff --git a/vm/mterp/x86-atom/OP_RSUB_INT.S b/vm/mterp/x86-atom/OP_RSUB_INT.S
deleted file mode 100644
index 87498f9..0000000
--- a/vm/mterp/x86-atom/OP_RSUB_INT.S
+++ /dev/null
@@ -1,39 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RSUB_INT.S
-    *
-    * Code: 32-bit reverse-subtraction. Uses no substitutions.
-    *
-    * For: rsub-int
-    *
-    * Description: Perform a reverse subtraction on a register and a
-    *              signed extended 16-bit literal value and store the
-    *              result in a destination register.
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $$4, %ecx               # %ecx<- B
-    andl        $$15, rINST             # rINST<- A
-    FETCHs      1, %edx                 # %edx<- +CCCC, sign-extended literal
-    GET_VREG    %ecx                    # %ecx<- vB
-    subl        %ecx, %edx              # %edx<- +CCCC sub vB
-    SET_VREG    %edx, rINST             # vA<- %edx; result
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_RSUB_INT_LIT8.S b/vm/mterp/x86-atom/OP_RSUB_INT_LIT8.S
deleted file mode 100644
index d6114dd..0000000
--- a/vm/mterp/x86-atom/OP_RSUB_INT_LIT8.S
+++ /dev/null
@@ -1,36 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_RSUB_INT_LIT8.S
-    *
-    * Code: 32-bit reverse-subtraction. Uses no substitutions.
-    *
-    * For: rsub-int/lit8
-    *
-    * Description: Perform a reverse subtraction on a register and a
-    *              signed extended 8-bit literal value.
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CCs   1, %edx                 # %edx<- +CC, sign-extended literal
-    GET_VREG    %ecx                    # %ecx<- vBB
-    sub         %ecx, %edx              # %edx<- +CC sub vBB
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_SGET.S b/vm/mterp/x86-atom/OP_SGET.S
deleted file mode 100644
index 914b4dc..0000000
--- a/vm/mterp/x86-atom/OP_SGET.S
+++ /dev/null
@@ -1,60 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET.S
-    *
-    * Code: Generic 32-bit static field "get" operation. Uses no substitutions.
-    *
-    * For: sget-boolean, sget-byte, sget-char, sget-object, sget, sget-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; load the field value
-    *              into the value register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $$0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .L${opcode}_resolve
-    jmp         .L${opcode}_finish
-%break
-
-.L${opcode}_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $$0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    mov         %eax, %ecx              # %ecx<- result
-
-.L${opcode}_finish:
-    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
-    movl offStaticField_value(%ecx), %eax # %eax<- field value
-    SET_VREG    %eax, rINST             # vAA<- field value
-    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_SGET_BOOLEAN.S b/vm/mterp/x86-atom/OP_SGET_BOOLEAN.S
deleted file mode 100644
index 8e383b4..0000000
--- a/vm/mterp/x86-atom/OP_SGET_BOOLEAN.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_BOOLEAN.S
-    */
-
-%include "x86-atom/OP_SGET.S"
diff --git a/vm/mterp/x86-atom/OP_SGET_BYTE.S b/vm/mterp/x86-atom/OP_SGET_BYTE.S
deleted file mode 100644
index c86fc20..0000000
--- a/vm/mterp/x86-atom/OP_SGET_BYTE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_BYTE.S
-    */
-
-%include "x86-atom/OP_SGET.S"
diff --git a/vm/mterp/x86-atom/OP_SGET_CHAR.S b/vm/mterp/x86-atom/OP_SGET_CHAR.S
deleted file mode 100644
index 0a3cffd..0000000
--- a/vm/mterp/x86-atom/OP_SGET_CHAR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_CHAR.S
-    */
-
-%include "x86-atom/OP_SGET.S"
diff --git a/vm/mterp/x86-atom/OP_SGET_OBJECT.S b/vm/mterp/x86-atom/OP_SGET_OBJECT.S
deleted file mode 100644
index 5145f14..0000000
--- a/vm/mterp/x86-atom/OP_SGET_OBJECT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_OBJECT.S
-    */
-
-%include "x86-atom/OP_SGET.S"
diff --git a/vm/mterp/x86-atom/OP_SGET_OBJECT_VOLATILE.S b/vm/mterp/x86-atom/OP_SGET_OBJECT_VOLATILE.S
deleted file mode 100644
index 5f64fb5..0000000
--- a/vm/mterp/x86-atom/OP_SGET_OBJECT_VOLATILE.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "x86/OP_SGET.S"
diff --git a/vm/mterp/x86-atom/OP_SGET_SHORT.S b/vm/mterp/x86-atom/OP_SGET_SHORT.S
deleted file mode 100644
index 77064b6..0000000
--- a/vm/mterp/x86-atom/OP_SGET_SHORT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_SHORT.S
-    */
-
-%include "x86-atom/OP_SGET.S"
diff --git a/vm/mterp/x86-atom/OP_SGET_VOLATILE.S b/vm/mterp/x86-atom/OP_SGET_VOLATILE.S
deleted file mode 100644
index 5f64fb5..0000000
--- a/vm/mterp/x86-atom/OP_SGET_VOLATILE.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "x86/OP_SGET.S"
diff --git a/vm/mterp/x86-atom/OP_SGET_WIDE.S b/vm/mterp/x86-atom/OP_SGET_WIDE.S
deleted file mode 100644
index 3ef6916..0000000
--- a/vm/mterp/x86-atom/OP_SGET_WIDE.S
+++ /dev/null
@@ -1,65 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SGET_WIDE.S
-    *
-    * Code: 64-bit static field "get" operation. Uses no substitutions.
-    *
-    * For: sget-wide
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field, loading or storing
-    *              into the value register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_methodClassDex(%eax), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %edx                 # %edx<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $$0, (%ecx, %edx, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .L${opcode}_resolve
-
-.L${opcode}_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        offStaticField_value(%ecx), %xmm0 # %xmm0<- field value
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- field value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-%break
-
-   /*
-    * Continuation if the field has not yet been resolved.
-    *  %edx: BBBB field ref
-    */
-
-.L${opcode}_resolve:
-    movl        offGlue_method(%eax), %eax # %eax <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %edx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%eax), %eax # %eax<- method->clazz
-    movl        %eax, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    lea         8(%esp), %esp
-    cmp         $$0, %eax               # check if initalization failed
-    movl        %eax, %ecx              # %ecx<- result
-    jne         .L${opcode}_finish      # success, continue
-    jmp         common_exceptionThrown  # failed; handle exception
diff --git a/vm/mterp/x86-atom/OP_SHL_INT.S b/vm/mterp/x86-atom/OP_SHL_INT.S
deleted file mode 100644
index 13e4a11..0000000
--- a/vm/mterp/x86-atom/OP_SHL_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHL_INT.S
-    */
-
-%include "x86-atom/binopS.S" {"instr":"sal     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHL_INT_2ADDR.S b/vm/mterp/x86-atom/OP_SHL_INT_2ADDR.S
deleted file mode 100644
index a27e09a..0000000
--- a/vm/mterp/x86-atom/OP_SHL_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHL_INT_2ADDR.S
-    */
-
-%include "x86-atom/binopS2addr.S" {"instr":"sal     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHL_INT_LIT8.S b/vm/mterp/x86-atom/OP_SHL_INT_LIT8.S
deleted file mode 100644
index 5141e5c..0000000
--- a/vm/mterp/x86-atom/OP_SHL_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHL_INT_LIT8.S
-    */
-
-%include "x86-atom/binopLit8S.S" {"instr":"sal     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHL_LONG.S b/vm/mterp/x86-atom/OP_SHL_LONG.S
deleted file mode 100644
index cef558c..0000000
--- a/vm/mterp/x86-atom/OP_SHL_LONG.S
+++ /dev/null
@@ -1,40 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHL_LONG.S
-    *
-    * Code: Performs a shift left long. Uses no substitutions.
-    *
-    * For: shl-long
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where one is the shift amount and the other is the value to shift.
-    *              Store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_CC    1, %eax                 # %eax<- CC
-    FETCH_BB    1, %edx                 # %edx<- BB
-    movq        .LshiftMask, %xmm2      # %xmm2<- mask for the shift bits
-    movss       (rFP, %eax, 4), %xmm0   # %xmm0<- vCC
-    pand        %xmm2, %xmm0            # %xmm0<- masked shift bits
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vBB
-    psllq       %xmm0, %xmm1            # %xmm1<- shifted vBB
-    movq        %xmm1, (rFP, rINST, 4)  # vAA<- shifted vBB
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_SHL_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_SHL_LONG_2ADDR.S
deleted file mode 100644
index 28dfaf2..0000000
--- a/vm/mterp/x86-atom/OP_SHL_LONG_2ADDR.S
+++ /dev/null
@@ -1,41 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHL_LONG_2ADDR.S
-    *
-    * Code: Performs a shift left long. Uses no substitutions.
-    *
-    * For: shl-long/2addr
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where the fist is the value to shift and the second is the
-    *              shift amount. Store the result in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    andl        $$15, rINST             # rINST<- A
-    movss       (rFP, %edx, 4),  %xmm0  # %xmm0<- vB
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vA
-    movq        .LshiftMask, %xmm2      # %xmm2<- mask for the shift bits
-    pand        %xmm2, %xmm0            # %xmm0<- masked shift bits
-    psllq       %xmm0, %xmm1            # %xmm1<- shifted vA
-    movq        %xmm1, (rFP, rINST, 4)  # vA<- shifted vA
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_SHR_INT.S b/vm/mterp/x86-atom/OP_SHR_INT.S
deleted file mode 100644
index e7fd28b..0000000
--- a/vm/mterp/x86-atom/OP_SHR_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHR_INT.S
-    */
-
-%include "x86-atom/binopS.S" {"instr":"sar     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHR_INT_2ADDR.S b/vm/mterp/x86-atom/OP_SHR_INT_2ADDR.S
deleted file mode 100644
index 0d0b461..0000000
--- a/vm/mterp/x86-atom/OP_SHR_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHR_INT_2ADDR.S
-    */
-
-%include "x86-atom/binopS2addr.S" {"instr":"sar     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHR_INT_LIT8.S b/vm/mterp/x86-atom/OP_SHR_INT_LIT8.S
deleted file mode 100644
index 3467bf5..0000000
--- a/vm/mterp/x86-atom/OP_SHR_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHR_INT_LIT8.S
-    */
-
-%include "x86-atom/binopLit8S.S" {"instr":"sar     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHR_LONG.S b/vm/mterp/x86-atom/OP_SHR_LONG.S
deleted file mode 100644
index be893ef..0000000
--- a/vm/mterp/x86-atom/OP_SHR_LONG.S
+++ /dev/null
@@ -1,53 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHR_LONG.S
-    *
-    * Code: Performs a shift right long
-    *
-    * For: shl-long
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where one is the shift amount and the other is the value to shift.
-    *              Store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %edx                 # %edx<- BB
-    FETCH_CC    1, %eax                 # %eax<- CC
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vBB
-    movss       (rFP, %eax, 4), %xmm0   # %xmm0<- vCC
-    movq        .LshiftMask, %xmm2
-    pand        %xmm2, %xmm0            # %xmm0<- masked for the shift bits
-    psrlq       %xmm0, %xmm1            # %xmm1<- shifted vBB
-    cmpl        $$0, 4(rFP, %edx, 4)    # check if we need to consider sign
-    jl          .L${opcode}_finish      # consider sign
-    jmp         .L${opcode}_final       # sign is fine, finish
-%break
-
-.L${opcode}_finish:
-    movq        .Lvalue64, %xmm3        # %xmm3<- 64
-    psubq       %xmm0, %xmm3            # %xmm3<- 64 - shift amount
-    movq        .L64bits, %xmm4         # %xmm4<- lower 64 bits set
-    psllq       %xmm3, %xmm4            # %xmm4<- correct mask for sign bits
-    por         %xmm4, %xmm1            # %xmm1<- signed and shifted vBB
-
-.L${opcode}_final:
-    movq        %xmm1, (rFP, rINST, 4)  # vAA<- shifted vBB
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_SHR_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_SHR_LONG_2ADDR.S
deleted file mode 100644
index 38aefcf..0000000
--- a/vm/mterp/x86-atom/OP_SHR_LONG_2ADDR.S
+++ /dev/null
@@ -1,54 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SHR_LONG_2ADDR.S
-    *
-    * Code: Performs a shift left long
-    *
-    * For: shl-long/2addr
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where the fist is the value to shift and the second is the
-    *              shift amount. Store the result in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    andl        $$15, rINST             # rINST<- BA
-    movss       (rFP, %edx, 4),  %xmm0  # %xmm0<- vB
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vA
-    movq        .LshiftMask, %xmm2
-    pand        %xmm2, %xmm0            # %xmm0<- masked for the shift bits
-    psrlq       %xmm0, %xmm1            # %xmm1<- shifted vBB
-    cmpl        $$0, 4(rFP, rINST, 4)   # check if we need to consider sign
-    jl          .L${opcode}_finish      # consider sign
-    jmp         .L${opcode}_final       # sign is fine, finish
-%break
-
-.L${opcode}_finish:
-    movq        .Lvalue64, %xmm3        # %xmm3<- 64
-    psubq       %xmm0, %xmm3            # %xmm3<- 64 - shift amount
-    movq        .L64bits, %xmm4         # %xmm4<- lower 64 bits set
-    psllq       %xmm3, %xmm4            # %xmm4<- correct mask for sign bits
-    por         %xmm4, %xmm1            # %xmm1<- signed and shifted vBB
-
-.L${opcode}_final:
-    movq        %xmm1, (rFP, rINST, 4)  # vAA<- shifted vBB
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_SPARSE_SWITCH.S b/vm/mterp/x86-atom/OP_SPARSE_SWITCH.S
deleted file mode 100644
index 8020d1a..0000000
--- a/vm/mterp/x86-atom/OP_SPARSE_SWITCH.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPARSE_SWITCH.S
-    */
-
-%include "x86-atom/OP_PACKED_SWITCH.S" { "func":"dvmInterpHandleSparseSwitch" }
diff --git a/vm/mterp/x86-atom/OP_SPUT.S b/vm/mterp/x86-atom/OP_SPUT.S
deleted file mode 100644
index 55715a7..0000000
--- a/vm/mterp/x86-atom/OP_SPUT.S
+++ /dev/null
@@ -1,60 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT.S
-    *
-    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
-    *
-    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; store the field value
-    *              register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $$0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .L${opcode}_resolve
-    jmp         .L${opcode}_finish
-%break
-
-.L${opcode}_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $$0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    movl        %eax, %ecx              # %ecx<- result
-
-.L${opcode}_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vAA
-    movl        rINST, offStaticField_value(%ecx) # field value<- vAA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_SPUT_BOOLEAN.S b/vm/mterp/x86-atom/OP_SPUT_BOOLEAN.S
deleted file mode 100644
index 9bb64f8..0000000
--- a/vm/mterp/x86-atom/OP_SPUT_BOOLEAN.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_BOOLEAN.S
-    */
-
-%include "x86-atom/OP_SPUT.S"
diff --git a/vm/mterp/x86-atom/OP_SPUT_BYTE.S b/vm/mterp/x86-atom/OP_SPUT_BYTE.S
deleted file mode 100644
index 1d4f016..0000000
--- a/vm/mterp/x86-atom/OP_SPUT_BYTE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_BYTE.S
-    */
-
-%include "x86-atom/OP_SPUT.S"
diff --git a/vm/mterp/x86-atom/OP_SPUT_CHAR.S b/vm/mterp/x86-atom/OP_SPUT_CHAR.S
deleted file mode 100644
index 58300ef..0000000
--- a/vm/mterp/x86-atom/OP_SPUT_CHAR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_CHAR.S
-    */
-
-%include "x86-atom/OP_SPUT.S"
diff --git a/vm/mterp/x86-atom/OP_SPUT_OBJECT.S b/vm/mterp/x86-atom/OP_SPUT_OBJECT.S
deleted file mode 100644
index 88ebaf7..0000000
--- a/vm/mterp/x86-atom/OP_SPUT_OBJECT.S
+++ /dev/null
@@ -1,70 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_OBJECT.S
-    *
-    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
-    *
-    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; store the field value
-    *              register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- pDvmDex
-    FETCH       1, %eax                 # %eax<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $$0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField
-    je          .L${opcode}_resolve
-    jmp         .L${opcode}_finish
-%break
-
-.L${opcode}_resolve:
-    movl        offGlue_method(%edx), %edx # %edx <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    movl        %edx, -8(%esp)          # push parameter method->clazz
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    cmp         $$0, %eax               # check if initalization failed
-    lea         8(%esp), %esp
-    je          common_exceptionThrown  # failed; handle exception
-    movl        %eax, %ecx              # %ecx<- result
-
-.L${opcode}_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    rINST                   # rINST<- vAA
-
-
-    movl        rINST, offStaticField_value(%ecx) # field value<- vAA
-    testl       rINST, rINST            # stored null object ptr?
-    je          1f
-    movl        rGLUE, %edx             # get glue
-    movl        offField_clazz(%ecx), %ecx # ecx<- field->clazz
-    movl        offGlue_cardTable(%edx), %edx # get card table base
-    shrl        $$GC_CARD_SHIFT, %ecx   # head to card number
-    movb        %dl, (%edx, %ecx)       # mark card
-1:
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_SPUT_OBJECT_VOLATILE.S b/vm/mterp/x86-atom/OP_SPUT_OBJECT_VOLATILE.S
deleted file mode 100644
index b368e31..0000000
--- a/vm/mterp/x86-atom/OP_SPUT_OBJECT_VOLATILE.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "x86/OP_SPUT_OBJECT.S"
diff --git a/vm/mterp/x86-atom/OP_SPUT_SHORT.S b/vm/mterp/x86-atom/OP_SPUT_SHORT.S
deleted file mode 100644
index 1ecc562..0000000
--- a/vm/mterp/x86-atom/OP_SPUT_SHORT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_SHORT.S
-    */
-
-%include "x86-atom/OP_SPUT.S"
diff --git a/vm/mterp/x86-atom/OP_SPUT_VOLATILE.S b/vm/mterp/x86-atom/OP_SPUT_VOLATILE.S
deleted file mode 100644
index 7ee4140..0000000
--- a/vm/mterp/x86-atom/OP_SPUT_VOLATILE.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "x86/OP_SPUT.S"
diff --git a/vm/mterp/x86-atom/OP_SPUT_WIDE.S b/vm/mterp/x86-atom/OP_SPUT_WIDE.S
deleted file mode 100644
index 7d661cf..0000000
--- a/vm/mterp/x86-atom/OP_SPUT_WIDE.S
+++ /dev/null
@@ -1,65 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SPUT_WIDE.S
-    *
-    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
-    *
-    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
-    *
-    * Description: Perform the identified object static field operation
-    *              with the identified static field; store the field value
-    *              register.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, string@BBBB
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_methodClassDex(%eax), %ecx # %ecx<- glue->pDvmDex
-    FETCH       1, %edx                 # %edx<- BBBB
-    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $$0, (%ecx, %edx, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved StaticField ptr
-    je          .L${opcode}_resolve
-
-.L${opcode}_finish:
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vAA
-    movq        %xmm0, offStaticField_value(%ecx) # field value<- field value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
-%break
-
-   /*
-    * Continuation if the field has not yet been resolved.
-    *  %edx: BBBB field ref
-    */
-
-.L${opcode}_resolve:
-    movl        offGlue_method(%eax), %eax # %eax <- glue->method
-    EXPORT_PC                           # in case an exception is thrown
-    movl        %edx, -4(%esp)          # push parameter CCCC; field ref
-    movl        offMethod_clazz(%eax), %eax # %eax<- method->clazz
-    movl        %eax, -8(%esp)
-    lea         -8(%esp), %esp
-    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
-                                        # return: StaticField*
-    lea         8(%esp), %esp
-    cmp         $$0, %eax               # check if initalization failed
-    movl        %eax, %ecx              # %ecx<- result
-    jne         .L${opcode}_finish      # success, continue
-    jmp         common_exceptionThrown  # failed; handle exception
diff --git a/vm/mterp/x86-atom/OP_SUB_DOUBLE.S b/vm/mterp/x86-atom/OP_SUB_DOUBLE.S
deleted file mode 100644
index 5f2dbb6..0000000
--- a/vm/mterp/x86-atom/OP_SUB_DOUBLE.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_DOUBLE.S
-    */
-
-%include "x86-atom/binopWide.S" {"instr":"subsd   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_SUB_DOUBLE_2ADDR.S b/vm/mterp/x86-atom/OP_SUB_DOUBLE_2ADDR.S
deleted file mode 100644
index cd6f12a..0000000
--- a/vm/mterp/x86-atom/OP_SUB_DOUBLE_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_DOUBLE_2ADDR.S
-    */
-
-%include "x86-atom/binopWide2addr.S" {"instr":"subsd   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_SUB_FLOAT.S b/vm/mterp/x86-atom/OP_SUB_FLOAT.S
deleted file mode 100644
index eb79d79..0000000
--- a/vm/mterp/x86-atom/OP_SUB_FLOAT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_FLOAT.S
-    */
-
-%include "x86-atom/binopF.S" {"instr":"subss     %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_SUB_FLOAT_2ADDR.S b/vm/mterp/x86-atom/OP_SUB_FLOAT_2ADDR.S
deleted file mode 100644
index 77f23f1..0000000
--- a/vm/mterp/x86-atom/OP_SUB_FLOAT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_FLOAT_2ADDR.S
-    */
-
-%include "x86-atom/binopF2addr.S" {"instr":"subss     %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_SUB_INT.S b/vm/mterp/x86-atom/OP_SUB_INT.S
deleted file mode 100644
index 8d342cd..0000000
--- a/vm/mterp/x86-atom/OP_SUB_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_INT.S
-    */
-
-%include "x86-atom/binop.S" {"instr":"subl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_SUB_INT_2ADDR.S b/vm/mterp/x86-atom/OP_SUB_INT_2ADDR.S
deleted file mode 100644
index 4d295a4..0000000
--- a/vm/mterp/x86-atom/OP_SUB_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_INT_2ADDR.S
-    */
-
-%include "x86-atom/binop2addr.S" {"instr":"subl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_SUB_INT_LIT8.S b/vm/mterp/x86-atom/OP_SUB_INT_LIT8.S
deleted file mode 100644
index 8bf0902..0000000
--- a/vm/mterp/x86-atom/OP_SUB_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_INT_LIT8.S
-    */
-
-%include "x86-atom/binopLit8.S" {"instr":"subl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_SUB_LONG.S b/vm/mterp/x86-atom/OP_SUB_LONG.S
deleted file mode 100644
index 84e25d0..0000000
--- a/vm/mterp/x86-atom/OP_SUB_LONG.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_LONG.S
-    */
-
-%include "x86-atom/binopWide.S" {"instr":"psubq    %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_SUB_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_SUB_LONG_2ADDR.S
deleted file mode 100644
index ca6a2ad..0000000
--- a/vm/mterp/x86-atom/OP_SUB_LONG_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_SUB_LONG_2ADDR.S
-    */
-
-%include "x86-atom/binopWide2addr.S" {"instr":"psubq    %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_THROW.S b/vm/mterp/x86-atom/OP_THROW.S
deleted file mode 100644
index 120b1e9..0000000
--- a/vm/mterp/x86-atom/OP_THROW.S
+++ /dev/null
@@ -1,37 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_THROW.S
-    *
-    * Code: Throw an exception
-    *
-    * For: throw
-    *
-    * Description: Throw an exception object in the current thread.
-    *
-    * Format: AA|op (11x)
-    *
-    * Syntax: op vAA
-    */
-
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    EXPORT_PC                           # export the pc
-    GET_VREG    rINST                   # rINST<- vAA
-    cmp         $$0, rINST              # check for null
-    movl        offGlue_self(%eax), %ecx # %ecx<- glue->self
-    je          common_errNullObject    # handle null object
-    movl        rINST, offThread_exception(%ecx) # thread->exception<- object
-    jmp         common_exceptionThrown  # handle exception
diff --git a/vm/mterp/x86-atom/OP_THROW_VERIFICATION_ERROR.S b/vm/mterp/x86-atom/OP_THROW_VERIFICATION_ERROR.S
deleted file mode 100644
index f920b50..0000000
--- a/vm/mterp/x86-atom/OP_THROW_VERIFICATION_ERROR.S
+++ /dev/null
@@ -1,40 +0,0 @@
-   /* Copyright (C) 2009 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_THROW_VERIFICATION_ERROR.S
-    *
-    * Code:
-    *
-    * For: throw-verification-error
-    *
-    * Description: Throws an exception for an error discovered during verification.
-    *              The exception is indicated by AA with details provided by BBBB.
-    *
-    * Format: AA|op BBBB (21c)
-    *
-    * Syntax: op vAA, ref@BBBB
-    */
-
-    movl        rGLUE, %edx                  # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %ecx   # %ecx<- glue->method
-    EXPORT_PC                                # in case an exception is thrown
-    FETCH       1, %eax                      # %eax<- BBBB
-    movl        %eax, -4(%esp)               # push parameter BBBB; ref
-    movl        rINST, -8(%esp)              # push parameter AA
-    movl        %ecx, -12(%esp)              # push parameter glue->method
-    lea         -12(%esp), %esp
-    call        dvmThrowVerificationError    # call: (const Method* method, int kind, int ref)
-    jmp         common_exceptionThrown       # failed; handle exception
diff --git a/vm/mterp/x86-atom/OP_UNUSED_3E.S b/vm/mterp/x86-atom/OP_UNUSED_3E.S
deleted file mode 100644
index d91d469..0000000
--- a/vm/mterp/x86-atom/OP_UNUSED_3E.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_3E.S
-    */
-
-%include "x86-atom/unused.S"
diff --git a/vm/mterp/x86-atom/OP_UNUSED_3F.S b/vm/mterp/x86-atom/OP_UNUSED_3F.S
deleted file mode 100644
index 84cc69d..0000000
--- a/vm/mterp/x86-atom/OP_UNUSED_3F.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_3F.S
-    */
-
-%include "x86-atom/unused.S"
diff --git a/vm/mterp/x86-atom/OP_UNUSED_40.S b/vm/mterp/x86-atom/OP_UNUSED_40.S
deleted file mode 100644
index e0853da..0000000
--- a/vm/mterp/x86-atom/OP_UNUSED_40.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_40.S
-    */
-
-%include "x86-atom/unused.S"
diff --git a/vm/mterp/x86-atom/OP_UNUSED_41.S b/vm/mterp/x86-atom/OP_UNUSED_41.S
deleted file mode 100644
index a30fbe3..0000000
--- a/vm/mterp/x86-atom/OP_UNUSED_41.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_41.S
-    */
-
-%include "x86-atom/unused.S"
diff --git a/vm/mterp/x86-atom/OP_UNUSED_42.S b/vm/mterp/x86-atom/OP_UNUSED_42.S
deleted file mode 100644
index 64c5648..0000000
--- a/vm/mterp/x86-atom/OP_UNUSED_42.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_42.S
-    */
-
-%include "x86-atom/unused.S"
diff --git a/vm/mterp/x86-atom/OP_UNUSED_43.S b/vm/mterp/x86-atom/OP_UNUSED_43.S
deleted file mode 100644
index 4a6120b..0000000
--- a/vm/mterp/x86-atom/OP_UNUSED_43.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_43.S
-    */
-
-%include "x86-atom/unused.S"
diff --git a/vm/mterp/x86-atom/OP_UNUSED_73.S b/vm/mterp/x86-atom/OP_UNUSED_73.S
deleted file mode 100644
index 9808865..0000000
--- a/vm/mterp/x86-atom/OP_UNUSED_73.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_73.S
-    */
-
-%include "x86-atom/unused.S"
diff --git a/vm/mterp/x86-atom/OP_UNUSED_79.S b/vm/mterp/x86-atom/OP_UNUSED_79.S
deleted file mode 100644
index 6ebd8ff..0000000
--- a/vm/mterp/x86-atom/OP_UNUSED_79.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_79.S
-    */
-
-%include "x86-atom/unused.S"
diff --git a/vm/mterp/x86-atom/OP_UNUSED_7A.S b/vm/mterp/x86-atom/OP_UNUSED_7A.S
deleted file mode 100644
index 79a22d0..0000000
--- a/vm/mterp/x86-atom/OP_UNUSED_7A.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_UNUSED_7A.S
-    */
-
-%include "x86-atom/unused.S"
diff --git a/vm/mterp/x86-atom/OP_UNUSED_FF.S b/vm/mterp/x86-atom/OP_UNUSED_FF.S
deleted file mode 100644
index e6acc08..0000000
--- a/vm/mterp/x86-atom/OP_UNUSED_FF.S
+++ /dev/null
@@ -1,16 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-%include "x86-atom/unused.S"
diff --git a/vm/mterp/x86-atom/OP_USHR_INT.S b/vm/mterp/x86-atom/OP_USHR_INT.S
deleted file mode 100644
index a1d91c6..0000000
--- a/vm/mterp/x86-atom/OP_USHR_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_USHR_INT.S
-    */
-
-%include "x86-atom/binopS.S" {"instr":"shr     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_USHR_INT_2ADDR.S b/vm/mterp/x86-atom/OP_USHR_INT_2ADDR.S
deleted file mode 100644
index 9ee9c66..0000000
--- a/vm/mterp/x86-atom/OP_USHR_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_USHR_INT_2ADDR.S
-    */
-
-%include "x86-atom/binopS2addr.S" {"instr":"shr     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_USHR_INT_LIT8.S b/vm/mterp/x86-atom/OP_USHR_INT_LIT8.S
deleted file mode 100644
index 5a54df7..0000000
--- a/vm/mterp/x86-atom/OP_USHR_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_USHR_INT_LIT8.S
-    */
-
-%include "x86-atom/binopLit8S.S" {"instr":"shr     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_USHR_LONG.S b/vm/mterp/x86-atom/OP_USHR_LONG.S
deleted file mode 100644
index 1c404f0..0000000
--- a/vm/mterp/x86-atom/OP_USHR_LONG.S
+++ /dev/null
@@ -1,39 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_USHR_LONG.S
-    *
-    * Code: Performs an unsigned shift right long operation. Uses no substitutions.
-    *
-    * For: ushr-long
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where one is the shift amount and the other is the value to shift.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_CC    1, %eax                 # %eax<- CC
-    FETCH_BB    1, %edx                 # %edx<- BB
-    movsd        .LshiftMask, %xmm2     # %xmm2<- mask for the shift bits
-    movss       (rFP, %eax, 4), %xmm0   # %xmm0<- vCC
-    pand        %xmm2, %xmm0            # %xmm0<- masked shift bits
-    movsd       (rFP, %edx, 4), %xmm1   # %xmm1<- vBB
-    psrlq       %xmm0, %xmm1            # %xmm1<- shifted vBB
-    movsd       %xmm1, (rFP, rINST, 4)  # vAA<- shifted vBB
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_USHR_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_USHR_LONG_2ADDR.S
deleted file mode 100644
index 31cb5bc..0000000
--- a/vm/mterp/x86-atom/OP_USHR_LONG_2ADDR.S
+++ /dev/null
@@ -1,41 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_USHR_LONG_2ADDR.S
-    *
-    * Code: Performs an unsigned shift right long operation. Uses no substiutions.
-    *
-    * For: ushr-long/2addr
-    *
-    * Description: Perform a binary shift operation using two source registers
-    *              where the fist is the value to shift and the second is the
-    *              shift amount. Store the result in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    andl        $$15, rINST             # rINST<- A
-    movq        .LshiftMask, %xmm2      # %xmm2<- mask for the shift bits
-    movss       (rFP, %edx, 4),  %xmm0  # %xmm0<- vB
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vA
-    pand        %xmm2, %xmm0            # %xmm0<- masked shift bits
-    psrlq       %xmm0, %xmm1            # %xmm1<- shifted vA
-    movq        %xmm1, (rFP, rINST, 4)  # vA<- shifted vA
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_XOR_INT.S b/vm/mterp/x86-atom/OP_XOR_INT.S
deleted file mode 100644
index d36b83f..0000000
--- a/vm/mterp/x86-atom/OP_XOR_INT.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_INT.S
-    */
-
-%include "x86-atom/binop.S" {"instr":"xor     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_XOR_INT_2ADDR.S b/vm/mterp/x86-atom/OP_XOR_INT_2ADDR.S
deleted file mode 100644
index 0bab865..0000000
--- a/vm/mterp/x86-atom/OP_XOR_INT_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_INT_2ADDR.S
-    */
-
-%include "x86-atom/binop2addr.S" {"instr":"xor     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_XOR_INT_LIT16.S b/vm/mterp/x86-atom/OP_XOR_INT_LIT16.S
deleted file mode 100644
index a26bcc5..0000000
--- a/vm/mterp/x86-atom/OP_XOR_INT_LIT16.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_INT_LIT16.S
-    */
-
-%include "x86-atom/binopLit16.S" {"instr":"xor     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_XOR_INT_LIT8.S b/vm/mterp/x86-atom/OP_XOR_INT_LIT8.S
deleted file mode 100644
index 9a3c8e3..0000000
--- a/vm/mterp/x86-atom/OP_XOR_INT_LIT8.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_INT_LIT8.S
-    */
-
-%include "x86-atom/binopLit8.S" {"instr":"xor     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_XOR_LONG.S b/vm/mterp/x86-atom/OP_XOR_LONG.S
deleted file mode 100644
index 58a8384..0000000
--- a/vm/mterp/x86-atom/OP_XOR_LONG.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_LONG.S
-    */
-
-%include "x86-atom/binopWide.S" {"instr":"pxor   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_XOR_LONG_2ADDR.S b/vm/mterp/x86-atom/OP_XOR_LONG_2ADDR.S
deleted file mode 100644
index 6b42cbd..0000000
--- a/vm/mterp/x86-atom/OP_XOR_LONG_2ADDR.S
+++ /dev/null
@@ -1,20 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: OP_XOR_LONG_2ADDR.S
-    */
-
-%include "x86-atom/binopWide2addr.S" {"instr":"pxor   %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/TODO.txt b/vm/mterp/x86-atom/TODO.txt
deleted file mode 100644
index 4dfa06b..0000000
--- a/vm/mterp/x86-atom/TODO.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-Items requiring attention:
-
-(hi) Add gc card marking to aput/iput/sput/new_filled_array
-(hi) Correct stack overflow handling (dvmCleanupStackOverflow takes an
-     additional argument now)
-(hi) WITH_DEBUGGER and WITH_PROFILER are no longer defined (but are
-     assumed to be enabled)
-(hi) Rename dvmJitGetCodeAddr to dvmJitGetTraceAddr.
-(hi) Remove references to rGLUE and replace with rSELF
-(hi) Rework interpreter to co-exist the new switching model which
-     elminiates a separate debug interpreter.  Needs a dedicated
-     rIBASE register (or alternate switching model with variable
-     handler base).
-(hi) Add dvmReportXXXX()" calls in footer.cpp to support profilers &
-     debuggers.
-(hi) Set self->debugIsMethodEntry in invoke code.
-
-(md) Correct OP_MONITOR_EXIT (need to adjust PC before throw)
-(md) OP_THROW needs to export the PC
-(md) Use dvmThrowArrayIndexOutOfBoundsException(length, index) for
-     array bounds errors.
-(md) Use dvmThrowClassCastException(actual, desired) for class cast errors.
-(md) Use dvmThrowArrayStoreExceptionIncompatibleElement(actual, desired)
-     for array store errors.
-(md) Use dvmThrowNegativeArraySizeException(len) forarray alloc errors
-(md) Replace any remaining use of dvmThrowException with proper helper function
-
-(lo) Implement OP_BREAKPOINT
-(lo) Implement OP_*_VOLATILE (12 instructions)
-(lo) Implement OP_RETURN_VOID_BARRIER
-(lo) Implement OP_INVOKE_OBJECT_INIT
-(lo) Implement dvmJitScanAllClassPointers
diff --git a/vm/mterp/x86-atom/bincmp.S b/vm/mterp/x86-atom/bincmp.S
deleted file mode 100644
index a8fbed5..0000000
--- a/vm/mterp/x86-atom/bincmp.S
+++ /dev/null
@@ -1,44 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: bincmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform.
-    *
-    * For: if-eq, if-ge, if-gt, if-le, if-lt, if-ne
-    *
-    * Description: Branch to the given destination if the comparison
-    *              test between the given registers values is true.
-    *
-    * Format: B|A|op CCCC (22t)
-    *
-    * Syntax: op vA, vB, +CCCC
-    */
-
-    movl        rINST,  %eax            # %eax<- BA
-    andl        $$15, rINST             # rINST<- A
-    shr         $$4, %eax               # %eax<- B
-    GET_VREG    rINST                   # rINST<- vA
-    movl        $$4, %edx               # %edx<- 4
-    cmp         (rFP, %eax, 4), rINST   # compare vA and vB
-    j${revcmp}  1f                      # goto next instruction if reverse
-                                        # comparison is true
-    FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
-    sal         $$1, %edx
-    js          common_periodicChecks_backwardBranch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
diff --git a/vm/mterp/x86-atom/binop.S b/vm/mterp/x86-atom/binop.S
deleted file mode 100644
index 1706b72..0000000
--- a/vm/mterp/x86-atom/binop.S
+++ /dev/null
@@ -1,39 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    * For: add-int, and-int, mul-int, or-int, sub-int, xor-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    GET_VREG    %edx                    # %edx<- vCC
-    $instr                              # %ecx<- vBB op vCC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binop2addr.S b/vm/mterp/x86-atom/binop2addr.S
deleted file mode 100644
index b26b25a..0000000
--- a/vm/mterp/x86-atom/binop2addr.S
+++ /dev/null
@@ -1,45 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binop2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%ecx = %ecx op %edx".
-    *
-    * For: add-int/2addr, and-int/2addr, mul-int/2addr, or-int/2addr,
-    *      sub-int/2addr, xor-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    andl        $$15, rINST             # rINST<- A
-    movl        rINST, %ecx             # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vB
-    GET_VREG    %ecx                    # %ecx<- vA
-    $instr                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-
-
diff --git a/vm/mterp/x86-atom/binopD.S b/vm/mterp/x86-atom/binopD.S
deleted file mode 100644
index 20a2e9a..0000000
--- a/vm/mterp/x86-atom/binopD.S
+++ /dev/null
@@ -1,61 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopD.S
-    *
-    * Code: 32-bit integer divide operation. If "div" is set, the code
-    *       returns the quotient, else it returns the remainder.
-    *       Also, a divide-by-zero check is done.
-    *
-    * For: div-int, rem-int
-    *
-    * Description: Perform a binary operation on two source
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-%default {"div":"1"}
-
-    FETCH_BB    1, %eax                 # %eax<- BB
-    FETCH_CC    1, %ecx                 # %ecx<- CC
-    GET_VREG    %eax                    # %eax<- vBB
-    GET_VREG    %ecx                    # %ecx<- vCC
-    cmp         $$0, %ecx               # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    cmpl        $$-1, %ecx              # handle -1 special case divide error
-    jne         .L${opcode}_noerror
-    cmpl        $$0x80000000,%eax       # handle min int special case divide error
-    je         .L${opcode}_break
-.L${opcode}_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-    .if  $div
-    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    .endif
-    jmp         .L${opcode}_break2
-%break
-.L${opcode}_break:
-    .if  $div
-    movl        $$0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $$0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-.L${opcode}_break2:
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/binopD2addr.S b/vm/mterp/x86-atom/binopD2addr.S
deleted file mode 100644
index 392b46b..0000000
--- a/vm/mterp/x86-atom/binopD2addr.S
+++ /dev/null
@@ -1,68 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopD2addr.S
-    *
-    * Code: 32-bit "/2addr" integer divde operation. If "div"
-    *       is set, the code returns the quotient, else it returns
-    *       the remainder. Also, a divide-by-zero check is done.
-    *
-    * For: div-int/2addr, rem-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-%default {"div":"1"}
-    movl        rINST, %ecx             # %ecx<- BA
-    andl        $$15, rINST             # rINST<- A, to be used as dest
-    movl        rINST, %eax             # %eax<- A
-    shr         $$4, %ecx               # %ecx<- B
-    GET_VREG    %eax                    # %eax<- vA
-    GET_VREG    %ecx                    # %edx<- vB
-    cmp         $$0, %ecx               # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    cmpl        $$-1, %ecx              # handle -1 special case divide error
-    jne         .L${opcode}_noerror
-    cmpl        $$0x80000000,%eax       # handle min int special case divide error
-    je         .L${opcode}_break
-.L${opcode}_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-     .if  $div
-    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    .endif
-    jmp         .L${opcode}_break2
-    #FFETCH_ADV 1, %edx  # %ecx<- next instruction hi; fetch, advance
-    #FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
-%break
-.L${opcode}_break:
-    .if  $div
-    movl        $$0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $$0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-.L${opcode}_break2:
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
-
diff --git a/vm/mterp/x86-atom/binopDLit16.S b/vm/mterp/x86-atom/binopDLit16.S
deleted file mode 100644
index 3e67d0a..0000000
--- a/vm/mterp/x86-atom/binopDLit16.S
+++ /dev/null
@@ -1,66 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDLit16.S
-    *
-    * Code: 32-bit "lit16" divide operation. If "div" is set, the code
-    *       returns the quotient, else it returns the remainder.
-    *       Also, a divide-by-zero check is done.
-    *
-    * For: div-int/lit16, rem-int/lit16
-    *
-    * Description: Perform a binary operation on a register and a
-    *              sign extended 16-bit literal value
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-%default {"div":"1"}
-
-    movl        rINST, %eax             # %eax<- BA
-    shr         $$4, %eax               # %eax<- B
-    FETCHs      1, %ecx                 # %ecx<- +CCCC, sign-extended literal
-    cmp         $$0, %ecx               # check for divide by zero
-    GET_VREG    %eax                    # %eax<- vB
-    je          common_errDivideByZero  # handle divide by zero
-    andl        $$15, rINST             # rINST<- A
-    cmpl        $$-1, %ecx              # handle -1 special case divide error
-    jne         .L${opcode}_noerror
-    cmpl        $$0x80000000,%eax       # handle min int special case divide error
-    je         .L${opcode}_break
-.L${opcode}_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    .if  $div
-    SET_VREG    %eax rINST              # vA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vA<- %edx (remainder)
-    .endif
-    jmp         .L${opcode}_break2
-
-%break
-.L${opcode}_break:
-    .if  $div
-    movl        $$0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $$0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-.L${opcode}_break2:
-
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/binopDLit8.S b/vm/mterp/x86-atom/binopDLit8.S
deleted file mode 100644
index f197714..0000000
--- a/vm/mterp/x86-atom/binopDLit8.S
+++ /dev/null
@@ -1,65 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDLit8.S
-    *
-    * Code: 32-bit "lit8" divide operation. If "div" is set, the code
-    *       returns the quotient, else it returns the remainder.
-    *       Also, a divide-by-zero check is done.
-    *
-    * For: div-int/lit8, rem-int/lit8
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signe extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-%default {"div":"1"}
-
-    FETCH_BB    1, %eax                 # %eax<- BB
-    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
-    cmp         $$0, %ecx               # check for divide by zero
-    GET_VREG    %eax                    # %eax<- vBB
-    je          common_errDivideByZero  # handle divide by zero
-
-    cmpl        $$-1, %ecx              # handle -1 special case divide error
-    jne         .L${opcode}_noerror
-    cmpl        $$0x80000000,%eax       # handle min int special case divide error
-    je         .L${opcode}_break
-.L${opcode}_noerror:
-    cdq                                 # sign-extend %eax to %edx
-    idiv        %ecx                    # divide %edx:%eax by %ecx
-    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    .if  $div
-    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    .else
-    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    .endif
-    jmp         .L${opcode}_break2
-%break
-.L${opcode}_break:
-    .if  $div
-    movl        $$0x80000000, (rFP, rINST, 4) # vAA<- min int
-    .else
-    movl        $$0, (rFP, rINST, 4)    # vAA<- 0
-    .endif
-
-.L${opcode}_break2:
-    FINISH      2                       # jump to next instruction
-    #FGETOP_JMP 2, %ecx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopDivRemLong.S b/vm/mterp/x86-atom/binopDivRemLong.S
deleted file mode 100644
index 93ed4f8..0000000
--- a/vm/mterp/x86-atom/binopDivRemLong.S
+++ /dev/null
@@ -1,52 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDivRemLong.S
-    *
-    * Code: 64-bit long divide operation. Variable
-    *       "func" defines the function called to do the operation.
-    *
-    * For: div-long, rem-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-%default {"func":"__divdi3"}
-
-    FETCH_CC    1, %edx                 # %edx<- CC
-    movl        (rFP, %edx, 4), %eax    # %eax<- vCC
-    movl        4(rFP, %edx, 4), %ecx   # %ecx<- vCC+1
-    movl        %eax, -8(%esp)          # push arg vCC
-    or          %ecx, %eax              # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    FETCH_BB    1, %edx                 # %edx<- BB
-    movl        %ecx, -4(%esp)          # push arg vCC+1
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vBB,vBB+1
-    jmp         .L${opcode}_finish
-%break
-.L${opcode}_finish:
-    movq        %xmm0, -16(%esp)        # push arg vBB,vBB+1
-    lea         -16(%esp), %esp
-    call        $func                   # call func
-    lea         16(%esp), %esp
-    movl        %eax, (rFP, rINST, 4)   # vAA<- return low
-    movl        %edx, 4(rFP, rINST, 4)  # vAA+1<- return high
-    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/binopDivRemLong2Addr.S b/vm/mterp/x86-atom/binopDivRemLong2Addr.S
deleted file mode 100644
index aa427de..0000000
--- a/vm/mterp/x86-atom/binopDivRemLong2Addr.S
+++ /dev/null
@@ -1,54 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopDivRemLong2Addr.S
-    *
-    * Code: 64-bit "/2addr" long divide operation. Variable
-    *       "func" defines the function called to do the operation.
-    *
-    * For: div-long/2addr, rem-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register.
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-%default {"func":"__divdi3"}
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    and         $$15, rINST             # rINST<- A
-    movl        (rFP, %edx, 4), %eax    # %eax<- vB
-    movl        %eax, -12(%esp)         # push arg vB
-    movl        4(rFP, %edx, 4), %ecx   # %ecx<- vB+1
-    or          %ecx, %eax              # check for divide by zero
-    je          common_errDivideByZero  # handle divide by zero
-    movl        %ecx, -8(%esp)          # push arg vB+1
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vA,vA+1
-    jmp         .L${opcode}_break
-%break
-.L${opcode}_break:
-    movq        %xmm0, -20(%esp)        # push arg vA, vA+1
-    lea         -20(%esp), %esp
-    call        $func                   # call func
-    lea         20(%esp), %esp
-    movl        %eax, (rFP, rINST, 4)   # vA<- return low
-    movl        %edx, 4(rFP, rINST, 4)  # vA<- return high
-    FFETCH_ADV  1, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    FGETOP_JMP 1, %ecx                  # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopF.S b/vm/mterp/x86-atom/binopF.S
deleted file mode 100644
index 0c07b97..0000000
--- a/vm/mterp/x86-atom/binopF.S
+++ /dev/null
@@ -1,39 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopF.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-float, mul-float, sub-float
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movss       (rFP, %ecx, 4), %xmm0   # %xmm0<-vBB
-    movss       (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    $instr                              # %xmm0<- vBB op vCC
-    movss       %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopF2addr.S b/vm/mterp/x86-atom/binopF2addr.S
deleted file mode 100644
index 135ca0c..0000000
--- a/vm/mterp/x86-atom/binopF2addr.S
+++ /dev/null
@@ -1,41 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopF2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0 = %xmm0 op %xmm1".
-    *
-    * For: add-float/2addr, mul-float/2addr, sub-float/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    andl        $$15, %ecx              # %ecx<- A
-    shr         $$4, rINST              # rINST<- B
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
-    movss       (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
-    movss       (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    $instr                              # %xmm0<- vA op vB
-    movss       %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopLit16.S b/vm/mterp/x86-atom/binopLit16.S
deleted file mode 100644
index 4972b4d..0000000
--- a/vm/mterp/x86-atom/binopLit16.S
+++ /dev/null
@@ -1,43 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit16.S
-    *
-    * Code: 32-bit "lit16" operation. Provides an "instr" line to
-    *       specify an instruction that performs "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit16, and-int/lit16, mul-int/lit16, or-int/lit16
-    *      xor-int/lit16
-    *
-    * Description: Perform a binary operation on a register and a
-    *              sign extended 16-bit literal value and store the
-    *              result in a destination register.
-    *
-    * Format: B|A|op CCCC (22s)
-    *
-    * Syntax: op vA, vB, #+CCCC
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $$4, %ecx               # %ecx<- B
-    andl        $$15, rINST             # rINST<- A
-    FETCHs      1, %edx                 # %edx<- +CCCC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    $instr                              # %ecx<- vA op vB
-    SET_VREG    %ecx, rINST             # vA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopLit8.S b/vm/mterp/x86-atom/binopLit8.S
deleted file mode 100644
index 239e443..0000000
--- a/vm/mterp/x86-atom/binopLit8.S
+++ /dev/null
@@ -1,40 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit8.S
-    *
-    * Code: 32-bit "lit8" divide operation. Provides an "instr" line
-    *       to specify an instruction that performs  "%ecx = %ecx op %edx"
-    *
-    *
-    * For: add-int/lit8, and-int/lit8, mul-int/lit8, or-int/lit8
-    *      xor-int/lit8
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signed extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CCs   1, %edx                 # %edx<- +CC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    $instr                              # %ecx<- vBB op +CC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopLit8S.S b/vm/mterp/x86-atom/binopLit8S.S
deleted file mode 100644
index c0360aa..0000000
--- a/vm/mterp/x86-atom/binopLit8S.S
+++ /dev/null
@@ -1,40 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopLit8S.S
-    *
-    * Code: 32-bit "lit8" divide operation. Provides an "instr" line
-    *       to specify an instruction that performs "%edx = %edx op %cl"
-    *
-    *
-    * For: shl-int/lit8, shr-int/lit8, ushr-int/lit8
-    *
-    *
-    * Description: Perform a binary operation on a register and a
-    *              signed extended 8-bit literal value
-    *
-    * Format: AA|op CC|BB (22b)
-    *
-    * Syntax: op vAA, vBB, #+CC
-    */
-
-    FETCH_BB    1, %edx                 # %edx<- BB
-    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vBB
-    $instr                              # %edx<- vBB op +CC
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopS.S b/vm/mterp/x86-atom/binopS.S
deleted file mode 100644
index b09f5c2..0000000
--- a/vm/mterp/x86-atom/binopS.S
+++ /dev/null
@@ -1,39 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopS.S
-    *
-    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
-    *       specify an instruction that performs "%edx = %edx op %cl"
-    *
-    * For: shl-int, shr-int, ushr-int
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %edx                 # %edx<- BB
-    FETCH_CC    1, %ecx                 # %ecx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %edx                    # %edx<- vBB
-    GET_VREG    %ecx                    # %ecx<- vCC
-    $instr                              # %edx<- vBB op +CC
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopS2addr.S b/vm/mterp/x86-atom/binopS2addr.S
deleted file mode 100644
index 0c3c29a..0000000
--- a/vm/mterp/x86-atom/binopS2addr.S
+++ /dev/null
@@ -1,42 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopS2addr.S
-    *
-    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%edx = %edx op %cl".
-    *
-    * For: shl-int/2addr, shr-int/2addr, ushr-int/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %ecx             # %ecx<- BA
-    shr         $$4, %ecx               # %ecx<- B
-    andl        $$15, rINST             # rINST<- A
-    movl        rINST, %edx             # %edx<- A
-    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    GET_VREG    %edx                    # %edx<- vA
-    $instr                              # %edx<- vA op vB
-    SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopWide.S b/vm/mterp/x86-atom/binopWide.S
deleted file mode 100644
index 3cd3e52..0000000
--- a/vm/mterp/x86-atom/binopWide.S
+++ /dev/null
@@ -1,40 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide.S
-    *
-    * Code: Generic 64-bit binary operation.  Provides an "instr" variable to
-    *       specify an instruction that performs "%xmm0 = %xmm0 op %xmm1"
-    *
-    * For: add-double, add-long, and-long, mul-double, or-long,
-    *      sub-double, sub-long, xor-long
-    *
-    * Description: Perform a binary operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
-    */
-
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
-    movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
-    $instr                              # %xmm0<- vBB op vCC
-    movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopWide2addr.S b/vm/mterp/x86-atom/binopWide2addr.S
deleted file mode 100644
index f9aa29c..0000000
--- a/vm/mterp/x86-atom/binopWide2addr.S
+++ /dev/null
@@ -1,41 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: binopWide2addr.S
-    *
-    * Code: Generic 64-bit "/2addr" binary operation.  Provides an
-    *       "instr" line to specify an instruction that performs
-    *       "%xmm0= %xmm0 op %xmm1".
-    *
-    * For: add-double/2addr, add-long/2addr, and-long/2addr, mul-long/2addr,
-    *      or-long/2addr, sub-double/2addr, sub-long/2addr, xor-long/2addr
-    *
-    * Description: Perform a binary operation on two sources registers
-    *              and store the result in the first source register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, rINST              # rINST<- B
-    andl        $$15, %edx              # %edx<- A
-    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
-    movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
-    $instr                              # %xmm0<- vA op vB
-    movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/entry.S b/vm/mterp/x86-atom/entry.S
deleted file mode 100644
index e68e49e..0000000
--- a/vm/mterp/x86-atom/entry.S
+++ /dev/null
@@ -1,384 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: entry.S
-    */
-
-#define ASSIST_DEBUGGER 1
-    .text
-    .align      2
-    .global     dvmMterpStdRun
-    .type       dvmMterpStdRun, %function
-
-   /*
-    * Save registers, initialize sp and fp.
-    * On entry:
-    *     bool MterpGlue(glue *)
-    */
-
-    .macro      MTERP_ENTRY
-    movl        4(%esp), %ecx           # get first argument
-    movl        %ebp, -4(%esp)          # save caller base pointer
-    movl        %ebx, -8(%esp)          # save %ebx
-    movl        %esi, -12(%esp)         # save %esi
-    movl        %edi, -16(%esp)         # save %edi
-    lea         -40(%esp), %ebp         # set callee base pointer
-    lea         -40(%esp), %esp         # set callee stack pointer
-    .endm
-
-   /*
-    * Restore registers.
-    * This function returns a boolean "changeInterp" value.
-    * The return value is from dvmMterpStdBail().
-    */
-
-    .macro      MTERP_EXIT
-    lea         40(%esp), %esp          # correct stack pointer
-    movl        -16(%esp), %edi         # restore %edi
-    movl        -12(%esp), %esi         # restore %esi
-    movl        -8(%esp), %ebx          # restore %ebx
-    movl        -4(%esp), %ebp          # restore caller base pointer
-    ret                                 # return
-    .endm
-
-   /*
-    * DvmMterpStdRun entry point: save stack pointer, setup memory locations, get
-    * entry point, start executing instructions.
-    */
-
-dvmMterpStdRun:
-    MTERP_ENTRY
-    movl        %ecx, rGLUE             # save value for pMterpGlue
-    movl        offGlue_pc(%ecx), rPC   # get program counter
-    cmp         $$kInterpEntryInstr, offGlue_entryPoint(%ecx) # check instruction
-    movl        offGlue_fp(%ecx), rFP   # get frame pointer
-    movl        %esp, offGlue_bailPtr(%ecx) # save SP for eventual return
-    FFETCH      %edx                    # %edx<- opcode
-    jne         .Lnot_instr             # no, handle it
-    FGETOP_JMPa %edx                    # start executing the instruction at rPC
-
-   /*
-    * Not an instruction. Are we returning from a method?
-    */
-
-.Lnot_instr:
-    cmpl        $$kInterpEntryReturn, offGlue_entryPoint(%ecx)
-    je          common_returnFromMethod
-
-   /*
-    * No, are we throwing an exception?
-    */
-
-.Lnot_return:
-    cmpl        $$kInterpEntryThrow, offGlue_entryPoint(%ecx)
-    je          common_exceptionThrown
-
-   /*
-    * No, then we must abort.
-    */
-
-.Lbad_arg:
-    pushl       offGlue_entryPoint(%ecx)
-    movl        $$.LstrBadEntryPoint, -4(%esp)
-    lea         -4(%esp), %esp
-    call        printf
-    lea         8(%esp), %esp
-    call        dvmAbort                # call (void)
-
-   /*
-    * Restore the stack pointer and PC from the save point established on entry and
-    * return to whoever called dvmMterpStdRun.
-    *
-    * On entry:
-    *  4(%esp) MterpGlue* glue
-    *  8(%esp) bool changeInterp
-    */
-
-    .global     dvmMterpStdBail
-    .type       dvmMterpStdBail, %function
-
-dvmMterpStdBail:
-    movl        4(%esp), %ecx           # get first argument
-    movl        8(%esp), %eax           # get second argument
-    movl        offGlue_bailPtr(%ecx), %esp # sp <- saved SP
-    MTERP_EXIT
-
-   /*
-    * String references.
-    */
-
-.LstrBadEntryPoint:
-    .asciz "Bad entry point %d\n"
-
-
-dvmAsmInstructionJmpTable = .LdvmAsmInstructionJmpTable
-.LdvmAsmInstructionJmpTable:
-.long .L_OP_NOP
-.long .L_OP_MOVE
-.long .L_OP_MOVE_FROM16
-.long .L_OP_MOVE_16
-.long .L_OP_MOVE_WIDE
-.long .L_OP_MOVE_WIDE_FROM16
-.long .L_OP_MOVE_WIDE_16
-.long .L_OP_MOVE_OBJECT
-.long .L_OP_MOVE_OBJECT_FROM16
-.long .L_OP_MOVE_OBJECT_16
-.long .L_OP_MOVE_RESULT
-.long .L_OP_MOVE_RESULT_WIDE
-.long .L_OP_MOVE_RESULT_OBJECT
-.long .L_OP_MOVE_EXCEPTION
-.long .L_OP_RETURN_VOID
-.long .L_OP_RETURN
-.long .L_OP_RETURN_WIDE
-.long .L_OP_RETURN_OBJECT
-.long .L_OP_CONST_4
-.long .L_OP_CONST_16
-.long .L_OP_CONST
-.long .L_OP_CONST_HIGH16
-.long .L_OP_CONST_WIDE_16
-.long .L_OP_CONST_WIDE_32
-.long .L_OP_CONST_WIDE
-.long .L_OP_CONST_WIDE_HIGH16
-.long .L_OP_CONST_STRING
-.long .L_OP_CONST_STRING_JUMBO
-.long .L_OP_CONST_CLASS
-.long .L_OP_MONITOR_ENTER
-.long .L_OP_MONITOR_EXIT
-.long .L_OP_CHECK_CAST
-.long .L_OP_INSTANCE_OF
-.long .L_OP_ARRAY_LENGTH
-.long .L_OP_NEW_INSTANCE
-.long .L_OP_NEW_ARRAY
-.long .L_OP_FILLED_NEW_ARRAY
-.long .L_OP_FILLED_NEW_ARRAY_RANGE
-.long .L_OP_FILL_ARRAY_DATA
-.long .L_OP_THROW
-.long .L_OP_GOTO
-.long .L_OP_GOTO_16
-.long .L_OP_GOTO_32
-.long .L_OP_PACKED_SWITCH
-.long .L_OP_SPARSE_SWITCH
-.long .L_OP_CMPL_FLOAT
-.long .L_OP_CMPG_FLOAT
-.long .L_OP_CMPL_DOUBLE
-.long .L_OP_CMPG_DOUBLE
-.long .L_OP_CMP_LONG
-.long .L_OP_IF_EQ
-.long .L_OP_IF_NE
-.long .L_OP_IF_LT
-.long .L_OP_IF_GE
-.long .L_OP_IF_GT
-.long .L_OP_IF_LE
-.long .L_OP_IF_EQZ
-.long .L_OP_IF_NEZ
-.long .L_OP_IF_LTZ
-.long .L_OP_IF_GEZ
-.long .L_OP_IF_GTZ
-.long .L_OP_IF_LEZ
-.long .L_OP_UNUSED_3E
-.long .L_OP_UNUSED_3F
-.long .L_OP_UNUSED_40
-.long .L_OP_UNUSED_41
-.long .L_OP_UNUSED_42
-.long .L_OP_UNUSED_43
-.long .L_OP_AGET
-.long .L_OP_AGET_WIDE
-.long .L_OP_AGET_OBJECT
-.long .L_OP_AGET_BOOLEAN
-.long .L_OP_AGET_BYTE
-.long .L_OP_AGET_CHAR
-.long .L_OP_AGET_SHORT
-.long .L_OP_APUT
-.long .L_OP_APUT_WIDE
-.long .L_OP_APUT_OBJECT
-.long .L_OP_APUT_BOOLEAN
-.long .L_OP_APUT_BYTE
-.long .L_OP_APUT_CHAR
-.long .L_OP_APUT_SHORT
-.long .L_OP_IGET
-.long .L_OP_IGET_WIDE
-.long .L_OP_IGET_OBJECT
-.long .L_OP_IGET_BOOLEAN
-.long .L_OP_IGET_BYTE
-.long .L_OP_IGET_CHAR
-.long .L_OP_IGET_SHORT
-.long .L_OP_IPUT
-.long .L_OP_IPUT_WIDE
-.long .L_OP_IPUT_OBJECT
-.long .L_OP_IPUT_BOOLEAN
-.long .L_OP_IPUT_BYTE
-.long .L_OP_IPUT_CHAR
-.long .L_OP_IPUT_SHORT
-.long .L_OP_SGET
-.long .L_OP_SGET_WIDE
-.long .L_OP_SGET_OBJECT
-.long .L_OP_SGET_BOOLEAN
-.long .L_OP_SGET_BYTE
-.long .L_OP_SGET_CHAR
-.long .L_OP_SGET_SHORT
-.long .L_OP_SPUT
-.long .L_OP_SPUT_WIDE
-.long .L_OP_SPUT_OBJECT
-.long .L_OP_SPUT_BOOLEAN
-.long .L_OP_SPUT_BYTE
-.long .L_OP_SPUT_CHAR
-.long .L_OP_SPUT_SHORT
-.long .L_OP_INVOKE_VIRTUAL
-.long .L_OP_INVOKE_SUPER
-.long .L_OP_INVOKE_DIRECT
-.long .L_OP_INVOKE_STATIC
-.long .L_OP_INVOKE_INTERFACE
-.long .L_OP_UNUSED_73
-.long .L_OP_INVOKE_VIRTUAL_RANGE
-.long .L_OP_INVOKE_SUPER_RANGE
-.long .L_OP_INVOKE_DIRECT_RANGE
-.long .L_OP_INVOKE_STATIC_RANGE
-.long .L_OP_INVOKE_INTERFACE_RANGE
-.long .L_OP_UNUSED_79
-.long .L_OP_UNUSED_7A
-.long .L_OP_NEG_INT
-.long .L_OP_NOT_INT
-.long .L_OP_NEG_LONG
-.long .L_OP_NOT_LONG
-.long .L_OP_NEG_FLOAT
-.long .L_OP_NEG_DOUBLE
-.long .L_OP_INT_TO_LONG
-.long .L_OP_INT_TO_FLOAT
-.long .L_OP_INT_TO_DOUBLE
-.long .L_OP_LONG_TO_INT
-.long .L_OP_LONG_TO_FLOAT
-.long .L_OP_LONG_TO_DOUBLE
-.long .L_OP_FLOAT_TO_INT
-.long .L_OP_FLOAT_TO_LONG
-.long .L_OP_FLOAT_TO_DOUBLE
-.long .L_OP_DOUBLE_TO_INT
-.long .L_OP_DOUBLE_TO_LONG
-.long .L_OP_DOUBLE_TO_FLOAT
-.long .L_OP_INT_TO_BYTE
-.long .L_OP_INT_TO_CHAR
-.long .L_OP_INT_TO_SHORT
-.long .L_OP_ADD_INT
-.long .L_OP_SUB_INT
-.long .L_OP_MUL_INT
-.long .L_OP_DIV_INT
-.long .L_OP_REM_INT
-.long .L_OP_AND_INT
-.long .L_OP_OR_INT
-.long .L_OP_XOR_INT
-.long .L_OP_SHL_INT
-.long .L_OP_SHR_INT
-.long .L_OP_USHR_INT
-.long .L_OP_ADD_LONG
-.long .L_OP_SUB_LONG
-.long .L_OP_MUL_LONG
-.long .L_OP_DIV_LONG
-.long .L_OP_REM_LONG
-.long .L_OP_AND_LONG
-.long .L_OP_OR_LONG
-.long .L_OP_XOR_LONG
-.long .L_OP_SHL_LONG
-.long .L_OP_SHR_LONG
-.long .L_OP_USHR_LONG
-.long .L_OP_ADD_FLOAT
-.long .L_OP_SUB_FLOAT
-.long .L_OP_MUL_FLOAT
-.long .L_OP_DIV_FLOAT
-.long .L_OP_REM_FLOAT
-.long .L_OP_ADD_DOUBLE
-.long .L_OP_SUB_DOUBLE
-.long .L_OP_MUL_DOUBLE
-.long .L_OP_DIV_DOUBLE
-.long .L_OP_REM_DOUBLE
-.long .L_OP_ADD_INT_2ADDR
-.long .L_OP_SUB_INT_2ADDR
-.long .L_OP_MUL_INT_2ADDR
-.long .L_OP_DIV_INT_2ADDR
-.long .L_OP_REM_INT_2ADDR
-.long .L_OP_AND_INT_2ADDR
-.long .L_OP_OR_INT_2ADDR
-.long .L_OP_XOR_INT_2ADDR
-.long .L_OP_SHL_INT_2ADDR
-.long .L_OP_SHR_INT_2ADDR
-.long .L_OP_USHR_INT_2ADDR
-.long .L_OP_ADD_LONG_2ADDR
-.long .L_OP_SUB_LONG_2ADDR
-.long .L_OP_MUL_LONG_2ADDR
-.long .L_OP_DIV_LONG_2ADDR
-.long .L_OP_REM_LONG_2ADDR
-.long .L_OP_AND_LONG_2ADDR
-.long .L_OP_OR_LONG_2ADDR
-.long .L_OP_XOR_LONG_2ADDR
-.long .L_OP_SHL_LONG_2ADDR
-.long .L_OP_SHR_LONG_2ADDR
-.long .L_OP_USHR_LONG_2ADDR
-.long .L_OP_ADD_FLOAT_2ADDR
-.long .L_OP_SUB_FLOAT_2ADDR
-.long .L_OP_MUL_FLOAT_2ADDR
-.long .L_OP_DIV_FLOAT_2ADDR
-.long .L_OP_REM_FLOAT_2ADDR
-.long .L_OP_ADD_DOUBLE_2ADDR
-.long .L_OP_SUB_DOUBLE_2ADDR
-.long .L_OP_MUL_DOUBLE_2ADDR
-.long .L_OP_DIV_DOUBLE_2ADDR
-.long .L_OP_REM_DOUBLE_2ADDR
-.long .L_OP_ADD_INT_LIT16
-.long .L_OP_RSUB_INT
-.long .L_OP_MUL_INT_LIT16
-.long .L_OP_DIV_INT_LIT16
-.long .L_OP_REM_INT_LIT16
-.long .L_OP_AND_INT_LIT16
-.long .L_OP_OR_INT_LIT16
-.long .L_OP_XOR_INT_LIT16
-.long .L_OP_ADD_INT_LIT8
-.long .L_OP_RSUB_INT_LIT8
-.long .L_OP_MUL_INT_LIT8
-.long .L_OP_DIV_INT_LIT8
-.long .L_OP_REM_INT_LIT8
-.long .L_OP_AND_INT_LIT8
-.long .L_OP_OR_INT_LIT8
-.long .L_OP_XOR_INT_LIT8
-.long .L_OP_SHL_INT_LIT8
-.long .L_OP_SHR_INT_LIT8
-.long .L_OP_USHR_INT_LIT8
-.long .L_OP_IGET_VOLATILE
-.long .L_OP_IPUT_VOLATILE
-.long .L_OP_SGET_VOLATILE
-.long .L_OP_SPUT_VOLATILE
-.long .L_OP_IGET_OBJECT_VOLATILE
-.long .L_OP_IGET_WIDE_VOLATILE
-.long .L_OP_IPUT_WIDE_VOLATILE
-.long .L_OP_SGET_WIDE_VOLATILE
-.long .L_OP_SPUT_WIDE_VOLATILE
-.long .L_OP_BREAKPOINT
-.long .L_OP_THROW_VERIFICATION_ERROR
-.long .L_OP_EXECUTE_INLINE
-.long .L_OP_EXECUTE_INLINE_RANGE
-.long .L_OP_INVOKE_OBJECT_INIT_RANGE
-.long .L_OP_RETURN_VOID_BARRIER
-.long .L_OP_IGET_QUICK
-.long .L_OP_IGET_WIDE_QUICK
-.long .L_OP_IGET_OBJECT_QUICK
-.long .L_OP_IPUT_QUICK
-.long .L_OP_IPUT_WIDE_QUICK
-.long .L_OP_IPUT_OBJECT_QUICK
-.long .L_OP_INVOKE_VIRTUAL_QUICK
-.long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE
-.long .L_OP_INVOKE_SUPER_QUICK
-.long .L_OP_INVOKE_SUPER_QUICK_RANGE
-.long .L_OP_IPUT_OBJECT_VOLATILE
-.long .L_OP_SGET_OBJECT_VOLATILE
-.long .L_OP_SPUT_OBJECT_VOLATILE
-.long .L_OP_UNUSED_FF
diff --git a/vm/mterp/x86-atom/footer.S b/vm/mterp/x86-atom/footer.S
deleted file mode 100644
index ab4e63d..0000000
--- a/vm/mterp/x86-atom/footer.S
+++ /dev/null
@@ -1,663 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: footer.S
-    */
-
-    .text
-    .align      2
-
-   /*
-    * Check to see if the thread needs to be suspended or debugger/profiler
-    * activity has begun.
-    *
-    * On entry:
-    *  %ecx is reentry type, e.g. kInterpEntryInstr
-    *  %edx is PC adjustment in bytes
-    */
-
-common_periodicChecks:
-    movl        %edx, -8(%esp)          # save pc adjustments
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        %ebx, -4(%esp)          # save %ebx to the stack
-    movl        offGlue_pSelfSuspendCount(%edx), %ebx # %ebx<- pSuspendCount (int)
-4:
-    movl        offGlue_pDebuggerActive(%edx), %eax # %eax<- pDebuggerActive
-    testl       %eax, %eax
-    je          5f
-    movzbl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
-5:
-    cmp         $$0, (%ebx)             # check if suspend is pending
-    jne         2f                      # handle suspend
-    movl        offGlue_pActiveProfilers(%edx), %ebx # %ebx<- activeProfilers (int)
-    orl         (%ebx), %eax            # %eax<- merge activeProfilers and debuggerActive
-    movl        -8(%esp), %edx          # %edx<- restore %edx
-    jne         3f                      # debugger or profiler active; switch interp
-    movl        -4(%esp), %ebx          # %ebx<- restore %ebx
-    ret                                 # return
-2:                                      # check suspended
-    EXPORT_PC
-    movl        offGlue_self(%edx), %eax # %eax<- glue->self
-    movl        %eax, -12(%esp)         # push parameter boolean
-    lea         -12(%esp), %esp
-    call        dvmCheckSuspendPending  # call: (Thread* self)
-                                        # return: bool
-    movl        4(%esp), %edx           # %edx<- restore %edx
-    movl        8(%esp), %ebx           # %ebx<- restore %ebx
-    lea         12(%esp), %esp
-    ret
-3:                                      # debugger/profiler enabled, bail out
-    leal        (rPC, %edx, 2), rPC     # adjust pc to show target
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movb        $$kInterpEntryInstr, offGlue_entryPoint(%ecx)
-    movl        $$1, %edx               # switch interpreter
-    jmp         common_gotoBail         # bail
-
-   /*
-    * Check to see if the thread needs to be suspended or debugger/profiler
-    * activity has begun. With this variant, the reentry type is hard coded
-    * as kInterpEntryInstr.
-    *
-    * On entry:
-    *  %edx is PC adjustment in bytes
-    */
-
-common_periodicChecks_backwardBranch:
-    EXPORT_PC
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_pSelfSuspendCount(%ecx), rINST # %ebx<- pSuspendCount (int)
-4:
-    movl        offGlue_pDebuggerActive(%ecx), %eax # %eax<- pDebuggerActive
-    testl       %eax, %eax              # test for NULL pointer
-    je          5f
-    movzbl      (%eax), %eax            # %eax<- get debuggerActive count
-5:
-    cmp         $$0, (rINST)            # check if suspend is pending
-    jne         2f                      # handle suspend
-    movl        offGlue_pActiveProfilers(%ecx), rINST # %edx<- activeProfilers (int)
-    orl          (rINST), %eax           # %eax<- merge activeProfilers and debuggerActive
-    jne         3f                      # debugger or profiler active; switch interp
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-2:                                      # check suspended
-    movl        offGlue_self(%ecx), %eax# %eax<- glue->self
-    movl        %edx, rINST
-    movl        %eax, -12(%esp)         # push parameter boolean
-    lea         -12(%esp), %esp
-    call        dvmCheckSuspendPending  # call: (Thread* self)
-                                        # return: bool
-    movl        rINST, %edx             # %edx<- restore %edx
-    lea         12(%esp), %esp
-    FINISH_RB   %edx, %ecx
-3:                                      # debugger/profiler enabled, bail out
-    leal        (rPC, %edx, 2), rPC     # adjust pc to show target
-    movb        $$kInterpEntryInstr, offGlue_entryPoint(%ecx)
-    movl        $$1, %edx               # switch interpreter
-    jmp         common_gotoBail         # bail
-
-   /*
-    * The equivalent of "goto bail", this calls through the "bail handler".
-    * State registers will be saved to the "glue" area before bailing.
-    *
-    * On entry:
-    *  %edx is "bool changeInterp", indicating if we want to switch to the
-    *     other interpreter or just bail all the way out
-    */
-
-common_gotoBail:
-    SAVE_PC_FP_TO_GLUE %ecx             # save program counter and frame pointer
-
-   /*
-    * Inlined dvmMterpStdBail
-    */
-
-    lea         40(%ebp), %esp
-    movl        %edx, %eax
-    movl        24(%ebp), %edi
-    movl        28(%ebp), %esi
-    movl        32(%ebp), %ebx
-    movl        36(%ebp), %ebp
-    ret
-
-   /*
-    * Common code for method invocation with range.
-    *
-    * On entry:
-    *  %ecx is "Method* methodToCall", the method we're trying to call
-    */
-
-common_invokeMethodRange:
-.LinvokeNewRange:
-
-   /*
-    * prepare to copy args to "outs" area of current frame
-    */
-
-    SAVEAREA_FROM_FP %eax               # %eax<- &outs; &StackSaveArea
-    test        rINST, rINST            # test for no args
-    movl        rINST, sReg0            # sReg0<- AA
-    jz          .LinvokeArgsDone        # no args; jump to args done
-    FETCH       2, %edx                 # %edx<- CCCC
-
-   /*
-    * %ecx=methodToCall, %edx=CCCC, sReg0=count, %eax=&outs (&stackSaveArea)
-    * (very few methods have > 10 args; could unroll for common cases)
-    */
-
-    movl        %ebx, sReg1             # sReg1<- save %ebx
-    lea         (rFP, %edx, 4), %edx    # %edx<- &vCCCC
-    shll        $$2, sReg0              # sReg0<- offset
-    subl        sReg0, %eax             # %eax<- update &outs
-    shrl        $$2, sReg0              # sReg0<- offset
-1:
-    movl        (%edx), %ebx            # %ebx<- vCCCC
-    lea         4(%edx), %edx           # %edx<- &vCCCC++
-    subl        $$1, sReg0              # sReg<- sReg--
-    movl        %ebx, (%eax)            # *outs<- vCCCC
-    lea         4(%eax), %eax           # outs++
-    jne         1b                      # loop if count (sReg0) not zero
-    movl        sReg1, %ebx             # %ebx<- restore %ebx
-    jmp         .LinvokeArgsDone        # continue
-
-   /*
-    * %ecx is "Method* methodToCall", the method we're trying to call
-    * prepare to copy args to "outs" area of current frame
-    */
-
-common_invokeMethodNoRange:
-.LinvokeNewNoRange:
-    movl        rINST, sReg0            # sReg0<- BA
-    shrl        $$4, sReg0              # sReg0<- B
-    je          .LinvokeArgsDone        # no args; jump to args done
-    SAVEAREA_FROM_FP %eax               # %eax<- &outs; &StackSaveArea
-    FETCH       2, %edx                 # %edx<- GFED
-
-   /*
-    * %ecx=methodToCall, %edx=GFED, sReg0=count, %eax=outs
-    */
-
-.LinvokeNonRange:
-    cmp         $$2, sReg0              # compare sReg0 to 2
-    movl        %edx, sReg1             # sReg1<- GFED
-    jl          1f                      # handle 1 arg
-    je          2f                      # handle 2 args
-    cmp         $$4, sReg0              # compare sReg0 to 4
-    jl          3f                      # handle 3 args
-    je          4f                      # handle 4 args
-5:
-    andl        $$15, rINST             # rINST<- A
-    lea         -4(%eax), %eax          # %eax<- update &outs; &outs--
-    movl        (rFP, rINST, 4), %edx   # %edx<- vA
-    movl        %edx, (%eax)            # *outs<- vA
-    movl        sReg1, %edx             # %edx<- GFED
-4:
-    shr         $$12, %edx              # %edx<- G
-    lea         -4(%eax), %eax          # %eax<- update &outs; &outs--
-    movl        (rFP, %edx, 4), %edx    # %edx<- vG
-    movl        %edx, (%eax)            # *outs<- vG
-    movl        sReg1, %edx             # %edx<- GFED
-3:
-    and         $$0x0f00, %edx          # %edx<- 0F00
-    shr         $$6, %edx               # %edx<- F at correct offset
-    lea         -4(%eax), %eax          # %eax<- update &outs; &outs--
-    movl        (rFP, %edx), %edx       # %edx<- vF
-    movl        %edx, (%eax)            # *outs<- vF
-    movl        sReg1, %edx             # %edx<- GFED
-2:
-    and         $$0x00f0, %edx          # %edx<- 00E0
-    shr         $$2, %edx               # %edx<- E at correct offset
-    lea         -4(%eax), %eax          # %eax<- update &outs; &outs--
-    movl        (rFP, %edx), %edx       # %edx<- vE
-    movl        %edx, (%eax)            # *outs<- vE
-    movl        sReg1, %edx             # %edx<- GFED
-1:
-    and         $$0x000f, %edx          # %edx<- 000D
-    movl        (rFP, %edx, 4), %edx    # %edx<- vD
-    movl        %edx, -4(%eax)          # *--outs<- vD
-0:
-
-   /*
-    * %ecx is "Method* methodToCall", the method we're trying to call
-    * find space for the new stack frame, check for overflow
-    */
-
-.LinvokeArgsDone:
-    movzwl      offMethod_registersSize(%ecx), %eax # %eax<- methodToCall->regsSize
-    movzwl      offMethod_outsSize(%ecx), %edx # %edx<- methodToCall->outsSize
-    movl        %ecx, sReg0             # sReg<- methodToCall
-    shl         $$2, %eax               # %eax<- update offset
-    SAVEAREA_FROM_FP %ecx               # %ecx<- &outs; &StackSaveArea
-    subl        %eax, %ecx              # %ecx<- newFP; (old savearea - regsSize)
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        %ecx, sReg1             # sReg1<- &outs
-    subl        $$sizeofStackSaveArea, %ecx # %ecx<- newSaveArea (stack save area using newFP)
-    movl        offGlue_interpStackEnd(%eax), %eax # %eax<- glue->interpStackEnd
-    movl        %eax, sReg2             # sReg2<- glue->interpStackEnd
-    shl         $$2, %edx               # %edx<- update offset for outsSize
-    movl        %ecx, %eax              # %eax<- newSaveArea
-    sub         %edx, %ecx              # %ecx<- bottom; (newSaveArea - outsSize)
-    cmp         sReg2, %ecx             # compare interpStackEnd and bottom
-    movl        sReg0, %ecx             # %ecx<- restore methodToCall
-    jl          .LstackOverflow         # handle frame overflow
-
-   /*
-    * set up newSaveArea
-    */
-
-#ifdef EASY_GDB
-    SAVEAREA_FROM_FP %edx               # %edx<- &outs; &StackSaveArea
-    movl        %edx, offStackSaveArea_prevSave(%eax) # newSaveArea->prevSave<- &outs
-#endif
-    movl        rFP, offStackSaveArea_prevFrame(%eax) # newSaveArea->prevFrame<- rFP
-    movl        rPC, offStackSaveArea_savedPc(%eax) # newSaveArea->savedPc<- rPC
-    testl       $$ACC_NATIVE, offMethod_accessFlags(%ecx) # check for native call
-    movl        %ecx, offStackSaveArea_method(%eax) # newSaveArea->method<- method to call
-    jne         .LinvokeNative          # handle native call
-
-   /*
-    * Update "glue" values for the new method
-    * %ecx=methodToCall, sReg1=newFp
-    */
-
-    movl        offMethod_clazz(%ecx), %edx # %edx<- method->clazz
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        %ecx, offGlue_method(%eax) # glue->method<- methodToCall
-    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
-    movl        offMethod_insns(%ecx), rPC # rPC<- methodToCall->insns
-    movl        %edx, offGlue_methodClassDex(%eax) # glue->methodClassDex<- method->clazz->pDvmDex
-    movl        offGlue_self(%eax), %ecx # %ecx<- glue->self
-    movl        sReg1, rFP              # rFP<- newFP
-    movl        rFP, offThread_curFrame(%ecx) # glue->self->curFrame<- newFP
-    FINISH_A                            # jump to methodToCall->insns
-
-   /*
-    * Prep for the native call
-    * %ecx=methodToCall, sReg1=newFP, %eax=newSaveArea
-    */
-
-.LinvokeNative:
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        %ecx, -20(%esp)         # push parameter methodToCall
-    movl        offGlue_self(%edx), %edx # %edx<- glue->self
-    movl        offThread_jniLocal_topCookie(%edx), %ecx # %ecx<- glue->self->thread->refNext
-    movl        %ecx, offStackSaveArea_localRefCookie(%eax) # newSaveArea->localRefCookie<- refNext
-    movl        %eax, -4(%esp)          # save newSaveArea
-    movl        sReg1, %eax             # %eax<- newFP
-    movl        %eax, offThread_curFrame(%edx) # glue->self->curFrame<- newFP
-    movl        %edx, -8(%esp)          # save glue->self
-    movl        %edx, -16(%esp)         # push parameter glue->self
-    movl        rGLUE, %edx             # %edx<- pMterpGlue
-    movl        -20(%esp), %ecx         # %ecx<- methodToCall
-    lea         offGlue_retval(%edx), %edx # %edx<- &retval
-    movl        %edx, -24(%esp)         # push parameter pMterpGlue
-    movl        %eax, -28(%esp)         # push parameter newFP
-    lea         -28(%esp), %esp
-
-#ifdef ASSIST_DEBUGGER
-    jmp         .Lskip
-    .type       dalvik_mterp, %function
-dalvik_mterp:
-    MTERP_ENTRY
-.Lskip:
-#endif
-    call        *offMethod_nativeFunc(%ecx) # call methodToCall->nativeFunc
-    lea         28(%esp), %esp
-    movl        -4(%esp), %edx          # %edx<- newSaveArea
-    movl        -8(%esp), %ecx          # %ecx<- glue->self
-    movl        offStackSaveArea_localRefCookie(%edx), %eax  # %eax<- newSaveArea->localRefCookie
-    FFETCH_ADV  3, %edx                 # %edx<- next instruction hi; fetch, advance
-    cmp         $$0, offThread_exception(%ecx) # check for exception
-    movl        rFP, offThread_curFrame(%ecx) # glue->self->curFrame<- rFP
-    movl        %eax, offThread_jniLocal_topCookie(%ecx) # glue->self<- newSaveArea->localRefCookie
-    jne         common_exceptionThrown  # handle exception
-    FGETOP_JMP  3, %edx                 # jump to next instruction; getop, jmp
-
-.LstackOverflow:
-    movl        %ecx, -4(%esp)          # push method to call
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offGlue_self(%ecx), %ecx # %ecx<- glue->self
-    movl        %ecx, -8(%esp)          # push parameter self
-    lea         -8(%esp), %esp
-    call        dvmHandleStackOverflow  # call: (Thread* self, Method *meth)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-#ifdef ASSIST_DEBUGGER
-#endif
-
-   /*
-    * Common code for handling a return instruction.
-    *
-    * This does not return.
-    */
-
-common_returnFromMethod:
-.LreturnNew:
-
-   /*
-    * Inline common periodic checks
-    */
-
-    movl        rGLUE, rINST            # %ecx<- pMterpGlue
-    movl        offGlue_pSelfSuspendCount(rINST), %edx # %ebx<- pSuspendCount (int)
-    movl        offGlue_pDebuggerActive(rINST), %eax # %eax<- pDebuggerActive
-    testl       %eax, %eax
-    je          5f
-    movl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
-5:
-    and         $$7, %eax               # %eax<- mask for boolean (just how many bits does it take?)
-    cmp         $$0, (%edx)             # check if suspend is pending
-    jne         2f                      # handle suspend
-    movl        offGlue_pActiveProfilers(rINST), %edx # %edx<- activeProfilers (int)
-    or          (%edx), %eax            # %eax<- merge activeProfilers and debuggerActive
-    cmp         $$0, %eax               # check for debuggerActive
-    jne         3f                      # debugger or profiler active; switch interp
-    jmp         4f
-2:                                      # check suspended
-    movl        offGlue_self(rINST), %eax# %eax<- glue->self
-    movl        %eax, -12(%esp)         # push parameter boolean
-    lea         -12(%esp), %esp
-    call        dvmCheckSuspendPending  # call: (Thread* self)
-                                        # return: bool
-    lea         12(%esp), %esp
-    jmp         4f
-3:                                      # debugger/profiler enabled, bail out
-    movl        $$kInterpEntryInstr, offGlue_entryPoint(rINST) # glue->entryPoint<- reentry type
-    movl        $$1, %edx               # switch to interp<- true
-    jmp         common_gotoBail         # bail
-
-
-   /*
-    * Get save area; rGLUE is %ebx, rFP is %eax
-    */
-4:
-    SAVEAREA_FROM_FP %ecx               # %ecx<- saveArea(old)
-    movl        offStackSaveArea_prevFrame(%ecx), rFP # rFP<- saveArea->PrevFrame
-    movl        (offStackSaveArea_method - sizeofStackSaveArea)(rFP), %edx # %edx<- method we are returning to
-    cmpl        $$0, %edx               # check for break frame
-    je          common_gotoBail         # bail if break frame
-    movl        offStackSaveArea_savedPc(%ecx), rPC # rPC<- saveAreaOld->savedPc
-    movl        offGlue_self(rINST), %ecx # %eax<- glue->self
-    movl        %edx, offGlue_method(rINST) # glue->method<- newSave->method
-    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
-    FFETCH_ADV  3, %eax                 # %ecx<- next instruction hi; fetch, advance
-    movl        rFP, offThread_curFrame(%ecx) # glue->self->curFrame<- rFP
-    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
-    movl        %edx, offGlue_methodClassDex(rINST) # glue->pDvmDex<- method->clazz->pDvmDex
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
-
-   /*
-    * Handle thrown an exception. If the exception processing code
-    * returns to us (instead of falling out of the interpreter),
-    * continue with whatever the next instruction now happens to be.
-    * This does not return.
-    */
-
-common_exceptionThrown:
-.LexceptionNew:
-    movl        $$kInterpEntryThrow, %ecx # %ecx<- reentry type
-    movl        $$0, %edx               # %edx<- pc adjustment
-    call        common_periodicChecks
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_self(%eax), %edx # %edx<- glue->self
-    movl        offThread_exception(%edx), %ecx # %ecx<- pMterpGlue->self->exception
-    movl        %edx, -4(%esp)          # push parameter self
-    movl        %ecx, -8(%esp)          # push parameter obj
-    lea         -8(%esp), %esp
-    call        dvmAddTrackedAlloc      # don't allow the exception to be GC'd
-                                        # call: (Object* obj, Thread* self)
-                                        # return: void
-    movl        4(%esp), %edx           # %edx<- glue->self
-    movl        $$0, offThread_exception(%edx) # glue->self->exception<- NULL
-
-   /*
-    * set up args and a local for &fp
-    */
-
-    movl        rFP, -4(%esp)           # move fp to stack
-    lea         -4(%esp), %esp          # update %esp
-    movl        %esp, -4(%esp)          # push parameter 4<- &fp
-    movl        $$0, -8(%esp)           # push parameter 3<- false
-    movl        4(%esp), %edx
-    movl        %edx, -12(%esp)         # push parameter 2<- glue->self->exception
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_method(%eax), %edx # %edx<- glue->method
-    movl        offMethod_insns(%edx), %edx # %edx<- glue->method->insns
-    movl        rPC, %ecx               # %ecx<- rPC
-    subl        %edx, %ecx              # %ecx<- pc - glue->method->insns
-    sar         $$1, %ecx               # %ecx<- adjust %ecx for offset
-    movl        %ecx, -16(%esp)         # push parameter 1<- glue->method->insns
-    movl        8(%esp), %edx
-    movl        %edx, -20(%esp)         # push parameter 0<- glue->self
-    lea         -20(%esp), %esp
-
-   /*
-    * call dvmFindCatchBlock, %eax gets catchRelPc (a code-unit offset)
-    */
-
-    call        dvmFindCatchBlock       # call: (Thread* self, int relPc, Object* exception,
-                                        #      bool doUnroll, void** newFrame)
-                                        # return: int
-    lea         32(%esp), %esp
-    movl        -12(%esp), rFP          # rFP<- updated rFP
-    cmp         $$0, %eax               # check for catchRelPc < 0
-    jl          .LnotCaughtLocally      # handle not caught locally
-
-   /*
-    * fix stack overflow if necessary
-    */
-
-    movl        -4(%esp), %ecx          # %ecx<- glue->self
-    cmp         $$0, offThread_stackOverflowed(%ecx)
-    je          1f
-    movl        %eax, -4(%esp)          # save %eax for later
-    movl        %ecx, -12(%esp)         # push parameter 2 glue->self
-    lea         -12(%esp), %esp
-    call        dvmCleanupStackOverflow # call: (Thread* self, Object* exception)
-                                        # return: void
-    lea         12(%esp), %esp
-    movl        -4(%esp), %eax          # %eax<- restore %eax
-    jmp         2f
-1:
-    movl        %ecx, -12(%esp)         # push parameter 2 glue->self
-2:
-
-   /*
-    * adjust locals to match self->curFrame and updated PC
-    *
-    */
-
-    SAVEAREA_FROM_FP %edx               # %edx<- get newSaveArea
-    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
-    movl        offStackSaveArea_method(%edx), rPC # rPC<- newMethod
-    movl        rPC, offGlue_method(%ecx) # glue->method<- newMethod
-    movl        offMethod_clazz(rPC), %edx # %edx<- method->clazz
-    movl        offMethod_insns(rPC), rPC # rPC<- method->insns
-    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
-    lea         (rPC, %eax, 2), rPC     # rPC<- method->insns + catchRelPc
-    movl        %edx, offGlue_methodClassDex(%ecx) # glue->pDvmDex<- method->clazz->pDvmDex
-    movl        -8(%esp), %eax
-    movl        %eax, -16(%esp)         # push parameter 1 obj
-    lea         -16(%esp), %esp
-    call        dvmReleaseTrackedAlloc  # call: (Object* obj, Thread* self)
-                                        # return: void
-    lea         16(%esp), %esp
-    FINISH_FETCH %eax
-    cmp         $$OP_MOVE_EXCEPTION, %eax # is it a move exception
-    jne         1f
-    movl        -12(%esp), %edx         # %edx<- glue->self
-    movl        -8(%esp), %ecx          # %ecx<- exception
-    movl        %ecx, offThread_exception(%edx) # restore the exception
-1:
-    FINISH_JMP  %eax
-
-   /*
-    * -8(%esp) = exception, -4(%esp) = self
-    */
-
-.LnotCaughtLocally:
-    movl        -4(%esp), %edx          # %edx<- glue->self
-    movzb       offThread_stackOverflowed(%edx), %eax # %eax<- self->stackOverflowed
-    cmp         $$0, %eax               # check for stack overflow;
-                                        # maybe should use cmpb
-    je          1f                      #
-    movl        %edx, -12(%esp)         # push parameter 1 glue->self
-    lea         -12(%esp), %esp
-    call        dvmCleanupStackOverflow # call: (Thread* self, Object* exception)
-                                        # return: void
-    lea         12(%esp), %esp
-
-   /*
-    * Release the exception
-    * -8(%esp) = exception, -4(%esp) = self
-    */
-1:
-    movl        -8(%esp), %ecx          # %ecx<- exception
-    movl        -4(%esp), %edx          # %edx<- glue->self
-    movl        %ecx, offThread_exception(%edx) # glue->self<- exception
-    lea         -8(%esp), %esp
-    call        dvmReleaseTrackedAlloc  # call: (Object* obj, Thread* self)
-                                        # return: void
-    lea         8(%esp), %esp
-    movl        $$0, %edx               # switch to interp<- false
-    jmp         common_gotoBail         # bail
-
-   /*
-    * After returning from a "glued" function, pull out the updated
-    * values and start executing at the next instruction.
-    */
-
-common_resumeAfterGlueCall:
-    LOAD_PC_FP_FROM_GLUE                # pull rPC and rFP out of glue
-    FINISH_A                            # jump to next instruction
-
-   /*
-    * For debugging, cause an immediate fault.
-    */
-
-common_abort:
-    jmp         .LdeadFood
-
-.LdeadFood:
-.int 0xdeadf00d
-
-   /*
-    * Invalid array index.
-    */
-
-common_errArrayIndex:
-    EXPORT_PC
-    movl        $$.LstrArrayIndexException, -8(%esp) # push parameter description
-    movl        $$0, -4(%esp)           # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * Invalid array value.
-    */
-
-common_errArrayStore:
-    EXPORT_PC
-    movl        $$.LstrArrayStoreException, -8(%esp) # push parameter description
-    movl        $$0, -4(%esp)           # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * Integer divide or mod by zero.
-    */
-
-common_errDivideByZero:
-    EXPORT_PC
-    movl        $$.LstrArithmeticException, -8(%esp) # push parameter description
-    movl        $$.LstrDivideByZero, -4(%esp) # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * Attempt to allocate an array with a negative size.
-    */
-
-common_errNegativeArraySize:
-    EXPORT_PC
-    movl        $$.LstrNegativeArraySizeException, -8(%esp) # push parameter description
-    movl        $$0, -4(%esp)           # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * Invocation of a non-existent method.
-    */
-
-common_errNoSuchMethod:
-    EXPORT_PC
-    movl        $$.LstrNoSuchMethodError, -8(%esp) # push parameter description
-    movl        $$0, -4(%esp)           # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * Unexpected null object.
-    */
-
-common_errNullObject:
-    EXPORT_PC
-    movl        $$.LstrNullPointerException, -8(%esp) # push parameter description
-    movl        $$0, -4(%esp)           # push parameter msg paramter
-    lea         -8(%esp), %esp
-    call        dvmThrowException       # call: (const char* exceptionDescriptor, const char* msg)
-                                        # return: void
-    lea         8(%esp), %esp
-    jmp         common_exceptionThrown  # handle exception
-
-   /*
-    * String references
-    */
-
-    .align 4
-    .section .rodata
-.LstrArithmeticException:
-    .asciz "Ljava/lang/ArithmeticException;"
-.LstrArrayIndexException:
-    .asciz "Ljava/lang/ArrayIndexOutOfBoundsException;"
-.LstrArrayStoreException:
-    .asciz "Ljava/lang/ArrayStoreException;"
-.LstrDivideByZero:
-    .asciz "divide by zero"
-.LstrInstantiationError:
-    .asciz "Ljava/lang/InstantiationError;"
-.LstrNegativeArraySizeException:
-    .asciz "Ljava/lang/NegativeArraySizeException;"
-.LstrNoSuchMethodError:
-    .asciz "Ljava/lang/NoSuchMethodError;"
-.LstrNullPointerException:
-    .asciz "Ljava/lang/NullPointerException;"
-.LstrExceptionNotCaughtLocally:
-    .asciz "Exception %s from %s:%d not caught locally\n"
diff --git a/vm/mterp/x86-atom/header.S b/vm/mterp/x86-atom/header.S
deleted file mode 100644
index 28c19d6..0000000
--- a/vm/mterp/x86-atom/header.S
+++ /dev/null
@@ -1,433 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: header.S
-    */
-
-   /*
-    * IA32 calling convention and general notes:
-    *
-    * EAX, ECX, EDX - general purpose scratch registers (caller-saved);
-    *
-    * The stack (%esp) - used to pass arguments to functions
-    *
-    * EAX - holds the first 4 bytes of a return
-    * EDX - holds the second 4 bytes of a return
-    *
-    * EBX, ESI, EDI, EBP - are callee saved
-    *
-    * CS, DS, SS - are segment registers
-    * ES, FS, GS - are segment registers. We will try to avoid using these registers
-    *
-    * The stack is "full descending". Only the arguments that do not fit    * in the first two arg registers are placed on the stack.
-    * "%esp" points to the first stacked argument (i.e. the 3rd arg).
-    */
-
-   /*
-    * Mterp and IA32 notes
-    *
-    * mem          nick      purpose
-    * (%ebp)       rGLUE     InterpState base pointer (A.K.A. MterpGlue Pointer)
-    * %esi         rPC       interpreted program counter, used for fetching
-    *                        instructions
-    * %ebx         rINST     first 16-bit code unit of current instruction
-    * %edi         rFP       interpreted frame pointer, used for accessing
-    *                        locals and args
-    */
-
-   /*
-    * Includes
-    */
-
-#include "../common/asm-constants.h"
-
-   /*
-    * Reserved registers
-    */
-
-#define rGLUE  (%ebp)
-#define rINST   %ebx
-#define rINSTbl  %bl
-#define rINSTbh  %bh
-#define rINSTw  %bx
-#define rPC     %esi
-#define rFP     %edi
-
-   /*
-    * Temporary register used when finishing an opcode
-    */
-
-#define rFinish %edx
-
-   /*
-    * Stack locations used for temporary data. For convenience.
-    */
-
-#define sReg0    4(%ebp)
-#define sReg1    8(%ebp)
-#define sReg2   12(%ebp)
-#define sReg3   16(%ebp)
-
-   /*
-    * Save the PC and FP to the glue struct
-    */
-
-    .macro      SAVE_PC_FP_TO_GLUE _reg
-    movl        rGLUE, \_reg
-    movl        rPC, offGlue_pc(\_reg)
-    movl        rFP, offGlue_fp(\_reg)
-    .endm
-
-   /*
-    * Restore the PC and FP from the glue struct
-    */
-
-    .macro      LOAD_PC_FP_FROM_GLUE
-    movl        rGLUE, rFP
-    movl        offGlue_pc(rFP), rPC
-    movl        offGlue_fp(rFP), rFP
-    .endm
-
-   /*
-    * "Export" the PC to the stack frame, f/b/o future exception objects. This must
-    * be done *before* something calls dvmThrowException.
-    *
-    * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e.
-    * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc)
-    *
-    * It's okay to do this more than once.
-    */
-
-    .macro      EXPORT_PC
-    movl        rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP)
-    .endm
-
-   /*
-    * Given a frame pointer, find the stack save area.
-    * In C this is "((StackSaveArea*)(_fp) -1)".
-    */
-
-    .macro      SAVEAREA_FROM_FP  _reg
-    lea         -sizeofStackSaveArea(rFP), \_reg
-    .endm
-
-   /*
-    * Get the 32-bit value from a dalvik register.
-    */
-
-    .macro      GET_VREG _vreg
-    movl        (rFP,\_vreg, 4), \_vreg
-    .endm
-
-   /*
-    * Set the 32-bit value from a dalvik register.
-    */
-
-    .macro      SET_VREG _reg _vreg
-    movl        \_reg, (rFP,\_vreg, 4)
-    .endm
-
-   /*
-    * Fetch the next instruction from rPC into rINST. Does not advance rPC.
-    */
-
-    .macro      FETCH_INST
-    movzwl      (rPC), rINST
-    .endm
-
-   /*
-    * Fetch the next instruction from the specified offset. Advances rPC
-    * to point to the next instruction. "_count" is in 16-bit code units.
-    *
-    * This must come AFTER anything that can throw an exception, or the
-    * exception catch may miss. (This also implies that it must come after
-    * EXPORT_PC())
-    */
-
-    .macro      FETCH_ADVANCE_INST _count
-    add         $$(\_count*2), rPC
-    movzwl      (rPC), rINST
-    .endm
-
-   /*
-    * Fetch the next instruction from an offset specified by _reg. Updates
-    * rPC to point to the next instruction. "_reg" must specify the distance
-    * in bytes, *not* 16-bit code units, and may be a signed value.
-    */
-
-    .macro      FETCH_ADVANCE_INST_RB _reg
-    addl        \_reg, rPC
-    movzwl      (rPC), rINST
-    .endm
-
-   /*
-    * Fetch a half-word code unit from an offset past the current PC. The
-    * "_count" value is in 16-bit code units. Does not advance rPC.
-    * For example, given instruction of format: AA|op BBBB, it
-    * fetches BBBB.
-    */
-
-    .macro      FETCH _count _reg
-    movzwl      (\_count*2)(rPC), \_reg
-    .endm
-
-   /*
-    * Fetch a half-word code unit from an offset past the current PC. The
-    * "_count" value is in 16-bit code units. Does not advance rPC.
-    * This variant treats the value as signed.
-    */
-
-    .macro      FETCHs _count _reg
-    movswl      (\_count*2)(rPC), \_reg
-    .endm
-
-   /*
-    * Fetch the first byte from an offset past the current PC. The
-    * "_count" value is in 16-bit code units. Does not advance rPC.
-    * For example, given instruction of format: AA|op CC|BB, it
-    * fetches BB.
-    */
-
-    .macro      FETCH_BB _count _reg
-    movzbl      (\_count*2)(rPC), \_reg
-    .endm
-
-    /*
-    * Fetch the second byte from an offset past the current PC. The
-    * "_count" value is in 16-bit code units. Does not advance rPC.
-    * For example, given instruction of format: AA|op CC|BB, it
-    * fetches CC.
-    */
-
-    .macro      FETCH_CC _count _reg
-    movzbl      (\_count*2 + 1)(rPC), \_reg
-    .endm
-
-   /*
-    * Fetch the second byte from an offset past the current PC. The
-    * "_count" value is in 16-bit code units. Does not advance rPC.
-    * This variant treats the value as signed.
-    */
-
-    .macro      FETCH_CCs _count _reg
-    movsbl      (\_count*2 + 1)(rPC), \_reg
-    .endm
-
-
-   /*
-    * Fetch one byte from an offset past the current PC.  Pass in the same
-    * "_count" as you would for FETCH, and an additional 0/1 indicating which
-    * byte of the halfword you want (lo/hi).
-    */
-
-    .macro      FETCH_B _reg  _count  _byte
-    movzbl      (\_count*2+\_byte)(rPC), \_reg
-    .endm
-
-   /*
-    * Put the instruction's opcode field into the specified register.
-    */
-
-    .macro      GET_INST_OPCODE _reg
-    movzbl      rINSTbl, \_reg
-    .endm
-
-   /*
-    * Begin executing the opcode in _reg.
-    */
-
-    .macro      GOTO_OPCODE _reg
-    shl         $$${handler_size_bits}, \_reg
-    addl        $$dvmAsmInstructionStart,\_reg
-    jmp         *\_reg
-    .endm
-
-
-
-   /*
-    * Macros pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
-    * by using a jump table. _rFinish should must be the same register for
-    * both macros.
-    */
-
-    .macro      FFETCH _rFinish
-    movzbl      (rPC), \_rFinish
-    .endm
-
-    .macro      FGETOP_JMPa _rFinish
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-   /*
-    * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
-    * by using a jump table. _rFinish and _count should must be the same register for
-    * both macros.
-    */
-
-    .macro      FFETCH_ADV _count _rFinish
-    movzbl      (\_count*2)(rPC), \_rFinish
-    .endm
-
-    .macro      FGETOP_JMP _count _rFinish
-    movzbl      (\_count*2 + 1)(rPC), rINST
-    addl        $$(\_count*2), rPC
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-   /*
-    * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
-    * by using a jump table. _rFinish and _reg should must be the same register for
-    * both macros.
-    */
-
-    .macro      FFETCH_ADV_RB _reg _rFinish
-    movzbl      (\_reg, rPC), \_rFinish
-    .endm
-
-    .macro      FGETOP_RB_JMP _reg _rFinish
-    movzbl      1(\_reg, rPC), rINST
-    addl        \_reg, rPC
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-   /*
-    * Attempts to speed up FETCH_INST, GET_INST_OPCODE using
-    * a jump table. This macro should be called before FINISH_JMP where
-    * rFinish should be the same register containing the opcode value.
-    * This is an attempt to split up FINISH in order to reduce or remove
-    * potential stalls due to the wait for rFINISH.
-    */
-
-    .macro      FINISH_FETCH _rFinish
-    movzbl      (rPC), \_rFinish
-    movzbl      1(rPC), rINST
-    .endm
-
-
-   /*
-    * Attempts to speed up FETCH_ADVANCE_INST, GET_INST_OPCODE using
-    * a jump table. This macro should be called before FINISH_JMP where
-    * rFinish should be the same register containing the opcode value.
-    * This is an attempt to split up FINISH in order to reduce or remove
-    * potential stalls due to the wait for rFINISH.
-    */
-
-    .macro      FINISH_FETCH_ADVANCE _count _rFinish
-    movzbl      (\_count*2)(rPC), \_rFinish
-    movzbl      (\_count*2 + 1)(rPC), rINST
-    addl        $$(\_count*2), rPC
-    .endm
-
-   /*
-    * Attempts to speed up FETCH_ADVANCE_INST_RB, GET_INST_OPCODE using
-    * a jump table. This macro should be called before FINISH_JMP where
-    * rFinish should be the same register containing the opcode value.
-    * This is an attempt to split up FINISH in order to reduce or remove
-    * potential stalls due to the wait for rFINISH.
-    */
-
-    .macro      FINISH_FETCH_ADVANCE_RB _reg _rFinish
-    movzbl      (\_reg, rPC), \_rFinish
-    movzbl      1(\_reg, rPC), rINST
-    addl        \_reg, rPC
-    .endm
-
-   /*
-    * Attempts to speed up GOTO_OPCODE using a jump table. This macro should
-    * be called after a FINISH_FETCH* instruction where rFinish should be the
-    * same register containing the opcode value. This is an attempt to split up
-    * FINISH in order to reduce or remove potential stalls due to the wait for rFINISH.
-    */
-
-    .macro      FINISH_JMP _rFinish
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-   /*
-    * Attempts to speed up FETCH_INST, GET_INST_OPCODE, GOTO_OPCODE by using
-    * a jump table. Uses a single macro - but it should be faster if we
-    * split up the fetch for rFinish and the jump using rFinish.
-    */
-
-    .macro      FINISH_A
-    movzbl      (rPC), rFinish
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(,rFinish, 4)
-    .endm
-
-   /*
-    * Attempts to speed up FETCH_ADVANCE_INST, GET_INST_OPCODE,
-    * GOTO_OPCODE by using a jump table. Uses a single macro -
-    * but it should be faster if we split up the fetch for rFinish
-    * and the jump using rFinish.
-    */
-
-    .macro      FINISH _count
-    movzbl      (\_count*2)(rPC), rFinish
-    movzbl      (\_count*2 + 1)(rPC), rINST
-    addl        $$(\_count*2), rPC
-    jmp         *dvmAsmInstructionJmpTable(,rFinish, 4)
-    .endm
-
-   /*
-    * Attempts to speed up FETCH_ADVANCE_INST_RB, GET_INST_OPCODE,
-    * GOTO_OPCODE by using a jump table. Uses a single macro -
-    * but it should be faster if we split up the fetch for rFinish
-    * and the jump using rFinish.
-    */
-
-    .macro      FINISH_RB _reg _rFinish
-    movzbl      (\_reg, rPC), \_rFinish
-    movzbl      1(\_reg, rPC), rINST
-    addl        \_reg, rPC
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-   /*
-    * Hard coded helper values.
-    */
-
-.balign 16
-
-.LdoubNeg:
-    .quad       0x8000000000000000
-
-.L64bits:
-    .quad       0xFFFFFFFFFFFFFFFF
-
-.LshiftMask2:
-    .quad       0x0000000000000000
-.LshiftMask:
-    .quad       0x000000000000003F
-
-.Lvalue64:
-    .quad       0x0000000000000040
-
-.LvaluePosInfLong:
-    .quad       0x7FFFFFFFFFFFFFFF
-
-.LvalueNegInfLong:
-    .quad       0x8000000000000000
-
-.LvalueNanLong:
-    .quad       0x0000000000000000
-
-.LintMin:
-.long   0x80000000
-
-.LintMax:
-.long   0x7FFFFFFF
diff --git a/vm/mterp/x86-atom/stub.S b/vm/mterp/x86-atom/stub.S
deleted file mode 100644
index 54f3f54..0000000
--- a/vm/mterp/x86-atom/stub.S
+++ /dev/null
@@ -1,25 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: stub.S
-    */
-
-    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
-    pushl       rGLUE                   # push parameter glue
-    call        dvmMterp_${opcode}      # call c-based implementation
-    lea         4(%esp), %esp
-    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
-    FINISH_A                            # jump to next instruction
diff --git a/vm/mterp/x86-atom/unop.S b/vm/mterp/x86-atom/unop.S
deleted file mode 100644
index 00f9f8d..0000000
--- a/vm/mterp/x86-atom/unop.S
+++ /dev/null
@@ -1,43 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unop.S
-    *
-    * Code: Generic 32-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%ecx = op %edx".
-    *
-    * For: int-to-byte, int-to-char, int-to-short, neg-float, neg-int, not-int
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-%default {"preinstr":"", "instr":""}
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $$4, %ecx               # %ecx<- B
-    and         $$15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vB
-    $preinstr                           # do operation part 1
-    $instr                              # do operation part 2
-    SET_VREG    %ecx, rINST             # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/unopWide.S b/vm/mterp/x86-atom/unopWide.S
deleted file mode 100644
index 3790a2c..0000000
--- a/vm/mterp/x86-atom/unopWide.S
+++ /dev/null
@@ -1,43 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unopWide.S
-    *
-    * Code: Generic 64-bit unary operation. Provide an "instr" variable and a
-    *       preinstr variable that together specify an instruction that
-    *       performs, for example, "%xmm0 = op %xmm1".
-    *
-    * For:  neg-double, neg-long, not-long
-    *
-    * Description: Perform the identified unary operation on the source
-    *              register, storing the result in the destination register
-    *
-    * Format: B|A|op (12x)
-    *
-    * Syntax: op vA, vB
-    */
-
-%default {"preinstr":"","result":"%xmm0"}
-
-    movl        rINST, %ecx             # %ecx<- BA+
-    shr         $$4, rINST              # rINST<- B
-    and         $$15, %ecx              # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vB
-    $preinstr                           # do operation part 1
-    $instr                              # do operation part 2
-    movq        $result, (rFP, %ecx, 4) # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/unused.S b/vm/mterp/x86-atom/unused.S
deleted file mode 100644
index 8267709..0000000
--- a/vm/mterp/x86-atom/unused.S
+++ /dev/null
@@ -1,30 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: unused.S
-    *
-    * Code: Common code for unused bytecodes. Uses no subtitutions.
-    *
-    * For: all unused bytecodes
-    *
-    * Description: aborts if executed.
-    *
-    * Format: ØØ|op (10x)
-    *
-    * Syntax: op
-    */
-
-    call        common_abort
diff --git a/vm/mterp/x86-atom/zcmp.S b/vm/mterp/x86-atom/zcmp.S
deleted file mode 100644
index 6614dba..0000000
--- a/vm/mterp/x86-atom/zcmp.S
+++ /dev/null
@@ -1,53 +0,0 @@
-   /* Copyright (C) 2008 The Android Open Source Project
-    *
-    * Licensed under the Apache License, Version 2.0 (the "License");
-    * you may not use this file except in compliance with the License.
-    * You may obtain a copy of the License at
-    *
-    * http://www.apache.org/licenses/LICENSE-2.0
-    *
-    * Unless required by applicable law or agreed to in writing, software
-    * distributed under the License is distributed on an "AS IS" BASIS,
-    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    * See the License for the specific language governing permissions and
-    * limitations under the License.
-    */
-
-   /*
-    * File: zcmp.S
-    *
-    * Code: Generic 32-bit comparison operation. Provides a "revcmp"
-    *       variable to specify the reverse comparison to perform
-    *
-    * For: if-eqz, if-gez, if-gtz, if-lez, if-ltz, if-nez
-    *
-    * Description: Branch to the given destination if the given register's
-    *              value compares with 0 as specified.
-    *
-    * Format: AA|op BBBB (21t)
-    *
-    * Syntax: op vAA, +BBBB
-    */
-
-    cmp         $$0, (rFP, rINST, 4)    # compare vAA with zero
-    j${revcmp}  ${opcode}_2f                    # goto next instruction or branch
-    FETCHs      1, %edx                 # %edx<- BBBB; branch offset
-    sal         $$1, %edx               # %edx<- adjust byte offset
-
-   /*
-    * Inline common_backwardBranch
-    */
-
-    js          common_periodicChecks_backwardBranch  # jump on backwards branch
-1:
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
-   /*
-    * FINISH code
-    */
-
-${opcode}_2f:
-    movzbl      4(rPC), %edx            # grab the next opcode
-    movzbl      5(rPC), rINST           # update the instruction
-    addl        $$4, rPC                # update the program counter
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4) # jump to next instruction
diff --git a/vm/mterp/x86/OP_ADD_DOUBLE.S b/vm/mterp/x86/OP_ADD_DOUBLE.S
index 9fded29..27a47c1 100644
--- a/vm/mterp/x86/OP_ADD_DOUBLE.S
+++ b/vm/mterp/x86/OP_ADD_DOUBLE.S
@@ -1,2 +1,14 @@
-%verify "executed"
-%include "x86/binflop.S" {"instr":"faddl","load":"fldl","store":"fstpl"}
+   /*
+    * File: OP_ADD_DOUBLE.S
+    */
+
+    movzbl   2(rPC),%eax                # eax<- BB
+    movzbl   3(rPC),%ecx                # ecx<- CC
+    movq     (rFP, %eax, 4), %xmm0      # %xmm0<- vBB
+    movq     (rFP, %ecx, 4), %xmm1      # %xmm1<- vCC
+    FETCH_INST_OPCODE 2 %ecx
+    addsd    %xmm1, %xmm0
+    ADVANCE_PC 2
+    movq     %xmm0, (rFP, rINST, 4)     # vAA<- vBB * vCC
+    GOTO_NEXT_R %ecx
+
diff --git a/vm/mterp/x86/OP_ADD_DOUBLE_2ADDR.S b/vm/mterp/x86/OP_ADD_DOUBLE_2ADDR.S
index 81e55ea..d917578 100644
--- a/vm/mterp/x86/OP_ADD_DOUBLE_2ADDR.S
+++ b/vm/mterp/x86/OP_ADD_DOUBLE_2ADDR.S
@@ -1,2 +1,14 @@
-%verify "executed"
-%include "x86/binflop2addr.S" {"instr":"faddl","load":"fldl","store":"fstpl"}
+   /*
+    * File: OP_ADD_DOUBLE_2ADDR.S
+    */
+
+    movzx       rINSTbl,%ecx            # ecx<- A+
+    andb        $$0xf,%cl               # ecx<- A
+    sarl        $$4,rINST               # rINST<- B
+    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
+    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
+    FETCH_INST_OPCODE 1 %eax
+    addsd       %xmm1, %xmm0            # %xmm0<- vA op vB
+    ADVANCE_PC 1
+    movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
+    GOTO_NEXT_R %eax
diff --git a/vm/mterp/x86/OP_EXECUTE_INLINE.S b/vm/mterp/x86/OP_EXECUTE_INLINE.S
index ec91076..c739fdf 100644
--- a/vm/mterp/x86/OP_EXECUTE_INLINE.S
+++ b/vm/mterp/x86/OP_EXECUTE_INLINE.S
@@ -14,14 +14,18 @@
     movl      rSELF,%ecx
     EXPORT_PC
     movzwl    2(rPC),%eax               # eax<- BBBB
-    leal      offThread_retval(%ecx),%ecx # ecx<- & self->retval
     SPILL(rIBASE)                       # preserve rIBASE
+    movl      offThread_subMode(%ecx), %edx # edx<- submode flags
+    andl      $$kSubModeDebugProfile, %edx # debug or profile mode active?
+    jnz       .L${opcode}_debugprofile   # yes, take slow path
+.L${opcode}_resume:
+    leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
     movl      %ecx,OUT_ARG4(%esp)
     call      .L${opcode}_continue      # make call; will return after
     UNSPILL(rIBASE)                     # restore rIBASE
     testl     %eax,%eax                 # successful?
+    jz        common_exceptionThrown    # no, handle exception
     FETCH_INST_OPCODE 3 %ecx
-    je        common_exceptionThrown    # no, handle exception
     ADVANCE_PC 3
     GOTO_NEXT_R %ecx
 
@@ -64,3 +68,39 @@
     sall      $$4,%eax      # index *= sizeof(table entry)
     jmp       *gDvmInlineOpsTable(%eax)
     # will return to caller of .L${opcode}_continue
+
+    /*
+     * We're debugging or profiling.
+     * eax: opIndex
+     */
+.L${opcode}_debugprofile:
+    movl      %eax,OUT_ARG0(%esp)       # arg0<- BBBB
+    SPILL_TMP1(%eax)                    # save opIndex
+    call      dvmResolveInlineNative    # dvmResolveInlineNative(opIndex)
+    movl      rSELF,%ecx                # restore self
+    testl     %eax,%eax                 # method resolved?
+    movl      %eax,%edx                 # save possibly resolved method in edx
+    UNSPILL_TMP1(%eax)                  # in case not resolved, restore opIndex
+    jz        .L${opcode}_resume        # not resolved, just move on
+    SPILL_TMP2(%edx)                    # save method
+    movl      %edx,OUT_ARG0(%esp)       # arg0<- method
+    movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
+    call      dvmFastMethodTraceEnter   # dvmFastMethodTraceEnter(method,self)
+    movl      rSELF,%ecx                # restore self
+    UNSPILL_TMP1(%eax)                  # restore opIndex
+    leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
+    movl      %ecx,OUT_ARG4(%esp)       # needed for pResult of inline operation handler
+    call      .L${opcode}_continue      # make call; will return after
+    SPILL_TMP1(%eax)                    # save result of inline
+    UNSPILL_TMP2(%eax)                  # restore method
+    movl      rSELF,%ecx                # restore self
+    movl      %eax,OUT_ARG0(%esp)       # arg0<- method
+    movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
+    call      dvmFastNativeMethodTraceExit # dvmFastNativeMethodTraceExit(method,self)
+    UNSPILL(rIBASE)                     # restore rIBASE
+    UNSPILL_TMP1(%eax)                  # restore result of inline
+    testl     %eax,%eax                 # successful?
+    jz        common_exceptionThrown    # no, handle exception
+    FETCH_INST_OPCODE 3 %ecx
+    ADVANCE_PC 3
+    GOTO_NEXT_R %ecx
diff --git a/vm/mterp/x86/OP_GOTO.S b/vm/mterp/x86/OP_GOTO.S
index 2fc4c31..a7913d1 100644
--- a/vm/mterp/x86/OP_GOTO.S
+++ b/vm/mterp/x86/OP_GOTO.S
@@ -12,4 +12,9 @@
     movl    offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $$0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
diff --git a/vm/mterp/x86/OP_GOTO_16.S b/vm/mterp/x86/OP_GOTO_16.S
index de0903c..84220d0 100644
--- a/vm/mterp/x86/OP_GOTO_16.S
+++ b/vm/mterp/x86/OP_GOTO_16.S
@@ -11,4 +11,9 @@
     movl    offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $$0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
diff --git a/vm/mterp/x86/OP_GOTO_32.S b/vm/mterp/x86/OP_GOTO_32.S
index 84806b0..c3d1050 100644
--- a/vm/mterp/x86/OP_GOTO_32.S
+++ b/vm/mterp/x86/OP_GOTO_32.S
@@ -11,4 +11,9 @@
     movl    offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $$0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
diff --git a/vm/mterp/x86/OP_INVOKE_INTERFACE.S b/vm/mterp/x86/OP_INVOKE_INTERFACE.S
index 3fa4c94..26d2d5c 100644
--- a/vm/mterp/x86/OP_INVOKE_INTERFACE.S
+++ b/vm/mterp/x86/OP_INVOKE_INTERFACE.S
@@ -18,6 +18,7 @@
     EXPORT_PC
     testl      %eax,%eax                # null this?
     je         common_errNullObject     # yes, fail
+    movl       %eax, TMP_SPILL1(%ebp)
     movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
     movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
     movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
@@ -29,4 +30,5 @@
     call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
     testl      %eax,%eax
     je         common_exceptionThrown
+    movl       TMP_SPILL1(%ebp), %ecx
     jmp        common_invokeMethod${routine}
diff --git a/vm/mterp/x86/OP_INVOKE_OBJECT_INIT_RANGE.S b/vm/mterp/x86/OP_INVOKE_OBJECT_INIT_RANGE.S
index fb84b32..d5d10a6 100644
--- a/vm/mterp/x86/OP_INVOKE_OBJECT_INIT_RANGE.S
+++ b/vm/mterp/x86/OP_INVOKE_OBJECT_INIT_RANGE.S
@@ -1,4 +1,57 @@
+%default { "jumbo":"0", "cccc":"2" }
 %verify "executed"
+%verify "finalizable class"
     /*
-     * TODO (currently punting to stub)
+     * Invoke Object.<init> on an object.  In practice we know that
+     * Object's nullary constructor doesn't do anything, so we just
+     * skip it unless a debugger is active.
      */
+    movzwl     4(rPC),%eax              # eax<- CCCC, offset = 2 * cccc, cccc = 4 for jumbo
+    GET_VREG_R %ecx, %eax               # ecx<- "this" ptr
+    testl      %ecx,%ecx                # null this?
+    je         common_errNullObject     # yes, fail
+    movl       offObject_clazz(%ecx), %eax # eax<- obj->clazz
+    SPILL_TMP1(rIBASE)                  # save %edx
+    movl       offClassObject_accessFlags(%eax), %edx # edx<- clazz->accessFlags
+    andl       $$CLASS_ISFINALIZABLE, %edx # is this class finalizable?
+    jnz        .L${opcode}_setFinal     # yes, go
+.L${opcode}_finish:
+    movl       rSELF, %ecx
+    movl       offThread_subMode(%ecx), %eax
+    andl       $$kSubModeDebuggerActive, %eax # debugger active?
+    jnz        .L${opcode}_debugger     # Yes - skip optimization
+    UNSPILL_TMP1(rIBASE)
+    FETCH_INST_OPCODE 3 %ecx            # 3 = cccc + 1
+    ADVANCE_PC 3
+    GOTO_NEXT_R %ecx
+%break
+
+.L${opcode}_setFinal:
+    EXPORT_PC                           # can throw
+    movl       %ecx, OUT_ARG0(%esp)     # arg1<- obj
+    call       dvmSetFinalizable        # call dvmSetFinalizable(obj)
+    movl       rSELF, %ecx
+    movl       offThread_exception(%ecx), %eax # eax<- self->exception
+    cmpl       $$0, %eax                # exception pending?
+    jne        common_exceptionThrown   # yes, handle it
+    jmp        .L${opcode}_finish
+
+    /*
+     * A debugger is attached, so we need to go ahead and do
+     * this.  For simplicity, we'll just jump directly to the
+     * corresponding handler.  Note that we can't use
+     * rIBASE here because it may be in single-step mode.
+     * Load the primary table base directly.
+     */
+.L${opcode}_debugger:
+    movl    offThread_mainHandlerTable(%ecx), %ecx # load main handler table
+    .if $jumbo                               # if jumbo is enabled
+    movl       $$OP_INVOKE_DIRECT_JUMBO, %eax
+    .else
+    movl       $$OP_INVOKE_DIRECT_RANGE, %eax
+    .endif
+    /*
+     * We can't use GOTO_NEXT here since we want to jump directly to
+     * handler without touching rIBASE.
+     */
+    jmp        *(%ecx,%eax,4)
diff --git a/vm/mterp/x86/OP_INVOKE_STATIC.S b/vm/mterp/x86/OP_INVOKE_STATIC.S
index ca68a84..d5004bc 100644
--- a/vm/mterp/x86/OP_INVOKE_STATIC.S
+++ b/vm/mterp/x86/OP_INVOKE_STATIC.S
@@ -13,9 +13,17 @@
     movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
     EXPORT_PC
     movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
+#if defined(WITH_JIT)
+    movl     %edx, TMP_SPILL1(%ebp)
+    lea      (%ecx,%eax,4), %edx
+    movl     %edx, TMP_SPILL2(%ebp)
+    movl     TMP_SPILL1(%ebp), %edx
+#endif
     movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
+    movl      $$0, %ecx                 # make "this" null
     testl     %eax,%eax
     jne       common_invokeMethod${routine}
+
     movl      rSELF,%ecx
     movl      offThread_method(%ecx),%ecx # ecx<- self->method
     movzwl    2(rPC),%eax
@@ -24,7 +32,37 @@
     movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
     movl      $$METHOD_STATIC,%eax
     movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
+    SPILL(rIBASE)
     call      dvmResolveMethod          # call(clazz,ref,flags)
+    UNSPILL(rIBASE)
     testl     %eax,%eax                 # got null?
+#if defined(WITH_JIT)
+    movl      TMP_SPILL1(%ebp), %edx
+    movl      rSELF,%ecx
+    movzwl    offThread_subMode(%ecx), %ecx
+    je        common_exceptionThrown    # null, handle exception
+    andl      $$kSubModeJitTraceBuild, %ecx # is trace under construction?
+    movl      $$0, %ecx                 # make "this" null
+    je        common_invokeMethod${routine} # no (%eax=method, %ecx="this")
+    movl      TMP_SPILL2(%ebp), %edx
+    cmpl      $$0, (%edx)                  # finished resolving
+    movl      TMP_SPILL1(%ebp), %edx
+    jne        common_invokeMethod${routine} # yes (%eax=method, %ecx="this")
+    movl      rSELF, %edx
+    movl      %edx, OUT_ARG0(%esp)
+    movl      rPC, OUT_ARG1(%esp)
+    movl      %eax, TMP_SPILL2(%ebp)
+    movl      %ecx, TMP_SPILL3(%ebp)
+    SPILL(rIBASE)
+    call      dvmJitEndTraceSelect
+    UNSPILL(rIBASE)
+    movl      TMP_SPILL1(%ebp), %edx
+    movl      TMP_SPILL2(%ebp), %eax
+    movl      TMP_SPILL3(%ebp), %ecx
+    jmp       common_invokeMethod${routine}
+#else
+    movl      $$0, %ecx                 # make "this" null
     jne       common_invokeMethod${routine}
     jmp       common_exceptionThrown
+#endif
+
diff --git a/vm/mterp/x86/OP_INVOKE_SUPER.S b/vm/mterp/x86/OP_INVOKE_SUPER.S
index ecee028..d210daf 100644
--- a/vm/mterp/x86/OP_INVOKE_SUPER.S
+++ b/vm/mterp/x86/OP_INVOKE_SUPER.S
@@ -19,8 +19,9 @@
     .if       (!$isrange)
     andl      $$0xf,rINST               # rINST<- D (or stays CCCC)
     .endif
-    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
-    testl     rINST,rINST               # null "this"?
+    GET_VREG_R  %edx rINST             # %edx<- "this" ptr
+    testl     %edx,%edx                # null "this"?
+    SPILL_TMP1(%edx)
     je        common_errNullObject      # yes, throw
     movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
     testl     %ecx,%ecx                 # already resolved?
@@ -32,11 +33,13 @@
      */
 .L${opcode}_continue:
     movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
-    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
-    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
+    movzwl  offMethod_methodIndex(%ecx),%edx  # edx<- baseMthod->methodIndex
+    cmpl    offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount)
     jae     .L${opcode}_nsm           # method not present in superclass
     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
-    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
+    movl    (%eax,%edx,4),%eax        # eax<- vtable[methodIndex]
+    UNSPILL_TMP1(%edx)
+    movl    %edx, %ecx
     jmp     common_invokeMethod${routine}
 
 
@@ -45,7 +48,7 @@
      * eax = method->clazz
     */
 .L${opcode}_resolve:
-    SPILL_TMP1(%eax)                    # method->clazz
+    SPILL_TMP2(%eax)                    # method->clazz
     movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
     movzwl  2(rPC),%ecx                 # ecx<- BBBB
     movl    $$METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
@@ -53,7 +56,7 @@
     call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
     testl   %eax,%eax                   # got null?
     movl    %eax,%ecx                   # ecx<- resolved base method
-    UNSPILL_TMP1(%eax)                  # restore method->clazz
+    UNSPILL_TMP2(%eax)                  # restore method->clazz
     jne     .L${opcode}_continue        # good to go - continue
     jmp     common_exceptionThrown      # handle exception
 
diff --git a/vm/mterp/x86/OP_INVOKE_SUPER_QUICK.S b/vm/mterp/x86/OP_INVOKE_SUPER_QUICK.S
index 5fe098c..b93fce5 100644
--- a/vm/mterp/x86/OP_INVOKE_SUPER_QUICK.S
+++ b/vm/mterp/x86/OP_INVOKE_SUPER_QUICK.S
@@ -19,8 +19,10 @@
     movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
     testl     %eax,%eax                 # null "this"?
     je        common_errNullObject      # "this" is null, throw exception
+    movl       %eax, TMP_SPILL1(%ebp)
     movzwl    2(rPC),%eax               # eax<- BBBB
     movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
     EXPORT_PC
     movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
+    movl      TMP_SPILL1(%ebp), %ecx
     jmp       common_invokeMethod${routine}
diff --git a/vm/mterp/x86/OP_INVOKE_VIRTUAL.S b/vm/mterp/x86/OP_INVOKE_VIRTUAL.S
index 24d0170..23dee67 100644
--- a/vm/mterp/x86/OP_INVOKE_VIRTUAL.S
+++ b/vm/mterp/x86/OP_INVOKE_VIRTUAL.S
@@ -42,7 +42,7 @@
     movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
     testl     %ecx,%ecx                 # null this?
     je        common_errNullObject      # go if so
-    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
-    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
-    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
+    movl      offObject_clazz(%ecx),%edx  # edx<- thisPtr->clazz
+    movl      offClassObject_vtable(%edx),%edx # edx<- thisPtr->clazz->vtable
+    movl      (%edx,%eax,4),%eax        # eax<- vtable[methodIndex]
     jmp       common_invokeMethod${routine}
diff --git a/vm/mterp/x86/OP_INVOKE_VIRTUAL_QUICK.S b/vm/mterp/x86/OP_INVOKE_VIRTUAL_QUICK.S
index 14202d8..58f784d 100644
--- a/vm/mterp/x86/OP_INVOKE_VIRTUAL_QUICK.S
+++ b/vm/mterp/x86/OP_INVOKE_VIRTUAL_QUICK.S
@@ -8,16 +8,16 @@
      */
     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
-    movzwl    4(rPC),%eax               # eax<- FEDC or CCCC
-    movzwl    2(rPC),%ecx               # ecx<- BBBB
+    movzwl    4(rPC),%ecx               # eax<- FEDC or CCCC
+    movzwl    2(rPC),%edx               # ecx<- BBBB
     .if     (!$isrange)
-    andl      $$0xf,%eax                # eax<- C (or stays CCCC)
+    andl      $$0xf,%ecx                # eax<- C (or stays CCCC)
     .endif
-    GET_VREG_R  %eax %eax               # eax<- vC ("this" ptr)
-    testl     %eax,%eax                 # null?
+    GET_VREG_R  %ecx %ecx               # ecx<- vC ("this" ptr)
+    testl     %ecx,%ecx                 # null?
     je        common_errNullObject      # yep, throw exception
-    movl      offObject_clazz(%eax),%eax # eax<- thisPtr->clazz
+    movl      offObject_clazz(%ecx),%eax # eax<- thisPtr->clazz
     movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
     EXPORT_PC                           # might throw later - get ready
-    movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
+    movl      (%eax,%edx,4),%eax        # eax<- vtable[BBBB]
     jmp       common_invokeMethod${routine}
diff --git a/vm/mterp/x86/OP_MUL_DOUBLE.S b/vm/mterp/x86/OP_MUL_DOUBLE.S
index 59a2079..7d74f78 100644
--- a/vm/mterp/x86/OP_MUL_DOUBLE.S
+++ b/vm/mterp/x86/OP_MUL_DOUBLE.S
@@ -1,2 +1,14 @@
-%verify "executed"
-%include "x86/binflop.S" {"instr":"fmull","load":"fldl","store":"fstpl"}
+   /*
+    * File: OP_MUL_DOUBLE.S
+    */
+
+    movzbl   2(rPC),%eax                # eax<- BB
+    movzbl   3(rPC),%ecx                # ecx<- CC
+    # TODO: movsd?
+    movq        (rFP, %eax, 4), %xmm0   # %xmm0<- vBB
+    movq        (rFP, %ecx, 4), %xmm1   # %xmm1<- vCC
+    FETCH_INST_OPCODE 2 %ecx
+    mulsd       %xmm1, %xmm0
+    ADVANCE_PC 2
+    movq        %xmm0, (rFP, rINST, 4)  # vAA<- vBB * vCC
+    GOTO_NEXT_R %ecx
diff --git a/vm/mterp/x86/OP_MUL_DOUBLE_2ADDR.S b/vm/mterp/x86/OP_MUL_DOUBLE_2ADDR.S
index 45a2fa3..d277689 100644
--- a/vm/mterp/x86/OP_MUL_DOUBLE_2ADDR.S
+++ b/vm/mterp/x86/OP_MUL_DOUBLE_2ADDR.S
@@ -1,2 +1,15 @@
-%verify "executed"
-%include "x86/binflop2addr.S" {"instr":"fmull","load":"fldl","store":"fstpl"}
+   /*
+    * File: OP_MUL_DOUBLE_2ADDR.S
+    */
+
+    movzx       rINSTbl,%ecx            # ecx<- A+
+    andb        $$0xf,%cl               # ecx<- A
+    sarl        $$4,rINST               # rINST<- B
+    # TODO: movsd?
+    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
+    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
+    FETCH_INST_OPCODE 1 %eax
+    mulsd       %xmm1, %xmm0            # %xmm0<- vA op vB
+    ADVANCE_PC 1
+    movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
+    GOTO_NEXT_R %eax
diff --git a/vm/mterp/x86/OP_NEW_INSTANCE.S b/vm/mterp/x86/OP_NEW_INSTANCE.S
index 3e268c4..5638e10 100644
--- a/vm/mterp/x86/OP_NEW_INSTANCE.S
+++ b/vm/mterp/x86/OP_NEW_INSTANCE.S
@@ -14,8 +14,12 @@
     movzwl    2(rPC),%eax               # eax<- BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
     SPILL(rIBASE)
+    SPILL_TMP2(%ebx)
     movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
     EXPORT_PC
+#if defined(WITH_JIT)
+    lea       (%ecx,%eax,4),%ebx        # ebx <- &resolved class
+#endif
     movl      (%ecx,%eax,4),%ecx        # ecx<- resolved class
     testl     %ecx,%ecx                 # resolved?
     je        .L${opcode}_resolve       # no, go do it
@@ -26,14 +30,48 @@
     movl      $$ALLOC_DONT_TRACK,OUT_ARG1(%esp)
     movl     %ecx,OUT_ARG0(%esp)
     call     dvmAllocObject             # eax<- new object
-    FETCH_INST_OPCODE 2 %ecx
-    UNSPILL(rIBASE)
     testl    %eax,%eax                  # success?
     je       common_exceptionThrown     # no, bail out
+#if defined(WITH_JIT)
+        /*
+     * The JIT needs the class to be fully resolved before it can
+     * include this instruction in a trace.
+     */
+    movl    rSELF, %ecx
+    movl    offThread_subMode(%ecx), %ecx
+    andl    $$kSubModeJitTraceBuild, %ecx # under construction?
+    jne     .L${opcode}_jitCheck
+#endif
+.L${opcode}_end:
+    UNSPILL_TMP2(%ebx)
     SET_VREG %eax rINST
+    UNSPILL(rIBASE)
+    FETCH_INST_OPCODE 2 %ecx
     ADVANCE_PC 2
     GOTO_NEXT_R %ecx
 
+#if defined(WITH_JIT)
+    /*
+     * Check to see if we need to stop the trace building early.
+     * eax: new object
+     */
+.L${opcode}_jitCheck:
+    cmp     $$0, (%ebx)                   # okay?
+    jne     .L${opcode}_end        # yes, finish
+    SPILL_TMP1(%eax)                     # preserve new object
+    movl    rSELF, %ecx
+    movl    %ecx, OUT_ARG0(%esp)
+    movl    rPC, OUT_ARG1(%esp)
+    call    dvmJitEndTraceSelect         # (self, pc)
+    UNSPILL_TMP1(%eax)
+    UNSPILL_TMP2(%ebx)
+    SET_VREG %eax rINST                  # vAA <- new object
+    UNSPILL(rIBASE)
+    FETCH_INST_OPCODE 2 %ecx
+    ADVANCE_PC 2
+    GOTO_NEXT_R %ecx
+#endif
+
     /*
      * Class initialization required.
      *
diff --git a/vm/mterp/x86/OP_PACKED_SWITCH.S b/vm/mterp/x86/OP_PACKED_SWITCH.S
index c762a8b..af0df62 100644
--- a/vm/mterp/x86/OP_PACKED_SWITCH.S
+++ b/vm/mterp/x86/OP_PACKED_SWITCH.S
@@ -20,4 +20,9 @@
     ADVANCE_PC_INDEXED %eax
     movl    offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $$0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
diff --git a/vm/mterp/x86/OP_SGET.S b/vm/mterp/x86/OP_SGET.S
index 8ff0632..27d63b1 100644
--- a/vm/mterp/x86/OP_SGET.S
+++ b/vm/mterp/x86/OP_SGET.S
@@ -12,6 +12,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .L${opcode}_resolve                # if not, make it so
@@ -37,5 +43,11 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .L${opcode}_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .L${opcode}_finish                 # success, continue
diff --git a/vm/mterp/x86/OP_SGET_WIDE.S b/vm/mterp/x86/OP_SGET_WIDE.S
index 432763d..be97017 100644
--- a/vm/mterp/x86/OP_SGET_WIDE.S
+++ b/vm/mterp/x86/OP_SGET_WIDE.S
@@ -11,6 +11,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .L${opcode}_resolve                # if not, make it so
@@ -38,5 +44,11 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .L${opcode}_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .L${opcode}_finish                 # success, continue
diff --git a/vm/mterp/x86/OP_SPUT.S b/vm/mterp/x86/OP_SPUT.S
index bc76533..57a1543 100644
--- a/vm/mterp/x86/OP_SPUT.S
+++ b/vm/mterp/x86/OP_SPUT.S
@@ -12,6 +12,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .L${opcode}_resolve                # if not, make it so
@@ -28,7 +34,7 @@
 .L${opcode}_resolve:
     movl     rSELF,%ecx
     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
-    movl     offThread_method(%ecx),%ecx          # ecx<- current method
+    movl     offThread_method(%ecx),%ecx        # ecx<- current method
     EXPORT_PC                                   # could throw, need to export
     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
     movl     %eax,OUT_ARG1(%esp)
@@ -37,5 +43,11 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .L${opcode}_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .L${opcode}_finish                 # success, continue
\ No newline at end of file
diff --git a/vm/mterp/x86/OP_SPUT_OBJECT.S b/vm/mterp/x86/OP_SPUT_OBJECT.S
index 45d84c7..95a0a34 100644
--- a/vm/mterp/x86/OP_SPUT_OBJECT.S
+++ b/vm/mterp/x86/OP_SPUT_OBJECT.S
@@ -10,6 +10,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
     testl     %eax,%eax                          # resolved entry null?
     je        .L${opcode}_resolve                # if not, make it so
@@ -41,5 +47,11 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .L${opcode}_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .L${opcode}_finish                 # success, continue
diff --git a/vm/mterp/x86/OP_SPUT_WIDE.S b/vm/mterp/x86/OP_SPUT_WIDE.S
index d4c5841..d5825f6 100644
--- a/vm/mterp/x86/OP_SPUT_WIDE.S
+++ b/vm/mterp/x86/OP_SPUT_WIDE.S
@@ -12,6 +12,12 @@
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+#if defined(WITH_JIT)
+    movl      %ecx, TMP_SPILL1(%ebp)
+    lea       (%ecx,%eax,4),%ecx
+    movl      %ecx, TMP_SPILL2(%ebp)
+    movl      TMP_SPILL1(%ebp), %ecx
+#endif
     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
     testl     %eax,%eax                          # resolved entry null?
     je        .L${opcode}_resolve                # if not, make it so
@@ -39,5 +45,11 @@
     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
     UNSPILL(rIBASE)
     testl    %eax,%eax
-    jne      .L${opcode}_finish                 # success, continue
-    jmp      common_exceptionThrown             # no, handle exception
+    je      common_exceptionThrown             # no, handle exception
+#if defined(WITH_JIT)
+    movl      TMP_SPILL2(%ebp), %ecx
+    SPILL(rIBASE)
+    call     common_verifyField
+    UNSPILL(rIBASE)
+#endif
+    jmp      .L${opcode}_finish                 # success, continue
diff --git a/vm/mterp/x86/OP_SUB_DOUBLE.S b/vm/mterp/x86/OP_SUB_DOUBLE.S
index 224f3a1..cf84a65 100644
--- a/vm/mterp/x86/OP_SUB_DOUBLE.S
+++ b/vm/mterp/x86/OP_SUB_DOUBLE.S
@@ -1,2 +1,14 @@
-%verify "executed"
-%include "x86/binflop.S" {"instr":"fsubl","load":"fldl","store":"fstpl"}
+   /*
+    * File: OP_SUB_DOUBLE.S
+    */
+
+    movzbl   2(rPC),%eax                # eax<- BB
+    movzbl   3(rPC),%ecx                # ecx<- CC
+    # TODO: movsd?
+    movq        (rFP, %eax, 4), %xmm0   # %xmm0<- vBB
+    movq        (rFP, %ecx, 4), %xmm1   # %xmm1<- vCC
+    FETCH_INST_OPCODE 2 %ecx
+    subsd       %xmm1, %xmm0
+    ADVANCE_PC 2
+    movq        %xmm0, (rFP, rINST, 4)  # vAA<- vBB - vCC
+    GOTO_NEXT_R %ecx
diff --git a/vm/mterp/x86/OP_SUB_DOUBLE_2ADDR.S b/vm/mterp/x86/OP_SUB_DOUBLE_2ADDR.S
index 991c380..05dce86 100644
--- a/vm/mterp/x86/OP_SUB_DOUBLE_2ADDR.S
+++ b/vm/mterp/x86/OP_SUB_DOUBLE_2ADDR.S
@@ -1,2 +1,15 @@
-%verify "executed"
-%include "x86/binflop2addr.S" {"instr":"fsubl","load":"fldl","store":"fstpl"}
+   /*
+    * File: OP_SUB_DOUBLE_2ADDR.S
+    */
+
+    movzx       rINSTbl,%ecx            # ecx<- A+
+    andb        $$0xf,%cl               # ecx<- A
+    sarl        $$4,rINST               # rINST<- B
+    # TODO: movsd?
+    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
+    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
+    FETCH_INST_OPCODE 1 %eax
+    subsd       %xmm1, %xmm0            # %xmm0<- vA op vB
+    ADVANCE_PC 1
+    movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
+    GOTO_NEXT_R %eax
diff --git a/vm/mterp/x86/bincmp.S b/vm/mterp/x86/bincmp.S
index ffa4a24..ae68dd3 100644
--- a/vm/mterp/x86/bincmp.S
+++ b/vm/mterp/x86/bincmp.S
@@ -21,4 +21,9 @@
     movl     offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $$0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT
diff --git a/vm/mterp/x86/binop2addr.S b/vm/mterp/x86/binop2addr.S
index 7cd8c5b..4d30880 100644
--- a/vm/mterp/x86/binop2addr.S
+++ b/vm/mterp/x86/binop2addr.S
@@ -2,11 +2,7 @@
     /*
      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
      * that specifies an instruction that performs "result = r0 op r1".
-     * This could be an ARM instruction or a function call.  (If the result
-     * comes back in a register other than r0, you can override "result".)
-     *
-     * If "chkzero" is set to 1, we perform a divide-by-zero check on
-     * vCC (r1).  Useful for integer division and modulus.
+     * This could be an instruction or a function call.
      *
      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
@@ -15,7 +11,7 @@
      */
     /* binop/2addr vA, vB */
     movzx   rINSTbl,%ecx               # ecx<- A+
-    sarl    $$4,rINST                 # rINST<- B
+    sarl    $$4,rINST                  # rINST<- B
     GET_VREG_R %eax rINST              # eax<- vB
     andb    $$0xf,%cl                  # ecx<- A
     $instr                             # for ex: addl   %eax,(rFP,%ecx,4)
diff --git a/vm/mterp/x86/entry.S b/vm/mterp/x86/entry.S
index 3e2a708..f97d6a5 100644
--- a/vm/mterp/x86/entry.S
+++ b/vm/mterp/x86/entry.S
@@ -46,11 +46,19 @@
     movl    offThread_curFrame(%ecx),rFP
     movl    offThread_curHandlerTable(%ecx),rIBASE
 
-/* Remember %esp for future "longjmp" */
+    /* Remember %esp for future "longjmp" */
     movl    %esp,offThread_bailPtr(%ecx)
 
-   /* Normal case: start executing the instruction at rPC */
+    /* Fetch next instruction before potential jump */
     FETCH_INST
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    movl        $$0, offThread_inJitCodeCache(%ecx)
+    cmpl        $$0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
+
+   /* Normal case: start executing the instruction at rPC */
     GOTO_NEXT
 
     .global dvmMterpStdBail
@@ -72,7 +80,7 @@
 dvmMterpStdBail:
     movl    4(%esp),%ecx                 # grab self
     movl    8(%esp),%eax                 # changeInterp to return reg
-    movl    offThread_bailPtr(%ecx),%esp   # Restore "setjmp" esp
+    movl    offThread_bailPtr(%ecx),%esp # Restore "setjmp" esp
     movl    %esp,%ebp
     addl    $$(FRAME_SIZE-4), %ebp       # Restore %ebp at point of setjmp
     movl    EDI_SPILL(%ebp),%edi
@@ -83,6 +91,18 @@
     ret                                  # return to dvmMterpStdRun's caller
 
 
+#ifdef WITH_JIT
+    .global     dvmNcgInvokeInterpreter
+    .type       dvmNcgInvokeInterpreter, %function
+/* input: start of method in %eax */
+dvmNcgInvokeInterpreter:
+    movl        %eax, rPC
+    movl   rSELF, %ecx
+    movl   offThread_curHandlerTable(%ecx),rIBASE
+    FETCH_INST_R %ecx                    # %edx<- opcode
+    GOTO_NEXT_R %ecx                    # start executing the instruction at rPC
+#endif
+
 /*
  * Strings
  */
diff --git a/vm/mterp/x86/footer.S b/vm/mterp/x86/footer.S
index 6de4a33..52e55e9 100644
--- a/vm/mterp/x86/footer.S
+++ b/vm/mterp/x86/footer.S
@@ -35,12 +35,14 @@
  * the interpreter and code cache. rPC must be set on entry.
  */
 dvmJitToInterpPunt:
+    GET_PC
 #if defined(WITH_JIT_TUNING)
     movl   rPC, OUT_ARG0(%esp)
     call   dvmBumpPunt
 #endif
     movl   rSELF, %ecx
     movl   offThread_curHandlerTable(%ecx),rIBASE
+    movl        $$0, offThread_inJitCodeCache(%ecx)
     FETCH_INST_R %ecx
     GOTO_NEXT_R %ecx
 
@@ -77,17 +79,19 @@
 #if defined(WITH_JIT_TUNING)
     call   dvmBumpNoChain
 #endif
+    movl   %eax, rPC
     movl   rSELF, %eax
     movl   rPC,OUT_ARG0(%esp)
     movl   %eax,OUT_ARG1(%esp)
-    call   dvmJitGetTraceAddrThread        # (pc, self)
+    call   dvmJitGetTraceAddrThread  # (pc, self)
     movl   rSELF,%ecx                # ecx <- self
     movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
     cmpl   $$0, %eax
     jz     1f
-    call   *%eax                     # exec translation if we've got one
+    jmp    *%eax                     # exec translation if we've got one
     # won't return
 1:
+    EXPORT_PC
     movl   rSELF, %ecx
     movl   offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST_R %ecx
@@ -95,7 +99,7 @@
 
 /*
  * Return from the translation cache and immediately request a
- * translation fro the exit target, but don't attempt to chain.
+ * translation from the exit target, but don't attempt to chain.
  * rPC set on entry.
  */
     .global dvmJitToInterpTraceSelectNoChain
@@ -103,15 +107,17 @@
 #if defined(WITH_JIT_TUNING)
     call   dvmBumpNoChain
 #endif
+    movl   %ebx, rPC
+    lea    4(%esp), %esp #to recover the esp update due to function call
     movl   rSELF, %eax
     movl   rPC,OUT_ARG0(%esp)
     movl   %eax,OUT_ARG1(%esp)
-    call   dvmJitGetTraceAddrThread # (pc, self)
+    call   dvmJitGetTraceAddrThread  # (pc, self)
     movl   rSELF,%ecx
     cmpl   $$0,%eax
     movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
     jz     1f
-    call   *%eax              # jump to tranlation
+    jmp    *%eax              # jump to tranlation
     # won't return
 
 /* No Translation - request one */
@@ -124,7 +130,8 @@
     FETCH_INST_R %ecx         # Continue interpreting if not
     GOTO_NEXT_R %ecx
 2:
-    movl   $$kJitTSelectRequestHot,rINST  # ask for trace select
+    ## Looks like an EXPORT_PC is needed here. Now jmp to common_selectTrace2
+    movl   $$kJitTSelectRequestHot,%eax # ask for trace select
     jmp    common_selectTrace
 
 /*
@@ -134,21 +141,32 @@
  */
     .global dvmJitToInterpTraceSelect
 dvmJitToInterpTraceSelect:
-    pop    rINST           # save chain cell address in callee save reg
-    movl   (rINST),rPC
+    movl   0(%esp), %eax          # get return address
+    movl   %ebx, rPC              # get first argument (target rPC)
+
+    ## TODO, need to clean up stack manipulation ... this isn't signal safe and
+    ## doesn't use the calling conventions of header.S
+    lea    4(%esp), %esp #to recover the esp update due to function call
+
+    ## An additional 5B instruction "jump 0" was added for a thread-safe
+    ## chaining cell update in JIT code cache. So the offset is now -17=-12-5.
+    lea    -17(%eax), %ebx #$$JIT_OFFSET_CHAIN_START(%eax), %ebx
+    lea    -4(%esp), %esp
     movl   rSELF, %eax
     movl   rPC,OUT_ARG0(%esp)
     movl   %eax,OUT_ARG1(%esp)
     call   dvmJitGetTraceAddrThread # (pc, self)
+    lea    4(%esp), %esp
     cmpl   $$0,%eax
+    movl   rSELF, %ecx
+    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
     jz     1b                 # no - ask for one
     movl   %eax,OUT_ARG0(%esp)
-# TODO - need to adjust rINST to beginning of sequence
     movl   rINST,OUT_ARG1(%esp)
     call   dvmJitChain        # Attempt dvmJitChain(codeAddr,chainAddr)
     cmpl   $$0,%eax           # Success?
     jz     toInterpreter      # didn't chain - interpret
-    call   *%eax
+    jmp    *%eax
     # won't return
 
 /*
@@ -156,71 +174,210 @@
  */
     .global dvmJitToInterpBackwardBranch
 dvmJitToInterpBackwardBranch:
+
+    .global     dvmJitToExceptionThrown
+dvmJitToExceptionThrown: //rPC in
+    movl   rSELF, %edx
+    GET_PC
+    movl   $$0, offThread_inJitCodeCache(%edx)
+    jmp common_exceptionThrown
+
     .global dvmJitToInterpNormal
 dvmJitToInterpNormal:
+/* one input: the target rPC value */
+    movl        0(%esp), %eax          # get return address
+    movl        %ebx, rPC              # get first argument (target rPC)
+
+    ## TODO, need to clean up stack manipulation ... this isn't signal safe and
+    ## doesn't use the calling conventions of header.S
+
+    ## An additional 5B instruction "jump 0" was added for a thread-safe
+    ## chaining cell update in JIT code cache. So the offset is now -17=-12-5.
+    lea         -17(%eax), %ebx #$$JIT_OFFSET_CHAIN_START(%eax), %ebx
+    lea         4(%esp), %esp
+    movl        rPC, OUT_ARG0(%esp)
+    movl        rSELF, %ecx
+    movl        %ecx, OUT_ARG1(%esp)
+    call        dvmJitGetTraceAddrThread
+    ## Here is the change from using rGLUE to rSELF for accessing the
+    ## JIT code cache flag
+    movl        rSELF, %ecx
+    movl        %eax, offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
+    #lea         4(%esp), %esp
+    cmp         $$0, %eax
+    je          toInterpreter
+    #lea         -8(%esp), %esp
+    movl        %ebx, OUT_ARG1(%esp)    # %ebx live thorugh dvmJitGetTraceAddrThread
+    movl        %eax, OUT_ARG0(%esp)    # first argument
+    call        dvmJitChain
+    #lea         8(%esp), %esp
+    cmp         $$0, %eax
+    je          toInterpreter
+    jmp         *%eax                   #to native address
+
     .global dvmJitToInterpNoChain
 dvmJitToInterpNoChain:
+dvmJitToInterpNoChain: #rPC in eax
+    ## TODO, need to clean up stack manipulation ... this isn't signal safe and
+    ## doesn't use the calling conventions of header.S
+    movl        %eax, rPC
+    movl        rPC, OUT_ARG0(%esp)
+    movl        rSELF, %ecx
+    movl        %ecx, OUT_ARG1(%esp)
+    call        dvmJitGetTraceAddrThread
+    ## Here is the change from using rGLUE to rSELF for accessing the
+    ## JIT code cache flag
+    movl        rSELF, %ecx
+    movl        %eax, offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
+    cmp         $$0, %eax
+    je          toInterpreter
+    jmp         *%eax                   #to native address
+
 toInterpreter:
-    jmp  common_abort
+    EXPORT_PC
+    movl        rSELF, %ecx
+    movl        offThread_curHandlerTable(%ecx), rIBASE
+    FETCH_INST
+    movl        offThread_pJitProfTable(%ecx), %eax
+    #Fallthrough
+
+/* ebx holds the pointer to the jit profile table
+   edx has the opCode */
+common_testUpdateProfile:
+    cmp         $$0, %eax
+    je          4f
+/* eax holds the pointer to the jit profile table
+   edx has the opCode
+   rPC points to the next bytecode */
 
 common_updateProfile:
     # quick & dirty hash
-    movl   rPC, %eax
-    shrl   $$12, %eax
-    xorl   rPC, %eax
-    andl   $$((1<<JIT_PROF_SIZE_LOG_2)-1),%eax
-    decb   (%edx,%eax)
+    movl   rPC, %ecx
+    shrl   $$12, %ecx
+    xorl   rPC, %ecx
+    andl   $$((1<<JIT_PROF_SIZE_LOG_2)-1), %ecx
+    decb   (%ecx,%eax)
+    #jmp    1f # remove
     jz     2f
 1:
     GOTO_NEXT
 2:
+common_Profile:
 /*
  * Here, we switch to the debug interpreter to request
  * trace selection.  First, though, check to see if there
  * is already a native translation in place (and, if so,
  * jump to it now.
  */
-    GET_JIT_THRESHOLD %ecx rINST  # leaves rSELF in %ecx
+    SPILL(rIBASE)
+    SPILL_TMP1(rINST)
+    movl        rSELF, rIBASE
+    GET_JIT_THRESHOLD rIBASE rINST  # leaves rSELF in %ecx
     EXPORT_PC
-    movb   rINSTbl,(%edx,%eax)   # reset counter
-    movl   %ecx,rINST            # preserve rSELF
+    movb   rINSTbl,(%ecx,%eax)   # reset counter
+    movl   rIBASE,rINST            # preserve rSELF
     movl   rSELF, %eax
     movl   rPC,OUT_ARG0(%esp)
-    movl   %eax,OUT_ARG1(%esp)
-    call   dvmJitGetTraceAddr  # (pc, self)
+    movl   rIBASE,OUT_ARG1(%esp)
+    call   dvmJitGetTraceAddrThread  # (pc, self)
+    UNSPILL(rIBASE)
     movl   %eax,offThread_inJitCodeCache(rINST)   # set the inJitCodeCache flag
+    UNSPILL_TMP1(rINST)
     cmpl   $$0,%eax
+    #jmp    1f # remove
     jz     1f
-    call   *%eax        # TODO: decide call vs/ jmp!.  No return either way
+    jmp   *%eax        # TODO: decide call vs/ jmp!.  No return either way
 1:
     movl   $$kJitTSelectRequest,%eax
     # On entry, eax<- jitState, rPC valid
 common_selectTrace:
-/* TODO */
-    call   dvmAbort
-#if 0
-    movl   rSELF,%ecx
-    movl   %eax,offThread_jitState(%ecx)
-    movl   $$kInterpEntryInstr,offThread_entryPoint(%ecx)
-    movl   $$1,rINST
-    jmp    common_gotoBail
-#endif
-#endif
+    mov         %ebx, EBX_SPILL(%ebp)
+    movl        rSELF, %ebx
+    movzwl      offThread_subMode(%ebx), %ecx
+    and         $$(kSubModeJitTraceBuild | kSubModeJitSV), %ecx
+    jne         3f                     # already doing JIT work, continue
+    movl        %eax, offThread_jitState(%ebx)
+    movl        rSELF, %eax
+    movl       %eax, OUT_ARG0(%esp)
+
+/*
+ * Call out to validate trace-building request. If successful, rIBASE will be swapped
+ * to send us into single-steppign trace building mode, so we need to refresh before
+ * we continue.
+ */
+
+   EXPORT_PC
+   SAVE_PC_FP_TO_SELF %ecx
+   call dvmJitCheckTraceRequest
+3:
+   mov          EBX_SPILL(%ebp), %ebx
+   FETCH_INST
+   movl rSELF, %ecx
+   movl offThread_curHandlerTable(%ecx), rIBASE
+4:
+   GOTO_NEXT
+
+common_selectTrace2:
+    mov         %ebx, EBX_SPILL(%ebp)
+    movl        rSELF, %ebx
+    movl        %ebx, OUT_ARG0(%esp)
+    movl        %eax, offThread_jitState(%ebx)
+    movzwl      offThread_subMode(%ebx), %ecx
+    mov         EBX_SPILL(%ebp), %ebx
+    and         (kSubModeJitTraceBuild | kSubModeJitSV), %ecx
+    jne         3f                     # already doing JIT work, continue
 
 
 
 /*
+ * Call out to validate trace-building request. If successful, rIBASE will be swapped
+ * to send us into single-steppign trace building mode, so we need to refresh before
+ * we continue.
+ */
+
+   EXPORT_PC
+   SAVE_PC_FP_TO_SELF %ecx
+   call dvmJitCheckTraceRequest
+3:
+   FETCH_INST
+   movl rSELF, %ecx
+   movl offThread_curHandlerTable(%ecx), rIBASE
+4:
+   GOTO_NEXT
+
+#endif
+
+/*
+ * For the invoke codes we need to know what register holds the "this" pointer. However
+ * it seems the this pointer is assigned consistently most times it is in %ecx but other
+ * times it is in OP_INVOKE_INTERFACE_JUMBO OP_INVOKE_INTERFACE OP_INVOKE_SUPER_QUICK and
+ * OP_INVOKE_VIRTUAL_QUICK
+*/
+
+/*
  * Common code for method invocation with range.
  *
  * On entry:
  *   eax = Method* methodToCall
+ *   ecx = "this"
  *   rINSTw trashed, must reload
  *   rIBASE trashed, must reload before resuming interpreter
  */
 
 common_invokeMethodRange:
 .LinvokeNewRange:
-
+#if defined(WITH_JIT)
+    SPILL_TMP1(%edx)
+    SPILL_TMP2(%ebx)
+    movl        rSELF, %edx
+    movzwl      offThread_subMode(%edx), %ebx
+    and         $$kSubModeJitTraceBuild, %ebx
+    jz          6f
+    call        save_callsiteinfo
+6:
+    UNSPILL_TMP2(%ebx)
+    UNSPILL_TMP1(%edx)
+#endif
    /*
     * prepare to copy args to "outs" area of current frame
     */
@@ -262,6 +419,18 @@
     */
 
 common_invokeMethodNoRange:
+#if defined(WITH_JIT)
+    SPILL_TMP1(%edx)
+    SPILL_TMP2(%ebx)
+    movl        rSELF, %edx
+    movzwl      offThread_subMode(%edx), %ebx
+    and         $$kSubModeJitTraceBuild, %ebx
+    jz          6f
+    call        save_callsiteinfo
+6:
+    UNSPILL_TMP2(%ebx)
+    UNSPILL_TMP1(%edx)
+#endif
 .LinvokeNewNoRange:
     movzbl      1(rPC),rINST       # rINST<- BA
     movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA
@@ -349,6 +518,9 @@
     movl        rSELF,%ecx              # %ecx<- pthread
     movl        rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP
     movl        rPC, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC
+#if defined(WITH_JIT)
+    movl        $$0, offStackSaveArea_returnAddr(%edx)
+#endif
 
     /* Any special actions to take? */
     cmpw        $$0, offThread_subMode(%ecx)
@@ -372,6 +544,12 @@
     movl        rFP, offThread_curFrame(%ecx) # curFrame<-newFP
     movl        offThread_curHandlerTable(%ecx),rIBASE
     FETCH_INST
+#if defined(WITH_JIT)
+    /* rPC is already updated */
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $$0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT                           # jump to methodToCall->insns
 
 2:
@@ -431,8 +609,8 @@
      */
     SPILL_TMP1(%eax)                    # save methodTocall
     movl        rPC, offThread_pc(%ecx)
-    movl        %eax, OUT_ARG0(%esp)
     movl        %ecx, OUT_ARG1(%esp)
+    movl        %eax, OUT_ARG0(%esp)
     movl        rFP, OUT_ARG2(%esp)
     call        dvmReportPreNativeInvoke # (methodToCall, self, fp)
     UNSPILL_TMP1(%eax)                  # restore methodToCall
@@ -448,8 +626,8 @@
 
     UNSPILL_TMP1(%eax)                  # restore methodToCall
     movl        rSELF, %ecx
-    movl        %eax, OUT_ARG0(%esp)
     movl        %ecx, OUT_ARG1(%esp)
+    movl        %eax, OUT_ARG0(%esp)
     movl        rFP, OUT_ARG2(%esp)
     call        dvmReportPostNativeInvoke # (methodToCall, self, fp)
     jmp         7b                      # rejoin
@@ -466,36 +644,68 @@
  * Common code for handling a return instruction
  */
 common_returnFromMethod:
-    movl    rSELF,%ecx
-    SAVEAREA_FROM_FP %eax                         # eax<- saveArea (old)
+    movl    rSELF, %ecx
+    SAVEAREA_FROM_FP %eax                       # %eax<- saveArea(old)
     cmpw    $$0, offThread_subMode(%ecx)          # special action needed?
     jne     19f                                   # go if so
 14:
-    movl    offStackSaveArea_prevFrame(%eax),rFP  # rFP<- prevFrame
-    movl    (offStackSaveArea_method-sizeofStackSaveArea)(rFP),rINST
-    cmpl    $$0,rINST                             # break?
-    je      common_gotoBail    # break frame, bail out completely
 
-    movl    offStackSaveArea_savedPc(%eax),rPC # pc<- saveArea->savedPC
-    movl    rINST,offThread_method(%ecx)       # self->method = newSave->meethod
-    movl    rFP,offThread_curFrame(%ecx)       # curFrame = fp
-    movl    offMethod_clazz(rINST),%eax        # eax<- method->clazz
-    movl    offThread_curHandlerTable(%ecx),rIBASE
-    movl    offClassObject_pDvmDex(%eax),rINST # rINST<- method->clazz->pDvmDex
-    FETCH_INST_OPCODE 3 %eax
-    movl    rINST,offThread_methodClassDex(%ecx)
+    movl        offStackSaveArea_prevFrame(%eax), rFP # rFP<- saveArea->PrevFrame
+    movl        (offStackSaveArea_method - sizeofStackSaveArea)(rFP), rINST # rINST<- method we are returning to
+    cmpl        $$0, rINST               # check for break frame
+    je          common_gotoBail         # bail if break frame
+    movl        offThread_curHandlerTable(%ecx),rIBASE
+    movl        offStackSaveArea_savedPc(%eax), rPC # rPC<- saveAreaOld->savedPc
+#if defined(WITH_JIT)
+    movl        offStackSaveArea_returnAddr(%eax), %ecx
+#endif
+    movl        rSELF, %eax
+    movl        rINST, offThread_method(%eax) # glue->method<- newSave->method
+    movl        offMethod_clazz(rINST), rINST # rINST<- method->clazz
+    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- rFP
+#if defined(WITH_JIT)
+    //update self->offThread_inJitCodeCache
+    movl        %ecx, offThread_inJitCodeCache(%eax)
+#endif
+    movl        offClassObject_pDvmDex(rINST), rINST # rINST<- method->clazz->pDvmDex
+    movl        rINST, offThread_methodClassDex(%eax) # glue->pDvmDex<- method->clazz->pDvmDex
+#if defined(WITH_JIT)
+    cmp         $$0, %ecx
+    je          .returnToBC
+    movl        %ecx, %eax
+    jmp         *%eax
+#endif
+
+.returnToBC:
+
+#if defined(WITH_JIT)
+    FETCH_INST_OPCODE  3, %ecx                 # %eax<- next instruction hi; fetch, advance
+    // %ecx has the opcode
+    addl         $$6, rPC               # 3*2 = 6
+    SPILL_TMP1   (%ecx)
+    movl         rSELF, %ecx
+    FETCH_INST
+    UNSPILL_TMP1   (%ecx)
+    movzbl      1(rPC), rINST
+    jmp     *(rIBASE,%ecx,4)
+#else
+    FETCH_INST_WORD 3
     ADVANCE_PC 3
-    GOTO_NEXT_R %eax
+    GOTO_NEXT
+#endif
 
 19:
     /*
      * Handle special subMode actions
      * On entry, rFP: prevFP, %ecx: self, %eax: saveArea
      */
-    movl     rFP, offThread_curFrame(%ecx)    # update interpSave.curFrame
+    SPILL_TMP1(%ebx)
+    movl     offStackSaveArea_prevFrame(%eax), %ebx # %ebx<- saveArea->PrevFrame
     movl     rPC, offThread_pc(%ecx)          # update interpSave.pc
+    movl     %ebx, offThread_curFrame(%ecx)    # update interpSave.curFrame
     movl     %ecx, OUT_ARG0(%esp)             # parameter self
     call     dvmReportReturn                  # (self)
+    UNSPILL_TMP1(%ebx)
     movl     rSELF, %ecx                      # restore self
     SAVEAREA_FROM_FP %eax                     # restore saveArea
     jmp      14b
@@ -518,12 +728,74 @@
     movl   rINST,OUT_ARG1(%esp)     # changeInterp in arg1
     call   dvmMterpStdBail          # bail out....
 
+/*
+ * The JIT's invoke method needs to remember the callsite class and
+ * target pair.  Save them here so that they are available to
+ * dvmCheckJit following the interpretation of this invoke.
+ *
+ * eax = Method* methodToCall
+ * ecx = "this"
+ * edx = rSELF
+ * ebx = free to use
+ */
+#if defined(WITH_JIT)
+save_callsiteinfo:
+    cmp     $$0, %ecx
+    je      2f
+    movl    offObject_clazz(%ecx), %ecx
+2:
+    movl    rSELF, %ebx
+    movl    %eax, offThread_methodToCall(%ebx)
+    movl    %ecx, offThread_callsiteClass(%ebx)
+    ret
+#endif
+
+#if defined(WITH_JIT)
+
+    /*
+     * If the JIT is actively building a trace we need to make sure
+     * that the field is fully resolved before including the current
+     * instruction.
+     *
+     * On entry:
+     *     %ecx: &dvmDex->pResFields[field]
+     *     %eax:  field pointer (must preserve)
+     */
+common_verifyField:
+    movl    %ebx, TMP_SPILL1(%ebp)
+    movl     rSELF, %ebx
+    movzwl   offThread_subMode(%ebx), %ebx
+    andl     $$kSubModeJitTraceBuild, %ebx
+    movl    TMP_SPILL1(%ebp), %ebx
+    jne      1f
+    ret
+1:
+    movl    (%ecx), %ecx
+    cmp     $$0, %ecx
+    je      1f
+    ret
+1:
+    SPILL_TMP1(%eax)
+    SPILL_TMP2(%edx)
+    movl     rSELF, %ecx
+    # Because we call into this helper from a bytecode, we have
+    # to be careful not to write over the return address when using
+    # the OUT_ARG macros
+    lea      -8(%esp), %esp
+    movl     %ecx, OUT_ARG0(%esp)
+    movl     rPC, OUT_ARG1(%esp)
+    call     dvmJitEndTraceSelect
+    lea      8(%esp), %esp
+    UNSPILL_TMP2(%edx)
+    UNSPILL_TMP1(%eax)
+    ret
+#endif
 
 /*
  * After returning from a "selfd" function, pull out the updated values
  * and start executing at the next instruction.
  */
- common_resumeAfterGlueCall:
+common_resumeAfterGlueCall:
      movl  rSELF, %eax
      movl  offThread_pc(%eax),rPC
      movl  offThread_curFrame(%eax),rFP
@@ -556,7 +828,6 @@
  * On entry, method name in eax
  */
 common_errNoSuchMethod:
-
     EXPORT_PC
     movl    %eax,OUT_ARG0(%esp)
     call    dvmThrowNoSuchMethodError
@@ -599,12 +870,132 @@
  * This does not return.
  */
 common_exceptionThrown:
-    movl    rSELF,%ecx
-    movl    rPC,offThread_pc(%ecx)
-    movl    rFP,offThread_curFrame(%ecx)
-    movl    %ecx,OUT_ARG0(%esp)
-    call    dvmMterp_exceptionThrown
-    jmp     common_resumeAfterGlueCall
+.LexceptionNew:
+
+    EXPORT_PC
+    movl       rSELF, %ecx
+    movl       %ecx, OUT_ARG0(%esp)
+    call       dvmCheckSuspendPending
+
+    movl       rSELF, %ecx
+    movl       offThread_exception(%ecx), %edx   # %edx <- self->exception
+    movl       %edx, OUT_ARG0(%esp)
+    movl       %ecx, OUT_ARG1(%esp)
+    SPILL_TMP1(%edx)
+    call       dvmAddTrackedAlloc      # don't let the exception be GCed
+    UNSPILL_TMP1(%edx)
+    movl       rSELF, %ecx
+    movl       offThread_subMode(%ecx), %eax    # get subMode flags
+    movl       $$0, offThread_exception(%ecx)
+
+    # Special subMode?
+    cmpl       $$0, %eax                # any special subMode handling needed?
+    je         8f                      # go if so
+
+    # Manage debugger bookkeeping
+    movl       rPC, offThread_pc(%ecx) # update interpSave.pc
+    movl       rFP, offThread_curFrame(%ecx) # update interpSave.curFrame
+    movl       %ecx, OUT_ARG0(%esp)
+    movl       %edx, OUT_ARG1(%esp)
+    SPILL_TMP1(%edx)
+    call       dvmReportExceptionThrow # (self, exception)
+    UNSPILL_TMP1(%edx)
+    movl       rSELF, %ecx
+
+8:
+    /*
+    * set up args and a local for &fp
+    */
+    lea        20(%esp), %esp          # raise %esp
+    movl       rFP, (%esp)               # save fp
+    movl       %esp, %eax              # %eax = &fp
+    lea        -20(%esp), %esp         # reset %esp
+    movl       %eax, OUT_ARG4(%esp)    # Arg 4 = &fp
+    movl       $$0, OUT_ARG3(%esp)      # Arg 3 = false
+    movl       %edx, OUT_ARG2(%esp)    # Arg 2 = exception
+    movl       %ecx, OUT_ARG0(%esp)    # Arg 0 = self
+
+    movl       offThread_method(%ecx), %eax # %eax = self->method
+    movl       offMethod_insns(%eax), %eax  # %eax = self->method->insn
+    # ldrh    lr, [rSELF, #offThread_subMode]  @ lr<- subMode flags  # TODO
+    movl       rPC, %ecx
+    subl       %eax, %ecx              # %ecx = pc - self->method->insn
+    sar        $$1, %ecx                # adjust %ecx for code offset
+    movl       %ecx, OUT_ARG1(%esp)    # Arg 1 = %ecx
+
+    /* call, %eax gets catchRelPc (a code-unit offset) */
+    SPILL_TMP1(%edx)                   # save exception
+    call       dvmFindCatchBlock       # call(self, relPc, exc, scan?, &fp)
+    UNSPILL_TMP1(%edx)                 # restore exception
+
+    /* fix earlier stack overflow if necessary; may trash rFP */
+    movl       rSELF, %ecx
+    cmpl       $$0, offThread_stackOverflowed(%ecx) # did we overflow?
+    je         1f                         # no, skip ahead
+    movl       %eax, rFP                  # save relPc result in rFP
+    movl       %ecx, OUT_ARG0(%esp)       # Arg 0 = self
+    movl       %edx, OUT_ARG1(%esp)       # Arg 1 = exception
+    SPILL_TMP1(%edx)
+    call       dvmCleanupStackOverflow    # call(self, exception)
+    UNSPILL_TMP1(%edx)
+    movl       rFP, %eax                  # restore result
+    movl       rSELF, %ecx
+1:
+
+    /* update frame pointer and check result from dvmFindCatchBlock */
+    movl       20(%esp), rFP              # retrieve the updated rFP
+    cmpl       $$0, %eax                  # is catchRelPc < 0?
+    jl         .LnotCaughtLocally
+
+    /* adjust locals to match self->interpSave.curFrame and updated PC */
+    SAVEAREA_FROM_FP rINST             # rINST<- new save area
+    movl       offStackSaveArea_method(rINST), rINST # rINST<- new method
+    movl       rINST, offThread_method(%ecx)         # self->method = new method
+    movl       offMethod_clazz(rINST), %ecx          # %ecx = method->clazz
+    movl       offMethod_insns(rINST), rINST         # rINST = method->insn
+    movl       offClassObject_pDvmDex(%ecx), %ecx    # %ecx = method->clazz->pDvmDex
+    lea        (rINST, %eax, 2), rPC      # rPC<- method->insns + catchRelPc
+    movl       rSELF, rINST
+    movl       %ecx, offThread_methodClassDex(rINST) # self->pDvmDex = method->clazz->pDvmDex
+
+    /* release the tracked alloc on the exception */
+    movl       %edx, OUT_ARG0(%esp)       # Arg 0 = exception
+    movl       rINST, OUT_ARG1(%esp)      # Arg 1 = self
+    SPILL_TMP1(%edx)
+    call       dvmReleaseTrackedAlloc     # release the exception
+    UNSPILL_TMP1(%edx)
+
+    /* restore the exception if the handler wants it */
+    movl       rSELF, %ecx
+    FETCH_INST
+    movzbl     rINSTbl, %eax
+    cmpl       $$OP_MOVE_EXCEPTION, %eax   # is it "move-exception"?
+    jne        1f
+    movl       %edx, offThread_exception(%ecx) # restore exception
+1:
+    movl       offThread_curHandlerTable(%ecx), rIBASE # refresh rIBASE
+    GOTO_NEXT
+
+.LnotCaughtLocally: # %edx = exception
+    /* fix stack overflow if necessary */
+    movl       rSELF, %ecx
+    movl       offThread_stackOverflowed(%ecx), %eax
+    cmpl       $$0, %eax                   # did we overflow earlier?
+    je         1f
+    movl       %ecx, OUT_ARG0(%esp)
+    movl       %edx, OUT_ARG1(%esp)
+    SPILL_TMP1(%edx)
+    call       dvmCleanupStackOverflow
+    UNSPILL_TMP1(%edx)
+
+1:
+    movl       rSELF, %ecx
+    movl       %edx, offThread_exception(%ecx) #restore exception
+    movl       %edx, OUT_ARG0(%esp)
+    movl       %ecx, OUT_ARG1(%esp)
+    call       dvmReleaseTrackedAlloc     # release the exception
+    movl       rSELF, %ecx
+    jmp        common_gotoBail            # bail out
 
 common_abort:
     movl    $$0xdeadf00d,%eax
diff --git a/vm/mterp/x86/header.S b/vm/mterp/x86/header.S
index b612fd8..16f3d98 100644
--- a/vm/mterp/x86/header.S
+++ b/vm/mterp/x86/header.S
@@ -51,8 +51,8 @@
 to callee save registers).
 
   nick     reg   purpose
-  rPC      edi   interpreted program counter, used for fetching instructions
-  rFP      esi   interpreted frame pointer, used for accessing locals and args
+  rPC      esi   interpreted program counter, used for fetching instructions
+  rFP      edi   interpreted frame pointer, used for accessing locals and args
   rINSTw   bx    first 16-bit code of current instruction
   rINSTbl  bl    opcode portion of instruction word
   rINSTbh  bh    high byte of inst word, usually contains src/tgt reg names
@@ -99,7 +99,14 @@
 #define OUT_ARG2       (  8)
 #define OUT_ARG1       (  4)
 #define OUT_ARG0       (  0)  /* <- dvmMterpStdRun esp */
+#if defined(WITH_JIT)
+/* for spill region: increase size by 48 (to keep 16-byte alignment) */
+/* 76 + 48 = 124 */
+#define JIT_SPILL      (-56)
+#define FRAME_SIZE     124
+#else
 #define FRAME_SIZE     76
+#endif
 
 #define SPILL(reg) movl reg##,reg##_SPILL(%ebp)
 #define UNSPILL(reg) movl reg##_SPILL(%ebp),reg
@@ -149,6 +156,10 @@
     movl     rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP)
 .endm
 
+.macro GET_PC
+    movl     (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP), rPC
+.endm
+
 /*
  * Given a frame pointer, find the stack save area.
  *
@@ -250,6 +261,13 @@
 #define sReg2 LOCAL2_OFFSET(%ebp)
 
    /*
+    * x86 JIT Helpers
+    */
+
+    .macro dumpSwitch _regData _regScratch1 _regScratch2
+    .endm
+
+   /*
     * Hard coded helper values.
     */
 
diff --git a/vm/mterp/x86/zcmp.S b/vm/mterp/x86/zcmp.S
index cbda889..e9fc7d4 100644
--- a/vm/mterp/x86/zcmp.S
+++ b/vm/mterp/x86/zcmp.S
@@ -9,12 +9,17 @@
      */
     /* if-cmp vAA, +BBBB */
     cmpl     $$0,(rFP,rINST,4)     # compare (vA, 0)
+    movl     rSELF,%ecx
     movl     $$2,%eax              # assume branch not taken
     j${revcmp}   1f
-    movl     rSELF,%ecx
     movswl   2(rPC),%eax           # fetch signed displacement
     movl     offThread_curHandlerTable(%ecx),rIBASE
 1:
     FETCH_INST_INDEXED %eax
     ADVANCE_PC_INDEXED %eax
+#if defined(WITH_JIT)
+    GET_JIT_PROF_TABLE %ecx %eax
+    cmp         $$0, %eax
+    jne         common_updateProfile # set up %ebx & %edx & rPC
+#endif
     GOTO_NEXT